Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 3 additions & 14 deletions op-challenger/game/fault/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@ type GameContract interface {
GetMaxGameDepth(ctx context.Context) (uint64, error)
}

type gameTypeResources interface {
Contract() GameContract
CreateAccessor(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (types.TraceAccessor, error)
}

type resourceCreator func(addr common.Address) (gameTypeResources, error)
type resourceCreator func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (types.TraceAccessor, error)

func NewGamePlayer(
ctx context.Context,
Expand All @@ -50,17 +45,11 @@ func NewGamePlayer(
dir string,
addr common.Address,
txMgr txmgr.TxManager,
loader GameContract,
creator resourceCreator,
) (*GamePlayer, error) {
logger = logger.New("game", addr)

resources, err := creator(addr)
if err != nil {
return nil, fmt.Errorf("failed to create game resources: %w", err)
}

loader := resources.Contract()

status, err := loader.GetStatus(ctx)
if err != nil {
return nil, fmt.Errorf("failed to fetch game status: %w", err)
Expand All @@ -84,7 +73,7 @@ func NewGamePlayer(
return nil, fmt.Errorf("failed to fetch the game depth: %w", err)
}

accessor, err := resources.CreateAccessor(ctx, logger, gameDepth, dir)
accessor, err := creator(ctx, logger, gameDepth, dir)
if err != nil {
return nil, fmt.Errorf("failed to create trace accessor: %w", err)
}
Expand Down
198 changes: 60 additions & 138 deletions op-challenger/game/fault/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
Expand Down Expand Up @@ -57,7 +56,7 @@ func RegisterGameTypes(
registerOutputCannon(registry, ctx, logger, m, cfg, txMgr, caller, l2Client)
}
if cfg.TraceTypeEnabled(config.TraceTypeOutputAlphabet) {
registerOutputAlphabet(registry, ctx, logger, m, cfg, txMgr, caller, l2Client)
registerOutputAlphabet(registry, ctx, logger, m, cfg, txMgr, caller)
}
if cfg.TraceTypeEnabled(config.TraceTypeCannon) {
registerCannon(registry, ctx, logger, m, cfg, txMgr, caller, l2Client)
Expand All @@ -75,54 +74,33 @@ func registerOutputAlphabet(
m metrics.Metricer,
cfg *config.Config,
txMgr txmgr.TxManager,
caller *batching.MultiCaller,
l2Client cannon.L2HeaderSource) {
resourceCreator := func(addr common.Address) (gameTypeResources, error) {
contract, err := contracts.NewOutputBisectionGameContract(addr, caller)
caller *batching.MultiCaller) {
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewOutputBisectionGameContract(game.Proxy, caller)
if err != nil {
return nil, err
}
return &outputAlphabetResources{
m: m,
cfg: cfg,
l2Client: l2Client,
contract: contract,
}, nil
}
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, resourceCreator)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
// TODO(client-pod#44): Validate absolute pre-state for split games
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
splitDepth, err := contract.GetSplitDepth(ctx)
if err != nil {
return nil, err
}
accessor, err := outputs.NewOutputAlphabetTraceAccessor(ctx, logger, m, cfg, gameDepth, splitDepth, prestateBlock, poststateBlock)
if err != nil {
return nil, err
}
return accessor, nil
}
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, creator)
}
registry.RegisterGameType(outputAlphabetGameType, playerCreator)
}

type outputAlphabetResources struct {
m metrics.Metricer
cfg *config.Config
l2Client cannon.L2HeaderSource
contract *contracts.OutputBisectionGameContract
}

func (r *outputAlphabetResources) Contract() GameContract {
return r.contract
}

func (r *outputAlphabetResources) CreateAccessor(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
// TODO(client-pod#44): Validate absolute pre-state for split games
prestateBlock, poststateBlock, err := r.contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
splitDepth, err := r.contract.GetSplitDepth(ctx)
if err != nil {
return nil, err
}
accessor, err := outputs.NewOutputAlphabetTraceAccessor(ctx, logger, r.m, r.cfg, gameDepth, splitDepth, prestateBlock, poststateBlock)
if err != nil {
return nil, err
}
return accessor, nil
}

func registerOutputCannon(
registry Registry,
ctx context.Context,
Expand All @@ -132,48 +110,28 @@ func registerOutputCannon(
txMgr txmgr.TxManager,
caller *batching.MultiCaller,
l2Client cannon.L2HeaderSource) {
resourceCreator := func(addr common.Address) (gameTypeResources, error) {
contract, err := contracts.NewOutputBisectionGameContract(addr, caller)
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewOutputBisectionGameContract(game.Proxy, caller)
if err != nil {
return nil, err
}
return &outputCannonResources{
m: m,
cfg: cfg,
l2Client: l2Client,
contract: contract,
}, nil
}
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, resourceCreator)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
// TODO(client-pod#44): Validate absolute pre-state for split games
agreed, disputed, err := contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
accessor, err := outputs.NewOutputCannonTraceAccessor(ctx, logger, m, cfg, l2Client, contract, dir, gameDepth, agreed, disputed)
if err != nil {
return nil, err
}
return accessor, nil
}
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, creator)
}
registry.RegisterGameType(outputCannonGameType, playerCreator)
}

type outputCannonResources struct {
m metrics.Metricer
cfg *config.Config
l2Client cannon.L2HeaderSource
contract *contracts.OutputBisectionGameContract
}

func (r *outputCannonResources) Contract() GameContract {
return r.contract
}

func (r *outputCannonResources) CreateAccessor(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
// TODO(client-pod#44): Validate absolute pre-state for split games
agreed, disputed, err := r.contract.GetBlockRange(ctx)
if err != nil {
return nil, err
}
accessor, err := outputs.NewOutputCannonTraceAccessor(ctx, logger, r.m, r.cfg, r.l2Client, r.contract, dir, gameDepth, agreed, disputed)
if err != nil {
return nil, err
}
return accessor, nil
}

func registerCannon(
registry Registry,
ctx context.Context,
Expand All @@ -183,47 +141,27 @@ func registerCannon(
txMgr txmgr.TxManager,
caller *batching.MultiCaller,
l2Client cannon.L2HeaderSource) {
resourceCreator := func(addr common.Address) (gameTypeResources, error) {
contract, err := contracts.NewFaultDisputeGameContract(addr, caller)
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller)
if err != nil {
return nil, err
}
return &cannonResources{
m: m,
cfg: cfg,
l2Client: l2Client,
contract: contract,
}, nil
}
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, resourceCreator)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
localInputs, err := cannon.FetchLocalInputs(ctx, contract, l2Client)
if err != nil {
return nil, fmt.Errorf("failed to fetch cannon local inputs: %w", err)
}
provider := cannon.NewTraceProvider(logger, m, cfg, faultTypes.NoLocalContext, localInputs, dir, gameDepth)
if err := ValidateAbsolutePrestate(ctx, provider, contract); err != nil {
return nil, err
}
return trace.NewSimpleTraceAccessor(provider), nil
}
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, creator)
}
registry.RegisterGameType(cannonGameType, playerCreator)
}

type cannonResources struct {
m metrics.Metricer
cfg *config.Config
l2Client cannon.L2HeaderSource
contract *contracts.FaultDisputeGameContract
}

func (r *cannonResources) Contract() GameContract {
return r.contract
}

func (r *cannonResources) CreateAccessor(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
localInputs, err := cannon.FetchLocalInputs(ctx, r.contract, r.l2Client)
if err != nil {
return nil, fmt.Errorf("failed to fetch cannon local inputs: %w", err)
}
provider := cannon.NewTraceProvider(logger, r.m, r.cfg, faultTypes.NoLocalContext, localInputs, dir, gameDepth)
if err := ValidateAbsolutePrestate(ctx, provider, r.contract); err != nil {
return nil, err
}
return trace.NewSimpleTraceAccessor(provider), nil
}

func registerAlphabet(
registry Registry,
ctx context.Context,
Expand All @@ -232,35 +170,19 @@ func registerAlphabet(
cfg *config.Config,
txMgr txmgr.TxManager,
caller *batching.MultiCaller) {
resourceCreator := func(addr common.Address) (gameTypeResources, error) {
contract, err := contracts.NewFaultDisputeGameContract(addr, caller)
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract, err := contracts.NewFaultDisputeGameContract(game.Proxy, caller)
if err != nil {
return nil, err
}
return &alphabetResources{
cfg: cfg,
contract: contract,
}, nil
}
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, resourceCreator)
creator := func(ctx context.Context, logger log.Logger, gameDepth uint64, dir string) (faultTypes.TraceAccessor, error) {
provider := alphabet.NewTraceProvider(cfg.AlphabetTrace, gameDepth)
if err := ValidateAbsolutePrestate(ctx, provider, contract); err != nil {
return nil, err
}
return trace.NewSimpleTraceAccessor(provider), nil
}
return NewGamePlayer(ctx, logger, m, dir, game.Proxy, txMgr, contract, creator)
}
registry.RegisterGameType(alphabetGameType, playerCreator)
}

type alphabetResources struct {
cfg *config.Config
contract *contracts.FaultDisputeGameContract
}

func (r *alphabetResources) Contract() GameContract {
return r.contract
}

func (r *alphabetResources) CreateAccessor(ctx context.Context, _ log.Logger, gameDepth uint64, _ string) (faultTypes.TraceAccessor, error) {
provider := alphabet.NewTraceProvider(r.cfg.AlphabetTrace, gameDepth)
if err := ValidateAbsolutePrestate(ctx, provider, r.contract); err != nil {
return nil, err
}
return trace.NewSimpleTraceAccessor(provider), nil
}