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

Merge branch 'develop' into feat/storage-layout-getter

parents 5adbe662 64649169
......@@ -861,6 +861,18 @@ jobs:
command: make fuzz
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:
docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
......@@ -1415,6 +1427,7 @@ workflows:
- go-mod-tidy
- fuzz-op-node
- fuzz-op-chain-ops
- fuzz-cannon
- bedrock-markdown
- go-lint:
name: op-batcher-lint
......
......@@ -23,8 +23,20 @@ test: elf
lint:
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: \
cannon \
clean \
test \
lint
lint \
fuzz
This diff is collapsed.
This diff is collapsed.
......@@ -6,6 +6,16 @@ import (
"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) {
preimage := m.lastPreimage
if key != m.lastPreimageKey {
......@@ -43,7 +53,7 @@ func (m *InstrumentedState) handleSyscall() error {
//fmt.Printf("syscall: %d\n", syscallNum)
switch syscallNum {
case 4090: // mmap
case sysMmap:
sz := a1
if sz&PageAddrMask != 0 { // adjust size to align with page size
sz += PageSize - (sz & PageAddrMask)
......@@ -56,15 +66,15 @@ func (m *InstrumentedState) handleSyscall() error {
v0 = a0
//fmt.Printf("mmap hint 0x%x size 0x%x\n", v0, sz)
}
case 4045: // brk
case sysBrk:
v0 = 0x40000000
case 4120: // clone (not supported)
case sysClone: // clone (not supported)
v0 = 1
case 4246: // exit_group
case sysExitGroup:
m.state.Exited = true
m.state.ExitCode = uint8(a0)
return nil
case 4003: // read
case sysRead:
// args: a0 = fd, a1 = addr, a2 = count
// returns: v0 = read, v1 = err code
switch a0 {
......@@ -98,7 +108,7 @@ func (m *InstrumentedState) handleSyscall() error {
v0 = 0xFFffFFff
v1 = MipsEBADF
}
case 4004: // write
case sysWrite:
// args: a0 = fd, a1 = addr, a2 = count
// returns: v0 = written, v1 = err code
switch a0 {
......@@ -144,7 +154,7 @@ func (m *InstrumentedState) handleSyscall() error {
v0 = 0xFFffFFff
v1 = MipsEBADF
}
case 4055: // fcntl
case sysFcntl:
// args: a0 = fd, a1 = cmd
if a1 == 3 { // F_GETFL: get file descriptor flags
switch a0 {
......
This diff is collapsed.
......@@ -11,6 +11,9 @@ import (
var (
ErrMissingTraceType = errors.New("missing trace type")
ErrMissingCannonDatadir = errors.New("missing cannon datadir")
ErrMissingCannonL2 = errors.New("missing cannon L2")
ErrMissingCannonBin = errors.New("missing cannon bin")
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")
......@@ -57,8 +60,15 @@ type Config struct {
GameDepth int // Depth of the game tree
TraceType TraceType // Type of trace
// Specific to the alphabet trace provider
AlphabetTrace string // String for the AlphabetTraceProvider
CannonDatadir string // Cannon Data Directory for the CannonTraceProvider
// 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
}
......@@ -67,8 +77,6 @@ func NewConfig(
l1EthRpc string,
gameAddress common.Address,
traceType TraceType,
alphabetTrace string,
cannonDatadir string,
agreeWithProposedOutput bool,
gameDepth int,
) Config {
......@@ -80,8 +88,6 @@ func NewConfig(
GameDepth: gameDepth,
TraceType: traceType,
AlphabetTrace: alphabetTrace,
CannonDatadir: cannonDatadir,
TxMgrConfig: txmgr.NewCLIConfig(l1EthRpc),
}
......@@ -97,9 +103,20 @@ func (c Config) Check() error {
if c.TraceType == "" {
return ErrMissingTraceType
}
if c.TraceType == TraceTypeCannon && c.CannonDatadir == "" {
if c.TraceType == TraceTypeCannon {
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 == "" {
return ErrMissingAlphabetTrace
}
......
......@@ -12,20 +12,37 @@ var (
validL1EthRpc = "http://localhost:8545"
validGameAddress = common.HexToAddress("0x7bdd3b028C4796eF0EAf07d11394d0d9d8c24139")
validAlphabetTrace = "abcdefgh"
validCannonBin = "./bin/cannon"
validCannonAbsolutPreState = "pre.json"
validCannonDatadir = "/tmp/cannon"
validCannonL2 = "http://localhost:9545"
agreeWithProposedOutput = true
gameDepth = 4
)
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
}
// TestValidConfigIsValid checks that the config provided by validConfig is actually valid
func TestValidConfigIsValid(t *testing.T) {
err := validConfig(TraceTypeCannon).Check()
for _, traceType := range TraceTypes {
traceType := traceType
t.Run(traceType.String(), func(t *testing.T) {
err := validConfig(traceType).Check()
require.NoError(t, err)
})
}
}
func TestTxMgrConfig(t *testing.T) {
......@@ -40,30 +57,40 @@ func TestL1EthRpcRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.L1EthRpc = ""
require.ErrorIs(t, config.Check(), ErrMissingL1EthRPC)
config.L1EthRpc = validL1EthRpc
require.NoError(t, config.Check())
}
func TestGameAddressRequired(t *testing.T) {
config := validConfig(TraceTypeCannon)
config.GameAddress = common.Address{}
require.ErrorIs(t, config.Check(), ErrMissingGameAddress)
config.GameAddress = validGameAddress
require.NoError(t, config.Check())
}
func TestAlphabetTraceRequired(t *testing.T) {
config := validConfig(TraceTypeAlphabet)
config.AlphabetTrace = ""
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.CannonDatadir = ""
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 (
// Optional Flags
AlphabetFlag = &cli.StringFlag{
Name: "alphabet",
Usage: "Alphabet Trace (temporary)",
Usage: "Correct Alphabet Trace (alphabet trace type only)",
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{
Name: "cannon-datadir",
Usage: "Cannon Data Directory",
Usage: "Directory to store data generated by cannon (cannon trace type only)",
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]
......@@ -77,7 +92,10 @@ var requiredFlags = []cli.Flag{
// optionalFlags is a list of unchecked cli flags
var optionalFlags = []cli.Flag{
AlphabetFlag,
CannonBinFlag,
CannonPreStateFlag,
CannonDatadirFlag,
CannonL2Flag,
}
func init() {
......@@ -99,8 +117,17 @@ func CheckRequired(ctx *cli.Context) error {
gameType := config.TraceType(strings.ToLower(ctx.String(TraceTypeFlag.Name)))
switch gameType {
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) {
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:
if !ctx.IsSet(AlphabetFlag.Name) {
......@@ -132,7 +159,10 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
TraceType: traceTypeFlag,
GameAddress: dgfAddress,
AlphabetTrace: ctx.String(AlphabetFlag.Name),
CannonBin: ctx.String(CannonBinFlag.Name),
CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name),
CannonDatadir: ctx.String(CannonDatadirFlag.Name),
CannonL2: ctx.String(CannonL2Flag.Name),
AgreeWithProposedOutput: ctx.Bool(AgreeWithProposedOutputFlag.Name),
GameDepth: ctx.Int(GameDepthFlag.Name),
TxMgrConfig: txMgrConfig,
......
......@@ -109,7 +109,7 @@ func (s *L1Miner) ActL1IncludeTx(from common.Address) Action {
func (s *L1Miner) IncludeTx(t Testing, tx *types.Transaction) {
from, err := s.l1Signer.Sender(tx)
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 {
t.Fatalf("tx consumes %d gas, more than available in L1 block %d", tx.Gas(), s.l1BuildingHeader.GasLimit)
}
......
......@@ -7,6 +7,7 @@ import (
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
......@@ -15,6 +16,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"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-proposer/metrics"
"github.com/ethereum-optimism/optimism/op-proposer/proposer"
......@@ -31,6 +33,7 @@ type L2Proposer struct {
log log.Logger
l1 *ethclient.Client
driver *proposer.L2OutputSubmitter
contract *bindings.L2OutputOracleCaller
address common.Address
privKey *ecdsa.PrivateKey
contractAddr common.Address
......@@ -55,7 +58,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 {
proposerCfg := proposer.Config{
L2OutputOracleAddr: cfg.OutputOracleAddr,
PollInterval: time.Second,
......@@ -69,12 +71,20 @@ func NewL2Proposer(t Testing, log log.Logger, cfg *ProposerCfg, l1 *ethclient.Cl
dr, err := proposer.NewL2OutputSubmitter(proposerCfg, log, metrics.NoopMetrics)
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{
log: log,
l1: l1,
driver: dr,
address: crypto.PubkeyToAddress(cfg.ProposerKey.PublicKey),
contract: contract,
address: address,
privKey: cfg.ProposerKey,
contractAddr: cfg.OutputOracleAddr,
}
......
......@@ -231,6 +231,11 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *
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{
L1Cfg: l1Genesis,
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