Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(p2p): test bench scaffold #11758

Merged
merged 26 commits into from
Feb 7, 2025
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
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_p2p/p2p_network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { type Logger, createLogger } from '@aztec/foundation/log';
import { ForwarderAbi, ForwarderBytecode, RollupAbi, TestERC20Abi } from '@aztec/l1-artifacts';
import { SpamContract } from '@aztec/noir-contracts.js/Spam';
import { type BootstrapNode } from '@aztec/p2p';
import { createBootstrapNodeFromPrivateKey } from '@aztec/p2p/mocks';
import { createBootstrapNodeFromPrivateKey } from '@aztec/p2p/test-helpers';

import getPort from 'get-port';
import { getContract } from 'viem';
Expand Down
23 changes: 20 additions & 3 deletions yarn-project/epoch-cache/src/epoch_cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ type EpochAndSlot = {
ts: bigint;
};

export interface EpochCacheInterface {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interface added to make mocking simpler in the mock p2p client

getCommittee(nextSlot: boolean): Promise<EthAddress[]>;
getEpochAndSlotNow(): EpochAndSlot;
getProposerIndexEncoding(epoch: bigint, slot: bigint, seed: bigint): `0x${string}`;
computeProposerIndex(slot: bigint, epoch: bigint, seed: bigint, size: bigint): bigint;
getProposerInCurrentOrNextSlot(): Promise<{
currentProposer: EthAddress;
nextProposer: EthAddress;
currentSlot: bigint;
nextSlot: bigint;
}>;
isInCommittee(validator: EthAddress): Promise<boolean>;
}

/**
* Epoch cache
*
Expand All @@ -30,7 +44,10 @@ type EpochAndSlot = {
*
* Note: This class is very dependent on the system clock being in sync.
*/
export class EpochCache extends EventEmitter<{ committeeChanged: [EthAddress[], bigint] }> {
export class EpochCache
extends EventEmitter<{ committeeChanged: [EthAddress[], bigint] }>
implements EpochCacheInterface
{
private committee: EthAddress[];
private cachedEpoch: bigint;
private cachedSampleSeed: bigint;
Expand Down Expand Up @@ -99,12 +116,12 @@ export class EpochCache extends EventEmitter<{ committeeChanged: [EthAddress[],
return this.getEpochAndSlotAtTimestamp(this.nowInSeconds());
}

getEpochAndSlotInNextSlot(): EpochAndSlot {
private getEpochAndSlotInNextSlot(): EpochAndSlot {
const nextSlotTs = this.nowInSeconds() + BigInt(this.l1constants.slotDuration);
return this.getEpochAndSlotAtTimestamp(nextSlotTs);
}

getEpochAndSlotAtTimestamp(ts: bigint): EpochAndSlot {
private getEpochAndSlotAtTimestamp(ts: bigint): EpochAndSlot {
return {
epoch: getEpochNumberAtTimestamp(ts, this.l1constants),
slot: getSlotAtTimestamp(ts, this.l1constants),
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/foundation/src/config/env_var.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ export type EnvVar =
| 'DATA_DIRECTORY'
| 'DATA_STORE_MAP_SIZE_KB'
| 'DEBUG'
| 'DEBUG_P2P_DISABLE_MESSAGE_VALIDATION'
| 'DEBUG_P2P_DISABLE_COLOCATION_PENALTY'
| 'DEPLOY_AZTEC_CONTRACTS_SALT'
| 'DEPLOY_AZTEC_CONTRACTS'
| 'ENFORCE_FEES'
Expand Down Expand Up @@ -83,6 +85,8 @@ export type EnvVar =
| 'P2P_GOSSIPSUB_D'
| 'P2P_GOSSIPSUB_DHI'
| 'P2P_GOSSIPSUB_DLO'
| 'P2P_GOSSIPSUB_DLAZY'
| 'P2P_GOSSIPSUB_FLOOD_PUBLISH'
| 'P2P_GOSSIPSUB_INTERVAL_MS'
| 'P2P_GOSSIPSUB_MCACHE_GOSSIP'
| 'P2P_GOSSIPSUB_MCACHE_LENGTH'
Expand Down
12 changes: 10 additions & 2 deletions yarn-project/foundation/src/log/log-filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ export type LogFilters = [string, LogLevel][];

export function getLogLevelFromFilters(filters: LogFilters, module: string): LogLevel | undefined {
for (const [filterModule, level] of filters) {
if (module.startsWith(filterModule)) {
return level as LogLevel;
try {
const regex = new RegExp(filterModule);
if (regex.test(module)) {
return level as LogLevel;
}
} catch {
// If regex is invalid, fall back to startsWith check
if (module.startsWith(filterModule)) {
return level as LogLevel;
}
}
}
return undefined;
Expand Down
18 changes: 15 additions & 3 deletions yarn-project/foundation/src/log/pino-logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,23 @@ import { getLogLevelFromFilters, parseEnv } from './log-filters.js';
import { type LogLevel } from './log-levels.js';
import { type LogData, type LogFn } from './log_fn.js';

export function createLogger(module: string): Logger {
export function createLogger(module: string, fixedTerms = {}): Logger {
module = logNameHandlers.reduce((moduleName, handler) => handler(moduleName), module.replace(/^aztec:/, ''));
const pinoLogger = logger.child({ module }, { level: getLogLevelFromFilters(logFilters, module) });

// Only perform copy of data if fixed terms are provided
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used in the libp2p logger to enable tagging the sourcePeer to all messages. If fixed terms are not set, then we should skip doing the extra allocation in the ternary operation below

const hasFixedTerms = Object.keys(fixedTerms).length > 0;

// We check manually for isLevelEnabled to avoid calling processLogData unnecessarily.
// Note that isLevelEnabled is missing from the browser version of pino.
const logFn = (level: LogLevel, msg: string, data?: unknown) =>
isLevelEnabled(pinoLogger, level) && pinoLogger[level](processLogData((data as LogData) ?? {}), msg);
isLevelEnabled(pinoLogger, level) &&
pinoLogger[level](
hasFixedTerms
? processLogData({ ...fixedTerms, ...(data ?? {}) } as LogData)
: processLogData((data as LogData) ?? {}),
msg,
);

return {
silent: () => {},
Expand Down Expand Up @@ -149,7 +158,10 @@ function makeLogger() {
if (!isNode) {
// We are on the browser.
return pino({ ...pinoOpts, browser: { asObject: false } });
} else if (process.env.JEST_WORKER_ID) {
}
// If running in a child process then cancel this if statement section by uncommenting below
// else if (false) {
else if (process.env.JEST_WORKER_ID) {
// We are on jest, so we need sync logging and stream to stderr.
// We expect jest/setup.mjs to kick in later and replace set up a pretty logger,
// but if for some reason it doesn't, at least we're covered with a default logger.
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/p2p/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "module",
"exports": {
".": "./dest/index.js",
"./mocks": "./dest/mocks/index.js",
"./test-helpers": "./dest/test-helpers/index.js",
"./bootstrap": "./dest/bootstrap/bootstrap.js",
"./config": "./dest/config.js",
"./msg_validators": "./dest/msg_validators/index.js"
Expand Down
17 changes: 12 additions & 5 deletions yarn-project/p2p/src/client/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
P2PClientType,
type WorldStateSynchronizer,
} from '@aztec/circuit-types';
import { type EpochCache } from '@aztec/epoch-cache';
import { createLogger } from '@aztec/foundation/log';
import { type EpochCacheInterface } from '@aztec/epoch-cache';
import { type Logger, createLogger } from '@aztec/foundation/log';
import { type AztecAsyncKVStore } from '@aztec/kv-store';
import { type DataStoreConfig } from '@aztec/kv-store/config';
import { createStore } from '@aztec/kv-store/lmdb-v2';
Expand All @@ -29,6 +29,7 @@ type P2PClientDeps<T extends P2PClientType> = {
store?: AztecAsyncKVStore;
attestationPool?: T extends P2PClientType.Full ? AttestationPool : undefined;
epochProofQuotePool?: EpochProofQuotePool;
logger?: Logger;
};

export const createP2PClient = async <T extends P2PClientType>(
Expand All @@ -37,12 +38,12 @@ export const createP2PClient = async <T extends P2PClientType>(
l2BlockSource: L2BlockSource,
proofVerifier: ClientProtocolCircuitVerifier,
worldStateSynchronizer: WorldStateSynchronizer,
epochCache: EpochCache,
epochCache: EpochCacheInterface,
telemetry: TelemetryClient = getTelemetryClient(),
deps: P2PClientDeps<T> = {},
) => {
let config = { ..._config };
const logger = createLogger('p2p');
const logger = deps.logger ?? createLogger('p2p');
const store = deps.store ?? (await createStore('p2p', config, createLogger('p2p:lmdb-v2')));
const archive = await createStore('p2p-archive', config, createLogger('p2p-archive:lmdb-v2'));

Expand All @@ -66,7 +67,12 @@ export const createP2PClient = async <T extends P2PClientType>(
// Create peer discovery service
const peerIdPrivateKey = await getPeerIdPrivateKey(config, store);
const peerId = await createLibP2PPeerIdFromPrivateKey(peerIdPrivateKey);
const discoveryService = new DiscV5Service(peerId, config, telemetry);
const discoveryService = new DiscV5Service(
peerId,
config,
telemetry,
createLogger(`${logger.module}:discv5_service`),
);

p2pService = await LibP2PService.new<T>(
clientType,
Expand All @@ -80,6 +86,7 @@ export const createP2PClient = async <T extends P2PClientType>(
worldStateSynchronizer,
store,
telemetry,
createLogger(`${logger.module}:libp2p_service`),
);
} else {
logger.verbose('P2P is disabled. Using dummy P2P service');
Expand Down
Loading
Loading