Skip to content

Commit c49779c

Browse files
committed
test(fast-inbox): stub parent-checkpoint sourcing for the inbox rolling hash (A-1373)
The proposal handler, sequencer job, and prover node now source the parent checkpoint's inboxRollingHash. Serve zeroed parent headers from the mocks so scenarios beyond the genesis checkpoint resolve their chain start: the validator suite stubs the proposed-checkpoint fallback (getCheckpointData doubles as the already-published existence check), the sequencer suite stubs getCheckpointData, and the prover-node suite serves synthetic ancestors below the mined window.
1 parent a0e7d0a commit c49779c

3 files changed

Lines changed: 30 additions & 5 deletions

File tree

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ describe('ProverNode', () => {
723723
): Checkpoint {
724724
return {
725725
number: CheckpointNumber(checkpointNumber),
726-
header: { slotNumber: SlotNumber(slot) },
726+
header: { slotNumber: SlotNumber(slot), inboxRollingHash: Fr.ZERO },
727727
archive: { root: archiveRoot },
728728
blocks: [{ number: blockNumber, header: { hash: () => Promise.resolve('0x01') } }],
729729
hash: () => new Fr(checkpointNumber),
@@ -745,9 +745,19 @@ describe('ProverNode', () => {
745745
*/
746746
function mineCheckpoint(checkpoint: Checkpoint): L2BlockStreamEvent {
747747
mined.set(Number(checkpoint.number), checkpoint);
748-
l2BlockSource.getCheckpoint.mockImplementation((query: any) =>
749-
Promise.resolve('number' in query ? makeMaybePublished(mined.get(Number(query.number))) : undefined),
750-
);
748+
l2BlockSource.getCheckpoint.mockImplementation((query: any) => {
749+
if (!('number' in query)) {
750+
return Promise.resolve(undefined);
751+
}
752+
const number = Number(query.number);
753+
const found = mined.get(number);
754+
// Ancestors below the mined window exist on chain but are irrelevant to the scenario; serve a synthetic
755+
// parent so inbox rolling-hash sourcing for the earliest mined checkpoint resolves.
756+
const belowWindow = number > 0 && number < Math.min(...mined.keys());
757+
return Promise.resolve(
758+
makeMaybePublished(found ?? (belowWindow ? makeCheckpoint(number, number, number) : undefined)),
759+
);
760+
});
751761
l2BlockSource.getCheckpointsData.mockImplementation((query: any) => {
752762
if (!('from' in query)) {
753763
return Promise.resolve([]);

yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,11 @@ describe('CheckpointProposalJob', () => {
249249

250250
l2BlockSource = mock<L2BlockSource>();
251251
l2BlockSource.getCheckpointsData.mockResolvedValue([]);
252+
// The job sources the parent checkpoint's inboxRollingHash; serve an empty parent header so jobs beyond
253+
// the genesis checkpoint resolve their chain start.
254+
l2BlockSource.getCheckpointData.mockImplementation(query =>
255+
Promise.resolve('number' in query ? ({ header: CheckpointHeader.empty() } as CheckpointData) : undefined),
256+
);
252257
// The (always-on) pipelined submission path waits for the archiver to confirm the parent
253258
// checkpoint on L1 before enqueuing the proposal. For the default job (checkpoint 1, no
254259
// proposed parent), the parent is genesis (cp 0), so a synced archiver reporting a

yarn-project/validator-client/src/validator.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ import {
3030
import { OffenseType, WANT_TO_CLEAR_SLASH_EVENT, WANT_TO_SLASH_EVENT } from '@aztec/slasher';
3131
import { AztecAddress } from '@aztec/stdlib/aztec-address';
3232
import { type BlockData, BlockHash, L2Block, type L2BlockSink, type L2BlockSource } from '@aztec/stdlib/block';
33-
import { type Checkpoint, CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint';
33+
import { type Checkpoint, CheckpointReexecutionTracker, type ProposedCheckpointData } from '@aztec/stdlib/checkpoint';
3434
import type { SlasherConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
3535
import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
3636
import type { BlockProposal } from '@aztec/stdlib/p2p';
37+
import { CheckpointHeader } from '@aztec/stdlib/rollup';
3738
import {
3839
TEST_COORDINATION_SIGNATURE_CONTEXT,
3940
makeBlockHeader,
@@ -166,6 +167,15 @@ describe('ValidatorClient', () => {
166167
blockSource.getBlocksForSlot.mockResolvedValue([]);
167168
blockSource.getSyncedL2SlotNumber.mockResolvedValue(SlotNumber(Number.MAX_SAFE_INTEGER));
168169
blockSource.syncImmediate.mockResolvedValue(undefined);
170+
// The proposal handler sources the parent checkpoint's inboxRollingHash from the block source; serve an
171+
// empty (all-zero) parent header from the proposed-checkpoint fallback so proposals beyond the genesis
172+
// checkpoint resolve their chain start. getCheckpointData stays undefined: the checkpoint-proposal path
173+
// uses it as an already-published-on-L1 existence check.
174+
blockSource.getProposedCheckpointData.mockImplementation(query =>
175+
Promise.resolve(
176+
query && 'number' in query ? ({ header: CheckpointHeader.empty() } as ProposedCheckpointData) : undefined,
177+
),
178+
);
169179
epochCache.isEscapeHatchOpenAtSlot.mockResolvedValue(false);
170180
l1ToL2MessageSource = mock<L1ToL2MessageSource>();
171181
txProvider = mock<TxProvider>();

0 commit comments

Comments
 (0)