Commit 4cddf82c authored by Tei Im's avatar Tei Im

Parameterize span batch related test cases

parent a6d211ab
...@@ -6,20 +6,47 @@ import ( ...@@ -6,20 +6,47 @@ import (
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// TestBatchInLastPossibleBlocks tests that the derivation pipeline // TestBlockTimeBatchType run each blocktime-related test case in singular batch mode and span batch mode.
func TestBlockTimeBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"BatchInLastPossibleBlocks", BatchInLastPossibleBlocks},
{"LargeL1Gaps", LargeL1Gaps},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
// BatchInLastPossibleBlocks tests that the derivation pipeline
// accepts a batch that is included in the last possible L1 block // accepts a batch that is included in the last possible L1 block
// where there are also no other batches included in the sequence // where there are also no other batches included in the sequence
// window. // window.
// This is a regression test against the bug fixed in PR #4566 // This is a regression test against the bug fixed in PR #4566
func TestBatchInLastPossibleBlocks(gt *testing.T) { func BatchInLastPossibleBlocks(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
dp.DeployConfig.SequencerWindowSize = 4 dp.DeployConfig.SequencerWindowSize = 4
dp.DeployConfig.L2BlockTime = 2 dp.DeployConfig.L2BlockTime = 2
...@@ -116,7 +143,7 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) { ...@@ -116,7 +143,7 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) {
verifyChainStateOnSequencer(12, 23, 11, 17, 8) verifyChainStateOnSequencer(12, 23, 11, 17, 8)
} }
// TestLargeL1Gaps tests the case that there is a gap between two L1 blocks which // LargeL1Gaps tests the case that there is a gap between two L1 blocks which
// is larger than the sequencer drift. // is larger than the sequencer drift.
// This test has the following parameters: // This test has the following parameters:
// L1 Block time: 4s. L2 Block time: 2s. Sequencer Drift: 32s // L1 Block time: 4s. L2 Block time: 2s. Sequencer Drift: 32s
...@@ -127,13 +154,14 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) { ...@@ -127,13 +154,14 @@ func TestBatchInLastPossibleBlocks(gt *testing.T) {
// Then it generates 3 more L1 blocks. // Then it generates 3 more L1 blocks.
// At this point it can verify that the batches where properly generated. // At this point it can verify that the batches where properly generated.
// Note: It batches submits when possible. // Note: It batches submits when possible.
func TestLargeL1Gaps(gt *testing.T) { func LargeL1Gaps(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L1BlockTime = 4 dp.DeployConfig.L1BlockTime = 4
dp.DeployConfig.L2BlockTime = 2 dp.DeployConfig.L2BlockTime = 2
dp.DeployConfig.SequencerWindowSize = 4 dp.DeployConfig.SequencerWindowSize = 4
dp.DeployConfig.MaxSequencerDrift = 32 dp.DeployConfig.MaxSequencerDrift = 32
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
...@@ -20,7 +21,36 @@ import ( ...@@ -20,7 +21,36 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
) )
func TestBatcher(gt *testing.T) { // TestL2BatcherBatchType run each batcher-related test case in singular batch mode and span batch mode.
func TestL2BatcherBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"NormalBatcher", NormalBatcher},
{"L2Finalization", L2Finalization},
{"L2FinalizationWithSparseL1", L2FinalizationWithSparseL1},
{"GarbageBatch", GarbageBatch},
{"ExtendedTimeWithoutL1Batches", ExtendedTimeWithoutL1Batches},
{"BigL2Txs", BigL2Txs},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func NormalBatcher(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
p := &e2eutils.TestParams{ p := &e2eutils.TestParams{
MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12)
...@@ -29,6 +59,7 @@ func TestBatcher(gt *testing.T) { ...@@ -29,6 +59,7 @@ func TestBatcher(gt *testing.T) {
L1BlockTime: 12, L1BlockTime: 12,
} }
dp := e2eutils.MakeDeployParams(t, p) dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
...@@ -55,7 +86,7 @@ func TestBatcher(gt *testing.T) { ...@@ -55,7 +86,7 @@ func TestBatcher(gt *testing.T) {
To: &dp.Addresses.Bob, To: &dp.Addresses.Bob,
Value: e2eutils.Ether(2), Value: e2eutils.Ether(2),
}) })
require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) require.NoError(t, cl.SendTransaction(t.Ctx(), tx))
sequencer.ActL2PipelineFull(t) sequencer.ActL2PipelineFull(t)
verifier.ActL2PipelineFull(t) verifier.ActL2PipelineFull(t)
...@@ -97,9 +128,10 @@ func TestBatcher(gt *testing.T) { ...@@ -97,9 +128,10 @@ func TestBatcher(gt *testing.T) {
require.NotNil(t, vTx) require.NotNil(t, vTx)
} }
func TestL2Finalization(gt *testing.T) { func L2Finalization(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
miner, engine, sequencer := setupSequencerTest(t, sd, log) miner, engine, sequencer := setupSequencerTest(t, sd, log)
...@@ -202,10 +234,11 @@ func TestL2Finalization(gt *testing.T) { ...@@ -202,10 +234,11 @@ func TestL2Finalization(gt *testing.T) {
require.Equal(t, heightToSubmit, sequencer.SyncStatus().FinalizedL2.Number, "unknown/bad finalized L1 blocks are ignored") require.Equal(t, heightToSubmit, sequencer.SyncStatus().FinalizedL2.Number, "unknown/bad finalized L1 blocks are ignored")
} }
// TestL2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal // L2FinalizationWithSparseL1 tests that safe L2 blocks can be finalized even if we do not regularly get a L1 finalization signal
func TestL2FinalizationWithSparseL1(gt *testing.T) { func L2FinalizationWithSparseL1(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
miner, engine, sequencer := setupSequencerTest(t, sd, log) miner, engine, sequencer := setupSequencerTest(t, sd, log)
...@@ -258,13 +291,14 @@ func TestL2FinalizationWithSparseL1(gt *testing.T) { ...@@ -258,13 +291,14 @@ func TestL2FinalizationWithSparseL1(gt *testing.T) {
require.Equal(t, finalStatus.FinalizedL2.Number, finalStatus.UnsafeL2.Number, "sequencer submitted its L2 block and it finalized") require.Equal(t, finalStatus.FinalizedL2.Number, finalStatus.UnsafeL2.Number, "sequencer submitted its L2 block and it finalized")
} }
// TestGarbageBatch tests the behavior of an invalid/malformed output channel frame containing // GarbageBatch tests the behavior of an invalid/malformed output channel frame containing
// valid batches being submitted to the batch inbox. These batches should always be rejected // valid batches being submitted to the batch inbox. These batches should always be rejected
// and the safe L2 head should remain unaltered. // and the safe L2 head should remain unaltered.
func TestGarbageBatch(gt *testing.T) { func GarbageBatch(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
p := defaultRollupTestParams p := defaultRollupTestParams
dp := e2eutils.MakeDeployParams(t, p) dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
for _, garbageKind := range GarbageKinds { for _, garbageKind := range GarbageKinds {
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError) log := testlog.Logger(t, log.LvlError)
...@@ -340,7 +374,7 @@ func TestGarbageBatch(gt *testing.T) { ...@@ -340,7 +374,7 @@ func TestGarbageBatch(gt *testing.T) {
} }
} }
func TestExtendedTimeWithoutL1Batches(gt *testing.T) { func ExtendedTimeWithoutL1Batches(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
p := &e2eutils.TestParams{ p := &e2eutils.TestParams{
MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12) MaxSequencerDrift: 20, // larger than L1 block time we simulate in this test (12)
...@@ -349,6 +383,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { ...@@ -349,6 +383,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) {
L1BlockTime: 12, L1BlockTime: 12,
} }
dp := e2eutils.MakeDeployParams(t, p) dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError) log := testlog.Logger(t, log.LvlError)
miner, engine, sequencer := setupSequencerTest(t, sd, log) miner, engine, sequencer := setupSequencerTest(t, sd, log)
...@@ -386,7 +421,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { ...@@ -386,7 +421,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) {
require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe(), "same for sequencer") require.Equal(t, sequencer.L2Unsafe(), sequencer.L2Safe(), "same for sequencer")
} }
// TestBigL2Txs tests a high-throughput case with constrained batcher: // BigL2Txs tests a high-throughput case with constrained batcher:
// - Fill 40 L2 blocks to near max-capacity, with txs of 120 KB each // - Fill 40 L2 blocks to near max-capacity, with txs of 120 KB each
// - Buffer the L2 blocks into channels together as much as possible, submit data-txs only when necessary // - Buffer the L2 blocks into channels together as much as possible, submit data-txs only when necessary
// (just before crossing the max RLP channel size) // (just before crossing the max RLP channel size)
...@@ -398,7 +433,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) { ...@@ -398,7 +433,7 @@ func TestExtendedTimeWithoutL1Batches(gt *testing.T) {
// The goal of this test is to quickly run through an otherwise very slow process of submitting and including lots of data. // The goal of this test is to quickly run through an otherwise very slow process of submitting and including lots of data.
// This does not test the batcher code, but is really focused at testing the batcher utils // This does not test the batcher code, but is really focused at testing the batcher utils
// and channel-decoding verifier code in the derive package. // and channel-decoding verifier code in the derive package.
func TestBigL2Txs(gt *testing.T) { func BigL2Txs(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
p := &e2eutils.TestParams{ p := &e2eutils.TestParams{
MaxSequencerDrift: 100, MaxSequencerDrift: 100,
...@@ -407,6 +442,7 @@ func TestBigL2Txs(gt *testing.T) { ...@@ -407,6 +442,7 @@ func TestBigL2Txs(gt *testing.T) {
L1BlockTime: 12, L1BlockTime: 12,
} }
dp := e2eutils.MakeDeployParams(t, p) dp := e2eutils.MakeDeployParams(t, p)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlInfo) log := testlog.Logger(t, log.LvlInfo)
miner, engine, sequencer := setupSequencerTest(t, sd, log) miner, engine, sequencer := setupSequencerTest(t, sd, log)
...@@ -464,7 +500,7 @@ func TestBigL2Txs(gt *testing.T) { ...@@ -464,7 +500,7 @@ func TestBigL2Txs(gt *testing.T) {
Value: big.NewInt(0), Value: big.NewInt(0),
Data: data, Data: data,
}) })
require.NoError(gt, cl.SendTransaction(t.Ctx(), tx)) require.NoError(t, cl.SendTransaction(t.Ctx(), tx))
engine.ActL2IncludeTx(dp.Addresses.Alice)(t) engine.ActL2IncludeTx(dp.Addresses.Alice)(t)
} }
sequencer.ActL2EndBlock(t) sequencer.ActL2EndBlock(t)
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
...@@ -14,9 +15,34 @@ import ( ...@@ -14,9 +15,34 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
) )
func TestProposer(gt *testing.T) { // TestProposerBatchType run each proposer-related test case in singular batch mode and span batch mode.
func TestProposerBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"RunProposerTest", RunProposerTest},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func RunProposerTest(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
...@@ -21,8 +22,9 @@ import ( ...@@ -21,8 +22,9 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
) )
func setupReorgTest(t Testing, config *e2eutils.TestParams) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) { func setupReorgTest(t Testing, config *e2eutils.TestParams, spanBatchTimeOffset *hexutil.Uint64) (*e2eutils.SetupData, *e2eutils.DeployParams, *L1Miner, *L2Sequencer, *L2Engine, *L2Verifier, *L2Engine, *L2Batcher) {
dp := e2eutils.MakeDeployParams(t, config) dp := e2eutils.MakeDeployParams(t, config)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
...@@ -44,9 +46,38 @@ func setupReorgTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.Set ...@@ -44,9 +46,38 @@ func setupReorgTestActors(t Testing, dp *e2eutils.DeployParams, sd *e2eutils.Set
return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine, batcher return sd, dp, miner, sequencer, seqEngine, verifier, verifEngine, batcher
} }
func TestReorgOrphanBlock(gt *testing.T) { // TestReorgBatchType run each reorg-related test case in singular batch mode and span batch mode.
func TestReorgBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"ReorgOrphanBlock", ReorgOrphanBlock},
{"ReorgFlipFlop", ReorgFlipFlop},
{"DeepReorg", DeepReorg},
{"RestartOpGeth", RestartOpGeth},
{"ConflictingL2Blocks", ConflictingL2Blocks},
{"SyncAfterReorg", SyncAfterReorg},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func ReorgOrphanBlock(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams) sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, spanBatchTimeOffset)
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
sequencer.ActL2PipelineFull(t) sequencer.ActL2PipelineFull(t)
...@@ -112,9 +143,9 @@ func TestReorgOrphanBlock(gt *testing.T) { ...@@ -112,9 +143,9 @@ func TestReorgOrphanBlock(gt *testing.T) {
require.Equal(t, verifier.L2Safe(), sequencer.L2Safe(), "verifier and sequencer see same safe L2 block, while only verifier dealt with the orphan and replay") require.Equal(t, verifier.L2Safe(), sequencer.L2Safe(), "verifier and sequencer see same safe L2 block, while only verifier dealt with the orphan and replay")
} }
func TestReorgFlipFlop(gt *testing.T) { func ReorgFlipFlop(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams) sd, _, miner, sequencer, _, verifier, verifierEng, batcher := setupReorgTest(t, defaultRollupTestParams, spanBatchTimeOffset)
minerCl := miner.L1Client(t, sd.RollupCfg) minerCl := miner.L1Client(t, sd.RollupCfg)
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
checkVerifEngine := func() { checkVerifEngine := func() {
...@@ -333,7 +364,7 @@ func TestReorgFlipFlop(gt *testing.T) { ...@@ -333,7 +364,7 @@ func TestReorgFlipFlop(gt *testing.T) {
// Verifier // Verifier
// - Unsafe head is 62 // - Unsafe head is 62
// - Safe head is 42 // - Safe head is 42
func TestDeepReorg(gt *testing.T) { func DeepReorg(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
// Create actor and verification engine client // Create actor and verification engine client
...@@ -342,7 +373,7 @@ func TestDeepReorg(gt *testing.T) { ...@@ -342,7 +373,7 @@ func TestDeepReorg(gt *testing.T) {
SequencerWindowSize: 20, SequencerWindowSize: 20,
ChannelTimeout: 120, ChannelTimeout: 120,
L1BlockTime: 4, L1BlockTime: 4,
}) }, spanBatchTimeOffset)
minerCl := miner.L1Client(t, sd.RollupCfg) minerCl := miner.L1Client(t, sd.RollupCfg)
l2Client := seqEngine.EthClient() l2Client := seqEngine.EthClient()
verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg) verifEngClient := verifierEng.EngineClient(t, sd.RollupCfg)
...@@ -566,9 +597,9 @@ type rpcWrapper struct { ...@@ -566,9 +597,9 @@ type rpcWrapper struct {
client.RPC client.RPC
} }
// TestRestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart, // RestartOpGeth tests that the sequencer can restart its execution engine without rollup-node restart,
// including recovering the finalized/safe state of L2 chain without reorging. // including recovering the finalized/safe state of L2 chain without reorging.
func TestRestartOpGeth(gt *testing.T) { func RestartOpGeth(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dbPath := path.Join(t.TempDir(), "testdb") dbPath := path.Join(t.TempDir(), "testdb")
dbOption := func(_ *ethconfig.Config, nodeCfg *node.Config) error { dbOption := func(_ *ethconfig.Config, nodeCfg *node.Config) error {
...@@ -576,6 +607,7 @@ func TestRestartOpGeth(gt *testing.T) { ...@@ -576,6 +607,7 @@ func TestRestartOpGeth(gt *testing.T) {
return nil return nil
} }
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
jwtPath := e2eutils.WriteDefaultJWT(t) jwtPath := e2eutils.WriteDefaultJWT(t)
...@@ -660,12 +692,13 @@ func TestRestartOpGeth(gt *testing.T) { ...@@ -660,12 +692,13 @@ func TestRestartOpGeth(gt *testing.T) {
require.Equal(t, statusBeforeRestart.SafeL2, sequencer.L2Safe(), "expecting the safe block to catch up to what it was before shutdown after syncing from L1, and not be stuck at the finalized block") require.Equal(t, statusBeforeRestart.SafeL2, sequencer.L2Safe(), "expecting the safe block to catch up to what it was before shutdown after syncing from L1, and not be stuck at the finalized block")
} }
// TestConflictingL2Blocks tests that a second copy of the sequencer stack cannot introduce an alternative // ConflictingL2Blocks tests that a second copy of the sequencer stack cannot introduce an alternative
// L2 block (compared to something already secured by the first sequencer): // L2 block (compared to something already secured by the first sequencer):
// the alt block is not synced by the verifier, in unsafe and safe sync modes. // the alt block is not synced by the verifier, in unsafe and safe sync modes.
func TestConflictingL2Blocks(gt *testing.T) { func ConflictingL2Blocks(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
...@@ -772,7 +805,7 @@ func TestConflictingL2Blocks(gt *testing.T) { ...@@ -772,7 +805,7 @@ func TestConflictingL2Blocks(gt *testing.T) {
require.Equal(t, sequencer.L2Unsafe(), altSequencer.L2Unsafe(), "and gets back in harmony with original sequencer") require.Equal(t, sequencer.L2Unsafe(), altSequencer.L2Unsafe(), "and gets back in harmony with original sequencer")
} }
func TestSyncAfterReorg(gt *testing.T) { func SyncAfterReorg(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
testingParams := e2eutils.TestParams{ testingParams := e2eutils.TestParams{
MaxSequencerDrift: 60, MaxSequencerDrift: 60,
...@@ -780,7 +813,7 @@ func TestSyncAfterReorg(gt *testing.T) { ...@@ -780,7 +813,7 @@ func TestSyncAfterReorg(gt *testing.T) {
ChannelTimeout: 2, ChannelTimeout: 2,
L1BlockTime: 12, L1BlockTime: 12,
} }
sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams) sd, dp, miner, sequencer, seqEngine, verifier, _, batcher := setupReorgTest(t, &testingParams, spanBatchTimeOffset)
l2Client := seqEngine.EthClient() l2Client := seqEngine.EthClient()
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
addresses := e2eutils.CollectAddresses(sd, dp) addresses := e2eutils.CollectAddresses(sd, dp)
......
...@@ -23,9 +23,35 @@ import ( ...@@ -23,9 +23,35 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestDerivationWithFlakyL1RPC(gt *testing.T) { // TestSyncBatchType run each sync test case in singular batch mode and span batch mode.
func TestSyncBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"DerivationWithFlakyL1RPC", DerivationWithFlakyL1RPC},
{"FinalizeWhileSyncing", FinalizeWhileSyncing},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func DerivationWithFlakyL1RPC(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create
_, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log)
...@@ -62,9 +88,10 @@ func TestDerivationWithFlakyL1RPC(gt *testing.T) { ...@@ -62,9 +88,10 @@ func TestDerivationWithFlakyL1RPC(gt *testing.T) {
require.Equal(t, sequencer.L2Unsafe(), verifier.L2Safe(), "verifier is synced") require.Equal(t, sequencer.L2Unsafe(), verifier.L2Safe(), "verifier is synced")
} }
func TestFinalizeWhileSyncing(gt *testing.T) { func FinalizeWhileSyncing(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create log := testlog.Logger(t, log.LvlError) // mute all the temporary derivation errors that we forcefully create
_, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log) _, _, miner, sequencer, _, verifier, _, batcher := setupReorgTestActors(t, dp, sd, log)
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
...@@ -19,13 +20,40 @@ import ( ...@@ -19,13 +20,40 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
) )
// TestBatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A, // TestSystemConfigBatchType run each system config-related test case in singular batch mode and span batch mode.
func TestSystemConfigBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"BatcherKeyRotation", BatcherKeyRotation},
{"GPOParamsChange", GPOParamsChange},
{"GasLimitChange", GasLimitChange},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
// BatcherKeyRotation tests that batcher A can operate, then be replaced with batcher B, then ignore old batcher A,
// and that the change to batcher B is reverted properly upon reorg of L1. // and that the change to batcher B is reverted properly upon reorg of L1.
func TestBatcherKeyRotation(gt *testing.T) { func BatcherKeyRotation(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2BlockTime = 2 dp.DeployConfig.L2BlockTime = 2
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
...@@ -198,11 +226,12 @@ func TestBatcherKeyRotation(gt *testing.T) { ...@@ -198,11 +226,12 @@ func TestBatcherKeyRotation(gt *testing.T) {
require.Equal(t, sequencer.L2Unsafe(), verifier.L2Unsafe(), "verifier synced") require.Equal(t, sequencer.L2Unsafe(), verifier.L2Unsafe(), "verifier synced")
} }
// TestGPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions, // GPOParamsChange tests that the GPO params can be updated to adjust fees of L2 transactions,
// and that the L1 data fees to the L2 transaction are applied correctly before, during and after the GPO update in L2. // and that the L1 data fees to the L2 transaction are applied correctly before, during and after the GPO update in L2.
func TestGPOParamsChange(gt *testing.T) { func GPOParamsChange(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
...@@ -326,12 +355,13 @@ func TestGPOParamsChange(gt *testing.T) { ...@@ -326,12 +355,13 @@ func TestGPOParamsChange(gt *testing.T) {
require.Equal(t, "2.3", receipt.FeeScalar.String(), "2_300_000 divided by 6 decimals = float(2.3)") require.Equal(t, "2.3", receipt.FeeScalar.String(), "2_300_000 divided by 6 decimals = float(2.3)")
} }
// TestGasLimitChange tests that the gas limit can be configured to L1, // GasLimitChange tests that the gas limit can be configured to L1,
// and that the L2 changes the gas limit instantly at the exact block that adopts the L1 origin with // and that the L2 changes the gas limit instantly at the exact block that adopts the L1 origin with
// the gas limit change event. And checks if a verifier node can reproduce the same gas limit change. // the gas limit change event. And checks if a verifier node can reproduce the same gas limit change.
func TestGasLimitChange(gt *testing.T) { func GasLimitChange(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
miner, seqEngine, sequencer := setupSequencerTest(t, sd, log) miner, seqEngine, sequencer := setupSequencerTest(t, sd, log)
......
...@@ -13,10 +13,12 @@ import ( ...@@ -13,10 +13,12 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
) )
type regolithScheduledTest struct { type hardforkScheduledTest struct {
name string name string
regolithTime *hexutil.Uint64 regolithTime *hexutil.Uint64
activateRegolith bool spanBatchTime *hexutil.Uint64
activateRegolith bool
activateSpanBatch bool
} }
// TestCrossLayerUser tests that common actions of the CrossLayerUser actor work in various regolith configurations: // TestCrossLayerUser tests that common actions of the CrossLayerUser actor work in various regolith configurations:
...@@ -31,11 +33,18 @@ func TestCrossLayerUser(t *testing.T) { ...@@ -31,11 +33,18 @@ func TestCrossLayerUser(t *testing.T) {
zeroTime := hexutil.Uint64(0) zeroTime := hexutil.Uint64(0)
futureTime := hexutil.Uint64(20) futureTime := hexutil.Uint64(20)
farFutureTime := hexutil.Uint64(2000) farFutureTime := hexutil.Uint64(2000)
tests := []regolithScheduledTest{ tests := []hardforkScheduledTest{
{name: "NoRegolith", regolithTime: nil, activateRegolith: false}, {name: "NoRegolith", regolithTime: nil, activateRegolith: false, spanBatchTime: nil, activateSpanBatch: false},
{name: "NotYetRegolith", regolithTime: &farFutureTime, activateRegolith: false}, {name: "NotYetRegolith", regolithTime: &farFutureTime, activateRegolith: false, spanBatchTime: nil, activateSpanBatch: false},
{name: "RegolithAtGenesis", regolithTime: &zeroTime, activateRegolith: true}, {name: "RegolithAtGenesis", regolithTime: &zeroTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false},
{name: "RegolithAfterGenesis", regolithTime: &futureTime, activateRegolith: true}, {name: "RegolithAfterGenesis", regolithTime: &futureTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false},
{name: "NoSpanBatch", regolithTime: &zeroTime, activateRegolith: true, spanBatchTime: nil, activateSpanBatch: false},
{name: "NotYetSpanBatch", regolithTime: &zeroTime, activateRegolith: true,
spanBatchTime: &farFutureTime, activateSpanBatch: false},
{name: "SpanBatchAtGenesis", regolithTime: &zeroTime, activateRegolith: true,
spanBatchTime: &zeroTime, activateSpanBatch: true},
{name: "SpanBatchAfterGenesis", regolithTime: &zeroTime, activateRegolith: true,
spanBatchTime: &futureTime, activateSpanBatch: true},
} }
for _, test := range tests { for _, test := range tests {
test := test // Use a fixed reference as the tests run in parallel test := test // Use a fixed reference as the tests run in parallel
...@@ -45,10 +54,11 @@ func TestCrossLayerUser(t *testing.T) { ...@@ -45,10 +54,11 @@ func TestCrossLayerUser(t *testing.T) {
} }
} }
func runCrossLayerUserTest(gt *testing.T, test regolithScheduledTest) { func runCrossLayerUserTest(gt *testing.T, test hardforkScheduledTest) {
t := NewDefaultTesting(gt) t := NewDefaultTesting(gt)
dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams) dp := e2eutils.MakeDeployParams(t, defaultRollupTestParams)
dp.DeployConfig.L2GenesisRegolithTimeOffset = test.regolithTime dp.DeployConfig.L2GenesisRegolithTimeOffset = test.regolithTime
dp.DeployConfig.L2GenesisSpanBatchTimeOffset = test.spanBatchTime
sd := e2eutils.Setup(t, dp, defaultAlloc) sd := e2eutils.Setup(t, dp, defaultAlloc)
log := testlog.Logger(t, log.LvlDebug) log := testlog.Logger(t, log.LvlDebug)
......
...@@ -684,7 +684,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste ...@@ -684,7 +684,7 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
} }
var batchType uint = derive.SingularBatchType var batchType uint = derive.SingularBatchType
if os.Getenv("OP_E2E_USE_SPAN_BATCH") == "true" { if cfg.DeployConfig.L2GenesisSpanBatchTimeOffset != nil && *cfg.DeployConfig.L2GenesisSpanBatchTimeOffset == hexutil.Uint64(0) {
batchType = derive.SpanBatchType batchType = derive.SpanBatchType
} }
batcherMaxL1TxSizeBytes := cfg.BatcherMaxL1TxSizeBytes batcherMaxL1TxSizeBytes := cfg.BatcherMaxL1TxSizeBytes
......
...@@ -15,25 +15,42 @@ import ( ...@@ -15,25 +15,42 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestVerifyL2OutputRoot(t *testing.T) { func TestVerifyL2OutputRoot(t *testing.T) {
testVerifyL2OutputRoot(t, false) testVerifyL2OutputRoot(t, false, false)
}
func TestVerifyL2OutputRootSpanBatch(t *testing.T) {
testVerifyL2OutputRoot(t, false, true)
} }
func TestVerifyL2OutputRootDetached(t *testing.T) { func TestVerifyL2OutputRootDetached(t *testing.T) {
testVerifyL2OutputRoot(t, true) testVerifyL2OutputRoot(t, true, false)
}
func TestVerifyL2OutputRootDetachedSpanBatch(t *testing.T) {
testVerifyL2OutputRoot(t, true, true)
} }
func TestVerifyL2OutputRootEmptyBlock(t *testing.T) { func TestVerifyL2OutputRootEmptyBlock(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, false) testVerifyL2OutputRootEmptyBlock(t, false, false)
}
func TestVerifyL2OutputRootEmptyBlockSpanBatch(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, false, true)
} }
func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) { func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, true) testVerifyL2OutputRootEmptyBlock(t, true, false)
}
func TestVerifyL2OutputRootEmptyBlockDetachedSpanBatch(t *testing.T) {
testVerifyL2OutputRootEmptyBlock(t, true, true)
} }
// TestVerifyL2OutputRootEmptyBlock asserts that the program can verify the output root of an empty block // TestVerifyL2OutputRootEmptyBlock asserts that the program can verify the output root of an empty block
...@@ -46,7 +63,7 @@ func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) { ...@@ -46,7 +63,7 @@ func TestVerifyL2OutputRootEmptyBlockDetached(t *testing.T) {
// - reboot the batch submitter // - reboot the batch submitter
// - update the state root via a tx // - update the state root via a tx
// - run program // - run program
func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool, spanBatchActivated bool) {
InitParallel(t) InitParallel(t)
ctx := context.Background() ctx := context.Background()
...@@ -56,6 +73,13 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { ...@@ -56,6 +73,13 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) {
// Use a small sequencer window size to avoid test timeout while waiting for empty blocks // Use a small sequencer window size to avoid test timeout while waiting for empty blocks
// But not too small to ensure that our claim and subsequent state change is published // But not too small to ensure that our claim and subsequent state change is published
cfg.DeployConfig.SequencerWindowSize = 16 cfg.DeployConfig.SequencerWindowSize = 16
if spanBatchActivated {
// Activate span batch hard fork
minTs := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs
} else {
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = nil
}
sys, err := cfg.Start(t) sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system") require.Nil(t, err, "Error starting up system")
...@@ -147,13 +171,20 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) { ...@@ -147,13 +171,20 @@ func testVerifyL2OutputRootEmptyBlock(t *testing.T, detached bool) {
}) })
} }
func testVerifyL2OutputRoot(t *testing.T, detached bool) { func testVerifyL2OutputRoot(t *testing.T, detached bool, spanBatchActivated bool) {
InitParallel(t) InitParallel(t)
ctx := context.Background() ctx := context.Background()
cfg := DefaultSystemConfig(t) cfg := DefaultSystemConfig(t)
// We don't need a verifier - just the sequencer is enough // We don't need a verifier - just the sequencer is enough
delete(cfg.Nodes, "verifier") delete(cfg.Nodes, "verifier")
if spanBatchActivated {
// Activate span batch hard fork
minTs := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = &minTs
} else {
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = nil
}
sys, err := cfg.Start(t) sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system") require.Nil(t, err, "Error starting up system")
......
...@@ -45,6 +45,31 @@ import ( ...@@ -45,6 +45,31 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testlog" "github.com/ethereum-optimism/optimism/op-service/testlog"
) )
// TestSystemBatchType run each system e2e test case in singular batch mode and span batch mode.
// If the test case tests batch submission and advancing safe head, it should be tested in both singular and span batch mode.
func TestSystemBatchType(t *testing.T) {
tests := []struct {
name string
f func(gt *testing.T, spanBatchTimeOffset *hexutil.Uint64)
}{
{"StopStartBatcher", StopStartBatcher},
}
for _, test := range tests {
test := test
t.Run(test.name+"_SingularBatch", func(t *testing.T) {
test.f(t, nil)
})
}
spanBatchTimeOffset := hexutil.Uint64(0)
for _, test := range tests {
test := test
t.Run(test.name+"_SpanBatch", func(t *testing.T) {
test.f(t, &spanBatchTimeOffset)
})
}
}
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
if config.ExternalL2Shim != "" { if config.ExternalL2Shim != "" {
fmt.Println("Running tests with external L2 process adapter at ", config.ExternalL2Shim) fmt.Println("Running tests with external L2 process adapter at ", config.ExternalL2Shim)
...@@ -1222,10 +1247,11 @@ func TestFees(t *testing.T) { ...@@ -1222,10 +1247,11 @@ func TestFees(t *testing.T) {
require.Equal(t, balanceDiff, totalFee, "balances should add up") require.Equal(t, balanceDiff, totalFee, "balances should add up")
} }
func TestStopStartBatcher(t *testing.T) { func StopStartBatcher(t *testing.T, spanBatchTimeOffset *hexutil.Uint64) {
InitParallel(t) InitParallel(t)
cfg := DefaultSystemConfig(t) cfg := DefaultSystemConfig(t)
cfg.DeployConfig.L2GenesisSpanBatchTimeOffset = spanBatchTimeOffset
sys, err := cfg.Start(t) sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system") require.Nil(t, err, "Error starting up system")
defer sys.Close() defer sys.Close()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment