@@ -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+ }
0 commit comments