|
1 | 1 | import type { Logger } from '@aztec/aztec.js/log'; |
2 | 2 | import { RollupContract } from '@aztec/ethereum/contracts'; |
3 | | -import { ChainMonitor } from '@aztec/ethereum/test'; |
4 | | -import { sleep } from '@aztec/foundation/sleep'; |
| 3 | +import { CheckpointNumber } from '@aztec/foundation/branded-types'; |
5 | 4 |
|
6 | 5 | import type { EndToEndContext } from '../../fixtures/utils.js'; |
7 | 6 | import { SingleNodeTestContext, jest, setupWithProver } from './setup.js'; |
8 | 7 |
|
9 | | -// Starts a prover node (fake proofs) on the default setup, raises minTxsPerBlock=1 so blocks are |
10 | | -// empty, then verifies the prover still submits a proof for those empty-block checkpoints within the |
11 | | -// proof submission window. |
| 8 | +// Starts a prover node (fake proofs) on the default setup and verifies the prover submits a proof for |
| 9 | +// a real non-genesis checkpoint with no txs. |
12 | 10 | describe('single-node/proving/empty_blocks', () => { |
13 | 11 | let context: EndToEndContext; |
14 | 12 | let rollup: RollupContract; |
15 | 13 | let logger: Logger; |
16 | | - let monitor: ChainMonitor; |
17 | | - |
18 | | - let L1_BLOCK_TIME_IN_S: number; |
19 | 14 |
|
20 | 15 | let test: SingleNodeTestContext; |
21 | 16 |
|
22 | 17 | beforeEach(async () => { |
23 | 18 | test = await setupWithProver({}); |
24 | | - ({ context, rollup, logger, monitor, L1_BLOCK_TIME_IN_S } = test); |
| 19 | + ({ context, rollup, logger } = test); |
25 | 20 | }); |
26 | 21 |
|
27 | 22 | afterEach(async () => { |
28 | 23 | jest.restoreAllMocks(); |
29 | 24 | await test.teardown(); |
30 | 25 | }); |
31 | 26 |
|
32 | | - // Raises minTxsPerBlock to 1 so the sequencer cannot build blocks, advances to epoch 1, |
33 | | - // then waits for the prover to submit a proof for the empty checkpoint. Asserts that the |
34 | | - // monitor's checkpointNumber matches the proven target, confirming the proof landed on L1. |
| 27 | + // Waits for a real empty checkpoint, raises minTxsPerBlock to 1 to stop more empty checkpoints |
| 28 | + // from being built, then waits for the prover to submit a proof covering that target. |
35 | 29 | it('submits proof even if there are no txs to build a block', async () => { |
| 30 | + // Let the sequencer build its first empty checkpoint (at the setup default minTxsPerBlock:0) |
| 31 | + // before raising the floor. Raising minTxsPerBlock first races the sequencer's first proposal |
| 32 | + // loop: if the config lands before block 1 is built, the sequencer waits forever for a tx that |
| 33 | + // never arrives, no non-genesis checkpoint is built, and there is nothing to prove. |
| 34 | + const proofTargetCheckpoint = CheckpointNumber(1); |
| 35 | + await test.waitUntilCheckpointNumber(proofTargetCheckpoint); |
36 | 36 | context.sequencer?.updateConfig({ minTxsPerBlock: 1 }); |
37 | | - await test.waitUntilEpochStarts(1); |
38 | | - |
39 | | - // Sleep to make sure any pending checkpoints are published. We deliberately keep the fixed |
40 | | - // sleep rather than waiting for the sequencer to reach IDLE: the sequencer is typically already |
41 | | - // idle here, so an IDLE wait would return immediately and not give the in-flight L1 publish time |
42 | | - // to land. The window we need is the publish settling, not the sequencer becoming idle. |
43 | | - await sleep(L1_BLOCK_TIME_IN_S * 1000); |
44 | | - const checkpointNumberAtEndOfEpoch0 = await rollup.getCheckpointNumber(); |
45 | | - logger.info(`Starting epoch 1 after checkpoint ${checkpointNumberAtEndOfEpoch0}`); |
46 | 37 |
|
47 | | - await test.waitUntilProvenCheckpointNumber(checkpointNumberAtEndOfEpoch0, 240); |
48 | | - expect(monitor.checkpointNumber).toEqual(checkpointNumberAtEndOfEpoch0); |
| 38 | + await test.waitUntilProvenCheckpointNumber(proofTargetCheckpoint, 240); |
| 39 | + expect(await rollup.getProvenCheckpointNumber()).toBeGreaterThanOrEqual(proofTargetCheckpoint); |
49 | 40 | logger.info(`Test succeeded`); |
50 | 41 | }); |
51 | 42 | }); |
0 commit comments