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:
machine:
image: ubuntu-2004:2022.07.1
docker_layer_caching: true
parameters:
deploy:
description: Deploy contracts
default: false
type: boolean
environment:
DOCKER_BUILDKIT: 1
steps:
......@@ -539,22 +544,48 @@ jobs:
command: |
yarn install
yarn build
- run:
name: Bring up the stack
command: |
make devnet-up
- run:
name: Deposit ERC20 through the bridge
command: timeout 5m npx hardhat deposit-erc20 --network devnetL1
working_directory: packages/sdk
- run:
name: Deposit ETH through the bridge
command: timeout 5m npx hardhat deposit-eth --network devnetL1
working_directory: packages/sdk
- run:
name: Check the status
command: npx hardhat check-op-node
working_directory: packages/contracts-bedrock
- 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:
name: Bring up the stack
command: |
make devnet-up
- run:
name: Deposit ERC20 through the bridge
command: timeout 5m npx hardhat deposit-erc20 --network devnetL1
working_directory: packages/sdk
- run:
name: Deposit ETH through the bridge
command: timeout 5m npx hardhat deposit-eth --network devnetL1
working_directory: packages/sdk
- run:
name: Check the status
command: npx hardhat check-op-node
working_directory: packages/contracts-bedrock
integration-tests:
machine:
......@@ -773,7 +804,12 @@ workflows:
- bedrock-go-tests
- fuzz-op-node
- bedrock-markdown
- devnet
- devnet:
name: devnet (with deployed contracts)
deploy: true
- devnet:
name: devnet (with genesis contracts)
deploy: false
- go-lint-test-build:
name: batch-submitter-tests
binary_name: batch-submitter
......
......@@ -53,3 +53,6 @@ coverage.out
# Ignore bedrock go bindings local output files
op-bindings/bin
op-exporter
__pycache__
......@@ -68,6 +68,10 @@ devnet-up:
@bash ./ops-bedrock/devnet-up.sh
.PHONY: devnet-up
devnet-up-deploy:
PYTHONPATH=./bedrock-devnet python3 ./bedrock-devnet/main.py --monorepo-dir=.
.PHONY: devnet-up-deploy
devnet-down:
@(cd ./ops-bedrock && GENESIS_TIMESTAMP=$(shell date +%s) docker-compose stop)
.PHONY: devnet-down
......@@ -114,4 +118,4 @@ tag-bedrock-go-modules:
update-op-geth:
./ops/scripts/update-op-geth.py
.PHONY: update-op-geth
\ No newline at end of file
.PHONY: update-op-geth
# 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 @@
"@eth-optimism/contracts": "^0.5.37",
"@eth-optimism/contracts-periphery": "^1.0.2",
"@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/providers": "^5.7.0",
"@ethersproject/transactions": "^5.7.0",
......
# Changelog
## 0.5.26
### Patch Changes
- 397b27ee: Add data exporter
## 0.5.25
### Patch Changes
......
......@@ -24,6 +24,8 @@ import (
"sort"
"time"
"github.com/ethereum-optimism/optimism/l2geth/statedumper"
"github.com/ethereum-optimism/optimism/l2geth/common"
"github.com/ethereum-optimism/optimism/l2geth/core/types"
"github.com/ethereum-optimism/optimism/l2geth/crypto"
......@@ -244,6 +246,7 @@ func (s *StateDB) GetBalance(addr common.Address) *big.Int {
if rcfg.UsingOVM {
// Get balance from the OVM_ETH contract.
// NOTE: We may remove this feature in a future release.
statedumper.WriteETH(addr)
key := GetOVMBalanceKey(addr)
bal := s.GetState(dump.OvmEthAddress, key)
return bal.Big()
......@@ -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
// 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.
statedumper.WriteETH(addr)
key := GetOVMBalanceKey(addr)
value := s.GetState(dump.OvmEthAddress, key)
bal := value.Big()
......@@ -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
// 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.
statedumper.WriteETH(addr)
key := GetOVMBalanceKey(addr)
value := s.GetState(dump.OvmEthAddress, key)
bal := value.Big()
......@@ -413,6 +418,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
func (s *StateDB) SetBalance(addr common.Address, amount *big.Int) {
if rcfg.UsingOVM {
// Mutate the storage slot inside of OVM_ETH to change balances.
statedumper.WriteETH(addr)
key := GetOVMBalanceKey(addr)
s.SetState(dump.OvmEthAddress, key, common.BigToHash(amount))
} else {
......@@ -580,8 +586,8 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
// CreateAccount is called during the EVM CREATE operation. The situation might arise that
// a contract does the following:
//
// 1. sends funds to sha(account ++ (nonce + 1))
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
// 1. sends funds to sha(account ++ (nonce + 1))
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
//
// Carrying over the balance ensures that Ether doesn't disappear.
func (s *StateDB) CreateAccount(addr common.Address) {
......
......@@ -18,6 +18,7 @@ package vm
import (
"fmt"
"github.com/ethereum-optimism/optimism/l2geth/statedumper"
"math/big"
"sync/atomic"
"time"
......@@ -198,6 +199,10 @@ func (evm *EVM) Interpreter() Interpreter {
// the necessary steps to create accounts and reverses the state in case of an
// 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) {
if addr == dump.MessagePasserAddress {
statedumper.WriteMessage(caller.Address(), input)
}
if evm.vmConfig.NoRecursion && evm.depth > 0 {
return nil, gas, nil
}
......
{
"name": "@eth-optimism/l2geth",
"version": "0.5.25",
"version": "0.5.26",
"private": true,
"devDependencies": {}
}
......@@ -7,3 +7,4 @@ import (
var OvmEthAddress = common.HexToAddress("0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000")
var OvmFeeWallet = common.HexToAddress("0x4200000000000000000000000000000000000011")
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:
l.ch = ch
}
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)
block, err := l.cfg.L2Client.BlockByNumber(ctx, new(big.Int).SetUint64(i))
cancel()
......
surgery:
go build -o ./surgery ./cmd/main.go
go build -o ./surgery ./cmd/surgery/main.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 (
"bufio"
......
package state_surgery
package ether
import (
"bytes"
......
package state_surgery
package ether
import (
"path/filepath"
......
package state_surgery
package ether
import (
"encoding/json"
......
package state_surgery
package ether
import (
"math/big"
......
package state_surgery
package ether
import (
"github.com/ethereum/go-ethereum/common"
......
package state_surgery
package ether
import (
"fmt"
......
......@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"math/big"
"os"
"path/filepath"
......@@ -125,7 +126,7 @@ var Subcommands = cli.Commands{
l1StartBlock, err = client.BlockByNumber(context.Background(), big.NewInt(config.L1StartingBlockTag.BlockNumber.Int64()))
}
if err != nil {
return err
return fmt.Errorf("error getting l1 start block: %w", err)
}
depPath, network := filepath.Split(ctx.String("deployment-dir"))
......@@ -157,7 +158,7 @@ var Subcommands = cli.Commands{
}
l2Genesis, err := genesis.BuildL2DeveloperGenesis(config, l1StartBlock, l2Addrs)
if err != nil {
return err
return fmt.Errorf("error creating l2 developer genesis: %w", err)
}
rollupConfig := makeRollupConfig(config, l1StartBlock, l2Genesis, portalProxy.Address)
......
# @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
### Patch Changes
......
{
"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.",
"license": "MIT",
"author": "",
......@@ -18,9 +18,9 @@
"test:coverage": "yarn test"
},
"dependencies": {
"@eth-optimism/contracts-bedrock": "0.8.1",
"@eth-optimism/contracts-bedrock": "0.8.2",
"@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-as-promised": "^7.1.4",
"async-mutex": "^0.3.2",
......
# @eth-optimism/contracts-bedrock
## 0.8.2
### Patch Changes
- 7d7d9ba8: Moves initializers underneath constructors always
## 0.8.1
### Patch Changes
......
......@@ -23,6 +23,8 @@
"optimismBaseFeeRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"optimismL1FeeRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"finalizationPeriodSeconds": 2,
"deploymentWaitConfirmations": 1,
"fundDevAccounts": true
}
{
"name": "@eth-optimism/contracts-bedrock",
"version": "0.8.1",
"version": "0.8.2",
"description": "Contracts for Optimism Specs",
"main": "dist/index",
"types": "dist/index",
......
# @eth-optimism/drippie-mon
## 0.3.19
### Patch Changes
- @eth-optimism/sdk@1.6.8
## 0.3.18
### Patch Changes
......
{
"private": true,
"name": "@eth-optimism/drippie-mon",
"version": "0.3.18",
"version": "0.3.19",
"description": "[Optimism] Service for monitoring Drippie instances",
"main": "dist/index",
"types": "dist/index",
......@@ -35,7 +35,7 @@
"@eth-optimism/common-ts": "0.6.6",
"@eth-optimism/contracts-periphery": "1.0.2",
"@eth-optimism/core-utils": "0.10.1",
"@eth-optimism/sdk": "1.6.7",
"@eth-optimism/sdk": "1.6.8",
"ethers": "^5.7.0"
},
"devDependencies": {
......
......@@ -29,7 +29,7 @@
"devDependencies": {
"@eth-optimism/contracts": "0.5.37",
"@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",
"chai-as-promised": "^7.1.1",
"chai": "^4.3.4",
......
# @eth-optimism/message-relayer
## 0.5.18
### Patch Changes
- @eth-optimism/sdk@1.6.8
## 0.5.17
### Patch Changes
......
{
"private": true,
"name": "@eth-optimism/message-relayer",
"version": "0.5.17",
"version": "0.5.18",
"description": "[Optimism] Service for automatically relaying L2 to L1 transactions",
"main": "dist/index",
"types": "dist/index",
......@@ -33,7 +33,7 @@
"dependencies": {
"@eth-optimism/common-ts": "0.6.6",
"@eth-optimism/core-utils": "0.10.1",
"@eth-optimism/sdk": "1.6.7",
"@eth-optimism/sdk": "1.6.8",
"ethers": "^5.7.0"
},
"devDependencies": {
......
# @eth-optimism/sdk
## 1.6.8
### Patch Changes
- Updated dependencies [7d7d9ba8]
- @eth-optimism/contracts-bedrock@0.8.2
## 1.6.7
### Patch Changes
......
{
"name": "@eth-optimism/sdk",
"version": "1.6.7",
"version": "1.6.8",
"description": "[Optimism] Tools for working with Optimism",
"main": "dist/index",
"types": "dist/index",
......@@ -50,7 +50,7 @@
"dependencies": {
"@eth-optimism/contracts": "0.5.37",
"@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",
"merkletreejs": "^0.2.27",
"rlp": "^2.2.7"
......
......@@ -176,6 +176,7 @@ export class CrossChainMessenger {
this.bridges = getBridgeAdapters(this.l2ChainId, this, {
overrides: opts.bridges,
contracts: opts.contracts,
})
}
......
......@@ -161,6 +161,7 @@ export const getBridgeAdapters = (
messenger: CrossChainMessenger,
opts?: {
overrides?: BridgeAdapterData
contracts?: DeepPartial<OEContractsLike>
}
): BridgeAdapters => {
const adapterData: BridgeAdapterData = {
......@@ -168,12 +169,16 @@ export const getBridgeAdapters = (
? {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge,
l1Bridge:
opts.contracts?.l1?.L1StandardBridge ||
CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
ETH: {
Adapter: ETHBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge,
l1Bridge:
opts.contracts?.l1?.L1StandardBridge ||
CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
}
......
import { promises as fs } from 'fs'
import { task, types } from 'hardhat/config'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@nomiclabs/hardhat-ethers'
......@@ -8,7 +10,13 @@ import {
} from '@eth-optimism/contracts-bedrock'
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 (
hre: HardhatRuntimeEnvironment,
......@@ -102,6 +110,12 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
'http://localhost:7545',
types.string
)
.addOptionalParam(
'l1ContractsJsonPath',
'Path to a JSON with L1 contract addresses in it',
'',
types.string
)
.setAction(async (args, hre) => {
const signers = await hre.ethers.getSigners()
if (signers.length === 0) {
......@@ -127,7 +141,14 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
)
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(
'L2ToL1MessagePasser'
......@@ -192,6 +213,7 @@ task('deposit-erc20', 'Deposits WETH9 onto L2.')
l1ChainId: await signer.getChainId(),
l2ChainId,
bedrock: true,
contracts: contractAddrs,
})
console.log('Deploying WETH9 to L1')
......
import { promises as fs } from 'fs'
import { task, types } from 'hardhat/config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
......@@ -7,7 +9,13 @@ import {
} from '@eth-optimism/contracts-bedrock'
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.')
.addParam(
......@@ -35,6 +43,12 @@ task('deposit-eth', 'Deposits WETH9 onto L2.')
true,
types.boolean
)
.addOptionalParam(
'l1ContractsJsonPath',
'Path to a JSON with L1 contract addresses in it',
'',
types.string
)
.addOptionalParam('withdrawAmount', 'Amount to withdraw', '', types.string)
.setAction(async (args, hre) => {
const signers = await hre.ethers.getSigners()
......@@ -70,7 +84,14 @@ task('deposit-eth', 'Deposits WETH9 onto L2.')
)
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(
'L2ToL1MessagePasser'
......@@ -135,6 +156,7 @@ task('deposit-eth', 'Deposits WETH9 onto L2.')
l1ChainId: await signer.getChainId(),
l2ChainId,
bedrock: true,
contracts: contractAddrs,
})
const opBalanceBefore = await signer.provider.getBalance(
......
......@@ -299,9 +299,8 @@ Batcher transactions are encoded as `version_byte ++ rollup_payload` (where `++`
| 0 | `frame ...` (one or more frames, concatenated) |
Unknown versions make the batcher transaction invalid (it must be ignored by the rollup node).
The `rollup_payload` may be right-padded with 0s, which will be ignored. It's allowed for them to be
interpreted as frames for channel 0, which must always be ignored.
All frames in a batcher transaction must be parseable. If any one frame fails to parse, the all frames in the
transaction are rejected.
> **TODO** specify batcher authentication (i.e. where do we store / make available the public keys of authorize batcher
> signers)
......
......@@ -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.
- 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
### `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