diff --git a/.changeset/thin-dodos-reply.md b/.changeset/thin-dodos-reply.md new file mode 100644 index 00000000000..a844f4c0492 --- /dev/null +++ b/.changeset/thin-dodos-reply.md @@ -0,0 +1,5 @@ +--- +"@eth-optimism/l2geth": patch +--- + +Add `VerifiedIndex` to db and api diff --git a/l2geth/core/rawdb/rollup_indexes.go b/l2geth/core/rawdb/rollup_indexes.go index 4ce5532c175..91b1b638546 100644 --- a/l2geth/core/rawdb/rollup_indexes.go +++ b/l2geth/core/rawdb/rollup_indexes.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/log" ) +// ReadHeadIndex will read the known tip of the CTC func ReadHeadIndex(db ethdb.KeyValueReader) *uint64 { data, _ := db.Get(headIndexKey) if len(data) == 0 { @@ -16,6 +17,7 @@ func ReadHeadIndex(db ethdb.KeyValueReader) *uint64 { return &ret } +// WriteHeadIndex will write the known tip of the CTC func WriteHeadIndex(db ethdb.KeyValueWriter, index uint64) { value := new(big.Int).SetUint64(index).Bytes() if index == 0 { @@ -26,6 +28,7 @@ func WriteHeadIndex(db ethdb.KeyValueWriter, index uint64) { } } +// ReadHeadQueueIndex will read the known tip of the queue func ReadHeadQueueIndex(db ethdb.KeyValueReader) *uint64 { data, _ := db.Get(headQueueIndexKey) if len(data) == 0 { @@ -35,6 +38,7 @@ func ReadHeadQueueIndex(db ethdb.KeyValueReader) *uint64 { return &ret } +// WriteHeadQueueIndex will write the known tip of the queue func WriteHeadQueueIndex(db ethdb.KeyValueWriter, index uint64) { value := new(big.Int).SetUint64(index).Bytes() if index == 0 { @@ -44,3 +48,24 @@ func WriteHeadQueueIndex(db ethdb.KeyValueWriter, index uint64) { log.Crit("Failed to store queue index", "err", err) } } + +// ReadHeadVerifiedIndex will read the known tip of the batched transactions +func ReadHeadVerifiedIndex(db ethdb.KeyValueReader) *uint64 { + data, _ := db.Get(headVerifiedIndexKey) + if len(data) == 0 { + return nil + } + ret := new(big.Int).SetBytes(data).Uint64() + return &ret +} + +// WriteHeadVerifiedIndex will write the known tip of the batched transactions +func WriteHeadVerifiedIndex(db ethdb.KeyValueWriter, index uint64) { + value := new(big.Int).SetUint64(index).Bytes() + if index == 0 { + value = []byte{0} + } + if err := db.Put(headVerifiedIndexKey, value); err != nil { + log.Crit("Failed to store verifier index", "err", err) + } +} diff --git a/l2geth/core/rawdb/schema.go b/l2geth/core/rawdb/schema.go index ed091fa2398..d0f951e2bdc 100644 --- a/l2geth/core/rawdb/schema.go +++ b/l2geth/core/rawdb/schema.go @@ -60,6 +60,8 @@ var ( headIndexKey = []byte("LastIndex") // headQueueIndexKey tracks th last processed queue index headQueueIndexKey = []byte("LastQueueIndex") + // headVerifiedIndexKey tracks the latest verified index + headVerifiedIndexKey = []byte("LastVerifiedIndex") preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage configPrefix = []byte("ethereum-config-") // config prefix for the db diff --git a/l2geth/eth/api_backend.go b/l2geth/eth/api_backend.go index a0889ea4333..06c495eab00 100644 --- a/l2geth/eth/api_backend.go +++ b/l2geth/eth/api_backend.go @@ -71,18 +71,21 @@ func (b *EthAPIBackend) GetEthContext() (uint64, uint64) { return bn, ts } -func (b *EthAPIBackend) GetRollupContext() (uint64, uint64) { - i := uint64(0) - q := uint64(0) - index := b.eth.syncService.GetLatestIndex() - if index != nil { - i = *index +func (b *EthAPIBackend) GetRollupContext() (uint64, uint64, uint64) { + index := uint64(0) + queueIndex := uint64(0) + verifiedIndex := uint64(0) + + if latest := b.eth.syncService.GetLatestIndex(); latest != nil { + index = *latest + } + if latest := b.eth.syncService.GetLatestEnqueueIndex(); latest != nil { + queueIndex = *latest } - queueIndex := b.eth.syncService.GetLatestEnqueueIndex() - if queueIndex != nil { - q = *queueIndex + if latest := b.eth.syncService.GetLatestVerifiedIndex(); latest != nil { + verifiedIndex = *latest } - return i, q + return index, queueIndex, verifiedIndex } // ChainConfig returns the active chain configuration. diff --git a/l2geth/internal/ethapi/api.go b/l2geth/internal/ethapi/api.go index 6c384955ce1..7b765cbe30b 100644 --- a/l2geth/internal/ethapi/api.go +++ b/l2geth/internal/ethapi/api.go @@ -1913,9 +1913,15 @@ type EthContext struct { BlockNumber uint64 `json:"blockNumber"` Timestamp uint64 `json:"timestamp"` } + +// RollupContext represents the height of the rollup. +// Index is the last processed CanonicalTransactionChain index +// QueueIndex is the last processed `enqueue` index +// VerifiedIndex is the last processed CTC index that was batched type RollupContext struct { - Index uint64 `json:"index"` - QueueIndex uint64 `json:"queueIndex"` + Index uint64 `json:"index"` + QueueIndex uint64 `json:"queueIndex"` + VerifiedIndex uint64 `json:"verifiedIndex"` } type rollupInfo struct { @@ -1932,7 +1938,7 @@ func (api *PublicRollupAPI) GetInfo(ctx context.Context) rollupInfo { } syncing := api.b.IsSyncing() bn, ts := api.b.GetEthContext() - index, queueIndex := api.b.GetRollupContext() + index, queueIndex, verifiedIndex := api.b.GetRollupContext() return rollupInfo{ Mode: mode, @@ -1942,8 +1948,9 @@ func (api *PublicRollupAPI) GetInfo(ctx context.Context) rollupInfo { Timestamp: ts, }, RollupContext: RollupContext{ - Index: index, - QueueIndex: queueIndex, + Index: index, + QueueIndex: queueIndex, + VerifiedIndex: verifiedIndex, }, } } diff --git a/l2geth/internal/ethapi/backend.go b/l2geth/internal/ethapi/backend.go index 734a83702fd..beef5aaf053 100644 --- a/l2geth/internal/ethapi/backend.go +++ b/l2geth/internal/ethapi/backend.go @@ -91,7 +91,7 @@ type Backend interface { IsVerifier() bool IsSyncing() bool GetEthContext() (uint64, uint64) - GetRollupContext() (uint64, uint64) + GetRollupContext() (uint64, uint64, uint64) GasLimit() uint64 GetDiff(*big.Int) (diffdb.Diff, error) SuggestDataPrice(ctx context.Context) (*big.Int, error) diff --git a/l2geth/les/api_backend.go b/l2geth/les/api_backend.go index 75e30bbbd83..1dbd466497a 100644 --- a/l2geth/les/api_backend.go +++ b/l2geth/les/api_backend.go @@ -58,8 +58,8 @@ func (b *LesApiBackend) GetEthContext() (uint64, uint64) { return 0, 0 } -func (b *LesApiBackend) GetRollupContext() (uint64, uint64) { - return 0, 0 +func (b *LesApiBackend) GetRollupContext() (uint64, uint64, uint64) { + return 0, 0, 0 } func (b *LesApiBackend) IsSyncing() bool { diff --git a/l2geth/rollup/sync_service.go b/l2geth/rollup/sync_service.go index 4a8864e5bc5..4d8f542d0c1 100644 --- a/l2geth/rollup/sync_service.go +++ b/l2geth/rollup/sync_service.go @@ -537,40 +537,90 @@ func (s *SyncService) syncTransactionsToTip() error { // Methods for safely accessing and storing the latest // L1 blocknumber and timestamp. These are held in memory. + +// GetLatestL1Timestamp returns the OVMContext timestamp func (s *SyncService) GetLatestL1Timestamp() uint64 { return atomic.LoadUint64(&s.OVMContext.timestamp) } +// GetLatestL1BlockNumber returns the OVMContext blocknumber func (s *SyncService) GetLatestL1BlockNumber() uint64 { return atomic.LoadUint64(&s.OVMContext.blockNumber) } +// SetLatestL1Timestamp will set the OVMContext timestamp func (s *SyncService) SetLatestL1Timestamp(ts uint64) { atomic.StoreUint64(&s.OVMContext.timestamp, ts) } +// SetLatestL1BlockNumber will set the OVMContext blocknumber func (s *SyncService) SetLatestL1BlockNumber(bn uint64) { atomic.StoreUint64(&s.OVMContext.blockNumber, bn) } +// GetLatestEnqueueIndex reads the last queue index processed func (s *SyncService) GetLatestEnqueueIndex() *uint64 { return rawdb.ReadHeadQueueIndex(s.db) } +// GetNextEnqueueIndex returns the next queue index to process +func (s *SyncService) GetNextEnqueueIndex() uint64 { + latest := s.GetLatestEnqueueIndex() + if latest == nil { + return 0 + } + return *latest + 1 +} + +// SetLatestEnqueueIndex writes the last queue index that was processed func (s *SyncService) SetLatestEnqueueIndex(index *uint64) { if index != nil { rawdb.WriteHeadQueueIndex(s.db, *index) } } +// GetLatestIndex reads the last CTC index that was processed +func (s *SyncService) GetLatestIndex() *uint64 { + return rawdb.ReadHeadIndex(s.db) +} + +// GetNextIndex reads the next CTC index to process +func (s *SyncService) GetNextIndex() uint64 { + latest := s.GetLatestIndex() + if latest == nil { + return 0 + } + return *latest + 1 +} + +// SetLatestIndex writes the last CTC index that was processed func (s *SyncService) SetLatestIndex(index *uint64) { if index != nil { rawdb.WriteHeadIndex(s.db, *index) } } -func (s *SyncService) GetLatestIndex() *uint64 { - return rawdb.ReadHeadIndex(s.db) +// GetLatestVerifiedIndex reads the last verified CTC index that was processed +// These are set by processing batches of transactions that were submitted to +// the Canonical Transaction Chain. +func (s *SyncService) GetLatestVerifiedIndex() *uint64 { + return rawdb.ReadHeadVerifiedIndex(s.db) +} + +// GetNextVerifiedIndex reads the next verified index +func (s *SyncService) GetNextVerifiedIndex() uint64 { + index := s.GetLatestVerifiedIndex() + if index == nil { + return 0 + } + return *index + 1 +} + +// SetLatestVerifiedIndex writes the last verified index that was processed +func (s *SyncService) SetLatestVerifiedIndex(index *uint64) { + if index != nil { + rawdb.WriteHeadVerifiedIndex(s.db, *index) + } } // reorganize will reorganize to directly to the index passed in.