@aztec/p2p 0.0.1-commit.9ef841308 → 0.0.1-commit.a89ec08

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 (207) 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 -2
  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 +4 -6
  7. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -17
  8. package/dest/config.d.ts +6 -6
  9. package/dest/config.d.ts.map +1 -1
  10. package/dest/config.js +6 -6
  11. package/dest/index.d.ts +2 -1
  12. package/dest/index.d.ts.map +1 -1
  13. package/dest/index.js +1 -0
  14. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
  15. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  16. package/dest/mem_pools/attestation_pool/attestation_pool.js +4 -8
  17. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  18. package/dest/mem_pools/index.d.ts +2 -1
  19. package/dest/mem_pools/index.d.ts.map +1 -1
  20. package/dest/mem_pools/instrumentation.d.ts +2 -4
  21. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  22. package/dest/mem_pools/instrumentation.js +14 -16
  23. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +125 -0
  24. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -0
  25. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +596 -0
  26. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +32 -0
  27. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
  28. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +112 -0
  29. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +157 -0
  30. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
  31. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +52 -0
  32. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
  33. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
  34. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +123 -0
  35. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
  36. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
  37. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
  38. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
  39. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
  40. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +78 -0
  41. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
  42. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
  43. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
  44. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
  45. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
  46. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
  47. package/dest/mem_pools/tx_pool/index.d.ts +3 -0
  48. package/dest/mem_pools/tx_pool/index.d.ts.map +1 -0
  49. package/dest/mem_pools/tx_pool/index.js +2 -0
  50. package/dest/mem_pools/tx_pool/priority.d.ts +12 -0
  51. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -0
  52. package/dest/mem_pools/tx_pool/priority.js +15 -0
  53. package/dest/mem_pools/tx_pool/tx_pool.d.ts +127 -0
  54. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -0
  55. package/dest/mem_pools/tx_pool/tx_pool.js +3 -0
  56. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +7 -0
  57. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -0
  58. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +402 -0
  59. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +5 -7
  60. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  61. package/dest/mem_pools/tx_pool_v2/interfaces.js +0 -1
  62. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +6 -5
  63. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  64. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +1 -5
  65. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  66. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  67. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +43 -26
  68. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +1 -1
  69. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  70. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +0 -3
  71. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -2
  72. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  73. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +1 -18
  74. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
  75. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  76. package/dest/msg_validators/attestation_validator/attestation_validator.js +4 -5
  77. package/dest/msg_validators/clock_tolerance.d.ts +1 -1
  78. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  79. package/dest/msg_validators/clock_tolerance.js +3 -4
  80. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +1 -1
  81. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  82. package/dest/msg_validators/proposal_validator/proposal_validator.js +5 -5
  83. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  84. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  85. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  86. package/dest/services/discv5/discV5_service.d.ts +1 -1
  87. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  88. package/dest/services/discv5/discV5_service.js +2 -4
  89. package/dest/services/libp2p/libp2p_service.d.ts +9 -7
  90. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  91. package/dest/services/libp2p/libp2p_service.js +59 -137
  92. package/dest/services/peer-manager/metrics.d.ts +1 -3
  93. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  94. package/dest/services/peer-manager/metrics.js +0 -6
  95. package/dest/services/peer-manager/peer_manager.d.ts +2 -6
  96. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  97. package/dest/services/peer-manager/peer_manager.js +9 -24
  98. package/dest/services/peer-manager/peer_scoring.d.ts +2 -5
  99. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  100. package/dest/services/peer-manager/peer_scoring.js +10 -28
  101. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +8 -11
  102. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  103. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +101 -82
  104. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -3
  105. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  106. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +4 -5
  107. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  108. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +7 -13
  109. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +11 -19
  110. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  111. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +15 -52
  112. package/dest/services/reqresp/reqresp.d.ts +1 -1
  113. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  114. package/dest/services/reqresp/reqresp.js +3 -4
  115. package/dest/services/service.d.ts +1 -7
  116. package/dest/services/service.d.ts.map +1 -1
  117. package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -1
  118. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  119. package/dest/services/tx_collection/fast_tx_collection.js +73 -57
  120. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  121. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  122. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  123. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
  124. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  125. package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
  126. package/dest/services/tx_collection/slow_tx_collection.js +1 -1
  127. package/dest/services/tx_collection/tx_collection.d.ts +6 -3
  128. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  129. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  130. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  131. package/dest/test-helpers/mock-pubsub.d.ts +1 -6
  132. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  133. package/dest/test-helpers/mock-pubsub.js +1 -9
  134. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  135. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  136. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  137. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  138. package/dest/test-helpers/testbench-utils.js +2 -20
  139. package/dest/testbench/p2p_client_testbench_worker.js +15 -44
  140. package/dest/testbench/worker_client_manager.d.ts +1 -1
  141. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  142. package/dest/testbench/worker_client_manager.js +2 -2
  143. package/dest/util.d.ts +4 -9
  144. package/dest/util.d.ts.map +1 -1
  145. package/dest/util.js +9 -2
  146. package/package.json +14 -14
  147. package/src/client/factory.ts +2 -3
  148. package/src/client/p2p_client.ts +4 -6
  149. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +9 -19
  150. package/src/config.ts +10 -10
  151. package/src/index.ts +1 -0
  152. package/src/mem_pools/attestation_pool/attestation_pool.ts +7 -8
  153. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  154. package/src/mem_pools/index.ts +3 -0
  155. package/src/mem_pools/instrumentation.ts +13 -17
  156. package/src/mem_pools/tx_pool/README.md +270 -0
  157. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +746 -0
  158. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +132 -0
  159. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +208 -0
  160. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +163 -0
  161. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
  162. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +93 -0
  163. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
  164. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
  165. package/src/mem_pools/tx_pool/index.ts +2 -0
  166. package/src/mem_pools/tx_pool/priority.ts +20 -0
  167. package/src/mem_pools/tx_pool/tx_pool.ts +141 -0
  168. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +321 -0
  169. package/src/mem_pools/tx_pool_v2/interfaces.ts +4 -7
  170. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +5 -11
  171. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -29
  172. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +0 -3
  173. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1 -19
  174. package/src/msg_validators/attestation_validator/README.md +1 -1
  175. package/src/msg_validators/attestation_validator/attestation_validator.ts +4 -5
  176. package/src/msg_validators/clock_tolerance.ts +3 -4
  177. package/src/msg_validators/proposal_validator/README.md +4 -4
  178. package/src/msg_validators/proposal_validator/proposal_validator.ts +5 -6
  179. package/src/msg_validators/tx_validator/metadata_validator.ts +4 -12
  180. package/src/services/discv5/discV5_service.ts +2 -4
  181. package/src/services/libp2p/libp2p_service.ts +71 -135
  182. package/src/services/peer-manager/metrics.ts +0 -7
  183. package/src/services/peer-manager/peer_manager.ts +9 -28
  184. package/src/services/peer-manager/peer_scoring.ts +5 -21
  185. package/src/services/reqresp/batch-tx-requester/README.md +7 -46
  186. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +111 -78
  187. package/src/services/reqresp/batch-tx-requester/interface.ts +1 -2
  188. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +6 -13
  189. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +24 -68
  190. package/src/services/reqresp/reqresp.ts +3 -5
  191. package/src/services/service.ts +0 -7
  192. package/src/services/tx_collection/fast_tx_collection.ts +83 -57
  193. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  194. package/src/services/tx_collection/proposal_tx_collector.ts +13 -8
  195. package/src/services/tx_collection/slow_tx_collection.ts +1 -1
  196. package/src/services/tx_collection/tx_collection.ts +5 -3
  197. package/src/test-helpers/make-test-p2p-clients.ts +1 -1
  198. package/src/test-helpers/mock-pubsub.ts +0 -9
  199. package/src/test-helpers/reqresp-nodes.ts +1 -1
  200. package/src/test-helpers/testbench-utils.ts +3 -28
  201. package/src/testbench/p2p_client_testbench_worker.ts +15 -44
  202. package/src/testbench/worker_client_manager.ts +2 -2
  203. package/src/util.ts +13 -9
  204. package/dest/services/tx_collection/request_tracker.d.ts +0 -53
  205. package/dest/services/tx_collection/request_tracker.d.ts.map +0 -1
  206. package/dest/services/tx_collection/request_tracker.js +0 -84
  207. package/src/services/tx_collection/request_tracker.ts +0 -127
@@ -1,7 +1,7 @@
1
1
  import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { compactArray } from '@aztec/foundation/collection';
3
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
4
- import { RunningPromise } from '@aztec/foundation/promise';
4
+ import { type PromiseWithResolvers, RunningPromise } from '@aztec/foundation/promise';
5
5
  import { sleep } from '@aztec/foundation/sleep';
6
6
  import { DateProvider } from '@aztec/foundation/timer';
7
7
  import type { L2Block, L2BlockInfo } from '@aztec/stdlib/block';
@@ -19,7 +19,7 @@ import type { TxCollectionConfig } from './config.js';
19
19
  import { FastTxCollection } from './fast_tx_collection.js';
20
20
  import { FileStoreTxCollection } from './file_store_tx_collection.js';
21
21
  import type { FileStoreTxSource } from './file_store_tx_source.js';
22
- import type { IRequestTracker } from './request_tracker.js';
22
+ import type { IMissingTxsTracker } from './missing_txs_tracker.js';
23
23
  import { SlowTxCollection, getProofDeadlineForSlot } from './slow_tx_collection.js';
24
24
  import { type TxAddContext, TxCollectionSink } from './tx_collection_sink.js';
25
25
  import type { TxSource } from './tx_source.js';
@@ -33,8 +33,10 @@ export type FastCollectionRequestInput =
33
33
  | { type: 'proposal'; blockProposal: BlockProposal; blockNumber: BlockNumber };
34
34
 
35
35
  export type FastCollectionRequest = FastCollectionRequestInput & {
36
- requestTracker: IRequestTracker;
36
+ missingTxTracker: IMissingTxsTracker;
37
+ deadline: Date;
37
38
  blockInfo: L2BlockInfo;
39
+ promise: PromiseWithResolvers<void>;
38
40
  };
39
41
 
40
42
  /**
@@ -4,9 +4,9 @@ import { SecretValue } from '@aztec/foundation/config';
4
4
  import { type Logger, createLogger } from '@aztec/foundation/log';
5
5
  import { retryUntil } from '@aztec/foundation/retry';
6
6
  import { sleep } from '@aztec/foundation/sleep';
7
+ import type { DataStoreConfig } from '@aztec/kv-store/config';
7
8
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
8
9
  import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
9
- import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
10
10
 
11
11
  import { createP2PClient } from '../client/index.js';
12
12
  import type { P2PClient } from '../client/p2p_client.js';
@@ -15,7 +15,6 @@ import {
15
15
  type TopicValidatorResult,
16
16
  TypedEventEmitter,
17
17
  } from '@libp2p/interface';
18
- import type { AddressManager, ConnectionManager } from '@libp2p/interface-internal';
19
18
 
20
19
  import type { P2PConfig } from '../config.js';
21
20
  import type { MemPools } from '../mem_pools/interface.js';
@@ -213,14 +212,6 @@ export class MockPubSub implements PubSubLibp2p {
213
212
  get services() {
214
213
  return {
215
214
  pubsub: this.gossipSub,
216
- components: {
217
- addressManager: {
218
- removeObservedAddr: () => {},
219
- addObservedAddr: () => {},
220
- confirmObservedAddr: () => {},
221
- } as unknown as AddressManager,
222
- connectionManager: {} as unknown as ConnectionManager,
223
- },
224
215
  };
225
216
  }
226
217
 
@@ -2,6 +2,7 @@ import type { EpochCache } from '@aztec/epoch-cache';
2
2
  import { timesParallel } from '@aztec/foundation/collection';
3
3
  import { SecretValue } from '@aztec/foundation/config';
4
4
  import { createLogger } from '@aztec/foundation/log';
5
+ import type { DataStoreConfig } from '@aztec/kv-store/config';
5
6
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
6
7
  import type { L2BlockSource } from '@aztec/stdlib/block';
7
8
  import { type ChainConfig, emptyChainConfig } from '@aztec/stdlib/config';
@@ -11,7 +12,6 @@ import type {
11
12
  IVCProofVerificationResult,
12
13
  WorldStateSynchronizer,
13
14
  } from '@aztec/stdlib/interfaces/server';
14
- import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
15
15
  import type { Tx } from '@aztec/stdlib/tx';
16
16
  import { compressComponentVersions } from '@aztec/stdlib/versioning';
17
17
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
@@ -273,41 +273,17 @@ export class InMemoryAttestationPool {
273
273
  * Creates a mock EpochCache for testing.
274
274
  */
275
275
  export function createMockEpochCache(): EpochCacheInterface {
276
- const cache: EpochCacheInterface = {
276
+ return {
277
277
  getCommittee: () => Promise.resolve({ committee: [], seed: 1n, epoch: EpochNumber.ZERO, isEscapeHatchOpen: false }),
278
278
  getProposerIndexEncoding: () => '0x' as `0x${string}`,
279
- getSlotNow: () => SlotNumber.ZERO,
280
- getTargetSlot: () => SlotNumber.ZERO,
281
- getEpochNow: () => EpochNumber.ZERO,
282
- getTargetEpoch: () => EpochNumber.ZERO,
283
- getEpochAndSlotNow: () => ({
284
- epoch: EpochNumber.ZERO,
285
- slot: SlotNumber.ZERO,
286
- ts: 0n,
287
- nowMs: 0n,
288
- }),
289
- isProposerPipeliningEnabled: () => false,
279
+ getEpochAndSlotNow: () => ({ epoch: EpochNumber.ZERO, slot: SlotNumber.ZERO, ts: 0n, nowMs: 0n }),
290
280
  computeProposerIndex: () => 0n,
291
281
  getCurrentAndNextSlot: () => ({ currentSlot: SlotNumber.ZERO, nextSlot: SlotNumber.ZERO }),
292
- getTargetAndNextSlot: () => ({ targetSlot: SlotNumber.ZERO, nextSlot: SlotNumber.ZERO }),
293
282
  getProposerAttesterAddressInSlot: () => Promise.resolve(undefined),
294
- getEpochAndSlotInNextL1Slot: () => ({
295
- epoch: EpochNumber.ZERO,
296
- slot: SlotNumber.ZERO,
297
- ts: 0n,
298
- nowSeconds: 0n,
299
- }),
300
- getTargetEpochAndSlotInNextL1Slot: () => ({
301
- epoch: EpochNumber.ZERO,
302
- slot: SlotNumber.ZERO,
303
- ts: 0n,
304
- nowSeconds: 0n,
305
- }),
283
+ getEpochAndSlotInNextL1Slot: () => ({ epoch: EpochNumber.ZERO, slot: SlotNumber.ZERO, ts: 0n, now: 0n }),
306
284
  isInCommittee: () => Promise.resolve(false),
307
285
  getRegisteredValidators: () => Promise.resolve([]),
308
286
  filterInCommittee: () => Promise.resolve([]),
309
- isEscapeHatchOpen: () => Promise.resolve(false),
310
- isEscapeHatchOpenAtSlot: () => Promise.resolve(false),
311
287
  getL1Constants: () => ({
312
288
  l1StartBlock: 0n,
313
289
  l1GenesisTime: 0n,
@@ -319,7 +295,6 @@ export function createMockEpochCache(): EpochCacheInterface {
319
295
  rollupManaLimit: Number.MAX_SAFE_INTEGER,
320
296
  }),
321
297
  };
322
- return cache;
323
298
  }
324
299
 
325
300
  /**
@@ -12,13 +12,13 @@ import { Fr } from '@aztec/foundation/curves/bn254';
12
12
  import { type Logger, createLogger } from '@aztec/foundation/log';
13
13
  import { sleep } from '@aztec/foundation/sleep';
14
14
  import { DateProvider, Timer } from '@aztec/foundation/timer';
15
+ import type { DataStoreConfig } from '@aztec/kv-store/config';
15
16
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
16
17
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
17
18
  import { protocolContractsHash } from '@aztec/protocol-contracts';
18
19
  import type { L2BlockSource } from '@aztec/stdlib/block';
19
20
  import type { ContractDataSource } from '@aztec/stdlib/contract';
20
21
  import type { ClientProtocolCircuitVerifier, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
21
- import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
22
22
  import { type BlockProposal, P2PMessage } from '@aztec/stdlib/p2p';
23
23
  import { ChonkProof } from '@aztec/stdlib/proofs';
24
24
  import { makeAztecAddress, makeBlockHeader, makeBlockProposal, mockTx } from '@aztec/stdlib/testing';
@@ -40,7 +40,7 @@ import type { IBatchRequestTxValidator } from '../services/reqresp/batch-tx-requ
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 { RequestTracker } from '../services/tx_collection/request_tracker.js';
43
+ import { MissingTxsTracker } from '../services/tx_collection/missing_txs_tracker.js';
44
44
  import { AlwaysTrueCircuitVerifier } from '../test-helpers/index.js';
45
45
  import {
46
46
  BENCHMARK_CONSTANTS,
@@ -273,9 +273,10 @@ async function runAggregatorBenchmark(
273
273
  noopTxValidator,
274
274
  );
275
275
  const fetchedTxs = await collector.collectTxs(
276
- RequestTracker.create(txHashes, new Date(Date.now() + timeoutMs)),
276
+ MissingTxsTracker.fromArray(txHashes),
277
277
  blockProposal,
278
278
  pinnedPeer,
279
+ timeoutMs,
279
280
  );
280
281
  const durationMs = timer.ms();
281
282
  return {
@@ -292,9 +293,10 @@ async function runAggregatorBenchmark(
292
293
  BENCHMARK_CONSTANTS.FIXED_MAX_RETRY_ATTEMPTS,
293
294
  );
294
295
  const fetchedTxs = await collector.collectTxs(
295
- RequestTracker.create(txHashes, new Date(Date.now() + timeoutMs)),
296
+ MissingTxsTracker.fromArray(txHashes),
296
297
  blockProposal,
297
298
  pinnedPeer,
299
+ timeoutMs,
298
300
  );
299
301
  const durationMs = timer.ms();
300
302
  return {
@@ -321,37 +323,6 @@ let workerConfig: P2PConfig | null = null;
321
323
  let workerLogger: Logger | null = null;
322
324
  let kvStore: Awaited<ReturnType<typeof openTmpStore>> | null = null;
323
325
 
324
- async function stopWorker() {
325
- try {
326
- if (workerClient) {
327
- await workerClient.stop();
328
- workerClient = null;
329
- }
330
- } catch (e) {
331
- workerLogger?.error('Error stopping worker client', e);
332
- }
333
- try {
334
- if (kvStore?.close) {
335
- await kvStore.close();
336
- kvStore = null;
337
- }
338
- } catch (e) {
339
- workerLogger?.error('Error closing kv store', e);
340
- }
341
- }
342
-
343
- function gracefulExit(code: number = 0) {
344
- try {
345
- if (process.connected) {
346
- process.disconnect();
347
- }
348
- } catch {
349
- // IPC channel already closed
350
- }
351
- // Safety fallback if lingering handles prevent the event loop from draining
352
- setTimeout(() => process.exit(code), 5000).unref();
353
- }
354
-
355
326
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
356
327
  process.on('message', async msg => {
357
328
  const {
@@ -441,8 +412,13 @@ process.on('message', async msg => {
441
412
  const cmd = msg as any;
442
413
  switch (cmd.type) {
443
414
  case 'STOP':
444
- await stopWorker();
445
- gracefulExit(0);
415
+ if (workerClient) {
416
+ await workerClient.stop();
417
+ }
418
+ if (kvStore?.close) {
419
+ await kvStore.close();
420
+ }
421
+ process.exit(0);
446
422
  break;
447
423
 
448
424
  case 'SEND_TX':
@@ -519,12 +495,7 @@ process.on('message', async msg => {
519
495
  }
520
496
  }
521
497
  } catch (err: any) {
522
- try {
523
- process.send!({ type: 'ERROR', error: err.message });
524
- } catch {
525
- // IPC channel may be closed
526
- }
527
- await stopWorker();
528
- gracefulExit(1);
498
+ process.send!({ type: 'ERROR', error: err.message });
499
+ process.exit(1);
529
500
  }
530
501
  });
@@ -72,6 +72,7 @@ class WorkerClientManager {
72
72
  destroy() {
73
73
  this.cleanup().catch((error: Error) => {
74
74
  this.logger.error('Failed to cleanup worker client manager', error);
75
+ process.exit(1);
75
76
  });
76
77
  }
77
78
 
@@ -489,8 +490,7 @@ class WorkerClientManager {
489
490
  };
490
491
 
491
492
  this.processes[0].send(aggregatorCmd);
492
- const aggregatorBudgetMs = config.timeoutMs + BENCHMARK_CONSTANTS.MAX_PEER_WAIT_MS + 30000;
493
- const result = await this.waitForBenchResult(0, aggregatorBudgetMs);
493
+ const result = await this.waitForBenchResult(0, config.timeoutMs + 30000);
494
494
 
495
495
  this.logger.info(
496
496
  `Benchmark complete: fetched=${result.fetchedCount}/${config.txCount}, duration=${result.durationMs.toFixed(0)}ms, success=${result.success}`,
package/src/util.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import { SecretValue } from '@aztec/foundation/config';
2
2
  import type { Logger } from '@aztec/foundation/log';
3
3
  import type { AztecAsyncKVStore, AztecAsyncSingleton } from '@aztec/kv-store';
4
- import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
4
+ import type { DataStoreConfig } from '@aztec/kv-store/config';
5
5
 
6
6
  import type { GossipSub } from '@chainsafe/libp2p-gossipsub';
7
7
  import { generateKeyPair, marshalPrivateKey, unmarshalPrivateKey } from '@libp2p/crypto/keys';
8
8
  import type { Identify } from '@libp2p/identify';
9
9
  import type { PeerId, PrivateKey } from '@libp2p/interface';
10
- import type { AddressManager, ConnectionManager } from '@libp2p/interface-internal';
10
+ import type { ConnectionManager } from '@libp2p/interface-internal';
11
11
  import { createFromPrivKey } from '@libp2p/peer-id-factory';
12
12
  import { resolve } from 'dns/promises';
13
13
  import { promises as fs } from 'fs';
@@ -31,10 +31,6 @@ export interface PubSubLibp2p extends Pick<Libp2p, 'status' | 'start' | 'stop' |
31
31
  | 'direct'
32
32
  | 'getMeshPeers'
33
33
  > & { score: Pick<GossipSub['score'], 'score'> };
34
- components: {
35
- connectionManager: ConnectionManager;
36
- addressManager: AddressManager;
37
- };
38
34
  };
39
35
  }
40
36
 
@@ -43,7 +39,6 @@ export type FullLibp2p = Libp2p<{
43
39
  pubsub: GossipSub;
44
40
  components: {
45
41
  connectionManager: ConnectionManager;
46
- addressManager: AddressManager;
47
42
  };
48
43
  }>;
49
44
 
@@ -107,15 +102,24 @@ function addressToMultiAddressType(address: string): 'ip4' | 'ip6' | 'dns' {
107
102
  }
108
103
  }
109
104
 
110
- export function configureP2PClientAddresses(_config: P2PConfig & DataStoreConfig): P2PConfig & DataStoreConfig {
105
+ export async function configureP2PClientAddresses(
106
+ _config: P2PConfig & DataStoreConfig,
107
+ ): Promise<P2PConfig & DataStoreConfig> {
111
108
  const config = { ..._config };
112
- const { p2pBroadcastPort, p2pPort } = config;
109
+ const { p2pIp, queryForIp, p2pBroadcastPort, p2pPort } = config;
113
110
 
114
111
  // If no broadcast port is provided, use the given p2p port as the broadcast port
115
112
  if (!p2pBroadcastPort) {
116
113
  config.p2pBroadcastPort = p2pPort;
117
114
  }
118
115
 
116
+ // check if no announce IP was provided
117
+ if (!p2pIp) {
118
+ if (queryForIp) {
119
+ const publicIp = await getPublicIp();
120
+ config.p2pIp = publicIp;
121
+ }
122
+ }
119
123
  // TODO(md): guard against setting a local ip address as the announce ip
120
124
 
121
125
  return config;
@@ -1,53 +0,0 @@
1
- import type { DateProvider } from '@aztec/foundation/timer';
2
- import { TxHash } from '@aztec/stdlib/tx';
3
- import type { Tx } from '@aztec/stdlib/tx';
4
- /**
5
- * Tracks which transactions are still missing and need to be fetched.
6
- * Manages the request deadline and serves as the sole source of cancellation signal.
7
- * The request is cancelled when all txs are fetched or the deadline expires.
8
- */
9
- export interface IRequestTracker {
10
- /** Returns the set of transaction hashes that are still missing. */
11
- get missingTxHashes(): Set<string>;
12
- /** Size of this.missingTxHashes */
13
- get numberOfMissingTxs(): number;
14
- /** Are all requested txs fetched */
15
- allFetched(): boolean;
16
- /** Checks that transaction is still missing */
17
- isMissing(txHash: string): boolean;
18
- /** Marks a transaction as fetched. Returns true if it was previously missing. */
19
- markFetched(tx: Tx): boolean;
20
- /** Get list of collected txs */
21
- get collectedTxs(): Tx[];
22
- /** The deadline for this request. */
23
- get deadline(): Date;
24
- /** Remaining time in milliseconds until deadline. Returns 0 if already past. */
25
- get timeoutMs(): number;
26
- /** Checks whether the request is cancelled (deadline expired or all fetched). May trigger cancellation if deadline has passed. */
27
- checkCancelled(): boolean;
28
- /** Resolves when deadline expires or all txs are fetched. */
29
- get cancellationToken(): Promise<void>;
30
- /** Externally cancel the request. */
31
- cancel(): void;
32
- }
33
- export declare class RequestTracker implements IRequestTracker {
34
- readonly missingTxHashes: Set<string>;
35
- readonly deadline: Date;
36
- private readonly dateProvider?;
37
- readonly collectedTxs: Tx[];
38
- private done;
39
- private readonly cancellationTokenPromise;
40
- private readonly deadlineTimer;
41
- private constructor();
42
- static create(hashes: TxHash[] | string[], deadline: Date, dateProvider?: DateProvider): RequestTracker;
43
- markFetched(tx: Tx): boolean;
44
- get numberOfMissingTxs(): number;
45
- allFetched(): boolean;
46
- isMissing(txHash: string): boolean;
47
- get timeoutMs(): number;
48
- checkCancelled(): boolean;
49
- get cancellationToken(): Promise<void>;
50
- cancel(): void;
51
- private finish;
52
- }
53
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdF90cmFja2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvdHhfY29sbGVjdGlvbi9yZXF1ZXN0X3RyYWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTNDOzs7O0dBSUc7QUFDSCxNQUFNLFdBQVcsZUFBZTtJQUM5QixvRUFBb0U7SUFDcEUsSUFBSSxlQUFlLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25DLG1DQUFtQztJQUNuQyxJQUFJLGtCQUFrQixJQUFJLE1BQU0sQ0FBQztJQUNqQyxvQ0FBb0M7SUFDcEMsVUFBVSxJQUFJLE9BQU8sQ0FBQztJQUN0QiwrQ0FBK0M7SUFDL0MsU0FBUyxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUFDO0lBQ25DLGlGQUFpRjtJQUNqRixXQUFXLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFDN0IsZ0NBQWdDO0lBQ2hDLElBQUksWUFBWSxJQUFJLEVBQUUsRUFBRSxDQUFDO0lBQ3pCLHFDQUFxQztJQUNyQyxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUM7SUFDckIsZ0ZBQWdGO0lBQ2hGLElBQUksU0FBUyxJQUFJLE1BQU0sQ0FBQztJQUN4QixrSUFBa0k7SUFDbEksY0FBYyxJQUFJLE9BQU8sQ0FBQztJQUMxQiw2REFBNkQ7SUFDN0QsSUFBSSxpQkFBaUIsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkMscUNBQXFDO0lBQ3JDLE1BQU0sSUFBSSxJQUFJLENBQUM7Q0FDaEI7QUFFRCxxQkFBYSxjQUFlLFlBQVcsZUFBZTthQU9sQyxlQUFlLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQzthQUM1QixRQUFRLEVBQUUsSUFBSTtJQUM5QixPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQztJQVJoQyxTQUFnQixZQUFZLEVBQUUsRUFBRSxFQUFFLENBQU07SUFDeEMsT0FBTyxDQUFDLElBQUksQ0FBUztJQUNyQixPQUFPLENBQUMsUUFBUSxDQUFDLHdCQUF3QixDQUE2QjtJQUN0RSxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBNEM7SUFFMUUsT0FBTyxlQW1CTjtJQUVELE9BQWMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFlBQVksQ0FBQyxFQUFFLFlBQVksa0JBRTVGO0lBRUQsV0FBVyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQVMzQjtJQUVELElBQUksa0JBQWtCLElBQUksTUFBTSxDQUUvQjtJQUVELFVBQVUsSUFBSSxPQUFPLENBRXBCO0lBRUQsU0FBUyxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUVqQztJQUVELElBQUksU0FBUyxJQUFJLE1BQU0sQ0FHdEI7SUFFRCxjQUFjLElBQUksT0FBTyxDQVl4QjtJQUVELElBQUksaUJBQWlCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUVyQztJQUVELE1BQU0sSUFBSSxJQUFJLENBRWI7SUFFRCxPQUFPLENBQUMsTUFBTTtDQVVmIn0=
@@ -1 +0,0 @@
1
- {"version":3,"file":"request_tracker.d.ts","sourceRoot":"","sources":["../../../src/services/tx_collection/request_tracker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAE3C;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,IAAI,eAAe,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,mCAAmC;IACnC,IAAI,kBAAkB,IAAI,MAAM,CAAC;IACjC,oCAAoC;IACpC,UAAU,IAAI,OAAO,CAAC;IACtB,+CAA+C;IAC/C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,iFAAiF;IACjF,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;IAC7B,gCAAgC;IAChC,IAAI,YAAY,IAAI,EAAE,EAAE,CAAC;IACzB,qCAAqC;IACrC,IAAI,QAAQ,IAAI,IAAI,CAAC;IACrB,gFAAgF;IAChF,IAAI,SAAS,IAAI,MAAM,CAAC;IACxB,kIAAkI;IAClI,cAAc,IAAI,OAAO,CAAC;IAC1B,6DAA6D;IAC7D,IAAI,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,qCAAqC;IACrC,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,qBAAa,cAAe,YAAW,eAAe;aAOlC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC;aAC5B,QAAQ,EAAE,IAAI;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IARhC,SAAgB,YAAY,EAAE,EAAE,EAAE,CAAM;IACxC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA6B;IACtE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4C;IAE1E,OAAO,eAmBN;IAED,OAAc,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,YAAY,kBAE5F;IAED,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAS3B;IAED,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED,UAAU,IAAI,OAAO,CAEpB;IAED,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjC;IAED,IAAI,SAAS,IAAI,MAAM,CAGtB;IAED,cAAc,IAAI,OAAO,CAYxB;IAED,IAAI,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAErC;IAED,MAAM,IAAI,IAAI,CAEb;IAED,OAAO,CAAC,MAAM;CAUf"}
@@ -1,84 +0,0 @@
1
- import { promiseWithResolvers } from '@aztec/foundation/promise';
2
- export class RequestTracker {
3
- missingTxHashes;
4
- deadline;
5
- dateProvider;
6
- collectedTxs;
7
- done;
8
- cancellationTokenPromise;
9
- deadlineTimer;
10
- constructor(missingTxHashes, deadline, dateProvider){
11
- this.missingTxHashes = missingTxHashes;
12
- this.deadline = deadline;
13
- this.dateProvider = dateProvider;
14
- this.collectedTxs = [];
15
- this.done = false;
16
- this.cancellationTokenPromise = promiseWithResolvers();
17
- if (missingTxHashes.size === 0) {
18
- this.finish();
19
- return;
20
- }
21
- const now = this.dateProvider?.now() ?? Date.now();
22
- const remaining = deadline.getTime() - now;
23
- if (remaining <= 0) {
24
- this.finish();
25
- } else {
26
- this.deadlineTimer = setTimeout(()=>this.finish(), remaining);
27
- }
28
- }
29
- static create(hashes, deadline, dateProvider) {
30
- return new RequestTracker(new Set(hashes.map((hash)=>hash.toString())), deadline, dateProvider);
31
- }
32
- markFetched(tx) {
33
- if (this.missingTxHashes.delete(tx.txHash.toString())) {
34
- this.collectedTxs.push(tx);
35
- if (this.allFetched()) {
36
- this.finish();
37
- }
38
- return true;
39
- }
40
- return false;
41
- }
42
- get numberOfMissingTxs() {
43
- return this.missingTxHashes.size;
44
- }
45
- allFetched() {
46
- return this.numberOfMissingTxs === 0;
47
- }
48
- isMissing(txHash) {
49
- return this.missingTxHashes.has(txHash.toString());
50
- }
51
- get timeoutMs() {
52
- const now = this.dateProvider?.now() ?? Date.now();
53
- return Math.max(0, this.deadline.getTime() - now);
54
- }
55
- checkCancelled() {
56
- if (this.done) {
57
- return true;
58
- }
59
- // Synchronous fallback: check deadline even if setTimeout hasn't fired yet.
60
- // This prevents macrotask starvation in tight async loops from blocking cancellation.
61
- const now = this.dateProvider?.now() ?? Date.now();
62
- if (now >= this.deadline.getTime()) {
63
- this.finish();
64
- return true;
65
- }
66
- return false;
67
- }
68
- get cancellationToken() {
69
- return this.cancellationTokenPromise.promise;
70
- }
71
- cancel() {
72
- this.finish();
73
- }
74
- finish() {
75
- if (this.done) {
76
- return;
77
- }
78
- this.done = true;
79
- if (this.deadlineTimer) {
80
- clearTimeout(this.deadlineTimer);
81
- }
82
- this.cancellationTokenPromise.resolve();
83
- }
84
- }
@@ -1,127 +0,0 @@
1
- import { type PromiseWithResolvers, promiseWithResolvers } from '@aztec/foundation/promise';
2
- import type { DateProvider } from '@aztec/foundation/timer';
3
- import { TxHash } from '@aztec/stdlib/tx';
4
- import type { Tx } from '@aztec/stdlib/tx';
5
-
6
- /**
7
- * Tracks which transactions are still missing and need to be fetched.
8
- * Manages the request deadline and serves as the sole source of cancellation signal.
9
- * The request is cancelled when all txs are fetched or the deadline expires.
10
- */
11
- export interface IRequestTracker {
12
- /** Returns the set of transaction hashes that are still missing. */
13
- get missingTxHashes(): Set<string>;
14
- /** Size of this.missingTxHashes */
15
- get numberOfMissingTxs(): number;
16
- /** Are all requested txs fetched */
17
- allFetched(): boolean;
18
- /** Checks that transaction is still missing */
19
- isMissing(txHash: string): boolean;
20
- /** Marks a transaction as fetched. Returns true if it was previously missing. */
21
- markFetched(tx: Tx): boolean;
22
- /** Get list of collected txs */
23
- get collectedTxs(): Tx[];
24
- /** The deadline for this request. */
25
- get deadline(): Date;
26
- /** Remaining time in milliseconds until deadline. Returns 0 if already past. */
27
- get timeoutMs(): number;
28
- /** Checks whether the request is cancelled (deadline expired or all fetched). May trigger cancellation if deadline has passed. */
29
- checkCancelled(): boolean;
30
- /** Resolves when deadline expires or all txs are fetched. */
31
- get cancellationToken(): Promise<void>;
32
- /** Externally cancel the request. */
33
- cancel(): void;
34
- }
35
-
36
- export class RequestTracker implements IRequestTracker {
37
- public readonly collectedTxs: Tx[] = [];
38
- private done = false;
39
- private readonly cancellationTokenPromise: PromiseWithResolvers<void>;
40
- private readonly deadlineTimer: ReturnType<typeof setTimeout> | undefined;
41
-
42
- private constructor(
43
- public readonly missingTxHashes: Set<string>,
44
- public readonly deadline: Date,
45
- private readonly dateProvider?: DateProvider,
46
- ) {
47
- this.cancellationTokenPromise = promiseWithResolvers<void>();
48
-
49
- if (missingTxHashes.size === 0) {
50
- this.finish();
51
- return;
52
- }
53
-
54
- const now = this.dateProvider?.now() ?? Date.now();
55
- const remaining = deadline.getTime() - now;
56
- if (remaining <= 0) {
57
- this.finish();
58
- } else {
59
- this.deadlineTimer = setTimeout(() => this.finish(), remaining);
60
- }
61
- }
62
-
63
- public static create(hashes: TxHash[] | string[], deadline: Date, dateProvider?: DateProvider) {
64
- return new RequestTracker(new Set(hashes.map(hash => hash.toString())), deadline, dateProvider);
65
- }
66
-
67
- markFetched(tx: Tx): boolean {
68
- if (this.missingTxHashes.delete(tx.txHash.toString())) {
69
- this.collectedTxs.push(tx);
70
- if (this.allFetched()) {
71
- this.finish();
72
- }
73
- return true;
74
- }
75
- return false;
76
- }
77
-
78
- get numberOfMissingTxs(): number {
79
- return this.missingTxHashes.size;
80
- }
81
-
82
- allFetched(): boolean {
83
- return this.numberOfMissingTxs === 0;
84
- }
85
-
86
- isMissing(txHash: string): boolean {
87
- return this.missingTxHashes.has(txHash.toString());
88
- }
89
-
90
- get timeoutMs(): number {
91
- const now = this.dateProvider?.now() ?? Date.now();
92
- return Math.max(0, this.deadline.getTime() - now);
93
- }
94
-
95
- checkCancelled(): boolean {
96
- if (this.done) {
97
- return true;
98
- }
99
- // Synchronous fallback: check deadline even if setTimeout hasn't fired yet.
100
- // This prevents macrotask starvation in tight async loops from blocking cancellation.
101
- const now = this.dateProvider?.now() ?? Date.now();
102
- if (now >= this.deadline.getTime()) {
103
- this.finish();
104
- return true;
105
- }
106
- return false;
107
- }
108
-
109
- get cancellationToken(): Promise<void> {
110
- return this.cancellationTokenPromise.promise;
111
- }
112
-
113
- cancel(): void {
114
- this.finish();
115
- }
116
-
117
- private finish() {
118
- if (this.done) {
119
- return;
120
- }
121
- this.done = true;
122
- if (this.deadlineTimer) {
123
- clearTimeout(this.deadlineTimer);
124
- }
125
- this.cancellationTokenPromise.resolve();
126
- }
127
- }