diff --git a/system_tests/large_reorg_test.go b/system_tests/large_reorg_test.go new file mode 100644 index 0000000000..c5e867c0db --- /dev/null +++ b/system_tests/large_reorg_test.go @@ -0,0 +1,60 @@ +// Copyright 2024, Offchain Labs, Inc. +// For license information, see https://github.com/nitro/blob/master/LICENSE + +package arbtest + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/types" +) + +func TestLargeReorg(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + builder.nodeConfig.TransactionStreamer.MaxReorgResequenceDepth = 1_000_000_000 + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + + _, simple := builder.L2.DeploySimple(t, auth) + + startMsgCount, err := builder.L2.ConsensusNode.TxStreamer.GetMessageCount() + Require(t, err) + + checkCounter := func(expected int64) { + t.Helper() + counter, err := simple.Counter(&bind.CallOpts{Context: ctx}) + Require(t, err) + if counter != uint64(expected) { + Fatal(t, "counter was", counter, "expected", expected) + } + } + + i := int64(0) + var tx *types.Transaction + for ; i < 10_000; i++ { + tx, err = simple.LogAndIncrement(&auth, big.NewInt(1)) + Require(t, err, "failed to call Increment()") + if (i+1)%100 == 0 { + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + } + } + + checkCounter(i) + + err = builder.L2.ConsensusNode.TxStreamer.ReorgTo(startMsgCount) + Require(t, err) + // Old messages are replayed asynchronously so we must wait for them to catch up. + _, err = builder.L2.ExecNode.ExecEngine.HeadMessageNumberSync(t) + Require(t, err) + checkCounter(i) +}