@aztec/p2p 0.73.0 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2

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 (220) hide show
  1. package/dest/bootstrap/bootstrap.js +41 -29
  2. package/dest/client/factory.js +10 -12
  3. package/dest/client/index.js +0 -1
  4. package/dest/client/p2p_client.js +513 -507
  5. package/dest/config.js +44 -39
  6. package/dest/errors/reqresp.error.js +6 -10
  7. package/dest/index.js +0 -1
  8. package/dest/mem_pools/attestation_pool/attestation_pool.js +6 -2
  9. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +64 -32
  10. package/dest/mem_pools/attestation_pool/index.js +0 -1
  11. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +22 -19
  12. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +22 -26
  13. package/dest/mem_pools/attestation_pool/mocks.js +10 -6
  14. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js +1 -2
  15. package/dest/mem_pools/epoch_proof_quote_pool/index.js +0 -1
  16. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js +5 -4
  17. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.js +2 -3
  18. package/dest/mem_pools/index.js +1 -2
  19. package/dest/mem_pools/instrumentation.js +37 -42
  20. package/dest/mem_pools/interface.js +3 -2
  21. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +127 -134
  22. package/dest/mem_pools/tx_pool/index.js +0 -1
  23. package/dest/mem_pools/tx_pool/memory_tx_pool.js +45 -43
  24. package/dest/mem_pools/tx_pool/priority.js +1 -3
  25. package/dest/mem_pools/tx_pool/tx_pool.js +3 -2
  26. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +107 -37
  27. package/dest/mocks/index.js +49 -40
  28. package/dest/msg_validators/attestation_validator/attestation_validator.js +3 -3
  29. package/dest/msg_validators/attestation_validator/index.js +0 -1
  30. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +2 -2
  31. package/dest/msg_validators/block_proposal_validator/index.js +0 -1
  32. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.js +2 -2
  33. package/dest/msg_validators/epoch_proof_quote_validator/index.js +0 -1
  34. package/dest/msg_validators/index.js +0 -1
  35. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +9 -11
  36. package/dest/msg_validators/tx_validator/block_header_validator.js +17 -12
  37. package/dest/msg_validators/tx_validator/data_validator.js +41 -32
  38. package/dest/msg_validators/tx_validator/double_spend_validator.js +22 -14
  39. package/dest/msg_validators/tx_validator/index.js +0 -1
  40. package/dest/msg_validators/tx_validator/metadata_validator.js +29 -26
  41. package/dest/msg_validators/tx_validator/tx_proof_validator.js +17 -12
  42. package/dest/services/data_store.js +57 -57
  43. package/dest/services/discv5/discV5_service.js +31 -23
  44. package/dest/services/dummy_service.js +40 -58
  45. package/dest/services/encoding.js +10 -9
  46. package/dest/services/index.js +0 -1
  47. package/dest/services/libp2p/libp2p_service.js +709 -695
  48. package/dest/services/peer-manager/metrics.js +14 -7
  49. package/dest/services/peer-manager/peer_manager.js +340 -342
  50. package/dest/services/peer-manager/peer_scoring.js +20 -18
  51. package/dest/services/reqresp/config.js +4 -5
  52. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +35 -28
  53. package/dest/services/reqresp/connection-sampler/connection_sampler.js +60 -59
  54. package/dest/services/reqresp/index.js +1 -3
  55. package/dest/services/reqresp/interface.js +25 -30
  56. package/dest/services/reqresp/metrics.js +23 -10
  57. package/dest/services/reqresp/protocols/block.js +1 -2
  58. package/dest/services/reqresp/protocols/goodbye.js +35 -40
  59. package/dest/services/reqresp/protocols/index.js +1 -3
  60. package/dest/services/reqresp/protocols/ping.js +1 -3
  61. package/dest/services/reqresp/protocols/status.js +1 -3
  62. package/dest/services/reqresp/protocols/tx.js +5 -8
  63. package/dest/services/reqresp/rate-limiter/index.js +0 -1
  64. package/dest/services/reqresp/rate-limiter/rate_limiter.js +42 -36
  65. package/dest/services/reqresp/rate-limiter/rate_limits.js +16 -17
  66. package/dest/services/reqresp/reqresp.js +461 -395
  67. package/dest/services/reqresp/status.js +51 -0
  68. package/dest/services/service.js +3 -4
  69. package/dest/services/types.js +16 -23
  70. package/dest/util.js +23 -34
  71. package/package.json +8 -8
  72. package/src/client/factory.ts +5 -5
  73. package/src/client/p2p_client.ts +159 -125
  74. package/src/mem_pools/index.ts +3 -3
  75. package/src/mem_pools/instrumentation.ts +3 -2
  76. package/src/mocks/index.ts +2 -2
  77. package/src/services/libp2p/libp2p_service.ts +1 -1
  78. package/src/services/reqresp/interface.ts +11 -0
  79. package/src/services/reqresp/rate-limiter/rate_limiter.ts +3 -1
  80. package/src/services/reqresp/rate-limiter/rate_limits.ts +2 -2
  81. package/src/services/reqresp/reqresp.ts +111 -24
  82. package/src/services/reqresp/status.ts +59 -0
  83. package/dest/bootstrap/bootstrap.d.ts +0 -38
  84. package/dest/bootstrap/bootstrap.d.ts.map +0 -1
  85. package/dest/client/factory.d.ts +0 -19
  86. package/dest/client/factory.d.ts.map +0 -1
  87. package/dest/client/index.d.ts +0 -3
  88. package/dest/client/index.d.ts.map +0 -1
  89. package/dest/client/p2p_client.d.ts +0 -321
  90. package/dest/client/p2p_client.d.ts.map +0 -1
  91. package/dest/config.d.ts +0 -171
  92. package/dest/config.d.ts.map +0 -1
  93. package/dest/errors/reqresp.error.d.ts +0 -28
  94. package/dest/errors/reqresp.error.d.ts.map +0 -1
  95. package/dest/index.d.ts +0 -9
  96. package/dest/index.d.ts.map +0 -1
  97. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +0 -57
  98. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +0 -1
  99. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +0 -3
  100. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +0 -1
  101. package/dest/mem_pools/attestation_pool/index.d.ts +0 -3
  102. package/dest/mem_pools/attestation_pool/index.d.ts.map +0 -1
  103. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -22
  104. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
  105. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -17
  106. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  107. package/dest/mem_pools/attestation_pool/mocks.d.ts +0 -18
  108. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +0 -1
  109. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts +0 -7
  110. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts.map +0 -1
  111. package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts +0 -4
  112. package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts.map +0 -1
  113. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts +0 -12
  114. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts.map +0 -1
  115. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts +0 -8
  116. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts.map +0 -1
  117. package/dest/mem_pools/index.d.ts +0 -5
  118. package/dest/mem_pools/index.d.ts.map +0 -1
  119. package/dest/mem_pools/instrumentation.d.ts +0 -31
  120. package/dest/mem_pools/instrumentation.d.ts.map +0 -1
  121. package/dest/mem_pools/interface.d.ts +0 -13
  122. package/dest/mem_pools/interface.d.ts.map +0 -1
  123. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -66
  124. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  125. package/dest/mem_pools/tx_pool/index.d.ts +0 -4
  126. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  127. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -56
  128. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
  129. package/dest/mem_pools/tx_pool/priority.d.ts +0 -8
  130. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  131. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -66
  132. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  133. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  134. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  135. package/dest/mocks/index.d.ts +0 -54
  136. package/dest/mocks/index.d.ts.map +0 -1
  137. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +0 -8
  138. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +0 -1
  139. package/dest/msg_validators/attestation_validator/index.d.ts +0 -2
  140. package/dest/msg_validators/attestation_validator/index.d.ts.map +0 -1
  141. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -8
  142. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
  143. package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
  144. package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
  145. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts +0 -8
  146. package/dest/msg_validators/epoch_proof_quote_validator/epoch_proof_quote_validator.d.ts.map +0 -1
  147. package/dest/msg_validators/epoch_proof_quote_validator/index.d.ts +0 -2
  148. package/dest/msg_validators/epoch_proof_quote_validator/index.d.ts.map +0 -1
  149. package/dest/msg_validators/index.d.ts +0 -4
  150. package/dest/msg_validators/index.d.ts.map +0 -1
  151. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +0 -7
  152. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +0 -1
  153. package/dest/msg_validators/tx_validator/block_header_validator.d.ts +0 -11
  154. package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +0 -1
  155. package/dest/msg_validators/tx_validator/data_validator.d.ts +0 -6
  156. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +0 -1
  157. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +0 -12
  158. package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +0 -1
  159. package/dest/msg_validators/tx_validator/index.d.ts +0 -7
  160. package/dest/msg_validators/tx_validator/index.d.ts.map +0 -1
  161. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +0 -10
  162. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +0 -1
  163. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +0 -8
  164. package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +0 -1
  165. package/dest/services/data_store.d.ts +0 -27
  166. package/dest/services/data_store.d.ts.map +0 -1
  167. package/dest/services/discv5/discV5_service.d.ts +0 -36
  168. package/dest/services/discv5/discV5_service.d.ts.map +0 -1
  169. package/dest/services/dummy_service.d.ts +0 -82
  170. package/dest/services/dummy_service.d.ts.map +0 -1
  171. package/dest/services/encoding.d.ts +0 -31
  172. package/dest/services/encoding.d.ts.map +0 -1
  173. package/dest/services/index.d.ts +0 -3
  174. package/dest/services/index.d.ts.map +0 -1
  175. package/dest/services/libp2p/libp2p_service.d.ts +0 -225
  176. package/dest/services/libp2p/libp2p_service.d.ts.map +0 -1
  177. package/dest/services/peer-manager/metrics.d.ts +0 -12
  178. package/dest/services/peer-manager/metrics.d.ts.map +0 -1
  179. package/dest/services/peer-manager/peer_manager.d.ts +0 -76
  180. package/dest/services/peer-manager/peer_manager.d.ts.map +0 -1
  181. package/dest/services/peer-manager/peer_scoring.d.ts +0 -28
  182. package/dest/services/peer-manager/peer_scoring.d.ts.map +0 -1
  183. package/dest/services/reqresp/config.d.ts +0 -16
  184. package/dest/services/reqresp/config.d.ts.map +0 -1
  185. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -45
  186. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
  187. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +0 -61
  188. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +0 -1
  189. package/dest/services/reqresp/index.d.ts +0 -6
  190. package/dest/services/reqresp/index.d.ts.map +0 -1
  191. package/dest/services/reqresp/interface.d.ts +0 -107
  192. package/dest/services/reqresp/interface.d.ts.map +0 -1
  193. package/dest/services/reqresp/metrics.d.ts +0 -15
  194. package/dest/services/reqresp/metrics.d.ts.map +0 -1
  195. package/dest/services/reqresp/protocols/block.d.ts +0 -4
  196. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  197. package/dest/services/reqresp/protocols/goodbye.d.ts +0 -51
  198. package/dest/services/reqresp/protocols/goodbye.d.ts.map +0 -1
  199. package/dest/services/reqresp/protocols/index.d.ts +0 -9
  200. package/dest/services/reqresp/protocols/index.d.ts.map +0 -1
  201. package/dest/services/reqresp/protocols/ping.d.ts +0 -9
  202. package/dest/services/reqresp/protocols/ping.d.ts.map +0 -1
  203. package/dest/services/reqresp/protocols/status.d.ts +0 -9
  204. package/dest/services/reqresp/protocols/status.d.ts.map +0 -1
  205. package/dest/services/reqresp/protocols/tx.d.ts +0 -13
  206. package/dest/services/reqresp/protocols/tx.d.ts.map +0 -1
  207. package/dest/services/reqresp/rate-limiter/index.d.ts +0 -2
  208. package/dest/services/reqresp/rate-limiter/index.d.ts.map +0 -1
  209. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +0 -102
  210. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +0 -1
  211. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +0 -3
  212. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +0 -1
  213. package/dest/services/reqresp/reqresp.d.ts +0 -161
  214. package/dest/services/reqresp/reqresp.d.ts.map +0 -1
  215. package/dest/services/service.d.ts +0 -85
  216. package/dest/services/service.d.ts.map +0 -1
  217. package/dest/services/types.d.ts +0 -38
  218. package/dest/services/types.d.ts.map +0 -1
  219. package/dest/util.d.ts +0 -53
  220. package/dest/util.d.ts.map +0 -1
@@ -10,6 +10,7 @@ import {
10
10
  type P2PApi,
11
11
  type P2PClientType,
12
12
  type PeerInfo,
13
+ type ProverCoordination,
13
14
  type Tx,
14
15
  type TxHash,
15
16
  } from '@aztec/circuit-types';
@@ -62,130 +63,131 @@ export interface P2PSyncState {
62
63
  /**
63
64
  * Interface of a P2P client.
64
65
  **/
65
- export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApi<T> & {
66
- /**
67
- * Broadcasts a block proposal to other peers.
68
- *
69
- * @param proposal - the block proposal
70
- */
71
- broadcastProposal(proposal: BlockProposal): void;
72
-
73
- /**
74
- * Queries the EpochProofQuote pool for quotes for the given epoch
75
- *
76
- * @param epoch - the epoch to query
77
- * @returns EpochProofQuotes
78
- */
79
- getEpochProofQuotes(epoch: bigint): Promise<EpochProofQuote[]>;
80
-
81
- /**
82
- * Adds an EpochProofQuote to the pool and broadcasts an EpochProofQuote to other peers.
83
- *
84
- * @param quote - the quote to broadcast
85
- */
86
- addEpochProofQuote(quote: EpochProofQuote): Promise<void>;
87
-
88
- /**
89
- * Registers a callback from the validator client that determines how to behave when
90
- * foreign block proposals are received
91
- *
92
- * @param handler - A function taking a received block proposal and producing an attestation
93
- */
94
- // REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
95
- // ^ This pattern is not my favorite (md)
96
- registerBlockProposalHandler(handler: (block: BlockProposal) => Promise<BlockAttestation | undefined>): void;
97
-
98
- /**
99
- * Request a list of transactions from another peer by their tx hashes.
100
- * @param txHashes - Hashes of the txs to query.
101
- * @returns A list of transactions or undefined if the transactions are not found.
102
- */
103
- requestTxs(txHashes: TxHash[]): Promise<(Tx | undefined)[]>;
104
-
105
- /**
106
- * Request a transaction from another peer by its tx hash.
107
- * @param txHash - Hash of the tx to query.
108
- */
109
- requestTxByHash(txHash: TxHash): Promise<Tx | undefined>;
110
-
111
- /**
112
- * Verifies the 'tx' and, if valid, adds it to local tx pool and forwards it to other peers.
113
- * @param tx - The transaction.
114
- **/
115
- sendTx(tx: Tx): Promise<void>;
116
-
117
- /**
118
- * Deletes 'txs' from the pool, given hashes.
119
- * NOT used if we use sendTx as reconcileTxPool will handle this.
120
- * @param txHashes - Hashes to check.
121
- **/
122
- deleteTxs(txHashes: TxHash[]): Promise<void>;
123
-
124
- /**
125
- * Returns a transaction in the transaction pool by its hash.
126
- * @param txHash - Hash of tx to return.
127
- * @returns A single tx or undefined.
128
- */
129
- getTxByHashFromPool(txHash: TxHash): Promise<Tx | undefined>;
130
-
131
- /**
132
- * Returns a transaction in the transaction pool by its hash, requesting it from the network if it is not found.
133
- * @param txHash - Hash of tx to return.
134
- * @returns A single tx or undefined.
135
- */
136
- getTxByHash(txHash: TxHash): Promise<Tx | undefined>;
137
-
138
- /**
139
- * Returns an archived transaction from the transaction pool by its hash.
140
- * @param txHash - Hash of tx to return.
141
- * @returns A single tx or undefined.
142
- */
143
- getArchivedTxByHash(txHash: TxHash): Promise<Tx | undefined>;
144
-
145
- /**
146
- * Returns whether the given tx hash is flagged as pending or mined.
147
- * @param txHash - Hash of the tx to query.
148
- * @returns Pending or mined depending on its status, or undefined if not found.
149
- */
150
- getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined>;
151
-
152
- /** Returns an iterator over pending txs on the mempool. */
153
- iteratePendingTxs(): AsyncIterableIterator<Tx>;
154
-
155
- /** Returns the number of pending txs in the mempool. */
156
- getPendingTxCount(): Promise<number>;
157
-
158
- /**
159
- * Starts the p2p client.
160
- * @returns A promise signalling the completion of the block sync.
161
- */
162
- start(): Promise<void>;
163
-
164
- /**
165
- * Stops the p2p client.
166
- * @returns A promise signalling the completion of the stop process.
167
- */
168
- stop(): Promise<void>;
169
-
170
- /**
171
- * Indicates if the p2p client is ready for transaction submission.
172
- * @returns A boolean flag indicating readiness.
173
- */
174
- isReady(): boolean;
175
-
176
- /**
177
- * Returns the current status of the p2p client.
178
- */
179
- getStatus(): Promise<P2PSyncState>;
180
-
181
- /**
182
- * Returns the ENR of this node, if any.
183
- */
184
- getEnr(): ENR | undefined;
185
-
186
- /** Identifies a p2p client. */
187
- isP2PClient(): true;
188
- };
66
+ export type P2P<T extends P2PClientType = P2PClientType.Full> = ProverCoordination &
67
+ P2PApi<T> & {
68
+ /**
69
+ * Broadcasts a block proposal to other peers.
70
+ *
71
+ * @param proposal - the block proposal
72
+ */
73
+ broadcastProposal(proposal: BlockProposal): void;
74
+
75
+ /**
76
+ * Queries the EpochProofQuote pool for quotes for the given epoch
77
+ *
78
+ * @param epoch - the epoch to query
79
+ * @returns EpochProofQuotes
80
+ */
81
+ getEpochProofQuotes(epoch: bigint): Promise<EpochProofQuote[]>;
82
+
83
+ /**
84
+ * Adds an EpochProofQuote to the pool and broadcasts an EpochProofQuote to other peers.
85
+ *
86
+ * @param quote - the quote to broadcast
87
+ */
88
+ addEpochProofQuote(quote: EpochProofQuote): Promise<void>;
89
+
90
+ /**
91
+ * Registers a callback from the validator client that determines how to behave when
92
+ * foreign block proposals are received
93
+ *
94
+ * @param handler - A function taking a received block proposal and producing an attestation
95
+ */
96
+ // REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
97
+ // ^ This pattern is not my favorite (md)
98
+ registerBlockProposalHandler(handler: (block: BlockProposal) => Promise<BlockAttestation | undefined>): void;
99
+
100
+ /**
101
+ * Request a list of transactions from another peer by their tx hashes.
102
+ * @param txHashes - Hashes of the txs to query.
103
+ * @returns A list of transactions or undefined if the transactions are not found.
104
+ */
105
+ requestTxs(txHashes: TxHash[]): Promise<(Tx | undefined)[]>;
106
+
107
+ /**
108
+ * Request a transaction from another peer by its tx hash.
109
+ * @param txHash - Hash of the tx to query.
110
+ */
111
+ requestTxByHash(txHash: TxHash): Promise<Tx | undefined>;
112
+
113
+ /**
114
+ * Verifies the 'tx' and, if valid, adds it to local tx pool and forwards it to other peers.
115
+ * @param tx - The transaction.
116
+ **/
117
+ sendTx(tx: Tx): Promise<void>;
118
+
119
+ /**
120
+ * Deletes 'txs' from the pool, given hashes.
121
+ * NOT used if we use sendTx as reconcileTxPool will handle this.
122
+ * @param txHashes - Hashes to check.
123
+ **/
124
+ deleteTxs(txHashes: TxHash[]): Promise<void>;
125
+
126
+ /**
127
+ * Returns a transaction in the transaction pool by its hash.
128
+ * @param txHash - Hash of tx to return.
129
+ * @returns A single tx or undefined.
130
+ */
131
+ getTxByHashFromPool(txHash: TxHash): Promise<Tx | undefined>;
132
+
133
+ /**
134
+ * Returns a transaction in the transaction pool by its hash, requesting it from the network if it is not found.
135
+ * @param txHash - Hash of tx to return.
136
+ * @returns A single tx or undefined.
137
+ */
138
+ getTxByHash(txHash: TxHash): Promise<Tx | undefined>;
139
+
140
+ /**
141
+ * Returns an archived transaction from the transaction pool by its hash.
142
+ * @param txHash - Hash of tx to return.
143
+ * @returns A single tx or undefined.
144
+ */
145
+ getArchivedTxByHash(txHash: TxHash): Promise<Tx | undefined>;
146
+
147
+ /**
148
+ * Returns whether the given tx hash is flagged as pending or mined.
149
+ * @param txHash - Hash of the tx to query.
150
+ * @returns Pending or mined depending on its status, or undefined if not found.
151
+ */
152
+ getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined>;
153
+
154
+ /** Returns an iterator over pending txs on the mempool. */
155
+ iteratePendingTxs(): AsyncIterableIterator<Tx>;
156
+
157
+ /** Returns the number of pending txs in the mempool. */
158
+ getPendingTxCount(): Promise<number>;
159
+
160
+ /**
161
+ * Starts the p2p client.
162
+ * @returns A promise signalling the completion of the block sync.
163
+ */
164
+ start(): Promise<void>;
165
+
166
+ /**
167
+ * Stops the p2p client.
168
+ * @returns A promise signalling the completion of the stop process.
169
+ */
170
+ stop(): Promise<void>;
171
+
172
+ /**
173
+ * Indicates if the p2p client is ready for transaction submission.
174
+ * @returns A boolean flag indicating readiness.
175
+ */
176
+ isReady(): boolean;
177
+
178
+ /**
179
+ * Returns the current status of the p2p client.
180
+ */
181
+ getStatus(): Promise<P2PSyncState>;
182
+
183
+ /**
184
+ * Returns the ENR of this node, if any.
185
+ */
186
+ getEnr(): ENR | undefined;
187
+
188
+ /** Identifies a p2p client. */
189
+ isP2PClient(): true;
190
+ };
189
191
 
190
192
  /**
191
193
  * The P2P client implementation.
@@ -467,6 +469,17 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
467
469
  return tx;
468
470
  }
469
471
 
472
+ /**
473
+ * Uses the batched Request Response protocol to request a set of transactions from the network.
474
+ */
475
+ public async requestTxsByHash(txHashes: TxHash[]): Promise<Tx[]> {
476
+ const txs = (await this.p2pService.sendBatchRequest(ReqRespSubProtocol.TX, txHashes)) ?? [];
477
+ await this.txPool.addTxs(txs);
478
+ const txHashesStr = txHashes.map(tx => tx.toString()).join(', ');
479
+ this.log.debug(`Received batched txs ${txHashesStr} (${txs.length} / ${txHashes.length}}) from peers`);
480
+ return txs as Tx[];
481
+ }
482
+
470
483
  public getPendingTxs(): Promise<Tx[]> {
471
484
  return Promise.resolve(this.getTxs('pending'));
472
485
  }
@@ -529,6 +542,27 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
529
542
  return this.requestTxByHash(txHash);
530
543
  }
531
544
 
545
+ /**
546
+ * Returns transactions in the transaction pool by hash.
547
+ * If a transaction is not in the pool, it will be requested from the network.
548
+ * @param txHashes - Hashes of the transactions to look for.
549
+ * @returns The txs found, not necessarily on the same order as the hashes.
550
+ */
551
+ async getTxsByHash(txHashes: TxHash[]): Promise<Tx[]> {
552
+ const txs = await Promise.all(txHashes.map(txHash => this.txPool.getTxByHash(txHash)));
553
+ const missingTxHashes = txs
554
+ .map((tx, index) => [tx, index] as const)
555
+ .filter(([tx, _index]) => !tx)
556
+ .map(([_tx, index]) => txHashes[index]);
557
+
558
+ if (missingTxHashes.length === 0) {
559
+ return txs as Tx[];
560
+ }
561
+
562
+ const missingTxs = await this.requestTxsByHash(missingTxHashes);
563
+ return txs.filter((tx): tx is Tx => !!tx).concat(missingTxs);
564
+ }
565
+
532
566
  /**
533
567
  * Returns an archived transaction in the transaction pool by its hash.
534
568
  * @param txHash - Hash of the archived transaction to look for.
@@ -662,7 +696,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
662
696
  blocks.map(async block => this.synchedBlockHashes.set(block.number, (await block.hash()).toString())),
663
697
  );
664
698
  await this.synchedLatestBlockNumber.set(lastBlockNum);
665
- this.log.debug(`Synched to latest block ${lastBlockNum}`);
699
+ this.log.verbose(`Synched to latest block ${lastBlockNum}`);
666
700
  await this.startServiceIfSynched();
667
701
  }
668
702
 
@@ -1,4 +1,4 @@
1
- export { TxPool } from './tx_pool/tx_pool.js';
2
- export { AttestationPool } from './attestation_pool/attestation_pool.js';
3
- export { EpochProofQuotePool } from './epoch_proof_quote_pool/epoch_proof_quote_pool.js';
1
+ export type { TxPool } from './tx_pool/tx_pool.js';
2
+ export type { AttestationPool } from './attestation_pool/attestation_pool.js';
3
+ export type { EpochProofQuotePool } from './epoch_proof_quote_pool/epoch_proof_quote_pool.js';
4
4
  export { type MemPools } from './interface.js';
@@ -5,6 +5,7 @@ import {
5
5
  LmdbMetrics,
6
6
  type LmdbStatsCallback,
7
7
  Metrics,
8
+ type MetricsType,
8
9
  type TelemetryClient,
9
10
  type UpDownCounter,
10
11
  } from '@aztec/telemetry-client';
@@ -16,8 +17,8 @@ export enum PoolName {
16
17
  }
17
18
 
18
19
  type MetricsLabels = {
19
- objectInMempool: Metrics;
20
- objectSize: Metrics;
20
+ objectInMempool: MetricsType;
21
+ objectSize: MetricsType;
21
22
  };
22
23
 
23
24
  /**
@@ -8,7 +8,7 @@ import {
8
8
  import { type EpochCache } from '@aztec/epoch-cache';
9
9
  import { timesParallel } from '@aztec/foundation/collection';
10
10
  import { type DataStoreConfig } from '@aztec/kv-store/config';
11
- import { openTmpStore } from '@aztec/kv-store/lmdb';
11
+ import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
12
12
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
13
13
 
14
14
  import { gossipsub } from '@chainsafe/libp2p-gossipsub';
@@ -263,7 +263,7 @@ export async function createBootstrapNode(
263
263
 
264
264
  async function startBootstrapNode(config: BootnodeConfig, telemetry: TelemetryClient) {
265
265
  // Open an ephemeral store that will only exist in memory
266
- const store = openTmpStore(true);
266
+ const store = await openTmpStore('bootstrap-node', true);
267
267
  const bootstrapNode = new BootstrapNode(store, telemetry);
268
268
  await bootstrapNode.start(config);
269
269
  return bootstrapNode;
@@ -584,7 +584,7 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
584
584
  }
585
585
 
586
586
  private async processTxFromPeer(tx: Tx): Promise<void> {
587
- const txHash = tx.getTxHash();
587
+ const txHash = await tx.getTxHash();
588
588
  const txHashString = txHash.toString();
589
589
  this.logger.verbose(`Received tx ${txHashString} from external peer.`);
590
590
  await this.mempools.txPool.addTxs([tx]);
@@ -3,6 +3,8 @@ import { Fr } from '@aztec/foundation/fields';
3
3
 
4
4
  import { type PeerId } from '@libp2p/interface';
5
5
 
6
+ import { type ReqRespStatus } from './status.js';
7
+
6
8
  /*
7
9
  * Request Response Sub Protocols
8
10
  */
@@ -31,6 +33,15 @@ export type ReqRespSubProtocolHandler = (peerId: PeerId, msg: Buffer) => Promise
31
33
  */
32
34
  export type ReqRespSubProtocolRateLimits = Record<ReqRespSubProtocol, ProtocolRateLimitQuota>;
33
35
 
36
+ /**
37
+ * The response from the ReqResp protocol
38
+ * Consists of a status (Error code) and data
39
+ */
40
+ export interface ReqRespResponse {
41
+ status: ReqRespStatus;
42
+ data: Buffer;
43
+ }
44
+
34
45
  /**
35
46
  * A rate limit quota
36
47
  */
@@ -200,9 +200,11 @@ export class RequestResponseRateLimiter {
200
200
 
201
201
  switch (rateLimitStatus) {
202
202
  case RateLimitStatus.DeniedPeer:
203
- this.peerScoring.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
203
+ // Hitting a peer specific limit, we should lightly penalise the peer
204
+ this.peerScoring.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
204
205
  return false;
205
206
  case RateLimitStatus.DeniedGlobal:
207
+ // Hitting a global limit, we should not penalise the peer
206
208
  return false;
207
209
  default:
208
210
  return true;
@@ -25,11 +25,11 @@ export const DEFAULT_RATE_LIMITS: ReqRespSubProtocolRateLimits = {
25
25
  [ReqRespSubProtocol.TX]: {
26
26
  peerLimit: {
27
27
  quotaTimeMs: 1000,
28
- quotaCount: 5,
28
+ quotaCount: 10,
29
29
  },
30
30
  globalLimit: {
31
31
  quotaTimeMs: 1000,
32
- quotaCount: 10,
32
+ quotaCount: 20,
33
33
  },
34
34
  },
35
35
  [ReqRespSubProtocol.BLOCK]: {
@@ -22,7 +22,8 @@ import { ConnectionSampler } from './connection-sampler/connection_sampler.js';
22
22
  import {
23
23
  DEFAULT_SUB_PROTOCOL_HANDLERS,
24
24
  DEFAULT_SUB_PROTOCOL_VALIDATORS,
25
- type ReqRespSubProtocol,
25
+ type ReqRespResponse,
26
+ ReqRespSubProtocol,
26
27
  type ReqRespSubProtocolHandlers,
27
28
  type ReqRespSubProtocolValidators,
28
29
  type SubProtocolMap,
@@ -30,6 +31,7 @@ import {
30
31
  } from './interface.js';
31
32
  import { ReqRespMetrics } from './metrics.js';
32
33
  import { RequestResponseRateLimiter } from './rate-limiter/rate_limiter.js';
34
+ import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqRespStatus } from './status.js';
33
35
 
34
36
  /**
35
37
  * The Request Response Service
@@ -190,10 +192,17 @@ export class ReqResp {
190
192
  this.logger.trace(`Sending request to peer: ${peer.toString()}`);
191
193
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffer);
192
194
 
195
+ if (response && response.status !== ReqRespStatus.SUCCESS) {
196
+ this.logger.debug(
197
+ `Request to peer ${peer.toString()} failed with status ${prettyPrintReqRespStatus(response.status)}`,
198
+ );
199
+ continue;
200
+ }
201
+
193
202
  // If we get a response, return it, otherwise we iterate onto the next peer
194
203
  // We do not consider it a success if we have an empty buffer
195
- if (response && response.length > 0) {
196
- const object = subProtocolMap[subProtocol].response.fromBuffer(response);
204
+ if (response && response.data.length > 0) {
205
+ const object = subProtocolMap[subProtocol].response.fromBuffer(response.data);
197
206
  // The response validator handles peer punishment within
198
207
  const isValid = await responseValidator(request, object, peer);
199
208
  if (!isValid) {
@@ -311,8 +320,22 @@ export class ReqResp {
311
320
  for (const index of indices) {
312
321
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffers[index]);
313
322
 
314
- if (response && response.length > 0) {
315
- const object = subProtocolMap[subProtocol].response.fromBuffer(response);
323
+ // Check the status of the response buffer
324
+ if (response && response.status !== ReqRespStatus.SUCCESS) {
325
+ this.logger.debug(
326
+ `Request to peer ${peer.toString()} failed with status ${prettyPrintReqRespStatus(
327
+ response.status,
328
+ )}`,
329
+ );
330
+
331
+ // If we hit a rate limit or some failure, we remove the peer and return the results,
332
+ // they will be split among remaining peers and the new sampled peer
333
+ batchSampler.removePeerAndReplace(peer);
334
+ return { peer, results: peerResults };
335
+ }
336
+
337
+ if (response && response.data.length > 0) {
338
+ const object = subProtocolMap[subProtocol].response.fromBuffer(response.data);
316
339
  const isValid = await responseValidator(requests[index], object, peer);
317
340
 
318
341
  if (isValid) {
@@ -394,7 +417,7 @@ export class ReqResp {
394
417
  peerId: PeerId,
395
418
  subProtocol: ReqRespSubProtocol,
396
419
  payload: Buffer,
397
- ): Promise<Buffer | undefined> {
420
+ ): Promise<ReqRespResponse | undefined> {
398
421
  let stream: Stream | undefined;
399
422
  try {
400
423
  this.metrics.recordRequestSent(subProtocol);
@@ -402,8 +425,8 @@ export class ReqResp {
402
425
  stream = await this.connectionSampler.dialProtocol(peerId, subProtocol);
403
426
 
404
427
  // Open the stream with a timeout
405
- const result = await executeTimeout<Buffer>(
406
- (): Promise<Buffer> => pipe([payload], stream!, this.readMessage.bind(this)),
428
+ const result = await executeTimeout<ReqRespResponse>(
429
+ (): Promise<ReqRespResponse> => pipe([payload], stream!, this.readMessage.bind(this)),
407
430
  this.individualRequestTimeoutMs,
408
431
  () => new IndividualReqRespTimeoutError(),
409
432
  );
@@ -447,7 +470,15 @@ export class ReqResp {
447
470
  * Categorize the error and log it.
448
471
  */
449
472
  private categorizeError(e: any, peerId: PeerId, subProtocol: ReqRespSubProtocol): PeerErrorSeverity | undefined {
450
- // Non pubishable errors
473
+ // Non punishable errors - we do not expect a response for goodbye messages
474
+ if (subProtocol === ReqRespSubProtocol.GOODBYE) {
475
+ this.logger.debug('Error encountered on goodbye sub protocol, no penalty', {
476
+ peerId: peerId.toString(),
477
+ subProtocol,
478
+ });
479
+ return undefined;
480
+ }
481
+
451
482
  // We do not punish a collective timeout, as the node triggers this interupt, independent of the peer's behaviour
452
483
  const logTags = {
453
484
  peerId: peerId.toString(),
@@ -492,14 +523,45 @@ export class ReqResp {
492
523
 
493
524
  /**
494
525
  * Read a message returned from a stream into a single buffer
526
+ *
527
+ * The message is split into two components
528
+ * - The first chunk should contain a control byte, indicating the status of the response see `ReqRespStatus`
529
+ * - The second chunk should contain the response data
495
530
  */
496
- private async readMessage(source: AsyncIterable<Uint8ArrayList>): Promise<Buffer> {
531
+ private async readMessage(source: AsyncIterable<Uint8ArrayList>): Promise<ReqRespResponse> {
532
+ let statusBuffer: ReqRespStatus | undefined;
497
533
  const chunks: Uint8Array[] = [];
498
- for await (const chunk of source) {
499
- chunks.push(chunk.subarray());
534
+
535
+ try {
536
+ for await (const chunk of source) {
537
+ if (statusBuffer === undefined) {
538
+ const firstChunkBuffer = chunk.subarray();
539
+ statusBuffer = parseStatusChunk(firstChunkBuffer);
540
+ } else {
541
+ chunks.push(chunk.subarray());
542
+ }
543
+ }
544
+
545
+ const messageData = Buffer.concat(chunks);
546
+ const message: Buffer = this.snappyTransform.inboundTransformNoTopic(messageData);
547
+
548
+ return {
549
+ status: statusBuffer ?? ReqRespStatus.UNKNOWN,
550
+ data: message,
551
+ };
552
+ } catch (e: any) {
553
+ this.logger.debug(`Reading message failed: ${e.message}`);
554
+
555
+ let status = ReqRespStatus.UNKNOWN;
556
+ if (e instanceof ReqRespStatusError) {
557
+ status = e.status;
558
+ }
559
+
560
+ return {
561
+ status,
562
+ data: Buffer.from([]),
563
+ };
500
564
  }
501
- const messageData = Buffer.concat(chunks);
502
- return this.snappyTransform.inboundTransformNoTopic(messageData);
503
565
  }
504
566
 
505
567
  /**
@@ -525,25 +587,28 @@ export class ReqResp {
525
587
  private async streamHandler(protocol: ReqRespSubProtocol, { stream, connection }: IncomingStreamData) {
526
588
  this.metrics.recordRequestReceived(protocol);
527
589
 
528
- // Store a reference to from this for the async generator
529
- if (!this.rateLimiter.allow(protocol, connection.remotePeer)) {
530
- this.logger.warn(`Rate limit exceeded for ${protocol} from ${connection.remotePeer}`);
590
+ try {
591
+ // Store a reference to from this for the async generator
592
+ if (!this.rateLimiter.allow(protocol, connection.remotePeer)) {
593
+ this.logger.warn(`Rate limit exceeded for ${protocol} from ${connection.remotePeer}`);
531
594
 
532
- // TODO(#8483): handle changing peer scoring for failed rate limit, maybe differentiate between global and peer limits here when punishing
533
- await stream.close();
534
- return;
535
- }
595
+ throw new ReqRespStatusError(ReqRespStatus.RATE_LIMIT_EXCEEDED);
596
+ }
536
597
 
537
- const handler = this.subProtocolHandlers[protocol];
538
- const transform = this.snappyTransform;
598
+ const handler = this.subProtocolHandlers[protocol];
599
+ const transform = this.snappyTransform;
539
600
 
540
- try {
541
601
  await pipe(
542
602
  stream,
543
603
  async function* (source: any) {
544
604
  for await (const chunkList of source) {
545
605
  const msg = Buffer.from(chunkList.subarray());
546
606
  const response = await handler(connection.remotePeer, msg);
607
+
608
+ // Send success code first, then the response
609
+ const successChunk = Buffer.from([ReqRespStatus.SUCCESS]);
610
+ yield new Uint8Array(successChunk);
611
+
547
612
  yield new Uint8Array(transform.outboundTransformNoTopic(response));
548
613
  }
549
614
  },
@@ -552,8 +617,30 @@ export class ReqResp {
552
617
  } catch (e: any) {
553
618
  this.logger.warn(e);
554
619
  this.metrics.recordResponseError(protocol);
620
+
621
+ // If we receive a known error, we use the error status in the response chunk, otherwise we categorize as unknown
622
+ let errorStatus = ReqRespStatus.UNKNOWN;
623
+ if (e instanceof ReqRespStatusError) {
624
+ errorStatus = e.status;
625
+ }
626
+
627
+ const sendErrorChunk = this.sendErrorChunk(errorStatus);
628
+
629
+ // Return and yield the response chunk
630
+ await pipe(
631
+ stream,
632
+ async function* (_source: any) {
633
+ yield* sendErrorChunk;
634
+ },
635
+ stream,
636
+ );
555
637
  } finally {
556
638
  await stream.close();
557
639
  }
558
640
  }
641
+
642
+ private async *sendErrorChunk(error: ReqRespStatus): AsyncIterable<Uint8Array> {
643
+ const errorChunk = Buffer.from([error]);
644
+ yield new Uint8Array(errorChunk);
645
+ }
559
646
  }