Skip to content

Commit ec29c67

Browse files
author
AztecBot
committed
Merge remote-tracking branch 'origin/v4' into v4-next
2 parents aec8c16 + fd89d46 commit ec29c67

2 files changed

Lines changed: 130 additions & 0 deletions

File tree

yarn-project/prover-node/src/prover-node-publisher.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,82 @@ describe('prover-node-publisher', () => {
199199
},
200200
);
201201

202+
it('waits until the proven checkpoint reaches the checkpoint before the proof start', async () => {
203+
const checkpoints = Array.from({ length: 100 }, () => RootRollupPublicInputs.random());
204+
const fromCheckpoint = CheckpointNumber(33);
205+
const toCheckpoint = CheckpointNumber(64);
206+
207+
rollup.getTips
208+
.mockResolvedValueOnce({
209+
pending: CheckpointNumber(65),
210+
proven: CheckpointNumber(31),
211+
})
212+
.mockResolvedValueOnce({
213+
pending: CheckpointNumber(65),
214+
proven: CheckpointNumber(32),
215+
})
216+
.mockResolvedValue({
217+
pending: CheckpointNumber(65),
218+
proven: CheckpointNumber(32),
219+
});
220+
rollup.getRollupConstants.mockResolvedValue({
221+
l1StartBlock: 0n,
222+
l1GenesisTime: BigInt(Math.floor(Date.now() / 1000)),
223+
slotDuration: 1,
224+
epochDuration: 1,
225+
proofSubmissionEpochs: 100,
226+
targetCommitteeSize: 48,
227+
rollupManaLimit: Number.MAX_SAFE_INTEGER,
228+
});
229+
230+
rollup.getCheckpoint.mockImplementation((checkpointNumber: CheckpointNumber) =>
231+
Promise.resolve({
232+
archive: checkpoints[checkpointNumber - 1].endArchiveRoot,
233+
attestationsHash: Buffer32.ZERO,
234+
payloadDigest: Buffer32.ZERO,
235+
headerHash: Buffer32.ZERO,
236+
blobCommitmentsHash: Buffer32.ZERO,
237+
outHash: '0x',
238+
slotNumber: SlotNumber(0),
239+
feeHeader: {
240+
excessMana: 0n,
241+
manaUsed: 0n,
242+
ethPerFeeAsset: 0n,
243+
congestionCost: 0n,
244+
proverCost: 0n,
245+
},
246+
}),
247+
);
248+
249+
const ourPublicInputs = RootRollupPublicInputs.random();
250+
ourPublicInputs.previousArchiveRoot = checkpoints[fromCheckpoint - 2].endArchiveRoot;
251+
ourPublicInputs.endArchiveRoot = checkpoints[toCheckpoint - 1].endArchiveRoot;
252+
253+
const ourBatchedBlob = new BatchedBlob(
254+
ourPublicInputs.blobPublicInputs.blobCommitmentsHash,
255+
ourPublicInputs.blobPublicInputs.z,
256+
ourPublicInputs.blobPublicInputs.y,
257+
ourPublicInputs.blobPublicInputs.c,
258+
ourPublicInputs.blobPublicInputs.c.negate(),
259+
);
260+
261+
rollup.getEpochProofPublicInputs.mockResolvedValue(ourPublicInputs.toFields());
262+
263+
await publisher.submitEpochProof({
264+
epochNumber: EpochNumber(2),
265+
fromCheckpoint,
266+
toCheckpoint,
267+
publicInputs: ourPublicInputs,
268+
proof: Proof.empty(),
269+
batchedBlobInputs: ourBatchedBlob,
270+
attestations: [],
271+
});
272+
273+
expect(rollup.getRollupConstants).toHaveBeenCalled();
274+
expect(rollup.getTips).toHaveBeenCalledTimes(3);
275+
expect(l1Utils.sendAndMonitorTransaction).toHaveBeenCalled();
276+
});
277+
202278
it('handles reverted txs correctly', async () => {
203279
const checkpoints = [RootRollupPublicInputs.random(), RootRollupPublicInputs.random()];
204280

yarn-project/prover-node/src/prover-node-publisher.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import { areArraysEqual } from '@aztec/foundation/collection';
88
import { Fr } from '@aztec/foundation/curves/bn254';
99
import { EthAddress } from '@aztec/foundation/eth-address';
1010
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
11+
import { retryUntil } from '@aztec/foundation/retry';
1112
import type { Tuple } from '@aztec/foundation/serialize';
1213
import { Timer } from '@aztec/foundation/timer';
1314
import { RollupAbi } from '@aztec/l1-artifacts';
1415
import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
1516
import { CommitteeAttestation, CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
17+
import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
1618
import type { Proof } from '@aztec/stdlib/proofs';
1719
import type { FeeRecipient, RootRollupPublicInputs } from '@aztec/stdlib/rollup';
1820
import 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

Comments
 (0)