diff --git a/op-e2e/e2eutils/disputegame/helper.go b/op-e2e/e2eutils/disputegame/helper.go index 51b3b179d8f11f230f5548aaf5dc8524cdb342d7..28fbd47e86f30e73f9c39dca70dfe926d1fcc2ec 100644 --- a/op-e2e/e2eutils/disputegame/helper.go +++ b/op-e2e/e2eutils/disputegame/helper.go @@ -18,6 +18,7 @@ import ( faultTypes "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "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/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/l2oo" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" @@ -156,11 +157,11 @@ func (h *FactoryHelper) StartAlphabetGame(ctx context.Context, claimedAlphabet s } } -func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string, rootClaim common.Hash) *OutputCannonGameHelper { +func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string, l2BlockNumber uint64, rootClaim common.Hash) *OutputCannonGameHelper { logger := testlog.Logger(h.t, log.LvlInfo).New("role", "OutputCannonGameHelper") rollupClient := h.system.RollupClient(l2Node) - extraData, _ := h.createBisectionGameExtraData(ctx, rollupClient) + extraData := h.createBisectionGameExtraData(l2Node, l2BlockNumber) ctx, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() @@ -201,11 +202,11 @@ func (h *FactoryHelper) StartOutputCannonGame(ctx context.Context, l2Node string } } -func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node string, claimedAlphabet string) *OutputAlphabetGameHelper { +func (h *FactoryHelper) StartOutputAlphabetGame(ctx context.Context, l2Node string, l2BlockNumber uint64, claimedAlphabet string) *OutputAlphabetGameHelper { logger := testlog.Logger(h.t, log.LvlInfo).New("role", "OutputAlphabetGameHelper") rollupClient := h.system.RollupClient(l2Node) - extraData, _ := h.createBisectionGameExtraData(ctx, rollupClient) + extraData := h.createBisectionGameExtraData(l2Node, l2BlockNumber) ctx, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() @@ -351,24 +352,14 @@ func (h *FactoryHelper) createCannonGame(ctx context.Context, rootClaim common.H } } -func (h *FactoryHelper) createBisectionGameExtraData(ctx context.Context, client *sources.RollupClient) (extraData []byte, l2BlockNumber uint64) { - timeoutCtx, cancel := context.WithTimeout(ctx, 1*time.Minute) - defer cancel() - err := wait.For(timeoutCtx, time.Second, func() (bool, error) { - status, err := client.SyncStatus(ctx) - if err != nil { - return false, err - } - return status.SafeL2.Number > 0, nil - }) - h.require.NoError(err, "Safe head did not progress past genesis") - syncStatus, err := client.SyncStatus(ctx) - h.require.NoError(err, "failed to get sync status") - l2BlockNumber = syncStatus.SafeL2.Number +func (h *FactoryHelper) createBisectionGameExtraData(l2Node string, l2BlockNumber uint64) []byte { + l2Client := h.system.NodeClient(l2Node) + _, 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.t.Logf("Creating game with l2 block number: %v", l2BlockNumber) - extraData = make([]byte, 32) + extraData := make([]byte, 32) binary.BigEndian.PutUint64(extraData[24:], l2BlockNumber) - return + return extraData } func (h *FactoryHelper) createDisputeGameExtraData(ctx context.Context) (extraData []byte, l1Head *big.Int, l2BlockNumber uint64) { diff --git a/op-e2e/faultproofs/output_alphabet_test.go b/op-e2e/faultproofs/output_alphabet_test.go index 73d43ab7d8f71038655f9f95f7324bb036b475f7..0c19ae0a55378f4bf46e33f6905c7cc7b35ed77e 100644 --- a/op-e2e/faultproofs/output_alphabet_test.go +++ b/op-e2e/faultproofs/output_alphabet_test.go @@ -19,7 +19,7 @@ func TestOutputAlphabetGame(t *testing.T) { t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) - game := disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", "abcdexyz") + game := disputeGameFactory.StartOutputAlphabetGame(ctx, "sequencer", 3, "abcdexyz") game.LogGameData(ctx) opts := challenger.WithPrivKey(sys.Cfg.Secrets.Alice) diff --git a/op-e2e/faultproofs/output_cannon_test.go b/op-e2e/faultproofs/output_cannon_test.go index 0d84055929165dc38ccff5e69e548b63da5fb329..aa1599aeeeba389e6a19dc87aafe12f1ce17166c 100644 --- a/op-e2e/faultproofs/output_cannon_test.go +++ b/op-e2e/faultproofs/output_cannon_test.go @@ -2,6 +2,7 @@ package faultproofs import ( "context" + "fmt" "testing" op_e2e "github.com/ethereum-optimism/optimism/op-e2e" @@ -21,7 +22,7 @@ func TestOutputCannonGame(t *testing.T) { t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) - game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", common.Hash{0x01}) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 4, common.Hash{0x01}) game.LogGameData(ctx) game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) @@ -61,6 +62,42 @@ func TestOutputCannonGame(t *testing.T) { game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins) } +func TestOutputCannon_PublishCannonRootClaim(t *testing.T) { + // TODO(client-pod#336) Reduce the number of cases and enable this tests + t.Skip("Contracts always require VM status to indicate the post-state output root is invalid") + op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(outputCannonTestExecutor)) + tests := []struct { + disputeL2BlockNumber uint64 + }{ + {1}, + {2}, + {3}, + {4}, + {5}, + {6}, + {7}, + {8}, + } + for _, test := range tests { + test := test + t.Run(fmt.Sprintf("Dispute_%v", test.disputeL2BlockNumber), func(t *testing.T) { + op_e2e.InitParallel(t, op_e2e.UsesCannon, op_e2e.UseExecutor(outputCannonTestExecutor)) + ctx := context.Background() + sys, _ := startFaultDisputeSystem(t) + + disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", test.disputeL2BlockNumber, common.Hash{0x01}) + game.DisputeLastBlock(ctx) + game.LogGameData(ctx) + + game.StartChallenger(ctx, "sequencer", "Challenger", challenger.WithPrivKey(sys.Cfg.Secrets.Alice)) + + splitDepth := game.SplitDepth(ctx) + game.WaitForClaimAtDepth(ctx, int(splitDepth)+1) + }) + } +} + func TestOutputCannonDisputeGame(t *testing.T) { // TODO(client-pod#247): Fix and enable this. t.Skip("Currently failing because of invalid pre-state") @@ -84,7 +121,7 @@ func TestOutputCannonDisputeGame(t *testing.T) { t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) - game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", common.Hash{0x01, 0xaa}) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0x01, 0xaa}) require.NotNil(t, game) game.LogGameData(ctx) @@ -122,7 +159,7 @@ func TestOutputCannonDefendStep(t *testing.T) { t.Cleanup(sys.Close) disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys) - game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", common.Hash{0x01, 0xaa}) + game := disputeGameFactory.StartOutputCannonGame(ctx, "sequencer", 1, common.Hash{0x01, 0xaa}) require.NotNil(t, game) game.DisputeLastBlock(ctx) game.LogGameData(ctx)