Commit 2586a82f authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

op-e2e: Convert most FaultDisputeGame read operations to use custom contract bindings (#10533)

* op-e2e: Delete unused helpers from pre-output root support

* op-e2e: Convert most FaultDisputeGame read operations to use custom contract bindings

* op-e2e: Remove manual creation of contract bindings
parent 9300db95
...@@ -16,19 +16,19 @@ type ClaimHelper struct { ...@@ -16,19 +16,19 @@ type ClaimHelper struct {
require *require.Assertions require *require.Assertions
game *OutputGameHelper game *OutputGameHelper
Index int64 Index int64
ParentIndex uint32 ParentIndex int
Position types.Position Position types.Position
claim common.Hash claim common.Hash
} }
func newClaimHelper(game *OutputGameHelper, idx int64, claim ContractClaim) *ClaimHelper { func newClaimHelper(game *OutputGameHelper, idx int64, claim types.Claim) *ClaimHelper {
return &ClaimHelper{ return &ClaimHelper{
require: game.Require, require: game.Require,
game: game, game: game,
Index: idx, Index: idx,
ParentIndex: claim.ParentIndex, ParentIndex: claim.ParentContractIndex,
Position: types.NewPositionFromGIndex(claim.Position), Position: claim.Position,
claim: claim.Claim, claim: claim.Value,
} }
} }
...@@ -72,8 +72,8 @@ func (c *ClaimHelper) WaitForCounterClaim(ctx context.Context, ignoreClaims ...* ...@@ -72,8 +72,8 @@ func (c *ClaimHelper) WaitForCounterClaim(ctx context.Context, ignoreClaims ...*
// This is the first claim we need to run cannon on, so give it more time // This is the first claim we need to run cannon on, so give it more time
timeout = timeout * 2 timeout = timeout * 2
} }
counterIdx, counterClaim := c.game.waitForClaim(ctx, timeout, fmt.Sprintf("failed to find claim with parent idx %v", c.Index), func(claimIdx int64, claim ContractClaim) bool { counterIdx, counterClaim := c.game.waitForClaim(ctx, timeout, fmt.Sprintf("failed to find claim with parent idx %v", c.Index), func(claimIdx int64, claim types.Claim) bool {
return int64(claim.ParentIndex) == c.Index && !containsClaim(claimIdx, ignoreClaims) return int64(claim.ParentContractIndex) == c.Index && !containsClaim(claimIdx, ignoreClaims)
}) })
return newClaimHelper(c.game, counterIdx, counterClaim) return newClaimHelper(c.game, counterIdx, counterClaim)
} }
...@@ -115,7 +115,7 @@ func (c *ClaimHelper) RequireDifferentClaimValue(other *ClaimHelper) { ...@@ -115,7 +115,7 @@ func (c *ClaimHelper) RequireDifferentClaimValue(other *ClaimHelper) {
func (c *ClaimHelper) RequireOnlyCounteredBy(ctx context.Context, expected ...*ClaimHelper) { func (c *ClaimHelper) RequireOnlyCounteredBy(ctx context.Context, expected ...*ClaimHelper) {
claims := c.game.getAllClaims(ctx) claims := c.game.getAllClaims(ctx)
for idx, claim := range claims { for idx, claim := range claims {
if int64(claim.ParentIndex) != c.Index { if int64(claim.ParentContractIndex) != c.Index {
// Doesn't counter this claim, so ignore // Doesn't counter this claim, so ignore
continue continue
} }
......
...@@ -25,7 +25,7 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context, rootClaim ...@@ -25,7 +25,7 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context, rootClaim
depth := d.MaxDepth(ctx) depth := d.MaxDepth(ctx)
splitDepth := d.SplitDepth(ctx) splitDepth := d.SplitDepth(ctx)
move := func(claimIndex int64, claimData ContractClaim) { move := func(claimIndex int64, claimData types.Claim) {
// dishonest level, valid attack // dishonest level, valid attack
// dishonest level, invalid attack // dishonest level, invalid attack
// dishonest level, valid defense // dishonest level, valid defense
...@@ -33,22 +33,21 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context, rootClaim ...@@ -33,22 +33,21 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context, rootClaim
// honest level, invalid attack // honest level, invalid attack
// honest level, invalid defense // honest level, invalid defense
pos := types.NewPositionFromGIndex(claimData.Position) if claimData.Depth() == depth {
if pos.Depth() == depth {
return return
} }
d.LogGameData(ctx) d.LogGameData(ctx)
d.OutputGameHelper.T.Logf("Dishonest moves against claimIndex %d", claimIndex) d.OutputGameHelper.T.Logf("Dishonest moves against claimIndex %d", claimIndex)
agreeWithLevel := d.defender == (pos.Depth()%2 == 0) agreeWithLevel := d.defender == (claimData.Depth()%2 == 0)
if !agreeWithLevel { if !agreeWithLevel {
d.OutputHonestHelper.Attack(ctx, claimIndex, WithIgnoreDuplicates()) d.OutputHonestHelper.Attack(ctx, claimIndex, WithIgnoreDuplicates())
if claimIndex != 0 && pos.Depth() != splitDepth+1 { if claimIndex != 0 && claimData.Depth() != splitDepth+1 {
d.OutputHonestHelper.Defend(ctx, claimIndex, WithIgnoreDuplicates()) d.OutputHonestHelper.Defend(ctx, claimIndex, WithIgnoreDuplicates())
} }
} }
d.OutputGameHelper.Attack(ctx, claimIndex, common.Hash{byte(claimIndex)}, WithIgnoreDuplicates()) d.OutputGameHelper.Attack(ctx, claimIndex, common.Hash{byte(claimIndex)}, WithIgnoreDuplicates())
if claimIndex != 0 && pos.Depth() != splitDepth+1 { if claimIndex != 0 && claimData.Depth() != splitDepth+1 {
d.OutputGameHelper.Defend(ctx, claimIndex, common.Hash{byte(claimIndex)}, WithIgnoreDuplicates()) d.OutputGameHelper.Defend(ctx, claimIndex, common.Hash{byte(claimIndex)}, WithIgnoreDuplicates())
} }
} }
......
...@@ -3,14 +3,14 @@ package disputegame ...@@ -3,14 +3,14 @@ package disputegame
import ( import (
"context" "context"
"encoding/binary" "encoding/binary"
"fmt"
"math/big" "math/big"
"testing" "testing"
"time" "time"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs"
faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame/preimage" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame/preimage"
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/sources" "github.com/ethereum-optimism/optimism/op-service/sources"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -38,32 +39,10 @@ var ( ...@@ -38,32 +39,10 @@ var (
) )
const ( const (
cannonGameType uint32 = 0 cannonGameType uint32 = 0
alphabetGameType uint32 = 255 alphabetGameType uint32 = 255
alphabetGameDepth = 4
) )
type Status uint8
const (
StatusInProgress Status = iota
StatusChallengerWins
StatusDefenderWins
)
func (s Status) String() string {
switch s {
case StatusInProgress:
return "In Progress"
case StatusChallengerWins:
return "Challenger Wins"
case StatusDefenderWins:
return "Defender Wins"
default:
return fmt.Sprintf("Unknown status: %v", int(s))
}
}
type GameCfg struct { type GameCfg struct {
allowFuture bool allowFuture bool
allowUnsafe bool allowUnsafe bool
...@@ -188,28 +167,27 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string ...@@ -188,28 +167,27 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string
h.Require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event") h.Require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event")
createdEvent, err := h.Factory.ParseDisputeGameCreated(*rcpt.Logs[1]) createdEvent, err := h.Factory.ParseDisputeGameCreated(*rcpt.Logs[1])
h.Require.NoError(err) h.Require.NoError(err)
game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.Client) gameBindings, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.Client)
h.Require.NoError(err)
game, err := contracts.NewFaultDisputeGameContract(ctx, metrics.NoopContractMetrics, createdEvent.DisputeProxy, batching.NewMultiCaller(h.Client.Client(), batching.DefaultBatchSize))
h.Require.NoError(err) h.Require.NoError(err)
callOpts := &bind.CallOpts{Context: ctx} prestateBlock, poststateBlock, err := game.GetBlockRange(ctx)
prestateBlock, err := game.StartingBlockNumber(callOpts)
h.Require.NoError(err, "Failed to load starting block number") h.Require.NoError(err, "Failed to load starting block number")
poststateBlock, err := game.L2BlockNumber(callOpts) splitDepth, err := game.GetSplitDepth(ctx)
h.Require.NoError(err, "Failed to load l2 block number")
splitDepth, err := game.SplitDepth(callOpts)
h.Require.NoError(err, "Failed to load split depth") h.Require.NoError(err, "Failed to load split depth")
l1Head := h.GetL1Head(ctx, game) l1Head := h.GetL1Head(ctx, game)
prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock.Uint64()) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock)
provider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, faultTypes.Depth(splitDepth.Uint64()), prestateBlock.Uint64(), poststateBlock.Uint64()) provider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock)
return &OutputCannonGameHelper{ return &OutputCannonGameHelper{
OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, game, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System), OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, game, gameBindings, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System),
} }
} }
func (h *FactoryHelper) GetL1Head(ctx context.Context, game *bindings.FaultDisputeGame) eth.BlockID { func (h *FactoryHelper) GetL1Head(ctx context.Context, game contracts.FaultDisputeGameContract) eth.BlockID {
l1HeadHash, err := game.L1Head(&bind.CallOpts{Context: ctx}) l1HeadHash, err := game.GetL1Head(ctx)
h.Require.NoError(err, "Failed to load L1 head") h.Require.NoError(err, "Failed to load L1 head")
l1Header, err := h.Client.HeaderByHash(ctx, l1HeadHash) l1Header, err := h.Client.HeaderByHash(ctx, l1HeadHash)
h.Require.NoError(err, "Failed to load L1 header") h.Require.NoError(err, "Failed to load L1 header")
...@@ -245,23 +223,22 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri ...@@ -245,23 +223,22 @@ func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node stri
h.Require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event") h.Require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event")
createdEvent, err := h.Factory.ParseDisputeGameCreated(*rcpt.Logs[1]) createdEvent, err := h.Factory.ParseDisputeGameCreated(*rcpt.Logs[1])
h.Require.NoError(err) h.Require.NoError(err)
game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.Client) gameBindings, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.Client)
h.Require.NoError(err)
game, err := contracts.NewFaultDisputeGameContract(ctx, metrics.NoopContractMetrics, createdEvent.DisputeProxy, batching.NewMultiCaller(h.Client.Client(), batching.DefaultBatchSize))
h.Require.NoError(err) h.Require.NoError(err)
callOpts := &bind.CallOpts{Context: ctx} prestateBlock, poststateBlock, err := game.GetBlockRange(ctx)
prestateBlock, err := game.StartingBlockNumber(callOpts)
h.Require.NoError(err, "Failed to load starting block number") h.Require.NoError(err, "Failed to load starting block number")
poststateBlock, err := game.L2BlockNumber(callOpts) splitDepth, err := game.GetSplitDepth(ctx)
h.Require.NoError(err, "Failed to load l2 block number")
splitDepth, err := game.SplitDepth(callOpts)
h.Require.NoError(err, "Failed to load split depth") h.Require.NoError(err, "Failed to load split depth")
l1Head := h.GetL1Head(ctx, game) l1Head := h.GetL1Head(ctx, game)
prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock.Uint64()) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock)
provider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, faultTypes.Depth(splitDepth.Uint64()), prestateBlock.Uint64(), poststateBlock.Uint64()) provider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock)
return &OutputAlphabetGameHelper{ return &OutputAlphabetGameHelper{
OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, game, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System), OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, game, gameBindings, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System),
} }
} }
......
...@@ -3,12 +3,9 @@ package disputegame ...@@ -3,12 +3,9 @@ package disputegame
import ( import (
"context" "context"
"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/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs"
"github.com/ethereum-optimism/optimism/op-challenger/metrics" "github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-service/sources/batching"
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
...@@ -38,10 +35,7 @@ func (g *OutputAlphabetGameHelper) StartChallenger( ...@@ -38,10 +35,7 @@ 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) prestateBlock, poststateBlock, err := g.Game.GetBlockRange(ctx)
contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
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)
l1Head := g.GetL1Head(ctx) l1Head := g.GetL1Head(ctx)
...@@ -50,7 +44,7 @@ func (g *OutputAlphabetGameHelper) CreateHonestActor(ctx context.Context, l2Node ...@@ -50,7 +44,7 @@ func (g *OutputAlphabetGameHelper) CreateHonestActor(ctx context.Context, l2Node
prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock)
correctTrace, err := outputs.NewOutputAlphabetTraceAccessor(logger, metrics.NoopMetrics, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock) correctTrace, err := outputs.NewOutputAlphabetTraceAccessor(logger, metrics.NoopMetrics, prestateProvider, rollupClient, l2Client, l1Head, splitDepth, prestateBlock, poststateBlock)
g.Require.NoError(err, "Create trace accessor") g.Require.NoError(err, "Create trace accessor")
return NewOutputHonestHelper(g.T, g.Require, &g.OutputGameHelper, contract, correctTrace) return NewOutputHonestHelper(g.T, g.Require, &g.OutputGameHelper, g.Game, correctTrace)
} }
func (g *OutputAlphabetGameHelper) CreateDishonestHelper(ctx context.Context, l2Node string, defender bool) *DishonestHelper { func (g *OutputAlphabetGameHelper) CreateDishonestHelper(ctx context.Context, l2Node string, defender bool) *DishonestHelper {
......
...@@ -9,8 +9,6 @@ import ( ...@@ -9,8 +9,6 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"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/game/fault/trace" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/cannon"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs"
...@@ -55,11 +53,8 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s ...@@ -55,11 +53,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)
contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) prestateBlock, poststateBlock, err := g.Game.GetBlockRange(ctx)
g.Require.NoError(err, "Failed to load block range") g.Require.NoError(err, "Failed to load block range")
dir := filepath.Join(cfg.Datadir, "honest") dir := filepath.Join(cfg.Datadir, "honest")
splitDepth := g.SplitDepth(ctx) splitDepth := g.SplitDepth(ctx)
...@@ -69,7 +64,7 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s ...@@ -69,7 +64,7 @@ func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node s
accessor, err := outputs.NewOutputCannonTraceAccessor( accessor, err := outputs.NewOutputCannonTraceAccessor(
logger, metrics.NoopMetrics, cfg, l2Client, prestateProvider, rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) logger, metrics.NoopMetrics, cfg, l2Client, prestateProvider, rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock)
g.Require.NoError(err, "Failed to create output cannon trace accessor") g.Require.NoError(err, "Failed to create output cannon trace accessor")
return NewOutputHonestHelper(g.T, g.Require, &g.OutputGameHelper, contract, accessor) return NewOutputHonestHelper(g.T, g.Require, &g.OutputGameHelper, g.Game, accessor)
} }
type PreimageLoadCheck func(types.TraceProvider, uint64) error type PreimageLoadCheck func(types.TraceProvider, uint64) error
...@@ -238,7 +233,7 @@ func (g *OutputCannonGameHelper) VerifyPreimage(ctx context.Context, outputRootC ...@@ -238,7 +233,7 @@ func (g *OutputCannonGameHelper) VerifyPreimage(ctx context.Context, outputRootC
g.Require.NotNil(oracleData, "Should have had required preimage oracle data") g.Require.NotNil(oracleData, "Should have had required preimage oracle data")
g.Require.Equal(common.Hash(preimageKey.PreimageKey()).Bytes(), oracleData.OracleKey, "Must have correct preimage key") g.Require.Equal(common.Hash(preimageKey.PreimageKey()).Bytes(), oracleData.OracleKey, "Must have correct preimage key")
tx, err := g.Game.AddLocalData(g.Opts, tx, err := g.GameBindings.AddLocalData(g.Opts,
oracleData.GetIdent(), oracleData.GetIdent(),
big.NewInt(outputRootClaim.Index), big.NewInt(outputRootClaim.Index),
new(big.Int).SetUint64(uint64(oracleData.OracleOffset))) new(big.Int).SetUint64(uint64(oracleData.OracleOffset)))
...@@ -250,7 +245,7 @@ func (g *OutputCannonGameHelper) VerifyPreimage(ctx context.Context, outputRootC ...@@ -250,7 +245,7 @@ func (g *OutputCannonGameHelper) VerifyPreimage(ctx context.Context, outputRootC
g.Require.NoError(err, "Failed to get expected post state") g.Require.NoError(err, "Failed to get expected post state")
callOpts := &bind.CallOpts{Context: ctx} callOpts := &bind.CallOpts{Context: ctx}
vmAddr, err := g.Game.Vm(callOpts) vmAddr, err := g.GameBindings.Vm(callOpts)
g.Require.NoError(err, "Failed to get VM address") g.Require.NoError(err, "Failed to get VM address")
abi, err := bindings.MIPSMetaData.GetAbi() abi, err := bindings.MIPSMetaData.GetAbi()
...@@ -280,12 +275,9 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context, ...@@ -280,12 +275,9 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context,
opt = append(opt, options...) opt = append(opt, options...)
cfg := challenger.NewChallengerConfig(g.T, g.System, l2Node, opt...) cfg := challenger.NewChallengerConfig(g.T, g.System, l2Node, opt...)
caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize)
l2Client := g.System.NodeClient(l2Node) l2Client := g.System.NodeClient(l2Node)
contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) prestateBlock, poststateBlock, err := g.Game.GetBlockRange(ctx)
g.Require.NoError(err, "Failed to load block range") g.Require.NoError(err, "Failed to load block range")
rollupClient := g.System.RollupClient(l2Node) rollupClient := g.System.RollupClient(l2Node)
prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock)
...@@ -305,7 +297,7 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context, ...@@ -305,7 +297,7 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context,
return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics, cfg, localInputs, subdir, g.MaxDepth(ctx)-splitDepth-1), nil return cannon.NewTraceProviderForTest(logger, metrics.NoopMetrics, cfg, localInputs, subdir, g.MaxDepth(ctx)-splitDepth-1), nil
}) })
claims, err := contract.GetAllClaims(ctx, rpcblock.Latest) claims, err := g.Game.GetAllClaims(ctx, rpcblock.Latest)
g.Require.NoError(err) g.Require.NoError(err)
game := types.NewGameState(claims, g.MaxDepth(ctx)) game := types.NewGameState(claims, g.MaxDepth(ctx))
......
...@@ -9,16 +9,15 @@ import ( ...@@ -9,16 +9,15 @@ import (
"time" "time"
"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/game/fault/preimages" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/preimages"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/outputs"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types" keccakTypes "github.com/ethereum-optimism/optimism/op-challenger/game/keccak/types"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-e2e/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
preimage "github.com/ethereum-optimism/optimism/op-preimage" preimage "github.com/ethereum-optimism/optimism/op-preimage"
"github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum-optimism/optimism/op-service/eth"
"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/rpcblock"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -34,7 +33,8 @@ type OutputGameHelper struct { ...@@ -34,7 +33,8 @@ type OutputGameHelper struct {
Require *require.Assertions Require *require.Assertions
Client *ethclient.Client Client *ethclient.Client
Opts *bind.TransactOpts Opts *bind.TransactOpts
Game *bindings.FaultDisputeGame Game contracts.FaultDisputeGameContract
GameBindings *bindings.FaultDisputeGame
FactoryAddr common.Address FactoryAddr common.Address
Addr common.Address Addr common.Address
CorrectOutputProvider *outputs.OutputTraceProvider CorrectOutputProvider *outputs.OutputTraceProvider
...@@ -42,13 +42,14 @@ type OutputGameHelper struct { ...@@ -42,13 +42,14 @@ type OutputGameHelper struct {
} }
func NewOutputGameHelper(t *testing.T, require *require.Assertions, client *ethclient.Client, opts *bind.TransactOpts, func NewOutputGameHelper(t *testing.T, require *require.Assertions, client *ethclient.Client, opts *bind.TransactOpts,
game *bindings.FaultDisputeGame, factoryAddr common.Address, addr common.Address, correctOutputProvider *outputs.OutputTraceProvider, system DisputeSystem) *OutputGameHelper { game contracts.FaultDisputeGameContract, gameBindings *bindings.FaultDisputeGame, factoryAddr common.Address, addr common.Address, correctOutputProvider *outputs.OutputTraceProvider, system DisputeSystem) *OutputGameHelper {
return &OutputGameHelper{ return &OutputGameHelper{
T: t, T: t,
Require: require, Require: require,
Client: client, Client: client,
Opts: opts, Opts: opts,
Game: game, Game: game,
GameBindings: gameBindings,
FactoryAddr: factoryAddr, FactoryAddr: factoryAddr,
Addr: addr, Addr: addr,
CorrectOutputProvider: correctOutputProvider, CorrectOutputProvider: correctOutputProvider,
...@@ -84,9 +85,9 @@ func WithIgnoreDuplicates() MoveOpt { ...@@ -84,9 +85,9 @@ func WithIgnoreDuplicates() MoveOpt {
} }
func (g *OutputGameHelper) SplitDepth(ctx context.Context) types.Depth { func (g *OutputGameHelper) SplitDepth(ctx context.Context) types.Depth {
splitDepth, err := g.Game.SplitDepth(&bind.CallOpts{Context: ctx}) splitDepth, err := g.Game.GetSplitDepth(ctx)
g.Require.NoError(err, "failed to load split depth") g.Require.NoError(err, "failed to load split depth")
return types.Depth(splitDepth.Uint64()) return splitDepth
} }
func (g *OutputGameHelper) ExecDepth(ctx context.Context) types.Depth { func (g *OutputGameHelper) ExecDepth(ctx context.Context) types.Depth {
...@@ -94,15 +95,15 @@ func (g *OutputGameHelper) ExecDepth(ctx context.Context) types.Depth { ...@@ -94,15 +95,15 @@ func (g *OutputGameHelper) ExecDepth(ctx context.Context) types.Depth {
} }
func (g *OutputGameHelper) L2BlockNum(ctx context.Context) uint64 { func (g *OutputGameHelper) L2BlockNum(ctx context.Context) uint64 {
blockNum, err := g.Game.L2BlockNumber(&bind.CallOpts{Context: ctx}) _, blockNum, err := g.Game.GetBlockRange(ctx)
g.Require.NoError(err, "failed to load l2 block number") g.Require.NoError(err, "failed to load l2 block number")
return blockNum.Uint64() return blockNum
} }
func (g *OutputGameHelper) StartingBlockNum(ctx context.Context) uint64 { func (g *OutputGameHelper) StartingBlockNum(ctx context.Context) uint64 {
blockNum, err := g.Game.StartingBlockNumber(&bind.CallOpts{Context: ctx}) blockNum, _, err := g.Game.GetBlockRange(ctx)
g.Require.NoError(err, "failed to load starting block number") g.Require.NoError(err, "failed to load starting block number")
return blockNum.Uint64() return blockNum
} }
func (g *OutputGameHelper) DisputeLastBlock(ctx context.Context) *ClaimHelper { func (g *OutputGameHelper) DisputeLastBlock(ctx context.Context) *ClaimHelper {
...@@ -162,8 +163,8 @@ func (g *OutputGameHelper) RootClaim(ctx context.Context) *ClaimHelper { ...@@ -162,8 +163,8 @@ func (g *OutputGameHelper) RootClaim(ctx context.Context) *ClaimHelper {
func (g *OutputGameHelper) WaitForCorrectOutputRoot(ctx context.Context, claimIdx int64) { func (g *OutputGameHelper) WaitForCorrectOutputRoot(ctx context.Context, claimIdx int64) {
g.WaitForClaimCount(ctx, claimIdx+1) g.WaitForClaimCount(ctx, claimIdx+1)
claim := g.getClaim(ctx, claimIdx) claim := g.getClaim(ctx, claimIdx)
output := g.correctOutputRoot(ctx, types.NewPositionFromGIndex(claim.Position)) output := g.correctOutputRoot(ctx, claim.Position)
g.Require.EqualValuesf(output, claim.Claim, "Incorrect output root at claim %v at position %v", claimIdx, claim.Position.Uint64()) g.Require.EqualValuesf(output, claim.Value, "Incorrect output root at claim %v at position %v", claimIdx, claim.Position.ToGIndex().Uint64())
} }
func (g *OutputGameHelper) correctOutputRoot(ctx context.Context, pos types.Position) common.Hash { func (g *OutputGameHelper) correctOutputRoot(ctx context.Context, pos types.Position) common.Hash {
...@@ -173,16 +174,16 @@ func (g *OutputGameHelper) correctOutputRoot(ctx context.Context, pos types.Posi ...@@ -173,16 +174,16 @@ func (g *OutputGameHelper) correctOutputRoot(ctx context.Context, pos types.Posi
} }
func (g *OutputGameHelper) MaxClockDuration(ctx context.Context) time.Duration { func (g *OutputGameHelper) MaxClockDuration(ctx context.Context) time.Duration {
duration, err := g.Game.MaxClockDuration(&bind.CallOpts{Context: ctx}) duration, err := g.Game.GetMaxClockDuration(ctx)
g.Require.NoError(err, "failed to get max clock duration") g.Require.NoError(err, "failed to get max clock duration")
return time.Duration(duration) * time.Second return duration
} }
func (g *OutputGameHelper) WaitForNoAvailableCredit(ctx context.Context, addr common.Address) { func (g *OutputGameHelper) WaitForNoAvailableCredit(ctx context.Context, addr common.Address) {
timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout)
defer cancel() defer cancel()
err := wait.For(timedCtx, time.Second, func() (bool, error) { err := wait.For(timedCtx, time.Second, func() (bool, error) {
bal, err := g.Game.Credit(&bind.CallOpts{Context: timedCtx}, addr) bal, _, err := g.Game.GetCredit(timedCtx, addr)
if err != nil { if err != nil {
return false, err return false, err
} }
...@@ -196,13 +197,13 @@ func (g *OutputGameHelper) WaitForNoAvailableCredit(ctx context.Context, addr co ...@@ -196,13 +197,13 @@ func (g *OutputGameHelper) WaitForNoAvailableCredit(ctx context.Context, addr co
} }
func (g *OutputGameHelper) AvailableCredit(ctx context.Context, addr common.Address) *big.Int { func (g *OutputGameHelper) AvailableCredit(ctx context.Context, addr common.Address) *big.Int {
credit, err := g.Game.Credit(&bind.CallOpts{Context: ctx}, addr) credit, _, err := g.Game.GetCredit(ctx, addr)
g.Require.NoErrorf(err, "Failed to fetch available credit for %v", addr) g.Require.NoErrorf(err, "Failed to fetch available credit for %v", addr)
return credit return credit
} }
func (g *OutputGameHelper) CreditUnlockDuration(ctx context.Context) time.Duration { func (g *OutputGameHelper) CreditUnlockDuration(ctx context.Context) time.Duration {
weth, err := g.Game.Weth(&bind.CallOpts{Context: ctx}) weth, err := g.GameBindings.Weth(&bind.CallOpts{Context: ctx})
g.Require.NoError(err, "Failed to get WETH contract") g.Require.NoError(err, "Failed to get WETH contract")
contract, err := bindings.NewDelayedWETH(weth, g.Client) contract, err := bindings.NewDelayedWETH(weth, g.Client)
g.Require.NoError(err) g.Require.NoError(err)
...@@ -213,7 +214,7 @@ func (g *OutputGameHelper) CreditUnlockDuration(ctx context.Context) time.Durati ...@@ -213,7 +214,7 @@ func (g *OutputGameHelper) CreditUnlockDuration(ctx context.Context) time.Durati
} }
func (g *OutputGameHelper) WethBalance(ctx context.Context, addr common.Address) *big.Int { func (g *OutputGameHelper) WethBalance(ctx context.Context, addr common.Address) *big.Int {
weth, err := g.Game.Weth(&bind.CallOpts{Context: ctx}) weth, err := g.GameBindings.Weth(&bind.CallOpts{Context: ctx})
g.Require.NoError(err, "Failed to get WETH contract") g.Require.NoError(err, "Failed to get WETH contract")
contract, err := bindings.NewDelayedWETH(weth, g.Client) contract, err := bindings.NewDelayedWETH(weth, g.Client)
g.Require.NoError(err) g.Require.NoError(err)
...@@ -229,12 +230,12 @@ func (g *OutputGameHelper) WaitForClaimCount(ctx context.Context, count int64) { ...@@ -229,12 +230,12 @@ func (g *OutputGameHelper) WaitForClaimCount(ctx context.Context, count int64) {
timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout)
defer cancel() defer cancel()
err := wait.For(timedCtx, time.Second, func() (bool, error) { err := wait.For(timedCtx, time.Second, func() (bool, error) {
actual, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) actual, err := g.Game.GetClaimCount(timedCtx)
if err != nil { if err != nil {
return false, err return false, err
} }
g.T.Log("Waiting for claim count", "current", actual, "expected", count, "game", g.Addr) g.T.Log("Waiting for claim count", "current", actual, "expected", count, "game", g.Addr)
return actual.Cmp(big.NewInt(count)) >= 0, nil return int64(actual) >= count, nil
}) })
if err != nil { if err != nil {
g.LogGameData(ctx) g.LogGameData(ctx)
...@@ -253,30 +254,27 @@ type ContractClaim struct { ...@@ -253,30 +254,27 @@ type ContractClaim struct {
} }
func (g *OutputGameHelper) MaxDepth(ctx context.Context) types.Depth { func (g *OutputGameHelper) MaxDepth(ctx context.Context) types.Depth {
depth, err := g.Game.MaxGameDepth(&bind.CallOpts{Context: ctx}) depth, err := g.Game.GetMaxGameDepth(ctx)
g.Require.NoError(err, "Failed to load game depth") g.Require.NoError(err, "Failed to load game depth")
return types.Depth(depth.Uint64()) return depth
} }
func (g *OutputGameHelper) waitForClaim(ctx context.Context, timeout time.Duration, errorMsg string, predicate func(claimIdx int64, claim ContractClaim) bool) (int64, ContractClaim) { func (g *OutputGameHelper) waitForClaim(ctx context.Context, timeout time.Duration, errorMsg string, predicate func(claimIdx int64, claim types.Claim) bool) (int64, types.Claim) {
timedCtx, cancel := context.WithTimeout(ctx, timeout) timedCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel() defer cancel()
var matchedClaim ContractClaim var matchedClaim types.Claim
var matchClaimIdx int64 var matchClaimIdx int64
err := wait.For(timedCtx, time.Second, func() (bool, error) { err := wait.For(timedCtx, time.Second, func() (bool, error) {
count, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) claims, err := g.Game.GetAllClaims(ctx, rpcblock.Latest)
if err != nil { if err != nil {
return false, fmt.Errorf("retrieve number of claims: %w", err) return false, fmt.Errorf("retrieve all claims: %w", err)
} }
// Search backwards because the new claims are at the end and more likely the ones we want. // Search backwards because the new claims are at the end and more likely the ones we want.
for i := count.Int64() - 1; i >= 0; i-- { for i := len(claims) - 1; i >= 0; i-- {
claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: timedCtx}, big.NewInt(i)) claim := claims[i]
if err != nil { if predicate(int64(i), claim) {
return false, fmt.Errorf("retrieve claim %v: %w", i, err) matchClaimIdx = int64(i)
} matchedClaim = claim
if predicate(i, claimData) {
matchClaimIdx = i
matchedClaim = claimData
return true, nil return true, nil
} }
} }
...@@ -288,21 +286,18 @@ func (g *OutputGameHelper) waitForClaim(ctx context.Context, timeout time.Durati ...@@ -288,21 +286,18 @@ func (g *OutputGameHelper) waitForClaim(ctx context.Context, timeout time.Durati
return matchClaimIdx, matchedClaim return matchClaimIdx, matchedClaim
} }
func (g *OutputGameHelper) waitForNoClaim(ctx context.Context, errorMsg string, predicate func(claim ContractClaim) bool) { func (g *OutputGameHelper) waitForNoClaim(ctx context.Context, errorMsg string, predicate func(claim types.Claim) bool) {
timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout)
defer cancel() defer cancel()
err := wait.For(timedCtx, time.Second, func() (bool, error) { err := wait.For(timedCtx, time.Second, func() (bool, error) {
count, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) claims, err := g.Game.GetAllClaims(ctx, rpcblock.Latest)
if err != nil { if err != nil {
return false, fmt.Errorf("retrieve number of claims: %w", err) return false, fmt.Errorf("retrieve all claims: %w", err)
} }
// Search backwards because the new claims are at the end and more likely the ones we will fail on. // Search backwards because the new claims are at the end and more likely the ones we want.
for i := count.Int64() - 1; i >= 0; i-- { for i := len(claims) - 1; i >= 0; i-- {
claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: timedCtx}, big.NewInt(i)) claim := claims[i]
if err != nil { if predicate(claim) {
return false, fmt.Errorf("retrieve claim %v: %w", i, err)
}
if predicate(claimData) {
return false, nil return false, nil
} }
} }
...@@ -316,22 +311,19 @@ func (g *OutputGameHelper) waitForNoClaim(ctx context.Context, errorMsg string, ...@@ -316,22 +311,19 @@ func (g *OutputGameHelper) waitForNoClaim(ctx context.Context, errorMsg string,
func (g *OutputGameHelper) GetClaimValue(ctx context.Context, claimIdx int64) common.Hash { func (g *OutputGameHelper) GetClaimValue(ctx context.Context, claimIdx int64) common.Hash {
g.WaitForClaimCount(ctx, claimIdx+1) g.WaitForClaimCount(ctx, claimIdx+1)
claim := g.getClaim(ctx, claimIdx) claim := g.getClaim(ctx, claimIdx)
return claim.Claim return claim.Value
} }
func (g *OutputGameHelper) getAllClaims(ctx context.Context) []ContractClaim { func (g *OutputGameHelper) getAllClaims(ctx context.Context) []types.Claim {
count := g.getClaimCount(ctx) claims, err := g.Game.GetAllClaims(ctx, rpcblock.Latest)
var claims []ContractClaim g.Require.NoError(err, "Failed to get all claims")
for i := int64(0); i < count; i++ {
claims = append(claims, g.getClaim(ctx, i))
}
return claims return claims
} }
// getClaim retrieves the claim data for a specific index. // getClaim retrieves the claim data for a specific index.
// Note that it is deliberately not exported as tests should use WaitForClaim to avoid race conditions. // Note that it is deliberately not exported as tests should use WaitForClaim to avoid race conditions.
func (g *OutputGameHelper) getClaim(ctx context.Context, claimIdx int64) ContractClaim { func (g *OutputGameHelper) getClaim(ctx context.Context, claimIdx int64) types.Claim {
claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) claimData, err := g.Game.GetClaim(ctx, uint64(claimIdx))
if err != nil { if err != nil {
g.Require.NoErrorf(err, "retrieve claim %v", claimIdx) g.Require.NoErrorf(err, "retrieve claim %v", claimIdx)
} }
...@@ -343,9 +335,8 @@ func (g *OutputGameHelper) WaitForClaimAtDepth(ctx context.Context, depth types. ...@@ -343,9 +335,8 @@ func (g *OutputGameHelper) WaitForClaimAtDepth(ctx context.Context, depth types.
ctx, ctx,
defaultTimeout, defaultTimeout,
fmt.Sprintf("Could not find claim depth %v", depth), fmt.Sprintf("Could not find claim depth %v", depth),
func(_ int64, claim ContractClaim) bool { func(_ int64, claim types.Claim) bool {
pos := types.NewPositionFromGIndex(claim.Position) return claim.Depth() == depth
return pos.Depth() == depth
}) })
} }
...@@ -355,9 +346,8 @@ func (g *OutputGameHelper) WaitForClaimAtMaxDepth(ctx context.Context, countered ...@@ -355,9 +346,8 @@ func (g *OutputGameHelper) WaitForClaimAtMaxDepth(ctx context.Context, countered
ctx, ctx,
defaultTimeout, defaultTimeout,
fmt.Sprintf("Could not find claim depth %v with countered=%v", maxDepth, countered), fmt.Sprintf("Could not find claim depth %v with countered=%v", maxDepth, countered),
func(_ int64, claim ContractClaim) bool { func(_ int64, claim types.Claim) bool {
pos := types.NewPositionFromGIndex(claim.Position) return claim.Depth() == maxDepth && (claim.CounteredBy != common.Address{}) == countered
return pos.Depth() == maxDepth && (claim.CounteredBy != common.Address{}) == countered
}) })
} }
...@@ -365,7 +355,7 @@ func (g *OutputGameHelper) WaitForAllClaimsCountered(ctx context.Context) { ...@@ -365,7 +355,7 @@ func (g *OutputGameHelper) WaitForAllClaimsCountered(ctx context.Context) {
g.waitForNoClaim( g.waitForNoClaim(
ctx, ctx,
"Did not find all claims countered", "Did not find all claims countered",
func(claim ContractClaim) bool { func(claim types.Claim) bool {
return claim.CounteredBy == common.Address{} return claim.CounteredBy == common.Address{}
}) })
} }
...@@ -373,31 +363,31 @@ func (g *OutputGameHelper) WaitForAllClaimsCountered(ctx context.Context) { ...@@ -373,31 +363,31 @@ func (g *OutputGameHelper) WaitForAllClaimsCountered(ctx context.Context) {
func (g *OutputGameHelper) Resolve(ctx context.Context) { func (g *OutputGameHelper) Resolve(ctx context.Context) {
ctx, cancel := context.WithTimeout(ctx, time.Minute) ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel() defer cancel()
tx, err := g.Game.Resolve(g.Opts) tx, err := g.GameBindings.Resolve(g.Opts)
g.Require.NoError(err) g.Require.NoError(err)
_, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash()) _, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash())
g.Require.NoError(err) g.Require.NoError(err)
} }
func (g *OutputGameHelper) Status(ctx context.Context) Status { func (g *OutputGameHelper) Status(ctx context.Context) gameTypes.GameStatus {
status, err := g.Game.Status(&bind.CallOpts{Context: ctx}) status, err := g.Game.GetStatus(ctx)
g.Require.NoError(err) g.Require.NoError(err)
return Status(status) return status
} }
func (g *OutputGameHelper) WaitForGameStatus(ctx context.Context, expected Status) { func (g *OutputGameHelper) WaitForGameStatus(ctx context.Context, expected gameTypes.GameStatus) {
g.T.Logf("Waiting for game %v to have status %v", g.Addr, expected) g.T.Logf("Waiting for game %v to have status %v", g.Addr, expected)
timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout)
defer cancel() defer cancel()
err := wait.For(timedCtx, time.Second, func() (bool, error) { err := wait.For(timedCtx, time.Second, func() (bool, error) {
ctx, cancel := context.WithTimeout(timedCtx, 30*time.Second) ctx, cancel := context.WithTimeout(timedCtx, 30*time.Second)
defer cancel() defer cancel()
status, err := g.Game.Status(&bind.CallOpts{Context: ctx}) status, err := g.Game.GetStatus(ctx)
if err != nil { if err != nil {
return false, fmt.Errorf("game status unavailable: %w", err) return false, fmt.Errorf("game status unavailable: %w", err)
} }
g.T.Logf("Game %v has state %v, waiting for state %v", g.Addr, Status(status), expected) g.T.Logf("Game %v has state %v, waiting for state %v", g.Addr, status, expected)
return expected == Status(status), nil return expected == status, nil
}) })
g.Require.NoErrorf(err, "wait for Game status. Game state: \n%v", g.GameData(ctx)) g.Require.NoErrorf(err, "wait for Game status. Game state: \n%v", g.GameData(ctx))
} }
...@@ -411,7 +401,7 @@ func (g *OutputGameHelper) WaitForInactivity(ctx context.Context, numInactiveBlo ...@@ -411,7 +401,7 @@ func (g *OutputGameHelper) WaitForInactivity(ctx context.Context, numInactiveBlo
var lastActiveBlock uint64 var lastActiveBlock uint64
for { for {
if untilGameEnds && g.Status(ctx) != StatusInProgress { if untilGameEnds && g.Status(ctx) != gameTypes.GameStatusInProgress {
break break
} }
select { select {
...@@ -444,13 +434,10 @@ func (g *OutputGameHelper) WaitForInactivity(ctx context.Context, numInactiveBlo ...@@ -444,13 +434,10 @@ func (g *OutputGameHelper) WaitForInactivity(ctx context.Context, numInactiveBlo
func (g *OutputGameHelper) WaitForL2BlockNumberChallenged(ctx context.Context) { func (g *OutputGameHelper) WaitForL2BlockNumberChallenged(ctx context.Context) {
g.T.Logf("Waiting for game %v to have L2 block number challenged", g.Addr) g.T.Logf("Waiting for game %v to have L2 block number challenged", g.Addr)
caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize)
contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
timedCtx, cancel := context.WithTimeout(ctx, 30*time.Second) timedCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel() defer cancel()
err = wait.For(timedCtx, time.Second, func() (bool, error) { err := wait.For(timedCtx, time.Second, func() (bool, error) {
return contract.IsL2BlockNumberChallenged(ctx, rpcblock.Latest) return g.Game.IsL2BlockNumberChallenged(ctx, rpcblock.Latest)
}) })
g.Require.NoError(err, "L2 block number was not challenged in time") g.Require.NoError(err, "L2 block number was not challenged in time")
} }
...@@ -522,12 +509,6 @@ func (g *OutputGameHelper) ChallengeClaim(ctx context.Context, claim *ClaimHelpe ...@@ -522,12 +509,6 @@ func (g *OutputGameHelper) ChallengeClaim(ctx context.Context, claim *ClaimHelpe
attemptStep(claim.Index) attemptStep(claim.Index)
} }
func (g *OutputGameHelper) getClaimCount(ctx context.Context) int64 {
claimCount, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: ctx})
g.Require.NoError(err, "Failed to get current claim count")
return claimCount.Int64()
}
func (g *OutputGameHelper) WaitForNewClaim(ctx context.Context, checkPoint int64) (int64, error) { func (g *OutputGameHelper) WaitForNewClaim(ctx context.Context, checkPoint int64) (int64, error) {
return g.waitForNewClaim(ctx, checkPoint, defaultTimeout) return g.waitForNewClaim(ctx, checkPoint, defaultTimeout)
} }
...@@ -537,12 +518,12 @@ func (g *OutputGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64 ...@@ -537,12 +518,12 @@ func (g *OutputGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64
defer cancel() defer cancel()
var newClaimLen int64 var newClaimLen int64
err := wait.For(timedCtx, time.Second, func() (bool, error) { err := wait.For(timedCtx, time.Second, func() (bool, error) {
actual, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: ctx}) actual, err := g.Game.GetClaimCount(ctx)
if err != nil { if err != nil {
return false, err return false, err
} }
newClaimLen = actual.Int64() newClaimLen = int64(actual)
return actual.Cmp(big.NewInt(checkPoint)) > 0, nil return int64(actual) > checkPoint, nil
}) })
return newClaimLen, err return newClaimLen, err
} }
...@@ -561,14 +542,13 @@ func (g *OutputGameHelper) Attack(ctx context.Context, claimIdx int64, claim com ...@@ -561,14 +542,13 @@ func (g *OutputGameHelper) Attack(ctx context.Context, claimIdx int64, claim com
g.T.Logf("Attacking claim %v with value %v", claimIdx, claim) g.T.Logf("Attacking claim %v with value %v", claimIdx, claim)
cfg := g.moveCfg(Opts...) cfg := g.moveCfg(Opts...)
claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) claimData, err := g.Game.GetClaim(ctx, uint64(claimIdx))
g.Require.NoError(err, "Failed to get claim data") g.Require.NoError(err, "Failed to get claim data")
pos := types.NewPositionFromGIndex(claimData.Position) attackPos := claimData.Position.Attack()
attackPos := pos.Attack() transactOpts := g.makeBondedTransactOpts(ctx, claimData.Position.Attack().ToGIndex(), cfg.Opts)
transactOpts := g.makeBondedTransactOpts(ctx, pos.Attack().ToGIndex(), cfg.Opts)
err = g.sendMove(ctx, func() (*gethtypes.Transaction, error) { err = g.sendMove(ctx, func() (*gethtypes.Transaction, error) {
return g.Game.Attack(transactOpts, claimData.Claim, big.NewInt(claimIdx), claim) return g.GameBindings.Attack(transactOpts, claimData.Value, big.NewInt(claimIdx), claim)
}) })
if err != nil { if err != nil {
if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, attackPos, claim) { if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, attackPos, claim) {
...@@ -582,14 +562,13 @@ func (g *OutputGameHelper) Defend(ctx context.Context, claimIdx int64, claim com ...@@ -582,14 +562,13 @@ func (g *OutputGameHelper) Defend(ctx context.Context, claimIdx int64, claim com
g.T.Logf("Defending claim %v with value %v", claimIdx, claim) g.T.Logf("Defending claim %v with value %v", claimIdx, claim)
cfg := g.moveCfg(Opts...) cfg := g.moveCfg(Opts...)
claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) claimData, err := g.Game.GetClaim(ctx, uint64(claimIdx))
g.Require.NoError(err, "Failed to get claim data") g.Require.NoError(err, "Failed to get claim data")
pos := types.NewPositionFromGIndex(claimData.Position) defendPos := claimData.Position.Defend()
defendPos := pos.Defend()
transactOpts := g.makeBondedTransactOpts(ctx, defendPos.ToGIndex(), cfg.Opts) transactOpts := g.makeBondedTransactOpts(ctx, defendPos.ToGIndex(), cfg.Opts)
err = g.sendMove(ctx, func() (*gethtypes.Transaction, error) { err = g.sendMove(ctx, func() (*gethtypes.Transaction, error) {
return g.Game.Defend(transactOpts, claimData.Claim, big.NewInt(claimIdx), claim) return g.GameBindings.Defend(transactOpts, claimData.Value, big.NewInt(claimIdx), claim)
}) })
if err != nil { if err != nil {
if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, defendPos, claim) { if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, defendPos, claim) {
...@@ -602,7 +581,7 @@ func (g *OutputGameHelper) Defend(ctx context.Context, claimIdx int64, claim com ...@@ -602,7 +581,7 @@ func (g *OutputGameHelper) Defend(ctx context.Context, claimIdx int64, claim com
func (g *OutputGameHelper) hasClaim(ctx context.Context, parentIdx int64, pos types.Position, value common.Hash) bool { func (g *OutputGameHelper) hasClaim(ctx context.Context, parentIdx int64, pos types.Position, value common.Hash) bool {
claims := g.getAllClaims(ctx) claims := g.getAllClaims(ctx)
for _, claim := range claims { for _, claim := range claims {
if int64(claim.ParentIndex) == parentIdx && claim.Position.Cmp(pos.ToGIndex()) == 0 && claim.Claim == value { if int64(claim.ParentContractIndex) == parentIdx && claim.Position.ToGIndex().Cmp(pos.ToGIndex()) == 0 && claim.Value == value {
return true return true
} }
} }
...@@ -623,7 +602,7 @@ func (g *OutputGameHelper) sendMove(ctx context.Context, send func() (*gethtypes ...@@ -623,7 +602,7 @@ func (g *OutputGameHelper) sendMove(ctx context.Context, send func() (*gethtypes
func (g *OutputGameHelper) makeBondedTransactOpts(ctx context.Context, pos *big.Int, Opts *bind.TransactOpts) *bind.TransactOpts { func (g *OutputGameHelper) makeBondedTransactOpts(ctx context.Context, pos *big.Int, Opts *bind.TransactOpts) *bind.TransactOpts {
bOpts := *Opts bOpts := *Opts
bond, err := g.Game.GetRequiredBond(&bind.CallOpts{Context: ctx}, pos) bond, err := g.GameBindings.GetRequiredBond(&bind.CallOpts{Context: ctx}, pos)
g.Require.NoError(err, "Failed to get required bond") g.Require.NoError(err, "Failed to get required bond")
bOpts.Value = bond bOpts.Value = bond
return &bOpts return &bOpts
...@@ -636,7 +615,7 @@ type ErrWithData interface { ...@@ -636,7 +615,7 @@ type ErrWithData interface {
// StepFails attempts to call step and verifies that it fails with ValidStep() // StepFails attempts to call step and verifies that it fails with ValidStep()
func (g *OutputGameHelper) StepFails(claimIdx int64, isAttack bool, stateData []byte, proof []byte) { func (g *OutputGameHelper) StepFails(claimIdx int64, isAttack bool, stateData []byte, proof []byte) {
g.T.Logf("Attempting step against claim %v isAttack: %v", claimIdx, isAttack) g.T.Logf("Attempting step against claim %v isAttack: %v", claimIdx, isAttack)
_, err := g.Game.Step(g.Opts, big.NewInt(claimIdx), isAttack, stateData, proof) _, err := g.GameBindings.Step(g.Opts, big.NewInt(claimIdx), isAttack, stateData, proof)
errData, ok := err.(ErrWithData) errData, ok := err.(ErrWithData)
g.Require.Truef(ok, "Error should provide ErrorData method: %v", err) g.Require.Truef(ok, "Error should provide ErrorData method: %v", err)
g.Require.Equal("0xfb4e40dd", errData.ErrorData(), "Revert reason should be abi encoded ValidStep()") g.Require.Equal("0xfb4e40dd", errData.ErrorData(), "Revert reason should be abi encoded ValidStep()")
...@@ -644,7 +623,7 @@ func (g *OutputGameHelper) StepFails(claimIdx int64, isAttack bool, stateData [] ...@@ -644,7 +623,7 @@ func (g *OutputGameHelper) StepFails(claimIdx int64, isAttack bool, stateData []
// ResolveClaim resolves a single subgame // ResolveClaim resolves a single subgame
func (g *OutputGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) { func (g *OutputGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) {
tx, err := g.Game.ResolveClaim(g.Opts, big.NewInt(claimIdx), common.Big0) tx, err := g.GameBindings.ResolveClaim(g.Opts, big.NewInt(claimIdx), common.Big0)
g.Require.NoError(err, "ResolveClaim transaction did not send") g.Require.NoError(err, "ResolveClaim transaction did not send")
_, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash()) _, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash())
g.Require.NoError(err, "ResolveClaim transaction was not OK") g.Require.NoError(err, "ResolveClaim transaction was not OK")
...@@ -725,26 +704,19 @@ func (g *OutputGameHelper) UploadPreimage(ctx context.Context, data *types.Preim ...@@ -725,26 +704,19 @@ 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) oracle, err := g.Game.GetOracle(ctx)
contract, err := contracts.NewFaultDisputeGameContract(ctx, contractMetrics.NoopContractMetrics, g.Addr, caller)
g.Require.NoError(err)
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
} }
func (g *OutputGameHelper) GameData(ctx context.Context) string { func (g *OutputGameHelper) GameData(ctx context.Context) string {
Opts := &bind.CallOpts{Context: ctx}
maxDepth := g.MaxDepth(ctx) maxDepth := g.MaxDepth(ctx)
splitDepth := g.SplitDepth(ctx) splitDepth := g.SplitDepth(ctx)
claimCount, err := g.Game.ClaimDataLen(Opts) claims, err := g.Game.GetAllClaims(ctx, rpcblock.Latest)
info := fmt.Sprintf("Claim count: %v\n", claimCount) g.Require.NoError(err, "Fetching claims")
g.Require.NoError(err, "Fetching claim count") info := fmt.Sprintf("Claim count: %v\n", len(claims))
for i := int64(0); i < claimCount.Int64(); i++ { for i, claim := range claims {
claim, err := g.Game.ClaimData(Opts, big.NewInt(i)) pos := claim.Position
g.Require.NoErrorf(err, "Fetch claim %v", i)
pos := types.NewPositionFromGIndex(claim.Position)
extra := "" extra := ""
if pos.Depth() <= splitDepth { if pos.Depth() <= splitDepth {
blockNum, err := g.CorrectOutputProvider.ClaimedBlockNumber(pos) blockNum, err := g.CorrectOutputProvider.ClaimedBlockNumber(pos)
...@@ -754,13 +726,13 @@ func (g *OutputGameHelper) GameData(ctx context.Context) string { ...@@ -754,13 +726,13 @@ func (g *OutputGameHelper) GameData(ctx context.Context) string {
} }
} }
info = info + fmt.Sprintf("%v - Position: %v, Depth: %v, IndexAtDepth: %v Trace Index: %v, ClaimHash: %v, Countered By: %v, ParentIndex: %v Claimant: %v Bond: %v %v\n", info = info + fmt.Sprintf("%v - Position: %v, Depth: %v, IndexAtDepth: %v Trace Index: %v, ClaimHash: %v, Countered By: %v, ParentIndex: %v Claimant: %v Bond: %v %v\n",
i, claim.Position.Int64(), pos.Depth(), pos.IndexAtDepth(), pos.TraceIndex(maxDepth), common.Hash(claim.Claim).Hex(), claim.CounteredBy, claim.ParentIndex, claim.Claimant, claim.Bond, extra) i, claim.Position.ToGIndex().Int64(), pos.Depth(), pos.IndexAtDepth(), pos.TraceIndex(maxDepth), claim.Value.Hex(), claim.CounteredBy, claim.ParentContractIndex, claim.Claimant, claim.Bond, extra)
} }
l2BlockNum := g.L2BlockNum(ctx) l2BlockNum := g.L2BlockNum(ctx)
status, err := g.Game.Status(Opts) status, err := g.Game.GetStatus(ctx)
g.Require.NoError(err, "Load game status") g.Require.NoError(err, "Load game status")
return fmt.Sprintf("Game %v - %v - L2 Block: %v - Split Depth: %v - Max Depth: %v:\n%v\n", return fmt.Sprintf("Game %v - %v - L2 Block: %v - Split Depth: %v - Max Depth: %v:\n%v\n",
g.Addr, Status(status), l2BlockNum, splitDepth, maxDepth, info) g.Addr, status, l2BlockNum, splitDepth, maxDepth, info)
} }
func (g *OutputGameHelper) LogGameData(ctx context.Context) { func (g *OutputGameHelper) LogGameData(ctx context.Context) {
...@@ -768,14 +740,13 @@ func (g *OutputGameHelper) LogGameData(ctx context.Context) { ...@@ -768,14 +740,13 @@ func (g *OutputGameHelper) LogGameData(ctx context.Context) {
} }
func (g *OutputGameHelper) Credit(ctx context.Context, addr common.Address) *big.Int { func (g *OutputGameHelper) Credit(ctx context.Context, addr common.Address) *big.Int {
Opts := &bind.CallOpts{Context: ctx} amt, _, err := g.Game.GetCredit(ctx, addr)
amt, err := g.Game.Credit(Opts, addr)
g.Require.NoError(err) g.Require.NoError(err)
return amt return amt
} }
func (g *OutputGameHelper) GetL1Head(ctx context.Context) eth.BlockID { func (g *OutputGameHelper) GetL1Head(ctx context.Context) eth.BlockID {
l1HeadHash, err := g.Game.L1Head(&bind.CallOpts{Context: ctx}) l1HeadHash, err := g.Game.GetL1Head(ctx)
g.Require.NoError(err, "Failed to load L1 head") g.Require.NoError(err, "Failed to load L1 head")
l1Header, err := g.Client.HeaderByHash(ctx, l1HeadHash) l1Header, err := g.Client.HeaderByHash(ctx, l1HeadHash)
g.Require.NoError(err, "Failed to load L1 header") g.Require.NoError(err, "Failed to load L1 header")
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/ethereum-optimism/optimism/op-challenger/game/types"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e" op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
...@@ -68,7 +69,7 @@ func TestOutputAlphabetGame_ChallengerWins(t *testing.T) { ...@@ -68,7 +69,7 @@ func TestOutputAlphabetGame_ChallengerWins(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, types.GameStatusChallengerWon)
game.LogGameData(ctx) game.LogGameData(ctx)
} }
...@@ -110,7 +111,7 @@ func TestOutputAlphabetGame_ReclaimBond(t *testing.T) { ...@@ -110,7 +111,7 @@ func TestOutputAlphabetGame_ReclaimBond(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, types.GameStatusChallengerWon)
game.LogGameData(ctx) game.LogGameData(ctx)
// Expect Alice's credit to be non-zero // Expect Alice's credit to be non-zero
...@@ -161,7 +162,7 @@ func TestOutputAlphabetGame_ValidOutputRoot(t *testing.T) { ...@@ -161,7 +162,7 @@ func TestOutputAlphabetGame_ValidOutputRoot(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusDefenderWins) game.WaitForGameStatus(ctx, types.GameStatusDefenderWon)
} }
func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) {
...@@ -213,9 +214,9 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { ...@@ -213,9 +214,9 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(gameDuration) sys.TimeTravelClock.AdvanceTime(gameDuration)
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
expectedStatus := disputegame.StatusChallengerWins expectedStatus := types.GameStatusChallengerWon
if isRootCorrect { if isRootCorrect {
expectedStatus = disputegame.StatusDefenderWins expectedStatus = types.GameStatusDefenderWon
} }
game.WaitForGameStatus(ctx, expectedStatus) game.WaitForGameStatus(ctx, expectedStatus)
game.LogGameData(ctx) game.LogGameData(ctx)
...@@ -288,10 +289,11 @@ func TestOutputAlphabetGame_FreeloaderEarnsNothing(t *testing.T) { ...@@ -288,10 +289,11 @@ func TestOutputAlphabetGame_FreeloaderEarnsNothing(t *testing.T) {
game.LogGameData(ctx) game.LogGameData(ctx)
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusDefenderWins) game.WaitForGameStatus(ctx, types.GameStatusDefenderWon)
game.LogGameData(ctx)
amt := game.Credit(ctx, freeloaderOpts.From) amt := game.Credit(ctx, freeloaderOpts.From)
require.True(t, amt.BitLen() == 0, "freeloaders should not be rewarded") require.Truef(t, amt.BitLen() == 0, "freeloaders should not be rewarded. Credit: %v", amt)
} }
func TestHighestActedL1BlockMetric(t *testing.T) { func TestHighestActedL1BlockMetric(t *testing.T) {
...@@ -307,7 +309,7 @@ func TestHighestActedL1BlockMetric(t *testing.T) { ...@@ -307,7 +309,7 @@ func TestHighestActedL1BlockMetric(t *testing.T) {
sys.AdvanceTime(game1.MaxClockDuration(ctx)) sys.AdvanceTime(game1.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game1.WaitForGameStatus(ctx, disputegame.StatusDefenderWins) game1.WaitForGameStatus(ctx, types.GameStatusDefenderWon)
disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 2, common.Hash{0xaa}) disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 2, common.Hash{0xaa})
disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 3, common.Hash{0xaa}) disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 3, common.Hash{0xaa})
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/utils"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e" op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
...@@ -70,7 +71,7 @@ func TestOutputCannonGame(t *testing.T) { ...@@ -70,7 +71,7 @@ func TestOutputCannonGame(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
} }
func TestOutputCannon_ChallengeAllZeroClaim(t *testing.T) { func TestOutputCannon_ChallengeAllZeroClaim(t *testing.T) {
...@@ -98,7 +99,7 @@ func TestOutputCannon_ChallengeAllZeroClaim(t *testing.T) { ...@@ -98,7 +99,7 @@ func TestOutputCannon_ChallengeAllZeroClaim(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
game.LogGameData(ctx) game.LogGameData(ctx)
} }
...@@ -175,7 +176,7 @@ func TestOutputCannonDisputeGame(t *testing.T) { ...@@ -175,7 +176,7 @@ func TestOutputCannonDisputeGame(t *testing.T) {
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.LogGameData(ctx) game.LogGameData(ctx)
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
}) })
} }
} }
...@@ -213,7 +214,7 @@ func TestOutputCannonDefendStep(t *testing.T) { ...@@ -213,7 +214,7 @@ func TestOutputCannonDefendStep(t *testing.T) {
game.WaitForInactivity(ctx, 10, true) game.WaitForInactivity(ctx, 10, true)
game.LogGameData(ctx) game.LogGameData(ctx)
require.EqualValues(t, disputegame.StatusChallengerWins, game.Status(ctx)) require.EqualValues(t, gameTypes.GameStatusChallengerWon, game.Status(ctx))
} }
func TestOutputCannonStepWithLargePreimage(t *testing.T) { func TestOutputCannonStepWithLargePreimage(t *testing.T) {
...@@ -431,7 +432,7 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) { ...@@ -431,7 +432,7 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) {
game.WaitForInactivity(ctx, 10, true) game.WaitForInactivity(ctx, 10, true)
game.LogGameData(ctx) game.LogGameData(ctx)
require.EqualValues(t, disputegame.StatusDefenderWins, game.Status(ctx)) require.EqualValues(t, gameTypes.GameStatusDefenderWon, game.Status(ctx))
}) })
} }
} }
...@@ -497,7 +498,7 @@ func TestOutputCannonPoisonedPostState(t *testing.T) { ...@@ -497,7 +498,7 @@ func TestOutputCannonPoisonedPostState(t *testing.T) {
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.LogGameData(ctx) game.LogGameData(ctx)
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
} }
func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) { func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) {
...@@ -546,7 +547,7 @@ func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) { ...@@ -546,7 +547,7 @@ func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusDefenderWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusDefenderWon)
game.LogGameData(ctx) game.LogGameData(ctx)
} }
...@@ -597,7 +598,7 @@ func TestDisputeOutputRootBeyondProposedBlock_InvalidOutputRoot(t *testing.T) { ...@@ -597,7 +598,7 @@ func TestDisputeOutputRootBeyondProposedBlock_InvalidOutputRoot(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
game.LogGameData(ctx) game.LogGameData(ctx)
} }
...@@ -657,7 +658,7 @@ func TestDisputeOutputRoot_ChangeClaimedOutputRoot(t *testing.T) { ...@@ -657,7 +658,7 @@ func TestDisputeOutputRoot_ChangeClaimedOutputRoot(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
game.LogGameData(ctx) game.LogGameData(ctx)
} }
...@@ -717,7 +718,7 @@ func TestInvalidateUnsafeProposal(t *testing.T) { ...@@ -717,7 +718,7 @@ func TestInvalidateUnsafeProposal(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
game.LogGameData(ctx) game.LogGameData(ctx)
}) })
} }
...@@ -779,7 +780,7 @@ func TestInvalidateProposalForFutureBlock(t *testing.T) { ...@@ -779,7 +780,7 @@ func TestInvalidateProposalForFutureBlock(t *testing.T) {
sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client)) require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
game.LogGameData(ctx) game.LogGameData(ctx)
}) })
} }
...@@ -813,6 +814,6 @@ func TestInvalidateCorrectProposalFutureBlock(t *testing.T) { ...@@ -813,6 +814,6 @@ func TestInvalidateCorrectProposalFutureBlock(t *testing.T) {
// The game should resolve as `CHALLENGER_WINS` always, because the root claim signifies a claim that does not exist // The game should resolve as `CHALLENGER_WINS` always, because the root claim signifies a claim that does not exist
// yet in the L2 chain. // yet in the L2 chain.
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) game.WaitForGameStatus(ctx, gameTypes.GameStatusChallengerWon)
game.LogGameData(ctx) game.LogGameData(ctx)
} }
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