@aztec/p2p 0.0.1-commit.c0b82b2 → 0.0.1-commit.c2eed6949
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -3
- package/dest/client/factory.d.ts +2 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +22 -9
- package/dest/client/p2p_client.d.ts +1 -1
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +22 -34
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +3 -3
- package/dest/config.d.ts +32 -11
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +86 -32
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +8 -4
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
- package/dest/mem_pools/instrumentation.d.ts +4 -2
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +16 -14
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +2 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +4 -4
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +9 -5
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +25 -10
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +33 -10
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -43
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +4 -2
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +6 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +2 -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 +24 -6
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +5 -4
- package/dest/msg_validators/clock_tolerance.d.ts +1 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +4 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +53 -41
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +23 -4
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +36 -10
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +13 -4
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +39 -9
- package/dest/msg_validators/tx_validator/index.d.ts +2 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +22 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +4 -2
- package/dest/services/encoding.d.ts +5 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -1
- package/dest/services/libp2p/libp2p_service.d.ts +7 -9
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +166 -72
- package/dest/services/peer-manager/metrics.d.ts +3 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +6 -0
- package/dest/services/peer-manager/peer_manager.d.ts +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +6 -3
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +69 -65
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +3 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +3 -0
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +17 -9
- package/dest/services/service.d.ts +7 -1
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +57 -73
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
- package/dest/services/tx_collection/request_tracker.d.ts +53 -0
- package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/request_tracker.js +84 -0
- package/dest/services/tx_collection/slow_tx_collection.js +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +3 -6
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +6 -1
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +9 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.d.ts +1 -1
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +22 -3
- package/dest/testbench/p2p_client_testbench_worker.js +5 -4
- package/dest/testbench/worker_client_manager.d.ts +3 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +6 -2
- package/dest/util.d.ts +9 -4
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +2 -9
- package/package.json +14 -14
- package/src/client/factory.ts +37 -13
- package/src/client/p2p_client.ts +22 -34
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +4 -6
- package/src/config.ts +124 -34
- package/src/mem_pools/attestation_pool/attestation_pool.ts +8 -7
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
- package/src/mem_pools/instrumentation.ts +17 -13
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +2 -1
- package/src/mem_pools/tx_pool/priority.ts +4 -4
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
- package/src/mem_pools/tx_pool_v2/README.md +9 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/interfaces.ts +9 -4
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +52 -12
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +16 -1
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +28 -6
- package/src/msg_validators/attestation_validator/README.md +49 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +5 -4
- package/src/msg_validators/clock_tolerance.ts +4 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +69 -45
- package/src/msg_validators/tx_validator/README.md +5 -1
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +42 -1
- package/src/msg_validators/tx_validator/factory.ts +43 -3
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +41 -8
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
- package/src/services/discv5/discV5_service.ts +4 -2
- package/src/services/encoding.ts +9 -1
- package/src/services/libp2p/libp2p_service.ts +164 -80
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +7 -3
- package/src/services/reqresp/README.md +229 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +64 -69
- package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +5 -0
- package/src/services/reqresp/reqresp.ts +19 -11
- package/src/services/service.ts +7 -0
- package/src/services/tx_collection/fast_tx_collection.ts +57 -83
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/slow_tx_collection.ts +1 -1
- package/src/services/tx_collection/tx_collection.ts +3 -5
- package/src/test-helpers/make-test-p2p-clients.ts +1 -1
- package/src/test-helpers/mock-pubsub.ts +9 -0
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/test-helpers/testbench-utils.ts +29 -3
- package/src/testbench/p2p_client_testbench_worker.ts +5 -6
- package/src/testbench/worker_client_manager.ts +13 -5
- package/src/util.ts +9 -13
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
- package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
- package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
2
|
import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { maxBy } from '@aztec/foundation/collection';
|
|
3
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
5
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
5
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
@@ -17,8 +18,8 @@ import {
|
|
|
17
18
|
type CheckpointProposalCore,
|
|
18
19
|
type Gossipable,
|
|
19
20
|
P2PMessage,
|
|
20
|
-
type ValidationResult as P2PValidationResult,
|
|
21
21
|
PeerErrorSeverity,
|
|
22
|
+
PeerErrorSeverityByHarshness,
|
|
22
23
|
TopicType,
|
|
23
24
|
createTopicString,
|
|
24
25
|
getTopicsForConfig,
|
|
@@ -50,9 +51,10 @@ import { yamux } from '@chainsafe/libp2p-yamux';
|
|
|
50
51
|
import { bootstrap } from '@libp2p/bootstrap';
|
|
51
52
|
import { identify } from '@libp2p/identify';
|
|
52
53
|
import { type Message, type MultiaddrConnection, type PeerId, TopicValidatorResult } from '@libp2p/interface';
|
|
53
|
-
import type { ConnectionManager } from '@libp2p/interface-internal';
|
|
54
|
+
import type { AddressManager, ConnectionManager } from '@libp2p/interface-internal';
|
|
54
55
|
import { mplex } from '@libp2p/mplex';
|
|
55
56
|
import { tcp } from '@libp2p/tcp';
|
|
57
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
56
58
|
import { ENR } from '@nethermindeth/enr';
|
|
57
59
|
import { createLibp2p } from 'libp2p';
|
|
58
60
|
|
|
@@ -129,7 +131,7 @@ type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: Vali
|
|
|
129
131
|
// REFACTOR: Unify with the type above
|
|
130
132
|
type ReceivedMessageValidationResult<T, M = undefined> =
|
|
131
133
|
| { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
|
|
132
|
-
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
|
|
134
|
+
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M; severity: PeerErrorSeverity };
|
|
133
135
|
|
|
134
136
|
/**
|
|
135
137
|
* Lib P2P implementation of the P2PService interface.
|
|
@@ -173,6 +175,10 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
173
175
|
private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
174
176
|
|
|
175
177
|
private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
|
|
178
|
+
private ipChangedHandler?: (ip: string) => void;
|
|
179
|
+
|
|
180
|
+
/** Discovered public IP address (set when queryForIp is enabled and no static IP was configured). */
|
|
181
|
+
private discoveredP2pIp?: string;
|
|
176
182
|
|
|
177
183
|
private instrumentation: P2PInstrumentation;
|
|
178
184
|
|
|
@@ -222,10 +228,12 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
222
228
|
this.protocolVersion,
|
|
223
229
|
);
|
|
224
230
|
|
|
225
|
-
|
|
226
|
-
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
|
|
231
|
+
const proposalValidatorOpts = {
|
|
227
232
|
txsPermitted: !config.disableTransactions,
|
|
228
|
-
|
|
233
|
+
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
|
|
234
|
+
};
|
|
235
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
|
|
236
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
|
|
229
237
|
this.checkpointAttestationValidator = config.fishermanMode
|
|
230
238
|
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
|
|
231
239
|
: new CheckpointAttestationValidator(epochCache);
|
|
@@ -233,11 +241,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
233
241
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
234
242
|
|
|
235
243
|
this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
|
|
236
|
-
this.logger.
|
|
237
|
-
`Handler not yet registered
|
|
244
|
+
this.logger.warn(
|
|
245
|
+
`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`,
|
|
238
246
|
{ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
|
|
239
247
|
);
|
|
240
|
-
return
|
|
248
|
+
return true;
|
|
241
249
|
};
|
|
242
250
|
|
|
243
251
|
this.checkpointReceivedCallback = (
|
|
@@ -439,8 +447,9 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
439
447
|
topics: topicScoreParams,
|
|
440
448
|
}),
|
|
441
449
|
}) as (components: GossipSubComponents) => GossipSub,
|
|
442
|
-
components: (components: { connectionManager: ConnectionManager }) => ({
|
|
450
|
+
components: (components: { connectionManager: ConnectionManager; addressManager: AddressManager }) => ({
|
|
443
451
|
connectionManager: components.connectionManager,
|
|
452
|
+
addressManager: components.addressManager,
|
|
444
453
|
}),
|
|
445
454
|
},
|
|
446
455
|
logger: createLibp2pComponentLogger(logger.module, logger.getBindings()),
|
|
@@ -499,10 +508,10 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
499
508
|
|
|
500
509
|
// Get listen & announce addresses for logging
|
|
501
510
|
const { p2pIp, p2pPort } = this.config;
|
|
502
|
-
if (!p2pIp) {
|
|
511
|
+
if (!p2pIp && !this.config.queryForIp) {
|
|
503
512
|
throw new Error('Announce address not provided.');
|
|
504
513
|
}
|
|
505
|
-
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
514
|
+
const announceTcpMultiaddr = p2pIp ? convertToMultiaddr(p2pIp, p2pPort, 'tcp') : undefined;
|
|
506
515
|
|
|
507
516
|
// Create request response protocol handlers
|
|
508
517
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
@@ -556,6 +565,31 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
556
565
|
if (!this.config.p2pDiscoveryDisabled) {
|
|
557
566
|
await this.peerDiscoveryService.start();
|
|
558
567
|
}
|
|
568
|
+
|
|
569
|
+
// When queryForIp is enabled and no static IP was configured, bridge discv5 IP discovery to libp2p.
|
|
570
|
+
// Discv5 discovers our public IP via peer WHOAREYOU exchanges (enrUpdate=true) and emits 'ip:changed'.
|
|
571
|
+
// We confirm the discovered address in the libp2p AddressManager so it appears in getMultiaddrs()
|
|
572
|
+
// and is pushed to all connected peers via the identify protocol.
|
|
573
|
+
if (this.config.queryForIp && !p2pIp) {
|
|
574
|
+
this.ipChangedHandler = (ip: string) => {
|
|
575
|
+
const addressManager = this.node.services.components.addressManager;
|
|
576
|
+
const newAddr = multiaddr(convertToMultiaddr(ip, this.config.p2pPort, 'tcp'));
|
|
577
|
+
|
|
578
|
+
// Remove old discovered IP if one exists
|
|
579
|
+
if (this.discoveredP2pIp) {
|
|
580
|
+
const oldAddr = multiaddr(convertToMultiaddr(this.discoveredP2pIp, this.config.p2pPort, 'tcp'));
|
|
581
|
+
addressManager.removeObservedAddr(oldAddr);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
addressManager.addObservedAddr(newAddr);
|
|
585
|
+
addressManager.confirmObservedAddr(newAddr);
|
|
586
|
+
// Store discovered IP
|
|
587
|
+
this.discoveredP2pIp = ip;
|
|
588
|
+
this.logger.info('Public IP discovered via discv5', { ip });
|
|
589
|
+
};
|
|
590
|
+
this.peerDiscoveryService.on('ip:changed', this.ipChangedHandler);
|
|
591
|
+
}
|
|
592
|
+
|
|
559
593
|
this.discoveryRunningPromise = new RunningPromise(
|
|
560
594
|
async () => {
|
|
561
595
|
await this.peerManager.heartbeat();
|
|
@@ -568,7 +602,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
568
602
|
this.logger.info(`Started P2P service`, {
|
|
569
603
|
listen: this.config.listenAddress,
|
|
570
604
|
port: this.config.p2pPort,
|
|
571
|
-
announce: announceTcpMultiaddr,
|
|
605
|
+
announce: announceTcpMultiaddr ?? 'pending (queryForIp=true)',
|
|
572
606
|
peerId: this.node.peerId.toString(),
|
|
573
607
|
});
|
|
574
608
|
}
|
|
@@ -581,6 +615,12 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
581
615
|
// Remove gossip sub listener
|
|
582
616
|
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
583
617
|
|
|
618
|
+
// Remove ip:changed listener if registered
|
|
619
|
+
if (this.ipChangedHandler) {
|
|
620
|
+
this.peerDiscoveryService.off('ip:changed', this.ipChangedHandler);
|
|
621
|
+
this.ipChangedHandler = undefined;
|
|
622
|
+
}
|
|
623
|
+
|
|
584
624
|
// Stop peer manager
|
|
585
625
|
this.logger.debug('Stopping peer manager...');
|
|
586
626
|
await this.peerManager.stop();
|
|
@@ -750,6 +790,9 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
750
790
|
if (!validator || !validator.addMessage(msgId)) {
|
|
751
791
|
this.instrumentation.incMessagePrevalidationStatus(false, topicType);
|
|
752
792
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
793
|
+
if (topicType === TopicType.tx) {
|
|
794
|
+
this.logger.verbose(`Ignoring already-seen tx gossip message`, { msgId, source: source.toString() });
|
|
795
|
+
}
|
|
753
796
|
return { result: false, topicType };
|
|
754
797
|
}
|
|
755
798
|
|
|
@@ -876,30 +919,56 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
876
919
|
source: PeerId,
|
|
877
920
|
topicType: TopicType,
|
|
878
921
|
): Promise<ReceivedMessageValidationResult<T, M>> {
|
|
879
|
-
|
|
922
|
+
// Default to reject result with a penalty if validation function throws an error
|
|
923
|
+
let resultAndObj: ReceivedMessageValidationResult<T, M> = {
|
|
924
|
+
result: TopicValidatorResult.Reject,
|
|
925
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
926
|
+
};
|
|
880
927
|
const timer = new Timer();
|
|
881
928
|
try {
|
|
882
929
|
resultAndObj = await validationFunc();
|
|
883
930
|
} catch (err) {
|
|
884
|
-
this.
|
|
885
|
-
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
886
|
-
msgId,
|
|
887
|
-
source: source.toString(),
|
|
888
|
-
topicType,
|
|
889
|
-
});
|
|
931
|
+
this.logger.error(`Error validating gossipsub message`, err, { msgId, source: source.toString(), topicType });
|
|
890
932
|
}
|
|
891
933
|
|
|
892
934
|
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
935
|
+
this.logger.debug(`Message ${topicType} accepted by validator`, { msgId, source: source.toString(), topicType });
|
|
893
936
|
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
937
|
+
} else if (resultAndObj.result === TopicValidatorResult.Reject) {
|
|
938
|
+
this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
|
|
939
|
+
msgId,
|
|
940
|
+
source: source.toString(),
|
|
941
|
+
topicType,
|
|
942
|
+
severity: resultAndObj.severity,
|
|
943
|
+
});
|
|
944
|
+
this.peerManager.penalizePeer(source, resultAndObj.severity);
|
|
945
|
+
} else {
|
|
946
|
+
this.logger.trace(`Message ${topicType} ignored by validator`, { msgId, source: source.toString(), topicType });
|
|
894
947
|
}
|
|
895
948
|
|
|
896
949
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
897
950
|
return resultAndObj;
|
|
898
951
|
}
|
|
899
952
|
|
|
953
|
+
private tryDeserialize<T>(deserializeFunc: () => T, msgId: string, source: PeerId): T | undefined {
|
|
954
|
+
try {
|
|
955
|
+
return deserializeFunc();
|
|
956
|
+
} catch (err) {
|
|
957
|
+
this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
|
|
958
|
+
err,
|
|
959
|
+
msgId,
|
|
960
|
+
source: source.toString(),
|
|
961
|
+
});
|
|
962
|
+
return undefined;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
|
|
900
966
|
protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
|
|
901
967
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
|
|
902
|
-
const tx = Tx.fromBuffer(payloadData);
|
|
968
|
+
const tx = this.tryDeserialize(() => Tx.fromBuffer(payloadData), msgId, source);
|
|
969
|
+
if (!tx) {
|
|
970
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.LowToleranceError };
|
|
971
|
+
}
|
|
903
972
|
|
|
904
973
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
905
974
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
@@ -919,13 +988,20 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
919
988
|
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
920
989
|
}
|
|
921
990
|
|
|
922
|
-
this.
|
|
923
|
-
|
|
991
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
|
|
992
|
+
validator: name,
|
|
993
|
+
severity,
|
|
994
|
+
source: source.toString(),
|
|
995
|
+
});
|
|
996
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
924
997
|
}
|
|
925
998
|
|
|
926
999
|
// Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
|
|
927
1000
|
const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
|
|
928
1001
|
if (canAdd === 'ignored') {
|
|
1002
|
+
this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
|
|
1003
|
+
source: source.toString(),
|
|
1004
|
+
});
|
|
929
1005
|
return { result: TopicValidatorResult.Ignore, obj: tx };
|
|
930
1006
|
}
|
|
931
1007
|
|
|
@@ -933,9 +1009,13 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
933
1009
|
const secondStageValidators = this.createSecondStageMessageValidators();
|
|
934
1010
|
const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
|
|
935
1011
|
if (!secondStageOutcome.allPassed) {
|
|
936
|
-
const { severity } = secondStageOutcome.failure;
|
|
937
|
-
this.
|
|
938
|
-
|
|
1012
|
+
const { severity, name } = secondStageOutcome.failure;
|
|
1013
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
|
|
1014
|
+
validator: name,
|
|
1015
|
+
severity,
|
|
1016
|
+
source: source.toString(),
|
|
1017
|
+
});
|
|
1018
|
+
return { result: TopicValidatorResult.Reject, severity };
|
|
939
1019
|
}
|
|
940
1020
|
|
|
941
1021
|
// Pool add: persist the tx
|
|
@@ -945,7 +1025,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
945
1025
|
const wasAccepted = addResult.accepted.some(h => h.equals(txHash));
|
|
946
1026
|
const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
|
|
947
1027
|
|
|
948
|
-
this.logger.
|
|
1028
|
+
this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
|
|
949
1029
|
wasAccepted,
|
|
950
1030
|
wasIgnored,
|
|
951
1031
|
[Attributes.P2P_ID]: source.toString(),
|
|
@@ -956,7 +1036,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
956
1036
|
} else if (wasIgnored) {
|
|
957
1037
|
return { result: TopicValidatorResult.Ignore, obj: tx };
|
|
958
1038
|
} else {
|
|
959
|
-
|
|
1039
|
+
this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
|
|
1040
|
+
source: source.toString(),
|
|
1041
|
+
txHash: txHash.toString(),
|
|
1042
|
+
});
|
|
1043
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
960
1044
|
}
|
|
961
1045
|
};
|
|
962
1046
|
|
|
@@ -986,7 +1070,16 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
986
1070
|
source: PeerId,
|
|
987
1071
|
): Promise<void> {
|
|
988
1072
|
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
989
|
-
() =>
|
|
1073
|
+
() => {
|
|
1074
|
+
const attestation = this.tryDeserialize(() => CheckpointAttestation.fromBuffer(payloadData), msgId, source);
|
|
1075
|
+
if (!attestation) {
|
|
1076
|
+
return Promise.resolve({
|
|
1077
|
+
result: TopicValidatorResult.Reject,
|
|
1078
|
+
severity: PeerErrorSeverity.LowToleranceError,
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
return this.validateAndStoreCheckpointAttestation(source, attestation);
|
|
1082
|
+
},
|
|
990
1083
|
msgId,
|
|
991
1084
|
source,
|
|
992
1085
|
TopicType.checkpoint_attestation,
|
|
@@ -1019,8 +1112,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1019
1112
|
|
|
1020
1113
|
if (validationResult.result === 'reject') {
|
|
1021
1114
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1022
|
-
|
|
1023
|
-
return { result: TopicValidatorResult.Reject };
|
|
1115
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1024
1116
|
}
|
|
1025
1117
|
|
|
1026
1118
|
if (validationResult.result === 'ignore') {
|
|
@@ -1046,16 +1138,16 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1046
1138
|
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
1047
1139
|
}
|
|
1048
1140
|
|
|
1049
|
-
// Could not add (cap reached for signer),
|
|
1141
|
+
// Could not add (cap reached for signer), penalize and do not re-broadcast
|
|
1050
1142
|
if (!added) {
|
|
1051
|
-
this.logger.warn(`
|
|
1143
|
+
this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
|
|
1052
1144
|
slot: slot.toString(),
|
|
1053
1145
|
archive: attestation.archive.toString(),
|
|
1054
1146
|
source: peerId.toString(),
|
|
1055
1147
|
attester: attestation.getSender()?.toString(),
|
|
1056
1148
|
count,
|
|
1057
1149
|
});
|
|
1058
|
-
return { result: TopicValidatorResult.
|
|
1150
|
+
return { result: TopicValidatorResult.Reject, severity: PeerErrorSeverity.HighToleranceError };
|
|
1059
1151
|
}
|
|
1060
1152
|
|
|
1061
1153
|
// Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
|
|
@@ -1110,8 +1202,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1110
1202
|
|
|
1111
1203
|
if (validationResult.result === 'reject') {
|
|
1112
1204
|
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1113
|
-
|
|
1114
|
-
return { result: TopicValidatorResult.Reject };
|
|
1205
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1115
1206
|
}
|
|
1116
1207
|
|
|
1117
1208
|
if (validationResult.result === 'ignore') {
|
|
@@ -1135,7 +1226,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1135
1226
|
|
|
1136
1227
|
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1137
1228
|
if (!added) {
|
|
1138
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1139
1229
|
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1140
1230
|
...block.toBlockInfo(),
|
|
1141
1231
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
@@ -1143,7 +1233,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1143
1233
|
proposer: block.getSender()?.toString(),
|
|
1144
1234
|
source: peerId.toString(),
|
|
1145
1235
|
});
|
|
1146
|
-
return {
|
|
1236
|
+
return {
|
|
1237
|
+
result: TopicValidatorResult.Reject,
|
|
1238
|
+
metadata: { isEquivocated },
|
|
1239
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1240
|
+
};
|
|
1147
1241
|
}
|
|
1148
1242
|
|
|
1149
1243
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1188,7 +1282,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1188
1282
|
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1189
1283
|
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1190
1284
|
if (!isValid) {
|
|
1191
|
-
this.logger.
|
|
1285
|
+
this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1192
1286
|
}
|
|
1193
1287
|
}
|
|
1194
1288
|
|
|
@@ -1236,8 +1330,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1236
1330
|
|
|
1237
1331
|
if (validationResult.result === 'reject') {
|
|
1238
1332
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1239
|
-
|
|
1240
|
-
return { result: TopicValidatorResult.Reject };
|
|
1333
|
+
return { result: TopicValidatorResult.Reject, severity: validationResult.severity };
|
|
1241
1334
|
}
|
|
1242
1335
|
|
|
1243
1336
|
if (validationResult.result === 'ignore') {
|
|
@@ -1252,20 +1345,21 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1252
1345
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1253
1346
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1254
1347
|
});
|
|
1255
|
-
const
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
metadata: { isEquivocated } = {},
|
|
1259
|
-
} = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1260
|
-
if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1348
|
+
const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1349
|
+
const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
|
|
1350
|
+
if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1261
1351
|
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1262
1352
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1263
1353
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1264
1354
|
isEquivocated,
|
|
1265
|
-
result,
|
|
1355
|
+
result: blockProposalResult.result,
|
|
1266
1356
|
});
|
|
1267
|
-
return {
|
|
1268
|
-
|
|
1357
|
+
return {
|
|
1358
|
+
result: TopicValidatorResult.Reject,
|
|
1359
|
+
severity:
|
|
1360
|
+
'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError,
|
|
1361
|
+
};
|
|
1362
|
+
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1269
1363
|
processBlock = true;
|
|
1270
1364
|
}
|
|
1271
1365
|
}
|
|
@@ -1292,13 +1386,17 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1292
1386
|
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1293
1387
|
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1294
1388
|
if (!added) {
|
|
1295
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1296
1389
|
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1297
1390
|
...checkpoint.toCheckpointInfo(),
|
|
1298
1391
|
count,
|
|
1299
1392
|
source: peerId.toString(),
|
|
1300
1393
|
});
|
|
1301
|
-
return {
|
|
1394
|
+
return {
|
|
1395
|
+
result: TopicValidatorResult.Reject,
|
|
1396
|
+
obj: checkpoint,
|
|
1397
|
+
metadata: { isEquivocated, processBlock },
|
|
1398
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
1399
|
+
};
|
|
1302
1400
|
}
|
|
1303
1401
|
|
|
1304
1402
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1617,8 +1715,12 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1617
1715
|
nextSlotTimestamp: UInt64,
|
|
1618
1716
|
): Promise<Record<string, TransactionValidator>> {
|
|
1619
1717
|
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
1620
|
-
const allowedInSetup =
|
|
1718
|
+
const allowedInSetup = [
|
|
1719
|
+
...(await getDefaultAllowedSetupFunctions()),
|
|
1720
|
+
...(this.config.txPublicSetupAllowListExtend ?? []),
|
|
1721
|
+
];
|
|
1621
1722
|
const blockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1723
|
+
const l1Constants = await this.archiver.getL1Constants();
|
|
1622
1724
|
|
|
1623
1725
|
return createFirstStageTxValidationsForGossipedTransactions(
|
|
1624
1726
|
nextSlotTimestamp,
|
|
@@ -1632,6 +1734,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1632
1734
|
!this.config.disableTransactions,
|
|
1633
1735
|
allowedInSetup,
|
|
1634
1736
|
this.logger.getBindings(),
|
|
1737
|
+
{
|
|
1738
|
+
rollupManaLimit: l1Constants.rollupManaLimit,
|
|
1739
|
+
maxBlockL2Gas: this.config.validateMaxL2BlockGas,
|
|
1740
|
+
maxBlockDAGas: this.config.validateMaxDABlockGas,
|
|
1741
|
+
},
|
|
1635
1742
|
);
|
|
1636
1743
|
}
|
|
1637
1744
|
|
|
@@ -1657,8 +1764,10 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1657
1764
|
|
|
1658
1765
|
// A promise that resolves when all validations have been run
|
|
1659
1766
|
const allValidations = await Promise.all(validationPromises);
|
|
1660
|
-
const
|
|
1661
|
-
if (
|
|
1767
|
+
const failures = allValidations.filter(x => !x.isValid);
|
|
1768
|
+
if (failures.length > 0) {
|
|
1769
|
+
// Pick the most severe failure (lowest tolerance = harshest penalty)
|
|
1770
|
+
const failed = maxBy(failures, f => PeerErrorSeverityByHarshness.indexOf(f.severity))!;
|
|
1662
1771
|
return {
|
|
1663
1772
|
allPassed: false,
|
|
1664
1773
|
failure: {
|
|
@@ -1711,31 +1820,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
1711
1820
|
return PeerErrorSeverity.HighToleranceError;
|
|
1712
1821
|
}
|
|
1713
1822
|
|
|
1714
|
-
/**
|
|
1715
|
-
* Validate a checkpoint attestation.
|
|
1716
|
-
*
|
|
1717
|
-
* @param attestation - The checkpoint attestation to validate.
|
|
1718
|
-
* @returns True if the checkpoint attestation is valid, false otherwise.
|
|
1719
|
-
*/
|
|
1720
|
-
@trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
|
|
1721
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
1722
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1723
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1724
|
-
}))
|
|
1725
|
-
public async validateCheckpointAttestation(
|
|
1726
|
-
peerId: PeerId,
|
|
1727
|
-
attestation: CheckpointAttestation,
|
|
1728
|
-
): Promise<P2PValidationResult> {
|
|
1729
|
-
const result = await this.checkpointAttestationValidator.validate(attestation);
|
|
1730
|
-
|
|
1731
|
-
if (result.result === 'reject') {
|
|
1732
|
-
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1733
|
-
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
return result;
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
1823
|
public getPeerScore(peerId: PeerId): number {
|
|
1740
1824
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
1741
1825
|
}
|
|
@@ -18,6 +18,7 @@ export class PeerManagerMetrics {
|
|
|
18
18
|
private sentGoodbyes: UpDownCounter;
|
|
19
19
|
private receivedGoodbyes: UpDownCounter;
|
|
20
20
|
private peerCount: Gauge;
|
|
21
|
+
private healthyPeerCount: Gauge;
|
|
21
22
|
private lowScoreDisconnects: UpDownCounter;
|
|
22
23
|
private peerConnectionDuration: Histogram;
|
|
23
24
|
|
|
@@ -49,6 +50,7 @@ export class PeerManagerMetrics {
|
|
|
49
50
|
goodbyeReasonAttrs,
|
|
50
51
|
);
|
|
51
52
|
this.peerCount = meter.createGauge(Metrics.PEER_MANAGER_PEER_COUNT);
|
|
53
|
+
this.healthyPeerCount = meter.createGauge(Metrics.PEER_MANAGER_HEALTHY_PEER_COUNT);
|
|
52
54
|
this.lowScoreDisconnects = createUpDownCounterWithDefault(meter, Metrics.PEER_MANAGER_LOW_SCORE_DISCONNECTS, {
|
|
53
55
|
[Attributes.P2P_PEER_SCORE_STATE]: ['Banned', 'Disconnect'],
|
|
54
56
|
});
|
|
@@ -67,6 +69,10 @@ export class PeerManagerMetrics {
|
|
|
67
69
|
this.peerCount.record(count);
|
|
68
70
|
}
|
|
69
71
|
|
|
72
|
+
public recordHealthyPeerCount(count: number) {
|
|
73
|
+
this.healthyPeerCount.record(count);
|
|
74
|
+
}
|
|
75
|
+
|
|
70
76
|
public recordLowScoreDisconnect(scoreState: 'Banned' | 'Disconnect') {
|
|
71
77
|
this.lowScoreDisconnects.add(1, { [Attributes.P2P_PEER_SCORE_STATE]: scoreState });
|
|
72
78
|
}
|
|
@@ -79,6 +85,7 @@ export class PeerManagerMetrics {
|
|
|
79
85
|
const connectedAt = this.peerConnectedAt.get(id.toString());
|
|
80
86
|
if (connectedAt) {
|
|
81
87
|
this.peerConnectionDuration.record(Date.now() - connectedAt);
|
|
88
|
+
this.peerConnectedAt.delete(id.toString());
|
|
82
89
|
}
|
|
83
90
|
}
|
|
84
91
|
}
|
|
@@ -32,7 +32,7 @@ import { PeerScoreState, type PeerScoring } from './peer_scoring.js';
|
|
|
32
32
|
const MAX_DIAL_ATTEMPTS = 3;
|
|
33
33
|
const MAX_CACHED_PEERS = 100;
|
|
34
34
|
const MAX_CACHED_PEER_AGE_MS = 5 * 60 * 1000; // 5 minutes
|
|
35
|
-
const
|
|
35
|
+
const DEFAULT_FAILED_PEER_BAN_TIME_MS = 5 * 60 * 1000; // 5 minutes timeout after failing MAX_DIAL_ATTEMPTS
|
|
36
36
|
const GOODBYE_DIAL_TIMEOUT_MS = 1000;
|
|
37
37
|
const FAILED_AUTH_HANDSHAKE_EXPIRY_MS = 60 * 60 * 1000; // 1 hour
|
|
38
38
|
|
|
@@ -515,7 +515,8 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
515
515
|
...this.peerScoring.getStats(),
|
|
516
516
|
});
|
|
517
517
|
|
|
518
|
-
this.metrics.recordPeerCount(
|
|
518
|
+
this.metrics.recordPeerCount(connections.length);
|
|
519
|
+
this.metrics.recordHealthyPeerCount(healthyConnections.length);
|
|
519
520
|
|
|
520
521
|
// Exit if no peers to connect
|
|
521
522
|
if (peersToConnect <= 0) {
|
|
@@ -775,7 +776,8 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
775
776
|
// Add to timed out peers
|
|
776
777
|
this.timedOutPeers.set(id, {
|
|
777
778
|
peerId: id,
|
|
778
|
-
timeoutUntilMs:
|
|
779
|
+
timeoutUntilMs:
|
|
780
|
+
this.dateProvider.now() + (this.config.peerFailedBanTimeMs ?? DEFAULT_FAILED_PEER_BAN_TIME_MS),
|
|
779
781
|
});
|
|
780
782
|
}
|
|
781
783
|
}
|
|
@@ -937,6 +939,8 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
937
939
|
`Received auth for validator ${sender.toString()} from peer ${peerIdString}, but this validator is already authenticated to peer ${peerForAddress.toString()}`,
|
|
938
940
|
{ ...logData, address: sender.toString() },
|
|
939
941
|
);
|
|
942
|
+
this.markAuthHandshakeFailed(peerId);
|
|
943
|
+
this.markPeerForDisconnect(peerId);
|
|
940
944
|
return;
|
|
941
945
|
}
|
|
942
946
|
|