@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.
- package/dest/client/factory.d.ts +2 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +1 -2
- package/dest/client/p2p_client.d.ts +1 -1
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +4 -6
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -17
- package/dest/config.d.ts +6 -6
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +6 -6
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +4 -8
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
- package/dest/mem_pools/index.d.ts +2 -1
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.d.ts +2 -4
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +14 -16
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +125 -0
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +596 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +32 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +112 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +157 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +52 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +123 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +78 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
- package/dest/mem_pools/tx_pool/index.d.ts +3 -0
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/index.js +2 -0
- package/dest/mem_pools/tx_pool/priority.d.ts +12 -0
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/priority.js +15 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +127 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/tx_pool.js +3 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +7 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +402 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +5 -7
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +0 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +6 -5
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +1 -5
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +43 -26
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +0 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -2
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +1 -18
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +4 -5
- package/dest/msg_validators/clock_tolerance.d.ts +1 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +3 -4
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +5 -5
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +2 -4
- package/dest/services/libp2p/libp2p_service.d.ts +9 -7
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +59 -137
- package/dest/services/peer-manager/metrics.d.ts +1 -3
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +0 -6
- package/dest/services/peer-manager/peer_manager.d.ts +2 -6
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +9 -24
- package/dest/services/peer-manager/peer_scoring.d.ts +2 -5
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +10 -28
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +8 -11
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +101 -82
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -3
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +4 -5
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +7 -13
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +11 -19
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +15 -52
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +3 -4
- package/dest/services/service.d.ts +1 -7
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +73 -57
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
- package/dest/services/tx_collection/slow_tx_collection.js +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +6 -3
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +1 -6
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +1 -9
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.d.ts +1 -1
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +2 -20
- package/dest/testbench/p2p_client_testbench_worker.js +15 -44
- package/dest/testbench/worker_client_manager.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +2 -2
- package/dest/util.d.ts +4 -9
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +9 -2
- package/package.json +14 -14
- package/src/client/factory.ts +2 -3
- package/src/client/p2p_client.ts +4 -6
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +9 -19
- package/src/config.ts +10 -10
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +7 -8
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
- package/src/mem_pools/index.ts +3 -0
- package/src/mem_pools/instrumentation.ts +13 -17
- package/src/mem_pools/tx_pool/README.md +270 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +746 -0
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +132 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +208 -0
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +163 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +93 -0
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
- package/src/mem_pools/tx_pool/index.ts +2 -0
- package/src/mem_pools/tx_pool/priority.ts +20 -0
- package/src/mem_pools/tx_pool/tx_pool.ts +141 -0
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +321 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +4 -7
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +5 -11
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -29
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +0 -3
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1 -19
- package/src/msg_validators/attestation_validator/README.md +1 -1
- package/src/msg_validators/attestation_validator/attestation_validator.ts +4 -5
- package/src/msg_validators/clock_tolerance.ts +3 -4
- package/src/msg_validators/proposal_validator/README.md +4 -4
- package/src/msg_validators/proposal_validator/proposal_validator.ts +5 -6
- package/src/msg_validators/tx_validator/metadata_validator.ts +4 -12
- package/src/services/discv5/discV5_service.ts +2 -4
- package/src/services/libp2p/libp2p_service.ts +71 -135
- package/src/services/peer-manager/metrics.ts +0 -7
- package/src/services/peer-manager/peer_manager.ts +9 -28
- package/src/services/peer-manager/peer_scoring.ts +5 -21
- package/src/services/reqresp/batch-tx-requester/README.md +7 -46
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +111 -78
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -2
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +6 -13
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +24 -68
- package/src/services/reqresp/reqresp.ts +3 -5
- package/src/services/service.ts +0 -7
- package/src/services/tx_collection/fast_tx_collection.ts +83 -57
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +13 -8
- package/src/services/tx_collection/slow_tx_collection.ts +1 -1
- package/src/services/tx_collection/tx_collection.ts +5 -3
- package/src/test-helpers/make-test-p2p-clients.ts +1 -1
- package/src/test-helpers/mock-pubsub.ts +0 -9
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/test-helpers/testbench-utils.ts +3 -28
- package/src/testbench/p2p_client_testbench_worker.ts +15 -44
- package/src/testbench/worker_client_manager.ts +2 -2
- package/src/util.ts +13 -9
- package/dest/services/tx_collection/request_tracker.d.ts +0 -53
- package/dest/services/tx_collection/request_tracker.d.ts.map +0 -1
- package/dest/services/tx_collection/request_tracker.js +0 -84
- package/src/services/tx_collection/request_tracker.ts +0 -127
|
@@ -170,37 +170,6 @@ class BlockTxsResponse {
|
|
|
170
170
|
|
|
171
171
|
The `BitVector` is a compact representation where each bit corresponds to a transaction index in the block proposal. This allows efficient capability advertisement without repeating full hashes.
|
|
172
172
|
|
|
173
|
-
## Cancellation
|
|
174
|
-
|
|
175
|
-
All cancellation is managed by a single `RequestTracker` instance, shared across the entire collection
|
|
176
|
-
flow. The `RequestTracker` owns the deadline, tracks which txs are still missing, and exposes a
|
|
177
|
-
`cancellationToken` promise that resolves when the request should stop (deadline hit, all txs fetched,
|
|
178
|
-
or external `cancel()` call).
|
|
179
|
-
|
|
180
|
-
Cancellation propagates from the deepest stack level upward:
|
|
181
|
-
|
|
182
|
-
```
|
|
183
|
-
RequestTracker.finish()
|
|
184
|
-
├── resolves cancellationToken promise
|
|
185
|
-
│
|
|
186
|
-
├── BatchTxRequester workers (deepest)
|
|
187
|
-
│ ├── shouldStop() checks requestTracker.cancelled → exit loop
|
|
188
|
-
│ ├── sleepClampedToDeadline races sleep vs cancellationToken → wakes
|
|
189
|
-
│ └── semaphore.acquire races vs cancellationToken → wakes
|
|
190
|
-
│ │
|
|
191
|
-
│ ▼ workers settle → txQueue.end() → generator returns
|
|
192
|
-
│
|
|
193
|
-
├── Node collection loops
|
|
194
|
-
│ ├── notFinished() checks requestTracker.cancelled → exit loop
|
|
195
|
-
│ └── inter-retry sleep races vs cancellationToken → wakes
|
|
196
|
-
│ │
|
|
197
|
-
│ ▼ all node loops settle
|
|
198
|
-
│
|
|
199
|
-
└── collectFast (outermost)
|
|
200
|
-
awaits Promise.allSettled([reqresp, nodes]) → settles after inner tasks
|
|
201
|
-
finally: requestTracker.cancel() (idempotent), cleanup
|
|
202
|
-
```
|
|
203
|
-
|
|
204
173
|
## Key Files
|
|
205
174
|
|
|
206
175
|
| File | Description |
|
|
@@ -210,16 +179,15 @@ RequestTracker.finish()
|
|
|
210
179
|
| `peer_collection.ts` | Manages peer classification (dumb/smart/bad) and rate limiting |
|
|
211
180
|
| `interface.ts` | Type definitions for dependencies |
|
|
212
181
|
| `../protocols/block_txs/` | Wire protocol definitions (`BlockTxsRequest`, `BlockTxsResponse`, `BitVector`) |
|
|
213
|
-
| `../../tx_collection/request_tracker.ts` | Centralized deadline, missing tx tracking, and cancellation signal |
|
|
214
182
|
|
|
215
183
|
## Stopping Conditions
|
|
216
184
|
|
|
217
|
-
The `BatchTxRequester` stops when any of these conditions are met
|
|
185
|
+
The `BatchTxRequester` stops when any of these conditions are met:
|
|
218
186
|
|
|
219
|
-
1. **All transactions fetched** -
|
|
220
|
-
2. **Deadline exceeded** -
|
|
221
|
-
3. **
|
|
222
|
-
4. **No transactions to fetch** -
|
|
187
|
+
1. **All transactions fetched** - Success!
|
|
188
|
+
2. **Deadline exceeded** - Timeout configured by caller
|
|
189
|
+
3. **Abort signal** - External cancellation
|
|
190
|
+
4. **No transactions to fetch** - Nothing was missing
|
|
223
191
|
|
|
224
192
|
## Configuration
|
|
225
193
|
|
|
@@ -260,15 +228,11 @@ Request to peer fails
|
|
|
260
228
|
## Usage Example
|
|
261
229
|
|
|
262
230
|
```typescript
|
|
263
|
-
const requestTracker = RequestTracker.create(
|
|
264
|
-
missingTxHashes, // TxHash[] - what we need
|
|
265
|
-
new Date(Date.now() + 5_000), // deadline
|
|
266
|
-
);
|
|
267
|
-
|
|
268
231
|
const requester = new BatchTxRequester(
|
|
269
|
-
|
|
232
|
+
missingTxHashes, // TxHash[] - what we need
|
|
270
233
|
blockTxsSource, // BlockTxsSource - the proposal or block we need txs for
|
|
271
234
|
pinnedPeer, // PeerId | undefined - peer expected to have the txs
|
|
235
|
+
timeoutMs, // number - how long to try
|
|
272
236
|
p2pService, // BatchTxRequesterLibP2PService
|
|
273
237
|
);
|
|
274
238
|
|
|
@@ -309,8 +273,6 @@ const txs = await BatchTxRequester.collectAllTxs(requester.run());
|
|
|
309
273
|
│ 1. Try RPC nodes first (fast) │ │ Periodic polling of RPC nodes │
|
|
310
274
|
│ 2. Fall back to BatchTxRequester │ │ and peers for missing txs │
|
|
311
275
|
│ │ │ │
|
|
312
|
-
│ Creates RequestTracker per │ │ │
|
|
313
|
-
│ request with deadline │ │ │
|
|
314
276
|
└───────────────────┬───────────────┘ └─────────────────────────────────────┘
|
|
315
277
|
│
|
|
316
278
|
│ For 'proposal' and 'block' requests
|
|
@@ -319,7 +281,6 @@ const txs = await BatchTxRequester.collectAllTxs(requester.run());
|
|
|
319
281
|
│ BatchTxRequester │
|
|
320
282
|
│ │
|
|
321
283
|
│ Aggressive parallel fetching from multiple peers │
|
|
322
|
-
│ Shares RequestTracker with FastTxCollection for unified cancellation │
|
|
323
284
|
│ Uses BLOCK_TXS sub-protocol for efficient batching │
|
|
324
285
|
└───────────────────┬─────────────────────────────────────────────────────────┘
|
|
325
286
|
│
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { chunkWrapAround } from '@aztec/foundation/collection';
|
|
2
|
+
import { TimeoutError } from '@aztec/foundation/error';
|
|
2
3
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
4
|
import { FifoMemoryQueue, type ISemaphore, Semaphore } from '@aztec/foundation/queue';
|
|
4
5
|
import { sleep } from '@aztec/foundation/sleep';
|
|
5
|
-
import { DateProvider } from '@aztec/foundation/timer';
|
|
6
|
+
import { DateProvider, executeTimeout } from '@aztec/foundation/timer';
|
|
6
7
|
import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
7
8
|
import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx';
|
|
8
9
|
|
|
9
10
|
import type { PeerId } from '@libp2p/interface';
|
|
11
|
+
import { peerIdFromString } from '@libp2p/peer-id';
|
|
10
12
|
|
|
11
|
-
import type {
|
|
13
|
+
import type { IMissingTxsTracker } from '../../tx_collection/missing_txs_tracker.js';
|
|
12
14
|
import { ReqRespSubProtocol } from '.././interface.js';
|
|
13
15
|
import { BlockTxsRequest, BlockTxsResponse, type BlockTxsSource } from '.././protocols/index.js';
|
|
14
16
|
import { ReqRespStatus } from '.././status.js';
|
|
@@ -41,14 +43,16 @@ import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_val
|
|
|
41
43
|
* - Is the peer which was unable to send us successful response N times in a row
|
|
42
44
|
* */
|
|
43
45
|
export class BatchTxRequester {
|
|
44
|
-
private readonly requestTracker: IRequestTracker;
|
|
45
46
|
private readonly blockTxsSource: BlockTxsSource;
|
|
46
47
|
private readonly pinnedPeer: PeerId | undefined;
|
|
48
|
+
private readonly timeoutMs: number;
|
|
47
49
|
private readonly p2pService: BatchTxRequesterLibP2PService;
|
|
48
50
|
private readonly logger: Logger;
|
|
51
|
+
private readonly dateProvider: DateProvider;
|
|
49
52
|
private readonly opts: BatchTxRequesterOptions;
|
|
50
53
|
private readonly peers: IPeerCollection;
|
|
51
54
|
private readonly txsMetadata: ITxMetadataCollection;
|
|
55
|
+
private readonly deadline: number;
|
|
52
56
|
private readonly smartRequesterSemaphore: ISemaphore;
|
|
53
57
|
private readonly txQueue: FifoMemoryQueue<Tx>;
|
|
54
58
|
private readonly txValidator: IBatchRequestTxValidator;
|
|
@@ -57,19 +61,21 @@ export class BatchTxRequester {
|
|
|
57
61
|
private readonly txBatchSize: number;
|
|
58
62
|
|
|
59
63
|
constructor(
|
|
60
|
-
|
|
64
|
+
missingTxsTracker: IMissingTxsTracker,
|
|
61
65
|
blockTxsSource: BlockTxsSource,
|
|
62
66
|
pinnedPeer: PeerId | undefined,
|
|
67
|
+
timeoutMs: number,
|
|
63
68
|
p2pService: BatchTxRequesterLibP2PService,
|
|
64
69
|
logger?: Logger,
|
|
65
70
|
dateProvider?: DateProvider,
|
|
66
71
|
opts?: BatchTxRequesterOptions,
|
|
67
72
|
) {
|
|
68
|
-
this.requestTracker = requestTracker;
|
|
69
73
|
this.blockTxsSource = blockTxsSource;
|
|
70
74
|
this.pinnedPeer = pinnedPeer;
|
|
75
|
+
this.timeoutMs = timeoutMs;
|
|
71
76
|
this.p2pService = p2pService;
|
|
72
77
|
this.logger = logger ?? createLogger('p2p:reqresp_batch');
|
|
78
|
+
this.dateProvider = dateProvider ?? new DateProvider();
|
|
73
79
|
this.opts = opts ?? {};
|
|
74
80
|
|
|
75
81
|
this.smartParallelWorkerCount =
|
|
@@ -77,22 +83,24 @@ export class BatchTxRequester {
|
|
|
77
83
|
this.dumbParallelWorkerCount =
|
|
78
84
|
this.opts.dumbParallelWorkerCount ?? DEFAULT_BATCH_TX_REQUESTER_DUMB_PARALLEL_WORKER_COUNT;
|
|
79
85
|
this.txBatchSize = this.opts.txBatchSize ?? DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE;
|
|
86
|
+
this.deadline = this.dateProvider.now() + this.timeoutMs;
|
|
80
87
|
this.txQueue = new FifoMemoryQueue(this.logger);
|
|
81
88
|
this.txValidator = this.opts.txValidator ?? new BatchRequestTxValidator(this.p2pService.txValidatorConfig);
|
|
82
89
|
|
|
83
90
|
if (this.opts.peerCollection) {
|
|
84
91
|
this.peers = this.opts.peerCollection;
|
|
85
92
|
} else {
|
|
93
|
+
const initialPeers = this.p2pService.connectionSampler.getPeerListSortedByConnectionCountAsc();
|
|
86
94
|
const badPeerThreshold = this.opts.badPeerThreshold ?? DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD;
|
|
87
95
|
this.peers = new PeerCollection(
|
|
88
|
-
|
|
96
|
+
initialPeers,
|
|
89
97
|
this.pinnedPeer,
|
|
90
|
-
dateProvider
|
|
98
|
+
this.dateProvider,
|
|
91
99
|
badPeerThreshold,
|
|
92
100
|
this.p2pService.peerScoring,
|
|
93
101
|
);
|
|
94
102
|
}
|
|
95
|
-
this.txsMetadata = new MissingTxMetadataCollection(
|
|
103
|
+
this.txsMetadata = new MissingTxMetadataCollection(missingTxsTracker, this.txBatchSize);
|
|
96
104
|
this.smartRequesterSemaphore = this.opts.semaphore ?? new Semaphore(0);
|
|
97
105
|
}
|
|
98
106
|
|
|
@@ -100,30 +108,40 @@ export class BatchTxRequester {
|
|
|
100
108
|
* Fetches all missing transactions and yields them one by one
|
|
101
109
|
* */
|
|
102
110
|
public async *run(): AsyncGenerator<Tx, Tx | undefined, unknown> {
|
|
111
|
+
// Our timeout is represented in milliseconds but queue expects seconds
|
|
112
|
+
// We also want to make sure we wait at least 1 second in case of very low timeouts
|
|
113
|
+
const timeoutQueueAfter = Math.max(Math.ceil(this.timeoutMs / 1_000), 1);
|
|
103
114
|
try {
|
|
104
115
|
if (this.txsMetadata.getMissingTxHashes().size === 0) {
|
|
105
116
|
return undefined;
|
|
106
117
|
}
|
|
107
118
|
|
|
108
|
-
// Start workers in background
|
|
109
|
-
const workersPromise =
|
|
110
|
-
this.smartRequester(),
|
|
111
|
-
this.
|
|
112
|
-
|
|
113
|
-
]).finally(() => {
|
|
119
|
+
// Start workers in background
|
|
120
|
+
const workersPromise = executeTimeout(
|
|
121
|
+
() => Promise.allSettled([this.smartRequester(), this.dumbRequester(), this.pinnedPeerRequester()]),
|
|
122
|
+
this.timeoutMs,
|
|
123
|
+
).finally(() => {
|
|
114
124
|
this.txQueue.end();
|
|
115
125
|
});
|
|
116
126
|
|
|
117
|
-
// Yield txs as workers put them on the queue. The queue's end() drains remaining items
|
|
118
|
-
// before returning null, so we don't lose any txs.
|
|
119
127
|
while (true) {
|
|
120
|
-
const tx = await this.txQueue.get();
|
|
128
|
+
const tx = await this.txQueue.get(timeoutQueueAfter);
|
|
121
129
|
|
|
130
|
+
// null indicates that the queue has ended
|
|
122
131
|
if (tx === null) {
|
|
123
132
|
break;
|
|
124
133
|
}
|
|
125
134
|
|
|
126
135
|
yield tx;
|
|
136
|
+
|
|
137
|
+
if (this.shouldStop()) {
|
|
138
|
+
// Drain queue before ending
|
|
139
|
+
let remaining;
|
|
140
|
+
while ((remaining = this.txQueue.getImmediate()) !== undefined) {
|
|
141
|
+
yield remaining;
|
|
142
|
+
}
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
127
145
|
}
|
|
128
146
|
|
|
129
147
|
this.unlockSmartRequesterSemaphores();
|
|
@@ -209,6 +227,7 @@ export class BatchTxRequester {
|
|
|
209
227
|
* Starts dumb worker loops
|
|
210
228
|
* */
|
|
211
229
|
private async dumbRequester() {
|
|
230
|
+
const nextPeerIndex = this.makeRoundRobinIndexer();
|
|
212
231
|
const nextBatchIndex = this.makeRoundRobinIndexer();
|
|
213
232
|
|
|
214
233
|
// Chunk missing tx hashes into batches of txBatchSize, wrapping around to ensure no peer gets less than txBatchSize
|
|
@@ -244,9 +263,15 @@ export class BatchTxRequester {
|
|
|
244
263
|
return { blockRequest, txs };
|
|
245
264
|
};
|
|
246
265
|
|
|
247
|
-
const
|
|
266
|
+
const nextPeer = () => {
|
|
267
|
+
const peers = this.peers.getDumbPeersToQuery();
|
|
268
|
+
const idx = nextPeerIndex(() => peers.length);
|
|
269
|
+
return idx === undefined ? undefined : peerIdFromString(peers[idx]);
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const workerCount = Math.min(this.dumbParallelWorkerCount, this.peers.getAllPeers().size);
|
|
248
273
|
const workers = Array.from({ length: workerCount }, (_, index) =>
|
|
249
|
-
this.dumbWorkerLoop(
|
|
274
|
+
this.dumbWorkerLoop(nextPeer, makeRequest, index + 1),
|
|
250
275
|
);
|
|
251
276
|
|
|
252
277
|
await Promise.allSettled(workers);
|
|
@@ -307,6 +332,14 @@ export class BatchTxRequester {
|
|
|
307
332
|
* Starts smart worker loops
|
|
308
333
|
* */
|
|
309
334
|
private async smartRequester() {
|
|
335
|
+
const nextPeerIndex = this.makeRoundRobinIndexer();
|
|
336
|
+
|
|
337
|
+
const nextPeer = () => {
|
|
338
|
+
const peers = this.peers.getSmartPeersToQuery();
|
|
339
|
+
const idx = nextPeerIndex(() => peers.length);
|
|
340
|
+
return idx === undefined ? undefined : peerIdFromString(peers[idx]);
|
|
341
|
+
};
|
|
342
|
+
|
|
310
343
|
const makeRequest = (pid: PeerId) => {
|
|
311
344
|
const txs = this.txsMetadata.getTxsToRequestFromThePeer(pid);
|
|
312
345
|
const blockRequest = BlockTxsRequest.fromTxsSourceAndMissingTxs(this.blockTxsSource, txs);
|
|
@@ -317,8 +350,9 @@ export class BatchTxRequester {
|
|
|
317
350
|
return { blockRequest, txs };
|
|
318
351
|
};
|
|
319
352
|
|
|
320
|
-
const workers = Array.from(
|
|
321
|
-
|
|
353
|
+
const workers = Array.from(
|
|
354
|
+
{ length: Math.min(this.smartParallelWorkerCount, this.peers.getAllPeers().size) },
|
|
355
|
+
(_, index) => this.smartWorkerLoop(nextPeer, makeRequest, index + 1),
|
|
322
356
|
);
|
|
323
357
|
|
|
324
358
|
await Promise.allSettled(workers);
|
|
@@ -344,10 +378,7 @@ export class BatchTxRequester {
|
|
|
344
378
|
) {
|
|
345
379
|
try {
|
|
346
380
|
this.logger.trace(`Smart worker ${workerIndex} started`);
|
|
347
|
-
await
|
|
348
|
-
if (this.requestTracker.checkCancelled()) {
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
381
|
+
await executeTimeout((_: AbortSignal) => this.smartRequesterSemaphore.acquire(), this.timeoutMs);
|
|
351
382
|
this.logger.trace(`Smart worker ${workerIndex} acquired semaphore`);
|
|
352
383
|
|
|
353
384
|
while (!this.shouldStop()) {
|
|
@@ -356,25 +387,30 @@ export class BatchTxRequester {
|
|
|
356
387
|
if (weRanOutOfPeersToQuery) {
|
|
357
388
|
this.logger.debug(`Worker loop smart: No more peers to query`);
|
|
358
389
|
|
|
359
|
-
// If
|
|
360
|
-
|
|
361
|
-
const
|
|
362
|
-
if (
|
|
363
|
-
|
|
364
|
-
|
|
390
|
+
// If there are no more dumb peers to query then none of our peers can become smart,
|
|
391
|
+
// thus we can simply exit this worker
|
|
392
|
+
const noMoreDumbPeersToQuery = this.peers.getDumbPeersToQuery().length === 0;
|
|
393
|
+
if (noMoreDumbPeersToQuery) {
|
|
394
|
+
// These might be either smart peers that will get unblocked after _some time_
|
|
395
|
+
const nextSmartPeerDelay = this.peers.getNextSmartPeerAvailabilityDelayMs();
|
|
396
|
+
const thereAreSomeRateLimitedSmartPeers = nextSmartPeerDelay !== undefined;
|
|
397
|
+
if (thereAreSomeRateLimitedSmartPeers) {
|
|
398
|
+
await this.sleepClampedToDeadline(nextSmartPeerDelay);
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
this.logger.debug(`Worker loop smart: No more smart peers to query killing ${workerIndex}`);
|
|
403
|
+
break;
|
|
365
404
|
}
|
|
366
405
|
|
|
406
|
+
// Otherwise there are still some dumb peers that could become smart.
|
|
367
407
|
// We end up here when all known smart peers became temporarily unavailable via combination of
|
|
368
408
|
// (bad, in-flight, or rate-limited) or in some weird scenario all current smart peers turn bad which is permanent
|
|
369
|
-
// but
|
|
370
|
-
// or new peer can join as dumb and be promoted later
|
|
409
|
+
// but dumb peers still exist that could become smart.
|
|
371
410
|
//
|
|
372
411
|
// When a dumb peer responds with valid txIndices, it gets
|
|
373
412
|
// promoted to smart and releases the semaphore, waking this worker.
|
|
374
|
-
await
|
|
375
|
-
if (this.requestTracker.checkCancelled()) {
|
|
376
|
-
break;
|
|
377
|
-
}
|
|
413
|
+
await executeTimeout((_: AbortSignal) => this.smartRequesterSemaphore.acquire(), this.timeoutMs);
|
|
378
414
|
this.logger.debug(`Worker loop smart: acquired next smart peer`);
|
|
379
415
|
continue;
|
|
380
416
|
}
|
|
@@ -401,7 +437,11 @@ export class BatchTxRequester {
|
|
|
401
437
|
});
|
|
402
438
|
}
|
|
403
439
|
} catch (err: any) {
|
|
404
|
-
|
|
440
|
+
if (err instanceof TimeoutError) {
|
|
441
|
+
this.logger.debug(`Smart worker ${workerIndex} timed out waiting for semaphore`);
|
|
442
|
+
} else {
|
|
443
|
+
this.logger.error(`Smart worker ${workerIndex} encountered an error: ${err}`);
|
|
444
|
+
}
|
|
405
445
|
} finally {
|
|
406
446
|
this.logger.debug(`Smart worker ${workerIndex} finished`);
|
|
407
447
|
}
|
|
@@ -449,18 +489,9 @@ export class BatchTxRequester {
|
|
|
449
489
|
* this implies we will query these peers couple of more times and give them a chance to "redeem" themselves before completely ignoring them
|
|
450
490
|
*/
|
|
451
491
|
private handleFailResponseFromPeer(peerId: PeerId, responseStatus: ReqRespStatus) {
|
|
492
|
+
//TODO: Should we ban these peers?
|
|
452
493
|
if (responseStatus === ReqRespStatus.FAILURE || responseStatus === ReqRespStatus.UNKNOWN) {
|
|
453
494
|
this.peers.penalisePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
454
|
-
this.peers.markPeerDumb(peerId);
|
|
455
|
-
this.txsMetadata.clearPeerData(peerId);
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// NOT_FOUND means the peer pruned its block proposal — it can no longer serve
|
|
460
|
-
// index-based requests, but this is a legitimate state so we don't penalize.
|
|
461
|
-
if (responseStatus === ReqRespStatus.NOT_FOUND) {
|
|
462
|
-
this.peers.markPeerDumb(peerId);
|
|
463
|
-
this.txsMetadata.clearPeerData(peerId);
|
|
464
495
|
return;
|
|
465
496
|
}
|
|
466
497
|
|
|
@@ -514,9 +545,6 @@ export class BatchTxRequester {
|
|
|
514
545
|
});
|
|
515
546
|
|
|
516
547
|
if (hasInvalidTx) {
|
|
517
|
-
this.logger.warn(`Penalizing peer ${peerId.toString()} for sending invalid transactions in batch response`, {
|
|
518
|
-
peerId,
|
|
519
|
-
});
|
|
520
548
|
this.peers.penalisePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
521
549
|
} else {
|
|
522
550
|
// If we have received successful response from the peer, they have "redeemed" themselves and not considered bad anymore
|
|
@@ -553,9 +581,10 @@ export class BatchTxRequester {
|
|
|
553
581
|
return;
|
|
554
582
|
}
|
|
555
583
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
584
|
+
// If block response is invalid we still want to query this peer in the future
|
|
585
|
+
// Because they sent successful response, so they might become smart peer in the future
|
|
586
|
+
// Or send us needed txs
|
|
587
|
+
if (!this.isBlockResponseValid(response)) {
|
|
559
588
|
return;
|
|
560
589
|
}
|
|
561
590
|
|
|
@@ -570,28 +599,18 @@ export class BatchTxRequester {
|
|
|
570
599
|
this.markTxsPeerHas(peerId, response);
|
|
571
600
|
|
|
572
601
|
// Unblock smart workers
|
|
573
|
-
this.
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* Handles an archive root mismatch between local state and peer response.
|
|
578
|
-
*
|
|
579
|
-
* - Response archive is Fr.ZERO (peer pruned proposal, legitimate): marks peer dumb.
|
|
580
|
-
* - Non-zero archive mismatch (malicious response): penalises + marks dumb.
|
|
581
|
-
*/
|
|
582
|
-
private handleArchiveRootMismatch(peerId: PeerId, response: BlockTxsResponse): void {
|
|
583
|
-
if (!response.archiveRoot.isZero()) {
|
|
584
|
-
this.peers.penalisePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
602
|
+
if (this.peers.getSmartPeersToQuery().length <= this.smartParallelWorkerCount) {
|
|
603
|
+
this.smartRequesterSemaphore.release();
|
|
585
604
|
}
|
|
605
|
+
}
|
|
586
606
|
|
|
587
|
-
|
|
588
|
-
this.
|
|
607
|
+
private isBlockResponseValid(response: BlockTxsResponse): boolean {
|
|
608
|
+
const archiveRootsMatch = this.blockTxsSource.archive.toString() === response.archiveRoot.toString();
|
|
609
|
+
const peerHasSomeTxsFromProposal = !response.txIndices.isEmpty();
|
|
610
|
+
return archiveRootsMatch && peerHasSomeTxsFromProposal;
|
|
589
611
|
}
|
|
590
612
|
|
|
591
613
|
private peerHasSomeTxsWeAreMissing(_peerId: PeerId, response: BlockTxsResponse): boolean {
|
|
592
|
-
if (response.txIndices.isEmpty()) {
|
|
593
|
-
return false;
|
|
594
|
-
}
|
|
595
614
|
const txsPeerHas = new Set(this.extractHashesPeerHasFromResponse(response).map(h => h.toString()));
|
|
596
615
|
return this.txsMetadata.getMissingTxHashes().intersection(txsPeerHas).size > 0;
|
|
597
616
|
}
|
|
@@ -640,14 +659,27 @@ export class BatchTxRequester {
|
|
|
640
659
|
}
|
|
641
660
|
|
|
642
661
|
/*
|
|
643
|
-
*
|
|
644
|
-
|
|
662
|
+
* @returns true if all missing txs have been fetched */
|
|
663
|
+
private fetchedAllTxs() {
|
|
664
|
+
return this.txsMetadata.getMissingTxHashes().size == 0;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/*
|
|
668
|
+
* Checks if the BatchTxRequester should stop fetching missing txs
|
|
669
|
+
* Conditions for stopping are:
|
|
670
|
+
* - There have been no missing transactions to start with
|
|
671
|
+
* - All transactions have been fetched
|
|
672
|
+
* - The deadline has been hit (no more time to fetch)
|
|
673
|
+
* - This process has been cancelled via abortSignal
|
|
674
|
+
*
|
|
675
|
+
* @returns true if BatchTxRequester should stop, otherwise false*/
|
|
645
676
|
private shouldStop() {
|
|
646
|
-
|
|
677
|
+
const aborted = this.opts.abortSignal?.aborted ?? false;
|
|
678
|
+
if (aborted) {
|
|
647
679
|
this.unlockSmartRequesterSemaphores();
|
|
648
680
|
}
|
|
649
681
|
|
|
650
|
-
return this.
|
|
682
|
+
return aborted || this.fetchedAllTxs() || this.dateProvider.now() > this.deadline;
|
|
651
683
|
}
|
|
652
684
|
|
|
653
685
|
/*
|
|
@@ -665,9 +697,10 @@ export class BatchTxRequester {
|
|
|
665
697
|
* This ensures we don't sleep past the deadline.
|
|
666
698
|
* */
|
|
667
699
|
private async sleepClampedToDeadline(durationMs: number) {
|
|
668
|
-
|
|
669
|
-
|
|
700
|
+
const remaining = this.deadline - this.dateProvider.now();
|
|
701
|
+
const thereIsTimeRemaining = remaining > 0;
|
|
702
|
+
if (thereIsTimeRemaining) {
|
|
703
|
+
await sleep(Math.min(durationMs, remaining));
|
|
670
704
|
}
|
|
671
|
-
await Promise.race([sleep(durationMs), this.requestTracker.cancellationToken]);
|
|
672
705
|
}
|
|
673
706
|
}
|
|
@@ -23,8 +23,6 @@ export interface ITxMetadataCollection {
|
|
|
23
23
|
alreadyFetched(txHash: TxHash): boolean;
|
|
24
24
|
// Returns true if tx was marked as fetched, false if it was already marked as fetched
|
|
25
25
|
markPeerHas(peerId: PeerId, txHashes: TxHash[]): void;
|
|
26
|
-
/** Remove all tx metadata associations for a peer (e.g. on demotion from smart to dumb). */
|
|
27
|
-
clearPeerData(peerId: PeerId): void;
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
/**
|
|
@@ -49,6 +47,7 @@ export interface BatchTxRequesterOptions {
|
|
|
49
47
|
//Injectable for testing purposes
|
|
50
48
|
semaphore?: ISemaphore;
|
|
51
49
|
peerCollection?: IPeerCollection;
|
|
50
|
+
abortSignal?: AbortSignal;
|
|
52
51
|
/** Optional tx validator for testing - if not provided, one is created from p2pService.txValidatorConfig */
|
|
53
52
|
txValidator?: IBatchRequestTxValidator;
|
|
54
53
|
}
|
|
@@ -2,7 +2,7 @@ import { type Tx, TxHash } from '@aztec/stdlib/tx';
|
|
|
2
2
|
|
|
3
3
|
import type { PeerId } from '@libp2p/interface';
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { IMissingTxsTracker } from '../../tx_collection/missing_txs_tracker.js';
|
|
6
6
|
import { DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE } from './config.js';
|
|
7
7
|
import type { ITxMetadataCollection } from './interface.js';
|
|
8
8
|
|
|
@@ -41,10 +41,10 @@ export class MissingTxMetadataCollection implements ITxMetadataCollection {
|
|
|
41
41
|
private txMetadata = new Map<string, MissingTxMetadata>();
|
|
42
42
|
|
|
43
43
|
constructor(
|
|
44
|
-
private
|
|
44
|
+
private missingTxsTracker: IMissingTxsTracker,
|
|
45
45
|
private readonly txBatchSize: number = DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE,
|
|
46
46
|
) {
|
|
47
|
-
|
|
47
|
+
missingTxsTracker.missingTxHashes.forEach(hash => this.txMetadata.set(hash, new MissingTxMetadata(hash)));
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
public getPrioritizingNotInFlightAndLowerRequestCount(txs: string[]): MissingTxMetadata[] {
|
|
@@ -65,7 +65,7 @@ export class MissingTxMetadataCollection implements ITxMetadataCollection {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
public getMissingTxHashes(): Set<string> {
|
|
68
|
-
return this.
|
|
68
|
+
return this.missingTxsTracker.missingTxHashes;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
public getTxsPeerHas(peer: PeerId): Set<string> {
|
|
@@ -128,7 +128,7 @@ export class MissingTxMetadataCollection implements ITxMetadataCollection {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
public alreadyFetched(txHash: TxHash): boolean {
|
|
131
|
-
return !this.
|
|
131
|
+
return !this.missingTxsTracker.isMissing(txHash.toString());
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
public markFetched(peerId: PeerId, tx: Tx): boolean {
|
|
@@ -144,7 +144,7 @@ export class MissingTxMetadataCollection implements ITxMetadataCollection {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
txMeta.peers.add(peerId.toString());
|
|
147
|
-
return this.
|
|
147
|
+
return this.missingTxsTracker.markFetched(tx);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
public markPeerHas(peerId: PeerId, txHash: TxHash[]) {
|
|
@@ -158,11 +158,4 @@ export class MissingTxMetadataCollection implements ITxMetadataCollection {
|
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
|
-
|
|
162
|
-
public clearPeerData(peerId: PeerId) {
|
|
163
|
-
const peerIdStr = peerId.toString();
|
|
164
|
-
for (const txMeta of this.txMetadata.values()) {
|
|
165
|
-
txMeta.peers.delete(peerIdStr);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
161
|
}
|