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)