Skip to content

Commit 081fc7c

Browse files
committed
test: add tests
1 parent 943ca27 commit 081fc7c

15 files changed

Lines changed: 638 additions & 5 deletions

File tree

yarn-project/end-to-end/src/e2e_slashing/attested_invalid_proposal.test.ts

Lines changed: 574 additions & 0 deletions
Large diffs are not rendered by default.

yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ export type CreateNodeConfig = AztecNodeConfig & {
8888
dontStartSequencer?: boolean;
8989
/** Override the private key (instead of deriving from addressIndex). */
9090
validatorPrivateKey?: `0x${string}`;
91+
/** Corrupt only the block proposal at this indexWithinCheckpoint (testing only). */
92+
invalidBlockProposalIndexWithinCheckpoint?: number;
93+
/** Accept proposal gossip regardless of slot timing (testing only). */
94+
skipProposalSlotValidation?: boolean;
9195
};
9296

9397
/** Creates a P2P enabled instance of Aztec Node Service with a validator. */

yarn-project/p2p/src/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ export interface P2PConfig
229229

230230
/** Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only) */
231231
skipIncomingProposals?: boolean;
232+
233+
/** Accept proposal gossip regardless of slot timing (for testing only). */
234+
skipProposalSlotValidation?: boolean;
232235
}
233236

234237
export const DEFAULT_P2P_PORT = 40400;
@@ -554,6 +557,10 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
554557
description: 'Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only)',
555558
...booleanConfigHelper(false),
556559
},
560+
skipProposalSlotValidation: {
561+
description: 'Accept proposal gossip regardless of slot timing (for testing only)',
562+
...booleanConfigHelper(false),
563+
},
557564
minTxPoolAgeMs: {
558565
env: 'P2P_MIN_TX_POOL_AGE_MS',
559566
description: 'Minimum age (ms) a transaction must have been in the pool before it is eligible for block building.',

yarn-project/p2p/src/msg_validators/proposal_validator/block_proposal_validator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class BlockProposalValidator implements P2PValidator<BlockProposal> {
1313
maxTxsPerBlock?: number;
1414
maxBlocksPerCheckpoint?: number;
1515
p2pPropagationTime?: number;
16+
skipSlotValidation?: boolean;
1617
signatureContext: CoordinationSignatureContext;
1718
},
1819
) {

yarn-project/p2p/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class CheckpointProposalValidator implements P2PValidator<CheckpointPropo
1818
maxTxsPerBlock?: number;
1919
maxBlocksPerCheckpoint?: number;
2020
p2pPropagationTime?: number;
21+
skipSlotValidation?: boolean;
2122
signatureContext: CoordinationSignatureContext;
2223
},
2324
) {

yarn-project/p2p/src/msg_validators/proposal_validator/proposal_validator.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export class ProposalValidator {
2020
private maxTxsPerBlock?: number;
2121
private maxBlocksPerCheckpoint?: number;
2222
private pipeliningWindow: PipeliningWindow;
23+
private skipSlotValidation: boolean;
2324
private signatureContext: CoordinationSignatureContext;
2425

2526
constructor(
@@ -29,6 +30,7 @@ export class ProposalValidator {
2930
maxTxsPerBlock?: number;
3031
maxBlocksPerCheckpoint?: number;
3132
p2pPropagationTime?: number;
33+
skipSlotValidation?: boolean;
3234
signatureContext: CoordinationSignatureContext;
3335
},
3436
loggerName: string,
@@ -38,6 +40,7 @@ export class ProposalValidator {
3840
this.maxTxsPerBlock = opts.maxTxsPerBlock;
3941
this.maxBlocksPerCheckpoint = opts.maxBlocksPerCheckpoint;
4042
this.pipeliningWindow = new PipeliningWindow(epochCache, { p2pPropagationTime: opts.p2pPropagationTime });
43+
this.skipSlotValidation = opts.skipSlotValidation ?? false;
4144
this.signatureContext = opts.signatureContext;
4245
this.logger = createLogger(loggerName);
4346
}
@@ -60,7 +63,7 @@ export class ProposalValidator {
6063
const { targetSlot, nextSlot } = this.epochCache.getTargetAndNextSlot();
6164

6265
const slotNumber = proposal.slotNumber;
63-
if (slotNumber !== targetSlot && slotNumber !== nextSlot) {
66+
if (!this.skipSlotValidation && slotNumber !== targetSlot && slotNumber !== nextSlot) {
6467
// When pipelining, accept proposals for the current slot (built in the previous slot)
6568
// if they're still within the shared proposal acceptance window.
6669
if (this.pipeliningWindow.acceptsProposal(slotNumber)) {

yarn-project/p2p/src/services/libp2p/libp2p_service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ export class LibP2PService extends WithTracer implements P2PService {
240240
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
241241
maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
242242
p2pPropagationTime,
243+
skipSlotValidation: config.skipProposalSlotValidation,
243244
signatureContext: {
244245
chainId: config.l1ChainId,
245246
rollupAddress: config.rollupAddress,

yarn-project/sequencer-client/src/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
191191
description: 'Broadcast invalid block proposals with corrupted state (for testing only)',
192192
...booleanConfigHelper(DefaultSequencerConfig.broadcastInvalidBlockProposal),
193193
},
194+
invalidBlockProposalIndexWithinCheckpoint: {
195+
description: 'Broadcast an invalid block proposal only at this indexWithinCheckpoint (for testing only)',
196+
...optionalNumberConfigHelper(),
197+
},
194198
injectFakeAttestation: {
195199
description: 'Inject a fake attestation (for testing only)',
196200
...booleanConfigHelper(DefaultSequencerConfig.injectFakeAttestation),

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,12 @@ export class CheckpointProposalJob implements Traceable {
879879
usedTxs.forEach(tx => txHashesAlreadyIncluded.add(tx.txHash.toString()));
880880

881881
// Sign the block proposal. This will throw if HA signing fails.
882-
const proposal = await this.createBlockProposal(block, inHash, usedTxs, blockProposalOptions);
882+
const proposal = await this.createBlockProposal(block, inHash, usedTxs, {
883+
...blockProposalOptions,
884+
broadcastInvalidBlockProposal:
885+
blockProposalOptions.broadcastInvalidBlockProposal ||
886+
block.indexWithinCheckpoint === this.config.invalidBlockProposalIndexWithinCheckpoint,
887+
});
883888

884889
// Sync the proposed block to the archiver to make it available, only after we've managed to sign the proposal,
885890
// so we avoid polluting our archive with a block that would fail.
@@ -1099,6 +1104,9 @@ export class CheckpointProposalJob implements Traceable {
10991104
// `buildSlot` is the wall-clock slot during which the block was actually built.
11001105
this.eventEmitter.emit('block-proposed', {
11011106
blockNumber: block.number,
1107+
blockHash,
1108+
checkpointNumber: this.checkpointNumber,
1109+
indexWithinCheckpoint: block.indexWithinCheckpoint,
11021110
slot: this.targetSlot,
11031111
buildSlot: this.slotNow,
11041112
});

yarn-project/sequencer-client/src/sequencer/events.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
1+
import type { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
2+
import type { BlockHash } from '@aztec/stdlib/block';
23

34
import type { Action } from '../publisher/sequencer-publisher.js';
45
import type { SequencerState } from './utils.js';
@@ -37,7 +38,14 @@ export type SequencerEvents = {
3738
['proposer-rollup-check-failed']: (args: { reason: string; slot: SlotNumber }) => void;
3839
['block-tx-count-check-failed']: (args: { minTxs: number; availableTxs: number; slot: SlotNumber }) => void;
3940
['block-build-failed']: (args: { reason: string; slot: SlotNumber }) => void;
40-
['block-proposed']: (args: { blockNumber: BlockNumber; slot: SlotNumber; buildSlot: SlotNumber }) => void;
41+
['block-proposed']: (args: {
42+
blockNumber: BlockNumber;
43+
blockHash: BlockHash;
44+
checkpointNumber: CheckpointNumber;
45+
indexWithinCheckpoint: IndexWithinCheckpoint;
46+
slot: SlotNumber;
47+
buildSlot: SlotNumber;
48+
}) => void;
4149
['checkpoint-empty']: (args: { slot: SlotNumber }) => void;
4250
/**
4351
* Emitted when the proposer's pre-broadcast `validateBlockHeader` simulation fails. This is a

0 commit comments

Comments
 (0)