@@ -2,6 +2,7 @@ package tests
22
33import (
44 "context"
5+ "fmt"
56 "math"
67 "math/big"
78 "testing"
@@ -12,6 +13,7 @@ import (
1213 gethTypes "github.com/scroll-tech/go-ethereum/core/types"
1314 "github.com/scroll-tech/go-ethereum/params"
1415 "github.com/stretchr/testify/assert"
16+ "github.com/stretchr/testify/require"
1517
1618 "scroll-tech/common/database"
1719 "scroll-tech/common/types"
@@ -216,3 +218,217 @@ func testCommitBatchAndFinalizeBundleCodecV4(t *testing.T) {
216218 database .CloseDB (db )
217219 }
218220}
221+
222+ func testCommitBatchAndFinalizeBundleCodecV7 (t * testing.T ) {
223+ db := setupDB (t )
224+
225+ prepareContracts (t )
226+
227+ var chainConfig * params.ChainConfig
228+ chainConfig = & params.ChainConfig {
229+ LondonBlock : big .NewInt (0 ),
230+ BernoulliBlock : big .NewInt (0 ),
231+ CurieBlock : big .NewInt (0 ),
232+ DarwinTime : new (uint64 ),
233+ DarwinV2Time : new (uint64 ),
234+ EuclidTime : new (uint64 ),
235+ EuclidV2Time : new (uint64 ),
236+ }
237+
238+ // Create L2Relayer
239+ l2Cfg := rollupApp .Config .L2Config
240+ l2Relayer , err := relayer .NewLayer2Relayer (context .Background (), l2Client , db , l2Cfg .RelayerConfig , chainConfig , true , relayer .ServiceTypeL2RollupRelayer , nil )
241+ require .NoError (t , err )
242+
243+ defer l2Relayer .StopSenders ()
244+ defer database .CloseDB (db )
245+
246+ // add some blocks to db
247+ var blocks []* encoding.Block
248+ genesis , err := l2Client .HeaderByNumber (context .Background (), big .NewInt (0 ))
249+ require .NoError (t , err )
250+
251+ var l1MessageIndex uint64 = 0
252+ parentHash := genesis .Hash ()
253+ for i := int64 (0 ); i < 10 ; i ++ {
254+ header := gethTypes.Header {
255+ Number : big .NewInt (i + 1 ),
256+ ParentHash : parentHash ,
257+ Difficulty : big .NewInt (i + 1 ),
258+ BaseFee : big .NewInt (i + 1 ),
259+ Root : common .HexToHash ("0x1" ),
260+ }
261+ fmt .Println ("block number: " , i + 1 , header .Hash (), parentHash )
262+ var transactions []* gethTypes.TransactionData
263+ if i % 2 == 0 {
264+ txs := []* gethTypes.Transaction {
265+ gethTypes .NewTx (& gethTypes.L1MessageTx {
266+ QueueIndex : l1MessageIndex ,
267+ Gas : 0 ,
268+ To : & common.Address {1 , 2 , 3 },
269+ Value : big .NewInt (10 ),
270+ Data : nil ,
271+ Sender : common.Address {1 , 2 , 3 },
272+ }),
273+ }
274+ transactions = append (transactions , encoding .TxsToTxsData (txs )... )
275+ l1MessageIndex ++
276+ }
277+
278+ blocks = append (blocks , & encoding.Block {
279+ Header : & header ,
280+ Transactions : transactions ,
281+ WithdrawRoot : common .HexToHash ("0x2" ),
282+ RowConsumption : & gethTypes.RowConsumption {},
283+ })
284+ parentHash = header .Hash ()
285+ }
286+
287+ cp := watcher .NewChunkProposer (context .Background (), & config.ChunkProposerConfig {
288+ MaxBlockNumPerChunk : 100 ,
289+ MaxTxNumPerChunk : 10000 ,
290+ MaxL1CommitGasPerChunk : 50000000000 ,
291+ MaxL1CommitCalldataSizePerChunk : 1000000 ,
292+ MaxRowConsumptionPerChunk : 1048319 ,
293+ ChunkTimeoutSec : 300 ,
294+ MaxUncompressedBatchBytesSize : math .MaxUint64 ,
295+ }, encoding .CodecV7 , chainConfig , db , nil )
296+
297+ bap := watcher .NewBatchProposer (context .Background (), & config.BatchProposerConfig {
298+ MaxL1CommitGasPerBatch : 50000000000 ,
299+ MaxL1CommitCalldataSizePerBatch : 1000000 ,
300+ BatchTimeoutSec : 300 ,
301+ MaxUncompressedBatchBytesSize : math .MaxUint64 ,
302+ }, encoding .CodecV7 , chainConfig , db , nil )
303+
304+ bup := watcher .NewBundleProposer (context .Background (), & config.BundleProposerConfig {
305+ MaxBatchNumPerBundle : 1000000 ,
306+ BundleTimeoutSec : 300 ,
307+ }, encoding .CodecV7 , chainConfig , db , nil )
308+
309+ l2BlockOrm := orm .NewL2Block (db )
310+ batchOrm := orm .NewBatch (db )
311+ bundleOrm := orm .NewBundle (db )
312+
313+ fmt .Println ("insert first 5 blocks ------------------------" )
314+ err = l2BlockOrm .InsertL2Blocks (context .Background (), blocks [:5 ])
315+ require .NoError (t , err )
316+ batch1ExpectedLastL1MessageQueueHash , err := encoding .MessageQueueV2ApplyL1MessagesFromBlocks (common.Hash {}, blocks [:5 ])
317+ require .NoError (t , err )
318+
319+ cp .TryProposeChunk ()
320+ bap .TryProposeBatch ()
321+
322+ fmt .Println ("insert last 5 blocks ------------------------" )
323+ err = l2BlockOrm .InsertL2Blocks (context .Background (), blocks [5 :])
324+ require .NoError (t , err )
325+ batch2ExpectedLastL1MessageQueueHash , err := encoding .MessageQueueV2ApplyL1MessagesFromBlocks (batch1ExpectedLastL1MessageQueueHash , blocks [5 :])
326+ require .NoError (t , err )
327+
328+ cp .TryProposeChunk ()
329+ bap .TryProposeBatch ()
330+
331+ bup .TryProposeBundle () // The proposed bundle contains two batches when codec version is codecv3.
332+
333+ // make sure that batches are created as expected
334+ require .Eventually (t , func () bool {
335+ batches , getErr := batchOrm .GetBatches (context .Background (), map [string ]interface {}{}, nil , 0 )
336+ if getErr != nil {
337+ return false
338+ }
339+ if len (batches ) != 3 {
340+ return false
341+ }
342+
343+ // batches[0] is the genesis batch, no need to check
344+
345+ // assert correctness of L1 message queue hashes
346+ require .Equal (t , common.Hash {}, common .HexToHash (batches [1 ].InitialL1MessageQueueHash ))
347+ require .Equal (t , batch1ExpectedLastL1MessageQueueHash , common .HexToHash (batches [1 ].LastL1MessageQueueHash ))
348+ require .Equal (t , batch1ExpectedLastL1MessageQueueHash , common .HexToHash (batches [2 ].InitialL1MessageQueueHash ))
349+ require .Equal (t , batch2ExpectedLastL1MessageQueueHash , common .HexToHash (batches [2 ].LastL1MessageQueueHash ))
350+
351+ return true
352+ }, 30 * time .Second , time .Second )
353+
354+ // simulate proof generation -> all batches and bundle are verified
355+ {
356+ batchProof := & message.BatchProof {
357+ Proof : []byte {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 },
358+ Instances : []byte {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 },
359+ Vk : []byte {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 },
360+ }
361+ batches , err := batchOrm .GetBatches (context .Background (), map [string ]interface {}{}, nil , 0 )
362+ require .NoError (t , err )
363+ batches = batches [1 :]
364+ for _ , batch := range batches {
365+ err = batchOrm .UpdateProofByHash (context .Background (), batch .Hash , batchProof , 100 )
366+ require .NoError (t , err )
367+ err = batchOrm .UpdateProvingStatus (context .Background (), batch .Hash , types .ProvingTaskVerified )
368+ require .NoError (t , err )
369+ }
370+
371+ bundleProof := & message.BundleProof {
372+ Proof : []byte {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 },
373+ Instances : []byte {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 },
374+ Vk : []byte {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 },
375+ }
376+ bundles , err := bundleOrm .GetBundles (context .Background (), map [string ]interface {}{}, nil , 0 )
377+ require .NoError (t , err )
378+ for _ , bundle := range bundles {
379+ err = bundleOrm .UpdateProofAndProvingStatusByHash (context .Background (), bundle .Hash , bundleProof , types .ProvingTaskVerified , 100 )
380+ require .NoError (t , err )
381+ }
382+ }
383+
384+ return
385+ // TODO: assert that batches have been submitted together in a single transaction after contract ABI is updated
386+ //for _, batch := range batches {
387+ // fmt.Println("batch hash: ", batch.Hash, batch.Index, batch.RollupStatus)
388+ // //if types.RollupCommitted != types.RollupStatus(batch.RollupStatus) {
389+ // // return false
390+ // //}
391+ //}
392+ l2Relayer .ProcessPendingBatches ()
393+
394+ assert .Eventually (t , func () bool {
395+ l2Relayer .ProcessPendingBundles ()
396+
397+ batches , err := batchOrm .GetBatches (context .Background (), map [string ]interface {}{}, nil , 0 )
398+ assert .NoError (t , err )
399+ assert .Len (t , batches , 3 )
400+ batches = batches [1 :]
401+ for _ , batch := range batches {
402+ if types .RollupStatus (batch .RollupStatus ) != types .RollupFinalized {
403+ return false
404+ }
405+
406+ assert .NotEmpty (t , batch .FinalizeTxHash )
407+ receipt , getErr := l1Client .TransactionReceipt (context .Background (), common .HexToHash (batch .FinalizeTxHash ))
408+ assert .NoError (t , getErr )
409+ assert .Equal (t , gethTypes .ReceiptStatusSuccessful , receipt .Status )
410+ }
411+
412+ bundles , err := bundleOrm .GetBundles (context .Background (), map [string ]interface {}{}, nil , 0 )
413+ assert .NoError (t , err )
414+ assert .Len (t , bundles , 1 )
415+
416+ bundle := bundles [0 ]
417+ if types .RollupStatus (bundle .RollupStatus ) != types .RollupFinalized {
418+ return false
419+ }
420+ assert .NotEmpty (t , bundle .FinalizeTxHash )
421+ receipt , err := l1Client .TransactionReceipt (context .Background (), common .HexToHash (bundle .FinalizeTxHash ))
422+ assert .NoError (t , err )
423+ assert .Equal (t , gethTypes .ReceiptStatusSuccessful , receipt .Status )
424+ batches , err = batchOrm .GetBatches (context .Background (), map [string ]interface {}{"bundle_hash" : bundle .Hash }, nil , 0 )
425+ assert .NoError (t , err )
426+ assert .Len (t , batches , 2 )
427+ for _ , batch := range batches {
428+ assert .Equal (t , batch .RollupStatus , bundle .RollupStatus )
429+ assert .Equal (t , bundle .FinalizeTxHash , batch .FinalizeTxHash )
430+ }
431+
432+ return true
433+ }, 30 * time .Second , time .Second )
434+ }
0 commit comments