@aztec/p2p 4.0.0-devnet.1-patch.1 → 4.0.0-devnet.2-patch.0

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 (175) 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 +9 -5
  4. package/dest/client/interface.d.ts +8 -8
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +4 -6
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +46 -14
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -5
  10. package/dest/config.d.ts +10 -1
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +5 -0
  13. package/dest/errors/tx-pool.error.d.ts +8 -0
  14. package/dest/errors/tx-pool.error.d.ts.map +1 -0
  15. package/dest/errors/tx-pool.error.js +9 -0
  16. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -2
  17. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  18. package/dest/mem_pools/attestation_pool/attestation_pool.js +5 -0
  19. package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
  20. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  21. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  22. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
  23. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +30 -13
  24. package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
  25. package/dest/mem_pools/tx_pool_v2/deleted_pool.js +91 -20
  26. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
  27. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
  29. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
  30. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +4 -1
  32. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
  33. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +10 -4
  35. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
  36. package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
  38. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +48 -5
  39. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
  41. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
  42. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +5 -3
  43. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +1 -1
  44. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  45. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +8 -4
  46. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
  47. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  48. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +14 -4
  49. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
  50. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  51. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
  52. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
  53. package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
  54. package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
  55. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +14 -2
  56. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  57. package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
  58. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +9 -5
  59. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  60. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +30 -5
  61. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
  62. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  63. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +27 -4
  64. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +8 -3
  65. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  66. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +11 -6
  67. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -4
  68. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  69. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +164 -37
  70. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +2 -2
  71. package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
  72. package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
  73. package/dest/services/encoding.d.ts +1 -1
  74. package/dest/services/encoding.d.ts.map +1 -1
  75. package/dest/services/encoding.js +2 -1
  76. package/dest/services/libp2p/libp2p_service.js +2 -2
  77. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
  78. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  79. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +5 -9
  80. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
  81. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  82. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
  83. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  84. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
  85. package/dest/services/tx_collection/config.d.ts +13 -1
  86. package/dest/services/tx_collection/config.d.ts.map +1 -1
  87. package/dest/services/tx_collection/config.js +30 -0
  88. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -1
  89. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  90. package/dest/services/tx_collection/fast_tx_collection.js +39 -33
  91. package/dest/services/tx_collection/file_store_tx_collection.d.ts +38 -29
  92. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  93. package/dest/services/tx_collection/file_store_tx_collection.js +126 -77
  94. package/dest/services/tx_collection/file_store_tx_source.d.ts +16 -6
  95. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  96. package/dest/services/tx_collection/file_store_tx_source.js +49 -16
  97. package/dest/services/tx_collection/instrumentation.d.ts +1 -1
  98. package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
  99. package/dest/services/tx_collection/instrumentation.js +2 -1
  100. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  101. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  102. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  103. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
  104. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  105. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  106. package/dest/services/tx_collection/slow_tx_collection.d.ts +5 -3
  107. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  108. package/dest/services/tx_collection/slow_tx_collection.js +17 -12
  109. package/dest/services/tx_collection/tx_collection.d.ts +9 -6
  110. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  111. package/dest/services/tx_collection/tx_collection.js +26 -10
  112. package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
  113. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  114. package/dest/services/tx_collection/tx_collection_sink.js +13 -22
  115. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  116. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  117. package/dest/services/tx_collection/tx_source.js +19 -2
  118. package/dest/services/tx_file_store/tx_file_store.d.ts +3 -2
  119. package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
  120. package/dest/services/tx_file_store/tx_file_store.js +9 -6
  121. package/dest/test-helpers/testbench-utils.d.ts +7 -2
  122. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  123. package/dest/test-helpers/testbench-utils.js +7 -1
  124. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  125. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  126. package/dest/testbench/p2p_client_testbench_worker.js +8 -8
  127. package/package.json +14 -14
  128. package/src/client/factory.ts +18 -3
  129. package/src/client/interface.ts +10 -8
  130. package/src/client/p2p_client.ts +52 -17
  131. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +18 -8
  132. package/src/config.ts +8 -0
  133. package/src/errors/tx-pool.error.ts +12 -0
  134. package/src/mem_pools/attestation_pool/attestation_pool.ts +8 -0
  135. package/src/mem_pools/attestation_pool/mocks.ts +2 -1
  136. package/src/mem_pools/tx_pool/README.md +1 -1
  137. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
  138. package/src/mem_pools/tx_pool_v2/README.md +43 -27
  139. package/src/mem_pools/tx_pool_v2/deleted_pool.ts +109 -22
  140. package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
  141. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +4 -1
  142. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +15 -4
  143. package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
  144. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +49 -4
  145. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
  146. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
  147. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +8 -7
  148. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +24 -6
  149. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +3 -3
  150. package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
  151. package/src/mem_pools/tx_pool_v2/interfaces.ts +14 -2
  152. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +44 -9
  153. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +32 -5
  154. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +17 -6
  155. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +186 -29
  156. package/src/msg_validators/tx_validator/timestamp_validator.ts +7 -7
  157. package/src/services/encoding.ts +2 -1
  158. package/src/services/libp2p/libp2p_service.ts +2 -2
  159. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +6 -6
  160. package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
  161. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
  162. package/src/services/tx_collection/config.ts +42 -0
  163. package/src/services/tx_collection/fast_tx_collection.ts +51 -30
  164. package/src/services/tx_collection/file_store_tx_collection.ts +143 -93
  165. package/src/services/tx_collection/file_store_tx_source.ts +64 -17
  166. package/src/services/tx_collection/instrumentation.ts +7 -1
  167. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  168. package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
  169. package/src/services/tx_collection/slow_tx_collection.ts +17 -13
  170. package/src/services/tx_collection/tx_collection.ts +45 -14
  171. package/src/services/tx_collection/tx_collection_sink.ts +15 -29
  172. package/src/services/tx_collection/tx_source.ts +22 -3
  173. package/src/services/tx_file_store/tx_file_store.ts +6 -4
  174. package/src/test-helpers/testbench-utils.ts +10 -2
  175. package/src/testbench/p2p_client_testbench_worker.ts +20 -13
@@ -7,7 +7,8 @@ import { DateProvider } from '@aztec/foundation/timer';
7
7
  import type { L2Block, L2BlockInfo } from '@aztec/stdlib/block';
8
8
  import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
9
9
  import type { BlockProposal } from '@aztec/stdlib/p2p';
10
- import { Tx, TxHash } from '@aztec/stdlib/tx';
10
+ import type { Tx } from '@aztec/stdlib/tx';
11
+ import { TxHash } from '@aztec/stdlib/tx';
11
12
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
12
13
 
13
14
  import type { PeerId } from '@libp2p/interface';
@@ -18,7 +19,8 @@ import type { TxCollectionConfig } from './config.js';
18
19
  import { FastTxCollection } from './fast_tx_collection.js';
19
20
  import { FileStoreTxCollection } from './file_store_tx_collection.js';
20
21
  import type { FileStoreTxSource } from './file_store_tx_source.js';
21
- import { SlowTxCollection } from './slow_tx_collection.js';
22
+ import type { IMissingTxsTracker } from './missing_txs_tracker.js';
23
+ import { SlowTxCollection, getProofDeadlineForSlot } from './slow_tx_collection.js';
22
24
  import { type TxAddContext, TxCollectionSink } from './tx_collection_sink.js';
23
25
  import type { TxSource } from './tx_source.js';
24
26
 
@@ -31,11 +33,10 @@ export type FastCollectionRequestInput =
31
33
  | { type: 'proposal'; blockProposal: BlockProposal; blockNumber: BlockNumber };
32
34
 
33
35
  export type FastCollectionRequest = FastCollectionRequestInput & {
34
- missingTxHashes: Set<string>;
36
+ missingTxTracker: IMissingTxsTracker;
35
37
  deadline: Date;
36
38
  blockInfo: L2BlockInfo;
37
39
  promise: PromiseWithResolvers<void>;
38
- foundTxs: Map<string, Tx>;
39
40
  };
40
41
 
41
42
  /**
@@ -56,8 +57,11 @@ export class TxCollection {
56
57
  /** Fast collection methods */
57
58
  protected readonly fastCollection: FastTxCollection;
58
59
 
59
- /** File store collection */
60
- protected readonly fileStoreCollection: FileStoreTxCollection;
60
+ /** File store collection for slow (mined block) path */
61
+ protected readonly fileStoreSlowCollection: FileStoreTxCollection;
62
+
63
+ /** File store collection for fast (proposal/proving) path */
64
+ protected readonly fileStoreFastCollection: FileStoreTxCollection;
61
65
 
62
66
  /** Loop for periodically reconciling found transactions from the tx pool in case we missed some */
63
67
  private readonly reconcileFoundTxsLoop: RunningPromise;
@@ -111,7 +115,28 @@ export class TxCollection {
111
115
  );
112
116
 
113
117
  this.hasFileStoreSources = fileStoreSources.length > 0;
114
- this.fileStoreCollection = new FileStoreTxCollection(fileStoreSources, this.txCollectionSink, this.log);
118
+ this.fileStoreSlowCollection = new FileStoreTxCollection(
119
+ fileStoreSources,
120
+ this.txCollectionSink,
121
+ {
122
+ workerCount: config.txCollectionFileStoreSlowWorkerCount,
123
+ backoffBaseMs: config.txCollectionFileStoreSlowBackoffBaseMs,
124
+ backoffMaxMs: config.txCollectionFileStoreSlowBackoffMaxMs,
125
+ },
126
+ this.dateProvider,
127
+ this.log,
128
+ );
129
+ this.fileStoreFastCollection = new FileStoreTxCollection(
130
+ fileStoreSources,
131
+ this.txCollectionSink,
132
+ {
133
+ workerCount: config.txCollectionFileStoreFastWorkerCount,
134
+ backoffBaseMs: config.txCollectionFileStoreFastBackoffBaseMs,
135
+ backoffMaxMs: config.txCollectionFileStoreFastBackoffMaxMs,
136
+ },
137
+ this.dateProvider,
138
+ this.log,
139
+ );
115
140
 
116
141
  this.reconcileFoundTxsLoop = new RunningPromise(
117
142
  () => this.reconcileFoundTxsWithPool(),
@@ -137,7 +162,8 @@ export class TxCollection {
137
162
  public start(): Promise<void> {
138
163
  this.started = true;
139
164
  this.slowCollection.start();
140
- this.fileStoreCollection.start();
165
+ this.fileStoreSlowCollection.start();
166
+ this.fileStoreFastCollection.start();
141
167
  this.reconcileFoundTxsLoop.start();
142
168
 
143
169
  // TODO(palla/txs): Collect mined unproven tx hashes for txs we dont have in the pool and populate missingTxs on startup
@@ -150,7 +176,8 @@ export class TxCollection {
150
176
  await Promise.all([
151
177
  this.slowCollection.stop(),
152
178
  this.fastCollection.stop(),
153
- this.fileStoreCollection.stop(),
179
+ this.fileStoreSlowCollection.stop(),
180
+ this.fileStoreFastCollection.stop(),
154
181
  this.reconcileFoundTxsLoop.stop(),
155
182
  ]);
156
183
 
@@ -175,6 +202,7 @@ export class TxCollection {
175
202
  // Delay file store collection to give P2P methods time to find txs first
176
203
  if (this.hasFileStoreSources) {
177
204
  const context: TxAddContext = { type: 'mined', block };
205
+ const deadline = getProofDeadlineForSlot(block.header.getSlot(), this.constants);
178
206
  sleep(this.config.txCollectionFileStoreSlowDelayMs)
179
207
  .then(() => {
180
208
  if (this.started) {
@@ -182,7 +210,7 @@ export class TxCollection {
182
210
  const stillMissing = new Set(this.slowCollection.getMissingTxHashes().map(h => h.toString()));
183
211
  const remaining = txHashes.filter(h => stillMissing.has(h.toString()));
184
212
  if (remaining.length > 0) {
185
- this.fileStoreCollection.startCollecting(remaining, context);
213
+ this.fileStoreSlowCollection.startCollecting(remaining, context, deadline);
186
214
  }
187
215
  }
188
216
  })
@@ -223,7 +251,7 @@ export class TxCollection {
223
251
  sleep(this.config.txCollectionFileStoreFastDelayMs)
224
252
  .then(() => {
225
253
  if (this.started) {
226
- this.fileStoreCollection.startCollecting(hashes, context);
254
+ this.fileStoreFastCollection.startCollecting(hashes, context, opts.deadline);
227
255
  }
228
256
  })
229
257
  .catch(err => this.log.error('Error in file store fast delay', err));
@@ -245,7 +273,8 @@ export class TxCollection {
245
273
  private foundTxs(txs: Tx[]) {
246
274
  this.slowCollection.foundTxs(txs);
247
275
  this.fastCollection.foundTxs(txs);
248
- this.fileStoreCollection.foundTxs(txs);
276
+ this.fileStoreSlowCollection.foundTxs(txs);
277
+ this.fileStoreFastCollection.foundTxs(txs);
249
278
  }
250
279
 
251
280
  /**
@@ -255,7 +284,8 @@ export class TxCollection {
255
284
  public stopCollectingForBlocksUpTo(blockNumber: BlockNumber): void {
256
285
  this.slowCollection.stopCollectingForBlocksUpTo(blockNumber);
257
286
  this.fastCollection.stopCollectingForBlocksUpTo(blockNumber);
258
- this.fileStoreCollection.clearPending();
287
+ this.fileStoreSlowCollection.clearPending();
288
+ this.fileStoreFastCollection.clearPending();
259
289
  }
260
290
 
261
291
  /**
@@ -265,7 +295,8 @@ export class TxCollection {
265
295
  public stopCollectingForBlocksAfter(blockNumber: BlockNumber): void {
266
296
  this.slowCollection.stopCollectingForBlocksAfter(blockNumber);
267
297
  this.fastCollection.stopCollectingForBlocksAfter(blockNumber);
268
- this.fileStoreCollection.clearPending();
298
+ this.fileStoreSlowCollection.clearPending();
299
+ this.fileStoreFastCollection.clearPending();
269
300
  }
270
301
 
271
302
  /** Every now and then, check if the pool has received one of the txs we are looking for, just to catch any race conditions */
@@ -2,14 +2,15 @@ import type { Logger } from '@aztec/foundation/log';
2
2
  import { elapsed } from '@aztec/foundation/timer';
3
3
  import type { TypedEventEmitter } from '@aztec/foundation/types';
4
4
  import type { L2Block } from '@aztec/stdlib/block';
5
- import type { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
5
+ import type { BlockHeader, Tx } from '@aztec/stdlib/tx';
6
6
  import type { TelemetryClient } from '@aztec/telemetry-client';
7
7
 
8
8
  import EventEmitter from 'node:events';
9
9
 
10
- import type { TxPoolV2, TxPoolV2Events } from '../../mem_pools/tx_pool_v2/interfaces.js';
10
+ import type { TxPoolV2, TxPoolV2Events } from '../../mem_pools/index.js';
11
11
  import { TxCollectionInstrumentation } from './instrumentation.js';
12
12
  import type { CollectionMethod } from './tx_collection.js';
13
+ import type { TxSourceCollectionResult } from './tx_source.js';
13
14
 
14
15
  /** Context determining how collected txs should be added to the pool. */
15
16
  export type TxAddContext = { type: 'proposal'; blockHeader: BlockHeader } | { type: 'mined'; block: L2Block };
@@ -31,52 +32,37 @@ export class TxCollectionSink extends (EventEmitter as new () => TypedEventEmitt
31
32
  }
32
33
 
33
34
  public async collect(
34
- collectValidTxsFn: (txHashes: TxHash[]) => Promise<(Tx | undefined)[]>,
35
- requested: TxHash[],
35
+ collectValidTxsFn: () => Promise<TxSourceCollectionResult>,
36
+ requested: string[],
36
37
  info: Record<string, any> & { description: string; method: CollectionMethod },
37
38
  context: TxAddContext,
38
39
  ) {
39
40
  this.log.trace(`Requesting ${requested.length} txs via ${info.description}`, {
40
41
  ...info,
41
- requestedTxs: requested.map(t => t.toString()),
42
+ requestedTxs: requested,
42
43
  });
43
44
 
44
45
  // Execute collection function and measure the time taken, catching any errors.
45
- const [duration, txs] = await elapsed(async () => {
46
+ const [duration, { validTxs, invalidTxHashes }] = await elapsed(async () => {
46
47
  try {
47
- const response = await collectValidTxsFn(requested);
48
- return response.filter(tx => tx !== undefined);
48
+ return await collectValidTxsFn();
49
49
  } catch (err) {
50
50
  this.log.error(`Error collecting txs via ${info.description}`, err, {
51
51
  ...info,
52
- requestedTxs: requested.map(hash => hash.toString()),
52
+ requestedTxs: requested,
53
53
  });
54
- return [] as Tx[];
54
+ return { validTxs: [] as Tx[], invalidTxHashes: [] as string[] };
55
55
  }
56
56
  });
57
57
 
58
- if (txs.length === 0) {
58
+ if (validTxs.length === 0 && invalidTxHashes.length === 0) {
59
59
  this.log.trace(`No txs found via ${info.description}`, {
60
60
  ...info,
61
- requestedTxs: requested.map(t => t.toString()),
61
+ requestedTxs: requested,
62
62
  });
63
- return { txs, requested, duration };
63
+ return { txs: validTxs, requested, duration };
64
64
  }
65
65
 
66
- // Validate tx hashes for all collected txs from external sources
67
- const validTxs: Tx[] = [];
68
- const invalidTxHashes: string[] = [];
69
- await Promise.all(
70
- txs.map(async tx => {
71
- const isValid = await tx.validateTxHash();
72
- if (isValid) {
73
- validTxs.push(tx);
74
- } else {
75
- invalidTxHashes.push(tx.getTxHash().toString());
76
- }
77
- }),
78
- );
79
-
80
66
  if (invalidTxHashes.length > 0) {
81
67
  this.log.warn(`Rejecting ${invalidTxHashes.length} txs with invalid hashes from ${info.description}`, {
82
68
  ...info,
@@ -87,7 +73,7 @@ export class TxCollectionSink extends (EventEmitter as new () => TypedEventEmitt
87
73
  if (validTxs.length === 0) {
88
74
  this.log.trace(`No valid txs found via ${info.description} after validation`, {
89
75
  ...info,
90
- requestedTxs: requested.map(t => t.toString()),
76
+ requestedTxs: requested,
91
77
  invalidTxHashes,
92
78
  });
93
79
  return { txs: [], requested, duration };
@@ -99,7 +85,7 @@ export class TxCollectionSink extends (EventEmitter as new () => TypedEventEmitt
99
85
  ...info,
100
86
  duration,
101
87
  txs: validTxs.map(t => t.getTxHash().toString()),
102
- requestedTxs: requested.map(t => t.toString()),
88
+ requestedTxs: requested,
103
89
  rejectedCount: invalidTxHashes.length,
104
90
  },
105
91
  );
@@ -6,9 +6,11 @@ import type { Tx, TxHash } from '@aztec/stdlib/tx';
6
6
  import { type ComponentsVersions, getComponentsVersionsFromConfig } from '@aztec/stdlib/versioning';
7
7
  import { makeTracedFetch } from '@aztec/telemetry-client';
8
8
 
9
+ export type TxSourceCollectionResult = { validTxs: Tx[]; invalidTxHashes: string[] };
10
+
9
11
  export interface TxSource {
10
12
  getInfo(): string;
11
- getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]>;
13
+ getTxsByHash(txHashes: TxHash[]): Promise<TxSourceCollectionResult>;
12
14
  }
13
15
 
14
16
  export class NodeRpcTxSource implements TxSource {
@@ -26,8 +28,25 @@ export class NodeRpcTxSource implements TxSource {
26
28
  return this.info;
27
29
  }
28
30
 
29
- public getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
30
- return this.client.getTxsByHash(txHashes);
31
+ public async getTxsByHash(txHashes: TxHash[]): Promise<TxSourceCollectionResult> {
32
+ return this.verifyTxs(await this.client.getTxsByHash(txHashes));
33
+ }
34
+
35
+ private async verifyTxs(txs: Tx[]): Promise<TxSourceCollectionResult> {
36
+ // Validate tx hashes for all collected txs from external sources
37
+ const validTxs: Tx[] = [];
38
+ const invalidTxHashes: string[] = [];
39
+ await Promise.all(
40
+ txs.map(async tx => {
41
+ const isValid = await tx.validateTxHash();
42
+ if (isValid) {
43
+ validTxs.push(tx);
44
+ } else {
45
+ invalidTxHashes.push(tx.getTxHash().toString());
46
+ }
47
+ }),
48
+ );
49
+ return { validTxs: validTxs, invalidTxHashes: invalidTxHashes };
31
50
  }
32
51
  }
33
52
 
@@ -31,6 +31,7 @@ export class TxFileStore {
31
31
  private readonly config: TxFileStoreConfig,
32
32
  private readonly instrumentation: TxFileStoreInstrumentation,
33
33
  private readonly log: Logger,
34
+ private readonly basePath: string,
34
35
  ) {
35
36
  this.handleTxsAdded = (args: { txs: Tx[]; source?: string }) => {
36
37
  this.enqueueTxs(args.txs);
@@ -50,6 +51,7 @@ export class TxFileStore {
50
51
  static async create(
51
52
  txPool: TxPoolV2,
52
53
  config: TxFileStoreConfig,
54
+ basePath: string,
53
55
  log: Logger = createLogger('p2p:tx_file_store'),
54
56
  telemetry: TelemetryClient = getTelemetryClient(),
55
57
  fileStoreOverride?: FileStore,
@@ -71,8 +73,8 @@ export class TxFileStore {
71
73
  }
72
74
 
73
75
  const instrumentation = new TxFileStoreInstrumentation(telemetry, 'TxFileStore');
74
- log.info('Created tx file store', { url: config.txFileStoreUrl });
75
- return new TxFileStore(fileStore, txPool, config, instrumentation, log);
76
+ log.info('Created tx file store', { url: config.txFileStoreUrl, basePath });
77
+ return new TxFileStore(fileStore, txPool, config, instrumentation, log, basePath);
76
78
  }
77
79
 
78
80
  /** Starts listening to TxPool events and uploading txs. */
@@ -122,7 +124,7 @@ export class TxFileStore {
122
124
 
123
125
  private async uploadTx(tx: Tx): Promise<void> {
124
126
  const txHash = tx.getTxHash().toString();
125
- const path = `txs/${txHash}.bin`;
127
+ const path = `${this.basePath}/txs/${txHash}.bin`;
126
128
  const timer = new Timer();
127
129
 
128
130
  if (this.recentUploads.has(txHash)) {
@@ -144,7 +146,7 @@ export class TxFileStore {
144
146
  }
145
147
 
146
148
  await retry(
147
- () => this.fileStore.save(path, tx.toBuffer(), { compress: false }),
149
+ () => this.fileStore.save(path, tx.toBuffer(), { compress: true }),
148
150
  `Uploading tx ${txHash}`,
149
151
  makeBackoff([0.1, 0.5, 2]),
150
152
  this.log,
@@ -59,7 +59,7 @@ export class InMemoryTxPool extends EventEmitter implements TxPoolV2 {
59
59
 
60
60
  // === Core Operations (TxPoolV2) ===
61
61
 
62
- addPendingTxs(txs: Tx[], opts?: { source?: string }): Promise<AddTxsResult> {
62
+ addPendingTxs(txs: Tx[], opts?: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult> {
63
63
  const accepted: TxHash[] = [];
64
64
  const newTxs: Tx[] = [];
65
65
  for (const tx of txs) {
@@ -123,7 +123,7 @@ export class InMemoryTxPool extends EventEmitter implements TxPoolV2 {
123
123
  return Promise.resolve();
124
124
  }
125
125
 
126
- handlePrunedBlocks(_latestBlock: L2BlockId): Promise<void> {
126
+ handlePrunedBlocks(_latestBlock: L2BlockId, _options?: { deleteAllTxs?: boolean }): Promise<void> {
127
127
  return Promise.resolve();
128
128
  }
129
129
 
@@ -163,6 +163,10 @@ export class InMemoryTxPool extends EventEmitter implements TxPoolV2 {
163
163
  return Promise.resolve([...this.txsByHash.keys()].map(key => TxHash.fromString(key)));
164
164
  }
165
165
 
166
+ getEligiblePendingTxHashes(): Promise<TxHash[]> {
167
+ return this.getPendingTxHashes();
168
+ }
169
+
166
170
  getPendingTxCount(): Promise<number> {
167
171
  return Promise.resolve(this.txsByHash.size);
168
172
  }
@@ -252,6 +256,10 @@ export class InMemoryAttestationPool {
252
256
  return Promise.resolve({ added: true, alreadyExists: false, count: 1 });
253
257
  }
254
258
 
259
+ hasBlockProposalsForSlot(_slot: SlotNumber): Promise<boolean> {
260
+ return Promise.resolve(false);
261
+ }
262
+
255
263
  isEmpty(): Promise<boolean> {
256
264
  return Promise.resolve(this.proposals.size === 0);
257
265
  }
@@ -29,22 +29,19 @@ import type { Message, PeerId } from '@libp2p/interface';
29
29
  import { TopicValidatorResult } from '@libp2p/interface';
30
30
  import { peerIdFromString } from '@libp2p/peer-id';
31
31
 
32
- import type { P2PClient } from '../client/p2p_client.js';
32
+ import type { P2PClient } from '../client/index.js';
33
33
  import type { P2PConfig } from '../config.js';
34
34
  import { createP2PClient } from '../index.js';
35
- import type { MemPools } from '../mem_pools/interface.js';
36
- import { LibP2PService } from '../services/libp2p/libp2p_service.js';
35
+ import type { MemPools } from '../mem_pools/index.js';
36
+ import { BatchTxRequesterCollector, LibP2PService, SendBatchRequestCollector } from '../services/index.js';
37
37
  import type { PeerManager } from '../services/peer-manager/peer_manager.js';
38
38
  import type { BatchTxRequesterLibP2PService } from '../services/reqresp/batch-tx-requester/interface.js';
39
39
  import type { IBatchRequestTxValidator } from '../services/reqresp/batch-tx-requester/tx_validator.js';
40
40
  import { RateLimitStatus } from '../services/reqresp/rate-limiter/rate_limiter.js';
41
41
  import type { ReqResp } from '../services/reqresp/reqresp.js';
42
42
  import type { PeerDiscoveryService } from '../services/service.js';
43
- import {
44
- BatchTxRequesterCollector,
45
- SendBatchRequestCollector,
46
- } from '../services/tx_collection/proposal_tx_collector.js';
47
- import { AlwaysTrueCircuitVerifier } from '../test-helpers/reqresp-nodes.js';
43
+ import { MissingTxsTracker } from '../services/tx_collection/missing_txs_tracker.js';
44
+ import { AlwaysTrueCircuitVerifier } from '../test-helpers/index.js';
48
45
  import {
49
46
  BENCHMARK_CONSTANTS,
50
47
  type CollectorType,
@@ -55,7 +52,7 @@ import {
55
52
  createMockEpochCache,
56
53
  createMockWorldStateSynchronizer,
57
54
  filterTxsByDistribution,
58
- } from '../test-helpers/testbench-utils.js';
55
+ } from '../test-helpers/index.js';
59
56
  import type { PubSubLibp2p } from '../util.js';
60
57
 
61
58
  export type { DistributionPattern, CollectorType } from '../test-helpers/testbench-utils.js';
@@ -166,7 +163,7 @@ async function generateDeterministicTxs(txCount: number, seed: number, config: P
166
163
  return cached.slice(0, txCount);
167
164
  }
168
165
 
169
- const includeByTimestampBase = BigInt(seed);
166
+ const expirationTimestampBase = BigInt(seed);
170
167
  for (let i = cached.length; i < txCount; i++) {
171
168
  const txSeed = seed * 10000 + i;
172
169
  const tx = await mockTx(txSeed, {
@@ -182,7 +179,7 @@ async function generateDeterministicTxs(txCount: number, seed: number, config: P
182
179
  hasPublicTeardownCallRequest: false,
183
180
  publicCalldataSize: 0,
184
181
  });
185
- tx.data.includeByTimestamp = includeByTimestampBase + BigInt(i);
182
+ tx.data.expirationTimestamp = expirationTimestampBase + BigInt(i);
186
183
  await tx.recomputeHash();
187
184
  cached.push(tx);
188
185
  }
@@ -277,7 +274,12 @@ async function runAggregatorBenchmark(
277
274
  new DateProvider(),
278
275
  noopTxValidator,
279
276
  );
280
- const fetchedTxs = await collector.collectTxs(txHashes, blockProposal, pinnedPeer, timeoutMs);
277
+ const fetchedTxs = await collector.collectTxs(
278
+ MissingTxsTracker.fromArray(txHashes),
279
+ blockProposal,
280
+ pinnedPeer,
281
+ timeoutMs,
282
+ );
281
283
  const durationMs = timer.ms();
282
284
  return {
283
285
  type: 'BENCH_RESULT',
@@ -292,7 +294,12 @@ async function runAggregatorBenchmark(
292
294
  BENCHMARK_CONSTANTS.FIXED_MAX_PEERS,
293
295
  BENCHMARK_CONSTANTS.FIXED_MAX_RETRY_ATTEMPTS,
294
296
  );
295
- const fetchedTxs = await collector.collectTxs(txHashes, blockProposal, pinnedPeer, timeoutMs);
297
+ const fetchedTxs = await collector.collectTxs(
298
+ MissingTxsTracker.fromArray(txHashes),
299
+ blockProposal,
300
+ pinnedPeer,
301
+ timeoutMs,
302
+ );
296
303
  const durationMs = timer.ms();
297
304
  return {
298
305
  type: 'BENCH_RESULT',