Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(rollup sync service): use CalldataBlobSource to retrieve data from L1 #1103

Open
wants to merge 20 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1629,15 +1629,15 @@ func setEnableRollupVerify(ctx *cli.Context, cfg *ethconfig.Config) {
func setDA(ctx *cli.Context, cfg *ethconfig.Config) {
if ctx.IsSet(DASyncEnabledFlag.Name) {
cfg.EnableDASyncing = ctx.Bool(DASyncEnabledFlag.Name)
if ctx.IsSet(DABlobScanAPIEndpointFlag.Name) {
cfg.DA.BlobScanAPIEndpoint = ctx.String(DABlobScanAPIEndpointFlag.Name)
}
if ctx.IsSet(DABlockNativeAPIEndpointFlag.Name) {
cfg.DA.BlockNativeAPIEndpoint = ctx.String(DABlockNativeAPIEndpointFlag.Name)
}
if ctx.IsSet(DABeaconNodeAPIEndpointFlag.Name) {
cfg.DA.BeaconNodeAPIEndpoint = ctx.String(DABeaconNodeAPIEndpointFlag.Name)
}
}
if ctx.IsSet(DABlobScanAPIEndpointFlag.Name) {
cfg.DA.BlobScanAPIEndpoint = ctx.String(DABlobScanAPIEndpointFlag.Name)
}
if ctx.IsSet(DABlockNativeAPIEndpointFlag.Name) {
cfg.DA.BlockNativeAPIEndpoint = ctx.String(DABlockNativeAPIEndpointFlag.Name)
}
if ctx.IsSet(DABeaconNodeAPIEndpointFlag.Name) {
cfg.DA.BeaconNodeAPIEndpoint = ctx.String(DABeaconNodeAPIEndpointFlag.Name)
}
}

Expand Down
3 changes: 2 additions & 1 deletion core/rawdb/accessors_rollup_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ type ChunkBlockRange struct {

// CommittedBatchMeta holds metadata for committed batches.
type CommittedBatchMeta struct {
Version uint8
Version uint8
// BlobVersionedHashes are the versioned hashes of the blobs in the batch. Currently unused. Left for compatibility.
BlobVersionedHashes []common.Hash
ChunkBlockRanges []*ChunkBlockRange
}
Expand Down
2 changes: 1 addition & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client l1.Client) (*Ether

if config.EnableRollupVerify {
// initialize and start rollup event sync service
eth.rollupSyncService, err = rollup_sync_service.NewRollupSyncService(context.Background(), chainConfig, eth.chainDb, l1Client, eth.blockchain, stack)
eth.rollupSyncService, err = rollup_sync_service.NewRollupSyncService(context.Background(), chainConfig, eth.chainDb, l1Client, eth.blockchain, stack, config.DA)
if err != nil {
return nil, fmt.Errorf("cannot initialize rollup event sync service: %w", err)
}
Expand Down
24 changes: 22 additions & 2 deletions rollup/da_syncer/da/calldata_blob_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,18 @@ func (ds *CalldataBlobSource) NextData() (Entries, error) {
return da, nil
}

func (ds *CalldataBlobSource) SetL1Height(l1Height uint64) {
ds.l1Height = l1Height
}
Comment on lines +84 to +86
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation and documentation for state management methods.

The new methods expose and modify internal state:

  1. SetL1Height should validate that the new height doesn't exceed l1Finalized
  2. L1Finalized should document that the value might be stale until the next NextData call
+// SetL1Height updates the L1 block height for data fetching.
+// The new height must not exceed the finalized block height.
 func (ds *CalldataBlobSource) SetL1Height(l1Height uint64) {
+    if l1Height > ds.l1Finalized {
+        panic("attempted to set L1 height beyond finalized height")
+    }
     ds.l1Height = l1Height
 }

+// L1Finalized returns the last known L1 finalized block height.
+// Note: This value might be stale until the next NextData call.
 func (ds *CalldataBlobSource) L1Finalized() uint64 {
     return ds.l1Finalized
 }

Also applies to: 92-94


func (ds *CalldataBlobSource) L1Height() uint64 {
return ds.l1Height
}

func (ds *CalldataBlobSource) L1Finalized() uint64 {
return ds.l1Finalized
}

func (ds *CalldataBlobSource) processRollupEventsToDA(rollupEvents l1.RollupEvents) (Entries, error) {
var entries Entries
var entry Entry
Expand All @@ -102,10 +110,22 @@ func (ds *CalldataBlobSource) processRollupEventsToDA(rollupEvents l1.RollupEven
}

case l1.RevertEventType:
entry = NewRevertBatch(rollupEvent.BatchIndex().Uint64())
revertEvent, ok := rollupEvent.(*l1.RevertBatchEvent)
// this should never happen because we just check event type
if !ok {
return nil, fmt.Errorf("unexpected type of rollup event: %T", rollupEvent)
}

entry = NewRevertBatch(revertEvent)

case l1.FinalizeEventType:
entry = NewFinalizeBatch(rollupEvent.BatchIndex().Uint64())
finalizeEvent, ok := rollupEvent.(*l1.FinalizeBatchEvent)
// this should never happen because we just check event type
if !ok {
return nil, fmt.Errorf("unexpected type of rollup event: %T", rollupEvent)
}

entry = NewFinalizeBatch(finalizeEvent)

default:
return nil, fmt.Errorf("unknown rollup event, type: %v", rollupEvent.Type())
Expand Down
31 changes: 24 additions & 7 deletions rollup/da_syncer/da/commitV0.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/scroll-tech/da-codec/encoding"

"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/rawdb"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/ethdb"
Expand All @@ -14,14 +15,14 @@ import (
)

type CommitBatchDAV0 struct {
version uint8
version encoding.CodecVersion
batchIndex uint64
parentTotalL1MessagePopped uint64
skippedL1MessageBitmap []byte
chunks []*encoding.DAChunkRawTx
l1Txs []*types.L1MessageTx

l1BlockNumber uint64
event *l1.CommitBatchEvent
}

func NewCommitBatchDAV0(db ethdb.Database,
Expand All @@ -36,16 +37,16 @@ func NewCommitBatchDAV0(db ethdb.Database,
return nil, fmt.Errorf("failed to unpack chunks: %d, err: %w", commitEvent.BatchIndex().Uint64(), err)
}

return NewCommitBatchDAV0WithChunks(db, uint8(codec.Version()), commitEvent.BatchIndex().Uint64(), parentBatchHeader, decodedChunks, skippedL1MessageBitmap, commitEvent.BlockNumber())
return NewCommitBatchDAV0WithChunks(db, codec.Version(), commitEvent.BatchIndex().Uint64(), parentBatchHeader, decodedChunks, skippedL1MessageBitmap, commitEvent)
}

func NewCommitBatchDAV0WithChunks(db ethdb.Database,
version uint8,
version encoding.CodecVersion,
batchIndex uint64,
parentBatchHeader []byte,
decodedChunks []*encoding.DAChunkRawTx,
skippedL1MessageBitmap []byte,
l1BlockNumber uint64,
event *l1.CommitBatchEvent,
) (*CommitBatchDAV0, error) {
parentTotalL1MessagePopped := getBatchTotalL1MessagePopped(parentBatchHeader)
l1Txs, err := getL1Messages(db, parentTotalL1MessagePopped, skippedL1MessageBitmap, getTotalMessagesPoppedFromChunks(decodedChunks))
Expand All @@ -60,7 +61,7 @@ func NewCommitBatchDAV0WithChunks(db ethdb.Database,
skippedL1MessageBitmap: skippedL1MessageBitmap,
chunks: decodedChunks,
l1Txs: l1Txs,
l1BlockNumber: l1BlockNumber,
event: event,
}, nil
}

Expand All @@ -70,12 +71,28 @@ func NewCommitBatchDAV0Empty() *CommitBatchDAV0 {
}
}

func (c *CommitBatchDAV0) Version() encoding.CodecVersion {
return c.version
}

func (c *CommitBatchDAV0) Chunks() []*encoding.DAChunkRawTx {
return c.chunks
}

func (c *CommitBatchDAV0) BlobVersionedHashes() []common.Hash {
return nil
}

func (c *CommitBatchDAV0) Type() Type {
return CommitBatchV0Type
}

func (c *CommitBatchDAV0) L1BlockNumber() uint64 {
return c.l1BlockNumber
return c.event.BlockNumber()
}

func (c *CommitBatchDAV0) Event() l1.RollupEvent {
return c.event
}

func (c *CommitBatchDAV0) BatchIndex() uint64 {
Expand Down
21 changes: 18 additions & 3 deletions rollup/da_syncer/da/commitV1.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (

type CommitBatchDAV1 struct {
*CommitBatchDAV0

versionedHashes []common.Hash
}

func NewCommitBatchDAWithBlob(ctx context.Context, db ethdb.Database,
Expand All @@ -33,11 +35,17 @@ func NewCommitBatchDAWithBlob(ctx context.Context, db ethdb.Database,
return nil, fmt.Errorf("failed to unpack chunks: %v, err: %w", commitEvent.BatchIndex().Uint64(), err)
}

versionedHash, err := l1Reader.FetchTxBlobHash(commitEvent.TxHash(), commitEvent.BlockHash())
versionedHashes, err := l1Reader.FetchTxBlobHashes(commitEvent.TxHash(), commitEvent.BlockHash())
if err != nil {
return nil, fmt.Errorf("failed to fetch blob hash, err: %w", err)
}

// with CommitBatchDAV1 we expect only one versioned hash as we commit only one blob per batch submission
if len(versionedHashes) != 1 {
return nil, fmt.Errorf("unexpected number of versioned hashes: %d", len(versionedHashes))
}
versionedHash := versionedHashes[0]

header, err := l1Reader.FetchBlockHeaderByNumber(commitEvent.BlockNumber())
if err != nil {
return nil, fmt.Errorf("failed to get header by number, err: %w", err)
Expand Down Expand Up @@ -70,14 +78,21 @@ func NewCommitBatchDAWithBlob(ctx context.Context, db ethdb.Database,
return nil, fmt.Errorf("decodedChunks is nil after decoding")
}

v0, err := NewCommitBatchDAV0WithChunks(db, uint8(codec.Version()), commitEvent.BatchIndex().Uint64(), parentBatchHeader, decodedChunks, skippedL1MessageBitmap, commitEvent.BlockNumber())
v0, err := NewCommitBatchDAV0WithChunks(db, codec.Version(), commitEvent.BatchIndex().Uint64(), parentBatchHeader, decodedChunks, skippedL1MessageBitmap, commitEvent)
if err != nil {
return nil, err
}

return &CommitBatchDAV1{v0}, nil
return &CommitBatchDAV1{
CommitBatchDAV0: v0,
versionedHashes: versionedHashes,
}, nil
}

func (c *CommitBatchDAV1) Type() Type {
return CommitBatchWithBlobType
}

func (c *CommitBatchDAV1) BlobVersionedHashes() []common.Hash {
return c.versionedHashes
}
8 changes: 8 additions & 0 deletions rollup/da_syncer/da/da.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ package da
import (
"math/big"

"github.com/scroll-tech/da-codec/encoding"

"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/rollup/l1"
)

type Type int
Expand All @@ -25,11 +29,15 @@ type Entry interface {
BatchIndex() uint64
L1BlockNumber() uint64
CompareTo(Entry) int
Event() l1.RollupEvent
}

type EntryWithBlocks interface {
Entry
Blocks() []*PartialBlock
Version() encoding.CodecVersion
Chunks() []*encoding.DAChunkRawTx
BlobVersionedHashes() []common.Hash
}

type Entries []Entry
Expand Down
20 changes: 13 additions & 7 deletions rollup/da_syncer/da/finalize.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package da

type FinalizeBatch struct {
batchIndex uint64
import (
"github.com/scroll-tech/go-ethereum/rollup/l1"
)

l1BlockNumber uint64
type FinalizeBatch struct {
event *l1.FinalizeBatchEvent
}

func NewFinalizeBatch(batchIndex uint64) *FinalizeBatch {
func NewFinalizeBatch(event *l1.FinalizeBatchEvent) *FinalizeBatch {
return &FinalizeBatch{
batchIndex: batchIndex,
event: event,
}
}

Expand All @@ -17,11 +19,15 @@ func (f *FinalizeBatch) Type() Type {
}

func (f *FinalizeBatch) L1BlockNumber() uint64 {
return f.l1BlockNumber
return f.event.BlockNumber()
}

func (f *FinalizeBatch) BatchIndex() uint64 {
return f.batchIndex
return f.event.BatchIndex().Uint64()
}

func (f *FinalizeBatch) Event() l1.RollupEvent {
return f.event
}

func (f *FinalizeBatch) CompareTo(other Entry) int {
Expand Down
20 changes: 13 additions & 7 deletions rollup/da_syncer/da/revert.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package da

type RevertBatch struct {
batchIndex uint64
import (
"github.com/scroll-tech/go-ethereum/rollup/l1"
)

l1BlockNumber uint64
type RevertBatch struct {
event *l1.RevertBatchEvent
}

func NewRevertBatch(batchIndex uint64) *RevertBatch {
func NewRevertBatch(event *l1.RevertBatchEvent) *RevertBatch {
return &RevertBatch{
batchIndex: batchIndex,
event: event,
}
}

Expand All @@ -17,10 +19,14 @@ func (r *RevertBatch) Type() Type {
}

func (r *RevertBatch) L1BlockNumber() uint64 {
return r.l1BlockNumber
return r.event.BlockNumber()
}
func (r *RevertBatch) BatchIndex() uint64 {
return r.batchIndex
return r.event.BatchIndex().Uint64()
}

func (r *RevertBatch) Event() l1.RollupEvent {
return r.event
}

func (r *RevertBatch) CompareTo(other Entry) int {
Expand Down
20 changes: 20 additions & 0 deletions rollup/l1/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,26 @@ type FinalizeBatchEvent struct {
blockNumber uint64
}

func NewFinalizeBatchEvent(
batchIndex *big.Int,
batchHash common.Hash,
stateRoot common.Hash,
withdrawRoot common.Hash,
txHash common.Hash,
blockHash common.Hash,
blockNumber uint64,
) *FinalizeBatchEvent {
return &FinalizeBatchEvent{
batchIndex: batchIndex,
batchHash: batchHash,
stateRoot: stateRoot,
withdrawRoot: withdrawRoot,
txHash: txHash,
blockHash: blockHash,
blockNumber: blockNumber,
}
}

func (f *FinalizeBatchEvent) TxHash() common.Hash {
return f.txHash
}
Expand Down
13 changes: 8 additions & 5 deletions rollup/l1/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,23 @@ func (r *Reader) FetchTxData(txHash, blockHash common.Hash) ([]byte, error) {
if err != nil {
return nil, err
}

return tx.Data(), nil
}

// FetchTxBlobHash fetches tx blob hash corresponding to given event log
func (r *Reader) FetchTxBlobHash(txHash, blockHash common.Hash) (common.Hash, error) {
// FetchTxBlobHashes fetches tx blob hash corresponding to given event log
func (r *Reader) FetchTxBlobHashes(txHash, blockHash common.Hash) ([]common.Hash, error) {
tx, err := r.fetchTx(txHash, blockHash)
if err != nil {
return common.Hash{}, err
return nil, fmt.Errorf("failed to fetch tx, tx hash: %v, block hash: %v, err: %w", txHash.Hex(), blockHash.Hex(), err)
}

blobHashes := tx.BlobHashes()
if len(blobHashes) == 0 {
return common.Hash{}, fmt.Errorf("transaction does not contain any blobs, tx hash: %v", txHash.Hex())
return nil, fmt.Errorf("transaction does not contain any blobs, tx hash: %v", txHash.Hex())
}
return blobHashes[0], nil

return blobHashes, nil
}

// FetchRollupEventsInRange retrieves and parses commit/revert/finalize rollup events between block numbers: [from, to].
Expand Down
Loading
Loading