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
c35b6e39
Unverified
Commit
c35b6e39
authored
Mar 07, 2023
by
mergify[bot]
Committed by
GitHub
Mar 07, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5058 from ethereum-optimism/feat/migration-fixes
op-chain-ops: Migration fixes
parents
ad4d235d
dfcd8feb
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
344 additions
and
82 deletions
+344
-82
main.go
op-chain-ops/cmd/op-migrate/main.go
+19
-18
main.go
op-chain-ops/cmd/withdrawals/main.go
+5
-7
legacy.go
op-chain-ops/crossdomain/legacy.go
+1
-1
params.go
op-chain-ops/crossdomain/params.go
+1
-1
precheck.go
op-chain-ops/crossdomain/precheck.go
+30
-9
precheck_test.go
op-chain-ops/crossdomain/precheck_test.go
+2
-2
witness.txt
op-chain-ops/crossdomain/testdata/witness.txt
+3
-0
types.go
op-chain-ops/crossdomain/types.go
+35
-0
types_test.go
op-chain-ops/crossdomain/types_test.go
+57
-0
witness.go
op-chain-ops/crossdomain/witness.go
+85
-15
witness_test.go
op-chain-ops/crossdomain/witness_test.go
+43
-0
addresses.go
op-chain-ops/ether/addresses.go
+3
-3
migrate.go
op-chain-ops/ether/migrate.go
+5
-4
precheck.go
op-chain-ops/ether/precheck.go
+17
-6
check.go
op-chain-ops/genesis/check.go
+24
-4
db_migration.go
op-chain-ops/genesis/db_migration.go
+5
-4
action.go
op-chain-ops/genesis/migration_action/action.go
+8
-7
util.go
op-chain-ops/util/util.go
+1
-1
No files found.
op-chain-ops/cmd/op-migrate/main.go
View file @
c35b6e39
...
@@ -8,6 +8,8 @@ import (
...
@@ -8,6 +8,8 @@ import (
"os"
"os"
"strings"
"strings"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/db"
"github.com/ethereum-optimism/optimism/op-chain-ops/db"
"github.com/mattn/go-isatty"
"github.com/mattn/go-isatty"
...
@@ -22,7 +24,6 @@ import (
...
@@ -22,7 +24,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/urfave/cli"
"github.com/urfave/cli"
...
@@ -46,11 +47,6 @@ func main() {
...
@@ -46,11 +47,6 @@ func main() {
Usage
:
"Path to ovm-addresses.json"
,
Usage
:
"Path to ovm-addresses.json"
,
Required
:
true
,
Required
:
true
,
},
},
&
cli
.
StringFlag
{
Name
:
"evm-addresses"
,
Usage
:
"Path to evm-addresses.json"
,
Required
:
true
,
},
&
cli
.
StringFlag
{
&
cli
.
StringFlag
{
Name
:
"ovm-allowances"
,
Name
:
"ovm-allowances"
,
Usage
:
"Path to ovm-allowances.json"
,
Usage
:
"Path to ovm-allowances.json"
,
...
@@ -62,8 +58,8 @@ func main() {
...
@@ -62,8 +58,8 @@ func main() {
Required
:
true
,
Required
:
true
,
},
},
&
cli
.
StringFlag
{
&
cli
.
StringFlag
{
Name
:
"
evm-messages
"
,
Name
:
"
witness-file
"
,
Usage
:
"Path to
evm-messages.json
"
,
Usage
:
"Path to
witness file
"
,
Required
:
true
,
Required
:
true
,
},
},
&
cli
.
StringFlag
{
&
cli
.
StringFlag
{
...
@@ -118,30 +114,35 @@ func main() {
...
@@ -118,30 +114,35 @@ func main() {
return
err
return
err
}
}
ovmAddresses
,
err
:=
migratio
n
.
NewAddresses
(
ctx
.
String
(
"ovm-addresses"
))
ovmAddresses
,
err
:=
crossdomai
n
.
NewAddresses
(
ctx
.
String
(
"ovm-addresses"
))
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
evmAddresess
,
err
:=
migration
.
NewAddresses
(
ctx
.
String
(
"evm-address
es"
))
ovmAllowances
,
err
:=
crossdomain
.
NewAllowances
(
ctx
.
String
(
"ovm-allowanc
es"
))
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
ovm
Allowances
,
err
:=
migration
.
NewAllowances
(
ctx
.
String
(
"ovm-allowanc
es"
))
ovm
Messages
,
err
:=
crossdomain
.
NewSentMessageFromJSON
(
ctx
.
String
(
"ovm-messag
es"
))
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
ovmMessages
,
err
:=
migration
.
NewSentMessage
(
ctx
.
String
(
"ovm-messages"
))
evmMessages
,
evmAddresses
,
err
:=
crossdomain
.
ReadWitnessData
(
ctx
.
String
(
"witness-file"
))
if
err
!=
nil
{
return
err
}
evmMessages
,
err
:=
migration
.
NewSentMessage
(
ctx
.
String
(
"evm-messages"
))
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
migrationData
:=
migration
.
MigrationData
{
log
.
Info
(
"Loaded witness data"
,
"ovmAddresses"
,
len
(
ovmAddresses
),
"evmAddresses"
,
len
(
evmAddresses
),
"ovmAllowances"
,
len
(
ovmAllowances
),
"ovmMessages"
,
len
(
ovmMessages
),
"evmMessages"
,
len
(
evmMessages
),
)
migrationData
:=
crossdomain
.
MigrationData
{
OvmAddresses
:
ovmAddresses
,
OvmAddresses
:
ovmAddresses
,
EvmAddresses
:
evmAddres
es
s
,
EvmAddresses
:
evmAddres
se
s
,
OvmAllowances
:
ovmAllowances
,
OvmAllowances
:
ovmAllowances
,
OvmMessages
:
ovmMessages
,
OvmMessages
:
ovmMessages
,
EvmMessages
:
evmMessages
,
EvmMessages
:
evmMessages
,
...
...
op-chain-ops/cmd/withdrawals/main.go
View file @
c35b6e39
...
@@ -18,8 +18,6 @@ import (
...
@@ -18,8 +18,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"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"
...
@@ -768,7 +766,7 @@ func newWithdrawals(ctx *cli.Context, l1ChainID *big.Int) ([]*crossdomain.Legacy
...
@@ -768,7 +766,7 @@ func newWithdrawals(ctx *cli.Context, l1ChainID *big.Int) ([]*crossdomain.Legacy
evmMsgs
:=
ctx
.
String
(
"evm-messages"
)
evmMsgs
:=
ctx
.
String
(
"evm-messages"
)
log
.
Debug
(
"Migration data"
,
"ovm-path"
,
ovmMsgs
,
"evm-messages"
,
evmMsgs
)
log
.
Debug
(
"Migration data"
,
"ovm-path"
,
ovmMsgs
,
"evm-messages"
,
evmMsgs
)
ovmMessages
,
err
:=
migration
.
NewSentMessage
(
ovmMsgs
)
ovmMessages
,
err
:=
crossdomain
.
NewSentMessageFromJSON
(
ovmMsgs
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -777,20 +775,20 @@ func newWithdrawals(ctx *cli.Context, l1ChainID *big.Int) ([]*crossdomain.Legacy
...
@@ -777,20 +775,20 @@ func newWithdrawals(ctx *cli.Context, l1ChainID *big.Int) ([]*crossdomain.Legacy
// committed to in git.
// committed to in git.
if
l1ChainID
.
Cmp
(
common
.
Big1
)
!=
0
{
if
l1ChainID
.
Cmp
(
common
.
Big1
)
!=
0
{
log
.
Info
(
"not using ovm messages because its not mainnet"
)
log
.
Info
(
"not using ovm messages because its not mainnet"
)
ovmMessages
=
[]
*
migratio
n
.
SentMessage
{}
ovmMessages
=
[]
*
crossdomai
n
.
SentMessage
{}
}
}
evmMessages
,
err
:=
migration
.
NewSentMessage
(
evmMsgs
)
evmMessages
,
err
:=
crossdomain
.
NewSentMessageFromJSON
(
evmMsgs
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
migrationData
:=
migratio
n
.
MigrationData
{
migrationData
:=
crossdomai
n
.
MigrationData
{
OvmMessages
:
ovmMessages
,
OvmMessages
:
ovmMessages
,
EvmMessages
:
evmMessages
,
EvmMessages
:
evmMessages
,
}
}
wds
,
err
:=
migrationData
.
ToWithdrawals
()
wds
,
_
,
err
:=
migrationData
.
ToWithdrawals
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
op-chain-ops/
genesis/migratio
n/legacy.go
→
op-chain-ops/
crossdomai
n/legacy.go
View file @
c35b6e39
package
migratio
n
package
crossdomai
n
import
(
import
(
"errors"
"errors"
...
...
op-chain-ops/
genesis/migratio
n/params.go
→
op-chain-ops/
crossdomai
n/params.go
View file @
c35b6e39
package
migratio
n
package
crossdomai
n
import
(
import
(
"math/big"
"math/big"
...
...
op-chain-ops/crossdomain/precheck.go
View file @
c35b6e39
...
@@ -5,6 +5,7 @@ import (
...
@@ -5,6 +5,7 @@ import (
"fmt"
"fmt"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/util"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
...
@@ -12,28 +13,40 @@ import (
...
@@ -12,28 +13,40 @@ import (
var
(
var
(
ErrUnknownSlotInMessagePasser
=
errors
.
New
(
"unknown slot in legacy message passer"
)
ErrUnknownSlotInMessagePasser
=
errors
.
New
(
"unknown slot in legacy message passer"
)
ErrMissingSlotInWitness
=
errors
.
New
(
"missing storage slot in witness data"
)
ErrMissingSlotInWitness
=
errors
.
New
(
"missing storage slot in witness data
(see logs for details)
"
)
)
)
// PreCheckWithdrawals checks that the given list of withdrawals represents all withdrawals made
// PreCheckWithdrawals checks that the given list of withdrawals represents all withdrawals made
// in the legacy system and filters out any extra withdrawals not included in the legacy system.
// in the legacy system and filters out any extra withdrawals not included in the legacy system.
func
PreCheckWithdrawals
(
db
*
state
.
StateDB
,
withdrawals
DangerousUnfilteredWithdrawals
)
(
SafeFilteredWithdrawals
,
error
)
{
func
PreCheckWithdrawals
(
db
*
state
.
StateDB
,
withdrawals
DangerousUnfilteredWithdrawals
,
invalidMessages
[]
InvalidMessage
)
(
SafeFilteredWithdrawals
,
error
)
{
// Convert each withdrawal into a storage slot, and build a map of those slots.
// Convert each withdrawal into a storage slot, and build a map of those slots.
s
lotsInp
:=
make
(
map
[
common
.
Hash
]
*
LegacyWithdrawal
)
validS
lotsInp
:=
make
(
map
[
common
.
Hash
]
*
LegacyWithdrawal
)
for
_
,
wd
:=
range
withdrawals
{
for
_
,
wd
:=
range
withdrawals
{
slot
,
err
:=
wd
.
StorageSlot
()
slot
,
err
:=
wd
.
StorageSlot
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot check withdrawals: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"cannot check withdrawals: %w"
,
err
)
}
}
slotsInp
[
slot
]
=
wd
validSlotsInp
[
slot
]
=
wd
}
// Convert each invalid message into a storage slot, and build a map of those slots.
invalidSlotsInp
:=
make
(
map
[
common
.
Hash
]
InvalidMessage
)
for
_
,
msg
:=
range
invalidMessages
{
slot
,
err
:=
msg
.
StorageSlot
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot check invalid messages: %w"
,
err
)
}
invalidSlotsInp
[
slot
]
=
msg
}
}
// Build a mapping of the slots of all messages actually sent in the legacy system.
// Build a mapping of the slots of all messages actually sent in the legacy system.
var
count
int
var
count
int
var
innerErr
error
var
innerErr
error
slotsAct
:=
make
(
map
[
common
.
Hash
]
bool
)
slotsAct
:=
make
(
map
[
common
.
Hash
]
bool
)
progress
:=
util
.
ProgressLogger
(
1000
,
"Iterating legacy messages"
)
err
:=
db
.
ForEachStorage
(
predeploys
.
LegacyMessagePasserAddr
,
func
(
key
,
value
common
.
Hash
)
bool
{
err
:=
db
.
ForEachStorage
(
predeploys
.
LegacyMessagePasserAddr
,
func
(
key
,
value
common
.
Hash
)
bool
{
progress
()
// When a message is inserted into the LegacyMessagePasser, it is stored with the value
// When a message is inserted into the LegacyMessagePasser, it is stored with the value
// of the ABI encoding of "true". Although there should not be any other storage slots, we
// of the ABI encoding of "true". Although there should not be any other storage slots, we
// can safely ignore anything that is not "true".
// can safely ignore anything that is not "true".
...
@@ -59,24 +72,32 @@ func PreCheckWithdrawals(db *state.StateDB, withdrawals DangerousUnfilteredWithd
...
@@ -59,24 +72,32 @@ func PreCheckWithdrawals(db *state.StateDB, withdrawals DangerousUnfilteredWithd
log
.
Info
(
"Iterated legacy messages"
,
"count"
,
count
)
log
.
Info
(
"Iterated legacy messages"
,
"count"
,
count
)
// Iterate over the list of actual slots and check that we have an input message for each one.
// Iterate over the list of actual slots and check that we have an input message for each one.
var
missing
int
for
slot
:=
range
slotsAct
{
for
slot
:=
range
slotsAct
{
_
,
ok
:=
slotsInp
[
slot
]
_
,
okValid
:=
validSlotsInp
[
slot
]
if
!
ok
{
_
,
okInvalid
:=
invalidSlotsInp
[
slot
]
return
nil
,
ErrMissingSlotInWitness
if
!
okValid
&&
!
okInvalid
{
log
.
Error
(
"missing storage slot"
,
"slot"
,
slot
.
String
())
missing
++
}
}
}
}
if
missing
>
0
{
log
.
Error
(
"missing storage slots in witness data"
,
"count"
,
missing
)
return
nil
,
ErrMissingSlotInWitness
}
// Iterate over the list of input messages and check that we have a known slot for each one.
// Iterate over the list of input messages and check that we have a known slot for each one.
// We'll filter out any extra messages that are not in the legacy system.
// We'll filter out any extra messages that are not in the legacy system.
filtered
:=
make
(
SafeFilteredWithdrawals
,
0
)
filtered
:=
make
(
SafeFilteredWithdrawals
,
0
)
for
slot
:=
range
s
lotsInp
{
for
slot
:=
range
validS
lotsInp
{
_
,
ok
:=
slotsAct
[
slot
]
_
,
ok
:=
slotsAct
[
slot
]
if
!
ok
{
if
!
ok
{
log
.
Info
(
"filtering out unknown input message"
,
"slot"
,
slot
.
String
())
log
.
Info
(
"filtering out unknown input message"
,
"slot"
,
slot
.
String
())
continue
continue
}
}
wd
:=
s
lotsInp
[
slot
]
wd
:=
validS
lotsInp
[
slot
]
if
wd
.
MessageSender
!=
predeploys
.
L2CrossDomainMessengerAddr
{
if
wd
.
MessageSender
!=
predeploys
.
L2CrossDomainMessengerAddr
{
log
.
Info
(
"filtering out message from sender other than the L2XDM"
,
"sender"
,
wd
.
MessageSender
)
log
.
Info
(
"filtering out message from sender other than the L2XDM"
,
"sender"
,
wd
.
MessageSender
)
continue
continue
...
...
op-chain-ops/crossdomain/precheck_test.go
View file @
c35b6e39
...
@@ -71,7 +71,7 @@ func TestPreCheckWithdrawals_InvalidSlotInStorage(t *testing.T) {
...
@@ -71,7 +71,7 @@ func TestPreCheckWithdrawals_InvalidSlotInStorage(t *testing.T) {
err
=
stateDB
.
Database
()
.
TrieDB
()
.
Commit
(
root
,
true
)
err
=
stateDB
.
Database
()
.
TrieDB
()
.
Commit
(
root
,
true
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
_
,
err
=
PreCheckWithdrawals
(
stateDB
,
nil
)
_
,
err
=
PreCheckWithdrawals
(
stateDB
,
nil
,
nil
)
require
.
ErrorIs
(
t
,
err
,
ErrUnknownSlotInMessagePasser
)
require
.
ErrorIs
(
t
,
err
,
ErrUnknownSlotInMessagePasser
)
}
}
...
@@ -130,5 +130,5 @@ func runPrecheck(t *testing.T, dbWds []*LegacyWithdrawal, witnessWds []*LegacyWi
...
@@ -130,5 +130,5 @@ func runPrecheck(t *testing.T, dbWds []*LegacyWithdrawal, witnessWds []*LegacyWi
err
=
stateDB
.
Database
()
.
TrieDB
()
.
Commit
(
root
,
true
)
err
=
stateDB
.
Database
()
.
TrieDB
()
.
Commit
(
root
,
true
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
return
PreCheckWithdrawals
(
stateDB
,
witnessWds
)
return
PreCheckWithdrawals
(
stateDB
,
witnessWds
,
nil
)
}
}
op-chain-ops/crossdomain/testdata/witness.txt
0 → 100644
View file @
c35b6e39
MSG|0x4200000000000000000000000000000000000007|cafa81dc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001a4cbd4ece900000000000000000000000099c9fc46f92e8a1c0dec1b1747d010903e884be1000000000000000000000000420000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000019bd000000000000000000000000000000000000000000000000000000000000000e4a9f9e675000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd520000000000000000000000000994206dfe8de6ec6920ff4d779b0d950605fb53000000000000000000000000e3a44dd2a8c108be56a78635121ec914074da16d000000000000000000000000e3a44dd2a8c108be56a78635121ec914074da16d0000000000000000000000000000000000000000000001b0ac98ab3858d7547800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
MSG|0x8B1d477410344785ff1DF52500032E6D5f532EE4|cafa81dc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030420690000000000000000000000000000000000000000000000000000000000
ETH|0x6340d44c5174588B312F545eEC4a42f8a514eF50
\ No newline at end of file
op-chain-ops/crossdomain/types.go
View file @
c35b6e39
package
crossdomain
package
crossdomain
import
(
import
(
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
)
// DangerousUnfilteredWithdrawals is a list of raw withdrawal witness
// DangerousUnfilteredWithdrawals is a list of raw withdrawal witness
...
@@ -30,3 +33,35 @@ type WithdrawalMessage interface {
...
@@ -30,3 +33,35 @@ type WithdrawalMessage interface {
Hash
()
(
common
.
Hash
,
error
)
Hash
()
(
common
.
Hash
,
error
)
StorageSlot
()
(
common
.
Hash
,
error
)
StorageSlot
()
(
common
.
Hash
,
error
)
}
}
// InvalidMessage represents a message to the L1 message passer that
// cannot be decoded as a withdrawal. They are defined as a separate
// type in order to completely disambiguate them from any other
// message.
type
InvalidMessage
SentMessage
func
(
msg
*
InvalidMessage
)
Encode
()
([]
byte
,
error
)
{
out
:=
make
([]
byte
,
len
(
msg
.
Msg
)
+
20
)
copy
(
out
,
msg
.
Msg
)
copy
(
out
[
len
(
msg
.
Msg
)
:
],
msg
.
Who
.
Bytes
())
return
out
,
nil
}
func
(
msg
*
InvalidMessage
)
Hash
()
(
common
.
Hash
,
error
)
{
bytes
,
err
:=
msg
.
Encode
()
if
err
!=
nil
{
return
common
.
Hash
{},
fmt
.
Errorf
(
"cannot hash: %w"
,
err
)
}
return
crypto
.
Keccak256Hash
(
bytes
),
nil
}
func
(
msg
*
InvalidMessage
)
StorageSlot
()
(
common
.
Hash
,
error
)
{
hash
,
err
:=
msg
.
Hash
()
if
err
!=
nil
{
return
common
.
Hash
{},
fmt
.
Errorf
(
"cannot compute storage slot: %w"
,
err
)
}
preimage
:=
make
([]
byte
,
64
)
copy
(
preimage
,
hash
.
Bytes
())
return
crypto
.
Keccak256Hash
(
preimage
),
nil
}
op-chain-ops/crossdomain/types_test.go
0 → 100644
View file @
c35b6e39
package
crossdomain
import
(
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func
TestInvalidMessage
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
msg
InvalidMessage
slot
common
.
Hash
}{
{
name
:
"unparseable x-domain message on mainnet"
,
msg
:
InvalidMessage
{
Who
:
common
.
HexToAddress
(
"0x8b1d477410344785ff1df52500032e6d5f532ee4"
),
Msg
:
common
.
FromHex
(
"0x042069"
),
},
slot
:
common
.
HexToHash
(
"0x2a49ae6579c3878f10cf87ecdbebc6c4e2b2159ffe2b1af88af6ca9697fc32cb"
),
},
{
name
:
"valid x-domain message on mainnet for validation"
,
msg
:
InvalidMessage
{
Who
:
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000007"
),
Msg
:
common
.
FromHex
(
""
+
"0xcbd4ece900000000000000000000000099c9fc46f92e8a1c0dec1b1747d01090"
+
"3e884be100000000000000000000000042000000000000000000000000000000"
+
"0000001000000000000000000000000000000000000000000000000000000000"
+
"0000008000000000000000000000000000000000000000000000000000000000"
+
"00019be200000000000000000000000000000000000000000000000000000000"
+
"000000e4a9f9e675000000000000000000000000a0b86991c6218b36c1d19d4a"
+
"2e9eb0ce3606eb480000000000000000000000007f5c764cbc14f9669b88837c"
+
"a1490cca17c31607000000000000000000000000a420b2d1c0841415a695b81e"
+
"5b867bcd07dff8c9000000000000000000000000c186fa914353c44b2e33ebe0"
+
"5f21846f1048beda000000000000000000000000000000000000000000000000"
+
"00000000295d681d000000000000000000000000000000000000000000000000"
+
"00000000000000c0000000000000000000000000000000000000000000000000"
+
"0000000000000000000000000000000000000000000000000000000000000000"
+
"00000000"
,
),
},
slot
:
common
.
HexToHash
(
"0x8f8f6be7a4c5048f46ca41897181d17c10c39365ead5ac27c23d1e8e466d0ed5"
),
},
}
for
_
,
test
:=
range
tests
{
t
.
Run
(
test
.
name
,
func
(
t
*
testing
.
T
)
{
// StorageSlot() tests Hash() and Encode() so we don't
// need to test these separately.
slot
,
err
:=
test
.
msg
.
StorageSlot
()
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
test
.
slot
,
slot
)
})
}
}
op-chain-ops/
genesis/migration/type
s.go
→
op-chain-ops/
crossdomain/witnes
s.go
View file @
c35b6e39
package
migratio
n
package
crossdomai
n
import
(
import
(
"bufio"
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"os"
"os"
"strings"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"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"
)
)
// SentMessage
JSON
represents an entry in the JSON file that is created by
// SentMessage represents an entry in the JSON file that is created by
// the `migration-data` package. Each entry represents a call to the
// the `migration-data` package. Each entry represents a call to the
// `LegacyMessagePasser`. The `who` should always be the
// `LegacyMessagePasser`. The `who` should always be the
// `L2CrossDomainMessenger` and the `msg` should be an abi encoded
// `L2CrossDomainMessenger` and the `msg` should be an abi encoded
...
@@ -20,10 +24,10 @@ type SentMessage struct {
...
@@ -20,10 +24,10 @@ type SentMessage struct {
Msg
hexutil
.
Bytes
`json:"msg"`
Msg
hexutil
.
Bytes
`json:"msg"`
}
}
// NewSentMessageJSON will read a JSON file from disk given a path to the JSON
// NewSentMessage
From
JSON will read a JSON file from disk given a path to the JSON
// file. The JSON file this function reads from disk is an output from the
// file. The JSON file this function reads from disk is an output from the
// `migration-data` package.
// `migration-data` package.
func
NewSentMessage
(
path
string
)
([]
*
SentMessage
,
error
)
{
func
NewSentMessage
FromJSON
(
path
string
)
([]
*
SentMessage
,
error
)
{
file
,
err
:=
os
.
ReadFile
(
path
)
file
,
err
:=
os
.
ReadFile
(
path
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot find sent message json at %s: %w"
,
path
,
err
)
return
nil
,
fmt
.
Errorf
(
"cannot find sent message json at %s: %w"
,
path
,
err
)
...
@@ -37,15 +41,81 @@ func NewSentMessage(path string) ([]*SentMessage, error) {
...
@@ -37,15 +41,81 @@ func NewSentMessage(path string) ([]*SentMessage, error) {
return
j
,
nil
return
j
,
nil
}
}
// ReadWitnessData will read messages and addresses from a raw l2geth state
// dump file.
func
ReadWitnessData
(
path
string
)
([]
*
SentMessage
,
OVMETHAddresses
,
error
)
{
f
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
return
nil
,
nil
,
fmt
.
Errorf
(
"cannot open witness data file: %w"
,
err
)
}
defer
f
.
Close
()
scan
:=
bufio
.
NewScanner
(
f
)
var
witnesses
[]
*
SentMessage
addresses
:=
make
(
map
[
common
.
Address
]
bool
)
for
scan
.
Scan
()
{
line
:=
scan
.
Text
()
splits
:=
strings
.
Split
(
line
,
"|"
)
if
len
(
splits
)
<
2
{
return
nil
,
nil
,
fmt
.
Errorf
(
"invalid line: %s"
,
line
)
}
switch
splits
[
0
]
{
case
"MSG"
:
if
len
(
splits
)
!=
3
{
return
nil
,
nil
,
fmt
.
Errorf
(
"invalid line: %s"
,
line
)
}
msg
:=
splits
[
2
]
// Make sure that the witness data has a 0x prefix
if
!
strings
.
HasPrefix
(
msg
,
"0x"
)
{
msg
=
"0x"
+
msg
}
abi
,
err
:=
bindings
.
LegacyMessagePasserMetaData
.
GetAbi
()
if
err
!=
nil
{
return
nil
,
nil
,
fmt
.
Errorf
(
"failed to get abi: %w"
,
err
)
}
msgB
:=
hexutil
.
MustDecode
(
msg
)
method
,
err
:=
abi
.
MethodById
(
msgB
[
:
4
])
if
err
!=
nil
{
return
nil
,
nil
,
fmt
.
Errorf
(
"failed to get method: %w"
,
err
)
}
out
,
err
:=
method
.
Inputs
.
Unpack
(
msgB
[
4
:
])
if
err
!=
nil
{
return
nil
,
nil
,
fmt
.
Errorf
(
"failed to unpack: %w"
,
err
)
}
cast
,
ok
:=
out
[
0
]
.
([]
byte
)
if
!
ok
{
return
nil
,
nil
,
fmt
.
Errorf
(
"failed to cast to bytes"
)
}
witnesses
=
append
(
witnesses
,
&
SentMessage
{
Who
:
common
.
HexToAddress
(
splits
[
1
]),
Msg
:
cast
,
})
case
"ETH"
:
addresses
[
common
.
HexToAddress
(
splits
[
1
])]
=
true
default
:
return
nil
,
nil
,
fmt
.
Errorf
(
"invalid line: %s"
,
line
)
}
}
return
witnesses
,
addresses
,
nil
}
// ToLegacyWithdrawal will convert a SentMessageJSON to a LegacyWithdrawal
// ToLegacyWithdrawal will convert a SentMessageJSON to a LegacyWithdrawal
// struct. This is useful because the LegacyWithdrawal struct has helper
// struct. This is useful because the LegacyWithdrawal struct has helper
// functions on it that can compute the withdrawal hash and the storage slot.
// functions on it that can compute the withdrawal hash and the storage slot.
func
(
s
*
SentMessage
)
ToLegacyWithdrawal
()
(
*
crossdomain
.
LegacyWithdrawal
,
error
)
{
func
(
s
*
SentMessage
)
ToLegacyWithdrawal
()
(
*
LegacyWithdrawal
,
error
)
{
data
:=
make
([]
byte
,
len
(
s
.
Who
)
+
len
(
s
.
Msg
))
data
:=
make
([]
byte
,
len
(
s
.
Who
)
+
len
(
s
.
Msg
))
copy
(
data
,
s
.
Msg
)
copy
(
data
,
s
.
Msg
)
copy
(
data
[
len
(
s
.
Msg
)
:
],
s
.
Who
[
:
])
copy
(
data
[
len
(
s
.
Msg
)
:
],
s
.
Who
[
:
])
var
w
crossdomain
.
LegacyWithdrawal
var
w
LegacyWithdrawal
if
err
:=
w
.
Decode
(
data
);
err
!=
nil
{
if
err
:=
w
.
Decode
(
data
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -117,26 +187,26 @@ type MigrationData struct {
...
@@ -117,26 +187,26 @@ type MigrationData struct {
EvmMessages
[]
*
SentMessage
EvmMessages
[]
*
SentMessage
}
}
func
(
m
*
MigrationData
)
ToWithdrawals
()
(
crossdomain
.
DangerousUnfilteredWithdrawals
,
error
)
{
func
(
m
*
MigrationData
)
ToWithdrawals
()
(
DangerousUnfilteredWithdrawals
,
[]
InvalidMessage
,
error
)
{
messages
:=
make
(
crossdomain
.
DangerousUnfilteredWithdrawals
,
0
)
messages
:=
make
(
DangerousUnfilteredWithdrawals
,
0
)
invalidMessages
:=
make
([]
InvalidMessage
,
0
)
for
_
,
msg
:=
range
m
.
OvmMessages
{
for
_
,
msg
:=
range
m
.
OvmMessages
{
wd
,
err
:=
msg
.
ToLegacyWithdrawal
()
wd
,
err
:=
msg
.
ToLegacyWithdrawal
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
nil
,
fmt
.
Errorf
(
"error serializing OVM message: %w"
,
err
)
}
}
messages
=
append
(
messages
,
wd
)
messages
=
append
(
messages
,
wd
)
if
err
!=
nil
{
return
nil
,
err
}
}
}
for
_
,
msg
:=
range
m
.
EvmMessages
{
for
_
,
msg
:=
range
m
.
EvmMessages
{
wd
,
err
:=
msg
.
ToLegacyWithdrawal
()
wd
,
err
:=
msg
.
ToLegacyWithdrawal
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
log
.
Warn
(
"Discovered mal-formed withdrawal"
,
"who"
,
msg
.
Who
,
"data"
,
msg
.
Msg
)
invalidMessages
=
append
(
invalidMessages
,
InvalidMessage
(
*
msg
))
continue
}
}
messages
=
append
(
messages
,
wd
)
messages
=
append
(
messages
,
wd
)
}
}
return
messages
,
nil
return
messages
,
invalidMessages
,
nil
}
}
func
(
m
*
MigrationData
)
Addresses
()
[]
common
.
Address
{
func
(
m
*
MigrationData
)
Addresses
()
[]
common
.
Address
{
...
...
op-chain-ops/crossdomain/witness_test.go
0 → 100644
View file @
c35b6e39
package
crossdomain
import
(
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func
TestRead
(
t
*
testing
.
T
)
{
witnesses
,
addresses
,
err
:=
ReadWitnessData
(
"testdata/witness.txt"
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
[]
*
SentMessage
{
{
Who
:
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000007"
),
Msg
:
common
.
FromHex
(
"0xcbd4ece900000000000000000000000099c9fc46f92e8a1c0dec1b1747d01090"
+
"3e884be100000000000000000000000042000000000000000000000000000000"
+
"0000001000000000000000000000000000000000000000000000000000000000"
+
"0000008000000000000000000000000000000000000000000000000000000000"
+
"00019bd000000000000000000000000000000000000000000000000000000000"
+
"000000e4a9f9e675000000000000000000000000d533a949740bb3306d119cc7"
+
"77fa900ba034cd520000000000000000000000000994206dfe8de6ec6920ff4d"
+
"779b0d950605fb53000000000000000000000000e3a44dd2a8c108be56a78635"
+
"121ec914074da16d000000000000000000000000e3a44dd2a8c108be56a78635"
+
"121ec914074da16d0000000000000000000000000000000000000000000001b0"
+
"ac98ab3858d75478000000000000000000000000000000000000000000000000"
+
"00000000000000c0000000000000000000000000000000000000000000000000"
+
"0000000000000000000000000000000000000000000000000000000000000000"
+
"00000000"
,
),
},
{
Who
:
common
.
HexToAddress
(
"0x8b1d477410344785ff1df52500032e6d5f532ee4"
),
Msg
:
common
.
FromHex
(
"0x042069"
),
},
},
witnesses
)
require
.
Equal
(
t
,
OVMETHAddresses
{
common
.
HexToAddress
(
"0x6340d44c5174588B312F545eEC4a42f8a514eF50"
)
:
true
,
},
addresses
)
}
op-chain-ops/ether/addresses.go
View file @
c35b6e39
...
@@ -8,9 +8,9 @@ import (
...
@@ -8,9 +8,9 @@ import (
"io"
"io"
"strings"
"strings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb"
...
@@ -105,7 +105,7 @@ func IterateAllowanceList(r io.Reader, cb AllowanceCB) error {
...
@@ -105,7 +105,7 @@ func IterateAllowanceList(r io.Reader, cb AllowanceCB) error {
func
IterateMintEvents
(
db
ethdb
.
Database
,
headNum
uint64
,
cb
AddressCBWithHead
,
progressCb
func
(
uint64
))
error
{
func
IterateMintEvents
(
db
ethdb
.
Database
,
headNum
uint64
,
cb
AddressCBWithHead
,
progressCb
func
(
uint64
))
error
{
for
headNum
>
0
{
for
headNum
>
0
{
hash
:=
rawdb
.
ReadCanonicalHash
(
db
,
headNum
)
hash
:=
rawdb
.
ReadCanonicalHash
(
db
,
headNum
)
receipts
,
err
:=
migratio
n
.
ReadLegacyReceipts
(
db
,
hash
,
headNum
)
receipts
,
err
:=
crossdomai
n
.
ReadLegacyReceipts
(
db
,
hash
,
headNum
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
op-chain-ops/ether/migrate.go
View file @
c35b6e39
...
@@ -4,9 +4,10 @@ import (
...
@@ -4,9 +4,10 @@ import (
"fmt"
"fmt"
"math/big"
"math/big"
"github.com/ethereum-optimism/optimism/op-
bindings/predeploys
"
"github.com/ethereum-optimism/optimism/op-
chain-ops/crossdomain
"
"github.com/ethereum-optimism/optimism/op-chain-ops/
genesis/migration
"
"github.com/ethereum-optimism/optimism/op-chain-ops/
util
"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
...
@@ -30,7 +31,7 @@ var (
...
@@ -30,7 +31,7 @@ var (
func
MigrateLegacyETH
(
db
*
state
.
StateDB
,
addresses
[]
common
.
Address
,
chainID
int
,
noCheck
bool
)
error
{
func
MigrateLegacyETH
(
db
*
state
.
StateDB
,
addresses
[]
common
.
Address
,
chainID
int
,
noCheck
bool
)
error
{
// Chain params to use for integrity checking.
// Chain params to use for integrity checking.
params
:=
migratio
n
.
ParamsByChainID
[
chainID
]
params
:=
crossdomai
n
.
ParamsByChainID
[
chainID
]
if
params
==
nil
{
if
params
==
nil
{
return
fmt
.
Errorf
(
"no chain params for %d"
,
chainID
)
return
fmt
.
Errorf
(
"no chain params for %d"
,
chainID
)
}
}
...
@@ -47,7 +48,7 @@ func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int
...
@@ -47,7 +48,7 @@ func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int
// Migrate the legacy ETH to ETH.
// Migrate the legacy ETH to ETH.
log
.
Info
(
"Migrating legacy ETH to ETH"
,
"num-accounts"
,
len
(
addresses
))
log
.
Info
(
"Migrating legacy ETH to ETH"
,
"num-accounts"
,
len
(
addresses
))
totalMigrated
:=
new
(
big
.
Int
)
totalMigrated
:=
new
(
big
.
Int
)
logAccountProgress
:=
ProgressLogger
(
1000
,
"imported accounts"
)
logAccountProgress
:=
util
.
ProgressLogger
(
1000
,
"imported accounts"
)
for
addr
:=
range
deduped
{
for
addr
:=
range
deduped
{
// No accounts should have a balance in state. If they do, bail.
// No accounts should have a balance in state. If they do, bail.
if
db
.
GetBalance
(
addr
)
.
Sign
()
>
0
{
if
db
.
GetBalance
(
addr
)
.
Sign
()
>
0
{
...
...
op-chain-ops/ether/precheck.go
View file @
c35b6e39
package
ether
package
ether
import
(
import
(
"errors"
"fmt"
"fmt"
"math/big"
"math/big"
"github.com/ethereum-optimism/optimism/op-
bindings/predeploys
"
"github.com/ethereum-optimism/optimism/op-
chain-ops/crossdomain
"
"github.com/ethereum-optimism/optimism/op-chain-ops/
genesis/migration
"
"github.com/ethereum-optimism/optimism/op-chain-ops/
util
"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb"
...
@@ -17,9 +19,9 @@ import (
...
@@ -17,9 +19,9 @@ import (
// slots in the LegacyERC20ETH contract. We don't have to filter out extra addresses like we do for
// slots in the LegacyERC20ETH contract. We don't have to filter out extra addresses like we do for
// withdrawals because we'll simply carry the balance of a given address to the new system, if the
// withdrawals because we'll simply carry the balance of a given address to the new system, if the
// account is extra then it won't have any balance and nothing will happen.
// account is extra then it won't have any balance and nothing will happen.
func
PreCheckBalances
(
ldb
ethdb
.
Database
,
db
*
state
.
StateDB
,
addresses
[]
common
.
Address
,
allowances
[]
*
migratio
n
.
Allowance
,
chainID
int
,
noCheck
bool
)
([]
common
.
Address
,
error
)
{
func
PreCheckBalances
(
ldb
ethdb
.
Database
,
db
*
state
.
StateDB
,
addresses
[]
common
.
Address
,
allowances
[]
*
crossdomai
n
.
Allowance
,
chainID
int
,
noCheck
bool
)
([]
common
.
Address
,
error
)
{
// Chain params to use for integrity checking.
// Chain params to use for integrity checking.
params
:=
migratio
n
.
ParamsByChainID
[
chainID
]
params
:=
crossdomai
n
.
ParamsByChainID
[
chainID
]
if
params
==
nil
{
if
params
==
nil
{
return
nil
,
fmt
.
Errorf
(
"no chain params for %d"
,
chainID
)
return
nil
,
fmt
.
Errorf
(
"no chain params for %d"
,
chainID
)
}
}
...
@@ -53,7 +55,10 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
...
@@ -53,7 +55,10 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
// slots that we know we can ignore (totalSupply, name, symbol).
// slots that we know we can ignore (totalSupply, name, symbol).
var
count
int
var
count
int
slotsAct
:=
make
(
map
[
common
.
Hash
]
common
.
Hash
)
slotsAct
:=
make
(
map
[
common
.
Hash
]
common
.
Hash
)
progress
:=
util
.
ProgressLogger
(
1000
,
"Read OVM_ETH storage slot"
)
err
:=
db
.
ForEachStorage
(
predeploys
.
LegacyERC20ETHAddr
,
func
(
key
,
value
common
.
Hash
)
bool
{
err
:=
db
.
ForEachStorage
(
predeploys
.
LegacyERC20ETHAddr
,
func
(
key
,
value
common
.
Hash
)
bool
{
progress
()
// We can safely ignore specific slots (totalSupply, name, symbol).
// We can safely ignore specific slots (totalSupply, name, symbol).
if
ignoredSlots
[
key
]
{
if
ignoredSlots
[
key
]
{
return
true
return
true
...
@@ -75,13 +80,16 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
...
@@ -75,13 +80,16 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
// keep track of the total balance to be migrated and throw if the total supply exceeds the
// keep track of the total balance to be migrated and throw if the total supply exceeds the
// expected supply delta.
// expected supply delta.
totalFound
:=
new
(
big
.
Int
)
totalFound
:=
new
(
big
.
Int
)
var
unknown
bool
for
slot
:=
range
slotsAct
{
for
slot
:=
range
slotsAct
{
slotType
,
ok
:=
slotsInp
[
slot
]
slotType
,
ok
:=
slotsInp
[
slot
]
if
!
ok
{
if
!
ok
{
if
noCheck
{
if
noCheck
{
log
.
Error
(
"ignoring unknown storage slot in state"
,
"slot"
,
slot
)
log
.
Error
(
"ignoring unknown storage slot in state"
,
"slot"
,
slot
.
String
()
)
}
else
{
}
else
{
log
.
Crit
(
"unknown storage slot in state: %s"
,
slot
)
unknown
=
true
log
.
Error
(
"unknown storage slot in state"
,
"slot"
,
slot
.
String
())
continue
}
}
}
}
...
@@ -102,6 +110,9 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
...
@@ -102,6 +110,9 @@ func PreCheckBalances(ldb ethdb.Database, db *state.StateDB, addresses []common.
}
}
}
}
}
}
if
unknown
{
return
nil
,
errors
.
New
(
"unknown storage slots in state (see logs for details)"
)
}
// Verify the supply delta. Recorded total supply in the LegacyERC20ETH contract may be higher
// Verify the supply delta. Recorded total supply in the LegacyERC20ETH contract may be higher
// than the actual migrated amount because self-destructs will remove ETH supply in a way that
// than the actual migrated amount because self-destructs will remove ETH supply in a way that
...
...
op-chain-ops/genesis/check.go
View file @
c35b6e39
...
@@ -19,7 +19,6 @@ import (
...
@@ -19,7 +19,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
)
)
...
@@ -89,7 +88,7 @@ var (
...
@@ -89,7 +88,7 @@ var (
// PostCheckMigratedDB will check that the migration was performed correctly
// PostCheckMigratedDB will check that the migration was performed correctly
func
PostCheckMigratedDB
(
func
PostCheckMigratedDB
(
ldb
ethdb
.
Database
,
ldb
ethdb
.
Database
,
migrationData
migratio
n
.
MigrationData
,
migrationData
crossdomai
n
.
MigrationData
,
l1XDM
*
common
.
Address
,
l1XDM
*
common
.
Address
,
l1ChainID
uint64
,
l1ChainID
uint64
,
finalSystemOwner
common
.
Address
,
finalSystemOwner
common
.
Address
,
...
@@ -468,8 +467,8 @@ func PostCheckL1Block(db vm.StateDB, info *derive.L1BlockInfo) error {
...
@@ -468,8 +467,8 @@ func PostCheckL1Block(db vm.StateDB, info *derive.L1BlockInfo) error {
return
nil
return
nil
}
}
func
CheckWithdrawalsAfter
(
db
vm
.
StateDB
,
data
migratio
n
.
MigrationData
,
l1CrossDomainMessenger
*
common
.
Address
)
error
{
func
CheckWithdrawalsAfter
(
db
vm
.
StateDB
,
data
crossdomai
n
.
MigrationData
,
l1CrossDomainMessenger
*
common
.
Address
)
error
{
wds
,
err
:=
data
.
ToWithdrawals
()
wds
,
invalidMessages
,
err
:=
data
.
ToWithdrawals
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -479,6 +478,7 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
...
@@ -479,6 +478,7 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
// some witness data may references withdrawals that reverted.
// some witness data may references withdrawals that reverted.
oldToNewSlots
:=
make
(
map
[
common
.
Hash
]
common
.
Hash
)
oldToNewSlots
:=
make
(
map
[
common
.
Hash
]
common
.
Hash
)
wdsByOldSlot
:=
make
(
map
[
common
.
Hash
]
*
crossdomain
.
LegacyWithdrawal
)
wdsByOldSlot
:=
make
(
map
[
common
.
Hash
]
*
crossdomain
.
LegacyWithdrawal
)
invalidMessagesByOldSlot
:=
make
(
map
[
common
.
Hash
]
crossdomain
.
InvalidMessage
)
for
_
,
wd
:=
range
wds
{
for
_
,
wd
:=
range
wds
{
migrated
,
err
:=
crossdomain
.
MigrateWithdrawal
(
wd
,
l1CrossDomainMessenger
)
migrated
,
err
:=
crossdomain
.
MigrateWithdrawal
(
wd
,
l1CrossDomainMessenger
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -497,6 +497,15 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
...
@@ -497,6 +497,15 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
oldToNewSlots
[
legacySlot
]
=
migratedSlot
oldToNewSlots
[
legacySlot
]
=
migratedSlot
wdsByOldSlot
[
legacySlot
]
=
wd
wdsByOldSlot
[
legacySlot
]
=
wd
}
}
for
_
,
im
:=
range
invalidMessages
{
invalidSlot
,
err
:=
im
.
StorageSlot
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"cannot compute legacy storage slot: %w"
,
err
)
}
invalidMessagesByOldSlot
[
invalidSlot
]
=
im
}
log
.
Info
(
"computed withdrawal storage slots"
,
"migrated"
,
len
(
oldToNewSlots
),
"invalid"
,
len
(
invalidMessagesByOldSlot
))
// Now, iterate over each legacy withdrawal and check if there is a corresponding
// Now, iterate over each legacy withdrawal and check if there is a corresponding
// migrated withdrawal.
// migrated withdrawal.
...
@@ -515,6 +524,17 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
...
@@ -515,6 +524,17 @@ func CheckWithdrawalsAfter(db vm.StateDB, data migration.MigrationData, l1CrossD
return
false
return
false
}
}
// Make sure invalid slots don't get migrated.
_
,
isInvalidSlot
:=
invalidMessagesByOldSlot
[
key
]
if
isInvalidSlot
{
value
:=
db
.
GetState
(
predeploys
.
L2ToL1MessagePasserAddr
,
key
)
if
value
!=
abiFalse
{
innerErr
=
fmt
.
Errorf
(
"expected invalid slot not to be migrated, but got %s"
,
value
)
return
false
}
return
true
}
// Grab the migrated slot.
// Grab the migrated slot.
migratedSlot
:=
oldToNewSlots
[
key
]
migratedSlot
:=
oldToNewSlots
[
key
]
if
migratedSlot
==
(
common
.
Hash
{})
{
if
migratedSlot
==
(
common
.
Hash
{})
{
...
...
op-chain-ops/genesis/db_migration.go
View file @
c35b6e39
...
@@ -8,7 +8,6 @@ import (
...
@@ -8,7 +8,6 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/ether"
"github.com/ethereum-optimism/optimism/op-chain-ops/ether"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state"
...
@@ -35,7 +34,7 @@ type MigrationResult struct {
...
@@ -35,7 +34,7 @@ type MigrationResult struct {
}
}
// MigrateDB will migrate an l2geth legacy Optimism database to a Bedrock database.
// MigrateDB will migrate an l2geth legacy Optimism database to a Bedrock database.
func
MigrateDB
(
ldb
ethdb
.
Database
,
config
*
DeployConfig
,
l1Block
*
types
.
Block
,
migrationData
*
migratio
n
.
MigrationData
,
commit
,
noCheck
bool
)
(
*
MigrationResult
,
error
)
{
func
MigrateDB
(
ldb
ethdb
.
Database
,
config
*
DeployConfig
,
l1Block
*
types
.
Block
,
migrationData
*
crossdomai
n
.
MigrationData
,
commit
,
noCheck
bool
)
(
*
MigrationResult
,
error
)
{
// Grab the hash of the tip of the legacy chain.
// Grab the hash of the tip of the legacy chain.
hash
:=
rawdb
.
ReadHeadHeaderHash
(
ldb
)
hash
:=
rawdb
.
ReadHeadHeaderHash
(
ldb
)
log
.
Info
(
"Reading chain tip from database"
,
"hash"
,
hash
)
log
.
Info
(
"Reading chain tip from database"
,
"hash"
,
hash
)
...
@@ -114,17 +113,19 @@ func MigrateDB(ldb ethdb.Database, config *DeployConfig, l1Block *types.Block, m
...
@@ -114,17 +113,19 @@ func MigrateDB(ldb ethdb.Database, config *DeployConfig, l1Block *types.Block, m
// Convert all input messages into legacy messages. Note that this list is not yet filtered and
// Convert all input messages into legacy messages. Note that this list is not yet filtered and
// may be missing some messages or have some extra messages.
// may be missing some messages or have some extra messages.
unfilteredWithdrawals
,
err
:=
migrationData
.
ToWithdrawals
()
unfilteredWithdrawals
,
invalidMessages
,
err
:=
migrationData
.
ToWithdrawals
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot serialize withdrawals: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"cannot serialize withdrawals: %w"
,
err
)
}
}
log
.
Info
(
"Read withdrawals from witness data"
,
"unfiltered"
,
len
(
unfilteredWithdrawals
),
"invalid"
,
len
(
invalidMessages
))
// We now need to check that we have all of the withdrawals that we expect to have. An error
// We now need to check that we have all of the withdrawals that we expect to have. An error
// will be thrown if there are any missing messages, and any extra messages will be removed.
// will be thrown if there are any missing messages, and any extra messages will be removed.
var
filteredWithdrawals
crossdomain
.
SafeFilteredWithdrawals
var
filteredWithdrawals
crossdomain
.
SafeFilteredWithdrawals
if
!
noCheck
{
if
!
noCheck
{
log
.
Info
(
"Checking withdrawals..."
)
log
.
Info
(
"Checking withdrawals..."
)
filteredWithdrawals
,
err
=
crossdomain
.
PreCheckWithdrawals
(
db
,
unfilteredWithdrawals
)
filteredWithdrawals
,
err
=
crossdomain
.
PreCheckWithdrawals
(
db
,
unfilteredWithdrawals
,
invalidMessages
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"withdrawals mismatch: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"withdrawals mismatch: %w"
,
err
)
}
}
...
...
op-chain-ops/genesis/migration_action/action.go
View file @
c35b6e39
...
@@ -5,8 +5,9 @@ import (
...
@@ -5,8 +5,9 @@ import (
"math/big"
"math/big"
"path/filepath"
"path/filepath"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient"
)
)
...
@@ -30,28 +31,28 @@ type Config struct {
...
@@ -30,28 +31,28 @@ type Config struct {
func
Migrate
(
cfg
*
Config
)
(
*
genesis
.
MigrationResult
,
error
)
{
func
Migrate
(
cfg
*
Config
)
(
*
genesis
.
MigrationResult
,
error
)
{
deployConfig
:=
cfg
.
DeployConfig
deployConfig
:=
cfg
.
DeployConfig
ovmAddresses
,
err
:=
migratio
n
.
NewAddresses
(
cfg
.
OVMAddressesPath
)
ovmAddresses
,
err
:=
crossdomai
n
.
NewAddresses
(
cfg
.
OVMAddressesPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
evmAddresess
,
err
:=
migratio
n
.
NewAddresses
(
cfg
.
EVMAddressesPath
)
evmAddresess
,
err
:=
crossdomai
n
.
NewAddresses
(
cfg
.
EVMAddressesPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
ovmAllowances
,
err
:=
migratio
n
.
NewAllowances
(
cfg
.
OVMAllowancesPath
)
ovmAllowances
,
err
:=
crossdomai
n
.
NewAllowances
(
cfg
.
OVMAllowancesPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
ovmMessages
,
err
:=
migration
.
NewSentMessage
(
cfg
.
OVMMessagesPath
)
ovmMessages
,
err
:=
crossdomain
.
NewSentMessageFromJSON
(
cfg
.
OVMMessagesPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
evmMessages
,
err
:=
migration
.
NewSentMessage
(
cfg
.
EVMMessagesPath
)
evmMessages
,
err
:=
crossdomain
.
NewSentMessageFromJSON
(
cfg
.
EVMMessagesPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
migrationData
:=
migratio
n
.
MigrationData
{
migrationData
:=
crossdomai
n
.
MigrationData
{
OvmAddresses
:
ovmAddresses
,
OvmAddresses
:
ovmAddresses
,
EvmAddresses
:
evmAddresess
,
EvmAddresses
:
evmAddresess
,
OvmAllowances
:
ovmAllowances
,
OvmAllowances
:
ovmAllowances
,
...
...
op-chain-ops/
ether
/util.go
→
op-chain-ops/
util
/util.go
View file @
c35b6e39
package
ether
package
util
import
(
import
(
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
...
...
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