@aztec/p2p 0.87.4 → 0.87.6

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 (76) hide show
  1. package/dest/client/interface.d.ts +8 -4
  2. package/dest/client/interface.d.ts.map +1 -1
  3. package/dest/client/p2p_client.d.ts +4 -3
  4. package/dest/client/p2p_client.d.ts.map +1 -1
  5. package/dest/client/p2p_client.js +17 -10
  6. package/dest/config.d.ts +10 -0
  7. package/dest/config.d.ts.map +1 -1
  8. package/dest/config.js +12 -2
  9. package/dest/index.d.ts +1 -0
  10. package/dest/index.d.ts.map +1 -1
  11. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +5 -6
  12. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  13. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +37 -12
  14. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +2 -2
  15. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
  16. package/dest/mem_pools/tx_pool/memory_tx_pool.js +1 -3
  17. package/dest/mem_pools/tx_pool/tx_pool.d.ts +6 -1
  18. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  19. package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +10 -0
  20. package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -0
  21. package/dest/msg_validators/msg_seen_validator/msg_seen_validator.js +36 -0
  22. package/dest/services/dummy_service.d.ts +1 -1
  23. package/dest/services/dummy_service.d.ts.map +1 -1
  24. package/dest/services/dummy_service.js +1 -1
  25. package/dest/services/index.d.ts +1 -0
  26. package/dest/services/index.d.ts.map +1 -1
  27. package/dest/services/index.js +1 -0
  28. package/dest/services/libp2p/libp2p_service.d.ts +5 -3
  29. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  30. package/dest/services/libp2p/libp2p_service.js +42 -8
  31. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +1 -1
  32. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
  33. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +7 -3
  34. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -1
  35. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  36. package/dest/services/reqresp/connection-sampler/connection_sampler.js +8 -3
  37. package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
  38. package/dest/services/reqresp/protocols/goodbye.js +3 -1
  39. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +4 -2
  40. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  41. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -2
  42. package/dest/services/reqresp/rate-limiter/rate_limits.js +1 -1
  43. package/dest/services/reqresp/reqresp.d.ts +3 -3
  44. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  45. package/dest/services/reqresp/reqresp.js +39 -13
  46. package/dest/services/service.d.ts +3 -2
  47. package/dest/services/service.d.ts.map +1 -1
  48. package/dest/services/tx_collector.d.ts +14 -0
  49. package/dest/services/tx_collector.d.ts.map +1 -0
  50. package/dest/services/tx_collector.js +73 -0
  51. package/dest/test-helpers/reqresp-nodes.d.ts +3 -3
  52. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  53. package/dest/test-helpers/reqresp-nodes.js +4 -4
  54. package/dest/testbench/p2p_client_testbench_worker.js +1 -1
  55. package/package.json +12 -12
  56. package/src/client/interface.ts +8 -4
  57. package/src/client/p2p_client.ts +22 -10
  58. package/src/config.ts +22 -1
  59. package/src/index.ts +2 -0
  60. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +45 -18
  61. package/src/mem_pools/tx_pool/memory_tx_pool.ts +2 -4
  62. package/src/mem_pools/tx_pool/tx_pool.ts +7 -1
  63. package/src/msg_validators/msg_seen_validator/msg_seen_validator.ts +36 -0
  64. package/src/services/dummy_service.ts +3 -1
  65. package/src/services/index.ts +1 -0
  66. package/src/services/libp2p/libp2p_service.ts +51 -9
  67. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +4 -2
  68. package/src/services/reqresp/connection-sampler/connection_sampler.ts +8 -3
  69. package/src/services/reqresp/protocols/goodbye.ts +3 -1
  70. package/src/services/reqresp/rate-limiter/rate_limiter.ts +9 -3
  71. package/src/services/reqresp/rate-limiter/rate_limits.ts +1 -1
  72. package/src/services/reqresp/reqresp.ts +44 -16
  73. package/src/services/service.ts +4 -1
  74. package/src/services/tx_collector.ts +98 -0
  75. package/src/test-helpers/reqresp-nodes.ts +13 -8
  76. package/src/testbench/p2p_client_testbench_worker.ts +1 -1
@@ -0,0 +1,73 @@
1
+ import { compactArray } from '@aztec/foundation/collection';
2
+ import { createLogger } from '@aztec/foundation/log';
3
+ export class TxCollector {
4
+ p2pClient;
5
+ log;
6
+ constructor(p2pClient, log = createLogger('p2p:tx-collector')){
7
+ this.p2pClient = p2pClient;
8
+ this.log = log;
9
+ }
10
+ async collectForBlockProposal(proposal, peerWhoSentTheProposal) {
11
+ if (proposal.payload.txHashes.length === 0) {
12
+ this.log.verbose(`Received block proposal with no transactions, skipping transaction availability check`);
13
+ return {
14
+ txs: []
15
+ };
16
+ }
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
57
+ 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
+ // This will request from the network any txs that are missing
65
+ const retrievedTxs = await this.p2pClient.getTxsByHash(txHashes, peerWhoSentTheProposal);
66
+ const missingTxs = compactArray(retrievedTxs.map((tx, index)=>tx === undefined ? txHashes[index] : undefined));
67
+ await this.p2pClient.validate(retrievedTxs);
68
+ return {
69
+ txs: retrievedTxs,
70
+ missing: missingTxs
71
+ };
72
+ }
73
+ }
@@ -14,7 +14,7 @@ import type { BootnodeConfig } from '../config.js';
14
14
  import type { MemPools } from '../mem_pools/interface.js';
15
15
  import { LibP2PService } from '../services/libp2p/libp2p_service.js';
16
16
  import type { PeerScoring } from '../services/peer-manager/peer_scoring.js';
17
- import { type ReqRespSubProtocolHandlers, type ReqRespSubProtocolValidators } from '../services/reqresp/interface.js';
17
+ import { type ReqRespSubProtocolHandlers, type ReqRespSubProtocolRateLimits, type ReqRespSubProtocolValidators } from '../services/reqresp/interface.js';
18
18
  import { ReqResp } from '../services/reqresp/reqresp.js';
19
19
  /**
20
20
  * Creates a libp2p node, pre configured.
@@ -43,10 +43,10 @@ export declare const MOCK_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators;
43
43
  * @param numberOfNodes - the number of nodes to create
44
44
  * @returns An array of the created nodes
45
45
  */
46
- export declare const createNodes: (peerScoring: PeerScoring, numberOfNodes: number) => Promise<ReqRespNode[]>;
46
+ export declare const createNodes: (peerScoring: PeerScoring, numberOfNodes: number, rateLimits?: Partial<ReqRespSubProtocolRateLimits>) => Promise<ReqRespNode[]>;
47
47
  export declare const startNodes: (nodes: ReqRespNode[], subProtocolHandlers?: ReqRespSubProtocolHandlers, subProtocolValidators?: ReqRespSubProtocolValidators) => Promise<void>;
48
48
  export declare const stopNodes: (nodes: ReqRespNode[]) => Promise<void>;
49
- export declare const createReqResp: (peerScoring: PeerScoring) => Promise<ReqRespNode>;
49
+ export declare const createReqResp: (peerScoring: PeerScoring, rateLimits?: Partial<ReqRespSubProtocolRateLimits>) => Promise<ReqRespNode>;
50
50
  export declare const connectToPeers: (nodes: ReqRespNode[]) => Promise<void>;
51
51
  export declare class AlwaysTrueCircuitVerifier implements ClientProtocolCircuitVerifier {
52
52
  verifyProof(_tx: Tx): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"reqresp-nodes.d.ts","sourceRoot":"","sources":["../../src/test-helpers/reqresp-nodes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reqresp-nodes.d.ts","sourceRoot":"","sources":["../../src/test-helpers/reqresp-nodes.ts"],"names":[],"mappings":"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"}
@@ -112,8 +112,8 @@ export const MOCK_SUB_PROTOCOL_VALIDATORS = {
112
112
  /**
113
113
  * @param numberOfNodes - the number of nodes to create
114
114
  * @returns An array of the created nodes
115
- */ export const createNodes = (peerScoring, numberOfNodes)=>{
116
- return timesParallel(numberOfNodes, ()=>createReqResp(peerScoring));
115
+ */ export const createNodes = (peerScoring, numberOfNodes, rateLimits = {})=>{
116
+ return timesParallel(numberOfNodes, ()=>createReqResp(peerScoring, rateLimits));
117
117
  };
118
118
  export const startNodes = async (nodes, subProtocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS, subProtocolValidators = MOCK_SUB_PROTOCOL_VALIDATORS)=>{
119
119
  for (const node of nodes){
@@ -128,13 +128,13 @@ export const stopNodes = async (nodes)=>{
128
128
  await Promise.all(stopPromises);
129
129
  };
130
130
  // Create a req resp node, exposing the underlying p2p node
131
- export const createReqResp = async (peerScoring)=>{
131
+ export const createReqResp = async (peerScoring, rateLimits = {})=>{
132
132
  const p2p = await createLibp2pNode();
133
133
  const config = {
134
134
  overallRequestTimeoutMs: 4000,
135
135
  individualRequestTimeoutMs: 2000
136
136
  };
137
- const req = new ReqResp(config, p2p, peerScoring);
137
+ const req = new ReqResp(config, p2p, peerScoring, rateLimits);
138
138
  return {
139
139
  p2p,
140
140
  req
@@ -33,7 +33,7 @@ function mockTxPool() {
33
33
  getTxStatus: ()=>Promise.resolve(TxStatus.PENDING),
34
34
  getTxsByHash: ()=>Promise.resolve([]),
35
35
  hasTxs: ()=>Promise.resolve([]),
36
- setMaxTxPoolSize: ()=>Promise.resolve(),
36
+ updateConfig: ()=>{},
37
37
  markTxsAsNonEvictable: ()=>Promise.resolve()
38
38
  };
39
39
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.87.4",
3
+ "version": "0.87.6",
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.4",
67
- "@aztec/epoch-cache": "0.87.4",
68
- "@aztec/foundation": "0.87.4",
69
- "@aztec/kv-store": "0.87.4",
70
- "@aztec/noir-contracts.js": "0.87.4",
71
- "@aztec/noir-protocol-circuits-types": "0.87.4",
72
- "@aztec/protocol-contracts": "0.87.4",
73
- "@aztec/simulator": "0.87.4",
74
- "@aztec/stdlib": "0.87.4",
75
- "@aztec/telemetry-client": "0.87.4",
66
+ "@aztec/constants": "0.87.6",
67
+ "@aztec/epoch-cache": "0.87.6",
68
+ "@aztec/foundation": "0.87.6",
69
+ "@aztec/kv-store": "0.87.6",
70
+ "@aztec/noir-contracts.js": "0.87.6",
71
+ "@aztec/noir-protocol-circuits-types": "0.87.6",
72
+ "@aztec/protocol-contracts": "0.87.6",
73
+ "@aztec/simulator": "0.87.6",
74
+ "@aztec/stdlib": "0.87.6",
75
+ "@aztec/telemetry-client": "0.87.6",
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.4",
104
+ "@aztec/archiver": "0.87.6",
105
105
  "@jest/globals": "^29.5.0",
106
106
  "@types/jest": "^29.5.0",
107
107
  "@types/node": "^22.15.17",
@@ -1,11 +1,13 @@
1
1
  import type { L2BlockId } from '@aztec/stdlib/block';
2
2
  import type { P2PApi } from '@aztec/stdlib/interfaces/server';
3
- import { BlockAttestation, type BlockProposal, type P2PClientType } from '@aztec/stdlib/p2p';
3
+ import type { BlockProposal, P2PClientType } from '@aztec/stdlib/p2p';
4
4
  import type { Tx, TxHash } from '@aztec/stdlib/tx';
5
5
 
6
6
  import type { ENR } from '@chainsafe/enr';
7
+ import type { PeerId } from '@libp2p/interface';
7
8
 
8
9
  import type { P2PConfig } from '../config.js';
10
+ import type { P2PBlockReceivedCallback } from '../services/service.js';
9
11
 
10
12
  /**
11
13
  * Enum defining the possible states of the p2p client.
@@ -50,14 +52,15 @@ export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApi<T> & {
50
52
  */
51
53
  // REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
52
54
  // ^ This pattern is not my favorite (md)
53
- registerBlockProposalHandler(handler: (block: BlockProposal) => Promise<BlockAttestation | undefined>): void;
55
+ registerBlockProposalHandler(callback: P2PBlockReceivedCallback): void;
54
56
 
55
57
  /**
56
58
  * Request a list of transactions from another peer by their tx hashes.
57
59
  * @param txHashes - Hashes of the txs to query.
60
+ * @param pinnedPeerId - An optional peer id that will be used to request the tx from (in addition to other random peers).
58
61
  * @returns A list of transactions or undefined if the transactions are not found.
59
62
  */
60
- requestTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]>;
63
+ requestTxsByHash(txHashes: TxHash[], pinnedPeerId: PeerId): Promise<(Tx | undefined)[]>;
61
64
 
62
65
  /**
63
66
  * Request a transaction from another peer by its tx hash.
@@ -115,9 +118,10 @@ export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApi<T> & {
115
118
  /**
116
119
  * Returns transactions in the transaction pool by hash, requesting from the network if not found.
117
120
  * @param txHashes - Hashes of tx to return.
121
+ * @param pinnedPeerId - An optional peer id that will be used to request the tx from (in addition to other random peers).
118
122
  * @returns An array of tx or undefined.
119
123
  */
120
- getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]>;
124
+ getTxsByHash(txHashes: TxHash[], pinnedPeerId: PeerId | undefined): Promise<(Tx | undefined)[]>;
121
125
 
122
126
  /**
123
127
  * Returns an archived transaction from the transaction pool by its hash.
@@ -24,6 +24,7 @@ import {
24
24
  } from '@aztec/telemetry-client';
25
25
 
26
26
  import type { ENR } from '@chainsafe/enr';
27
+ import type { PeerId } from '@libp2p/interface';
27
28
 
28
29
  import { type P2PConfig, getP2PDefaultConfig } from '../config.js';
29
30
  import type { AttestationPool } from '../mem_pools/attestation_pool/attestation_pool.js';
@@ -31,6 +32,7 @@ import type { MemPools } from '../mem_pools/interface.js';
31
32
  import type { TxPool } from '../mem_pools/tx_pool/index.js';
32
33
  import { ReqRespSubProtocol } from '../services/reqresp/interface.js';
33
34
  import type { P2PService } from '../services/service.js';
35
+ import { TxCollector } from '../services/tx_collector.js';
34
36
  import { type P2P, P2PClientState, type P2PSyncState } from './interface.js';
35
37
 
36
38
  /**
@@ -87,6 +89,15 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
87
89
  this.txPool = mempools.txPool;
88
90
  this.attestationPool = mempools.attestationPool!;
89
91
 
92
+ // Default to collecting all txs when we see a valid proposal
93
+ // This can be overridden by the validator client to attest, and it will call collectForBlockProposal on its own
94
+ const txCollector = new TxCollector(this, this.log);
95
+ this.registerBlockProposalHandler(async (block, sender) => {
96
+ this.log.debug(`Received block proposal from ${sender.toString()}`);
97
+ await txCollector.collectForBlockProposal(block, sender);
98
+ return undefined;
99
+ });
100
+
90
101
  // REFACTOR: Try replacing these with an L2TipsStore
91
102
  this.synchedBlockHashes = store.openMap('p2p_pool_block_hashes');
92
103
  this.synchedLatestBlockNumber = store.openSingleton('p2p_pool_last_l2_block');
@@ -111,11 +122,9 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
111
122
  return this.synchedBlockHashes.getAsync(number);
112
123
  }
113
124
 
114
- public async updateP2PConfig(config: Partial<P2PConfig>): Promise<void> {
115
- if (typeof config.maxTxPoolSize === 'number' && this.config.maxTxPoolSize !== config.maxTxPoolSize) {
116
- await this.txPool.setMaxTxPoolSize(config.maxTxPoolSize);
117
- this.config.maxTxPoolSize = config.maxTxPoolSize;
118
- }
125
+ public updateP2PConfig(config: Partial<P2PConfig>): Promise<void> {
126
+ this.txPool.updateConfig(config);
127
+ return Promise.resolve();
119
128
  }
120
129
 
121
130
  public async getL2Tips(): Promise<L2Tips> {
@@ -328,7 +337,9 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
328
337
 
329
338
  // REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
330
339
  // ^ This pattern is not my favorite (md)
331
- public registerBlockProposalHandler(handler: (block: BlockProposal) => Promise<BlockAttestation | undefined>): void {
340
+ public registerBlockProposalHandler(
341
+ handler: (block: BlockProposal, sender: any) => Promise<BlockAttestation | undefined>,
342
+ ): void {
332
343
  this.p2pService.registerBlockReceivedCallback(handler);
333
344
  }
334
345
 
@@ -357,7 +368,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
357
368
  /**
358
369
  * Uses the batched Request Response protocol to request a set of transactions from the network.
359
370
  */
360
- public async requestTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
371
+ public async requestTxsByHash(txHashes: TxHash[], pinnedPeerId: PeerId | undefined): Promise<(Tx | undefined)[]> {
361
372
  const timeoutMs = 8000; // Longer timeout for now
362
373
  const maxPeers = Math.min(Math.ceil(txHashes.length / 3), 10);
363
374
  const maxRetryAttempts = 10; // Keep retrying within the timeout
@@ -365,6 +376,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
365
376
  const txs = await this.p2pService.sendBatchRequest(
366
377
  ReqRespSubProtocol.TX,
367
378
  txHashes,
379
+ pinnedPeerId,
368
380
  timeoutMs,
369
381
  maxPeers,
370
382
  maxRetryAttempts,
@@ -462,7 +474,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
462
474
  * @param txHashes - Hashes of the transactions to look for.
463
475
  * @returns The txs found, or undefined if not found in the order requested.
464
476
  */
465
- async getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
477
+ async getTxsByHash(txHashes: TxHash[], pinnedPeerId: PeerId | undefined): Promise<(Tx | undefined)[]> {
466
478
  const txs = await Promise.all(txHashes.map(txHash => this.txPool.getTxByHash(txHash)));
467
479
  const missingTxHashes = txs
468
480
  .map((tx, index) => [tx, index] as const)
@@ -473,7 +485,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
473
485
  return txs as Tx[];
474
486
  }
475
487
 
476
- const missingTxs = await this.requestTxsByHash(missingTxHashes);
488
+ const missingTxs = await this.requestTxsByHash(missingTxHashes, pinnedPeerId);
477
489
  const fetchedMissingTxs = missingTxs.filter((tx): tx is Tx => !!tx);
478
490
 
479
491
  // TODO: optimize
@@ -678,7 +690,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
678
690
  `Requesting ${missingTxHashes.length} missing txs from peers for ${unprovenBlocks.length} unproven mined blocks`,
679
691
  { missingTxHashes, unprovenBlockNumbers: unprovenBlocks.map(block => block.number) },
680
692
  );
681
- await this.requestTxsByHash(missingTxHashes);
693
+ await this.requestTxsByHash(missingTxHashes, undefined);
682
694
  }
683
695
  } catch (err) {
684
696
  this.log.error(`Error requesting missing txs from unproven blocks`, err, {
package/src/config.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  type ConfigMappingsType,
3
3
  booleanConfigHelper,
4
+ floatConfigHelper,
4
5
  getConfigFromMappings,
5
6
  getDefaultConfig,
6
7
  numberConfigHelper,
@@ -196,6 +197,16 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
196
197
  * The maximum cumulative tx size (in bytes) of pending txs before evicting lower priority txs.
197
198
  */
198
199
  maxTxPoolSize: number;
200
+
201
+ /**
202
+ * If the pool is full, it will still accept a few more txs until it reached maxTxPoolOverspillFactor * maxTxPoolSize. Then it will evict
203
+ */
204
+ txPoolOverflowFactor: number;
205
+
206
+ /**
207
+ * The node's seen message ID cache size
208
+ */
209
+ seenMessageCacheSize: number;
199
210
  }
200
211
 
201
212
  export const DEFAULT_P2P_PORT = 40400;
@@ -308,7 +319,7 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
308
319
  gossipsubFloodPublish: {
309
320
  env: 'P2P_GOSSIPSUB_FLOOD_PUBLISH',
310
321
  description: 'Whether to flood publish messages. - For testing purposes only',
311
- ...booleanConfigHelper(true),
322
+ ...booleanConfigHelper(false),
312
323
  },
313
324
  gossipsubMcacheLength: {
314
325
  env: 'P2P_GOSSIPSUB_MCACHE_LENGTH',
@@ -393,6 +404,16 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
393
404
  description: 'The maximum cumulative tx size of pending txs (in bytes) before evicting lower priority txs.',
394
405
  ...numberConfigHelper(100_000_000), // 100MB
395
406
  },
407
+ txPoolOverflowFactor: {
408
+ env: 'P2P_TX_POOL_OVERFLOW_FACTOR',
409
+ description: 'How much the tx pool can overflow before it starts evicting txs. Must be greater than 1',
410
+ ...floatConfigHelper(1.1), // 10% overflow
411
+ },
412
+ seenMessageCacheSize: {
413
+ env: 'P2P_SEEN_MSG_CACHE_SIZE',
414
+ description: 'The number of messages to keep in the seen message cache',
415
+ ...numberConfigHelper(100_000), // 100K
416
+ },
396
417
  ...p2pReqRespConfigMappings,
397
418
  ...chainConfigMappings,
398
419
  };
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export type { PeerId } from '@libp2p/interface';
2
+
1
3
  export * from './bootstrap/bootstrap.js';
2
4
  export * from './client/index.js';
3
5
  export * from './enr/index.js';
@@ -11,11 +11,13 @@ import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
11
11
  import { Tx, TxHash } from '@aztec/stdlib/tx';
12
12
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
13
13
 
14
+ import assert from 'assert';
15
+
14
16
  import { ArchiveCache } from '../../msg_validators/tx_validator/archive_cache.js';
15
17
  import { GasTxValidator } from '../../msg_validators/tx_validator/gas_validator.js';
16
18
  import { PoolInstrumentation, PoolName } from '../instrumentation.js';
17
19
  import { getPendingTxPriority } from './priority.js';
18
- import type { TxPool } from './tx_pool.js';
20
+ import type { TxPool, TxPoolOptions } from './tx_pool.js';
19
21
 
20
22
  /**
21
23
  * KV implementation of the Transaction Pool.
@@ -27,7 +29,10 @@ export class AztecKVTxPool implements TxPool {
27
29
  #txs: AztecAsyncMap<string, Buffer>;
28
30
 
29
31
  /** The maximum cumulative tx size that the pending txs in the pool take up. */
30
- #maxTxPoolSize: number | undefined;
32
+ #maxTxPoolSize: number = 0;
33
+
34
+ /** The tx evicion logic will kick after pool size is greater than maxTxPoolSize * txPoolOverflowFactor */
35
+ txPoolOverflowFactor: number = 1;
31
36
 
32
37
  /** Index from tx hash to the block number in which they were mined, filtered by mined txs. */
33
38
  #minedTxHashToBlock: AztecAsyncMap<string, number>;
@@ -63,7 +68,7 @@ export class AztecKVTxPool implements TxPool {
63
68
  #archivedTxIndices: AztecAsyncMap<number, string>;
64
69
 
65
70
  /** Number of txs to archive. */
66
- #archivedTxLimit: number;
71
+ #archivedTxLimit: number = 0;
67
72
 
68
73
  /** The world state synchronizer used in the node. */
69
74
  #worldStateSynchronizer: WorldStateSynchronizer;
@@ -85,12 +90,12 @@ export class AztecKVTxPool implements TxPool {
85
90
  archive: AztecAsyncKVStore,
86
91
  worldStateSynchronizer: WorldStateSynchronizer,
87
92
  telemetry: TelemetryClient = getTelemetryClient(),
88
- config: {
89
- maxTxPoolSize?: number;
90
- archivedTxLimit?: number;
91
- } = {},
93
+ config: TxPoolOptions = {},
92
94
  log = createLogger('p2p:tx_pool'),
93
95
  ) {
96
+ this.#log = log;
97
+ this.updateConfig(config);
98
+
94
99
  this.#txs = store.openMap('txs');
95
100
  this.#minedTxHashToBlock = store.openMap('txHashToBlockMined');
96
101
  this.#pendingTxPriorityToHash = store.openMultiMap('pendingTxFeeToHash');
@@ -98,18 +103,16 @@ export class AztecKVTxPool implements TxPool {
98
103
  this.#pendingTxHashToHeaderHash = store.openMap('pendingTxHashToHeaderHash');
99
104
  this.#pendingTxSize = store.openSingleton('pendingTxSize');
100
105
  this.#pendingTxCount = store.openSingleton('pendingTxCount');
101
- this.#maxTxPoolSize = config.maxTxPoolSize;
106
+
102
107
  this.#pendingTxs = new Map<string, Tx>();
103
108
  this.#nonEvictableTxs = new Set<string>();
104
109
 
105
110
  this.#archivedTxs = archive.openMap('archivedTxs');
106
111
  this.#archivedTxIndices = archive.openMap('archivedTxIndices');
107
- this.#archivedTxLimit = config.archivedTxLimit ?? 0;
108
112
 
109
113
  this.#store = store;
110
114
  this.#archive = archive;
111
115
  this.#worldStateSynchronizer = worldStateSynchronizer;
112
- this.#log = log;
113
116
  this.#metrics = new PoolInstrumentation(telemetry, PoolName.TX_POOL, () => store.estimateSize());
114
117
  }
115
118
 
@@ -386,9 +389,28 @@ export class AztecKVTxPool implements TxPool {
386
389
  return vals.map(x => TxHash.fromString(x));
387
390
  }
388
391
 
389
- public setMaxTxPoolSize(maxSizeBytes: number | undefined): Promise<void> {
390
- this.#maxTxPoolSize = maxSizeBytes;
391
- return Promise.resolve();
392
+ public updateConfig({ maxTxPoolSize, txPoolOverflowFactor, archivedTxLimit }: TxPoolOptions): void {
393
+ if (typeof maxTxPoolSize === 'number') {
394
+ assert(maxTxPoolSize >= 0, 'maxTxPoolSize must be greater or equal to 0');
395
+ this.#maxTxPoolSize = maxTxPoolSize;
396
+
397
+ if (maxTxPoolSize === 0) {
398
+ this.#log.info(`Disabling maximum tx mempool size. Tx eviction stopped`);
399
+ } else {
400
+ this.#log.info(`Setting maximum tx mempool size`, { maxTxPoolSize });
401
+ }
402
+ }
403
+
404
+ if (typeof txPoolOverflowFactor === 'number') {
405
+ assert(txPoolOverflowFactor >= 1, 'txPoolOveflowFactor must be greater or equal to 1');
406
+ this.txPoolOverflowFactor = txPoolOverflowFactor;
407
+ this.#log.info(`Allowing tx pool size to grow above limit`, { maxTxPoolSize, txPoolOverflowFactor });
408
+ }
409
+
410
+ if (typeof archivedTxLimit === 'number') {
411
+ assert(archivedTxLimit >= 0, 'archivedTxLimit must be greater or equal to 0');
412
+ this.#archivedTxLimit = archivedTxLimit;
413
+ }
392
414
  }
393
415
 
394
416
  public markTxsAsNonEvictable(txHashes: TxHash[]): Promise<void> {
@@ -483,7 +505,7 @@ export class AztecKVTxPool implements TxPool {
483
505
  private async evictLowPriorityTxs(
484
506
  newTxHashes: TxHash[],
485
507
  ): Promise<{ numLowPriorityTxsEvicted: number; numNewTxsEvicted: number }> {
486
- if (this.#maxTxPoolSize === undefined) {
508
+ if (this.#maxTxPoolSize === undefined || this.#maxTxPoolSize === 0) {
487
509
  return { numLowPriorityTxsEvicted: 0, numNewTxsEvicted: 0 };
488
510
  }
489
511
 
@@ -491,17 +513,22 @@ export class AztecKVTxPool implements TxPool {
491
513
  const txsToEvict: TxHash[] = [];
492
514
 
493
515
  let pendingTxsSize = (await this.#pendingTxSize.getAsync()) ?? 0;
494
- if (pendingTxsSize > this.#maxTxPoolSize) {
516
+ if (pendingTxsSize > this.#maxTxPoolSize * this.txPoolOverflowFactor) {
495
517
  for await (const txHash of this.#pendingTxPriorityToHash.valuesAsync()) {
496
518
  if (this.#nonEvictableTxs.has(txHash.toString())) {
497
519
  continue;
498
520
  }
499
- this.#log.verbose(`Evicting tx ${txHash} from pool due to low priority to satisfy max tx size limit`);
500
- txsToEvict.push(TxHash.fromString(txHash));
501
-
502
521
  const txSize =
503
522
  (await this.#pendingTxHashToSize.getAsync(txHash.toString())) ??
504
523
  (await this.getPendingTxByHash(txHash))?.getSize();
524
+
525
+ this.#log.verbose(`Evicting tx ${txHash} from pool due to low priority to satisfy max tx size limit`, {
526
+ txHash,
527
+ txSize,
528
+ });
529
+
530
+ txsToEvict.push(TxHash.fromString(txHash));
531
+
505
532
  if (txSize) {
506
533
  pendingTxsSize -= txSize;
507
534
  if (pendingTxsSize <= this.#maxTxPoolSize) {
@@ -5,7 +5,7 @@ import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-clien
5
5
 
6
6
  import { PoolInstrumentation, PoolName } from '../instrumentation.js';
7
7
  import { getPendingTxPriority } from './priority.js';
8
- import type { TxPool } from './tx_pool.js';
8
+ import type { TxPool, TxPoolOptions } from './tx_pool.js';
9
9
 
10
10
  /**
11
11
  * In-memory implementation of the Transaction Pool.
@@ -190,9 +190,7 @@ export class InMemoryTxPool implements TxPool {
190
190
  return Promise.resolve(Array.from(this.txs.keys()).map(x => TxHash.fromBigInt(x)));
191
191
  }
192
192
 
193
- setMaxTxPoolSize(_maxSizeBytes: number | undefined): Promise<void> {
194
- return Promise.resolve();
195
- }
193
+ updateConfig(_config: TxPoolOptions): void {}
196
194
 
197
195
  markTxsAsNonEvictable(_: TxHash[]): Promise<void> {
198
196
  return Promise.resolve();
@@ -1,5 +1,11 @@
1
1
  import type { Tx, TxHash } from '@aztec/stdlib/tx';
2
2
 
3
+ export type TxPoolOptions = {
4
+ maxTxPoolSize?: number;
5
+ txPoolOverflowFactor?: number;
6
+ archivedTxLimit?: number;
7
+ };
8
+
3
9
  /**
4
10
  * Interface of a transaction pool. The pool includes tx requests and is kept up-to-date by a P2P client.
5
11
  */
@@ -95,7 +101,7 @@ export interface TxPool {
95
101
  * Configure the maximum size of the tx pool
96
102
  * @param maxSizeBytes - The maximum size in bytes of the mempool. Set to undefined to disable it
97
103
  */
98
- setMaxTxPoolSize(maxSizeBytes: number | undefined): Promise<void>;
104
+ updateConfig(config: TxPoolOptions): void;
99
105
 
100
106
  /** Returns whether the pool is empty. */
101
107
  isEmpty(): Promise<boolean>;
@@ -0,0 +1,36 @@
1
+ // Implements a queue of message IDs
2
+ export class MessageSeenValidator {
3
+ private queue: Array<string>;
4
+ private writePointer = 0;
5
+ private seenMessages: Set<string> = new Set();
6
+
7
+ constructor(private queueLength: number) {
8
+ if (this.queueLength <= 0) {
9
+ throw new Error('Queue length must be greater than 0');
10
+ }
11
+ this.queue = new Array<string>(this.queueLength);
12
+ }
13
+
14
+ // Adds a message if not seen before. Returns true if added, false if already seen.
15
+ public addMessage(msgId: string): boolean {
16
+ // Check if the message is already in the cache
17
+ if (this.seenMessages.has(msgId)) {
18
+ return false;
19
+ }
20
+ // If we are at the cache limit, remove the oldest msg ID
21
+ if (this.seenMessages.size >= this.queueLength) {
22
+ const msgToRemove = this.queue[this.writePointer];
23
+ this.seenMessages.delete(msgToRemove);
24
+ }
25
+
26
+ // Insert the message into the cache and the queue
27
+ this.seenMessages.add(msgId);
28
+ this.queue[this.writePointer] = msgId;
29
+ this.writePointer = this.writePointer === this.queueLength - 1 ? 0 : this.writePointer + 1;
30
+ return true;
31
+ }
32
+
33
+ public size() {
34
+ return this.seenMessages.size;
35
+ }
36
+ }
@@ -51,7 +51,9 @@ export class DummyP2PService implements P2PService {
51
51
  /**
52
52
  * Register a callback into the validator client for when a block proposal is received
53
53
  */
54
- public registerBlockReceivedCallback(_: (block: BlockProposal) => Promise<BlockAttestation>) {}
54
+ public registerBlockReceivedCallback(
55
+ _callback: (block: BlockProposal, sender: PeerId) => Promise<BlockAttestation>,
56
+ ) {}
55
57
 
56
58
  /**
57
59
  * Sends a request to a peer.
@@ -1,2 +1,3 @@
1
1
  export * from './service.js';
2
2
  export * from './libp2p/libp2p_service.js';
3
+ export * from './tx_collector.js';