Commit 935cba01 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into jg/drop_invalid_batch

parents 911ffa6b ee494343
---
'@eth-optimism/indexer': patch
---
Delete unused flags
---
'@eth-optimism/l2geth': patch
---
Fixes a small l2geth bug when trying to dump state
---
'@eth-optimism/contracts-bedrock': patch
---
Added codecov badge to readme
---
'@eth-optimism/ci-builder': patch
---
Update geth to 1.10.25
This diff is collapsed.
...@@ -3,6 +3,7 @@ ignore: ...@@ -3,6 +3,7 @@ ignore:
- "l2geth" - "l2geth"
- "**/*.t.sol" - "**/*.t.sol"
- "op-bindings/bindings/*.go" - "op-bindings/bindings/*.go"
- "packages/contracts-bedrock/contracts/(vendor|libraries)/(trie|rlp)"
flag_management: flag_management:
# Note: flags should have the same name as the circleci job in which they # Note: flags should have the same name as the circleci job in which they
# are uploaded. # are uploaded.
......
...@@ -22,12 +22,6 @@ var ( ...@@ -22,12 +22,6 @@ var (
Required: true, Required: true,
EnvVar: prefixEnvVar("BUILD_ENV"), EnvVar: prefixEnvVar("BUILD_ENV"),
} }
EthNetworkNameFlag = cli.StringFlag{
Name: "eth-network-name",
Usage: "Ethereum network name",
Required: true,
EnvVar: prefixEnvVar("ETH_NETWORK_NAME"),
}
ChainIDFlag = cli.StringFlag{ ChainIDFlag = cli.StringFlag{
Name: "chain-id", Name: "chain-id",
Usage: "Ethereum chain ID", Usage: "Ethereum chain ID",
...@@ -188,7 +182,6 @@ var ( ...@@ -188,7 +182,6 @@ var (
var requiredFlags = []cli.Flag{ var requiredFlags = []cli.Flag{
BuildEnvFlag, BuildEnvFlag,
EthNetworkNameFlag,
ChainIDFlag, ChainIDFlag,
L1EthRPCFlag, L1EthRPCFlag,
L2EthRPCFlag, L2EthRPCFlag,
......
...@@ -2,10 +2,11 @@ package statedumper ...@@ -2,10 +2,11 @@ package statedumper
import ( import (
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/l2geth/common"
"io" "io"
"os" "os"
"sync" "sync"
"github.com/ethereum-optimism/optimism/l2geth/common"
) )
type StateDumper interface { type StateDumper interface {
...@@ -21,7 +22,7 @@ func NewStateDumper() StateDumper { ...@@ -21,7 +22,7 @@ func NewStateDumper() StateDumper {
return &noopStateDumper{} return &noopStateDumper{}
} }
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE, 0o755) f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o755)
if err != nil { if err != nil {
panic(err) panic(err)
} }
......
...@@ -108,7 +108,7 @@ more: ...@@ -108,7 +108,7 @@ more:
go run ./gen/main.go \ go run ./gen/main.go \
-artifacts ../packages/contracts-bedrock/artifacts \ -artifacts ../packages/contracts-bedrock/artifacts \
-out ./bindings \ -out ./bindings \
-contracts OptimismMintableERC20Factory,L2StandardBridge,L1BlockNumber,LegacyMessagePasser,DeployerWhitelist,Proxy,OptimismPortal,L2ToL1MessagePasser,L2CrossDomainMessenger,GasPriceOracle,SequencerFeeVault,L1Block,LegacyERC20ETH,WETH9,GovernanceToken,L1CrossDomainMessenger,L2ERC721Bridge,OptimismMintableERC721Factory \ -contracts OptimismMintableERC20Factory,L2StandardBridge,L1BlockNumber,LegacyMessagePasser,DeployerWhitelist,Proxy,OptimismPortal,L2ToL1MessagePasser,L2CrossDomainMessenger,GasPriceOracle,SequencerFeeVault,L1Block,LegacyERC20ETH,WETH9,GovernanceToken,L1CrossDomainMessenger,L2ERC721Bridge,OptimismMintableERC721Factory,ProxyAdmin \
-package bindings -package bindings
mkdir: mkdir:
......
# op-bindings
This package contains built go bindings of the smart contracts. It must be
updated after any changes to the smart contracts to ensure that the bindings are
up to date.
The bindings include the bytecode for each contract so that go based tests
can deploy the contracts. There are also `more` files that include the deployed
bytecode as well as the storage layout. These are used to dynamically set
bytecode and storage slots in state.
## Dependencies
- `abigen` version 1.10.25
- `make`
To check the version of `abigen`, run the command `abigen --version`.
## abigen
The `abigen` tool is part of `go-ethereum` and can be used to build go bindings
for smart contracts. It can be installed with go using the commands:
```bash
$ go get -u github.com/ethereum/go-ethereum
$ cd $GOPATH/src/github.com/ethereum/go-ethereum/
$ make devtools
```
The geth docs for `abigen` can be found [here](https://geth.ethereum.org/docs/dapp/native-bindings).
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const DeployerWhitelistStorageLayoutJSON = "{\"storage\":[{\"astId\":3246,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":3251,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"whitelist\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_bool\"}}}" const DeployerWhitelistStorageLayoutJSON = "{\"storage\":[{\"astId\":3248,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":3253,\"contract\":\"contracts/legacy/DeployerWhitelist.sol:DeployerWhitelist\",\"label\":\"whitelist\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_bool\"}}}"
var DeployerWhitelistStorageLayout = new(solc.StorageLayout) var DeployerWhitelistStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const GasPriceOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":28492,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1951,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer_1_0_32\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1954,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer_2_0_32\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1957,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"overhead\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint256\"},{\"astId\":1960,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"scalar\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_uint256\"},{\"astId\":1963,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"decimals\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_uint256\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}" const GasPriceOracleStorageLayoutJSON = "{\"storage\":[{\"astId\":28513,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1953,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer_1_0_32\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":1956,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"spacer_2_0_32\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1959,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"overhead\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint256\"},{\"astId\":1962,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"scalar\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_uint256\"},{\"astId\":1965,\"contract\":\"contracts/L2/GasPriceOracle.sol:GasPriceOracle\",\"label\":\"decimals\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_uint256\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var GasPriceOracleStorageLayout = new(solc.StorageLayout) var GasPriceOracleStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const GovernanceTokenStorageLayoutJSON = "{\"storage\":[{\"astId\":28842,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":28848,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":28850,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":28852,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":28854,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":30219,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_nonces\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_mapping(t_address,t_struct(Counter)32405_storage)\"},{\"astId\":30227,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_PERMIT_TYPEHASH_DEPRECATED_SLOT\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_bytes32\"},{\"astId\":29560,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_delegates\",\"offset\":0,\"slot\":\"7\",\"type\":\"t_mapping(t_address,t_address)\"},{\"astId\":29566,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_checkpoints\",\"offset\":0,\"slot\":\"8\",\"type\":\"t_mapping(t_address,t_array(t_struct(Checkpoint)29551_storage)dyn_storage)\"},{\"astId\":29570,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_totalSupplyCheckpoints\",\"offset\":0,\"slot\":\"9\",\"type\":\"t_array(t_struct(Checkpoint)29551_storage)dyn_storage\"},{\"astId\":28492,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"10\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(Checkpoint)29551_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct ERC20Votes.Checkpoint[]\",\"numberOfBytes\":\"32\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_address,t_address)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e address)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_address\"},\"t_mapping(t_address,t_array(t_struct(Checkpoint)29551_storage)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct ERC20Votes.Checkpoint[])\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_array(t_struct(Checkpoint)29551_storage)dyn_storage\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_struct(Counter)32405_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct Counters.Counter)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_struct(Counter)32405_storage\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_struct(Checkpoint)29551_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ERC20Votes.Checkpoint\",\"numberOfBytes\":\"32\"},\"t_struct(Counter)32405_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Counters.Counter\",\"numberOfBytes\":\"32\"},\"t_uint224\":{\"encoding\":\"inplace\",\"label\":\"uint224\",\"numberOfBytes\":\"28\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"}}}" const GovernanceTokenStorageLayoutJSON = "{\"storage\":[{\"astId\":28863,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":28869,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":28871,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":28873,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":28875,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":30240,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_nonces\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_mapping(t_address,t_struct(Counter)32426_storage)\"},{\"astId\":30248,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_PERMIT_TYPEHASH_DEPRECATED_SLOT\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_bytes32\"},{\"astId\":29581,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_delegates\",\"offset\":0,\"slot\":\"7\",\"type\":\"t_mapping(t_address,t_address)\"},{\"astId\":29587,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_checkpoints\",\"offset\":0,\"slot\":\"8\",\"type\":\"t_mapping(t_address,t_array(t_struct(Checkpoint)29572_storage)dyn_storage)\"},{\"astId\":29591,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_totalSupplyCheckpoints\",\"offset\":0,\"slot\":\"9\",\"type\":\"t_array(t_struct(Checkpoint)29572_storage)dyn_storage\"},{\"astId\":28513,\"contract\":\"contracts/L2/GovernanceToken.sol:GovernanceToken\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"10\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_struct(Checkpoint)29572_storage)dyn_storage\":{\"encoding\":\"dynamic_array\",\"label\":\"struct ERC20Votes.Checkpoint[]\",\"numberOfBytes\":\"32\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_address,t_address)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e address)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_address\"},\"t_mapping(t_address,t_array(t_struct(Checkpoint)29572_storage)dyn_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct ERC20Votes.Checkpoint[])\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_array(t_struct(Checkpoint)29572_storage)dyn_storage\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_struct(Counter)32426_storage)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e struct Counters.Counter)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_struct(Counter)32426_storage\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_struct(Checkpoint)29572_storage\":{\"encoding\":\"inplace\",\"label\":\"struct ERC20Votes.Checkpoint\",\"numberOfBytes\":\"32\"},\"t_struct(Counter)32426_storage\":{\"encoding\":\"inplace\",\"label\":\"struct Counters.Counter\",\"numberOfBytes\":\"32\"},\"t_uint224\":{\"encoding\":\"inplace\",\"label\":\"uint224\",\"numberOfBytes\":\"28\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint32\":{\"encoding\":\"inplace\",\"label\":\"uint32\",\"numberOfBytes\":\"4\"}}}"
var GovernanceTokenStorageLayout = new(solc.StorageLayout) var GovernanceTokenStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const L1BlockStorageLayoutJSON = "{\"storage\":[{\"astId\":2298,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"number\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":2301,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"timestamp\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":2304,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"basefee\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":2307,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"hash\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_bytes32\"},{\"astId\":2310,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"sequenceNumber\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint64\"}],\"types\":{\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"}}}" const L1BlockStorageLayoutJSON = "{\"storage\":[{\"astId\":2300,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"number\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":2303,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"timestamp\",\"offset\":8,\"slot\":\"0\",\"type\":\"t_uint64\"},{\"astId\":2306,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"basefee\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"},{\"astId\":2309,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"hash\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_bytes32\"},{\"astId\":2312,\"contract\":\"contracts/L2/L1Block.sol:L1Block\",\"label\":\"sequenceNumber\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_uint64\"}],\"types\":{\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint64\":{\"encoding\":\"inplace\",\"label\":\"uint64\",\"numberOfBytes\":\"8\"}}}"
var L1BlockStorageLayout = new(solc.StorageLayout) var L1BlockStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const L1CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":24883,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27869,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27872,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":28483,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":27741,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":27861,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":28034,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_paused\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":28139,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":28154,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_status\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":28198,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":24935,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24940,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24945,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24948,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":24951,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":24956,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"receivedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24961,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" const L1CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":24904,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27890,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27893,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":28504,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":27762,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":27882,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":28055,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_paused\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":28160,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":28175,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"_status\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":28219,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":24956,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24961,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24966,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24969,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":24972,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":24977,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"receivedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24982,\"contract\":\"contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
var L1CrossDomainMessengerStorageLayout = new(solc.StorageLayout) var L1CrossDomainMessengerStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const L2CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":24883,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27869,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27872,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":28483,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":27741,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":27861,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":28034,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_paused\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":28139,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":28154,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_status\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":28198,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":24935,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24940,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24945,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24948,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":24951,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":24956,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"receivedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24961,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}" const L2CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":24904,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27890,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initialized\",\"offset\":20,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":27893,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_initializing\",\"offset\":21,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":28504,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":27762,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":27882,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":28055,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_paused\",\"offset\":0,\"slot\":\"101\",\"type\":\"t_bool\"},{\"astId\":28160,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"102\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":28175,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"_status\",\"offset\":0,\"slot\":\"151\",\"type\":\"t_uint256\"},{\"astId\":28219,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"152\",\"type\":\"t_array(t_uint256)49_storage\"},{\"astId\":24956,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_201_0_32\",\"offset\":0,\"slot\":\"201\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24961,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"spacer_202_0_32\",\"offset\":0,\"slot\":\"202\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24966,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"203\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24969,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"xDomainMsgSender\",\"offset\":0,\"slot\":\"204\",\"type\":\"t_address\"},{\"astId\":24972,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"205\",\"type\":\"t_uint240\"},{\"astId\":24977,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"receivedMessages\",\"offset\":0,\"slot\":\"206\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":24982,\"contract\":\"contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"207\",\"type\":\"t_array(t_uint256)42_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)42_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[42]\",\"numberOfBytes\":\"1344\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
var L2CrossDomainMessengerStorageLayout = new(solc.StorageLayout) var L2CrossDomainMessengerStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const L2ERC721BridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":25389,\"contract\":\"contracts/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_array(t_uint256)49_storage\"}],\"types\":{\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}" const L2ERC721BridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":25410,\"contract\":\"contracts/L2/L2ERC721Bridge.sol:L2ERC721Bridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_array(t_uint256)49_storage\"}],\"types\":{\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var L2ERC721BridgeStorageLayout = new(solc.StorageLayout) var L2ERC721BridgeStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const L2StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":27042,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27045,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":27052,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":27057,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_uint256)47_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)47_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[47]\",\"numberOfBytes\":\"1504\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}" const L2StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":27063,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":27066,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":27073,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":27078,\"contract\":\"contracts/L2/L2StandardBridge.sol:L2StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_uint256)47_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)47_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[47]\",\"numberOfBytes\":\"1504\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var L2StandardBridgeStorageLayout = new(solc.StorageLayout) var L2StandardBridgeStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const L2ToL1MessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":2945,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":2948,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"nonce\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}" const L2ToL1MessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":2947,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":2950,\"contract\":\"contracts/L2/L2ToL1MessagePasser.sol:L2ToL1MessagePasser\",\"label\":\"nonce\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint256\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var L2ToL1MessagePasserStorageLayout = new(solc.StorageLayout) var L2ToL1MessagePasserStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const LegacyERC20ETHStorageLayoutJSON = "{\"storage\":[{\"astId\":28842,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":28848,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":28850,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":28852,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":28854,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":25618,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"remoteToken\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_address\"},{\"astId\":25621,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"bridge\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}" const LegacyERC20ETHStorageLayoutJSON = "{\"storage\":[{\"astId\":28863,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":28869,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":28871,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":28873,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":28875,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"},{\"astId\":25639,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"remoteToken\",\"offset\":0,\"slot\":\"5\",\"type\":\"t_address\"},{\"astId\":25642,\"contract\":\"contracts/legacy/LegacyERC20ETH.sol:LegacyERC20ETH\",\"label\":\"bridge\",\"offset\":0,\"slot\":\"6\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var LegacyERC20ETHStorageLayout = new(solc.StorageLayout) var LegacyERC20ETHStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const LegacyMessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":3889,\"contract\":\"contracts/legacy/LegacyMessagePasser.sol:LegacyMessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"}}}" const LegacyMessagePasserStorageLayoutJSON = "{\"storage\":[{\"astId\":3891,\"contract\":\"contracts/legacy/LegacyMessagePasser.sol:LegacyMessagePasser\",\"label\":\"sentMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"}}}"
var LegacyMessagePasserStorageLayout = new(solc.StorageLayout) var LegacyMessagePasserStorageLayout = new(solc.StorageLayout)
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const OptimismMintableERC721FactoryStorageLayoutJSON = "{\"storage\":[{\"astId\":26141,\"contract\":\"contracts/universal/OptimismMintableERC721Factory.sol:OptimismMintableERC721Factory\",\"label\":\"isOptimismMintableERC721\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_bool\"}}}" const OptimismMintableERC721FactoryStorageLayoutJSON = "{\"storage\":[{\"astId\":26162,\"contract\":\"contracts/universal/OptimismMintableERC721Factory.sol:OptimismMintableERC721Factory\",\"label\":\"isOptimismMintableERC721\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_bool)\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_mapping(t_address,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_bool\"}}}"
var OptimismMintableERC721FactoryStorageLayout = new(solc.StorageLayout) var OptimismMintableERC721FactoryStorageLayout = new(solc.StorageLayout)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const SequencerFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":3087,\"contract\":\"contracts/L2/SequencerFeeVault.sol:SequencerFeeVault\",\"label\":\"l1FeeWallet\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"}}}" const SequencerFeeVaultStorageLayoutJSON = "{\"storage\":[{\"astId\":3089,\"contract\":\"contracts/L2/SequencerFeeVault.sol:SequencerFeeVault\",\"label\":\"l1FeeWallet\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"}}}"
var SequencerFeeVaultStorageLayout = new(solc.StorageLayout) var SequencerFeeVaultStorageLayout = new(solc.StorageLayout)
......
...@@ -18,6 +18,7 @@ const ( ...@@ -18,6 +18,7 @@ const (
LegacyMessagePasser = "0x4200000000000000000000000000000000000000" LegacyMessagePasser = "0x4200000000000000000000000000000000000000"
L2ERC721Bridge = "0x4200000000000000000000000000000000000014" L2ERC721Bridge = "0x4200000000000000000000000000000000000014"
OptimismMintableERC721Factory = "0x4200000000000000000000000000000000000017" OptimismMintableERC721Factory = "0x4200000000000000000000000000000000000017"
ProxyAdmin = "0x4200000000000000000000000000000000000018"
) )
var ( var (
...@@ -36,6 +37,7 @@ var ( ...@@ -36,6 +37,7 @@ var (
LegacyMessagePasserAddr = common.HexToAddress(LegacyMessagePasser) LegacyMessagePasserAddr = common.HexToAddress(LegacyMessagePasser)
L2ERC721BridgeAddr = common.HexToAddress(L2ERC721Bridge) L2ERC721BridgeAddr = common.HexToAddress(L2ERC721Bridge)
OptimismMintableERC721FactoryAddr = common.HexToAddress(OptimismMintableERC721Factory) OptimismMintableERC721FactoryAddr = common.HexToAddress(OptimismMintableERC721Factory)
ProxyAdminAddr = common.HexToAddress(ProxyAdmin)
Predeploys = make(map[string]*common.Address) Predeploys = make(map[string]*common.Address)
) )
...@@ -56,4 +58,5 @@ func init() { ...@@ -56,4 +58,5 @@ func init() {
Predeploys["LegacyMessagePasser"] = &LegacyMessagePasserAddr Predeploys["LegacyMessagePasser"] = &LegacyMessagePasserAddr
Predeploys["L2ERC721Bridge"] = &L2ERC721BridgeAddr Predeploys["L2ERC721Bridge"] = &L2ERC721BridgeAddr
Predeploys["OptimismMintableERC721Factory"] = &OptimismMintableERC721FactoryAddr Predeploys["OptimismMintableERC721Factory"] = &OptimismMintableERC721FactoryAddr
Predeploys["ProxyAdmin"] = &ProxyAdminAddr
} }
...@@ -3,6 +3,7 @@ package genesis ...@@ -3,6 +3,7 @@ package genesis
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"math/big" "math/big"
"os" "os"
"path/filepath" "path/filepath"
...@@ -63,6 +64,7 @@ type DeployConfig struct { ...@@ -63,6 +64,7 @@ type DeployConfig struct {
L2GenesisBlockParentHash common.Hash `json:"l2GenesisBlockParentHash"` L2GenesisBlockParentHash common.Hash `json:"l2GenesisBlockParentHash"`
L2GenesisBlockBaseFeePerGas *hexutil.Big `json:"l2GenesisBlockBaseFeePerGas"` L2GenesisBlockBaseFeePerGas *hexutil.Big `json:"l2GenesisBlockBaseFeePerGas"`
ProxyAdminOwner common.Address `json:"proxyAdminOwner"`
L2CrossDomainMessengerOwner common.Address `json:"l2CrossDomainMessengerOwner"` L2CrossDomainMessengerOwner common.Address `json:"l2CrossDomainMessengerOwner"`
OptimismBaseFeeRecipient common.Address `json:"optimismBaseFeeRecipient"` OptimismBaseFeeRecipient common.Address `json:"optimismBaseFeeRecipient"`
OptimismL1FeeRecipient common.Address `json:"optimismL1FeeRecipient"` OptimismL1FeeRecipient common.Address `json:"optimismL1FeeRecipient"`
...@@ -83,7 +85,7 @@ type DeployConfig struct { ...@@ -83,7 +85,7 @@ type DeployConfig struct {
func NewDeployConfig(path string) (*DeployConfig, error) { func NewDeployConfig(path string) (*DeployConfig, error) {
file, err := os.ReadFile(path) file, err := os.ReadFile(path)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("deploy config at %s not found: %w", path, err)
} }
var config DeployConfig var config DeployConfig
...@@ -104,22 +106,26 @@ func NewDeployConfigWithNetwork(network, path string) (*DeployConfig, error) { ...@@ -104,22 +106,26 @@ func NewDeployConfigWithNetwork(network, path string) (*DeployConfig, error) {
// NewL2ImmutableConfig will create an ImmutableConfig given an instance of a // NewL2ImmutableConfig will create an ImmutableConfig given an instance of a
// Hardhat and a DeployConfig. // Hardhat and a DeployConfig.
func NewL2ImmutableConfig(config *DeployConfig, block *types.Block, proxyL1StandardBridge, proxyL1CrossDomainMessenger, proxyL1ERC721Bridge common.Address) (immutables.ImmutableConfig, error) { func NewL2ImmutableConfig(config *DeployConfig, block *types.Block, l2Addrs *L2Addresses) (immutables.ImmutableConfig, error) {
immutable := make(immutables.ImmutableConfig) immutable := make(immutables.ImmutableConfig)
if proxyL1ERC721Bridge == (common.Address{}) { if l2Addrs == nil {
return immutable, errors.New("must pass L1 contract addresses")
}
if l2Addrs.L1ERC721BridgeProxy == (common.Address{}) {
return immutable, errors.New("L1ERC721BridgeProxy cannot be address(0)") return immutable, errors.New("L1ERC721BridgeProxy cannot be address(0)")
} }
immutable["L2StandardBridge"] = immutables.ImmutableValues{ immutable["L2StandardBridge"] = immutables.ImmutableValues{
"otherBridge": proxyL1StandardBridge, "otherBridge": l2Addrs.L1StandardBridgeProxy,
} }
immutable["L2CrossDomainMessenger"] = immutables.ImmutableValues{ immutable["L2CrossDomainMessenger"] = immutables.ImmutableValues{
"otherMessenger": proxyL1CrossDomainMessenger, "otherMessenger": l2Addrs.L1CrossDomainMessengerProxy,
} }
immutable["L2ERC721Bridge"] = immutables.ImmutableValues{ immutable["L2ERC721Bridge"] = immutables.ImmutableValues{
"messenger": predeploys.L2CrossDomainMessengerAddr, "messenger": predeploys.L2CrossDomainMessengerAddr,
"otherBridge": proxyL1ERC721Bridge, "otherBridge": l2Addrs.L1ERC721BridgeProxy,
} }
immutable["OptimismMintableERC721Factory"] = immutables.ImmutableValues{ immutable["OptimismMintableERC721Factory"] = immutables.ImmutableValues{
"bridge": predeploys.L2ERC721BridgeAddr, "bridge": predeploys.L2ERC721BridgeAddr,
...@@ -131,7 +137,7 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block, proxyL1Stand ...@@ -131,7 +137,7 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block, proxyL1Stand
// NewL2StorageConfig will create a StorageConfig given an instance of a // NewL2StorageConfig will create a StorageConfig given an instance of a
// Hardhat and a DeployConfig. // Hardhat and a DeployConfig.
func NewL2StorageConfig(config *DeployConfig, block *types.Block, proxyL1StandardBridge common.Address, proxyL1CrossDomainMessenger common.Address) (state.StorageConfig, error) { func NewL2StorageConfig(config *DeployConfig, block *types.Block, l2Addrs *L2Addresses) (state.StorageConfig, error) {
storage := make(state.StorageConfig) storage := make(state.StorageConfig)
if block.Number() == nil { if block.Number() == nil {
...@@ -140,6 +146,9 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block, proxyL1Standar ...@@ -140,6 +146,9 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block, proxyL1Standar
if block.BaseFee() == nil { if block.BaseFee() == nil {
return storage, errors.New("block base fee not set") return storage, errors.New("block base fee not set")
} }
if l2Addrs == nil {
return storage, errors.New("must pass L1 address info")
}
storage["L2ToL1MessagePasser"] = state.StorageValues{ storage["L2ToL1MessagePasser"] = state.StorageValues{
"nonce": 0, "nonce": 0,
...@@ -187,5 +196,8 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block, proxyL1Standar ...@@ -187,5 +196,8 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block, proxyL1Standar
// TODO: this should be set to the MintManager // TODO: this should be set to the MintManager
"_owner": common.Address{}, "_owner": common.Address{},
} }
storage["ProxyAdmin"] = state.StorageValues{
"owner": l2Addrs.ProxyAdminOwner,
}
return storage, nil return storage, nil
} }
...@@ -9,8 +9,10 @@ import ( ...@@ -9,8 +9,10 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
) )
// L2Addresses represents L1 contract addresses
// that are required for the construction of an L2 state
type L2Addresses struct { type L2Addresses struct {
ProxyAdmin common.Address ProxyAdminOwner common.Address
L1StandardBridgeProxy common.Address L1StandardBridgeProxy common.Address
L1CrossDomainMessengerProxy common.Address L1CrossDomainMessengerProxy common.Address
L1ERC721BridgeProxy common.Address L1ERC721BridgeProxy common.Address
...@@ -31,9 +33,11 @@ func BuildL2DeveloperGenesis(config *DeployConfig, l1StartBlock *types.Block, l2 ...@@ -31,9 +33,11 @@ func BuildL2DeveloperGenesis(config *DeployConfig, l1StartBlock *types.Block, l2
} }
SetPrecompileBalances(db) SetPrecompileBalances(db)
// Use the known developer addresses if they are not set
if l2Addrs == nil { if l2Addrs == nil {
l2Addrs = &L2Addresses{ l2Addrs = &L2Addresses{
ProxyAdmin: predeploys.DevProxyAdminAddr, // corresponds to m/44'/60'/0'/0/1 in the 'test test... junk' mnemonic
ProxyAdminOwner: common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"),
L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr, L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr,
L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr, L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr,
L1ERC721BridgeProxy: predeploys.DevL1ERC721BridgeAddr, L1ERC721BridgeProxy: predeploys.DevL1ERC721BridgeAddr,
...@@ -45,31 +49,16 @@ func BuildL2DeveloperGenesis(config *DeployConfig, l1StartBlock *types.Block, l2 ...@@ -45,31 +49,16 @@ func BuildL2DeveloperGenesis(config *DeployConfig, l1StartBlock *types.Block, l2
// BuildL2Genesis will build the L2 Optimism Genesis Block // BuildL2Genesis will build the L2 Optimism Genesis Block
func BuildL2Genesis(db *state.MemoryStateDB, config *DeployConfig, l1Block *types.Block, l2Addrs *L2Addresses) (*core.Genesis, error) { func BuildL2Genesis(db *state.MemoryStateDB, config *DeployConfig, l1Block *types.Block, l2Addrs *L2Addresses) (*core.Genesis, error) {
// TODO(tynes): need a function for clearing old, unused storage slots. if err := SetL2Proxies(db); err != nil {
// Each deployed contract on L2 needs to have its existing storage
// inspected and then cleared if they are no longer used.
if err := SetL2Proxies(db, l2Addrs.ProxyAdmin); err != nil {
return nil, err return nil, err
} }
storage, err := NewL2StorageConfig( storage, err := NewL2StorageConfig(config, l1Block, l2Addrs)
config,
l1Block,
l2Addrs.L1StandardBridgeProxy,
l2Addrs.L1CrossDomainMessengerProxy,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
immutable, err := NewL2ImmutableConfig( immutable, err := NewL2ImmutableConfig(config, l1Block, l2Addrs)
config,
l1Block,
l2Addrs.L1StandardBridgeProxy,
l2Addrs.L1CrossDomainMessengerProxy,
l2Addrs.L1ERC721BridgeProxy,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -16,7 +16,6 @@ import ( ...@@ -16,7 +16,6 @@ import (
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
...@@ -31,19 +30,9 @@ func init() { ...@@ -31,19 +30,9 @@ func init() {
var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
func TestBuildL2DeveloperGenesis(t *testing.T) { func TestBuildL2DeveloperGenesis(t *testing.T) {
hh, err := hardhat.New(
"alpha-1",
nil,
[]string{"../../packages/contracts-bedrock/deployments"},
)
require.Nil(t, err)
config, err := genesis.NewDeployConfig("./testdata/test-deploy-config-devnet-l1.json") config, err := genesis.NewDeployConfig("./testdata/test-deploy-config-devnet-l1.json")
require.Nil(t, err) require.Nil(t, err)
proxyAdmin, err := hh.GetDeployment("ProxyAdmin")
require.Nil(t, err)
backend := backends.NewSimulatedBackend( backend := backends.NewSimulatedBackend(
core.GenesisAlloc{ core.GenesisAlloc{
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)}, crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)},
...@@ -52,12 +41,8 @@ func TestBuildL2DeveloperGenesis(t *testing.T) { ...@@ -52,12 +41,8 @@ func TestBuildL2DeveloperGenesis(t *testing.T) {
) )
block, err := backend.BlockByNumber(context.Background(), common.Big0) block, err := backend.BlockByNumber(context.Background(), common.Big0)
require.NoError(t, err) require.NoError(t, err)
gen, err := genesis.BuildL2DeveloperGenesis(config, block, &genesis.L2Addresses{
ProxyAdmin: proxyAdmin.Address, gen, err := genesis.BuildL2DeveloperGenesis(config, block, nil)
L1ERC721BridgeProxy: predeploys.DevL1ERC721BridgeAddr,
L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr,
L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr,
})
require.Nil(t, err) require.Nil(t, err)
require.NotNil(t, gen) require.NotNil(t, gen)
...@@ -71,13 +56,13 @@ func TestBuildL2DeveloperGenesis(t *testing.T) { ...@@ -71,13 +56,13 @@ func TestBuildL2DeveloperGenesis(t *testing.T) {
require.Equal(t, ok, true) require.Equal(t, ok, true)
require.Greater(t, len(account.Code), 0) require.Greater(t, len(account.Code), 0)
if name == "GovernanceToken" || name == "LegacyERC20ETH" { if name == "GovernanceToken" || name == "LegacyERC20ETH" || name == "ProxyAdmin" {
continue continue
} }
adminSlot, ok := account.Storage[genesis.AdminSlot] adminSlot, ok := account.Storage[genesis.AdminSlot]
require.Equal(t, ok, true) require.Equal(t, ok, true)
require.Equal(t, adminSlot, proxyAdmin.Address.Hash()) require.Equal(t, adminSlot, predeploys.ProxyAdminAddr.Hash())
require.Equal(t, account.Code, depB) require.Equal(t, account.Code, depB)
} }
require.Equal(t, 2341, len(gen.Alloc)) require.Equal(t, 2341, len(gen.Alloc))
...@@ -101,12 +86,8 @@ func TestBuildL2DeveloperGenesisDevAccountsFunding(t *testing.T) { ...@@ -101,12 +86,8 @@ func TestBuildL2DeveloperGenesisDevAccountsFunding(t *testing.T) {
) )
block, err := backend.BlockByNumber(context.Background(), common.Big0) block, err := backend.BlockByNumber(context.Background(), common.Big0)
require.NoError(t, err) require.NoError(t, err)
gen, err := genesis.BuildL2DeveloperGenesis(config, block, &genesis.L2Addresses{
ProxyAdmin: common.Address{}, gen, err := genesis.BuildL2DeveloperGenesis(config, block, nil)
L1ERC721BridgeProxy: predeploys.DevL1ERC721BridgeAddr,
L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr,
L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr,
})
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 2319, len(gen.Alloc)) require.Equal(t, 2319, len(gen.Alloc))
} }
...@@ -25,8 +25,8 @@ func FundDevAccounts(db vm.StateDB) { ...@@ -25,8 +25,8 @@ func FundDevAccounts(db vm.StateDB) {
// a Proxy and ProxyAdmin deployment present so that the Proxy bytecode // a Proxy and ProxyAdmin deployment present so that the Proxy bytecode
// can be set in state and the ProxyAdmin can be set as the admin of the // can be set in state and the ProxyAdmin can be set as the admin of the
// Proxy. // Proxy.
func SetL2Proxies(db vm.StateDB, proxyAdminAddr common.Address) error { func SetL2Proxies(db vm.StateDB) error {
return setProxies(db, proxyAdminAddr, bigL2PredeployNamespace, 2048) return setProxies(db, predeploys.ProxyAdminAddr, bigL2PredeployNamespace, 2048)
} }
// SetL1Proxies will set each of the proxies in the state. It requires // SetL1Proxies will set each of the proxies in the state. It requires
...@@ -47,8 +47,10 @@ func setProxies(db vm.StateDB, proxyAdminAddr common.Address, namespace *big.Int ...@@ -47,8 +47,10 @@ func setProxies(db vm.StateDB, proxyAdminAddr common.Address, namespace *big.Int
bigAddr := new(big.Int).Or(namespace, new(big.Int).SetUint64(i)) bigAddr := new(big.Int).Or(namespace, new(big.Int).SetUint64(i))
addr := common.BigToAddress(bigAddr) addr := common.BigToAddress(bigAddr)
// There is no proxy at the governance token address // There is no proxy at the governance token address or
if addr == predeploys.GovernanceTokenAddr { // the proxy admin address. LegacyERC20ETH lives in the
// 0xDead namespace so it can be ignored here
if addr == predeploys.GovernanceTokenAddr || addr == predeploys.ProxyAdminAddr {
continue continue
} }
...@@ -69,13 +71,16 @@ func SetImplementations(db vm.StateDB, storage state.StorageConfig, immutable im ...@@ -69,13 +71,16 @@ func SetImplementations(db vm.StateDB, storage state.StorageConfig, immutable im
} }
for name, address := range predeploys.Predeploys { for name, address := range predeploys.Predeploys {
// Convert the address to the code address // Convert the address to the code address unless it is
// designed to not be behind a proxy
var addr common.Address var addr common.Address
switch *address { switch *address {
case predeploys.GovernanceTokenAddr: case predeploys.GovernanceTokenAddr:
addr = predeploys.GovernanceTokenAddr addr = predeploys.GovernanceTokenAddr
case predeploys.LegacyERC20ETHAddr: case predeploys.LegacyERC20ETHAddr:
addr = predeploys.LegacyERC20ETHAddr addr = predeploys.LegacyERC20ETHAddr
case predeploys.ProxyAdminAddr:
addr = predeploys.ProxyAdminAddr
default: default:
addr, err = AddressToCodeNamespace(*address) addr, err = AddressToCodeNamespace(*address)
if err != nil { if err != nil {
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
"optimismL1FeeRecipient": "0x0000000000000000000000000000000000000000", "optimismL1FeeRecipient": "0x0000000000000000000000000000000000000000",
"l2CrossDomainMessengerOwner": "0x42000000000000000000000000000000000000f2", "l2CrossDomainMessengerOwner": "0x42000000000000000000000000000000000000f2",
"gasPriceOracleOwner": "0x42000000000000000000000000000000000000f3", "gasPriceOracleOwner": "0x42000000000000000000000000000000000000f3",
"proxyAdminOwner": "0x0000000000000000000000000000000000000000",
"gasPriceOracleOverhead": 2100, "gasPriceOracleOverhead": 2100,
"gasPriceOracleScalar": 1000000, "gasPriceOracleScalar": 1000000,
"gasPriceOracleDecimals": 6, "gasPriceOracleDecimals": 6,
...@@ -49,4 +50,4 @@ ...@@ -49,4 +50,4 @@
"eip1559Denominator": 8, "eip1559Denominator": 8,
"eip1559Elasticity": 2, "eip1559Elasticity": 2,
"fundDevAccounts": true "fundDevAccounts": true
} }
\ No newline at end of file
...@@ -152,6 +152,11 @@ func (s *L1Miner) ActL1EndBlock(t Testing) { ...@@ -152,6 +152,11 @@ func (s *L1Miner) ActL1EndBlock(t Testing) {
} }
} }
func (s *L1Miner) ActEmptyBlock(t Testing) {
s.ActL1StartBlock(12)(t)
s.ActL1EndBlock(t)
}
func (s *L1Miner) Close() error { func (s *L1Miner) Close() error {
return s.L1Replica.Close() return s.L1Replica.Close()
} }
...@@ -125,6 +125,7 @@ func (s *L2Batcher) ActL2BatchBuffer(t Testing) { ...@@ -125,6 +125,7 @@ func (s *L2Batcher) ActL2BatchBuffer(t Testing) {
if err := s.l2ChannelOut.AddBlock(block); err != nil { // should always succeed if err := s.l2ChannelOut.AddBlock(block); err != nil { // should always succeed
t.Fatalf("failed to add block to channel: %v", err) t.Fatalf("failed to add block to channel: %v", err)
} }
s.l2BufferedBlock = eth.ToBlockID(block)
} }
func (s *L2Batcher) ActL2ChannelClose(t Testing) { func (s *L2Batcher) ActL2ChannelClose(t Testing) {
...@@ -181,3 +182,17 @@ func (s *L2Batcher) ActL2BatchSubmit(t Testing) { ...@@ -181,3 +182,17 @@ func (s *L2Batcher) ActL2BatchSubmit(t Testing) {
err = s.l1.SendTransaction(t.Ctx(), tx) err = s.l1.SendTransaction(t.Ctx(), tx)
require.NoError(t, err, "need to send tx") require.NoError(t, err, "need to send tx")
} }
func (s *L2Batcher) ActBufferAll(t Testing) {
stat, err := s.syncStatusAPI.SyncStatus(t.Ctx())
require.NoError(t, err)
for s.l2BufferedBlock.Number < stat.UnsafeL2.Number {
s.ActL2BatchBuffer(t)
}
}
func (s *L2Batcher) ActSubmitAll(t Testing) {
s.ActBufferAll(t)
s.ActL2ChannelClose(t)
s.ActL2BatchSubmit(t)
}
...@@ -92,3 +92,12 @@ func (s *L2Sequencer) ActL2KeepL1Origin(t Testing) { ...@@ -92,3 +92,12 @@ func (s *L2Sequencer) ActL2KeepL1Origin(t Testing) {
} }
s.seqOldOrigin = true s.seqOldOrigin = true
} }
// ActBuildToL1Head builds empty blocks until (incl.) the L1 head becomes the L2 origin
func (s *L2Sequencer) ActBuildToL1Head(t Testing) {
for s.derivation.UnsafeL2Head().L1Origin.Number < s.l1State.L1Head().Number {
s.ActL2PipelineFull(t)
s.ActL2StartBlock(t)
s.ActL2EndBlock(t)
}
}
...@@ -104,15 +104,27 @@ func (s *l2VerifierBackend) ResetDerivationPipeline(ctx context.Context) error { ...@@ -104,15 +104,27 @@ func (s *l2VerifierBackend) ResetDerivationPipeline(ctx context.Context) error {
return nil return nil
} }
func (s *L2Verifier) L2Finalized() eth.L2BlockRef {
return s.derivation.Finalized()
}
func (s *L2Verifier) L2Safe() eth.L2BlockRef {
return s.derivation.SafeL2Head()
}
func (s *L2Verifier) L2Unsafe() eth.L2BlockRef {
return s.derivation.UnsafeL2Head()
}
func (s *L2Verifier) SyncStatus() *eth.SyncStatus { func (s *L2Verifier) SyncStatus() *eth.SyncStatus {
return &eth.SyncStatus{ return &eth.SyncStatus{
CurrentL1: s.derivation.Origin(), CurrentL1: s.derivation.Origin(),
HeadL1: s.l1State.L1Head(), HeadL1: s.l1State.L1Head(),
SafeL1: s.l1State.L1Safe(), SafeL1: s.l1State.L1Safe(),
FinalizedL1: s.l1State.L1Finalized(), FinalizedL1: s.l1State.L1Finalized(),
UnsafeL2: s.derivation.UnsafeL2Head(), UnsafeL2: s.L2Unsafe(),
SafeL2: s.derivation.SafeL2Head(), SafeL2: s.L2Safe(),
FinalizedL2: s.derivation.Finalized(), FinalizedL2: s.L2Finalized(),
} }
} }
......
This diff is collapsed.
...@@ -168,6 +168,7 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) * ...@@ -168,6 +168,7 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *
} }
l1Block := l1Genesis.ToBlock() l1Block := l1Genesis.ToBlock()
l2Genesis, err := genesis.BuildL2DeveloperGenesis(deployConf, l1Block, nil) l2Genesis, err := genesis.BuildL2DeveloperGenesis(deployConf, l1Block, nil)
require.NoError(t, err, "failed to create l2 genesis") require.NoError(t, err, "failed to create l2 genesis")
if alloc.PrefundTestUsers { if alloc.PrefundTestUsers {
......
...@@ -57,13 +57,7 @@ var Subcommands = cli.Commands{ ...@@ -57,13 +57,7 @@ var Subcommands = cli.Commands{
} }
l1StartBlock := l1Genesis.ToBlock() l1StartBlock := l1Genesis.ToBlock()
l2Addrs := &genesis.L2Addresses{ l2Genesis, err := genesis.BuildL2DeveloperGenesis(config, l1StartBlock, nil)
ProxyAdmin: predeploys.DevProxyAdminAddr,
L1StandardBridgeProxy: predeploys.DevL1StandardBridgeAddr,
L1CrossDomainMessengerProxy: predeploys.DevL1CrossDomainMessengerAddr,
L1ERC721BridgeProxy: predeploys.DevL1ERC721BridgeAddr,
}
l2Genesis, err := genesis.BuildL2DeveloperGenesis(config, l1StartBlock, l2Addrs)
if err != nil { if err != nil {
return err return err
} }
...@@ -136,10 +130,6 @@ var Subcommands = cli.Commands{ ...@@ -136,10 +130,6 @@ var Subcommands = cli.Commands{
return err return err
} }
proxyAdmin, err := hh.GetDeployment("ProxyAdmin")
if err != nil {
return err
}
l1SBP, err := hh.GetDeployment("L1StandardBridgeProxy") l1SBP, err := hh.GetDeployment("L1StandardBridgeProxy")
if err != nil { if err != nil {
return err return err
...@@ -158,7 +148,7 @@ var Subcommands = cli.Commands{ ...@@ -158,7 +148,7 @@ var Subcommands = cli.Commands{
} }
l2Addrs := &genesis.L2Addresses{ l2Addrs := &genesis.L2Addresses{
ProxyAdmin: proxyAdmin.Address, ProxyAdminOwner: config.ProxyAdminOwner,
L1StandardBridgeProxy: l1SBP.Address, L1StandardBridgeProxy: l1SBP.Address,
L1CrossDomainMessengerProxy: l1XDMP.Address, L1CrossDomainMessengerProxy: l1XDMP.Address,
L1ERC721BridgeProxy: l1ERC721BP.Address, L1ERC721BridgeProxy: l1ERC721BP.Address,
......
...@@ -10,8 +10,8 @@ import ( ...@@ -10,8 +10,8 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
type NextDataProvider interface { type NextFrameProvider interface {
NextData(ctx context.Context) ([]byte, error) NextFrame(ctx context.Context) (Frame, error)
Origin() eth.L1BlockRef Origin() eth.L1BlockRef
} }
...@@ -34,14 +34,14 @@ type ChannelBank struct { ...@@ -34,14 +34,14 @@ type ChannelBank struct {
channels map[ChannelID]*Channel // channels by ID channels map[ChannelID]*Channel // channels by ID
channelQueue []ChannelID // channels in FIFO order channelQueue []ChannelID // channels in FIFO order
prev NextDataProvider prev NextFrameProvider
fetcher L1Fetcher fetcher L1Fetcher
} }
var _ ResetableStage = (*ChannelBank)(nil) var _ ResetableStage = (*ChannelBank)(nil)
// NewChannelBank creates a ChannelBank, which should be Reset(origin) before use. // NewChannelBank creates a ChannelBank, which should be Reset(origin) before use.
func NewChannelBank(log log.Logger, cfg *rollup.Config, prev NextDataProvider, fetcher L1Fetcher) *ChannelBank { func NewChannelBank(log log.Logger, cfg *rollup.Config, prev NextFrameProvider, fetcher L1Fetcher) *ChannelBank {
return &ChannelBank{ return &ChannelBank{
log: log, log: log,
cfg: cfg, cfg: cfg,
...@@ -73,42 +73,34 @@ func (cb *ChannelBank) prune() { ...@@ -73,42 +73,34 @@ func (cb *ChannelBank) prune() {
} }
// IngestData adds new L1 data to the channel bank. // IngestData adds new L1 data to the channel bank.
// Read() should be called repeatedly first, until everything has been read, before adding new data.\ // Read() should be called repeatedly first, until everything has been read, before adding new data.
func (cb *ChannelBank) IngestData(data []byte) { func (cb *ChannelBank) IngestFrame(f Frame) {
origin := cb.Origin() origin := cb.Origin()
cb.log.Debug("channel bank got new data", "origin", origin, "data_len", len(data)) log := log.New("origin", origin, "channel", f.ID, "length", len(f.Data), "frame_number", f.FrameNumber)
log.Debug("channel bank got new data")
// TODO: Why is the prune here?
cb.prune() currentCh, ok := cb.channels[f.ID]
if !ok {
// create new channel if it doesn't exist yet
currentCh = NewChannel(f.ID, origin)
cb.channels[f.ID] = currentCh
cb.channelQueue = append(cb.channelQueue, f.ID)
}
frames, err := ParseFrames(data) // check if the channel is not timed out
if err != nil { if currentCh.OpenBlockNumber()+cb.cfg.ChannelTimeout < origin.Number {
cb.log.Warn("malformed frame", "err", err) log.Warn("channel is timed out, ignore frame")
return return
} }
// Process each frame log.Trace("ingesting frame")
for _, f := range frames { if err := currentCh.AddFrame(f, origin); err != nil {
currentCh, ok := cb.channels[f.ID] log.Warn("failed to ingest frame into channel", "err", err)
if !ok { return
// create new channel if it doesn't exist yet
currentCh = NewChannel(f.ID, origin)
cb.channels[f.ID] = currentCh
cb.channelQueue = append(cb.channelQueue, f.ID)
}
// check if the channel is not timed out
if currentCh.OpenBlockNumber()+cb.cfg.ChannelTimeout < origin.Number {
cb.log.Warn("channel is timed out, ignore frame", "channel", f.ID, "frame", f.FrameNumber)
continue
}
cb.log.Trace("ingesting frame", "channel", f.ID, "frame_number", f.FrameNumber, "length", len(f.Data))
if err := currentCh.AddFrame(f, origin); err != nil {
cb.log.Warn("failed to ingest frame into channel", "channel", f.ID, "frame_number", f.FrameNumber, "err", err)
continue
}
} }
// Prune after the frame is loaded.
cb.prune()
} }
// Read the raw data of the first channel, if it's timed-out or closed. // Read the raw data of the first channel, if it's timed-out or closed.
...@@ -156,12 +148,12 @@ func (cb *ChannelBank) NextData(ctx context.Context) ([]byte, error) { ...@@ -156,12 +148,12 @@ func (cb *ChannelBank) NextData(ctx context.Context) ([]byte, error) {
} }
// Then load data into the channel bank // Then load data into the channel bank
if data, err := cb.prev.NextData(ctx); err == io.EOF { if frame, err := cb.prev.NextFrame(ctx); err == io.EOF {
return nil, io.EOF return nil, io.EOF
} else if err != nil { } else if err != nil {
return nil, err return nil, err
} else { } else {
cb.IngestData(data) cb.IngestFrame(frame)
return nil, NotEnoughData return nil, NotEnoughData
} }
} }
......
package derive package derive
import ( import (
"bytes"
"context" "context"
"fmt"
"io" "io"
"math/rand" "math/rand"
"strconv" "strconv"
...@@ -21,8 +19,8 @@ import ( ...@@ -21,8 +19,8 @@ import (
type fakeChannelBankInput struct { type fakeChannelBankInput struct {
origin eth.L1BlockRef origin eth.L1BlockRef
data []struct { data []struct {
data []byte frame Frame
err error err error
} }
} }
...@@ -30,34 +28,28 @@ func (f *fakeChannelBankInput) Origin() eth.L1BlockRef { ...@@ -30,34 +28,28 @@ func (f *fakeChannelBankInput) Origin() eth.L1BlockRef {
return f.origin return f.origin
} }
func (f *fakeChannelBankInput) NextData(_ context.Context) ([]byte, error) { func (f *fakeChannelBankInput) NextFrame(_ context.Context) (Frame, error) {
out := f.data[0] out := f.data[0]
f.data = f.data[1:] f.data = f.data[1:]
return out.data, out.err return out.frame, out.err
} }
func (f *fakeChannelBankInput) AddOutput(data []byte, err error) { func (f *fakeChannelBankInput) AddFrame(frame Frame, err error) {
f.data = append(f.data, struct { f.data = append(f.data, struct {
data []byte frame Frame
err error err error
}{data: data, err: err}) }{frame: frame, err: err})
} }
// ExpectNextFrameData takes a set of test frame & turns into the raw data // ExpectNextFrameData takes a set of test frame & turns into the raw data
// for reading into the channel bank via `NextData` // for reading into the channel bank via `NextData`
func (f *fakeChannelBankInput) AddFrames(frames ...testFrame) { func (f *fakeChannelBankInput) AddFrames(frames ...testFrame) {
data := new(bytes.Buffer)
data.WriteByte(DerivationVersion0)
for _, frame := range frames { for _, frame := range frames {
ff := frame.ToFrame() f.AddFrame(frame.ToFrame(), nil)
if err := ff.MarshalBinary(data); err != nil {
panic(fmt.Errorf("error in making frame during test: %w", err))
}
} }
f.AddOutput(data.Bytes(), nil)
} }
var _ NextDataProvider = (*fakeChannelBankInput)(nil) var _ NextFrameProvider = (*fakeChannelBankInput)(nil)
// format: <channelID-data>:<frame-number>:<content><optional-last-frame-marker "!"> // format: <channelID-data>:<frame-number>:<content><optional-last-frame-marker "!">
// example: "abc:0:helloworld!" // example: "abc:0:helloworld!"
...@@ -105,17 +97,22 @@ func TestChannelBankSimple(t *testing.T) { ...@@ -105,17 +97,22 @@ func TestChannelBankSimple(t *testing.T) {
input := &fakeChannelBankInput{origin: a} input := &fakeChannelBankInput{origin: a}
input.AddFrames("a:0:first", "a:2:third!") input.AddFrames("a:0:first", "a:2:third!")
input.AddFrames("a:1:second") input.AddFrames("a:1:second")
input.AddOutput(nil, io.EOF) input.AddFrame(Frame{}, io.EOF)
cfg := &rollup.Config{ChannelTimeout: 10} cfg := &rollup.Config{ChannelTimeout: 10}
cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil) cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil)
// Load the first + third frame // Load the first frame
out, err := cb.NextData(context.Background()) out, err := cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData) require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out) require.Equal(t, []byte(nil), out)
// Load the third frame
out, err = cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out)
// Load the second frame // Load the second frame
out, err = cb.NextData(context.Background()) out, err = cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData) require.ErrorIs(t, err, NotEnoughData)
...@@ -140,21 +137,29 @@ func TestChannelBankDuplicates(t *testing.T) { ...@@ -140,21 +137,29 @@ func TestChannelBankDuplicates(t *testing.T) {
input.AddFrames("a:0:first", "a:2:third!") input.AddFrames("a:0:first", "a:2:third!")
input.AddFrames("a:0:altfirst", "a:2:altthird!") input.AddFrames("a:0:altfirst", "a:2:altthird!")
input.AddFrames("a:1:second") input.AddFrames("a:1:second")
input.AddOutput(nil, io.EOF) input.AddFrame(Frame{}, io.EOF)
cfg := &rollup.Config{ChannelTimeout: 10} cfg := &rollup.Config{ChannelTimeout: 10}
cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil) cb := NewChannelBank(testlog.Logger(t, log.LvlCrit), cfg, input, nil)
// Load the first + third frame // Load the first frame
out, err := cb.NextData(context.Background()) out, err := cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData) require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out) require.Equal(t, []byte(nil), out)
// Load the third frame
out, err = cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out)
// Load the duplicate frames // Load the duplicate frames
out, err = cb.NextData(context.Background()) out, err = cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData) require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out) require.Equal(t, []byte(nil), out)
out, err = cb.NextData(context.Background())
require.ErrorIs(t, err, NotEnoughData)
require.Equal(t, []byte(nil), out)
// Load the second frame // Load the second frame
out, err = cb.NextData(context.Background()) out, err = cb.NextData(context.Background())
......
...@@ -84,7 +84,7 @@ func (co *ChannelOut) AddBlock(block *types.Block) error { ...@@ -84,7 +84,7 @@ func (co *ChannelOut) AddBlock(block *types.Block) error {
return err return err
} }
// We encode to a temporary buffer to determine the encoded length to // We encode to a temporary buffer to determine the encoded length to
// ensure that the total size of all RLP elements is less than MAX_RLP_BYTES_PER_CHANNEL // ensure that the total size of all RLP elements is less than or equal to MAX_RLP_BYTES_PER_CHANNEL
var buf bytes.Buffer var buf bytes.Buffer
if err := rlp.Encode(&buf, batch); err != nil { if err := rlp.Encode(&buf, batch); err != nil {
return err return err
......
package derive package derive
import ( import (
"bytes"
"math/big" "math/big"
"testing" "testing"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
...@@ -25,3 +27,25 @@ func TestChannelOutAddBlock(t *testing.T) { ...@@ -25,3 +27,25 @@ func TestChannelOutAddBlock(t *testing.T) {
require.Equal(t, ErrNotDepositTx, err) require.Equal(t, ErrNotDepositTx, err)
}) })
} }
// TestRLPByteLimit ensures that stream encoder is properly limiting the length.
// It will decode the input if `len(input) <= inputLimit`.
func TestRLPByteLimit(t *testing.T) {
// Should succeed if `len(input) == inputLimit`
enc := []byte("\x8bhello world") // RLP encoding of the string "hello world"
in := bytes.NewBuffer(enc)
var out string
stream := rlp.NewStream(in, 12)
err := stream.Decode(&out)
require.Nil(t, err)
require.Equal(t, out, "hello world")
// Should fail if the `inputLimit = len(input) - 1`
enc = []byte("\x8bhello world") // RLP encoding of the string "hello world"
in = bytes.NewBuffer(enc)
var out2 string
stream = rlp.NewStream(in, 11)
err = stream.Decode(&out2)
require.Equal(t, err, rlp.ErrValueTooLarge)
require.Equal(t, out2, "")
}
...@@ -7,13 +7,14 @@ import ( ...@@ -7,13 +7,14 @@ import (
"io" "io"
"time" "time"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/sync"
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"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/log"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/sync"
) )
type NextAttributesProvider interface { type NextAttributesProvider interface {
...@@ -66,6 +67,11 @@ type EngineQueue struct { ...@@ -66,6 +67,11 @@ type EngineQueue struct {
safeHead eth.L2BlockRef safeHead eth.L2BlockRef
unsafeHead eth.L2BlockRef unsafeHead eth.L2BlockRef
// Track when the rollup node changes the forkchoice without engine action,
// e.g. on a reset after a reorg, or after consolidating a block.
// This update may repeat if the engine returns a temporary error.
needForkchoiceUpdate bool
finalizedL1 eth.BlockID finalizedL1 eth.BlockID
safeAttributes []*eth.PayloadAttributes safeAttributes []*eth.PayloadAttributes
...@@ -153,6 +159,9 @@ func (eq *EngineQueue) LastL2Time() uint64 { ...@@ -153,6 +159,9 @@ func (eq *EngineQueue) LastL2Time() uint64 {
} }
func (eq *EngineQueue) Step(ctx context.Context) error { func (eq *EngineQueue) Step(ctx context.Context) error {
if eq.needForkchoiceUpdate {
return eq.tryUpdateEngine(ctx)
}
if len(eq.safeAttributes) > 0 { if len(eq.safeAttributes) > 0 {
return eq.tryNextSafeAttributes(ctx) return eq.tryNextSafeAttributes(ctx)
} }
...@@ -228,6 +237,32 @@ func (eq *EngineQueue) logSyncProgress(reason string) { ...@@ -228,6 +237,32 @@ func (eq *EngineQueue) logSyncProgress(reason string) {
) )
} }
// tryUpdateEngine attempts to update the engine with the current forkchoice state of the rollup node,
// this is a no-op if the nodes already agree on the forkchoice state.
func (eq *EngineQueue) tryUpdateEngine(ctx context.Context) error {
fc := eth.ForkchoiceState{
HeadBlockHash: eq.unsafeHead.Hash,
SafeBlockHash: eq.safeHead.Hash,
FinalizedBlockHash: eq.finalized.Hash,
}
_, err := eq.engine.ForkchoiceUpdate(ctx, &fc, nil)
if err != nil {
var inputErr eth.InputError
if errors.As(err, &inputErr) {
switch inputErr.Code {
case eth.InvalidForkchoiceState:
return NewResetError(fmt.Errorf("forkchoice update was inconsistent with engine, need reset to resolve: %w", inputErr.Unwrap()))
default:
return NewTemporaryError(fmt.Errorf("unexpected error code in forkchoice-updated response: %w", err))
}
} else {
return NewTemporaryError(fmt.Errorf("failed to sync forkchoice with engine: %w", err))
}
}
eq.needForkchoiceUpdate = false
return nil
}
func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error { func (eq *EngineQueue) tryNextUnsafePayload(ctx context.Context) error {
first := eq.unsafePayloads.Peek() first := eq.unsafePayloads.Peek()
...@@ -338,6 +373,7 @@ func (eq *EngineQueue) consolidateNextSafeAttributes(ctx context.Context) error ...@@ -338,6 +373,7 @@ func (eq *EngineQueue) consolidateNextSafeAttributes(ctx context.Context) error
return NewResetError(fmt.Errorf("failed to decode L2 block ref from payload: %w", err)) return NewResetError(fmt.Errorf("failed to decode L2 block ref from payload: %w", err))
} }
eq.safeHead = ref eq.safeHead = ref
eq.needForkchoiceUpdate = true
eq.metrics.RecordL2Ref("l2_safe", ref) eq.metrics.RecordL2Ref("l2_safe", ref)
// unsafe head stays the same, we did not reorg the chain. // unsafe head stays the same, we did not reorg the chain.
eq.safeAttributes = eq.safeAttributes[1:] eq.safeAttributes = eq.safeAttributes[1:]
...@@ -437,6 +473,7 @@ func (eq *EngineQueue) Reset(ctx context.Context, _ eth.L1BlockRef) error { ...@@ -437,6 +473,7 @@ func (eq *EngineQueue) Reset(ctx context.Context, _ eth.L1BlockRef) error {
eq.unsafeHead = unsafe eq.unsafeHead = unsafe
eq.safeHead = safe eq.safeHead = safe
eq.finalized = finalized eq.finalized = finalized
eq.needForkchoiceUpdate = true
eq.finalityData = eq.finalityData[:0] eq.finalityData = eq.finalityData[:0]
// note: we do not clear the unsafe payloadds queue; if the payloads are not applicable anymore the parent hash checks will clear out the old payloads. // note: we do not clear the unsafe payloadds queue; if the payloads are not applicable anymore the parent hash checks will clear out the old payloads.
eq.origin = pipelineOrigin eq.origin = pipelineOrigin
......
package derive
import (
"context"
"io"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum/go-ethereum/log"
)
var _ NextFrameProvider = &FrameQueue{}
type NextDataProvider interface {
NextData(context.Context) ([]byte, error)
Origin() eth.L1BlockRef
}
type FrameQueue struct {
log log.Logger
frames []Frame
prev NextDataProvider
}
func NewFrameQueue(log log.Logger, prev NextDataProvider) *FrameQueue {
return &FrameQueue{
log: log,
prev: prev,
}
}
func (fq *FrameQueue) Origin() eth.L1BlockRef {
return fq.prev.Origin()
}
func (fq *FrameQueue) NextFrame(ctx context.Context) (Frame, error) {
// Find more frames if we need to
if len(fq.frames) == 0 {
if data, err := fq.prev.NextData(ctx); err != nil {
return Frame{}, err
} else {
if new, err := ParseFrames(data); err == nil {
fq.frames = append(fq.frames, new...)
} else {
fq.log.Warn("Failed to parse frames", "origin", fq.prev.Origin(), "err", err)
}
}
}
// If we did not add more frames but still have more data, retry this function.
if len(fq.frames) == 0 {
return Frame{}, NotEnoughData
}
ret := fq.frames[0]
fq.frames = fq.frames[1:]
return ret, nil
}
func (fq *FrameQueue) Reset(ctx context.Context, base eth.L1BlockRef) error {
fq.frames = fq.frames[:0]
return io.EOF
}
...@@ -67,7 +67,8 @@ func NewDerivationPipeline(log log.Logger, cfg *rollup.Config, l1Fetcher L1Fetch ...@@ -67,7 +67,8 @@ func NewDerivationPipeline(log log.Logger, cfg *rollup.Config, l1Fetcher L1Fetch
l1Traversal := NewL1Traversal(log, l1Fetcher) l1Traversal := NewL1Traversal(log, l1Fetcher)
dataSrc := NewDataSourceFactory(log, cfg, l1Fetcher) // auxiliary stage for L1Retrieval dataSrc := NewDataSourceFactory(log, cfg, l1Fetcher) // auxiliary stage for L1Retrieval
l1Src := NewL1Retrieval(log, dataSrc, l1Traversal) l1Src := NewL1Retrieval(log, dataSrc, l1Traversal)
bank := NewChannelBank(log, cfg, l1Src, l1Fetcher) frameQueue := NewFrameQueue(log, l1Src)
bank := NewChannelBank(log, cfg, frameQueue, l1Fetcher)
chInReader := NewChannelInReader(log, bank) chInReader := NewChannelInReader(log, bank)
batchQueue := NewBatchQueue(log, cfg, chInReader) batchQueue := NewBatchQueue(log, cfg, chInReader)
attributesQueue := NewAttributesQueue(log, cfg, l1Fetcher, batchQueue) attributesQueue := NewAttributesQueue(log, cfg, l1Fetcher, batchQueue)
......
...@@ -17,7 +17,6 @@ import ( ...@@ -17,7 +17,6 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient/gethclient" "github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
) )
...@@ -158,7 +157,7 @@ type FinalizedWithdrawalParameters struct { ...@@ -158,7 +157,7 @@ type FinalizedWithdrawalParameters struct {
BlockNumber *big.Int BlockNumber *big.Int
Data []byte Data []byte
OutputRootProof bindings.TypesOutputRootProof OutputRootProof bindings.TypesOutputRootProof
WithdrawalProof []byte // RLP Encoded list of trie nodes to prove L2 storage WithdrawalProof [][]byte // List of trie nodes to prove L2 storage
} }
// FinalizeWithdrawalParameters queries L2 to generate all withdrawal parameters and proof necessary to finalize an withdrawal on L1. // FinalizeWithdrawalParameters queries L2 to generate all withdrawal parameters and proof necessary to finalize an withdrawal on L1.
...@@ -203,11 +202,6 @@ func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txH ...@@ -203,11 +202,6 @@ func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txH
trieNodes[i] = common.FromHex(s) trieNodes[i] = common.FromHex(s)
} }
withdrawalProof, err := rlp.EncodeToBytes(trieNodes)
if err != nil {
return FinalizedWithdrawalParameters{}, err
}
return FinalizedWithdrawalParameters{ return FinalizedWithdrawalParameters{
Nonce: ev.Nonce, Nonce: ev.Nonce,
Sender: ev.Sender, Sender: ev.Sender,
...@@ -222,7 +216,7 @@ func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txH ...@@ -222,7 +216,7 @@ func FinalizeWithdrawalParameters(ctx context.Context, l2client ProofClient, txH
MessagePasserStorageRoot: p.StorageHash, MessagePasserStorageRoot: p.StorageHash,
LatestBlockhash: header.Hash(), LatestBlockhash: header.Hash(),
}, },
WithdrawalProof: withdrawalProof, WithdrawalProof: trieNodes,
}, nil }, nil
} }
......
...@@ -24,7 +24,7 @@ RUN source $HOME/.profile && \ ...@@ -24,7 +24,7 @@ RUN source $HOME/.profile && \
strip /opt/foundry/target/release/cast && \ strip /opt/foundry/target/release/cast && \
strip /opt/foundry/target/release/anvil strip /opt/foundry/target/release/anvil
FROM ethereum/client-go:alltools-v1.10.21 as geth FROM ethereum/client-go:alltools-v1.10.25 as geth
FROM python:3.8.13-slim-bullseye FROM python:3.8.13-slim-bullseye
......
...@@ -6,7 +6,7 @@ dashboard_list=[ ...@@ -6,7 +6,7 @@ dashboard_list=[
{ {
'name': 'Single Geth', 'name': 'Single Geth',
'filename': 'single_geth.json', 'filename': 'single_geth.json',
'url': 'https://gist.githubusercontent.com/karalabe/1e26f9ea5c842fb118584edadc454e18/raw/6754e6d5c59328e19ad3a8a29a8e7e41fd46e202/geth.json' 'url': 'https://grafana.com/api/dashboards/13877/revisions/1/download'
} }
] ]
dashboard_path="/grafana-dashboards" dashboard_path="/grafana-dashboards"
......
# Actor Tests # Actor Tests
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=actor-tests-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
This README describes how to use the actor testing library to write new tests. If you're just looking for how to run test cases, check out the README [in the root of the repo](../README.md). This README describes how to use the actor testing library to write new tests. If you're just looking for how to run test cases, check out the README [in the root of the repo](../README.md).
## Introduction ## Introduction
...@@ -122,7 +124,7 @@ It's useful to use `expect`/`assert` to make sure that actors are executing prop ...@@ -122,7 +124,7 @@ It's useful to use `expect`/`assert` to make sure that actors are executing prop
### Test Runner ### Test Runner
The test runner is responsible for executing actor tests and managing their lifecycle. It can run in one of two modes: The test runner is responsible for executing actor tests and managing their lifecycle. It can run in one of two modes:
1. Fixed run mode, which will execute the `run` method a fixed number of times. 1. Fixed run mode, which will execute the `run` method a fixed number of times.
2. Timed mode, which will will execute the `run` method as many times as possible until a period of time has elapsed. 2. Timed mode, which will will execute the `run` method as many times as possible until a period of time has elapsed.
...@@ -130,7 +132,7 @@ The test runner is responsible for executing actor tests and managing their life ...@@ -130,7 +132,7 @@ The test runner is responsible for executing actor tests and managing their life
Test lifecycle is as follows: Test lifecycle is as follows:
1. The runner collects all the actors it needs to run. 1. The runner collects all the actors it needs to run.
> Actors automatically register themselves with the default instance of the runner upon being `require()`d. > Actors automatically register themselves with the default instance of the runner upon being `require()`d.
2. The runner executes each actor's `setupActor` method. 2. The runner executes each actor's `setupActor` method.
3. The runner spawns `n` workers. 3. The runner spawns `n` workers.
......
# @eth-optimism/common-ts # @eth-optimism/common-ts
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=common-ts-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
## What is this? ## What is this?
`@eth-optimism/common-ts` contains useful tools for logging, metrics, and other Node stuff. `@eth-optimism/common-ts` contains useful tools for logging, metrics, and other Node stuff.
......
This diff is collapsed.
# Optimism Smart Contracts (Bedrock) # Optimism Smart Contracts (Bedrock)
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=contracts-bedrock-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
This package contains the smart contracts that compose the on-chain component of Optimism's upcoming Bedrock upgrade. This package contains the smart contracts that compose the on-chain component of Optimism's upcoming Bedrock upgrade.
We've tried to maintain 100% backwards compatibility with the existing system while also introducing new useful features. We've tried to maintain 100% backwards compatibility with the existing system while also introducing new useful features.
You can find detailed specifications for the contracts contained within this package [here](../../specs). You can find detailed specifications for the contracts contained within this package [here](../../specs).
......
...@@ -129,7 +129,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -129,7 +129,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
Types.WithdrawalTransaction memory _tx, Types.WithdrawalTransaction memory _tx,
uint256 _l2BlockNumber, uint256 _l2BlockNumber,
Types.OutputRootProof calldata _outputRootProof, Types.OutputRootProof calldata _outputRootProof,
bytes calldata _withdrawalProof bytes[] calldata _withdrawalProof
) external { ) external {
// Prevent nested withdrawals within withdrawals. // Prevent nested withdrawals within withdrawals.
require( require(
...@@ -293,7 +293,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { ...@@ -293,7 +293,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
function _verifyWithdrawalInclusion( function _verifyWithdrawalInclusion(
bytes32 _withdrawalHash, bytes32 _withdrawalHash,
bytes32 _storageRoot, bytes32 _storageRoot,
bytes memory _proof bytes[] memory _proof
) internal pure returns (bool) { ) internal pure returns (bool) {
bytes32 storageKey = keccak256( bytes32 storageKey = keccak256(
abi.encode( abi.encode(
......
...@@ -112,11 +112,19 @@ library Bytes { ...@@ -112,11 +112,19 @@ library Bytes {
* @return Resulting nibble array. * @return Resulting nibble array.
*/ */
function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) { function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {
bytes memory nibbles = new bytes(_bytes.length * 2); uint256 bytesLength = _bytes.length;
for (uint256 i = 0; i < _bytes.length; i++) { bytes memory nibbles = new bytes(bytesLength * 2);
nibbles[i * 2] = _bytes[i] >> 4; bytes1 b;
nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16);
for (uint256 i = 0; i < bytesLength; ) {
b = _bytes[i];
nibbles[i * 2] = b >> 4;
nibbles[i * 2 + 1] = b & 0x0f;
unchecked {
++i;
}
} }
return nibbles; return nibbles;
} }
......
...@@ -89,4 +89,9 @@ library Predeploys { ...@@ -89,4 +89,9 @@ library Predeploys {
* L2ToL1MessagePasser contract instead. * L2ToL1MessagePasser contract instead.
*/ */
address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000; address internal constant LEGACY_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;
/**
* @notice Address of the ProxyAdmin predeploy.
*/
address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018;
} }
...@@ -3,7 +3,6 @@ pragma solidity ^0.8.0; ...@@ -3,7 +3,6 @@ pragma solidity ^0.8.0;
import { Bytes } from "../Bytes.sol"; import { Bytes } from "../Bytes.sol";
import { RLPReader } from "../rlp/RLPReader.sol"; import { RLPReader } from "../rlp/RLPReader.sol";
import { RLPWriter } from "../rlp/RLPWriter.sol";
/** /**
* @title MerkleTrie * @title MerkleTrie
...@@ -58,7 +57,7 @@ library MerkleTrie { ...@@ -58,7 +57,7 @@ library MerkleTrie {
/** /**
* @notice RLP representation of `NULL`. * @notice RLP representation of `NULL`.
*/ */
bytes1 internal constant RLP_NULL = bytes1(0x80); bytes internal constant RLP_NULL = hex"80";
/** /**
* @notice Verifies a proof that a given key/value pair is present in the trie. * @notice Verifies a proof that a given key/value pair is present in the trie.
...@@ -76,7 +75,7 @@ library MerkleTrie { ...@@ -76,7 +75,7 @@ library MerkleTrie {
function verifyInclusionProof( function verifyInclusionProof(
bytes memory _key, bytes memory _key,
bytes memory _value, bytes memory _value,
bytes memory _proof, bytes[] memory _proof,
bytes32 _root bytes32 _root
) internal pure returns (bool) { ) internal pure returns (bool) {
(bool exists, bytes memory value) = get(_key, _proof, _root); (bool exists, bytes memory value) = get(_key, _proof, _root);
...@@ -95,7 +94,7 @@ library MerkleTrie { ...@@ -95,7 +94,7 @@ library MerkleTrie {
*/ */
function get( function get(
bytes memory _key, bytes memory _key,
bytes memory _proof, bytes[] memory _proof,
bytes32 _root bytes32 _root
) internal pure returns (bool, bytes memory) { ) internal pure returns (bool, bytes memory) {
TrieNode[] memory proof = _parseProof(_proof); TrieNode[] memory proof = _parseProof(_proof);
...@@ -105,13 +104,13 @@ library MerkleTrie { ...@@ -105,13 +104,13 @@ library MerkleTrie {
_root _root
); );
bool exists = keyRemainder.length == 0; bool noRemainder = keyRemainder.length == 0;
require(exists || isFinalNode, "MerkleTrie: provided proof is invalid"); require(noRemainder || isFinalNode, "MerkleTrie: provided proof is invalid");
bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes(""); bytes memory value = noRemainder ? _getNodeValue(proof[pathLength - 1]) : bytes("");
return (exists, value); return (value.length > 0, value);
} }
/** /**
...@@ -142,7 +141,7 @@ library MerkleTrie { ...@@ -142,7 +141,7 @@ library MerkleTrie {
uint256 pathLength = 0; uint256 pathLength = 0;
bytes memory key = Bytes.toNibbles(_key); bytes memory key = Bytes.toNibbles(_key);
bytes32 currentNodeID = _root; bytes memory currentNodeID = abi.encodePacked(_root);
uint256 currentKeyIndex = 0; uint256 currentKeyIndex = 0;
uint256 currentKeyIncrement = 0; uint256 currentKeyIncrement = 0;
TrieNode memory currentNode; TrieNode memory currentNode;
...@@ -159,19 +158,19 @@ library MerkleTrie { ...@@ -159,19 +158,19 @@ library MerkleTrie {
if (currentKeyIndex == 0) { if (currentKeyIndex == 0) {
// First proof element is always the root node. // First proof element is always the root node.
require( require(
keccak256(currentNode.encoded) == currentNodeID, Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),
"MerkleTrie: invalid root hash" "MerkleTrie: invalid root hash"
); );
} else if (currentNode.encoded.length >= 32) { } else if (currentNode.encoded.length >= 32) {
// Nodes 32 bytes or larger are hashed inside branch nodes. // Nodes 32 bytes or larger are hashed inside branch nodes.
require( require(
keccak256(currentNode.encoded) == currentNodeID, Bytes.equal(abi.encodePacked(keccak256(currentNode.encoded)), currentNodeID),
"MerkleTrie: invalid large internal hash" "MerkleTrie: invalid large internal hash"
); );
} else { } else {
// Nodes smaller than 31 bytes aren't hashed. // Nodes smaller than 32 bytes aren't hashed.
require( require(
bytes32(currentNode.encoded) == currentNodeID, Bytes.equal(currentNode.encoded, currentNodeID),
"MerkleTrie: invalid internal node hash" "MerkleTrie: invalid internal node hash"
); );
} }
...@@ -198,6 +197,11 @@ library MerkleTrie { ...@@ -198,6 +197,11 @@ library MerkleTrie {
bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex); bytes memory keyRemainder = Bytes.slice(key, currentKeyIndex);
uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder); uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);
require(
keyRemainder.length >= pathRemainder.length,
"MerkleTrie: invalid key length for leaf or extension node"
);
if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) { if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {
if ( if (
pathRemainder.length == sharedNibbleLength && pathRemainder.length == sharedNibbleLength &&
...@@ -209,14 +213,14 @@ library MerkleTrie { ...@@ -209,14 +213,14 @@ library MerkleTrie {
} }
// We've hit a leaf node, so our next node should be NULL. // We've hit a leaf node, so our next node should be NULL.
currentNodeID = bytes32(RLP_NULL); currentNodeID = RLP_NULL;
break; break;
} else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) { } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {
if (sharedNibbleLength != pathRemainder.length) { if (sharedNibbleLength != pathRemainder.length) {
// Our extension node is not identical to the remainder. // Our extension node is not identical to the remainder.
// We've hit the end of this path // We've hit the end of this path
// updates will need to modify this extension. // updates will need to modify this extension.
currentNodeID = bytes32(RLP_NULL); currentNodeID = RLP_NULL;
break; break;
} else { } else {
// Our extension shares some nibbles. // Our extension shares some nibbles.
...@@ -233,27 +237,30 @@ library MerkleTrie { ...@@ -233,27 +237,30 @@ library MerkleTrie {
} }
} }
// If our node ID is NULL, then we're at a dead end. return (
bool isFinalNode = currentNodeID == bytes32(RLP_NULL); pathLength,
return (pathLength, Bytes.slice(key, currentKeyIndex), isFinalNode); Bytes.slice(key, currentKeyIndex),
Bytes.equal(currentNodeID, RLP_NULL)
);
} }
/** /**
* @notice Parses an RLP-encoded proof into something more useful. * @notice Parses an array of proof elements into a new array that contains both the original
* encoded element and the RLP-decoded element.
* *
* @param _proof RLP-encoded proof to parse. * @param _proof Array of proof elements to parse.
* *
* @return Proof parsed into easily accessible structs. * @return Proof parsed into easily accessible structs.
*/ */
function _parseProof(bytes memory _proof) private pure returns (TrieNode[] memory) { function _parseProof(bytes[] memory _proof) private pure returns (TrieNode[] memory) {
RLPReader.RLPItem[] memory nodes = RLPReader.readList(_proof); uint256 length = _proof.length;
TrieNode[] memory proof = new TrieNode[](nodes.length); TrieNode[] memory proof = new TrieNode[](length);
for (uint256 i = 0; i < length; ) {
for (uint256 i = 0; i < nodes.length; i++) { proof[i] = TrieNode({ encoded: _proof[i], decoded: RLPReader.readList(_proof[i]) });
bytes memory encoded = RLPReader.readBytes(nodes[i]); unchecked {
proof[i] = TrieNode({ encoded: encoded, decoded: RLPReader.readList(encoded) }); ++i;
}
} }
return proof; return proof;
} }
...@@ -265,18 +272,8 @@ library MerkleTrie { ...@@ -265,18 +272,8 @@ library MerkleTrie {
* *
* @return ID for the node, depending on the size of its contents. * @return ID for the node, depending on the size of its contents.
*/ */
function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes32) { function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes memory) {
bytes memory nodeID; return _node.length < 32 ? RLPReader.readRawBytes(_node) : RLPReader.readBytes(_node);
if (_node.length < 32) {
// Nodes smaller than 32 bytes are RLP encoded.
nodeID = RLPReader.readRawBytes(_node);
} else {
// Nodes 32 bytes or larger are hashed.
nodeID = RLPReader.readBytes(_node);
}
return bytes32(nodeID);
} }
/** /**
...@@ -291,7 +288,7 @@ library MerkleTrie { ...@@ -291,7 +288,7 @@ library MerkleTrie {
} }
/** /**
* @notice Gets the path for a node. * @notice Gets the value for a node.
* *
* @param _node Node to get a value for. * @param _node Node to get a value for.
* *
...@@ -314,10 +311,13 @@ library MerkleTrie { ...@@ -314,10 +311,13 @@ library MerkleTrie {
pure pure
returns (uint256) returns (uint256)
{ {
uint256 i = 0; uint256 shared;
while (_a.length > i && _b.length > i && _a[i] == _b[i]) { uint256 max = (_a.length < _b.length) ? _a.length : _b.length;
i++; for (; shared < max && _a[shared] == _b[shared]; ) {
unchecked {
++shared;
}
} }
return i; return shared;
} }
} }
...@@ -26,7 +26,7 @@ library SecureMerkleTrie { ...@@ -26,7 +26,7 @@ library SecureMerkleTrie {
function verifyInclusionProof( function verifyInclusionProof(
bytes memory _key, bytes memory _key,
bytes memory _value, bytes memory _value,
bytes memory _proof, bytes[] memory _proof,
bytes32 _root bytes32 _root
) internal pure returns (bool) { ) internal pure returns (bool) {
bytes memory key = _getSecureKey(_key); bytes memory key = _getSecureKey(_key);
...@@ -45,7 +45,7 @@ library SecureMerkleTrie { ...@@ -45,7 +45,7 @@ library SecureMerkleTrie {
*/ */
function get( function get(
bytes memory _key, bytes memory _key,
bytes memory _proof, bytes[] memory _proof,
bytes32 _root bytes32 _root
) internal pure returns (bool, bytes memory) { ) internal pure returns (bool, bytes memory) {
bytes memory key = _getSecureKey(_key); bytes memory key = _getSecureKey(_key);
......
...@@ -463,7 +463,7 @@ contract FFIInterface is Test { ...@@ -463,7 +463,7 @@ contract FFIInterface is Test {
bytes32, bytes32,
bytes32, bytes32,
bytes32, bytes32,
bytes memory bytes[] memory
) )
{ {
string[] memory cmds = new string[](9); string[] memory cmds = new string[](9);
...@@ -483,8 +483,8 @@ contract FFIInterface is Test { ...@@ -483,8 +483,8 @@ contract FFIInterface is Test {
bytes32 storageRoot, bytes32 storageRoot,
bytes32 outputRoot, bytes32 outputRoot,
bytes32 withdrawalHash, bytes32 withdrawalHash,
bytes memory withdrawalProof bytes[] memory withdrawalProof
) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes)); ) = abi.decode(result, (bytes32, bytes32, bytes32, bytes32, bytes[]));
return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof); return (stateRoot, storageRoot, outputRoot, withdrawalHash, withdrawalProof);
} }
......
...@@ -8,12 +8,12 @@ import { Messenger_Initializer, Reverter, CallerCaller } from "./CommonTest.t.so ...@@ -8,12 +8,12 @@ import { Messenger_Initializer, Reverter, CallerCaller } from "./CommonTest.t.so
contract CrossDomainMessenger_Test is Messenger_Initializer { contract CrossDomainMessenger_Test is Messenger_Initializer {
// Ensure that baseGas passes for the max value of _minGasLimit, // Ensure that baseGas passes for the max value of _minGasLimit,
// this is about 4 Billion. // this is about 4 Billion.
function test_baseGas() external { function test_baseGas() external view {
L1Messenger.baseGas(hex"ff", type(uint32).max); L1Messenger.baseGas(hex"ff", type(uint32).max);
} }
// Fuzz for other values which might cause a revert in baseGas. // Fuzz for other values which might cause a revert in baseGas.
function testFuzz_baseGas(uint32 _minGasLimit) external { function testFuzz_baseGas(uint32 _minGasLimit) external view {
L1Messenger.baseGas(hex"ff", _minGasLimit); L1Messenger.baseGas(hex"ff", _minGasLimit);
} }
} }
...@@ -269,7 +269,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -269,7 +269,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
bytes32 _storageRoot; bytes32 _storageRoot;
bytes32 _outputRoot; bytes32 _outputRoot;
bytes32 _withdrawalHash; bytes32 _withdrawalHash;
bytes _withdrawalProof; bytes[] _withdrawalProof;
Types.OutputRootProof internal _outputRootProof; Types.OutputRootProof internal _outputRootProof;
event WithdrawalFinalized(bytes32 indexed, bool success); event WithdrawalFinalized(bytes32 indexed, bool success);
...@@ -422,7 +422,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -422,7 +422,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
gasLimit: gasLimit, gasLimit: gasLimit,
data: hex"" data: hex""
}); });
(bytes32 stateRoot, bytes32 storageRoot, , , bytes memory withdrawalProof) = ffi (bytes32 stateRoot, bytes32 storageRoot, , , bytes[] memory withdrawalProof) = ffi
.getFinalizeWithdrawalTransactionInputs(insufficientGasTx); .getFinalizeWithdrawalTransactionInputs(insufficientGasTx);
Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({
version: bytes32(0), version: bytes32(0),
...@@ -463,7 +463,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -463,7 +463,8 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function callPortalAndExpectRevert() external payable { function callPortalAndExpectRevert() external payable {
vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction"); vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction");
// Arguments here don't matter, as the require check is the first thing that happens. // Arguments here don't matter, as the require check is the first thing that happens.
op.finalizeWithdrawalTransaction(_defaultTx, 0, _outputRootProof, hex""); bytes[] memory proof = new bytes[](1);
op.finalizeWithdrawalTransaction(_defaultTx, 0, _outputRootProof, proof);
// Assert that the withdrawal was not finalized. // Assert that the withdrawal was not finalized.
assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx))); assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));
} }
...@@ -484,7 +485,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -484,7 +485,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
bytes32 storageRoot, bytes32 storageRoot,
bytes32 outputRoot, bytes32 outputRoot,
bytes32 withdrawalHash, bytes32 withdrawalHash,
bytes memory withdrawalProof bytes[] memory withdrawalProof
) = ffi.getFinalizeWithdrawalTransactionInputs(_testTx); ) = ffi.getFinalizeWithdrawalTransactionInputs(_testTx);
Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({ Types.OutputRootProof memory outputRootProof = Types.OutputRootProof({
version: bytes32(0), version: bytes32(0),
...@@ -544,7 +545,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -544,7 +545,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
bytes32 storageRoot, bytes32 storageRoot,
bytes32 outputRoot, bytes32 outputRoot,
bytes32 withdrawalHash, bytes32 withdrawalHash,
bytes memory withdrawalProof bytes[] memory withdrawalProof
) = ffi.getFinalizeWithdrawalTransactionInputs(_tx); ) = ffi.getFinalizeWithdrawalTransactionInputs(_tx);
Types.OutputRootProof memory proof = Types.OutputRootProof({ Types.OutputRootProof memory proof = Types.OutputRootProof({
......
...@@ -309,6 +309,10 @@ const config: HardhatUserConfig = { ...@@ -309,6 +309,10 @@ const config: HardhatUserConfig = {
type: 'address', type: 'address',
default: ethers.constants.AddressZero, default: ethers.constants.AddressZero,
}, },
proxyAdminOwner: {
type: 'address',
default: ethers.constants.AddressZero,
},
gasPriceOracleOwner: { gasPriceOracleOwner: {
type: 'address', type: 'address',
default: ethers.constants.AddressZero, default: ethers.constants.AddressZero,
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
"scripts": { "scripts": {
"build:forge": "forge build", "build:forge": "forge build",
"build:differential": "tsc scripts/differential-testing.ts --outDir dist --moduleResolution node --esModuleInterop", "build:differential": "tsc scripts/differential-testing.ts --outDir dist --moduleResolution node --esModuleInterop",
"prebuild": "yarn ts-node scripts/verifyFoundryInstall.ts", "prebuild": "yarn ts-node scripts/verify-foundry-install.ts",
"build": "hardhat compile && yarn autogen:artifacts && yarn build:ts && yarn typechain", "build": "hardhat compile && yarn autogen:artifacts && yarn build:ts && yarn typechain",
"build:ts": "tsc -p tsconfig.json", "build:ts": "tsc -p tsconfig.json",
"autogen:artifacts": "ts-node scripts/generate-artifacts.ts", "autogen:artifacts": "ts-node scripts/generate-artifacts.ts",
......
...@@ -13,7 +13,7 @@ import { Account, Address, toBuffer, bufferToHex } from '@ethereumjs/util' ...@@ -13,7 +13,7 @@ import { Account, Address, toBuffer, bufferToHex } from '@ethereumjs/util'
import { predeploys } from '../src' import { predeploys } from '../src'
const { hexZeroPad, RLP, keccak256 } = utils const { hexZeroPad, keccak256 } = utils
const args = process.argv.slice(2) const args = process.argv.slice(2)
const command = args[0] const command = args[0]
...@@ -215,11 +215,9 @@ const command = args[0] ...@@ -215,11 +215,9 @@ const command = args[0]
latestBlockhash: constants.HashZero, latestBlockhash: constants.HashZero,
}) })
const encodedProof = RLP.encode(proof)
const output = utils.defaultAbiCoder.encode( const output = utils.defaultAbiCoder.encode(
['bytes32', 'bytes32', 'bytes32', 'bytes32', 'bytes'], ['bytes32', 'bytes32', 'bytes32', 'bytes32', 'bytes[]'],
[world.root, storage.root, outputRoot, withdrawalHash, encodedProof] [world.root, storage.root, outputRoot, withdrawalHash, proof]
) )
process.stdout.write(output) process.stdout.write(output)
break break
......
...@@ -22,4 +22,9 @@ export const predeploys = { ...@@ -22,4 +22,9 @@ export const predeploys = {
LegacyMessagePasser: '0x4200000000000000000000000000000000000000', LegacyMessagePasser: '0x4200000000000000000000000000000000000000',
L2ERC721Bridge: '0x4200000000000000000000000000000000000014', L2ERC721Bridge: '0x4200000000000000000000000000000000000014',
OptimismMintableERC721Factory: '0x4200000000000000000000000000000000000017', OptimismMintableERC721Factory: '0x4200000000000000000000000000000000000017',
ProxyAdmin: '0x4200000000000000000000000000000000000018',
}
export const futurePredeploys = {
System1: '0x4200000000000000000000000000000000000014',
} }
...@@ -8,7 +8,7 @@ task('rekey', 'Generates a new set of keys for a test network').setAction( ...@@ -8,7 +8,7 @@ task('rekey', 'Generates a new set of keys for a test network').setAction(
const pathPrefix = "m/44'/60'/0'/0" const pathPrefix = "m/44'/60'/0'/0"
const labels = [ const labels = [
'l2OutputOracleProposer', 'l2OutputOracleProposer',
'proxyAdmin', 'proxyAdminOwner',
'optimismBaseFeeRecipient', 'optimismBaseFeeRecipient',
'optimismL1FeeRecipient', 'optimismL1FeeRecipient',
'optimismL2FeeRecipient', 'optimismL2FeeRecipient',
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<h1> Optimism Governance Contracts</h1> <h1> Optimism Governance Contracts</h1>
</div> </div>
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=contracts-governance-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
## TL;DR ## TL;DR
The token and governance smart contracts for the Optimism DAO. Built using [OpenZeppelin libraries](https://docs.openzeppelin.com/contracts/4.x/) with some customisations. The token is an [ERC20](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20) that is [permissible](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Permit) and allows for [delegate voting](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Votes). The token is also [burnable](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Burnable). See more in the [Specification section](#specification). The token and governance smart contracts for the Optimism DAO. Built using [OpenZeppelin libraries](https://docs.openzeppelin.com/contracts/4.x/) with some customisations. The token is an [ERC20](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20) that is [permissible](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Permit) and allows for [delegate voting](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Votes). The token is also [burnable](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Burnable). See more in the [Specification section](#specification).
...@@ -106,4 +108,4 @@ The contract is also upgradable to allow changes in the inflation schedule. ...@@ -106,4 +108,4 @@ The contract is also upgradable to allow changes in the inflation schedule.
### Governance (DAO) Contracts ### Governance (DAO) Contracts
(WIP) (WIP)
\ No newline at end of file
# Optimism Peripheral Smart Contracts # Optimism Peripheral Smart Contracts
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=contracts-periphery-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=contracts)](https://codecov.io/gh/ethereum-optimism/optimism)
# Optimism Smart Contracts # Optimism Smart Contracts
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=contracts-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
`@eth-optimism/contracts` contains the various Solidity smart contracts used within the Optimism system. `@eth-optimism/contracts` contains the various Solidity smart contracts used within the Optimism system.
Some of these contracts are [meant to be deployed to Ethereum ("Layer 1")](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/contracts/L1), while others are [meant to be deployed to Optimism ("Layer 2")](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/contracts/L2). Some of these contracts are [meant to be deployed to Ethereum ("Layer 1")](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/contracts/L1), while others are [meant to be deployed to Optimism ("Layer 2")](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/contracts/L2).
Within each contract file you'll find the network upon which the contract is meant to be deloyed, listed as either `EVM` (for Ethereum) or `OVM` (for Optimism). Within each contract file you'll find the network upon which the contract is meant to be deloyed, listed as either `EVM` (for Ethereum) or `OVM` (for Optimism).
......
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=core-utils)](https://codecov.io/gh/ethereum-optimism/optimism)
# @eth-optimism/core-utils # @eth-optimism/core-utils
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=core-utils-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
## What is this? ## What is this?
`@eth-optimism/core-utils` contains the Optimistic Virtual Machine core utilities. `@eth-optimism/core-utils` contains the Optimistic Virtual Machine core utilities.
......
...@@ -34,7 +34,7 @@ export interface OutputRootProof { ...@@ -34,7 +34,7 @@ export interface OutputRootProof {
*/ */
export interface BedrockCrossChainMessageProof { export interface BedrockCrossChainMessageProof {
outputRootProof: OutputRootProof outputRootProof: OutputRootProof
withdrawalProof: string withdrawalProof: string[]
} }
/** /**
......
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=data-transport-layer)](https://codecov.io/gh/ethereum-optimism/optimism)
# @eth-optimism/data-transport-layer # @eth-optimism/data-transport-layer
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=dtl-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
## What is this? ## What is this?
The Optimism Data Transport Layer is a long-running software service (written in TypeScript) designed to reliably index Optimism transaction data from Layer 1 (Ethereum). Specifically, this service indexes: The Optimism Data Transport Layer is a long-running software service (written in TypeScript) designed to reliably index Optimism transaction data from Layer 1 (Ethereum). Specifically, this service indexes:
......
# @eth-optimism/drippie-mon # @eth-optimism/drippie-mon
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=drippie-mon-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
`drippie-mon` is a simple service for monitoring Drippie contracts. `drippie-mon` is a simple service for monitoring Drippie contracts.
## Installation ## Installation
......
# @eth-optimism/fault-detector # @eth-optimism/fault-detector
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=fault-detector-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
The `fault-detector` is a simple service for detecting discrepancies between your local view of the Optimism network and the L2 output proposals published to Ethereum. The `fault-detector` is a simple service for detecting discrepancies between your local view of the Optimism network and the L2 output proposals published to Ethereum.
## Installation ## Installation
......
# @eth-optimism/message-relayer # @eth-optimism/message-relayer
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=message-relayer-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
`message-relayer` is a service that automatically finalizes ("relays") messages sent from Optimism to Ethereum. `message-relayer` is a service that automatically finalizes ("relays") messages sent from Optimism to Ethereum.
This package is meant to be used during local development and should NOT be used on a production network. This package is meant to be used during local development and should NOT be used on a production network.
......
/data/evm-messages.json /data/evm-messages.json
/data/slots.json /data/slots.json
/data/evm-addresses.json
...@@ -14,6 +14,33 @@ program ...@@ -14,6 +14,33 @@ program
.description('CLI for querying Bedrock migration data') .description('CLI for querying Bedrock migration data')
.version(version) .version(version)
program
.command('parse-state-dump')
.description('parses state dump to json')
.option('--file <file>', 'path to state dump file')
.action(async (options) => {
const iface = getContractInterface('OVM_L2ToL1MessagePasser')
const dump = fs.readFileSync(options.file, 'utf-8')
const addrs: string[] = []
const msgs: any[] = []
for (const line of dump.split('\n')) {
if (line.startsWith('ETH')) {
addrs.push(line.split('|')[1].replace('\r', ''))
} else if (line.startsWith('MSG')) {
const msg = '0x' + line.split('|')[2].replace('\r', '')
const parsed = iface.decodeFunctionData('passMessageToL1', msg)
msgs.push({
who: line.split('|')[1],
msg: parsed._message,
})
}
}
fs.writeFileSync('./data/evm-addresses.json', JSON.stringify(addrs, null, 2))
fs.writeFileSync('./data/evm-messages.json', JSON.stringify(msgs, null, 2))
})
program program
.command('evm-sent-messages') .command('evm-sent-messages')
.description('queries messages sent after the EVM upgrade') .description('queries messages sent after the EVM upgrade')
......
# @eth-optimism/replica-healthcheck # @eth-optimism/replica-healthcheck
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=replica-healthcheck-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
## What is this? ## What is this?
`replica-healthcheck` is an express server to be run alongside a replica instance, to ensure that the replica is healthy. Currently, it exposes metrics on syncing stats and exits when the replica has a mismatched state root against the sequencer. `replica-healthcheck` is an express server to be run alongside a replica instance, to ensure that the replica is healthy. Currently, it exposes metrics on syncing stats and exits when the replica has a mismatched state root against the sequencer.
......
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=sdk)](https://codecov.io/gh/ethereum-optimism/optimism)
# @eth-optimism/sdk # @eth-optimism/sdk
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=sdk-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
The `@eth-optimism/sdk` package provides a set of tools for interacting with Optimism. The `@eth-optimism/sdk` package provides a set of tools for interacting with Optimism.
## Installation ## Installation
......
...@@ -1296,7 +1296,7 @@ export class CrossChainMessenger { ...@@ -1296,7 +1296,7 @@ export class CrossChainMessenger {
messagePasserStorageRoot: stateTrieProof.storageRoot, messagePasserStorageRoot: stateTrieProof.storageRoot,
latestBlockhash: block.hash, latestBlockhash: block.hash,
}, },
withdrawalProof: ethers.utils.RLP.encode(stateTrieProof.storageProof), withdrawalProof: stateTrieProof.storageProof,
}, },
output, output,
// TODO(tynes): use better type, typechain? // TODO(tynes): use better type, typechain?
......
...@@ -363,11 +363,10 @@ where: ...@@ -363,11 +363,10 @@ where:
When decompressing a channel, we limit the amount of decompressed data to `MAX_RLP_BYTES_PER_CHANNEL` (currently When decompressing a channel, we limit the amount of decompressed data to `MAX_RLP_BYTES_PER_CHANNEL` (currently
10,000,000 bytes), in order to avoid "zip-bomb" types of attack (where a small compressed input decompresses to a 10,000,000 bytes), in order to avoid "zip-bomb" types of attack (where a small compressed input decompresses to a
humongous amount of data). If the decompressed data exceeds the limit, things proceeds as thought the channel contained humongous amount of data). If the decompressed data exceeds the limit, things proceeds as though the channel contained
only the first `MAX_RLP_BYTES_PER_CHANNEL` decompressed bytes. only the first `MAX_RLP_BYTES_PER_CHANNEL` decompressed bytes. The limit is set on RLP decoding, so all batches that
can be decoded in `MAX_RLP_BYTES_PER_CHANNEL` will be accepted ven if the size of the channel is greater than
When decoding batches, all batches that can be completly decoded below `MAX_RLP_BYTES_PER_CHANNEL` will be accepted `MAX_RLP_BYTES_PER_CHANNEL`. The exact requirement is that `length(input) <= MAX_RLP_BYTES_PER_CHANNEL`.
even if the size of the channel is greater than `MAX_RLP_BYTES_PER_CHANNEL`.
While the above pseudocode implies that all batches are known in advance, it is possible to perform streaming While the above pseudocode implies that all batches are known in advance, it is possible to perform streaming
compression and decompression of RLP-encoded batches. This means it is possible to start including channel frames in a compression and decompression of RLP-encoded batches. This means it is possible to start including channel frames in a
...@@ -521,6 +520,14 @@ As currently implemented, each step in this stage performs the following actions ...@@ -521,6 +520,14 @@ As currently implemented, each step in this stage performs the following actions
frame are discarded. frame are discarded.
- Concatenate the data of the *contiguous frame sequence* (in sequential order) and push it to the next stage. - Concatenate the data of the *contiguous frame sequence* (in sequential order) and push it to the next stage.
The ordering of these actions is very important to be consistent across nodes & pipeline resets. The rollup node
must attempt to do the following in order to maintain a consistent channel bank even in the presence of pruning.
1. Attempt to read as many channels as possible from the channel bank.
2. Load in a single frame
3. Check if channel bank needs to be pruned & do so if needed.
4. Go to step 1 once the channel bank is under it's size limit.
> **TODO** Instead of waiting on the first seen channel (which might not contain the oldest batches, meaning buffering > **TODO** Instead of waiting on the first seen channel (which might not contain the oldest batches, meaning buffering
> further down the pipeline), we could process any channel in the queue that is ready. We could do this by checking for > further down the pipeline), we could process any channel in the queue that is ready. We could do this by checking for
> channel readiness upon writing into the bank, and moving ready channel to the front of the queue. > channel readiness upon writing into the bank, and moving ready channel to the front of the queue.
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
**Table of Contents** **Table of Contents**
- [Overview](#overview) - [Overview](#overview)
- [OVM\_L2ToL1MessagePasser](#ovm%5C_l2tol1messagepasser) - [L2ToL1MessagePasser](#l2tol1messagepasser)
- [OVM\_DeployerWhitelist](#ovm%5C_deployerwhitelist) - [DeployerWhitelist](#deployerwhitelist)
- [OVM\_ETH](#ovm%5C_eth) - [OVM\_ETH](#ovm%5C_eth)
- [WETH9](#weth9) - [WETH9](#weth9)
- [L2CrossDomainMessenger](#l2crossdomainmessenger) - [L2CrossDomainMessenger](#l2crossdomainmessenger)
...@@ -14,8 +14,9 @@ ...@@ -14,8 +14,9 @@
- [SequencerFeeVault](#sequencerfeevault) - [SequencerFeeVault](#sequencerfeevault)
- [OptimismMintableERC20Factory](#optimismmintableerc20factory) - [OptimismMintableERC20Factory](#optimismmintableerc20factory)
- [L1BlockNumber](#l1blocknumber) - [L1BlockNumber](#l1blocknumber)
- [OVM\_GasPriceOracle](#ovm%5C_gaspriceoracle) - [GasPriceOracle](#gaspriceoracle)
- [L1Block](#l1block) - [L1Block](#l1block)
- [ProxyAdmin](#proxyadmin)
<!-- END doctoc generated TOC please keep comment here to allow auto update --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->
...@@ -52,8 +53,9 @@ or `Bedrock`. Deprecated contracts should not be used. ...@@ -52,8 +53,9 @@ or `Bedrock`. Deprecated contracts should not be used.
| L2ToL1MessagePasser | 0x4200000000000000000000000000000000000016 | Bedrock | No | | L2ToL1MessagePasser | 0x4200000000000000000000000000000000000016 | Bedrock | No |
| L2ERC721Bridge | 0x4200000000000000000000000000000000000014 | Legacy | No | | L2ERC721Bridge | 0x4200000000000000000000000000000000000014 | Legacy | No |
| OptimismMintableERC721Factory | 0x4200000000000000000000000000000000000017 | Bedrock | No | | OptimismMintableERC721Factory | 0x4200000000000000000000000000000000000017 | Bedrock | No |
| ProxyAdmin | 0x4200000000000000000000000000000000000018 | Bedrock | No |
## OVM\_L2ToL1MessagePasser ## L2ToL1MessagePasser
The `OVM_L2ToL1MessagePasser` stores commitments to withdrawal transactions. The `OVM_L2ToL1MessagePasser` stores commitments to withdrawal transactions.
When a user is submitting the withdrawing transaction on L1, they provide a When a user is submitting the withdrawing transaction on L1, they provide a
...@@ -73,9 +75,9 @@ interface iLegacyOVM_L2ToL1MessagePasser { ...@@ -73,9 +75,9 @@ interface iLegacyOVM_L2ToL1MessagePasser {
} }
``` ```
## OVM\_DeployerWhitelist ## DeployerWhitelist
The `OVM_DeployerWhitelist` is a predeploy used to provide additional The `DeployerWhitelist` is a predeploy used to provide additional
safety during the initial phases of Optimism. It is owned by the safety during the initial phases of Optimism. It is owned by the
Optimism team, and defines accounts which are allowed to deploy contracts to the Optimism team, and defines accounts which are allowed to deploy contracts to the
network. network.
...@@ -90,7 +92,7 @@ In the Bedrock system, this contract will no longer be used as part of the ...@@ -90,7 +92,7 @@ In the Bedrock system, this contract will no longer be used as part of the
This contract is deprecated and its usage should be avoided. This contract is deprecated and its usage should be avoided.
```solidity ```solidity
interface iOVM_DeployerWhitelist { interface iDeployerWhitelist {
event OwnerChanged(address,address); event OwnerChanged(address,address);
event WhitelistStatusChanged(address,bool); event WhitelistStatusChanged(address,bool);
event WhitelistDisabled(address); event WhitelistDisabled(address);
...@@ -249,9 +251,9 @@ interface iOVM_L1BlockNumber { ...@@ -249,9 +251,9 @@ interface iOVM_L1BlockNumber {
} }
``` ```
## OVM\_GasPriceOracle ## GasPriceOracle
The `OVM_GasPriceOracle` is pushed the L1 basefee and the L2 gas price by The `GasPriceOracle` is pushed the L1 basefee and the L2 gas price by
an offchain actor. The offchain actor observes the L1 blockheaders to get the an offchain actor. The offchain actor observes the L1 blockheaders to get the
L1 basefee as well as the gas usage on L2 to compute what the L2 gas price L1 basefee as well as the gas usage on L2 to compute what the L2 gas price
should be based on a congestion control algorithm. should be based on a congestion control algorithm.
...@@ -261,7 +263,7 @@ Bedrock, but it is still used to hold the `overhead`, `scalar`, and `decimals` ...@@ -261,7 +263,7 @@ Bedrock, but it is still used to hold the `overhead`, `scalar`, and `decimals`
values which are used to compute the L1 portion of the transaction fee. values which are used to compute the L1 portion of the transaction fee.
```solidity ```solidity
interface OVM_GasPriceOracle { interface GasPriceOracle {
/** /**
* @dev Returns the current gas price on L2 * @dev Returns the current gas price on L2
*/ */
...@@ -370,3 +372,9 @@ interface L1Block { ...@@ -370,3 +372,9 @@ interface L1Block {
) external; ) external;
} }
``` ```
## ProxyAdmin
The `ProxyAdmin` is the owner of all of the proxy contracts set at the
predeploys. It is not behind a proxy itself. The owner of the `ProxyAdmin` will
have the ability to upgrade any of the other predeploy contracts.
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