Skip to content

Commit

Permalink
op-challenger: Support multiple asterisc prestates (ethereum-optimism…
Browse files Browse the repository at this point in the history
…#10313)

* op-challenger: Apply multiple prestates for asterisc

* op-challenger: Add asterisc-prestates-url flag to configure a source for prestates based on hash
  • Loading branch information
pcw109550 authored Apr 26, 2024
1 parent 113e274 commit 8447d16
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 91 deletions.
17 changes: 16 additions & 1 deletion op-challenger/cmd/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ func TestAsteriscRequiredArgs(t *testing.T) {
})

t.Run("Required", func(t *testing.T) {
verifyArgsInvalid(t, "flag asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate"))
verifyArgsInvalid(t, "flag asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate"))
})

t.Run("Valid", func(t *testing.T) {
Expand All @@ -299,6 +299,21 @@ func TestAsteriscRequiredArgs(t *testing.T) {
})
})

t.Run(fmt.Sprintf("TestAsteriscAbsolutePrestateBaseURL-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTrace", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--asterisc-prestates-url"))
})

t.Run("Required", func(t *testing.T) {
verifyArgsInvalid(t, "flag asterisc-prestates-url or asterisc-prestate is required", addRequiredArgsExcept(traceType, "--asterisc-prestate"))
})

t.Run("Valid", func(t *testing.T) {
cfg := configForArgs(t, addRequiredArgsExcept(traceType, "--asterisc-prestates-url", "--asterisc-prestates-url=http://localhost/bar"))
require.Equal(t, "http://localhost/bar", cfg.AsteriscAbsolutePreStateBaseURL.String())
})
})

t.Run(fmt.Sprintf("TestL2Rpc-%v", traceType), func(t *testing.T) {
t.Run("NotRequiredForAlphabetTraceLegacy", func(t *testing.T) {
configForArgs(t, addRequiredArgsExcept(config.TraceTypeAlphabet, "--cannon-l2"))
Expand Down
43 changes: 24 additions & 19 deletions op-challenger/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,17 @@ var (
ErrCannonNetworkUnknown = errors.New("unknown cannon network")
ErrMissingRollupRpc = errors.New("missing rollup rpc url")

ErrMissingAsteriscBin = errors.New("missing asterisc bin")
ErrMissingAsteriscServer = errors.New("missing asterisc server")
ErrMissingAsteriscAbsolutePreState = errors.New("missing asterisc absolute pre-state")
ErrMissingAsteriscSnapshotFreq = errors.New("missing asterisc snapshot freq")
ErrMissingAsteriscInfoFreq = errors.New("missing asterisc info freq")
ErrMissingAsteriscRollupConfig = errors.New("missing asterisc network or rollup config path")
ErrMissingAsteriscL2Genesis = errors.New("missing asterisc network or l2 genesis path")
ErrAsteriscNetworkAndRollupConfig = errors.New("only specify one of network or rollup config path")
ErrAsteriscNetworkAndL2Genesis = errors.New("only specify one of network or l2 genesis path")
ErrAsteriscNetworkUnknown = errors.New("unknown asterisc network")
ErrMissingAsteriscBin = errors.New("missing asterisc bin")
ErrMissingAsteriscServer = errors.New("missing asterisc server")
ErrMissingAsteriscAbsolutePreState = errors.New("missing asterisc absolute pre-state")
ErrAsteriscAbsolutePreStateAndBaseURL = errors.New("only specify one of asterisc absolute pre-state and asterisc absolute pre-state base URL")
ErrMissingAsteriscSnapshotFreq = errors.New("missing asterisc snapshot freq")
ErrMissingAsteriscInfoFreq = errors.New("missing asterisc info freq")
ErrMissingAsteriscRollupConfig = errors.New("missing asterisc network or rollup config path")
ErrMissingAsteriscL2Genesis = errors.New("missing asterisc network or l2 genesis path")
ErrAsteriscNetworkAndRollupConfig = errors.New("only specify one of network or rollup config path")
ErrAsteriscNetworkAndL2Genesis = errors.New("only specify one of network or l2 genesis path")
ErrAsteriscNetworkUnknown = errors.New("unknown asterisc network")
)

type TraceType string
Expand Down Expand Up @@ -137,14 +138,15 @@ type Config struct {
CannonInfoFreq uint // Frequency of cannon progress log messages (in VM instructions)

// Specific to the asterisc trace provider
AsteriscBin string // Path to the asterisc executable to run when generating trace data
AsteriscServer string // Path to the op-program executable that provides the pre-image oracle server
AsteriscAbsolutePreState string // File to load the absolute pre-state for Asterisc traces from
AsteriscNetwork string
AsteriscRollupConfigPath string
AsteriscL2GenesisPath string
AsteriscSnapshotFreq uint // Frequency of snapshots to create when executing asterisc (in VM instructions)
AsteriscInfoFreq uint // Frequency of asterisc progress log messages (in VM instructions)
AsteriscBin string // Path to the asterisc executable to run when generating trace data
AsteriscServer string // Path to the op-program executable that provides the pre-image oracle server
AsteriscAbsolutePreState string // File to load the absolute pre-state for Asterisc traces from
AsteriscAbsolutePreStateBaseURL *url.URL // Base URL to retrieve absolute pre-states for Asterisc traces from
AsteriscNetwork string
AsteriscRollupConfigPath string
AsteriscL2GenesisPath string
AsteriscSnapshotFreq uint // Frequency of snapshots to create when executing asterisc (in VM instructions)
AsteriscInfoFreq uint // Frequency of asterisc progress log messages (in VM instructions)

MaxPendingTx uint64 // Maximum number of pending transactions (0 == no limit)

Expand Down Expand Up @@ -277,9 +279,12 @@ func (c Config) Check() error {
return fmt.Errorf("%w: %v", ErrAsteriscNetworkUnknown, c.AsteriscNetwork)
}
}
if c.AsteriscAbsolutePreState == "" {
if c.AsteriscAbsolutePreState == "" && c.AsteriscAbsolutePreStateBaseURL == nil {
return ErrMissingAsteriscAbsolutePreState
}
if c.AsteriscAbsolutePreState != "" && c.AsteriscAbsolutePreStateBaseURL != nil {
return ErrAsteriscAbsolutePreStateAndBaseURL
}
if c.L2Rpc == "" {
return ErrMissingL2Rpc
}
Expand Down
120 changes: 115 additions & 5 deletions op-challenger/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ var (
validL2Rpc = "http://localhost:9545"
validRollupRpc = "http://localhost:8555"

validAsteriscBin = "./bin/asterisc"
validAsteriscOpProgramBin = "./bin/op-program"
validAsteriscNetwork = "mainnet"
validAsteriscAbsolutPreState = "pre.json"
validAsteriscBin = "./bin/asterisc"
validAsteriscOpProgramBin = "./bin/op-program"
validAsteriscNetwork = "mainnet"
validAsteriscAbsolutPreState = "pre.json"
validAsteriscAbsolutPreStateBaseURL, _ = url.Parse("http://localhost/bar/")
)

var cannonTraceTypes = []TraceType{TraceTypeCannon, TraceTypePermissioned}
var asteriscTraceTypes = []TraceType{TraceTypeAsterisc}

func applyValidConfigForCannon(cfg *Config) {
cfg.CannonBin = validCannonBin
Expand All @@ -44,7 +46,7 @@ func applyValidConfigForCannon(cfg *Config) {
func applyValidConfigForAsterisc(cfg *Config) {
cfg.AsteriscBin = validAsteriscBin
cfg.AsteriscServer = validAsteriscOpProgramBin
cfg.AsteriscAbsolutePreState = validAsteriscAbsolutPreState
cfg.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutPreStateBaseURL
cfg.AsteriscNetwork = validAsteriscNetwork
cfg.L2Rpc = validL2Rpc
}
Expand Down Expand Up @@ -216,6 +218,112 @@ func TestCannonRequiredArgs(t *testing.T) {
}
}

func TestAsteriscRequiredArgs(t *testing.T) {
for _, traceType := range asteriscTraceTypes {
traceType := traceType

t.Run(fmt.Sprintf("TestAsteriscBinRequired-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.AsteriscBin = ""
require.ErrorIs(t, config.Check(), ErrMissingAsteriscBin)
})

t.Run(fmt.Sprintf("TestAsteriscServerRequired-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.AsteriscServer = ""
require.ErrorIs(t, config.Check(), ErrMissingAsteriscServer)
})

t.Run(fmt.Sprintf("TestAsteriscAbsolutePreStateOrBaseURLRequired-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.AsteriscAbsolutePreState = ""
config.AsteriscAbsolutePreStateBaseURL = nil
require.ErrorIs(t, config.Check(), ErrMissingAsteriscAbsolutePreState)
})

t.Run(fmt.Sprintf("TestAsteriscAbsolutePreState-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.AsteriscAbsolutePreState = validAsteriscAbsolutPreState
config.AsteriscAbsolutePreStateBaseURL = nil
require.NoError(t, config.Check())
})

t.Run(fmt.Sprintf("TestAsteriscAbsolutePreStateBaseURL-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.AsteriscAbsolutePreState = ""
config.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutPreStateBaseURL
require.NoError(t, config.Check())
})

t.Run(fmt.Sprintf("TestMustNotSupplyBothAsteriscAbsolutePreStateAndBaseURL-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.AsteriscAbsolutePreState = validAsteriscAbsolutPreState
config.AsteriscAbsolutePreStateBaseURL = validAsteriscAbsolutPreStateBaseURL
require.ErrorIs(t, config.Check(), ErrAsteriscAbsolutePreStateAndBaseURL)
})

t.Run(fmt.Sprintf("TestL2RpcRequired-%v", traceType), func(t *testing.T) {
config := validConfig(traceType)
config.L2Rpc = ""
require.ErrorIs(t, config.Check(), ErrMissingL2Rpc)
})

t.Run(fmt.Sprintf("TestAsteriscSnapshotFreq-%v", traceType), func(t *testing.T) {
t.Run("MustNotBeZero", func(t *testing.T) {
cfg := validConfig(traceType)
cfg.AsteriscSnapshotFreq = 0
require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscSnapshotFreq)
})
})

t.Run(fmt.Sprintf("TestAsteriscInfoFreq-%v", traceType), func(t *testing.T) {
t.Run("MustNotBeZero", func(t *testing.T) {
cfg := validConfig(traceType)
cfg.AsteriscInfoFreq = 0
require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscInfoFreq)
})
})

t.Run(fmt.Sprintf("TestAsteriscNetworkOrRollupConfigRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.AsteriscNetwork = ""
cfg.AsteriscRollupConfigPath = ""
cfg.AsteriscL2GenesisPath = "genesis.json"
require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscRollupConfig)
})

t.Run(fmt.Sprintf("TestAsteriscNetworkOrL2GenesisRequired-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.AsteriscNetwork = ""
cfg.AsteriscRollupConfigPath = "foo.json"
cfg.AsteriscL2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscL2Genesis)
})

t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndRollup-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.AsteriscNetwork = validAsteriscNetwork
cfg.AsteriscRollupConfigPath = "foo.json"
cfg.AsteriscL2GenesisPath = ""
require.ErrorIs(t, cfg.Check(), ErrAsteriscNetworkAndRollupConfig)
})

t.Run(fmt.Sprintf("TestMustNotSpecifyNetworkAndL2Genesis-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.AsteriscNetwork = validAsteriscNetwork
cfg.AsteriscRollupConfigPath = ""
cfg.AsteriscL2GenesisPath = "foo.json"
require.ErrorIs(t, cfg.Check(), ErrAsteriscNetworkAndL2Genesis)
})

t.Run(fmt.Sprintf("TestNetworkMustBeValid-%v", traceType), func(t *testing.T) {
cfg := validConfig(traceType)
cfg.AsteriscNetwork = "unknown"
require.ErrorIs(t, cfg.Check(), ErrAsteriscNetworkUnknown)
})
}
}

func TestDatadirRequired(t *testing.T) {
config := validConfig(TraceTypeAlphabet)
config.Datadir = ""
Expand Down Expand Up @@ -280,6 +388,7 @@ func TestRequireConfigForMultipleTraceTypesForAsterisc(t *testing.T) {

// Require asterisc specific args
cfg.AsteriscAbsolutePreState = ""
cfg.AsteriscAbsolutePreStateBaseURL = nil
require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscAbsolutePreState)
cfg.AsteriscAbsolutePreState = validAsteriscAbsolutPreState

Expand All @@ -304,6 +413,7 @@ func TestRequireConfigForMultipleTraceTypesForCannonAndAsterisc(t *testing.T) {

// Require asterisc specific args
cfg.AsteriscAbsolutePreState = ""
cfg.AsteriscAbsolutePreStateBaseURL = nil
require.ErrorIs(t, cfg.Check(), ErrMissingAsteriscAbsolutePreState)
cfg.AsteriscAbsolutePreState = validAsteriscAbsolutPreState

Expand Down
90 changes: 53 additions & 37 deletions op-challenger/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ var (
Usage: "Path to absolute prestate to use when generating trace data (asterisc trace type only)",
EnvVars: prefixEnvVars("ASTERISC_PRESTATE"),
}
AsteriscPreStatesURLFlag = &cli.StringFlag{
Name: "asterisc-prestates-url",
Usage: "Base URL to absolute prestates to use when generating trace data. " +
"Prestates in this directory should be name as <commitment>.json (asterisc trace type only)",
EnvVars: prefixEnvVars("ASTERISC_PRESTATES_URL"),
}
AsteriscSnapshotFreqFlag = &cli.UintFlag{
Name: "asterisc-snapshot-freq",
Usage: "Frequency of asterisc snapshots to generate in VM steps (asterisc trace type only)",
Expand Down Expand Up @@ -250,6 +256,7 @@ var optionalFlags = []cli.Flag{
AsteriscBinFlag,
AsteriscServerFlag,
AsteriscPreStateFlag,
AsteriscPreStatesURLFlag,
AsteriscSnapshotFreqFlag,
AsteriscInfoFreqFlag,
GameWindowFlag,
Expand Down Expand Up @@ -313,8 +320,8 @@ func CheckAsteriscFlags(ctx *cli.Context) error {
if !ctx.IsSet(AsteriscServerFlag.Name) {
return fmt.Errorf("flag %s is required", AsteriscServerFlag.Name)
}
if !ctx.IsSet(AsteriscPreStateFlag.Name) {
return fmt.Errorf("flag %s is required", AsteriscPreStateFlag.Name)
if !ctx.IsSet(AsteriscPreStateFlag.Name) && !ctx.IsSet(AsteriscPreStatesURLFlag.Name) {
return fmt.Errorf("flag %s or %s is required", AsteriscPreStatesURLFlag.Name, AsteriscPreStateFlag.Name)
}
// CannonL2Flag is checked because it is an alias with L2EthRpcFlag
if !ctx.IsSet(CannonL2Flag.Name) && !ctx.IsSet(L2EthRpcFlag.Name) {
Expand Down Expand Up @@ -426,46 +433,55 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
}
cannonPrestatesURL = parsed
}
var asteriscPreStatesURL *url.URL
if ctx.IsSet(AsteriscPreStatesURLFlag.Name) {
parsed, err := url.Parse(ctx.String(AsteriscPreStatesURLFlag.Name))
if err != nil {
return nil, fmt.Errorf("invalid asterisc pre states url (%v): %w", ctx.String(CannonPreStatesURLFlag.Name), err)
}
asteriscPreStatesURL = parsed
}
l2Rpc, err := getL2Rpc(ctx, logger)
if err != nil {
return nil, err
}
return &config.Config{
// Required Flags
L1EthRpc: ctx.String(L1EthRpcFlag.Name),
L1Beacon: ctx.String(L1BeaconFlag.Name),
TraceTypes: traceTypes,
GameFactoryAddress: gameFactoryAddress,
GameAllowlist: allowedGames,
GameWindow: ctx.Duration(GameWindowFlag.Name),
MaxConcurrency: maxConcurrency,
L2Rpc: l2Rpc,
MaxPendingTx: ctx.Uint64(MaxPendingTransactionsFlag.Name),
PollInterval: ctx.Duration(HTTPPollInterval.Name),
AdditionalBondClaimants: claimants,
RollupRpc: ctx.String(RollupRpcFlag.Name),
CannonNetwork: ctx.String(CannonNetworkFlag.Name),
CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name),
CannonL2GenesisPath: ctx.String(CannonL2GenesisFlag.Name),
CannonBin: ctx.String(CannonBinFlag.Name),
CannonServer: ctx.String(CannonServerFlag.Name),
CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name),
CannonAbsolutePreStateBaseURL: cannonPrestatesURL,
Datadir: ctx.String(DatadirFlag.Name),
CannonSnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name),
CannonInfoFreq: ctx.Uint(CannonInfoFreqFlag.Name),
AsteriscNetwork: ctx.String(AsteriscNetworkFlag.Name),
AsteriscRollupConfigPath: ctx.String(AsteriscRollupConfigFlag.Name),
AsteriscL2GenesisPath: ctx.String(AsteriscL2GenesisFlag.Name),
AsteriscBin: ctx.String(AsteriscBinFlag.Name),
AsteriscServer: ctx.String(AsteriscServerFlag.Name),
AsteriscAbsolutePreState: ctx.String(AsteriscPreStateFlag.Name),
AsteriscSnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name),
AsteriscInfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name),
TxMgrConfig: txMgrConfig,
MetricsConfig: metricsConfig,
PprofConfig: pprofConfig,
SelectiveClaimResolution: ctx.Bool(SelectiveClaimResolutionFlag.Name),
AllowInvalidPrestate: ctx.Bool(UnsafeAllowInvalidPrestate.Name),
L1EthRpc: ctx.String(L1EthRpcFlag.Name),
L1Beacon: ctx.String(L1BeaconFlag.Name),
TraceTypes: traceTypes,
GameFactoryAddress: gameFactoryAddress,
GameAllowlist: allowedGames,
GameWindow: ctx.Duration(GameWindowFlag.Name),
MaxConcurrency: maxConcurrency,
L2Rpc: l2Rpc,
MaxPendingTx: ctx.Uint64(MaxPendingTransactionsFlag.Name),
PollInterval: ctx.Duration(HTTPPollInterval.Name),
AdditionalBondClaimants: claimants,
RollupRpc: ctx.String(RollupRpcFlag.Name),
CannonNetwork: ctx.String(CannonNetworkFlag.Name),
CannonRollupConfigPath: ctx.String(CannonRollupConfigFlag.Name),
CannonL2GenesisPath: ctx.String(CannonL2GenesisFlag.Name),
CannonBin: ctx.String(CannonBinFlag.Name),
CannonServer: ctx.String(CannonServerFlag.Name),
CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name),
CannonAbsolutePreStateBaseURL: cannonPrestatesURL,
Datadir: ctx.String(DatadirFlag.Name),
CannonSnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name),
CannonInfoFreq: ctx.Uint(CannonInfoFreqFlag.Name),
AsteriscNetwork: ctx.String(AsteriscNetworkFlag.Name),
AsteriscRollupConfigPath: ctx.String(AsteriscRollupConfigFlag.Name),
AsteriscL2GenesisPath: ctx.String(AsteriscL2GenesisFlag.Name),
AsteriscBin: ctx.String(AsteriscBinFlag.Name),
AsteriscServer: ctx.String(AsteriscServerFlag.Name),
AsteriscAbsolutePreState: ctx.String(AsteriscPreStateFlag.Name),
AsteriscAbsolutePreStateBaseURL: asteriscPreStatesURL,
AsteriscSnapshotFreq: ctx.Uint(AsteriscSnapshotFreqFlag.Name),
AsteriscInfoFreq: ctx.Uint(AsteriscInfoFreqFlag.Name),
TxMgrConfig: txMgrConfig,
MetricsConfig: metricsConfig,
PprofConfig: pprofConfig,
SelectiveClaimResolution: ctx.Bool(SelectiveClaimResolutionFlag.Name),
AllowInvalidPrestate: ctx.Bool(UnsafeAllowInvalidPrestate.Name),
}, nil
}
Loading

0 comments on commit 8447d16

Please sign in to comment.