@aztec/p2p 0.0.1-commit.d3ec352c → 0.0.1-commit.e61ad554
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 +2 -3
- package/dest/client/interface.d.ts +18 -5
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +11 -14
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +456 -124
- package/dest/config.d.ts +4 -7
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +10 -13
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +61 -42
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +239 -265
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +21 -18
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +114 -109
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +17 -16
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +89 -128
- package/dest/mem_pools/attestation_pool/mocks.d.ts +11 -8
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +17 -13
- package/dest/mem_pools/instrumentation.d.ts +7 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +30 -12
- package/dest/mem_pools/interface.d.ts +3 -4
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +35 -26
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +314 -335
- 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 +122 -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 +1 -2
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +6 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +8 -4
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- 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 +25 -20
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -4
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +52 -19
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +18 -14
- package/dest/msg_validators/clock_tolerance.d.ts +21 -0
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -0
- package/dest/msg_validators/clock_tolerance.js +37 -0
- package/dest/msg_validators/index.d.ts +2 -2
- package/dest/msg_validators/index.d.ts.map +1 -1
- package/dest/msg_validators/index.js +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
- package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/index.js +3 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.js +104 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +212 -0
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
- 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/factory.d.ts +2 -2
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +10 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +20 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +8 -14
- 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 +2 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/size_validator.d.ts +6 -0
- package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/size_validator.js +20 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/services/dummy_service.d.ts +6 -2
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +3 -0
- package/dest/services/encoding.d.ts +1 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -6
- package/dest/services/libp2p/instrumentation.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +20 -73
- package/dest/services/libp2p/libp2p_service.d.ts +31 -14
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +718 -164
- package/dest/services/peer-manager/metrics.d.ts +6 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +18 -21
- package/dest/services/peer-manager/peer_manager.d.ts +2 -2
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +4 -12
- package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +2 -5
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/constants.d.ts +12 -0
- package/dest/services/reqresp/constants.d.ts.map +1 -0
- package/dest/services/reqresp/constants.js +7 -0
- package/dest/services/reqresp/interface.d.ts +2 -2
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +1 -1
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +5 -21
- package/dest/services/reqresp/protocols/auth.d.ts +2 -2
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.js +2 -2
- package/dest/services/reqresp/protocols/block.js +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +7 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +2 -2
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +1 -1
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +4 -1
- package/dest/services/reqresp/protocols/tx.d.ts +2 -3
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +402 -24
- package/dest/services/service.d.ts +16 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +4 -14
- package/dest/services/tx_collection/tx_collection.d.ts +3 -3
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +1 -1
- package/dest/services/tx_provider.d.ts +4 -3
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +11 -2
- package/dest/services/tx_provider_instrumentation.d.ts +5 -2
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +13 -13
- package/dest/test-helpers/mock-tx-helpers.js +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +31 -17
- 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 +6 -1
- package/package.json +16 -16
- package/src/client/factory.ts +5 -10
- package/src/client/interface.ts +19 -4
- package/src/client/p2p_client.ts +89 -144
- package/src/config.ts +12 -18
- package/src/mem_pools/attestation_pool/attestation_pool.ts +68 -41
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +241 -289
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +163 -141
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +141 -164
- package/src/mem_pools/attestation_pool/mocks.ts +21 -15
- package/src/mem_pools/instrumentation.ts +38 -14
- package/src/mem_pools/interface.ts +2 -4
- package/src/mem_pools/tx_pool/README.md +270 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +362 -367
- 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 +162 -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 +0 -1
- package/src/mem_pools/tx_pool/priority.ts +8 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +8 -3
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +18 -13
- package/src/msg_validators/attestation_validator/attestation_validator.ts +37 -22
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +13 -16
- package/src/msg_validators/clock_tolerance.ts +51 -0
- package/src/msg_validators/index.ts +1 -1
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
- package/src/msg_validators/proposal_validator/index.ts +3 -0
- package/src/msg_validators/proposal_validator/proposal_validator.ts +92 -0
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +230 -0
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +4 -2
- package/src/msg_validators/tx_validator/data_validator.ts +12 -4
- package/src/msg_validators/tx_validator/factory.ts +1 -1
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +8 -25
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +13 -5
- package/src/msg_validators/tx_validator/size_validator.ts +18 -0
- package/src/msg_validators/tx_validator/test_utils.ts +1 -1
- package/src/msg_validators/tx_validator/timestamp_validator.ts +3 -1
- package/src/services/dummy_service.ts +6 -0
- package/src/services/encoding.ts +6 -5
- package/src/services/libp2p/instrumentation.ts +19 -73
- package/src/services/libp2p/libp2p_service.ts +361 -130
- package/src/services/peer-manager/metrics.ts +22 -21
- package/src/services/peer-manager/peer_manager.ts +5 -4
- package/src/services/peer-manager/peer_scoring.ts +1 -5
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +3 -1
- package/src/services/reqresp/constants.ts +14 -0
- package/src/services/reqresp/interface.ts +1 -1
- package/src/services/reqresp/metrics.ts +7 -23
- package/src/services/reqresp/protocols/auth.ts +2 -2
- package/src/services/reqresp/protocols/block.ts +1 -1
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +9 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
- package/src/services/reqresp/protocols/status.ts +7 -4
- package/src/services/reqresp/protocols/tx.ts +1 -2
- package/src/services/service.ts +19 -4
- package/src/services/tx_collection/config.ts +1 -1
- package/src/services/tx_collection/instrumentation.ts +4 -21
- package/src/services/tx_collection/tx_collection.ts +3 -3
- package/src/services/tx_provider.ts +19 -4
- package/src/services/tx_provider_instrumentation.ts +18 -14
- package/src/test-helpers/mock-pubsub.ts +1 -1
- package/src/test-helpers/mock-tx-helpers.ts +1 -1
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/testbench/p2p_client_testbench_worker.ts +42 -22
- package/src/testbench/worker_client_manager.ts +6 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -81
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -239
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -12
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +0 -82
- package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/index.js +0 -1
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -285
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -97
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
-
import { BlockNumber
|
|
3
|
-
import { randomInt } from '@aztec/foundation/crypto';
|
|
4
|
-
import { Fr } from '@aztec/foundation/
|
|
2
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { randomInt } from '@aztec/foundation/crypto/random';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
7
|
import { Timer } from '@aztec/foundation/timer';
|
|
@@ -13,11 +13,14 @@ import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
|
13
13
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
14
14
|
import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
15
15
|
import {
|
|
16
|
-
BlockAttestation,
|
|
17
16
|
BlockProposal,
|
|
17
|
+
CheckpointAttestation,
|
|
18
|
+
CheckpointProposal,
|
|
19
|
+
type CheckpointProposalCore,
|
|
18
20
|
type Gossipable,
|
|
19
21
|
P2PClientType,
|
|
20
22
|
P2PMessage,
|
|
23
|
+
type ValidationResult as P2PValidationResult,
|
|
21
24
|
PeerErrorSeverity,
|
|
22
25
|
TopicType,
|
|
23
26
|
createTopicString,
|
|
@@ -28,7 +31,14 @@ import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
|
28
31
|
import { Tx, type TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
29
32
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
30
33
|
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
31
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
Attributes,
|
|
36
|
+
OtelMetricsAdapter,
|
|
37
|
+
SpanStatusCode,
|
|
38
|
+
type TelemetryClient,
|
|
39
|
+
WithTracer,
|
|
40
|
+
trackSpan,
|
|
41
|
+
} from '@aztec/telemetry-client';
|
|
32
42
|
|
|
33
43
|
import {
|
|
34
44
|
type GossipSub,
|
|
@@ -53,9 +63,11 @@ import type { P2PConfig } from '../../config.js';
|
|
|
53
63
|
import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
|
|
54
64
|
import type { MemPools } from '../../mem_pools/interface.js';
|
|
55
65
|
import {
|
|
56
|
-
AttestationValidator,
|
|
57
66
|
BlockProposalValidator,
|
|
67
|
+
CheckpointAttestationValidator,
|
|
68
|
+
CheckpointProposalValidator,
|
|
58
69
|
FishermanAttestationValidator,
|
|
70
|
+
SizeTxValidator,
|
|
59
71
|
} from '../../msg_validators/index.js';
|
|
60
72
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
61
73
|
import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
|
|
@@ -101,7 +113,12 @@ import {
|
|
|
101
113
|
reqRespTxHandler,
|
|
102
114
|
} from '../reqresp/protocols/index.js';
|
|
103
115
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
104
|
-
import type {
|
|
116
|
+
import type {
|
|
117
|
+
P2PBlockReceivedCallback,
|
|
118
|
+
P2PCheckpointReceivedCallback,
|
|
119
|
+
P2PService,
|
|
120
|
+
PeerDiscoveryService,
|
|
121
|
+
} from '../service.js';
|
|
105
122
|
import { P2PInstrumentation } from './instrumentation.js';
|
|
106
123
|
|
|
107
124
|
interface ValidationResult {
|
|
@@ -125,8 +142,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
125
142
|
private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
|
|
126
143
|
|
|
127
144
|
// Message validators
|
|
128
|
-
private attestationValidator: AttestationValidator;
|
|
129
145
|
private blockProposalValidator: BlockProposalValidator;
|
|
146
|
+
private checkpointProposalValidator: CheckpointProposalValidator;
|
|
147
|
+
private checkpointAttestationValidator: CheckpointAttestationValidator;
|
|
130
148
|
|
|
131
149
|
private protocolVersion = '';
|
|
132
150
|
private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
|
|
@@ -140,10 +158,19 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
140
158
|
*/
|
|
141
159
|
private blockReceivedCallback: P2PBlockReceivedCallback;
|
|
142
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Callback for when a checkpoint proposal is received from a peer.
|
|
163
|
+
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
164
|
+
* @returns The attestations for the checkpoint, if any.
|
|
165
|
+
*/
|
|
166
|
+
private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
167
|
+
|
|
143
168
|
private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
|
|
144
169
|
|
|
145
170
|
private instrumentation: P2PInstrumentation;
|
|
146
171
|
|
|
172
|
+
private telemetry: TelemetryClient;
|
|
173
|
+
|
|
147
174
|
protected logger: Logger;
|
|
148
175
|
|
|
149
176
|
constructor(
|
|
@@ -153,7 +180,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
153
180
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
154
181
|
private reqresp: ReqRespInterface,
|
|
155
182
|
private peerManager: PeerManagerInterface,
|
|
156
|
-
protected mempools: MemPools
|
|
183
|
+
protected mempools: MemPools,
|
|
157
184
|
private archiver: L2BlockSource & ContractDataSource,
|
|
158
185
|
private epochCache: EpochCacheInterface,
|
|
159
186
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
@@ -162,6 +189,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
162
189
|
logger: Logger = createLogger('p2p:libp2p_service'),
|
|
163
190
|
) {
|
|
164
191
|
super(telemetry, 'LibP2PService');
|
|
192
|
+
this.telemetry = telemetry;
|
|
165
193
|
|
|
166
194
|
// Create child logger with fisherman prefix if in fisherman mode
|
|
167
195
|
this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
|
|
@@ -170,7 +198,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
170
198
|
|
|
171
199
|
this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
172
200
|
this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
173
|
-
this.msgIdSeenValidators[TopicType.
|
|
201
|
+
this.msgIdSeenValidators[TopicType.checkpoint_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
202
|
+
this.msgIdSeenValidators[TopicType.checkpoint_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
174
203
|
|
|
175
204
|
const versions = getVersions(config);
|
|
176
205
|
this.protocolVersion = compressComponentVersions(versions);
|
|
@@ -178,25 +207,40 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
178
207
|
|
|
179
208
|
this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
|
|
180
209
|
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
181
|
-
this.topicStrings[TopicType.
|
|
182
|
-
TopicType.
|
|
210
|
+
this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(
|
|
211
|
+
TopicType.checkpoint_proposal,
|
|
212
|
+
this.protocolVersion,
|
|
213
|
+
);
|
|
214
|
+
this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(
|
|
215
|
+
TopicType.checkpoint_attestation,
|
|
183
216
|
this.protocolVersion,
|
|
184
217
|
);
|
|
185
218
|
|
|
186
|
-
// Use FishermanAttestationValidator in fisherman mode to validate attestation payloads against proposals
|
|
187
|
-
this.attestationValidator = config.fishermanMode
|
|
188
|
-
? new FishermanAttestationValidator(epochCache, mempools.attestationPool!, telemetry)
|
|
189
|
-
: new AttestationValidator(epochCache);
|
|
190
219
|
this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
|
|
220
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
|
|
221
|
+
txsPermitted: !config.disableTransactions,
|
|
222
|
+
});
|
|
223
|
+
this.checkpointAttestationValidator = config.fishermanMode
|
|
224
|
+
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
|
|
225
|
+
: new CheckpointAttestationValidator(epochCache);
|
|
191
226
|
|
|
192
227
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
193
228
|
|
|
194
|
-
this.blockReceivedCallback = async (block: BlockProposal): Promise<
|
|
229
|
+
this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
|
|
195
230
|
this.logger.debug(
|
|
196
231
|
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
|
|
197
232
|
{ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
|
|
198
233
|
);
|
|
199
|
-
return
|
|
234
|
+
return false;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
this.checkpointReceivedCallback = (
|
|
238
|
+
checkpoint: CheckpointProposalCore,
|
|
239
|
+
): Promise<CheckpointAttestation[] | undefined> => {
|
|
240
|
+
this.logger.debug(
|
|
241
|
+
`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
|
|
242
|
+
);
|
|
243
|
+
return Promise.resolve(undefined);
|
|
200
244
|
};
|
|
201
245
|
}
|
|
202
246
|
|
|
@@ -215,7 +259,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
215
259
|
config: P2PConfig,
|
|
216
260
|
peerId: PeerId,
|
|
217
261
|
deps: {
|
|
218
|
-
mempools: MemPools
|
|
262
|
+
mempools: MemPools;
|
|
219
263
|
l2BlockSource: L2BlockSource & ContractDataSource;
|
|
220
264
|
epochCache: EpochCacheInterface;
|
|
221
265
|
proofVerifier: ClientProtocolCircuitVerifier;
|
|
@@ -265,7 +309,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
265
309
|
|
|
266
310
|
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
267
311
|
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
268
|
-
const
|
|
312
|
+
const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
|
|
313
|
+
const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
|
|
269
314
|
|
|
270
315
|
const preferredPeersEnrs: ENR[] = config.preferredPeers.map(enr => ENR.decodeTxt(enr));
|
|
271
316
|
const directPeers = (
|
|
@@ -387,12 +432,17 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
387
432
|
invalidMessageDeliveriesWeight: -20,
|
|
388
433
|
invalidMessageDeliveriesDecay: 0.5,
|
|
389
434
|
}),
|
|
390
|
-
[
|
|
435
|
+
[blockProposalTopic]: createTopicScoreParams({
|
|
391
436
|
topicWeight: 1,
|
|
392
437
|
invalidMessageDeliveriesWeight: -20,
|
|
393
438
|
invalidMessageDeliveriesDecay: 0.5,
|
|
394
439
|
}),
|
|
395
|
-
[
|
|
440
|
+
[checkpointProposalTopic]: createTopicScoreParams({
|
|
441
|
+
topicWeight: 1,
|
|
442
|
+
invalidMessageDeliveriesWeight: -20,
|
|
443
|
+
invalidMessageDeliveriesDecay: 0.5,
|
|
444
|
+
}),
|
|
445
|
+
[checkpointAttestationTopic]: createTopicScoreParams({
|
|
396
446
|
topicWeight: 1,
|
|
397
447
|
invalidMessageDeliveriesWeight: -20,
|
|
398
448
|
invalidMessageDeliveriesDecay: 0.5,
|
|
@@ -462,17 +512,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
462
512
|
}
|
|
463
513
|
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
464
514
|
|
|
465
|
-
await this.peerManager.initializePeers();
|
|
466
|
-
if (!this.config.p2pDiscoveryDisabled) {
|
|
467
|
-
await this.peerDiscoveryService.start();
|
|
468
|
-
}
|
|
469
|
-
await this.node.start();
|
|
470
|
-
|
|
471
|
-
// Subscribe to standard GossipSub topics by default
|
|
472
|
-
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
|
|
473
|
-
this.subscribeToTopic(this.topicStrings[topic]);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
515
|
// Create request response protocol handlers
|
|
477
516
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
478
517
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
@@ -486,8 +525,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
486
525
|
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
487
526
|
};
|
|
488
527
|
|
|
489
|
-
|
|
490
|
-
if (this.mempools.attestationPool && !this.config.disableTransactions) {
|
|
528
|
+
if (!this.config.disableTransactions) {
|
|
491
529
|
const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
|
|
492
530
|
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
493
531
|
}
|
|
@@ -496,10 +534,32 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
496
534
|
requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this);
|
|
497
535
|
}
|
|
498
536
|
|
|
537
|
+
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
538
|
+
const reqrespSubProtocolValidators = {
|
|
539
|
+
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
540
|
+
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
541
|
+
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
542
|
+
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
await this.peerManager.initializePeers();
|
|
546
|
+
|
|
547
|
+
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
548
|
+
|
|
549
|
+
await this.node.start();
|
|
550
|
+
|
|
551
|
+
// Subscribe to standard GossipSub topics by default
|
|
552
|
+
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
|
|
553
|
+
this.subscribeToTopic(this.topicStrings[topic]);
|
|
554
|
+
}
|
|
555
|
+
|
|
499
556
|
// add GossipSub listener
|
|
500
557
|
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
501
558
|
|
|
502
559
|
// Start running promise for peer discovery and metrics collection
|
|
560
|
+
if (!this.config.p2pDiscoveryDisabled) {
|
|
561
|
+
await this.peerDiscoveryService.start();
|
|
562
|
+
}
|
|
503
563
|
this.discoveryRunningPromise = new RunningPromise(
|
|
504
564
|
async () => {
|
|
505
565
|
await this.peerManager.heartbeat();
|
|
@@ -509,14 +569,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
509
569
|
);
|
|
510
570
|
this.discoveryRunningPromise.start();
|
|
511
571
|
|
|
512
|
-
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
513
|
-
const reqrespSubProtocolValidators = {
|
|
514
|
-
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
515
|
-
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
516
|
-
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
517
|
-
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
|
|
518
|
-
};
|
|
519
|
-
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
520
572
|
this.logger.info(`Started P2P service`, {
|
|
521
573
|
listen: this.config.listenAddress,
|
|
522
574
|
port: this.config.p2pPort,
|
|
@@ -602,6 +654,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
602
654
|
this.blockReceivedCallback = callback;
|
|
603
655
|
}
|
|
604
656
|
|
|
657
|
+
public registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
658
|
+
this.checkpointReceivedCallback = callback;
|
|
659
|
+
}
|
|
660
|
+
|
|
605
661
|
/**
|
|
606
662
|
* Subscribes to a topic.
|
|
607
663
|
* @param topic - The topic to subscribe to.
|
|
@@ -623,7 +679,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
623
679
|
if (!this.node.services.pubsub) {
|
|
624
680
|
throw new Error('Pubsub service not available.');
|
|
625
681
|
}
|
|
626
|
-
const
|
|
682
|
+
const isBlockProposal = topic === this.topicStrings[TopicType.block_proposal];
|
|
683
|
+
const traceContext =
|
|
684
|
+
this.config.debugP2PInstrumentMessages && isBlockProposal ? this.telemetry.getTraceContext() : undefined;
|
|
685
|
+
const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages, traceContext);
|
|
627
686
|
const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
|
|
628
687
|
return result.recipients.length;
|
|
629
688
|
}
|
|
@@ -644,12 +703,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
644
703
|
case this.topicStrings[TopicType.tx]:
|
|
645
704
|
topicType = TopicType.tx;
|
|
646
705
|
break;
|
|
647
|
-
case this.topicStrings[TopicType.block_attestation]:
|
|
648
|
-
topicType = TopicType.block_attestation;
|
|
649
|
-
break;
|
|
650
706
|
case this.topicStrings[TopicType.block_proposal]:
|
|
651
707
|
topicType = TopicType.block_proposal;
|
|
652
708
|
break;
|
|
709
|
+
case this.topicStrings[TopicType.checkpoint_proposal]:
|
|
710
|
+
topicType = TopicType.checkpoint_proposal;
|
|
711
|
+
break;
|
|
712
|
+
case this.topicStrings[TopicType.checkpoint_attestation]:
|
|
713
|
+
topicType = TopicType.checkpoint_attestation;
|
|
714
|
+
break;
|
|
653
715
|
default:
|
|
654
716
|
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
655
717
|
break;
|
|
@@ -708,23 +770,74 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
708
770
|
return;
|
|
709
771
|
}
|
|
710
772
|
|
|
773
|
+
// Determine topic type for attributes
|
|
711
774
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
712
775
|
topicType = TopicType.tx;
|
|
713
|
-
|
|
776
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
777
|
+
topicType = TopicType.checkpoint_attestation;
|
|
778
|
+
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
779
|
+
topicType = TopicType.block_proposal;
|
|
780
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
781
|
+
topicType = TopicType.checkpoint_proposal;
|
|
714
782
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
783
|
+
|
|
784
|
+
// Process the message, optionally within a linked span for trace propagation
|
|
785
|
+
const processMessage = async () => {
|
|
786
|
+
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
787
|
+
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
788
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
789
|
+
if (this.clientType === P2PClientType.Full) {
|
|
790
|
+
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
791
|
+
}
|
|
792
|
+
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
793
|
+
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
794
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
795
|
+
await this.handleGossipedCheckpointProposal(p2pMessage.payload, msgId, source);
|
|
796
|
+
} else {
|
|
797
|
+
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
719
798
|
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
const latency = p2pMessage.timestamp !== undefined ? msgReceivedTime - p2pMessage.timestamp.getTime() : undefined;
|
|
802
|
+
const propagatedContext = p2pMessage.traceContext
|
|
803
|
+
? this.telemetry.extractPropagatedContext(p2pMessage.traceContext)
|
|
804
|
+
: undefined;
|
|
805
|
+
|
|
806
|
+
if (propagatedContext) {
|
|
807
|
+
await this.tracer.startActiveSpan(
|
|
808
|
+
'LibP2PService.processMessage',
|
|
809
|
+
{
|
|
810
|
+
attributes: {
|
|
811
|
+
[Attributes.TOPIC_NAME]: topicType!,
|
|
812
|
+
[Attributes.PEER_ID]: source.toString(),
|
|
813
|
+
},
|
|
814
|
+
},
|
|
815
|
+
propagatedContext,
|
|
816
|
+
async span => {
|
|
817
|
+
try {
|
|
818
|
+
await processMessage();
|
|
819
|
+
span.setStatus({
|
|
820
|
+
code: SpanStatusCode.OK,
|
|
821
|
+
});
|
|
822
|
+
} catch (err) {
|
|
823
|
+
span.setStatus({
|
|
824
|
+
code: SpanStatusCode.ERROR,
|
|
825
|
+
message: String(err),
|
|
826
|
+
});
|
|
827
|
+
if (typeof err === 'string' || (err && err instanceof Error)) {
|
|
828
|
+
span.recordException(err);
|
|
829
|
+
}
|
|
830
|
+
throw err;
|
|
831
|
+
} finally {
|
|
832
|
+
span.end();
|
|
833
|
+
}
|
|
834
|
+
},
|
|
835
|
+
);
|
|
836
|
+
} else {
|
|
837
|
+
await processMessage();
|
|
724
838
|
}
|
|
725
839
|
|
|
726
|
-
if (
|
|
727
|
-
const latency = msgReceivedTime - p2pMessage.timestamp.getTime();
|
|
840
|
+
if (latency !== undefined && topicType !== undefined) {
|
|
728
841
|
this.instrumentation.recordMessageLatency(topicType, latency);
|
|
729
842
|
}
|
|
730
843
|
|
|
@@ -801,27 +914,30 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
801
914
|
}
|
|
802
915
|
|
|
803
916
|
/**
|
|
804
|
-
* Process
|
|
805
|
-
*
|
|
806
|
-
*
|
|
807
|
-
* @param attestation - The attestation to process.
|
|
917
|
+
* Process a checkpoint attestation from a peer.
|
|
918
|
+
* Validates the attestation and adds it to the pool.
|
|
808
919
|
*/
|
|
809
|
-
private async
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
920
|
+
private async processCheckpointAttestationFromPeer(
|
|
921
|
+
payloadData: Buffer,
|
|
922
|
+
msgId: string,
|
|
923
|
+
source: PeerId,
|
|
924
|
+
): Promise<void> {
|
|
925
|
+
const validationFunc: () => Promise<ReceivedMessageValidationResult<CheckpointAttestation>> = async () => {
|
|
926
|
+
const attestation = CheckpointAttestation.fromBuffer(payloadData);
|
|
927
|
+
const pool = this.mempools.attestationPool;
|
|
928
|
+
const validationResult = await this.validateCheckpointAttestation(source, attestation);
|
|
929
|
+
const isValid = validationResult.result === 'accept';
|
|
930
|
+
const exists = isValid && (await pool.hasCheckpointAttestation(attestation));
|
|
815
931
|
|
|
816
932
|
let canAdd = true;
|
|
817
933
|
if (isValid && !exists) {
|
|
818
934
|
const slot = attestation.payload.header.slotNumber;
|
|
819
935
|
const { committee } = await this.epochCache.getCommittee(slot);
|
|
820
936
|
const committeeSize = committee?.length ?? 0;
|
|
821
|
-
canAdd = await pool.
|
|
937
|
+
canAdd = await pool.canAddCheckpointAttestation(attestation, committeeSize);
|
|
822
938
|
}
|
|
823
939
|
|
|
824
|
-
this.logger.trace(`Validate propagated
|
|
940
|
+
this.logger.trace(`Validate propagated checkpoint attestation`, {
|
|
825
941
|
isValid,
|
|
826
942
|
exists,
|
|
827
943
|
canAdd,
|
|
@@ -829,12 +945,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
829
945
|
[Attributes.P2P_ID]: source.toString(),
|
|
830
946
|
});
|
|
831
947
|
|
|
832
|
-
if (
|
|
948
|
+
if (validationResult.result === 'reject') {
|
|
833
949
|
return { result: TopicValidatorResult.Reject };
|
|
834
|
-
} else if (exists) {
|
|
950
|
+
} else if (validationResult.result === 'ignore' || exists) {
|
|
835
951
|
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
836
952
|
} else if (!canAdd) {
|
|
837
|
-
this.logger.warn(`Dropping
|
|
953
|
+
this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
|
|
838
954
|
slot: attestation.payload.header.slotNumber.toString(),
|
|
839
955
|
archive: attestation.archive.toString(),
|
|
840
956
|
source: source.toString(),
|
|
@@ -845,11 +961,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
845
961
|
}
|
|
846
962
|
};
|
|
847
963
|
|
|
848
|
-
const { result, obj: attestation } = await this.validateReceivedMessage<
|
|
964
|
+
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
849
965
|
validationFunc,
|
|
850
966
|
msgId,
|
|
851
967
|
source,
|
|
852
|
-
TopicType.
|
|
968
|
+
TopicType.checkpoint_attestation,
|
|
853
969
|
);
|
|
854
970
|
|
|
855
971
|
if (result !== TopicValidatorResult.Accept || !attestation) {
|
|
@@ -857,7 +973,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
857
973
|
}
|
|
858
974
|
|
|
859
975
|
this.logger.debug(
|
|
860
|
-
`Received attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
|
|
976
|
+
`Received checkpoint attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
|
|
861
977
|
{
|
|
862
978
|
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
863
979
|
slot: attestation.slotNumber,
|
|
@@ -866,31 +982,30 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
866
982
|
},
|
|
867
983
|
);
|
|
868
984
|
|
|
869
|
-
await this.mempools.attestationPool
|
|
985
|
+
await this.mempools.attestationPool.addCheckpointAttestations([attestation]);
|
|
870
986
|
}
|
|
871
987
|
|
|
872
988
|
private async processBlockFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
873
989
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockProposal>> = async () => {
|
|
874
990
|
const block = BlockProposal.fromBuffer(payloadData);
|
|
875
|
-
const
|
|
991
|
+
const validationResult = await this.validateBlockProposal(source, block);
|
|
992
|
+
const isValid = validationResult.result === 'accept';
|
|
876
993
|
const pool = this.mempools.attestationPool;
|
|
877
994
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
const exists = isValid && (await pool?.hasBlockProposal(block));
|
|
881
|
-
const canAdd = isValid && (await pool?.canAddProposal(block));
|
|
995
|
+
const exists = isValid && (await pool.hasBlockProposal(block));
|
|
996
|
+
const canAdd = isValid && (await pool.canAddProposal(block));
|
|
882
997
|
|
|
883
998
|
this.logger.trace(`Validate propagated block proposal`, {
|
|
884
999
|
isValid,
|
|
885
1000
|
exists,
|
|
886
1001
|
canAdd,
|
|
887
|
-
[Attributes.SLOT_NUMBER]: block.
|
|
1002
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
|
|
888
1003
|
[Attributes.P2P_ID]: source.toString(),
|
|
889
1004
|
});
|
|
890
1005
|
|
|
891
|
-
if (
|
|
1006
|
+
if (validationResult.result === 'reject') {
|
|
892
1007
|
return { result: TopicValidatorResult.Reject };
|
|
893
|
-
} else if (exists) {
|
|
1008
|
+
} else if (validationResult.result === 'ignore' || exists) {
|
|
894
1009
|
return { result: TopicValidatorResult.Ignore, obj: block };
|
|
895
1010
|
} else if (!canAdd) {
|
|
896
1011
|
this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
|
|
@@ -920,6 +1035,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
920
1035
|
}
|
|
921
1036
|
|
|
922
1037
|
// REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
1038
|
+
// REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
|
|
1039
|
+
// should not be here as it does not deal with p2p networking.
|
|
923
1040
|
@trackSpan('Libp2pService.processValidBlockProposal', async block => ({
|
|
924
1041
|
[Attributes.SLOT_NUMBER]: block.slotNumber,
|
|
925
1042
|
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
@@ -927,21 +1044,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
927
1044
|
}))
|
|
928
1045
|
private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
|
|
929
1046
|
const slot = block.slotNumber;
|
|
930
|
-
const previousSlot = SlotNumber(slot - 1);
|
|
931
1047
|
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
932
1048
|
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
933
|
-
slot: block.slotNumber,
|
|
934
|
-
archive: block.archive.toString(),
|
|
935
1049
|
source: sender.toString(),
|
|
1050
|
+
...block.toBlockInfo(),
|
|
936
1051
|
});
|
|
937
|
-
const attestationsForPreviousSlot = await this.mempools.attestationPool?.getAttestationsForSlot(previousSlot);
|
|
938
|
-
if (attestationsForPreviousSlot !== undefined) {
|
|
939
|
-
this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
|
|
940
|
-
}
|
|
941
1052
|
|
|
942
|
-
// Attempt to add proposal
|
|
1053
|
+
// Attempt to add proposal
|
|
943
1054
|
try {
|
|
944
|
-
await this.mempools.attestationPool
|
|
1055
|
+
await this.mempools.attestationPool.addBlockProposal(block);
|
|
945
1056
|
} catch (err: unknown) {
|
|
946
1057
|
// Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
|
|
947
1058
|
if (err instanceof ProposalSlotCapExceededError) {
|
|
@@ -954,34 +1065,126 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
954
1065
|
}
|
|
955
1066
|
throw err;
|
|
956
1067
|
}
|
|
1068
|
+
|
|
1069
|
+
// Mark the txs in this proposal as non-evictable
|
|
957
1070
|
await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
|
|
958
|
-
const attestations = await this.blockReceivedCallback(block, sender);
|
|
959
1071
|
|
|
960
|
-
//
|
|
961
|
-
//
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1072
|
+
// Call the block received callback to validate the proposal.
|
|
1073
|
+
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1074
|
+
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1075
|
+
if (!isValid) {
|
|
1076
|
+
this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* Handle a gossiped checkpoint proposal.
|
|
1082
|
+
* Validates and processes the checkpoint proposal, then triggers the callback for attestation.
|
|
1083
|
+
*/
|
|
1084
|
+
private async handleGossipedCheckpointProposal(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
1085
|
+
// TODO(palla/mbps): This pattern is repeated across multiple message handlers, consider abstracting it.
|
|
1086
|
+
const validationFunc: () => Promise<ReceivedMessageValidationResult<CheckpointProposal>> = async () => {
|
|
1087
|
+
const checkpoint = CheckpointProposal.fromBuffer(payloadData);
|
|
1088
|
+
const validationResult = await this.validateCheckpointProposal(source, checkpoint);
|
|
1089
|
+
const isValid = validationResult.result === 'accept';
|
|
1090
|
+
const pool = this.mempools.attestationPool;
|
|
1091
|
+
|
|
1092
|
+
const exists = isValid && (await pool.hasCheckpointProposal(checkpoint));
|
|
1093
|
+
const canAdd = isValid && (await pool.canAddCheckpointProposal(checkpoint));
|
|
1094
|
+
|
|
1095
|
+
this.logger.trace(`Validate propagated checkpoint proposal`, {
|
|
1096
|
+
isValid,
|
|
1097
|
+
exists,
|
|
1098
|
+
canAdd,
|
|
1099
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1100
|
+
[Attributes.P2P_ID]: source.toString(),
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
if (validationResult.result === 'reject') {
|
|
1104
|
+
return { result: TopicValidatorResult.Reject };
|
|
1105
|
+
} else if (validationResult.result === 'ignore' || exists) {
|
|
1106
|
+
return { result: TopicValidatorResult.Ignore, obj: checkpoint };
|
|
1107
|
+
} else if (!canAdd) {
|
|
1108
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
|
|
1109
|
+
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1110
|
+
slot: checkpoint.slotNumber.toString(),
|
|
1111
|
+
archive: checkpoint.archive.toString(),
|
|
1112
|
+
source: source.toString(),
|
|
968
1113
|
});
|
|
969
|
-
|
|
1114
|
+
return { result: TopicValidatorResult.Reject };
|
|
1115
|
+
} else {
|
|
1116
|
+
return { result: TopicValidatorResult.Accept, obj: checkpoint };
|
|
970
1117
|
}
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
const { result, obj: checkpoint } = await this.validateReceivedMessage<CheckpointProposal>(
|
|
1121
|
+
validationFunc,
|
|
1122
|
+
msgId,
|
|
1123
|
+
source,
|
|
1124
|
+
TopicType.checkpoint_proposal,
|
|
1125
|
+
);
|
|
1126
|
+
|
|
1127
|
+
if (result !== TopicValidatorResult.Accept || !checkpoint) {
|
|
1128
|
+
return;
|
|
971
1129
|
}
|
|
1130
|
+
|
|
1131
|
+
await this.processValidCheckpointProposal(checkpoint, source);
|
|
972
1132
|
}
|
|
973
1133
|
|
|
974
1134
|
/**
|
|
975
|
-
*
|
|
976
|
-
*
|
|
1135
|
+
* Process a validated checkpoint proposal.
|
|
1136
|
+
* Extracts and processes the last block proposal (if present) first, then processes the checkpoint.
|
|
1137
|
+
* The block callback is invoked before the checkpoint callback.
|
|
977
1138
|
*/
|
|
978
|
-
@trackSpan('Libp2pService.
|
|
979
|
-
[Attributes.SLOT_NUMBER]:
|
|
980
|
-
[Attributes.BLOCK_ARCHIVE]:
|
|
981
|
-
[Attributes.P2P_ID]: await
|
|
1139
|
+
@trackSpan('Libp2pService.processValidCheckpointProposal', async checkpoint => ({
|
|
1140
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber,
|
|
1141
|
+
[Attributes.BLOCK_ARCHIVE]: checkpoint.archive.toString(),
|
|
1142
|
+
[Attributes.P2P_ID]: await checkpoint.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
982
1143
|
}))
|
|
983
|
-
private async
|
|
984
|
-
|
|
1144
|
+
private async processValidCheckpointProposal(checkpoint: CheckpointProposal, sender: PeerId) {
|
|
1145
|
+
const slot = checkpoint.slotNumber;
|
|
1146
|
+
this.logger.verbose(`Received checkpoint proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1147
|
+
p2pMessageIdentifier: await checkpoint.p2pMessageLoggingIdentifier(),
|
|
1148
|
+
slot: checkpoint.slotNumber,
|
|
1149
|
+
archive: checkpoint.archive.toString(),
|
|
1150
|
+
source: sender.toString(),
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
// Extract block proposal before adding to pool (pool stores them separately)
|
|
1154
|
+
const blockProposal = checkpoint.getBlockProposal();
|
|
1155
|
+
|
|
1156
|
+
// Add proposal to the pool (this extracts and stores block proposal separately)
|
|
1157
|
+
await this.mempools.attestationPool.addCheckpointProposal(checkpoint);
|
|
1158
|
+
|
|
1159
|
+
// Mark txs as non-evictable if present (from the last block)
|
|
1160
|
+
if (checkpoint.txHashes.length > 0) {
|
|
1161
|
+
await this.mempools.txPool.markTxsAsNonEvictable(checkpoint.txHashes);
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// If there was a last block proposal, invoke the block callback first for validation.
|
|
1165
|
+
// Note: The block proposal is already stored in the pool by addCheckpointProposal.
|
|
1166
|
+
if (blockProposal) {
|
|
1167
|
+
const isValid = await this.blockReceivedCallback(blockProposal, sender);
|
|
1168
|
+
if (!isValid) {
|
|
1169
|
+
this.logger.warn(`Block proposal from checkpoint failed validation`, {
|
|
1170
|
+
slot: slot.toString(),
|
|
1171
|
+
archive: checkpoint.archive.toString(),
|
|
1172
|
+
blockNumber: blockProposal.blockNumber.toString(),
|
|
1173
|
+
});
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1179
|
+
// to validate and potentially generate attestations
|
|
1180
|
+
const attestations = await this.checkpointReceivedCallback(checkpoint.toCore(), sender);
|
|
1181
|
+
if (attestations && attestations.length > 0) {
|
|
1182
|
+
// If the callback returned attestations, add them to the pool and propagate them
|
|
1183
|
+
await this.mempools.attestationPool.addCheckpointAttestations(attestations);
|
|
1184
|
+
for (const attestation of attestations) {
|
|
1185
|
+
await this.propagate(attestation);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
985
1188
|
}
|
|
986
1189
|
|
|
987
1190
|
/**
|
|
@@ -1047,7 +1250,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1047
1250
|
}
|
|
1048
1251
|
|
|
1049
1252
|
// Given proposal (should have locally), ensure returned txs are valid subset and match request indices
|
|
1050
|
-
const proposal = await this.mempools.attestationPool
|
|
1253
|
+
const proposal = await this.mempools.attestationPool.getBlockProposal(request.blockHash.toString());
|
|
1051
1254
|
if (proposal) {
|
|
1052
1255
|
// Build intersected indices
|
|
1053
1256
|
const intersectIdx = request.txIndices.getTrueIndices().filter(i => response.txIndices.isSet(i));
|
|
@@ -1172,6 +1375,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1172
1375
|
private createRequestedTxValidator(): TxValidator {
|
|
1173
1376
|
return new AggregateTxValidator(
|
|
1174
1377
|
new DataTxValidator(),
|
|
1378
|
+
new SizeTxValidator(),
|
|
1175
1379
|
new MetadataTxValidator({
|
|
1176
1380
|
l1ChainId: new Fr(this.config.l1ChainId),
|
|
1177
1381
|
rollupVersion: new Fr(this.config.rollupVersion),
|
|
@@ -1366,24 +1570,28 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1366
1570
|
}
|
|
1367
1571
|
|
|
1368
1572
|
/**
|
|
1369
|
-
* Validate
|
|
1573
|
+
* Validate a checkpoint attestation.
|
|
1370
1574
|
*
|
|
1371
|
-
* @param attestation - The attestation to validate.
|
|
1372
|
-
* @returns True if the attestation is valid, false otherwise.
|
|
1575
|
+
* @param attestation - The checkpoint attestation to validate.
|
|
1576
|
+
* @returns True if the checkpoint attestation is valid, false otherwise.
|
|
1373
1577
|
*/
|
|
1374
|
-
@trackSpan('Libp2pService.
|
|
1578
|
+
@trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
|
|
1375
1579
|
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
1376
1580
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1377
1581
|
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1378
1582
|
}))
|
|
1379
|
-
public async
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1583
|
+
public async validateCheckpointAttestation(
|
|
1584
|
+
peerId: PeerId,
|
|
1585
|
+
attestation: CheckpointAttestation,
|
|
1586
|
+
): Promise<P2PValidationResult> {
|
|
1587
|
+
const result = await this.checkpointAttestationValidator.validate(attestation);
|
|
1588
|
+
|
|
1589
|
+
if (result.result === 'reject') {
|
|
1590
|
+
this.logger.debug(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1591
|
+
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1384
1592
|
}
|
|
1385
1593
|
|
|
1386
|
-
return
|
|
1594
|
+
return result;
|
|
1387
1595
|
}
|
|
1388
1596
|
|
|
1389
1597
|
/**
|
|
@@ -1393,17 +1601,40 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1393
1601
|
* @returns True if the block proposal is valid, false otherwise.
|
|
1394
1602
|
*/
|
|
1395
1603
|
@trackSpan('Libp2pService.validateBlockProposal', (_peerId, block) => ({
|
|
1396
|
-
[Attributes.SLOT_NUMBER]: block.
|
|
1604
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
|
|
1397
1605
|
}))
|
|
1398
|
-
public async validateBlockProposal(peerId: PeerId, block: BlockProposal): Promise<
|
|
1399
|
-
const
|
|
1400
|
-
|
|
1606
|
+
public async validateBlockProposal(peerId: PeerId, block: BlockProposal): Promise<P2PValidationResult> {
|
|
1607
|
+
const result = await this.blockProposalValidator.validate(block);
|
|
1608
|
+
|
|
1609
|
+
if (result.result === 'reject') {
|
|
1401
1610
|
this.logger.debug(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1402
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
1403
|
-
return false;
|
|
1611
|
+
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1404
1612
|
}
|
|
1405
1613
|
|
|
1406
|
-
return
|
|
1614
|
+
return result;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
/**
|
|
1618
|
+
* Validate a checkpoint proposal.
|
|
1619
|
+
*
|
|
1620
|
+
* @param checkpoint - The checkpoint proposal to validate.
|
|
1621
|
+
* @returns True if the checkpoint proposal is valid, false otherwise.
|
|
1622
|
+
*/
|
|
1623
|
+
@trackSpan('Libp2pService.validateCheckpointProposal', (_peerId, checkpoint) => ({
|
|
1624
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1625
|
+
}))
|
|
1626
|
+
public async validateCheckpointProposal(
|
|
1627
|
+
peerId: PeerId,
|
|
1628
|
+
checkpoint: CheckpointProposal,
|
|
1629
|
+
): Promise<P2PValidationResult> {
|
|
1630
|
+
const result = await this.checkpointProposalValidator.validate(checkpoint);
|
|
1631
|
+
|
|
1632
|
+
if (result.result === 'reject') {
|
|
1633
|
+
this.logger.debug(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1634
|
+
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
return result;
|
|
1407
1638
|
}
|
|
1408
1639
|
|
|
1409
1640
|
public getPeerScore(peerId: PeerId): number {
|