Commit f8da0f3d authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Cache the cannon absolute prestate (#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.
parent b8242180
......@@ -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 {
......@@ -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)
}
......
......@@ -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) {
......@@ -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)
......@@ -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
}
......@@ -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) {
......
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