@aztec/p2p 0.0.1-commit.5de5ca79e → 0.0.1-commit.6201a7b05
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 +3 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +22 -20
- package/dest/client/interface.d.ts +9 -2
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +3 -2
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +30 -10
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +20 -7
- package/dest/config.d.ts +106 -99
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +16 -7
- package/dest/errors/p2p-service.error.d.ts +9 -0
- package/dest/errors/p2p-service.error.d.ts.map +1 -0
- package/dest/errors/p2p-service.error.js +10 -0
- package/dest/index.d.ts +1 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +0 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -2
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +8 -5
- package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +6 -4
- package/dest/mem_pools/index.d.ts +1 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +17 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +4 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -2
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +2 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +34 -10
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
- package/dest/msg_validators/clock_tolerance.d.ts +12 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +57 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +4 -2
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +4 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +6 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +32 -9
- package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +2 -2
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +11 -5
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +36 -4
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +50 -33
- package/dest/msg_validators/tx_validator/phases_validator.js +1 -1
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/data_store.js +5 -5
- package/dest/services/dummy_service.d.ts +6 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +6 -1
- package/dest/services/gossipsub/topic_score_params.d.ts +13 -2
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +21 -4
- package/dest/services/libp2p/instrumentation.d.ts +3 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +14 -0
- package/dest/services/libp2p/libp2p_service.d.ts +20 -21
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +151 -110
- package/dest/services/peer-manager/peer_manager.d.ts +6 -2
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +33 -8
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +32 -10
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -1
- 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 +3 -0
- package/dest/services/reqresp/config.d.ts +3 -3
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/interface.d.ts +14 -9
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +10 -11
- 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 +0 -1
- package/dest/services/reqresp/protocols/index.d.ts +1 -2
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +0 -1
- package/dest/services/reqresp/protocols/tx.d.ts +1 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +1 -3
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
- package/dest/services/reqresp/reqresp.d.ts +4 -2
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +11 -2
- package/dest/services/service.d.ts +5 -2
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -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 +39 -29
- package/dest/services/tx_collection/tx_source.d.ts +6 -5
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +9 -7
- package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +4 -1
- package/dest/test-helpers/mock-pubsub.d.ts +11 -3
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +36 -11
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +5 -3
- package/dest/test-helpers/testbench-utils.d.ts +1 -1
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +1 -0
- package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +72 -17
- package/dest/testbench/worker_client_manager.d.ts +8 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +49 -1
- package/package.json +14 -14
- package/src/client/factory.ts +31 -21
- package/src/client/interface.ts +9 -1
- package/src/client/p2p_client.ts +34 -11
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -6
- package/src/config.ts +27 -7
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/index.ts +0 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +9 -5
- package/src/mem_pools/attestation_pool/mocks.ts +13 -8
- package/src/mem_pools/index.ts +0 -3
- package/src/mem_pools/instrumentation.ts +5 -1
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
- package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/interfaces.ts +3 -0
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +20 -8
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +2 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +38 -7
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +12 -2
- package/src/msg_validators/clock_tolerance.ts +75 -0
- package/src/msg_validators/proposal_validator/README.md +1 -1
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -2
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +15 -2
- package/src/msg_validators/proposal_validator/proposal_validator.ts +33 -7
- package/src/msg_validators/tx_validator/README.md +11 -3
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +42 -1
- package/src/msg_validators/tx_validator/factory.ts +10 -1
- package/src/msg_validators/tx_validator/gas_validator.ts +82 -33
- package/src/msg_validators/tx_validator/phases_validator.ts +1 -1
- package/src/services/data_store.ts +5 -13
- package/src/services/dummy_service.ts +8 -2
- package/src/services/gossipsub/topic_score_params.ts +36 -4
- package/src/services/libp2p/instrumentation.ts +14 -0
- package/src/services/libp2p/libp2p_service.ts +155 -117
- package/src/services/peer-manager/peer_manager.ts +38 -8
- package/src/services/peer-manager/peer_scoring.ts +27 -5
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +3 -0
- package/src/services/reqresp/config.ts +2 -2
- package/src/services/reqresp/interface.ts +21 -11
- package/src/services/reqresp/metrics.ts +0 -1
- package/src/services/reqresp/protocols/index.ts +0 -1
- package/src/services/reqresp/protocols/tx.ts +1 -3
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
- package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
- package/src/services/reqresp/reqresp.ts +18 -1
- package/src/services/service.ts +6 -1
- package/src/services/tx_collection/file_store_tx_source.ts +43 -31
- package/src/services/tx_collection/tx_source.ts +8 -7
- package/src/test-helpers/make-test-p2p-clients.ts +2 -0
- package/src/test-helpers/mock-pubsub.ts +34 -5
- package/src/test-helpers/reqresp-nodes.ts +4 -2
- package/src/test-helpers/testbench-utils.ts +1 -0
- package/src/testbench/p2p_client_testbench_worker.ts +73 -12
- package/src/testbench/worker_client_manager.ts +55 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
- package/dest/mem_pools/tx_pool/index.d.ts +0 -3
- package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/index.js +0 -2
- package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
- package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/priority.js +0 -15
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
- package/dest/services/reqresp/protocols/block.d.ts +0 -9
- package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/block.js +0 -32
- package/src/mem_pools/tx_pool/README.md +0 -270
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
- package/src/mem_pools/tx_pool/index.ts +0 -2
- package/src/mem_pools/tx_pool/priority.ts +0 -20
- package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
- package/src/services/reqresp/protocols/block.ts +0 -37
|
@@ -1,15 +1,14 @@
|
|
|
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';
|
|
4
|
-
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
+
import { maxBy, merge } from '@aztec/foundation/collection';
|
|
5
4
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
6
5
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
6
|
import { Timer } from '@aztec/foundation/timer';
|
|
8
7
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
9
8
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
10
|
-
import type { EthAddress,
|
|
9
|
+
import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
|
|
11
10
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
12
|
-
import { GasFees } from '@aztec/stdlib/gas';
|
|
11
|
+
import { type BlockMinFeesProvider, GasFees } from '@aztec/stdlib/gas';
|
|
13
12
|
import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
14
13
|
import {
|
|
15
14
|
BlockProposal,
|
|
@@ -58,6 +57,7 @@ import { ENR } from '@nethermindeth/enr';
|
|
|
58
57
|
import { createLibp2p } from 'libp2p';
|
|
59
58
|
|
|
60
59
|
import type { P2PConfig } from '../../config.js';
|
|
60
|
+
import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
|
|
61
61
|
import type { MemPools } from '../../mem_pools/interface.js';
|
|
62
62
|
import {
|
|
63
63
|
BlockProposalValidator,
|
|
@@ -104,7 +104,6 @@ import {
|
|
|
104
104
|
ValidationError,
|
|
105
105
|
pingHandler,
|
|
106
106
|
reqGoodbyeHandler,
|
|
107
|
-
reqRespBlockHandler,
|
|
108
107
|
reqRespBlockTxsHandler,
|
|
109
108
|
reqRespStatusHandler,
|
|
110
109
|
reqRespTxHandler,
|
|
@@ -130,7 +129,7 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
|
|
|
130
129
|
// REFACTOR: Unify with the type above
|
|
131
130
|
type ReceivedMessageValidationResult<T, M = undefined> =
|
|
132
131
|
| { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
|
|
133
|
-
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
|
|
132
|
+
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
|
|
134
133
|
|
|
135
134
|
/**
|
|
136
135
|
* Lib P2P implementation of the P2PService interface.
|
|
@@ -147,8 +146,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
147
146
|
private protocolVersion = '';
|
|
148
147
|
private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
|
|
149
148
|
|
|
150
|
-
private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
|
|
151
|
-
|
|
152
149
|
/** Callback invoked when a duplicate proposal is detected (triggers slashing). */
|
|
153
150
|
private duplicateProposalCallback?: (info: {
|
|
154
151
|
slot: SlotNumber;
|
|
@@ -171,7 +168,13 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
171
168
|
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
172
169
|
* @returns The attestations for the checkpoint, if any.
|
|
173
170
|
*/
|
|
174
|
-
private
|
|
171
|
+
private allNodesCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
172
|
+
/**
|
|
173
|
+
* Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
|
|
174
|
+
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
175
|
+
* @returns The attestations for the checkpoint, if any.
|
|
176
|
+
*/
|
|
177
|
+
private validatorCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
175
178
|
|
|
176
179
|
private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
|
|
177
180
|
|
|
@@ -192,6 +195,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
192
195
|
private epochCache: EpochCacheInterface,
|
|
193
196
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
194
197
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
198
|
+
private blockMinFeesProvider: BlockMinFeesProvider,
|
|
195
199
|
telemetry: TelemetryClient,
|
|
196
200
|
logger: Logger = createLogger('p2p:libp2p_service'),
|
|
197
201
|
) {
|
|
@@ -223,15 +227,26 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
223
227
|
this.protocolVersion,
|
|
224
228
|
);
|
|
225
229
|
|
|
230
|
+
const p2pPropagationTime = config.attestationPropagationTime;
|
|
226
231
|
const proposalValidatorOpts = {
|
|
227
232
|
txsPermitted: !config.disableTransactions,
|
|
228
233
|
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
|
|
234
|
+
p2pPropagationTime,
|
|
235
|
+
signatureContext: {
|
|
236
|
+
chainId: config.l1ChainId,
|
|
237
|
+
rollupAddress: config.l1Contracts.rollupAddress,
|
|
238
|
+
},
|
|
229
239
|
};
|
|
230
240
|
this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
|
|
231
241
|
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
|
|
242
|
+
const attestationValidatorOpts = {
|
|
243
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
244
|
+
p2pPropagationTime,
|
|
245
|
+
signatureContext: proposalValidatorOpts.signatureContext,
|
|
246
|
+
};
|
|
232
247
|
this.checkpointAttestationValidator = config.fishermanMode
|
|
233
|
-
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
|
|
234
|
-
: new CheckpointAttestationValidator(epochCache);
|
|
248
|
+
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, attestationValidatorOpts)
|
|
249
|
+
: new CheckpointAttestationValidator(epochCache, attestationValidatorOpts);
|
|
235
250
|
|
|
236
251
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
237
252
|
|
|
@@ -243,18 +258,22 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
243
258
|
return true;
|
|
244
259
|
};
|
|
245
260
|
|
|
246
|
-
this.
|
|
247
|
-
|
|
261
|
+
this.allNodesCheckpointReceivedCallback = (
|
|
262
|
+
_checkpoint: CheckpointProposalCore,
|
|
263
|
+
): Promise<CheckpointAttestation[] | undefined> => {
|
|
264
|
+
throw new CheckpointProposalReceivedCallbackNotRegisteredError();
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
this.validatorCheckpointReceivedCallback = (
|
|
268
|
+
_checkpoint: CheckpointProposalCore,
|
|
248
269
|
): Promise<CheckpointAttestation[] | undefined> => {
|
|
249
|
-
this.logger.debug(
|
|
250
|
-
`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
|
|
251
|
-
);
|
|
252
270
|
return Promise.resolve(undefined);
|
|
253
271
|
};
|
|
254
272
|
}
|
|
255
273
|
|
|
256
|
-
public updateConfig(config: Partial<P2PReqRespConfig
|
|
274
|
+
public updateConfig(config: Partial<P2PReqRespConfig & Pick<P2PConfig, 'skipIncomingProposals'>>) {
|
|
257
275
|
this.reqresp.updateConfig(config);
|
|
276
|
+
this.config = merge(this.config, config);
|
|
258
277
|
}
|
|
259
278
|
|
|
260
279
|
/**
|
|
@@ -273,6 +292,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
273
292
|
proofVerifier: ClientProtocolCircuitVerifier;
|
|
274
293
|
worldStateSynchronizer: WorldStateSynchronizer;
|
|
275
294
|
peerStore: AztecAsyncKVStore;
|
|
295
|
+
blockMinFeesProvider: BlockMinFeesProvider;
|
|
276
296
|
telemetry: TelemetryClient;
|
|
277
297
|
logger: Logger;
|
|
278
298
|
packageVersion: string;
|
|
@@ -285,6 +305,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
285
305
|
mempools,
|
|
286
306
|
proofVerifier,
|
|
287
307
|
peerStore,
|
|
308
|
+
blockMinFeesProvider,
|
|
288
309
|
telemetry,
|
|
289
310
|
logger,
|
|
290
311
|
packageVersion,
|
|
@@ -338,9 +359,12 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
338
359
|
const l1Constants = epochCache.getL1Constants();
|
|
339
360
|
const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
|
|
340
361
|
slotDurationMs: l1Constants.slotDuration * 1000,
|
|
362
|
+
ethereumSlotDuration: l1Constants.ethereumSlotDuration,
|
|
341
363
|
heartbeatIntervalMs: config.gossipsubInterval,
|
|
342
364
|
targetCommitteeSize: l1Constants.targetCommitteeSize,
|
|
343
365
|
blockDurationMs: config.blockDurationMs,
|
|
366
|
+
l1PublishingTime: config.l1PublishingTime,
|
|
367
|
+
p2pPropagationTime: config.attestationPropagationTime,
|
|
344
368
|
expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot,
|
|
345
369
|
});
|
|
346
370
|
|
|
@@ -465,6 +489,9 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
465
489
|
epochCache,
|
|
466
490
|
);
|
|
467
491
|
|
|
492
|
+
// Gate req/resp data protocols for unauthenticated peers when p2pAllowOnlyValidators is enabled
|
|
493
|
+
reqresp.setShouldRejectPeer(peerId => peerManager.shouldDisableP2PGossip(peerId));
|
|
494
|
+
|
|
468
495
|
// Configure application-specific scoring for gossipsub.
|
|
469
496
|
// The weight scales app score to align with gossipsub thresholds:
|
|
470
497
|
// - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
|
|
@@ -485,6 +512,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
485
512
|
epochCache,
|
|
486
513
|
proofVerifier,
|
|
487
514
|
worldStateSynchronizer,
|
|
515
|
+
blockMinFeesProvider,
|
|
488
516
|
telemetry,
|
|
489
517
|
logger,
|
|
490
518
|
);
|
|
@@ -510,14 +538,12 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
510
538
|
// Create request response protocol handlers
|
|
511
539
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
512
540
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
513
|
-
const blockHandler = reqRespBlockHandler(this.archiver);
|
|
514
541
|
const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
|
|
515
542
|
|
|
516
543
|
const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
|
|
517
544
|
[ReqRespSubProtocol.PING]: pingHandler,
|
|
518
545
|
[ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
|
|
519
546
|
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
520
|
-
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
521
547
|
};
|
|
522
548
|
|
|
523
549
|
if (!this.config.disableTransactions) {
|
|
@@ -538,7 +564,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
538
564
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
539
565
|
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
540
566
|
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
541
|
-
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
|
|
542
567
|
};
|
|
543
568
|
|
|
544
569
|
await this.peerManager.initializePeers();
|
|
@@ -666,8 +691,16 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
666
691
|
this.blockReceivedCallback = callback;
|
|
667
692
|
}
|
|
668
693
|
|
|
669
|
-
public
|
|
670
|
-
this.
|
|
694
|
+
public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
695
|
+
this.validatorCheckpointReceivedCallback = callback;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
699
|
+
this.allNodesCheckpointReceivedCallback = callback;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
|
|
703
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
|
|
671
704
|
}
|
|
672
705
|
|
|
673
706
|
/**
|
|
@@ -817,6 +850,15 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
817
850
|
|
|
818
851
|
// Process the message, optionally within a linked span for trace propagation
|
|
819
852
|
const processMessage = async () => {
|
|
853
|
+
if (
|
|
854
|
+
this.config.skipIncomingProposals &&
|
|
855
|
+
(msg.topic === this.topicStrings[TopicType.block_proposal] ||
|
|
856
|
+
msg.topic === this.topicStrings[TopicType.checkpoint_proposal])
|
|
857
|
+
) {
|
|
858
|
+
this.logger.warn(`Ignoring incoming proposal (skipIncomingProposals is set)`, { topic: msg.topic });
|
|
859
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
820
862
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
821
863
|
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
822
864
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
@@ -882,30 +924,67 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
882
924
|
source: PeerId,
|
|
883
925
|
topicType: TopicType,
|
|
884
926
|
): Promise<ReceivedMessageValidationResult<T, M>> {
|
|
885
|
-
|
|
927
|
+
// Default to reject result with a penalty if validation function throws an error
|
|
928
|
+
let resultAndObj: ReceivedMessageValidationResult<T, M> = {
|
|
929
|
+
result: TopicValidatorResult.Reject,
|
|
930
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
931
|
+
};
|
|
886
932
|
const timer = new Timer();
|
|
887
933
|
try {
|
|
888
934
|
resultAndObj = await validationFunc();
|
|
889
935
|
} catch (err) {
|
|
890
|
-
this.
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
936
|
+
this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
const validationTimeMs = timer.ms();
|
|
940
|
+
const mcacheWindowMs = this.config.gossipsubMcacheLength * this.config.gossipsubInterval;
|
|
941
|
+
if (validationTimeMs > mcacheWindowMs * 0.75) {
|
|
942
|
+
this.instrumentation.incSlowValidation(topicType);
|
|
943
|
+
this.logger.warn(
|
|
944
|
+
`Gossip validation for ${topicType} took ${validationTimeMs}ms, approaching mcache eviction window of ${mcacheWindowMs}ms. ` +
|
|
945
|
+
`Message forwarding may be skipped if validation exceeds the window.`,
|
|
946
|
+
{ msgId, source: source.toString(), topicType, validationTimeMs, mcacheWindowMs },
|
|
947
|
+
);
|
|
896
948
|
}
|
|
897
949
|
|
|
898
950
|
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
951
|
+
this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
|
|
899
952
|
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
953
|
+
} else if (resultAndObj.result === TopicValidatorResult.Reject) {
|
|
954
|
+
this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
|
|
955
|
+
msgId,
|
|
956
|
+
source: source.toString(),
|
|
957
|
+
topicType,
|
|
958
|
+
severity: resultAndObj.severity,
|
|
959
|
+
});
|
|
960
|
+
this.peerManager.penalizePeer(source, resultAndObj.severity);
|
|
961
|
+
} else {
|
|
962
|
+
this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
|
|
900
963
|
}
|
|
901
964
|
|
|
902
965
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
903
966
|
return resultAndObj;
|
|
904
967
|
}
|
|
905
968
|
|
|
969
|
+
private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
|
|
970
|
+
try {
|
|
971
|
+
return deserializeFunc();
|
|
972
|
+
} catch (err) {
|
|
973
|
+
this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
|
|
974
|
+
err,
|
|
975
|
+
msgId,
|
|
976
|
+
source: source.toString(),
|
|
977
|
+
});
|
|
978
|
+
return undefined;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
906
982
|
protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
|
|
907
983
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
|
|
908
|
-
const tx = Tx.fromBuffer(payloadData);
|
|
984
|
+
const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
|
|
985
|
+
if (!tx) {
|
|
986
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
|
|
987
|
+
}
|
|
909
988
|
|
|
910
989
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
911
990
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
@@ -930,8 +1009,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
930
1009
|
severity,
|
|
931
1010
|
source: source.toString(),
|
|
932
1011
|
});
|
|
933
|
-
|
|
934
|
-
return { result: TopicValidatorResult.Reject };
|
|
1012
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
935
1013
|
}
|
|
936
1014
|
|
|
937
1015
|
// Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
|
|
@@ -953,8 +1031,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
953
1031
|
severity,
|
|
954
1032
|
source: source.toString(),
|
|
955
1033
|
});
|
|
956
|
-
|
|
957
|
-
return { result: TopicValidatorResult.Reject };
|
|
1034
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
958
1035
|
}
|
|
959
1036
|
|
|
960
1037
|
// Pool add: persist the tx
|
|
@@ -979,8 +1056,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
979
1056
|
source: source.toString(),
|
|
980
1057
|
txHash: txHash.toString(),
|
|
981
1058
|
});
|
|
982
|
-
|
|
983
|
-
return { result: TopicValidatorResult.Reject };
|
|
1059
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
984
1060
|
}
|
|
985
1061
|
};
|
|
986
1062
|
|
|
@@ -1010,7 +1086,16 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1010
1086
|
source: PeerId,
|
|
1011
1087
|
): Promise<void> {
|
|
1012
1088
|
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
1013
|
-
() =>
|
|
1089
|
+
() => {
|
|
1090
|
+
const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
|
|
1091
|
+
if (!attestation) {
|
|
1092
|
+
return Promise.resolve({
|
|
1093
|
+
result: TopicValidatorResult.Reject,
|
|
1094
|
+
severity: PeerErrorSeverity.LowToleranceError,
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
return this.validateAndStoreCheckpointAttestation(source, attestation);
|
|
1098
|
+
},
|
|
1014
1099
|
msgId,
|
|
1015
1100
|
source,
|
|
1016
1101
|
TopicType.checkpoint_attestation,
|
|
@@ -1043,8 +1128,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1043
1128
|
|
|
1044
1129
|
if (validationResult.result === 'reject') {
|
|
1045
1130
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1046
|
-
|
|
1047
|
-
return { result: TopicValidatorResult.Reject };
|
|
1131
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1048
1132
|
}
|
|
1049
1133
|
|
|
1050
1134
|
if (validationResult.result === 'ignore') {
|
|
@@ -1070,16 +1154,16 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1070
1154
|
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
1071
1155
|
}
|
|
1072
1156
|
|
|
1073
|
-
// Could not add (cap reached for signer),
|
|
1157
|
+
// Could not add (cap reached for signer), penalize and do not re-broadcast
|
|
1074
1158
|
if (!added) {
|
|
1075
|
-
this.logger.warn(`
|
|
1159
|
+
this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
|
|
1076
1160
|
slot: slot.toString(),
|
|
1077
1161
|
archive: attestation.archive.toString(),
|
|
1078
1162
|
source: peerId.toString(),
|
|
1079
1163
|
attester: attestation.getSender()?.toString(),
|
|
1080
1164
|
count,
|
|
1081
1165
|
});
|
|
1082
|
-
return { result: TopicValidatorResult.
|
|
1166
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
1083
1167
|
}
|
|
1084
1168
|
|
|
1085
1169
|
// Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
|
|
@@ -1134,8 +1218,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1134
1218
|
|
|
1135
1219
|
if (validationResult.result === 'reject') {
|
|
1136
1220
|
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1137
|
-
|
|
1138
|
-
return { result: TopicValidatorResult.Reject };
|
|
1221
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1139
1222
|
}
|
|
1140
1223
|
|
|
1141
1224
|
if (validationResult.result === 'ignore') {
|
|
@@ -1159,7 +1242,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1159
1242
|
|
|
1160
1243
|
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1161
1244
|
if (!added) {
|
|
1162
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1163
1245
|
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1164
1246
|
...block.toBlockInfo(),
|
|
1165
1247
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
@@ -1167,7 +1249,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1167
1249
|
proposer: block.getSender()?.toString(),
|
|
1168
1250
|
source: peerId.toString(),
|
|
1169
1251
|
});
|
|
1170
|
-
return {
|
|
1252
|
+
return {
|
|
1253
|
+
result: TopicValidatorResult.Reject,
|
|
1254
|
+
metadata: { isEquivocated },
|
|
1255
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1256
|
+
};
|
|
1171
1257
|
}
|
|
1172
1258
|
|
|
1173
1259
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1260,8 +1346,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1260
1346
|
|
|
1261
1347
|
if (validationResult.result === 'reject') {
|
|
1262
1348
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1263
|
-
|
|
1264
|
-
return { result: TopicValidatorResult.Reject };
|
|
1349
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1265
1350
|
}
|
|
1266
1351
|
|
|
1267
1352
|
if (validationResult.result === 'ignore') {
|
|
@@ -1276,20 +1361,21 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1276
1361
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1277
1362
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1278
1363
|
});
|
|
1279
|
-
const
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
metadata: { isEquivocated } = {},
|
|
1283
|
-
} = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1284
|
-
if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1364
|
+
const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1365
|
+
const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
|
|
1366
|
+
if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1285
1367
|
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1286
1368
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1287
1369
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1288
1370
|
isEquivocated,
|
|
1289
|
-
result,
|
|
1371
|
+
result: blockProposalResult.result,
|
|
1290
1372
|
});
|
|
1291
|
-
return {
|
|
1292
|
-
|
|
1373
|
+
return {
|
|
1374
|
+
result: TopicValidatorResult.Reject,
|
|
1375
|
+
severity:
|
|
1376
|
+
'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
|
|
1377
|
+
};
|
|
1378
|
+
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1293
1379
|
processBlock = true;
|
|
1294
1380
|
}
|
|
1295
1381
|
}
|
|
@@ -1316,13 +1402,17 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1316
1402
|
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1317
1403
|
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1318
1404
|
if (!added) {
|
|
1319
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1320
1405
|
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1321
1406
|
...checkpoint.toCheckpointInfo(),
|
|
1322
1407
|
count,
|
|
1323
1408
|
source: peerId.toString(),
|
|
1324
1409
|
});
|
|
1325
|
-
return {
|
|
1410
|
+
return {
|
|
1411
|
+
result: TopicValidatorResult.Reject,
|
|
1412
|
+
obj: checkpoint,
|
|
1413
|
+
metadata: { isEquivocated, processBlock },
|
|
1414
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1415
|
+
};
|
|
1326
1416
|
}
|
|
1327
1417
|
|
|
1328
1418
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1367,9 +1457,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1367
1457
|
source: sender.toString(),
|
|
1368
1458
|
});
|
|
1369
1459
|
|
|
1460
|
+
await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
|
|
1461
|
+
|
|
1370
1462
|
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1371
1463
|
// to validate and potentially generate attestations
|
|
1372
|
-
const attestations = await this.
|
|
1464
|
+
const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
|
|
1373
1465
|
if (attestations && attestations.length > 0) {
|
|
1374
1466
|
// If the callback returned attestations, add them to the pool and propagate them
|
|
1375
1467
|
await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
@@ -1517,53 +1609,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1517
1609
|
}
|
|
1518
1610
|
}
|
|
1519
1611
|
|
|
1520
|
-
/**
|
|
1521
|
-
* Validates a BLOCK response.
|
|
1522
|
-
*
|
|
1523
|
-
* If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
|
|
1524
|
-
* Penalizes on block number mismatch or hash mismatch.
|
|
1525
|
-
*
|
|
1526
|
-
* @param requestedBlockNumber - The requested block number.
|
|
1527
|
-
* @param responseBlock - The block returned by the peer.
|
|
1528
|
-
* @param peerId - The peer that returned the block.
|
|
1529
|
-
* @returns True if the response is valid, false otherwise.
|
|
1530
|
-
*/
|
|
1531
|
-
@trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
|
|
1532
|
-
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
|
|
1533
|
-
}))
|
|
1534
|
-
protected async validateRequestedBlock(
|
|
1535
|
-
requestedBlockNumber: Fr,
|
|
1536
|
-
responseBlock: L2Block,
|
|
1537
|
-
peerId: PeerId,
|
|
1538
|
-
): Promise<boolean> {
|
|
1539
|
-
try {
|
|
1540
|
-
const reqNum = Number(requestedBlockNumber.toString());
|
|
1541
|
-
if (responseBlock.number !== reqNum) {
|
|
1542
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1543
|
-
return false;
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
const local = await this.archiver.getBlock(BlockNumber(reqNum));
|
|
1547
|
-
if (!local) {
|
|
1548
|
-
// We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
|
|
1549
|
-
// TODO: Consider extending this validator to accept an expected hash or
|
|
1550
|
-
// performing quorum-based checks when using P2P syncing prior to L1 sync.
|
|
1551
|
-
this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
|
|
1552
|
-
return false;
|
|
1553
|
-
}
|
|
1554
|
-
const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
|
|
1555
|
-
if (!localHash.equals(respHash)) {
|
|
1556
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1557
|
-
return false;
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
|
-
return true;
|
|
1561
|
-
} catch (e) {
|
|
1562
|
-
this.logger.warn(`Error validating requested block`, e);
|
|
1563
|
-
return false;
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
|
|
1567
1612
|
protected async validateRequestedTx(
|
|
1568
1613
|
tx: Tx,
|
|
1569
1614
|
peerId: PeerId,
|
|
@@ -1590,15 +1635,8 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1590
1635
|
});
|
|
1591
1636
|
}
|
|
1592
1637
|
|
|
1593
|
-
private
|
|
1594
|
-
|
|
1595
|
-
return this.feesCache.gasFees;
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
const header = await this.archiver.getBlockHeader(blockNumber);
|
|
1599
|
-
const gasFees = header?.globalVariables.gasFees ?? GasFees.empty();
|
|
1600
|
-
this.feesCache = { blockNumber, gasFees };
|
|
1601
|
-
return gasFees;
|
|
1638
|
+
private getGasFees(): Promise<GasFees> {
|
|
1639
|
+
return this.blockMinFeesProvider.getCurrentMinFees();
|
|
1602
1640
|
}
|
|
1603
1641
|
|
|
1604
1642
|
/**
|
|
@@ -1640,7 +1678,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1640
1678
|
currentBlockNumber: BlockNumber,
|
|
1641
1679
|
nextSlotTimestamp: UInt64,
|
|
1642
1680
|
): Promise<Record<string, TransactionValidator>> {
|
|
1643
|
-
const gasFees = await this.getGasFees(
|
|
1681
|
+
const gasFees = await this.getGasFees();
|
|
1644
1682
|
const allowedInSetup = [
|
|
1645
1683
|
...(await getDefaultAllowedSetupFunctions()),
|
|
1646
1684
|
...(this.config.txPublicSetupAllowListExtend ?? []),
|
|
@@ -226,20 +226,30 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
/**
|
|
229
|
-
* Cleans up expired timeouts.
|
|
229
|
+
* Cleans up expired timeouts and stale failed-auth-handshake entries.
|
|
230
230
|
*
|
|
231
231
|
* When peers fail to dial after a number of retries, they are temporarily timed out.
|
|
232
232
|
* This function removes any peers that have been in the timed out state for too long.
|
|
233
233
|
* To give them a chance to reconnect.
|
|
234
|
+
*
|
|
235
|
+
* Also evicts entries from the failed-auth-handshake map whose expiry window has passed.
|
|
236
|
+
* Without this, peers that probe once and never reconnect would leave their entries in the
|
|
237
|
+
* map forever, causing an unbounded memory leak.
|
|
234
238
|
*/
|
|
235
239
|
private cleanupExpiredTimeouts() {
|
|
236
|
-
// Clean up expired timeouts
|
|
237
240
|
const now = this.dateProvider.now();
|
|
241
|
+
|
|
238
242
|
for (const [peerId, timedOutPeer] of this.timedOutPeers.entries()) {
|
|
239
243
|
if (now >= timedOutPeer.timeoutUntilMs) {
|
|
240
244
|
this.timedOutPeers.delete(peerId);
|
|
241
245
|
}
|
|
242
246
|
}
|
|
247
|
+
|
|
248
|
+
for (const [id, entry] of this.failedAuthHandshakes.entries()) {
|
|
249
|
+
if (now - entry.lastFailureTimestamp > FAILED_AUTH_HANDSHAKE_EXPIRY_MS) {
|
|
250
|
+
this.failedAuthHandshakes.delete(id);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
243
253
|
}
|
|
244
254
|
|
|
245
255
|
/**
|
|
@@ -303,15 +313,20 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
303
313
|
*/
|
|
304
314
|
private handleDisconnectedPeerEvent(e: CustomEvent<PeerId>) {
|
|
305
315
|
const peerId = e.detail;
|
|
316
|
+
const peerIdStr = peerId.toString();
|
|
306
317
|
this.metrics.peerDisconnected(peerId);
|
|
307
|
-
this.logger.verbose(`Disconnected from peer ${
|
|
308
|
-
const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(
|
|
318
|
+
this.logger.verbose(`Disconnected from peer ${peerIdStr}`);
|
|
319
|
+
const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerIdStr);
|
|
309
320
|
if (validatorAddress !== undefined) {
|
|
310
321
|
this.logger.info(
|
|
311
|
-
`Removing authentication for validator ${validatorAddress} at peer id ${
|
|
322
|
+
`Removing authentication for validator ${validatorAddress} at peer id ${peerIdStr} due to disconnection`,
|
|
312
323
|
);
|
|
313
324
|
this.authenticatedValidatorAddressToPeerId.delete(validatorAddress.toString());
|
|
314
|
-
this.authenticatedPeerIdToValidatorAddress.delete(
|
|
325
|
+
this.authenticatedPeerIdToValidatorAddress.delete(peerIdStr);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (this.peerScoring.getScoreState(peerIdStr) === PeerScoreState.Healthy) {
|
|
329
|
+
this.peerScoring.removePeer(peerIdStr);
|
|
315
330
|
}
|
|
316
331
|
}
|
|
317
332
|
|
|
@@ -713,6 +728,12 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
713
728
|
return;
|
|
714
729
|
}
|
|
715
730
|
|
|
731
|
+
// Don't dial peers that have exceeded the auth failure threshold
|
|
732
|
+
if (!this.isNodeAllowedToConnect(peerId)) {
|
|
733
|
+
this.logger.trace(`Skipping peer ${peerId} due to failed auth handshake attempts`);
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
|
|
716
737
|
const [multiaddrTcp] = await Promise.all([enr.getFullMultiaddr('tcp')]);
|
|
717
738
|
|
|
718
739
|
this.logger.trace(`Handling discovered peer ${peerId} at ${multiaddrTcp?.toString() ?? 'undefined address'}`);
|
|
@@ -970,14 +991,14 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
970
991
|
const peerIdStr = peerId.toString();
|
|
971
992
|
|
|
972
993
|
const existingEntry = this.failedAuthHandshakes.get(peerIdStr);
|
|
994
|
+
const failureCount = (existingEntry?.count || 0) + 1;
|
|
973
995
|
this.failedAuthHandshakes.set(peerIdStr, {
|
|
974
|
-
count:
|
|
996
|
+
count: failureCount,
|
|
975
997
|
lastFailureTimestamp: now,
|
|
976
998
|
});
|
|
977
999
|
|
|
978
1000
|
const connections = this.libP2PNode.getConnections(peerId);
|
|
979
1001
|
connections.forEach(conn => {
|
|
980
|
-
// We mark the IP address
|
|
981
1002
|
const address = conn.remoteAddr.nodeAddress().address;
|
|
982
1003
|
const existingAddressEntry = this.failedAuthHandshakes.get(address);
|
|
983
1004
|
this.failedAuthHandshakes.set(address, {
|
|
@@ -985,6 +1006,15 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
985
1006
|
lastFailureTimestamp: now,
|
|
986
1007
|
});
|
|
987
1008
|
});
|
|
1009
|
+
|
|
1010
|
+
// Ban the peer from being re-dialed for a cooldown period (exponential backoff)
|
|
1011
|
+
const banTimeMs = this.config.peerFailedBanTimeMs ?? DEFAULT_FAILED_PEER_BAN_TIME_MS;
|
|
1012
|
+
const backoffMs = banTimeMs * Math.pow(2, Math.min(failureCount - 1, 5));
|
|
1013
|
+
this.timedOutPeers.set(peerIdStr, {
|
|
1014
|
+
peerId: peerIdStr,
|
|
1015
|
+
timeoutUntilMs: now + backoffMs,
|
|
1016
|
+
});
|
|
1017
|
+
this.cachedPeers.delete(peerIdStr);
|
|
988
1018
|
}
|
|
989
1019
|
|
|
990
1020
|
/*
|