Commit 113e2744 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-challenger, op-dispute-mon: Support both old and new versions of the...

op-challenger, op-dispute-mon: Support both old and new versions of the dispute game contracts (#10302)

* op-challenger, op-dispute-mon: Support both old and new versions of the dispute game contracts.

* op-challenger: Update fault dispute game contract tests to cover multiple versions.
parent ba174f4d
package main package main
import ( import (
"context"
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/op-challenger/config" "github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/flags" "github.com/ethereum-optimism/optimism/op-challenger/flags"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/tools" "github.com/ethereum-optimism/optimism/op-challenger/tools"
opservice "github.com/ethereum-optimism/optimism/op-service" opservice "github.com/ethereum-optimism/optimism/op-service"
oplog "github.com/ethereum-optimism/optimism/op-service/log" oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
...@@ -38,7 +41,10 @@ func CreateGame(ctx *cli.Context) error { ...@@ -38,7 +41,10 @@ func CreateGame(ctx *cli.Context) error {
traceType := ctx.Uint64(TraceTypeFlag.Name) traceType := ctx.Uint64(TraceTypeFlag.Name)
l2BlockNum := ctx.Uint64(L2BlockNumFlag.Name) l2BlockNum := ctx.Uint64(L2BlockNumFlag.Name)
contract, txMgr, err := NewContractWithTxMgr[*contracts.DisputeGameFactoryContract](ctx, flags.FactoryAddressFlag.Name, contracts.NewDisputeGameFactoryContract) contract, txMgr, err := NewContractWithTxMgr[*contracts.DisputeGameFactoryContract](ctx, flags.FactoryAddressFlag.Name,
func(ctx context.Context, metricer contractMetrics.ContractMetricer, address common.Address, caller *batching.MultiCaller) (*contracts.DisputeGameFactoryContract, error) {
return contracts.NewDisputeGameFactoryContract(metricer, address, caller), nil
})
if err != nil { if err != nil {
return fmt.Errorf("failed to create dispute game factory bindings: %w", err) return fmt.Errorf("failed to create dispute game factory bindings: %w", err)
} }
......
...@@ -48,11 +48,14 @@ func ListClaims(ctx *cli.Context) error { ...@@ -48,11 +48,14 @@ func ListClaims(ctx *cli.Context) error {
defer l1Client.Close() defer l1Client.Close()
caller := batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize) caller := batching.NewMultiCaller(l1Client.Client(), batching.DefaultBatchSize)
contract := contracts.NewFaultDisputeGameContract(metrics.NoopContractMetrics, gameAddr, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx.Context, metrics.NoopContractMetrics, gameAddr, caller)
if err != nil {
return err
}
return listClaims(ctx.Context, contract) return listClaims(ctx.Context, contract)
} }
func listClaims(ctx context.Context, game *contracts.FaultDisputeGameContract) error { func listClaims(ctx context.Context, game contracts.FaultDisputeGameContract) error {
maxDepth, err := game.GetMaxGameDepth(ctx) maxDepth, err := game.GetMaxGameDepth(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed to retrieve max depth: %w", err) return fmt.Errorf("failed to retrieve max depth: %w", err)
......
...@@ -66,7 +66,10 @@ func listGames(ctx context.Context, caller *batching.MultiCaller, factory *contr ...@@ -66,7 +66,10 @@ func listGames(ctx context.Context, caller *batching.MultiCaller, factory *contr
infos := make([]*gameInfo, len(games)) infos := make([]*gameInfo, len(games))
var wg sync.WaitGroup var wg sync.WaitGroup
for idx, game := range games { for idx, game := range games {
gameContract := contracts.NewFaultDisputeGameContract(metrics.NoopContractMetrics, game.Proxy, caller) gameContract, err := contracts.NewFaultDisputeGameContract(ctx, metrics.NoopContractMetrics, game.Proxy, caller)
if err != nil {
return fmt.Errorf("failed to create dispute game contract: %w", err)
}
info := gameInfo{GameMetadata: game} info := gameInfo{GameMetadata: game}
infos[idx] = &info infos[idx] = &info
gameProxy := game.Proxy gameProxy := game.Proxy
......
...@@ -46,7 +46,7 @@ func Move(ctx *cli.Context) error { ...@@ -46,7 +46,7 @@ func Move(ctx *cli.Context) error {
return fmt.Errorf("both attack and defense flags cannot be set") return fmt.Errorf("both attack and defense flags cannot be set")
} }
contract, txMgr, err := NewContractWithTxMgr[*contracts.FaultDisputeGameContract](ctx, GameAddressFlag.Name, contracts.NewFaultDisputeGameContract) contract, txMgr, err := NewContractWithTxMgr[contracts.FaultDisputeGameContract](ctx, GameAddressFlag.Name, contracts.NewFaultDisputeGameContract)
if err != nil { if err != nil {
return fmt.Errorf("failed to create dispute game bindings: %w", err) return fmt.Errorf("failed to create dispute game bindings: %w", err)
} }
......
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
) )
func Resolve(ctx *cli.Context) error { func Resolve(ctx *cli.Context) error {
contract, txMgr, err := NewContractWithTxMgr[*contracts.FaultDisputeGameContract](ctx, GameAddressFlag.Name, contracts.NewFaultDisputeGameContract) contract, txMgr, err := NewContractWithTxMgr[contracts.FaultDisputeGameContract](ctx, GameAddressFlag.Name, contracts.NewFaultDisputeGameContract)
if err != nil { if err != nil {
return fmt.Errorf("failed to create dispute game bindings: %w", err) return fmt.Errorf("failed to create dispute game bindings: %w", err)
} }
......
package main package main
import ( import (
"context"
"fmt" "fmt"
"github.com/ethereum-optimism/optimism/op-challenger/flags" "github.com/ethereum-optimism/optimism/op-challenger/flags"
...@@ -14,7 +15,7 @@ import ( ...@@ -14,7 +15,7 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
type ContractCreator[T any] func(contractMetrics.ContractMetricer, common.Address, *batching.MultiCaller) T type ContractCreator[T any] func(context.Context, contractMetrics.ContractMetricer, common.Address, *batching.MultiCaller) (T, error)
// NewContractWithTxMgr creates a new contract and a transaction manager. // NewContractWithTxMgr creates a new contract and a transaction manager.
func NewContractWithTxMgr[T any](ctx *cli.Context, flagName string, creator ContractCreator[T]) (T, txmgr.TxManager, error) { func NewContractWithTxMgr[T any](ctx *cli.Context, flagName string, creator ContractCreator[T]) (T, txmgr.TxManager, error) {
...@@ -40,7 +41,10 @@ func newContractFromCLI[T any](ctx *cli.Context, flagName string, caller *batchi ...@@ -40,7 +41,10 @@ func newContractFromCLI[T any](ctx *cli.Context, flagName string, caller *batchi
return contract, err return contract, err
} }
created := creator(contractMetrics.NoopContractMetrics, gameAddr, caller) created, err := creator(ctx.Context, contractMetrics.NoopContractMetrics, gameAddr, caller)
if err != nil {
return contract, fmt.Errorf("failed to create contract bindings: %w", err)
}
return created, nil return created, nil
} }
......
package contracts
import (
"context"
_ "embed"
"fmt"
"math/big"
"time"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"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/txmgr"
"github.com/ethereum/go-ethereum/common"
)
//go:embed abis/FaultDisputeGame-0.8.0.json
var faultDisputeGameAbi020 []byte
var resolvedBondAmount = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 128), big.NewInt(1))
var (
methodGameDuration = "gameDuration"
)
type FaultDisputeGameContract080 struct {
FaultDisputeGameContractLatest
}
// GetGameMetadata returns the game's L1 head, L2 block number, root claim, status, and max clock duration.
func (f *FaultDisputeGameContract080) GetGameMetadata(ctx context.Context, block rpcblock.Block) (common.Hash, uint64, common.Hash, gameTypes.GameStatus, uint64, error) {
defer f.metrics.StartContractRequest("GetGameMetadata")()
results, err := f.multiCaller.Call(ctx, block,
f.contract.Call(methodL1Head),
f.contract.Call(methodL2BlockNumber),
f.contract.Call(methodRootClaim),
f.contract.Call(methodStatus),
f.contract.Call(methodGameDuration))
if err != nil {
return common.Hash{}, 0, common.Hash{}, 0, 0, fmt.Errorf("failed to retrieve game metadata: %w", err)
}
if len(results) != 5 {
return common.Hash{}, 0, common.Hash{}, 0, 0, fmt.Errorf("expected 3 results but got %v", len(results))
}
l1Head := results[0].GetHash(0)
l2BlockNumber := results[1].GetBigInt(0).Uint64()
rootClaim := results[2].GetHash(0)
status, err := gameTypes.GameStatusFromUint8(results[3].GetUint8(0))
if err != nil {
return common.Hash{}, 0, common.Hash{}, 0, 0, fmt.Errorf("failed to convert game status: %w", err)
}
duration := results[4].GetUint64(0)
return l1Head, l2BlockNumber, rootClaim, status, duration / 2, nil
}
func (f *FaultDisputeGameContract080) GetMaxClockDuration(ctx context.Context) (time.Duration, error) {
defer f.metrics.StartContractRequest("GetMaxClockDuration")()
result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, f.contract.Call(methodGameDuration))
if err != nil {
return 0, fmt.Errorf("failed to fetch game duration: %w", err)
}
return time.Duration(result.GetUint64(0)) * time.Second / 2, nil
}
func (f *FaultDisputeGameContract080) GetClaim(ctx context.Context, idx uint64) (types.Claim, error) {
claim, err := f.FaultDisputeGameContractLatest.GetClaim(ctx, idx)
if err != nil {
return types.Claim{}, err
}
// Replace the resolved sentinel with what the bond would have been
if claim.Bond.Cmp(resolvedBondAmount) == 0 {
bond, err := f.GetRequiredBond(ctx, claim.Position)
if err != nil {
return types.Claim{}, err
}
claim.Bond = bond
}
return claim, nil
}
func (f *FaultDisputeGameContract080) GetAllClaims(ctx context.Context, block rpcblock.Block) ([]types.Claim, error) {
claims, err := f.FaultDisputeGameContractLatest.GetAllClaims(ctx, block)
if err != nil {
return nil, err
}
resolvedClaims := make([]*types.Claim, 0, len(claims))
positions := make([]*big.Int, 0, len(claims))
for i, claim := range claims {
if claim.Bond.Cmp(resolvedBondAmount) == 0 {
resolvedClaims = append(resolvedClaims, &claims[i])
positions = append(positions, claim.Position.ToGIndex())
}
}
bonds, err := f.GetRequiredBonds(ctx, block, positions...)
if err != nil {
return nil, fmt.Errorf("failed to get required bonds for resolved claims: %w", err)
}
for i, bond := range bonds {
resolvedClaims[i].Bond = bond
}
return claims, nil
}
func (f *FaultDisputeGameContract080) IsResolved(ctx context.Context, block rpcblock.Block, claims ...types.Claim) ([]bool, error) {
rawClaims, err := f.FaultDisputeGameContractLatest.GetAllClaims(ctx, block)
if err != nil {
return nil, fmt.Errorf("failed to get raw claim data: %w", err)
}
results := make([]bool, len(claims))
for i, claim := range claims {
results[i] = rawClaims[claim.ContractIndex].Bond.Cmp(resolvedBondAmount) == 0
}
return results, nil
}
func (f *FaultDisputeGameContract080) CallResolveClaim(ctx context.Context, claimIdx uint64) error {
defer f.metrics.StartContractRequest("CallResolveClaim")()
call := f.resolveClaimCall(claimIdx)
_, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, call)
if err != nil {
return fmt.Errorf("failed to call resolve claim: %w", err)
}
return nil
}
func (f *FaultDisputeGameContract080) ResolveClaimTx(claimIdx uint64) (txmgr.TxCandidate, error) {
call := f.resolveClaimCall(claimIdx)
return call.ToTxCandidate()
}
func (f *FaultDisputeGameContract080) resolveClaimCall(claimIdx uint64) *batching.ContractCall {
return f.contract.Call(methodResolveClaim, new(big.Int).SetUint64(claimIdx))
}
...@@ -120,7 +120,10 @@ func registerAlphabet( ...@@ -120,7 +120,10 @@ func registerAlphabet(
claimants []common.Address, claimants []common.Address,
) error { ) error {
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract := contracts.NewFaultDisputeGameContract(m, game.Proxy, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller)
if err != nil {
return nil, fmt.Errorf("failed to create fault dispute game contract: %w", err)
}
oracle, err := contract.GetOracle(ctx) oracle, err := contract.GetOracle(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to load oracle for game %v: %w", game.Proxy, err) return nil, fmt.Errorf("failed to load oracle for game %v: %w", game.Proxy, err)
...@@ -157,7 +160,7 @@ func registerAlphabet( ...@@ -157,7 +160,7 @@ func registerAlphabet(
registry.RegisterGameType(faultTypes.AlphabetGameType, playerCreator) registry.RegisterGameType(faultTypes.AlphabetGameType, playerCreator)
contractCreator := func(game types.GameMetadata) (claims.BondContract, error) { contractCreator := func(game types.GameMetadata) (claims.BondContract, error) {
return contracts.NewFaultDisputeGameContract(m, game.Proxy, caller), nil return contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller)
} }
registry.RegisterBondContract(faultTypes.AlphabetGameType, contractCreator) registry.RegisterBondContract(faultTypes.AlphabetGameType, contractCreator)
return nil return nil
...@@ -168,7 +171,10 @@ func registerOracle(ctx context.Context, m metrics.Metricer, oracles OracleRegis ...@@ -168,7 +171,10 @@ func registerOracle(ctx context.Context, m metrics.Metricer, oracles OracleRegis
if err != nil { if err != nil {
return fmt.Errorf("failed to load implementation for game type %v: %w", gameType, err) return fmt.Errorf("failed to load implementation for game type %v: %w", gameType, err)
} }
contract := contracts.NewFaultDisputeGameContract(m, implAddr, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx, m, implAddr, caller)
if err != nil {
return fmt.Errorf("failed to create fault dispute game contracts: %w", err)
}
oracle, err := contract.GetOracle(ctx) oracle, err := contract.GetOracle(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed to load oracle address: %w", err) return fmt.Errorf("failed to load oracle address: %w", err)
...@@ -199,7 +205,10 @@ func registerAsterisc( ...@@ -199,7 +205,10 @@ func registerAsterisc(
) error { ) error {
asteriscPrestateProvider := asterisc.NewPrestateProvider(cfg.AsteriscAbsolutePreState) asteriscPrestateProvider := asterisc.NewPrestateProvider(cfg.AsteriscAbsolutePreState)
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract := contracts.NewFaultDisputeGameContract(m, game.Proxy, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller)
if err != nil {
return nil, fmt.Errorf("failed to create fault dispute game contracts: %w", err)
}
oracle, err := contract.GetOracle(ctx) oracle, err := contract.GetOracle(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to load oracle for game %v: %w", game.Proxy, err) return nil, fmt.Errorf("failed to load oracle for game %v: %w", game.Proxy, err)
...@@ -236,7 +245,7 @@ func registerAsterisc( ...@@ -236,7 +245,7 @@ func registerAsterisc(
registry.RegisterGameType(gameType, playerCreator) registry.RegisterGameType(gameType, playerCreator)
contractCreator := func(game types.GameMetadata) (claims.BondContract, error) { contractCreator := func(game types.GameMetadata) (claims.BondContract, error) {
return contracts.NewFaultDisputeGameContract(m, game.Proxy, caller), nil return contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller)
} }
registry.RegisterBondContract(gameType, contractCreator) registry.RegisterBondContract(gameType, contractCreator)
return nil return nil
...@@ -276,7 +285,10 @@ func registerCannon( ...@@ -276,7 +285,10 @@ func registerCannon(
return cannon.NewPrestateProvider(prestatePath), nil return cannon.NewPrestateProvider(prestatePath), nil
}) })
playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) { playerCreator := func(game types.GameMetadata, dir string) (scheduler.GamePlayer, error) {
contract := contracts.NewFaultDisputeGameContract(m, game.Proxy, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller)
if err != nil {
return nil, fmt.Errorf("failed to create fault dispute game contracts: %w", err)
}
requiredPrestatehash, err := contract.GetAbsolutePrestateHash(ctx) requiredPrestatehash, err := contract.GetAbsolutePrestateHash(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to load prestate hash for game %v: %w", game.Proxy, err) return nil, fmt.Errorf("failed to load prestate hash for game %v: %w", game.Proxy, err)
...@@ -324,13 +336,13 @@ func registerCannon( ...@@ -324,13 +336,13 @@ func registerCannon(
registry.RegisterGameType(gameType, playerCreator) registry.RegisterGameType(gameType, playerCreator)
contractCreator := func(game types.GameMetadata) (claims.BondContract, error) { contractCreator := func(game types.GameMetadata) (claims.BondContract, error) {
return contracts.NewFaultDisputeGameContract(m, game.Proxy, caller), nil return contracts.NewFaultDisputeGameContract(ctx, m, game.Proxy, caller)
} }
registry.RegisterBondContract(gameType, contractCreator) registry.RegisterBondContract(gameType, contractCreator)
return nil return nil
} }
func loadL1Head(contract *contracts.FaultDisputeGameContract, ctx context.Context, l1HeaderSource L1HeaderSource) (eth.BlockID, error) { func loadL1Head(contract contracts.FaultDisputeGameContract, ctx context.Context, l1HeaderSource L1HeaderSource) (eth.BlockID, error) {
l1Head, err := contract.GetL1Head(ctx) l1Head, err := contract.GetL1Head(ctx)
if err != nil { if err != nil {
return eth.BlockID{}, fmt.Errorf("failed to load L1 head: %w", err) return eth.BlockID{}, fmt.Errorf("failed to load L1 head: %w", err)
......
...@@ -34,7 +34,7 @@ type GameCaller interface { ...@@ -34,7 +34,7 @@ type GameCaller interface {
type GameCallerCreator struct { type GameCallerCreator struct {
m GameCallerMetrics m GameCallerMetrics
cache *caching.LRUCache[common.Address, *contracts.FaultDisputeGameContract] cache *caching.LRUCache[common.Address, contracts.FaultDisputeGameContract]
caller *batching.MultiCaller caller *batching.MultiCaller
} }
...@@ -42,17 +42,20 @@ func NewGameCallerCreator(m GameCallerMetrics, caller *batching.MultiCaller) *Ga ...@@ -42,17 +42,20 @@ func NewGameCallerCreator(m GameCallerMetrics, caller *batching.MultiCaller) *Ga
return &GameCallerCreator{ return &GameCallerCreator{
m: m, m: m,
caller: caller, caller: caller,
cache: caching.NewLRUCache[common.Address, *contracts.FaultDisputeGameContract](m, metricsLabel, 100), cache: caching.NewLRUCache[common.Address, contracts.FaultDisputeGameContract](m, metricsLabel, 100),
} }
} }
func (g *GameCallerCreator) CreateContract(game gameTypes.GameMetadata) (GameCaller, error) { func (g *GameCallerCreator) CreateContract(ctx context.Context, game gameTypes.GameMetadata) (GameCaller, error) {
if fdg, ok := g.cache.Get(game.Proxy); ok { if fdg, ok := g.cache.Get(game.Proxy); ok {
return fdg, nil return fdg, nil
} }
switch game.GameType { switch game.GameType {
case faultTypes.CannonGameType, faultTypes.AsteriscGameType, faultTypes.AlphabetGameType: case faultTypes.CannonGameType, faultTypes.AsteriscGameType, faultTypes.AlphabetGameType:
fdg := contracts.NewFaultDisputeGameContract(g.m, game.Proxy, g.caller) fdg, err := contracts.NewFaultDisputeGameContract(ctx, g.m, game.Proxy, g.caller)
if err != nil {
return nil, fmt.Errorf("failed to create fault dispute game contract: %w", err)
}
g.cache.Add(game.Proxy, fdg) g.cache.Add(game.Proxy, fdg)
return fdg, nil return fdg, nil
default: default:
......
package extract package extract
import ( import (
"context"
"fmt" "fmt"
"testing" "testing"
contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" contractMetrics "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics"
"github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
...@@ -49,13 +51,13 @@ func TestMetadataCreator_CreateContract(t *testing.T) { ...@@ -49,13 +51,13 @@ func TestMetadataCreator_CreateContract(t *testing.T) {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
caller, metrics := setupMetadataLoaderTest(t) caller, metrics := setupMetadataLoaderTest(t)
creator := NewGameCallerCreator(metrics, caller) creator := NewGameCallerCreator(metrics, caller)
_, err := creator.CreateContract(test.game) _, err := creator.CreateContract(context.Background(), test.game)
require.Equal(t, test.expectedErr, err) require.Equal(t, test.expectedErr, err)
if test.expectedErr == nil { if test.expectedErr == nil {
require.Equal(t, 1, metrics.cacheAddCalls) require.Equal(t, 1, metrics.cacheAddCalls)
require.Equal(t, 1, metrics.cacheGetCalls) require.Equal(t, 1, metrics.cacheGetCalls)
} }
_, err = creator.CreateContract(test.game) _, err = creator.CreateContract(context.Background(), test.game)
require.Equal(t, test.expectedErr, err) require.Equal(t, test.expectedErr, err)
if test.expectedErr == nil { if test.expectedErr == nil {
require.Equal(t, 1, metrics.cacheAddCalls) require.Equal(t, 1, metrics.cacheAddCalls)
...@@ -70,6 +72,7 @@ func setupMetadataLoaderTest(t *testing.T) (*batching.MultiCaller, *mockCacheMet ...@@ -70,6 +72,7 @@ func setupMetadataLoaderTest(t *testing.T) (*batching.MultiCaller, *mockCacheMet
require.NoError(t, err) require.NoError(t, err)
stubRpc := batchingTest.NewAbiBasedRpc(t, fdgAddr, fdgAbi) stubRpc := batchingTest.NewAbiBasedRpc(t, fdgAddr, fdgAbi)
caller := batching.NewMultiCaller(stubRpc, batching.DefaultBatchSize) caller := batching.NewMultiCaller(stubRpc, batching.DefaultBatchSize)
stubRpc.SetResponse(fdgAddr, "version", rpcblock.Latest, nil, []interface{}{"0.18.0"})
return caller, &mockCacheMetrics{} return caller, &mockCacheMetrics{}
} }
......
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
) )
type ( type (
CreateGameCaller func(game gameTypes.GameMetadata) (GameCaller, error) CreateGameCaller func(ctx context.Context, game gameTypes.GameMetadata) (GameCaller, error)
FactoryGameFetcher func(ctx context.Context, blockHash common.Hash, earliestTimestamp uint64) ([]gameTypes.GameMetadata, error) FactoryGameFetcher func(ctx context.Context, blockHash common.Hash, earliestTimestamp uint64) ([]gameTypes.GameMetadata, error)
) )
...@@ -48,7 +48,7 @@ func (e *Extractor) Extract(ctx context.Context, blockHash common.Hash, minTimes ...@@ -48,7 +48,7 @@ func (e *Extractor) Extract(ctx context.Context, blockHash common.Hash, minTimes
func (e *Extractor) enrichGames(ctx context.Context, blockHash common.Hash, games []gameTypes.GameMetadata) []*monTypes.EnrichedGameData { func (e *Extractor) enrichGames(ctx context.Context, blockHash common.Hash, games []gameTypes.GameMetadata) []*monTypes.EnrichedGameData {
var enrichedGames []*monTypes.EnrichedGameData var enrichedGames []*monTypes.EnrichedGameData
for _, game := range games { for _, game := range games {
caller, err := e.createContract(game) caller, err := e.createContract(ctx, game)
if err != nil { if err != nil {
e.logger.Error("Failed to create game caller", "err", err) e.logger.Error("Failed to create game caller", "err", err)
continue continue
......
...@@ -167,7 +167,7 @@ type mockGameCallerCreator struct { ...@@ -167,7 +167,7 @@ type mockGameCallerCreator struct {
caller *mockGameCaller caller *mockGameCaller
} }
func (m *mockGameCallerCreator) CreateGameCaller(_ gameTypes.GameMetadata) (GameCaller, error) { func (m *mockGameCallerCreator) CreateGameCaller(_ context.Context, _ gameTypes.GameMetadata) (GameCaller, error) {
m.calls++ m.calls++
if m.err != nil { if m.err != nil {
return nil, m.err return nil, m.err
......
...@@ -39,7 +39,8 @@ func (g *OutputAlphabetGameHelper) StartChallenger( ...@@ -39,7 +39,8 @@ func (g *OutputAlphabetGameHelper) StartChallenger(
func (g *OutputAlphabetGameHelper) CreateHonestActor(ctx context.Context, l2Node string) *OutputHonestHelper { func (g *OutputAlphabetGameHelper) CreateHonestActor(ctx context.Context, l2Node string) *OutputHonestHelper {
logger := testlog.Logger(g.T, log.LevelInfo).New("role", "HonestHelper", "game", g.Addr) logger := testlog.Logger(g.T, log.LevelInfo).New("role", "HonestHelper", "game", g.Addr)
caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize) caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize)
contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.Addr, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
g.Require.NoError(err, "Get block range") g.Require.NoError(err, "Get block range")
splitDepth := g.SplitDepth(ctx) splitDepth := g.SplitDepth(ctx)
......
...@@ -63,7 +63,8 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s ...@@ -63,7 +63,8 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s
logger := testlog.Logger(g.T, log.LevelInfo).New("role", "HonestHelper", "game", g.Addr) logger := testlog.Logger(g.T, log.LevelInfo).New("role", "HonestHelper", "game", g.Addr)
l2Client := g.System.NodeClient(l2Node) l2Client := g.System.NodeClient(l2Node)
caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize) caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize)
contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.Addr, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
g.Require.NoError(err, "Failed to load block range") g.Require.NoError(err, "Failed to load block range")
...@@ -288,7 +289,8 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context, ...@@ -288,7 +289,8 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context,
caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize) caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize)
l2Client := g.System.NodeClient(l2Node) l2Client := g.System.NodeClient(l2Node)
contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.Addr, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx)
g.Require.NoError(err, "Failed to load block range") g.Require.NoError(err, "Failed to load block range")
......
...@@ -713,7 +713,8 @@ func (g *OutputGameHelper) UploadPreimage(ctx context.Context, data *types.Preim ...@@ -713,7 +713,8 @@ func (g *OutputGameHelper) UploadPreimage(ctx context.Context, data *types.Preim
func (g *OutputGameHelper) oracle(ctx context.Context) *contracts.PreimageOracleContract { func (g *OutputGameHelper) oracle(ctx context.Context) *contracts.PreimageOracleContract {
caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize) caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize)
contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.Addr, caller) contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
oracle, err := contract.GetOracle(ctx) oracle, err := contract.GetOracle(ctx)
g.Require.NoError(err, "Failed to create oracle contract") g.Require.NoError(err, "Failed to create oracle contract")
return oracle return oracle
......
...@@ -17,11 +17,11 @@ type OutputHonestHelper struct { ...@@ -17,11 +17,11 @@ type OutputHonestHelper struct {
t *testing.T t *testing.T
require *require.Assertions require *require.Assertions
game *OutputGameHelper game *OutputGameHelper
contract *contracts.FaultDisputeGameContract contract contracts.FaultDisputeGameContract
correctTrace types.TraceAccessor correctTrace types.TraceAccessor
} }
func NewOutputHonestHelper(t *testing.T, require *require.Assertions, game *OutputGameHelper, contract *contracts.FaultDisputeGameContract, correctTrace types.TraceAccessor) *OutputHonestHelper { func NewOutputHonestHelper(t *testing.T, require *require.Assertions, game *OutputGameHelper, contract contracts.FaultDisputeGameContract, correctTrace types.TraceAccessor) *OutputHonestHelper {
return &OutputHonestHelper{ return &OutputHonestHelper{
t: t, t: t,
require: require, require: require,
......
...@@ -63,3 +63,7 @@ func (c *CallResult) GetBytes32(i int) [32]byte { ...@@ -63,3 +63,7 @@ func (c *CallResult) GetBytes32(i int) [32]byte {
func (c *CallResult) GetBytes32Slice(i int) [][32]byte { func (c *CallResult) GetBytes32Slice(i int) [][32]byte {
return *abi.ConvertType(c.out[i], new([][32]byte)).(*[][32]byte) return *abi.ConvertType(c.out[i], new([][32]byte)).(*[][32]byte)
} }
func (c *CallResult) GetString(i int) string {
return *abi.ConvertType(c.out[i], new(string)).(*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