Skip to content

Commit a140d2e

Browse files
author
colinlyguo
committed
add unit tests for UncompressedBatchBytesLimit
1 parent c3eafe5 commit a140d2e

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

rollup/internal/controller/watcher/batch_proposer_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,102 @@ func testBatchProposerMaxChunkNumPerBatchLimitCodecV7(t *testing.T) {
256256

257257
assert.Equal(t, expectedChunkNum, dbBatch.EndChunkIndex)
258258
}
259+
260+
func testBatchProposerUncompressedBatchBytesLimitCodecV8(t *testing.T) {
261+
db := setupDB(t)
262+
defer database.CloseDB(db)
263+
264+
// Add genesis batch
265+
genesisBlock := &encoding.Block{
266+
Header: &gethTypes.Header{
267+
Number: big.NewInt(0),
268+
},
269+
}
270+
genesisChunk := &encoding.Chunk{
271+
Blocks: []*encoding.Block{genesisBlock},
272+
}
273+
chunkOrm := orm.NewChunk(db)
274+
_, err := chunkOrm.InsertChunk(context.Background(), genesisChunk, encoding.CodecV0, utils.ChunkMetrics{})
275+
assert.NoError(t, err)
276+
277+
genesisBatch := &encoding.Batch{
278+
Index: 0,
279+
TotalL1MessagePoppedBefore: 0,
280+
ParentBatchHash: common.Hash{},
281+
Chunks: []*encoding.Chunk{genesisChunk},
282+
}
283+
batchOrm := orm.NewBatch(db)
284+
_, err = batchOrm.InsertBatch(context.Background(), genesisBatch, encoding.CodecV0, utils.BatchMetrics{})
285+
assert.NoError(t, err)
286+
287+
// Create blocks with large calldata
288+
block := readBlockFromJSON(t, "../../../testdata/blockTrace_03.json")
289+
290+
// Create large calldata (3MB per block)
291+
largeCalldata := make([]byte, 3*1024*1024) // 3MB calldata
292+
for i := range largeCalldata {
293+
largeCalldata[i] = byte(i % 256)
294+
}
295+
296+
// Modify the block to have a transaction with large calldata
297+
block.Transactions[0].Data = "0x" + common.Bytes2Hex(largeCalldata)
298+
299+
chainConfig := &params.ChainConfig{
300+
LondonBlock: big.NewInt(0),
301+
BernoulliBlock: big.NewInt(0),
302+
CurieBlock: big.NewInt(0),
303+
DarwinTime: new(uint64),
304+
DarwinV2Time: new(uint64),
305+
EuclidTime: new(uint64),
306+
EuclidV2Time: new(uint64),
307+
FeynmanTime: new(uint64),
308+
}
309+
310+
// Create chunk proposer with no uncompressed batch bytes limit for chunks
311+
cp := NewChunkProposer(context.Background(), &config.ChunkProposerConfig{
312+
MaxBlockNumPerChunk: 1, // One block per chunk
313+
MaxL2GasPerChunk: math.MaxUint64,
314+
ChunkTimeoutSec: math.MaxUint32,
315+
MaxUncompressedBatchBytesSize: math.MaxUint64,
316+
}, encoding.CodecV8, chainConfig, db, nil)
317+
318+
// Insert 2 blocks with large calldata and create 2 chunks
319+
l2BlockOrm := orm.NewL2Block(db)
320+
for i := uint64(1); i <= 2; i++ {
321+
blockCopy := *block
322+
blockCopy.Header = &gethTypes.Header{}
323+
*blockCopy.Header = *block.Header
324+
blockCopy.Header.Number = new(big.Int).SetUint64(i)
325+
blockCopy.Header.Time = i
326+
err := l2BlockOrm.InsertL2Blocks(context.Background(), []*encoding.Block{&blockCopy})
327+
assert.NoError(t, err)
328+
329+
cp.TryProposeChunk() // Each call creates one chunk with one block
330+
}
331+
332+
// Create batch proposer with 4MB uncompressed batch bytes limit
333+
// Each chunk is ~3MB, so 1 chunk (~3MB) should fit, but 2 chunks (~6MB) should exceed limit
334+
bp := NewBatchProposer(context.Background(), &config.BatchProposerConfig{
335+
MaxChunksPerBatch: math.MaxInt32, // No chunk count limit
336+
BatchTimeoutSec: math.MaxUint32, // No timeout limit
337+
MaxUncompressedBatchBytesSize: 4 * 1024 * 1024, // 4MB limit
338+
}, encoding.CodecV8, chainConfig, db, nil)
339+
340+
bp.TryProposeBatch()
341+
342+
// Check that a batch was created
343+
batches, err := batchOrm.GetBatches(context.Background(), map[string]interface{}{}, []string{}, 0)
344+
assert.NoError(t, err)
345+
assert.Len(t, batches, 2) // genesis batch + 1 new batch
346+
347+
// Verify that the batch contains only 1 chunk (not 2) due to uncompressed batch bytes limit
348+
newBatch := batches[1] // Skip genesis batch
349+
assert.Equal(t, uint64(1), newBatch.StartChunkIndex)
350+
assert.Equal(t, uint64(1), newBatch.EndChunkIndex) // Should only include chunk 1
351+
352+
// Verify that the second chunk is still available for next batch
353+
chunks, err := chunkOrm.GetChunksGEIndex(context.Background(), 2, 0)
354+
assert.NoError(t, err)
355+
assert.Len(t, chunks, 1) // Second chunk should still be available
356+
assert.Equal(t, "", chunks[0].BatchHash) // Should not be assigned to any batch yet
357+
}

rollup/internal/controller/watcher/chunk_proposer_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing"
77

88
"github.com/scroll-tech/da-codec/encoding"
9+
"github.com/scroll-tech/go-ethereum/common"
910
"github.com/scroll-tech/go-ethereum/common/math"
1011
gethTypes "github.com/scroll-tech/go-ethereum/core/types"
1112
"github.com/scroll-tech/go-ethereum/params"
@@ -155,3 +156,76 @@ func testChunkProposerBlobSizeLimitCodecV7(t *testing.T) {
155156
assert.Equal(t, expected, chunk.EndBlockNumber)
156157
}
157158
}
159+
160+
func testChunkProposerUncompressedBatchBytesLimitCodecV8(t *testing.T) {
161+
db := setupDB(t)
162+
defer database.CloseDB(db)
163+
164+
// Create a block with very large calldata to test uncompressed batch bytes limit
165+
block := readBlockFromJSON(t, "../../../testdata/blockTrace_03.json")
166+
167+
// Create a transaction with large calldata (around 3MB)
168+
largeCalldata := make([]byte, 3*1024*1024) // 3MB calldata
169+
for i := range largeCalldata {
170+
largeCalldata[i] = byte(i % 256)
171+
}
172+
173+
// Modify the block to have a transaction with large calldata
174+
block.Transactions[0].Data = "0x" + common.Bytes2Hex(largeCalldata)
175+
176+
// Insert two identical blocks with large calldata
177+
l2BlockOrm := orm.NewL2Block(db)
178+
for i := uint64(0); i < 2; i++ {
179+
blockCopy := *block
180+
blockCopy.Header = &gethTypes.Header{}
181+
*blockCopy.Header = *block.Header
182+
blockCopy.Header.Number = new(big.Int).SetUint64(i + 1)
183+
blockCopy.Header.Time = i + 1
184+
err := l2BlockOrm.InsertL2Blocks(context.Background(), []*encoding.Block{&blockCopy})
185+
assert.NoError(t, err)
186+
}
187+
188+
// Add genesis chunk
189+
chunkOrm := orm.NewChunk(db)
190+
_, err := chunkOrm.InsertChunk(context.Background(), &encoding.Chunk{Blocks: []*encoding.Block{{Header: &gethTypes.Header{Number: big.NewInt(0)}}}}, encoding.CodecV0, utils.ChunkMetrics{})
191+
assert.NoError(t, err)
192+
193+
chainConfig := &params.ChainConfig{
194+
LondonBlock: big.NewInt(0),
195+
BernoulliBlock: big.NewInt(0),
196+
CurieBlock: big.NewInt(0),
197+
DarwinTime: new(uint64),
198+
DarwinV2Time: new(uint64),
199+
EuclidTime: new(uint64),
200+
EuclidV2Time: new(uint64),
201+
FeynmanTime: new(uint64),
202+
}
203+
204+
// Set max_uncompressed_batch_bytes_size to 4MB (4 * 1024 * 1024)
205+
// One block (~3MB) should fit, but two blocks (~6MB) should exceed the limit
206+
cp := NewChunkProposer(context.Background(), &config.ChunkProposerConfig{
207+
MaxBlockNumPerChunk: math.MaxUint64, // No block number limit
208+
MaxL2GasPerChunk: math.MaxUint64, // No gas limit
209+
ChunkTimeoutSec: math.MaxUint32, // No timeout limit
210+
MaxUncompressedBatchBytesSize: 4 * 1024 * 1024, // 4MB limit
211+
}, encoding.CodecV8, chainConfig, db, nil)
212+
213+
// Try to propose chunk
214+
cp.TryProposeChunk()
215+
216+
// Check that a chunk was created
217+
chunks, err := chunkOrm.GetChunksGEIndex(context.Background(), 1, 0)
218+
assert.NoError(t, err)
219+
assert.Len(t, chunks, 1)
220+
221+
// Verify that the chunk contains only 1 block (not 2) due to uncompressed batch bytes limit
222+
chunk := chunks[0]
223+
assert.Equal(t, uint64(1), chunk.StartBlockNumber)
224+
assert.Equal(t, uint64(1), chunk.EndBlockNumber)
225+
226+
// Verify that the second block is still available for next chunk
227+
blockOrm := orm.NewL2Block(db)
228+
blocks, err := blockOrm.GetL2BlocksGEHeight(context.Background(), 2, 0)
229+
assert.NoError(t, err)
230+
assert.Len(t, blocks, 1) // Second block should still be available
231+
}

rollup/internal/controller/watcher/watcher_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,13 @@ func TestFunction(t *testing.T) {
103103
// Run chunk proposer test cases.
104104
t.Run("TestChunkProposerLimitsCodecV7", testChunkProposerLimitsCodecV7)
105105
t.Run("TestChunkProposerBlobSizeLimitCodecV7", testChunkProposerBlobSizeLimitCodecV7)
106+
t.Run("TestChunkProposerUncompressedBatchBytesLimitCodecV8", testChunkProposerUncompressedBatchBytesLimitCodecV8)
106107

107108
// Run batch proposer test cases.
108109
t.Run("TestBatchProposerLimitsCodecV7", testBatchProposerLimitsCodecV7)
109110
t.Run("TestBatchProposerBlobSizeLimitCodecV7", testBatchProposerBlobSizeLimitCodecV7)
110111
t.Run("TestBatchProposerMaxChunkNumPerBatchLimitCodecV7", testBatchProposerMaxChunkNumPerBatchLimitCodecV7)
112+
t.Run("TestBatchProposerUncompressedBatchBytesLimitCodecV8", testBatchProposerUncompressedBatchBytesLimitCodecV8)
111113

112114
// Run bundle proposer test cases.
113115
t.Run("TestBundleProposerLimitsCodecV7", testBundleProposerLimitsCodecV7)

0 commit comments

Comments
 (0)