feat(rollup-verifier): codecv4 (#991)

* feat(rollup-verifier): codecv4

* fix golint

* enhancements

* rename

* rename

* feat: add darwinv2 in genesis config

* bump version

* fix typo

* Update params/config.go

Co-authored-by: georgehao <haohongfan@gmail.com>

* add DarwinV2

* address comments

* move a comment to other places

* small refactors

* chore: auto version bump [bot]

* update da-codec commit

* fix a bug

---------

Co-authored-by: georgehao <haohongfan@gmail.com>
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
This commit is contained in:
colin 2024-08-23 14:50:08 +08:00 committed by GitHub
parent 0ed16b0739
commit 9de4980851
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 361 additions and 77 deletions

View file

@ -16,6 +16,13 @@ type ChunkBlockRange struct {
EndBlockNumber uint64
}
// CommittedBatchMeta holds metadata for committed batches.
type CommittedBatchMeta struct {
Version uint8
BlobVersionedHashes []common.Hash
ChunkBlockRanges []*ChunkBlockRange
}
// FinalizedBatchMeta holds metadata for finalized batches.
type FinalizedBatchMeta struct {
BatchHash common.Hash
@ -53,6 +60,7 @@ func ReadRollupEventSyncedL1BlockNumber(db ethdb.Reader) *uint64 {
// WriteBatchChunkRanges writes the block ranges for each chunk within a batch to the database.
// It serializes the chunk ranges using RLP and stores them under a key derived from the batch index.
// for backward compatibility, new info is also stored in CommittedBatchMeta.
func WriteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64, chunkBlockRanges []*ChunkBlockRange) {
value, err := rlp.EncodeToBytes(chunkBlockRanges)
if err != nil {
@ -65,6 +73,7 @@ func WriteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64, chunkBloc
// DeleteBatchChunkRanges removes the block ranges of all chunks associated with a specific batch from the database.
// Note: Only non-finalized batches can be reverted.
// for backward compatibility, new info is also stored in CommittedBatchMeta.
func DeleteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64) {
if err := db.Delete(batchChunkRangesKey(batchIndex)); err != nil {
log.Crit("failed to delete batch chunk ranges", "batch index", batchIndex, "err", err)
@ -73,6 +82,7 @@ func DeleteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64) {
// ReadBatchChunkRanges retrieves the block ranges of all chunks associated with a specific batch from the database.
// It returns a list of ChunkBlockRange pointers, or nil if no chunk ranges are found for the given batch index.
// for backward compatibility, new info is also stored in CommittedBatchMeta.
func ReadBatchChunkRanges(db ethdb.Reader, batchIndex uint64) []*ChunkBlockRange {
data, err := db.Get(batchChunkRangesKey(batchIndex))
if err != nil && isNotFoundErr(err) {
@ -91,13 +101,12 @@ func ReadBatchChunkRanges(db ethdb.Reader, batchIndex uint64) []*ChunkBlockRange
// WriteFinalizedBatchMeta stores the metadata of a finalized batch in the database.
func WriteFinalizedBatchMeta(db ethdb.KeyValueWriter, batchIndex uint64, finalizedBatchMeta *FinalizedBatchMeta) {
var err error
value, err := rlp.EncodeToBytes(finalizedBatchMeta)
if err != nil {
log.Crit("failed to RLP encode batch metadata", "batch index", batchIndex, "finalized batch meta", finalizedBatchMeta, "err", err)
log.Crit("failed to RLP encode finalized batch metadata", "batch index", batchIndex, "finalized batch meta", finalizedBatchMeta, "err", err)
}
if err := db.Put(batchMetaKey(batchIndex), value); err != nil {
log.Crit("failed to store batch metadata", "batch index", batchIndex, "value", value, "err", err)
log.Crit("failed to store finalized batch metadata", "batch index", batchIndex, "value", value, "err", err)
}
}
@ -171,3 +180,31 @@ func ReadLastFinalizedBatchIndex(db ethdb.Reader) *uint64 {
lastFinalizedBatchIndex := number.Uint64()
return &lastFinalizedBatchIndex
}
// WriteCommittedBatchMeta stores the CommittedBatchMeta for a specific batch in the database.
func WriteCommittedBatchMeta(db ethdb.KeyValueWriter, batchIndex uint64, committedBatchMeta *CommittedBatchMeta) {
value, err := rlp.EncodeToBytes(committedBatchMeta)
if err != nil {
log.Crit("failed to RLP encode committed batch metadata", "batch index", batchIndex, "committed batch meta", committedBatchMeta, "err", err)
}
if err := db.Put(committedBatchMetaKey(batchIndex), value); err != nil {
log.Crit("failed to store committed batch metadata", "batch index", batchIndex, "value", value, "err", err)
}
}
// ReadCommittedBatchMeta fetches the CommittedBatchMeta for a specific batch from the database.
func ReadCommittedBatchMeta(db ethdb.Reader, batchIndex uint64) *CommittedBatchMeta {
data, err := db.Get(committedBatchMetaKey(batchIndex))
if err != nil && isNotFoundErr(err) {
return nil
}
if err != nil {
log.Crit("failed to read committed batch metadata from database", "batch index", batchIndex, "err", err)
}
cbm := new(CommittedBatchMeta)
if err := rlp.Decode(bytes.NewReader(data), cbm); err != nil {
log.Crit("Invalid CommittedBatchMeta RLP", "batch index", batchIndex, "data", data, "err", err)
}
return cbm
}

View file

@ -210,3 +210,118 @@ func TestBatchChunkRanges(t *testing.T) {
// delete non-existing value: ensure the delete operation handles non-existing values without errors.
DeleteBatchChunkRanges(db, uint64(len(chunks)+1))
}
func TestWriteReadCommittedBatchMeta(t *testing.T) {
db := NewMemoryDatabase()
testCases := []struct {
batchIndex uint64
meta *CommittedBatchMeta
}{
{
batchIndex: 0,
meta: &CommittedBatchMeta{
Version: 0,
BlobVersionedHashes: []common.Hash{},
ChunkBlockRanges: []*ChunkBlockRange{},
},
},
{
batchIndex: 1,
meta: &CommittedBatchMeta{
Version: 1,
BlobVersionedHashes: []common.Hash{common.HexToHash("0x1234")},
ChunkBlockRanges: []*ChunkBlockRange{{StartBlockNumber: 0, EndBlockNumber: 10}},
},
},
{
batchIndex: 255,
meta: &CommittedBatchMeta{
Version: 255,
BlobVersionedHashes: []common.Hash{common.HexToHash("0xabcd"), common.HexToHash("0xef01")},
ChunkBlockRanges: []*ChunkBlockRange{{StartBlockNumber: 0, EndBlockNumber: 10}, {StartBlockNumber: 11, EndBlockNumber: 20}},
},
},
}
for _, tc := range testCases {
WriteCommittedBatchMeta(db, tc.batchIndex, tc.meta)
got := ReadCommittedBatchMeta(db, tc.batchIndex)
if got == nil {
t.Fatalf("Expected non-nil value for batch index %d", tc.batchIndex)
}
if !compareCommittedBatchMeta(tc.meta, got) {
t.Fatalf("CommittedBatchMeta mismatch for batch index %d, expected %+v, got %+v", tc.batchIndex, tc.meta, got)
}
}
// reading a non-existing value
if got := ReadCommittedBatchMeta(db, 256); got != nil {
t.Fatalf("Expected nil for non-existing value, got %+v", got)
}
}
func TestOverwriteCommittedBatchMeta(t *testing.T) {
db := NewMemoryDatabase()
batchIndex := uint64(42)
initialMeta := &CommittedBatchMeta{
Version: 1,
BlobVersionedHashes: []common.Hash{common.HexToHash("0x1234")},
ChunkBlockRanges: []*ChunkBlockRange{{StartBlockNumber: 0, EndBlockNumber: 10}},
}
newMeta := &CommittedBatchMeta{
Version: 2,
BlobVersionedHashes: []common.Hash{common.HexToHash("0x5678"), common.HexToHash("0x9abc")},
ChunkBlockRanges: []*ChunkBlockRange{{StartBlockNumber: 0, EndBlockNumber: 20}, {StartBlockNumber: 21, EndBlockNumber: 30}},
}
// write initial meta
WriteCommittedBatchMeta(db, batchIndex, initialMeta)
got := ReadCommittedBatchMeta(db, batchIndex)
if !compareCommittedBatchMeta(initialMeta, got) {
t.Fatalf("Initial write failed, expected %+v, got %+v", initialMeta, got)
}
// overwrite with new meta
WriteCommittedBatchMeta(db, batchIndex, newMeta)
got = ReadCommittedBatchMeta(db, batchIndex)
if !compareCommittedBatchMeta(newMeta, got) {
t.Fatalf("Overwrite failed, expected %+v, got %+v", newMeta, got)
}
// read non-existing batch index
nonExistingIndex := uint64(999)
got = ReadCommittedBatchMeta(db, nonExistingIndex)
if got != nil {
t.Fatalf("Expected nil for non-existing batch index, got %+v", got)
}
}
func compareCommittedBatchMeta(a, b *CommittedBatchMeta) bool {
if a.Version != b.Version {
return false
}
if len(a.BlobVersionedHashes) != len(b.BlobVersionedHashes) {
return false
}
for i := range a.BlobVersionedHashes {
if a.BlobVersionedHashes[i] != b.BlobVersionedHashes[i] {
return false
}
}
if len(a.ChunkBlockRanges) != len(b.ChunkBlockRanges) {
return false
}
for i := range a.ChunkBlockRanges {
if a.ChunkBlockRanges[i].StartBlockNumber != b.ChunkBlockRanges[i].StartBlockNumber || a.ChunkBlockRanges[i].EndBlockNumber != b.ChunkBlockRanges[i].EndBlockNumber {
return false
}
}
return true
}

View file

@ -116,6 +116,7 @@ var (
batchMetaPrefix = []byte("R-bm")
finalizedL2BlockNumberKey = []byte("R-finalized")
lastFinalizedBatchIndexKey = []byte("R-finalizedBatchIndex")
committedBatchMetaPrefix = []byte("R-cbm")
// Row consumption
rowConsumptionPrefix = []byte("rc") // rowConsumptionPrefix + hash -> row consumption by block
@ -309,3 +310,8 @@ func batchChunkRangesKey(batchIndex uint64) []byte {
func batchMetaKey(batchIndex uint64) []byte {
return append(batchMetaPrefix, encodeBigEndian(batchIndex)...)
}
// committedBatchMetaKey = committedBatchMetaPrefix + batch index (uint64 big endian)
func committedBatchMetaKey(batchIndex uint64) []byte {
return append(committedBatchMetaPrefix, encodeBigEndian(batchIndex)...)
}

2
go.mod
View file

@ -50,7 +50,7 @@ require (
github.com/prometheus/tsdb v0.7.1
github.com/rjeczalik/notify v0.9.1
github.com/rs/cors v1.7.0
github.com/scroll-tech/da-codec v0.1.1-0.20240718144756-1875fd490923
github.com/scroll-tech/da-codec v0.1.1-0.20240822151711-9e32313056ac
github.com/scroll-tech/zktrie v0.8.4
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4

4
go.sum
View file

@ -392,8 +392,8 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj
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.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scroll-tech/da-codec v0.1.1-0.20240718144756-1875fd490923 h1:A1ItzpnFDCHMh4g6cpeBZf7/fPf2lfwHbhjr/FSpk2w=
github.com/scroll-tech/da-codec v0.1.1-0.20240718144756-1875fd490923/go.mod h1:D6XEESeNVJkQJlv3eK+FyR+ufPkgVQbJzERylQi53Bs=
github.com/scroll-tech/da-codec v0.1.1-0.20240822151711-9e32313056ac h1:DjLrqjoOLVFug9ZkAbJYwjtYW51YZE0Num3p4cZXaZs=
github.com/scroll-tech/da-codec v0.1.1-0.20240822151711-9e32313056ac/go.mod h1:D6XEESeNVJkQJlv3eK+FyR+ufPkgVQbJzERylQi53Bs=
github.com/scroll-tech/zktrie v0.8.4 h1:UagmnZ4Z3ITCk+aUq9NQZJNAwnWl4gSxsLb2Nl7IgRE=
github.com/scroll-tech/zktrie v0.8.4/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=

View file

@ -24,7 +24,7 @@ import (
const (
VersionMajor = 5 // Major version component of the current release
VersionMinor = 6 // Minor version component of the current release
VersionPatch = 2 // Patch version component of the current release
VersionPatch = 3 // Patch version component of the current release
VersionMeta = "mainnet" // Version metadata to append to the version string
)

View file

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"math/big"
"os"
"reflect"
"time"
@ -13,6 +14,7 @@ import (
"github.com/scroll-tech/da-codec/encoding/codecv1"
"github.com/scroll-tech/da-codec/encoding/codecv2"
"github.com/scroll-tech/da-codec/encoding/codecv3"
"github.com/scroll-tech/da-codec/encoding/codecv4"
"github.com/scroll-tech/go-ethereum/accounts/abi"
"github.com/scroll-tech/go-ethereum/common"
@ -202,10 +204,11 @@ func (s *RollupSyncService) parseAndUpdateRollupEventLogs(logs []types.Log, endB
batchIndex := event.BatchIndex.Uint64()
log.Trace("found new CommitBatch event", "batch index", batchIndex)
chunkBlockRanges, err := s.getChunkRanges(batchIndex, &vLog)
committedBatchMeta, chunkBlockRanges, err := s.getCommittedBatchMeta(batchIndex, &vLog)
if err != nil {
return fmt.Errorf("failed to get chunk ranges, batch index: %v, err: %w", batchIndex, err)
}
rawdb.WriteCommittedBatchMeta(s.db, batchIndex, committedBatchMeta)
rawdb.WriteBatchChunkRanges(s.db, batchIndex, chunkBlockRanges)
case s.l1RevertBatchEventSignature:
@ -241,27 +244,29 @@ func (s *RollupSyncService) parseAndUpdateRollupEventLogs(logs []types.Log, endB
log.Warn("got nil when reading last finalized batch index. This should happen only once.")
}
parentBatchMeta := &rawdb.FinalizedBatchMeta{}
parentFinalizedBatchMeta := &rawdb.FinalizedBatchMeta{}
if startBatchIndex > 0 {
parentBatchMeta = rawdb.ReadFinalizedBatchMeta(s.db, startBatchIndex-1)
parentFinalizedBatchMeta = rawdb.ReadFinalizedBatchMeta(s.db, startBatchIndex-1)
}
var highestFinalizedBlockNumber uint64
batchWriter := s.db.NewBatch()
for index := startBatchIndex; index <= batchIndex; index++ {
committedBatchMeta := rawdb.ReadCommittedBatchMeta(s.db, index)
chunks, err := s.getLocalChunksForBatch(index)
if err != nil {
return fmt.Errorf("failed to get local node info, batch index: %v, err: %w", index, err)
}
endBlock, finalizedBatchMeta, err := validateBatch(index, event, parentBatchMeta, chunks, s.bc.Config(), s.stack)
endBlock, finalizedBatchMeta, err := validateBatch(index, event, parentFinalizedBatchMeta, committedBatchMeta, chunks, s.bc.Config(), s.stack)
if err != nil {
return fmt.Errorf("fatal: validateBatch failed: finalize event: %v, err: %w", event, err)
}
rawdb.WriteFinalizedBatchMeta(batchWriter, index, finalizedBatchMeta)
highestFinalizedBlockNumber = endBlock
parentBatchMeta = finalizedBatchMeta
parentFinalizedBatchMeta = finalizedBatchMeta
if index%100 == 0 {
log.Info("finalized batch progress", "batch index", index, "finalized l2 block height", endBlock)
@ -342,9 +347,13 @@ func (s *RollupSyncService) getLocalChunksForBatch(batchIndex uint64) ([]*encodi
return chunks, nil
}
func (s *RollupSyncService) getChunkRanges(batchIndex uint64, vLog *types.Log) ([]*rawdb.ChunkBlockRange, error) {
func (s *RollupSyncService) getCommittedBatchMeta(batchIndex uint64, vLog *types.Log) (*rawdb.CommittedBatchMeta, []*rawdb.ChunkBlockRange, error) {
if batchIndex == 0 {
return []*rawdb.ChunkBlockRange{{StartBlockNumber: 0, EndBlockNumber: 0}}, nil
return &rawdb.CommittedBatchMeta{
Version: 0,
BlobVersionedHashes: nil,
ChunkBlockRanges: []*rawdb.ChunkBlockRange{{StartBlockNumber: 0, EndBlockNumber: 0}},
}, []*rawdb.ChunkBlockRange{{StartBlockNumber: 0, EndBlockNumber: 0}}, nil
}
tx, _, err := s.client.client.TransactionByHash(s.ctx, vLog.TxHash)
@ -353,11 +362,11 @@ func (s *RollupSyncService) getChunkRanges(batchIndex uint64, vLog *types.Log) (
"tx hash", vLog.TxHash.Hex(), "block number", vLog.BlockNumber, "block hash", vLog.BlockHash.Hex(), "err", err)
block, err := s.client.client.BlockByHash(s.ctx, vLog.BlockHash)
if err != nil {
return nil, fmt.Errorf("failed to get block by hash, block number: %v, block hash: %v, err: %w", vLog.BlockNumber, vLog.BlockHash.Hex(), err)
return nil, nil, fmt.Errorf("failed to get block by hash, block number: %v, block hash: %v, err: %w", vLog.BlockNumber, vLog.BlockHash.Hex(), err)
}
if block == nil {
return nil, fmt.Errorf("failed to get block by hash, block not found, block number: %v, block hash: %v", vLog.BlockNumber, vLog.BlockHash.Hex())
return nil, nil, fmt.Errorf("failed to get block by hash, block not found, block number: %v, block hash: %v", vLog.BlockNumber, vLog.BlockHash.Hex())
}
found := false
@ -369,28 +378,45 @@ func (s *RollupSyncService) getChunkRanges(batchIndex uint64, vLog *types.Log) (
}
}
if !found {
return nil, fmt.Errorf("transaction not found in the block, tx hash: %v, block number: %v, block hash: %v", vLog.TxHash.Hex(), vLog.BlockNumber, vLog.BlockHash.Hex())
return nil, nil, fmt.Errorf("transaction not found in the block, tx hash: %v, block number: %v, block hash: %v", vLog.TxHash.Hex(), vLog.BlockNumber, vLog.BlockHash.Hex())
}
}
return s.decodeChunkBlockRanges(tx.Data())
var commitBatchMeta rawdb.CommittedBatchMeta
if tx.Type() == types.BlobTxType {
blobVersionedHashes := tx.BlobHashes()
if blobVersionedHashes == nil {
return nil, nil, fmt.Errorf("invalid blob transaction, blob hashes is nil, tx hash: %v", tx.Hash().Hex())
}
commitBatchMeta.BlobVersionedHashes = blobVersionedHashes
}
// decodeChunkBlockRanges decodes chunks in a batch based on the commit batch transaction's calldata.
func (s *RollupSyncService) decodeChunkBlockRanges(txData []byte) ([]*rawdb.ChunkBlockRange, error) {
version, ranges, err := s.decodeBatchVersionAndChunkBlockRanges(tx.Data())
if err != nil {
return nil, nil, fmt.Errorf("failed to decode chunk block ranges, batch index: %v, err: %w", batchIndex, err)
}
commitBatchMeta.Version = version
commitBatchMeta.ChunkBlockRanges = ranges
return &commitBatchMeta, ranges, nil
}
// decodeBatchVersionAndChunkBlockRanges decodes version and chunks' block ranges in a batch based on the commit batch transaction's calldata.
func (s *RollupSyncService) decodeBatchVersionAndChunkBlockRanges(txData []byte) (uint8, []*rawdb.ChunkBlockRange, error) {
const methodIDLength = 4
if len(txData) < methodIDLength {
return nil, fmt.Errorf("transaction data is too short, length of tx data: %v, minimum length required: %v", len(txData), methodIDLength)
return 0, nil, fmt.Errorf("transaction data is too short, length of tx data: %v, minimum length required: %v", len(txData), methodIDLength)
}
method, err := s.scrollChainABI.MethodById(txData[:methodIDLength])
if err != nil {
return nil, fmt.Errorf("failed to get method by ID, ID: %v, err: %w", txData[:methodIDLength], err)
return 0, nil, fmt.Errorf("failed to get method by ID, ID: %v, err: %w", txData[:methodIDLength], err)
}
values, err := method.Inputs.Unpack(txData[methodIDLength:])
if err != nil {
return nil, fmt.Errorf("failed to unpack transaction data using ABI, tx data: %v, err: %w", txData, err)
return 0, nil, fmt.Errorf("failed to unpack transaction data using ABI, tx data: %v, err: %w", txData, err)
}
if method.Name == "commitBatch" {
@ -403,10 +429,15 @@ func (s *RollupSyncService) decodeChunkBlockRanges(txData []byte) ([]*rawdb.Chun
var args commitBatchArgs
if err = method.Inputs.Copy(&args, values); err != nil {
return nil, fmt.Errorf("failed to decode calldata into commitBatch args, values: %+v, err: %w", values, err)
return 0, nil, fmt.Errorf("failed to decode calldata into commitBatch args, values: %+v, err: %w", values, err)
}
return decodeBlockRangesFromEncodedChunks(encoding.CodecVersion(args.Version), args.Chunks)
chunkRanges, err := decodeBlockRangesFromEncodedChunks(encoding.CodecVersion(args.Version), args.Chunks)
if err != nil {
return 0, nil, fmt.Errorf("failed to decode block ranges from encoded chunks, version: %v, chunks: %+v, err: %w", args.Version, args.Chunks, err)
}
return args.Version, chunkRanges, nil
} else if method.Name == "commitBatchWithBlobProof" {
type commitBatchWithBlobProofArgs struct {
Version uint8
@ -418,13 +449,18 @@ func (s *RollupSyncService) decodeChunkBlockRanges(txData []byte) ([]*rawdb.Chun
var args commitBatchWithBlobProofArgs
if err = method.Inputs.Copy(&args, values); err != nil {
return nil, fmt.Errorf("failed to decode calldata into commitBatchWithBlobProofArgs args, values: %+v, err: %w", values, err)
return 0, nil, fmt.Errorf("failed to decode calldata into commitBatchWithBlobProofArgs args, values: %+v, err: %w", values, err)
}
return decodeBlockRangesFromEncodedChunks(encoding.CodecVersion(args.Version), args.Chunks)
chunkRanges, err := decodeBlockRangesFromEncodedChunks(encoding.CodecVersion(args.Version), args.Chunks)
if err != nil {
return 0, nil, fmt.Errorf("failed to decode block ranges from encoded chunks, version: %v, chunks: %+v, err: %w", args.Version, args.Chunks, err)
}
return nil, fmt.Errorf("unexpected method name: %v", method.Name)
return args.Version, chunkRanges, nil
}
return 0, nil, fmt.Errorf("unexpected method name: %v", method.Name)
}
// validateBatch verifies the consistency between the L1 contract and L2 node data.
@ -437,9 +473,11 @@ func (s *RollupSyncService) decodeChunkBlockRanges(txData []byte) ([]*rawdb.Chun
// Parameters:
// - batchIndex: batch index of the validated batch
// - event: L1 finalize batch event data
// - parentBatchMeta: metadata of the parent batch
// - parentFinalizedBatchMeta: metadata of the finalized parent batch
// - committedBatchMeta: committed batch metadata stored in the database.
// Can be nil for older client versions that don't store this information.
// - chunks: slice of chunk data for the current batch
// - chainCfg: chain configuration to identify the codec version
// - chainCfg: chain configuration to identify the codec version when committedBatchMeta is nil
// - stack: node stack to terminate the node in case of inconsistency
//
// Returns:
@ -450,7 +488,7 @@ func (s *RollupSyncService) decodeChunkBlockRanges(txData []byte) ([]*rawdb.Chun
// Note: This function is compatible with both "finalize by batch" and "finalize by bundle" methods.
// In "finalize by bundle", only the last batch of each bundle is fully verified.
// This check still ensures the correctness of all batch hashes in the bundle due to the parent-child relationship between batch hashes.
func validateBatch(batchIndex uint64, event *L1FinalizeBatchEvent, parentBatchMeta *rawdb.FinalizedBatchMeta, chunks []*encoding.Chunk, chainCfg *params.ChainConfig, stack *node.Node) (uint64, *rawdb.FinalizedBatchMeta, error) {
func validateBatch(batchIndex uint64, event *L1FinalizeBatchEvent, parentFinalizedBatchMeta *rawdb.FinalizedBatchMeta, committedBatchMeta *rawdb.CommittedBatchMeta, chunks []*encoding.Chunk, chainCfg *params.ChainConfig, stack *node.Node) (uint64, *rawdb.FinalizedBatchMeta, error) {
if len(chunks) == 0 {
return 0, nil, fmt.Errorf("invalid argument: length of chunks is 0, batch index: %v", batchIndex)
}
@ -470,36 +508,75 @@ func validateBatch(batchIndex uint64, event *L1FinalizeBatchEvent, parentBatchMe
// Note: All params of batch are calculated locally based on the block data.
batch := &encoding.Batch{
Index: batchIndex,
TotalL1MessagePoppedBefore: parentBatchMeta.TotalL1MessagePopped,
ParentBatchHash: parentBatchMeta.BatchHash,
TotalL1MessagePoppedBefore: parentFinalizedBatchMeta.TotalL1MessagePopped,
ParentBatchHash: parentFinalizedBatchMeta.BatchHash,
Chunks: chunks,
}
var codecVersion encoding.CodecVersion
if committedBatchMeta != nil {
codecVersion = encoding.CodecVersion(committedBatchMeta.Version)
} else {
codecVersion = determineCodecVersion(startBlock.Header.Number, startBlock.Header.Time, chainCfg)
}
var localBatchHash common.Hash
if startBlock.Header.Number.Uint64() == 0 || !chainCfg.IsBernoulli(startBlock.Header.Number) { // codecv0: genesis batch or batches before Bernoulli
if codecVersion == encoding.CodecV0 {
daBatch, err := codecv0.NewDABatch(batch)
if err != nil {
return 0, nil, fmt.Errorf("failed to create codecv0 DA batch, batch index: %v, err: %w", batchIndex, err)
}
localBatchHash = daBatch.Hash()
} else if !chainCfg.IsCurie(startBlock.Header.Number) { // codecv1: batches after Bernoulli and before Curie
} else if codecVersion == encoding.CodecV1 {
daBatch, err := codecv1.NewDABatch(batch)
if err != nil {
return 0, nil, fmt.Errorf("failed to create codecv1 DA batch, batch index: %v, err: %w", batchIndex, err)
}
localBatchHash = daBatch.Hash()
} else if !chainCfg.IsDarwin(startBlock.Header.Time) { // codecv2: batches after Curie and before Darwin
} else if codecVersion == encoding.CodecV2 {
daBatch, err := codecv2.NewDABatch(batch)
if err != nil {
return 0, nil, fmt.Errorf("failed to create codecv2 DA batch, batch index: %v, err: %w", batchIndex, err)
}
localBatchHash = daBatch.Hash()
} else { // codecv3: batches after Darwin
} else if codecVersion == encoding.CodecV3 {
daBatch, err := codecv3.NewDABatch(batch)
if err != nil {
return 0, nil, fmt.Errorf("failed to create codecv3 DA batch, batch index: %v, err: %w", batchIndex, err)
}
localBatchHash = daBatch.Hash()
} else if codecVersion == encoding.CodecV4 {
// Check if committedBatchMeta exists, for backward compatibility with older client versions
if committedBatchMeta == nil {
return 0, nil, fmt.Errorf("missing committed batch metadata for codecV4, please use the latest client version, batch index: %v", batchIndex)
}
// Validate BlobVersionedHashes
if committedBatchMeta.BlobVersionedHashes == nil || len(committedBatchMeta.BlobVersionedHashes) != 1 {
return 0, nil, fmt.Errorf("invalid blob hashes, batch index: %v, blob hashes: %v", batchIndex, committedBatchMeta.BlobVersionedHashes)
}
// Attempt to create DA batch with compression
daBatch, err := codecv4.NewDABatch(batch, true)
if err != nil {
// If compression fails, try without compression
log.Warn("failed to create codecv4 DA batch with compress enabling", "batch index", batchIndex, "err", err)
daBatch, err = codecv4.NewDABatch(batch, false)
if err != nil {
return 0, nil, fmt.Errorf("failed to create codecv4 DA batch, batch index: %v, err: %w", batchIndex, err)
}
} else if daBatch.BlobVersionedHash != committedBatchMeta.BlobVersionedHashes[0] {
// Inconsistent blob versioned hash, fallback to uncompressed DA batch
log.Warn("impossible case: inconsistent blob versioned hash", "batch index", batchIndex, "expected", committedBatchMeta.BlobVersionedHashes[0], "actual", daBatch.BlobVersionedHash)
daBatch, err = codecv4.NewDABatch(batch, false)
if err != nil {
return 0, nil, fmt.Errorf("failed to create codecv4 DA batch, batch index: %v, err: %w", batchIndex, err)
}
}
localBatchHash = daBatch.Hash()
} else {
return 0, nil, fmt.Errorf("unsupported codec version: %v", codecVersion)
}
localStateRoot := endBlock.Header.Root
@ -513,13 +590,13 @@ func validateBatch(batchIndex uint64, event *L1FinalizeBatchEvent, parentBatchMe
// - finalize by bundle: check the last batch, because only one event (containing the info of the last batch) is emitted per bundle
if batchIndex == event.BatchIndex.Uint64() {
if localStateRoot != event.StateRoot {
log.Error("State root mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentBatchMeta.BatchHash.Hex(), "l1 finalized state root", event.StateRoot.Hex(), "l2 state root", localStateRoot.Hex())
log.Error("State root mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentFinalizedBatchMeta.BatchHash.Hex(), "l1 finalized state root", event.StateRoot.Hex(), "l2 state root", localStateRoot.Hex())
stack.Close()
os.Exit(1)
}
if localWithdrawRoot != event.WithdrawRoot {
log.Error("Withdraw root mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentBatchMeta.BatchHash.Hex(), "l1 finalized withdraw root", event.WithdrawRoot.Hex(), "l2 withdraw root", localWithdrawRoot.Hex())
log.Error("Withdraw root mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentFinalizedBatchMeta.BatchHash.Hex(), "l1 finalized withdraw root", event.WithdrawRoot.Hex(), "l2 withdraw root", localWithdrawRoot.Hex())
stack.Close()
os.Exit(1)
}
@ -528,7 +605,7 @@ func validateBatch(batchIndex uint64, event *L1FinalizeBatchEvent, parentBatchMe
// This check ensures the correctness of all batch hashes in the bundle
// due to the parent-child relationship between batch hashes
if localBatchHash != event.BatchHash {
log.Error("Batch hash mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentBatchMeta.BatchHash.Hex(), "parent TotalL1MessagePopped", parentBatchMeta.TotalL1MessagePopped, "l1 finalized batch hash", event.BatchHash.Hex(), "l2 batch hash", localBatchHash.Hex())
log.Error("Batch hash mismatch", "batch index", event.BatchIndex.Uint64(), "start block", startBlock.Header.Number.Uint64(), "end block", endBlock.Header.Number.Uint64(), "parent batch hash", parentFinalizedBatchMeta.BatchHash.Hex(), "parent TotalL1MessagePopped", parentFinalizedBatchMeta.TotalL1MessagePopped, "l1 finalized batch hash", event.BatchHash.Hex(), "l2 batch hash", localBatchHash.Hex())
chunksJson, err := json.Marshal(chunks)
if err != nil {
log.Error("marshal chunks failed", "err", err)
@ -539,7 +616,7 @@ func validateBatch(batchIndex uint64, event *L1FinalizeBatchEvent, parentBatchMe
}
}
totalL1MessagePopped := parentBatchMeta.TotalL1MessagePopped
totalL1MessagePopped := parentFinalizedBatchMeta.TotalL1MessagePopped
for _, chunk := range chunks {
totalL1MessagePopped += chunk.NumL1Messages(totalL1MessagePopped)
}
@ -552,6 +629,22 @@ func validateBatch(batchIndex uint64, event *L1FinalizeBatchEvent, parentBatchMe
return endBlock.Header.Number.Uint64(), finalizedBatchMeta, nil
}
// determineCodecVersion determines the codec version based on the block number and chain configuration.
func determineCodecVersion(startBlockNumber *big.Int, startBlockTimestamp uint64, chainCfg *params.ChainConfig) encoding.CodecVersion {
switch {
case startBlockNumber.Uint64() == 0 || !chainCfg.IsBernoulli(startBlockNumber):
return encoding.CodecV0 // codecv0: genesis batch or batches before Bernoulli
case !chainCfg.IsCurie(startBlockNumber):
return encoding.CodecV1 // codecv1: batches after Bernoulli and before Curie
case !chainCfg.IsDarwin(startBlockTimestamp):
return encoding.CodecV2 // codecv2: batches after Curie and before Darwin
case !chainCfg.IsDarwinV2(startBlockTimestamp):
return encoding.CodecV3 // codecv3: batches after Darwin
default:
return encoding.CodecV4 // codecv4: batches after DarwinV2
}
}
// decodeBlockRangesFromEncodedChunks decodes the provided chunks into a list of block ranges.
func decodeBlockRangesFromEncodedChunks(codecVersion encoding.CodecVersion, chunks [][]byte) ([]*rawdb.ChunkBlockRange, error) {
var chunkBlockRanges []*rawdb.ChunkBlockRange
@ -635,7 +728,24 @@ func decodeBlockRangesFromEncodedChunks(codecVersion encoding.CodecVersion, chun
StartBlockNumber: daBlocks[0].BlockNumber,
EndBlockNumber: daBlocks[len(daBlocks)-1].BlockNumber,
})
case encoding.CodecV4:
if len(chunk) != 1+numBlocks*60 {
return nil, fmt.Errorf("invalid chunk byte length, expected: %v, got: %v", 1+numBlocks*60, len(chunk))
}
daBlocks := make([]*codecv4.DABlock, numBlocks)
for i := 0; i < numBlocks; i++ {
startIdx := 1 + i*60 // add 1 to skip numBlocks byte
endIdx := startIdx + 60
daBlocks[i] = &codecv4.DABlock{}
if err := daBlocks[i].Decode(chunk[startIdx:endIdx]); err != nil {
return nil, err
}
}
chunkBlockRanges = append(chunkBlockRanges, &rawdb.ChunkBlockRange{
StartBlockNumber: daBlocks[0].BlockNumber,
EndBlockNumber: daBlocks[len(daBlocks)-1].BlockNumber,
})
default:
return nil, fmt.Errorf("unexpected batch version %v", codecVersion)
}

View file

@ -50,7 +50,7 @@ func TestRollupSyncServiceStartAndStop(t *testing.T) {
service.Stop()
}
func TestDecodeChunkRangesCodecv0(t *testing.T) {
func TestDecodeBatchVersionAndChunkBlockRangesCodecv0(t *testing.T) {
scrollChainABI, err := scrollChainMetaData.GetAbi()
require.NoError(t, err)
@ -73,11 +73,13 @@ func TestDecodeChunkRangesCodecv0(t *testing.T) {
t.Fatalf("Failed to decode string: %v", err)
}
ranges, err := service.decodeChunkBlockRanges(testTxData)
version, ranges, err := service.decodeBatchVersionAndChunkBlockRanges(testTxData)
if err != nil {
t.Fatalf("Failed to decode chunk ranges: %v", err)
}
assert.Equal(t, encoding.CodecV0, encoding.CodecVersion(version))
expectedRanges := []*rawdb.ChunkBlockRange{
{StartBlockNumber: 4435142, EndBlockNumber: 4435142},
{StartBlockNumber: 4435143, EndBlockNumber: 4435144},
@ -107,7 +109,7 @@ func TestDecodeChunkRangesCodecv0(t *testing.T) {
}
}
func TestDecodeChunkRangesCodecv1(t *testing.T) {
func TestDecodeBatchVersionAndChunkBlockRangesCodecv1(t *testing.T) {
scrollChainABI, err := scrollChainMetaData.GetAbi()
require.NoError(t, err)
@ -130,11 +132,13 @@ func TestDecodeChunkRangesCodecv1(t *testing.T) {
t.Fatalf("Failed to decode string: %v", err)
}
ranges, err := service.decodeChunkBlockRanges(testTxData)
version, ranges, err := service.decodeBatchVersionAndChunkBlockRanges(testTxData)
if err != nil {
t.Fatalf("Failed to decode chunk ranges: %v", err)
}
assert.Equal(t, encoding.CodecV1, encoding.CodecVersion(version))
expectedRanges := []*rawdb.ChunkBlockRange{
{StartBlockNumber: 1690, EndBlockNumber: 1780},
{StartBlockNumber: 1781, EndBlockNumber: 1871},
@ -158,7 +162,7 @@ func TestDecodeChunkRangesCodecv1(t *testing.T) {
}
}
func TestDecodeChunkRangesCodecv2(t *testing.T) {
func TestDecodeBatchVersionAndChunkBlockRangesCodecv2(t *testing.T) {
scrollChainABI, err := scrollChainMetaData.GetAbi()
require.NoError(t, err)
@ -181,11 +185,13 @@ func TestDecodeChunkRangesCodecv2(t *testing.T) {
t.Fatalf("Failed to decode string: %v", err)
}
ranges, err := service.decodeChunkBlockRanges(testTxData)
version, ranges, err := service.decodeBatchVersionAndChunkBlockRanges(testTxData)
if err != nil {
t.Fatalf("Failed to decode chunk ranges: %v", err)
}
assert.Equal(t, encoding.CodecV2, encoding.CodecVersion(version))
expectedRanges := []*rawdb.ChunkBlockRange{
{StartBlockNumber: 200, EndBlockNumber: 290},
{StartBlockNumber: 291, EndBlockNumber: 381},
@ -209,7 +215,7 @@ func TestDecodeChunkRangesCodecv2(t *testing.T) {
}
}
func TestDecodeChunkRangesCodecv3(t *testing.T) {
func TestDecodeBatchVersionAndChunkBlockRangesCodecv3(t *testing.T) {
scrollChainABI, err := scrollChainMetaData.GetAbi()
require.NoError(t, err)
@ -232,11 +238,13 @@ func TestDecodeChunkRangesCodecv3(t *testing.T) {
t.Fatalf("Failed to decode string: %v", err)
}
ranges, err := service.decodeChunkBlockRanges(testTxData)
version, ranges, err := service.decodeBatchVersionAndChunkBlockRanges(testTxData)
if err != nil {
t.Fatalf("Failed to decode chunk ranges: %v", err)
}
assert.Equal(t, encoding.CodecV3, encoding.CodecVersion(version))
expectedRanges := []*rawdb.ChunkBlockRange{
{StartBlockNumber: 1, EndBlockNumber: 9},
{StartBlockNumber: 10, EndBlockNumber: 20},
@ -273,7 +281,7 @@ func TestDecodeChunkRangesCodecv3(t *testing.T) {
}
}
func TestGetChunkRangesCodecv0(t *testing.T) {
func TestGetCommittedBatchMetaCodecv0(t *testing.T) {
genesisConfig := &params.ChainConfig{
Scroll: params.ScrollConfig{
L1Config: &params.L1Config{
@ -305,9 +313,11 @@ func TestGetChunkRangesCodecv0(t *testing.T) {
vLog := &types.Log{
TxHash: common.HexToHash("0x0"),
}
ranges, err := service.getChunkRanges(1, vLog)
metadata, ranges, err := service.getCommittedBatchMeta(1, vLog)
require.NoError(t, err)
assert.Equal(t, encoding.CodecV0, encoding.CodecVersion(metadata.Version))
expectedRanges := []*rawdb.ChunkBlockRange{
{StartBlockNumber: 911145, EndBlockNumber: 911151},
{StartBlockNumber: 911152, EndBlockNumber: 911155},
@ -325,7 +335,7 @@ func TestGetChunkRangesCodecv0(t *testing.T) {
}
}
func TestGetChunkRangesCodecv1(t *testing.T) {
func TestGetCommittedBatchMetaCodecv1(t *testing.T) {
genesisConfig := &params.ChainConfig{
Scroll: params.ScrollConfig{
L1Config: &params.L1Config{
@ -357,9 +367,11 @@ func TestGetChunkRangesCodecv1(t *testing.T) {
vLog := &types.Log{
TxHash: common.HexToHash("0x1"),
}
ranges, err := service.getChunkRanges(1, vLog)
metadata, ranges, err := service.getCommittedBatchMeta(1, vLog)
require.NoError(t, err)
assert.Equal(t, encoding.CodecV1, encoding.CodecVersion(metadata.Version))
expectedRanges := []*rawdb.ChunkBlockRange{
{StartBlockNumber: 1, EndBlockNumber: 11},
}
@ -375,7 +387,7 @@ func TestGetChunkRangesCodecv1(t *testing.T) {
}
}
func TestGetChunkRangesCodecv2(t *testing.T) {
func TestGetCommittedBatchMetaCodecv2(t *testing.T) {
genesisConfig := &params.ChainConfig{
Scroll: params.ScrollConfig{
L1Config: &params.L1Config{
@ -407,9 +419,11 @@ func TestGetChunkRangesCodecv2(t *testing.T) {
vLog := &types.Log{
TxHash: common.HexToHash("0x2"),
}
ranges, err := service.getChunkRanges(1, vLog)
metadata, ranges, err := service.getCommittedBatchMeta(1, vLog)
require.NoError(t, err)
assert.Equal(t, encoding.CodecV2, encoding.CodecVersion(metadata.Version))
expectedRanges := []*rawdb.ChunkBlockRange{
{StartBlockNumber: 143, EndBlockNumber: 143},
{StartBlockNumber: 144, EndBlockNumber: 144},
@ -453,7 +467,7 @@ func TestGetChunkRangesCodecv2(t *testing.T) {
}
}
func TestGetChunkRangesCodecv3(t *testing.T) {
func TestGetCommittedBatchMetaCodecv3(t *testing.T) {
genesisConfig := &params.ChainConfig{
Scroll: params.ScrollConfig{
L1Config: &params.L1Config{
@ -485,9 +499,11 @@ func TestGetChunkRangesCodecv3(t *testing.T) {
vLog := &types.Log{
TxHash: common.HexToHash("0x3"),
}
ranges, err := service.getChunkRanges(1, vLog)
metadata, ranges, err := service.getCommittedBatchMeta(1, vLog)
require.NoError(t, err)
assert.Equal(t, encoding.CodecV3, encoding.CodecVersion(metadata.Version))
expectedRanges := []*rawdb.ChunkBlockRange{
{StartBlockNumber: 41, EndBlockNumber: 41},
{StartBlockNumber: 42, EndBlockNumber: 42},
@ -552,7 +568,7 @@ func TestValidateBatchCodecv0(t *testing.T) {
WithdrawRoot: chunk3.Blocks[len(chunk3.Blocks)-1].WithdrawRoot,
}
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, []*encoding.Chunk{chunk1, chunk2, chunk3}, chainConfig, nil)
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, nil, []*encoding.Chunk{chunk1, chunk2, chunk3}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(13), endBlock1)
@ -572,7 +588,7 @@ func TestValidateBatchCodecv0(t *testing.T) {
StateRoot: chunk4.Blocks[len(chunk4.Blocks)-1].Header.Root,
WithdrawRoot: chunk4.Blocks[len(chunk4.Blocks)-1].WithdrawRoot,
}
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, []*encoding.Chunk{chunk4}, chainConfig, nil)
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, nil, []*encoding.Chunk{chunk4}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(17), endBlock2)
@ -605,7 +621,7 @@ func TestValidateBatchCodecv1(t *testing.T) {
WithdrawRoot: chunk3.Blocks[len(chunk3.Blocks)-1].WithdrawRoot,
}
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, []*encoding.Chunk{chunk1, chunk2, chunk3}, chainConfig, nil)
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, nil, []*encoding.Chunk{chunk1, chunk2, chunk3}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(13), endBlock1)
@ -625,7 +641,7 @@ func TestValidateBatchCodecv1(t *testing.T) {
StateRoot: chunk4.Blocks[len(chunk4.Blocks)-1].Header.Root,
WithdrawRoot: chunk4.Blocks[len(chunk4.Blocks)-1].WithdrawRoot,
}
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, []*encoding.Chunk{chunk4}, chainConfig, nil)
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, nil, []*encoding.Chunk{chunk4}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(17), endBlock2)
@ -658,7 +674,7 @@ func TestValidateBatchCodecv2(t *testing.T) {
WithdrawRoot: chunk3.Blocks[len(chunk3.Blocks)-1].WithdrawRoot,
}
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, []*encoding.Chunk{chunk1, chunk2, chunk3}, chainConfig, nil)
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, nil, []*encoding.Chunk{chunk1, chunk2, chunk3}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(13), endBlock1)
@ -678,7 +694,7 @@ func TestValidateBatchCodecv2(t *testing.T) {
StateRoot: chunk4.Blocks[len(chunk4.Blocks)-1].Header.Root,
WithdrawRoot: chunk4.Blocks[len(chunk4.Blocks)-1].WithdrawRoot,
}
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, []*encoding.Chunk{chunk4}, chainConfig, nil)
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, nil, []*encoding.Chunk{chunk4}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(17), endBlock2)
@ -711,7 +727,7 @@ func TestValidateBatchCodecv3(t *testing.T) {
WithdrawRoot: chunk3.Blocks[len(chunk3.Blocks)-1].WithdrawRoot,
}
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, []*encoding.Chunk{chunk1, chunk2, chunk3}, chainConfig, nil)
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, nil, []*encoding.Chunk{chunk1, chunk2, chunk3}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(13), endBlock1)
@ -731,7 +747,7 @@ func TestValidateBatchCodecv3(t *testing.T) {
StateRoot: chunk4.Blocks[len(chunk4.Blocks)-1].Header.Root,
WithdrawRoot: chunk4.Blocks[len(chunk4.Blocks)-1].WithdrawRoot,
}
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, []*encoding.Chunk{chunk4}, chainConfig, nil)
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, nil, []*encoding.Chunk{chunk4}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(17), endBlock2)
@ -758,7 +774,7 @@ func TestValidateBatchUpgrades(t *testing.T) {
WithdrawRoot: chunk1.Blocks[len(chunk1.Blocks)-1].WithdrawRoot,
}
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, []*encoding.Chunk{chunk1}, chainConfig, nil)
endBlock1, finalizedBatchMeta1, err := validateBatch(event1.BatchIndex.Uint64(), event1, parentBatchMeta1, nil, []*encoding.Chunk{chunk1}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(2), endBlock1)
@ -778,7 +794,7 @@ func TestValidateBatchUpgrades(t *testing.T) {
StateRoot: chunk2.Blocks[len(chunk2.Blocks)-1].Header.Root,
WithdrawRoot: chunk2.Blocks[len(chunk2.Blocks)-1].WithdrawRoot,
}
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, []*encoding.Chunk{chunk2}, chainConfig, nil)
endBlock2, finalizedBatchMeta2, err := validateBatch(event2.BatchIndex.Uint64(), event2, parentBatchMeta2, nil, []*encoding.Chunk{chunk2}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(3), endBlock2)
@ -798,7 +814,7 @@ func TestValidateBatchUpgrades(t *testing.T) {
StateRoot: chunk3.Blocks[len(chunk3.Blocks)-1].Header.Root,
WithdrawRoot: chunk3.Blocks[len(chunk3.Blocks)-1].WithdrawRoot,
}
endBlock3, finalizedBatchMeta3, err := validateBatch(event3.BatchIndex.Uint64(), event3, parentBatchMeta3, []*encoding.Chunk{chunk3}, chainConfig, nil)
endBlock3, finalizedBatchMeta3, err := validateBatch(event3.BatchIndex.Uint64(), event3, parentBatchMeta3, nil, []*encoding.Chunk{chunk3}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(13), endBlock3)
@ -818,7 +834,7 @@ func TestValidateBatchUpgrades(t *testing.T) {
StateRoot: chunk4.Blocks[len(chunk4.Blocks)-1].Header.Root,
WithdrawRoot: chunk4.Blocks[len(chunk4.Blocks)-1].WithdrawRoot,
}
endBlock4, finalizedBatchMeta4, err := validateBatch(event4.BatchIndex.Uint64(), event4, parentBatchMeta4, []*encoding.Chunk{chunk4}, chainConfig, nil)
endBlock4, finalizedBatchMeta4, err := validateBatch(event4.BatchIndex.Uint64(), event4, parentBatchMeta4, nil, []*encoding.Chunk{chunk4}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(17), endBlock4)
@ -851,19 +867,19 @@ func TestValidateBatchInFinalizeByBundle(t *testing.T) {
WithdrawRoot: chunk4.Blocks[len(chunk4.Blocks)-1].WithdrawRoot,
}
endBlock1, finalizedBatchMeta1, err := validateBatch(0, event, &rawdb.FinalizedBatchMeta{}, []*encoding.Chunk{chunk1}, chainConfig, nil)
endBlock1, finalizedBatchMeta1, err := validateBatch(0, event, &rawdb.FinalizedBatchMeta{}, nil, []*encoding.Chunk{chunk1}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(2), endBlock1)
endBlock2, finalizedBatchMeta2, err := validateBatch(1, event, finalizedBatchMeta1, []*encoding.Chunk{chunk2}, chainConfig, nil)
endBlock2, finalizedBatchMeta2, err := validateBatch(1, event, finalizedBatchMeta1, nil, []*encoding.Chunk{chunk2}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(3), endBlock2)
endBlock3, finalizedBatchMeta3, err := validateBatch(2, event, finalizedBatchMeta2, []*encoding.Chunk{chunk3}, chainConfig, nil)
endBlock3, finalizedBatchMeta3, err := validateBatch(2, event, finalizedBatchMeta2, nil, []*encoding.Chunk{chunk3}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(13), endBlock3)
endBlock4, finalizedBatchMeta4, err := validateBatch(3, event, finalizedBatchMeta3, []*encoding.Chunk{chunk4}, chainConfig, nil)
endBlock4, finalizedBatchMeta4, err := validateBatch(3, event, finalizedBatchMeta3, nil, []*encoding.Chunk{chunk4}, chainConfig, nil)
assert.NoError(t, err)
assert.Equal(t, uint64(17), endBlock4)