Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 31 additions & 8 deletions yarn-project/p2p/src/client/p2p_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,14 @@ describe('P2P Client', () => {
});

describe('Chain prunes', () => {
it('passes deleteAllTxs: false when prune does not cross a checkpoint boundary', async () => {
it('detects checkpoint prune when checkpoint number stays the same', async () => {
client = createClient({ txPoolDeleteTxsAfterReorg: true });
blockSource.setProvenBlockNumber(0);
// Only checkpoint up to block 90 — blocks 91-100 are proposed but not checkpointed
blockSource.setCheckpointedBlockNumber(90);
await client.start();

// Prune 5 blocks (91-100): checkpointed tip stays at checkpoint 90
// Prune 10 blocks (91-100): checkpoint number stays at 90, so this is a checkpoint prune
blockSource.removeBlocks(10);
await client.sync();

Expand All @@ -228,14 +228,38 @@ describe('P2P Client', () => {
await client.stop();
});

it('passes deleteAllTxs: true when prune crosses a checkpoint boundary', async () => {
it('detects checkpoint prune when checkpoint number increases by one', async () => {
client = createClient({ txPoolDeleteTxsAfterReorg: true });
blockSource.setProvenBlockNumber(0);
// Checkpoint all 100 blocks
blockSource.setCheckpointedBlockNumber(100);
await client.start();

// Prune 5 blocks (96-100): checkpointed tip moves from checkpoint 100 to 95
// Propose block 101 and sync it
blockSource.addProposedBlocks([await L2Block.random(BlockNumber(101))]);
await client.sync();

// Replace block 101 with a different block and checkpoint it
blockSource.removeBlocks(1);
blockSource.addProposedBlocks([await L2Block.random(BlockNumber(101))]);
blockSource.setCheckpointedBlockNumber(101);
await client.sync();

// Checkpoint advanced from 100 to 101: not an epoch prune
expect(txPool.handlePrunedBlocks).toHaveBeenCalledWith(
{ number: BlockNumber(100), hash: expect.any(String) },
{ deleteAllTxs: false },
);
await client.stop();
});

it('detects epoch prune when checkpoint number decreases', async () => {
client = createClient({ txPoolDeleteTxsAfterReorg: true });
blockSource.setProvenBlockNumber(0);
// Checkpoint all 100 blocks — client stores checkpoint number 100
blockSource.setCheckpointedBlockNumber(100);
await client.start();

// Prune 5 blocks (96-100): checkpoint number drops from 100 to 95, so this is an epoch prune
blockSource.removeBlocks(5);
await client.sync();

Expand All @@ -246,18 +270,17 @@ describe('P2P Client', () => {
await client.stop();
});

it('passes deleteAllTxs: false for cross-checkpoint prune when txPoolDeleteTxsAfterReorg is disabled', async () => {
it('does not delete all txs on epoch prune when txPoolDeleteTxsAfterReorg is disabled', async () => {
// Default config has txPoolDeleteTxsAfterReorg: false
blockSource.setProvenBlockNumber(0);
// Checkpoint all 100 blocks
blockSource.setCheckpointedBlockNumber(100);
await client.start();

// Prune 5 blocks (96-100): checkpointed tip moves from checkpoint 100 to 95
// Prune 5 blocks (96-100): epoch prune but flag is off
blockSource.removeBlocks(5);
await client.sync();

// Should delete all txs but flag is off
expect(txPool.handlePrunedBlocks).toHaveBeenCalledWith(
{ number: BlockNumber(95), hash: expect.any(String) },
{ deleteAllTxs: false },
Expand Down
7 changes: 3 additions & 4 deletions yarn-project/p2p/src/client/p2p_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,9 +669,8 @@ export class P2PClient extends WithTracer implements P2P {
}

/**
* Returns true if the prune crossed a checkpoint boundary.
* If the old and new checkpoint numbers are the same, the prune is within a single checkpoint.
* If they differ, the prune spans across checkpoints (epoch prune).
* Returns true if the prune is an epoch prune (new checkpoint number is less than old).
* If the checkpoint number stays the same or increases, the prune is within a checkpoint.
*/
private async isEpochPrune(newCheckpoint: CheckpointId): Promise<boolean> {
const tips = await this.l2Tips.getL2Tips();
Expand All @@ -680,7 +679,7 @@ export class P2PClient extends WithTracer implements P2P {
return false;
}
const newCheckpointNumber = newCheckpoint.number;
const isEpochPrune = oldCheckpointNumber !== newCheckpointNumber;
const isEpochPrune = newCheckpointNumber < oldCheckpointNumber;
if (isEpochPrune) {
this.log.info(`Detected epoch prune to ${newCheckpointNumber}`, { oldCheckpointNumber, newCheckpointNumber });
}
Expand Down
Loading