Commit b49317b1 authored by Adrian Sutton's avatar Adrian Sutton

op-e2e: Fix issues running cannon

Ensure op-program is in server mode.
Avoid overflow when calculating --stop-at value
parent 64bc4d78
...@@ -4,11 +4,13 @@ import ( ...@@ -4,11 +4,13 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"math"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv" "strconv"
"strings"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
oplog "github.com/ethereum-optimism/optimism/op-service/log" oplog "github.com/ethereum-optimism/optimism/op-service/log"
...@@ -75,12 +77,11 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro ...@@ -75,12 +77,11 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro
"--output", filepath.Join(dir, "out.json"), "--output", filepath.Join(dir, "out.json"),
"--meta", "", "--meta", "",
"--proof-at", "=" + strconv.FormatUint(i, 10), "--proof-at", "=" + strconv.FormatUint(i, 10),
"--stop-at", "=" + strconv.FormatUint(i+1, 10),
"--proof-fmt", filepath.Join(proofDir, "%d.json"), "--proof-fmt", filepath.Join(proofDir, "%d.json"),
"--snapshot-at", "%" + strconv.FormatUint(uint64(e.snapshotFreq), 10), "--snapshot-at", "%" + strconv.FormatUint(uint64(e.snapshotFreq), 10),
"--snapshot-fmt", filepath.Join(snapshotDir, "%d.json"), "--snapshot-fmt", filepath.Join(snapshotDir, "%d.json"),
"--", "--",
e.server, e.server, "--server",
"--l1", e.l1, "--l1", e.l1,
"--l2", e.l2, "--l2", e.l2,
"--datadir", dataDir, "--datadir", dataDir,
...@@ -90,6 +91,9 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro ...@@ -90,6 +91,9 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro
"--l2.claim", e.inputs.l2Claim.Hex(), "--l2.claim", e.inputs.l2Claim.Hex(),
"--l2.blocknumber", e.inputs.l2BlockNumber.Text(10), "--l2.blocknumber", e.inputs.l2BlockNumber.Text(10),
} }
if i < math.MaxUint64 {
args = append(args, "--stop-at", "="+strconv.FormatUint(i+1, 10))
}
if e.network != "" { if e.network != "" {
args = append(args, "--network", e.network) args = append(args, "--network", e.network)
} }
...@@ -109,7 +113,7 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro ...@@ -109,7 +113,7 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro
if err := os.MkdirAll(proofDir, 0755); err != nil { if err := os.MkdirAll(proofDir, 0755); err != nil {
return fmt.Errorf("could not create proofs directory %v: %w", proofDir, err) return fmt.Errorf("could not create proofs directory %v: %w", proofDir, err)
} }
e.logger.Info("Generating trace", "proof", i, "cmd", e.cannon, "args", args) e.logger.Info("Generating trace", "proof", i, "cmd", e.cannon, "args", strings.Join(args, ", "))
return e.cmdExecutor(ctx, e.logger.New("proof", i), e.cannon, args...) return e.cmdExecutor(ctx, e.logger.New("proof", i), e.cannon, args...)
} }
...@@ -117,7 +121,8 @@ func runCmd(ctx context.Context, l log.Logger, binary string, args ...string) er ...@@ -117,7 +121,8 @@ func runCmd(ctx context.Context, l log.Logger, binary string, args ...string) er
cmd := exec.CommandContext(ctx, binary, args...) cmd := exec.CommandContext(ctx, binary, args...)
stdOut := oplog.NewWriter(l, log.LvlInfo) stdOut := oplog.NewWriter(l, log.LvlInfo)
defer stdOut.Close() defer stdOut.Close()
stdErr := oplog.NewWriter(l, log.LvlError) // Keep stdErr at info level because cannon uses stderr for progress messages
stdErr := oplog.NewWriter(l, log.LvlInfo)
defer stdErr.Close() defer stdErr.Close()
cmd.Stdout = stdOut cmd.Stdout = stdOut
cmd.Stderr = stdErr cmd.Stderr = stdErr
......
...@@ -3,6 +3,7 @@ package cannon ...@@ -3,6 +3,7 @@ package cannon
import ( import (
"context" "context"
"fmt" "fmt"
"math"
"math/big" "math/big"
"os" "os"
"path/filepath" "path/filepath"
...@@ -35,7 +36,7 @@ func TestGenerateProof(t *testing.T) { ...@@ -35,7 +36,7 @@ func TestGenerateProof(t *testing.T) {
l2Claim: common.Hash{0x44}, l2Claim: common.Hash{0x44},
l2BlockNumber: big.NewInt(3333), l2BlockNumber: big.NewInt(3333),
} }
captureExec := func(cfg config.Config) (string, string, map[string]string) { captureExec := func(cfg config.Config, proofAt uint64) (string, string, map[string]string) {
executor := NewExecutor(testlog.Logger(t, log.LvlInfo), &cfg, inputs) executor := NewExecutor(testlog.Logger(t, log.LvlInfo), &cfg, inputs)
executor.selectSnapshot = func(logger log.Logger, dir string, absolutePreState string, i uint64) (string, error) { executor.selectSnapshot = func(logger log.Logger, dir string, absolutePreState string, i uint64) (string, error) {
return input, nil return input, nil
...@@ -46,12 +47,18 @@ func TestGenerateProof(t *testing.T) { ...@@ -46,12 +47,18 @@ func TestGenerateProof(t *testing.T) {
executor.cmdExecutor = func(ctx context.Context, l log.Logger, b string, a ...string) error { executor.cmdExecutor = func(ctx context.Context, l log.Logger, b string, a ...string) error {
binary = b binary = b
subcommand = a[0] subcommand = a[0]
for i := 1; i < len(a); i += 2 { for i := 1; i < len(a); {
if a[i] == "--" {
// Skip over the divider between cannon and server program
i += 1
continue
}
args[a[i]] = a[i+1] args[a[i]] = a[i+1]
i += 2
} }
return nil return nil
} }
err := executor.GenerateProof(context.Background(), cfg.CannonDatadir, 150_000_000) err := executor.GenerateProof(context.Background(), cfg.CannonDatadir, proofAt)
require.NoError(t, err) require.NoError(t, err)
return binary, subcommand, args return binary, subcommand, args
} }
...@@ -60,7 +67,7 @@ func TestGenerateProof(t *testing.T) { ...@@ -60,7 +67,7 @@ func TestGenerateProof(t *testing.T) {
cfg.CannonNetwork = "mainnet" cfg.CannonNetwork = "mainnet"
cfg.CannonRollupConfigPath = "" cfg.CannonRollupConfigPath = ""
cfg.CannonL2GenesisPath = "" cfg.CannonL2GenesisPath = ""
binary, subcommand, args := captureExec(cfg) binary, subcommand, args := captureExec(cfg, 150_000_000)
require.DirExists(t, filepath.Join(cfg.CannonDatadir, preimagesDir)) require.DirExists(t, filepath.Join(cfg.CannonDatadir, preimagesDir))
require.DirExists(t, filepath.Join(cfg.CannonDatadir, proofsDir)) require.DirExists(t, filepath.Join(cfg.CannonDatadir, proofsDir))
require.DirExists(t, filepath.Join(cfg.CannonDatadir, snapsDir)) require.DirExists(t, filepath.Join(cfg.CannonDatadir, snapsDir))
...@@ -73,7 +80,10 @@ func TestGenerateProof(t *testing.T) { ...@@ -73,7 +80,10 @@ func TestGenerateProof(t *testing.T) {
require.Equal(t, "=150000000", args["--proof-at"]) require.Equal(t, "=150000000", args["--proof-at"])
require.Equal(t, "=150000001", args["--stop-at"]) require.Equal(t, "=150000001", args["--stop-at"])
require.Equal(t, "%500", args["--snapshot-at"]) require.Equal(t, "%500", args["--snapshot-at"])
require.Equal(t, cfg.CannonServer, args["--"]) // Slight quirk of how we pair off args
// The server binary winds up as the key and the first arg --server as the value which has no value
// Then everything else pairs off correctly again
require.Equal(t, "--server", args[cfg.CannonServer])
require.Equal(t, cfg.L1EthRpc, args["--l1"]) require.Equal(t, cfg.L1EthRpc, args["--l1"])
require.Equal(t, cfg.CannonL2, args["--l2"]) require.Equal(t, cfg.CannonL2, args["--l2"])
require.Equal(t, filepath.Join(cfg.CannonDatadir, preimagesDir), args["--datadir"]) require.Equal(t, filepath.Join(cfg.CannonDatadir, preimagesDir), args["--datadir"])
...@@ -95,11 +105,21 @@ func TestGenerateProof(t *testing.T) { ...@@ -95,11 +105,21 @@ func TestGenerateProof(t *testing.T) {
cfg.CannonNetwork = "" cfg.CannonNetwork = ""
cfg.CannonRollupConfigPath = "rollup.json" cfg.CannonRollupConfigPath = "rollup.json"
cfg.CannonL2GenesisPath = "genesis.json" cfg.CannonL2GenesisPath = "genesis.json"
_, _, args := captureExec(cfg) _, _, args := captureExec(cfg, 150_000_000)
require.NotContains(t, args, "--network") require.NotContains(t, args, "--network")
require.Equal(t, cfg.CannonRollupConfigPath, args["--rollup.config"]) require.Equal(t, cfg.CannonRollupConfigPath, args["--rollup.config"])
require.Equal(t, cfg.CannonL2GenesisPath, args["--l2.genesis"]) require.Equal(t, cfg.CannonL2GenesisPath, args["--l2.genesis"])
}) })
t.Run("NoStopAtWhenProofIsMaxUInt", func(t *testing.T) {
cfg.CannonNetwork = "mainnet"
cfg.CannonRollupConfigPath = "rollup.json"
cfg.CannonL2GenesisPath = "genesis.json"
_, _, args := captureExec(cfg, math.MaxUint64)
// stop-at would need to be one more than the proof step which would overflow back to 0
// so expect that it will be omitted. We'll ultimately want cannon to execute until the program exits.
require.NotContains(t, args, "--stop-at")
})
} }
func TestRunCmdLogsOutput(t *testing.T) { func TestRunCmdLogsOutput(t *testing.T) {
......
...@@ -173,8 +173,10 @@ func TestCannonDisputeGame(t *testing.T) { ...@@ -173,8 +173,10 @@ func TestCannonDisputeGame(t *testing.T) {
func startFaultDisputeSystem(t *testing.T) (*System, *ethclient.Client) { func startFaultDisputeSystem(t *testing.T) (*System, *ethclient.Client) {
cfg := DefaultSystemConfig(t) cfg := DefaultSystemConfig(t)
delete(cfg.Nodes, "verifier") delete(cfg.Nodes, "verifier")
cfg.DeployConfig.SequencerWindowSize = 4
cfg.DeployConfig.FinalizationPeriodSeconds = 2
cfg.SupportL1TimeTravel = true cfg.SupportL1TimeTravel = true
cfg.DeployConfig.L2OutputOracleSubmissionInterval = 2 cfg.DeployConfig.L2OutputOracleSubmissionInterval = 1
cfg.NonFinalizedProposals = true // Submit output proposals asap cfg.NonFinalizedProposals = true // Submit output proposals asap
sys, err := cfg.Start() sys, err := cfg.Start()
require.NoError(t, err, "Error starting up system") require.NoError(t, err, "Error starting up system")
......
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