Commit 43ec97dd authored by Inphi's avatar Inphi Committed by GitHub

vm-runner: User-provided mt-cannon absolute prestate URL (#12016)

* vm-runner: User-provided mt-cannon absolute prestate URL

* placate semgrep
parent 45a266e7
...@@ -2,9 +2,13 @@ package main ...@@ -2,9 +2,13 @@ package main
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"net/url"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/flags" "github.com/ethereum-optimism/optimism/op-challenger/flags"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/vm"
"github.com/ethereum-optimism/optimism/op-challenger/runner" "github.com/ethereum-optimism/optimism/op-challenger/runner"
opservice "github.com/ethereum-optimism/optimism/op-service" opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/cliapp" "github.com/ethereum-optimism/optimism/op-service/cliapp"
...@@ -27,18 +31,36 @@ func RunTrace(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, er ...@@ -27,18 +31,36 @@ func RunTrace(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, er
if err := cfg.Check(); err != nil { if err := cfg.Check(); err != nil {
return nil, err return nil, err
} }
if ctx.IsSet(addMTCannonPrestate.Name) && cfg.CannonAbsolutePreStateBaseURL == nil { if err := checkMTCannonFlags(ctx, cfg); err != nil {
return nil, fmt.Errorf("flag %v is required when using %v", flags.CannonPreStateFlag.Name, addMTCannonPrestate.Name) return nil, err
} }
var mtPrestate common.Hash var mtPrestate common.Hash
if ctx.IsSet(addMTCannonPrestate.Name) { var mtPrestateURL *url.URL
mtPrestate = common.HexToHash(ctx.String(addMTCannonPrestate.Name)) if ctx.IsSet(addMTCannonPrestateFlag.Name) {
mtPrestate = common.HexToHash(ctx.String(addMTCannonPrestateFlag.Name))
mtPrestateURL, err = url.Parse(ctx.String(addMTCannonPrestateURLFlag.Name))
if err != nil {
return nil, fmt.Errorf("invalid mt-cannon prestate url (%v): %w", ctx.String(addMTCannonPrestateFlag.Name), err)
}
} }
return runner.NewRunner(logger, cfg, mtPrestate), nil return runner.NewRunner(logger, cfg, mtPrestate, mtPrestateURL), nil
}
func checkMTCannonFlags(ctx *cli.Context, cfg *config.Config) error {
if ctx.IsSet(addMTCannonPrestateFlag.Name) || ctx.IsSet(addMTCannonPrestateURLFlag.Name) {
if ctx.IsSet(addMTCannonPrestateFlag.Name) != ctx.IsSet(addMTCannonPrestateURLFlag.Name) {
return fmt.Errorf("both flag %v and %v must be set when running MT-Cannon traces", addMTCannonPrestateURLFlag.Name, addMTCannonPrestateFlag.Name)
}
if cfg.Cannon == (vm.Config{}) {
return errors.New("required Cannon vm configuration for mt-cannon traces is missing")
}
}
return nil
} }
func runTraceFlags() []cli.Flag { func runTraceFlags() []cli.Flag {
return append(flags.Flags, addMTCannonPrestate) return append(flags.Flags, addMTCannonPrestateFlag, addMTCannonPrestateURLFlag)
} }
var RunTraceCommand = &cli.Command{ var RunTraceCommand = &cli.Command{
...@@ -49,8 +71,15 @@ var RunTraceCommand = &cli.Command{ ...@@ -49,8 +71,15 @@ var RunTraceCommand = &cli.Command{
Flags: runTraceFlags(), Flags: runTraceFlags(),
} }
var addMTCannonPrestate = &cli.StringFlag{ var (
addMTCannonPrestateFlag = &cli.StringFlag{
Name: "add-mt-cannon-prestate", Name: "add-mt-cannon-prestate",
Usage: "Use this prestate to run MT-Cannon compatibility tests", Usage: "Use this prestate to run MT-Cannon compatibility tests",
EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ADD_MT_CANNON_PRESTATE"), EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ADD_MT_CANNON_PRESTATE"),
} }
addMTCannonPrestateURLFlag = &cli.StringFlag{
Name: "add-mt-cannon-prestate-url",
Usage: "Use this prestate URL to run MT-Cannon compatibility tests",
EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ADD_MT_CANNON_PRESTATE_URL"),
}
)
...@@ -58,6 +58,28 @@ func createTraceProvider( ...@@ -58,6 +58,28 @@ func createTraceProvider(
return nil, errors.New("invalid trace type") return nil, errors.New("invalid trace type")
} }
func createMTTraceProvider(
logger log.Logger,
m vm.Metricer,
vmConfig vm.Config,
prestateHash common.Hash,
absolutePrestateBaseURL *url.URL,
traceType types.TraceType,
localInputs utils.LocalGameInputs,
dir string,
) (types.TraceProvider, error) {
executor := vm.NewOpProgramServerExecutor()
stateConverter := cannon.NewStateConverter()
prestateSource := prestates.NewMultiPrestateProvider(absolutePrestateBaseURL, filepath.Join(dir, "prestates"), cannon.NewStateConverter())
prestatePath, err := prestateSource.PrestatePath(prestateHash)
if err != nil {
return nil, fmt.Errorf("failed to get prestate %v: %w", prestateHash, err)
}
prestateProvider := vm.NewPrestateProvider(prestatePath, stateConverter)
return cannon.NewTraceProvider(logger, m, vmConfig, executor, prestateProvider, prestatePath, localInputs, dir, 42), nil
}
func getPrestate(prestateHash common.Hash, prestateBaseUrl *url.URL, prestatePath string, dataDir string, stateConverter vm.StateConverter) (string, error) { func getPrestate(prestateHash common.Hash, prestateBaseUrl *url.URL, prestatePath string, dataDir string, stateConverter vm.StateConverter) (string, error) {
prestateSource := prestates.NewPrestateSource( prestateSource := prestates.NewPrestateSource(
prestateBaseUrl, prestateBaseUrl,
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
...@@ -45,6 +46,7 @@ type Runner struct { ...@@ -45,6 +46,7 @@ type Runner struct {
log log.Logger log log.Logger
cfg *config.Config cfg *config.Config
addMTCannonPrestate common.Hash addMTCannonPrestate common.Hash
addMTCannonPrestateURL *url.URL
m Metricer m Metricer
running atomic.Bool running atomic.Bool
...@@ -54,11 +56,12 @@ type Runner struct { ...@@ -54,11 +56,12 @@ type Runner struct {
metricsSrv *httputil.HTTPServer metricsSrv *httputil.HTTPServer
} }
func NewRunner(logger log.Logger, cfg *config.Config, mtCannonPrestate common.Hash) *Runner { func NewRunner(logger log.Logger, cfg *config.Config, mtCannonPrestate common.Hash, mtCannonPrestateURL *url.URL) *Runner {
return &Runner{ return &Runner{
log: logger, log: logger,
cfg: cfg, cfg: cfg,
addMTCannonPrestate: mtCannonPrestate, addMTCannonPrestate: mtCannonPrestate,
addMTCannonPrestateURL: mtCannonPrestateURL,
m: NewMetrics(), m: NewMetrics(),
} }
} }
...@@ -148,16 +151,17 @@ func (r *Runner) runAndRecordOnce(ctx context.Context, traceType types.TraceType ...@@ -148,16 +151,17 @@ func (r *Runner) runAndRecordOnce(ctx context.Context, traceType types.TraceType
recordError(err, traceType.String(), r.m, r.log) recordError(err, traceType.String(), r.m, r.log)
}() }()
if r.addMTCannonPrestate != (common.Hash{}) { if r.addMTCannonPrestate != (common.Hash{}) && r.addMTCannonPrestateURL != nil {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
dir, err := r.prepDatadir("mt-cannon") dir, err := r.prepDatadir("mt-cannon")
if err != nil { if err != nil {
recordError(err, traceType.String(), r.m, r.log) recordError(err, "mt-cannon", r.m, r.log)
return return
} }
err = r.runOnce(ctx, inputsLogger.With("type", "mt-cannon"), types.TraceTypeCannon, r.addMTCannonPrestate, localInputs, dir) logger := inputsLogger.With("type", "mt-cannon")
err = r.runMTOnce(ctx, logger, traceType, prestateHash, localInputs, dir)
recordError(err, traceType.String(), r.m, r.log.With("mt-cannon", true)) recordError(err, traceType.String(), r.m, r.log.With("mt-cannon", true))
}() }()
} }
...@@ -179,6 +183,21 @@ func (r *Runner) runOnce(ctx context.Context, logger log.Logger, traceType types ...@@ -179,6 +183,21 @@ func (r *Runner) runOnce(ctx context.Context, logger log.Logger, traceType types
return nil return nil
} }
func (r *Runner) runMTOnce(ctx context.Context, logger log.Logger, traceType types.TraceType, prestateHash common.Hash, localInputs utils.LocalGameInputs, dir string) error {
provider, err := createMTTraceProvider(logger, r.m, r.cfg.Cannon, r.addMTCannonPrestate, r.addMTCannonPrestateURL, types.TraceTypeCannon, localInputs, dir)
if err != nil {
return fmt.Errorf("failed to create trace provider: %w", err)
}
hash, err := provider.Get(ctx, types.RootPosition)
if err != nil {
return fmt.Errorf("failed to execute trace provider: %w", err)
}
if hash[0] != mipsevm.VMStatusValid {
return fmt.Errorf("%w: %v", ErrUnexpectedStatusCode, hash)
}
return nil
}
func (r *Runner) prepDatadir(traceType string) (string, error) { func (r *Runner) prepDatadir(traceType string) (string, error) {
dir := filepath.Join(r.cfg.Datadir, traceType) dir := filepath.Join(r.cfg.Datadir, traceType)
if err := os.RemoveAll(dir); err != nil { if err := os.RemoveAll(dir); err != nil {
......
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