Commit d15b39d7 authored by Adrian Sutton's avatar Adrian Sutton

op-challenger: Start support for executing cannon to generate traces

Net yet providing the local game data to pre-image oracle server.
parent cf41f5c4
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv" "strconv"
...@@ -13,22 +14,27 @@ import ( ...@@ -13,22 +14,27 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
const snapsDir = "snapshots" const (
snapsDir = "snapshots"
preimagesDir = "snapshots"
)
var snapshotNameRegexp = regexp.MustCompile(`^[0-9]+\.json$`) var snapshotNameRegexp = regexp.MustCompile(`^[0-9]+\.json$`)
const snapshotFrequency = 10_000
type snapshotSelect func(logger log.Logger, dir string, absolutePreState string, i uint64) (string, error) type snapshotSelect func(logger log.Logger, dir string, absolutePreState string, i uint64) (string, error)
type cmdExecutor func(ctx context.Context, binary string, args ...string) error
type Executor struct { type Executor struct {
logger log.Logger logger log.Logger
l1 string l1 string
l2 string l2 string
cannon string cannon string
server string
absolutePreState string absolutePreState string
dataDir string dataDir string
snapshotFreq uint
selectSnapshot snapshotSelect selectSnapshot snapshotSelect
cmdExecutor cmdExecutor
} }
func NewExecutor(logger log.Logger, cfg *config.Config) *Executor { func NewExecutor(logger log.Logger, cfg *config.Config) *Executor {
...@@ -37,9 +43,12 @@ func NewExecutor(logger log.Logger, cfg *config.Config) *Executor { ...@@ -37,9 +43,12 @@ func NewExecutor(logger log.Logger, cfg *config.Config) *Executor {
l1: cfg.L1EthRpc, l1: cfg.L1EthRpc,
l2: cfg.CannonL2, l2: cfg.CannonL2,
cannon: cfg.CannonBin, cannon: cfg.CannonBin,
server: cfg.CannonServer,
absolutePreState: cfg.CannonAbsolutePreState, absolutePreState: cfg.CannonAbsolutePreState,
dataDir: cfg.CannonDatadir, dataDir: cfg.CannonDatadir,
snapshotFreq: cfg.CannonSnapshotFreq,
selectSnapshot: findStartingSnapshot, selectSnapshot: findStartingSnapshot,
cmdExecutor: runCmd,
} }
} }
...@@ -48,8 +57,31 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro ...@@ -48,8 +57,31 @@ func (e *Executor) GenerateProof(ctx context.Context, dir string, i uint64) erro
if err != nil { if err != nil {
return fmt.Errorf("find starting snapshot: %w", err) return fmt.Errorf("find starting snapshot: %w", err)
} }
return fmt.Errorf("please execute cannon with --input %v --proof-at %v --proof-fmt %v/%v/%%d.json --snapshot-at %%%d --snapshot-fmt '%v/%v/%%d.json", proofIndexStr := strconv.FormatUint(i, 10)
start, i, dir, proofsDir, snapshotFrequency, dir, snapsDir) args := []string{
"--input", start,
"--proof-at", proofIndexStr,
"--proof-fmt", filepath.Join(dir, proofsDir, proofIndexStr+".json"),
"--snapshot-at", "%" + strconv.FormatUint(uint64(e.snapshotFreq), 10),
"--snapshot-fmt", filepath.Join(e.dataDir, snapsDir, "%d.json"),
"--",
e.server,
"--l1", e.l1,
"--l2", e.l2,
"--datadir", filepath.Join(e.dataDir, preimagesDir),
// TODO(CLI-4240): Pass local game inputs (l1.head, l2.head, l2.claim etc)
}
e.logger.Info("Generating trace", "idx", i, "cmd", e.cannon, "args", args)
return e.cmdExecutor(ctx, e.cannon, args...)
}
func runCmd(ctx context.Context, binary string, args ...string) error {
cmd := exec.CommandContext(ctx, binary, args...)
// TODO(CLI-4242): Provide context about what the generation is for in logs
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
} }
// findStartingSnapshot finds the closest snapshot before the specified traceIndex in snapDir. // findStartingSnapshot finds the closest snapshot before the specified traceIndex in snapDir.
......
package cannon package cannon
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-node/testlog" "github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
const execTestCannonPrestate = "/foo/pre.json" const execTestCannonPrestate = "/foo/pre.json"
func TestGenerateProof(t *testing.T) {
input := "starting.json"
cfg := config.NewConfig("http://localhost:8888", common.Address{0xaa}, config.TraceTypeCannon, true, 5)
cfg.CannonDatadir = t.TempDir()
cfg.CannonAbsolutePreState = "pre.json"
cfg.CannonBin = "./bin/cannon"
cfg.CannonServer = "./bin/op-program"
cfg.CannonL2 = "http://localhost:9999"
cfg.CannonSnapshotFreq = 500
executor := NewExecutor(testlog.Logger(t, log.LvlInfo), &cfg)
executor.selectSnapshot = func(logger log.Logger, dir string, absolutePreState string, i uint64) (string, error) {
return input, nil
}
var binary string
args := make(map[string]string)
executor.cmdExecutor = func(ctx context.Context, b string, a ...string) error {
binary = b
for i := 0; i < len(a); i += 2 {
args[a[i]] = a[i+1]
}
return nil
}
err := executor.GenerateProof(context.Background(), cfg.CannonDatadir, 150_000_000)
require.NoError(t, err)
require.Equal(t, cfg.CannonBin, binary)
require.Contains(t, args, "--input", input)
require.Contains(t, args, "--proof-at", "150000000")
require.Contains(t, args, "--snapshot-at", "%500")
require.Contains(t, args, "--", cfg.CannonServer)
require.Contains(t, args, "--l1", cfg.L1EthRpc)
require.Contains(t, args, "--l2", cfg.CannonL2)
require.Contains(t, args, "--datadir", filepath.Join(cfg.CannonDatadir, preimagesDir))
require.Contains(t, args, "--proof-fmt", filepath.Join(cfg.CannonDatadir, "150000000.json"))
require.Contains(t, args, "--snapshot-fmt", filepath.Join(cfg.CannonDatadir, snapsDir, "%d.json"))
}
func TestFindStartingSnapshot(t *testing.T) { func TestFindStartingSnapshot(t *testing.T) {
logger := testlog.Logger(t, log.LvlInfo) logger := testlog.Logger(t, log.LvlInfo)
......
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