@aztec/p2p 0.0.1-commit.8c0b8ff → 0.0.1-commit.8cb2d04d8

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 (270) hide show
  1. package/dest/client/factory.d.ts +2 -2
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +1 -0
  4. package/dest/client/interface.d.ts +9 -2
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +3 -2
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +30 -8
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +17 -6
  10. package/dest/config.d.ts +107 -103
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +17 -12
  13. package/dest/errors/p2p-service.error.d.ts +9 -0
  14. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  15. package/dest/errors/p2p-service.error.js +10 -0
  16. package/dest/index.d.ts +1 -2
  17. package/dest/index.d.ts.map +1 -1
  18. package/dest/index.js +0 -1
  19. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +7 -5
  20. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/attestation_pool.js +16 -9
  22. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  23. package/dest/mem_pools/index.d.ts +1 -2
  24. package/dest/mem_pools/index.d.ts.map +1 -1
  25. package/dest/mem_pools/instrumentation.d.ts +4 -2
  26. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  27. package/dest/mem_pools/instrumentation.js +16 -14
  28. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  29. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +7 -5
  30. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/interfaces.js +1 -0
  32. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -6
  33. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +6 -2
  35. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  36. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -43
  38. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +1 -1
  39. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +3 -0
  41. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +2 -1
  42. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +18 -1
  44. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +5 -2
  45. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  46. package/dest/msg_validators/attestation_validator/attestation_validator.js +20 -11
  47. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -2
  48. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  49. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  50. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  51. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  52. package/dest/msg_validators/clock_tolerance.js +54 -3
  53. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +2 -1
  54. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  55. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +2 -1
  56. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  57. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +3 -1
  58. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  59. package/dest/msg_validators/proposal_validator/proposal_validator.js +19 -11
  60. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  61. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  62. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  63. package/dest/msg_validators/tx_validator/gas_validator.js +11 -9
  64. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  65. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  66. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  67. package/dest/services/data_store.d.ts +1 -1
  68. package/dest/services/data_store.d.ts.map +1 -1
  69. package/dest/services/data_store.js +5 -5
  70. package/dest/services/dummy_service.d.ts +6 -3
  71. package/dest/services/dummy_service.d.ts.map +1 -1
  72. package/dest/services/dummy_service.js +6 -1
  73. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  74. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  75. package/dest/services/gossipsub/topic_score_params.js +21 -4
  76. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  77. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  78. package/dest/services/libp2p/instrumentation.js +14 -0
  79. package/dest/services/libp2p/libp2p_service.d.ts +15 -25
  80. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  81. package/dest/services/libp2p/libp2p_service.js +150 -115
  82. package/dest/services/peer-manager/metrics.d.ts +3 -1
  83. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  84. package/dest/services/peer-manager/metrics.js +6 -0
  85. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  86. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  87. package/dest/services/peer-manager/peer_manager.js +39 -11
  88. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  89. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  90. package/dest/services/peer-manager/peer_scoring.js +32 -10
  91. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
  92. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  93. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +82 -101
  94. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
  95. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  96. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
  97. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  98. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
  99. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -11
  100. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  101. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
  102. package/dest/services/reqresp/config.d.ts +3 -3
  103. package/dest/services/reqresp/config.d.ts.map +1 -1
  104. package/dest/services/reqresp/interface.d.ts +14 -9
  105. package/dest/services/reqresp/interface.d.ts.map +1 -1
  106. package/dest/services/reqresp/interface.js +10 -11
  107. package/dest/services/reqresp/metrics.d.ts +1 -1
  108. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  109. package/dest/services/reqresp/metrics.js +0 -1
  110. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  111. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  112. package/dest/services/reqresp/protocols/index.js +0 -1
  113. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  114. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  115. package/dest/services/reqresp/protocols/tx.js +1 -3
  116. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  117. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  118. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  119. package/dest/services/reqresp/reqresp.d.ts +4 -2
  120. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  121. package/dest/services/reqresp/reqresp.js +13 -3
  122. package/dest/services/service.d.ts +5 -2
  123. package/dest/services/service.d.ts.map +1 -1
  124. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
  125. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  126. package/dest/services/tx_collection/fast_tx_collection.js +57 -73
  127. package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
  128. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  129. package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
  130. package/dest/services/tx_collection/request_tracker.d.ts +53 -0
  131. package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
  132. package/dest/services/tx_collection/request_tracker.js +84 -0
  133. package/dest/services/tx_collection/slow_tx_collection.js +1 -1
  134. package/dest/services/tx_collection/tx_collection.d.ts +3 -6
  135. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  136. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  137. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  138. package/dest/test-helpers/mock-pubsub.d.ts +11 -3
  139. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  140. package/dest/test-helpers/mock-pubsub.js +35 -10
  141. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  142. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  143. package/dest/test-helpers/reqresp-nodes.js +1 -2
  144. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  145. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  146. package/dest/test-helpers/testbench-utils.js +21 -2
  147. package/dest/testbench/p2p_client_testbench_worker.js +66 -15
  148. package/dest/testbench/worker_client_manager.d.ts +8 -1
  149. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  150. package/dest/testbench/worker_client_manager.js +51 -2
  151. package/dest/util.d.ts +1 -1
  152. package/package.json +14 -14
  153. package/src/client/factory.ts +2 -1
  154. package/src/client/interface.ts +9 -1
  155. package/src/client/p2p_client.ts +34 -9
  156. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -9
  157. package/src/config.ts +29 -17
  158. package/src/errors/p2p-service.error.ts +11 -0
  159. package/src/index.ts +0 -1
  160. package/src/mem_pools/attestation_pool/attestation_pool.ts +17 -12
  161. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  162. package/src/mem_pools/index.ts +0 -3
  163. package/src/mem_pools/instrumentation.ts +17 -13
  164. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  165. package/src/mem_pools/tx_pool_v2/interfaces.ts +7 -4
  166. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +12 -6
  167. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
  168. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +3 -0
  169. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +19 -1
  170. package/src/msg_validators/attestation_validator/README.md +1 -1
  171. package/src/msg_validators/attestation_validator/attestation_validator.ts +21 -9
  172. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -1
  173. package/src/msg_validators/clock_tolerance.ts +72 -3
  174. package/src/msg_validators/proposal_validator/README.md +4 -4
  175. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +4 -1
  176. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +4 -1
  177. package/src/msg_validators/proposal_validator/proposal_validator.ts +17 -10
  178. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  179. package/src/msg_validators/tx_validator/gas_validator.ts +25 -9
  180. package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
  181. package/src/services/data_store.ts +5 -13
  182. package/src/services/dummy_service.ts +8 -2
  183. package/src/services/gossipsub/topic_score_params.ts +36 -4
  184. package/src/services/libp2p/instrumentation.ts +14 -0
  185. package/src/services/libp2p/libp2p_service.ts +146 -130
  186. package/src/services/peer-manager/metrics.ts +7 -0
  187. package/src/services/peer-manager/peer_manager.ts +45 -11
  188. package/src/services/peer-manager/peer_scoring.ts +27 -5
  189. package/src/services/reqresp/batch-tx-requester/README.md +46 -7
  190. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +78 -111
  191. package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
  192. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
  193. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
  194. package/src/services/reqresp/config.ts +2 -2
  195. package/src/services/reqresp/interface.ts +21 -11
  196. package/src/services/reqresp/metrics.ts +0 -1
  197. package/src/services/reqresp/protocols/index.ts +0 -1
  198. package/src/services/reqresp/protocols/tx.ts +1 -3
  199. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  200. package/src/services/reqresp/reqresp.ts +21 -2
  201. package/src/services/service.ts +6 -1
  202. package/src/services/tx_collection/fast_tx_collection.ts +57 -83
  203. package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
  204. package/src/services/tx_collection/request_tracker.ts +127 -0
  205. package/src/services/tx_collection/slow_tx_collection.ts +1 -1
  206. package/src/services/tx_collection/tx_collection.ts +3 -5
  207. package/src/test-helpers/make-test-p2p-clients.ts +1 -1
  208. package/src/test-helpers/mock-pubsub.ts +31 -5
  209. package/src/test-helpers/reqresp-nodes.ts +3 -3
  210. package/src/test-helpers/testbench-utils.ts +29 -3
  211. package/src/testbench/p2p_client_testbench_worker.ts +71 -15
  212. package/src/testbench/worker_client_manager.ts +57 -2
  213. package/src/util.ts +1 -1
  214. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  215. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  216. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  217. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  218. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  219. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  220. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  221. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  222. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  223. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  224. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  225. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  226. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  227. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  228. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  229. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  230. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  231. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  232. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  233. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  234. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  235. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  236. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  237. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  238. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  239. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  240. package/dest/mem_pools/tx_pool/index.js +0 -2
  241. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  242. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  243. package/dest/mem_pools/tx_pool/priority.js +0 -15
  244. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  245. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  246. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  247. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  248. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  249. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  250. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  251. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  252. package/dest/services/reqresp/protocols/block.js +0 -32
  253. package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
  254. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
  255. package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
  256. package/src/mem_pools/tx_pool/README.md +0 -270
  257. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  258. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  259. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  260. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  261. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  262. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  263. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  264. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  265. package/src/mem_pools/tx_pool/index.ts +0 -2
  266. package/src/mem_pools/tx_pool/priority.ts +0 -20
  267. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  268. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  269. package/src/services/reqresp/protocols/block.ts +0 -37
  270. package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
@@ -37,7 +37,6 @@ class WorkerClientManager {
37
37
  destroy() {
38
38
  this.cleanup().catch((error)=>{
39
39
  this.logger.error('Failed to cleanup worker client manager', error);
40
- process.exit(1);
41
40
  });
42
41
  }
43
42
  /**
@@ -318,6 +317,55 @@ class WorkerClientManager {
318
317
  this.logger.info('All worker processes cleaned up');
319
318
  }
320
319
  /**
320
+ * Checks that the aggregator (client 0) has sufficient peer connections before running a benchmark.
321
+ * This prevents benchmark cases from starting with degraded connectivity after a previous case
322
+ * caused connection failures.
323
+ */ async waitForConnectivity(minPeers, timeoutMs = 15_000) {
324
+ const waitInterval = 1000;
325
+ let waited = 0;
326
+ while(waited < timeoutMs){
327
+ const count = await this.getPeerCount(0, 5000);
328
+ if (count >= minPeers) {
329
+ this.logger.info(`Connectivity check passed: ${count}/${minPeers} peers connected`);
330
+ return count;
331
+ }
332
+ this.logger.debug(`Waiting for connectivity: ${count}/${minPeers} (waited ${waited}ms)`);
333
+ await sleep(waitInterval);
334
+ waited += waitInterval;
335
+ }
336
+ const finalCount = await this.getPeerCount(0, 5000);
337
+ this.logger.warn(`Connectivity check: only ${finalCount}/${minPeers} peers after ${timeoutMs}ms`);
338
+ return finalCount;
339
+ }
340
+ getPeerCount(clientIndex, timeoutMs) {
341
+ return new Promise((resolve)=>{
342
+ let resolved = false;
343
+ const handler = (msg)=>{
344
+ if (resolved) {
345
+ return;
346
+ }
347
+ if (msg.type === 'PEER_COUNT') {
348
+ resolved = true;
349
+ clearTimeout(timeout);
350
+ this.processes[clientIndex].off('message', handler);
351
+ resolve(msg.count);
352
+ }
353
+ };
354
+ const timeout = setTimeout(()=>{
355
+ if (resolved) {
356
+ return;
357
+ }
358
+ resolved = true;
359
+ this.processes[clientIndex].off('message', handler);
360
+ resolve(0);
361
+ }, timeoutMs);
362
+ this.processes[clientIndex].on('message', handler);
363
+ this.processes[clientIndex].send({
364
+ type: 'GET_PEER_COUNT'
365
+ });
366
+ });
367
+ }
368
+ /**
321
369
  * Run a req/resp benchmark across all worker clients.
322
370
  *
323
371
  * This sends a BENCH_REQRESP command to all workers:
@@ -371,7 +419,8 @@ class WorkerClientManager {
371
419
  seed
372
420
  };
373
421
  this.processes[0].send(aggregatorCmd);
374
- const result = await this.waitForBenchResult(0, config.timeoutMs + 30000);
422
+ const aggregatorBudgetMs = config.timeoutMs + BENCHMARK_CONSTANTS.MAX_PEER_WAIT_MS + 30000;
423
+ const result = await this.waitForBenchResult(0, aggregatorBudgetMs);
375
424
  this.logger.info(`Benchmark complete: fetched=${result.fetchedCount}/${config.txCount}, duration=${result.durationMs.toFixed(0)}ms, success=${result.success}`);
376
425
  return {
377
426
  txCount: config.txCount,
package/dest/util.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { SecretValue } from '@aztec/foundation/config';
2
2
  import type { Logger } from '@aztec/foundation/log';
3
3
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
4
- import type { DataStoreConfig } from '@aztec/kv-store/config';
4
+ import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
5
5
  import type { GossipSub } from '@chainsafe/libp2p-gossipsub';
6
6
  import type { Identify } from '@libp2p/identify';
7
7
  import type { PeerId } from '@libp2p/interface';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.0.1-commit.8c0b8ff",
3
+ "version": "0.0.1-commit.8cb2d04d8",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -67,17 +67,17 @@
67
67
  ]
68
68
  },
69
69
  "dependencies": {
70
- "@aztec/constants": "0.0.1-commit.8c0b8ff",
71
- "@aztec/epoch-cache": "0.0.1-commit.8c0b8ff",
72
- "@aztec/ethereum": "0.0.1-commit.8c0b8ff",
73
- "@aztec/foundation": "0.0.1-commit.8c0b8ff",
74
- "@aztec/kv-store": "0.0.1-commit.8c0b8ff",
75
- "@aztec/noir-contracts.js": "0.0.1-commit.8c0b8ff",
76
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.8c0b8ff",
77
- "@aztec/protocol-contracts": "0.0.1-commit.8c0b8ff",
78
- "@aztec/simulator": "0.0.1-commit.8c0b8ff",
79
- "@aztec/stdlib": "0.0.1-commit.8c0b8ff",
80
- "@aztec/telemetry-client": "0.0.1-commit.8c0b8ff",
70
+ "@aztec/constants": "0.0.1-commit.8cb2d04d8",
71
+ "@aztec/epoch-cache": "0.0.1-commit.8cb2d04d8",
72
+ "@aztec/ethereum": "0.0.1-commit.8cb2d04d8",
73
+ "@aztec/foundation": "0.0.1-commit.8cb2d04d8",
74
+ "@aztec/kv-store": "0.0.1-commit.8cb2d04d8",
75
+ "@aztec/noir-contracts.js": "0.0.1-commit.8cb2d04d8",
76
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.8cb2d04d8",
77
+ "@aztec/protocol-contracts": "0.0.1-commit.8cb2d04d8",
78
+ "@aztec/simulator": "0.0.1-commit.8cb2d04d8",
79
+ "@aztec/stdlib": "0.0.1-commit.8cb2d04d8",
80
+ "@aztec/telemetry-client": "0.0.1-commit.8cb2d04d8",
81
81
  "@chainsafe/libp2p-gossipsub": "13.0.0",
82
82
  "@chainsafe/libp2p-noise": "^15.0.0",
83
83
  "@chainsafe/libp2p-yamux": "^6.0.2",
@@ -104,8 +104,8 @@
104
104
  "xxhash-wasm": "^1.1.0"
105
105
  },
106
106
  "devDependencies": {
107
- "@aztec/archiver": "0.0.1-commit.8c0b8ff",
108
- "@aztec/world-state": "0.0.1-commit.8c0b8ff",
107
+ "@aztec/archiver": "0.0.1-commit.8cb2d04d8",
108
+ "@aztec/world-state": "0.0.1-commit.8cb2d04d8",
109
109
  "@jest/globals": "^30.0.0",
110
110
  "@types/jest": "^30.0.0",
111
111
  "@types/node": "^22.15.17",
@@ -3,12 +3,12 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
4
  import { DateProvider } from '@aztec/foundation/timer';
5
5
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
6
- import type { DataStoreConfig } from '@aztec/kv-store/config';
7
6
  import { AztecLMDBStoreV2, createStore } from '@aztec/kv-store/lmdb-v2';
8
7
  import type { L2BlockSource } from '@aztec/stdlib/block';
9
8
  import type { ChainConfig } from '@aztec/stdlib/config';
10
9
  import type { ContractDataSource } from '@aztec/stdlib/contract';
11
10
  import type { AztecNode, ClientProtocolCircuitVerifier, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
11
+ import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
12
12
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
13
13
 
14
14
  import { P2PClient } from '../client/p2p_client.js';
@@ -123,6 +123,7 @@ export async function createP2PClient(
123
123
  maxPendingTxCount: config.maxPendingTxCount,
124
124
  archivedTxLimit: config.archivedTxLimit,
125
125
  minTxPoolAgeMs: config.minTxPoolAgeMs,
126
+ dropTransactionsProbability: config.dropTransactionsProbability,
126
127
  priceBumpPercentage: config.priceBumpPercentage,
127
128
  },
128
129
  dateProvider,
@@ -82,7 +82,15 @@ export type P2P = P2PClient & {
82
82
  *
83
83
  * @param handler - A function taking a received checkpoint proposal and producing attestations
84
84
  */
85
- registerCheckpointProposalHandler(callback: P2PCheckpointReceivedCallback): void;
85
+ registerValidatorCheckpointProposalHandler(callback: P2PCheckpointReceivedCallback): void;
86
+
87
+ /**
88
+ * Registers a callback that runs for ALL nodes (not just validators) when a checkpoint proposal is received.
89
+ * Used to set the proposed checkpoint number on the archiver so the sequencer can build on top of it.
90
+ *
91
+ * @param handler - A function taking a received checkpoint proposal
92
+ */
93
+ registerAllNodesCheckpointProposalHandler(callback: P2PCheckpointReceivedCallback): void;
86
94
 
87
95
  /**
88
96
  * Registers a callback invoked when a duplicate proposal is detected (equivocation).
@@ -1,4 +1,3 @@
1
- import { GENESIS_BLOCK_HEADER_HASH } from '@aztec/constants';
2
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
3
2
  import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
4
3
  import { createLogger } from '@aztec/foundation/log';
@@ -9,6 +8,7 @@ import { L2TipsKVStore } from '@aztec/kv-store/stores';
9
8
  import {
10
9
  type CheckpointId,
11
10
  type EthAddress,
11
+ GENESIS_BLOCK_HEADER_HASH,
12
12
  type L2Block,
13
13
  type L2BlockId,
14
14
  type L2BlockSource,
@@ -257,7 +257,11 @@ export class P2PClient extends WithTracer implements P2P {
257
257
  });
258
258
  }
259
259
 
260
- this.blockStream!.start();
260
+ // Should never happen: all branches above call initBlockStream()
261
+ if (!this.blockStream) {
262
+ throw new Error('Block stream not initialized');
263
+ }
264
+ this.blockStream.start();
261
265
  await this.txCollection.start();
262
266
  this.txFileStore?.start();
263
267
 
@@ -319,7 +323,11 @@ export class P2PClient extends WithTracer implements P2P {
319
323
  /** Triggers a sync to the archiver. Used for testing. */
320
324
  public async sync() {
321
325
  this.initBlockStream();
322
- await this.blockStream!.sync();
326
+ // Should never happen: initBlockStream() creates blockStream if absent
327
+ if (!this.blockStream) {
328
+ throw new Error('Block stream not initialized');
329
+ }
330
+ await this.blockStream.sync();
323
331
  }
324
332
 
325
333
  @trackSpan('p2pClient.broadcastProposal', async proposal => ({
@@ -357,6 +365,8 @@ export class P2PClient extends WithTracer implements P2P {
357
365
  // Store our own last-block proposal so we can respond to req/resp requests for it.
358
366
  await this.attestationPool.tryAddBlockProposal(blockProposal);
359
367
  }
368
+ // Gossipsub doesn't deliver own messages, so fire the all-nodes handler locally
369
+ await this.p2pService.notifyOwnCheckpointProposal(proposal.toCore());
360
370
  return this.p2pService.propagate(proposal);
361
371
  }
362
372
 
@@ -388,8 +398,12 @@ export class P2PClient extends WithTracer implements P2P {
388
398
  this.p2pService.registerBlockReceivedCallback(handler);
389
399
  }
390
400
 
391
- public registerCheckpointProposalHandler(handler: P2PCheckpointReceivedCallback): void {
392
- this.p2pService.registerCheckpointReceivedCallback(handler);
401
+ public registerValidatorCheckpointProposalHandler(handler: P2PCheckpointReceivedCallback): void {
402
+ this.p2pService.registerValidatorCheckpointReceivedCallback(handler);
403
+ }
404
+
405
+ public registerAllNodesCheckpointProposalHandler(handler: P2PCheckpointReceivedCallback): void {
406
+ this.p2pService.registerAllNodesCheckpointReceivedCallback(handler);
393
407
  }
394
408
 
395
409
  public registerDuplicateProposalCallback(callback: (info: DuplicateProposalInfo) => void): void {
@@ -696,12 +710,23 @@ export class P2PClient extends WithTracer implements P2P {
696
710
 
697
711
  /** Checks if the slot has changed and calls prepareForSlot if so. */
698
712
  private async maybeCallPrepareForSlot(): Promise<void> {
699
- const { currentSlot } = this.epochCache.getCurrentAndNextSlot();
700
- if (currentSlot <= this.lastSlotProcessed) {
713
+ // If we have a proposed checkpoint available, we want to prepare the target slot - otherwise we prepare the current slot
714
+ const l2Tips = await this.l2Tips.getL2Tips();
715
+ const hasProposedCheckpoint = l2Tips.proposedCheckpoint.checkpoint.number > l2Tips.checkpointed.checkpoint.number;
716
+
717
+ let slot;
718
+ if (this.epochCache.isProposerPipeliningEnabled() && hasProposedCheckpoint) {
719
+ const { targetSlot } = this.epochCache.getTargetAndNextSlot();
720
+ slot = targetSlot;
721
+ } else {
722
+ const { currentSlot } = this.epochCache.getCurrentAndNextSlot();
723
+ slot = currentSlot;
724
+ }
725
+ if (slot <= this.lastSlotProcessed) {
701
726
  return;
702
727
  }
703
- this.lastSlotProcessed = currentSlot;
704
- await this.txPool.prepareForSlot(currentSlot);
728
+ this.lastSlotProcessed = slot;
729
+ await this.txPool.prepareForSlot(slot);
705
730
  }
706
731
 
707
732
  private async startServiceIfSynched() {
@@ -3,11 +3,11 @@ import { SecretValue } from '@aztec/foundation/config';
3
3
  import { createLogger } from '@aztec/foundation/log';
4
4
  import { sleep } from '@aztec/foundation/sleep';
5
5
  import { DateProvider, Timer, executeTimeout } from '@aztec/foundation/timer';
6
- import type { DataStoreConfig } from '@aztec/kv-store/config';
7
6
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
8
7
  import type { L2BlockSource } from '@aztec/stdlib/block';
9
8
  import type { ContractDataSource } from '@aztec/stdlib/contract';
10
9
  import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
10
+ import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
11
11
  import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
12
12
  import type { Tx, TxValidationResult } from '@aztec/stdlib/tx';
13
13
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
@@ -19,7 +19,7 @@ import type { P2PConfig } from '../../../config.js';
19
19
  import { BatchTxRequesterCollector, SendBatchRequestCollector } from '../../../services/index.js';
20
20
  import type { IBatchRequestTxValidator } from '../../../services/reqresp/batch-tx-requester/tx_validator.js';
21
21
  import { RateLimitStatus } from '../../../services/reqresp/rate-limiter/rate_limiter.js';
22
- import { MissingTxsTracker } from '../../../services/tx_collection/missing_txs_tracker.js';
22
+ import { RequestTracker } from '../../../services/tx_collection/request_tracker.js';
23
23
  import {
24
24
  AlwaysTrueCircuitVerifier,
25
25
  BENCHMARK_CONSTANTS,
@@ -213,10 +213,9 @@ async function runCollector(cmd: Extract<WorkerCommand, { type: 'RUN_COLLECTOR'
213
213
  const fetched = await executeTimeout(
214
214
  (_signal: AbortSignal) =>
215
215
  collector.collectTxs(
216
- MissingTxsTracker.fromArray(parsedTxHashes),
216
+ RequestTracker.create(parsedTxHashes, new Date(Date.now() + internalTimeoutMs)),
217
217
  parsedProposal,
218
218
  pinnedPeer,
219
- internalTimeoutMs,
220
219
  ),
221
220
  timeoutMs,
222
221
  () => new Error(`Collector timed out after ${timeoutMs}ms`),
@@ -231,10 +230,9 @@ async function runCollector(cmd: Extract<WorkerCommand, { type: 'RUN_COLLECTOR'
231
230
  const fetched = await executeTimeout(
232
231
  (_signal: AbortSignal) =>
233
232
  collector.collectTxs(
234
- MissingTxsTracker.fromArray(parsedTxHashes),
233
+ RequestTracker.create(parsedTxHashes, new Date(Date.now() + internalTimeoutMs)),
235
234
  parsedProposal,
236
235
  pinnedPeer,
237
- internalTimeoutMs,
238
236
  ),
239
237
  timeoutMs,
240
238
  () => new Error(`Collector timed out after ${timeoutMs}ms`),
@@ -261,9 +259,20 @@ async function stopClient() {
261
259
  attestationPool = undefined;
262
260
  }
263
261
 
262
+ function gracefulExit(code: number = 0) {
263
+ try {
264
+ if (process.connected) {
265
+ process.disconnect();
266
+ }
267
+ } catch {
268
+ // IPC channel already closed
269
+ }
270
+ setTimeout(() => process.exit(code), 5000).unref();
271
+ }
272
+
264
273
  process.on('disconnect', () => {
265
274
  ipcDisconnected = true;
266
- void stopClient().finally(() => process.exit(0));
275
+ void stopClient();
267
276
  });
268
277
 
269
278
  process.on('error', err => {
@@ -327,7 +336,7 @@ process.on('message', (msg: WorkerCommand) => {
327
336
  case 'STOP': {
328
337
  await stopClient();
329
338
  await sendMessage({ type: 'STOPPED', requestId });
330
- process.exit(0);
339
+ gracefulExit(0);
331
340
  break;
332
341
  }
333
342
  default: {
@@ -338,7 +347,8 @@ process.on('message', (msg: WorkerCommand) => {
338
347
  } catch (err: any) {
339
348
  await sendMessage({ type: 'ERROR', requestId, error: err?.message ?? String(err) });
340
349
  if (msg.type === 'START') {
341
- process.exit(1);
350
+ await stopClient();
351
+ gracefulExit(1);
342
352
  }
343
353
  }
344
354
  })();
package/src/config.ts CHANGED
@@ -11,7 +11,6 @@ import {
11
11
  secretStringConfigHelper,
12
12
  } from '@aztec/foundation/config';
13
13
  import { Fr } from '@aztec/foundation/curves/bn254';
14
- import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
15
14
  import { FunctionSelector } from '@aztec/stdlib/abi/function-selector';
16
15
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
17
16
  import {
@@ -21,6 +20,7 @@ import {
21
20
  chainConfigMappings,
22
21
  sharedSequencerConfigMappings,
23
22
  } from '@aztec/stdlib/config';
23
+ import { type DataStoreConfig, dataConfigMappings } from '@aztec/stdlib/kv-store';
24
24
 
25
25
  import {
26
26
  type BatchTxRequesterConfig,
@@ -39,7 +39,14 @@ export interface P2PConfig
39
39
  ChainConfig,
40
40
  TxCollectionConfig,
41
41
  TxFileStoreConfig,
42
- Pick<SequencerConfig, 'blockDurationMs' | 'expectedBlockProposalsPerSlot' | 'maxTxsPerBlock'> {
42
+ Pick<
43
+ SequencerConfig,
44
+ | 'blockDurationMs'
45
+ | 'expectedBlockProposalsPerSlot'
46
+ | 'l1PublishingTime'
47
+ | 'maxTxsPerBlock'
48
+ | 'attestationPropagationTime'
49
+ > {
43
50
  /** Maximum transactions per block for validation. Overrides maxTxsPerBlock for gossip validation when set. */
44
51
  validateMaxTxsPerBlock?: number;
45
52
 
@@ -70,6 +77,9 @@ export interface P2PConfig
70
77
  /** The frequency in which to check for new peers. */
71
78
  peerCheckIntervalMS: number;
72
79
 
80
+ /** How long to ban a peer after it fails MAX_DIAL_ATTEMPTS dials. */
81
+ peerFailedBanTimeMs: number;
82
+
73
83
  /** Size of queue of L2 blocks to store. */
74
84
  l2QueueSize: number;
75
85
 
@@ -186,10 +196,7 @@ export interface P2PConfig
186
196
  /** Whether transactions are disabled for this node. This means transactions will be rejected at the RPC and P2P layers. */
187
197
  disableTransactions: boolean;
188
198
 
189
- /** True to simulate discarding transactions. - For testing purposes only*/
190
- dropTransactions: boolean;
191
-
192
- /** The probability that a transaction is discarded. - For testing purposes only */
199
+ /** The probability that a transaction is discarded (0 = disabled). - For testing purposes only */
193
200
  dropTransactionsProbability: number;
194
201
 
195
202
  /** Whether to delete transactions from the pool after a reorg instead of moving them back to pending. */
@@ -218,23 +225,23 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
218
225
  env: 'VALIDATOR_MAX_TX_PER_BLOCK',
219
226
  description:
220
227
  'Maximum transactions per block for validation. Overrides maxTxsPerBlock for gossip validation when set.',
221
- parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
228
+ parseEnv: (val: string) => parseInt(val, 10),
222
229
  },
223
230
  validateMaxTxsPerCheckpoint: {
224
231
  env: 'VALIDATOR_MAX_TX_PER_CHECKPOINT',
225
232
  description:
226
233
  'Maximum transactions per checkpoint for validation. Used as fallback for maxTxsPerBlock when that is not set.',
227
- parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
234
+ parseEnv: (val: string) => parseInt(val, 10),
228
235
  },
229
236
  validateMaxL2BlockGas: {
230
237
  env: 'VALIDATOR_MAX_L2_BLOCK_GAS',
231
238
  description: 'Maximum L2 gas per block for validation. When set, txs exceeding this limit are rejected.',
232
- parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
239
+ parseEnv: (val: string) => parseInt(val, 10),
233
240
  },
234
241
  validateMaxDABlockGas: {
235
242
  env: 'VALIDATOR_MAX_DA_BLOCK_GAS',
236
243
  description: 'Maximum DA gas per block for validation. When set, txs exceeding this limit are rejected.',
237
- parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
244
+ parseEnv: (val: string) => parseInt(val, 10),
238
245
  },
239
246
  p2pEnabled: {
240
247
  env: 'P2P_ENABLED',
@@ -266,6 +273,11 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
266
273
  description: 'The frequency in which to check for new peers.',
267
274
  ...numberConfigHelper(30_000),
268
275
  },
276
+ peerFailedBanTimeMs: {
277
+ env: 'P2P_PEER_FAILED_BAN_TIME_MS',
278
+ description: 'How long to ban a peer after it fails maximum dial attempts.',
279
+ ...numberConfigHelper(5 * 60 * 1000),
280
+ },
269
281
  l2QueueSize: {
270
282
  env: 'P2P_L2_QUEUE_SIZE',
271
283
  description: 'Size of queue of L2 blocks to store.',
@@ -359,7 +371,7 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
359
371
  gossipsubMcacheLength: {
360
372
  env: 'P2P_GOSSIPSUB_MCACHE_LENGTH',
361
373
  description: 'The number of gossipsub interval message cache windows to keep.',
362
- ...numberConfigHelper(6),
374
+ ...numberConfigHelper(12),
363
375
  },
364
376
  gossipsubMcacheGossip: {
365
377
  env: 'P2P_GOSSIPSUB_MCACHE_GOSSIP',
@@ -431,7 +443,7 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
431
443
  },
432
444
  p2pStoreMapSizeKb: {
433
445
  env: 'P2P_STORE_MAP_SIZE_KB',
434
- parseEnv: (val: string | undefined) => (val ? +val : undefined),
446
+ parseEnv: (val: string) => +val,
435
447
  description: 'The maximum possible size of the P2P DB in KB. Overwrites the general dataStoreMapSizeKb.',
436
448
  },
437
449
  txPublicSetupAllowListExtend: {
@@ -469,11 +481,6 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
469
481
  description: 'Number of auth attempts to allow before peer is banned. Number is inclusive',
470
482
  ...numberConfigHelper(3),
471
483
  },
472
- dropTransactions: {
473
- env: 'P2P_DROP_TX',
474
- description: 'True to simulate discarding transactions. - For testing purposes only',
475
- ...booleanConfigHelper(false),
476
- },
477
484
  dropTransactionsProbability: {
478
485
  env: 'P2P_DROP_TX_CHANCE',
479
486
  description: 'The probability that a transaction is discarded (0 - 1). - For testing purposes only',
@@ -495,6 +502,11 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
495
502
  description: 'Alters the format of p2p messages to include things like broadcast timestamp FOR TESTING ONLY',
496
503
  ...booleanConfigHelper(false),
497
504
  },
505
+ l1PublishingTime: {
506
+ env: 'SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT',
507
+ description: 'How much time (in seconds) we allow in the slot for publishing the L1 tx (defaults to 1 L1 slot).',
508
+ parseEnv: (val: string) => parseInt(val, 10),
509
+ },
498
510
  fishermanMode: {
499
511
  env: 'FISHERMAN_MODE',
500
512
  description:
@@ -0,0 +1,11 @@
1
+ /** Checkpoint Proposal Received Callback Not Registered Error
2
+ *
3
+ * Error triggered if the allNodesCheckpointReceivedCallback is not registered
4
+ * @category Errors
5
+ */
6
+ export class CheckpointProposalReceivedCallbackNotRegisteredError extends Error {
7
+ constructor() {
8
+ super('FATAL (allNodesCheckpointReceivedCallback): All nodes should register a checkpoint proposal handler');
9
+ this.name = 'CheckpointProposalReceivedCallbackNotRegisteredError';
10
+ }
11
+ }
package/src/index.ts CHANGED
@@ -6,7 +6,6 @@ export * from './client/index.js';
6
6
  export * from './enr/index.js';
7
7
  export * from './config.js';
8
8
  export * from './mem_pools/attestation_pool/index.js';
9
- export * from './mem_pools/tx_pool/index.js';
10
9
  export * from './mem_pools/tx_pool_v2/index.js';
11
10
  export * from './msg_validators/index.js';
12
11
  export * from './services/index.js';
@@ -26,10 +26,10 @@ export type TryAddResult = {
26
26
  count: number;
27
27
  };
28
28
 
29
- export const MAX_CHECKPOINT_PROPOSALS_PER_SLOT = 5;
30
- export const MAX_BLOCK_PROPOSALS_PER_POSITION = 3;
29
+ export const MAX_CHECKPOINT_PROPOSALS_PER_SLOT = 2;
30
+ export const MAX_BLOCK_PROPOSALS_PER_POSITION = 2;
31
31
  /** Maximum attestations a single signer can make per slot before being rejected. */
32
- export const MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER = 3;
32
+ export const MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER = 2;
33
33
 
34
34
  /** Public API interface for attestation pools. Used for typing mocks and test implementations. */
35
35
  export type AttestationPoolApi = Pick<
@@ -154,14 +154,16 @@ export class AttestationPool {
154
154
  /** Maximum indexWithinCheckpoint value (2^10 - 1 = 1023). */
155
155
  private static readonly MAX_INDEX = (1 << AttestationPool.INDEX_BITS) - 1;
156
156
 
157
- /** Creates a position key for block proposals: (slot << 10) | indexWithinCheckpoint. */
157
+ /** Creates a position key for block proposals: slot * 1024 + indexWithinCheckpoint.
158
+ * Uses multiplication instead of bit-shift to avoid 32-bit signed integer overflow
159
+ * (bit-shift overflows after slot ~2^21, roughly 278 days of uptime). */
158
160
  private getBlockPositionKey(slot: number, indexWithinCheckpoint: number): number {
159
161
  if (indexWithinCheckpoint > AttestationPool.MAX_INDEX) {
160
162
  throw new Error(
161
163
  `Value for indexWithinCheckpoint ${indexWithinCheckpoint} exceeds maximum ${AttestationPool.MAX_INDEX}`,
162
164
  );
163
165
  }
164
- return (slot << AttestationPool.INDEX_BITS) | indexWithinCheckpoint;
166
+ return slot * (1 << AttestationPool.INDEX_BITS) + indexWithinCheckpoint;
165
167
  }
166
168
 
167
169
  /**
@@ -278,7 +280,7 @@ export class AttestationPool {
278
280
  * @returns Result indicating whether the proposal was added and duplicate detection info
279
281
  */
280
282
  public async tryAddCheckpointProposal(proposal: CheckpointProposalCore): Promise<TryAddResult> {
281
- return await this.store.transactionAsync(async () => {
283
+ const result = await this.store.transactionAsync(async () => {
282
284
  const proposalId = proposal.archive.toString();
283
285
 
284
286
  // Check if already exists
@@ -304,6 +306,8 @@ export class AttestationPool {
304
306
 
305
307
  return { added: true, alreadyExists: false, count: count + 1 };
306
308
  });
309
+
310
+ return result;
307
311
  }
308
312
 
309
313
  /** Internal method - must be called within a transaction. */
@@ -345,7 +349,7 @@ export class AttestationPool {
345
349
  await this.store.transactionAsync(async () => {
346
350
  for (const attestation of attestations) {
347
351
  const slotNumber = attestation.payload.header.slotNumber;
348
- const proposalId = attestation.archive;
352
+ const proposalId = attestation.archive.toString();
349
353
  const sender = attestation.getSender();
350
354
 
351
355
  // Skip attestations with invalid signatures
@@ -359,11 +363,10 @@ export class AttestationPool {
359
363
  }
360
364
 
361
365
  const address = sender.toString();
366
+ const ownKey = this.getAttestationKey(slotNumber, proposalId, address);
362
367
 
363
- await this.checkpointAttestations.set(
364
- this.getAttestationKey(slotNumber, proposalId, address),
365
- attestation.toBuffer(),
366
- );
368
+ await this.checkpointAttestations.set(ownKey, attestation.toBuffer());
369
+ this.metrics.trackMempoolItemAdded(ownKey);
367
370
 
368
371
  this.log.debug(`Added own checkpoint attestation for slot ${slotNumber} from ${address}`, {
369
372
  signature: attestation.signature.toString(),
@@ -429,6 +432,7 @@ export class AttestationPool {
429
432
  const attestationEndKey = new Fr(oldestSlot).toString();
430
433
  for await (const key of this.checkpointAttestations.keysAsync({ end: attestationEndKey })) {
431
434
  await this.checkpointAttestations.delete(key);
435
+ this.metrics.trackMempoolItemRemoved(key);
432
436
  numberOfAttestations++;
433
437
  }
434
438
 
@@ -452,7 +456,7 @@ export class AttestationPool {
452
456
 
453
457
  // Delete block proposals for slots < oldestSlot, using blockProposalsForSlotAndIndex as index
454
458
  // Key format: (slot << INDEX_BITS) | indexWithinCheckpoint
455
- const blockPositionEndKey = oldestSlot << AttestationPool.INDEX_BITS;
459
+ const blockPositionEndKey = oldestSlot * (1 << AttestationPool.INDEX_BITS);
456
460
  for await (const positionKey of this.blockProposalsForSlotAndIndex.keysAsync({ end: blockPositionEndKey })) {
457
461
  const proposalIds = await toArray(this.blockProposalsForSlotAndIndex.getValuesAsync(positionKey));
458
462
  for (const proposalId of proposalIds) {
@@ -526,6 +530,7 @@ export class AttestationPool {
526
530
 
527
531
  // Add the attestation
528
532
  await this.checkpointAttestations.set(key, attestation.toBuffer());
533
+ this.metrics.trackMempoolItemAdded(key);
529
534
 
530
535
  // Track this attestation in the per-signer-per-slot index for duplicate detection
531
536
  const slotSignerKey = this.getSlotSignerKey(slotNumber, signerAddress);
@@ -446,12 +446,12 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
446
446
  const result2 = await ap.tryAddBlockProposal(proposal2);
447
447
  expect(result2.count).toBe(2);
448
448
 
449
- // Add a third proposal for same position
449
+ // Third proposal for same position should be rejected (cap is 2)
450
450
  const proposal3 = await mockBlockProposalWithIndex(signers[2], slotNumber, indexWithinCheckpoint);
451
451
  const result3 = await ap.tryAddBlockProposal(proposal3);
452
452
 
453
- expect(result3.added).toBe(true);
454
- expect(result3.count).toBe(3);
453
+ expect(result3.added).toBe(false);
454
+ expect(result3.count).toBe(2);
455
455
  });
456
456
 
457
457
  it('should return added=false when exceeding capacity', async () => {
@@ -666,12 +666,12 @@ export function describeAttestationPool(getAttestationPool: () => AttestationPoo
666
666
  const result2 = await ap.tryAddCheckpointProposal(proposal2);
667
667
  expect(result2.count).toBe(2);
668
668
 
669
- // Add a third proposal for same slot
669
+ // Third proposal for same slot should be rejected (cap is 2)
670
670
  const proposal3 = await mockCheckpointProposalCoreForPool(signers[2], slotNumber);
671
671
  const result3 = await ap.tryAddCheckpointProposal(proposal3);
672
672
 
673
- expect(result3.added).toBe(true);
674
- expect(result3.count).toBe(3);
673
+ expect(result3.added).toBe(false);
674
+ expect(result3.count).toBe(2);
675
675
  });
676
676
 
677
677
  it('should not count attestations as proposals for duplicate detection', async () => {
@@ -1,6 +1,3 @@
1
1
  export { AttestationPool, type AttestationPoolApi } from './attestation_pool/attestation_pool.js';
2
2
  export { type MemPools } from './interface.js';
3
- // Old TxPool exports - kept temporarily for external consumers
4
- export { type TxPool } from './tx_pool/tx_pool.js';
5
- // New TxPoolV2 exports
6
3
  export { type TxPoolV2, type TxPoolV2Config, type TxPoolV2Events, type AddTxsResult } from './tx_pool_v2/index.js';