Commit 8fdcec2d authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into inphi/fix-svc

parents 0462cbd2 8272207c
---
'@eth-optimism/atst': minor
---
Update readAttestations and prepareWriteAttestation to handle keys longer than 32 bytes
---
'@eth-optimism/sdk': patch
---
Update migrated withdrawal gaslimit calculation
---
'@eth-optimism/atst': minor
---
Fix main and module in atst package.json
---
'@eth-optimism/fault-detector': patch
---
Fixes a bug that would cause the fault detector to error out if no outputs had been proposed yet.
---
'@eth-optimism/contracts-bedrock': patch
---
Print tenderly simulation links during deployment
...@@ -163,6 +163,10 @@ jobs: ...@@ -163,6 +163,10 @@ jobs:
description: Docker build context description: Docker build context
type: string type: string
default: "." default: "."
docker_target:
description: "target build stage"
type: string
default: ""
registry: registry:
description: Docker registry description: Docker registry
type: string type: string
...@@ -196,7 +200,7 @@ jobs: ...@@ -196,7 +200,7 @@ jobs:
DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|") DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|")
docker context create buildx-build docker context create buildx-build
docker buildx create --use buildx-build docker buildx create --use buildx-build
docker buildx build --platform=<<parameters.platforms>> --push \ docker buildx build --platform=<<parameters.platforms>> --target "<<parameters.docker_target>>" --push \
$(echo -ne $DOCKER_TAGS | tr '\n' ' ') \ $(echo -ne $DOCKER_TAGS | tr '\n' ' ') \
-f <<parameters.docker_file>> \ -f <<parameters.docker_file>> \
<<parameters.docker_context>> <<parameters.docker_context>>
...@@ -534,7 +538,7 @@ jobs: ...@@ -534,7 +538,7 @@ jobs:
command: | command: |
# Note: We don't use circle CI test splits because we need to split by test name, not by package. There is an additional # Note: We don't use circle CI test splits because we need to split by test name, not by package. There is an additional
# constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building. # constraint that gotestsum does not currently (nor likely will) accept files from different pacakges when building.
OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=true OP_E2E_USE_HTTP=<<parameters.use_http>> gotestsum \ OP_TESTLOG_DISABLE_COLOR=true OP_E2E_DISABLE_PARALLEL=false OP_E2E_USE_HTTP=<<parameters.use_http>> gotestsum \
--format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>_http_<<parameters.use_http>>.xml \ --format=standard-verbose --junitfile=/tmp/test-results/<<parameters.module>>_http_<<parameters.use_http>>.xml \
-- -timeout=20m ./... -- -timeout=20m ./...
working_directory: <<parameters.module>> working_directory: <<parameters.module>>
...@@ -845,7 +849,7 @@ jobs: ...@@ -845,7 +849,7 @@ jobs:
./hive \ ./hive \
-sim=<<parameters.sim>> \ -sim=<<parameters.sim>> \
-sim.loglevel=5 \ -sim.loglevel=5 \
-client=go-ethereum,op-geth_optimism-history,op-proposer_<<parameters.version>>,op-batcher_<<parameters.version>>,op-node_<<parameters.version>> |& tee /tmp/hive.log || echo "failed." -client=go-ethereum,op-geth_optimism,op-proposer_<<parameters.version>>,op-batcher_<<parameters.version>>,op-node_<<parameters.version>> |& tee /tmp/hive.log || echo "failed."
- run: - run:
command: | command: |
tar -cvf /tmp/workspace.tgz -C /home/circleci/project /home/circleci/project/workspace tar -cvf /tmp/workspace.tgz -C /home/circleci/project /home/circleci/project/workspace
...@@ -1137,6 +1141,7 @@ workflows: ...@@ -1137,6 +1141,7 @@ workflows:
docker_file: ./ops/docker/Dockerfile.packages docker_file: ./ops/docker/Dockerfile.packages
docker_name: chain-mon docker_name: chain-mon
docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>> docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
docker_target: wd-mon
context: context:
- oplabs-gcr - oplabs-gcr
- hive-test: - hive-test:
......
...@@ -191,6 +191,6 @@ require ( ...@@ -191,6 +191,6 @@ require (
nhooyr.io/websocket v1.8.7 // indirect nhooyr.io/websocket v1.8.7 // indirect
) )
replace github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7 replace github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230308025559-13ee9ab9153b
//replace github.com/ethereum/go-ethereum v1.11.2 => ../go-ethereum //replace github.com/ethereum/go-ethereum v1.11.2 => ../go-ethereum
...@@ -217,8 +217,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 ...@@ -217,8 +217,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs=
github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7 h1:bkttBXCRDv2Mp4VoGBglr4BjS7icIuN8HS5ZFpeKfvE= github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230308025559-13ee9ab9153b h1:7RNzqCwam//7PPieblo8GSIVukwrfoPO+0xT1yMp9Zw=
github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7/go.mod h1:/tjlXxOaovIyuF0l6+wCzr6AtDb3lYWTymmpQAQcqu8= github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230308025559-13ee9ab9153b/go.mod h1:/tjlXxOaovIyuF0l6+wCzr6AtDb3lYWTymmpQAQcqu8=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
......
...@@ -4,7 +4,7 @@ go 1.17 ...@@ -4,7 +4,7 @@ go 1.17
replace ( replace (
github.com/ethereum/go-ethereum v1.10.26 => github.com/ethereum-optimism/op-geth v0.0.0-20230214215134-401b7fd3309b github.com/ethereum/go-ethereum v1.10.26 => github.com/ethereum-optimism/op-geth v0.0.0-20230214215134-401b7fd3309b
github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-aea0402.0.20230301232322-c407b2a217b7 github.com/ethereum/go-ethereum v1.11.2 => github.com/ethereum-optimism/op-geth v1.11.2-de8c5df46.0.20230308025559-13ee9ab9153b
) )
require ( require (
......
...@@ -81,6 +81,7 @@ func Main(version string, cliCtx *cli.Context) error { ...@@ -81,6 +81,7 @@ func Main(version string, cliCtx *cli.Context) error {
rpcCfg.ListenAddr, rpcCfg.ListenAddr,
rpcCfg.ListenPort, rpcCfg.ListenPort,
version, version,
oprpc.WithLogger(l),
) )
if rpcCfg.EnableAdmin { if rpcCfg.EnableAdmin {
server.AddAPI(gethrpc.API{ server.AddAPI(gethrpc.API{
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
) )
var ( var (
...@@ -82,8 +83,7 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com ...@@ -82,8 +83,7 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com
return nil, fmt.Errorf("cannot abi encode relayMessage: %w", err) return nil, fmt.Errorf("cannot abi encode relayMessage: %w", err)
} }
// Set the outer gas limit. This cannot be zero gasLimit := MigrateWithdrawalGasLimit(data)
gasLimit := uint64(len(data)*16 + 200_000)
w := NewWithdrawal( w := NewWithdrawal(
versionedNonce, versionedNonce,
...@@ -95,3 +95,25 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com ...@@ -95,3 +95,25 @@ func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *com
) )
return w, nil return w, nil
} }
func MigrateWithdrawalGasLimit(data []byte) uint64 {
// Compute the cost of the calldata
dataCost := uint64(0)
for _, b := range data {
if b == 0 {
dataCost += params.TxDataZeroGas
} else {
dataCost += params.TxDataNonZeroGasEIP2028
}
}
// Set the outer gas limit. This cannot be zero
gasLimit := dataCost + 200_000
// Cap the gas limit to be 25 million to prevent creating withdrawals
// that go over the block gas limit.
if gasLimit > 25_000_000 {
gasLimit = 25_000_000
}
return gasLimit
}
...@@ -2,6 +2,7 @@ package crossdomain_test ...@@ -2,6 +2,7 @@ package crossdomain_test
import ( import (
"fmt" "fmt"
"math/big"
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-bindings/predeploys"
...@@ -11,6 +12,8 @@ import ( ...@@ -11,6 +12,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var big25Million = big.NewInt(25_000_000)
func TestMigrateWithdrawal(t *testing.T) { func TestMigrateWithdrawal(t *testing.T) {
withdrawals := make([]*crossdomain.LegacyWithdrawal, 0) withdrawals := make([]*crossdomain.LegacyWithdrawal, 0)
...@@ -31,6 +34,57 @@ func TestMigrateWithdrawal(t *testing.T) { ...@@ -31,6 +34,57 @@ func TestMigrateWithdrawal(t *testing.T) {
require.Equal(t, legacy.XDomainNonce.Uint64(), withdrawal.Nonce.Uint64()) require.Equal(t, legacy.XDomainNonce.Uint64(), withdrawal.Nonce.Uint64())
require.Equal(t, *withdrawal.Sender, predeploys.L2CrossDomainMessengerAddr) require.Equal(t, *withdrawal.Sender, predeploys.L2CrossDomainMessengerAddr)
require.Equal(t, *withdrawal.Target, l1CrossDomainMessenger) require.Equal(t, *withdrawal.Target, l1CrossDomainMessenger)
// Always equal to or lower than the cap
require.True(t, withdrawal.GasLimit.Cmp(big25Million) <= 0)
}) })
} }
} }
// TestMigrateWithdrawalGasLimitMax computes the migrated withdrawal
// gas limit with a very large amount of data. The max value for a migrated
// withdrawal's gas limit is 25 million.
func TestMigrateWithdrawalGasLimitMax(t *testing.T) {
size := 300_000_000 / 16
data := make([]byte, size)
for _, i := range data {
data[i] = 0xff
}
result := crossdomain.MigrateWithdrawalGasLimit(data)
require.Equal(t, result, big25Million.Uint64())
}
// TestMigrateWithdrawalGasLimit tests an assortment of zero and non zero
// bytes when computing the migrated withdrawal's gas limit.
func TestMigrateWithdrawalGasLimit(t *testing.T) {
tests := []struct {
input []byte
output uint64
}{
{
input: []byte{},
output: 200_000,
},
{
input: []byte{0xff},
output: 200_000 + 16,
},
{
input: []byte{0xff, 0x00},
output: 200_000 + 16 + 4,
},
{
input: []byte{0x00},
output: 200_000 + 4,
},
{
input: []byte{0x00, 0x00, 0x00},
output: 200_000 + 4 + 4 + 4,
},
}
for _, test := range tests {
result := crossdomain.MigrateWithdrawalGasLimit(test.input)
require.Equal(t, test.output, result)
}
}
...@@ -20,13 +20,3 @@ func getOVMETHTotalSupplySlot() common.Hash { ...@@ -20,13 +20,3 @@ func getOVMETHTotalSupplySlot() common.Hash {
key := common.BytesToHash(common.LeftPadBytes(position.Bytes(), 32)) key := common.BytesToHash(common.LeftPadBytes(position.Bytes(), 32))
return key return key
} }
func GetOVMETHTotalSupplySlot() common.Hash {
return getOVMETHTotalSupplySlot()
}
// getOVMETHBalance gets a user's OVM ETH balance from state by querying the
// appropriate storage slot directly.
func getOVMETHBalance(db *state.StateDB, addr common.Address) *big.Int {
return db.GetState(OVMETHAddress, CalcOVMETHStorageKey(addr)).Big()
}
...@@ -17,7 +17,7 @@ var ( ...@@ -17,7 +17,7 @@ var (
// OVMETHAddress is the address of the OVM ETH predeploy. // OVMETHAddress is the address of the OVM ETH predeploy.
OVMETHAddress = common.HexToAddress("0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000") OVMETHAddress = common.HexToAddress("0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000")
ignoredSlots = map[common.Hash]bool{ OVMETHIgnoredSlots = map[common.Hash]bool{
// Total Supply // Total Supply
common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000002"): true, common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000002"): true,
// Name // Name
...@@ -29,7 +29,14 @@ var ( ...@@ -29,7 +29,14 @@ var (
} }
) )
func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int, noCheck bool) error { // MigrateLegacyETH checks that the given list of addresses and allowances represents all storage
// 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
// account is extra then it won't have any balance and nothing will happen. For each valid balance,
// this method will migrate into state. This method does the checking as part of the migration loop
// in order to avoid having to iterate over state twice. This saves approximately 40 minutes during
// the mainnet migration.
func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, allowances []*crossdomain.Allowance, chainID int, noCheck bool, commit bool) error {
// Chain params to use for integrity checking. // Chain params to use for integrity checking.
params := crossdomain.ParamsByChainID[chainID] params := crossdomain.ParamsByChainID[chainID]
if params == nil { if params == nil {
...@@ -39,38 +46,99 @@ func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int ...@@ -39,38 +46,99 @@ func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int
// Log the chain params for debugging purposes. // Log the chain params for debugging purposes.
log.Info("Chain params", "chain-id", chainID, "supply-delta", params.ExpectedSupplyDelta) log.Info("Chain params", "chain-id", chainID, "supply-delta", params.ExpectedSupplyDelta)
// Deduplicate the list of addresses by converting to a map. return doMigration(db, addresses, allowances, params.ExpectedSupplyDelta, noCheck, commit)
deduped := make(map[common.Address]bool) }
func doMigration(db *state.StateDB, addresses []common.Address, allowances []*crossdomain.Allowance, expSupplyDiff *big.Int, noCheck bool, commit bool) error {
// We'll need to maintain a list of all addresses that we've seen along with all of the storage
// slots based on the witness data.
slotsAddrs := make(map[common.Hash]common.Address)
slotTypes := make(map[common.Hash]int)
// For each known address, compute its balance key and add it to the list of addresses.
// Mint events are instrumented as regular ETH events in the witness data, so we no longer
// need to iterate over mint events during the migration.
for _, addr := range addresses { for _, addr := range addresses {
deduped[addr] = true sk := CalcOVMETHStorageKey(addr)
slotTypes[sk] = 1
slotsAddrs[sk] = addr
}
// For each known allowance, compute its storage key and add it to the list of addresses.
for _, allowance := range allowances {
slotTypes[CalcAllowanceStorageKey(allowance.From, allowance.To)] = 2
} }
// Migrate the legacy ETH to ETH. // Add the old SequencerEntrypoint because someone sent it ETH a long time ago and it has a
// balance but none of our instrumentation could easily find it. Special case.
sequencerEntrypointAddr := common.HexToAddress("0x4200000000000000000000000000000000000005")
slotTypes[CalcOVMETHStorageKey(sequencerEntrypointAddr)] = 1
// Migrate the OVM_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 := util.ProgressLogger(1000, "imported accounts") logAccountProgress := util.ProgressLogger(1000, "imported OVM_ETH storage slot")
for addr := range deduped { var innerErr error
// No accounts should have a balance in state. If they do, bail. err := db.ForEachStorage(predeploys.LegacyERC20ETHAddr, func(key, value common.Hash) bool {
if db.GetBalance(addr).Sign() > 0 { defer logAccountProgress()
if noCheck {
log.Error("account has non-zero balance in state - should never happen", "addr", addr) // We can safely ignore specific slots (totalSupply, name, symbol).
} else { if OVMETHIgnoredSlots[key] {
log.Crit("account has non-zero balance in state - should never happen", "addr", addr) return true
}
// Look up the slot type.
slotType, ok := slotTypes[key]
if !ok {
log.Error("unknown storage slot in state", "slot", key.String())
if !noCheck {
innerErr = fmt.Errorf("unknown storage slot in state: %s", key.String())
return false
} }
} }
// Pull out the OVM ETH balance. switch slotType {
ovmBalance := getOVMETHBalance(db, addr) case 1:
// Balance slot.
bal := value.Big()
totalMigrated.Add(totalMigrated, bal)
addr := slotsAddrs[key]
// Actually perform the migration by setting the appropriate values in state. // There should never be any balances in state, so verify that here.
db.SetBalance(addr, ovmBalance) if db.GetBalance(addr).Sign() > 0 {
db.SetState(predeploys.LegacyERC20ETHAddr, CalcOVMETHStorageKey(addr), common.Hash{}) log.Error("account has non-zero balance in state - should never happen", "addr", addr)
if !noCheck {
innerErr = fmt.Errorf("account has non-zero balance in state - should never happen: %s", addr)
return false
}
}
if !commit {
return true
}
// Bump the total OVM balance. // Set the balance, and delete the legacy slot.
totalMigrated = totalMigrated.Add(totalMigrated, ovmBalance) db.SetBalance(addr, bal)
db.SetState(predeploys.LegacyERC20ETHAddr, key, common.Hash{})
case 2:
// Allowance slot. Nothing to do here.
return true
default:
// Should never happen.
log.Error("unknown slot type", "slot", key.String(), "type", slotType)
if !noCheck {
innerErr = fmt.Errorf("unknown slot type: %d", slotType)
return false
}
}
// Log progress. return true
logAccountProgress() })
if err != nil {
return fmt.Errorf("failed to iterate over OVM_ETH storage: %w", err)
}
if innerErr != nil {
return fmt.Errorf("error in migration: %w", innerErr)
} }
// Make sure that the total supply delta matches the expected delta. This is equivalent to // Make sure that the total supply delta matches the expected delta. This is equivalent to
...@@ -78,33 +146,44 @@ func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int ...@@ -78,33 +146,44 @@ func MigrateLegacyETH(db *state.StateDB, addresses []common.Address, chainID int
// same check against the total found (a = b, b = c => a = c). // same check against the total found (a = b, b = c => a = c).
totalSupply := getOVMETHTotalSupply(db) totalSupply := getOVMETHTotalSupply(db)
delta := new(big.Int).Sub(totalSupply, totalMigrated) delta := new(big.Int).Sub(totalSupply, totalMigrated)
if delta.Cmp(params.ExpectedSupplyDelta) != 0 { if delta.Cmp(expSupplyDiff) != 0 {
if noCheck { if noCheck {
log.Error( log.Error(
"supply mismatch", "supply mismatch",
"migrated", totalMigrated.String(), "migrated", totalMigrated.String(),
"supply", totalSupply.String(), "supply", totalSupply.String(),
"delta", delta.String(), "delta", delta.String(),
"exp_delta", params.ExpectedSupplyDelta.String(), "exp_delta", expSupplyDiff.String(),
) )
} else { } else {
log.Crit( log.Error(
"supply mismatch", "supply mismatch",
"migrated", totalMigrated.String(), "migrated", totalMigrated.String(),
"supply", totalSupply.String(), "supply", totalSupply.String(),
"delta", delta.String(), "delta", delta.String(),
"exp_delta", params.ExpectedSupplyDelta.String(), "exp_delta", expSupplyDiff.String(),
) )
return fmt.Errorf("supply mismatch: exp delta %s != %s", expSupplyDiff.String(), delta.String())
} }
} }
// Supply is verified.
log.Info(
"supply verified OK",
"migrated", totalMigrated.String(),
"supply", totalSupply.String(),
"delta", delta.String(),
"exp_delta", expSupplyDiff.String(),
)
// Set the total supply to 0. We do this because the total supply is necessarily going to be // Set the total supply to 0. We do this because the total supply is necessarily going to be
// different than the sum of all balances since we no longer track balances inside the contract // different than the sum of all balances since we no longer track balances inside the contract
// itself. The total supply is going to be weird no matter what, might as well set it to zero // itself. The total supply is going to be weird no matter what, might as well set it to zero
// so it's explicitly weird instead of implicitly weird. // so it's explicitly weird instead of implicitly weird.
db.SetState(predeploys.LegacyERC20ETHAddr, getOVMETHTotalSupplySlot(), common.Hash{}) if commit {
log.Info("Set the totalSupply to 0") db.SetState(predeploys.LegacyERC20ETHAddr, getOVMETHTotalSupplySlot(), common.Hash{})
log.Info("Set the totalSupply to 0")
}
// Fin.
return nil return nil
} }
package ether
import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/trie"
"github.com/stretchr/testify/require"
)
func TestMigrateLegacyETH(t *testing.T) {
tests := []struct {
name string
totalSupply *big.Int
expDiff *big.Int
stateBalances map[common.Address]*big.Int
stateAllowances map[common.Address]common.Address
inputAddresses []common.Address
inputAllowances []*crossdomain.Allowance
check func(t *testing.T, db *state.StateDB, err error)
}{
{
name: "everything matches",
totalSupply: big.NewInt(3),
expDiff: big.NewInt(0),
stateBalances: map[common.Address]*big.Int{
common.HexToAddress("0x123"): big.NewInt(1),
common.HexToAddress("0x456"): big.NewInt(2),
},
stateAllowances: map[common.Address]common.Address{
common.HexToAddress("0x123"): common.HexToAddress("0x456"),
},
inputAddresses: []common.Address{
common.HexToAddress("0x123"),
common.HexToAddress("0x456"),
},
inputAllowances: []*crossdomain.Allowance{
{
From: common.HexToAddress("0x123"),
To: common.HexToAddress("0x456"),
},
},
check: func(t *testing.T, db *state.StateDB, err error) {
require.NoError(t, err)
require.Equal(t, db.GetBalance(common.HexToAddress("0x123")), big.NewInt(1))
require.Equal(t, db.GetBalance(common.HexToAddress("0x456")), big.NewInt(2))
require.Equal(t, db.GetState(OVMETHAddress, CalcOVMETHStorageKey(common.HexToAddress("0x123"))), common.Hash{})
require.Equal(t, db.GetState(OVMETHAddress, CalcOVMETHStorageKey(common.HexToAddress("0x456"))), common.Hash{})
require.Equal(t, db.GetState(OVMETHAddress, getOVMETHTotalSupplySlot()), common.Hash{})
},
},
{
name: "extra input addresses",
totalSupply: big.NewInt(1),
expDiff: big.NewInt(0),
stateBalances: map[common.Address]*big.Int{
common.HexToAddress("0x123"): big.NewInt(1),
},
inputAddresses: []common.Address{
common.HexToAddress("0x123"),
common.HexToAddress("0x456"),
},
check: func(t *testing.T, db *state.StateDB, err error) {
require.NoError(t, err)
require.Equal(t, db.GetBalance(common.HexToAddress("0x123")), big.NewInt(1))
require.Equal(t, db.GetState(OVMETHAddress, CalcOVMETHStorageKey(common.HexToAddress("0x123"))), common.Hash{})
require.Equal(t, db.GetState(OVMETHAddress, getOVMETHTotalSupplySlot()), common.Hash{})
},
},
{
name: "extra input allowances",
totalSupply: big.NewInt(1),
expDiff: big.NewInt(0),
stateBalances: map[common.Address]*big.Int{
common.HexToAddress("0x123"): big.NewInt(1),
},
stateAllowances: map[common.Address]common.Address{
common.HexToAddress("0x123"): common.HexToAddress("0x456"),
},
inputAddresses: []common.Address{
common.HexToAddress("0x123"),
common.HexToAddress("0x456"),
},
inputAllowances: []*crossdomain.Allowance{
{
From: common.HexToAddress("0x123"),
To: common.HexToAddress("0x456"),
},
{
From: common.HexToAddress("0x123"),
To: common.HexToAddress("0x789"),
},
},
check: func(t *testing.T, db *state.StateDB, err error) {
require.NoError(t, err)
require.Equal(t, db.GetBalance(common.HexToAddress("0x123")), big.NewInt(1))
require.Equal(t, db.GetState(OVMETHAddress, CalcOVMETHStorageKey(common.HexToAddress("0x123"))), common.Hash{})
require.Equal(t, db.GetState(OVMETHAddress, getOVMETHTotalSupplySlot()), common.Hash{})
},
},
{
name: "missing input addresses",
totalSupply: big.NewInt(2),
expDiff: big.NewInt(0),
stateBalances: map[common.Address]*big.Int{
common.HexToAddress("0x123"): big.NewInt(1),
common.HexToAddress("0x456"): big.NewInt(1),
},
inputAddresses: []common.Address{
common.HexToAddress("0x123"),
},
check: func(t *testing.T, db *state.StateDB, err error) {
require.Error(t, err)
require.ErrorContains(t, err, "unknown storage slot")
},
},
{
name: "missing input allowances",
totalSupply: big.NewInt(2),
expDiff: big.NewInt(0),
stateBalances: map[common.Address]*big.Int{
common.HexToAddress("0x123"): big.NewInt(1),
},
stateAllowances: map[common.Address]common.Address{
common.HexToAddress("0x123"): common.HexToAddress("0x456"),
common.HexToAddress("0x123"): common.HexToAddress("0x789"),
},
inputAddresses: []common.Address{
common.HexToAddress("0x123"),
},
inputAllowances: []*crossdomain.Allowance{
{
From: common.HexToAddress("0x123"),
To: common.HexToAddress("0x456"),
},
},
check: func(t *testing.T, db *state.StateDB, err error) {
require.Error(t, err)
require.ErrorContains(t, err, "unknown storage slot")
},
},
{
name: "bad supply diff",
totalSupply: big.NewInt(4),
expDiff: big.NewInt(0),
stateBalances: map[common.Address]*big.Int{
common.HexToAddress("0x123"): big.NewInt(1),
common.HexToAddress("0x456"): big.NewInt(2),
},
inputAddresses: []common.Address{
common.HexToAddress("0x123"),
common.HexToAddress("0x456"),
},
check: func(t *testing.T, db *state.StateDB, err error) {
require.Error(t, err)
require.ErrorContains(t, err, "supply mismatch")
},
},
{
name: "good supply diff",
totalSupply: big.NewInt(4),
expDiff: big.NewInt(1),
stateBalances: map[common.Address]*big.Int{
common.HexToAddress("0x123"): big.NewInt(1),
common.HexToAddress("0x456"): big.NewInt(2),
},
inputAddresses: []common.Address{
common.HexToAddress("0x123"),
common.HexToAddress("0x456"),
},
check: func(t *testing.T, db *state.StateDB, err error) {
require.NoError(t, err)
require.Equal(t, db.GetBalance(common.HexToAddress("0x123")), big.NewInt(1))
require.Equal(t, db.GetBalance(common.HexToAddress("0x456")), big.NewInt(2))
require.Equal(t, db.GetState(OVMETHAddress, CalcOVMETHStorageKey(common.HexToAddress("0x123"))), common.Hash{})
require.Equal(t, db.GetState(OVMETHAddress, CalcOVMETHStorageKey(common.HexToAddress("0x456"))), common.Hash{})
require.Equal(t, db.GetState(OVMETHAddress, getOVMETHTotalSupplySlot()), common.Hash{})
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db := makeLegacyETH(t, tt.totalSupply, tt.stateBalances, tt.stateAllowances)
err := doMigration(db, tt.inputAddresses, tt.inputAllowances, tt.expDiff, false, true)
tt.check(t, db, err)
})
}
}
func makeLegacyETH(t *testing.T, totalSupply *big.Int, balances map[common.Address]*big.Int, allowances map[common.Address]common.Address) *state.StateDB {
db, err := state.New(common.Hash{}, state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &trie.Config{
Preimages: true,
Cache: 1024,
}), nil)
require.NoError(t, err)
db.CreateAccount(OVMETHAddress)
db.SetState(OVMETHAddress, getOVMETHTotalSupplySlot(), common.BigToHash(totalSupply))
for slot := range OVMETHIgnoredSlots {
if slot == getOVMETHTotalSupplySlot() {
continue
}
db.SetState(OVMETHAddress, slot, common.Hash{31: 0xff})
}
for addr, balance := range balances {
db.SetState(OVMETHAddress, CalcOVMETHStorageKey(addr), common.BigToHash(balance))
}
for from, to := range allowances {
db.SetState(OVMETHAddress, CalcAllowanceStorageKey(from, to), common.BigToHash(big.NewInt(1)))
}
root, err := db.Commit(false)
require.NoError(t, err)
err = db.Database().TrieDB().Commit(root, true)
require.NoError(t, err)
return db
}
This diff is collapsed.
...@@ -31,7 +31,6 @@ const MaxSlotChecks = 1000 ...@@ -31,7 +31,6 @@ const MaxSlotChecks = 1000
type StorageCheckMap = map[common.Hash]common.Hash type StorageCheckMap = map[common.Hash]common.Hash
var ( var (
L2XDMOwnerSlot = common.Hash{31: 0x33}
ProxyAdminOwnerSlot = common.Hash{} ProxyAdminOwnerSlot = common.Hash{}
LegacyETHCheckSlots = map[common.Hash]common.Hash{ LegacyETHCheckSlots = map[common.Hash]common.Hash{
...@@ -53,10 +52,6 @@ var ( ...@@ -53,10 +52,6 @@ var (
predeploys.L2CrossDomainMessengerAddr: { predeploys.L2CrossDomainMessengerAddr: {
// Slot 0x00 (0) is a combination of spacer_0_0_20, _initialized, and _initializing // Slot 0x00 (0) is a combination of spacer_0_0_20, _initialized, and _initializing
common.Hash{}: common.HexToHash("0x0000000000000000000000010000000000000000000000000000000000000000"), common.Hash{}: common.HexToHash("0x0000000000000000000000010000000000000000000000000000000000000000"),
// Slot 0x33 (51) is _owner. Requires custom check, so set to a garbage value
L2XDMOwnerSlot: common.HexToHash("0xbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad0"),
// Slot 0x97 (151) is _status
common.Hash{31: 0x97}: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001"),
// Slot 0xcc (204) is xDomainMsgSender // Slot 0xcc (204) is xDomainMsgSender
common.Hash{31: 0xcc}: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000dead"), common.Hash{31: 0xcc}: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000dead"),
// EIP-1967 storage slots // EIP-1967 storage slots
...@@ -346,7 +341,7 @@ func PostCheckPredeployStorage(db vm.StateDB, finalSystemOwner common.Address, p ...@@ -346,7 +341,7 @@ func PostCheckPredeployStorage(db vm.StateDB, finalSystemOwner common.Address, p
for key, value := range expSlots { for key, value := range expSlots {
// The owner slots for the L2XDM and ProxyAdmin are special cases. // The owner slots for the L2XDM and ProxyAdmin are special cases.
// They are set to the final system owner in the config. // They are set to the final system owner in the config.
if (*addr == predeploys.L2CrossDomainMessengerAddr && key == L2XDMOwnerSlot) || (*addr == predeploys.ProxyAdminAddr && key == ProxyAdminOwnerSlot) { if *addr == predeploys.ProxyAdminAddr && key == ProxyAdminOwnerSlot {
actualOwner := common.BytesToAddress(slots[key].Bytes()) actualOwner := common.BytesToAddress(slots[key].Bytes())
if actualOwner != proxyAdminOwner { if actualOwner != proxyAdminOwner {
return fmt.Errorf("expected owner for %s to be %s but got %s", name, proxyAdminOwner, actualOwner) return fmt.Errorf("expected owner for %s to be %s but got %s", name, proxyAdminOwner, actualOwner)
......
This diff is collapsed.
...@@ -53,7 +53,7 @@ func waitForL1OriginOnL2(l1BlockNum uint64, client *ethclient.Client, timeout ti ...@@ -53,7 +53,7 @@ func waitForL1OriginOnL2(l1BlockNum uint64, client *ethclient.Client, timeout ti
} }
case err := <-headSub.Err(): case err := <-headSub.Err():
return nil, fmt.Errorf("Error in head subscription: %w", err) return nil, fmt.Errorf("error in head subscription: %w", err)
case <-timeoutCh: case <-timeoutCh:
return nil, errors.New("timeout") return nil, errors.New("timeout")
} }
...@@ -101,7 +101,7 @@ func waitForBlock(number *big.Int, client *ethclient.Client, timeout time.Durati ...@@ -101,7 +101,7 @@ func waitForBlock(number *big.Int, client *ethclient.Client, timeout time.Durati
return client.BlockByNumber(ctx, number) return client.BlockByNumber(ctx, number)
} }
case err := <-headSub.Err(): case err := <-headSub.Err():
return nil, fmt.Errorf("Error in head subscription: %w", err) return nil, fmt.Errorf("error in head subscription: %w", err)
case <-timeoutCh: case <-timeoutCh:
return nil, errors.New("timeout") return nil, errors.New("timeout")
} }
......
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"time" "time"
bss "github.com/ethereum-optimism/optimism/op-batcher/batcher" bss "github.com/ethereum-optimism/optimism/op-batcher/batcher"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/sources" "github.com/ethereum-optimism/optimism/op-node/sources"
l2os "github.com/ethereum-optimism/optimism/op-proposer/proposer" l2os "github.com/ethereum-optimism/optimism/op-proposer/proposer"
oplog "github.com/ethereum-optimism/optimism/op-service/log" oplog "github.com/ethereum-optimism/optimism/op-service/log"
...@@ -311,7 +312,9 @@ func TestMigration(t *testing.T) { ...@@ -311,7 +312,9 @@ func TestMigration(t *testing.T) {
}, },
L1EpochPollInterval: 4 * time.Second, L1EpochPollInterval: 4 * time.Second,
} }
rollupNode, err := node.New(ctx, rollupNodeConfig, log.New(), snapLog, "", metrics.NewMetrics("")) rollupLog := log.New()
rollupNodeConfig.Rollup.LogDescription(rollupLog, chaincfg.L2ChainIDToNetworkName)
rollupNode, err := node.New(ctx, rollupNodeConfig, rollupLog, snapLog, "", metrics.NewMetrics(""))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, rollupNode.Start(ctx)) require.NoError(t, rollupNode.Start(ctx))
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -415,6 +415,7 @@ func TestMixedDepositValidity(t *testing.T) { ...@@ -415,6 +415,7 @@ func TestMixedDepositValidity(t *testing.T) {
// TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are // TestMixedWithdrawalValidity makes a number of withdrawal transactions and ensures ones with modified parameters are
// rejected while unmodified ones are accepted. This runs test cases in different systems. // rejected while unmodified ones are accepted. This runs test cases in different systems.
func TestMixedWithdrawalValidity(t *testing.T) { func TestMixedWithdrawalValidity(t *testing.T) {
parallel(t)
// Setup our logger handler // Setup our logger handler
if !verboseGethNodes { if !verboseGethNodes {
log.Root().SetHandler(log.DiscardHandler()) log.Root().SetHandler(log.DiscardHandler())
...@@ -424,7 +425,6 @@ func TestMixedWithdrawalValidity(t *testing.T) { ...@@ -424,7 +425,6 @@ func TestMixedWithdrawalValidity(t *testing.T) {
for i := 0; i <= 8; i++ { for i := 0; i <= 8; i++ {
i := i // avoid loop var capture i := i // avoid loop var capture
t.Run(fmt.Sprintf("withdrawal test#%d", i+1), func(t *testing.T) { t.Run(fmt.Sprintf("withdrawal test#%d", i+1), func(t *testing.T) {
parallel(t)
// Create our system configuration, funding all accounts we created for L1/L2, and start it // Create our system configuration, funding all accounts we created for L1/L2, and start it
cfg := DefaultSystemConfig(t) cfg := DefaultSystemConfig(t)
cfg.DeployConfig.FinalizationPeriodSeconds = 6 cfg.DeployConfig.FinalizationPeriodSeconds = 6
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -13,7 +13,6 @@ import ( ...@@ -13,7 +13,6 @@ import (
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/client" "github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/eth" "github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/metrics" "github.com/ethereum-optimism/optimism/op-node/metrics"
...@@ -62,8 +61,6 @@ func New(ctx context.Context, cfg *Config, log log.Logger, snapshotLog log.Logge ...@@ -62,8 +61,6 @@ func New(ctx context.Context, cfg *Config, log log.Logger, snapshotLog log.Logge
// not a context leak, gossipsub is closed with a context. // not a context leak, gossipsub is closed with a context.
n.resourcesCtx, n.resourcesClose = context.WithCancel(context.Background()) n.resourcesCtx, n.resourcesClose = context.WithCancel(context.Background())
log.Info("rollup config:\n" + cfg.Rollup.Description(chaincfg.L2ChainIDToNetworkName))
err := n.init(ctx, cfg, snapshotLog) err := n.init(ctx, cfg, snapshotLog)
if err != nil { if err != nil {
log.Error("Error initializing the rollup node", "err", err) log.Error("Error initializing the rollup node", "err", err)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -168,7 +168,7 @@ func TestP2PFull(t *testing.T) { ...@@ -168,7 +168,7 @@ func TestP2PFull(t *testing.T) {
_, err = p2pClientA.DiscoveryTable(ctx) _, err = p2pClientA.DiscoveryTable(ctx)
// rpc does not preserve error type // rpc does not preserve error type
require.Equal(t, err.Error(), DisabledDiscovery.Error(), "expecting discv5 to be disabled") require.Equal(t, err.Error(), ErrDisabledDiscovery.Error(), "expecting discv5 to be disabled")
require.NoError(t, p2pClientA.BlockPeer(ctx, hostB.ID())) require.NoError(t, p2pClientA.BlockPeer(ctx, hostB.ID()))
blockedPeers, err := p2pClientA.ListBlockedPeers(ctx) blockedPeers, err := p2pClientA.ListBlockedPeers(ctx)
......
This diff is collapsed.
This diff is collapsed.
// Code generated by mockery v2.14.0. DO NOT EDIT.
package mocks
import (
mock "github.com/stretchr/testify/mock"
peer "github.com/libp2p/go-libp2p/core/peer"
)
// PeerGater is an autogenerated mock type for the PeerGater type
type PeerGater struct {
mock.Mock
}
// Update provides a mock function with given fields: _a0, _a1
func (_m *PeerGater) Update(_a0 peer.ID, _a1 float64) {
_m.Called(_a0, _a1)
}
type mockConstructorTestingTNewPeerGater interface {
mock.TestingT
Cleanup(func())
}
// NewPeerGater creates a new instance of PeerGater. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewPeerGater(t mockConstructorTestingTNewPeerGater) *PeerGater {
mock := &PeerGater{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -64,6 +64,18 @@ func (p *Prepared) ConfigureGossip(params *pubsub.GossipSubParams) []pubsub.Opti ...@@ -64,6 +64,18 @@ func (p *Prepared) ConfigureGossip(params *pubsub.GossipSubParams) []pubsub.Opti
return nil return nil
} }
func (p *Prepared) PeerScoringParams() *pubsub.PeerScoreParams {
return nil
}
func (p *Prepared) BanPeers() bool {
return false
}
func (p *Prepared) TopicScoringParams() *pubsub.TopicScoreParams {
return nil
}
func (p *Prepared) Disabled() bool { func (p *Prepared) Disabled() bool {
return false return false
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -50,7 +50,6 @@ type EngineQueueStage interface { ...@@ -50,7 +50,6 @@ type EngineQueueStage interface {
SetUnsafeHead(head eth.L2BlockRef) SetUnsafeHead(head eth.L2BlockRef)
Finalize(l1Origin eth.L1BlockRef) Finalize(l1Origin eth.L1BlockRef)
AddSafeAttributes(attributes *eth.PayloadAttributes)
AddUnsafePayload(payload *eth.ExecutionPayload) AddUnsafePayload(payload *eth.ExecutionPayload)
Step(context.Context) error Step(context.Context) error
} }
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum-optimism/optimism/op-node/eth" "github.com/ethereum-optimism/optimism/op-node/eth"
...@@ -271,6 +272,28 @@ func (c *Config) Description(l2Chains map[string]string) string { ...@@ -271,6 +272,28 @@ func (c *Config) Description(l2Chains map[string]string) string {
return banner return banner
} }
// Description outputs a banner describing the important parts of rollup configuration in a log format.
// Optionally provide a mapping of L2 chain IDs to network names to label the L2 chain with if not unknown.
// The config should be config.Check()-ed before creating a description.
func (c *Config) LogDescription(log log.Logger, l2Chains map[string]string) {
// Find and report the network the user is running
networkL2 := ""
if l2Chains != nil {
networkL2 = l2Chains[c.L2ChainID.String()]
}
if networkL2 == "" {
networkL2 = "unknown L2"
}
networkL1 := params.NetworkNames[c.L1ChainID.String()]
if networkL1 == "" {
networkL1 = "unknown L1"
}
log.Info("Rollup Config", "l2_chain_id", c.L2ChainID, "l2_network", networkL2, "l1_chain_id", c.L1ChainID,
"l1_network", networkL1, "l2_start_time", c.Genesis.L2Time, "l2_block_hash", c.Genesis.L2.Hash.String(),
"l2_block_number", c.Genesis.L2.Number, "l1_block_hash", c.Genesis.L1.Hash.String(),
"l1_block_number", c.Genesis.L1.Number, "regolith_time", fmtForkTimeOrUnset(c.RegolithTime))
}
func fmtForkTimeOrUnset(v *uint64) string { func fmtForkTimeOrUnset(v *uint64) string {
if v == nil { if v == nil {
return "(not configured)" return "(not configured)"
......
This diff is collapsed.
...@@ -115,7 +115,6 @@ func (ibc *IterativeBatchCall[K, V]) Fetch(ctx context.Context) error { ...@@ -115,7 +115,6 @@ func (ibc *IterativeBatchCall[K, V]) Fetch(ctx context.Context) error {
} }
return ctx.Err() return ctx.Err()
default: default:
break
} }
break break
} }
......
...@@ -92,7 +92,7 @@ func Main(version string, cliCtx *cli.Context) error { ...@@ -92,7 +92,7 @@ func Main(version string, cliCtx *cli.Context) error {
} }
rpcCfg := cfg.RPCConfig rpcCfg := cfg.RPCConfig
server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version) server := oprpc.NewServer(rpcCfg.ListenAddr, rpcCfg.ListenPort, version, oprpc.WithLogger(l))
if err := server.Start(); err != nil { if err := server.Start(); err != nil {
cancel() cancel()
return fmt.Errorf("error starting RPC server: %w", err) return fmt.Errorf("error starting RPC server: %w", err)
......
This diff is collapsed.
...@@ -10,7 +10,7 @@ func SetupDefaults() { ...@@ -10,7 +10,7 @@ func SetupDefaults() {
log.Root().SetHandler( log.Root().SetHandler(
log.LvlFilterHandler( log.LvlFilterHandler(
log.LvlInfo, log.LvlInfo,
log.StreamHandler(os.Stdout, log.TerminalFormat(true)), log.StreamHandler(os.Stdout, log.LogfmtFormat()),
), ),
) )
} }
This diff is collapsed.
FROM ethereumoptimism/op-geth:optimism FROM us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:optimism
RUN apk add --no-cache jq RUN apk add --no-cache jq
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
"name": "@eth-optimism/atst", "name": "@eth-optimism/atst",
"version": "0.1.0", "version": "0.1.0",
"type": "module", "type": "module",
"main": "dist/index.js", "main": "dist/index.cjs",
"types": "src/index.ts", "types": "src/index.ts",
"module": "dist/index.cjs", "module": "dist/index.js",
"license": "MIT", "license": "MIT",
"exports": { "exports": {
".": { ".": {
...@@ -59,5 +59,15 @@ ...@@ -59,5 +59,15 @@
"@wagmi/core": "^0.9.2", "@wagmi/core": "^0.9.2",
"@wagmi/cli": "~0.1.5", "@wagmi/cli": "~0.1.5",
"wagmi": "~0.11.0" "wagmi": "~0.11.0"
} },
"keywords": [
"react",
"hooks",
"eth",
"ethereum",
"dapps",
"web3",
"optimism",
"attestation"
]
} }
This diff is collapsed.
...@@ -26,16 +26,14 @@ describe(readAttestation.name, () => { ...@@ -26,16 +26,14 @@ describe(readAttestation.name, () => {
) )
}) })
it('should throw an error if key is longer than 32 bytes', async () => { it('should work if key is longer than 32 bytes', async () => {
await expect( expect(
readAttestation( await readAttestation(
creator, creator,
about, about,
'this is a key that is way longer than 32 bytes so this key should throw an error matching the inline snapshot', 'this is a key that is way longer than 32 bytes so this key should throw an error matching the inline snapshot',
dataType dataType
) )
).rejects.toThrowErrorMatchingInlineSnapshot( ).toMatchInlineSnapshot('""')
'"Key is longer than the max length of 32 for attestation keys"'
)
}) })
}) })
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -11,3 +11,4 @@ tmp-artifacts ...@@ -11,3 +11,4 @@ tmp-artifacts
deployments/mainnet-forked deployments/mainnet-forked
deploy-config/mainnet-forked.json deploy-config/mainnet-forked.json
test-case-generator/fuzz test-case-generator/fuzz
.resource-metering.csv
This diff is collapsed.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
// Importing from the legacy contracts package causes issues with the build of the contract bindings
// so we just copy the library here from
// /packages/contracts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol at commit
// 7866168c
/**
* @title LegacyCrossDomainUtils
*/
library LegacyCrossDomainUtils {
/**
* Generates the correct cross domain calldata for a message.
* @param _target Target contract address.
* @param _sender Message sender address.
* @param _message Message to send to the target.
* @param _messageNonce Nonce for the provided message.
* @return ABI encoded cross domain calldata.
*/
function encodeXDomainCalldata(
address _target,
address _sender,
bytes memory _message,
uint256 _messageNonce
) internal pure returns (bytes memory) {
return
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_message,
_messageNonce
);
}
}
This diff is collapsed.
...@@ -141,16 +141,6 @@ abstract contract CrossDomainMessenger is ...@@ -141,16 +141,6 @@ abstract contract CrossDomainMessenger is
*/ */
uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16; uint64 public constant MIN_GAS_CALLDATA_OVERHEAD = 16;
/**
* @notice Minimum amount of gas required to relay a message.
*/
uint256 internal constant RELAY_GAS_REQUIRED = 45_000;
/**
* @notice Amount of gas held in reserve to guarantee that relay execution completes.
*/
uint256 internal constant RELAY_GAS_BUFFER = RELAY_GAS_REQUIRED - 5000;
/** /**
* @notice Address of the paired CrossDomainMessenger contract on the other chain. * @notice Address of the paired CrossDomainMessenger contract on the other chain.
*/ */
...@@ -367,16 +357,11 @@ abstract contract CrossDomainMessenger is ...@@ -367,16 +357,11 @@ abstract contract CrossDomainMessenger is
"CrossDomainMessenger: message has already been relayed" "CrossDomainMessenger: message has already been relayed"
); );
require(
gasleft() >= _minGasLimit + RELAY_GAS_REQUIRED,
"CrossDomainMessenger: insufficient gas to relay message"
);
xDomainMsgSender = _sender; xDomainMsgSender = _sender;
bool success = SafeCall.call(_target, gasleft() - RELAY_GAS_BUFFER, _value, _message); bool success = SafeCall.callWithMinGas(_target, _minGasLimit, _value, _message);
xDomainMsgSender = Constants.DEFAULT_L2_SENDER; xDomainMsgSender = Constants.DEFAULT_L2_SENDER;
if (success == true) { if (success) {
successfulMessages[versionedHash] = true; successfulMessages[versionedHash] = true;
emit RelayedMessage(versionedHash); emit RelayedMessage(versionedHash);
} else { } else {
......
...@@ -10,7 +10,7 @@ import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol ...@@ -10,7 +10,7 @@ import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol
* OptimismMintableERC20. * OptimismMintableERC20.
*/ */
interface IOptimismMintableERC20 is IERC165 { interface IOptimismMintableERC20 is IERC165 {
function remoteToken() external returns (address); function remoteToken() external view returns (address);
function bridge() external returns (address); function bridge() external returns (address);
...@@ -26,7 +26,7 @@ interface IOptimismMintableERC20 is IERC165 { ...@@ -26,7 +26,7 @@ interface IOptimismMintableERC20 is IERC165 {
* on the OptimismMintableERC20 contract for backwards compatibility. * on the OptimismMintableERC20 contract for backwards compatibility.
*/ */
interface ILegacyMintableERC20 is IERC165 { interface ILegacyMintableERC20 is IERC165 {
function l1Token() external returns (address); function l1Token() external view returns (address);
function mint(address _to, uint256 _amount) external; function mint(address _to, uint256 _amount) external;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment