@@ -8,11 +8,13 @@ import { areArraysEqual } from '@aztec/foundation/collection';
88import { Fr } from '@aztec/foundation/curves/bn254' ;
99import { EthAddress } from '@aztec/foundation/eth-address' ;
1010import { type Logger , type LoggerBindings , createLogger } from '@aztec/foundation/log' ;
11+ import { retryUntil } from '@aztec/foundation/retry' ;
1112import type { Tuple } from '@aztec/foundation/serialize' ;
1213import { Timer } from '@aztec/foundation/timer' ;
1314import { RollupAbi } from '@aztec/l1-artifacts' ;
1415import type { PublisherConfig , TxSenderConfig } from '@aztec/sequencer-client' ;
1516import { CommitteeAttestation , CommitteeAttestationsAndSigners } from '@aztec/stdlib/block' ;
17+ import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers' ;
1618import type { Proof } from '@aztec/stdlib/proofs' ;
1719import type { FeeRecipient , RootRollupPublicInputs } from '@aztec/stdlib/rollup' ;
1820import type { L1PublishProofStats } from '@aztec/stdlib/stats' ;
@@ -101,6 +103,11 @@ export class ProverNodePublisher {
101103 const ctx = { epochNumber, fromCheckpoint, toCheckpoint } ;
102104
103105 if ( ! this . interrupted ) {
106+ if ( ! ( await this . waitUntilStartBuildsOnProven ( args ) ) ) {
107+ this . log . verbose ( 'Checkpoint data syncing interrupted' , ctx ) ;
108+ return false ;
109+ }
110+
104111 const timer = new Timer ( ) ;
105112 // Validate epoch proof range and hashes are correct before submitting
106113 await this . validateEpochProofSubmission ( args ) ;
@@ -147,6 +154,53 @@ export class ProverNodePublisher {
147154 return false ;
148155 }
149156
157+ private async waitUntilStartBuildsOnProven ( args : { epochNumber : EpochNumber ; fromCheckpoint : CheckpointNumber } ) {
158+ const { epochNumber, fromCheckpoint } = args ;
159+ const provenCheckpoint = await this . getProvenCheckpoint ( ) ;
160+ if ( this . isStartBuildingOnProven ( fromCheckpoint , provenCheckpoint ) ) {
161+ return true ;
162+ }
163+
164+ const timeout = await this . getSecondsUntilProofSubmissionWindowEnd ( epochNumber ) ;
165+ this . log . info ( `Waiting for proven checkpoint to reach proof start` , {
166+ epochNumber,
167+ fromCheckpoint,
168+ provenCheckpoint,
169+ timeout,
170+ } ) ;
171+
172+ await retryUntil (
173+ async ( ) => {
174+ if ( this . interrupted ) {
175+ return true ;
176+ }
177+
178+ const proven = await this . getProvenCheckpoint ( ) ;
179+ this . log . verbose ( `Proven checkpoint is at ${ proven } (waiting for ${ fromCheckpoint - 1 } )` , { epochNumber } ) ;
180+ return this . isStartBuildingOnProven ( fromCheckpoint , proven ) ? true : undefined ;
181+ } ,
182+ `proven checkpoint to reach ${ fromCheckpoint - 1 } ` ,
183+ timeout ,
184+ 4 ,
185+ ) ;
186+
187+ return ! this . interrupted ;
188+ }
189+
190+ private async getProvenCheckpoint ( ) {
191+ return ( await this . rollupContract . getTips ( ) ) . proven ;
192+ }
193+
194+ private isStartBuildingOnProven ( fromCheckpoint : CheckpointNumber , provenCheckpoint : CheckpointNumber ) {
195+ return fromCheckpoint - 1 <= provenCheckpoint ;
196+ }
197+
198+ private async getSecondsUntilProofSubmissionWindowEnd ( epochNumber : EpochNumber ) {
199+ const deadline = getProofSubmissionDeadlineTimestamp ( epochNumber , await this . rollupContract . getRollupConstants ( ) ) ;
200+ const now = BigInt ( Math . floor ( Date . now ( ) / 1000 ) ) ;
201+ return Math . max ( Number ( deadline - now ) , 0.001 ) ;
202+ }
203+
150204 private async validateEpochProofSubmission ( args : {
151205 fromCheckpoint : CheckpointNumber ;
152206 toCheckpoint : CheckpointNumber ;
0 commit comments