@@ -2,13 +2,16 @@ package logic
22
33import (
44 "context"
5+ "fmt"
56 "math/big"
67
8+ "github.com/scroll-tech/da-codec/encoding"
79 "github.com/scroll-tech/go-ethereum/common"
810 "github.com/scroll-tech/go-ethereum/core/types"
911 "github.com/scroll-tech/go-ethereum/crypto"
1012 "github.com/scroll-tech/go-ethereum/ethclient"
1113 "github.com/scroll-tech/go-ethereum/log"
14+ "github.com/scroll-tech/go-ethereum/rollup/da_syncer/blob_client"
1215
1316 backendabi "scroll-tech/bridge-history-api/abi"
1417 "scroll-tech/bridge-history-api/internal/config"
@@ -19,15 +22,17 @@ import (
1922
2023// L1EventParser the l1 event parser
2124type L1EventParser struct {
22- cfg * config.FetcherConfig
23- client * ethclient.Client
25+ cfg * config.FetcherConfig
26+ client * ethclient.Client
27+ blobClient blob_client.BlobClient
2428}
2529
2630// NewL1EventParser creates l1 event parser
27- func NewL1EventParser (cfg * config.FetcherConfig , client * ethclient.Client ) * L1EventParser {
31+ func NewL1EventParser (cfg * config.FetcherConfig , client * ethclient.Client , blobClient blob_client. BlobClient ) * L1EventParser {
2832 return & L1EventParser {
29- cfg : cfg ,
30- client : client ,
33+ cfg : cfg ,
34+ client : client ,
35+ blobClient : blobClient ,
3136 }
3237}
3338
@@ -233,6 +238,7 @@ func (e *L1EventParser) ParseL1SingleCrossChainEventLogs(ctx context.Context, lo
233238
234239// ParseL1BatchEventLogs parses L1 watched batch events.
235240func (e * L1EventParser ) ParseL1BatchEventLogs (ctx context.Context , logs []types.Log , client * ethclient.Client ) ([]* orm.BatchEvent , error ) {
241+ txBlobIndexMap := make (map [common.Hash ]int )
236242 var l1BatchEvents []* orm.BatchEvent
237243 for _ , vlog := range logs {
238244 switch vlog .Topics [0 ] {
@@ -247,11 +253,37 @@ func (e *L1EventParser) ParseL1BatchEventLogs(ctx context.Context, logs []types.
247253 log .Error ("Failed to get commit batch tx or the tx is still pending" , "err" , err , "isPending" , isPending )
248254 return nil , err
249255 }
250- startBlock , endBlock , err := utils .GetBatchRangeFromCalldata (commitTx .Data ())
256+ version , startBlock , endBlock , err := utils .GetBatchRangeFromCalldata (commitTx .Data ())
251257 if err != nil {
252258 log .Error ("Failed to get batch range from calldata" , "hash" , commitTx .Hash ().String (), "height" , vlog .BlockNumber )
253259 return nil , err
254260 }
261+ if version >= 7 { // It's a batch with version >= 7.
262+ currentIndex := txBlobIndexMap [vlog .TxHash ]
263+
264+ if currentIndex >= len (commitTx .BlobHashes ()) {
265+ return nil , fmt .Errorf ("not enough blob hashes for commit transaction: %s, index in tx: %d, total blobs: %d, batch index: %d, batch hash: %s" ,
266+ vlog .TxHash .String (), currentIndex , len (commitTx .BlobHashes ()), event .BatchIndex .Uint64 (), event .BatchHash .String ())
267+ }
268+ header , err := client .HeaderByHash (ctx , vlog .BlockHash )
269+ if err != nil {
270+ return nil , fmt .Errorf ("failed to get L1 block header for blob context, blockHash: %s, err: %w" , vlog .BlockHash .Hex (), err )
271+ }
272+ blobVersionedHash := commitTx .BlobHashes ()[currentIndex ]
273+ blocks , err := e .processVersionedBlob (ctx , version , blobVersionedHash , header .Time , event .BatchIndex .Uint64 ())
274+ if err != nil {
275+ return nil , fmt .Errorf ("failed to process versioned blob, blobVersionedHash: %s, block number: %d, blob index: %d, err: %w" ,
276+ blobVersionedHash .String (), vlog .BlockNumber , currentIndex , err )
277+ }
278+ if len (blocks ) == 0 {
279+ return nil , fmt .Errorf ("no blocks found in the blob, blobVersionedHash: %s, block number: %d, blob index: %d" ,
280+ blobVersionedHash .String (), vlog .BlockNumber , currentIndex )
281+ }
282+ startBlock = blocks [0 ].Number ()
283+ endBlock = blocks [len (blocks )- 1 ].Number ()
284+
285+ txBlobIndexMap [vlog .TxHash ] = currentIndex + 1
286+ }
255287 l1BatchEvents = append (l1BatchEvents , & orm.BatchEvent {
256288 BatchStatus : int (btypes .BatchStatusTypeCommitted ),
257289 BatchIndex : event .BatchIndex .Uint64 (),
@@ -260,8 +292,8 @@ func (e *L1EventParser) ParseL1BatchEventLogs(ctx context.Context, logs []types.
260292 EndBlockNumber : endBlock ,
261293 L1BlockNumber : vlog .BlockNumber ,
262294 })
263- case backendabi .L1RevertBatchEventSig :
264- event := backendabi.L1RevertBatchEvent {}
295+ case backendabi .L1RevertBatchV0EventSig :
296+ event := backendabi.L1RevertBatchV0Event {}
265297 if err := utils .UnpackLog (backendabi .IScrollChainABI , & event , "RevertBatch" , vlog ); err != nil {
266298 log .Error ("Failed to unpack RevertBatch event" , "err" , err )
267299 return nil , err
@@ -272,6 +304,19 @@ func (e *L1EventParser) ParseL1BatchEventLogs(ctx context.Context, logs []types.
272304 BatchHash : event .BatchHash .String (),
273305 L1BlockNumber : vlog .BlockNumber ,
274306 })
307+ case backendabi .L1RevertBatchV7EventSig :
308+ event := backendabi.L1RevertBatchV7Event {}
309+ if err := utils .UnpackLog (backendabi .IScrollChainABI , & event , "RevertBatch" , vlog ); err != nil {
310+ log .Error ("Failed to unpack RevertBatch event" , "err" , err )
311+ return nil , err
312+ }
313+ for i := event .StartBatchIndex .Uint64 (); i <= event .FinishBatchIndex .Uint64 (); i ++ {
314+ l1BatchEvents = append (l1BatchEvents , & orm.BatchEvent {
315+ BatchStatus : int (btypes .BatchStatusTypeReverted ),
316+ BatchIndex : i ,
317+ L1BlockNumber : vlog .BlockNumber ,
318+ })
319+ }
275320 case backendabi .L1FinalizeBatchEventSig :
276321 event := backendabi.L1FinalizeBatchEvent {}
277322 if err := utils .UnpackLog (backendabi .IScrollChainABI , & event , "FinalizeBatch" , vlog ); err != nil {
@@ -389,3 +434,32 @@ func getRealFromAddress(ctx context.Context, eventSender common.Address, eventMe
389434 }
390435 return sender .String (), nil
391436}
437+
438+ func (e * L1EventParser ) processVersionedBlob (ctx context.Context , version uint8 , versionedHash common.Hash , l1BlockTime uint64 , batchIndex uint64 ) ([]encoding.DABlock , error ) {
439+ blob , err := e .blobClient .GetBlobByVersionedHashAndBlockTime (ctx , versionedHash , l1BlockTime )
440+ if err != nil {
441+ return nil , fmt .Errorf ("failed to get blob %s: %w" , versionedHash .Hex (), err )
442+ }
443+ if blob == nil {
444+ return nil , fmt .Errorf ("blob %s not found" , versionedHash .Hex ())
445+ }
446+
447+ codec , err := encoding .CodecFromVersion (encoding .CodecVersion (version ))
448+ if err != nil {
449+ return nil , fmt .Errorf ("unsupported codec version: %v, batch index: %v, err: %w" , version , batchIndex , err )
450+ }
451+
452+ blobPayload , err := codec .DecodeBlob (blob )
453+ if err != nil {
454+ return nil , fmt .Errorf ("blob %s decode error: %w" , versionedHash .Hex (), err )
455+ }
456+
457+ blocks := blobPayload .Blocks ()
458+ if len (blocks ) == 0 {
459+ return nil , fmt .Errorf ("empty blocks in blob %s" , versionedHash .Hex ())
460+ }
461+
462+ log .Debug ("Successfully processed blob" , "versionedHash" , versionedHash .Hex (), "blocksCount" , len (blocks ), "batchIndex" , batchIndex )
463+
464+ return blocks , nil
465+ }
0 commit comments