diff --git a/go.work.sum b/go.work.sum index 0bba0159e..140f64cd5 100644 --- a/go.work.sum +++ b/go.work.sum @@ -349,6 +349,8 @@ github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqn github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= +github.com/scroll-tech/da-codec v0.0.0-20240503072316-7a132fb88e47 h1:zPu1ain834p7+cFHPjHJIrcKs3VtCdFT6z3UEHdCM8o= +github.com/scroll-tech/da-codec v0.0.0-20240503072316-7a132fb88e47/go.mod h1:1wWYii0OPwd5kw+xrz0PFgS420xNadrNF1x/ELJT+TM= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= diff --git a/rollup/Makefile b/rollup/Makefile index 1fd37825d..ad1aeeb97 100644 --- a/rollup/Makefile +++ b/rollup/Makefile @@ -24,7 +24,7 @@ rollup_relayer: ## Builds the rollup_relayer bin test: go test -v -race -coverprofile=coverage.txt -covermode=atomic -p 1 $(PWD)/... -lint: mock_abi ## Lint the files - used for CI +lint: ## Lint the files - used for CI GOBIN=$(PWD)/build/bin go run ../build/lint.go clean: ## Empty out the bin folder diff --git a/rollup/go.mod b/rollup/go.mod index 5396064db..c43892dd8 100644 --- a/rollup/go.mod +++ b/rollup/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-resty/resty/v2 v2.7.0 github.com/holiman/uint256 v1.2.4 github.com/prometheus/client_golang v1.16.0 - github.com/scroll-tech/da-codec v0.0.0-20240429155648-9ac5267b55bd + github.com/scroll-tech/da-codec v0.0.0-20240503072316-7a132fb88e47 github.com/scroll-tech/go-ethereum v1.10.14-0.20240426041101-a860446ebaea github.com/smartystreets/goconvey v1.8.0 github.com/stretchr/testify v1.9.0 diff --git a/rollup/go.sum b/rollup/go.sum index d1e6390de..4d4115a95 100644 --- a/rollup/go.sum +++ b/rollup/go.sum @@ -236,8 +236,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/scroll-tech/da-codec v0.0.0-20240429155648-9ac5267b55bd h1:4lVhyymqeBaJ/iT9KYVoY9TOn9sr+FBqN9vZOVPGG4g= -github.com/scroll-tech/da-codec v0.0.0-20240429155648-9ac5267b55bd/go.mod h1:1wWYii0OPwd5kw+xrz0PFgS420xNadrNF1x/ELJT+TM= +github.com/scroll-tech/da-codec v0.0.0-20240503072316-7a132fb88e47 h1:zPu1ain834p7+cFHPjHJIrcKs3VtCdFT6z3UEHdCM8o= +github.com/scroll-tech/da-codec v0.0.0-20240503072316-7a132fb88e47/go.mod h1:1wWYii0OPwd5kw+xrz0PFgS420xNadrNF1x/ELJT+TM= github.com/scroll-tech/go-ethereum v1.10.14-0.20240426041101-a860446ebaea h1:CH1WXWrpEpLaP3N+bFs2a1xdE0+lRm1AuJQb5YvE6Ls= github.com/scroll-tech/go-ethereum v1.10.14-0.20240426041101-a860446ebaea/go.mod h1:i4VBgWoaW/y0D8MmQb7hSOulyw1dKhuiSFAbznwivCA= github.com/scroll-tech/zktrie v0.8.2 h1:UMuIfA+jdgWMLmTgTL64Emo+zzMOdcnH0+eYdDcshxQ= diff --git a/rollup/internal/controller/relayer/l2_relayer.go b/rollup/internal/controller/relayer/l2_relayer.go index 11988b532..6781aba00 100644 --- a/rollup/internal/controller/relayer/l2_relayer.go +++ b/rollup/internal/controller/relayer/l2_relayer.go @@ -12,6 +12,7 @@ import ( "github.com/scroll-tech/da-codec/encoding" "github.com/scroll-tech/da-codec/encoding/codecv0" "github.com/scroll-tech/da-codec/encoding/codecv1" + "github.com/scroll-tech/da-codec/encoding/codecv2" "github.com/scroll-tech/go-ethereum/accounts/abi" "github.com/scroll-tech/go-ethereum/common" gethTypes "github.com/scroll-tech/go-ethereum/core/types" @@ -196,7 +197,7 @@ func (r *Layer2Relayer) initializeGenesis() error { err = r.db.Transaction(func(dbTX *gorm.DB) error { var dbChunk *orm.Chunk - dbChunk, err = r.chunkOrm.InsertChunk(r.ctx, chunk, encoding.CodecV0, false /* no compression */, dbTX) + dbChunk, err = r.chunkOrm.InsertChunk(r.ctx, chunk, encoding.CodecV0, dbTX) if err != nil { return fmt.Errorf("failed to insert chunk: %v", err) } @@ -213,7 +214,7 @@ func (r *Layer2Relayer) initializeGenesis() error { } var dbBatch *orm.Batch - dbBatch, err = r.batchOrm.InsertBatch(r.ctx, batch, encoding.CodecV0, false /* no compression */, dbTX) + dbBatch, err = r.batchOrm.InsertBatch(r.ctx, batch, encoding.CodecV0, dbTX) if err != nil { return fmt.Errorf("failed to insert batch: %v", err) } @@ -380,19 +381,18 @@ func (r *Layer2Relayer) ProcessPendingBatches() { log.Error("failed to construct commitBatch payload codecv0", "index", dbBatch.Index, "err", err) return } - } else { // codecv1 - var useCompression bool - if r.chainCfg.IsCurie(new(big.Int).SetUint64(dbChunks[0].StartBlockNumber)) { - useCompression = true - } else { - useCompression = false - } - - calldata, blob, err = r.constructCommitBatchPayloadCodecV1(dbBatch, dbParentBatch, dbChunks, chunks, useCompression) + } else if !r.chainCfg.IsCurie(new(big.Int).SetUint64(dbChunks[0].StartBlockNumber)) { // codecv1 + calldata, blob, err = r.constructCommitBatchPayloadCodecV1(dbBatch, dbParentBatch, dbChunks, chunks) if err != nil { log.Error("failed to construct commitBatch payload codecv1", "index", dbBatch.Index, "err", err) return } + } else { + calldata, blob, err = r.constructCommitBatchPayloadCodecV2(dbBatch, dbParentBatch, dbChunks, chunks) + if err != nil { + log.Error("failed to construct commitBatch payload codecv2", "index", dbBatch.Index, "err", err) + return + } } // fallbackGasLimit is non-zero only in sending non-blob transactions. @@ -547,7 +547,7 @@ func (r *Layer2Relayer) finalizeBatch(dbBatch *orm.Batch, withProof bool) error if err != nil { return fmt.Errorf("failed to construct commitBatch payload codecv0, index: %v, err: %w", dbBatch.Index, err) } - } else { // codecv1 + } else if !r.chainCfg.IsCurie(new(big.Int).SetUint64(dbChunks[0].StartBlockNumber)) { // codecv2 chunks := make([]*encoding.Chunk, len(dbChunks)) for i, c := range dbChunks { blocks, dbErr := r.l2BlockOrm.GetL2BlocksInRange(r.ctx, c.StartBlockNumber, c.EndBlockNumber) @@ -557,14 +557,21 @@ func (r *Layer2Relayer) finalizeBatch(dbBatch *orm.Batch, withProof bool) error chunks[i] = &encoding.Chunk{Blocks: blocks} } - var useCompression bool - if r.chainCfg.IsCurie(new(big.Int).SetUint64(dbChunks[0].StartBlockNumber)) { - useCompression = true - } else { - useCompression = false + calldata, err = r.constructFinalizeBatchPayloadCodecV1(dbBatch, dbParentBatch, dbChunks, chunks, aggProof) + if err != nil { + return fmt.Errorf("failed to construct commitBatch payload codecv1, index: %v, err: %w", dbBatch.Index, err) + } + } else { + chunks := make([]*encoding.Chunk, len(dbChunks)) + for i, c := range dbChunks { + blocks, dbErr := r.l2BlockOrm.GetL2BlocksInRange(r.ctx, c.StartBlockNumber, c.EndBlockNumber) + if dbErr != nil { + return fmt.Errorf("failed to fetch blocks: %w", dbErr) + } + chunks[i] = &encoding.Chunk{Blocks: blocks} } - calldata, err = r.constructFinalizeBatchPayloadCodecV1(dbBatch, dbParentBatch, dbChunks, chunks, aggProof, useCompression) + calldata, err = r.constructFinalizeBatchPayloadCodecV2(dbBatch, dbParentBatch, dbChunks, chunks, aggProof) if err != nil { return fmt.Errorf("failed to construct commitBatch payload codecv1, index: %v, err: %w", dbBatch.Index, err) } @@ -772,7 +779,7 @@ func (r *Layer2Relayer) constructCommitBatchPayloadCodecV0(dbBatch *orm.Batch, d return calldata, nil } -func (r *Layer2Relayer) constructCommitBatchPayloadCodecV1(dbBatch *orm.Batch, dbParentBatch *orm.Batch, dbChunks []*orm.Chunk, chunks []*encoding.Chunk, useCompression bool) ([]byte, *kzg4844.Blob, error) { +func (r *Layer2Relayer) constructCommitBatchPayloadCodecV1(dbBatch *orm.Batch, dbParentBatch *orm.Batch, dbChunks []*orm.Chunk, chunks []*encoding.Chunk) ([]byte, *kzg4844.Blob, error) { batch := &encoding.Batch{ Index: dbBatch.Index, TotalL1MessagePoppedBefore: dbChunks[0].TotalL1MessagesPoppedBefore, @@ -780,7 +787,7 @@ func (r *Layer2Relayer) constructCommitBatchPayloadCodecV1(dbBatch *orm.Batch, d Chunks: chunks, } - daBatch, createErr := codecv1.NewDABatch(batch, useCompression) + daBatch, createErr := codecv1.NewDABatch(batch) if createErr != nil { return nil, nil, fmt.Errorf("failed to create DA batch: %w", createErr) } @@ -801,6 +808,35 @@ func (r *Layer2Relayer) constructCommitBatchPayloadCodecV1(dbBatch *orm.Batch, d return calldata, daBatch.Blob(), nil } +func (r *Layer2Relayer) constructCommitBatchPayloadCodecV2(dbBatch *orm.Batch, dbParentBatch *orm.Batch, dbChunks []*orm.Chunk, chunks []*encoding.Chunk) ([]byte, *kzg4844.Blob, error) { + batch := &encoding.Batch{ + Index: dbBatch.Index, + TotalL1MessagePoppedBefore: dbChunks[0].TotalL1MessagesPoppedBefore, + ParentBatchHash: common.HexToHash(dbParentBatch.Hash), + Chunks: chunks, + } + + daBatch, createErr := codecv2.NewDABatch(batch) + if createErr != nil { + return nil, nil, fmt.Errorf("failed to create DA batch: %w", createErr) + } + + encodedChunks := make([][]byte, len(dbChunks)) + for i, c := range dbChunks { + daChunk, createErr := codecv2.NewDAChunk(chunks[i], c.TotalL1MessagesPoppedBefore) + if createErr != nil { + return nil, nil, fmt.Errorf("failed to create DA chunk: %w", createErr) + } + encodedChunks[i] = daChunk.Encode() + } + + calldata, packErr := r.l1RollupABI.Pack("commitBatch", daBatch.Version, dbParentBatch.BatchHeader, encodedChunks, daBatch.SkippedL1MessageBitmap) + if packErr != nil { + return nil, nil, fmt.Errorf("failed to pack commitBatch: %w", packErr) + } + return calldata, daBatch.Blob(), nil +} + func (r *Layer2Relayer) constructFinalizeBatchPayloadCodecV0(dbBatch *orm.Batch, dbParentBatch *orm.Batch, aggProof *message.BatchProof) ([]byte, error) { if aggProof != nil { // finalizeBatch with proof. calldata, packErr := r.l1RollupABI.Pack( @@ -831,7 +867,7 @@ func (r *Layer2Relayer) constructFinalizeBatchPayloadCodecV0(dbBatch *orm.Batch, return calldata, nil } -func (r *Layer2Relayer) constructFinalizeBatchPayloadCodecV1(dbBatch *orm.Batch, dbParentBatch *orm.Batch, dbChunks []*orm.Chunk, chunks []*encoding.Chunk, aggProof *message.BatchProof, useCompression bool) ([]byte, error) { +func (r *Layer2Relayer) constructFinalizeBatchPayloadCodecV1(dbBatch *orm.Batch, dbParentBatch *orm.Batch, dbChunks []*orm.Chunk, chunks []*encoding.Chunk, aggProof *message.BatchProof) ([]byte, error) { batch := &encoding.Batch{ Index: dbBatch.Index, TotalL1MessagePoppedBefore: dbChunks[0].TotalL1MessagesPoppedBefore, @@ -839,7 +875,56 @@ func (r *Layer2Relayer) constructFinalizeBatchPayloadCodecV1(dbBatch *orm.Batch, Chunks: chunks, } - daBatch, createErr := codecv1.NewDABatch(batch, useCompression) + daBatch, createErr := codecv1.NewDABatch(batch) + if createErr != nil { + return nil, fmt.Errorf("failed to create DA batch: %w", createErr) + } + + blobDataProof, getErr := daBatch.BlobDataProof() + if getErr != nil { + return nil, fmt.Errorf("failed to get blob data proof: %w", getErr) + } + + if aggProof != nil { // finalizeBatch4844 with proof. + calldata, packErr := r.l1RollupABI.Pack( + "finalizeBatchWithProof4844", + dbBatch.BatchHeader, + common.HexToHash(dbParentBatch.StateRoot), + common.HexToHash(dbBatch.StateRoot), + common.HexToHash(dbBatch.WithdrawRoot), + blobDataProof, + aggProof.Proof, + ) + if packErr != nil { + return nil, fmt.Errorf("failed to pack finalizeBatchWithProof4844: %w", packErr) + } + return calldata, nil + } + + // finalizeBatch4844 without proof. + calldata, packErr := r.l1RollupABI.Pack( + "finalizeBatch4844", + dbBatch.BatchHeader, + common.HexToHash(dbParentBatch.StateRoot), + common.HexToHash(dbBatch.StateRoot), + common.HexToHash(dbBatch.WithdrawRoot), + blobDataProof, + ) + if packErr != nil { + return nil, fmt.Errorf("failed to pack finalizeBatch4844: %w", packErr) + } + return calldata, nil +} + +func (r *Layer2Relayer) constructFinalizeBatchPayloadCodecV2(dbBatch *orm.Batch, dbParentBatch *orm.Batch, dbChunks []*orm.Chunk, chunks []*encoding.Chunk, aggProof *message.BatchProof) ([]byte, error) { + batch := &encoding.Batch{ + Index: dbBatch.Index, + TotalL1MessagePoppedBefore: dbChunks[0].TotalL1MessagesPoppedBefore, + ParentBatchHash: common.HexToHash(dbParentBatch.Hash), + Chunks: chunks, + } + + daBatch, createErr := codecv2.NewDABatch(batch) if createErr != nil { return nil, fmt.Errorf("failed to create DA batch: %w", createErr) } diff --git a/rollup/internal/controller/relayer/l2_relayer_test.go b/rollup/internal/controller/relayer/l2_relayer_test.go index 78441f7a4..ad849a8bd 100644 --- a/rollup/internal/controller/relayer/l2_relayer_test.go +++ b/rollup/internal/controller/relayer/l2_relayer_test.go @@ -72,9 +72,9 @@ func testL2RelayerProcessPendingBatches(t *testing.T) { err = l2BlockOrm.InsertL2Blocks(context.Background(), []*encoding.Block{block1, block2}) assert.NoError(t, err) chunkOrm := orm.NewChunk(db) - _, err = chunkOrm.InsertChunk(context.Background(), chunk1, codecVersion, false) + _, err = chunkOrm.InsertChunk(context.Background(), chunk1, codecVersion) assert.NoError(t, err) - _, err = chunkOrm.InsertChunk(context.Background(), chunk2, codecVersion, false) + _, err = chunkOrm.InsertChunk(context.Background(), chunk2, codecVersion) assert.NoError(t, err) batch := &encoding.Batch{ @@ -85,7 +85,7 @@ func testL2RelayerProcessPendingBatches(t *testing.T) { } batchOrm := orm.NewBatch(db) - dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion, false) + dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion) assert.NoError(t, err) relayer.ProcessPendingBatches() @@ -117,9 +117,9 @@ func testL2RelayerProcessCommittedBatches(t *testing.T) { err = l2BlockOrm.InsertL2Blocks(context.Background(), []*encoding.Block{block1, block2}) assert.NoError(t, err) chunkOrm := orm.NewChunk(db) - _, err = chunkOrm.InsertChunk(context.Background(), chunk1, codecVersion, false) + _, err = chunkOrm.InsertChunk(context.Background(), chunk1, codecVersion) assert.NoError(t, err) - _, err = chunkOrm.InsertChunk(context.Background(), chunk2, codecVersion, false) + _, err = chunkOrm.InsertChunk(context.Background(), chunk2, codecVersion) assert.NoError(t, err) batch := &encoding.Batch{ @@ -130,7 +130,7 @@ func testL2RelayerProcessCommittedBatches(t *testing.T) { } batchOrm := orm.NewBatch(db) - dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion, false) + dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion) assert.NoError(t, err) err = batchOrm.UpdateRollupStatus(context.Background(), dbBatch.Hash, types.RollupCommitted) @@ -182,9 +182,9 @@ func testL2RelayerFinalizeTimeoutBatches(t *testing.T) { err = l2BlockOrm.InsertL2Blocks(context.Background(), []*encoding.Block{block1, block2}) assert.NoError(t, err) chunkOrm := orm.NewChunk(db) - chunkDB1, err := chunkOrm.InsertChunk(context.Background(), chunk1, codecVersion, false) + chunkDB1, err := chunkOrm.InsertChunk(context.Background(), chunk1, codecVersion) assert.NoError(t, err) - chunkDB2, err := chunkOrm.InsertChunk(context.Background(), chunk2, codecVersion, false) + chunkDB2, err := chunkOrm.InsertChunk(context.Background(), chunk2, codecVersion) assert.NoError(t, err) batch := &encoding.Batch{ @@ -195,7 +195,7 @@ func testL2RelayerFinalizeTimeoutBatches(t *testing.T) { } batchOrm := orm.NewBatch(db) - dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion, false) + dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion) assert.NoError(t, err) err = batchOrm.UpdateRollupStatus(context.Background(), dbBatch.Hash, types.RollupCommitted) @@ -255,7 +255,7 @@ func testL2RelayerCommitConfirm(t *testing.T) { Chunks: []*encoding.Chunk{chunk1, chunk2}, } - dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0, false) + dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0) assert.NoError(t, err) batchHashes[i] = dbBatch.Hash } @@ -311,7 +311,7 @@ func testL2RelayerFinalizeConfirm(t *testing.T) { Chunks: []*encoding.Chunk{chunk1, chunk2}, } - dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0, false) + dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0) assert.NoError(t, err) batchHashes[i] = dbBatch.Hash } @@ -355,7 +355,7 @@ func testL2RelayerGasOracleConfirm(t *testing.T) { } batchOrm := orm.NewBatch(db) - dbBatch1, err := batchOrm.InsertBatch(context.Background(), batch1, encoding.CodecV0, false) + dbBatch1, err := batchOrm.InsertBatch(context.Background(), batch1, encoding.CodecV0) assert.NoError(t, err) batch2 := &encoding.Batch{ @@ -365,7 +365,7 @@ func testL2RelayerGasOracleConfirm(t *testing.T) { Chunks: []*encoding.Chunk{chunk2}, } - dbBatch2, err := batchOrm.InsertBatch(context.Background(), batch2, encoding.CodecV0, false) + dbBatch2, err := batchOrm.InsertBatch(context.Background(), batch2, encoding.CodecV0) assert.NoError(t, err) // Create and set up the Layer2 Relayer. @@ -517,9 +517,9 @@ func testGetBatchStatusByIndex(t *testing.T) { err = l2BlockOrm.InsertL2Blocks(context.Background(), []*encoding.Block{block1, block2}) assert.NoError(t, err) chunkOrm := orm.NewChunk(db) - _, err = chunkOrm.InsertChunk(context.Background(), chunk1, encoding.CodecV0, false) + _, err = chunkOrm.InsertChunk(context.Background(), chunk1, encoding.CodecV0) assert.NoError(t, err) - _, err = chunkOrm.InsertChunk(context.Background(), chunk2, encoding.CodecV0, false) + _, err = chunkOrm.InsertChunk(context.Background(), chunk2, encoding.CodecV0) assert.NoError(t, err) batch := &encoding.Batch{ @@ -530,7 +530,7 @@ func testGetBatchStatusByIndex(t *testing.T) { } batchOrm := orm.NewBatch(db) - dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0, false) + dbBatch, err := batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0) assert.NoError(t, err) status, err := relayer.getBatchStatusByIndex(dbBatch) diff --git a/rollup/internal/controller/watcher/batch_proposer.go b/rollup/internal/controller/watcher/batch_proposer.go index 26cdf58f5..4324e2888 100644 --- a/rollup/internal/controller/watcher/batch_proposer.go +++ b/rollup/internal/controller/watcher/batch_proposer.go @@ -128,9 +128,9 @@ func (p *BatchProposer) TryProposeBatch() { } } -func (p *BatchProposer) updateDBBatchInfo(batch *encoding.Batch, codecVersion encoding.CodecVersion, useCompression bool) error { +func (p *BatchProposer) updateDBBatchInfo(batch *encoding.Batch, codecVersion encoding.CodecVersion) error { err := p.db.Transaction(func(dbTX *gorm.DB) error { - dbBatch, dbErr := p.batchOrm.InsertBatch(p.ctx, batch, codecVersion, useCompression, dbTX) + dbBatch, dbErr := p.batchOrm.InsertBatch(p.ctx, batch, codecVersion, dbTX) if dbErr != nil { log.Warn("BatchProposer.updateBatchInfoInDB insert batch failure", "index", batch.Index, "parent hash", batch.ParentBatchHash.Hex(), "error", dbErr) return dbErr @@ -162,20 +162,16 @@ func (p *BatchProposer) proposeBatch() error { startBlockNum := new(big.Int).SetUint64(firstUnbatchedChunk.StartBlockNumber) var codecVersion encoding.CodecVersion - if p.chainCfg.IsBernoulli(startBlockNum) { - codecVersion = encoding.CodecV1 - } else { - codecVersion = encoding.CodecV0 - } - - var useCompression bool var maxChunksThisBatch uint64 - if codecVersion == encoding.CodecV1 && p.chainCfg.IsCurie(startBlockNum) { - useCompression = true - maxChunksThisBatch = 45 - } else { - useCompression = false + if !p.chainCfg.IsBernoulli(startBlockNum) { + codecVersion = encoding.CodecV0 maxChunksThisBatch = 15 + } else if !p.chainCfg.IsCurie(startBlockNum) { + codecVersion = encoding.CodecV1 + maxChunksThisBatch = 15 + } else { + codecVersion = encoding.CodecV2 + maxChunksThisBatch = 45 } // select at most maxChunkNumPerBatch chunks @@ -216,7 +212,7 @@ func (p *BatchProposer) proposeBatch() error { for i, chunk := range daChunks { batch.Chunks = append(batch.Chunks, chunk) - metrics, calcErr := utils.CalculateBatchMetrics(&batch, codecVersion, useCompression) + metrics, calcErr := utils.CalculateBatchMetrics(&batch, codecVersion) if calcErr != nil { return fmt.Errorf("failed to calculate batch metrics: %w", calcErr) } @@ -241,17 +237,17 @@ func (p *BatchProposer) proposeBatch() error { batch.Chunks = batch.Chunks[:len(batch.Chunks)-1] - metrics, err := utils.CalculateBatchMetrics(&batch, codecVersion, useCompression) + metrics, err := utils.CalculateBatchMetrics(&batch, codecVersion) if err != nil { return fmt.Errorf("failed to calculate batch metrics: %w", err) } p.recordBatchMetrics(metrics) - return p.updateDBBatchInfo(&batch, codecVersion, useCompression) + return p.updateDBBatchInfo(&batch, codecVersion) } } - metrics, calcErr := utils.CalculateBatchMetrics(&batch, codecVersion, useCompression) + metrics, calcErr := utils.CalculateBatchMetrics(&batch, codecVersion) if calcErr != nil { return fmt.Errorf("failed to calculate batch metrics: %w", calcErr) } @@ -265,7 +261,7 @@ func (p *BatchProposer) proposeBatch() error { p.batchFirstBlockTimeoutReached.Inc() p.recordBatchMetrics(metrics) - return p.updateDBBatchInfo(&batch, codecVersion, useCompression) + return p.updateDBBatchInfo(&batch, codecVersion) } log.Debug("pending chunks do not reach one of the constraints or contain a timeout block") diff --git a/rollup/internal/controller/watcher/batch_proposer_test.go b/rollup/internal/controller/watcher/batch_proposer_test.go index 682dd3c23..1766ccedc 100644 --- a/rollup/internal/controller/watcher/batch_proposer_test.go +++ b/rollup/internal/controller/watcher/batch_proposer_test.go @@ -109,7 +109,7 @@ func testBatchProposerCodecv0Limits(t *testing.T) { Blocks: []*encoding.Block{block}, } chunkOrm := orm.NewChunk(db) - _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV0, false) + _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV0) assert.NoError(t, err) batch := &encoding.Batch{ Index: 0, @@ -118,7 +118,7 @@ func testBatchProposerCodecv0Limits(t *testing.T) { Chunks: []*encoding.Chunk{chunk}, } batchOrm := orm.NewBatch(db) - _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0, false) + _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0) assert.NoError(t, err) l2BlockOrm := orm.NewL2Block(db) @@ -227,7 +227,7 @@ func testBatchProposerCodecv1Limits(t *testing.T) { Blocks: []*encoding.Block{block}, } chunkOrm := orm.NewChunk(db) - _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV1, false) + _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV1) assert.NoError(t, err) batch := &encoding.Batch{ Index: 0, @@ -236,7 +236,7 @@ func testBatchProposerCodecv1Limits(t *testing.T) { Chunks: []*encoding.Chunk{chunk}, } batchOrm := orm.NewBatch(db) - _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV1, false) + _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV1) assert.NoError(t, err) l2BlockOrm := orm.NewL2Block(db) @@ -311,7 +311,7 @@ func testBatchCommitGasAndCalldataSizeEstimation(t *testing.T) { Blocks: []*encoding.Block{block}, } chunkOrm := orm.NewChunk(db) - _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV0, false) + _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV0) assert.NoError(t, err) batch := &encoding.Batch{ Index: 0, @@ -320,7 +320,7 @@ func testBatchCommitGasAndCalldataSizeEstimation(t *testing.T) { Chunks: []*encoding.Chunk{chunk}, } batchOrm := orm.NewBatch(db) - _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0, false) + _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0) assert.NoError(t, err) l2BlockOrm := orm.NewL2Block(db) @@ -391,7 +391,7 @@ func testBatchProposerBlobSizeLimit(t *testing.T) { Blocks: []*encoding.Block{block}, } chunkOrm := orm.NewChunk(db) - _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV0, false) + _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV0) assert.NoError(t, err) batch := &encoding.Batch{ Index: 0, @@ -400,7 +400,7 @@ func testBatchProposerBlobSizeLimit(t *testing.T) { Chunks: []*encoding.Chunk{chunk}, } batchOrm := orm.NewBatch(db) - _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0, false) + _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0) assert.NoError(t, err) var chainConfig *params.ChainConfig @@ -482,7 +482,7 @@ func testBatchProposerMaxChunkNumPerBatchLimit(t *testing.T) { Blocks: []*encoding.Block{block}, } chunkOrm := orm.NewChunk(db) - _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV0, false) + _, err := chunkOrm.InsertChunk(context.Background(), chunk, encoding.CodecV0) assert.NoError(t, err) batch := &encoding.Batch{ Index: 0, @@ -491,7 +491,7 @@ func testBatchProposerMaxChunkNumPerBatchLimit(t *testing.T) { Chunks: []*encoding.Chunk{chunk}, } batchOrm := orm.NewBatch(db) - _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0, false) + _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0) assert.NoError(t, err) var chainConfig *params.ChainConfig diff --git a/rollup/internal/controller/watcher/chunk_proposer.go b/rollup/internal/controller/watcher/chunk_proposer.go index ce6b96376..3e28f3039 100644 --- a/rollup/internal/controller/watcher/chunk_proposer.go +++ b/rollup/internal/controller/watcher/chunk_proposer.go @@ -144,14 +144,14 @@ func (p *ChunkProposer) TryProposeChunk() { } } -func (p *ChunkProposer) updateDBChunkInfo(chunk *encoding.Chunk, codecVersion encoding.CodecVersion, useCompression bool) error { +func (p *ChunkProposer) updateDBChunkInfo(chunk *encoding.Chunk, codecVersion encoding.CodecVersion) error { if chunk == nil { return nil } p.proposeChunkUpdateInfoTotal.Inc() err := p.db.Transaction(func(dbTX *gorm.DB) error { - dbChunk, err := p.chunkOrm.InsertChunk(p.ctx, chunk, codecVersion, useCompression, dbTX) + dbChunk, err := p.chunkOrm.InsertChunk(p.ctx, chunk, codecVersion, dbTX) if err != nil { log.Warn("ChunkProposer.InsertChunk failed", "err", err) return err @@ -193,24 +193,19 @@ func (p *ChunkProposer) proposeChunk() error { } var codecVersion encoding.CodecVersion - if p.chainCfg.IsBernoulli(blocks[0].Header.Number) { + if !p.chainCfg.IsBernoulli(blocks[0].Header.Number) { + codecVersion = encoding.CodecV0 + } else if !p.chainCfg.IsCurie(blocks[0].Header.Number) { codecVersion = encoding.CodecV1 } else { - codecVersion = encoding.CodecV0 - } - - var useCompression bool - if codecVersion == encoding.CodecV1 && p.chainCfg.IsCurie(blocks[0].Header.Number) { - useCompression = true - } else { - useCompression = false + codecVersion = encoding.CodecV2 } var chunk encoding.Chunk for i, block := range blocks { chunk.Blocks = append(chunk.Blocks, block) - metrics, calcErr := utils.CalculateChunkMetrics(&chunk, codecVersion, useCompression) + metrics, calcErr := utils.CalculateChunkMetrics(&chunk, codecVersion) if calcErr != nil { return fmt.Errorf("failed to calculate chunk metrics: %w", calcErr) } @@ -242,17 +237,17 @@ func (p *ChunkProposer) proposeChunk() error { chunk.Blocks = chunk.Blocks[:len(chunk.Blocks)-1] - metrics, calcErr := utils.CalculateChunkMetrics(&chunk, codecVersion, useCompression) + metrics, calcErr := utils.CalculateChunkMetrics(&chunk, codecVersion) if calcErr != nil { return fmt.Errorf("failed to calculate chunk metrics: %w", calcErr) } p.recordChunkMetrics(metrics) - return p.updateDBChunkInfo(&chunk, codecVersion, useCompression) + return p.updateDBChunkInfo(&chunk, codecVersion) } } - metrics, calcErr := utils.CalculateChunkMetrics(&chunk, codecVersion, useCompression) + metrics, calcErr := utils.CalculateChunkMetrics(&chunk, codecVersion) if calcErr != nil { return fmt.Errorf("failed to calculate chunk metrics: %w", calcErr) } @@ -268,7 +263,7 @@ func (p *ChunkProposer) proposeChunk() error { p.chunkFirstBlockTimeoutReached.Inc() p.recordChunkMetrics(metrics) - return p.updateDBChunkInfo(&chunk, codecVersion, useCompression) + return p.updateDBChunkInfo(&chunk, codecVersion) } log.Debug("pending blocks do not reach one of the constraints or contain a timeout block") diff --git a/rollup/internal/orm/batch.go b/rollup/internal/orm/batch.go index 883fdaa32..c1328a1c5 100644 --- a/rollup/internal/orm/batch.go +++ b/rollup/internal/orm/batch.go @@ -224,7 +224,7 @@ func (o *Batch) GetBatchByIndex(ctx context.Context, index uint64) (*Batch, erro } // InsertBatch inserts a new batch into the database. -func (o *Batch) InsertBatch(ctx context.Context, batch *encoding.Batch, codecVersion encoding.CodecVersion, useCompression bool, dbTX ...*gorm.DB) (*Batch, error) { +func (o *Batch) InsertBatch(ctx context.Context, batch *encoding.Batch, codecVersion encoding.CodecVersion, dbTX ...*gorm.DB) (*Batch, error) { if batch == nil { return nil, errors.New("invalid args: batch is nil") } @@ -234,7 +234,7 @@ func (o *Batch) InsertBatch(ctx context.Context, batch *encoding.Batch, codecVer return nil, errors.New("invalid args: batch contains 0 chunk") } - metrics, err := rutils.CalculateBatchMetrics(batch, codecVersion, useCompression) + metrics, err := rutils.CalculateBatchMetrics(batch, codecVersion) if err != nil { log.Error("failed to calculate batch metrics", "index", batch.Index, "total l1 message popped before", batch.TotalL1MessagePoppedBefore, @@ -252,7 +252,7 @@ func (o *Batch) InsertBatch(ctx context.Context, batch *encoding.Batch, codecVer startChunkIndex = parentBatch.EndChunkIndex + 1 } - batchMeta, err := rutils.GetBatchMetadata(batch, codecVersion, useCompression) + batchMeta, err := rutils.GetBatchMetadata(batch, codecVersion) if err != nil { log.Error("failed to get batch metadata", "index", batch.Index, "total l1 message popped before", batch.TotalL1MessagePoppedBefore, "parent hash", batch.ParentBatchHash, "number of chunks", numChunks, "err", err) diff --git a/rollup/internal/orm/chunk.go b/rollup/internal/orm/chunk.go index f7c390d64..7909a8b0a 100644 --- a/rollup/internal/orm/chunk.go +++ b/rollup/internal/orm/chunk.go @@ -175,7 +175,7 @@ func (o *Chunk) GetChunksByBatchHash(ctx context.Context, batchHash string) ([]* } // InsertChunk inserts a new chunk into the database. -func (o *Chunk) InsertChunk(ctx context.Context, chunk *encoding.Chunk, codecVersion encoding.CodecVersion, useCompression bool, dbTX ...*gorm.DB) (*Chunk, error) { +func (o *Chunk) InsertChunk(ctx context.Context, chunk *encoding.Chunk, codecVersion encoding.CodecVersion, dbTX ...*gorm.DB) (*Chunk, error) { if chunk == nil || len(chunk.Blocks) == 0 { return nil, errors.New("invalid args") } @@ -200,7 +200,7 @@ func (o *Chunk) InsertChunk(ctx context.Context, chunk *encoding.Chunk, codecVer parentChunkStateRoot = parentChunk.StateRoot } - metrics, err := utils.CalculateChunkMetrics(chunk, codecVersion, useCompression) + metrics, err := utils.CalculateChunkMetrics(chunk, codecVersion) if err != nil { log.Error("failed to calculate chunk metrics", "err", err) return nil, fmt.Errorf("Chunk.InsertChunk error: %w", err) diff --git a/rollup/internal/orm/orm_test.go b/rollup/internal/orm/orm_test.go index ea09fb2bc..d709778e2 100644 --- a/rollup/internal/orm/orm_test.go +++ b/rollup/internal/orm/orm_test.go @@ -194,11 +194,11 @@ func TestChunkOrm(t *testing.T) { assert.NoError(t, err) } - dbChunk1, err := chunkOrm.InsertChunk(context.Background(), chunk1, codecVersion, false) + dbChunk1, err := chunkOrm.InsertChunk(context.Background(), chunk1, codecVersion) assert.NoError(t, err) assert.Equal(t, dbChunk1.Hash, chunkHash1.Hex()) - dbChunk2, err := chunkOrm.InsertChunk(context.Background(), chunk2, codecVersion, false) + dbChunk2, err := chunkOrm.InsertChunk(context.Background(), chunk2, codecVersion) assert.NoError(t, err) assert.Equal(t, dbChunk2.Hash, chunkHash2.Hex()) @@ -250,7 +250,7 @@ func TestBatchOrm(t *testing.T) { ParentBatchHash: common.Hash{}, Chunks: []*encoding.Chunk{chunk1}, } - batch1, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion, false) + batch1, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion) assert.NoError(t, err) hash1 := batch1.Hash @@ -275,7 +275,7 @@ func TestBatchOrm(t *testing.T) { ParentBatchHash: common.Hash{}, Chunks: []*encoding.Chunk{chunk2}, } - batch2, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion, false) + batch2, err := batchOrm.InsertBatch(context.Background(), batch, codecVersion) assert.NoError(t, err) hash2 := batch2.Hash diff --git a/rollup/internal/utils/utils.go b/rollup/internal/utils/utils.go index f39e47a34..d75493f74 100644 --- a/rollup/internal/utils/utils.go +++ b/rollup/internal/utils/utils.go @@ -7,6 +7,7 @@ import ( "github.com/scroll-tech/da-codec/encoding" "github.com/scroll-tech/da-codec/encoding/codecv0" "github.com/scroll-tech/da-codec/encoding/codecv1" + "github.com/scroll-tech/da-codec/encoding/codecv2" "github.com/scroll-tech/go-ethereum/accounts/abi" "github.com/scroll-tech/go-ethereum/common" "github.com/scroll-tech/go-ethereum/core/types" @@ -84,7 +85,7 @@ type ChunkMetrics struct { } // CalculateChunkMetrics calculates chunk metrics. -func CalculateChunkMetrics(chunk *encoding.Chunk, codecVersion encoding.CodecVersion, useCompression bool) (*ChunkMetrics, error) { +func CalculateChunkMetrics(chunk *encoding.Chunk, codecVersion encoding.CodecVersion) (*ChunkMetrics, error) { var err error metrics := &ChunkMetrics{ TxNum: chunk.NumTransactions(), @@ -108,11 +109,18 @@ func CalculateChunkMetrics(chunk *encoding.Chunk, codecVersion encoding.CodecVer return metrics, nil case encoding.CodecV1: metrics.L1CommitCalldataSize = codecv1.EstimateChunkL1CommitCalldataSize(chunk) - metrics.L1CommitBlobSize, err = codecv1.EstimateChunkL1CommitBlobSize(chunk, useCompression) + metrics.L1CommitBlobSize, err = codecv1.EstimateChunkL1CommitBlobSize(chunk) if err != nil { return nil, fmt.Errorf("failed to estimate codecv1 chunk L1 commit blob size: %w", err) } return metrics, nil + case encoding.CodecV2: + metrics.L1CommitCalldataSize = codecv2.EstimateChunkL1CommitCalldataSize(chunk) + metrics.L1CommitBlobSize, err = codecv2.EstimateChunkL1CommitBlobSize(chunk) + if err != nil { + return nil, fmt.Errorf("failed to estimate codecv2 chunk L1 commit blob size: %w", err) + } + return metrics, nil default: return nil, fmt.Errorf("unsupported codec version: %v", codecVersion) } @@ -133,7 +141,7 @@ type BatchMetrics struct { } // CalculateBatchMetrics calculates batch metrics. -func CalculateBatchMetrics(batch *encoding.Batch, codecVersion encoding.CodecVersion, useCompression bool) (*BatchMetrics, error) { +func CalculateBatchMetrics(batch *encoding.Batch, codecVersion encoding.CodecVersion) (*BatchMetrics, error) { var err error metrics := &BatchMetrics{ NumChunks: uint64(len(batch.Chunks)), @@ -152,11 +160,18 @@ func CalculateBatchMetrics(batch *encoding.Batch, codecVersion encoding.CodecVer return metrics, nil case encoding.CodecV1: metrics.L1CommitCalldataSize = codecv1.EstimateBatchL1CommitCalldataSize(batch) - metrics.L1CommitBlobSize, err = codecv1.EstimateBatchL1CommitBlobSize(batch, useCompression) + metrics.L1CommitBlobSize, err = codecv1.EstimateBatchL1CommitBlobSize(batch) if err != nil { return nil, fmt.Errorf("failed to estimate codecv1 batch L1 commit blob size: %w", err) } return metrics, nil + case encoding.CodecV2: + metrics.L1CommitCalldataSize = codecv2.EstimateBatchL1CommitCalldataSize(batch) + metrics.L1CommitBlobSize, err = codecv2.EstimateBatchL1CommitBlobSize(batch) + if err != nil { + return nil, fmt.Errorf("failed to estimate codecv2 batch L1 commit blob size: %w", err) + } + return metrics, nil default: return nil, fmt.Errorf("unsupported codec version: %v", codecVersion) } @@ -185,6 +200,16 @@ func GetChunkHash(chunk *encoding.Chunk, totalL1MessagePoppedBefore uint64, code return common.Hash{}, fmt.Errorf("failed to get codecv1 DA chunk hash: %w", err) } return chunkHash, nil + case encoding.CodecV2: + daChunk, err := codecv2.NewDAChunk(chunk, totalL1MessagePoppedBefore) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to create codecv2 DA chunk: %w", err) + } + chunkHash, err := daChunk.Hash() + if err != nil { + return common.Hash{}, fmt.Errorf("failed to get codecv2 DA chunk hash: %w", err) + } + return chunkHash, nil default: return common.Hash{}, fmt.Errorf("unsupported codec version: %v", codecVersion) } @@ -201,7 +226,7 @@ type BatchMetadata struct { } // GetBatchMetadata retrieves the metadata of a batch. -func GetBatchMetadata(batch *encoding.Batch, codecVersion encoding.CodecVersion, useCompression bool) (*BatchMetadata, error) { +func GetBatchMetadata(batch *encoding.Batch, codecVersion encoding.CodecVersion) (*BatchMetadata, error) { numChunks := len(batch.Chunks) totalL1MessagePoppedBeforeEndDAChunk := batch.TotalL1MessagePoppedBefore for i := 0; i < numChunks-1; i++ { @@ -243,7 +268,7 @@ func GetBatchMetadata(batch *encoding.Batch, codecVersion encoding.CodecVersion, } return batchMeta, nil case encoding.CodecV1: - daBatch, err := codecv1.NewDABatch(batch, useCompression) + daBatch, err := codecv1.NewDABatch(batch) if err != nil { return nil, fmt.Errorf("failed to create codecv1 DA batch: %w", err) } @@ -280,6 +305,44 @@ func GetBatchMetadata(batch *encoding.Batch, codecVersion encoding.CodecVersion, return nil, fmt.Errorf("failed to get codecv1 end DA chunk hash: %w", err) } return batchMeta, nil + case encoding.CodecV2: + daBatch, err := codecv2.NewDABatch(batch) + if err != nil { + return nil, fmt.Errorf("failed to create codecv2 DA batch: %w", err) + } + + blobDataProof, err := daBatch.BlobDataProof() + if err != nil { + return nil, fmt.Errorf("failed to get codecv2 blob data proof: %w", err) + } + + batchMeta := &BatchMetadata{ + BatchHash: daBatch.Hash(), + BatchDataHash: daBatch.DataHash, + BatchBlobDataProof: blobDataProof, + BatchBytes: daBatch.Encode(), + } + + startDAChunk, err := codecv2.NewDAChunk(batch.Chunks[0], batch.TotalL1MessagePoppedBefore) + if err != nil { + return nil, fmt.Errorf("failed to create codecv2 start DA chunk: %w", err) + } + + batchMeta.StartChunkHash, err = startDAChunk.Hash() + if err != nil { + return nil, fmt.Errorf("failed to get codecv2 start DA chunk hash: %w", err) + } + + endDAChunk, err := codecv2.NewDAChunk(batch.Chunks[numChunks-1], totalL1MessagePoppedBeforeEndDAChunk) + if err != nil { + return nil, fmt.Errorf("failed to create codecv2 end DA chunk: %w", err) + } + + batchMeta.EndChunkHash, err = endDAChunk.Hash() + if err != nil { + return nil, fmt.Errorf("failed to get codecv2 end DA chunk hash: %w", err) + } + return batchMeta, nil default: return nil, fmt.Errorf("unsupported codec version: %v", codecVersion) } diff --git a/rollup/tests/gas_oracle_test.go b/rollup/tests/gas_oracle_test.go index 80fd4ac44..839efc557 100644 --- a/rollup/tests/gas_oracle_test.go +++ b/rollup/tests/gas_oracle_test.go @@ -98,7 +98,7 @@ func testImportL2GasPrice(t *testing.T) { } batchOrm := orm.NewBatch(db) - _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0, false) + _, err = batchOrm.InsertBatch(context.Background(), batch, encoding.CodecV0) assert.NoError(t, err) // check db status