github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/core/rawdb/accessors_rollup_event.go (about)

     1  package rawdb
     2  
     3  import (
     4  	"bytes"
     5  	"math/big"
     6  
     7  	"github.com/scroll-tech/go-ethereum/common"
     8  	"github.com/scroll-tech/go-ethereum/ethdb"
     9  	"github.com/scroll-tech/go-ethereum/log"
    10  	"github.com/scroll-tech/go-ethereum/rlp"
    11  )
    12  
    13  // ChunkBlockRange represents the range of blocks within a chunk.
    14  type ChunkBlockRange struct {
    15  	StartBlockNumber uint64
    16  	EndBlockNumber   uint64
    17  }
    18  
    19  // FinalizedBatchMeta holds metadata for finalized batches.
    20  type FinalizedBatchMeta struct {
    21  	BatchHash            common.Hash
    22  	TotalL1MessagePopped uint64 // total number of L1 messages popped before and in this batch.
    23  	StateRoot            common.Hash
    24  	WithdrawRoot         common.Hash
    25  }
    26  
    27  // WriteRollupEventSyncedL1BlockNumber stores the latest synced L1 block number related to rollup events in the database.
    28  func WriteRollupEventSyncedL1BlockNumber(db ethdb.KeyValueWriter, l1BlockNumber uint64) {
    29  	value := big.NewInt(0).SetUint64(l1BlockNumber).Bytes()
    30  	if err := db.Put(rollupEventSyncedL1BlockNumberKey, value); err != nil {
    31  		log.Crit("failed to store rollup event synced L1 block number for rollup event", "err", err)
    32  	}
    33  }
    34  
    35  // ReadRollupEventSyncedL1BlockNumber fetches the highest synced L1 block number associated with rollup events from the database.
    36  func ReadRollupEventSyncedL1BlockNumber(db ethdb.Reader) *uint64 {
    37  	data, err := db.Get(rollupEventSyncedL1BlockNumberKey)
    38  	if err != nil && isNotFoundErr(err) {
    39  		return nil
    40  	}
    41  	if err != nil {
    42  		log.Crit("failed to read rollup event synced L1 block number from database", "err", err)
    43  	}
    44  
    45  	number := new(big.Int).SetBytes(data)
    46  	if !number.IsUint64() {
    47  		log.Crit("unexpected rollup event synced L1 block number in database", "number", number)
    48  	}
    49  
    50  	rollupEventSyncedL1BlockNumber := number.Uint64()
    51  	return &rollupEventSyncedL1BlockNumber
    52  }
    53  
    54  // WriteBatchChunkRanges writes the block ranges for each chunk within a batch to the database.
    55  // It serializes the chunk ranges using RLP and stores them under a key derived from the batch index.
    56  func WriteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64, chunkBlockRanges []*ChunkBlockRange) {
    57  	bytes, err := rlp.EncodeToBytes(chunkBlockRanges)
    58  	if err != nil {
    59  		log.Crit("failed to RLP encode batch chunk ranges", "batch index", batchIndex, "err", err)
    60  	}
    61  	if err := db.Put(batchChunkRangesKey(batchIndex), bytes); err != nil {
    62  		log.Crit("failed to store batch chunk ranges", "batch index", batchIndex, "err", err)
    63  	}
    64  }
    65  
    66  // DeleteBatchChunkRanges removes the block ranges of all chunks associated with a specific batch from the database.
    67  // Note: Only non-finalized batches can be reverted.
    68  func DeleteBatchChunkRanges(db ethdb.KeyValueWriter, batchIndex uint64) {
    69  	if err := db.Delete(batchChunkRangesKey(batchIndex)); err != nil {
    70  		log.Crit("failed to delete batch chunk ranges", "batch index", batchIndex, "err", err)
    71  	}
    72  }
    73  
    74  // ReadBatchChunkRanges retrieves the block ranges of all chunks associated with a specific batch from the database.
    75  // It returns a list of ChunkBlockRange pointers, or nil if no chunk ranges are found for the given batch index.
    76  func ReadBatchChunkRanges(db ethdb.Reader, batchIndex uint64) []*ChunkBlockRange {
    77  	data, err := db.Get(batchChunkRangesKey(batchIndex))
    78  	if err != nil && isNotFoundErr(err) {
    79  		return nil
    80  	}
    81  	if err != nil {
    82  		log.Crit("failed to read batch chunk ranges from database", "err", err)
    83  	}
    84  
    85  	cr := new([]*ChunkBlockRange)
    86  	if err := rlp.Decode(bytes.NewReader(data), cr); err != nil {
    87  		log.Crit("Invalid ChunkBlockRange RLP", "batch index", batchIndex, "data", data, "err", err)
    88  	}
    89  	return *cr
    90  }
    91  
    92  // WriteFinalizedBatchMeta stores the metadata of a finalized batch in the database.
    93  func WriteFinalizedBatchMeta(db ethdb.KeyValueWriter, batchIndex uint64, finalizedBatchMeta *FinalizedBatchMeta) {
    94  	var err error
    95  	bytes, err := rlp.EncodeToBytes(finalizedBatchMeta)
    96  	if err != nil {
    97  		log.Crit("failed to RLP encode batch metadata", "batch index", batchIndex, "err", err)
    98  	}
    99  	if err := db.Put(batchMetaKey(batchIndex), bytes); err != nil {
   100  		log.Crit("failed to store batch metadata", "batch index", batchIndex, "err", err)
   101  	}
   102  }
   103  
   104  // ReadFinalizedBatchMeta fetches the metadata of a finalized batch from the database.
   105  func ReadFinalizedBatchMeta(db ethdb.Reader, batchIndex uint64) *FinalizedBatchMeta {
   106  	data, err := db.Get(batchMetaKey(batchIndex))
   107  	if err != nil && isNotFoundErr(err) {
   108  		return nil
   109  	}
   110  	if err != nil {
   111  		log.Crit("failed to read finalized batch metadata from database", "err", err)
   112  	}
   113  
   114  	fbm := new(FinalizedBatchMeta)
   115  	if err := rlp.Decode(bytes.NewReader(data), fbm); err != nil {
   116  		log.Crit("Invalid FinalizedBatchMeta RLP", "batch index", batchIndex, "data", data, "err", err)
   117  	}
   118  	return fbm
   119  }
   120  
   121  // WriteFinalizedL2BlockNumber stores the highest finalized L2 block number in the database.
   122  func WriteFinalizedL2BlockNumber(db ethdb.KeyValueWriter, l2BlockNumber uint64) {
   123  	value := big.NewInt(0).SetUint64(l2BlockNumber).Bytes()
   124  	if err := db.Put(finalizedL2BlockNumberKey, value); err != nil {
   125  		log.Crit("failed to store finalized L2 block number for rollup event", "err", err)
   126  	}
   127  }
   128  
   129  // ReadFinalizedL2BlockNumber fetches the highest finalized L2 block number from the database.
   130  func ReadFinalizedL2BlockNumber(db ethdb.Reader) *uint64 {
   131  	data, err := db.Get(finalizedL2BlockNumberKey)
   132  	if err != nil && isNotFoundErr(err) {
   133  		return nil
   134  	}
   135  	if err != nil {
   136  		log.Crit("failed to read finalized L2 block number from database", "err", err)
   137  	}
   138  
   139  	number := new(big.Int).SetBytes(data)
   140  	if !number.IsUint64() {
   141  		log.Crit("unexpected finalized L2 block number in database", "number", number)
   142  	}
   143  
   144  	finalizedL2BlockNumber := number.Uint64()
   145  	return &finalizedL2BlockNumber
   146  }