Commit 3fe1a51f authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge branch 'develop' into fix/remove-legacy-code

parents 2bddcd21 596c974e
---
'@eth-optimism/contracts-bedrock': patch
---
Moves initializers underneath constructors always
---
'@eth-optimism/l2geth': patch
---
Kick the build
...@@ -508,6 +508,11 @@ jobs: ...@@ -508,6 +508,11 @@ jobs:
machine: machine:
image: ubuntu-2004:2022.07.1 image: ubuntu-2004:2022.07.1
docker_layer_caching: true docker_layer_caching: true
parameters:
deploy:
description: Deploy contracts
default: false
type: boolean
environment: environment:
DOCKER_BUILDKIT: 1 DOCKER_BUILDKIT: 1
steps: steps:
...@@ -539,6 +544,32 @@ jobs: ...@@ -539,6 +544,32 @@ jobs:
command: | command: |
yarn install yarn install
yarn build yarn build
- when:
condition:
and:
- equal: [ true, <<parameters.deploy>> ]
steps:
- run:
name: Bring up the stack
command: |
make devnet-up-deploy
- run:
name: Deposit ERC20 through the bridge
command: timeout 5m npx hardhat deposit-erc20 --network devnetL1 --l1-contracts-json-path ../../.devnet/sdk-addresses.json
working_directory: packages/sdk
- run:
name: Deposit ETH through the bridge
command: timeout 5m npx hardhat deposit-eth --network devnetL1 --l1-contracts-json-path ../../.devnet/sdk-addresses.json
working_directory: packages/sdk
- run:
name: Check the status
command: npx hardhat check-op-node
working_directory: packages/contracts-bedrock
- when:
condition:
and:
- equal: [ false, <<parameters.deploy>> ]
steps:
- run: - run:
name: Bring up the stack name: Bring up the stack
command: | command: |
...@@ -773,7 +804,12 @@ workflows: ...@@ -773,7 +804,12 @@ workflows:
- bedrock-go-tests - bedrock-go-tests
- fuzz-op-node - fuzz-op-node
- bedrock-markdown - bedrock-markdown
- devnet - devnet:
name: devnet (with deployed contracts)
deploy: true
- devnet:
name: devnet (with genesis contracts)
deploy: false
- go-lint-test-build: - go-lint-test-build:
name: batch-submitter-tests name: batch-submitter-tests
binary_name: batch-submitter binary_name: batch-submitter
......
...@@ -53,3 +53,6 @@ coverage.out ...@@ -53,3 +53,6 @@ coverage.out
# Ignore bedrock go bindings local output files # Ignore bedrock go bindings local output files
op-bindings/bin op-bindings/bin
op-exporter op-exporter
__pycache__
...@@ -68,6 +68,10 @@ devnet-up: ...@@ -68,6 +68,10 @@ devnet-up:
@bash ./ops-bedrock/devnet-up.sh @bash ./ops-bedrock/devnet-up.sh
.PHONY: devnet-up .PHONY: devnet-up
devnet-up-deploy:
PYTHONPATH=./bedrock-devnet python3 ./bedrock-devnet/main.py --monorepo-dir=.
.PHONY: devnet-up-deploy
devnet-down: devnet-down:
@(cd ./ops-bedrock && GENESIS_TIMESTAMP=$(shell date +%s) docker-compose stop) @(cd ./ops-bedrock && GENESIS_TIMESTAMP=$(shell date +%s) docker-compose stop)
.PHONY: devnet-down .PHONY: devnet-down
......
# bedrock-devnet
This is a utility for running a local Bedrock devnet. It is designed to replace the legacy Bash-based devnet runner as part of a progressive migration away from Bash automation.
The easiest way to invoke this script is to run `make devnet-up-deploy` from the root of this repository. Otherwise, to use this script run `python3 main.py --monorepo-path=<path to the monorepo>`. You may need to set `PYTHONPATH` to this directory if you are invoking the script from somewhere other than `bedrock-devnet`.
\ No newline at end of file
import argparse
import logging
import os
import subprocess
import json
import socket
import time
import shutil
import devnet.log_setup
from devnet.genesis import GENESIS_TMPL
parser = argparse.ArgumentParser(description='Bedrock devnet launcher')
parser.add_argument('--monorepo-dir', help='Directory of the monorepo', default=os.getcwd())
log = logging.getLogger()
def main():
args = parser.parse_args()
pjoin = os.path.join
monorepo_dir = os.path.abspath(args.monorepo_dir)
devnet_dir = pjoin(monorepo_dir, '.devnet')
ops_bedrock_dir = pjoin(monorepo_dir, 'ops-bedrock')
contracts_bedrock_dir = pjoin(monorepo_dir, 'packages', 'contracts-bedrock')
deployment_dir = pjoin(contracts_bedrock_dir, 'deployments', 'devnetL1')
op_node_dir = pjoin(args.monorepo_dir, 'op-node')
genesis_l1_path = pjoin(devnet_dir, 'genesis-l1.json')
genesis_l2_path = pjoin(devnet_dir, 'genesis-l2.json')
addresses_json_path = pjoin(devnet_dir, 'addresses.json')
sdk_addresses_json_path = pjoin(devnet_dir, 'sdk-addresses.json')
rollup_config_path = pjoin(devnet_dir, 'rollup.json')
os.makedirs(devnet_dir, exist_ok=True)
if os.path.exists(genesis_l1_path):
log.info('L2 genesis already generated.')
else:
log.info('Generating L1 genesis.')
write_json(genesis_l1_path, GENESIS_TMPL)
log.info('Starting L1.')
run_command(['docker-compose', 'up', '-d', 'l1'], cwd=ops_bedrock_dir, env={
'PWD': ops_bedrock_dir
})
wait_up(8545)
log.info('Generating network config.')
devnet_cfg_orig = pjoin(contracts_bedrock_dir, 'deploy-config', 'devnetL1.json')
devnet_cfg_backup = pjoin(devnet_dir, 'devnetL1.json.bak')
shutil.copy(devnet_cfg_orig, devnet_cfg_backup)
deploy_config = read_json(devnet_cfg_orig)
deploy_config['l1GenesisBlockTimestamp'] = GENESIS_TMPL['timestamp']
deploy_config['l1StartingBlockTag'] = 'earliest'
write_json(devnet_cfg_orig, deploy_config)
if os.path.exists(addresses_json_path):
log.info('Contracts already deployed.')
addresses = read_json(addresses_json_path)
else:
log.info('Deploying contracts.')
run_command(['yarn', 'hardhat', '--network', 'devnetL1', 'deploy'], env={
'CHAIN_ID': '900',
'L1_RPC': 'http://localhost:8545',
'PRIVATE_KEY_DEPLOYER': 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
}, cwd=contracts_bedrock_dir)
contracts = os.listdir(deployment_dir)
addresses = {}
for c in contracts:
if not c.endswith('.json'):
continue
data = read_json(pjoin(deployment_dir, c))
addresses[c.replace('.json', '')] = data['address']
sdk_addresses = {}
sdk_addresses.update({
'StateCommitmentChain': '0x0000000000000000000000000000000000000000',
'CanonicalTransactionChain': '0x0000000000000000000000000000000000000000',
'BondManager': '0x0000000000000000000000000000000000000000',
})
sdk_addresses['AddressManager'] = addresses['AddressManager']
sdk_addresses['L1CrossDomainMessenger'] = addresses['L1CrossDomainMessengerProxy']
sdk_addresses['L1StandardBridge'] = addresses['L1StandardBridgeProxy']
sdk_addresses['OptimismPortal'] = addresses['OptimismPortalProxy']
sdk_addresses['L2OutputOracle'] = addresses['L2OutputOracleProxy']
write_json(addresses_json_path, addresses)
write_json(sdk_addresses_json_path, sdk_addresses)
if os.path.exists(genesis_l2_path):
log.info('L2 genesis and rollup configs already generated.')
else:
log.info('Generating L2 genesis and rollup configs.')
run_command([
'go', 'run', 'cmd/main.go', 'genesis', 'l2',
'--l1-rpc', 'http://localhost:8545',
'--deploy-config', devnet_cfg_orig,
'--deployment-dir', deployment_dir,
'--outfile.l2', pjoin(devnet_dir, 'genesis-l2.json'),
'--outfile.rollup', pjoin(devnet_dir, 'rollup.json')
], cwd=op_node_dir)
rollup_config = read_json(rollup_config_path)
if os.path.exists(devnet_cfg_backup):
shutil.move(devnet_cfg_backup, devnet_cfg_orig)
log.info('Bringing up L2.')
run_command(['docker-compose', 'up', '-d', 'l2'], cwd=ops_bedrock_dir, env={
'PWD': ops_bedrock_dir
})
wait_up(9545)
log.info('Bringing up everything else.')
run_command(['docker-compose', 'up', '-d', 'op-node', 'op-proposer', 'op-batcher'], cwd=ops_bedrock_dir, env={
'PWD': ops_bedrock_dir,
'L2OO_ADDRESS': addresses['L2OutputOracleProxy'],
'SEQUENCER_GENESIS_HASH': rollup_config['genesis']['l2']['hash'],
'SEQUENCER_BATCH_INBOX_ADDRESS': rollup_config['batch_inbox_address']
})
log.info('Devnet ready.')
def run_command(args, check=True, shell=False, cwd=None, env=None):
env = env if env else {}
return subprocess.run(
args,
check=check,
shell=shell,
env={
**os.environ,
**env
},
cwd=cwd
)
def wait_up(port, retries=10, wait_secs=1):
for i in range(0, retries):
log.info(f'Trying 127.0.0.1:{port}')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('127.0.0.1', int(port)))
s.shutdown(2)
log.info(f'Connected 127.0.0.1:{port}')
return True
except Exception:
time.sleep(wait_secs)
raise Exception(f'Timed out waiting for port {port}.')
def write_json(path, data):
with open(path, 'w+') as f:
json.dump(data, f, indent=' ')
def read_json(path):
with open(path, 'r') as f:
return json.load(f)
import time
DEV_ACCOUNTS = [
'3c44cdddb6a900fa2b585dd299e03d12fa4293bc',
'70997970c51812dc3a010c7d01b50e0d17dc79c8',
'f39fd6e51aad88f6f4ce6ab8827279cfffb92266'
]
GENESIS_TMPL = {
'config': {
'chainId': 900,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"arrowGlacierBlock": 0,
"grayGlacierBlock": 0,
"shanghaiBlock": None,
"cancunBlock": None,
'clique': {
'period': 15,
'epoch': 30000
}
},
'nonce': '0x0',
'timestamp': '{:#x}'.format(int(time.time())),
'extraData': '0x0000000000000000000000000000000000000000000000000000000000000000ca062b0fd91172d89bcd4bb084ac4e21972cc4670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
'gasLimit': '0xE4E1C0',
'difficulty': '0x1',
'mixHash': '0x0000000000000000000000000000000000000000000000000000000000000000',
'coinbase': '0x0000000000000000000000000000000000000000',
'alloc': {
'{:x}'.format(i).ljust(40, '0'): {
'balance': '0x1'
} for i in range(0, 255)
},
'number': '0x0',
'gasUsed': '0x0',
'parentHash': '0x0000000000000000000000000000000000000000000000000000000000000000',
'baseFeePergas': '0x3B9ACA00'
}
GENESIS_TMPL['alloc'].update({
d: {
'balance': '0x200000000000000000000000000000000000000000000000000000000000000'
} for d in DEV_ACCOUNTS
})
import os
from logging.config import dictConfig
log_level = os.getenv('LOG_LEVEL')
log_config = {
'version': 1,
'loggers': {
'': {
'handlers': ['console'],
'level': log_level if log_level is not None else 'INFO'
},
},
'handlers': {
'console': {
'formatter': 'stderr',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout'
}
},
'formatters': {
'stderr': {
'format': '[%(levelname)s|%(asctime)s] %(message)s',
'datefmt': '%m-%d-%Y %I:%M:%S'
}
},
}
dictConfig(log_config)
import devnet
def main():
devnet.main()
if __name__ == '__main__':
main()
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
"@eth-optimism/contracts": "^0.5.37", "@eth-optimism/contracts": "^0.5.37",
"@eth-optimism/contracts-periphery": "^1.0.2", "@eth-optimism/contracts-periphery": "^1.0.2",
"@eth-optimism/core-utils": "0.10.1", "@eth-optimism/core-utils": "0.10.1",
"@eth-optimism/sdk": "1.6.7", "@eth-optimism/sdk": "1.6.8",
"@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/abstract-provider": "^5.7.0",
"@ethersproject/providers": "^5.7.0", "@ethersproject/providers": "^5.7.0",
"@ethersproject/transactions": "^5.7.0", "@ethersproject/transactions": "^5.7.0",
......
# Changelog # Changelog
## 0.5.26
### Patch Changes
- 397b27ee: Add data exporter
## 0.5.25 ## 0.5.25
### Patch Changes ### Patch Changes
......
...@@ -24,6 +24,8 @@ import ( ...@@ -24,6 +24,8 @@ import (
"sort" "sort"
"time" "time"
"github.com/ethereum-optimism/optimism/l2geth/statedumper"
"github.com/ethereum-optimism/optimism/l2geth/common" "github.com/ethereum-optimism/optimism/l2geth/common"
"github.com/ethereum-optimism/optimism/l2geth/core/types" "github.com/ethereum-optimism/optimism/l2geth/core/types"
"github.com/ethereum-optimism/optimism/l2geth/crypto" "github.com/ethereum-optimism/optimism/l2geth/crypto"
...@@ -244,6 +246,7 @@ func (s *StateDB) GetBalance(addr common.Address) *big.Int { ...@@ -244,6 +246,7 @@ func (s *StateDB) GetBalance(addr common.Address) *big.Int {
if rcfg.UsingOVM { if rcfg.UsingOVM {
// Get balance from the OVM_ETH contract. // Get balance from the OVM_ETH contract.
// NOTE: We may remove this feature in a future release. // NOTE: We may remove this feature in a future release.
statedumper.WriteETH(addr)
key := GetOVMBalanceKey(addr) key := GetOVMBalanceKey(addr)
bal := s.GetState(dump.OvmEthAddress, key) bal := s.GetState(dump.OvmEthAddress, key)
return bal.Big() return bal.Big()
...@@ -377,6 +380,7 @@ func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) { ...@@ -377,6 +380,7 @@ func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {
// Note that we don't need to check for overflows or underflows here because the code that // Note that we don't need to check for overflows or underflows here because the code that
// uses this codepath already checks for them. You can follow the original codepath below // uses this codepath already checks for them. You can follow the original codepath below
// (stateObject.AddBalance) to confirm that there are no checks being performed here. // (stateObject.AddBalance) to confirm that there are no checks being performed here.
statedumper.WriteETH(addr)
key := GetOVMBalanceKey(addr) key := GetOVMBalanceKey(addr)
value := s.GetState(dump.OvmEthAddress, key) value := s.GetState(dump.OvmEthAddress, key)
bal := value.Big() bal := value.Big()
...@@ -397,6 +401,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) { ...@@ -397,6 +401,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
// Note that we don't need to check for overflows or underflows here because the code that // Note that we don't need to check for overflows or underflows here because the code that
// uses this codepath already checks for them. You can follow the original codepath below // uses this codepath already checks for them. You can follow the original codepath below
// (stateObject.SubBalance) to confirm that there are no checks being performed here. // (stateObject.SubBalance) to confirm that there are no checks being performed here.
statedumper.WriteETH(addr)
key := GetOVMBalanceKey(addr) key := GetOVMBalanceKey(addr)
value := s.GetState(dump.OvmEthAddress, key) value := s.GetState(dump.OvmEthAddress, key)
bal := value.Big() bal := value.Big()
...@@ -413,6 +418,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) { ...@@ -413,6 +418,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
func (s *StateDB) SetBalance(addr common.Address, amount *big.Int) { func (s *StateDB) SetBalance(addr common.Address, amount *big.Int) {
if rcfg.UsingOVM { if rcfg.UsingOVM {
// Mutate the storage slot inside of OVM_ETH to change balances. // Mutate the storage slot inside of OVM_ETH to change balances.
statedumper.WriteETH(addr)
key := GetOVMBalanceKey(addr) key := GetOVMBalanceKey(addr)
s.SetState(dump.OvmEthAddress, key, common.BigToHash(amount)) s.SetState(dump.OvmEthAddress, key, common.BigToHash(amount))
} else { } else {
......
...@@ -18,6 +18,7 @@ package vm ...@@ -18,6 +18,7 @@ package vm
import ( import (
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/l2geth/statedumper"
"math/big" "math/big"
"sync/atomic" "sync/atomic"
"time" "time"
...@@ -198,6 +199,10 @@ func (evm *EVM) Interpreter() Interpreter { ...@@ -198,6 +199,10 @@ func (evm *EVM) Interpreter() Interpreter {
// the necessary steps to create accounts and reverses the state in case of an // the necessary steps to create accounts and reverses the state in case of an
// execution error or failed value transfer. // execution error or failed value transfer.
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
if addr == dump.MessagePasserAddress {
statedumper.WriteMessage(caller.Address(), input)
}
if evm.vmConfig.NoRecursion && evm.depth > 0 { if evm.vmConfig.NoRecursion && evm.depth > 0 {
return nil, gas, nil return nil, gas, nil
} }
......
{ {
"name": "@eth-optimism/l2geth", "name": "@eth-optimism/l2geth",
"version": "0.5.25", "version": "0.5.26",
"private": true, "private": true,
"devDependencies": {} "devDependencies": {}
} }
...@@ -7,3 +7,4 @@ import ( ...@@ -7,3 +7,4 @@ import (
var OvmEthAddress = common.HexToAddress("0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000") var OvmEthAddress = common.HexToAddress("0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000")
var OvmFeeWallet = common.HexToAddress("0x4200000000000000000000000000000000000011") var OvmFeeWallet = common.HexToAddress("0x4200000000000000000000000000000000000011")
var OvmWhitelistAddress = common.HexToAddress("0x4200000000000000000000000000000000000002") var OvmWhitelistAddress = common.HexToAddress("0x4200000000000000000000000000000000000002")
var MessagePasserAddress = common.HexToAddress("0x4200000000000000000000000000000000000000")
package statedumper
import (
"fmt"
"github.com/ethereum-optimism/optimism/l2geth/common"
"io"
"os"
"sync"
)
type StateDumper interface {
WriteETH(address common.Address)
WriteMessage(sender common.Address, msg []byte)
}
var DefaultStateDumper StateDumper
func NewStateDumper() StateDumper {
path := os.Getenv("L2GETH_STATE_DUMP_PATH")
if path == "" {
return &noopStateDumper{}
}
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE, 0o755)
if err != nil {
panic(err)
}
return &FileStateDumper{
f: f,
}
}
type FileStateDumper struct {
f io.Writer
mtx sync.Mutex
}
func (s *FileStateDumper) WriteETH(address common.Address) {
s.mtx.Lock()
defer s.mtx.Unlock()
if _, err := s.f.Write([]byte(fmt.Sprintf("ETH|%s\n", address.Hex()))); err != nil {
panic(err)
}
}
func (s *FileStateDumper) WriteMessage(sender common.Address, msg []byte) {
s.mtx.Lock()
defer s.mtx.Unlock()
if _, err := s.f.Write([]byte(fmt.Sprintf("MSG|%s|%x\n", sender.Hex(), msg))); err != nil {
panic(err)
}
}
type noopStateDumper struct {
}
func (n *noopStateDumper) WriteETH(address common.Address) {
}
func (n *noopStateDumper) WriteMessage(sender common.Address, msg []byte) {
}
func init() {
DefaultStateDumper = NewStateDumper()
}
func WriteETH(address common.Address) {
DefaultStateDumper.WriteETH(address)
}
func WriteMessage(sender common.Address, msg []byte) {
DefaultStateDumper.WriteMessage(sender, msg)
}
...@@ -313,7 +313,14 @@ mainLoop: ...@@ -313,7 +313,14 @@ mainLoop:
l.ch = ch l.ch = ch
} }
prevID := l.lastSubmittedBlock prevID := l.lastSubmittedBlock
for i := l.lastSubmittedBlock.Number + 1; i <= syncStatus.UnsafeL2.Number; i++ { maxBlocksPerChannel := uint64(100)
// Hacky min() here to ensure that we don't batch submit more than 100 blocks per channel.
// TODO: use proper channel size here instead.
upToBlockNumber := syncStatus.UnsafeL2.Number
if l.lastSubmittedBlock.Number+1+maxBlocksPerChannel < upToBlockNumber {
upToBlockNumber = l.lastSubmittedBlock.Number + 1 + maxBlocksPerChannel
}
for i := l.lastSubmittedBlock.Number + 1; i <= upToBlockNumber; i++ {
ctx, cancel := context.WithTimeout(l.ctx, time.Second*10) ctx, cancel := context.WithTimeout(l.ctx, time.Second*10)
block, err := l.cfg.L2Client.BlockByNumber(ctx, new(big.Int).SetUint64(i)) block, err := l.cfg.L2Client.BlockByNumber(ctx, new(big.Int).SetUint64(i))
cancel() cancel()
......
surgery: surgery:
go build -o ./surgery ./cmd/main.go go build -o ./surgery ./cmd/surgery/main.go
test: test:
go test ./... go test ./...
......
package main
import (
"os"
"strings"
ops "github.com/ethereum-optimism/optimism/op-chain-ops"
"github.com/ethereum/go-ethereum/log"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v2"
)
func main() {
log.Root().SetHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(isatty.IsTerminal(os.Stderr.Fd()))))
app := &cli.App{
Name: "surgery",
Usage: "migrates data from v0 to Bedrock",
Commands: []*cli.Command{
{
Name: "dump-addresses",
Usage: "dumps addresses from OVM ETH",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "out-file",
Aliases: []string{"o"},
Usage: "file to write addresses to",
Required: true,
},
},
Action: dumpAddressesAction,
},
{
Name: "migrate",
Usage: "migrates state in OVM ETH",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "genesis-file",
Aliases: []string{"g"},
Usage: "path to a genesis file",
Required: true,
},
&cli.StringFlag{
Name: "out-dir",
Aliases: []string{"o"},
Usage: "path to output directory",
Required: true,
},
&cli.StringFlag{
Name: "address-lists",
Aliases: []string{"a"},
Usage: "comma-separated list of address files to read",
Required: true,
},
&cli.StringFlag{
Name: "allowance-lists",
Aliases: []string{"l"},
Usage: "comma-separated list of allowance lists to read",
Required: true,
},
&cli.IntFlag{
Name: "chain-id",
Usage: "chain ID",
Value: 1,
Required: false,
},
&cli.IntFlag{
Name: "leveldb-cache-size-mb",
Usage: "leveldb cache size in MB",
Value: 16,
Required: false,
},
&cli.IntFlag{
Name: "leveldb-file-handles",
Usage: "leveldb file handles",
Value: 16,
Required: false,
},
},
Action: migrateAction,
},
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "data-dir",
Aliases: []string{"d"},
Usage: "data directory to read",
Required: true,
},
},
}
if err := app.Run(os.Args); err != nil {
log.Crit("error in migration", "err", err)
}
}
func dumpAddressesAction(cliCtx *cli.Context) error {
dataDir := cliCtx.String("data-dir")
outFile := cliCtx.String("out-file")
return ops.DumpAddresses(dataDir, outFile)
}
func migrateAction(cliCtx *cli.Context) error {
dataDir := cliCtx.String("data-dir")
outDir := cliCtx.String("out-dir")
genesisPath := cliCtx.String("genesis-file")
addressLists := strings.Split(cliCtx.String("address-lists"), ",")
allowanceLists := strings.Split(cliCtx.String("allowance-lists"), ",")
chainID := cliCtx.Int("chain-id")
levelDBCacheSize := cliCtx.Int("leveldb-cache-size-mb")
levelDBHandles := cliCtx.Int("leveldb-file-handles")
genesis, err := ops.ReadGenesisFromFile(genesisPath)
if err != nil {
return err
}
return ops.Migrate(dataDir, outDir, genesis, addressLists, allowanceLists, chainID, levelDBCacheSize, levelDBHandles)
}
package state_surgery package ether
import ( import (
"bufio" "bufio"
......
package state_surgery package ether
import ( import (
"bytes" "bytes"
......
package state_surgery package ether
import ( import (
"path/filepath" "path/filepath"
......
package state_surgery package ether
import ( import (
"encoding/json" "encoding/json"
......
package state_surgery package ether
import ( import (
"math/big" "math/big"
......
package state_surgery package ether
import ( import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
......
package state_surgery package ether
import ( import (
"fmt" "fmt"
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"math/big" "math/big"
"os" "os"
"path/filepath" "path/filepath"
...@@ -125,7 +126,7 @@ var Subcommands = cli.Commands{ ...@@ -125,7 +126,7 @@ var Subcommands = cli.Commands{
l1StartBlock, err = client.BlockByNumber(context.Background(), big.NewInt(config.L1StartingBlockTag.BlockNumber.Int64())) l1StartBlock, err = client.BlockByNumber(context.Background(), big.NewInt(config.L1StartingBlockTag.BlockNumber.Int64()))
} }
if err != nil { if err != nil {
return err return fmt.Errorf("error getting l1 start block: %w", err)
} }
depPath, network := filepath.Split(ctx.String("deployment-dir")) depPath, network := filepath.Split(ctx.String("deployment-dir"))
...@@ -157,7 +158,7 @@ var Subcommands = cli.Commands{ ...@@ -157,7 +158,7 @@ var Subcommands = cli.Commands{
} }
l2Genesis, err := genesis.BuildL2DeveloperGenesis(config, l1StartBlock, l2Addrs) l2Genesis, err := genesis.BuildL2DeveloperGenesis(config, l1StartBlock, l2Addrs)
if err != nil { if err != nil {
return err return fmt.Errorf("error creating l2 developer genesis: %w", err)
} }
rollupConfig := makeRollupConfig(config, l1StartBlock, l2Genesis, portalProxy.Address) rollupConfig := makeRollupConfig(config, l1StartBlock, l2Genesis, portalProxy.Address)
......
# @eth-optimism/actor-tests # @eth-optimism/actor-tests
## 0.0.10
### Patch Changes
- Updated dependencies [7d7d9ba8]
- @eth-optimism/contracts-bedrock@0.8.2
- @eth-optimism/sdk@1.6.8
## 0.0.9 ## 0.0.9
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/actor-tests", "name": "@eth-optimism/actor-tests",
"version": "0.0.9", "version": "0.0.10",
"description": "A library and suite of tests to stress test Optimism Bedrock.", "description": "A library and suite of tests to stress test Optimism Bedrock.",
"license": "MIT", "license": "MIT",
"author": "", "author": "",
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
"test:coverage": "yarn test" "test:coverage": "yarn test"
}, },
"dependencies": { "dependencies": {
"@eth-optimism/contracts-bedrock": "0.8.1", "@eth-optimism/contracts-bedrock": "0.8.2",
"@eth-optimism/core-utils": "^0.10.1", "@eth-optimism/core-utils": "^0.10.1",
"@eth-optimism/sdk": "^1.6.7", "@eth-optimism/sdk": "^1.6.8",
"@types/chai": "^4.2.18", "@types/chai": "^4.2.18",
"@types/chai-as-promised": "^7.1.4", "@types/chai-as-promised": "^7.1.4",
"async-mutex": "^0.3.2", "async-mutex": "^0.3.2",
......
# @eth-optimism/contracts-bedrock # @eth-optimism/contracts-bedrock
## 0.8.2
### Patch Changes
- 7d7d9ba8: Moves initializers underneath constructors always
## 0.8.1 ## 0.8.1
### Patch Changes ### Patch Changes
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
"optimismBaseFeeRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096", "optimismBaseFeeRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"optimismL1FeeRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788", "optimismL1FeeRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"finalizationPeriodSeconds": 2,
"deploymentWaitConfirmations": 1, "deploymentWaitConfirmations": 1,
"fundDevAccounts": true "fundDevAccounts": true
} }
{ {
"name": "@eth-optimism/contracts-bedrock", "name": "@eth-optimism/contracts-bedrock",
"version": "0.8.1", "version": "0.8.2",
"description": "Contracts for Optimism Specs", "description": "Contracts for Optimism Specs",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
......
# @eth-optimism/drippie-mon # @eth-optimism/drippie-mon
## 0.3.19
### Patch Changes
- @eth-optimism/sdk@1.6.8
## 0.3.18 ## 0.3.18
### Patch Changes ### Patch Changes
......
{ {
"private": true, "private": true,
"name": "@eth-optimism/drippie-mon", "name": "@eth-optimism/drippie-mon",
"version": "0.3.18", "version": "0.3.19",
"description": "[Optimism] Service for monitoring Drippie instances", "description": "[Optimism] Service for monitoring Drippie instances",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
"@eth-optimism/common-ts": "0.6.6", "@eth-optimism/common-ts": "0.6.6",
"@eth-optimism/contracts-periphery": "1.0.2", "@eth-optimism/contracts-periphery": "1.0.2",
"@eth-optimism/core-utils": "0.10.1", "@eth-optimism/core-utils": "0.10.1",
"@eth-optimism/sdk": "1.6.7", "@eth-optimism/sdk": "1.6.8",
"ethers": "^5.7.0" "ethers": "^5.7.0"
}, },
"devDependencies": { "devDependencies": {
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
"devDependencies": { "devDependencies": {
"@eth-optimism/contracts": "0.5.37", "@eth-optimism/contracts": "0.5.37",
"@eth-optimism/core-utils": "0.10.1", "@eth-optimism/core-utils": "0.10.1",
"@eth-optimism/sdk": "1.6.7", "@eth-optimism/sdk": "1.6.8",
"@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/abstract-provider": "^5.7.0",
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
"chai": "^4.3.4", "chai": "^4.3.4",
......
# @eth-optimism/message-relayer # @eth-optimism/message-relayer
## 0.5.18
### Patch Changes
- @eth-optimism/sdk@1.6.8
## 0.5.17 ## 0.5.17
### Patch Changes ### Patch Changes
......
{ {
"private": true, "private": true,
"name": "@eth-optimism/message-relayer", "name": "@eth-optimism/message-relayer",
"version": "0.5.17", "version": "0.5.18",
"description": "[Optimism] Service for automatically relaying L2 to L1 transactions", "description": "[Optimism] Service for automatically relaying L2 to L1 transactions",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
"dependencies": { "dependencies": {
"@eth-optimism/common-ts": "0.6.6", "@eth-optimism/common-ts": "0.6.6",
"@eth-optimism/core-utils": "0.10.1", "@eth-optimism/core-utils": "0.10.1",
"@eth-optimism/sdk": "1.6.7", "@eth-optimism/sdk": "1.6.8",
"ethers": "^5.7.0" "ethers": "^5.7.0"
}, },
"devDependencies": { "devDependencies": {
......
# @eth-optimism/sdk # @eth-optimism/sdk
## 1.6.8
### Patch Changes
- Updated dependencies [7d7d9ba8]
- @eth-optimism/contracts-bedrock@0.8.2
## 1.6.7 ## 1.6.7
### Patch Changes ### Patch Changes
......
{ {
"name": "@eth-optimism/sdk", "name": "@eth-optimism/sdk",
"version": "1.6.7", "version": "1.6.8",
"description": "[Optimism] Tools for working with Optimism", "description": "[Optimism] Tools for working with Optimism",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
"dependencies": { "dependencies": {
"@eth-optimism/contracts": "0.5.37", "@eth-optimism/contracts": "0.5.37",
"@eth-optimism/core-utils": "0.10.1", "@eth-optimism/core-utils": "0.10.1",
"@eth-optimism/contracts-bedrock": "0.8.1", "@eth-optimism/contracts-bedrock": "0.8.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"merkletreejs": "^0.2.27", "merkletreejs": "^0.2.27",
"rlp": "^2.2.7" "rlp": "^2.2.7"
......
...@@ -176,6 +176,7 @@ export class CrossChainMessenger { ...@@ -176,6 +176,7 @@ export class CrossChainMessenger {
this.bridges = getBridgeAdapters(this.l2ChainId, this, { this.bridges = getBridgeAdapters(this.l2ChainId, this, {
overrides: opts.bridges, overrides: opts.bridges,
contracts: opts.contracts,
}) })
} }
......
...@@ -161,6 +161,7 @@ export const getBridgeAdapters = ( ...@@ -161,6 +161,7 @@ export const getBridgeAdapters = (
messenger: CrossChainMessenger, messenger: CrossChainMessenger,
opts?: { opts?: {
overrides?: BridgeAdapterData overrides?: BridgeAdapterData
contracts?: DeepPartial<OEContractsLike>
} }
): BridgeAdapters => { ): BridgeAdapters => {
const adapterData: BridgeAdapterData = { const adapterData: BridgeAdapterData = {
...@@ -168,12 +169,16 @@ export const getBridgeAdapters = ( ...@@ -168,12 +169,16 @@ export const getBridgeAdapters = (
? { ? {
Standard: { Standard: {
Adapter: StandardBridgeAdapter, Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge, l1Bridge:
opts.contracts?.l1?.L1StandardBridge ||
CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge, l2Bridge: predeploys.L2StandardBridge,
}, },
ETH: { ETH: {
Adapter: ETHBridgeAdapter, Adapter: ETHBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge, l1Bridge:
opts.contracts?.l1?.L1StandardBridge ||
CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge, l2Bridge: predeploys.L2StandardBridge,
}, },
} }
......
import { promises as fs } from 'fs'
import { task, types } from 'hardhat/config' import { task, types } from 'hardhat/config'
import { HardhatRuntimeEnvironment } from 'hardhat/types' import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@nomiclabs/hardhat-ethers' import '@nomiclabs/hardhat-ethers'
...@@ -8,7 +10,13 @@ import { ...@@ -8,7 +10,13 @@ import {
} from '@eth-optimism/contracts-bedrock' } from '@eth-optimism/contracts-bedrock'
import { Event, Contract, Wallet, providers, utils } from 'ethers' import { Event, Contract, Wallet, providers, utils } from 'ethers'
import { CrossChainMessenger, MessageStatus, CONTRACT_ADDRESSES } from '../src' import {
CrossChainMessenger,
MessageStatus,
CONTRACT_ADDRESSES,
OEContractsLike,
DEFAULT_L2_CONTRACT_ADDRESSES,
} from '../src'
const deployWETH9 = async ( const deployWETH9 = async (
hre: HardhatRuntimeEnvironment, hre: HardhatRuntimeEnvironment,
...@@ -102,6 +110,12 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.') ...@@ -102,6 +110,12 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
'http://localhost:7545', 'http://localhost:7545',
types.string types.string
) )
.addOptionalParam(
'l1ContractsJsonPath',
'Path to a JSON with L1 contract addresses in it',
'',
types.string
)
.setAction(async (args, hre) => { .setAction(async (args, hre) => {
const signers = await hre.ethers.getSigners() const signers = await hre.ethers.getSigners()
if (signers.length === 0) { if (signers.length === 0) {
...@@ -127,7 +141,14 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.') ...@@ -127,7 +141,14 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
) )
const l2ChainId = await l2Signer.getChainId() const l2ChainId = await l2Signer.getChainId()
const contractAddrs = CONTRACT_ADDRESSES[l2ChainId] let contractAddrs = CONTRACT_ADDRESSES[l2ChainId]
if (args.l1ContractsJsonPath) {
const data = await fs.readFile(args.l1ContractsJsonPath)
contractAddrs = {
l1: JSON.parse(data.toString()),
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
} as OEContractsLike
}
const Artifact__L2ToL1MessagePasser = await getContractDefinition( const Artifact__L2ToL1MessagePasser = await getContractDefinition(
'L2ToL1MessagePasser' 'L2ToL1MessagePasser'
...@@ -192,6 +213,7 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.') ...@@ -192,6 +213,7 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
l1ChainId: await signer.getChainId(), l1ChainId: await signer.getChainId(),
l2ChainId, l2ChainId,
bedrock: true, bedrock: true,
contracts: contractAddrs,
}) })
console.log('Deploying WETH9 to L1') console.log('Deploying WETH9 to L1')
......
import { promises as fs } from 'fs'
import { task, types } from 'hardhat/config' import { task, types } from 'hardhat/config'
import '@nomiclabs/hardhat-ethers' import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy' import 'hardhat-deploy'
...@@ -7,7 +9,13 @@ import { ...@@ -7,7 +9,13 @@ import {
} from '@eth-optimism/contracts-bedrock' } from '@eth-optimism/contracts-bedrock'
import { providers, utils } from 'ethers' import { providers, utils } from 'ethers'
import { CrossChainMessenger, MessageStatus, CONTRACT_ADDRESSES } from '../src' import {
CrossChainMessenger,
MessageStatus,
CONTRACT_ADDRESSES,
OEContractsLike,
DEFAULT_L2_CONTRACT_ADDRESSES,
} from '../src'
task('deposit-eth', 'Deposits WETH9 onto L2.') task('deposit-eth', 'Deposits WETH9 onto L2.')
.addParam( .addParam(
...@@ -35,6 +43,12 @@ task('deposit-eth', 'Deposits WETH9 onto L2.') ...@@ -35,6 +43,12 @@ task('deposit-eth', 'Deposits WETH9 onto L2.')
true, true,
types.boolean types.boolean
) )
.addOptionalParam(
'l1ContractsJsonPath',
'Path to a JSON with L1 contract addresses in it',
'',
types.string
)
.addOptionalParam('withdrawAmount', 'Amount to withdraw', '', types.string) .addOptionalParam('withdrawAmount', 'Amount to withdraw', '', types.string)
.setAction(async (args, hre) => { .setAction(async (args, hre) => {
const signers = await hre.ethers.getSigners() const signers = await hre.ethers.getSigners()
...@@ -70,7 +84,14 @@ task('deposit-eth', 'Deposits WETH9 onto L2.') ...@@ -70,7 +84,14 @@ task('deposit-eth', 'Deposits WETH9 onto L2.')
) )
const l2ChainId = await l2Signer.getChainId() const l2ChainId = await l2Signer.getChainId()
const contractAddrs = CONTRACT_ADDRESSES[l2ChainId] let contractAddrs = CONTRACT_ADDRESSES[l2ChainId]
if (args.l1ContractsJsonPath) {
const data = await fs.readFile(args.l1ContractsJsonPath)
contractAddrs = {
l1: JSON.parse(data.toString()),
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
} as OEContractsLike
}
const Artifact__L2ToL1MessagePasser = await getContractDefinition( const Artifact__L2ToL1MessagePasser = await getContractDefinition(
'L2ToL1MessagePasser' 'L2ToL1MessagePasser'
...@@ -135,6 +156,7 @@ task('deposit-eth', 'Deposits WETH9 onto L2.') ...@@ -135,6 +156,7 @@ task('deposit-eth', 'Deposits WETH9 onto L2.')
l1ChainId: await signer.getChainId(), l1ChainId: await signer.getChainId(),
l2ChainId, l2ChainId,
bedrock: true, bedrock: true,
contracts: contractAddrs,
}) })
const opBalanceBefore = await signer.provider.getBalance( const opBalanceBefore = await signer.provider.getBalance(
......
...@@ -299,9 +299,8 @@ Batcher transactions are encoded as `version_byte ++ rollup_payload` (where `++` ...@@ -299,9 +299,8 @@ Batcher transactions are encoded as `version_byte ++ rollup_payload` (where `++`
| 0 | `frame ...` (one or more frames, concatenated) | | 0 | `frame ...` (one or more frames, concatenated) |
Unknown versions make the batcher transaction invalid (it must be ignored by the rollup node). Unknown versions make the batcher transaction invalid (it must be ignored by the rollup node).
All frames in a batcher transaction must be parseable. If any one frame fails to parse, the all frames in the
The `rollup_payload` may be right-padded with 0s, which will be ignored. It's allowed for them to be transaction are rejected.
interpreted as frames for channel 0, which must always be ignored.
> **TODO** specify batcher authentication (i.e. where do we store / make available the public keys of authorize batcher > **TODO** specify batcher authentication (i.e. where do we store / make available the public keys of authorize batcher
> signers) > signers)
......
...@@ -101,6 +101,11 @@ The `noTxPool` is optional as well, and extends the `transactions` meaning: ...@@ -101,6 +101,11 @@ The `noTxPool` is optional as well, and extends the `transactions` meaning:
into the payload, after any of the `transactions`. This is the default behavior a L1 node implements. into the payload, after any of the `transactions`. This is the default behavior a L1 node implements.
- If `true`, the execution engine must not change anything about the given list of `transactions`. - If `true`, the execution engine must not change anything about the given list of `transactions`.
If the `transactions` field is present, the engine must execute the transactions in order and return `STATUS_INVALID`
if there is an error processing the transactions. It must return `STATUS_VALID` if all of the transactions could
be executed without error. **Note**: The state transition rules have been modified such that deposits will never fail
so if `engine_forkchoiceUpdatedV1` returns `STATUS_INVALID` it is because a batched transaction is invalid.
[rollup-driver]: rollup-node.md [rollup-driver]: rollup-node.md
### `engine_newPayloadV1` ### `engine_newPayloadV1`
......
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