Commit 554b0da2 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into aj/op-geth-1.12.0

parents 9f68e371 2eb8cee5
...@@ -861,6 +861,18 @@ jobs: ...@@ -861,6 +861,18 @@ jobs:
command: make fuzz command: make fuzz
working_directory: op-chain-ops working_directory: op-chain-ops
fuzz-cannon:
docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
steps:
- checkout
- check-changed:
patterns: cannon,packages/contracts-bedrock/contracts/cannon
- run:
name: Fuzz
command: make fuzz
working_directory: cannon
depcheck: depcheck:
docker: docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
...@@ -1415,6 +1427,7 @@ workflows: ...@@ -1415,6 +1427,7 @@ workflows:
- go-mod-tidy - go-mod-tidy
- fuzz-op-node - fuzz-op-node
- fuzz-op-chain-ops - fuzz-op-chain-ops
- fuzz-cannon
- bedrock-markdown - bedrock-markdown
- go-lint: - go-lint:
name: op-batcher-lint name: op-batcher-lint
......
...@@ -23,8 +23,20 @@ test: elf ...@@ -23,8 +23,20 @@ test: elf
lint: lint:
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is" golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 5m -e "errors.As" -e "errors.Is"
fuzz:
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallBrk ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallClone ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallMmap ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallExitGroup ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateSyscallFnctl ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateHintRead ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 20s -fuzz=FuzzStatePreimageRead ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 10s -fuzz=FuzzStateHintWrite ./mipsevm
go test -run NOTAREALTEST -v -fuzztime 20s -fuzz=FuzzStatePreimageWrite ./mipsevm
.PHONY: \ .PHONY: \
cannon \ cannon \
clean \ clean \
test \ test \
lint lint \
fuzz
This diff is collapsed.
This diff is collapsed.
...@@ -6,6 +6,16 @@ import ( ...@@ -6,6 +6,16 @@ import (
"io" "io"
) )
const (
sysMmap = 4090
sysBrk = 4045
sysClone = 4120
sysExitGroup = 4246
sysRead = 4003
sysWrite = 4004
sysFcntl = 4055
)
func (m *InstrumentedState) readPreimage(key [32]byte, offset uint32) (dat [32]byte, datLen uint32) { func (m *InstrumentedState) readPreimage(key [32]byte, offset uint32) (dat [32]byte, datLen uint32) {
preimage := m.lastPreimage preimage := m.lastPreimage
if key != m.lastPreimageKey { if key != m.lastPreimageKey {
...@@ -43,7 +53,7 @@ func (m *InstrumentedState) handleSyscall() error { ...@@ -43,7 +53,7 @@ func (m *InstrumentedState) handleSyscall() error {
//fmt.Printf("syscall: %d\n", syscallNum) //fmt.Printf("syscall: %d\n", syscallNum)
switch syscallNum { switch syscallNum {
case 4090: // mmap case sysMmap:
sz := a1 sz := a1
if sz&PageAddrMask != 0 { // adjust size to align with page size if sz&PageAddrMask != 0 { // adjust size to align with page size
sz += PageSize - (sz & PageAddrMask) sz += PageSize - (sz & PageAddrMask)
...@@ -56,15 +66,15 @@ func (m *InstrumentedState) handleSyscall() error { ...@@ -56,15 +66,15 @@ func (m *InstrumentedState) handleSyscall() error {
v0 = a0 v0 = a0
//fmt.Printf("mmap hint 0x%x size 0x%x\n", v0, sz) //fmt.Printf("mmap hint 0x%x size 0x%x\n", v0, sz)
} }
case 4045: // brk case sysBrk:
v0 = 0x40000000 v0 = 0x40000000
case 4120: // clone (not supported) case sysClone: // clone (not supported)
v0 = 1 v0 = 1
case 4246: // exit_group case sysExitGroup:
m.state.Exited = true m.state.Exited = true
m.state.ExitCode = uint8(a0) m.state.ExitCode = uint8(a0)
return nil return nil
case 4003: // read case sysRead:
// args: a0 = fd, a1 = addr, a2 = count // args: a0 = fd, a1 = addr, a2 = count
// returns: v0 = read, v1 = err code // returns: v0 = read, v1 = err code
switch a0 { switch a0 {
...@@ -98,7 +108,7 @@ func (m *InstrumentedState) handleSyscall() error { ...@@ -98,7 +108,7 @@ func (m *InstrumentedState) handleSyscall() error {
v0 = 0xFFffFFff v0 = 0xFFffFFff
v1 = MipsEBADF v1 = MipsEBADF
} }
case 4004: // write case sysWrite:
// args: a0 = fd, a1 = addr, a2 = count // args: a0 = fd, a1 = addr, a2 = count
// returns: v0 = written, v1 = err code // returns: v0 = written, v1 = err code
switch a0 { switch a0 {
...@@ -144,7 +154,7 @@ func (m *InstrumentedState) handleSyscall() error { ...@@ -144,7 +154,7 @@ func (m *InstrumentedState) handleSyscall() error {
v0 = 0xFFffFFff v0 = 0xFFffFFff
v1 = MipsEBADF v1 = MipsEBADF
} }
case 4055: // fcntl case sysFcntl:
// args: a0 = fd, a1 = cmd // args: a0 = fd, a1 = cmd
if a1 == 3 { // F_GETFL: get file descriptor flags if a1 == 3 { // F_GETFL: get file descriptor flags
switch a0 { switch a0 {
......
...@@ -2,6 +2,7 @@ package solc ...@@ -2,6 +2,7 @@ package solc
import ( import (
"encoding/json" "encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
) )
...@@ -36,7 +37,8 @@ type CompilerOutput struct { ...@@ -36,7 +37,8 @@ type CompilerOutput struct {
type CompilerOutputContracts map[string]CompilerOutputContract type CompilerOutputContracts map[string]CompilerOutputContract
// TODO(tynes): ignoring devdoc and userdoc for now // CompilerOutputContract represents the solc compiler output for a contract.
// Ignoring some fields such as devdoc and userdoc.
type CompilerOutputContract struct { type CompilerOutputContract struct {
Abi abi.ABI `json:"abi"` Abi abi.ABI `json:"abi"`
Evm CompilerOutputEvm `json:"evm"` Evm CompilerOutputEvm `json:"evm"`
...@@ -44,11 +46,24 @@ type CompilerOutputContract struct { ...@@ -44,11 +46,24 @@ type CompilerOutputContract struct {
StorageLayout StorageLayout `json:"storageLayout"` StorageLayout StorageLayout `json:"storageLayout"`
} }
// StorageLayout represents the solc compilers output storage layout for
// a contract.
type StorageLayout struct { type StorageLayout struct {
Storage []StorageLayoutEntry `json:"storage"` Storage []StorageLayoutEntry `json:"storage"`
Types map[string]StorageLayoutType `json:"types"` Types map[string]StorageLayoutType `json:"types"`
} }
// GetStorageLayoutEntry returns the StorageLayoutEntry where the label matches
// the provided name.
func (s *StorageLayout) GetStorageLayoutEntry(name string) (StorageLayoutEntry, error) {
for _, entry := range s.Storage {
if entry.Label == name {
return entry, nil
}
}
return StorageLayoutEntry{}, fmt.Errorf("%s not found", name)
}
type StorageLayoutEntry struct { type StorageLayoutEntry struct {
AstId uint `json:"astId"` AstId uint `json:"astId"`
Contract string `json:"contract"` Contract string `json:"contract"`
......
...@@ -169,6 +169,22 @@ type DeployConfig struct { ...@@ -169,6 +169,22 @@ type DeployConfig struct {
FundDevAccounts bool `json:"fundDevAccounts"` FundDevAccounts bool `json:"fundDevAccounts"`
} }
// Copy will deeply copy the DeployConfig. This does a JSON roundtrip to copy
// which makes it easier to maintain, we do not need efficiency in this case.
func (d *DeployConfig) Copy() *DeployConfig {
raw, err := json.Marshal(d)
if err != nil {
panic(err)
}
cpy := DeployConfig{}
if err = json.Unmarshal(raw, &cpy); err != nil {
panic(err)
}
return &cpy
}
// Check will ensure that the config is sane and return an error when it is not // Check will ensure that the config is sane and return an error when it is not
func (d *DeployConfig) Check() error { func (d *DeployConfig) Check() error {
if d.L1StartingBlockTag == nil { if d.L1StartingBlockTag == nil {
......
...@@ -48,3 +48,19 @@ func TestRegolithTimeAsOffset(t *testing.T) { ...@@ -48,3 +48,19 @@ func TestRegolithTimeAsOffset(t *testing.T) {
config := &DeployConfig{L2GenesisRegolithTimeOffset: &regolithOffset} config := &DeployConfig{L2GenesisRegolithTimeOffset: &regolithOffset}
require.Equal(t, uint64(1500+5000), *config.RegolithTime(5000)) require.Equal(t, uint64(1500+5000), *config.RegolithTime(5000))
} }
// TestCopy will copy a DeployConfig and ensure that the copy is equal to the original.
func TestCopy(t *testing.T) {
b, err := os.ReadFile("testdata/test-deploy-config-full.json")
require.NoError(t, err)
decoded := new(DeployConfig)
require.NoError(t, json.NewDecoder(bytes.NewReader(b)).Decode(decoded))
cpy := decoded.Copy()
require.EqualValues(t, decoded, cpy)
offset := hexutil.Uint64(100)
cpy.L2GenesisRegolithTimeOffset = &offset
require.NotEqual(t, decoded, cpy)
}
This diff is collapsed.
...@@ -9,11 +9,14 @@ import ( ...@@ -9,11 +9,14 @@ import (
) )
var ( var (
ErrMissingTraceType = errors.New("missing trace type") ErrMissingTraceType = errors.New("missing trace type")
ErrMissingCannonDatadir = errors.New("missing cannon datadir") ErrMissingCannonDatadir = errors.New("missing cannon datadir")
ErrMissingAlphabetTrace = errors.New("missing alphabet trace") ErrMissingCannonL2 = errors.New("missing cannon L2")
ErrMissingL1EthRPC = errors.New("missing l1 eth rpc url") ErrMissingCannonBin = errors.New("missing cannon bin")
ErrMissingGameAddress = errors.New("missing game address") ErrMissingCannonAbsolutePreState = errors.New("missing cannon absolute pre-state")
ErrMissingAlphabetTrace = errors.New("missing alphabet trace")
ErrMissingL1EthRPC = errors.New("missing l1 eth rpc url")
ErrMissingGameAddress = errors.New("missing game address")
) )
type TraceType string type TraceType string
...@@ -56,9 +59,16 @@ type Config struct { ...@@ -56,9 +59,16 @@ type Config struct {
AgreeWithProposedOutput bool // Temporary config if we agree or disagree with the posted output AgreeWithProposedOutput bool // Temporary config if we agree or disagree with the posted output
GameDepth int // Depth of the game tree GameDepth int // Depth of the game tree
TraceType TraceType // Type of trace TraceType TraceType // Type of trace
AlphabetTrace string // String for the AlphabetTraceProvider
CannonDatadir string // Cannon Data Directory for the CannonTraceProvider // Specific to the alphabet trace provider
AlphabetTrace string // String for the AlphabetTraceProvider
// Specific to the cannon trace provider
CannonBin string // Path to the cannon executable to run when generating trace data
CannonAbsolutePreState string // File to load the absolute pre-state for Cannon traces from
CannonDatadir string // Cannon Data Directory
CannonL2 string // L2 RPC Url
TxMgrConfig txmgr.CLIConfig TxMgrConfig txmgr.CLIConfig
} }
...@@ -67,8 +77,6 @@ func NewConfig( ...@@ -67,8 +77,6 @@ func NewConfig(
l1EthRpc string, l1EthRpc string,
gameAddress common.Address, gameAddress common.Address,
traceType TraceType, traceType TraceType,
alphabetTrace string,
cannonDatadir string,
agreeWithProposedOutput bool, agreeWithProposedOutput bool,
gameDepth int, gameDepth int,
) Config { ) Config {
...@@ -79,9 +87,7 @@ func NewConfig( ...@@ -79,9 +87,7 @@ func NewConfig(
AgreeWithProposedOutput: agreeWithProposedOutput, AgreeWithProposedOutput: agreeWithProposedOutput,
GameDepth: gameDepth, GameDepth: gameDepth,
TraceType: traceType, TraceType: traceType,
AlphabetTrace: alphabetTrace,
CannonDatadir: cannonDatadir,
TxMgrConfig: txmgr.NewCLIConfig(l1EthRpc), TxMgrConfig: txmgr.NewCLIConfig(l1EthRpc),
} }
...@@ -97,8 +103,19 @@ func (c Config) Check() error { ...@@ -97,8 +103,19 @@ func (c Config) Check() error {
if c.TraceType == "" { if c.TraceType == "" {
return ErrMissingTraceType return ErrMissingTraceType
} }
if c.TraceType == TraceTypeCannon && c.CannonDatadir == "" { if c.TraceType == TraceTypeCannon {
return ErrMissingCannonDatadir if c.CannonBin == "" {
return ErrMissingCannonBin
}
if c.CannonAbsolutePreState == "" {
return ErrMissingCannonAbsolutePreState
}
if c.CannonDatadir == "" {
return ErrMissingCannonDatadir
}
if c.CannonL2 == "" {
return ErrMissingCannonL2
}
} }
if c.TraceType == TraceTypeAlphabet && c.AlphabetTrace == "" { if c.TraceType == TraceTypeAlphabet && c.AlphabetTrace == "" {
return ErrMissingAlphabetTrace return ErrMissingAlphabetTrace
......
...@@ -9,23 +9,40 @@ import ( ...@@ -9,23 +9,40 @@ import (
) )
var ( var (
validL1EthRpc = "http://localhost:8545" validL1EthRpc = "http://localhost:8545"
validGameAddress = common.HexToAddress("0x7bdd3b028C4796eF0EAf07d11394d0d9d8c24139") validGameAddress = common.HexToAddress("0x7bdd3b028C4796eF0EAf07d11394d0d9d8c24139")
validAlphabetTrace = "abcdefgh" validAlphabetTrace = "abcdefgh"
validCannonDatadir = "/tmp/cannon" validCannonBin = "./bin/cannon"
agreeWithProposedOutput = true validCannonAbsolutPreState = "pre.json"
gameDepth = 4 validCannonDatadir = "/tmp/cannon"
validCannonL2 = "http://localhost:9545"
agreeWithProposedOutput = true
gameDepth = 4
) )
func validConfig(traceType TraceType) Config { func validConfig(traceType TraceType) Config {
cfg := NewConfig(validL1EthRpc, validGameAddress, traceType, validAlphabetTrace, validCannonDatadir, agreeWithProposedOutput, gameDepth) cfg := NewConfig(validL1EthRpc, validGameAddress, traceType, agreeWithProposedOutput, gameDepth)
switch traceType {
case TraceTypeAlphabet:
cfg.AlphabetTrace = validAlphabetTrace
case TraceTypeCannon:
cfg.CannonBin = validCannonBin
cfg.CannonAbsolutePreState = validCannonAbsolutPreState
cfg.CannonDatadir = validCannonDatadir
cfg.CannonL2 = validCannonL2
}
return cfg return cfg
} }
// TestValidConfigIsValid checks that the config provided by validConfig is actually valid // TestValidConfigIsValid checks that the config provided by validConfig is actually valid
func TestValidConfigIsValid(t *testing.T) { func TestValidConfigIsValid(t *testing.T) {
err := validConfig(TraceTypeCannon).Check() for _, traceType := range TraceTypes {
require.NoError(t, err) traceType := traceType
t.Run(traceType.String(), func(t *testing.T) {
err := validConfig(traceType).Check()
require.NoError(t, err)
})
}
} }
func TestTxMgrConfig(t *testing.T) { func TestTxMgrConfig(t *testing.T) {
...@@ -40,30 +57,40 @@ func TestL1EthRpcRequired(t *testing.T) { ...@@ -40,30 +57,40 @@ func TestL1EthRpcRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(TraceTypeCannon)
config.L1EthRpc = "" config.L1EthRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC) require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC)
config.L1EthRpc = validL1EthRpc
require.NoError(t, config.Check())
} }
func TestGameAddressRequired(t *testing.T) { func TestGameAddressRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(TraceTypeCannon)
config.GameAddress = common.Address{} config.GameAddress = common.Address{}
require.ErrorIs(t, config.Check(), ErrMissingGameAddress) require.ErrorIs(t, config.Check(), ErrMissingGameAddress)
config.GameAddress = validGameAddress
require.NoError(t, config.Check())
} }
func TestAlphabetTraceRequired(t *testing.T) { func TestAlphabetTraceRequired(t *testing.T) {
config := validConfig(TraceTypeAlphabet) config := validConfig(TraceTypeAlphabet)
config.AlphabetTrace = "" config.AlphabetTrace = ""
require.ErrorIs(t, config.Check(), ErrMissingAlphabetTrace) require.ErrorIs(t, config.Check(), ErrMissingAlphabetTrace)
config.AlphabetTrace = validAlphabetTrace
require.NoError(t, config.Check())
} }
func TestCannonTraceRequired(t *testing.T) { func TestCannonBinRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.CannonBin = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonBin)
}
func TestCannonAbsolutePreStateRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.CannonAbsolutePreState = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonAbsolutePreState)
}
func TestCannonDatadirRequired(t *testing.T) {
config := validConfig(TraceTypeCannon) config := validConfig(TraceTypeCannon)
config.CannonDatadir = "" config.CannonDatadir = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonDatadir) require.ErrorIs(t, config.Check(), ErrMissingCannonDatadir)
config.CannonDatadir = validCannonDatadir }
require.NoError(t, config.Check())
func TestCannonL2Required(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.CannonL2 = ""
require.ErrorIs(t, config.Check(), ErrMissingCannonL2)
} }
...@@ -55,14 +55,29 @@ var ( ...@@ -55,14 +55,29 @@ var (
// Optional Flags // Optional Flags
AlphabetFlag = &cli.StringFlag{ AlphabetFlag = &cli.StringFlag{
Name: "alphabet", Name: "alphabet",
Usage: "Alphabet Trace (temporary)", Usage: "Correct Alphabet Trace (alphabet trace type only)",
EnvVars: prefixEnvVars("ALPHABET"), EnvVars: prefixEnvVars("ALPHABET"),
} }
CannonBinFlag = &cli.StringFlag{
Name: "cannon-bin",
Usage: "Path to cannon executable to use when generating trace data (cannon trace type only)",
EnvVars: prefixEnvVars("CANNON_BIN"),
}
CannonPreStateFlag = &cli.StringFlag{
Name: "cannon-prestate",
Usage: "Path to absolute prestate to use when generating trace data (cannon trace type only)",
EnvVars: prefixEnvVars("CANNON_PRESTATE"),
}
CannonDatadirFlag = &cli.StringFlag{ CannonDatadirFlag = &cli.StringFlag{
Name: "cannon-datadir", Name: "cannon-datadir",
Usage: "Cannon Data Directory", Usage: "Directory to store data generated by cannon (cannon trace type only)",
EnvVars: prefixEnvVars("CANNON_DATADIR"), EnvVars: prefixEnvVars("CANNON_DATADIR"),
} }
CannonL2Flag = &cli.StringFlag{
Name: "cannon-l2",
Usage: "L2 Address of L2 JSON-RPC endpoint to use (eth and debug namespace required) (cannon trace type only)",
EnvVars: prefixEnvVars("CANNON_L2"),
}
) )
// requiredFlags are checked by [CheckRequired] // requiredFlags are checked by [CheckRequired]
...@@ -77,7 +92,10 @@ var requiredFlags = []cli.Flag{ ...@@ -77,7 +92,10 @@ var requiredFlags = []cli.Flag{
// optionalFlags is a list of unchecked cli flags // optionalFlags is a list of unchecked cli flags
var optionalFlags = []cli.Flag{ var optionalFlags = []cli.Flag{
AlphabetFlag, AlphabetFlag,
CannonBinFlag,
CannonPreStateFlag,
CannonDatadirFlag, CannonDatadirFlag,
CannonL2Flag,
} }
func init() { func init() {
...@@ -99,8 +117,17 @@ func CheckRequired(ctx *cli.Context) error { ...@@ -99,8 +117,17 @@ func CheckRequired(ctx *cli.Context) error {
gameType := config.TraceType(strings.ToLower(ctx.String(TraceTypeFlag.Name))) gameType := config.TraceType(strings.ToLower(ctx.String(TraceTypeFlag.Name)))
switch gameType { switch gameType {
case config.TraceTypeCannon: case config.TraceTypeCannon:
if !ctx.IsSet(CannonBinFlag.Name) {
return fmt.Errorf("flag %s is required", CannonBinFlag.Name)
}
if !ctx.IsSet(CannonPreStateFlag.Name) {
return fmt.Errorf("flag %s is required", CannonPreStateFlag.Name)
}
if !ctx.IsSet(CannonDatadirFlag.Name) { if !ctx.IsSet(CannonDatadirFlag.Name) {
return fmt.Errorf("flag %s is required", "cannon-datadir") return fmt.Errorf("flag %s is required", CannonDatadirFlag.Name)
}
if !ctx.IsSet(CannonL2Flag.Name) {
return fmt.Errorf("flag %s is required", CannonL2Flag.Name)
} }
case config.TraceTypeAlphabet: case config.TraceTypeAlphabet:
if !ctx.IsSet(AlphabetFlag.Name) { if !ctx.IsSet(AlphabetFlag.Name) {
...@@ -132,7 +159,10 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) { ...@@ -132,7 +159,10 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
TraceType: traceTypeFlag, TraceType: traceTypeFlag,
GameAddress: dgfAddress, GameAddress: dgfAddress,
AlphabetTrace: ctx.String(AlphabetFlag.Name), AlphabetTrace: ctx.String(AlphabetFlag.Name),
CannonBin: ctx.String(CannonBinFlag.Name),
CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name),
CannonDatadir: ctx.String(CannonDatadirFlag.Name), CannonDatadir: ctx.String(CannonDatadirFlag.Name),
CannonL2: ctx.String(CannonL2Flag.Name),
AgreeWithProposedOutput: ctx.Bool(AgreeWithProposedOutputFlag.Name), AgreeWithProposedOutput: ctx.Bool(AgreeWithProposedOutputFlag.Name),
GameDepth: ctx.Int(GameDepthFlag.Name), GameDepth: ctx.Int(GameDepthFlag.Name),
TxMgrConfig: txMgrConfig, TxMgrConfig: txMgrConfig,
......
...@@ -109,7 +109,7 @@ func (s *L1Miner) ActL1IncludeTx(from common.Address) Action { ...@@ -109,7 +109,7 @@ func (s *L1Miner) ActL1IncludeTx(from common.Address) Action {
func (s *L1Miner) IncludeTx(t Testing, tx *types.Transaction) { func (s *L1Miner) IncludeTx(t Testing, tx *types.Transaction) {
from, err := s.l1Signer.Sender(tx) from, err := s.l1Signer.Sender(tx)
require.NoError(t, err) require.NoError(t, err)
s.log.Info("including tx", "nonce", tx.Nonce(), "from", from) s.log.Info("including tx", "nonce", tx.Nonce(), "from", from, "to", tx.To())
if tx.Gas() > s.l1BuildingHeader.GasLimit { if tx.Gas() > s.l1BuildingHeader.GasLimit {
t.Fatalf("tx consumes %d gas, more than available in L1 block %d", tx.Gas(), s.l1BuildingHeader.GasLimit) t.Fatalf("tx consumes %d gas, more than available in L1 block %d", tx.Gas(), s.l1BuildingHeader.GasLimit)
} }
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
...@@ -16,6 +17,7 @@ import ( ...@@ -16,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-node/sources" "github.com/ethereum-optimism/optimism/op-node/sources"
"github.com/ethereum-optimism/optimism/op-proposer/metrics" "github.com/ethereum-optimism/optimism/op-proposer/metrics"
"github.com/ethereum-optimism/optimism/op-proposer/proposer" "github.com/ethereum-optimism/optimism/op-proposer/proposer"
...@@ -32,6 +34,7 @@ type L2Proposer struct { ...@@ -32,6 +34,7 @@ type L2Proposer struct {
log log.Logger log log.Logger
l1 *ethclient.Client l1 *ethclient.Client
driver *proposer.L2OutputSubmitter driver *proposer.L2OutputSubmitter
contract *bindings.L2OutputOracleCaller
address common.Address address common.Address
privKey *ecdsa.PrivateKey privKey *ecdsa.PrivateKey
contractAddr common.Address contractAddr common.Address
...@@ -56,7 +59,6 @@ func (f fakeTxMgr) Send(_ context.Context, _ txmgr.TxCandidate) (*types.Receipt, ...@@ -56,7 +59,6 @@ func (f fakeTxMgr) Send(_ context.Context, _ txmgr.TxCandidate) (*types.Receipt,
} }
func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Client, rollupCl *sources.RollupClient) *L2Proposer { func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Client, rollupCl *sources.RollupClient) *L2Proposer {
proposerCfg := proposer.Config{ proposerCfg := proposer.Config{
L2OutputOracleAddr: cfg.OutputOracleAddr, L2OutputOracleAddr: cfg.OutputOracleAddr,
PollInterval: time.Second, PollInterval: time.Second,
...@@ -70,12 +72,20 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl ...@@ -70,12 +72,20 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
dr, err := proposer.NewL2OutputSubmitter(proposerCfg, log, metrics.NoopMetrics) dr, err := proposer.NewL2OutputSubmitter(proposerCfg, log, metrics.NoopMetrics)
require.NoError(t, err) require.NoError(t, err)
contract, err := bindings.NewL2OutputOracleCaller(cfg.OutputOracleAddr, l1)
require.NoError(t, err)
address := crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey)
proposer, err := contract.PROPOSER(&bind.CallOpts{})
require.NoError(t, err)
require.Equal(t, proposer, address, "PROPOSER must be the proposer's address")
return &L2Proposer{ return &L2Proposer{
log: log, log: log,
l1: l1, l1: l1,
driver: dr, driver: dr,
address: crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey), contract: contract,
address: address,
privKey: cfg.ProposerKey, privKey: cfg.ProposerKey,
contractAddr: cfg.OutputOracleAddr, contractAddr: cfg.OutputOracleAddr,
} }
......
...@@ -231,6 +231,11 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) * ...@@ -231,6 +231,11 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *
SystemConfigProxy: predeploys.DevSystemConfigAddr, SystemConfigProxy: predeploys.DevSystemConfigAddr,
} }
// Sanity check that the config is correct
require.Equal(t, deployParams.Secrets.Addresses().Batcher, deployParams.DeployConfig.BatchSenderAddress)
require.Equal(t, deployParams.Secrets.Addresses().SequencerP2P, deployParams.DeployConfig.P2PSequencerAddress)
require.Equal(t, deployParams.Secrets.Addresses().Proposer, deployParams.DeployConfig.L2OutputOracleProposer)
return &SetupData{ return &SetupData{
L1Cfg: l1Genesis, L1Cfg: l1Genesis,
L2Cfg: l2Genesis, L2Cfg: l2Genesis,
......
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