diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69148590613..6b9aa664cdd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -175,6 +175,7 @@ jobs: LABELS="" fi echo Labels: $LABELS + echo REF: $REF echo "list=$(./scripts/ci/get_e2e_jobs.sh $REF "$LABELS")" echo "list=$(./scripts/ci/get_e2e_jobs.sh $REF "$LABELS")" >> $GITHUB_OUTPUT - name: Create list of bench end-to-end jobs diff --git a/yarn-project/aztec-node/src/aztec-node/server.test.ts b/yarn-project/aztec-node/src/aztec-node/server.test.ts index 942c544b26f..3508f8068f7 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.test.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.test.ts @@ -7,6 +7,7 @@ import { MerkleTreeId, type MerkleTreeReadOperations, type NullifierWithBlockSource, + type P2PClientType, type WorldStateSynchronizer, mockTxForRollup, } from '@aztec/circuit-types'; @@ -21,7 +22,7 @@ import { type AztecNodeConfig, getConfigEnvVars } from './config.js'; import { AztecNodeService } from './server.js'; describe('aztec node', () => { - let p2p: MockProxy; + let p2p: MockProxy>; let globalVariablesBuilder: MockProxy; let merkleTreeOps: MockProxy; @@ -34,7 +35,7 @@ describe('aztec node', () => { beforeEach(() => { lastBlockNumber = 0; - p2p = mock(); + p2p = mock>(); globalVariablesBuilder = mock(); merkleTreeOps = mock(); diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index fa7904296cc..8d61932840f 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -15,6 +15,7 @@ import { MerkleTreeId, NullifierMembershipWitness, type NullifierWithBlockSource, + P2PClientType, type ProcessedTx, type ProverConfig, PublicDataWitness, @@ -92,7 +93,7 @@ export class AztecNodeService implements AztecNode { constructor( protected config: AztecNodeConfig, - protected readonly p2pClient: P2P, + protected readonly p2pClient: P2P, protected readonly blockSource: L2BlockSource & Partial, protected readonly logsSource: L2LogsSource, protected readonly contractDataSource: ContractDataSource, @@ -162,7 +163,14 @@ export class AztecNodeService implements AztecNode { } // create the tx pool and the p2p client, which will need the l2 block source - const p2pClient = await createP2PClient(config, archiver, proofVerifier, worldStateSynchronizer, telemetry); + const p2pClient = await createP2PClient( + P2PClientType.Full, + config, + archiver, + proofVerifier, + worldStateSynchronizer, + telemetry, + ); // start both and wait for them to sync from the block source await Promise.all([p2pClient.start(), worldStateSynchronizer.start()]); @@ -214,7 +222,7 @@ export class AztecNodeService implements AztecNode { return this.blockSource; } - public getP2P(): P2P { + public getP2P(): P2P { return this.p2pClient; } diff --git a/yarn-project/circuit-types/src/interfaces/p2p.test.ts b/yarn-project/circuit-types/src/interfaces/p2p.test.ts index d9eb0cc654a..ffd506c0276 100644 --- a/yarn-project/circuit-types/src/interfaces/p2p.test.ts +++ b/yarn-project/circuit-types/src/interfaces/p2p.test.ts @@ -1,19 +1,20 @@ import { type JsonRpcTestContext, createJsonRpcTestSetup } from '@aztec/foundation/json-rpc/test'; import { BlockAttestation } from '../p2p/block_attestation.js'; +import { type P2PClientType } from '../p2p/client_type.js'; import { EpochProofQuote } from '../prover_coordination/epoch_proof_quote.js'; import { Tx } from '../tx/tx.js'; import { type P2PApi, P2PApiSchema, type PeerInfo } from './p2p.js'; describe('P2PApiSchema', () => { let handler: MockP2P; - let context: JsonRpcTestContext; + let context: JsonRpcTestContext>; const tested = new Set(); beforeEach(async () => { handler = new MockP2P(); - context = await createJsonRpcTestSetup(handler, P2PApiSchema); + context = await createJsonRpcTestSetup>(handler, P2PApiSchema); }); afterEach(() => { @@ -65,7 +66,7 @@ const peers: PeerInfo[] = [ { status: 'cached', id: 'id', addresses: ['address'], enr: 'enr', dialAttempts: 1 }, ]; -class MockP2P implements P2PApi { +class MockP2P implements P2PApi { getAttestationsForSlot(slot: bigint, proposalId?: string | undefined): Promise { expect(slot).toEqual(1n); expect(proposalId).toEqual('proposalId'); diff --git a/yarn-project/circuit-types/src/interfaces/p2p.ts b/yarn-project/circuit-types/src/interfaces/p2p.ts index 00fa526899d..5721d19c590 100644 --- a/yarn-project/circuit-types/src/interfaces/p2p.ts +++ b/yarn-project/circuit-types/src/interfaces/p2p.ts @@ -3,6 +3,7 @@ import { type ApiSchemaFor, optional, schemas } from '@aztec/foundation/schemas' import { z } from 'zod'; import { BlockAttestation } from '../p2p/block_attestation.js'; +import { type P2PClientType } from '../p2p/client_type.js'; import { EpochProofQuote } from '../prover_coordination/epoch_proof_quote.js'; import { Tx } from '../tx/tx.js'; @@ -24,16 +25,7 @@ const PeerInfoSchema = z.discriminatedUnion('status', [ ]); /** Exposed API to the P2P module. */ -export interface P2PApi { - /** - * Queries the Attestation pool for attestations for the given slot - * - * @param slot - the slot to query - * @param proposalId - the proposal id to query, or undefined to query all proposals for the slot - * @returns BlockAttestations - */ - getAttestationsForSlot(slot: bigint, proposalId?: string): Promise; - +export interface P2PApiWithoutAttestations { /** * Queries the EpochProofQuote pool for quotes for the given epoch * @@ -59,7 +51,22 @@ export interface P2PApi { getPeers(includePending?: boolean): Promise; } -export const P2PApiSchema: ApiSchemaFor = { +export interface P2PClient extends P2PApiWithoutAttestations { + /** + * Queries the Attestation pool for attestations for the given slot + * + * @param slot - the slot to query + * @param proposalId - the proposal id to query, or undefined to query all proposals for the slot + * @returns BlockAttestations + */ + getAttestationsForSlot(slot: bigint, proposalId?: string): Promise; +} + +export type P2PApi = T extends P2PClientType.Full + ? P2PClient & P2PApiWithoutAttestations + : P2PApiWithoutAttestations; + +export const P2PApiSchema: ApiSchemaFor> = { getAttestationsForSlot: z .function() .args(schemas.BigInt, optional(z.string())) diff --git a/yarn-project/circuit-types/src/p2p/client_type.ts b/yarn-project/circuit-types/src/p2p/client_type.ts new file mode 100644 index 00000000000..75d1fea547c --- /dev/null +++ b/yarn-project/circuit-types/src/p2p/client_type.ts @@ -0,0 +1,6 @@ +export enum P2PClientType { + // Full p2p clients will subscribe to all gossip topics + Full, + // Prove p2p clients will only subscribe to transaction and proving topics + Prover, +} diff --git a/yarn-project/circuit-types/src/p2p/index.ts b/yarn-project/circuit-types/src/p2p/index.ts index 0974775870a..972988c8b7f 100644 --- a/yarn-project/circuit-types/src/p2p/index.ts +++ b/yarn-project/circuit-types/src/p2p/index.ts @@ -5,3 +5,4 @@ export * from './gossipable.js'; export * from './interface.js'; export * from './signature_utils.js'; export * from './topic_type.js'; +export * from './client_type.js'; diff --git a/yarn-project/circuit-types/src/p2p/topic_type.ts b/yarn-project/circuit-types/src/p2p/topic_type.ts index 8094905276c..db8d215a5ca 100644 --- a/yarn-project/circuit-types/src/p2p/topic_type.ts +++ b/yarn-project/circuit-types/src/p2p/topic_type.ts @@ -1,3 +1,5 @@ +import { P2PClientType } from './client_type.js'; + /** Create Topic String * * The topic channel identifier @@ -18,6 +20,13 @@ export enum TopicType { epoch_proof_quote = 'epoch_proof_quote', } +export function getTopicTypeForClientType(clientType: P2PClientType) { + if (clientType === P2PClientType.Full) { + return Object.values(TopicType); + } + return [TopicType.tx, TopicType.epoch_proof_quote]; +} + /** * Convert the topic string into a set of labels * diff --git a/yarn-project/ivc-integration/defl.sh b/yarn-project/ivc-integration/defl.sh new file mode 100755 index 00000000000..66790acb96c --- /dev/null +++ b/yarn-project/ivc-integration/defl.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +testname=$1 +script_dir=$(dirname "$0") + +for i in {1..100} +do + echo "Run #$i" + if ! taskset -c 0-1 yarn test $1 > $script_dir/deflaker.log 2>&1; then + echo "failed" + exit 1 + fi +done +echo "success" diff --git a/yarn-project/p2p/src/client/index.ts b/yarn-project/p2p/src/client/index.ts index 509e5d51614..3e3d5de5ca3 100644 --- a/yarn-project/p2p/src/client/index.ts +++ b/yarn-project/p2p/src/client/index.ts @@ -1,4 +1,9 @@ -import type { ClientProtocolCircuitVerifier, L2BlockSource, WorldStateSynchronizer } from '@aztec/circuit-types'; +import { + type ClientProtocolCircuitVerifier, + type L2BlockSource, + P2PClientType, + type WorldStateSynchronizer, +} from '@aztec/circuit-types'; import { createLogger } from '@aztec/foundation/log'; import { type AztecKVStore } from '@aztec/kv-store'; import { type DataStoreConfig } from '@aztec/kv-store/config'; @@ -21,27 +26,35 @@ import { configureP2PClientAddresses, createLibP2PPeerIdFromPrivateKey, getPeerI export * from './p2p_client.js'; -export const createP2PClient = async ( +type P2PClientDeps = { + txPool?: TxPool; + store?: AztecKVStore; + attestationPool?: T extends P2PClientType.Full ? AttestationPool : undefined; + epochProofQuotePool?: EpochProofQuotePool; +}; + +export const createP2PClient = async ( + clientType: T, _config: P2PConfig & DataStoreConfig, l2BlockSource: L2BlockSource, proofVerifier: ClientProtocolCircuitVerifier, worldStateSynchronizer: WorldStateSynchronizer, telemetry: TelemetryClient = new NoopTelemetryClient(), - deps: { - txPool?: TxPool; - store?: AztecKVStore; - attestationPool?: AttestationPool; - epochProofQuotePool?: EpochProofQuotePool; - } = {}, + deps: P2PClientDeps = {}, ) => { let config = { ..._config }; const logger = createLogger('p2p'); const store = deps.store ?? (await createStore('p2p', config, createLogger('p2p:lmdb'))); - const mempools: MemPools = { + const mempools: MemPools = { txPool: deps.txPool ?? new AztecKVTxPool(store, telemetry), - attestationPool: deps.attestationPool ?? new InMemoryAttestationPool(telemetry), epochProofQuotePool: deps.epochProofQuotePool ?? new MemoryEpochProofQuotePool(telemetry), + attestationPool: + clientType === P2PClientType.Full + ? ((deps.attestationPool ?? new InMemoryAttestationPool(telemetry)) as T extends P2PClientType.Full + ? AttestationPool + : undefined) + : undefined, }; let p2pService; @@ -55,7 +68,8 @@ export const createP2PClient = async ( const peerId = await createLibP2PPeerIdFromPrivateKey(peerIdPrivateKey); const discoveryService = new DiscV5Service(peerId, config, telemetry); - p2pService = await LibP2PService.new( + p2pService = await LibP2PService.new( + clientType, config, discoveryService, peerId, @@ -70,5 +84,13 @@ export const createP2PClient = async ( logger.verbose('P2P is disabled. Using dummy P2P service'); p2pService = new DummyP2PService(); } - return new P2PClient(store, l2BlockSource, mempools, p2pService, config.keepProvenTxsInPoolFor, telemetry); + return new P2PClient( + clientType, + store, + l2BlockSource, + mempools, + p2pService, + config.keepProvenTxsInPoolFor, + telemetry, + ); }; diff --git a/yarn-project/p2p/src/client/p2p_client.test.ts b/yarn-project/p2p/src/client/p2p_client.test.ts index 5d926dec481..3df10ce45aa 100644 --- a/yarn-project/p2p/src/client/p2p_client.test.ts +++ b/yarn-project/p2p/src/client/p2p_client.test.ts @@ -1,5 +1,5 @@ import { MockL2BlockSource } from '@aztec/archiver/test'; -import { L2Block, mockEpochProofQuote, mockTx } from '@aztec/circuit-types'; +import { L2Block, P2PClientType, mockEpochProofQuote, mockTx } from '@aztec/circuit-types'; import { Fr } from '@aztec/circuits.js'; import { retryUntil } from '@aztec/foundation/retry'; import { sleep } from '@aztec/foundation/sleep'; @@ -19,11 +19,11 @@ describe('In-Memory P2P Client', () => { let txPool: MockProxy; let attestationPool: MockProxy; let epochProofQuotePool: MockProxy; - let mempools: MemPools; + let mempools: MemPools; let blockSource: MockL2BlockSource; let p2pService: MockProxy; let kvStore: AztecKVStore; - let client: P2PClient; + let client: P2PClient; beforeEach(() => { txPool = mock(); @@ -49,7 +49,7 @@ describe('In-Memory P2P Client', () => { }; kvStore = openTmpStore(); - client = new P2PClient(kvStore, blockSource, mempools, p2pService, 0); + client = new P2PClient(P2PClientType.Full, kvStore, blockSource, mempools, p2pService, 0); }); const advanceToProvenBlock = async (getProvenBlockNumber: number, provenEpochNumber = getProvenBlockNumber) => { @@ -119,7 +119,7 @@ describe('In-Memory P2P Client', () => { await client.start(); await client.stop(); - const client2 = new P2PClient(kvStore, blockSource, mempools, p2pService, 0); + const client2 = new P2PClient(P2PClientType.Full, kvStore, blockSource, mempools, p2pService, 0); expect(client2.getSyncedLatestBlockNum()).toEqual(client.getSyncedLatestBlockNum()); }); @@ -134,7 +134,7 @@ describe('In-Memory P2P Client', () => { }); it('deletes txs after waiting the set number of blocks', async () => { - client = new P2PClient(kvStore, blockSource, mempools, p2pService, 10); + client = new P2PClient(P2PClientType.Full, kvStore, blockSource, mempools, p2pService, 10); blockSource.setProvenBlockNumber(0); await client.start(); expect(txPool.deleteTxs).not.toHaveBeenCalled(); @@ -151,7 +151,7 @@ describe('In-Memory P2P Client', () => { }); it('stores and returns epoch proof quotes', async () => { - client = new P2PClient(kvStore, blockSource, mempools, p2pService, 0); + client = new P2PClient(P2PClientType.Full, kvStore, blockSource, mempools, p2pService, 0); blockSource.setProvenEpochNumber(2); await client.start(); @@ -182,7 +182,7 @@ describe('In-Memory P2P Client', () => { }); it('deletes expired proof quotes', async () => { - client = new P2PClient(kvStore, blockSource, mempools, p2pService, 0); + client = new P2PClient(P2PClientType.Full, kvStore, blockSource, mempools, p2pService, 0); blockSource.setProvenEpochNumber(1); blockSource.setProvenBlockNumber(1); @@ -245,7 +245,7 @@ describe('In-Memory P2P Client', () => { }); it('deletes txs created from a pruned block', async () => { - client = new P2PClient(kvStore, blockSource, mempools, p2pService, 10); + client = new P2PClient(P2PClientType.Full, kvStore, blockSource, mempools, p2pService, 10); blockSource.setProvenBlockNumber(0); await client.start(); @@ -267,7 +267,7 @@ describe('In-Memory P2P Client', () => { }); it('moves mined and valid txs back to the pending set', async () => { - client = new P2PClient(kvStore, blockSource, mempools, p2pService, 10); + client = new P2PClient(P2PClientType.Full, kvStore, blockSource, mempools, p2pService, 10); blockSource.setProvenBlockNumber(0); await client.start(); diff --git a/yarn-project/p2p/src/client/p2p_client.ts b/yarn-project/p2p/src/client/p2p_client.ts index db1ced07f76..6a13160dd63 100644 --- a/yarn-project/p2p/src/client/p2p_client.ts +++ b/yarn-project/p2p/src/client/p2p_client.ts @@ -9,6 +9,7 @@ import { type L2BlockStreamEvent, type L2Tips, type P2PApi, + type P2PClientType, type PeerInfo, type Tx, type TxHash, @@ -56,7 +57,7 @@ export interface P2PSyncState { /** * Interface of a P2P client. **/ -export interface P2P extends P2PApi { +export type P2P = P2PApi & { /** * Broadcasts a block proposal to other peers. * @@ -166,12 +167,15 @@ export interface P2P extends P2PApi { /** Identifies a p2p client. */ isP2PClient(): true; -} +}; /** * The P2P client implementation. */ -export class P2PClient extends WithTracer implements P2P { +export class P2PClient + extends WithTracer + implements P2P, P2P +{ /** Property that indicates whether the client is running. */ private stopping = false; @@ -189,7 +193,7 @@ export class P2PClient extends WithTracer implements P2P { private synchedProvenBlockNumber: AztecSingleton; private txPool: TxPool; - private attestationPool: AttestationPool; + private attestationPool: T extends P2PClientType.Full ? AttestationPool : undefined; private epochProofQuotePool: EpochProofQuotePool; /** How many slots to keep attestations for. */ @@ -207,9 +211,10 @@ export class P2PClient extends WithTracer implements P2P { * @param log - A logger. */ constructor( + clientType: T, store: AztecKVStore, private l2BlockSource: L2BlockSource, - mempools: MemPools, + mempools: MemPools, private p2pService: P2PService, private keepProvenTxsFor: number, telemetry: TelemetryClient = new NoopTelemetryClient(), @@ -231,8 +236,8 @@ export class P2PClient extends WithTracer implements P2P { this.synchedProvenBlockNumber = store.openSingleton('p2p_pool_last_proven_l2_block'); this.txPool = mempools.txPool; - this.attestationPool = mempools.attestationPool; this.epochProofQuotePool = mempools.epochProofQuotePool; + this.attestationPool = mempools.attestationPool!; } public isP2PClient(): true { @@ -399,7 +404,7 @@ export class P2PClient extends WithTracer implements P2P { } public getAttestationsForSlot(slot: bigint, proposalId: string): Promise { - return Promise.resolve(this.attestationPool.getAttestationsForSlot(slot, proposalId)); + return Promise.resolve(this.attestationPool?.getAttestationsForSlot(slot, proposalId) ?? []); } // REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963 @@ -644,7 +649,7 @@ export class P2PClient extends WithTracer implements P2P { // We delete attestations older than the last block slot minus the number of slots we want to keep in the pool. const lastBlockSlotMinusKeepAttestationsInPoolFor = lastBlockSlot - BigInt(this.keepAttestationsInPoolFor); if (lastBlockSlotMinusKeepAttestationsInPoolFor >= BigInt(INITIAL_L2_BLOCK_NUM)) { - await this.attestationPool.deleteAttestationsOlderThan(lastBlockSlotMinusKeepAttestationsInPoolFor); + await this.attestationPool?.deleteAttestationsOlderThan(lastBlockSlotMinusKeepAttestationsInPoolFor); } await this.synchedProvenBlockNumber.set(lastBlockNum); diff --git a/yarn-project/p2p/src/mem_pools/interface.ts b/yarn-project/p2p/src/mem_pools/interface.ts index faf38e0638c..38d82a7eaa4 100644 --- a/yarn-project/p2p/src/mem_pools/interface.ts +++ b/yarn-project/p2p/src/mem_pools/interface.ts @@ -1,3 +1,5 @@ +import { type P2PClientType } from '@aztec/circuit-types'; + import { type AttestationPool } from './attestation_pool/attestation_pool.js'; import { type EpochProofQuotePool } from './epoch_proof_quote_pool/epoch_proof_quote_pool.js'; import { type TxPool } from './tx_pool/tx_pool.js'; @@ -5,8 +7,8 @@ import { type TxPool } from './tx_pool/tx_pool.js'; /** * A interface the combines all mempools */ -export interface MemPools { +export type MemPools = { txPool: TxPool; - attestationPool: AttestationPool; + attestationPool?: T extends P2PClientType.Full ? AttestationPool : undefined; epochProofQuotePool: EpochProofQuotePool; -} +}; diff --git a/yarn-project/p2p/src/mocks/index.ts b/yarn-project/p2p/src/mocks/index.ts index d0524378806..bee6dc519fa 100644 --- a/yarn-project/p2p/src/mocks/index.ts +++ b/yarn-project/p2p/src/mocks/index.ts @@ -1,6 +1,7 @@ import { type ClientProtocolCircuitVerifier, type L2BlockSource, + type P2PClientType, type Tx, type WorldStateSynchronizer, } from '@aztec/circuit-types'; @@ -95,11 +96,12 @@ export async function createLibp2pNode( * * */ -export async function createTestLibP2PService( +export async function createTestLibP2PService( + clientType: T, boostrapAddrs: string[] = [], l2BlockSource: L2BlockSource, worldStateSynchronizer: WorldStateSynchronizer, - mempools: MemPools, + mempools: MemPools, telemetry: TelemetryClient, port: number = 0, peerId?: PeerId, @@ -123,7 +125,8 @@ export async function createTestLibP2PService( // No bootstrap nodes provided as the libp2p service will register them in the constructor const p2pNode = await createLibp2pNode([], peerId, port, /*enable gossip */ true, /**start */ false); - return new LibP2PService( + return new LibP2PService( + clientType, config, p2pNode as PubSubLibp2p, discoveryService, diff --git a/yarn-project/p2p/src/service/libp2p_service.ts b/yarn-project/p2p/src/service/libp2p_service.ts index 03bf7fc4ae6..14907201950 100644 --- a/yarn-project/p2p/src/service/libp2p_service.ts +++ b/yarn-project/p2p/src/service/libp2p_service.ts @@ -8,13 +8,14 @@ import { MerkleTreeId, type PeerInfo, type RawGossipMessage, - TopicType, TopicTypeMap, Tx, TxHash, type WorldStateSynchronizer, + getTopicTypeForClientType, metricsTopicStrToLabels, } from '@aztec/circuit-types'; +import { P2PClientType } from '@aztec/circuit-types'; import { Fr } from '@aztec/circuits.js'; import { createLogger } from '@aztec/foundation/log'; import { SerialQueue } from '@aztec/foundation/queue'; @@ -64,7 +65,7 @@ import type { P2PService, PeerDiscoveryService } from './service.js'; /** * Lib P2P implementation of the P2PService interface. */ -export class LibP2PService extends WithTracer implements P2PService { +export class LibP2PService extends WithTracer implements P2PService { private jobQueue: SerialQueue = new SerialQueue(); private peerManager: PeerManager; private discoveryRunningPromise?: RunningPromise; @@ -80,10 +81,11 @@ export class LibP2PService extends WithTracer implements P2PService { private blockReceivedCallback: (block: BlockProposal) => Promise; constructor( + private clientType: T, private config: P2PConfig, private node: PubSubLibp2p, private peerDiscoveryService: PeerDiscoveryService, - private mempools: MemPools, + private mempools: MemPools, private l2BlockSource: L2BlockSource, private proofVerifier: ClientProtocolCircuitVerifier, private worldStateSynchronizer: WorldStateSynchronizer, @@ -131,7 +133,7 @@ export class LibP2PService extends WithTracer implements P2PService { await this.node.start(); // Subscribe to standard GossipSub topics by default - for (const topic in TopicType) { + for (const topic of getTopicTypeForClientType(this.clientType)) { this.subscribeToTopic(TopicTypeMap[topic].p2pTopic); } @@ -186,11 +188,12 @@ export class LibP2PService extends WithTracer implements P2PService { * @param txPool - The transaction pool to be accessed by the service. * @returns The new service. */ - public static async new( + public static async new( + clientType: T, config: P2PConfig, peerDiscoveryService: PeerDiscoveryService, peerId: PeerId, - mempools: MemPools, + mempools: MemPools, l2BlockSource: L2BlockSource, proofVerifier: ClientProtocolCircuitVerifier, worldStateSynchronizer: WorldStateSynchronizer, @@ -299,6 +302,7 @@ export class LibP2PService extends WithTracer implements P2PService { }; return new LibP2PService( + clientType, config, node, peerDiscoveryService, @@ -381,7 +385,7 @@ export class LibP2PService extends WithTracer implements P2PService { const tx = Tx.fromBuffer(Buffer.from(message.data)); await this.processTxFromPeer(tx, peerId); } - if (message.topic === BlockAttestation.p2pTopic) { + if (message.topic === BlockAttestation.p2pTopic && this.clientType === P2PClientType.Full) { const attestation = BlockAttestation.fromBuffer(Buffer.from(message.data)); await this.processAttestationFromPeer(attestation); } @@ -410,7 +414,7 @@ export class LibP2PService extends WithTracer implements P2PService { })) private async processAttestationFromPeer(attestation: BlockAttestation): Promise { this.logger.debug(`Received attestation ${attestation.p2pMessageIdentifier()} from external peer.`); - await this.mempools.attestationPool.addAttestations([attestation]); + await this.mempools.attestationPool!.addAttestations([attestation]); } /**Process block from peer diff --git a/yarn-project/p2p/src/service/reqresp/reqresp.integration.test.ts b/yarn-project/p2p/src/service/reqresp/reqresp.integration.test.ts index 739da0d5a09..08312e88abc 100644 --- a/yarn-project/p2p/src/service/reqresp/reqresp.integration.test.ts +++ b/yarn-project/p2p/src/service/reqresp/reqresp.integration.test.ts @@ -1,6 +1,11 @@ // An integration test for the p2p client to test req resp protocols import { MockL2BlockSource } from '@aztec/archiver/test'; -import { type ClientProtocolCircuitVerifier, type WorldStateSynchronizer, mockTx } from '@aztec/circuit-types'; +import { + type ClientProtocolCircuitVerifier, + P2PClientType, + type WorldStateSynchronizer, + mockTx, +} from '@aztec/circuit-types'; import { createLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; import { type AztecKVStore } from '@aztec/kv-store'; @@ -90,8 +95,11 @@ describe('Req Resp p2p client integration', () => { const getPorts = (numberOfPeers: number) => Promise.all(Array.from({ length: numberOfPeers }, () => getPort())); - const createClients = async (numberOfPeers: number, alwaysTrueVerifier: boolean = true): Promise => { - const clients: P2PClient[] = []; + const createClients = async ( + numberOfPeers: number, + alwaysTrueVerifier: boolean = true, + ): Promise[]> => { + const clients: P2PClient[] = []; const peerIdPrivateKeys = generatePeerIdPrivateKeys(numberOfPeers); const ports = await getPorts(numberOfPeers); @@ -148,7 +156,15 @@ describe('Req Resp p2p client integration', () => { epochProofQuotePool: epochProofQuotePool as unknown as EpochProofQuotePool, store: kvStore, }; - const client = await createP2PClient(config, l2BlockSource, proofVerifier, worldState, undefined, deps); + const client = await createP2PClient( + P2PClientType.Full, + config, + l2BlockSource, + proofVerifier, + worldState, + undefined, + deps, + ); await client.start(); clients.push(client); @@ -163,7 +179,7 @@ describe('Req Resp p2p client integration', () => { }; // Shutdown all test clients - const shutdown = async (clients: P2PClient[]) => { + const shutdown = async (clients: P2PClient[]) => { await Promise.all([...clients.map(client => client.stop())]); await sleep(1000); }; diff --git a/yarn-project/prover-node/src/prover-coordination/factory.ts b/yarn-project/prover-node/src/prover-coordination/factory.ts index e8e94f1153a..48194d44c47 100644 --- a/yarn-project/prover-node/src/prover-coordination/factory.ts +++ b/yarn-project/prover-node/src/prover-coordination/factory.ts @@ -1,6 +1,11 @@ import { type ArchiveSource, type Archiver } from '@aztec/archiver'; import { BBCircuitVerifier, TestCircuitVerifier } from '@aztec/bb-prover'; -import { type ProverCoordination, type WorldStateSynchronizer, createAztecNodeClient } from '@aztec/circuit-types'; +import { + P2PClientType, + type ProverCoordination, + type WorldStateSynchronizer, + createAztecNodeClient, +} from '@aztec/circuit-types'; import { createLogger } from '@aztec/foundation/log'; import { type DataStoreConfig } from '@aztec/kv-store/config'; import { createP2PClient } from '@aztec/p2p'; @@ -42,6 +47,7 @@ export async function createProverCoordination( const proofVerifier = config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier(); const p2pClient = await createP2PClient( + P2PClientType.Prover, config, deps.archiver, proofVerifier, diff --git a/yarn-project/prover-node/src/prover-node.test.ts b/yarn-project/prover-node/src/prover-node.test.ts index 98714c2e1d0..59e55133cea 100644 --- a/yarn-project/prover-node/src/prover-node.test.ts +++ b/yarn-project/prover-node/src/prover-node.test.ts @@ -7,6 +7,7 @@ import { type L2Block, type L2BlockSource, type MerkleTreeWriteOperations, + P2PClientType, type ProverCache, type ProverCoordination, WorldStateRunningState, @@ -17,13 +18,7 @@ import { times } from '@aztec/foundation/collection'; import { Signature } from '@aztec/foundation/eth-signature'; import { sleep } from '@aztec/foundation/sleep'; import { openTmpStore } from '@aztec/kv-store/lmdb'; -import { - type BootstrapNode, - InMemoryAttestationPool, - InMemoryTxPool, - MemoryEpochProofQuotePool, - P2PClient, -} from '@aztec/p2p'; +import { type BootstrapNode, InMemoryTxPool, MemoryEpochProofQuotePool, P2PClient } from '@aztec/p2p'; import { createBootstrapNode, createTestLibP2PService } from '@aztec/p2p/mocks'; import { type L1Publisher } from '@aztec/sequencer-client'; import { type PublicProcessorFactory } from '@aztec/simulator'; @@ -297,16 +292,16 @@ describe('prover-node', () => { // - The prover node can get the it is missing via p2p, or it has them in it's mempool describe('Using a p2p coordination', () => { let bootnode: BootstrapNode; - let p2pClient: P2PClient; - let otherP2PClient: P2PClient; + let p2pClient: P2PClient; + let otherP2PClient: P2PClient; const createP2PClient = async (bootnodeAddr: string, port: number) => { const mempools = { txPool: new InMemoryTxPool(telemetryClient), - attestationPool: new InMemoryAttestationPool(telemetryClient), epochProofQuotePool: new MemoryEpochProofQuotePool(telemetryClient), }; const libp2pService = await createTestLibP2PService( + P2PClientType.Prover, [bootnodeAddr], l2BlockSource, worldState, @@ -315,7 +310,7 @@ describe('prover-node', () => { port, ); const kvStore = openTmpStore(); - return new P2PClient(kvStore, l2BlockSource, mempools, libp2pService, 0); + return new P2PClient(P2PClientType.Prover, kvStore, l2BlockSource, mempools, libp2pService, 0); }; beforeEach(async () => { diff --git a/yarn-project/prover-node/src/prover-node.ts b/yarn-project/prover-node/src/prover-node.ts index d70ce17bb87..ceabaf00e33 100644 --- a/yarn-project/prover-node/src/prover-node.ts +++ b/yarn-project/prover-node/src/prover-node.ts @@ -6,6 +6,7 @@ import { type L1ToL2MessageSource, type L2Block, type L2BlockSource, + type P2PClientType, type ProverCache, type ProverCoordination, type ProverNodeApi, @@ -80,7 +81,7 @@ export class ProverNode implements ClaimsMonitorHandler, EpochMonitorHandler, Pr } public getP2P() { - const asP2PClient = this.coordination as P2P; + const asP2PClient = this.coordination as P2P; if (typeof asP2PClient.isP2PClient === 'function' && asP2PClient.isP2PClient()) { return asP2PClient; } diff --git a/yarn-project/sequencer-client/src/client/sequencer-client.ts b/yarn-project/sequencer-client/src/client/sequencer-client.ts index ba9987262c2..b45dcbbb38a 100644 --- a/yarn-project/sequencer-client/src/client/sequencer-client.ts +++ b/yarn-project/sequencer-client/src/client/sequencer-client.ts @@ -1,4 +1,9 @@ -import { type L1ToL2MessageSource, type L2BlockSource, type WorldStateSynchronizer } from '@aztec/circuit-types'; +import { + type L1ToL2MessageSource, + type L2BlockSource, + type P2PClientType, + type WorldStateSynchronizer, +} from '@aztec/circuit-types'; import { type ContractDataSource } from '@aztec/circuits.js'; import { type EthAddress } from '@aztec/foundation/eth-address'; import { type P2P } from '@aztec/p2p'; @@ -36,7 +41,7 @@ export class SequencerClient { config: SequencerClientConfig, deps: { validatorClient: ValidatorClient | undefined; // allowed to be undefined while we migrate - p2pClient: P2P; + p2pClient: P2P; worldStateSynchronizer: WorldStateSynchronizer; contractDataSource: ContractDataSource; l2BlockSource: L2BlockSource; diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 1807a42a5e1..9475a6fc79b 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -10,6 +10,7 @@ import { MerkleTreeId, type MerkleTreeReadOperations, type MerkleTreeWriteOperations, + type P2PClientType, type Tx, TxHash, type UnencryptedL2Log, @@ -54,7 +55,7 @@ describe('sequencer', () => { let publisher: MockProxy; let validatorClient: MockProxy; let globalVariableBuilder: MockProxy; - let p2p: MockProxy; + let p2p: MockProxy>; let worldState: MockProxy; let fork: MockProxy; let blockBuilder: MockProxy; @@ -131,7 +132,7 @@ describe('sequencer', () => { return Promise.resolve([undefined]); }); - p2p = mock({ + p2p = mock>({ getStatus: mockFn().mockResolvedValue({ state: P2PClientState.IDLE, syncedToL2Block: { number: lastBlockNumber, hash }, diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index d13515124d3..52714871466 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -3,6 +3,7 @@ import { type L1ToL2MessageSource, type L2Block, type L2BlockSource, + type P2PClientType, type ProcessedTx, SequencerConfigSchema, Tx, @@ -98,7 +99,7 @@ export class Sequencer { private publisher: L1Publisher, private validatorClient: ValidatorClient | undefined, // During migration the validator client can be inactive private globalsBuilder: GlobalVariableBuilder, - private p2pClient: P2P, + private p2pClient: P2P, private worldState: WorldStateSynchronizer, private blockBuilderFactory: BlockBuilderFactory, private l2BlockSource: L2BlockSource, diff --git a/yarn-project/validator-client/src/factory.ts b/yarn-project/validator-client/src/factory.ts index 7ea8b09e8d6..ffd2ebe227d 100644 --- a/yarn-project/validator-client/src/factory.ts +++ b/yarn-project/validator-client/src/factory.ts @@ -1,3 +1,4 @@ +import { type P2PClientType } from '@aztec/circuit-types'; import { EpochCache, type EpochCacheConfig } from '@aztec/epoch-cache'; import { type EthAddress } from '@aztec/foundation/eth-address'; import { type P2P } from '@aztec/p2p'; @@ -11,7 +12,7 @@ import { ValidatorClient } from './validator.js'; export async function createValidatorClient( config: ValidatorClientConfig & EpochCacheConfig, rollupAddress: EthAddress, - p2pClient: P2P, + p2pClient: P2P, telemetry: TelemetryClient, ) { if (config.disableValidator) { diff --git a/yarn-project/validator-client/src/validator.test.ts b/yarn-project/validator-client/src/validator.test.ts index 7b6fdca5a26..99017cc7e82 100644 --- a/yarn-project/validator-client/src/validator.test.ts +++ b/yarn-project/validator-client/src/validator.test.ts @@ -1,7 +1,7 @@ /** * Validation logic unit tests */ -import { TxHash, mockTx } from '@aztec/circuit-types'; +import { type P2PClientType, TxHash, mockTx } from '@aztec/circuit-types'; import { makeHeader } from '@aztec/circuits.js/testing'; import { type EpochCache } from '@aztec/epoch-cache'; import { Secp256k1Signer } from '@aztec/foundation/crypto'; @@ -27,12 +27,12 @@ import { ValidatorClient } from './validator.js'; describe('ValidationService', () => { let config: ValidatorClientConfig; let validatorClient: ValidatorClient; - let p2pClient: MockProxy; + let p2pClient: MockProxy>; let epochCache: MockProxy; let validatorAccount: PrivateKeyAccount; beforeEach(() => { - p2pClient = mock(); + p2pClient = mock>(); p2pClient.getAttestationsForSlot.mockImplementation(() => Promise.resolve([])); epochCache = mock(); diff --git a/yarn-project/validator-client/src/validator.ts b/yarn-project/validator-client/src/validator.ts index 6e2890334f8..c8cf60b649b 100644 --- a/yarn-project/validator-client/src/validator.ts +++ b/yarn-project/validator-client/src/validator.ts @@ -2,6 +2,7 @@ import { type BlockAttestation, type BlockProposal, type L2Block, + type P2PClientType, type ProcessedTx, type Tx, type TxHash, @@ -74,7 +75,7 @@ export class ValidatorClient extends WithTracer implements Validator { constructor( private keyStore: ValidatorKeyStore, private epochCache: EpochCache, - private p2pClient: P2P, + private p2pClient: P2P, private config: ValidatorClientConfig, telemetry: TelemetryClient = new NoopTelemetryClient(), private log = createLogger('validator'), @@ -106,7 +107,7 @@ export class ValidatorClient extends WithTracer implements Validator { static new( config: ValidatorClientConfig, epochCache: EpochCache, - p2pClient: P2P, + p2pClient: P2P, telemetry: TelemetryClient = new NoopTelemetryClient(), ) { if (!config.validatorPrivateKey) {