@@ -260,7 +260,9 @@ func (c *Sequencer) GetNextBatch(ctx context.Context, req coresequencer.GetNextB
260260 }
261261 }
262262
263- // Process forced txs sequentially (TxIndex must track consumed txs in order)
263+ // Process filter results sequentially for forced txs to maintain ordering.
264+ // We stop at the first Postpone to ensure crash recovery works correctly:
265+ // TxIndex tracks consumed txs from the start of the epoch, so we must process in order.
264266 var validForcedTxs [][]byte
265267 var validMempoolTxs [][]byte
266268 var forcedTxConsumedCount uint64
@@ -270,26 +272,33 @@ func (c *Sequencer) GetNextBatch(ctx context.Context, req coresequencer.GetNextB
270272 isForcedTx := i < forcedTxCount
271273 if isForcedTx {
272274 if forcedTxPostponed {
275+ // Already hit a postpone, skip remaining forced txs for this batch
273276 continue
274277 }
275278 switch status {
276279 case execution .FilterOK :
277280 validForcedTxs = append (validForcedTxs , allTxs [i ])
278281 forcedTxConsumedCount ++
279282 case execution .FilterRemove :
283+ // Skip removed transactions but count as consumed
280284 forcedTxConsumedCount ++
281285 case execution .FilterPostpone :
286+ // Stop processing forced txs at first postpone to maintain order
282287 forcedTxPostponed = true
283288 }
284289 } else {
290+ // Mempool txs can be processed in any order
285291 switch status {
286292 case execution .FilterOK :
287293 validMempoolTxs = append (validMempoolTxs , allTxs [i ])
294+ case execution .FilterPostpone , execution .FilterRemove :
295+ // Mempool txs that are postponed/removed are handled separately
288296 }
289297 }
290298 }
291299
292- // Return postponed mempool txs to queue
300+ // Return any postponed mempool txs to the queue for the next batch
301+ // (they were valid but didn't fit due to size/gas limits)
293302 var postponedMempoolTxs [][]byte
294303 for i , status := range filterStatuses {
295304 if i >= forcedTxCount && status == execution .FilterPostpone {
@@ -304,6 +313,7 @@ func (c *Sequencer) GetNextBatch(ctx context.Context, req coresequencer.GetNextB
304313
305314 // Update checkpoint after consuming forced inclusion transactions
306315 if daHeight > 0 || len (forcedTxs ) > 0 {
316+ // Advance TxIndex by the number of consumed forced transactions
307317 c .checkpoint .TxIndex += forcedTxConsumedCount
308318
309319 if c .checkpoint .TxIndex >= uint64 (len (c .cachedForcedInclusionTxs )) {
@@ -493,11 +503,8 @@ func (c *Sequencer) updateCatchUpState(ctx context.Context) {
493503 return
494504 }
495505
506+ // At head, no catch-up needed
496507 if latestDAHeight <= currentDAHeight {
497- c .logger .Debug ().
498- Uint64 ("checkpoint_da_height" , currentDAHeight ).
499- Uint64 ("latest_da_height" , latestDAHeight ).
500- Msg ("sequencer is at or ahead of DA head, no catch-up needed" )
501508 return
502509 }
503510
0 commit comments