Commit 8910388c authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger: Lazy create clients (#13810)

Make sync validator configurable per game type.
parent bd7c16b8
package fault
import (
"context"
"fmt"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
type clientProvider struct {
ctx context.Context
logger log.Logger
cfg *config.Config
l2HeaderSource utils.L2HeaderSource
rollupClient RollupClient
syncValidator *syncStatusValidator
toClose []CloseFunc
}
func (c *clientProvider) Close() {
for _, closeFunc := range c.toClose {
closeFunc()
}
}
func (c *clientProvider) SingleChainClients() (utils.L2HeaderSource, RollupClient, *syncStatusValidator, error) {
headers, err := c.L2HeaderSource()
if err != nil {
return nil, nil, nil, err
}
rollup, err := c.RollupClient()
if err != nil {
return nil, nil, nil, err
}
return headers, rollup, c.syncValidator, nil
}
func (c *clientProvider) L2HeaderSource() (utils.L2HeaderSource, error) {
if c.l2HeaderSource != nil {
return c.l2HeaderSource, nil
}
l2Client, err := ethclient.DialContext(c.ctx, c.cfg.L2Rpc)
if err != nil {
return nil, fmt.Errorf("dial l2 client %v: %w", c.cfg.L2Rpc, err)
}
c.l2HeaderSource = l2Client
c.toClose = append(c.toClose, l2Client.Close)
return l2Client, nil
}
func (c *clientProvider) RollupClient() (RollupClient, error) {
if c.rollupClient != nil {
return c.rollupClient, nil
}
rollupClient, err := dial.DialRollupClientWithTimeout(c.ctx, dial.DefaultDialTimeout, c.logger, c.cfg.RollupRpc)
if err != nil {
return nil, fmt.Errorf("dial rollup client %v: %w", c.cfg.RollupRpc, err)
}
c.rollupClient = rollupClient
c.syncValidator = newSyncStatusValidator(rollupClient)
c.toClose = append(c.toClose, rollupClient.Close)
return rollupClient, nil
}
...@@ -14,10 +14,8 @@ import ( ...@@ -14,10 +14,8 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/scheduler" "github.com/ethereum-optimism/optimism/op-challenger/game/scheduler"
"github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/clock" "github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum-optimism/optimism/op-service/dial"
"github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
...@@ -60,45 +58,54 @@ func RegisterGameTypes( ...@@ -60,45 +58,54 @@ func RegisterGameTypes(
selective bool, selective bool,
claimants []common.Address, claimants []common.Address,
) (CloseFunc, error) { ) (CloseFunc, error) {
l2Client, err := ethclient.DialContext(ctx, cfg.L2Rpc) clients := &clientProvider{ctx: ctx, logger: logger, cfg: cfg}
if err != nil {
return nil, fmt.Errorf("dial l2 client %v: %w", cfg.L2Rpc, err)
}
closer := l2Client.Close
rollupClient, err := dial.DialRollupClientWithTimeout(ctx, dial.DefaultDialTimeout, logger, cfg.RollupRpc)
if err != nil {
return closer, fmt.Errorf("dial rollup client %v: %w", cfg.RollupRpc, err)
}
closer = func() {
l2Client.Close()
rollupClient.Close()
}
syncValidator := newSyncStatusValidator(rollupClient)
var registerTasks []*RegisterTask var registerTasks []*RegisterTask
if cfg.TraceTypeEnabled(faultTypes.TraceTypeCannon) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeCannon) {
registerTasks = append(registerTasks, NewCannonRegisterTask(faultTypes.CannonGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2Client, rollupClient)) l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients()
if err != nil {
return nil, err
}
registerTasks = append(registerTasks, NewCannonRegisterTask(faultTypes.CannonGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator))
} }
if cfg.TraceTypeEnabled(faultTypes.TraceTypePermissioned) { if cfg.TraceTypeEnabled(faultTypes.TraceTypePermissioned) {
registerTasks = append(registerTasks, NewCannonRegisterTask(faultTypes.PermissionedGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2Client, rollupClient)) l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients()
if err != nil {
return nil, err
}
registerTasks = append(registerTasks, NewCannonRegisterTask(faultTypes.PermissionedGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator))
} }
if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsterisc) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsterisc) {
registerTasks = append(registerTasks, NewAsteriscRegisterTask(faultTypes.AsteriscGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2Client, rollupClient)) l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients()
if err != nil {
return nil, err
}
registerTasks = append(registerTasks, NewAsteriscRegisterTask(faultTypes.AsteriscGameType, cfg, m, vm.NewOpProgramServerExecutor(logger), l2HeaderSource, rollupClient, syncValidator))
} }
if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsteriscKona) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeAsteriscKona) {
registerTasks = append(registerTasks, NewAsteriscKonaRegisterTask(faultTypes.AsteriscKonaGameType, cfg, m, vm.NewKonaExecutor(), l2Client, rollupClient)) l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients()
if err != nil {
return nil, err
}
registerTasks = append(registerTasks, NewAsteriscKonaRegisterTask(faultTypes.AsteriscKonaGameType, cfg, m, vm.NewKonaExecutor(), l2HeaderSource, rollupClient, syncValidator))
} }
if cfg.TraceTypeEnabled(faultTypes.TraceTypeFast) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeFast) {
registerTasks = append(registerTasks, NewAlphabetRegisterTask(faultTypes.FastGameType, l2Client, rollupClient)) l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients()
if err != nil {
return nil, err
}
registerTasks = append(registerTasks, NewAlphabetRegisterTask(faultTypes.FastGameType, l2HeaderSource, rollupClient, syncValidator))
} }
if cfg.TraceTypeEnabled(faultTypes.TraceTypeAlphabet) { if cfg.TraceTypeEnabled(faultTypes.TraceTypeAlphabet) {
registerTasks = append(registerTasks, NewAlphabetRegisterTask(faultTypes.AlphabetGameType, l2Client, rollupClient)) l2HeaderSource, rollupClient, syncValidator, err := clients.SingleChainClients()
if err != nil {
return nil, err
}
registerTasks = append(registerTasks, NewAlphabetRegisterTask(faultTypes.AlphabetGameType, l2HeaderSource, rollupClient, syncValidator))
} }
for _, task := range registerTasks { for _, task := range registerTasks {
if err := task.Register(ctx, registry, oracles, systemClock, l1Clock, logger, m, syncValidator, txSender, gameFactory, caller, l1HeaderSource, selective, claimants); err != nil { if err := task.Register(ctx, registry, oracles, systemClock, l1Clock, logger, m, txSender, gameFactory, caller, l1HeaderSource, selective, claimants); err != nil {
return closer, fmt.Errorf("failed to register %v game type: %w", task.gameType, err) return clients.Close, fmt.Errorf("failed to register %v game type: %w", task.gameType, err)
} }
} }
return closer, nil return clients.Close, nil
} }
...@@ -33,6 +33,8 @@ type RegisterTask struct { ...@@ -33,6 +33,8 @@ type RegisterTask struct {
gameType faultTypes.GameType gameType faultTypes.GameType
skipPrestateValidation bool skipPrestateValidation bool
syncValidator SyncValidator
getTopPrestateProvider func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) getTopPrestateProvider func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error)
getBottomPrestateProvider func(ctx context.Context, prestateHash common.Hash) (faultTypes.PrestateProvider, error) getBottomPrestateProvider func(ctx context.Context, prestateHash common.Hash) (faultTypes.PrestateProvider, error)
newTraceAccessor func( newTraceAccessor func(
...@@ -47,10 +49,11 @@ type RegisterTask struct { ...@@ -47,10 +49,11 @@ type RegisterTask struct {
poststateBlock uint64) (*trace.Accessor, error) poststateBlock uint64) (*trace.Accessor, error)
} }
func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient) *RegisterTask { func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask {
stateConverter := cannon.NewStateConverter(cfg.Cannon) stateConverter := cannon.NewStateConverter(cfg.Cannon)
return &RegisterTask{ return &RegisterTask{
gameType: gameType, gameType: gameType,
syncValidator: syncValidator,
// Don't validate the absolute prestate or genesis output root for permissioned games // Don't validate the absolute prestate or genesis output root for permissioned games
// Only trusted actors participate in these games so they aren't expected to reach the step() call and // Only trusted actors participate in these games so they aren't expected to reach the step() call and
// are often configured without valid prestates but the challenger should still resolve the games. // are often configured without valid prestates but the challenger should still resolve the games.
...@@ -84,10 +87,11 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c ...@@ -84,10 +87,11 @@ func NewCannonRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m c
} }
} }
func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient) *RegisterTask { func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask {
stateConverter := asterisc.NewStateConverter(cfg.Asterisc) stateConverter := asterisc.NewStateConverter(cfg.Asterisc)
return &RegisterTask{ return &RegisterTask{
gameType: gameType, gameType: gameType,
syncValidator: syncValidator,
getTopPrestateProvider: func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) { getTopPrestateProvider: func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) {
return outputs.NewPrestateProvider(rollupClient, prestateBlock), nil return outputs.NewPrestateProvider(rollupClient, prestateBlock), nil
}, },
...@@ -117,10 +121,11 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m ...@@ -117,10 +121,11 @@ func NewAsteriscRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m
} }
} }
func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient) *RegisterTask { func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Config, m caching.Metrics, serverExecutor vm.OracleServerExecutor, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask {
stateConverter := asterisc.NewStateConverter(cfg.Asterisc) stateConverter := asterisc.NewStateConverter(cfg.Asterisc)
return &RegisterTask{ return &RegisterTask{
gameType: gameType, gameType: gameType,
syncValidator: syncValidator,
getTopPrestateProvider: func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) { getTopPrestateProvider: func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) {
return outputs.NewPrestateProvider(rollupClient, prestateBlock), nil return outputs.NewPrestateProvider(rollupClient, prestateBlock), nil
}, },
...@@ -150,9 +155,10 @@ func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Confi ...@@ -150,9 +155,10 @@ func NewAsteriscKonaRegisterTask(gameType faultTypes.GameType, cfg *config.Confi
} }
} }
func NewAlphabetRegisterTask(gameType faultTypes.GameType, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient) *RegisterTask { func NewAlphabetRegisterTask(gameType faultTypes.GameType, l2Client utils.L2HeaderSource, rollupClient outputs.OutputRollupClient, syncValidator SyncValidator) *RegisterTask {
return &RegisterTask{ return &RegisterTask{
gameType: gameType, gameType: gameType,
syncValidator: syncValidator,
getTopPrestateProvider: func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) { getTopPrestateProvider: func(ctx context.Context, prestateBlock uint64) (faultTypes.PrestateProvider, error) {
return outputs.NewPrestateProvider(rollupClient, prestateBlock), nil return outputs.NewPrestateProvider(rollupClient, prestateBlock), nil
}, },
...@@ -203,7 +209,6 @@ func (e *RegisterTask) Register( ...@@ -203,7 +209,6 @@ func (e *RegisterTask) Register(
l1Clock faultTypes.ClockReader, l1Clock faultTypes.ClockReader,
logger log.Logger, logger log.Logger,
m metrics.Metricer, m metrics.Metricer,
syncValidator SyncValidator,
txSender TxSender, txSender TxSender,
gameFactory *contracts.DisputeGameFactoryContract, gameFactory *contracts.DisputeGameFactoryContract,
caller *batching.MultiCaller, caller *batching.MultiCaller,
...@@ -259,7 +264,7 @@ func (e *RegisterTask) Register( ...@@ -259,7 +264,7 @@ func (e *RegisterTask) Register(
validators = append(validators, NewPrestateValidator(e.gameType.String(), contract.GetAbsolutePrestateHash, vmPrestateProvider)) validators = append(validators, NewPrestateValidator(e.gameType.String(), contract.GetAbsolutePrestateHash, vmPrestateProvider))
validators = append(validators, NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider)) validators = append(validators, NewPrestateValidator("output root", contract.GetStartingRootHash, prestateProvider))
} }
return NewGamePlayer(ctx, systemClock, l1Clock, logger, m, dir, game.Proxy, txSender, contract, syncValidator, validators, creator, l1HeaderSource, selective, claimants) return NewGamePlayer(ctx, systemClock, l1Clock, logger, m, dir, game.Proxy, txSender, contract, e.syncValidator, validators, creator, l1HeaderSource, selective, claimants)
} }
err := registerOracle(ctx, logger, m, oracles, gameFactory, caller, e.gameType) err := registerOracle(ctx, logger, m, oracles, gameFactory, caller, e.gameType)
if err != nil { if 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