Skip to content

Commit

Permalink
op-challenger: Cache the cannon absolute prestate (ethereum-optimism#…
Browse files Browse the repository at this point in the history
…9756)

The prestate is large so can be slow to load. Verifying the prestate for hundreds of games at startup is repeatedly loading the configured prestate file, adding a large delay to being able to start playing games.
  • Loading branch information
ajsutton authored Mar 6, 2024
1 parent b824218 commit f8da0f3
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
3 changes: 2 additions & 1 deletion op-challenger/game/fault/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ func registerCannon(
l2Client cannon.L2HeaderSource,
l1HeaderSource L1HeaderSource,
) error {
cannonPrestateProvider := cannon.NewPrestateProvider(cfg.CannonAbsolutePreState)
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller)
if err != nil {
Expand All @@ -188,7 +189,7 @@ func registerCannon(
}
return accessor, nil
}
prestateValidator := NewPrestateValidator("cannon", contract.GetAbsolutePrestateHash, cannon.NewPrestateProvider(cfg.CannonAbsolutePreState))
prestateValidator := NewPrestateValidator("cannon", contract.GetAbsolutePrestateHash, cannonPrestateProvider)
genesisValidator := NewPrestateValidator("output root", contract.GetGenesisOutputRoot, prestateProvider)
return NewGamePlayer(ctx, cl, logger, m, dir, game.Proxy, txSender, contract, syncValidator, []Validator{prestateValidator, genesisValidator}, creator, l1HeaderSource)
}
Expand Down
8 changes: 7 additions & 1 deletion op-challenger/game/fault/trace/cannon/prestate.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ var _ types.PrestateProvider = (*CannonPrestateProvider)(nil)

type CannonPrestateProvider struct {
prestate string

prestateCommitment common.Hash
}

func NewPrestateProvider(prestate string) *CannonPrestateProvider {
return &CannonPrestateProvider{prestate}
return &CannonPrestateProvider{prestate: prestate}
}

func (p *CannonPrestateProvider) absolutePreState() ([]byte, error) {
Expand All @@ -29,6 +31,9 @@ func (p *CannonPrestateProvider) absolutePreState() ([]byte, error) {
}

func (p *CannonPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) {
if p.prestateCommitment != (common.Hash{}) {
return p.prestateCommitment, nil
}
state, err := p.absolutePreState()
if err != nil {
return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err)
Expand All @@ -37,5 +42,6 @@ func (p *CannonPrestateProvider) AbsolutePreStateCommitment(_ context.Context) (
if err != nil {
return common.Hash{}, fmt.Errorf("cannot hash absolute pre-state: %w", err)
}
p.prestateCommitment = hash
return hash, nil
}
15 changes: 15 additions & 0 deletions op-challenger/game/fault/trace/cannon/prestate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ func TestAbsolutePreStateCommitment(t *testing.T) {
require.NoError(t, err)
require.Equal(t, expected, actual)
})

t.Run("CacheAbsolutePreState", func(t *testing.T) {
setupPreState(t, dataDir, "state.json")
provider := newCannonPrestateProvider(dataDir, prestate)
first, err := provider.AbsolutePreStateCommitment(context.Background())
require.NoError(t, err)

// Remove the prestate from disk
require.NoError(t, os.Remove(provider.prestate))

// Value should still be available from cache
cached, err := provider.AbsolutePreStateCommitment(context.Background())
require.NoError(t, err)
require.Equal(t, first, cached)
})
}

func setupPreState(t *testing.T, dataDir string, filename string) {
Expand Down

0 comments on commit f8da0f3

Please sign in to comment.