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
import (
"context"
"errors"
"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/game/fault/trace/vm"
"github.com/ethereum-optimism/optimism/op-challenger/runner"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/ethereum-optimism/optimism/op-service/cliapp"
......@@ -27,18 +31,36 @@ func RunTrace(ctx *cli.Context, _ context.CancelCauseFunc) (cliapp.Lifecycle, er
if err := cfg.Check(); err != nil {
return nil, err
}
if ctx.IsSet(addMTCannonPrestate.Name) && cfg.CannonAbsolutePreStateBaseURL == nil {
return nil, fmt.Errorf("flag %v is required when using %v", flags.CannonPreStateFlag.Name, addMTCannonPrestate.Name)
if err := checkMTCannonFlags(ctx, cfg); err != nil {
return nil, err
}
var mtPrestate common.Hash
if ctx.IsSet(addMTCannonPrestate.Name) {
mtPrestate = common.HexToHash(ctx.String(addMTCannonPrestate.Name))
var mtPrestateURL *url.URL
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, 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 runner.NewRunner(logger, cfg, mtPrestate), nil
return nil
}
func runTraceFlags() []cli.Flag {
return append(flags.Flags, addMTCannonPrestate)
return append(flags.Flags, addMTCannonPrestateFlag, addMTCannonPrestateURLFlag)
}
var RunTraceCommand = &cli.Command{
......@@ -49,8 +71,15 @@ var RunTraceCommand = &cli.Command{
Flags: runTraceFlags(),
}
var addMTCannonPrestate = &cli.StringFlag{
Name: "add-mt-cannon-prestate",
Usage: "Use this prestate to run MT-Cannon compatibility tests",
EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "ADD_MT_CANNON_PRESTATE"),
}
var (
addMTCannonPrestateFlag = &cli.StringFlag{
Name: "add-mt-cannon-prestate",
Usage: "Use this prestate to run MT-Cannon compatibility tests",
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(
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) {
prestateSource := prestates.NewPrestateSource(
prestateBaseUrl,
......
......@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"math/big"
"net/url"
"os"
"path/filepath"
"sync"
......@@ -42,10 +43,11 @@ type Metricer interface {
}
type Runner struct {
log log.Logger
cfg *config.Config
addMTCannonPrestate common.Hash
m Metricer
log log.Logger
cfg *config.Config
addMTCannonPrestate common.Hash
addMTCannonPrestateURL *url.URL
m Metricer
running atomic.Bool
ctx context.Context
......@@ -54,12 +56,13 @@ type Runner struct {
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{
log: logger,
cfg: cfg,
addMTCannonPrestate: mtCannonPrestate,
m: NewMetrics(),
log: logger,
cfg: cfg,
addMTCannonPrestate: mtCannonPrestate,
addMTCannonPrestateURL: mtCannonPrestateURL,
m: NewMetrics(),
}
}
......@@ -148,16 +151,17 @@ func (r *Runner) runAndRecordOnce(ctx context.Context, traceType types.TraceType
recordError(err, traceType.String(), r.m, r.log)
}()
if r.addMTCannonPrestate != (common.Hash{}) {
if r.addMTCannonPrestate != (common.Hash{}) && r.addMTCannonPrestateURL != nil {
wg.Add(1)
go func() {
defer wg.Done()
dir, err := r.prepDatadir("mt-cannon")
if err != nil {
recordError(err, traceType.String(), r.m, r.log)
recordError(err, "mt-cannon", r.m, r.log)
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))
}()
}
......@@ -179,6 +183,21 @@ func (r *Runner) runOnce(ctx context.Context, logger log.Logger, traceType types
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) {
dir := filepath.Join(r.cfg.Datadir, traceType)
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