@aztec/p2p 0.0.1-commit.cf93bcc56 → 0.0.1-commit.d0fcfb7f

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 (226) hide show
  1. package/dest/client/factory.d.ts +4 -5
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +20 -26
  4. package/dest/client/interface.d.ts +8 -13
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +7 -13
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +35 -86
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
  10. package/dest/config.d.ts +29 -10
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +80 -31
  13. package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
  14. package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
  15. package/dest/mem_pools/tx_pool/priority.js +4 -4
  16. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
  17. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  18. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
  19. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
  20. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
  21. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  22. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +2 -0
  23. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
  24. package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
  25. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  26. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  27. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +10 -6
  29. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
  30. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
  32. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
  33. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
  34. package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
  35. package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
  36. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/index.js +1 -1
  38. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +10 -6
  39. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  40. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  41. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +38 -7
  42. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  43. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +74 -16
  44. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  45. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  46. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +9 -10
  47. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +5 -3
  48. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  49. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +2 -2
  50. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +5 -3
  51. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  52. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +169 -141
  53. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
  54. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  55. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
  56. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
  57. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  58. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
  59. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
  60. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  61. package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
  62. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
  63. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  64. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  65. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  66. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  67. package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
  68. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
  69. package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
  70. package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
  71. package/dest/msg_validators/tx_validator/factory.d.ts +125 -6
  72. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  73. package/dest/msg_validators/tx_validator/factory.js +226 -58
  74. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
  75. package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
  76. package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
  77. package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
  78. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  79. package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
  80. package/dest/msg_validators/tx_validator/index.d.ts +3 -1
  81. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  82. package/dest/msg_validators/tx_validator/index.js +2 -0
  83. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  84. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  85. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  86. package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
  87. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  88. package/dest/msg_validators/tx_validator/phases_validator.js +44 -23
  89. package/dest/services/dummy_service.d.ts +4 -4
  90. package/dest/services/dummy_service.d.ts.map +1 -1
  91. package/dest/services/dummy_service.js +4 -4
  92. package/dest/services/encoding.d.ts +2 -2
  93. package/dest/services/encoding.d.ts.map +1 -1
  94. package/dest/services/encoding.js +7 -7
  95. package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
  96. package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
  97. package/dest/services/gossipsub/topic_score_params.js +32 -10
  98. package/dest/services/libp2p/libp2p_service.d.ts +16 -13
  99. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  100. package/dest/services/libp2p/libp2p_service.js +92 -93
  101. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
  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 +5 -9
  104. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
  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 +10 -13
  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 +25 -46
  109. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  110. package/dest/services/service.d.ts +5 -3
  111. package/dest/services/service.d.ts.map +1 -1
  112. package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -1
  113. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  114. package/dest/services/tx_collection/fast_tx_collection.js +39 -33
  115. package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
  116. package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
  117. package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
  118. package/dest/services/tx_collection/file_store_tx_source.d.ts +4 -4
  119. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  120. package/dest/services/tx_collection/file_store_tx_source.js +27 -16
  121. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  122. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  123. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  124. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
  125. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  126. package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
  127. package/dest/services/tx_collection/slow_tx_collection.d.ts +2 -2
  128. package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
  129. package/dest/services/tx_collection/slow_tx_collection.js +10 -8
  130. package/dest/services/tx_collection/tx_collection.d.ts +5 -4
  131. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  132. package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
  133. package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
  134. package/dest/services/tx_collection/tx_collection_sink.js +13 -22
  135. package/dest/services/tx_collection/tx_source.d.ts +8 -3
  136. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  137. package/dest/services/tx_collection/tx_source.js +19 -2
  138. package/dest/services/tx_provider.d.ts +3 -3
  139. package/dest/services/tx_provider.d.ts.map +1 -1
  140. package/dest/services/tx_provider.js +4 -4
  141. package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
  142. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  143. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  144. package/dest/test-helpers/mock-pubsub.d.ts +4 -4
  145. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  146. package/dest/test-helpers/mock-pubsub.js +8 -2
  147. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  148. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  149. package/dest/test-helpers/reqresp-nodes.js +2 -2
  150. package/dest/test-helpers/testbench-utils.d.ts +5 -3
  151. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  152. package/dest/test-helpers/testbench-utils.js +3 -2
  153. package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
  154. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  155. package/dest/testbench/p2p_client_testbench_worker.js +13 -12
  156. package/dest/testbench/worker_client_manager.d.ts +3 -1
  157. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  158. package/dest/testbench/worker_client_manager.js +4 -1
  159. package/dest/util.d.ts +2 -2
  160. package/dest/util.d.ts.map +1 -1
  161. package/package.json +14 -14
  162. package/src/client/factory.ts +28 -46
  163. package/src/client/interface.ts +8 -13
  164. package/src/client/p2p_client.ts +35 -113
  165. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -10
  166. package/src/config.ts +115 -33
  167. package/src/mem_pools/tx_pool/priority.ts +4 -4
  168. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
  169. package/src/mem_pools/tx_pool_v2/README.md +9 -1
  170. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
  171. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
  172. package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
  173. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +2 -2
  174. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +10 -6
  175. package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
  176. package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
  177. package/src/mem_pools/tx_pool_v2/index.ts +1 -1
  178. package/src/mem_pools/tx_pool_v2/interfaces.ts +8 -5
  179. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +102 -17
  180. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +11 -11
  181. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +3 -3
  182. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +178 -141
  183. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
  184. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
  185. package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
  186. package/src/msg_validators/tx_validator/README.md +115 -0
  187. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
  188. package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
  189. package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
  190. package/src/msg_validators/tx_validator/factory.ts +366 -77
  191. package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
  192. package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
  193. package/src/msg_validators/tx_validator/index.ts +2 -0
  194. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  195. package/src/msg_validators/tx_validator/phases_validator.ts +51 -26
  196. package/src/services/dummy_service.ts +6 -6
  197. package/src/services/encoding.ts +5 -6
  198. package/src/services/gossipsub/README.md +29 -14
  199. package/src/services/gossipsub/topic_score_params.ts +49 -13
  200. package/src/services/libp2p/libp2p_service.ts +106 -101
  201. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +6 -6
  202. package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
  203. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
  204. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  205. package/src/services/service.ts +11 -2
  206. package/src/services/tx_collection/fast_tx_collection.ts +51 -30
  207. package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
  208. package/src/services/tx_collection/file_store_tx_source.ts +32 -19
  209. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  210. package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
  211. package/src/services/tx_collection/slow_tx_collection.ts +8 -9
  212. package/src/services/tx_collection/tx_collection.ts +4 -3
  213. package/src/services/tx_collection/tx_collection_sink.ts +15 -29
  214. package/src/services/tx_collection/tx_source.ts +22 -3
  215. package/src/services/tx_provider.ts +2 -2
  216. package/src/test-helpers/make-test-p2p-clients.ts +0 -2
  217. package/src/test-helpers/mock-pubsub.ts +13 -6
  218. package/src/test-helpers/reqresp-nodes.ts +2 -5
  219. package/src/test-helpers/testbench-utils.ts +3 -2
  220. package/src/testbench/p2p_client_testbench_worker.ts +21 -17
  221. package/src/testbench/worker_client_manager.ts +11 -4
  222. package/src/util.ts +7 -1
  223. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
  224. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
  225. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
  226. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
@@ -1,5 +1,6 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
2
  import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { maxBy } from '@aztec/foundation/collection';
3
4
  import { Fr } from '@aztec/foundation/curves/bn254';
4
5
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
5
6
  import { RunningPromise } from '@aztec/foundation/running-promise';
@@ -16,13 +17,13 @@ import {
16
17
  CheckpointProposal,
17
18
  type CheckpointProposalCore,
18
19
  type Gossipable,
19
- P2PClientType,
20
20
  P2PMessage,
21
21
  type ValidationResult as P2PValidationResult,
22
22
  PeerErrorSeverity,
23
+ PeerErrorSeverityByHarshness,
23
24
  TopicType,
24
25
  createTopicString,
25
- getTopicsForClientAndConfig,
26
+ getTopicsForConfig,
26
27
  metricsTopicStrToLabels,
27
28
  } from '@aztec/stdlib/p2p';
28
29
  import { MerkleTreeId } from '@aztec/stdlib/trees';
@@ -69,9 +70,11 @@ import {
69
70
  } from '../../msg_validators/index.js';
70
71
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
71
72
  import {
72
- type MessageValidator,
73
- createTxMessageValidators,
74
- createTxReqRespValidator,
73
+ type TransactionValidator,
74
+ createFirstStageTxValidationsForGossipedTransactions,
75
+ createSecondStageTxValidationsForGossipedTransactions,
76
+ createTxValidatorForBlockProposalReceivedTxs,
77
+ createTxValidatorForReqResponseReceivedTxs,
75
78
  } from '../../msg_validators/tx_validator/factory.js';
76
79
  import { GossipSubEvent } from '../../types/index.js';
77
80
  import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
@@ -87,6 +90,9 @@ import { PeerScoring } from '../peer-manager/peer_scoring.js';
87
90
  import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
88
91
  import type { P2PReqRespConfig } from '../reqresp/config.js';
89
92
  import {
93
+ AuthRequest,
94
+ BlockTxsRequest,
95
+ BlockTxsResponse,
90
96
  DEFAULT_SUB_PROTOCOL_VALIDATORS,
91
97
  type ReqRespInterface,
92
98
  type ReqRespResponse,
@@ -94,14 +100,9 @@ import {
94
100
  type ReqRespSubProtocolHandler,
95
101
  type ReqRespSubProtocolHandlers,
96
102
  type ReqRespSubProtocolValidators,
103
+ StatusMessage,
97
104
  type SubProtocolMap,
98
105
  ValidationError,
99
- } from '../reqresp/index.js';
100
- import {
101
- AuthRequest,
102
- BlockTxsRequest,
103
- BlockTxsResponse,
104
- StatusMessage,
105
106
  pingHandler,
106
107
  reqGoodbyeHandler,
107
108
  reqRespBlockHandler,
@@ -135,7 +136,7 @@ type ReceivedMessageValidationResult<T, M = undefined> =
135
136
  /**
136
137
  * Lib P2P implementation of the P2PService interface.
137
138
  */
138
- export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends WithTracer implements P2PService {
139
+ export class LibP2PService extends WithTracer implements P2PService {
139
140
  private discoveryRunningPromise?: RunningPromise;
140
141
  private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
141
142
 
@@ -182,7 +183,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
182
183
  protected logger: Logger;
183
184
 
184
185
  constructor(
185
- private clientType: T,
186
186
  private config: P2PConfig,
187
187
  protected node: PubSubLibp2p,
188
188
  private peerDiscoveryService: PeerDiscoveryService,
@@ -224,10 +224,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
224
224
  this.protocolVersion,
225
225
  );
226
226
 
227
- this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
228
- this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
227
+ const proposalValidatorOpts = {
229
228
  txsPermitted: !config.disableTransactions,
230
- });
229
+ maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
230
+ };
231
+ this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
232
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
231
233
  this.checkpointAttestationValidator = config.fishermanMode
232
234
  ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
233
235
  : new CheckpointAttestationValidator(epochCache);
@@ -235,11 +237,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
235
237
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
236
238
 
237
239
  this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
238
- this.logger.debug(
239
- `Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
240
+ this.logger.warn(
241
+ `Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`,
240
242
  { p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
241
243
  );
242
- return false;
244
+ return true;
243
245
  };
244
246
 
245
247
  this.checkpointReceivedCallback = (
@@ -262,8 +264,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
262
264
  * @param txPool - The transaction pool to be accessed by the service.
263
265
  * @returns The new service.
264
266
  */
265
- public static async new<T extends P2PClientType>(
266
- clientType: T,
267
+ public static async new(
267
268
  config: P2PConfig,
268
269
  peerId: PeerId,
269
270
  deps: {
@@ -341,6 +342,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
341
342
  heartbeatIntervalMs: config.gossipsubInterval,
342
343
  targetCommitteeSize: l1Constants.targetCommitteeSize,
343
344
  blockDurationMs: config.blockDurationMs,
345
+ expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
344
346
  });
345
347
 
346
348
  const node = await createLibp2p({
@@ -474,7 +476,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
474
476
  peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
475
477
 
476
478
  return new LibP2PService(
477
- clientType,
478
479
  config,
479
480
  node,
480
481
  peerDiscoveryService,
@@ -548,7 +549,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
548
549
  await this.node.start();
549
550
 
550
551
  // Subscribe to standard GossipSub topics by default
551
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
552
+ for (const topic of getTopicsForConfig(this.config.disableTransactions)) {
552
553
  this.subscribeToTopic(this.topicStrings[topic]);
553
554
  }
554
555
 
@@ -614,6 +615,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
614
615
  return this.peerManager.getPeers(includePending);
615
616
  }
616
617
 
618
+ public getGossipMeshPeerCount(topicType: TopicType): number {
619
+ return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
620
+ }
621
+
617
622
  private handleGossipSubEvent(e: CustomEvent<GossipsubMessage>) {
618
623
  this.logger.trace(`Received PUBSUB message.`);
619
624
 
@@ -813,9 +818,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
813
818
  if (msg.topic === this.topicStrings[TopicType.tx]) {
814
819
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
815
820
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
816
- if (this.clientType === P2PClientType.Full) {
817
- await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
818
- }
821
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
819
822
  } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
820
823
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
821
824
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
@@ -901,15 +904,45 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
901
904
  protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
902
905
  const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
903
906
  const tx = Tx.fromBuffer(payloadData);
904
- const isValid = await this.validatePropagatedTx(tx, source);
905
- if (!isValid) {
906
- this.logger.trace(`Rejecting invalid propagated tx`, {
907
- [Attributes.P2P_ID]: source.toString(),
908
- });
907
+
908
+ const currentBlockNumber = await this.archiver.getBlockNumber();
909
+ const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
910
+
911
+ // Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
912
+ const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
913
+ const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
914
+ if (!firstStageOutcome.allPassed) {
915
+ const { name } = firstStageOutcome.failure;
916
+ let { severity } = firstStageOutcome.failure;
917
+
918
+ // Double spend validator has a special case handler. We perform more detailed examination
919
+ // as to how recently the nullifier was entered into the tree and if the transaction should
920
+ // have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
921
+ if (name === 'doubleSpendValidator') {
922
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1);
923
+ severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
924
+ }
925
+
926
+ this.peerManager.penalizePeer(source, severity);
909
927
  return { result: TopicValidatorResult.Reject };
910
928
  }
911
929
 
912
- // Propagate only on pool acceptance
930
+ // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
931
+ const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
932
+ if (canAdd === 'ignored') {
933
+ return { result: TopicValidatorResult.Ignore, obj: tx };
934
+ }
935
+
936
+ // Stage 2: expensive proof verification
937
+ const secondStageValidators = this.createSecondStageMessageValidators();
938
+ const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
939
+ if (!secondStageOutcome.allPassed) {
940
+ const { severity } = secondStageOutcome.failure;
941
+ this.peerManager.penalizePeer(source, severity);
942
+ return { result: TopicValidatorResult.Reject };
943
+ }
944
+
945
+ // Pool add: persist the tx
913
946
  const txHash = tx.getTxHash();
914
947
  const addResult = await this.mempools.txPool.addPendingTxs([tx], { source: 'gossip' });
915
948
 
@@ -917,7 +950,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
917
950
  const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
918
951
 
919
952
  this.logger.trace(`Validate propagated tx`, {
920
- isValid,
921
953
  wasAccepted,
922
954
  wasIgnored,
923
955
  [Attributes.P2P_ID]: source.toString(),
@@ -1160,7 +1192,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1160
1192
  // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
1161
1193
  const isValid = await this.blockReceivedCallback(block, sender);
1162
1194
  if (!isValid) {
1163
- this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1195
+ this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1164
1196
  }
1165
1197
  }
1166
1198
 
@@ -1532,43 +1564,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1532
1564
  }
1533
1565
 
1534
1566
  protected createRequestedTxValidator(): TxValidator {
1535
- return createTxReqRespValidator(this.proofVerifier, {
1567
+ return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
1536
1568
  l1ChainId: this.config.l1ChainId,
1537
1569
  rollupVersion: this.config.rollupVersion,
1538
1570
  });
1539
1571
  }
1540
1572
 
1541
- @trackSpan('Libp2pService.validatePropagatedTx', tx => ({
1542
- [Attributes.TX_HASH]: tx.getTxHash().toString(),
1543
- }))
1544
- protected async validatePropagatedTx(tx: Tx, peerId: PeerId): Promise<boolean> {
1545
- const currentBlockNumber = await this.archiver.getBlockNumber();
1546
-
1547
- // We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
1548
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1549
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1550
-
1551
- for (const validator of messageValidators) {
1552
- const outcome = await this.runValidations(tx, validator);
1553
-
1554
- if (outcome.allPassed) {
1555
- continue;
1556
- }
1557
- const { name } = outcome.failure;
1558
- let { severity } = outcome.failure;
1559
-
1560
- // Double spend validator has a special case handler
1561
- if (name === 'doubleSpendValidator') {
1562
- const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
1563
- severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1564
- }
1565
-
1566
- this.peerManager.penalizePeer(peerId, severity);
1567
- return false;
1568
- }
1569
- return true;
1570
- }
1571
-
1572
1573
  private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
1573
1574
  if (blockNumber === this.feesCache?.blockNumber) {
1574
1575
  return this.feesCache.gasFees;
@@ -1596,60 +1597,62 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1596
1597
  };
1597
1598
  }
1598
1599
 
1599
- public async validate(txs: Tx[]): Promise<void> {
1600
- const currentBlockNumber = await this.archiver.getBlockNumber();
1601
-
1602
- // We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
1603
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1604
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1600
+ public async validateTxsReceivedInBlockProposal(txs: Tx[]): Promise<void> {
1601
+ const validator = createTxValidatorForBlockProposalReceivedTxs(
1602
+ this.proofVerifier,
1603
+ { l1ChainId: this.config.l1ChainId, rollupVersion: this.config.rollupVersion },
1604
+ this.logger.getBindings(),
1605
+ );
1605
1606
 
1606
- await Promise.all(
1607
+ const results = await Promise.all(
1607
1608
  txs.map(async tx => {
1608
- for (const validator of messageValidators) {
1609
- const outcome = await this.runValidations(tx, validator);
1610
- if (!outcome.allPassed) {
1611
- throw new Error('Invalid tx detected', { cause: { outcome } });
1612
- }
1613
- }
1609
+ const result = await validator.validateTx(tx);
1610
+ return result.result !== 'invalid';
1614
1611
  }),
1615
1612
  );
1613
+ if (results.some(value => value === false)) {
1614
+ throw new Error('Invalid tx detected');
1615
+ }
1616
1616
  }
1617
1617
 
1618
- /**
1619
- * Create message validators for the given block number and timestamp.
1620
- *
1621
- * Each validator is a pair of a validator and a severity.
1622
- * If a validator fails, the peer is penalized with the severity of the validator.
1623
- *
1624
- * @param currentBlockNumber - The current synced block number.
1625
- * @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
1626
- * @returns The message validators.
1627
- */
1628
- private async createMessageValidators(
1618
+ /** Creates the first stage (fast) validators for gossiped transactions. */
1619
+ protected async createFirstStageMessageValidators(
1629
1620
  currentBlockNumber: BlockNumber,
1630
1621
  nextSlotTimestamp: UInt64,
1631
- ): Promise<Record<string, MessageValidator>[]> {
1622
+ ): Promise<Record<string, TransactionValidator>> {
1632
1623
  const gasFees = await this.getGasFees(currentBlockNumber);
1633
- const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
1634
-
1635
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1636
-
1637
- return createTxMessageValidators(
1624
+ const allowedInSetup = [
1625
+ ...(await getDefaultAllowedSetupFunctions()),
1626
+ ...(this.config.txPublicSetupAllowListExtend ?? []),
1627
+ ];
1628
+ const blockNumber = BlockNumber(currentBlockNumber + 1);
1629
+ const l1Constants = await this.archiver.getL1Constants();
1630
+
1631
+ return createFirstStageTxValidationsForGossipedTransactions(
1638
1632
  nextSlotTimestamp,
1639
- blockNumberInWhichTheTxIsConsideredToBeIncluded,
1633
+ blockNumber,
1640
1634
  this.worldStateSynchronizer,
1641
1635
  gasFees,
1642
1636
  this.config.l1ChainId,
1643
1637
  this.config.rollupVersion,
1644
1638
  protocolContractsHash,
1645
1639
  this.archiver,
1646
- this.proofVerifier,
1647
1640
  !this.config.disableTransactions,
1648
1641
  allowedInSetup,
1649
1642
  this.logger.getBindings(),
1643
+ {
1644
+ rollupManaLimit: l1Constants.rollupManaLimit,
1645
+ maxBlockL2Gas: this.config.validateMaxL2BlockGas,
1646
+ maxBlockDAGas: this.config.validateMaxDABlockGas,
1647
+ },
1650
1648
  );
1651
1649
  }
1652
1650
 
1651
+ /** Creates the second stage (expensive proof verification) validators for gossiped transactions. */
1652
+ protected createSecondStageMessageValidators(): Record<string, TransactionValidator> {
1653
+ return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
1654
+ }
1655
+
1653
1656
  /**
1654
1657
  * Run validations on a tx.
1655
1658
  * @param tx - The tx to validate.
@@ -1658,7 +1661,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1658
1661
  */
1659
1662
  private async runValidations(
1660
1663
  tx: Tx,
1661
- messageValidators: Record<string, MessageValidator>,
1664
+ messageValidators: Record<string, TransactionValidator>,
1662
1665
  ): Promise<ValidationOutcome> {
1663
1666
  const validationPromises = Object.entries(messageValidators).map(async ([name, { validator, severity }]) => {
1664
1667
  const { result } = await validator.validateTx(tx);
@@ -1667,8 +1670,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
1667
1670
 
1668
1671
  // A promise that resolves when all validations have been run
1669
1672
  const allValidations = await Promise.all(validationPromises);
1670
- const failed = allValidations.find(x => !x.isValid);
1671
- if (failed) {
1673
+ const failures = allValidations.filter(x => !x.isValid);
1674
+ if (failures.length > 0) {
1675
+ // Pick the most severe failure (lowest tolerance = harshest penalty)
1676
+ const failed = maxBy(failures, f => PeerErrorSeverityByHarshness.indexOf(f.severity))!;
1672
1677
  return {
1673
1678
  allPassed: false,
1674
1679
  failure: {
@@ -10,6 +10,7 @@ import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx';
10
10
  import type { PeerId } from '@libp2p/interface';
11
11
  import { peerIdFromString } from '@libp2p/peer-id';
12
12
 
13
+ import type { IMissingTxsTracker } from '../../tx_collection/missing_txs_tracker.js';
13
14
  import { ReqRespSubProtocol } from '.././interface.js';
14
15
  import { BlockTxsRequest, BlockTxsResponse, type BlockTxsSource } from '.././protocols/index.js';
15
16
  import { ReqRespStatus } from '.././status.js';
@@ -20,7 +21,7 @@ import {
20
21
  DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE,
21
22
  } from './config.js';
22
23
  import type { BatchTxRequesterLibP2PService, BatchTxRequesterOptions, ITxMetadataCollection } from './interface.js';
23
- import { MissingTxMetadata, MissingTxMetadataCollection } from './missing_txs.js';
24
+ import { MissingTxMetadataCollection } from './missing_txs.js';
24
25
  import { type IPeerCollection, PeerCollection } from './peer_collection.js';
25
26
  import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_validator.js';
26
27
 
@@ -60,7 +61,7 @@ export class BatchTxRequester {
60
61
  private readonly txBatchSize: number;
61
62
 
62
63
  constructor(
63
- missingTxs: TxHash[],
64
+ missingTxsTracker: IMissingTxsTracker,
64
65
  blockTxsSource: BlockTxsSource,
65
66
  pinnedPeer: PeerId | undefined,
66
67
  timeoutMs: number,
@@ -99,8 +100,7 @@ export class BatchTxRequester {
99
100
  this.p2pService.peerScoring,
100
101
  );
101
102
  }
102
- const entries: Array<[string, MissingTxMetadata]> = missingTxs.map(h => [h.toString(), new MissingTxMetadata(h)]);
103
- this.txsMetadata = new MissingTxMetadataCollection(entries, this.txBatchSize);
103
+ this.txsMetadata = new MissingTxMetadataCollection(missingTxsTracker, this.txBatchSize);
104
104
  this.smartRequesterSemaphore = this.opts.semaphore ?? new Semaphore(0);
105
105
  }
106
106
 
@@ -661,7 +661,7 @@ export class BatchTxRequester {
661
661
  /*
662
662
  * @returns true if all missing txs have been fetched */
663
663
  private fetchedAllTxs() {
664
- return Array.from(this.txsMetadata.values()).every(tx => tx.fetched);
664
+ return this.txsMetadata.getMissingTxHashes().size == 0;
665
665
  }
666
666
 
667
667
  /*
@@ -679,7 +679,7 @@ export class BatchTxRequester {
679
679
  this.unlockSmartRequesterSemaphores();
680
680
  }
681
681
 
682
- return aborted || this.txsMetadata.size === 0 || this.fetchedAllTxs() || this.dateProvider.now() > this.deadline;
682
+ return aborted || this.fetchedAllTxs() || this.dateProvider.now() > this.deadline;
683
683
  }
684
684
 
685
685
  /*
@@ -6,7 +6,6 @@ import type { PeerId } from '@libp2p/interface';
6
6
 
7
7
  import type { ConnectionSampler } from '../connection-sampler/connection_sampler.js';
8
8
  import type { ReqRespInterface } from '../interface.js';
9
- import type { MissingTxMetadata } from './missing_txs.js';
10
9
  import type { IPeerCollection } from './peer_collection.js';
11
10
  import type { BatchRequestTxValidatorConfig, IBatchRequestTxValidator } from './tx_validator.js';
12
11
 
@@ -15,18 +14,15 @@ export interface IPeerPenalizer {
15
14
  }
16
15
 
17
16
  export interface ITxMetadataCollection {
18
- size: number;
19
- values(): IterableIterator<MissingTxMetadata>;
20
17
  getMissingTxHashes(): Set<string>;
18
+ markFetched(peerId: PeerId, tx: Tx): boolean;
21
19
  getTxsToRequestFromThePeer(peer: PeerId): TxHash[];
22
20
  markRequested(txHash: TxHash): void;
23
21
  markInFlightBySmartPeer(txHash: TxHash): void;
24
22
  markNotInFlightBySmartPeer(txHash: TxHash): void;
25
23
  alreadyFetched(txHash: TxHash): boolean;
26
24
  // Returns true if tx was marked as fetched, false if it was already marked as fetched
27
- markFetched(peerId: PeerId, tx: Tx): boolean;
28
25
  markPeerHas(peerId: PeerId, txHashes: TxHash[]): void;
29
- getFetchedTxs(): Tx[];
30
26
  }
31
27
 
32
28
  /**
@@ -2,13 +2,13 @@ import { type Tx, TxHash } from '@aztec/stdlib/tx';
2
2
 
3
3
  import type { PeerId } from '@libp2p/interface';
4
4
 
5
+ import type { IMissingTxsTracker } from '../../tx_collection/missing_txs_tracker.js';
5
6
  import { DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE } from './config.js';
6
7
  import type { ITxMetadataCollection } from './interface.js';
7
8
 
8
- export class MissingTxMetadata {
9
+ class MissingTxMetadata {
9
10
  constructor(
10
- public readonly txHash: TxHash,
11
- public fetched = false,
11
+ public readonly txHash: string,
12
12
  public requestedCount = 0,
13
13
  public inFlightCount = 0,
14
14
  public tx: Tx | undefined = undefined,
@@ -30,24 +30,6 @@ export class MissingTxMetadata {
30
30
  public isInFlight(): boolean {
31
31
  return this.inFlightCount > 0;
32
32
  }
33
-
34
- //Returns true if this is the first time we mark it as fetched
35
- public markAsFetched(peerId: PeerId, tx: Tx): boolean {
36
- if (this.fetched) {
37
- return false;
38
- }
39
-
40
- this.fetched = true;
41
- this.tx = tx;
42
-
43
- this.peers.add(peerId.toString());
44
-
45
- return true;
46
- }
47
-
48
- public toString() {
49
- return this.txHash.toString();
50
- }
51
33
  }
52
34
 
53
35
  /*
@@ -55,21 +37,18 @@ export class MissingTxMetadata {
55
37
  * This could be better optimized but given expected count of missing txs (N < 100)
56
38
  * At the moment there is no need for it. And benefit is that we have everything in single store
57
39
  * */
58
- export class MissingTxMetadataCollection extends Map<string, MissingTxMetadata> implements ITxMetadataCollection {
40
+ export class MissingTxMetadataCollection implements ITxMetadataCollection {
41
+ private txMetadata = new Map<string, MissingTxMetadata>();
42
+
59
43
  constructor(
60
- entries?: readonly (readonly [string, MissingTxMetadata])[] | null,
44
+ private missingTxsTracker: IMissingTxsTracker,
61
45
  private readonly txBatchSize: number = DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE,
62
46
  ) {
63
- super(entries);
64
- }
65
- public getSortedByRequestedCountAsc(txs: string[]): MissingTxMetadata[] {
66
- return Array.from(this.values().filter(txMeta => txs.includes(txMeta.txHash.toString()))).sort(
67
- (a, b) => a.requestedCount - b.requestedCount,
68
- );
47
+ missingTxsTracker.missingTxHashes.forEach(hash => this.txMetadata.set(hash, new MissingTxMetadata(hash)));
69
48
  }
70
49
 
71
50
  public getPrioritizingNotInFlightAndLowerRequestCount(txs: string[]): MissingTxMetadata[] {
72
- const filtered = Array.from(this.values()).filter(txMeta => txs.includes(txMeta.txHash.toString()));
51
+ const filtered = Array.from(this.txMetadata.values()).filter(txMeta => txs.includes(txMeta.txHash.toString()));
73
52
 
74
53
  const [notInFlight, inFlight] = filtered.reduce<[MissingTxMetadata[], MissingTxMetadata[]]>(
75
54
  (buckets, tx) => {
@@ -85,43 +64,15 @@ export class MissingTxMetadataCollection extends Map<string, MissingTxMetadata>
85
64
  return [...notInFlight, ...inFlight];
86
65
  }
87
66
 
88
- public getFetchedTxHashes(): Set<string> {
89
- return new Set(
90
- this.values()
91
- .filter(t => t.fetched)
92
- .map(t => t.txHash.toString()),
93
- );
94
- }
95
-
96
67
  public getMissingTxHashes(): Set<string> {
97
- return new Set(
98
- this.values()
99
- .filter(t => !t.fetched)
100
- .map(t => t.txHash.toString()),
101
- );
102
- }
103
-
104
- public getInFlightTxHashes(): Set<string> {
105
- return new Set(
106
- this.values()
107
- .filter(t => t.isInFlight())
108
- .map(t => t.txHash.toString()),
109
- );
110
- }
111
-
112
- public getFetchedTxs(): Tx[] {
113
- return Array.from(
114
- this.values()
115
- .map(t => t.tx)
116
- .filter(t => !!t),
117
- );
68
+ return this.missingTxsTracker.missingTxHashes;
118
69
  }
119
70
 
120
71
  public getTxsPeerHas(peer: PeerId): Set<string> {
121
72
  const peerIdStr = peer.toString();
122
73
  const txsPeerHas = new Set<string>();
123
74
 
124
- this.values().forEach(txMeta => {
75
+ this.txMetadata.values().forEach(txMeta => {
125
76
  if (txMeta.peers.has(peerIdStr)) {
126
77
  txsPeerHas.add(txMeta.txHash.toString());
127
78
  }
@@ -132,13 +83,13 @@ export class MissingTxMetadataCollection extends Map<string, MissingTxMetadata>
132
83
 
133
84
  public getTxsToRequestFromThePeer(peer: PeerId): TxHash[] {
134
85
  const txsPeerHas = this.getTxsPeerHas(peer);
135
- const fetchedTxs = this.getFetchedTxHashes();
86
+ const missingTxHashes = this.getMissingTxHashes();
136
87
 
137
- const txsToRequest = txsPeerHas.difference(fetchedTxs);
88
+ const txsToRequest = txsPeerHas.intersection(missingTxHashes);
138
89
 
139
90
  if (txsToRequest.size >= this.txBatchSize) {
140
91
  return this.getPrioritizingNotInFlightAndLowerRequestCount(Array.from(txsToRequest))
141
- .map(t => t.txHash)
92
+ .map(t => TxHash.fromString(t.txHash))
142
93
  .slice(0, this.txBatchSize);
143
94
  }
144
95
 
@@ -150,13 +101,13 @@ export class MissingTxMetadataCollection extends Map<string, MissingTxMetadata>
150
101
  Array.from(this.getMissingTxHashes().difference(txsToRequest)),
151
102
  )
152
103
  .slice(0, countToFill)
153
- .map(t => t.txHash);
104
+ .map(t => TxHash.fromString(t.txHash));
154
105
 
155
106
  return [...Array.from(txsToRequest).map(t => TxHash.fromString(t)), ...txsToFill];
156
107
  }
157
108
 
158
109
  public markRequested(txHash: TxHash) {
159
- this.get(txHash.toString())?.markAsRequested();
110
+ this.txMetadata.get(txHash.toString())?.markAsRequested();
160
111
  }
161
112
 
162
113
  /*
@@ -165,7 +116,7 @@ export class MissingTxMetadataCollection extends Map<string, MissingTxMetadata>
165
116
  * "dumb" peer might return it, or might not - we don't know
166
117
  * */
167
118
  public markInFlightBySmartPeer(txHash: TxHash) {
168
- this.get(txHash.toString())?.markInFlight();
119
+ this.txMetadata.get(txHash.toString())?.markInFlight();
169
120
  }
170
121
 
171
122
  /*
@@ -173,16 +124,16 @@ export class MissingTxMetadataCollection extends Map<string, MissingTxMetadata>
173
124
  * Because the smart peer should return this tx, whereas
174
125
  * "dumb" peer might return it, or might not - we don't know*/
175
126
  public markNotInFlightBySmartPeer(txHash: TxHash) {
176
- this.get(txHash.toString())?.markNotInFlight();
127
+ this.txMetadata.get(txHash.toString())?.markNotInFlight();
177
128
  }
178
129
 
179
130
  public alreadyFetched(txHash: TxHash): boolean {
180
- return this.get(txHash.toString())?.fetched ?? false;
131
+ return !this.missingTxsTracker.isMissing(txHash.toString());
181
132
  }
182
133
 
183
134
  public markFetched(peerId: PeerId, tx: Tx): boolean {
184
135
  const txHashStr = tx.txHash.toString();
185
- const txMeta = this.get(txHashStr);
136
+ const txMeta = this.txMetadata.get(txHashStr);
186
137
  if (!txMeta) {
187
138
  //TODO: what to do about peer which sent txs we didn't request?
188
139
  // 1. don't request from it in the scope of this batch request
@@ -192,7 +143,8 @@ export class MissingTxMetadataCollection extends Map<string, MissingTxMetadata>
192
143
  return false;
193
144
  }
194
145
 
195
- return txMeta.markAsFetched(peerId, tx);
146
+ txMeta.peers.add(peerId.toString());
147
+ return this.missingTxsTracker.markFetched(tx);
196
148
  }
197
149
 
198
150
  public markPeerHas(peerId: PeerId, txHash: TxHash[]) {
@@ -200,7 +152,7 @@ export class MissingTxMetadataCollection extends Map<string, MissingTxMetadata>
200
152
  txHash
201
153
  .map(t => t.toString())
202
154
  .forEach(txh => {
203
- const txMeta = this.get(txh);
155
+ const txMeta = this.txMetadata.get(txh);
204
156
  if (txMeta) {
205
157
  txMeta.peers.add(peerIdStr);
206
158
  }