Skip to content

Commit

Permalink
op-challenger: Log warning and continue if game impl not available (e…
Browse files Browse the repository at this point in the history
  • Loading branch information
ajsutton authored Oct 22, 2024
1 parent 984bd41 commit de79564
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
8 changes: 6 additions & 2 deletions op-challenger/game/fault/register_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func (e *RegisterTask) Register(
}
return NewGamePlayer(ctx, systemClock, l1Clock, logger, m, dir, game.Proxy, txSender, contract, syncValidator, validators, creator, l1HeaderSource, selective, claimants)
}
err := registerOracle(ctx, m, oracles, gameFactory, caller, e.gameType)
err := registerOracle(ctx, logger, m, oracles, gameFactory, caller, e.gameType)
if err != nil {
return err
}
Expand All @@ -269,11 +269,15 @@ func (e *RegisterTask) Register(
return nil
}

func registerOracle(ctx context.Context, m metrics.Metricer, oracles OracleRegistry, gameFactory *contracts.DisputeGameFactoryContract, caller *batching.MultiCaller, gameType faultTypes.GameType) error {
func registerOracle(ctx context.Context, logger log.Logger, m metrics.Metricer, oracles OracleRegistry, gameFactory *contracts.DisputeGameFactoryContract, caller *batching.MultiCaller, gameType faultTypes.GameType) error {
implAddr, err := gameFactory.GetGameImpl(ctx, gameType)
if err != nil {
return fmt.Errorf("failed to load implementation for game type %v: %w", gameType, err)
}
if implAddr == (common.Address{}) {
logger.Warn("No game implementation set for game type", "gameType", gameType)
return nil
}
contract, err := contracts.NewFaultDisputeGameContract(ctx, m, implAddr, caller)
if err != nil {
return fmt.Errorf("failed to create fault dispute game contracts: %w", err)
Expand Down
71 changes: 71 additions & 0 deletions op-challenger/game/fault/register_task_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package fault

import (
"context"
"testing"

"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/game/registry"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock"
"github.com/ethereum-optimism/optimism/op-service/sources/batching/test"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)

func TestRegisterOracle_MissingGameImpl(t *testing.T) {
gameFactoryAddr := common.Address{0xaa}
rpc := test.NewAbiBasedRpc(t, gameFactoryAddr, snapshots.LoadDisputeGameFactoryABI())
m := metrics.NoopMetrics
caller := batching.NewMultiCaller(rpc, batching.DefaultBatchSize)
gameFactory := contracts.NewDisputeGameFactoryContract(m, gameFactoryAddr, caller)

logger, logs := testlog.CaptureLogger(t, log.LvlInfo)
oracles := registry.NewOracleRegistry()
gameType := faultTypes.CannonGameType

rpc.SetResponse(gameFactoryAddr, "gameImpls", rpcblock.Latest, []interface{}{gameType}, []interface{}{common.Address{}})

err := registerOracle(context.Background(), logger, m, oracles, gameFactory, caller, gameType)
require.NoError(t, err)
require.NotNil(t, logs.FindLog(
testlog.NewMessageFilter("No game implementation set for game type"),
testlog.NewAttributesFilter("gameType", gameType.String())))
}

func TestRegisterOracle_AddsOracle(t *testing.T) {
gameFactoryAddr := common.Address{0xaa}
gameImplAddr := common.Address{0xbb}
vmAddr := common.Address{0xcc}
oracleAddr := common.Address{0xdd}
rpc := test.NewAbiBasedRpc(t, gameFactoryAddr, snapshots.LoadDisputeGameFactoryABI())
rpc.AddContract(gameImplAddr, snapshots.LoadFaultDisputeGameABI())
rpc.AddContract(vmAddr, snapshots.LoadMIPSABI())
rpc.AddContract(oracleAddr, snapshots.LoadPreimageOracleABI())
m := metrics.NoopMetrics
caller := batching.NewMultiCaller(rpc, batching.DefaultBatchSize)
gameFactory := contracts.NewDisputeGameFactoryContract(m, gameFactoryAddr, caller)

logger := testlog.Logger(t, log.LvlInfo)
oracles := registry.NewOracleRegistry()
gameType := faultTypes.CannonGameType

// Use the latest v1 of these contracts. Doesn't have to be an exact match for the version.
rpc.SetResponse(gameImplAddr, "version", rpcblock.Latest, []interface{}{}, []interface{}{"1.100.0"})
rpc.SetResponse(oracleAddr, "version", rpcblock.Latest, []interface{}{}, []interface{}{"1.100.0"})

rpc.SetResponse(gameFactoryAddr, "gameImpls", rpcblock.Latest, []interface{}{gameType}, []interface{}{gameImplAddr})
rpc.SetResponse(gameImplAddr, "vm", rpcblock.Latest, []interface{}{}, []interface{}{vmAddr})
rpc.SetResponse(vmAddr, "oracle", rpcblock.Latest, []interface{}{}, []interface{}{oracleAddr})

err := registerOracle(context.Background(), logger, m, oracles, gameFactory, caller, gameType)
require.NoError(t, err)
registered := oracles.Oracles()
require.Len(t, registered, 1)
require.Equal(t, oracleAddr, registered[0].Addr())
}

0 comments on commit de79564

Please sign in to comment.