@@ -43,7 +43,38 @@ func ReadSyncedL1BlockNumber(db ethdb.Reader) *uint64 {
4343 return & value
4444}
4545
46+ // WriteHighestSyncedQueueIndex writes the highest synced L1 message queue index to the database.
47+ func WriteHighestSyncedQueueIndex (db ethdb.KeyValueWriter , queueIndex uint64 ) {
48+ value := big .NewInt (0 ).SetUint64 (queueIndex ).Bytes ()
49+
50+ if err := db .Put (highestSyncedQueueIndexKey , value ); err != nil {
51+ log .Crit ("Failed to update highest synced L1 message queue index" , "err" , err )
52+ }
53+ }
54+
55+ // ReadHighestSyncedQueueIndex retrieves the highest synced L1 message queue index.
56+ func ReadHighestSyncedQueueIndex (db ethdb.Reader ) uint64 {
57+ data , err := db .Get (highestSyncedQueueIndexKey )
58+ if err != nil && isNotFoundErr (err ) {
59+ return 0
60+ }
61+ if err != nil {
62+ log .Crit ("Failed to read highest synced L1 message queue index from database" , "err" , err )
63+ }
64+ if len (data ) == 0 {
65+ return 0
66+ }
67+
68+ number := new (big.Int ).SetBytes (data )
69+ if ! number .IsUint64 () {
70+ log .Crit ("Unexpected highest synced L1 block number in database" , "number" , number )
71+ }
72+
73+ return number .Uint64 ()
74+ }
75+
4676// WriteL1Message writes an L1 message to the database.
77+ // We assume that L1 messages are written to DB following their queue index order.
4778func WriteL1Message (db ethdb.KeyValueWriter , l1Msg types.L1MessageTx ) {
4879 bytes , err := rlp .EncodeToBytes (l1Msg )
4980 if err != nil {
@@ -52,6 +83,8 @@ func WriteL1Message(db ethdb.KeyValueWriter, l1Msg types.L1MessageTx) {
5283 if err := db .Put (L1MessageKey (l1Msg .QueueIndex ), bytes ); err != nil {
5384 log .Crit ("Failed to store L1 message" , "err" , err )
5485 }
86+
87+ WriteHighestSyncedQueueIndex (db , l1Msg .QueueIndex )
5588}
5689
5790// WriteL1Messages writes an array of L1 messages to the database.
@@ -91,20 +124,23 @@ func ReadL1Message(db ethdb.Reader, queueIndex uint64) *types.L1MessageTx {
91124// allows us to iterate over L1 messages in the database. It
92125// implements an interface similar to ethdb.Iterator.
93126type L1MessageIterator struct {
94- inner ethdb.Iterator
95- keyLength int
127+ inner ethdb.Iterator
128+ keyLength int
129+ maxQueueIndex uint64
96130}
97131
98132// IterateL1MessagesFrom creates an L1MessageIterator that iterates over
99133// all L1 message in the database starting at the provided enqueue index.
100- func IterateL1MessagesFrom (db ethdb.Iteratee , fromQueueIndex uint64 ) L1MessageIterator {
134+ func IterateL1MessagesFrom (db ethdb.Database , fromQueueIndex uint64 ) L1MessageIterator {
101135 start := encodeBigEndian (fromQueueIndex )
102136 it := db .NewIterator (l1MessagePrefix , start )
103137 keyLength := len (l1MessagePrefix ) + 8
138+ maxQueueIndex := ReadHighestSyncedQueueIndex (db )
104139
105140 return L1MessageIterator {
106- inner : it ,
107- keyLength : keyLength ,
141+ inner : it ,
142+ keyLength : keyLength ,
143+ maxQueueIndex : maxQueueIndex ,
108144 }
109145}
110146
@@ -145,7 +181,7 @@ func (it *L1MessageIterator) Release() {
145181}
146182
147183// ReadL1MessagesFrom retrieves up to `maxCount` L1 messages starting at `startIndex`.
148- func ReadL1MessagesFrom (db ethdb.Iteratee , startIndex , maxCount uint64 ) []types.L1MessageTx {
184+ func ReadL1MessagesFrom (db ethdb.Database , startIndex , maxCount uint64 ) []types.L1MessageTx {
149185 msgs := make ([]types.L1MessageTx , 0 , maxCount )
150186 it := IterateL1MessagesFrom (db , startIndex )
151187 defer it .Release ()
@@ -170,6 +206,10 @@ func ReadL1MessagesFrom(db ethdb.Iteratee, startIndex, maxCount uint64) []types.
170206 msgs = append (msgs , msg )
171207 index += 1
172208 count -= 1
209+
210+ if msg .QueueIndex == it .maxQueueIndex {
211+ break
212+ }
173213 }
174214
175215 return msgs
0 commit comments