@aztec/p2p 0.0.1-commit.e588bc7e5 → 0.0.1-commit.e5a3663dd

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 (164) hide show
  1. package/dest/client/factory.d.ts +3 -2
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +17 -16
  4. package/dest/client/p2p_client.d.ts +1 -1
  5. package/dest/client/p2p_client.d.ts.map +1 -1
  6. package/dest/client/p2p_client.js +9 -2
  7. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +4 -1
  8. package/dest/config.d.ts +107 -99
  9. package/dest/config.d.ts.map +1 -1
  10. package/dest/config.js +16 -7
  11. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -2
  12. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  13. package/dest/mem_pools/attestation_pool/attestation_pool.js +5 -3
  14. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
  15. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  16. package/dest/mem_pools/attestation_pool/mocks.js +6 -4
  17. package/dest/mem_pools/instrumentation.d.ts +1 -1
  18. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  19. package/dest/mem_pools/instrumentation.js +17 -1
  20. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
  21. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  22. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
  23. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
  24. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
  25. package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
  26. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  27. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +4 -1
  28. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  29. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -2
  30. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +8 -5
  32. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
  33. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +2 -1
  35. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
  36. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  37. package/dest/msg_validators/attestation_validator/attestation_validator.js +34 -10
  38. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
  39. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  40. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
  41. package/dest/msg_validators/clock_tolerance.d.ts +12 -1
  42. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  43. package/dest/msg_validators/clock_tolerance.js +57 -0
  44. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +5 -2
  45. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  46. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +5 -2
  47. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  48. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +8 -2
  49. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  50. package/dest/msg_validators/proposal_validator/proposal_validator.js +41 -9
  51. package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
  52. package/dest/msg_validators/tx_validator/factory.d.ts +2 -2
  53. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  54. package/dest/msg_validators/tx_validator/factory.js +3 -3
  55. package/dest/msg_validators/tx_validator/gas_validator.d.ts +36 -4
  56. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  57. package/dest/msg_validators/tx_validator/gas_validator.js +50 -33
  58. package/dest/services/data_store.d.ts +1 -1
  59. package/dest/services/data_store.d.ts.map +1 -1
  60. package/dest/services/data_store.js +5 -5
  61. package/dest/services/dummy_service.d.ts +2 -1
  62. package/dest/services/dummy_service.d.ts.map +1 -1
  63. package/dest/services/dummy_service.js +1 -0
  64. package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
  65. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  66. package/dest/services/gossipsub/topic_score_params.js +21 -4
  67. package/dest/services/libp2p/instrumentation.d.ts +3 -1
  68. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  69. package/dest/services/libp2p/instrumentation.js +14 -0
  70. package/dest/services/libp2p/libp2p_service.d.ts +7 -18
  71. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  72. package/dest/services/libp2p/libp2p_service.js +52 -74
  73. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  74. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  75. package/dest/services/peer-manager/peer_manager.js +15 -2
  76. package/dest/services/peer-manager/peer_scoring.d.ts +3 -1
  77. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  78. package/dest/services/peer-manager/peer_scoring.js +4 -0
  79. package/dest/services/reqresp/config.d.ts +3 -3
  80. package/dest/services/reqresp/config.d.ts.map +1 -1
  81. package/dest/services/reqresp/interface.d.ts +14 -9
  82. package/dest/services/reqresp/interface.d.ts.map +1 -1
  83. package/dest/services/reqresp/interface.js +10 -11
  84. package/dest/services/reqresp/metrics.d.ts +1 -1
  85. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  86. package/dest/services/reqresp/metrics.js +0 -1
  87. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  88. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  89. package/dest/services/reqresp/protocols/index.js +0 -1
  90. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  91. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  92. package/dest/services/reqresp/protocols/tx.js +1 -3
  93. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  94. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  95. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  96. package/dest/services/reqresp/reqresp.d.ts +4 -2
  97. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  98. package/dest/services/reqresp/reqresp.js +11 -2
  99. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  100. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  101. package/dest/test-helpers/make-test-p2p-clients.js +4 -1
  102. package/dest/test-helpers/mock-pubsub.d.ts +11 -3
  103. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  104. package/dest/test-helpers/mock-pubsub.js +36 -11
  105. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  106. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  107. package/dest/test-helpers/reqresp-nodes.js +5 -3
  108. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  109. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  110. package/dest/test-helpers/testbench-utils.js +1 -0
  111. package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
  112. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  113. package/dest/testbench/p2p_client_testbench_worker.js +29 -2
  114. package/dest/testbench/worker_client_manager.d.ts +8 -1
  115. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  116. package/dest/testbench/worker_client_manager.js +49 -0
  117. package/package.json +14 -14
  118. package/src/client/factory.ts +24 -19
  119. package/src/client/p2p_client.ts +11 -3
  120. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +2 -0
  121. package/src/config.ts +28 -7
  122. package/src/mem_pools/attestation_pool/attestation_pool.ts +5 -3
  123. package/src/mem_pools/attestation_pool/mocks.ts +13 -8
  124. package/src/mem_pools/instrumentation.ts +5 -1
  125. package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
  126. package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
  127. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  128. package/src/mem_pools/tx_pool_v2/interfaces.ts +3 -0
  129. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +13 -7
  130. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +2 -0
  131. package/src/msg_validators/attestation_validator/attestation_validator.ts +38 -7
  132. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +12 -2
  133. package/src/msg_validators/clock_tolerance.ts +75 -0
  134. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +11 -2
  135. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +16 -2
  136. package/src/msg_validators/proposal_validator/proposal_validator.ts +47 -7
  137. package/src/msg_validators/tx_validator/README.md +11 -3
  138. package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
  139. package/src/msg_validators/tx_validator/factory.ts +3 -1
  140. package/src/msg_validators/tx_validator/gas_validator.ts +82 -33
  141. package/src/services/data_store.ts +5 -13
  142. package/src/services/dummy_service.ts +1 -0
  143. package/src/services/gossipsub/topic_score_params.ts +36 -4
  144. package/src/services/libp2p/instrumentation.ts +14 -0
  145. package/src/services/libp2p/libp2p_service.ts +52 -70
  146. package/src/services/peer-manager/peer_manager.ts +17 -2
  147. package/src/services/peer-manager/peer_scoring.ts +6 -0
  148. package/src/services/reqresp/config.ts +2 -2
  149. package/src/services/reqresp/interface.ts +21 -11
  150. package/src/services/reqresp/metrics.ts +0 -1
  151. package/src/services/reqresp/protocols/index.ts +0 -1
  152. package/src/services/reqresp/protocols/tx.ts +1 -3
  153. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  154. package/src/services/reqresp/reqresp.ts +18 -1
  155. package/src/test-helpers/make-test-p2p-clients.ts +2 -0
  156. package/src/test-helpers/mock-pubsub.ts +34 -5
  157. package/src/test-helpers/reqresp-nodes.ts +4 -2
  158. package/src/test-helpers/testbench-utils.ts +1 -0
  159. package/src/testbench/p2p_client_testbench_worker.ts +30 -0
  160. package/src/testbench/worker_client_manager.ts +55 -0
  161. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  162. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  163. package/dest/services/reqresp/protocols/block.js +0 -32
  164. package/src/services/reqresp/protocols/block.ts +0 -37
@@ -13,6 +13,7 @@ import { DateProvider, Timer } from '@aztec/foundation/timer';
13
13
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
14
14
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
15
15
  import { protocolContractsHash } from '@aztec/protocol-contracts';
16
+ import { GasFees } from '@aztec/stdlib/gas';
16
17
  import { P2PMessage } from '@aztec/stdlib/p2p';
17
18
  import { ChonkProof } from '@aztec/stdlib/proofs';
18
19
  import { makeAztecAddress, makeBlockHeader, makeBlockProposal, mockTx } from '@aztec/stdlib/testing';
@@ -32,7 +33,9 @@ class TestLibP2PService extends LibP2PService {
32
33
  disableTxValidation;
33
34
  gossipMessageCount = 0;
34
35
  constructor(config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:test:libp2p_service'), disableTxValidation = true){
35
- super(config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
36
+ super(config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, {
37
+ getCurrentMinFees: ()=>Promise.resolve(GasFees.empty())
38
+ }, telemetry, logger);
36
39
  this.disableTxValidation = disableTxValidation;
37
40
  }
38
41
  getGossipMessageCount() {
@@ -110,6 +113,21 @@ function installUnlimitedRateLimits(client) {
110
113
  rateLimiter.getRateLimits = ()=>UNLIMITED_RATE_LIMIT_QUOTA;
111
114
  rateLimiter.allow = ()=>RateLimitStatus.Allowed;
112
115
  }
116
+ /** Resets peer scores to prevent cross-case contamination in benchmarks. */ function resetPeerScores(client) {
117
+ const peerManager = client.p2pService.peerManager;
118
+ const peerScoring = peerManager?.peerScoring;
119
+ if (peerScoring?.resetAllScores) {
120
+ peerScoring.resetAllScores();
121
+ }
122
+ }
123
+ /** Returns the number of connected peers for connectivity checks. */ function getConnectedPeerCount(client) {
124
+ const p2pService = client.p2pService;
125
+ const connectionSampler = p2pService?.reqresp?.getConnectionSampler?.();
126
+ if (connectionSampler?.getPeerListSortedByConnectionCountAsc) {
127
+ return connectionSampler.getPeerListSortedByConnectionCountAsc().length;
128
+ }
129
+ return 0;
130
+ }
113
131
  async function runAggregatorBenchmark(client, blockProposal, collectorType, timeoutMs, pinnedPeerId, pinnedPeerIndex, logger, expectedPeerCount) {
114
132
  let timer = new Timer();
115
133
  try {
@@ -244,7 +262,9 @@ process.on('message', async (msg)=>{
244
262
  store: kvStore,
245
263
  logger: workerLogger
246
264
  };
247
- const client = await createP2PClient(config, l2BlockSource, proofVerifier, worldState, epochCache, 'test-p2p-bench-worker', undefined, telemetry, deps);
265
+ const client = await createP2PClient(config, l2BlockSource, proofVerifier, worldState, epochCache, {
266
+ getCurrentMinFees: ()=>Promise.resolve(GasFees.empty())
267
+ }, 'test-p2p-bench-worker', undefined, telemetry, deps);
248
268
  const testService = new TestLibP2PService(config, client.p2pService.node, client.p2pService.peerDiscoveryService, client.p2pService.reqresp, client.p2pService.peerManager, client.p2pService.mempools, client.p2pService.archiver, epochCache, proofVerifier, worldState, telemetry, workerLogger, true);
249
269
  client.p2pService = testService;
250
270
  await client.start();
@@ -278,6 +298,12 @@ process.on('message', async (msg)=>{
278
298
  });
279
299
  }
280
300
  break;
301
+ case 'GET_PEER_COUNT':
302
+ process.send({
303
+ type: 'PEER_COUNT',
304
+ count: workerClient ? getConnectedPeerCount(workerClient) : 0
305
+ });
306
+ break;
281
307
  case 'BENCH_REQRESP':
282
308
  {
283
309
  const benchCmd = cmd;
@@ -294,6 +320,7 @@ process.on('message', async (msg)=>{
294
320
  // Reset state before each benchmark run to avoid cross-run contamination
295
321
  workerTxPool.resetState();
296
322
  workerAttestationPool.resetState();
323
+ resetPeerScores(workerClient);
297
324
  installUnlimitedRateLimits(workerClient);
298
325
  const allTxs = await generateDeterministicTxs(benchCmd.txCount, benchCmd.seed, workerConfig);
299
326
  const txHashes = allTxs.map((tx)=>tx.getTxHash());
@@ -78,6 +78,13 @@ declare class WorkerClientManager {
78
78
  * Cleans up all worker processes with timeout and force kill if needed
79
79
  */
80
80
  cleanup(): Promise<void>;
81
+ /**
82
+ * Checks that the aggregator (client 0) has sufficient peer connections before running a benchmark.
83
+ * This prevents benchmark cases from starting with degraded connectivity after a previous case
84
+ * caused connection failures.
85
+ */
86
+ waitForConnectivity(minPeers: number, timeoutMs?: number): Promise<number>;
87
+ private getPeerCount;
81
88
  /**
82
89
  * Run a req/resp benchmark across all worker clients.
83
90
  *
@@ -95,4 +102,4 @@ declare class WorkerClientManager {
95
102
  export { WorkerClientManager, testChainConfig };
96
103
  export type { DistributionPattern, CollectorType } from './p2p_client_testbench_worker.js';
97
104
  export { COLLECTOR_DISPLAY_NAMES } from './p2p_client_testbench_worker.js';
98
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyX2NsaWVudF9tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdGJlbmNoL3dvcmtlcl9jbGllbnRfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVwRCxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsS0FBSyxZQUFZLEVBQVEsTUFBTSxlQUFlLENBQUM7QUFLeEQsT0FBTyxFQUFFLEtBQUssU0FBUyxFQUF1QixNQUFNLGNBQWMsQ0FBQztBQUtuRSxPQUFPLEtBQUssRUFHVixhQUFhLEVBQ2IsbUJBQW1CLEVBQ3BCLE1BQU0sa0NBQWtDLENBQUM7QUFRMUMsUUFBQSxNQUFNLGVBQWUsRUFBRSxXQU10QixDQUFDO0FBRUYsTUFBTSxXQUFXLHNCQUFzQjtJQUNyQyxPQUFPLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLFlBQVksRUFBRSxtQkFBbUIsQ0FBQztJQUNsQyxhQUFhLEVBQUUsYUFBYSxDQUFDO0lBQzdCLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsZUFBZSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3pCLFdBQVcsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNyQixJQUFJLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDZjtBQUVELE1BQU0sV0FBVyxzQkFBc0I7SUFDckMsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixZQUFZLEVBQUUsbUJBQW1CLENBQUM7SUFDbEMsU0FBUyxFQUFFLGFBQWEsQ0FBQztJQUN6QixVQUFVLEVBQUUsTUFBTSxDQUFDO0lBQ25CLFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsT0FBTyxFQUFFLE9BQU8sQ0FBQztJQUNqQixLQUFLLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDaEI7QUFFRCxjQUFNLG1CQUFtQjtJQUNoQixTQUFTLEVBQUUsWUFBWSxFQUFFLENBQU07SUFDL0IsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLENBQU07SUFDakMsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFNO0lBQ3hCLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBTTtJQUNyQixPQUFPLEVBQUUsTUFBTSxFQUFFLENBQU07SUFDOUIsT0FBTyxDQUFDLFNBQVMsQ0FBcUI7SUFDdEMsT0FBTyxDQUFDLE1BQU0sQ0FBUztJQUN2QixPQUFPLENBQUMsdUJBQXVCLENBQWdCO0lBRS9DLFlBQVksTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUd4RDtJQUVELE9BQU8sU0FJTjtJQUVEOzs7Ozs7O09BT0c7SUFDSCxPQUFPLENBQUMsa0JBQWtCO0lBb0IxQjs7O09BR0c7SUFDSCxPQUFPLENBQUMsa0JBQWtCO0lBa0cxQjs7Ozs7OztPQU9HO0lBQ0csaUJBQWlCLENBQ3JCLGVBQWUsRUFBRSxNQUFNLEVBQ3ZCLE9BQU8sR0FBRTtRQUNQLGFBQWEsQ0FBQyxFQUFFLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakMsYUFBYSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ3ZCLFNBQVMsQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUNuQixZQUFZLENBQUMsRUFBRSxNQUFNLENBQUM7S0FDbEIscUJBK0RQO0lBRUQsNEJBQTRCLFNBRTNCO0lBRUQsa0NBQWtDLFdBRWpDO0lBRUQ7Ozs7O09BS0c7SUFDRyxVQUFVLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkE4Q3BEO0lBRUQ7O09BRUc7SUFDSCxPQUFPLENBQUMsZ0JBQWdCO0lBcUN4Qjs7T0FFRztJQUNHLE9BQU8sa0JBZ0NaO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0csbUJBQW1CLENBQUMsTUFBTSxFQUFFLHNCQUFzQixHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxDQXVFekY7SUFFRCxPQUFPLENBQUMsaUJBQWlCO0lBa0N6QixPQUFPLENBQUMsa0JBQWtCO0NBaUMzQjtBQUVELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxlQUFlLEVBQUUsQ0FBQztBQUNoRCxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDM0YsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sa0NBQWtDLENBQUMifQ==
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyX2NsaWVudF9tYW5hZ2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdGJlbmNoL3dvcmtlcl9jbGllbnRfbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVwRCxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsS0FBSyxZQUFZLEVBQVEsTUFBTSxlQUFlLENBQUM7QUFLeEQsT0FBTyxFQUFFLEtBQUssU0FBUyxFQUF1QixNQUFNLGNBQWMsQ0FBQztBQUtuRSxPQUFPLEtBQUssRUFHVixhQUFhLEVBQ2IsbUJBQW1CLEVBQ3BCLE1BQU0sa0NBQWtDLENBQUM7QUFRMUMsUUFBQSxNQUFNLGVBQWUsRUFBRSxXQU10QixDQUFDO0FBRUYsTUFBTSxXQUFXLHNCQUFzQjtJQUNyQyxPQUFPLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLFlBQVksRUFBRSxtQkFBbUIsQ0FBQztJQUNsQyxhQUFhLEVBQUUsYUFBYSxDQUFDO0lBQzdCLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsZUFBZSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ3pCLFdBQVcsQ0FBQyxFQUFFLE1BQU0sQ0FBQztJQUNyQixJQUFJLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDZjtBQUVELE1BQU0sV0FBVyxzQkFBc0I7SUFDckMsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUNoQixZQUFZLEVBQUUsbUJBQW1CLENBQUM7SUFDbEMsU0FBUyxFQUFFLGFBQWEsQ0FBQztJQUN6QixVQUFVLEVBQUUsTUFBTSxDQUFDO0lBQ25CLFlBQVksRUFBRSxNQUFNLENBQUM7SUFDckIsT0FBTyxFQUFFLE9BQU8sQ0FBQztJQUNqQixLQUFLLENBQUMsRUFBRSxNQUFNLENBQUM7Q0FDaEI7QUFFRCxjQUFNLG1CQUFtQjtJQUNoQixTQUFTLEVBQUUsWUFBWSxFQUFFLENBQU07SUFDL0IsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLENBQU07SUFDakMsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFNO0lBQ3hCLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBTTtJQUNyQixPQUFPLEVBQUUsTUFBTSxFQUFFLENBQU07SUFDOUIsT0FBTyxDQUFDLFNBQVMsQ0FBcUI7SUFDdEMsT0FBTyxDQUFDLE1BQU0sQ0FBUztJQUN2QixPQUFPLENBQUMsdUJBQXVCLENBQWdCO0lBRS9DLFlBQVksTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUd4RDtJQUVELE9BQU8sU0FJTjtJQUVEOzs7Ozs7O09BT0c7SUFDSCxPQUFPLENBQUMsa0JBQWtCO0lBb0IxQjs7O09BR0c7SUFDSCxPQUFPLENBQUMsa0JBQWtCO0lBa0cxQjs7Ozs7OztPQU9HO0lBQ0csaUJBQWlCLENBQ3JCLGVBQWUsRUFBRSxNQUFNLEVBQ3ZCLE9BQU8sR0FBRTtRQUNQLGFBQWEsQ0FBQyxFQUFFLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakMsYUFBYSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ3ZCLFNBQVMsQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUNuQixZQUFZLENBQUMsRUFBRSxNQUFNLENBQUM7S0FDbEIscUJBK0RQO0lBRUQsNEJBQTRCLFNBRTNCO0lBRUQsa0NBQWtDLFdBRWpDO0lBRUQ7Ozs7O09BS0c7SUFDRyxVQUFVLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkE4Q3BEO0lBRUQ7O09BRUc7SUFDSCxPQUFPLENBQUMsZ0JBQWdCO0lBcUN4Qjs7T0FFRztJQUNHLE9BQU8sa0JBZ0NaO0lBRUQ7Ozs7T0FJRztJQUNHLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxHQUFFLE1BQWUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBa0J2RjtJQUVELE9BQU8sQ0FBQyxZQUFZO0lBOEJwQjs7Ozs7Ozs7O09BU0c7SUFDRyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsc0JBQXNCLEdBQUcsT0FBTyxDQUFDLHNCQUFzQixDQUFDLENBdUV6RjtJQUVELE9BQU8sQ0FBQyxpQkFBaUI7SUFrQ3pCLE9BQU8sQ0FBQyxrQkFBa0I7Q0FpQzNCO0FBRUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGVBQWUsRUFBRSxDQUFDO0FBQ2hELFlBQVksRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMzRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQyJ9
@@ -1 +1 @@
1
- {"version":3,"file":"worker_client_manager.d.ts","sourceRoot":"","sources":["../../src/testbench/worker_client_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,KAAK,YAAY,EAAQ,MAAM,eAAe,CAAC;AAKxD,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,cAAc,CAAC;AAKnE,OAAO,KAAK,EAGV,aAAa,EACb,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAQ1C,QAAA,MAAM,eAAe,EAAE,WAMtB,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,mBAAmB,CAAC;IAClC,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,mBAAmB,CAAC;IAClC,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,cAAM,mBAAmB;IAChB,SAAS,EAAE,YAAY,EAAE,CAAM;IAC/B,iBAAiB,EAAE,MAAM,EAAE,CAAM;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAM;IACxB,KAAK,EAAE,MAAM,EAAE,CAAM;IACrB,OAAO,EAAE,MAAM,EAAE,CAAM;IAC9B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,uBAAuB,CAAgB;IAE/C,YAAY,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,EAGxD;IAED,OAAO,SAIN;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAkG1B;;;;;;;OAOG;IACG,iBAAiB,CACrB,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE;QACP,aAAa,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;QACjC,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KAClB,qBA+DP;IAED,4BAA4B,SAE3B;IAED,kCAAkC,WAEjC;IAED;;;;;OAKG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBA8CpD;IAED;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;OAEG;IACG,OAAO,kBAgCZ;IAED;;;;;;;;;OASG;IACG,mBAAmB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuEzF;IAED,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,kBAAkB;CAiC3B;AAED,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAC;AAChD,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAC3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"worker_client_manager.d.ts","sourceRoot":"","sources":["../../src/testbench/worker_client_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,KAAK,YAAY,EAAQ,MAAM,eAAe,CAAC;AAKxD,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,cAAc,CAAC;AAKnE,OAAO,KAAK,EAGV,aAAa,EACb,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAQ1C,QAAA,MAAM,eAAe,EAAE,WAMtB,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,mBAAmB,CAAC;IAClC,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,mBAAmB,CAAC;IAClC,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,cAAM,mBAAmB;IAChB,SAAS,EAAE,YAAY,EAAE,CAAM;IAC/B,iBAAiB,EAAE,MAAM,EAAE,CAAM;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAM;IACxB,KAAK,EAAE,MAAM,EAAE,CAAM;IACrB,OAAO,EAAE,MAAM,EAAE,CAAM;IAC9B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,uBAAuB,CAAgB;IAE/C,YAAY,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,EAGxD;IAED,OAAO,SAIN;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAkG1B;;;;;;;OAOG;IACG,iBAAiB,CACrB,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE;QACP,aAAa,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;QACjC,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KAClB,qBA+DP;IAED,4BAA4B,SAE3B;IAED,kCAAkC,WAEjC;IAED;;;;;OAKG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBA8CpD;IAED;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;OAEG;IACG,OAAO,kBAgCZ;IAED;;;;OAIG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAE,MAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBvF;IAED,OAAO,CAAC,YAAY;IA8BpB;;;;;;;;;OASG;IACG,mBAAmB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuEzF;IAED,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,kBAAkB;CAiC3B;AAED,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAC;AAChD,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAC3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC"}
@@ -317,6 +317,55 @@ class WorkerClientManager {
317
317
  this.logger.info('All worker processes cleaned up');
318
318
  }
319
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
+ /**
320
369
  * Run a req/resp benchmark across all worker clients.
321
370
  *
322
371
  * This sends a BENCH_REQRESP command to all workers:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.0.1-commit.e588bc7e5",
3
+ "version": "0.0.1-commit.e5a3663dd",
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.e588bc7e5",
71
- "@aztec/epoch-cache": "0.0.1-commit.e588bc7e5",
72
- "@aztec/ethereum": "0.0.1-commit.e588bc7e5",
73
- "@aztec/foundation": "0.0.1-commit.e588bc7e5",
74
- "@aztec/kv-store": "0.0.1-commit.e588bc7e5",
75
- "@aztec/noir-contracts.js": "0.0.1-commit.e588bc7e5",
76
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.e588bc7e5",
77
- "@aztec/protocol-contracts": "0.0.1-commit.e588bc7e5",
78
- "@aztec/simulator": "0.0.1-commit.e588bc7e5",
79
- "@aztec/stdlib": "0.0.1-commit.e588bc7e5",
80
- "@aztec/telemetry-client": "0.0.1-commit.e588bc7e5",
70
+ "@aztec/constants": "0.0.1-commit.e5a3663dd",
71
+ "@aztec/epoch-cache": "0.0.1-commit.e5a3663dd",
72
+ "@aztec/ethereum": "0.0.1-commit.e5a3663dd",
73
+ "@aztec/foundation": "0.0.1-commit.e5a3663dd",
74
+ "@aztec/kv-store": "0.0.1-commit.e5a3663dd",
75
+ "@aztec/noir-contracts.js": "0.0.1-commit.e5a3663dd",
76
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.e5a3663dd",
77
+ "@aztec/protocol-contracts": "0.0.1-commit.e5a3663dd",
78
+ "@aztec/simulator": "0.0.1-commit.e5a3663dd",
79
+ "@aztec/stdlib": "0.0.1-commit.e5a3663dd",
80
+ "@aztec/telemetry-client": "0.0.1-commit.e5a3663dd",
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.e588bc7e5",
108
- "@aztec/world-state": "0.0.1-commit.e588bc7e5",
107
+ "@aztec/archiver": "0.0.1-commit.e5a3663dd",
108
+ "@aztec/world-state": "0.0.1-commit.e5a3663dd",
109
109
  "@jest/globals": "^30.0.0",
110
110
  "@types/jest": "^30.0.0",
111
111
  "@types/node": "^22.15.17",
@@ -7,6 +7,7 @@ import { AztecLMDBStoreV2, createStore } from '@aztec/kv-store/lmdb-v2';
7
7
  import type { L2BlockSource } from '@aztec/stdlib/block';
8
8
  import type { ChainConfig } from '@aztec/stdlib/config';
9
9
  import type { ContractDataSource } from '@aztec/stdlib/contract';
10
+ import type { BlockMinFeesProvider } from '@aztec/stdlib/gas';
10
11
  import type { AztecNode, ClientProtocolCircuitVerifier, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
11
12
  import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
12
13
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
@@ -52,6 +53,7 @@ export async function createP2PClient(
52
53
  proofVerifier: ClientProtocolCircuitVerifier,
53
54
  worldStateSynchronizer: WorldStateSynchronizer,
54
55
  epochCache: EpochCacheInterface,
56
+ blockMinFeesProvider: BlockMinFeesProvider,
55
57
  packageVersion: string,
56
58
  dateProvider: DateProvider = new DateProvider(),
57
59
  telemetry: TelemetryClient = getTelemetryClient(),
@@ -74,7 +76,7 @@ export async function createP2PClient(
74
76
  const store = deps.store ?? (await createStore(P2P_STORE_NAME, 2, config, bindings));
75
77
  const archive = await createStore(P2P_ARCHIVE_STORE_NAME, 1, config, bindings);
76
78
  const peerStore = await createStore(P2P_PEER_STORE_NAME, 1, config, bindings);
77
- const attestationStore = await createStore(P2P_ATTESTATION_STORE_NAME, 1, config, bindings);
79
+ const attestationStore = await createStore(P2P_ATTESTATION_STORE_NAME, 2, config, bindings);
78
80
  const l1Constants = await archiver.getL1Constants();
79
81
 
80
82
  const rollupAddress = inputConfig.l1Contracts.rollupAddress.toString().toLowerCase().replace(/^0x/, '');
@@ -90,23 +92,6 @@ export async function createP2PClient(
90
92
  () => epochCache.getEpochAndSlotInNextL1Slot().ts,
91
93
  );
92
94
 
93
- const createTxValidator = async () => {
94
- // We accept transactions if they are not expired by the next slot and block number (checked based on the ExpirationTimestamp field)
95
- const currentBlockNumber = await archiver.getBlockNumber();
96
- const { ts: nextSlotTimestamp } = epochCache.getEpochAndSlotInNextL1Slot();
97
- const l1Constants = await archiver.getL1Constants();
98
- return createTxValidatorForTransactionsEnteringPendingTxPool(
99
- worldStateSynchronizer,
100
- nextSlotTimestamp,
101
- BlockNumber(currentBlockNumber + 1),
102
- {
103
- rollupManaLimit: l1Constants.rollupManaLimit,
104
- maxBlockL2Gas: config.validateMaxL2BlockGas,
105
- maxBlockDAGas: config.validateMaxDABlockGas,
106
- },
107
- );
108
- };
109
-
110
95
  const txPool =
111
96
  deps.txPool ??
112
97
  new AztecKVTxPoolV2(
@@ -116,7 +101,24 @@ export async function createP2PClient(
116
101
  l2BlockSource: archiver,
117
102
  worldStateSynchronizer,
118
103
  checkAllowedSetupCalls,
119
- createTxValidator,
104
+ createTxValidator: async () => {
105
+ const currentBlockNumber = await archiver.getBlockNumber();
106
+ const { ts: nextSlotTimestamp } = epochCache.getEpochAndSlotInNextL1Slot();
107
+ const l1Constants = await archiver.getL1Constants();
108
+ const gasFees = await blockMinFeesProvider.getCurrentMinFees();
109
+ return createTxValidatorForTransactionsEnteringPendingTxPool(
110
+ worldStateSynchronizer,
111
+ nextSlotTimestamp,
112
+ BlockNumber(currentBlockNumber + 1),
113
+ {
114
+ rollupManaLimit: l1Constants.rollupManaLimit,
115
+ maxBlockL2Gas: config.validateMaxL2BlockGas,
116
+ maxBlockDAGas: config.validateMaxDABlockGas,
117
+ },
118
+ gasFees,
119
+ );
120
+ },
121
+ blockMinFeesProvider,
120
122
  },
121
123
  telemetry,
122
124
  {
@@ -140,6 +142,7 @@ export async function createP2PClient(
140
142
  proofVerifier,
141
143
  worldStateSynchronizer,
142
144
  epochCache,
145
+ blockMinFeesProvider,
143
146
  store,
144
147
  peerStore,
145
148
  mempools,
@@ -216,6 +219,7 @@ async function createP2PService(
216
219
  proofVerifier: ClientProtocolCircuitVerifier,
217
220
  worldStateSynchronizer: WorldStateSynchronizer,
218
221
  epochCache: EpochCacheInterface,
222
+ blockMinFeesProvider: BlockMinFeesProvider,
219
223
  store: AztecAsyncKVStore,
220
224
  peerStore: AztecLMDBStoreV2,
221
225
  mempools: MemPools,
@@ -243,6 +247,7 @@ async function createP2PService(
243
247
  proofVerifier,
244
248
  worldStateSynchronizer,
245
249
  peerStore,
250
+ blockMinFeesProvider,
246
251
  telemetry,
247
252
  logger: logger.createChild(`libp2p_service`),
248
253
  });
@@ -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 => ({
@@ -6,6 +6,7 @@ import { DateProvider, Timer, executeTimeout } from '@aztec/foundation/timer';
6
6
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
7
7
  import type { L2BlockSource } from '@aztec/stdlib/block';
8
8
  import type { ContractDataSource } from '@aztec/stdlib/contract';
9
+ import { GasFees } from '@aztec/stdlib/gas';
9
10
  import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
10
11
  import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
11
12
  import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
@@ -119,6 +120,7 @@ async function startClient(config: P2PConfig, clientIndex: number) {
119
120
  proofVerifier as ClientProtocolCircuitVerifier,
120
121
  worldState,
121
122
  epochCache,
123
+ { getCurrentMinFees: () => Promise.resolve(GasFees.empty()) },
122
124
  'proposal-tx-collector-bench-worker',
123
125
  new DateProvider(),
124
126
  telemetry as TelemetryClient,
package/src/config.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  getConfigFromMappings,
7
7
  getDefaultConfig,
8
8
  numberConfigHelper,
9
+ optionalNumberConfigHelper,
9
10
  percentageConfigHelper,
10
11
  pickConfigMappings,
11
12
  secretStringConfigHelper,
@@ -39,7 +40,15 @@ export interface P2PConfig
39
40
  ChainConfig,
40
41
  TxCollectionConfig,
41
42
  TxFileStoreConfig,
42
- Pick<SequencerConfig, 'blockDurationMs' | 'expectedBlockProposalsPerSlot' | 'maxTxsPerBlock'> {
43
+ Pick<
44
+ SequencerConfig,
45
+ | 'blockDurationMs'
46
+ | 'expectedBlockProposalsPerSlot'
47
+ | 'l1PublishingTime'
48
+ | 'maxTxsPerBlock'
49
+ | 'attestationPropagationTime'
50
+ | 'maxBlocksPerCheckpoint'
51
+ > {
43
52
  /** Maximum transactions per block for validation. Overrides maxTxsPerBlock for gossip validation when set. */
44
53
  validateMaxTxsPerBlock?: number;
45
54
 
@@ -209,6 +218,9 @@ export interface P2PConfig
209
218
 
210
219
  /** Minimum percentage fee increase required to replace an existing tx via RPC (0 = no bump). */
211
220
  priceBumpPercentage: bigint;
221
+
222
+ /** Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only) */
223
+ skipIncomingProposals?: boolean;
212
224
  }
213
225
 
214
226
  export const DEFAULT_P2P_PORT = 40400;
@@ -218,23 +230,23 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
218
230
  env: 'VALIDATOR_MAX_TX_PER_BLOCK',
219
231
  description:
220
232
  'Maximum transactions per block for validation. Overrides maxTxsPerBlock for gossip validation when set.',
221
- parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
233
+ ...optionalNumberConfigHelper(),
222
234
  },
223
235
  validateMaxTxsPerCheckpoint: {
224
236
  env: 'VALIDATOR_MAX_TX_PER_CHECKPOINT',
225
237
  description:
226
238
  '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),
239
+ ...optionalNumberConfigHelper(),
228
240
  },
229
241
  validateMaxL2BlockGas: {
230
242
  env: 'VALIDATOR_MAX_L2_BLOCK_GAS',
231
243
  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),
244
+ ...optionalNumberConfigHelper(),
233
245
  },
234
246
  validateMaxDABlockGas: {
235
247
  env: 'VALIDATOR_MAX_DA_BLOCK_GAS',
236
248
  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),
249
+ ...optionalNumberConfigHelper(),
238
250
  },
239
251
  p2pEnabled: {
240
252
  env: 'P2P_ENABLED',
@@ -364,7 +376,7 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
364
376
  gossipsubMcacheLength: {
365
377
  env: 'P2P_GOSSIPSUB_MCACHE_LENGTH',
366
378
  description: 'The number of gossipsub interval message cache windows to keep.',
367
- ...numberConfigHelper(6),
379
+ ...numberConfigHelper(12),
368
380
  },
369
381
  gossipsubMcacheGossip: {
370
382
  env: 'P2P_GOSSIPSUB_MCACHE_GOSSIP',
@@ -436,7 +448,7 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
436
448
  },
437
449
  p2pStoreMapSizeKb: {
438
450
  env: 'P2P_STORE_MAP_SIZE_KB',
439
- parseEnv: (val: string | undefined) => (val ? +val : undefined),
451
+ ...optionalNumberConfigHelper(),
440
452
  description: 'The maximum possible size of the P2P DB in KB. Overwrites the general dataStoreMapSizeKb.',
441
453
  },
442
454
  txPublicSetupAllowListExtend: {
@@ -495,6 +507,11 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
495
507
  description: 'Alters the format of p2p messages to include things like broadcast timestamp FOR TESTING ONLY',
496
508
  ...booleanConfigHelper(false),
497
509
  },
510
+ l1PublishingTime: {
511
+ env: 'SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT',
512
+ description: 'How much time (in seconds) we allow in the slot for publishing the L1 tx (defaults to 1 L1 slot).',
513
+ ...optionalNumberConfigHelper(),
514
+ },
498
515
  fishermanMode: {
499
516
  env: 'FISHERMAN_MODE',
500
517
  description:
@@ -506,6 +523,10 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
506
523
  'Broadcast block proposals even when a conflicting proposal for the same slot already exists in the pool (for testing purposes only).',
507
524
  ...booleanConfigHelper(false),
508
525
  },
526
+ skipIncomingProposals: {
527
+ description: 'Drop incoming block and checkpoint proposals at the libp2p dispatch layer (for testing only)',
528
+ ...booleanConfigHelper(false),
529
+ },
509
530
  minTxPoolAgeMs: {
510
531
  env: 'P2P_MIN_TX_POOL_AGE_MS',
511
532
  description: 'Minimum age (ms) a transaction must have been in the pool before it is eligible for block building.',
@@ -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
  /**
@@ -454,7 +456,7 @@ export class AttestationPool {
454
456
 
455
457
  // Delete block proposals for slots < oldestSlot, using blockProposalsForSlotAndIndex as index
456
458
  // Key format: (slot << INDEX_BITS) | indexWithinCheckpoint
457
- const blockPositionEndKey = oldestSlot << AttestationPool.INDEX_BITS;
459
+ const blockPositionEndKey = oldestSlot * (1 << AttestationPool.INDEX_BITS);
458
460
  for await (const positionKey of this.blockProposalsForSlotAndIndex.keysAsync({ end: blockPositionEndKey })) {
459
461
  const proposalIds = await toArray(this.blockProposalsForSlotAndIndex.getValuesAsync(positionKey));
460
462
  for (const proposalId of proposalIds) {
@@ -3,11 +3,12 @@ import type { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer'
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import {
5
5
  CheckpointAttestation,
6
+ CheckpointProposal,
6
7
  ConsensusPayload,
7
- SignatureDomainSeparator,
8
- getHashedSignaturePayloadEthSignedMessage,
8
+ getHashedSignaturePayloadTypedData,
9
9
  } from '@aztec/stdlib/p2p';
10
10
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
11
+ import { TEST_COORDINATION_SIGNATURE_CONTEXT } from '@aztec/stdlib/testing';
11
12
 
12
13
  import { type LocalAccount, generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
13
14
 
@@ -37,15 +38,19 @@ export const mockCheckpointAttestation = (
37
38
  feeAssetPriceModifier: bigint = 0n,
38
39
  ): CheckpointAttestation => {
39
40
  header = header ?? CheckpointHeader.random({ slotNumber: SlotNumber(slot) });
40
- const payload = new ConsensusPayload(header, archive, feeAssetPriceModifier);
41
+ const payload = new ConsensusPayload(header, archive, feeAssetPriceModifier, TEST_COORDINATION_SIGNATURE_CONTEXT);
41
42
 
42
- const attestationHash = getHashedSignaturePayloadEthSignedMessage(
43
- payload,
44
- SignatureDomainSeparator.checkpointAttestation,
45
- );
43
+ const attestationHash = getHashedSignaturePayloadTypedData(payload);
46
44
  const attestationSignature = signer.sign(attestationHash);
47
45
 
48
- const proposalHash = getHashedSignaturePayloadEthSignedMessage(payload, SignatureDomainSeparator.checkpointProposal);
46
+ const proposal = new CheckpointProposal(
47
+ header,
48
+ archive,
49
+ feeAssetPriceModifier,
50
+ attestationSignature,
51
+ TEST_COORDINATION_SIGNATURE_CONTEXT,
52
+ );
53
+ const proposalHash = getHashedSignaturePayloadTypedData(proposal);
49
54
  const proposerSignature = signer.sign(proposalHash);
50
55
 
51
56
  return new CheckpointAttestation(payload, attestationSignature, proposerSignature);
@@ -100,7 +100,11 @@ export class PoolInstrumentation<PoolObject extends Gossipable> {
100
100
 
101
101
  this.addObjectCounter = createUpDownCounterWithDefault(this.meter, metricsLabels.itemsAdded);
102
102
 
103
- this.minedDelay = this.meter.createHistogram(metricsLabels.itemMinedDelay);
103
+ this.minedDelay = this.meter.createHistogram(metricsLabels.itemMinedDelay, {
104
+ advice: {
105
+ explicitBucketBoundaries: [100, 500, 1000, 5000, 10000, 30000, 60000, 300000, 600000, 1800000, 3600000],
106
+ },
107
+ });
104
108
 
105
109
  this.meter.addBatchObservableCallback(this.observeStats, [this.objectsInMempool]);
106
110
  }
@@ -21,6 +21,7 @@ export { FeePayerBalancePreAddRule } from './fee_payer_balance_pre_add_rule.js';
21
21
  export { LowPriorityPreAddRule } from './low_priority_pre_add_rule.js';
22
22
 
23
23
  // Post-event eviction rules
24
+ export { InsufficientFeePerGasEvictionRule } from './insufficient_fee_per_gas_eviction_rule.js';
24
25
  export { InvalidTxsAfterMiningRule } from './invalid_txs_after_mining_rule.js';
25
26
  export { InvalidTxsAfterReorgRule } from './invalid_txs_after_reorg_rule.js';
26
27
  export { FeePayerBalanceEvictionRule } from './fee_payer_balance_eviction_rule.js';
@@ -0,0 +1,65 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import type { BlockMinFeesProvider } from '@aztec/stdlib/gas';
3
+
4
+ import type { EvictionContext, EvictionResult, EvictionRule, PoolOperations } from './interfaces.js';
5
+ import { EvictionEvent } from './interfaces.js';
6
+
7
+ /**
8
+ * Eviction rule that removes transactions whose maxFeesPerGas no longer meets
9
+ * the projected minimum gas fees after a new block is mined.
10
+ * Uses the BlockMinFeesProvider (forward-looking) to get the projected minimum fees.
11
+ * Only triggers on BLOCK_MINED events.
12
+ */
13
+ export class InsufficientFeePerGasEvictionRule implements EvictionRule {
14
+ public readonly name = 'InsufficientFeePerGas';
15
+
16
+ private log = createLogger('p2p:tx_pool_v2:insufficient_fee_per_gas_eviction_rule');
17
+
18
+ constructor(private blockMinFeesProvider: BlockMinFeesProvider) {}
19
+
20
+ async evict(context: EvictionContext, pool: PoolOperations): Promise<EvictionResult> {
21
+ if (context.event !== EvictionEvent.BLOCK_MINED) {
22
+ return {
23
+ reason: 'insufficient_fee_per_gas',
24
+ success: true,
25
+ txsEvicted: [],
26
+ };
27
+ }
28
+
29
+ try {
30
+ const gasFees = await this.blockMinFeesProvider.getCurrentMinFees();
31
+ const txsToEvict: string[] = [];
32
+ const pendingTxs = pool.getPendingTxs();
33
+
34
+ for (const meta of pendingTxs) {
35
+ const maxFeesPerGas = meta.data.constants.txContext.gasSettings.maxFeesPerGas;
36
+ if (maxFeesPerGas.feePerDaGas < gasFees.feePerDaGas || maxFeesPerGas.feePerL2Gas < gasFees.feePerL2Gas) {
37
+ this.log.verbose(`Evicting tx ${meta.txHash} from pool due to insufficient fee per gas`, {
38
+ txMaxFeesPerGas: maxFeesPerGas.toInspect(),
39
+ blockGasFees: gasFees.toInspect(),
40
+ });
41
+ txsToEvict.push(meta.txHash);
42
+ }
43
+ }
44
+
45
+ if (txsToEvict.length > 0) {
46
+ this.log.info(`Evicted ${txsToEvict.length} txs with insufficient fee per gas after block mined`);
47
+ await pool.deleteTxs(txsToEvict, this.name);
48
+ }
49
+
50
+ return {
51
+ reason: 'insufficient_fee_per_gas',
52
+ success: true,
53
+ txsEvicted: txsToEvict,
54
+ };
55
+ } catch (err) {
56
+ this.log.error('Failed to evict transactions with insufficient fee per gas', { err });
57
+ return {
58
+ reason: 'insufficient_fee_per_gas',
59
+ success: false,
60
+ txsEvicted: [],
61
+ error: new Error('Failed to evict txs with insufficient fee per gas', { cause: err }),
62
+ };
63
+ }
64
+ }
65
+ }