@@ -31,6 +31,7 @@ export class L1Scanner {
3131 maxHeadAgeMs = 15 * 60_000 ,
3232 maxHeadStallMs = 2 * 60_000 ,
3333 maxFutureSkewMs = 2 * 60_000 ,
34+ slashLogStartBlock,
3435 slashLogLookbackBlocks = 600 ,
3536 slashLogChunkSize = 1_000 ,
3637 slashLogOverlapBlocks = 12 ,
@@ -48,6 +49,9 @@ export class L1Scanner {
4849 this . maxHeadAgeMs = maxHeadAgeMs ;
4950 this . maxHeadStallMs = maxHeadStallMs ;
5051 this . maxFutureSkewMs = maxFutureSkewMs ;
52+ this . slashLogStartBlock = slashLogStartBlock === undefined
53+ ? undefined
54+ : BigInt ( slashLogStartBlock ) ;
5155 this . slashLogLookbackBlocks = BigInt ( slashLogLookbackBlocks ) ;
5256 this . slashLogChunkSize = BigInt ( slashLogChunkSize ) ;
5357 this . slashLogOverlapBlocks = BigInt ( slashLogOverlapBlocks ) ;
@@ -63,6 +67,9 @@ export class L1Scanner {
6367 fetchOptions : { signal } ,
6468 } ) ,
6569 } ) ) ;
70+ if ( this . slashLogStartBlock !== undefined && this . slashLogStartBlock < 0n ) {
71+ throw new RangeError ( 'slash log start block must be non-negative' ) ;
72+ }
6673 if ( this . slashLogLookbackBlocks < 1n ) throw new RangeError ( 'slash log lookback must be positive' ) ;
6774 if ( this . slashLogChunkSize < 2n ) throw new RangeError ( 'slash log chunk size must be at least 2' ) ;
6875 if ( this . slashLogOverlapBlocks < 1n || this . slashLogOverlapBlocks >= this . slashLogChunkSize ) {
@@ -252,9 +259,24 @@ export class L1Scanner {
252259 if ( ( cursorNumber === undefined ) !== ! cursorHash ) {
253260 throw new Error ( 'persisted slash log checkpoint is incomplete' ) ;
254261 }
262+ if (
263+ this . slashLogStartBlock !== undefined &&
264+ this . slashLogStartBlock > confirmedBlockNumber
265+ ) {
266+ throw new Error (
267+ `configured slash log start block ${ this . slashLogStartBlock } is above confirmed L1 head ${ confirmedBlockNumber } ` ,
268+ ) ;
269+ }
270+ const persistedStartBlock = readOptionalBigInt (
271+ previous . metadata ?. backfillStartBlock ,
272+ ) ;
273+ const restartFromConfiguredStart =
274+ cursorNumber !== undefined &&
275+ this . slashLogStartBlock !== undefined &&
276+ persistedStartBlock !== this . slashLogStartBlock ;
255277
256278 let reorgDetected = false ;
257- if ( cursorNumber !== undefined ) {
279+ if ( cursorNumber !== undefined && ! restartFromConfiguredStart ) {
258280 if ( cursorNumber > confirmedBlockNumber ) {
259281 reorgDetected = true ;
260282 } else {
@@ -268,10 +290,12 @@ export class L1Scanner {
268290 }
269291
270292 let fromBlock ;
271- if ( cursorNumber === undefined ) {
272- fromBlock = confirmedBlockNumber + 1n > this . slashLogLookbackBlocks
273- ? confirmedBlockNumber + 1n - this . slashLogLookbackBlocks
274- : 0n ;
293+ if ( cursorNumber === undefined || restartFromConfiguredStart ) {
294+ fromBlock = this . slashLogStartBlock ?? (
295+ confirmedBlockNumber + 1n > this . slashLogLookbackBlocks
296+ ? confirmedBlockNumber + 1n - this . slashLogLookbackBlocks
297+ : 0n
298+ ) ;
275299 } else if ( reorgDetected ) {
276300 fromBlock = cursorNumber + 1n > this . slashLogReorgRewindBlocks
277301 ? cursorNumber + 1n - this . slashLogReorgRewindBlocks
@@ -282,6 +306,12 @@ export class L1Scanner {
282306 ? cursorNumber + 1n - this . slashLogOverlapBlocks
283307 : 0n ;
284308 }
309+ if (
310+ this . slashLogStartBlock !== undefined &&
311+ fromBlock < this . slashLogStartBlock
312+ ) {
313+ fromBlock = this . slashLogStartBlock ;
314+ }
285315 const toBlock = minBigInt ( confirmedBlockNumber , fromBlock + this . slashLogChunkSize - 1n ) ;
286316 const checkpointBlock = toBlock === confirmedBlockNumber
287317 ? confirmedBlock
@@ -364,8 +394,12 @@ export class L1Scanner {
364394 toBlockHash : checkpointBlock . hash ,
365395 confirmedBlockNumber : confirmedBlockNumber . toString ( ) ,
366396 reorgDetected,
367- initial : cursorNumber === undefined ,
368- initialBackfill : cursorNumber === undefined || previous . metadata ?. initialBackfill === true ,
397+ initial : cursorNumber === undefined || restartFromConfiguredStart ,
398+ initialBackfill :
399+ cursorNumber === undefined ||
400+ restartFromConfiguredStart ||
401+ previous . metadata ?. initialBackfill === true ,
402+ backfillStartBlock : this . slashLogStartBlock ?. toString ( ) ?? null ,
369403 hasMore : toBlock < confirmedBlockNumber ,
370404 registryAddress : this . registryAddress ,
371405 rollupAddresses : [ ...knownRollups ] . sort ( ) ,
0 commit comments