Skip to content

Commit 8ccf053

Browse files
author
AztecBot
committed
Merge branch 'next' into merge-train/spartan
2 parents 15b0245 + 5d263f1 commit 8ccf053

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

yarn-project/slasher/src/watchers/epoch_prune_watcher.test.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { EpochCache } from '@aztec/epoch-cache';
22
import { EthAddress } from '@aztec/foundation/eth-address';
33
import { sleep } from '@aztec/foundation/sleep';
44
import { L2Block, type L2BlockSourceEventEmitter, L2BlockSourceEvents } from '@aztec/stdlib/block';
5+
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
56
import type {
67
BuildBlockResult,
78
IFullNodeBlockBuilder,
@@ -28,6 +29,10 @@ describe('EpochPruneWatcher', () => {
2829
let txProvider: MockProxy<Pick<ITxProvider, 'getAvailableTxs'>>;
2930
let blockBuilder: MockProxy<IFullNodeBlockBuilder>;
3031
let fork: MockProxy<MerkleTreeWriteOperations>;
32+
33+
let ts: bigint;
34+
let l1Constants: L1RollupConstants;
35+
3136
const validEpochPrunedPenalty = BigInt(1000000000000000000n);
3237
const dataWithholdingPenalty = BigInt(2000000000000000000n);
3338

@@ -41,6 +46,18 @@ describe('EpochPruneWatcher', () => {
4146
fork = mock<MerkleTreeWriteOperations>();
4247
blockBuilder.getFork.mockResolvedValue(fork);
4348

49+
ts = BigInt(Math.ceil(Date.now() / 1000));
50+
l1Constants = {
51+
l1StartBlock: 1n,
52+
l1GenesisTime: ts,
53+
slotDuration: 24,
54+
epochDuration: 8,
55+
ethereumSlotDuration: 12,
56+
proofSubmissionEpochs: 1,
57+
};
58+
59+
epochCache.getL1Constants.mockReturnValue(l1Constants);
60+
4461
watcher = new EpochPruneWatcher(l2BlockSource, l1ToL2MessageSource, epochCache, txProvider, blockBuilder, {
4562
slashPrunePenalty: validEpochPrunedPenalty,
4663
slashDataWithholdingPenalty: dataWithholdingPenalty,
@@ -54,9 +71,10 @@ describe('EpochPruneWatcher', () => {
5471

5572
it('should emit WANT_TO_SLASH_EVENT when a validator is in a pruned epoch when data is unavailable', async () => {
5673
const emitSpy = jest.spyOn(watcher, 'emit');
74+
const epochNumber = 1n;
5775

5876
const block = await L2Block.random(
59-
1, // block number
77+
12, // block number
6078
4, // txs per block
6179
);
6280
txProvider.getAvailableTxs.mockResolvedValue({ txs: [], missingTxs: [block.body.txEffects[0].txHash] });
@@ -68,11 +86,11 @@ describe('EpochPruneWatcher', () => {
6886
epochCache.getCommitteeForEpoch.mockResolvedValue({
6987
committee: committee.map(EthAddress.fromString),
7088
seed: 0n,
71-
epoch: 1n,
89+
epoch: epochNumber,
7290
});
7391

7492
l2BlockSource.emit(L2BlockSourceEvents.L2PruneDetected, {
75-
epochNumber: 1n,
93+
epochNumber,
7694
blocks: [block],
7795
type: L2BlockSourceEvents.L2PruneDetected,
7896
});
@@ -85,13 +103,13 @@ describe('EpochPruneWatcher', () => {
85103
validator: EthAddress.fromString(committee[0]),
86104
amount: dataWithholdingPenalty,
87105
offenseType: OffenseType.DATA_WITHHOLDING,
88-
epochOrSlot: 1n,
106+
epochOrSlot: epochNumber,
89107
},
90108
{
91109
validator: EthAddress.fromString(committee[1]),
92110
amount: dataWithholdingPenalty,
93111
offenseType: OffenseType.DATA_WITHHOLDING,
94-
epochOrSlot: 1n,
112+
epochOrSlot: epochNumber,
95113
},
96114
] satisfies WantToSlashArgs[]);
97115
});
@@ -100,7 +118,7 @@ describe('EpochPruneWatcher', () => {
100118
const emitSpy = jest.spyOn(watcher, 'emit');
101119

102120
const block = await L2Block.random(
103-
1, // block number
121+
12, // block number
104122
4, // txs per block
105123
);
106124
const tx = Tx.random();
@@ -152,11 +170,11 @@ describe('EpochPruneWatcher', () => {
152170
const emitSpy = jest.spyOn(watcher, 'emit');
153171

154172
const blockFromL1 = await L2Block.random(
155-
1, // block number
173+
12, // block number
156174
1, // txs per block
157175
);
158176
const blockFromBuilder = await L2Block.random(
159-
2, // block number
177+
13, // block number
160178
1, // txs per block
161179
);
162180
const tx = Tx.random();

yarn-project/slasher/src/watchers/epoch_prune_watcher.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
type L2BlockSourceEventEmitter,
1010
L2BlockSourceEvents,
1111
} from '@aztec/stdlib/block';
12+
import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
1213
import type {
1314
IFullNodeBlockBuilder,
1415
ITxProvider,
@@ -78,9 +79,14 @@ export class EpochPruneWatcher extends (EventEmitter as new () => WatcherEmitter
7879

7980
private handlePruneL2Blocks(event: L2BlockPruneEvent): void {
8081
const { blocks, epochNumber } = event;
81-
this.log.info(`Detected chain prune. Validating epoch ${epochNumber}`);
82+
const l1Constants = this.epochCache.getL1Constants();
83+
const epochBlocks = blocks.filter(b => getEpochAtSlot(b.slot, l1Constants) === epochNumber);
84+
this.log.info(
85+
`Detected chain prune. Validating epoch ${epochNumber} with blocks ${epochBlocks[0]?.number} to ${epochBlocks[epochBlocks.length - 1]?.number}.`,
86+
{ blocks: epochBlocks.map(b => b.toBlockInfo()) },
87+
);
8288

83-
this.validateBlocks(blocks)
89+
this.validateBlocks(epochBlocks)
8490
.then(async () => {
8591
this.log.info(`Pruned epoch ${epochNumber} was valid. Want to slash committee for not having it proven.`);
8692
const validators = await this.getValidatorsForEpoch(epochNumber);

0 commit comments

Comments
 (0)