@aztec/p2p 0.0.1-commit.db765a8 → 0.0.1-commit.df81a97b5
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/README.md +129 -3
- package/dest/client/factory.d.ts +2 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +21 -8
- 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 +22 -34
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +3 -3
- package/dest/config.d.ts +24 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +66 -7
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +3 -3
- package/dest/mem_pools/attestation_pool/attestation_pool.js +3 -3
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +2 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +4 -4
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +9 -5
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +25 -10
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +33 -10
- 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 +26 -43
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +4 -2
- 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 +3 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
- 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 +21 -6
- 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 +5 -4
- 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 +4 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +5 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +5 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +12 -9
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +51 -49
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +21 -32
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +23 -4
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +36 -10
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +13 -4
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +39 -9
- package/dest/msg_validators/tx_validator/index.d.ts +2 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -0
- 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/msg_validators/tx_validator/phases_validator.d.ts +21 -1
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +49 -2
- package/dest/services/encoding.d.ts +5 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -1
- package/dest/services/libp2p/libp2p_service.d.ts +4 -9
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +125 -68
- package/dest/services/peer-manager/peer_manager.d.ts +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +4 -2
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
- 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 +69 -65
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +3 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +3 -0
- 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 +17 -9
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +57 -73
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
- 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/request_tracker.d.ts +53 -0
- package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/request_tracker.js +84 -0
- package/dest/services/tx_collection/slow_tx_collection.js +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +3 -6
- 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/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 +22 -3
- package/dest/testbench/p2p_client_testbench_worker.js +5 -4
- package/dest/testbench/worker_client_manager.d.ts +3 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +6 -2
- package/dest/util.d.ts +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +36 -12
- package/src/client/p2p_client.ts +22 -34
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +4 -6
- package/src/config.ts +92 -4
- package/src/mem_pools/attestation_pool/attestation_pool.ts +3 -3
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +2 -1
- package/src/mem_pools/tx_pool/priority.ts +4 -4
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
- package/src/mem_pools/tx_pool_v2/README.md +9 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/interfaces.ts +9 -4
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +52 -12
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +13 -1
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +23 -6
- package/src/msg_validators/attestation_validator/README.md +49 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +5 -4
- package/src/msg_validators/clock_tolerance.ts +4 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +13 -3
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +19 -6
- package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -53
- package/src/msg_validators/tx_validator/README.md +5 -1
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +16 -35
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +42 -1
- package/src/msg_validators/tx_validator/factory.ts +43 -3
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +41 -8
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/phases_validator.ts +60 -1
- package/src/services/encoding.ts +9 -1
- package/src/services/libp2p/libp2p_service.ts +118 -78
- package/src/services/peer-manager/peer_manager.ts +5 -2
- package/src/services/reqresp/README.md +229 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +64 -69
- package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +5 -0
- package/src/services/reqresp/reqresp.ts +19 -11
- package/src/services/tx_collection/fast_tx_collection.ts +57 -83
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/slow_tx_collection.ts +1 -1
- package/src/services/tx_collection/tx_collection.ts +3 -5
- package/src/test-helpers/make-test-p2p-clients.ts +1 -1
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/test-helpers/testbench-utils.ts +29 -3
- package/src/testbench/p2p_client_testbench_worker.ts +5 -6
- package/src/testbench/worker_client_manager.ts +13 -5
- package/src/util.ts +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -24
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -378
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
- package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -373
- package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
|
@@ -170,6 +170,37 @@ 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
|
+
|
|
173
204
|
## Key Files
|
|
174
205
|
|
|
175
206
|
| File | Description |
|
|
@@ -179,15 +210,16 @@ The `BitVector` is a compact representation where each bit corresponds to a tran
|
|
|
179
210
|
| `peer_collection.ts` | Manages peer classification (dumb/smart/bad) and rate limiting |
|
|
180
211
|
| `interface.ts` | Type definitions for dependencies |
|
|
181
212
|
| `../protocols/block_txs/` | Wire protocol definitions (`BlockTxsRequest`, `BlockTxsResponse`, `BitVector`) |
|
|
213
|
+
| `../../tx_collection/request_tracker.ts` | Centralized deadline, missing tx tracking, and cancellation signal |
|
|
182
214
|
|
|
183
215
|
## Stopping Conditions
|
|
184
216
|
|
|
185
|
-
The `BatchTxRequester` stops when any of these conditions are met
|
|
217
|
+
The `BatchTxRequester` stops when any of these conditions are met, all managed by the `RequestTracker`:
|
|
186
218
|
|
|
187
|
-
1. **All transactions fetched** -
|
|
188
|
-
2. **Deadline exceeded** -
|
|
189
|
-
3. **
|
|
190
|
-
4. **No transactions to fetch** -
|
|
219
|
+
1. **All transactions fetched** - `markFetched()` removes the last missing tx, triggering `finish()`
|
|
220
|
+
2. **Deadline exceeded** - `setTimeout` in `RequestTracker` fires, triggering `finish()`
|
|
221
|
+
3. **External cancellation** - `RequestTracker.cancel()` called (e.g., from `stop()`, `stopCollectingForBlocksUpTo`)
|
|
222
|
+
4. **No transactions to fetch** - Empty hash set at construction, `RequestTracker` finishes immediately
|
|
191
223
|
|
|
192
224
|
## Configuration
|
|
193
225
|
|
|
@@ -228,11 +260,15 @@ Request to peer fails
|
|
|
228
260
|
## Usage Example
|
|
229
261
|
|
|
230
262
|
```typescript
|
|
263
|
+
const requestTracker = RequestTracker.create(
|
|
264
|
+
missingTxHashes, // TxHash[] - what we need
|
|
265
|
+
new Date(Date.now() + 5_000), // deadline
|
|
266
|
+
);
|
|
267
|
+
|
|
231
268
|
const requester = new BatchTxRequester(
|
|
232
|
-
|
|
269
|
+
requestTracker, // IRequestTracker - tracks missing txs, deadline, and cancellation
|
|
233
270
|
blockTxsSource, // BlockTxsSource - the proposal or block we need txs for
|
|
234
271
|
pinnedPeer, // PeerId | undefined - peer expected to have the txs
|
|
235
|
-
timeoutMs, // number - how long to try
|
|
236
272
|
p2pService, // BatchTxRequesterLibP2PService
|
|
237
273
|
);
|
|
238
274
|
|
|
@@ -273,6 +309,8 @@ const txs = await BatchTxRequester.collectAllTxs(requester.run());
|
|
|
273
309
|
│ 1. Try RPC nodes first (fast) │ │ Periodic polling of RPC nodes │
|
|
274
310
|
│ 2. Fall back to BatchTxRequester │ │ and peers for missing txs │
|
|
275
311
|
│ │ │ │
|
|
312
|
+
│ Creates RequestTracker per │ │ │
|
|
313
|
+
│ request with deadline │ │ │
|
|
276
314
|
└───────────────────┬───────────────┘ └─────────────────────────────────────┘
|
|
277
315
|
│
|
|
278
316
|
│ For 'proposal' and 'block' requests
|
|
@@ -281,6 +319,7 @@ const txs = await BatchTxRequester.collectAllTxs(requester.run());
|
|
|
281
319
|
│ BatchTxRequester │
|
|
282
320
|
│ │
|
|
283
321
|
│ Aggressive parallel fetching from multiple peers │
|
|
322
|
+
│ Shares RequestTracker with FastTxCollection for unified cancellation │
|
|
284
323
|
│ Uses BLOCK_TXS sub-protocol for efficient batching │
|
|
285
324
|
└───────────────────┬─────────────────────────────────────────────────────────┘
|
|
286
325
|
│
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { chunkWrapAround } from '@aztec/foundation/collection';
|
|
2
|
-
import { TimeoutError } from '@aztec/foundation/error';
|
|
3
2
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
3
|
import { FifoMemoryQueue, type ISemaphore, Semaphore } from '@aztec/foundation/queue';
|
|
5
4
|
import { sleep } from '@aztec/foundation/sleep';
|
|
6
|
-
import { DateProvider
|
|
5
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
7
6
|
import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
8
7
|
import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx';
|
|
9
8
|
|
|
10
9
|
import type { PeerId } from '@libp2p/interface';
|
|
11
10
|
|
|
12
|
-
import type {
|
|
11
|
+
import type { IRequestTracker } from '../../tx_collection/request_tracker.js';
|
|
13
12
|
import { ReqRespSubProtocol } from '.././interface.js';
|
|
14
13
|
import { BlockTxsRequest, BlockTxsResponse, type BlockTxsSource } from '.././protocols/index.js';
|
|
15
14
|
import { ReqRespStatus } from '.././status.js';
|
|
@@ -42,16 +41,14 @@ import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_val
|
|
|
42
41
|
* - Is the peer which was unable to send us successful response N times in a row
|
|
43
42
|
* */
|
|
44
43
|
export class BatchTxRequester {
|
|
44
|
+
private readonly requestTracker: IRequestTracker;
|
|
45
45
|
private readonly blockTxsSource: BlockTxsSource;
|
|
46
46
|
private readonly pinnedPeer: PeerId | undefined;
|
|
47
|
-
private readonly timeoutMs: number;
|
|
48
47
|
private readonly p2pService: BatchTxRequesterLibP2PService;
|
|
49
48
|
private readonly logger: Logger;
|
|
50
|
-
private readonly dateProvider: DateProvider;
|
|
51
49
|
private readonly opts: BatchTxRequesterOptions;
|
|
52
50
|
private readonly peers: IPeerCollection;
|
|
53
51
|
private readonly txsMetadata: ITxMetadataCollection;
|
|
54
|
-
private readonly deadline: number;
|
|
55
52
|
private readonly smartRequesterSemaphore: ISemaphore;
|
|
56
53
|
private readonly txQueue: FifoMemoryQueue<Tx>;
|
|
57
54
|
private readonly txValidator: IBatchRequestTxValidator;
|
|
@@ -60,21 +57,19 @@ export class BatchTxRequester {
|
|
|
60
57
|
private readonly txBatchSize: number;
|
|
61
58
|
|
|
62
59
|
constructor(
|
|
63
|
-
|
|
60
|
+
requestTracker: IRequestTracker,
|
|
64
61
|
blockTxsSource: BlockTxsSource,
|
|
65
62
|
pinnedPeer: PeerId | undefined,
|
|
66
|
-
timeoutMs: number,
|
|
67
63
|
p2pService: BatchTxRequesterLibP2PService,
|
|
68
64
|
logger?: Logger,
|
|
69
65
|
dateProvider?: DateProvider,
|
|
70
66
|
opts?: BatchTxRequesterOptions,
|
|
71
67
|
) {
|
|
68
|
+
this.requestTracker = requestTracker;
|
|
72
69
|
this.blockTxsSource = blockTxsSource;
|
|
73
70
|
this.pinnedPeer = pinnedPeer;
|
|
74
|
-
this.timeoutMs = timeoutMs;
|
|
75
71
|
this.p2pService = p2pService;
|
|
76
72
|
this.logger = logger ?? createLogger('p2p:reqresp_batch');
|
|
77
|
-
this.dateProvider = dateProvider ?? new DateProvider();
|
|
78
73
|
this.opts = opts ?? {};
|
|
79
74
|
|
|
80
75
|
this.smartParallelWorkerCount =
|
|
@@ -82,7 +77,6 @@ export class BatchTxRequester {
|
|
|
82
77
|
this.dumbParallelWorkerCount =
|
|
83
78
|
this.opts.dumbParallelWorkerCount ?? DEFAULT_BATCH_TX_REQUESTER_DUMB_PARALLEL_WORKER_COUNT;
|
|
84
79
|
this.txBatchSize = this.opts.txBatchSize ?? DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE;
|
|
85
|
-
this.deadline = this.dateProvider.now() + this.timeoutMs;
|
|
86
80
|
this.txQueue = new FifoMemoryQueue(this.logger);
|
|
87
81
|
this.txValidator = this.opts.txValidator ?? new BatchRequestTxValidator(this.p2pService.txValidatorConfig);
|
|
88
82
|
|
|
@@ -93,12 +87,12 @@ export class BatchTxRequester {
|
|
|
93
87
|
this.peers = new PeerCollection(
|
|
94
88
|
this.p2pService.connectionSampler,
|
|
95
89
|
this.pinnedPeer,
|
|
96
|
-
|
|
90
|
+
dateProvider ?? new DateProvider(),
|
|
97
91
|
badPeerThreshold,
|
|
98
92
|
this.p2pService.peerScoring,
|
|
99
93
|
);
|
|
100
94
|
}
|
|
101
|
-
this.txsMetadata = new MissingTxMetadataCollection(
|
|
95
|
+
this.txsMetadata = new MissingTxMetadataCollection(requestTracker, this.txBatchSize);
|
|
102
96
|
this.smartRequesterSemaphore = this.opts.semaphore ?? new Semaphore(0);
|
|
103
97
|
}
|
|
104
98
|
|
|
@@ -106,40 +100,30 @@ export class BatchTxRequester {
|
|
|
106
100
|
* Fetches all missing transactions and yields them one by one
|
|
107
101
|
* */
|
|
108
102
|
public async *run(): AsyncGenerator<Tx, Tx | undefined, unknown> {
|
|
109
|
-
// Our timeout is represented in milliseconds but queue expects seconds
|
|
110
|
-
// We also want to make sure we wait at least 1 second in case of very low timeouts
|
|
111
|
-
const timeoutQueueAfter = Math.max(Math.ceil(this.timeoutMs / 1_000), 1);
|
|
112
103
|
try {
|
|
113
104
|
if (this.txsMetadata.getMissingTxHashes().size === 0) {
|
|
114
105
|
return undefined;
|
|
115
106
|
}
|
|
116
107
|
|
|
117
|
-
// Start workers in background
|
|
118
|
-
const workersPromise =
|
|
119
|
-
|
|
120
|
-
this.
|
|
121
|
-
|
|
108
|
+
// Start workers in background. Workers stop themselves via requestTracker.checkCancelled().
|
|
109
|
+
const workersPromise = Promise.allSettled([
|
|
110
|
+
this.smartRequester(),
|
|
111
|
+
this.dumbRequester(),
|
|
112
|
+
this.pinnedPeerRequester(),
|
|
113
|
+
]).finally(() => {
|
|
122
114
|
this.txQueue.end();
|
|
123
115
|
});
|
|
124
116
|
|
|
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.
|
|
125
119
|
while (true) {
|
|
126
|
-
const tx = await this.txQueue.get(
|
|
120
|
+
const tx = await this.txQueue.get();
|
|
127
121
|
|
|
128
|
-
// null indicates that the queue has ended
|
|
129
122
|
if (tx === null) {
|
|
130
123
|
break;
|
|
131
124
|
}
|
|
132
125
|
|
|
133
126
|
yield tx;
|
|
134
|
-
|
|
135
|
-
if (this.shouldStop()) {
|
|
136
|
-
// Drain queue before ending
|
|
137
|
-
let remaining;
|
|
138
|
-
while ((remaining = this.txQueue.getImmediate()) !== undefined) {
|
|
139
|
-
yield remaining;
|
|
140
|
-
}
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
127
|
}
|
|
144
128
|
|
|
145
129
|
this.unlockSmartRequesterSemaphores();
|
|
@@ -360,7 +344,10 @@ export class BatchTxRequester {
|
|
|
360
344
|
) {
|
|
361
345
|
try {
|
|
362
346
|
this.logger.trace(`Smart worker ${workerIndex} started`);
|
|
363
|
-
await
|
|
347
|
+
await Promise.race([this.smartRequesterSemaphore.acquire(), this.requestTracker.cancellationToken]);
|
|
348
|
+
if (this.requestTracker.checkCancelled()) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
364
351
|
this.logger.trace(`Smart worker ${workerIndex} acquired semaphore`);
|
|
365
352
|
|
|
366
353
|
while (!this.shouldStop()) {
|
|
@@ -384,7 +371,10 @@ export class BatchTxRequester {
|
|
|
384
371
|
//
|
|
385
372
|
// When a dumb peer responds with valid txIndices, it gets
|
|
386
373
|
// promoted to smart and releases the semaphore, waking this worker.
|
|
387
|
-
await
|
|
374
|
+
await Promise.race([this.smartRequesterSemaphore.acquire(), this.requestTracker.cancellationToken]);
|
|
375
|
+
if (this.requestTracker.checkCancelled()) {
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
388
378
|
this.logger.debug(`Worker loop smart: acquired next smart peer`);
|
|
389
379
|
continue;
|
|
390
380
|
}
|
|
@@ -411,11 +401,7 @@ export class BatchTxRequester {
|
|
|
411
401
|
});
|
|
412
402
|
}
|
|
413
403
|
} catch (err: any) {
|
|
414
|
-
|
|
415
|
-
this.logger.debug(`Smart worker ${workerIndex} timed out waiting for semaphore`);
|
|
416
|
-
} else {
|
|
417
|
-
this.logger.error(`Smart worker ${workerIndex} encountered an error: ${err}`);
|
|
418
|
-
}
|
|
404
|
+
this.logger.error(`Smart worker ${workerIndex} encountered an error: ${err}`);
|
|
419
405
|
} finally {
|
|
420
406
|
this.logger.debug(`Smart worker ${workerIndex} finished`);
|
|
421
407
|
}
|
|
@@ -463,9 +449,18 @@ export class BatchTxRequester {
|
|
|
463
449
|
* this implies we will query these peers couple of more times and give them a chance to "redeem" themselves before completely ignoring them
|
|
464
450
|
*/
|
|
465
451
|
private handleFailResponseFromPeer(peerId: PeerId, responseStatus: ReqRespStatus) {
|
|
466
|
-
//TODO: Should we ban these peers?
|
|
467
452
|
if (responseStatus === ReqRespStatus.FAILURE || responseStatus === ReqRespStatus.UNKNOWN) {
|
|
468
453
|
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);
|
|
469
464
|
return;
|
|
470
465
|
}
|
|
471
466
|
|
|
@@ -519,6 +514,9 @@ export class BatchTxRequester {
|
|
|
519
514
|
});
|
|
520
515
|
|
|
521
516
|
if (hasInvalidTx) {
|
|
517
|
+
this.logger.warn(`Penalizing peer ${peerId.toString()} for sending invalid transactions in batch response`, {
|
|
518
|
+
peerId,
|
|
519
|
+
});
|
|
522
520
|
this.peers.penalisePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
523
521
|
} else {
|
|
524
522
|
// If we have received successful response from the peer, they have "redeemed" themselves and not considered bad anymore
|
|
@@ -555,10 +553,9 @@ export class BatchTxRequester {
|
|
|
555
553
|
return;
|
|
556
554
|
}
|
|
557
555
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
if (!this.isBlockResponseValid(response)) {
|
|
556
|
+
const hasArchiveRootMismatch = this.blockTxsSource.archive.toString() !== response.archiveRoot.toString();
|
|
557
|
+
if (hasArchiveRootMismatch) {
|
|
558
|
+
this.handleArchiveRootMismatch(peerId, response);
|
|
562
559
|
return;
|
|
563
560
|
}
|
|
564
561
|
|
|
@@ -576,13 +573,25 @@ export class BatchTxRequester {
|
|
|
576
573
|
this.smartRequesterSemaphore.release();
|
|
577
574
|
}
|
|
578
575
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
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);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
this.peers.markPeerDumb(peerId);
|
|
588
|
+
this.txsMetadata.clearPeerData(peerId);
|
|
583
589
|
}
|
|
584
590
|
|
|
585
591
|
private peerHasSomeTxsWeAreMissing(_peerId: PeerId, response: BlockTxsResponse): boolean {
|
|
592
|
+
if (response.txIndices.isEmpty()) {
|
|
593
|
+
return false;
|
|
594
|
+
}
|
|
586
595
|
const txsPeerHas = new Set(this.extractHashesPeerHasFromResponse(response).map(h => h.toString()));
|
|
587
596
|
return this.txsMetadata.getMissingTxHashes().intersection(txsPeerHas).size > 0;
|
|
588
597
|
}
|
|
@@ -631,27 +640,14 @@ export class BatchTxRequester {
|
|
|
631
640
|
}
|
|
632
641
|
|
|
633
642
|
/*
|
|
634
|
-
*
|
|
635
|
-
|
|
636
|
-
return this.txsMetadata.getMissingTxHashes().size == 0;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
/*
|
|
640
|
-
* Checks if the BatchTxRequester should stop fetching missing txs
|
|
641
|
-
* Conditions for stopping are:
|
|
642
|
-
* - There have been no missing transactions to start with
|
|
643
|
-
* - All transactions have been fetched
|
|
644
|
-
* - The deadline has been hit (no more time to fetch)
|
|
645
|
-
* - This process has been cancelled via abortSignal
|
|
646
|
-
*
|
|
647
|
-
* @returns true if BatchTxRequester should stop, otherwise false*/
|
|
643
|
+
* Checks if the BatchTxRequester should stop fetching missing txs.
|
|
644
|
+
* Delegates to requestTracker which covers: deadline hit, all txs fetched, or external cancellation. */
|
|
648
645
|
private shouldStop() {
|
|
649
|
-
|
|
650
|
-
if (aborted) {
|
|
646
|
+
if (this.requestTracker.checkCancelled()) {
|
|
651
647
|
this.unlockSmartRequesterSemaphores();
|
|
652
648
|
}
|
|
653
649
|
|
|
654
|
-
return
|
|
650
|
+
return this.requestTracker.checkCancelled();
|
|
655
651
|
}
|
|
656
652
|
|
|
657
653
|
/*
|
|
@@ -669,10 +665,9 @@ export class BatchTxRequester {
|
|
|
669
665
|
* This ensures we don't sleep past the deadline.
|
|
670
666
|
* */
|
|
671
667
|
private async sleepClampedToDeadline(durationMs: number) {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
if (thereIsTimeRemaining) {
|
|
675
|
-
await sleep(Math.min(durationMs, remaining));
|
|
668
|
+
if (this.requestTracker.checkCancelled()) {
|
|
669
|
+
return;
|
|
676
670
|
}
|
|
671
|
+
await Promise.race([sleep(durationMs), this.requestTracker.cancellationToken]);
|
|
677
672
|
}
|
|
678
673
|
}
|
|
@@ -23,6 +23,8 @@ 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;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -47,7 +49,6 @@ export interface BatchTxRequesterOptions {
|
|
|
47
49
|
//Injectable for testing purposes
|
|
48
50
|
semaphore?: ISemaphore;
|
|
49
51
|
peerCollection?: IPeerCollection;
|
|
50
|
-
abortSignal?: AbortSignal;
|
|
51
52
|
/** Optional tx validator for testing - if not provided, one is created from p2pService.txValidatorConfig */
|
|
52
53
|
txValidator?: IBatchRequestTxValidator;
|
|
53
54
|
}
|
|
@@ -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 { IRequestTracker } from '../../tx_collection/request_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 requestTracker: IRequestTracker,
|
|
45
45
|
private readonly txBatchSize: number = DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE,
|
|
46
46
|
) {
|
|
47
|
-
|
|
47
|
+
requestTracker.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.requestTracker.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.requestTracker.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.requestTracker.markFetched(tx);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
public markPeerHas(peerId: PeerId, txHash: TxHash[]) {
|
|
@@ -158,4 +158,11 @@ 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
|
+
}
|
|
161
168
|
}
|
|
@@ -12,6 +12,7 @@ export const RATE_LIMIT_EXCEEDED_PEER_CACHE_TTL = 1000; // 1s
|
|
|
12
12
|
|
|
13
13
|
export interface IPeerCollection {
|
|
14
14
|
markPeerSmart(peerId: PeerId): void;
|
|
15
|
+
markPeerDumb(peerId: PeerId): void;
|
|
15
16
|
|
|
16
17
|
/** Sample next peer in round-robin fashion. No smart peers if returns undefined */
|
|
17
18
|
nextSmartPeerToQuery(): PeerId | undefined;
|
|
@@ -57,6 +58,10 @@ export class PeerCollection implements IPeerCollection {
|
|
|
57
58
|
this.smartPeers.add(peerId.toString());
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
public markPeerDumb(peerId: PeerId): void {
|
|
62
|
+
this.smartPeers.delete(peerId.toString());
|
|
63
|
+
}
|
|
64
|
+
|
|
60
65
|
// We keep track of all peers that are queried for peer sampling algorithm
|
|
61
66
|
private queriedSmartPeers: Set<string> = new Set<string>();
|
|
62
67
|
private queriedDumbPeers: Set<string> = new Set<string>();
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
IndividualReqRespTimeoutError,
|
|
17
17
|
InvalidResponseError,
|
|
18
18
|
} from '../../errors/reqresp.error.js';
|
|
19
|
-
import { SnappyTransform } from '../encoding.js';
|
|
19
|
+
import { OversizedSnappyResponseError, SnappyTransform } from '../encoding.js';
|
|
20
20
|
import type { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
21
21
|
import {
|
|
22
22
|
DEFAULT_INDIVIDUAL_REQUEST_TIMEOUT_MS,
|
|
@@ -320,7 +320,7 @@ export class ReqResp implements ReqRespInterface {
|
|
|
320
320
|
};
|
|
321
321
|
|
|
322
322
|
for (const index of indices) {
|
|
323
|
-
this.logger.
|
|
323
|
+
this.logger.trace(`Sending request ${index} to peer ${peerAsString}`);
|
|
324
324
|
const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffers[index]);
|
|
325
325
|
|
|
326
326
|
// Check the status of the response buffer
|
|
@@ -553,16 +553,10 @@ export class ReqResp implements ReqRespInterface {
|
|
|
553
553
|
data: message,
|
|
554
554
|
};
|
|
555
555
|
} catch (e: any) {
|
|
556
|
+
// All errors (invalid status bytes, oversized snappy responses, corrupt data, etc.)
|
|
557
|
+
// are re-thrown so the caller can penalize the peer via handleResponseError.
|
|
556
558
|
this.logger.debug(`Reading message failed: ${e.message}`);
|
|
557
|
-
|
|
558
|
-
let status = ReqRespStatus.UNKNOWN;
|
|
559
|
-
if (e instanceof ReqRespStatusError) {
|
|
560
|
-
status = e.status;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
return {
|
|
564
|
-
status,
|
|
565
|
-
};
|
|
559
|
+
throw e;
|
|
566
560
|
}
|
|
567
561
|
}
|
|
568
562
|
|
|
@@ -780,6 +774,20 @@ export class ReqResp implements ReqRespInterface {
|
|
|
780
774
|
return undefined;
|
|
781
775
|
}
|
|
782
776
|
|
|
777
|
+
// Invalid status byte: the peer sent a status byte that doesn't match any known status code.
|
|
778
|
+
// This is a protocol violation, penalize harshly.
|
|
779
|
+
if (e instanceof ReqRespStatusError) {
|
|
780
|
+
this.logger.warn(`Invalid status byte from peer ${peerId.toString()} in ${subProtocol}: ${e.message}`, logTags);
|
|
781
|
+
return PeerErrorSeverity.LowToleranceError;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
// Oversized snappy response: the peer is sending data that exceeds the allowed size.
|
|
785
|
+
// This is a protocol violation that wastes bandwidth, so penalize harshly.
|
|
786
|
+
if (e instanceof OversizedSnappyResponseError) {
|
|
787
|
+
this.logger.warn(`Oversized response from peer ${peerId.toString()} in ${subProtocol}: ${e.message}`, logTags);
|
|
788
|
+
return PeerErrorSeverity.LowToleranceError;
|
|
789
|
+
}
|
|
790
|
+
|
|
783
791
|
return this.categorizeConnectionErrors(e, peerId, subProtocol);
|
|
784
792
|
}
|
|
785
793
|
|