mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
* port changes from #1013 * port changes from #1068 * go.mod tidy * fix compile error * fix goimports * fix log * address review comments * upgrade golang.org/x/net to 0.23.0 * port changes from #1018 * fix tests and linter errors * address review comments * refactor rollup sync service / verifier to use CalldataBlobSource to retrieve data from L1 * add configuration and initialize blob clients * fix unit tests * remove unused code * address review comments * address more review comments * Allow using MPT * fix issues after merge * bump version --------- Co-authored-by: Ömer Faruk Irmak <omerfirmak@gmail.com> Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
162 lines
5.1 KiB
Go
162 lines
5.1 KiB
Go
package da
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/scroll-tech/da-codec/encoding"
|
|
|
|
"github.com/scroll-tech/go-ethereum/accounts/abi"
|
|
"github.com/scroll-tech/go-ethereum/ethdb"
|
|
"github.com/scroll-tech/go-ethereum/rollup/da_syncer/blob_client"
|
|
"github.com/scroll-tech/go-ethereum/rollup/da_syncer/serrors"
|
|
"github.com/scroll-tech/go-ethereum/rollup/l1"
|
|
)
|
|
|
|
const (
|
|
callDataBlobSourceFetchBlockRange uint64 = 500
|
|
)
|
|
|
|
var (
|
|
ErrSourceExhausted = errors.New("data source has been exhausted")
|
|
)
|
|
|
|
type CalldataBlobSource struct {
|
|
ctx context.Context
|
|
l1Reader *l1.Reader
|
|
blobClient blob_client.BlobClient
|
|
l1Height uint64
|
|
scrollChainABI *abi.ABI
|
|
db ethdb.Database
|
|
|
|
l1Finalized uint64
|
|
}
|
|
|
|
func NewCalldataBlobSource(ctx context.Context, l1height uint64, l1Reader *l1.Reader, blobClient blob_client.BlobClient, db ethdb.Database) (*CalldataBlobSource, error) {
|
|
scrollChainABI, err := l1.ScrollChainMetaData.GetAbi()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get scroll chain abi: %w", err)
|
|
}
|
|
return &CalldataBlobSource{
|
|
ctx: ctx,
|
|
l1Reader: l1Reader,
|
|
blobClient: blobClient,
|
|
l1Height: l1height,
|
|
scrollChainABI: scrollChainABI,
|
|
db: db,
|
|
}, nil
|
|
}
|
|
|
|
func (ds *CalldataBlobSource) NextData() (Entries, error) {
|
|
var err error
|
|
to := ds.l1Height + callDataBlobSourceFetchBlockRange
|
|
|
|
// If there's not enough finalized blocks to request up to, we need to query finalized block number.
|
|
// Otherwise, we know that there's more finalized blocks than we want to request up to
|
|
// -> no need to query finalized block number
|
|
if to > ds.l1Finalized {
|
|
ds.l1Finalized, err = ds.l1Reader.GetLatestFinalizedBlockNumber()
|
|
if err != nil {
|
|
return nil, serrors.NewTemporaryError(fmt.Errorf("failed to query GetLatestFinalizedBlockNumber, error: %v", err))
|
|
}
|
|
// make sure we don't request more than finalized blocks
|
|
to = min(to, ds.l1Finalized)
|
|
}
|
|
|
|
if ds.l1Height > to {
|
|
return nil, ErrSourceExhausted
|
|
}
|
|
|
|
rollupEvents, err := ds.l1Reader.FetchRollupEventsInRange(ds.l1Height, to)
|
|
if err != nil {
|
|
return nil, serrors.NewTemporaryError(fmt.Errorf("cannot get rollup events, l1Height: %d, error: %v", ds.l1Height, err))
|
|
}
|
|
da, err := ds.processRollupEventsToDA(rollupEvents)
|
|
if err != nil {
|
|
return nil, serrors.NewTemporaryError(fmt.Errorf("failed to process rollup events to DA, error: %v", err))
|
|
}
|
|
|
|
ds.l1Height = to + 1
|
|
return da, nil
|
|
}
|
|
|
|
func (ds *CalldataBlobSource) SetL1Height(l1Height uint64) {
|
|
ds.l1Height = l1Height
|
|
}
|
|
|
|
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
|
|
var err error
|
|
for _, rollupEvent := range rollupEvents {
|
|
switch rollupEvent.Type() {
|
|
case l1.CommitEventType:
|
|
commitEvent, ok := rollupEvent.(*l1.CommitBatchEvent)
|
|
// this should never happen because we just check event type
|
|
if !ok {
|
|
return nil, fmt.Errorf("unexpected type of rollup event: %T", rollupEvent)
|
|
}
|
|
if entry, err = ds.getCommitBatchDA(commitEvent); err != nil {
|
|
return nil, fmt.Errorf("failed to get commit batch da: %v, err: %w", rollupEvent.BatchIndex().Uint64(), err)
|
|
}
|
|
|
|
case l1.RevertEventType:
|
|
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:
|
|
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())
|
|
}
|
|
|
|
entries = append(entries, entry)
|
|
}
|
|
return entries, nil
|
|
}
|
|
|
|
func (ds *CalldataBlobSource) getCommitBatchDA(commitEvent *l1.CommitBatchEvent) (Entry, error) {
|
|
if commitEvent.BatchIndex().Uint64() == 0 {
|
|
return NewCommitBatchDAV0Empty(), nil
|
|
}
|
|
|
|
args, err := ds.l1Reader.FetchCommitTxData(commitEvent)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to fetch commit tx data of batch %d, tx hash: %v, err: %w", commitEvent.BatchIndex().Uint64(), commitEvent.TxHash().Hex(), err)
|
|
}
|
|
|
|
codec, err := encoding.CodecFromVersion(encoding.CodecVersion(args.Version))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unsupported codec version: %v, batch index: %v, err: %w", args.Version, commitEvent.BatchIndex().Uint64(), err)
|
|
}
|
|
|
|
switch codec.Version() {
|
|
case 0:
|
|
return NewCommitBatchDAV0(ds.db, codec, commitEvent, args.ParentBatchHeader, args.Chunks, args.SkippedL1MessageBitmap)
|
|
case 1, 2, 3, 4:
|
|
return NewCommitBatchDAWithBlob(ds.ctx, ds.db, ds.l1Reader, ds.blobClient, codec, commitEvent, args.ParentBatchHeader, args.Chunks, args.SkippedL1MessageBitmap)
|
|
default:
|
|
return nil, fmt.Errorf("failed to decode DA, codec version is unknown: codec version: %d", args.Version)
|
|
}
|
|
}
|