@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.
- package/dest/client/factory.d.ts +4 -5
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +20 -26
- package/dest/client/interface.d.ts +8 -13
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +7 -13
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +35 -86
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
- package/dest/config.d.ts +29 -10
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +80 -31
- 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.js +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +2 -0
- 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/invalid_txs_after_reorg_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +10 -6
- 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/index.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +10 -6
- 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 +38 -7
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +74 -16
- 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 +9 -10
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +5 -3
- 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 +2 -2
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +5 -3
- 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 +169 -141
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -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 +6 -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 +13 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -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 +24 -20
- 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/factory.d.ts +125 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +226 -58
- 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 +67 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
- package/dest/msg_validators/tx_validator/index.d.ts +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +44 -23
- package/dest/services/dummy_service.d.ts +4 -4
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +4 -4
- package/dest/services/encoding.d.ts +2 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -7
- package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +32 -10
- package/dest/services/libp2p/libp2p_service.d.ts +16 -13
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +92 -93
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
- 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 +5 -9
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- package/dest/services/service.d.ts +5 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +39 -33
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
- package/dest/services/tx_collection/file_store_tx_source.d.ts +4 -4
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.js +27 -16
- 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 +5 -4
- package/dest/services/tx_collection/slow_tx_collection.d.ts +2 -2
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +10 -8
- package/dest/services/tx_collection/tx_collection.d.ts +5 -4
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +13 -22
- package/dest/services/tx_collection/tx_source.d.ts +8 -3
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +19 -2
- package/dest/services/tx_provider.d.ts +3 -3
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +4 -4
- package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +1 -2
- package/dest/test-helpers/mock-pubsub.d.ts +4 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +8 -2
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -2
- package/dest/test-helpers/testbench-utils.d.ts +5 -3
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +3 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +13 -12
- 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 +4 -1
- package/dest/util.d.ts +2 -2
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +28 -46
- package/src/client/interface.ts +8 -13
- package/src/client/p2p_client.ts +35 -113
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -10
- package/src/config.ts +115 -33
- 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 +1 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +2 -2
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +10 -6
- 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/index.ts +1 -1
- package/src/mem_pools/tx_pool_v2/interfaces.ts +8 -5
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +102 -17
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +11 -11
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +3 -3
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +178 -141
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
- package/src/msg_validators/tx_validator/README.md +115 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/factory.ts +366 -77
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +51 -26
- package/src/services/dummy_service.ts +6 -6
- package/src/services/encoding.ts +5 -6
- package/src/services/gossipsub/README.md +29 -14
- package/src/services/gossipsub/topic_score_params.ts +49 -13
- package/src/services/libp2p/libp2p_service.ts +106 -101
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +6 -6
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/service.ts +11 -2
- package/src/services/tx_collection/fast_tx_collection.ts +51 -30
- package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
- package/src/services/tx_collection/file_store_tx_source.ts +32 -19
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
- package/src/services/tx_collection/slow_tx_collection.ts +8 -9
- package/src/services/tx_collection/tx_collection.ts +4 -3
- package/src/services/tx_collection/tx_collection_sink.ts +15 -29
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_provider.ts +2 -2
- package/src/test-helpers/make-test-p2p-clients.ts +0 -2
- package/src/test-helpers/mock-pubsub.ts +13 -6
- package/src/test-helpers/reqresp-nodes.ts +2 -5
- package/src/test-helpers/testbench-utils.ts +3 -2
- package/src/testbench/p2p_client_testbench_worker.ts +21 -17
- package/src/testbench/worker_client_manager.ts +11 -4
- package/src/util.ts +7 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
- 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 -212
- 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
|
-
|
|
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
|
|
73
|
-
|
|
74
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
239
|
-
`Handler not yet registered
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
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
|
-
//
|
|
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.
|
|
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
|
|
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
|
|
1600
|
-
const
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
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
|
-
|
|
1609
|
-
|
|
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
|
-
|
|
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,
|
|
1622
|
+
): Promise<Record<string, TransactionValidator>> {
|
|
1632
1623
|
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
1633
|
-
const allowedInSetup =
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
1671
|
-
if (
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
9
|
+
class MissingTxMetadata {
|
|
9
10
|
constructor(
|
|
10
|
-
public readonly 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
|
|
40
|
+
export class MissingTxMetadataCollection implements ITxMetadataCollection {
|
|
41
|
+
private txMetadata = new Map<string, MissingTxMetadata>();
|
|
42
|
+
|
|
59
43
|
constructor(
|
|
60
|
-
|
|
44
|
+
private missingTxsTracker: IMissingTxsTracker,
|
|
61
45
|
private readonly txBatchSize: number = DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE,
|
|
62
46
|
) {
|
|
63
|
-
|
|
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
|
|
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
|
|
86
|
+
const missingTxHashes = this.getMissingTxHashes();
|
|
136
87
|
|
|
137
|
-
const txsToRequest = txsPeerHas.
|
|
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.
|
|
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
|
-
|
|
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
|
}
|