Skip to content

Commit

Permalink
op-challenger: Support binary and JSON snapshots (#11754)
Browse files Browse the repository at this point in the history
* op-challenger: Support loading json or binary cannon states.

* op-challenger: Use binary cannon snapshots

* op-challenger: Support downloading prestates in multiple formats.

* op-challenger: Verify newly downloaded snapshots.

* op-e2e: Update test to handle binary snapshots correctly.

* op-e2e: Remove unused parameter

* op-challenger: Add more varied data to the test cannon state.

* op-challenger: Add more varied data to the test cannon state.
  • Loading branch information
ajsutton authored Sep 8, 2024
1 parent 9170e93 commit 40750a5
Show file tree
Hide file tree
Showing 21 changed files with 284 additions and 118 deletions.
15 changes: 8 additions & 7 deletions op-challenger/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,14 @@ func NewConfig(
Datadir: datadir,

Cannon: vm.Config{
VmType: types.TraceTypeCannon,
L1: l1EthRpc,
L1Beacon: l1BeaconApi,
L2: l2EthRpc,
SnapshotFreq: DefaultCannonSnapshotFreq,
InfoFreq: DefaultCannonInfoFreq,
DebugInfo: true,
VmType: types.TraceTypeCannon,
L1: l1EthRpc,
L1Beacon: l1BeaconApi,
L2: l2EthRpc,
SnapshotFreq: DefaultCannonSnapshotFreq,
InfoFreq: DefaultCannonInfoFreq,
DebugInfo: true,
BinarySnapshots: true,
},
Asterisc: vm.Config{
VmType: types.TraceTypeAsterisc,
Expand Down
1 change: 1 addition & 0 deletions op-challenger/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ func NewConfigFromCLI(ctx *cli.Context, logger log.Logger) (*config.Config, erro
SnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name),
InfoFreq: ctx.Uint(CannonInfoFreqFlag.Name),
DebugInfo: true,
BinarySnapshots: true,
},
CannonAbsolutePreState: ctx.String(CannonPreStateFlag.Name),
CannonAbsolutePreStateBaseURL: cannonPrestatesURL,
Expand Down
15 changes: 11 additions & 4 deletions op-challenger/game/fault/register_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,18 @@ type RegisterTask struct {
}

func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor) *RegisterTask {
stateConverter := cannon.NewStateConverter()
return &RegisterTask{
gameType: gameType,
getPrestateProvider: cachePrestates(
gameType,
stateConverter,
m,
cfg.CannonAbsolutePreStateBaseURL,
cfg.CannonAbsolutePreState,
filepath.Join(cfg.Datadir, "cannon-prestates"),
func(path string) faultTypes.PrestateProvider {
return vm.NewPrestateProvider(path, cannon.NewStateConverter())
return vm.NewPrestateProvider(path, stateConverter)
}),
newTraceAccessor: func(
logger log.Logger,
Expand All @@ -78,16 +80,18 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
}

func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor) *RegisterTask {
stateConverter := asterisc.NewStateConverter()
return &RegisterTask{
gameType: gameType,
getPrestateProvider: cachePrestates(
gameType,
stateConverter,
m,
cfg.AsteriscAbsolutePreStateBaseURL,
cfg.AsteriscAbsolutePreState,
filepath.Join(cfg.Datadir, "asterisc-prestates"),
func(path string) faultTypes.PrestateProvider {
return vm.NewPrestateProvider(path, asterisc.NewStateConverter())
return vm.NewPrestateProvider(path, stateConverter)
}),
newTraceAccessor: func(
logger log.Logger,
Expand All @@ -108,16 +112,18 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m
}

func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor) *RegisterTask {
stateConverter := asterisc.NewStateConverter()
return &RegisterTask{
gameType: gameType,
getPrestateProvider: cachePrestates(
gameType,
stateConverter,
m,
cfg.AsteriscKonaAbsolutePreStateBaseURL,
cfg.AsteriscKonaAbsolutePreState,
filepath.Join(cfg.Datadir, "asterisc-kona-prestates"),
func(path string) faultTypes.PrestateProvider {
return vm.NewPrestateProvider(path, asterisc.NewStateConverter())
return vm.NewPrestateProvider(path, stateConverter)
}),
newTraceAccessor: func(
logger log.Logger,
Expand Down Expand Up @@ -162,13 +168,14 @@ func NewAlphabetRegisterTask(gameType faultTypes.GameType) *RegisterTask {

func cachePrestates(
gameType faultTypes.GameType,
stateConverter vm.StateConverter,
m caching.Metrics,
prestateBaseURL *url.URL,
preStatePath string,
prestateDir string,
newPrestateProvider func(path string) faultTypes.PrestateProvider,
) func(prestateHash common.Hash) (faultTypes.PrestateProvider, error) {
prestateSource := prestates.NewPrestateSource(prestateBaseURL, preStatePath, prestateDir)
prestateSource := prestates.NewPrestateSource(prestateBaseURL, preStatePath, prestateDir, stateConverter)
prestateProviderCache := prestates.NewPrestateProviderCache(m, fmt.Sprintf("prestates-%v", gameType), func(prestateHash common.Hash) (faultTypes.PrestateProvider, error) {
prestatePath, err := prestateSource.PrestatePath(prestateHash)
if err != nil {
Expand Down
7 changes: 5 additions & 2 deletions op-challenger/game/fault/trace/asterisc/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type AsteriscTraceProvider struct {
gameDepth types.Depth
preimageLoader *utils.PreimageLoader
stateConverter vm.StateConverter
cfg vm.Config

types.PrestateProvider

Expand All @@ -48,6 +49,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.
}),
PrestateProvider: prestateProvider,
stateConverter: NewStateConverter(),
cfg: cfg,
}
}

Expand Down Expand Up @@ -122,7 +124,7 @@ func (p *AsteriscTraceProvider) loadProof(ctx context.Context, i uint64) (*utils
file, err = ioutil.OpenDecompressed(path)
if errors.Is(err, os.ErrNotExist) {
// Expected proof wasn't generated, check if we reached the end of execution
proof, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState))
proof, step, exited, err := p.stateConverter.ConvertStateToProof(vm.FinalStatePath(p.dir, p.cfg.BinarySnapshots))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -171,6 +173,7 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi
return kvstore.NewFileKV(vm.PreimageDir(dir))
}),
stateConverter: NewStateConverter(),
cfg: cfg.Asterisc,
}
return &AsteriscTraceProviderForTest{p}
}
Expand All @@ -181,7 +184,7 @@ func (p *AsteriscTraceProviderForTest) FindStep(ctx context.Context, start uint6
return 0, fmt.Errorf("generate asterisc trace (until preimage read): %w", err)
}
// Load the step from the state asterisc finished with
_, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState))
_, step, exited, err := p.stateConverter.ConvertStateToProof(vm.FinalStatePath(p.dir, p.cfg.BinarySnapshots))
if err != nil {
return 0, fmt.Errorf("failed to load final state: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion op-challenger/game/fault/trace/asterisc/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func (e *stubGenerator) GenerateProof(ctx context.Context, dir string, i uint64)
var err error
if e.finalState != nil && e.finalState.Step <= i {
// Requesting a trace index past the end of the trace
proofFile = filepath.Join(dir, vm.FinalState)
proofFile = vm.FinalStatePath(dir, false)
data, err = json.Marshal(e.finalState)
if err != nil {
return err
Expand Down
8 changes: 6 additions & 2 deletions op-challenger/game/fault/trace/cannon/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type CannonTraceProvider struct {
gameDepth types.Depth
preimageLoader *utils.PreimageLoader
stateConverter vm.StateConverter
cfg vm.Config

types.PrestateProvider

Expand All @@ -49,6 +50,7 @@ func NewTraceProvider(logger log.Logger, m vm.Metricer, cfg vm.Config, vmCfg vm.
}),
PrestateProvider: prestateProvider,
stateConverter: &StateConverter{},
cfg: cfg,
}
}

Expand Down Expand Up @@ -122,7 +124,7 @@ func (p *CannonTraceProvider) loadProof(ctx context.Context, i uint64) (*utils.P
// Try opening the file again now and it should exist.
file, err = ioutil.OpenDecompressed(path)
if errors.Is(err, os.ErrNotExist) {
proof, stateStep, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState))
proof, stateStep, exited, err := p.stateConverter.ConvertStateToProof(vm.FinalStatePath(p.dir, p.cfg.BinarySnapshots))
if err != nil {
return nil, fmt.Errorf("cannot create proof from final state: %w", err)
}
Expand Down Expand Up @@ -170,6 +172,7 @@ func NewTraceProviderForTest(logger log.Logger, m vm.Metricer, cfg *config.Confi
return kvstore.NewFileKV(vm.PreimageDir(dir))
}),
stateConverter: NewStateConverter(),
cfg: cfg.Cannon,
}
return &CannonTraceProviderForTest{p}
}
Expand All @@ -180,7 +183,8 @@ func (p *CannonTraceProviderForTest) FindStep(ctx context.Context, start uint64,
return 0, fmt.Errorf("generate cannon trace (until preimage read): %w", err)
}
// Load the step from the state cannon finished with
_, step, exited, err := p.stateConverter.ConvertStateToProof(filepath.Join(p.dir, vm.FinalState))

_, step, exited, err := p.stateConverter.ConvertStateToProof(vm.FinalStatePath(p.dir, p.cfg.BinarySnapshots))
if err != nil {
return 0, fmt.Errorf("failed to load final state: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion op-challenger/game/fault/trace/cannon/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func (e *stubGenerator) GenerateProof(ctx context.Context, dir string, i uint64)
var err error
if e.finalState != nil && e.finalState.Step <= i {
// Requesting a trace index past the end of the trace
proofFile = filepath.Join(dir, vm.FinalState)
proofFile = vm.FinalStatePath(dir, false)
data, err = json.Marshal(e.finalState)
if err != nil {
return err
Expand Down
19 changes: 2 additions & 17 deletions op-challenger/game/fault/trace/cannon/state_converter.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package cannon

import (
"encoding/json"
"fmt"
"io"

"github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded"
"github.com/ethereum-optimism/optimism/cannon/serialize"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-service/ioutil"
)

type StateConverter struct {
Expand Down Expand Up @@ -36,18 +34,5 @@ func (c *StateConverter) ConvertStateToProof(statePath string) (*utils.ProofData
}

func parseState(path string) (*singlethreaded.State, error) {
file, err := ioutil.OpenDecompressed(path)
if err != nil {
return nil, fmt.Errorf("cannot open state file (%v): %w", path, err)
}
return parseStateFromReader(file)
}

func parseStateFromReader(in io.ReadCloser) (*singlethreaded.State, error) {
defer in.Close()
var state singlethreaded.State
if err := json.NewDecoder(in).Decode(&state); err != nil {
return nil, fmt.Errorf("invalid mipsevm state: %w", err)
}
return &state, nil
return serialize.Load[singlethreaded.State](path)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"testing"

"github.com/ethereum-optimism/optimism/cannon/serialize"
"github.com/stretchr/testify/require"

"github.com/ethereum-optimism/optimism/cannon/mipsevm/singlethreaded"
Expand Down Expand Up @@ -48,4 +49,30 @@ func TestLoadState(t *testing.T) {
require.NoError(t, json.Unmarshal(testState, &expected))
require.Equal(t, &expected, state)
})

t.Run("Binary", func(t *testing.T) {
var expected singlethreaded.State
require.NoError(t, json.Unmarshal(testState, &expected))

dir := t.TempDir()
path := filepath.Join(dir, "state.bin")
require.NoError(t, serialize.Write[*singlethreaded.State](path, &expected, 0644))

state, err := parseState(path)
require.NoError(t, err)
require.Equal(t, &expected, state)
})

t.Run("BinaryGzip", func(t *testing.T) {
var expected singlethreaded.State
require.NoError(t, json.Unmarshal(testState, &expected))

dir := t.TempDir()
path := filepath.Join(dir, "state.bin.gz")
require.NoError(t, serialize.Write[*singlethreaded.State](path, &expected, 0644))

state, err := parseState(path)
require.NoError(t, err)
require.Equal(t, &expected, state)
})
}
20 changes: 10 additions & 10 deletions op-challenger/game/fault/trace/cannon/test_data/state.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"memory": [],
"memory": [{"index":10,"data":"eJzswAENAAAAwiD7p7bHBwMAAADyHgAA//8QAAAB"}],
"preimageKey": "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"preimageOffset": 0,
"pc": 0,
"preimageOffset": 42,
"pc": 94,
"nextPC": 1,
"lo": 0,
"hi": 0,
"heap": 0,
"exit": 0,
"exited": false,
"step": 0,
"registers": []
"lo": 3,
"hi": 5,
"heap": 4,
"exit": 1,
"exited": true,
"step": 8849,
"registers": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2147471360,0,0]
}
Loading

0 comments on commit 40750a5

Please sign in to comment.