@aztec/p2p 0.87.7 → 1.0.0-nightly.20250605

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dest/client/interface.d.ts +4 -3
  2. package/dest/client/interface.d.ts.map +1 -1
  3. package/dest/client/p2p_client.d.ts +5 -5
  4. package/dest/client/p2p_client.d.ts.map +1 -1
  5. package/dest/client/p2p_client.js +10 -9
  6. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +1 -1
  7. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +1 -1
  8. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  9. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +3 -2
  10. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +1 -1
  11. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
  12. package/dest/mem_pools/tx_pool/memory_tx_pool.js +1 -1
  13. package/dest/mem_pools/tx_pool/tx_pool.d.ts +2 -1
  14. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  15. package/dest/msg_validators/attestation_validator/attestation_validator.js +1 -1
  16. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +1 -1
  17. package/dest/msg_validators/tx_validator/data_validator.js +4 -4
  18. package/dest/services/dummy_service.d.ts +3 -3
  19. package/dest/services/dummy_service.d.ts.map +1 -1
  20. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  21. package/dest/services/libp2p/libp2p_service.js +15 -12
  22. package/dest/services/peer-manager/peer_manager.d.ts +16 -3
  23. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  24. package/dest/services/peer-manager/peer_manager.js +42 -2
  25. package/dest/services/reqresp/interface.d.ts.map +1 -1
  26. package/dest/services/reqresp/interface.js +3 -2
  27. package/dest/services/reqresp/protocols/status.d.ts +35 -4
  28. package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
  29. package/dest/services/reqresp/protocols/status.js +59 -5
  30. package/dest/services/service.d.ts +1 -1
  31. package/dest/services/service.d.ts.map +1 -1
  32. package/dest/services/tx_collector.d.ts +4 -2
  33. package/dest/services/tx_collector.d.ts.map +1 -1
  34. package/dest/services/tx_collector.js +41 -48
  35. package/dest/test-helpers/make-test-p2p-clients.d.ts +21 -0
  36. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  37. package/dest/test-helpers/make-test-p2p-clients.js +47 -2
  38. package/dest/test-helpers/reqresp-nodes.js +2 -2
  39. package/dest/testbench/p2p_client_testbench_worker.js +16 -3
  40. package/package.json +12 -12
  41. package/src/client/interface.ts +4 -3
  42. package/src/client/p2p_client.ts +12 -11
  43. package/src/mem_pools/attestation_pool/attestation_pool.ts +1 -1
  44. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +10 -3
  45. package/src/mem_pools/tx_pool/memory_tx_pool.ts +2 -2
  46. package/src/mem_pools/tx_pool/tx_pool.ts +2 -1
  47. package/src/msg_validators/attestation_validator/attestation_validator.ts +1 -1
  48. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +1 -1
  49. package/src/msg_validators/tx_validator/data_validator.ts +4 -4
  50. package/src/services/dummy_service.ts +8 -5
  51. package/src/services/libp2p/libp2p_service.ts +25 -15
  52. package/src/services/peer-manager/peer_manager.ts +48 -2
  53. package/src/services/reqresp/interface.ts +3 -2
  54. package/src/services/reqresp/protocols/status.ts +91 -5
  55. package/src/services/service.ts +4 -1
  56. package/src/services/tx_collector.ts +65 -67
  57. package/src/test-helpers/make-test-p2p-clients.ts +61 -3
  58. package/src/test-helpers/reqresp-nodes.ts +2 -2
  59. package/src/testbench/p2p_client_testbench_worker.ts +18 -4
@@ -1,6 +1,7 @@
1
1
  import { Fr } from '@aztec/foundation/fields';
2
2
  import { L2Block } from '@aztec/stdlib/block';
3
3
  import { Tx, TxHash } from '@aztec/stdlib/tx';
4
+ import { StatusMessage } from './protocols/status.js';
4
5
  /*
5
6
  * Request Response Sub Protocols
6
7
  */ export const PING_PROTOCOL = '/aztec/req/ping/0.1.0';
@@ -66,8 +67,8 @@ export const DEFAULT_SUB_PROTOCOL_VALIDATORS = {
66
67
  response: RequestableBuffer
67
68
  },
68
69
  [ReqRespSubProtocol.STATUS]: {
69
- request: RequestableBuffer,
70
- response: RequestableBuffer
70
+ request: StatusMessage,
71
+ response: StatusMessage
71
72
  },
72
73
  [ReqRespSubProtocol.TX]: {
73
74
  request: TxHash,
@@ -1,7 +1,38 @@
1
+ import { BufferReader } from '@aztec/foundation/serialize';
2
+ import type { WorldStateSyncStatus, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
3
+ import type { PeerId } from '@libp2p/interface';
4
+ export declare class StatusMessage {
5
+ readonly compressedComponentsVersion: string;
6
+ readonly latestBlockNumber: number;
7
+ readonly latestBlockHash: string;
8
+ readonly finalisedBlockNumber: number;
9
+ constructor(compressedComponentsVersion: string, latestBlockNumber: number, latestBlockHash: string, finalisedBlockNumber: number);
10
+ /**
11
+ * Deserializes the StatusMessage object from a Buffer.
12
+ * @param buffer - Buffer or BufferReader object to deserialize.
13
+ * @returns An instance of StatusMessage.
14
+ */
15
+ static fromBuffer(buffer: Buffer | BufferReader): StatusMessage;
16
+ /**
17
+ * Serializes the StatusMessage object into a Buffer.
18
+ * @returns Buffer representation of the StatusMessage object.
19
+ */
20
+ toBuffer(): Buffer<ArrayBufferLike>;
21
+ /**
22
+ * Builds Status message
23
+ * @param version - Compressed Components Version
24
+ * @param worldStateSyncStatus - Info about the current sync status
25
+ * @returns StatusMessage instance
26
+ */
27
+ static fromWorldStateSyncStatus(version: string, syncStatus: WorldStateSyncStatus): StatusMessage;
28
+ validate(peerStatus: StatusMessage): boolean;
29
+ }
1
30
  /**
2
- * Handles the status request.
3
- * @param _msg - The status request message.
4
- * @returns A resolved promise with the ok response.
31
+ * Handles the status request. By immediately responding with the current node status.
32
+ * @param compressedComponentsVersion - Compressed Components Version
33
+ * @param worldStateSynchronizer - World State Synchronizer to fetch the sync status from.
34
+ * Note the WorldStateSynchronizer must be injected to fetch the fresh sync status, we cannot pass in pre-built StatusMessage.
35
+ * @returns Status message handler
5
36
  */
6
- export declare function statusHandler(_msg: any): Promise<Buffer>;
37
+ export declare function reqRespStatusHandler(compressedComponentsVersion: string, worldStateSynchronizer: WorldStateSynchronizer): (_peerId: PeerId, _msg: Buffer) => Promise<Buffer<ArrayBufferLike>>;
7
38
  //# sourceMappingURL=status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/protocols/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAExD"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/protocols/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAC9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAEpG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAQhD,qBAAa,aAAa;IAEtB,QAAQ,CAAC,2BAA2B,EAAE,MAAM;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,MAAM;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM;IAChC,QAAQ,CAAC,oBAAoB,EAAE,MAAM;gBAH5B,2BAA2B,EAAE,MAAM,EACnC,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,EACvB,oBAAoB,EAAE,MAAM;IAKvC;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,aAAa;IAY/D;;;OAGG;IACH,QAAQ;IAWR;;;;;OAKG;IACH,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,GAAG,aAAa;IAUjG,QAAQ,CAAC,UAAU,EAAE,aAAa,GAAG,OAAO;CAI7C;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,2BAA2B,EAAE,MAAM,EACnC,sBAAsB,EAAE,sBAAsB,IAEhC,SAAS,MAAM,EAAE,MAAM,MAAM,sCAO5C"}
@@ -1,7 +1,61 @@
1
+ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
2
+ /*
3
+ * P2P Status Message
4
+ * It is used to establish Status handshake between to peers
5
+ * By validating Status handshake we ensure peers are on the same Blockchain fork
6
+ * And get peer sync status
7
+ */ export class StatusMessage {
8
+ compressedComponentsVersion;
9
+ latestBlockNumber;
10
+ latestBlockHash;
11
+ finalisedBlockNumber;
12
+ constructor(compressedComponentsVersion, latestBlockNumber, latestBlockHash, finalisedBlockNumber){
13
+ this.compressedComponentsVersion = compressedComponentsVersion;
14
+ this.latestBlockNumber = latestBlockNumber;
15
+ this.latestBlockHash = latestBlockHash;
16
+ this.finalisedBlockNumber = finalisedBlockNumber;
17
+ }
18
+ /**
19
+ * Deserializes the StatusMessage object from a Buffer.
20
+ * @param buffer - Buffer or BufferReader object to deserialize.
21
+ * @returns An instance of StatusMessage.
22
+ */ static fromBuffer(buffer) {
23
+ const reader = BufferReader.asReader(buffer);
24
+ return new StatusMessage(reader.readString(), reader.readNumber(), reader.readString(), reader.readNumber());
25
+ }
26
+ /**
27
+ * Serializes the StatusMessage object into a Buffer.
28
+ * @returns Buffer representation of the StatusMessage object.
29
+ */ toBuffer() {
30
+ return serializeToBuffer([
31
+ this.compressedComponentsVersion,
32
+ this.latestBlockNumber,
33
+ this.latestBlockHash,
34
+ this.finalisedBlockNumber
35
+ ]);
36
+ }
37
+ /**
38
+ * Builds Status message
39
+ * @param version - Compressed Components Version
40
+ * @param worldStateSyncStatus - Info about the current sync status
41
+ * @returns StatusMessage instance
42
+ */ static fromWorldStateSyncStatus(version, syncStatus) {
43
+ return new StatusMessage(version, syncStatus.latestBlockNumber, syncStatus.latestBlockHash, syncStatus.finalisedBlockNumber);
44
+ }
45
+ validate(peerStatus) {
46
+ // TODO: Validate other fields as well
47
+ return this.compressedComponentsVersion === peerStatus.compressedComponentsVersion;
48
+ }
49
+ }
1
50
  /**
2
- * Handles the status request.
3
- * @param _msg - The status request message.
4
- * @returns A resolved promise with the ok response.
5
- */ export function statusHandler(_msg) {
6
- return Promise.resolve(Buffer.from('ok'));
51
+ * Handles the status request. By immediately responding with the current node status.
52
+ * @param compressedComponentsVersion - Compressed Components Version
53
+ * @param worldStateSynchronizer - World State Synchronizer to fetch the sync status from.
54
+ * Note the WorldStateSynchronizer must be injected to fetch the fresh sync status, we cannot pass in pre-built StatusMessage.
55
+ * @returns Status message handler
56
+ */ export function reqRespStatusHandler(compressedComponentsVersion, worldStateSynchronizer) {
57
+ return async (_peerId, _msg)=>{
58
+ const status = StatusMessage.fromWorldStateSyncStatus(compressedComponentsVersion, (await worldStateSynchronizer.status()).syncSummary);
59
+ return Promise.resolve(status.toBuffer());
60
+ };
7
61
  }
@@ -9,7 +9,7 @@ export declare enum PeerDiscoveryState {
9
9
  RUNNING = "running",
10
10
  STOPPED = "stopped"
11
11
  }
12
- export type P2PBlockReceivedCallback = (block: BlockProposal, sender: PeerId) => Promise<BlockAttestation | undefined>;
12
+ export type P2PBlockReceivedCallback = (block: BlockProposal, sender: PeerId) => Promise<BlockAttestation[] | undefined>;
13
13
  /**
14
14
  * The interface for a P2P service implementation.
15
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,14 @@
1
1
  import { type Logger } from '@aztec/foundation/log';
2
2
  import type { BlockProposal } from '@aztec/stdlib/p2p';
3
3
  import type { Tx, TxHash } from '@aztec/stdlib/tx';
4
+ import type { PeerId } from '@libp2p/interface';
4
5
  import type { P2PClient } from '../client/p2p_client.js';
5
6
  export declare class TxCollector {
6
7
  private p2pClient;
7
8
  private log;
8
- constructor(p2pClient: Pick<P2PClient, 'getTxsByHashFromPool' | 'hasTxsInPool' | 'getTxsByHash' | 'validate' | 'requestTxsByHash'>, log?: Logger);
9
- collectForBlockProposal(proposal: BlockProposal, peerWhoSentTheProposal: any): Promise<{
9
+ constructor(p2pClient: Pick<P2PClient, 'getTxsByHashFromPool' | 'hasTxsInPool' | 'getTxsByHash' | 'validate' | 'requestTxsByHash' | 'addTxsToPool'>, log?: Logger);
10
+ private collectFromProposal;
11
+ collectForBlockProposal(proposal: BlockProposal, peerWhoSentTheProposal: PeerId | undefined): Promise<{
10
12
  txs: Tx[];
11
13
  missing?: TxHash[];
12
14
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"tx_collector.d.ts","sourceRoot":"","sources":["../../src/services/tx_collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,qBAAa,WAAW;IAEpB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,GAAG;gBAJH,SAAS,EAAE,IAAI,CACrB,SAAS,EACT,sBAAsB,GAAG,cAAc,GAAG,cAAc,GAAG,UAAU,GAAG,kBAAkB,CAC3F,EACO,GAAG,GAAE,MAAyC;IAGlD,uBAAuB,CAC3B,QAAQ,EAAE,aAAa,EACvB,sBAAsB,EAAE,GAAG,GAC1B,OAAO,CAAC;QAAE,GAAG,EAAE,EAAE,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAmF9C"}
1
+ {"version":3,"file":"tx_collector.d.ts","sourceRoot":"","sources":["../../src/services/tx_collector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,qBAAa,WAAW;IAEpB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,GAAG;gBAJH,SAAS,EAAE,IAAI,CACrB,SAAS,EACT,sBAAsB,GAAG,cAAc,GAAG,cAAc,GAAG,UAAU,GAAG,kBAAkB,GAAG,cAAc,CAC5G,EACO,GAAG,GAAE,MAAyC;YAI1C,mBAAmB;IAqD3B,uBAAuB,CAC3B,QAAQ,EAAE,aAAa,EACvB,sBAAsB,EAAE,MAAM,GAAG,SAAS,GACzC,OAAO,CAAC;QAAE,GAAG,EAAE,EAAE,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAyB9C"}
@@ -7,6 +7,42 @@ export class TxCollector {
7
7
  this.p2pClient = p2pClient;
8
8
  this.log = log;
9
9
  }
10
+ // Checks the proposal for transactions we don't already have, validates them and adds them to our pool
11
+ async collectFromProposal(proposal) {
12
+ // Does this proposal have any transactions?
13
+ if (!proposal.txs || proposal.txs.length === 0) {
14
+ return;
15
+ }
16
+ const proposalHashes = new Set((proposal.payload.txHashes ?? []).map((txHash)=>txHash.toString()));
17
+ // Get the transactions from the proposal and their hashes
18
+ // also, we are only interested in txs that are part of the proposal
19
+ const txsFromProposal = compactArray(await Promise.all(proposal.txs.map((tx)=>tx === undefined ? Promise.resolve(undefined) : tx.getTxHash().then((hash)=>({
20
+ txHash: hash,
21
+ tx
22
+ }))))).filter((tx)=>proposalHashes.has(tx.txHash.toString()));
23
+ // Of the transactions from the proposal, retrieve those that we have in the pool already
24
+ const txsToValidate = [];
25
+ const txsWeAlreadyHave = await this.p2pClient.getTxsByHashFromPool(txsFromProposal.map((tx)=>tx.txHash));
26
+ // Txs we already have will have holes where we did not find them
27
+ // Where that is the case we need to validate the tx in the proposal
28
+ for(let i = 0; i < txsWeAlreadyHave.length; i++){
29
+ if (txsWeAlreadyHave[i] === undefined) {
30
+ txsToValidate.push(txsFromProposal[i].tx);
31
+ }
32
+ }
33
+ // Now validate all the transactions from the proposal that we don't have
34
+ // This will throw if any of the transactions are invalid, this is probably correct, if someone sends us a proposal with invalid
35
+ // transactions we probably shouldn't spend any more effort on it
36
+ try {
37
+ await this.p2pClient.validate(txsToValidate);
38
+ } catch (err) {
39
+ this.log.error(`Received proposal with invalid transactions, skipping`);
40
+ throw err;
41
+ }
42
+ // Now store these transactions in our pool, provided these are the txs in proposal.payload.txHashes they will be pinned already
43
+ await this.p2pClient.addTxsToPool(txsToValidate);
44
+ this.log.info(`Received proposal with ${proposal.txs.length} transactions, ${txsToValidate.length} of which were new`);
45
+ }
10
46
  async collectForBlockProposal(proposal, peerWhoSentTheProposal) {
11
47
  if (proposal.payload.txHashes.length === 0) {
12
48
  this.log.verbose(`Received block proposal with no transactions, skipping transaction availability check`);
@@ -14,60 +50,17 @@ export class TxCollector {
14
50
  txs: []
15
51
  };
16
52
  }
17
- // Is this a new style proposal?
18
- if (proposal.txs && proposal.txs.length > 0 && proposal.txs.length === proposal.payload.txHashes.length) {
19
- // Yes, any txs that we already have we should use
20
- this.log.info(`Using new style proposal with ${proposal.txs.length} transactions`);
21
- // Request from the pool based on the signed hashes in the payload
22
- const hashesFromPayload = proposal.payload.txHashes;
23
- const txsToUse = await this.p2pClient.getTxsByHashFromPool(hashesFromPayload);
24
- const missingTxs = txsToUse.filter((tx)=>tx === undefined).length;
25
- if (missingTxs > 0) {
26
- this.log.verbose(`Missing ${missingTxs}/${hashesFromPayload.length} transactions in the tx pool, will attempt to take from the proposal`);
27
- }
28
- let usedFromProposal = 0;
29
- // Fill any holes with txs in the proposal, provided their hash matches the hash in the payload
30
- for(let i = 0; i < txsToUse.length; i++){
31
- if (txsToUse[i] === undefined) {
32
- // We don't have the transaction, take from the proposal, provided the hash is the same
33
- const hashOfTxInProposal = await proposal.txs[i].getTxHash();
34
- if (hashOfTxInProposal.equals(hashesFromPayload[i])) {
35
- // Hash is equal, we can use the tx from the proposal
36
- txsToUse[i] = proposal.txs[i];
37
- usedFromProposal++;
38
- } else {
39
- this.log.warn(`Unable to take tx: ${hashOfTxInProposal.toString()} from the proposal, it does not match payload hash: ${hashesFromPayload[i].toString()}`);
40
- }
41
- }
42
- }
43
- // See if we still have any holes, if there are then we were not successful and will try the old method
44
- if (txsToUse.some((tx)=>tx === undefined)) {
45
- this.log.warn(`Failed to use transactions from proposal. Falling back to old proposal logic`);
46
- } else {
47
- this.log.info(`Successfully used ${usedFromProposal}/${hashesFromPayload.length} transactions from the proposal`);
48
- await this.p2pClient.validate(txsToUse);
49
- return {
50
- txs: txsToUse
51
- };
52
- }
53
- }
54
- this.log.info(`Using old style proposal with ${proposal.payload.txHashes.length} transactions`);
55
- // Old style proposal, we will perform a request by hash from pool
56
- // This will request from network any txs that are missing
53
+ // Take txs from the proposal if there are any
54
+ await this.collectFromProposal(proposal);
55
+ // Now get the txs we need, either from the pool or the p2p network
57
56
  const txHashes = proposal.payload.txHashes;
58
- // This part is just for logging that we are requesting from the network
59
- const availability = await this.p2pClient.hasTxsInPool(txHashes);
60
- const notAvailable = availability.filter((availability)=>availability === false);
61
- if (notAvailable.length) {
62
- this.log.verbose(`Missing ${notAvailable.length} transactions in the tx pool, will need to request from the network`);
63
- }
64
57
  // This will request from the network any txs that are missing
65
58
  // NOTE: this could still return missing txs so we need to (1) be careful to handle undefined and (2) keep the txs in the correct order for re-execution
66
59
  const maybeRetrievedTxs = await this.p2pClient.getTxsByHash(txHashes, peerWhoSentTheProposal);
60
+ // Get the txs that we didn't get from the network, if any. This will be empty if we got them al
67
61
  const missingTxs = compactArray(maybeRetrievedTxs.map((tx, index)=>tx === undefined ? txHashes[index] : undefined));
68
- // if we found all txs, this is a noop. If we didn't find all txs then validate the ones we did find and tell the validator to skip attestations because missingTxs.length > 0
62
+ // if we found all txs, this is a noop. If we didn't find all txs then tell the validator to skip attestations because missingTxs.length > 0
69
63
  const retrievedTxs = compactArray(maybeRetrievedTxs);
70
- await this.p2pClient.validate(retrievedTxs);
71
64
  return {
72
65
  txs: retrievedTxs,
73
66
  missing: missingTxs
@@ -16,6 +16,15 @@ interface MakeTestP2PClientOptions {
16
16
  p2pConfigOverrides?: Partial<P2PConfig>;
17
17
  logger?: Logger;
18
18
  }
19
+ /**
20
+ * Creates a single P2P client and immediately starts it for testing purposes.
21
+ * @param peerIdPrivateKey - The private key of the peer.
22
+ * @param port - The port to run the client on.
23
+ * @param peers - The peers to connect to.
24
+ * @param options - The options for the client.
25
+ * @returns The created and already started client.
26
+ */
27
+ export declare function makeAndStartTestP2PClient(peerIdPrivateKey: string, port: number, peers: string[], options: MakeTestP2PClientOptions): Promise<P2PClient<P2PClientType.Full>>;
19
28
  /**
20
29
  * Creates a single P2P client for testing purposes.
21
30
  * @param peerIdPrivateKey - The private key of the peer.
@@ -25,6 +34,18 @@ interface MakeTestP2PClientOptions {
25
34
  * @returns The created client.
26
35
  */
27
36
  export declare function makeTestP2PClient(peerIdPrivateKey: string, port: number, peers: string[], { alwaysTrueVerifier, p2pBaseConfig, p2pConfigOverrides, mockAttestationPool, mockTxPool, mockEpochCache, mockWorldState, logger, }: MakeTestP2PClientOptions): Promise<P2PClient<P2PClientType.Full>>;
37
+ /**
38
+ * Creates a number of P2P clients and immediately starts them for testing purposes.
39
+ * @param numberOfPeers - The number of clients to create.
40
+ * @param options - The options for the clients.
41
+ * @returns The created and started clients.
42
+ */
43
+ export declare function makeAndStartTestP2PClients(numberOfPeers: number, testConfig: MakeTestP2PClientOptions): Promise<{
44
+ client: P2PClient<P2PClientType.Full>;
45
+ peerPrivateKey: string;
46
+ port: number;
47
+ enr: string;
48
+ }[]>;
28
49
  /**
29
50
  * Creates a number of P2P clients for testing purposes.
30
51
  * @param numberOfPeers - The number of clients to create.
@@ -1 +1 @@
1
- {"version":3,"file":"make-test-p2p-clients.d.ts","sourceRoot":"","sources":["../../src/test-helpers/make-test-p2p-clients.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAIlE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACzF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAM5D,UAAU,wBAAwB;IAChC,mBAAmB,EAAE,eAAe,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,UAAU,CAAC;IAC3B,cAAc,EAAE,sBAAsB,CAAC;IACvC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,EAAE,SAAS,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,EACE,kBAAyB,EACzB,aAAa,EACb,kBAAuB,EACvB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,cAAc,EACd,MAAwC,GACzC,EAAE,wBAAwB,0CA2C5B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB;;;;;KAiCnG"}
1
+ {"version":3,"file":"make-test-p2p-clients.d.ts","sourceRoot":"","sources":["../../src/test-helpers/make-test-p2p-clients.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAIlE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACzF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAM5D,UAAU,wBAAwB;IAChC,mBAAmB,EAAE,eAAe,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,UAAU,CAAC;IAC3B,cAAc,EAAE,sBAAsB,CAAC;IACvC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,EAAE,SAAS,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,wBAAwB,0CAMlC;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,EACE,kBAAyB,EACzB,aAAa,EACb,kBAAuB,EACvB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,cAAc,EACd,MAAwC,GACzC,EAAE,wBAAwB,0CAyC5B;AAED;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB;;;;;KAiC3G;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB;;;;;KAgCnG"}
@@ -8,6 +8,18 @@ import { generatePeerIdPrivateKeys } from '../test-helpers/generate-peer-id-priv
8
8
  import { getPorts } from './get-ports.js';
9
9
  import { makeEnrs } from './make-enrs.js';
10
10
  import { AlwaysFalseCircuitVerifier, AlwaysTrueCircuitVerifier } from './reqresp-nodes.js';
11
+ /**
12
+ * Creates a single P2P client and immediately starts it for testing purposes.
13
+ * @param peerIdPrivateKey - The private key of the peer.
14
+ * @param port - The port to run the client on.
15
+ * @param peers - The peers to connect to.
16
+ * @param options - The options for the client.
17
+ * @returns The created and already started client.
18
+ */ export async function makeAndStartTestP2PClient(peerIdPrivateKey, port, peers, options) {
19
+ const client = await makeTestP2PClient(peerIdPrivateKey, port, peers, options);
20
+ await client.start();
21
+ return client;
22
+ }
11
23
  /**
12
24
  * Creates a single P2P client for testing purposes.
13
25
  * @param peerIdPrivateKey - The private key of the peer.
@@ -41,9 +53,43 @@ import { AlwaysFalseCircuitVerifier, AlwaysTrueCircuitVerifier } from './reqresp
41
53
  logger
42
54
  };
43
55
  const client = await createP2PClient(P2PClientType.Full, config, l2BlockSource, proofVerifier, mockWorldState, mockEpochCache, 'test-p2p-client', undefined, deps);
44
- await client.start();
45
56
  return client;
46
57
  }
58
+ /**
59
+ * Creates a number of P2P clients and immediately starts them for testing purposes.
60
+ * @param numberOfPeers - The number of clients to create.
61
+ * @param options - The options for the clients.
62
+ * @returns The created and started clients.
63
+ */ export async function makeAndStartTestP2PClients(numberOfPeers, testConfig) {
64
+ const clients = [];
65
+ const peerIdPrivateKeys = generatePeerIdPrivateKeys(numberOfPeers);
66
+ let ports = [];
67
+ while(true){
68
+ try {
69
+ ports = await getPorts(numberOfPeers);
70
+ break;
71
+ } catch {
72
+ await sleep(1000);
73
+ }
74
+ }
75
+ const peerEnrs = await makeEnrs(peerIdPrivateKeys, ports, testConfig.p2pBaseConfig);
76
+ for(let i = 0; i < numberOfPeers; i++){
77
+ const client = await makeAndStartTestP2PClient(peerIdPrivateKeys[i], ports[i], peerEnrs, {
78
+ ...testConfig,
79
+ logger: createLogger(`p2p:${i}`)
80
+ });
81
+ clients.push(client);
82
+ }
83
+ await Promise.all(clients.map((client)=>client.isReady()));
84
+ return clients.map((client, index)=>{
85
+ return {
86
+ client,
87
+ peerPrivateKey: peerIdPrivateKeys[index],
88
+ port: ports[index],
89
+ enr: peerEnrs[index]
90
+ };
91
+ });
92
+ }
47
93
  /**
48
94
  * Creates a number of P2P clients for testing purposes.
49
95
  * @param numberOfPeers - The number of clients to create.
@@ -69,7 +115,6 @@ import { AlwaysFalseCircuitVerifier, AlwaysTrueCircuitVerifier } from './reqresp
69
115
  });
70
116
  clients.push(client);
71
117
  }
72
- await Promise.all(clients.map((client)=>client.isReady()));
73
118
  return clients.map((client, index)=>{
74
119
  return {
75
120
  client,
@@ -17,7 +17,7 @@ import { BootstrapNode } from '../bootstrap/bootstrap.js';
17
17
  import { DiscV5Service } from '../services/discv5/discV5_service.js';
18
18
  import { LibP2PService } from '../services/libp2p/libp2p_service.js';
19
19
  import { ReqRespSubProtocol, noopValidator } from '../services/reqresp/interface.js';
20
- import { pingHandler, statusHandler } from '../services/reqresp/protocols/index.js';
20
+ import { pingHandler } from '../services/reqresp/protocols/index.js';
21
21
  import { ReqResp } from '../services/reqresp/reqresp.js';
22
22
  import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js';
23
23
  /**
@@ -95,7 +95,7 @@ import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js
95
95
  // Mock sub protocol handlers
96
96
  export const MOCK_SUB_PROTOCOL_HANDLERS = {
97
97
  [ReqRespSubProtocol.PING]: pingHandler,
98
- [ReqRespSubProtocol.STATUS]: statusHandler,
98
+ [ReqRespSubProtocol.STATUS]: (_msg)=>Promise.resolve(Buffer.from('status')),
99
99
  [ReqRespSubProtocol.TX]: (_msg)=>Promise.resolve(Buffer.from('tx')),
100
100
  [ReqRespSubProtocol.GOODBYE]: (_msg)=>Promise.resolve(Buffer.from('goodbye')),
101
101
  [ReqRespSubProtocol.BLOCK]: (_msg)=>Promise.resolve(Buffer.from('block'))
@@ -19,7 +19,7 @@ function mockTxPool() {
19
19
  // Mock all methods
20
20
  return {
21
21
  isEmpty: ()=>Promise.resolve(false),
22
- addTxs: ()=>Promise.resolve(),
22
+ addTxs: ()=>Promise.resolve(1),
23
23
  getTxByHash: ()=>Promise.resolve(undefined),
24
24
  getArchivedTxByHash: ()=>Promise.resolve(undefined),
25
25
  markAsMined: ()=>Promise.resolve(),
@@ -63,7 +63,7 @@ function mockEpochCache() {
63
63
  ts: 0n
64
64
  }),
65
65
  computeProposerIndex: ()=>0n,
66
- getProposerInCurrentOrNextSlot: ()=>Promise.resolve({
66
+ getProposerAttesterAddressInCurrentOrNextSlot: ()=>Promise.resolve({
67
67
  currentProposer: EthAddress.ZERO,
68
68
  nextProposer: EthAddress.ZERO,
69
69
  currentSlot: 0n,
@@ -72,6 +72,19 @@ function mockEpochCache() {
72
72
  isInCommittee: ()=>Promise.resolve(false)
73
73
  };
74
74
  }
75
+ function mockWorldStateSynchronizer() {
76
+ return {
77
+ status: ()=>Promise.resolve({
78
+ syncSummary: {
79
+ latestBlockNumber: 0,
80
+ latestBlockHash: '',
81
+ finalisedBlockNumber: 0,
82
+ treesAreSynched: false,
83
+ oldestHistoricBlockNumber: 0
84
+ }
85
+ })
86
+ };
87
+ }
75
88
  class TestLibP2PService extends LibP2PService {
76
89
  disableTxValidation;
77
90
  gossipMessageCount = 0;
@@ -117,7 +130,7 @@ process.on('message', async (msg)=>{
117
130
  const txPool = mockTxPool();
118
131
  const attestationPool = mockAttestationPool();
119
132
  const epochCache = mockEpochCache();
120
- const worldState = {};
133
+ const worldState = mockWorldStateSynchronizer();
121
134
  const l2BlockSource = new MockL2BlockSource();
122
135
  const proofVerifier = new AlwaysTrueCircuitVerifier();
123
136
  const kvStore = await openTmpStore(`test-${clientIndex}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.87.7",
3
+ "version": "1.0.0-nightly.20250605",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -63,16 +63,16 @@
63
63
  ]
64
64
  },
65
65
  "dependencies": {
66
- "@aztec/constants": "0.87.7",
67
- "@aztec/epoch-cache": "0.87.7",
68
- "@aztec/foundation": "0.87.7",
69
- "@aztec/kv-store": "0.87.7",
70
- "@aztec/noir-contracts.js": "0.87.7",
71
- "@aztec/noir-protocol-circuits-types": "0.87.7",
72
- "@aztec/protocol-contracts": "0.87.7",
73
- "@aztec/simulator": "0.87.7",
74
- "@aztec/stdlib": "0.87.7",
75
- "@aztec/telemetry-client": "0.87.7",
66
+ "@aztec/constants": "1.0.0-nightly.20250605",
67
+ "@aztec/epoch-cache": "1.0.0-nightly.20250605",
68
+ "@aztec/foundation": "1.0.0-nightly.20250605",
69
+ "@aztec/kv-store": "1.0.0-nightly.20250605",
70
+ "@aztec/noir-contracts.js": "1.0.0-nightly.20250605",
71
+ "@aztec/noir-protocol-circuits-types": "1.0.0-nightly.20250605",
72
+ "@aztec/protocol-contracts": "1.0.0-nightly.20250605",
73
+ "@aztec/simulator": "1.0.0-nightly.20250605",
74
+ "@aztec/stdlib": "1.0.0-nightly.20250605",
75
+ "@aztec/telemetry-client": "1.0.0-nightly.20250605",
76
76
  "@chainsafe/discv5": "9.0.0",
77
77
  "@chainsafe/enr": "3.0.0",
78
78
  "@chainsafe/libp2p-gossipsub": "13.0.0",
@@ -101,7 +101,7 @@
101
101
  "xxhash-wasm": "^1.1.0"
102
102
  },
103
103
  "devDependencies": {
104
- "@aztec/archiver": "0.87.7",
104
+ "@aztec/archiver": "1.0.0-nightly.20250605",
105
105
  "@jest/globals": "^29.5.0",
106
106
  "@types/jest": "^29.5.0",
107
107
  "@types/node": "^22.15.17",
@@ -1,5 +1,5 @@
1
1
  import type { L2BlockId } from '@aztec/stdlib/block';
2
- import type { P2PApi } from '@aztec/stdlib/interfaces/server';
2
+ import type { P2PApiFull } from '@aztec/stdlib/interfaces/server';
3
3
  import type { BlockProposal, P2PClientType } from '@aztec/stdlib/p2p';
4
4
  import type { Tx, TxHash } from '@aztec/stdlib/tx';
5
5
 
@@ -36,7 +36,7 @@ export interface P2PSyncState {
36
36
  /**
37
37
  * Interface of a P2P client.
38
38
  **/
39
- export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApi<T> & {
39
+ export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApiFull<T> & {
40
40
  /**
41
41
  * Broadcasts a block proposal to other peers.
42
42
  *
@@ -77,8 +77,9 @@ export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApi<T> & {
77
77
  /**
78
78
  * Adds transactions to the pool. Does not send to peers or validate the tx.
79
79
  * @param txs - The transactions.
80
+ * @returns The number of txs added to the pool. Note if the transaction already exists, it will not be added again.
80
81
  **/
81
- addTxs(txs: Tx[]): Promise<void>;
82
+ addTxsToPool(txs: Tx[]): Promise<number>;
82
83
 
83
84
  /**
84
85
  * Deletes 'txs' from the pool, given hashes.
@@ -31,7 +31,7 @@ import type { AttestationPool } from '../mem_pools/attestation_pool/attestation_
31
31
  import type { MemPools } from '../mem_pools/interface.js';
32
32
  import type { TxPool } from '../mem_pools/tx_pool/index.js';
33
33
  import { ReqRespSubProtocol } from '../services/reqresp/interface.js';
34
- import type { P2PService } from '../services/service.js';
34
+ import type { P2PBlockReceivedCallback, P2PService } from '../services/service.js';
35
35
  import { TxCollector } from '../services/tx_collector.js';
36
36
  import { type P2P, P2PClientState, type P2PSyncState } from './interface.js';
37
37
 
@@ -331,15 +331,13 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
331
331
  );
332
332
  }
333
333
 
334
- public addAttestation(attestation: BlockAttestation): Promise<void> {
335
- return this.attestationPool?.addAttestations([attestation]) ?? Promise.resolve();
334
+ public addAttestations(attestations: BlockAttestation[]): Promise<void> {
335
+ return this.attestationPool?.addAttestations(attestations) ?? Promise.resolve();
336
336
  }
337
337
 
338
338
  // REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
339
339
  // ^ This pattern is not my favorite (md)
340
- public registerBlockProposalHandler(
341
- handler: (block: BlockProposal, sender: any) => Promise<BlockAttestation | undefined>,
342
- ): void {
340
+ public registerBlockProposalHandler(handler: P2PBlockReceivedCallback): void {
343
341
  this.p2pService.registerBlockReceivedCallback(handler);
344
342
  }
345
343
 
@@ -444,7 +442,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
444
442
  /**
445
443
  * Returns transactions in the transaction pool by hash.
446
444
  * @param txHashes - Hashes of the transactions to look for.
447
- * @returns The txs found, not necessarily on the same order as the hashes.
445
+ * @returns The txs found, in the same order as the requested hashes. If a tx is not found, it will be undefined.
448
446
  */
449
447
  getTxsByHashFromPool(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
450
448
  return this.txPool.getTxsByHash(txHashes);
@@ -527,17 +525,20 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
527
525
  * @returns Empty promise.
528
526
  **/
529
527
  public async sendTx(tx: Tx): Promise<void> {
530
- await this.addTxs([tx]);
531
- await this.p2pService.propagate(tx);
528
+ const addedCount = await this.addTxsToPool([tx]);
529
+ const txAddedSuccessfully = addedCount === 1;
530
+ if (txAddedSuccessfully) {
531
+ await this.p2pService.propagate(tx);
532
+ }
532
533
  }
533
534
 
534
535
  /**
535
536
  * Adds transactions to the pool. Does not send to peers or validate the txs.
536
537
  * @param txs - The transactions.
537
538
  **/
538
- public async addTxs(txs: Tx[]): Promise<void> {
539
+ public async addTxsToPool(txs: Tx[]): Promise<number> {
539
540
  this.#assertIsReady();
540
- await this.txPool.addTxs(txs);
541
+ return await this.txPool.addTxs(txs);
541
542
  }
542
543
 
543
544
  /**
@@ -8,7 +8,7 @@ import type { BlockAttestation } from '@aztec/stdlib/p2p';
8
8
  */
9
9
  export interface AttestationPool {
10
10
  /**
11
- * AddAttestation
11
+ * AddAttestations
12
12
  *
13
13
  * @param attestations - Attestations to add into the pool
14
14
  */