@@ -14,6 +14,7 @@ export class SentinelCollector {
1414 pollIntervalMs,
1515 maxBackoffMs,
1616 lookbackEpochs = 3 ,
17+ epochEndBufferSlots = 2 ,
1718 validatorConcurrency = 8 ,
1819 maxStallMs = 5 * 60_000 ,
1920 logger,
@@ -28,6 +29,10 @@ export class SentinelCollector {
2829 this . pollIntervalMs = pollIntervalMs ;
2930 this . maxBackoffMs = maxBackoffMs ;
3031 this . lookbackEpochs = requirePositiveSafeInteger ( lookbackEpochs , 'sentinel lookback epochs' ) ;
32+ this . epochEndBufferSlots = requireUnsignedSafeInteger (
33+ epochEndBufferSlots ,
34+ 'sentinel epoch-end buffer' ,
35+ ) ;
3136 this . validatorConcurrency = requirePositiveSafeInteger (
3237 validatorConcurrency ,
3338 'sentinel validator concurrency' ,
@@ -63,6 +68,12 @@ export class SentinelCollector {
6368 const l1State = this . repository . getSourceState ( 'l1' ) ;
6469 const l1Metadata = l1State ?. metadata ;
6570 const canonicalRollupAddress = readCanonicalRollupAddress ( this . repository ) ;
71+ if ( ! canonicalRollupAddress ) {
72+ return this . recordPollFailure (
73+ 'Canonical L1 Rollup is unavailable; validator duties are not trusted yet' ,
74+ attemptedAt ,
75+ ) ;
76+ }
6677 let l1Checkpoint ;
6778 let epochDuration ;
6879 let confirmedL1Slot ;
@@ -86,12 +97,6 @@ export class SentinelCollector {
8697 } catch ( error ) {
8798 return this . recordPollFailure ( errorMessage ( error ) , attemptedAt ) ;
8899 }
89- if ( ! canonicalRollupAddress ) {
90- return this . recordPollFailure (
91- 'Canonical L1 Rollup is unavailable; validator duties are not trusted yet' ,
92- attemptedAt ,
93- ) ;
94- }
95100
96101 const controller = new AbortController ( ) ;
97102 this . activeRequest = controller ;
@@ -116,7 +121,7 @@ export class SentinelCollector {
116121 syncedL2Slot,
117122 confirmedL1Slot,
118123 epochDuration,
119- epochEndBufferSlots : config . epochEndBufferSlots ,
124+ epochEndBufferSlots : this . epochEndBufferSlots ,
120125 } ) ;
121126 if ( cursor && ready <= cursor . epoch ) {
122127 return this . recordSuccess ( {
@@ -149,7 +154,7 @@ export class SentinelCollector {
149154 syncedL2Slot,
150155 confirmedL1Slot,
151156 epochDuration,
152- epochEndBufferSlots : config . epochEndBufferSlots ,
157+ epochEndBufferSlots : this . epochEndBufferSlots ,
153158 } ) ;
154159 if ( ready < 0 || ( cursor && ready <= cursor . epoch ) ) {
155160 return this . recordSuccess ( {
@@ -254,7 +259,7 @@ export class SentinelCollector {
254259 ? input . observedAt
255260 : input . prior . lastSyncProgressAt ,
256261 nodeReady : Boolean ( input . syncStatus . ready ) ,
257- epochEndBufferSlots : input . config . epochEndBufferSlots ,
262+ epochEndBufferSlots : this . epochEndBufferSlots ,
258263 targetPercentage : input . config . targetPercentage ,
259264 consecutiveEpochThreshold : input . config . consecutiveEpochThreshold ,
260265 epochDuration : String ( input . epochDuration ) ,
@@ -388,7 +393,6 @@ async function mapWithConcurrency(values, concurrency, operation) {
388393
389394function readStoredConfig ( metadata ) {
390395 if (
391- metadata . epochEndBufferSlots === undefined ||
392396 metadata . targetPercentage === undefined ||
393397 metadata . consecutiveEpochThreshold === undefined
394398 ) {
@@ -399,10 +403,6 @@ function readStoredConfig(metadata) {
399403 return undefined ;
400404 }
401405 return {
402- epochEndBufferSlots : requireUnsignedSafeInteger (
403- metadata . epochEndBufferSlots ,
404- 'stored sentinel epoch-end buffer' ,
405- ) ,
406406 targetPercentage,
407407 consecutiveEpochThreshold : requirePositiveSafeInteger (
408408 metadata . consecutiveEpochThreshold ,
0 commit comments