Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions yarn-project/end-to-end/src/fixtures/setup_p2p_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ export type CreateNodeConfig = AztecNodeConfig & {
dontStartSequencer?: boolean;
/** Override the private key (instead of deriving from addressIndex). */
validatorPrivateKey?: `0x${string}`;
/** Corrupt only the block proposal at this indexWithinCheckpoint (testing only). */
invalidBlockProposalIndexWithinCheckpoint?: number;
/** Accept proposal gossip regardless of slot timing (testing only). */
skipProposalSlotValidation?: boolean;
};

/** Creates a P2P enabled instance of Aztec Node Service with a validator. */
Expand Down
7 changes: 7 additions & 0 deletions yarn-project/p2p/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ export interface P2PConfig

/** Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only) */
skipIncomingProposals?: boolean;

/** Accept proposal gossip regardless of slot timing (for testing only). */
skipProposalSlotValidation?: boolean;
}

export const DEFAULT_P2P_PORT = 40400;
Expand Down Expand Up @@ -554,6 +557,10 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
description: 'Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only)',
...booleanConfigHelper(false),
},
skipProposalSlotValidation: {
description: 'Accept proposal gossip regardless of slot timing (for testing only)',
...booleanConfigHelper(false),
},
minTxPoolAgeMs: {
env: 'P2P_MIN_TX_POOL_AGE_MS',
description: 'Minimum age (ms) a transaction must have been in the pool before it is eligible for block building.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class BlockProposalValidator implements P2PValidator<BlockProposal> {
maxTxsPerBlock?: number;
maxBlocksPerCheckpoint?: number;
p2pPropagationTime?: number;
skipSlotValidation?: boolean;
signatureContext: CoordinationSignatureContext;
},
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class CheckpointProposalValidator implements P2PValidator<CheckpointPropo
maxTxsPerBlock?: number;
maxBlocksPerCheckpoint?: number;
p2pPropagationTime?: number;
skipSlotValidation?: boolean;
signatureContext: CoordinationSignatureContext;
},
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class ProposalValidator {
private maxTxsPerBlock?: number;
private maxBlocksPerCheckpoint?: number;
private pipeliningWindow: PipeliningWindow;
private skipSlotValidation: boolean;
private signatureContext: CoordinationSignatureContext;

constructor(
Expand All @@ -29,6 +30,7 @@ export class ProposalValidator {
maxTxsPerBlock?: number;
maxBlocksPerCheckpoint?: number;
p2pPropagationTime?: number;
skipSlotValidation?: boolean;
signatureContext: CoordinationSignatureContext;
},
loggerName: string,
Expand All @@ -38,6 +40,7 @@ export class ProposalValidator {
this.maxTxsPerBlock = opts.maxTxsPerBlock;
this.maxBlocksPerCheckpoint = opts.maxBlocksPerCheckpoint;
this.pipeliningWindow = new PipeliningWindow(epochCache, { p2pPropagationTime: opts.p2pPropagationTime });
this.skipSlotValidation = opts.skipSlotValidation ?? false;
this.signatureContext = opts.signatureContext;
this.logger = createLogger(loggerName);
}
Expand All @@ -60,7 +63,7 @@ export class ProposalValidator {
const { targetSlot, nextSlot } = this.epochCache.getTargetAndNextSlot();

const slotNumber = proposal.slotNumber;
if (slotNumber !== targetSlot && slotNumber !== nextSlot) {
if (!this.skipSlotValidation && slotNumber !== targetSlot && slotNumber !== nextSlot) {
// When pipelining, accept proposals for the current slot (built in the previous slot)
// if they're still within the shared proposal acceptance window.
if (this.pipeliningWindow.acceptsProposal(slotNumber)) {
Expand Down
1 change: 1 addition & 0 deletions yarn-project/p2p/src/services/libp2p/libp2p_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ export class LibP2PService extends WithTracer implements P2PService {
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
p2pPropagationTime,
skipSlotValidation: config.skipProposalSlotValidation,
signatureContext: {
chainId: config.l1ChainId,
rollupAddress: config.rollupAddress,
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/sequencer-client/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
description: 'Broadcast invalid block proposals with corrupted state (for testing only)',
...booleanConfigHelper(DefaultSequencerConfig.broadcastInvalidBlockProposal),
},
invalidBlockProposalIndexWithinCheckpoint: {
description: 'Broadcast an invalid block proposal only at this indexWithinCheckpoint (for testing only)',
...optionalNumberConfigHelper(),
},
injectFakeAttestation: {
description: 'Inject a fake attestation (for testing only)',
...booleanConfigHelper(DefaultSequencerConfig.injectFakeAttestation),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,12 @@ export class CheckpointProposalJob implements Traceable {
usedTxs.forEach(tx => txHashesAlreadyIncluded.add(tx.txHash.toString()));

// Sign the block proposal. This will throw if HA signing fails.
const proposal = await this.createBlockProposal(block, inHash, usedTxs, blockProposalOptions);
const proposal = await this.createBlockProposal(block, inHash, usedTxs, {
...blockProposalOptions,
broadcastInvalidBlockProposal:
blockProposalOptions.broadcastInvalidBlockProposal ||
block.indexWithinCheckpoint === this.config.invalidBlockProposalIndexWithinCheckpoint,
});

// Sync the proposed block to the archiver to make it available, only after we've managed to sign the proposal,
// so we avoid polluting our archive with a block that would fail.
Expand Down Expand Up @@ -1099,6 +1104,9 @@ export class CheckpointProposalJob implements Traceable {
// `buildSlot` is the wall-clock slot during which the block was actually built.
this.eventEmitter.emit('block-proposed', {
blockNumber: block.number,
blockHash,
checkpointNumber: this.checkpointNumber,
indexWithinCheckpoint: block.indexWithinCheckpoint,
slot: this.targetSlot,
buildSlot: this.slotNow,
});
Expand Down
12 changes: 10 additions & 2 deletions yarn-project/sequencer-client/src/sequencer/events.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
import type { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
import type { BlockHash } from '@aztec/stdlib/block';

import type { Action } from '../publisher/sequencer-publisher.js';
import type { SequencerState } from './utils.js';
Expand Down Expand Up @@ -37,7 +38,14 @@ export type SequencerEvents = {
['proposer-rollup-check-failed']: (args: { reason: string; slot: SlotNumber }) => void;
['block-tx-count-check-failed']: (args: { minTxs: number; availableTxs: number; slot: SlotNumber }) => void;
['block-build-failed']: (args: { reason: string; slot: SlotNumber }) => void;
['block-proposed']: (args: { blockNumber: BlockNumber; slot: SlotNumber; buildSlot: SlotNumber }) => void;
['block-proposed']: (args: {
blockNumber: BlockNumber;
blockHash: BlockHash;
checkpointNumber: CheckpointNumber;
indexWithinCheckpoint: IndexWithinCheckpoint;
slot: SlotNumber;
buildSlot: SlotNumber;
}) => void;
['checkpoint-empty']: (args: { slot: SlotNumber }) => void;
/**
* Emitted when the proposer's pre-broadcast `validateBlockHeader` simulation fails. This is a
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/stdlib/src/interfaces/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export interface SequencerConfig {
skipInvalidateBlockAsProposer?: boolean;
/** Broadcast invalid block proposals with corrupted state (for testing only) */
broadcastInvalidBlockProposal?: boolean;
/** Broadcast an invalid block proposal only at this indexWithinCheckpoint (for testing only) */
invalidBlockProposalIndexWithinCheckpoint?: number;
/** Inject a fake attestation (for testing only) */
injectFakeAttestation?: boolean;
/** Inject a malleable attestation with a high-s value (for testing only) */
Expand Down Expand Up @@ -121,6 +123,7 @@ export const SequencerConfigSchema = zodFor<SequencerConfig>()(
secondsBeforeInvalidatingBlockAsCommitteeMember: z.number(),
secondsBeforeInvalidatingBlockAsNonCommitteeMember: z.number(),
broadcastInvalidBlockProposal: z.boolean().optional(),
invalidBlockProposalIndexWithinCheckpoint: z.number().int().nonnegative().optional(),
injectFakeAttestation: z.boolean().optional(),
injectHighSValueAttestation: z.boolean().optional(),
injectUnrecoverableSignatureAttestation: z.boolean().optional(),
Expand Down Expand Up @@ -149,6 +152,7 @@ type SequencerConfigOptionalKeys =
| 'fakeThrowAfterProcessingTxCount'
| 'l1PublishingTime'
| 'txPublicSetupAllowListExtend'
| 'invalidBlockProposalIndexWithinCheckpoint'
| 'minValidTxsPerBlock'
| 'minBlocksForCheckpoint'
| 'maxTxsPerBlock'
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/stdlib/src/interfaces/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export type ValidatorClientConfig = ValidatorHASignerConfig &
/** Agree to attest to equivocated checkpoint proposals (for testing purposes only) */
attestToEquivocatedProposals?: boolean;

/** Accept proposal validation regardless of slot timing (for testing only) */
skipProposalSlotValidation?: boolean;

/** Maximum L2 gas per block for validation. Proposals exceeding this limit are rejected. */
validateMaxL2BlockGas?: number;

Expand Down Expand Up @@ -107,6 +110,7 @@ export const ValidatorClientConfigSchema = zodFor<Omit<ValidatorClientConfig, 'v
skipCheckpointProposalValidation: z.boolean().optional(),
skipPushProposedBlocksToArchiver: z.boolean().optional(),
attestToEquivocatedProposals: z.boolean().optional(),
skipProposalSlotValidation: z.boolean().optional(),
validateMaxL2BlockGas: z.number().optional(),
validateMaxDABlockGas: z.number().optional(),
validateMaxTxsPerBlock: z.number().optional(),
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/validator-client/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export const validatorClientConfigMappings: ConfigMappingsType<ValidatorClientCo
description: 'Agree to attest to equivocated checkpoint proposals (for testing purposes only)',
...booleanConfigHelper(false),
},
skipProposalSlotValidation: {
description: 'Accept proposal validation regardless of slot timing (for testing only)',
...booleanConfigHelper(false),
},
validateMaxL2BlockGas: {
env: 'VALIDATOR_MAX_L2_BLOCK_GAS',
description: 'Maximum L2 block gas for validation. Proposals exceeding this limit are rejected.',
Expand Down
8 changes: 8 additions & 0 deletions yarn-project/validator-client/src/proposal_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,14 @@ export class ProposalHandler {
return undefined;
}

if (this.config.skipCheckpointProposalValidation) {
this.log.warn(
`Skipping all-nodes checkpoint proposal validation for slot ${proposal.slotNumber}`,
proposalInfo,
);
return undefined;
}

const result = await this.handleCheckpointProposal(proposal, proposalInfo);
if (result.isValid && this.archiver && this.epochCache.isProposerPipeliningEnabled()) {
const set = await this.setProposedCheckpointFromValidation(proposal);
Expand Down
4 changes: 3 additions & 1 deletion yarn-project/validator-client/src/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
txsPermitted: !config.disableTransactions,
maxTxsPerBlock: config.validateMaxTxsPerBlock,
maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
skipSlotValidation: config.skipProposalSlotValidation,
signatureContext: {
chainId: config.l1ChainId,
rollupAddress: config.rollupAddress,
Expand Down Expand Up @@ -876,7 +877,8 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
proposerAddress,
{
...options,
broadcastInvalidBlockProposal: this.config.broadcastInvalidBlockProposal,
broadcastInvalidBlockProposal:
options.broadcastInvalidBlockProposal || this.config.broadcastInvalidBlockProposal,
},
);
this.lastProposedBlock = newProposal;
Expand Down
Loading