Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
2bdbeeeb
Unverified
Commit
2bdbeeeb
authored
Apr 18, 2023
by
OptimismBot
Committed by
GitHub
Apr 18, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5474 from ethereum-optimism/fix/debug-migrated-withdrawals
op-chain-ops: legacy withdrawal script refactoring
parents
d460e767
0ac98a2e
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
96 additions
and
27 deletions
+96
-27
main.go
op-chain-ops/cmd/withdrawals/main.go
+80
-8
migrate.go
op-chain-ops/crossdomain/migrate.go
+5
-10
migrate_test.go
op-chain-ops/crossdomain/migrate_test.go
+3
-3
message-utils.ts
packages/sdk/src/utils/message-utils.ts
+5
-3
message-utils.spec.ts
packages/sdk/test/utils/message-utils.spec.ts
+3
-3
No files found.
op-chain-ops/cmd/withdrawals/main.go
View file @
2bdbeeeb
...
@@ -22,11 +22,14 @@ import (
...
@@ -22,11 +22,14 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
)
)
// abiTrue represents the storage representation of the boolean
// abiTrue represents the storage representation of the boolean
...
@@ -116,6 +119,10 @@ func main() {
...
@@ -116,6 +119,10 @@ func main() {
Value
:
"bad-withdrawals.json"
,
Value
:
"bad-withdrawals.json"
,
Usage
:
"Path to write JSON file of bad withdrawals to manually inspect"
,
Usage
:
"Path to write JSON file of bad withdrawals to manually inspect"
,
},
},
&
cli
.
StringFlag
{
Name
:
"storage-out"
,
Usage
:
"Path to write text file of L2ToL1MessagePasser storage"
,
},
},
},
Action
:
func
(
ctx
*
cli
.
Context
)
error
{
Action
:
func
(
ctx
*
cli
.
Context
)
error
{
clients
,
err
:=
util
.
NewClients
(
ctx
)
clients
,
err
:=
util
.
NewClients
(
ctx
)
...
@@ -163,10 +170,11 @@ func main() {
...
@@ -163,10 +170,11 @@ func main() {
}
}
outfile
:=
ctx
.
String
(
"bad-withdrawals-out"
)
outfile
:=
ctx
.
String
(
"bad-withdrawals-out"
)
f
,
err
:=
os
.
OpenFile
(
outfile
,
os
.
O_WRONLY
|
os
.
O_CREATE
|
os
.
O_APPEND
,
0
o
755
)
f
,
err
:=
os
.
OpenFile
(
outfile
,
os
.
O_WRONLY
|
os
.
O_CREATE
|
os
.
O_APPEND
,
0
o
644
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
defer
f
.
Close
()
// create a transactor
// create a transactor
opts
,
err
:=
newTransactor
(
ctx
)
opts
,
err
:=
newTransactor
(
ctx
)
...
@@ -177,6 +185,28 @@ func main() {
...
@@ -177,6 +185,28 @@ func main() {
// Need this to compare in event parsing
// Need this to compare in event parsing
l1StandardBridgeAddress
:=
common
.
HexToAddress
(
ctx
.
String
(
"l1-standard-bridge-address"
))
l1StandardBridgeAddress
:=
common
.
HexToAddress
(
ctx
.
String
(
"l1-standard-bridge-address"
))
if
storageOutfile
:=
ctx
.
String
(
"storage-out"
);
storageOutfile
!=
""
{
ff
,
err
:=
os
.
OpenFile
(
storageOutfile
,
os
.
O_WRONLY
|
os
.
O_CREATE
|
os
.
O_APPEND
,
0
o644
)
if
err
!=
nil
{
return
err
}
defer
ff
.
Close
()
log
.
Info
(
"Fetching storage for L2ToL1MessagePasser"
)
if
storageRange
,
err
:=
callStorageRange
(
clients
,
predeploys
.
L2ToL1MessagePasserAddr
);
err
!=
nil
{
log
.
Info
(
"error getting storage range"
,
"err"
,
err
)
}
else
{
str
:=
""
for
key
,
value
:=
range
storageRange
{
str
+=
fmt
.
Sprintf
(
"%s: %s
\n
"
,
key
.
Hex
(),
value
.
Hex
())
}
_
,
err
=
ff
.
WriteString
(
str
)
if
err
!=
nil
{
return
err
}
}
}
// iterate over all of the withdrawals and submit them
// iterate over all of the withdrawals and submit them
for
i
,
wd
:=
range
wds
{
for
i
,
wd
:=
range
wds
{
log
.
Info
(
"Processing withdrawal"
,
"index"
,
i
)
log
.
Info
(
"Processing withdrawal"
,
"index"
,
i
)
...
@@ -234,7 +264,7 @@ func main() {
...
@@ -234,7 +264,7 @@ func main() {
// successful messages can be skipped, received messages failed
// successful messages can be skipped, received messages failed
// their execution and should be replayed
// their execution and should be replayed
if
isSuccessNew
{
if
isSuccessNew
{
log
.
Info
(
"Message already relayed"
,
"index"
,
i
,
"hash"
,
hash
,
"slot"
,
slot
)
log
.
Info
(
"Message already relayed"
,
"index"
,
i
,
"hash"
,
hash
.
Hex
(),
"slot"
,
slot
.
Hex
()
)
continue
continue
}
}
...
@@ -248,7 +278,7 @@ func main() {
...
@@ -248,7 +278,7 @@ func main() {
// the value should be set to a boolean in storage
// the value should be set to a boolean in storage
if
!
bytes
.
Equal
(
storageValue
,
abiTrue
.
Bytes
())
{
if
!
bytes
.
Equal
(
storageValue
,
abiTrue
.
Bytes
())
{
return
fmt
.
Errorf
(
"storage slot %x not found in state"
,
slot
)
return
fmt
.
Errorf
(
"storage slot %x not found in state"
,
slot
.
Hex
()
)
}
}
legacySlot
,
err
:=
wd
.
StorageSlot
()
legacySlot
,
err
:=
wd
.
StorageSlot
()
...
@@ -443,10 +473,48 @@ func callTrace(c *util.Clients, receipt *types.Receipt) (callFrame, error) {
...
@@ -443,10 +473,48 @@ func callTrace(c *util.Clients, receipt *types.Receipt) (callFrame, error) {
Tracer
:
&
tracer
,
Tracer
:
&
tracer
,
}
}
err
:=
c
.
L1RpcClient
.
Call
(
&
finalizationTrace
,
"debug_traceTransaction"
,
receipt
.
TxHash
,
traceConfig
)
err
:=
c
.
L1RpcClient
.
Call
(
&
finalizationTrace
,
"debug_traceTransaction"
,
receipt
.
TxHash
,
traceConfig
)
return
finalizationTrace
,
err
}
func
callStorageRangeAt
(
client
*
rpc
.
Client
,
blockHash
common
.
Hash
,
txIndex
int
,
addr
common
.
Address
,
keyStart
hexutil
.
Bytes
,
maxResult
int
,
)
(
*
eth
.
StorageRangeResult
,
error
)
{
var
storageRange
*
eth
.
StorageRangeResult
err
:=
client
.
Call
(
&
storageRange
,
"debug_storageRangeAt"
,
blockHash
,
txIndex
,
addr
,
keyStart
,
maxResult
)
return
storageRange
,
err
}
func
callStorageRange
(
c
*
util
.
Clients
,
addr
common
.
Address
)
(
state
.
Storage
,
error
)
{
header
,
err
:=
c
.
L2Client
.
HeaderByNumber
(
context
.
Background
(),
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
return
finalizationTrace
,
err
return
nil
,
err
}
}
return
finalizationTrace
,
err
hash
:=
header
.
Hash
()
keyStart
:=
hexutil
.
Bytes
(
common
.
Hash
{}
.
Bytes
())
maxResult
:=
1000
ret
:=
make
(
state
.
Storage
)
for
{
result
,
err
:=
callStorageRangeAt
(
c
.
L2RpcClient
,
hash
,
0
,
addr
,
keyStart
,
maxResult
)
if
err
!=
nil
{
return
nil
,
err
}
for
key
,
value
:=
range
result
.
Storage
{
ret
[
key
]
=
value
.
Value
}
if
result
.
NextKey
==
nil
{
break
}
else
{
keyStart
=
hexutil
.
Bytes
(
result
.
NextKey
.
Bytes
())
}
}
return
ret
,
nil
}
}
// handleFinalizeETHWithdrawal will ensure that the calldata is correct
// handleFinalizeETHWithdrawal will ensure that the calldata is correct
...
@@ -709,9 +777,13 @@ func newWithdrawals(ctx *cli.Context, l1ChainID *big.Int) ([]*crossdomain.Legacy
...
@@ -709,9 +777,13 @@ func newWithdrawals(ctx *cli.Context, l1ChainID *big.Int) ([]*crossdomain.Legacy
witnessFile
:=
ctx
.
String
(
"witness-file"
)
witnessFile
:=
ctx
.
String
(
"witness-file"
)
log
.
Debug
(
"Migration data"
,
"ovm-path"
,
ovmMsgs
,
"evm-messages"
,
evmMsgs
,
"witness-file"
,
witnessFile
)
log
.
Debug
(
"Migration data"
,
"ovm-path"
,
ovmMsgs
,
"evm-messages"
,
evmMsgs
,
"witness-file"
,
witnessFile
)
ovmMessages
,
err
:=
crossdomain
.
NewSentMessageFromJSON
(
ovmMsgs
)
var
ovmMessages
[]
*
crossdomain
.
SentMessage
if
err
!=
nil
{
var
err
error
return
nil
,
err
if
ovmMsgs
!=
""
{
ovmMessages
,
err
=
crossdomain
.
NewSentMessageFromJSON
(
ovmMsgs
)
if
err
!=
nil
{
return
nil
,
err
}
}
}
// use empty ovmMessages if its not mainnet. The mainnet messages are
// use empty ovmMessages if its not mainnet. The mainnet messages are
...
...
op-chain-ops/crossdomain/migrate.go
View file @
2bdbeeeb
...
@@ -96,17 +96,12 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com
...
@@ -96,17 +96,12 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com
return
w
,
nil
return
w
,
nil
}
}
// MigrateWithdrawalGasLimit computes the gas limit for the migrated withdrawal.
func
MigrateWithdrawalGasLimit
(
data
[]
byte
)
uint64
{
func
MigrateWithdrawalGasLimit
(
data
[]
byte
)
uint64
{
// Compute the cost of the calldata
// Compute the upper bound on the gas limit. This could be more
dataCost
:=
uint64
(
0
)
// accurate if individual 0 bytes and non zero bytes were accounted
for
_
,
b
:=
range
data
{
// for.
if
b
==
0
{
dataCost
:=
uint64
(
len
(
data
))
*
params
.
TxDataNonZeroGasEIP2028
dataCost
+=
params
.
TxDataZeroGas
}
else
{
dataCost
+=
params
.
TxDataNonZeroGasEIP2028
}
}
// Set the outer gas limit. This cannot be zero
// Set the outer gas limit. This cannot be zero
gasLimit
:=
dataCost
+
200
_000
gasLimit
:=
dataCost
+
200
_000
// Cap the gas limit to be 25 million to prevent creating withdrawals
// Cap the gas limit to be 25 million to prevent creating withdrawals
...
...
op-chain-ops/crossdomain/migrate_test.go
View file @
2bdbeeeb
...
@@ -71,15 +71,15 @@ func TestMigrateWithdrawalGasLimit(t *testing.T) {
...
@@ -71,15 +71,15 @@ func TestMigrateWithdrawalGasLimit(t *testing.T) {
},
},
{
{
input
:
[]
byte
{
0xff
,
0x00
},
input
:
[]
byte
{
0xff
,
0x00
},
output
:
200
_000
+
16
+
4
,
output
:
200
_000
+
16
+
16
,
},
},
{
{
input
:
[]
byte
{
0x00
},
input
:
[]
byte
{
0x00
},
output
:
200
_000
+
4
,
output
:
200
_000
+
16
,
},
},
{
{
input
:
[]
byte
{
0x00
,
0x00
,
0x00
},
input
:
[]
byte
{
0x00
,
0x00
,
0x00
},
output
:
200
_000
+
4
+
4
+
4
,
output
:
200
_000
+
16
+
16
+
16
,
},
},
}
}
...
...
packages/sdk/src/utils/message-utils.ts
View file @
2bdbeeeb
import
{
hashWithdrawal
,
calldataCost
}
from
'
@eth-optimism/core-utils
'
import
{
hashWithdrawal
}
from
'
@eth-optimism/core-utils
'
import
{
BigNumber
}
from
'
ethers
'
import
{
BigNumber
,
utils
}
from
'
ethers
'
import
{
LowLevelMessage
}
from
'
../interfaces
'
import
{
LowLevelMessage
}
from
'
../interfaces
'
const
{
hexDataLength
}
=
utils
/**
/**
* Utility for hashing a LowLevelMessage object.
* Utility for hashing a LowLevelMessage object.
*
*
...
@@ -25,7 +27,7 @@ export const hashLowLevelMessage = (message: LowLevelMessage): string => {
...
@@ -25,7 +27,7 @@ export const hashLowLevelMessage = (message: LowLevelMessage): string => {
*/
*/
export
const
migratedWithdrawalGasLimit
=
(
data
:
string
):
BigNumber
=>
{
export
const
migratedWithdrawalGasLimit
=
(
data
:
string
):
BigNumber
=>
{
// Compute the gas limit and cap at 25 million
// Compute the gas limit and cap at 25 million
const
dataCost
=
calldataCost
(
data
)
const
dataCost
=
BigNumber
.
from
(
hexDataLength
(
data
)).
mul
(
16
)
let
minGasLimit
=
dataCost
.
add
(
200
_000
)
let
minGasLimit
=
dataCost
.
add
(
200
_000
)
if
(
minGasLimit
.
gt
(
25
_000_000
))
{
if
(
minGasLimit
.
gt
(
25
_000_000
))
{
minGasLimit
=
BigNumber
.
from
(
25
_000_000
)
minGasLimit
=
BigNumber
.
from
(
25
_000_000
)
...
...
packages/sdk/test/utils/message-utils.spec.ts
View file @
2bdbeeeb
...
@@ -15,9 +15,9 @@ describe('Message Utils', () => {
...
@@ -15,9 +15,9 @@ describe('Message Utils', () => {
const
tests
=
[
const
tests
=
[
{
input
:
'
0x
'
,
result
:
BigNumber
.
from
(
200
_000
)
},
{
input
:
'
0x
'
,
result
:
BigNumber
.
from
(
200
_000
)
},
{
input
:
'
0xff
'
,
result
:
BigNumber
.
from
(
200
_000
+
16
)
},
{
input
:
'
0xff
'
,
result
:
BigNumber
.
from
(
200
_000
+
16
)
},
{
input
:
'
0xff00
'
,
result
:
BigNumber
.
from
(
200
_000
+
16
+
4
)
},
{
input
:
'
0xff00
'
,
result
:
BigNumber
.
from
(
200
_000
+
16
+
16
)
},
{
input
:
'
0x00
'
,
result
:
BigNumber
.
from
(
200
_000
+
4
)
},
{
input
:
'
0x00
'
,
result
:
BigNumber
.
from
(
200
_000
+
16
)
},
{
input
:
'
0x000000
'
,
result
:
BigNumber
.
from
(
200
_000
+
4
+
4
+
4
)
},
{
input
:
'
0x000000
'
,
result
:
BigNumber
.
from
(
200
_000
+
16
+
16
+
16
)
},
]
]
for
(
const
test
of
tests
)
{
for
(
const
test
of
tests
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment