diff --git a/op-e2e/e2eutils/challenger/helper.go b/op-e2e/e2eutils/challenger/helper.go index 1bef7b66c7f5..39dbeda65589 100644 --- a/op-e2e/e2eutils/challenger/helper.go +++ b/op-e2e/e2eutils/challenger/helper.go @@ -40,6 +40,16 @@ type Helper struct { chl cliapp.Lifecycle } +func NewHelper(log log.Logger, t *testing.T, require *require.Assertions, dir string, chl cliapp.Lifecycle) *Helper { + return &Helper{ + log: log, + t: t, + require: require, + dir: dir, + chl: chl, + } +} + type Option func(config2 *config.Config) func WithFactoryAddress(addr common.Address) Option { @@ -66,9 +76,9 @@ func WithPollInterval(pollInterval time.Duration) Option { } } -// findMonorepoRoot finds the relative path to the monorepo root +// FindMonorepoRoot finds the relative path to the monorepo root // Different tests might be nested in subdirectories of the op-e2e dir. -func findMonorepoRoot(t *testing.T) string { +func FindMonorepoRoot(t *testing.T) string { path := "./" // Only search up 5 directories // Avoids infinite recursion if the root isn't found for some reason @@ -94,7 +104,7 @@ func applyCannonConfig( ) { require := require.New(t) c.L2Rpc = l2Endpoint - root := findMonorepoRoot(t) + root := FindMonorepoRoot(t) c.CannonBin = root + "cannon/bin/cannon" c.CannonServer = root + "op-program/bin/op-program" c.CannonAbsolutePreState = root + "op-program/bin/prestate.json" diff --git a/op-e2e/e2eutils/disputegame/claim_helper.go b/op-e2e/e2eutils/disputegame/claim_helper.go index eff88db4240a..5221f0b5e58a 100644 --- a/op-e2e/e2eutils/disputegame/claim_helper.go +++ b/op-e2e/e2eutils/disputegame/claim_helper.go @@ -15,53 +15,53 @@ import ( type ClaimHelper struct { require *require.Assertions game *OutputGameHelper - index int64 - parentIndex uint32 - position types.Position + Index int64 + ParentIndex uint32 + Position types.Position claim common.Hash } func newClaimHelper(game *OutputGameHelper, idx int64, claim ContractClaim) *ClaimHelper { return &ClaimHelper{ - require: game.require, + require: game.Require, game: game, - index: idx, - parentIndex: claim.ParentIndex, - position: types.NewPositionFromGIndex(claim.Position), + Index: idx, + ParentIndex: claim.ParentIndex, + Position: types.NewPositionFromGIndex(claim.Position), claim: claim.Claim, } } func (c *ClaimHelper) AgreesWithOutputRoot() bool { - return c.position.Depth()%2 == 0 + return c.Position.Depth()%2 == 0 } func (c *ClaimHelper) IsRootClaim() bool { - return c.position.IsRootPosition() + return c.Position.IsRootPosition() } func (c *ClaimHelper) IsOutputRoot(ctx context.Context) bool { splitDepth := c.game.SplitDepth(ctx) - return c.position.Depth() <= splitDepth + return c.Position.Depth() <= splitDepth } func (c *ClaimHelper) IsOutputRootLeaf(ctx context.Context) bool { splitDepth := c.game.SplitDepth(ctx) - return c.position.Depth() == splitDepth + return c.Position.Depth() == splitDepth } func (c *ClaimHelper) IsBottomGameRoot(ctx context.Context) bool { splitDepth := c.game.SplitDepth(ctx) - return c.position.Depth() == splitDepth+1 + return c.Position.Depth() == splitDepth+1 } func (c *ClaimHelper) IsMaxDepth(ctx context.Context) bool { maxDepth := c.game.MaxDepth(ctx) - return c.position.Depth() == maxDepth + return c.Position.Depth() == maxDepth } func (c *ClaimHelper) Depth() types.Depth { - return c.position.Depth() + return c.Position.Depth() } // WaitForCounterClaim waits for the claim to be countered by another claim being posted. @@ -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 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 { - return int64(claim.ParentIndex) == c.index && !containsClaim(claimIdx, ignoreClaims) + 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 { + return int64(claim.ParentIndex) == c.Index && !containsClaim(claimIdx, ignoreClaims) }) return newClaimHelper(c.game, counterIdx, counterClaim) } @@ -83,28 +83,28 @@ func (c *ClaimHelper) WaitForCountered(ctx context.Context) { timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) defer cancel() err := wait.For(timedCtx, time.Second, func() (bool, error) { - latestData := c.game.getClaim(ctx, c.index) + latestData := c.game.getClaim(ctx, c.Index) return latestData.CounteredBy != common.Address{}, nil }) if err != nil { // Avoid waiting time capturing game data when there's no error - c.require.NoErrorf(err, "Claim %v was not countered\n%v", c.index, c.game.gameData(ctx)) + c.require.NoErrorf(err, "Claim %v was not countered\n%v", c.Index, c.game.GameData(ctx)) } } func (c *ClaimHelper) RequireCorrectOutputRoot(ctx context.Context) { c.require.True(c.IsOutputRoot(ctx), "Should not expect a valid output root in the bottom game") - expected, err := c.game.correctOutputProvider.Get(ctx, c.position) + expected, err := c.game.CorrectOutputProvider.Get(ctx, c.Position) c.require.NoError(err, "Failed to get correct output root") - c.require.Equalf(expected, c.claim, "Should have correct output root in claim %v and position %v", c.index, c.position) + c.require.Equalf(expected, c.claim, "Should have correct output root in claim %v and position %v", c.Index, c.Position) } func (c *ClaimHelper) Attack(ctx context.Context, value common.Hash, opts ...MoveOpt) *ClaimHelper { - c.game.Attack(ctx, c.index, value, opts...) + c.game.Attack(ctx, c.Index, value, opts...) return c.WaitForCounterClaim(ctx) } func (c *ClaimHelper) Defend(ctx context.Context, value common.Hash, opts ...MoveOpt) *ClaimHelper { - c.game.Defend(ctx, c.index, value, opts...) + c.game.Defend(ctx, c.Index, value, opts...) return c.WaitForCounterClaim(ctx) } @@ -115,19 +115,19 @@ func (c *ClaimHelper) RequireDifferentClaimValue(other *ClaimHelper) { func (c *ClaimHelper) RequireOnlyCounteredBy(ctx context.Context, expected ...*ClaimHelper) { claims := c.game.getAllClaims(ctx) for idx, claim := range claims { - if int64(claim.ParentIndex) != c.index { + if int64(claim.ParentIndex) != c.Index { // Doesn't counter this claim, so ignore continue } if !containsClaim(int64(idx), expected) { // Found a countering claim not in the expected list. Fail. - c.require.FailNowf("Found unexpected countering claim", "Parent claim index: %v Game state:\n%v", c.index, c.game.gameData(ctx)) + c.require.FailNowf("Found unexpected countering claim", "Parent claim index: %v Game state:\n%v", c.Index, c.game.GameData(ctx)) } } } func containsClaim(claimIdx int64, haystack []*ClaimHelper) bool { return slices.ContainsFunc(haystack, func(candidate *ClaimHelper) bool { - return candidate.index == claimIdx + return candidate.Index == claimIdx }) } diff --git a/op-e2e/e2eutils/disputegame/dishonest_helper.go b/op-e2e/e2eutils/disputegame/dishonest_helper.go index 1b5798a06f50..fafece1be5ea 100644 --- a/op-e2e/e2eutils/disputegame/dishonest_helper.go +++ b/op-e2e/e2eutils/disputegame/dishonest_helper.go @@ -39,7 +39,7 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context, rootClaim } 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) if !agreeWithLevel { d.OutputHonestHelper.Attack(ctx, claimIndex, WithIgnoreDuplicates()) @@ -53,7 +53,7 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context, rootClaim } } - numClaimsSeen := rootClaim.index + numClaimsSeen := rootClaim.Index for { // Use a short timeout since we don't know the challenger will respond, // and this is only designed for the alphabet game where the response should be fast. @@ -63,7 +63,7 @@ func (d *DishonestHelper) ExhaustDishonestClaims(ctx context.Context, rootClaim // There's nothing to respond to. break } - d.OutputGameHelper.require.NoError(err) + d.OutputGameHelper.Require.NoError(err) for ; numClaimsSeen < newCount; numClaimsSeen++ { claimData := d.getClaim(ctx, numClaimsSeen) diff --git a/op-e2e/e2eutils/disputegame/helper.go b/op-e2e/e2eutils/disputegame/helper.go index 788ae8dcadfa..22d7d4ad77fb 100644 --- a/op-e2e/e2eutils/disputegame/helper.go +++ b/op-e2e/e2eutils/disputegame/helper.go @@ -64,27 +64,27 @@ func (s Status) String() string { } } -type gameCfg struct { +type GameCfg struct { allowFuture bool allowUnsafe bool } type GameOpt interface { - Apply(cfg *gameCfg) + Apply(cfg *GameCfg) } -type gameOptFn func(c *gameCfg) +type gameOptFn func(c *GameCfg) -func (g gameOptFn) Apply(cfg *gameCfg) { +func (g gameOptFn) Apply(cfg *GameCfg) { g(cfg) } func WithUnsafeProposal() GameOpt { - return gameOptFn(func(c *gameCfg) { + return gameOptFn(func(c *GameCfg) { c.allowUnsafe = true }) } func WithFutureProposal() GameOpt { - return gameOptFn(func(c *gameCfg) { + return gameOptFn(func(c *GameCfg) { c.allowFuture = true }) } @@ -104,13 +104,13 @@ type DisputeSystem interface { } type FactoryHelper struct { - t *testing.T - require *require.Assertions - system DisputeSystem - client *ethclient.Client - opts *bind.TransactOpts - factoryAddr common.Address - factory *bindings.DisputeGameFactory + T *testing.T + Require *require.Assertions + System DisputeSystem + Client *ethclient.Client + Opts *bind.TransactOpts + FactoryAddr common.Address + Factory *bindings.DisputeGameFactory } func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem) *FactoryHelper { @@ -127,33 +127,33 @@ func NewFactoryHelper(t *testing.T, ctx context.Context, system DisputeSystem) * require.NoError(err) return &FactoryHelper{ - t: t, - require: require, - system: system, - client: client, - opts: opts, - factory: factory, - factoryAddr: factoryAddr, + T: t, + Require: require, + System: system, + Client: client, + Opts: opts, + Factory: factory, + FactoryAddr: factoryAddr, } } func (h *FactoryHelper) PreimageHelper(ctx context.Context) *preimage.Helper { opts := &bind.CallOpts{Context: ctx} - gameAddr, err := h.factory.GameImpls(opts, cannonGameType) - h.require.NoError(err) - game, err := bindings.NewFaultDisputeGameCaller(gameAddr, h.client) - h.require.NoError(err) + gameAddr, err := h.Factory.GameImpls(opts, cannonGameType) + h.Require.NoError(err) + game, err := bindings.NewFaultDisputeGameCaller(gameAddr, h.Client) + h.Require.NoError(err) vmAddr, err := game.Vm(opts) - h.require.NoError(err) - vm, err := bindings.NewMIPSCaller(vmAddr, h.client) - h.require.NoError(err) + h.Require.NoError(err) + vm, err := bindings.NewMIPSCaller(vmAddr, h.Client) + h.Require.NoError(err) oracleAddr, err := vm.Oracle(opts) - h.require.NoError(err) - return preimage.NewHelper(h.t, h.opts, h.client, oracleAddr) + h.Require.NoError(err) + return preimage.NewHelper(h.T, h.Opts, h.Client, oracleAddr) } -func newGameCfg(opts ...GameOpt) *gameCfg { - cfg := &gameCfg{} +func NewGameCfg(opts ...GameOpt) *GameCfg { + cfg := &GameCfg{} for _, opt := range opts { opt.Apply(cfg) } @@ -161,159 +161,139 @@ func newGameCfg(opts ...GameOpt) *gameCfg { } func (h *FactoryHelper) StartOutputCannonGameWithCorrectRoot(ctx context.Context, l2Node string, l2BlockNumber uint64, opts ...GameOpt) *OutputCannonGameHelper { - cfg := newGameCfg(opts...) - h.waitForBlock(l2Node, l2BlockNumber, cfg) - output, err := h.system.RollupClient(l2Node).OutputAtBlock(ctx, l2BlockNumber) - h.require.NoErrorf(err, "Failed to get output at block %v", l2BlockNumber) + cfg := NewGameCfg(opts...) + h.WaitForBlock(l2Node, l2BlockNumber, cfg) + output, err := h.System.RollupClient(l2Node).OutputAtBlock(ctx, l2BlockNumber) + h.Require.NoErrorf(err, "Failed to get output at block %v", l2BlockNumber) return h.StartOutputCannonGame(ctx, l2Node, l2BlockNumber, common.Hash(output.OutputRoot), opts...) } func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string, l2BlockNumber uint64, rootClaim common.Hash, opts ...GameOpt) *OutputCannonGameHelper { - cfg := newGameCfg(opts...) - logger := testlog.Logger(h.t, log.LevelInfo).New("role", "OutputCannonGameHelper") - rollupClient := h.system.RollupClient(l2Node) + cfg := NewGameCfg(opts...) + logger := testlog.Logger(h.T, log.LevelInfo).New("role", "OutputCannonGameHelper") + rollupClient := h.System.RollupClient(l2Node) - extraData := h.createBisectionGameExtraData(l2Node, l2BlockNumber, cfg) + extraData := h.CreateBisectionGameExtraData(l2Node, l2BlockNumber, cfg) ctx, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() - tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) { - return h.factory.Create(opts, cannonGameType, rootClaim, extraData) + tx, err := transactions.PadGasEstimate(h.Opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return h.Factory.Create(opts, cannonGameType, rootClaim, extraData) }) - h.require.NoError(err, "create fault dispute game") - rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash()) - h.require.NoError(err, "wait for create fault dispute game receipt to be OK") - h.require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event") - createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[1]) - h.require.NoError(err) - game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.client) - h.require.NoError(err) + h.Require.NoError(err, "create fault dispute game") + rcpt, err := wait.ForReceiptOK(ctx, h.Client, tx.Hash()) + h.Require.NoError(err, "wait for create fault dispute game receipt to be OK") + h.Require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event") + createdEvent, err := h.Factory.ParseDisputeGameCreated(*rcpt.Logs[1]) + h.Require.NoError(err) + game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.Client) + h.Require.NoError(err) callOpts := &bind.CallOpts{Context: 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) - h.require.NoError(err, "Failed to load l2 block number") + h.Require.NoError(err, "Failed to load l2 block number") splitDepth, err := game.SplitDepth(callOpts) - h.require.NoError(err, "Failed to load split depth") - l1Head := h.getL1Head(ctx, game) + h.Require.NoError(err, "Failed to load split depth") + l1Head := h.GetL1Head(ctx, game) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock.Uint64()) provider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l1Head, faultTypes.Depth(splitDepth.Uint64()), prestateBlock.Uint64(), poststateBlock.Uint64()) return &OutputCannonGameHelper{ - OutputGameHelper: OutputGameHelper{ - t: h.t, - require: h.require, - client: h.client, - opts: h.opts, - game: game, - factoryAddr: h.factoryAddr, - addr: createdEvent.DisputeProxy, - correctOutputProvider: provider, - system: h.system, - }, + OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, game, 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 *bindings.FaultDisputeGame) eth.BlockID { l1HeadHash, err := game.L1Head(&bind.CallOpts{Context: ctx}) - h.require.NoError(err, "Failed to load L1 head") - l1Header, err := h.client.HeaderByHash(ctx, l1HeadHash) - h.require.NoError(err, "Failed to load L1 header") + h.Require.NoError(err, "Failed to load L1 head") + l1Header, err := h.Client.HeaderByHash(ctx, l1HeadHash) + h.Require.NoError(err, "Failed to load L1 header") l1Head := eth.HeaderBlockID(l1Header) return l1Head } func (h *FactoryHelper) StartOutputAlphabetGameWithCorrectRoot(ctx context.Context, l2Node string, l2BlockNumber uint64, opts ...GameOpt) *OutputAlphabetGameHelper { - cfg := newGameCfg(opts...) - h.waitForBlock(l2Node, l2BlockNumber, cfg) - output, err := h.system.RollupClient(l2Node).OutputAtBlock(ctx, l2BlockNumber) - h.require.NoErrorf(err, "Failed to get output at block %v", l2BlockNumber) + cfg := NewGameCfg(opts...) + h.WaitForBlock(l2Node, l2BlockNumber, cfg) + output, err := h.System.RollupClient(l2Node).OutputAtBlock(ctx, l2BlockNumber) + h.Require.NoErrorf(err, "Failed to get output at block %v", l2BlockNumber) return h.StartOutputAlphabetGame(ctx, l2Node, l2BlockNumber, common.Hash(output.OutputRoot)) } func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node string, l2BlockNumber uint64, rootClaim common.Hash, opts ...GameOpt) *OutputAlphabetGameHelper { - cfg := newGameCfg(opts...) - logger := testlog.Logger(h.t, log.LevelInfo).New("role", "OutputAlphabetGameHelper") - rollupClient := h.system.RollupClient(l2Node) + cfg := NewGameCfg(opts...) + logger := testlog.Logger(h.T, log.LevelInfo).New("role", "OutputAlphabetGameHelper") + rollupClient := h.System.RollupClient(l2Node) - extraData := h.createBisectionGameExtraData(l2Node, l2BlockNumber, cfg) + extraData := h.CreateBisectionGameExtraData(l2Node, l2BlockNumber, cfg) ctx, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() - tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) { - return h.factory.Create(opts, alphabetGameType, rootClaim, extraData) + tx, err := transactions.PadGasEstimate(h.Opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) { + return h.Factory.Create(opts, alphabetGameType, rootClaim, extraData) }) - h.require.NoError(err, "create output bisection game") - rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash()) - h.require.NoError(err, "wait for create output bisection game receipt to be OK") - h.require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event") - createdEvent, err := h.factory.ParseDisputeGameCreated(*rcpt.Logs[1]) - h.require.NoError(err) - game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.client) - h.require.NoError(err) + h.Require.NoError(err, "create output bisection game") + rcpt, err := wait.ForReceiptOK(ctx, h.Client, tx.Hash()) + h.Require.NoError(err, "wait for create output bisection game receipt to be OK") + h.Require.Len(rcpt.Logs, 2, "should have emitted a single DisputeGameCreated event") + createdEvent, err := h.Factory.ParseDisputeGameCreated(*rcpt.Logs[1]) + h.Require.NoError(err) + game, err := bindings.NewFaultDisputeGame(createdEvent.DisputeProxy, h.Client) + h.Require.NoError(err) callOpts := &bind.CallOpts{Context: 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) - h.require.NoError(err, "Failed to load l2 block number") + h.Require.NoError(err, "Failed to load l2 block number") splitDepth, err := game.SplitDepth(callOpts) - h.require.NoError(err, "Failed to load split depth") - l1Head := h.getL1Head(ctx, game) + h.Require.NoError(err, "Failed to load split depth") + l1Head := h.GetL1Head(ctx, game) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock.Uint64()) provider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l1Head, faultTypes.Depth(splitDepth.Uint64()), prestateBlock.Uint64(), poststateBlock.Uint64()) return &OutputAlphabetGameHelper{ - OutputGameHelper: OutputGameHelper{ - t: h.t, - require: h.require, - client: h.client, - opts: h.opts, - game: game, - factoryAddr: h.factoryAddr, - addr: createdEvent.DisputeProxy, - correctOutputProvider: provider, - system: h.system, - }, + OutputGameHelper: *NewOutputGameHelper(h.T, h.Require, h.Client, h.Opts, game, h.FactoryAddr, createdEvent.DisputeProxy, provider, h.System), } } -func (h *FactoryHelper) createBisectionGameExtraData(l2Node string, l2BlockNumber uint64, cfg *gameCfg) []byte { - h.waitForBlock(l2Node, l2BlockNumber, cfg) - h.t.Logf("Creating game with l2 block number: %v", l2BlockNumber) +func (h *FactoryHelper) CreateBisectionGameExtraData(l2Node string, l2BlockNumber uint64, cfg *GameCfg) []byte { + h.WaitForBlock(l2Node, l2BlockNumber, cfg) + h.T.Logf("Creating game with l2 block number: %v", l2BlockNumber) extraData := make([]byte, 32) binary.BigEndian.PutUint64(extraData[24:], l2BlockNumber) return extraData } -func (h *FactoryHelper) waitForBlock(l2Node string, l2BlockNumber uint64, cfg *gameCfg) { +func (h *FactoryHelper) WaitForBlock(l2Node string, l2BlockNumber uint64, cfg *GameCfg) { if cfg.allowFuture { // Proposing a block that doesn't exist yet, so don't perform any checks return } - l2Client := h.system.NodeClient(l2Node) + l2Client := h.System.NodeClient(l2Node) if cfg.allowUnsafe { _, err := geth.WaitForBlock(new(big.Int).SetUint64(l2BlockNumber), l2Client, 1*time.Minute) - h.require.NoErrorf(err, "Block number %v did not become unsafe", l2BlockNumber) + h.Require.NoErrorf(err, "Block number %v did not become unsafe", l2BlockNumber) } else { _, err := geth.WaitForBlockToBeSafe(new(big.Int).SetUint64(l2BlockNumber), l2Client, 1*time.Minute) - h.require.NoErrorf(err, "Block number %v did not become safe", l2BlockNumber) + h.Require.NoErrorf(err, "Block number %v did not become safe", l2BlockNumber) } } func (h *FactoryHelper) StartChallenger(ctx context.Context, name string, options ...challenger.Option) *challenger.Helper { opts := []challenger.Option{ - challenger.WithFactoryAddress(h.factoryAddr), + challenger.WithFactoryAddress(h.FactoryAddr), } opts = append(opts, options...) - c := challenger.NewChallenger(h.t, ctx, h.system, name, opts...) - h.t.Cleanup(func() { + c := challenger.NewChallenger(h.T, ctx, h.System, name, opts...) + h.T.Cleanup(func() { _ = c.Close() }) return c diff --git a/op-e2e/e2eutils/disputegame/output_alphabet_helper.go b/op-e2e/e2eutils/disputegame/output_alphabet_helper.go index 1bcefc23de5d..96221d4a227b 100644 --- a/op-e2e/e2eutils/disputegame/output_alphabet_helper.go +++ b/op-e2e/e2eutils/disputegame/output_alphabet_helper.go @@ -24,37 +24,31 @@ func (g *OutputAlphabetGameHelper) StartChallenger( options ...challenger.Option, ) *challenger.Helper { opts := []challenger.Option{ - challenger.WithAlphabet(g.system.RollupEndpoint(l2Node)), - challenger.WithFactoryAddress(g.factoryAddr), - challenger.WithGameAddress(g.addr), + challenger.WithAlphabet(g.System.RollupEndpoint(l2Node)), + challenger.WithFactoryAddress(g.FactoryAddr), + challenger.WithGameAddress(g.Addr), } opts = append(opts, options...) - c := challenger.NewChallenger(g.t, ctx, g.system, name, opts...) - g.t.Cleanup(func() { + c := challenger.NewChallenger(g.T, ctx, g.System, name, opts...) + g.T.Cleanup(func() { _ = c.Close() }) return c } func (g *OutputAlphabetGameHelper) CreateHonestActor(ctx context.Context, l2Node string) *OutputHonestHelper { - logger := testlog.Logger(g.t, log.LevelInfo).New("role", "HonestHelper", "game", g.addr) - caller := batching.NewMultiCaller(g.system.NodeClient("l1").Client(), batching.DefaultBatchSize) - contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.addr, caller) + logger := testlog.Logger(g.T, log.LevelInfo).New("role", "HonestHelper", "game", g.Addr) + caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize) + contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.Addr, caller) prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) - g.require.NoError(err, "Get block range") + g.Require.NoError(err, "Get block range") splitDepth := g.SplitDepth(ctx) - l1Head := g.getL1Head(ctx) - rollupClient := g.system.RollupClient(l2Node) + l1Head := g.GetL1Head(ctx) + rollupClient := g.System.RollupClient(l2Node) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) correctTrace, err := outputs.NewOutputAlphabetTraceAccessor(logger, metrics.NoopMetrics, prestateProvider, rollupClient, l1Head, splitDepth, prestateBlock, poststateBlock) - g.require.NoError(err, "Create trace accessor") - return &OutputHonestHelper{ - t: g.t, - require: g.require, - game: &g.OutputGameHelper, - contract: contract, - correctTrace: correctTrace, - } + g.Require.NoError(err, "Create trace accessor") + return NewOutputHonestHelper(g.T, g.Require, &g.OutputGameHelper, contract, correctTrace) } func (g *OutputAlphabetGameHelper) CreateDishonestHelper(ctx context.Context, l2Node string, defender bool) *DishonestHelper { diff --git a/op-e2e/e2eutils/disputegame/output_cannon_helper.go b/op-e2e/e2eutils/disputegame/output_cannon_helper.go index b609468a381c..a87a2276eb9a 100644 --- a/op-e2e/e2eutils/disputegame/output_cannon_helper.go +++ b/op-e2e/e2eutils/disputegame/output_cannon_helper.go @@ -40,16 +40,16 @@ func (g *OutputCannonGameHelper) StartChallenger( name string, options ...challenger.Option, ) *challenger.Helper { - rollupEndpoint := g.system.RollupEndpoint(l2Node) - l2Endpoint := g.system.NodeEndpoint(l2Node) + rollupEndpoint := g.System.RollupEndpoint(l2Node) + l2Endpoint := g.System.NodeEndpoint(l2Node) opts := []challenger.Option{ - challenger.WithCannon(g.t, g.system.RollupCfg(), g.system.L2Genesis(), rollupEndpoint, l2Endpoint), - challenger.WithFactoryAddress(g.factoryAddr), - challenger.WithGameAddress(g.addr), + challenger.WithCannon(g.T, g.System.RollupCfg(), g.System.L2Genesis(), rollupEndpoint, l2Endpoint), + challenger.WithFactoryAddress(g.FactoryAddr), + challenger.WithGameAddress(g.Addr), } opts = append(opts, options...) - c := challenger.NewChallenger(g.t, ctx, g.system, name, opts...) - g.t.Cleanup(func() { + c := challenger.NewChallenger(g.T, ctx, g.System, name, opts...) + g.T.Cleanup(func() { _ = c.Close() }) return c @@ -58,30 +58,24 @@ func (g *OutputCannonGameHelper) StartChallenger( func (g *OutputCannonGameHelper) CreateHonestActor(ctx context.Context, l2Node string, options ...challenger.Option) *OutputHonestHelper { opts := g.defaultChallengerOptions(l2Node) opts = append(opts, options...) - cfg := challenger.NewChallengerConfig(g.t, g.system, opts...) + cfg := challenger.NewChallengerConfig(g.T, g.System, opts...) - logger := testlog.Logger(g.t, log.LevelInfo).New("role", "HonestHelper", "game", g.addr) - l2Client := g.system.NodeClient(l2Node) - caller := batching.NewMultiCaller(g.system.NodeClient("l1").Client(), batching.DefaultBatchSize) - contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.addr, caller) + logger := testlog.Logger(g.T, log.LevelInfo).New("role", "HonestHelper", "game", g.Addr) + l2Client := g.System.NodeClient(l2Node) + caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize) + contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.Addr, caller) prestateBlock, poststateBlock, err := contract.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") splitDepth := g.SplitDepth(ctx) - rollupClient := g.system.RollupClient(l2Node) + rollupClient := g.System.RollupClient(l2Node) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) - l1Head := g.getL1Head(ctx) + l1Head := g.GetL1Head(ctx) accessor, err := outputs.NewOutputCannonTraceAccessor( logger, metrics.NoopMetrics, cfg, l2Client, prestateProvider, rollupClient, dir, l1Head, splitDepth, prestateBlock, poststateBlock) - g.require.NoError(err, "Failed to create output cannon trace accessor") - return &OutputHonestHelper{ - t: g.t, - require: g.require, - game: &g.OutputGameHelper, - contract: contract, - correctTrace: accessor, - } + g.Require.NoError(err, "Failed to create output cannon trace accessor") + return NewOutputHonestHelper(g.T, g.Require, &g.OutputGameHelper, contract, accessor) } type PreimageLoadCheck func(types.TraceProvider, uint64) error @@ -94,7 +88,7 @@ func (g *OutputCannonGameHelper) CreateStepLargePreimageLoadCheck(ctx context.Co // Get the preimage data execDepth := g.ExecDepth(ctx) _, _, preimageData, err := provider.GetStepData(ctx, types.NewPosition(execDepth, big.NewInt(int64(targetTraceIndex)))) - g.require.NoError(err) + g.Require.NoError(err) // Wait until the challenge period has started by checking until the challenge // period start time is not zero by calling the ChallengePeriodStartTime method @@ -104,11 +98,11 @@ func (g *OutputCannonGameHelper) CreateStepLargePreimageLoadCheck(ctx context.Co challengePeriodEnd := challengePeriodStart + challengePeriod // Time travel past the challenge period. - g.system.AdvanceTime(time.Duration(challengePeriod) * time.Second) - g.require.NoError(wait.ForBlockWithTimestamp(ctx, g.system.NodeClient("l1"), challengePeriodEnd)) + g.System.AdvanceTime(time.Duration(challengePeriod) * time.Second) + g.Require.NoError(wait.ForBlockWithTimestamp(ctx, g.System.NodeClient("l1"), challengePeriodEnd)) // Assert that the preimage was indeed loaded by an honest challenger - g.waitForPreimageInOracle(ctx, preimageData) + g.WaitForPreimageInOracle(ctx, preimageData) return nil } } @@ -117,8 +111,8 @@ func (g *OutputCannonGameHelper) CreateStepPreimageLoadCheck(ctx context.Context return func(provider types.TraceProvider, targetTraceIndex uint64) error { execDepth := g.ExecDepth(ctx) _, _, preimageData, err := provider.GetStepData(ctx, types.NewPosition(execDepth, big.NewInt(int64(targetTraceIndex)))) - g.require.NoError(err) - g.waitForPreimageInOracle(ctx, preimageData) + g.Require.NoError(err) + g.WaitForPreimageInOracle(ctx, preimageData) return nil } } @@ -133,49 +127,49 @@ func (g *OutputCannonGameHelper) ChallengeToPreimageLoad(ctx context.Context, ou // Identifying the first state transition that loads a global preimage provider, _ := g.createCannonTraceProvider(ctx, "sequencer", outputRootClaim, challenger.WithPrivKey(challengerKey)) targetTraceIndex, err := provider.FindStep(ctx, 0, preimage) - g.require.NoError(err) + g.Require.NoError(err) splitDepth := g.SplitDepth(ctx) execDepth := g.ExecDepth(ctx) - g.require.NotEqual(outputRootClaim.position.TraceIndex(execDepth).Uint64(), targetTraceIndex, "cannot move to defend a terminal trace index") - g.require.EqualValues(splitDepth+1, outputRootClaim.Depth(), "supplied claim must be the root of an execution game") - g.require.EqualValues(execDepth%2, 1, "execution game depth must be odd") // since we're challenging the execution root claim + g.Require.NotEqual(outputRootClaim.Position.TraceIndex(execDepth).Uint64(), targetTraceIndex, "cannot move to defend a terminal trace index") + g.Require.EqualValues(splitDepth+1, outputRootClaim.Depth(), "supplied claim must be the root of an execution game") + g.Require.EqualValues(execDepth%2, 1, "execution game depth must be odd") // since we're challenging the execution root claim if preloadPreimage { _, _, preimageData, err := provider.GetStepData(ctx, types.NewPosition(execDepth, big.NewInt(int64(targetTraceIndex)))) - g.require.NoError(err) - g.uploadPreimage(ctx, preimageData, challengerKey) - g.waitForPreimageInOracle(ctx, preimageData) + g.Require.NoError(err) + g.UploadPreimage(ctx, preimageData, challengerKey) + g.WaitForPreimageInOracle(ctx, preimageData) } // Descending the execution game tree to reach the step that loads the preimage bisectTraceIndex := func(claim *ClaimHelper) *ClaimHelper { - execClaimPosition, err := claim.position.RelativeToAncestorAtDepth(splitDepth + 1) - g.require.NoError(err) + execClaimPosition, err := claim.Position.RelativeToAncestorAtDepth(splitDepth + 1) + g.Require.NoError(err) claimTraceIndex := execClaimPosition.TraceIndex(execDepth).Uint64() - g.t.Logf("Bisecting: Into targetTraceIndex %v: claimIndex=%v at depth=%v. claimPosition=%v execClaimPosition=%v claimTraceIndex=%v", - targetTraceIndex, claim.index, claim.Depth(), claim.position, execClaimPosition, claimTraceIndex) + g.T.Logf("Bisecting: Into targetTraceIndex %v: claimIndex=%v at depth=%v. claimPosition=%v execClaimPosition=%v claimTraceIndex=%v", + targetTraceIndex, claim.Index, claim.Depth(), claim.Position, execClaimPosition, claimTraceIndex) // We always want to position ourselves such that the challenger generates proofs for the targetTraceIndex as prestate if execClaimPosition.Depth() == execDepth-1 { if execClaimPosition.TraceIndex(execDepth).Uint64() == targetTraceIndex { newPosition := execClaimPosition.Attack() correct, err := provider.Get(ctx, newPosition) - g.require.NoError(err) - g.t.Logf("Bisecting: Attack correctly for step at newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + g.Require.NoError(err) + g.T.Logf("Bisecting: Attack correctly for step at newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) return claim.Attack(ctx, correct) } else if execClaimPosition.TraceIndex(execDepth).Uint64() > targetTraceIndex { - g.t.Logf("Bisecting: Attack incorrectly for step") + g.T.Logf("Bisecting: Attack incorrectly for step") return claim.Attack(ctx, common.Hash{0xdd}) } else if execClaimPosition.TraceIndex(execDepth).Uint64()+1 == targetTraceIndex { - g.t.Logf("Bisecting: Defend incorrectly for step") + g.T.Logf("Bisecting: Defend incorrectly for step") return claim.Defend(ctx, common.Hash{0xcc}) } else { newPosition := execClaimPosition.Defend() correct, err := provider.Get(ctx, newPosition) - g.require.NoError(err) - g.t.Logf("Bisecting: Defend correctly for step at newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + g.Require.NoError(err) + g.T.Logf("Bisecting: Defend correctly for step at newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) return claim.Defend(ctx, correct) } } @@ -185,23 +179,23 @@ func (g *OutputCannonGameHelper) ChallengeToPreimageLoad(ctx context.Context, ou if execClaimPosition.TraceIndex(execDepth).Uint64() < targetTraceIndex && claim.Depth() != splitDepth+1 { newPosition := execClaimPosition.Defend() if newPosition.TraceIndex(execDepth).Uint64() < targetTraceIndex { - g.t.Logf("Bisecting: Defend correct. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + g.T.Logf("Bisecting: Defend correct. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) correct, err := provider.Get(ctx, newPosition) - g.require.NoError(err) + g.Require.NoError(err) return claim.Defend(ctx, correct) } else { - g.t.Logf("Bisecting: Defend incorrect. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + g.T.Logf("Bisecting: Defend incorrect. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) return claim.Defend(ctx, common.Hash{0xaa}) } } else { newPosition := execClaimPosition.Attack() if newPosition.TraceIndex(execDepth).Uint64() < targetTraceIndex { - g.t.Logf("Bisecting: Attack correct. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + g.T.Logf("Bisecting: Attack correct. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) correct, err := provider.Get(ctx, newPosition) - g.require.NoError(err) + g.Require.NoError(err) return claim.Attack(ctx, correct) } else { - g.t.Logf("Bisecting: Attack incorrect. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) + g.T.Logf("Bisecting: Attack incorrect. newPosition=%v execIndexAtDepth=%v", newPosition, newPosition.TraceIndex(execDepth)) return claim.Attack(ctx, common.Hash{0xbb}) } } @@ -213,7 +207,7 @@ func (g *OutputCannonGameHelper) ChallengeToPreimageLoad(ctx context.Context, ou leafClaim := g.DefendClaim(ctx, mover, bisectTraceIndex, WithoutWaitingForStep()) // Validate that the preimage was loaded correctly - g.require.NoError(preimageCheck(provider, targetTraceIndex)) + g.Require.NoError(preimageCheck(provider, targetTraceIndex)) // Now the preimage is available wait for the step call to succeed. leafClaim.WaitForCountered(ctx) @@ -229,45 +223,45 @@ func (g *OutputCannonGameHelper) VerifyPreimage(ctx context.Context, outputRootC found := false for offset := uint32(0); ; offset += 4 { preimageOpt := utils.PreimageLoad(preimageKey, offset) - g.t.Logf("Searching for step with key %x and offset %v", preimageKey.PreimageKey(), offset) + g.T.Logf("Searching for step with key %x and offset %v", preimageKey.PreimageKey(), offset) targetTraceIndex, err := provider.FindStep(ctx, start, preimageOpt) if errors.Is(err, io.EOF) { // Did not find any more reads - g.require.True(found, "Should have found at least one preimage read") - g.t.Logf("Searching for step with key %x and offset %v did not find another read", preimageKey.PreimageKey(), offset) + g.Require.True(found, "Should have found at least one preimage read") + g.T.Logf("Searching for step with key %x and offset %v did not find another read", preimageKey.PreimageKey(), offset) return } - g.require.NoError(err, "Failed to find step that loads requested preimage") + g.Require.NoError(err, "Failed to find step that loads requested preimage") start = targetTraceIndex found = true - g.t.Logf("Target trace index: %v", targetTraceIndex) + g.T.Logf("Target trace index: %v", targetTraceIndex) pos := types.NewPosition(execDepth, new(big.Int).SetUint64(targetTraceIndex)) - g.require.Equal(targetTraceIndex, pos.TraceIndex(execDepth).Uint64()) + g.Require.Equal(targetTraceIndex, pos.TraceIndex(execDepth).Uint64()) prestate, proof, oracleData, err := provider.GetStepData(ctx, pos) - g.require.NoError(err, "Failed to get step 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.NoError(err, "Failed to get step 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") - tx, err := g.game.AddLocalData(g.opts, + tx, err := g.Game.AddLocalData(g.Opts, oracleData.GetIdent(), - big.NewInt(outputRootClaim.index), + big.NewInt(outputRootClaim.Index), new(big.Int).SetUint64(uint64(oracleData.OracleOffset))) - g.require.NoError(err) - _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) - g.require.NoError(err) + g.Require.NoError(err) + _, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash()) + g.Require.NoError(err) expectedPostState, err := provider.Get(ctx, pos) - 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} - vmAddr, err := g.game.Vm(callOpts) - g.require.NoError(err, "Failed to get VM address") + vmAddr, err := g.Game.Vm(callOpts) + g.Require.NoError(err, "Failed to get VM address") abi, err := bindings.MIPSMetaData.GetAbi() - g.require.NoError(err, "Failed to load MIPS ABI") - caller := batching.NewMultiCaller(g.client.Client(), batching.DefaultBatchSize) + g.Require.NoError(err, "Failed to load MIPS ABI") + caller := batching.NewMultiCaller(g.Client.Client(), batching.DefaultBatchSize) result, err := caller.SingleCall(ctx, rpcblock.Latest, &batching.ContractCall{ Abi: abi, Addr: vmAddr, @@ -275,41 +269,41 @@ func (g *OutputCannonGameHelper) VerifyPreimage(ctx context.Context, outputRootC Args: []interface{}{ prestate, proof, localContext, }, - From: g.addr, + From: g.Addr, }) - g.require.NoError(err, "Failed to call step") + g.Require.NoError(err, "Failed to call step") actualPostState := result.GetBytes32(0) - g.require.Equal(expectedPostState, common.Hash(actualPostState)) + g.Require.Equal(expectedPostState, common.Hash(actualPostState)) } } func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context, l2Node string, outputRootClaim *ClaimHelper, options ...challenger.Option) (*cannon.CannonTraceProviderForTest, common.Hash) { splitDepth := g.SplitDepth(ctx) - g.require.EqualValues(outputRootClaim.Depth(), splitDepth+1, "outputRootClaim must be the root of an execution game") + g.Require.EqualValues(outputRootClaim.Depth(), splitDepth+1, "outputRootClaim must be the root of an execution game") - logger := testlog.Logger(g.t, log.LevelInfo).New("role", "CannonTraceProvider", "game", g.addr) + logger := testlog.Logger(g.T, log.LevelInfo).New("role", "CannonTraceProvider", "game", g.Addr) opt := g.defaultChallengerOptions(l2Node) opt = append(opt, options...) - cfg := challenger.NewChallengerConfig(g.t, g.system, opt...) + cfg := challenger.NewChallengerConfig(g.T, g.System, opt...) - caller := batching.NewMultiCaller(g.system.NodeClient("l1").Client(), batching.DefaultBatchSize) - l2Client := g.system.NodeClient(l2Node) - contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.addr, caller) + caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize) + l2Client := g.System.NodeClient(l2Node) + contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.Addr, caller) prestateBlock, poststateBlock, err := contract.GetBlockRange(ctx) - g.require.NoError(err, "Failed to load block range") - rollupClient := g.system.RollupClient(l2Node) + g.Require.NoError(err, "Failed to load block range") + rollupClient := g.System.RollupClient(l2Node) prestateProvider := outputs.NewPrestateProvider(rollupClient, prestateBlock) - l1Head := g.getL1Head(ctx) + l1Head := g.GetL1Head(ctx) outputProvider := outputs.NewTraceProvider(logger, prestateProvider, rollupClient, l1Head, splitDepth, prestateBlock, poststateBlock) var localContext common.Hash selector := split.NewSplitProviderSelector(outputProvider, splitDepth, func(ctx context.Context, depth types.Depth, pre types.Claim, post types.Claim) (types.TraceProvider, error) { agreed, disputed, err := outputs.FetchProposals(ctx, outputProvider, pre, post) - g.require.NoError(err) - g.t.Logf("Using trace between blocks %v and %v\n", agreed.L2BlockNumber, disputed.L2BlockNumber) + g.Require.NoError(err) + g.T.Logf("Using trace between blocks %v and %v\n", agreed.L2BlockNumber, disputed.L2BlockNumber) localInputs, err := utils.FetchLocalInputsFromProposals(ctx, l1Head.Hash, l2Client, agreed, disputed) - g.require.NoError(err, "Failed to fetch local inputs") + g.Require.NoError(err, "Failed to fetch local inputs") localContext = outputs.CreateLocalContext(pre, post) dir := filepath.Join(cfg.Datadir, "cannon-trace") subdir := filepath.Join(dir, localContext.Hex()) @@ -317,19 +311,19 @@ func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context, }) claims, err := contract.GetAllClaims(ctx, rpcblock.Latest) - g.require.NoError(err) + g.Require.NoError(err) game := types.NewGameState(claims, g.MaxDepth(ctx)) - provider, err := selector(ctx, game, game.Claims()[outputRootClaim.parentIndex], outputRootClaim.position) - g.require.NoError(err) + provider, err := selector(ctx, game, game.Claims()[outputRootClaim.ParentIndex], outputRootClaim.Position) + g.Require.NoError(err) translatingProvider := provider.(*trace.TranslatingProvider) return translatingProvider.Original().(*cannon.CannonTraceProviderForTest), localContext } func (g *OutputCannonGameHelper) defaultChallengerOptions(l2Node string) []challenger.Option { return []challenger.Option{ - challenger.WithCannon(g.t, g.system.RollupCfg(), g.system.L2Genesis(), g.system.RollupEndpoint(l2Node), g.system.NodeEndpoint(l2Node)), - challenger.WithFactoryAddress(g.factoryAddr), - challenger.WithGameAddress(g.addr), + challenger.WithCannon(g.T, g.System.RollupCfg(), g.System.L2Genesis(), g.System.RollupEndpoint(l2Node), g.System.NodeEndpoint(l2Node)), + challenger.WithFactoryAddress(g.FactoryAddr), + challenger.WithGameAddress(g.Addr), } } diff --git a/op-e2e/e2eutils/disputegame/output_game_helper.go b/op-e2e/e2eutils/disputegame/output_game_helper.go index 46eb519450a9..44e948cd378b 100644 --- a/op-e2e/e2eutils/disputegame/output_game_helper.go +++ b/op-e2e/e2eutils/disputegame/output_game_helper.go @@ -30,19 +30,34 @@ import ( const defaultTimeout = 5 * time.Minute type OutputGameHelper struct { - 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 + 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 +} + +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 { + return &OutputGameHelper{ + T: t, + Require: require, + Client: client, + Opts: opts, + Game: game, + FactoryAddr: factoryAddr, + Addr: addr, + CorrectOutputProvider: correctOutputProvider, + System: system, + } } type moveCfg struct { - opts *bind.TransactOpts + Opts *bind.TransactOpts ignoreDupes bool } @@ -56,9 +71,9 @@ func (f moveOptFn) Apply(c *moveCfg) { f(c) } -func WithTransactOpts(opts *bind.TransactOpts) MoveOpt { +func WithTransactOpts(Opts *bind.TransactOpts) MoveOpt { return moveOptFn(func(c *moveCfg) { - c.opts = opts + c.Opts = Opts }) } @@ -68,13 +83,9 @@ func WithIgnoreDuplicates() MoveOpt { }) } -func (g *OutputGameHelper) Addr() common.Address { - return g.addr -} - func (g *OutputGameHelper) SplitDepth(ctx context.Context) types.Depth { - splitDepth, err := g.game.SplitDepth(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "failed to load split depth") + splitDepth, err := g.Game.SplitDepth(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "failed to load split depth") return types.Depth(splitDepth.Uint64()) } @@ -83,14 +94,14 @@ func (g *OutputGameHelper) ExecDepth(ctx context.Context) types.Depth { } func (g *OutputGameHelper) L2BlockNum(ctx context.Context) uint64 { - blockNum, err := g.game.L2BlockNumber(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "failed to load l2 block number") + blockNum, err := g.Game.L2BlockNumber(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "failed to load l2 block number") return blockNum.Uint64() } func (g *OutputGameHelper) StartingBlockNum(ctx context.Context) uint64 { - blockNum, err := g.game.StartingBlockNumber(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "failed to load starting block number") + blockNum, err := g.Game.StartingBlockNumber(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "failed to load starting block number") return blockNum.Uint64() } @@ -112,8 +123,8 @@ func (g *OutputGameHelper) DisputeBlock(ctx context.Context, disputeBlockNum uin } pos := types.NewPositionFromGIndex(big.NewInt(1)) getClaimValue := func(parentClaim *ClaimHelper, claimPos types.Position) common.Hash { - claimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(claimPos) - g.require.NoError(err, "failed to calculate claim block number") + claimBlockNum, err := g.CorrectOutputProvider.ClaimedBlockNumber(claimPos) + g.Require.NoError(err, "failed to calculate claim block number") if claimBlockNum < disputeBlockNum { // Use the correct output root for all claims prior to the dispute block number // This pushes the game to dispute the last block in the range @@ -130,8 +141,8 @@ func (g *OutputGameHelper) DisputeBlock(ctx context.Context, disputeBlockNum uin claim := g.RootClaim(ctx) for !claim.IsOutputRootLeaf(ctx) { - parentClaimBlockNum, err := g.correctOutputProvider.ClaimedBlockNumber(pos) - g.require.NoError(err, "failed to calculate parent claim block number") + parentClaimBlockNum, err := g.CorrectOutputProvider.ClaimedBlockNumber(pos) + g.Require.NoError(err, "failed to calculate parent claim block number") if parentClaimBlockNum >= disputeBlockNum { pos = pos.Attack() claim = claim.Attack(ctx, getClaimValue(claim, pos)) @@ -152,18 +163,18 @@ func (g *OutputGameHelper) WaitForCorrectOutputRoot(ctx context.Context, claimId g.WaitForClaimCount(ctx, claimIdx+1) claim := g.getClaim(ctx, claimIdx) output := g.correctOutputRoot(ctx, types.NewPositionFromGIndex(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.Claim, "Incorrect output root at claim %v at position %v", claimIdx, claim.Position.Uint64()) } func (g *OutputGameHelper) correctOutputRoot(ctx context.Context, pos types.Position) common.Hash { - outputRoot, err := g.correctOutputProvider.Get(ctx, pos) - g.require.NoErrorf(err, "Failed to get correct output for position %v", pos) + outputRoot, err := g.CorrectOutputProvider.Get(ctx, pos) + g.Require.NoErrorf(err, "Failed to get correct output for position %v", pos) return outputRoot } func (g *OutputGameHelper) MaxClockDuration(ctx context.Context) time.Duration { - duration, err := g.game.MaxClockDuration(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "failed to get max clock duration") + duration, err := g.Game.MaxClockDuration(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "failed to get max clock duration") return time.Duration(duration) * time.Second } @@ -171,43 +182,43 @@ func (g *OutputGameHelper) WaitForNoAvailableCredit(ctx context.Context, addr co timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) defer cancel() err := wait.For(timedCtx, time.Second, func() (bool, error) { - bal, err := g.game.Credit(&bind.CallOpts{Context: timedCtx}, addr) + bal, err := g.Game.Credit(&bind.CallOpts{Context: timedCtx}, addr) if err != nil { return false, err } - g.t.Log("Waiting for zero available credit", "current", bal, "addr", addr) + g.T.Log("Waiting for zero available credit", "current", bal, "addr", addr) return bal.Cmp(big.NewInt(0)) == 0, nil }) if err != nil { g.LogGameData(ctx) - g.require.NoError(err, "Failed to wait for zero available credit") + g.Require.NoError(err, "Failed to wait for zero available credit") } } func (g *OutputGameHelper) AvailableCredit(ctx context.Context, addr common.Address) *big.Int { - credit, err := g.game.Credit(&bind.CallOpts{Context: ctx}, addr) - g.require.NoErrorf(err, "Failed to fetch available credit for %v", addr) + credit, err := g.Game.Credit(&bind.CallOpts{Context: ctx}, addr) + g.Require.NoErrorf(err, "Failed to fetch available credit for %v", addr) return credit } func (g *OutputGameHelper) CreditUnlockDuration(ctx context.Context) time.Duration { - weth, err := g.game.Weth(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "Failed to get WETH contract") - contract, err := bindings.NewDelayedWETH(weth, g.client) - g.require.NoError(err) + weth, err := g.Game.Weth(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "Failed to get WETH contract") + contract, err := bindings.NewDelayedWETH(weth, g.Client) + g.Require.NoError(err) period, err := contract.Delay(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "Failed to get WETH unlock period") + g.Require.NoError(err, "Failed to get WETH unlock period") float, _ := period.Float64() return time.Duration(float) * time.Second } func (g *OutputGameHelper) WethBalance(ctx context.Context, addr common.Address) *big.Int { - weth, err := g.game.Weth(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "Failed to get WETH contract") - contract, err := bindings.NewDelayedWETH(weth, g.client) - g.require.NoError(err) + weth, err := g.Game.Weth(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "Failed to get WETH contract") + contract, err := bindings.NewDelayedWETH(weth, g.Client) + g.Require.NoError(err) balance, err := contract.BalanceOf(&bind.CallOpts{Context: ctx}, addr) - g.require.NoError(err, "Failed to get WETH balance") + g.Require.NoError(err, "Failed to get WETH balance") return balance } @@ -218,16 +229,16 @@ func (g *OutputGameHelper) WaitForClaimCount(ctx context.Context, count int64) { timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) defer cancel() err := wait.For(timedCtx, time.Second, func() (bool, error) { - actual, err := g.game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) + actual, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) if err != nil { 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 }) if err != nil { g.LogGameData(ctx) - g.require.NoErrorf(err, "Did not find expected claim count %v", count) + g.Require.NoErrorf(err, "Did not find expected claim count %v", count) } } @@ -242,8 +253,8 @@ type ContractClaim struct { } func (g *OutputGameHelper) MaxDepth(ctx context.Context) types.Depth { - depth, err := g.game.MaxGameDepth(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "Failed to load game depth") + depth, err := g.Game.MaxGameDepth(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "Failed to load game depth") return types.Depth(depth.Uint64()) } @@ -253,13 +264,13 @@ func (g *OutputGameHelper) waitForClaim(ctx context.Context, timeout time.Durati var matchedClaim ContractClaim var matchClaimIdx int64 err := wait.For(timedCtx, time.Second, func() (bool, error) { - count, err := g.game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) + count, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) if err != nil { return false, fmt.Errorf("retrieve number of claims: %w", err) } // 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-- { - claimData, err := g.game.ClaimData(&bind.CallOpts{Context: timedCtx}, big.NewInt(i)) + claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: timedCtx}, big.NewInt(i)) if err != nil { return false, fmt.Errorf("retrieve claim %v: %w", i, err) } @@ -272,7 +283,7 @@ func (g *OutputGameHelper) waitForClaim(ctx context.Context, timeout time.Durati return false, nil }) if err != nil { // Avoid waiting time capturing game data when there's no error - g.require.NoErrorf(err, "%v\n%v", errorMsg, g.gameData(ctx)) + g.Require.NoErrorf(err, "%v\n%v", errorMsg, g.GameData(ctx)) } return matchClaimIdx, matchedClaim } @@ -281,13 +292,13 @@ func (g *OutputGameHelper) waitForNoClaim(ctx context.Context, errorMsg string, timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) defer cancel() err := wait.For(timedCtx, time.Second, func() (bool, error) { - count, err := g.game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) + count, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: timedCtx}) if err != nil { return false, fmt.Errorf("retrieve number of claims: %w", err) } // Search backwards because the new claims are at the end and more likely the ones we will fail on. for i := count.Int64() - 1; i >= 0; i-- { - claimData, err := g.game.ClaimData(&bind.CallOpts{Context: timedCtx}, big.NewInt(i)) + claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: timedCtx}, big.NewInt(i)) if err != nil { return false, fmt.Errorf("retrieve claim %v: %w", i, err) } @@ -298,7 +309,7 @@ func (g *OutputGameHelper) waitForNoClaim(ctx context.Context, errorMsg string, return true, nil }) if err != nil { // Avoid waiting time capturing game data when there's no error - g.require.NoErrorf(err, "%v\n%v", errorMsg, g.gameData(ctx)) + g.Require.NoErrorf(err, "%v\n%v", errorMsg, g.GameData(ctx)) } } @@ -320,9 +331,9 @@ func (g *OutputGameHelper) getAllClaims(ctx context.Context) []ContractClaim { // 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. func (g *OutputGameHelper) getClaim(ctx context.Context, claimIdx int64) ContractClaim { - claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) + claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) if err != nil { - g.require.NoErrorf(err, "retrieve claim %v", claimIdx) + g.Require.NoErrorf(err, "retrieve claim %v", claimIdx) } return claimData } @@ -362,40 +373,40 @@ func (g *OutputGameHelper) WaitForAllClaimsCountered(ctx context.Context) { func (g *OutputGameHelper) Resolve(ctx context.Context) { ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() - tx, err := g.game.Resolve(g.opts) - g.require.NoError(err) - _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) - g.require.NoError(err) + tx, err := g.Game.Resolve(g.Opts) + g.Require.NoError(err) + _, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash()) + g.Require.NoError(err) } func (g *OutputGameHelper) Status(ctx context.Context) Status { - status, err := g.game.Status(&bind.CallOpts{Context: ctx}) - g.require.NoError(err) + status, err := g.Game.Status(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err) return Status(status) } func (g *OutputGameHelper) WaitForGameStatus(ctx context.Context, expected Status) { - 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) defer cancel() err := wait.For(timedCtx, time.Second, func() (bool, error) { ctx, cancel := context.WithTimeout(timedCtx, 30*time.Second) defer cancel() - status, err := g.game.Status(&bind.CallOpts{Context: ctx}) + status, err := g.Game.Status(&bind.CallOpts{Context: ctx}) if err != nil { 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(status), expected) return expected == Status(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)) } func (g *OutputGameHelper) WaitForInactivity(ctx context.Context, numInactiveBlocks int, untilGameEnds bool) { - g.t.Logf("Waiting for game %v to have no activity for %v blocks", g.addr, numInactiveBlocks) + g.T.Logf("Waiting for game %v to have no activity for %v blocks", g.Addr, numInactiveBlocks) headCh := make(chan *gethtypes.Header, 100) - headSub, err := g.client.SubscribeNewHead(ctx, headCh) - g.require.NoError(err) + headSub, err := g.Client.SubscribeNewHead(ctx, headCh) + g.Require.NoError(err) defer headSub.Unsubscribe() var lastActiveBlock uint64 @@ -411,22 +422,22 @@ func (g *OutputGameHelper) WaitForInactivity(ctx context.Context, numInactiveBlo } else if lastActiveBlock+uint64(numInactiveBlocks) < head.Number.Uint64() { return } - block, err := g.client.BlockByNumber(ctx, head.Number) - g.require.NoError(err) + block, err := g.Client.BlockByNumber(ctx, head.Number) + g.Require.NoError(err) numActions := 0 for _, tx := range block.Transactions() { - if tx.To().Hex() == g.addr.Hex() { + if tx.To().Hex() == g.Addr.Hex() { numActions++ } } if numActions != 0 { - g.t.Logf("Game %v has %v actions in block %d. Resetting inactivity timeout", g.addr, numActions, block.NumberU64()) + g.T.Logf("Game %v has %v actions in block %d. Resetting inactivity timeout", g.Addr, numActions, block.NumberU64()) lastActiveBlock = head.Number.Uint64() } case err := <-headSub.Err(): - g.require.NoError(err) + g.Require.NoError(err) case <-ctx.Done(): - g.require.Fail("Context canceled", ctx.Err()) + g.Require.Fail("Context canceled", ctx.Err()) } } } @@ -453,10 +464,10 @@ func WithoutWaitingForStep() DefendClaimOpt { // It is assumed that the specified claim is invalid and that an honest op-challenger is already running. // When the game has reached the maximum depth it waits for the honest challenger to counter the leaf claim with step. // Returns the final leaf claim -func (g *OutputGameHelper) DefendClaim(ctx context.Context, claim *ClaimHelper, performMove Mover, opts ...DefendClaimOpt) *ClaimHelper { - g.t.Logf("Defending claim %v at depth %v", claim.index, claim.Depth()) +func (g *OutputGameHelper) DefendClaim(ctx context.Context, claim *ClaimHelper, performMove Mover, Opts ...DefendClaimOpt) *ClaimHelper { + g.T.Logf("Defending claim %v at depth %v", claim.Index, claim.Depth()) cfg := &defendClaimCfg{} - for _, opt := range opts { + for _, opt := range Opts { opt(cfg) } for !claim.IsMaxDepth(ctx) { @@ -495,12 +506,12 @@ func (g *OutputGameHelper) ChallengeClaim(ctx context.Context, claim *ClaimHelpe g.LogGameData(ctx) // It's on us to call step if we want to win but shouldn't be possible - 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") + claimCount, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "Failed to get current claim count") return claimCount.Int64() } @@ -513,7 +524,7 @@ func (g *OutputGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64 defer cancel() var newClaimLen int64 err := wait.For(timedCtx, time.Second, func() (bool, error) { - actual, err := g.game.ClaimDataLen(&bind.CallOpts{Context: ctx}) + actual, err := g.Game.ClaimDataLen(&bind.CallOpts{Context: ctx}) if err != nil { return false, err } @@ -523,55 +534,55 @@ func (g *OutputGameHelper) waitForNewClaim(ctx context.Context, checkPoint int64 return newClaimLen, err } -func (g *OutputGameHelper) moveCfg(opts ...MoveOpt) *moveCfg { +func (g *OutputGameHelper) moveCfg(Opts ...MoveOpt) *moveCfg { cfg := &moveCfg{ - opts: g.opts, + Opts: g.Opts, } - for _, opt := range opts { + for _, opt := range Opts { opt.Apply(cfg) } return cfg } -func (g *OutputGameHelper) Attack(ctx context.Context, claimIdx int64, claim common.Hash, opts ...MoveOpt) { - g.t.Logf("Attacking claim %v with value %v", claimIdx, claim) - cfg := g.moveCfg(opts...) +func (g *OutputGameHelper) Attack(ctx context.Context, claimIdx int64, claim common.Hash, Opts ...MoveOpt) { + g.T.Logf("Attacking claim %v with value %v", claimIdx, claim) + cfg := g.moveCfg(Opts...) - claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) - g.require.NoError(err, "Failed to get claim data") + claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) + g.Require.NoError(err, "Failed to get claim data") pos := types.NewPositionFromGIndex(claimData.Position) attackPos := pos.Attack() - transactOpts := g.makeBondedTransactOpts(ctx, pos.Attack().ToGIndex(), cfg.opts) + transactOpts := g.makeBondedTransactOpts(ctx, pos.Attack().ToGIndex(), cfg.Opts) err = g.sendMove(ctx, func() (*gethtypes.Transaction, error) { - return g.game.Attack(transactOpts, big.NewInt(claimIdx), claim) + return g.Game.Attack(transactOpts, big.NewInt(claimIdx), claim) }) if err != nil { if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, attackPos, claim) { return } - g.require.NoErrorf(err, "Defend transaction failed. Game state: \n%v", g.gameData(ctx)) + g.Require.NoErrorf(err, "Defend transaction failed. Game state: \n%v", g.GameData(ctx)) } } -func (g *OutputGameHelper) Defend(ctx context.Context, claimIdx int64, claim common.Hash, opts ...MoveOpt) { - g.t.Logf("Defending claim %v with value %v", claimIdx, claim) - cfg := g.moveCfg(opts...) +func (g *OutputGameHelper) Defend(ctx context.Context, claimIdx int64, claim common.Hash, Opts ...MoveOpt) { + g.T.Logf("Defending claim %v with value %v", claimIdx, claim) + cfg := g.moveCfg(Opts...) - claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) - g.require.NoError(err, "Failed to get claim data") + claimData, err := g.Game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(claimIdx)) + g.Require.NoError(err, "Failed to get claim data") pos := types.NewPositionFromGIndex(claimData.Position) 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) { - return g.game.Defend(transactOpts, big.NewInt(claimIdx), claim) + return g.Game.Defend(transactOpts, big.NewInt(claimIdx), claim) }) if err != nil { if cfg.ignoreDupes && g.hasClaim(ctx, claimIdx, defendPos, claim) { return } - g.require.NoErrorf(err, "Defend transaction failed. Game state: \n%v", g.gameData(ctx)) + g.Require.NoErrorf(err, "Defend transaction failed. Game state: \n%v", g.GameData(ctx)) } } @@ -590,19 +601,19 @@ func (g *OutputGameHelper) sendMove(ctx context.Context, send func() (*gethtypes if err != nil { return fmt.Errorf("transaction did not send: %w", err) } - _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) + _, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash()) if err != nil { return fmt.Errorf("transaction was not ok: %w", err) } return nil } -func (g *OutputGameHelper) makeBondedTransactOpts(ctx context.Context, pos *big.Int, opts *bind.TransactOpts) *bind.TransactOpts { - bopts := *opts - bond, err := g.game.GetRequiredBond(&bind.CallOpts{Context: ctx}, pos) - g.require.NoError(err, "Failed to get required bond") - bopts.Value = bond - return &bopts +func (g *OutputGameHelper) makeBondedTransactOpts(ctx context.Context, pos *big.Int, Opts *bind.TransactOpts) *bind.TransactOpts { + bOpts := *Opts + bond, err := g.Game.GetRequiredBond(&bind.CallOpts{Context: ctx}, pos) + g.Require.NoError(err, "Failed to get required bond") + bOpts.Value = bond + return &bOpts } type ErrWithData interface { @@ -611,19 +622,19 @@ type ErrWithData interface { // StepFails attempts to call step and verifies that it fails with ValidStep() func (g *OutputGameHelper) StepFails(claimIdx int64, isAttack bool, stateData []byte, proof []byte) { - g.t.Logf("Attempting step against claim %v isAttack: %v", claimIdx, isAttack) - _, err := g.game.Step(g.opts, big.NewInt(claimIdx), isAttack, stateData, proof) + g.T.Logf("Attempting step against claim %v isAttack: %v", claimIdx, isAttack) + _, err := g.Game.Step(g.Opts, big.NewInt(claimIdx), isAttack, stateData, proof) errData, ok := err.(ErrWithData) - 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.Truef(ok, "Error should provide ErrorData method: %v", err) + g.Require.Equal("0xfb4e40dd", errData.ErrorData(), "Revert reason should be abi encoded ValidStep()") } // ResolveClaim resolves a single subgame func (g *OutputGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) { - tx, err := g.game.ResolveClaim(g.opts, big.NewInt(claimIdx), common.Big0) - g.require.NoError(err, "ResolveClaim transaction did not send") - _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) - g.require.NoError(err, "ResolveClaim transaction was not OK") + tx, err := g.Game.ResolveClaim(g.Opts, big.NewInt(claimIdx), common.Big0) + g.Require.NoError(err, "ResolveClaim transaction did not send") + _, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash()) + g.Require.NoError(err, "ResolveClaim transaction was not OK") } // ChallengePeriod returns the challenge period fetched from the PreimageOracle contract. @@ -631,7 +642,7 @@ func (g *OutputGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) { func (g *OutputGameHelper) ChallengePeriod(ctx context.Context) uint64 { oracle := g.oracle(ctx) period, err := oracle.ChallengePeriod(ctx) - g.require.NoError(err, "Failed to get challenge period") + g.Require.NoError(err, "Failed to get challenge period") return period } @@ -643,12 +654,12 @@ func (g *OutputGameHelper) WaitForChallengePeriodStart(ctx context.Context, send ctx, cancel := context.WithTimeout(timedCtx, 30*time.Second) defer cancel() timestamp := g.ChallengePeriodStartTime(ctx, sender, data) - g.t.Log("Waiting for challenge period start", "timestamp", timestamp, "key", data.OracleKey, "game", g.addr) + g.T.Log("Waiting for challenge period start", "timestamp", timestamp, "key", data.OracleKey, "game", g.Addr) return timestamp > 0, nil }) if err != nil { g.LogGameData(ctx) - g.require.NoErrorf(err, "Failed to get challenge start period for preimage data %v", data) + g.Require.NoErrorf(err, "Failed to get challenge start period for preimage data %v", data) } } @@ -661,68 +672,68 @@ func (g *OutputGameHelper) ChallengePeriodStartTime(ctx context.Context, sender Claimant: sender, UUID: uuid, }) - g.require.NoError(err, "Failed to get proposal metadata") + g.Require.NoError(err, "Failed to get proposal metadata") if len(metadata) == 0 { return 0 } return metadata[0].Timestamp } -func (g *OutputGameHelper) waitForPreimageInOracle(ctx context.Context, data *types.PreimageOracleData) { +func (g *OutputGameHelper) WaitForPreimageInOracle(ctx context.Context, data *types.PreimageOracleData) { timedCtx, cancel := context.WithTimeout(ctx, defaultTimeout) defer cancel() oracle := g.oracle(ctx) err := wait.For(timedCtx, time.Second, func() (bool, error) { - g.t.Logf("Waiting for preimage (%v) to be present in oracle", common.Bytes2Hex(data.OracleKey)) + g.T.Logf("Waiting for preimage (%v) to be present in oracle", common.Bytes2Hex(data.OracleKey)) return oracle.GlobalDataExists(ctx, data) }) - g.require.NoErrorf(err, "Did not find preimage (%v) in oracle", common.Bytes2Hex(data.OracleKey)) + g.Require.NoErrorf(err, "Did not find preimage (%v) in oracle", common.Bytes2Hex(data.OracleKey)) } -func (g *OutputGameHelper) uploadPreimage(ctx context.Context, data *types.PreimageOracleData, privateKey *ecdsa.PrivateKey) { +func (g *OutputGameHelper) UploadPreimage(ctx context.Context, data *types.PreimageOracleData, privateKey *ecdsa.PrivateKey) { oracle := g.oracle(ctx) - boundOracle, err := bindings.NewPreimageOracle(oracle.Addr(), g.client) - g.require.NoError(err) + boundOracle, err := bindings.NewPreimageOracle(oracle.Addr(), g.Client) + g.Require.NoError(err) var tx *gethtypes.Transaction switch data.OracleKey[0] { case byte(preimage.PrecompileKeyType): tx, err = boundOracle.LoadPrecompilePreimagePart( - g.opts, + g.Opts, new(big.Int).SetUint64(uint64(data.OracleOffset)), data.GetPrecompileAddress(), data.GetPrecompileInput(), ) default: - tx, err = boundOracle.LoadKeccak256PreimagePart(g.opts, new(big.Int).SetUint64(uint64(data.OracleOffset)), data.GetPreimageWithoutSize()) + tx, err = boundOracle.LoadKeccak256PreimagePart(g.Opts, new(big.Int).SetUint64(uint64(data.OracleOffset)), data.GetPreimageWithoutSize()) } - g.require.NoError(err, "Failed to load preimage part") - _, err = wait.ForReceiptOK(ctx, g.client, tx.Hash()) - g.require.NoError(err) + g.Require.NoError(err, "Failed to load preimage part") + _, err = wait.ForReceiptOK(ctx, g.Client, tx.Hash()) + g.Require.NoError(err) } func (g *OutputGameHelper) oracle(ctx context.Context) *contracts.PreimageOracleContract { - caller := batching.NewMultiCaller(g.system.NodeClient("l1").Client(), batching.DefaultBatchSize) - contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.addr, caller) + caller := batching.NewMultiCaller(g.System.NodeClient("l1").Client(), batching.DefaultBatchSize) + contract := contracts.NewFaultDisputeGameContract(contractMetrics.NoopContractMetrics, g.Addr, caller) 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 } -func (g *OutputGameHelper) gameData(ctx context.Context) string { - opts := &bind.CallOpts{Context: ctx} +func (g *OutputGameHelper) GameData(ctx context.Context) string { + Opts := &bind.CallOpts{Context: ctx} maxDepth := g.MaxDepth(ctx) splitDepth := g.SplitDepth(ctx) - claimCount, err := g.game.ClaimDataLen(opts) + claimCount, err := g.Game.ClaimDataLen(Opts) info := fmt.Sprintf("Claim count: %v\n", claimCount) - g.require.NoError(err, "Fetching claim count") + g.Require.NoError(err, "Fetching claim count") for i := int64(0); i < claimCount.Int64(); i++ { - claim, err := g.game.ClaimData(opts, big.NewInt(i)) - g.require.NoErrorf(err, "Fetch claim %v", i) + claim, err := g.Game.ClaimData(Opts, big.NewInt(i)) + g.Require.NoErrorf(err, "Fetch claim %v", i) pos := types.NewPositionFromGIndex(claim.Position) extra := "" if pos.Depth() <= splitDepth { - blockNum, err := g.correctOutputProvider.ClaimedBlockNumber(pos) + blockNum, err := g.CorrectOutputProvider.ClaimedBlockNumber(pos) if err != nil { } else { extra = fmt.Sprintf("Block num: %v", blockNum) @@ -732,28 +743,28 @@ func (g *OutputGameHelper) gameData(ctx context.Context) string { 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) } l2BlockNum := g.L2BlockNum(ctx) - status, err := g.game.Status(opts) - g.require.NoError(err, "Load game status") + status, err := g.Game.Status(Opts) + 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", - g.addr, Status(status), l2BlockNum, splitDepth, maxDepth, info) + g.Addr, Status(status), l2BlockNum, splitDepth, maxDepth, info) } func (g *OutputGameHelper) LogGameData(ctx context.Context) { - g.t.Log(g.gameData(ctx)) + g.T.Log(g.GameData(ctx)) } func (g *OutputGameHelper) Credit(ctx context.Context, addr common.Address) *big.Int { - opts := &bind.CallOpts{Context: ctx} - amt, err := g.game.Credit(opts, addr) - g.require.NoError(err) + Opts := &bind.CallOpts{Context: ctx} + amt, err := g.Game.Credit(Opts, addr) + g.Require.NoError(err) return amt } -func (g *OutputGameHelper) getL1Head(ctx context.Context) eth.BlockID { - l1HeadHash, err := g.game.L1Head(&bind.CallOpts{Context: ctx}) - g.require.NoError(err, "Failed to load L1 head") - l1Header, err := g.client.HeaderByHash(ctx, l1HeadHash) - g.require.NoError(err, "Failed to load L1 header") +func (g *OutputGameHelper) GetL1Head(ctx context.Context) eth.BlockID { + l1HeadHash, err := g.Game.L1Head(&bind.CallOpts{Context: ctx}) + g.Require.NoError(err, "Failed to load L1 head") + l1Header, err := g.Client.HeaderByHash(ctx, l1HeadHash) + g.Require.NoError(err, "Failed to load L1 header") l1Head := eth.HeaderBlockID(l1Header) return l1Head } diff --git a/op-e2e/e2eutils/disputegame/output_honest_helper.go b/op-e2e/e2eutils/disputegame/output_honest_helper.go index 4ec020c127f9..1a5d4e9dc328 100644 --- a/op-e2e/e2eutils/disputegame/output_honest_helper.go +++ b/op-e2e/e2eutils/disputegame/output_honest_helper.go @@ -21,8 +21,18 @@ type OutputHonestHelper struct { correctTrace types.TraceAccessor } +func NewOutputHonestHelper(t *testing.T, require *require.Assertions, game *OutputGameHelper, contract *contracts.FaultDisputeGameContract, correctTrace types.TraceAccessor) *OutputHonestHelper { + return &OutputHonestHelper{ + t: t, + require: require, + game: game, + contract: contract, + correctTrace: correctTrace, + } +} + func (h *OutputHonestHelper) CounterClaim(ctx context.Context, claim *ClaimHelper, opts ...MoveOpt) *ClaimHelper { - game, target := h.loadState(ctx, claim.index) + game, target := h.loadState(ctx, claim.Index) value, err := h.correctTrace.Get(ctx, game, target, target.Position) h.require.NoErrorf(err, "Failed to determine correct claim at position %v with g index %v", target.Position, target.Position.ToGIndex()) if value == claim.claim { @@ -33,12 +43,12 @@ func (h *OutputHonestHelper) CounterClaim(ctx context.Context, claim *ClaimHelpe } func (h *OutputHonestHelper) AttackClaim(ctx context.Context, claim *ClaimHelper, opts ...MoveOpt) *ClaimHelper { - h.Attack(ctx, claim.index, opts...) + h.Attack(ctx, claim.Index, opts...) return claim.WaitForCounterClaim(ctx) } func (h *OutputHonestHelper) DefendClaim(ctx context.Context, claim *ClaimHelper, opts ...MoveOpt) *ClaimHelper { - h.Defend(ctx, claim.index, opts...) + h.Defend(ctx, claim.Index, opts...) return claim.WaitForCounterClaim(ctx) } @@ -68,12 +78,12 @@ func (h *OutputHonestHelper) Defend(ctx context.Context, claimIdx int64, opts .. game, claim := h.loadState(ctx, claimIdx) defendPos := claim.Position.Defend() value, err := h.correctTrace.Get(ctx, game, claim, defendPos) - h.game.require.NoErrorf(err, "Get correct claim at position %v with g index %v", defendPos, defendPos.ToGIndex()) + h.game.Require.NoErrorf(err, "Get correct claim at position %v with g index %v", defendPos, defendPos.ToGIndex()) h.game.Defend(ctx, claimIdx, value, opts...) } func (h *OutputHonestHelper) StepClaimFails(ctx context.Context, claim *ClaimHelper, isAttack bool) { - h.StepFails(ctx, claim.index, isAttack) + h.StepFails(ctx, claim.Index, isAttack) } func (h *OutputHonestHelper) StepFails(ctx context.Context, claimIdx int64, isAttack bool) { diff --git a/op-e2e/faultproofs/challenge_preimage_test.go b/op-e2e/faultproofs/challenge_preimage_test.go index f071580b51ae..445bcf50c807 100644 --- a/op-e2e/faultproofs/challenge_preimage_test.go +++ b/op-e2e/faultproofs/challenge_preimage_test.go @@ -15,7 +15,7 @@ import ( func TestChallengeLargePreimages_ChallengeFirst(t *testing.T) { op_e2e.InitParallel(t) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t) + sys, _ := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -34,7 +34,7 @@ func TestChallengeLargePreimages_ChallengeFirst(t *testing.T) { func TestChallengeLargePreimages_ChallengeMiddle(t *testing.T) { op_e2e.InitParallel(t) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t) + sys, _ := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) disputeGameFactory.StartChallenger(ctx, "Challenger", @@ -52,7 +52,7 @@ func TestChallengeLargePreimages_ChallengeMiddle(t *testing.T) { func TestChallengeLargePreimages_ChallengeLast(t *testing.T) { op_e2e.InitParallel(t) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t) + sys, _ := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) disputeGameFactory.StartChallenger(ctx, "Challenger", diff --git a/op-e2e/faultproofs/multi_test.go b/op-e2e/faultproofs/multi_test.go index 0db4167cf492..a2a171adc875 100644 --- a/op-e2e/faultproofs/multi_test.go +++ b/op-e2e/faultproofs/multi_test.go @@ -14,7 +14,7 @@ func TestMultipleGameTypes(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t) + sys, _ := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) gameFactory := disputegame.NewFactoryHelper(t, ctx, sys) diff --git a/op-e2e/faultproofs/output_alphabet_test.go b/op-e2e/faultproofs/output_alphabet_test.go index 157b144a5ae5..0d5911dffd69 100644 --- a/op-e2e/faultproofs/output_alphabet_test.go +++ b/op-e2e/faultproofs/output_alphabet_test.go @@ -18,7 +18,7 @@ import ( func TestOutputAlphabetGame_ChallengerWins(t *testing.T) { op_e2e.InitParallel(t) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -75,7 +75,7 @@ func TestOutputAlphabetGame_ChallengerWins(t *testing.T) { func TestOutputAlphabetGame_ReclaimBond(t *testing.T) { op_e2e.InitParallel(t) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -83,7 +83,7 @@ func TestOutputAlphabetGame_ReclaimBond(t *testing.T) { game.LogGameData(ctx) // The dispute game should have a zero balance - balance := game.WethBalance(ctx, game.Addr()) + balance := game.WethBalance(ctx, game.Addr) require.Zero(t, balance.Uint64()) alice := sys.Cfg.Secrets.Addresses().Alice @@ -105,7 +105,7 @@ func TestOutputAlphabetGame_ReclaimBond(t *testing.T) { _ = claim.WaitForCounterClaim(ctx) // Expect posted claims so the game balance is non-zero - balance = game.WethBalance(ctx, game.Addr()) + balance = game.WethBalance(ctx, game.Addr) require.Truef(t, balance.Cmp(big.NewInt(0)) > 0, "Expected game balance to be above zero") sys.TimeTravelClock.AdvanceTime(game.MaxClockDuration(ctx)) @@ -130,13 +130,13 @@ func TestOutputAlphabetGame_ReclaimBond(t *testing.T) { game.WaitForNoAvailableCredit(ctx, alice) // The dispute game delayed weth balance should be zero since it's all claimed - require.True(t, game.WethBalance(ctx, game.Addr()).Cmp(big.NewInt(0)) == 0) + require.True(t, game.WethBalance(ctx, game.Addr).Cmp(big.NewInt(0)) == 0) } func TestOutputAlphabetGame_ValidOutputRoot(t *testing.T) { op_e2e.InitParallel(t) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -169,7 +169,7 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { testCase := func(t *testing.T, isRootCorrect bool) { ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -234,7 +234,7 @@ func TestChallengerCompleteExhaustiveDisputeGame(t *testing.T) { func TestOutputAlphabetGame_FreeloaderEarnsNothing(t *testing.T) { op_e2e.InitParallel(t) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) freeloaderOpts, err := bind.NewKeyedTransactorWithChainID(sys.Cfg.Secrets.Mallory, sys.Cfg.L1ChainIDBig()) diff --git a/op-e2e/faultproofs/output_cannon_test.go b/op-e2e/faultproofs/output_cannon_test.go index 92a39a8012d2..9003f68b1d6c 100644 --- a/op-e2e/faultproofs/output_cannon_test.go +++ b/op-e2e/faultproofs/output_cannon_test.go @@ -21,7 +21,7 @@ import ( func TestOutputCannonGame(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -77,7 +77,7 @@ func TestOutputCannon_ChallengeAllZeroClaim(t *testing.T) { // The dishonest actor always posts claims with all zeros. op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -116,7 +116,7 @@ func TestOutputCannon_PublishCannonRootClaim(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t) + sys, _ := StartFaultDisputeSystem(t) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", test.disputeL2BlockNumber, common.Hash{0x01}) @@ -147,7 +147,7 @@ func TestOutputCannonDisputeGame(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -184,7 +184,7 @@ func TestOutputCannonDefendStep(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -220,7 +220,7 @@ func TestOutputCannonStepWithLargePreimage(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t, withBatcherStopped()) + sys, _ := StartFaultDisputeSystem(t, WithBatcherStopped()) t.Cleanup(sys.Close) // Manually send a tx from the correct batcher key to the batcher input with very large (invalid) data @@ -263,7 +263,7 @@ func TestOutputCannonStepWithPreimage(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t, withBlobBatches()) + sys, _ := StartFaultDisputeSystem(t, WithBlobBatches()) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -306,7 +306,7 @@ func TestOutputCannonStepWithKZGPointEvaluation(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t, withEcotone()) + sys, _ := StartFaultDisputeSystem(t, WithEcotone()) t.Cleanup(sys.Close) // NOTE: Flake prevention @@ -315,7 +315,7 @@ func TestOutputCannonStepWithKZGPointEvaluation(t *testing.T) { require.NoError(t, err) require.NoError(t, wait.ForSafeBlock(ctx, sys.RollupClient("sequencer"), safeBlock.NumberU64()+3)) - receipt := sendKZGPointEvaluationTx(t, sys, "sequencer", sys.Cfg.Secrets.Alice) + receipt := SendKZGPointEvaluationTx(t, sys, "sequencer", sys.Cfg.Secrets.Alice) precompileBlock := receipt.BlockNumber t.Logf("KZG Point Evaluation block number: %d", precompileBlock) @@ -406,7 +406,7 @@ func TestOutputCannonProposedOutputRootValid(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -440,7 +440,7 @@ func TestOutputCannonPoisonedPostState(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -504,7 +504,7 @@ func TestDisputeOutputRootBeyondProposedBlock_ValidOutputRoot(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -554,7 +554,7 @@ func TestDisputeOutputRootBeyondProposedBlock_InvalidOutputRoot(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -605,7 +605,7 @@ func TestDisputeOutputRoot_ChangeClaimedOutputRoot(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, l1Client := startFaultDisputeSystem(t) + sys, l1Client := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) @@ -693,7 +693,7 @@ func TestInvalidateUnsafeProposal(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) - sys, l1Client := startFaultDisputeSystem(t, withSequencerWindowSize(100000), withBatcherStopped()) + sys, l1Client := StartFaultDisputeSystem(t, WithSequencerWindowSize(100000), WithBatcherStopped()) t.Cleanup(sys.Close) blockNum := uint64(1) @@ -755,7 +755,7 @@ func TestInvalidateProposalForFutureBlock(t *testing.T) { test := test t.Run(test.name, func(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) - sys, l1Client := startFaultDisputeSystem(t, withSequencerWindowSize(100000)) + sys, l1Client := StartFaultDisputeSystem(t, WithSequencerWindowSize(100000)) t.Cleanup(sys.Close) farFutureBlockNum := uint64(10_000_000) diff --git a/op-e2e/faultproofs/preimages_test.go b/op-e2e/faultproofs/preimages_test.go index fd6032b83fa1..03acf824daf3 100644 --- a/op-e2e/faultproofs/preimages_test.go +++ b/op-e2e/faultproofs/preimages_test.go @@ -32,7 +32,7 @@ func TestLocalPreimages(t *testing.T) { op_e2e.InitParallel(t, op_e2e.UsesCannon) ctx := context.Background() - sys, _ := startFaultDisputeSystem(t) + sys, _ := StartFaultDisputeSystem(t) t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) diff --git a/op-e2e/faultproofs/util.go b/op-e2e/faultproofs/util.go index 804c8f307a02..df3a81131c77 100644 --- a/op-e2e/faultproofs/util.go +++ b/op-e2e/faultproofs/util.go @@ -15,13 +15,13 @@ import ( type faultDisputeConfigOpts func(cfg *op_e2e.SystemConfig) -func withBatcherStopped() faultDisputeConfigOpts { +func WithBatcherStopped() faultDisputeConfigOpts { return func(cfg *op_e2e.SystemConfig) { cfg.DisableBatcher = true } } -func withBlobBatches() faultDisputeConfigOpts { +func WithBlobBatches() faultDisputeConfigOpts { return func(cfg *op_e2e.SystemConfig) { cfg.DataAvailabilityType = batcherFlags.BlobsType @@ -32,7 +32,7 @@ func withBlobBatches() faultDisputeConfigOpts { } } -func withEcotone() faultDisputeConfigOpts { +func WithEcotone() faultDisputeConfigOpts { return func(cfg *op_e2e.SystemConfig) { genesisActivation := hexutil.Uint64(0) cfg.DeployConfig.L1CancunTimeOffset = &genesisActivation @@ -41,13 +41,13 @@ func withEcotone() faultDisputeConfigOpts { } } -func withSequencerWindowSize(size uint64) faultDisputeConfigOpts { +func WithSequencerWindowSize(size uint64) faultDisputeConfigOpts { return func(cfg *op_e2e.SystemConfig) { cfg.DeployConfig.SequencerWindowSize = size } } -func startFaultDisputeSystem(t *testing.T, opts ...faultDisputeConfigOpts) (*op_e2e.System, *ethclient.Client) { +func StartFaultDisputeSystem(t *testing.T, opts ...faultDisputeConfigOpts) (*op_e2e.System, *ethclient.Client) { cfg := op_e2e.DefaultSystemConfig(t) delete(cfg.Nodes, "verifier") for _, opt := range opts { @@ -64,7 +64,7 @@ func startFaultDisputeSystem(t *testing.T, opts ...faultDisputeConfigOpts) (*op_ return sys, sys.Clients["l1"] } -func sendKZGPointEvaluationTx(t *testing.T, sys *op_e2e.System, l2Node string, privateKey *ecdsa.PrivateKey) *types.Receipt { +func SendKZGPointEvaluationTx(t *testing.T, sys *op_e2e.System, l2Node string, privateKey *ecdsa.PrivateKey) *types.Receipt { return op_e2e.SendL2Tx(t, sys.Cfg, sys.Clients[l2Node], privateKey, func(opts *op_e2e.TxOpts) { precompile := common.BytesToAddress([]byte{0x0a}) opts.Gas = 100_000