@aztec/p2p 0.0.1-commit.cd76b27 → 0.0.1-commit.ce4f8c4f2
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 +5 -6
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +28 -26
- package/dest/client/interface.d.ts +6 -13
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +5 -13
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +25 -92
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +4 -5
- package/dest/config.d.ts +33 -15
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +86 -37
- 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 +3 -2
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +2 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +10 -6
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +15 -9
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +48 -11
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +81 -17
- 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 -44
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +5 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +6 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +3 -2
- 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 +196 -151
- 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/aggregate_tx_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/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 +133 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +247 -60
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
- package/dest/msg_validators/tx_validator/index.d.ts +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/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/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +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/dummy_service.d.ts +2 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +1 -4
- package/dest/services/encoding.d.ts +6 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +14 -8
- package/dest/services/libp2p/libp2p_service.d.ts +20 -20
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +221 -143
- 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 +82 -101
- 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 +19 -11
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +52 -15
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- 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 +19 -10
- package/dest/services/service.d.ts +8 -2
- 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/services/tx_provider.d.ts +3 -3
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +4 -4
- package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +1 -2
- package/dest/test-helpers/mock-pubsub.d.ts +7 -3
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +11 -3
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -2
- package/dest/test-helpers/testbench-utils.d.ts +2 -2
- 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 +10 -9
- 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 +45 -45
- package/src/client/interface.ts +5 -19
- package/src/client/p2p_client.ts +26 -122
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +5 -8
- package/src/config.ts +125 -43
- 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 +3 -2
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +2 -2
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +10 -6
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/index.ts +1 -1
- package/src/mem_pools/tx_pool_v2/interfaces.ts +16 -8
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +115 -20
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +17 -2
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +207 -154
- 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 +119 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/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 +394 -78
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
- package/src/services/discv5/discV5_service.ts +4 -2
- package/src/services/dummy_service.ts +1 -5
- package/src/services/encoding.ts +14 -7
- package/src/services/libp2p/libp2p_service.ts +235 -166
- 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 +78 -111
- 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 +68 -24
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/reqresp/reqresp.ts +22 -12
- package/src/services/service.ts +8 -1
- 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/services/tx_provider.ts +2 -2
- package/src/test-helpers/make-test-p2p-clients.ts +1 -3
- package/src/test-helpers/mock-pubsub.ts +12 -6
- package/src/test-helpers/reqresp-nodes.ts +3 -6
- package/src/test-helpers/testbench-utils.ts +30 -4
- package/src/testbench/p2p_client_testbench_worker.ts +7 -12
- 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
|
@@ -370,14 +370,15 @@ function applyDecs2203RFactory() {
|
|
|
370
370
|
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
371
371
|
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
372
372
|
}
|
|
373
|
-
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7,
|
|
373
|
+
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _initProto;
|
|
374
374
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
375
|
+
import { maxBy } from '@aztec/foundation/collection';
|
|
375
376
|
import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
376
377
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
377
378
|
import { Timer } from '@aztec/foundation/timer';
|
|
378
379
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
379
380
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
380
|
-
import { BlockProposal, CheckpointAttestation, CheckpointProposal,
|
|
381
|
+
import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PMessage, PeerErrorSeverity, PeerErrorSeverityByHarshness, TopicType, createTopicString, getTopicsForConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
|
|
381
382
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
382
383
|
import { Tx } from '@aztec/stdlib/tx';
|
|
383
384
|
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
@@ -392,11 +393,12 @@ import { identify } from '@libp2p/identify';
|
|
|
392
393
|
import { TopicValidatorResult } from '@libp2p/interface';
|
|
393
394
|
import { mplex } from '@libp2p/mplex';
|
|
394
395
|
import { tcp } from '@libp2p/tcp';
|
|
396
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
395
397
|
import { ENR } from '@nethermindeth/enr';
|
|
396
398
|
import { createLibp2p } from 'libp2p';
|
|
397
399
|
import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, DoubleSpendTxValidator, FishermanAttestationValidator, getDefaultAllowedSetupFunctions } from '../../msg_validators/index.js';
|
|
398
400
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
399
|
-
import {
|
|
401
|
+
import { createFirstStageTxValidationsForGossipedTransactions, createSecondStageTxValidationsForGossipedTransactions, createTxValidatorForBlockProposalReceivedTxs, createTxValidatorForReqResponseReceivedTxs } from '../../msg_validators/tx_validator/factory.js';
|
|
400
402
|
import { GossipSubEvent } from '../../types/index.js';
|
|
401
403
|
import { convertToMultiaddr } from '../../util.js';
|
|
402
404
|
import { getVersions } from '../../versioning.js';
|
|
@@ -407,8 +409,7 @@ import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring
|
|
|
407
409
|
import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
|
|
408
410
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
409
411
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
410
|
-
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError } from '../reqresp/index.js';
|
|
411
|
-
import { pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
|
|
412
|
+
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError, pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
|
|
412
413
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
413
414
|
import { P2PInstrumentation } from './instrumentation.js';
|
|
414
415
|
_dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
|
|
@@ -432,17 +433,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
432
433
|
[Attributes.TX_HASH]: requestedTxHash.toString()
|
|
433
434
|
})), _dec7 = trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock)=>({
|
|
434
435
|
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString()
|
|
435
|
-
})), _dec8 = trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
|
|
436
|
-
[Attributes.TX_HASH]: tx.getTxHash().toString()
|
|
437
|
-
})), _dec9 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
|
|
438
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
439
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
440
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
|
|
441
436
|
}));
|
|
442
437
|
/**
|
|
443
438
|
* Lib P2P implementation of the P2PService interface.
|
|
444
439
|
*/ export class LibP2PService extends WithTracer {
|
|
445
|
-
clientType;
|
|
446
440
|
config;
|
|
447
441
|
node;
|
|
448
442
|
peerDiscoveryService;
|
|
@@ -494,16 +488,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
494
488
|
_dec7,
|
|
495
489
|
2,
|
|
496
490
|
"validateRequestedBlock"
|
|
497
|
-
],
|
|
498
|
-
[
|
|
499
|
-
_dec8,
|
|
500
|
-
2,
|
|
501
|
-
"validatePropagatedTx"
|
|
502
|
-
],
|
|
503
|
-
[
|
|
504
|
-
_dec9,
|
|
505
|
-
2,
|
|
506
|
-
"validateCheckpointAttestation"
|
|
507
491
|
]
|
|
508
492
|
], []));
|
|
509
493
|
}
|
|
@@ -529,11 +513,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
529
513
|
* @returns The attestations for the checkpoint, if any.
|
|
530
514
|
*/ checkpointReceivedCallback;
|
|
531
515
|
gossipSubEventHandler;
|
|
516
|
+
ipChangedHandler;
|
|
517
|
+
/** Discovered public IP address (set when queryForIp is enabled and no static IP was configured). */ discoveredP2pIp;
|
|
532
518
|
instrumentation;
|
|
533
519
|
telemetry;
|
|
534
520
|
logger;
|
|
535
|
-
constructor(
|
|
536
|
-
super(telemetry, 'LibP2PService'), this.
|
|
521
|
+
constructor(config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
|
|
522
|
+
super(telemetry, 'LibP2PService'), this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.msgIdSeenValidators = (_initProto(this), {}), this.protocolVersion = '', this.topicStrings = {};
|
|
537
523
|
this.telemetry = telemetry;
|
|
538
524
|
// Create child logger with fisherman prefix if in fisherman mode
|
|
539
525
|
this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
|
|
@@ -549,19 +535,19 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
549
535
|
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
550
536
|
this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
|
|
551
537
|
this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
|
|
552
|
-
|
|
553
|
-
txsPermitted: !config.disableTransactions
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
538
|
+
const proposalValidatorOpts = {
|
|
539
|
+
txsPermitted: !config.disableTransactions,
|
|
540
|
+
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint
|
|
541
|
+
};
|
|
542
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
|
|
543
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
|
|
558
544
|
this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new CheckpointAttestationValidator(epochCache);
|
|
559
545
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
560
546
|
this.blockReceivedCallback = async (block)=>{
|
|
561
|
-
this.logger.
|
|
547
|
+
this.logger.warn(`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`, {
|
|
562
548
|
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier()
|
|
563
549
|
});
|
|
564
|
-
return
|
|
550
|
+
return true;
|
|
565
551
|
};
|
|
566
552
|
this.checkpointReceivedCallback = (checkpoint)=>{
|
|
567
553
|
this.logger.debug(`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`);
|
|
@@ -576,7 +562,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
576
562
|
* @param config - The configuration to use when creating the service.
|
|
577
563
|
* @param txPool - The transaction pool to be accessed by the service.
|
|
578
564
|
* @returns The new service.
|
|
579
|
-
*/ static async new(
|
|
565
|
+
*/ static async new(config, peerId, deps) {
|
|
580
566
|
const { worldStateSynchronizer, epochCache, l2BlockSource, mempools, proofVerifier, peerStore, telemetry, logger, packageVersion } = deps;
|
|
581
567
|
const { p2pPort, maxPeerCount, listenAddress } = config;
|
|
582
568
|
const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
|
|
@@ -726,7 +712,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
726
712
|
})
|
|
727
713
|
}),
|
|
728
714
|
components: (components)=>({
|
|
729
|
-
connectionManager: components.connectionManager
|
|
715
|
+
connectionManager: components.connectionManager,
|
|
716
|
+
addressManager: components.addressManager
|
|
730
717
|
})
|
|
731
718
|
},
|
|
732
719
|
logger: createLibp2pComponentLogger(logger.module, logger.getBindings())
|
|
@@ -741,7 +728,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
741
728
|
// Note: positive topic scores can offset penalties, so alignment is best-effort.
|
|
742
729
|
node.services.pubsub.score.params.appSpecificWeight = APP_SPECIFIC_WEIGHT;
|
|
743
730
|
node.services.pubsub.score.params.appSpecificScore = (peerId)=>peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
744
|
-
return new LibP2PService(
|
|
731
|
+
return new LibP2PService(config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
|
|
745
732
|
}
|
|
746
733
|
/**
|
|
747
734
|
* Starts the LibP2P service.
|
|
@@ -753,10 +740,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
753
740
|
}
|
|
754
741
|
// Get listen & announce addresses for logging
|
|
755
742
|
const { p2pIp, p2pPort } = this.config;
|
|
756
|
-
if (!p2pIp) {
|
|
743
|
+
if (!p2pIp && !this.config.queryForIp) {
|
|
757
744
|
throw new Error('Announce address not provided.');
|
|
758
745
|
}
|
|
759
|
-
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
746
|
+
const announceTcpMultiaddr = p2pIp ? convertToMultiaddr(p2pIp, p2pPort, 'tcp') : undefined;
|
|
760
747
|
// Create request response protocol handlers
|
|
761
748
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
762
749
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
@@ -786,7 +773,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
786
773
|
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
787
774
|
await this.node.start();
|
|
788
775
|
// Subscribe to standard GossipSub topics by default
|
|
789
|
-
for (const topic of
|
|
776
|
+
for (const topic of getTopicsForConfig(this.config.disableTransactions)){
|
|
790
777
|
this.subscribeToTopic(this.topicStrings[topic]);
|
|
791
778
|
}
|
|
792
779
|
// add GossipSub listener
|
|
@@ -795,6 +782,29 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
795
782
|
if (!this.config.p2pDiscoveryDisabled) {
|
|
796
783
|
await this.peerDiscoveryService.start();
|
|
797
784
|
}
|
|
785
|
+
// When queryForIp is enabled and no static IP was configured, bridge discv5 IP discovery to libp2p.
|
|
786
|
+
// Discv5 discovers our public IP via peer WHOAREYOU exchanges (enrUpdate=true) and emits 'ip:changed'.
|
|
787
|
+
// We confirm the discovered address in the libp2p AddressManager so it appears in getMultiaddrs()
|
|
788
|
+
// and is pushed to all connected peers via the identify protocol.
|
|
789
|
+
if (this.config.queryForIp && !p2pIp) {
|
|
790
|
+
this.ipChangedHandler = (ip)=>{
|
|
791
|
+
const addressManager = this.node.services.components.addressManager;
|
|
792
|
+
const newAddr = multiaddr(convertToMultiaddr(ip, this.config.p2pPort, 'tcp'));
|
|
793
|
+
// Remove old discovered IP if one exists
|
|
794
|
+
if (this.discoveredP2pIp) {
|
|
795
|
+
const oldAddr = multiaddr(convertToMultiaddr(this.discoveredP2pIp, this.config.p2pPort, 'tcp'));
|
|
796
|
+
addressManager.removeObservedAddr(oldAddr);
|
|
797
|
+
}
|
|
798
|
+
addressManager.addObservedAddr(newAddr);
|
|
799
|
+
addressManager.confirmObservedAddr(newAddr);
|
|
800
|
+
// Store discovered IP
|
|
801
|
+
this.discoveredP2pIp = ip;
|
|
802
|
+
this.logger.info('Public IP discovered via discv5', {
|
|
803
|
+
ip
|
|
804
|
+
});
|
|
805
|
+
};
|
|
806
|
+
this.peerDiscoveryService.on('ip:changed', this.ipChangedHandler);
|
|
807
|
+
}
|
|
798
808
|
this.discoveryRunningPromise = new RunningPromise(async ()=>{
|
|
799
809
|
await this.peerManager.heartbeat();
|
|
800
810
|
}, this.logger, this.config.peerCheckIntervalMS);
|
|
@@ -802,7 +812,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
802
812
|
this.logger.info(`Started P2P service`, {
|
|
803
813
|
listen: this.config.listenAddress,
|
|
804
814
|
port: this.config.p2pPort,
|
|
805
|
-
announce: announceTcpMultiaddr,
|
|
815
|
+
announce: announceTcpMultiaddr ?? 'pending (queryForIp=true)',
|
|
806
816
|
peerId: this.node.peerId.toString()
|
|
807
817
|
});
|
|
808
818
|
}
|
|
@@ -812,6 +822,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
812
822
|
*/ async stop() {
|
|
813
823
|
// Remove gossip sub listener
|
|
814
824
|
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
825
|
+
// Remove ip:changed listener if registered
|
|
826
|
+
if (this.ipChangedHandler) {
|
|
827
|
+
this.peerDiscoveryService.off('ip:changed', this.ipChangedHandler);
|
|
828
|
+
this.ipChangedHandler = undefined;
|
|
829
|
+
}
|
|
815
830
|
// Stop peer manager
|
|
816
831
|
this.logger.debug('Stopping peer manager...');
|
|
817
832
|
await this.peerManager.stop();
|
|
@@ -935,6 +950,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
935
950
|
if (!validator || !validator.addMessage(msgId)) {
|
|
936
951
|
this.instrumentation.incMessagePrevalidationStatus(false, topicType);
|
|
937
952
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
953
|
+
if (topicType === TopicType.tx) {
|
|
954
|
+
this.logger.verbose(`Ignoring already-seen tx gossip message`, {
|
|
955
|
+
msgId,
|
|
956
|
+
source: source.toString()
|
|
957
|
+
});
|
|
958
|
+
}
|
|
938
959
|
return {
|
|
939
960
|
result: false,
|
|
940
961
|
topicType
|
|
@@ -995,9 +1016,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
995
1016
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
996
1017
|
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
997
1018
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
998
|
-
|
|
999
|
-
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
1000
|
-
}
|
|
1019
|
+
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
1001
1020
|
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
1002
1021
|
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
1003
1022
|
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
@@ -1042,39 +1061,119 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1042
1061
|
return;
|
|
1043
1062
|
}
|
|
1044
1063
|
async validateReceivedMessage(validationFunc, msgId, source, topicType) {
|
|
1064
|
+
// Default to reject result with a penalty if validation function throws an error
|
|
1045
1065
|
let resultAndObj = {
|
|
1046
|
-
result: TopicValidatorResult.Reject
|
|
1066
|
+
result: TopicValidatorResult.Reject,
|
|
1067
|
+
severity: PeerErrorSeverity.MidToleranceError
|
|
1047
1068
|
};
|
|
1048
1069
|
const timer = new Timer();
|
|
1049
1070
|
try {
|
|
1050
1071
|
resultAndObj = await validationFunc();
|
|
1051
1072
|
} catch (err) {
|
|
1052
|
-
this.
|
|
1053
|
-
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
1073
|
+
this.logger.error(`Error validating gossipsub message`, err, {
|
|
1054
1074
|
msgId,
|
|
1055
1075
|
source: source.toString(),
|
|
1056
1076
|
topicType
|
|
1057
1077
|
});
|
|
1058
1078
|
}
|
|
1059
1079
|
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
1080
|
+
this.logger.debug(`Message ${topicType} accepted by validator`, {
|
|
1081
|
+
msgId,
|
|
1082
|
+
source: source.toString(),
|
|
1083
|
+
topicType
|
|
1084
|
+
});
|
|
1060
1085
|
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
1086
|
+
} else if (resultAndObj.result === TopicValidatorResult.Reject) {
|
|
1087
|
+
this.logger.warn(`Message ${topicType} rejected by validator with severity ${resultAndObj.severity}`, {
|
|
1088
|
+
msgId,
|
|
1089
|
+
source: source.toString(),
|
|
1090
|
+
topicType,
|
|
1091
|
+
severity: resultAndObj.severity
|
|
1092
|
+
});
|
|
1093
|
+
this.peerManager.penalizePeer(source, resultAndObj.severity);
|
|
1094
|
+
} else {
|
|
1095
|
+
this.logger.trace(`Message ${topicType} ignored by validator`, {
|
|
1096
|
+
msgId,
|
|
1097
|
+
source: source.toString(),
|
|
1098
|
+
topicType
|
|
1099
|
+
});
|
|
1061
1100
|
}
|
|
1062
1101
|
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
1063
1102
|
return resultAndObj;
|
|
1064
1103
|
}
|
|
1104
|
+
tryDeserialize(deserializeFunc, msgId, source) {
|
|
1105
|
+
try {
|
|
1106
|
+
return deserializeFunc();
|
|
1107
|
+
} catch (err) {
|
|
1108
|
+
this.logger.warn(`Failed to deserialize gossipsub message from buffer`, {
|
|
1109
|
+
err,
|
|
1110
|
+
msgId,
|
|
1111
|
+
source: source.toString()
|
|
1112
|
+
});
|
|
1113
|
+
return undefined;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1065
1116
|
async handleGossipedTx(payloadData, msgId, source) {
|
|
1066
1117
|
const validationFunc = async ()=>{
|
|
1067
|
-
const tx = Tx.fromBuffer(payloadData);
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1118
|
+
const tx = this.tryDeserialize(()=>Tx.fromBuffer(payloadData), msgId, source);
|
|
1119
|
+
if (!tx) {
|
|
1120
|
+
return {
|
|
1121
|
+
result: TopicValidatorResult.Reject,
|
|
1122
|
+
severity: PeerErrorSeverity.LowToleranceError
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1126
|
+
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1127
|
+
// Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
|
|
1128
|
+
const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1129
|
+
const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
|
|
1130
|
+
if (!firstStageOutcome.allPassed) {
|
|
1131
|
+
const { name } = firstStageOutcome.failure;
|
|
1132
|
+
let { severity } = firstStageOutcome.failure;
|
|
1133
|
+
// Double spend validator has a special case handler. We perform more detailed examination
|
|
1134
|
+
// as to how recently the nullifier was entered into the tree and if the transaction should
|
|
1135
|
+
// have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
|
|
1136
|
+
if (name === 'doubleSpendValidator') {
|
|
1137
|
+
const txBlockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1138
|
+
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1139
|
+
}
|
|
1140
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
|
|
1141
|
+
validator: name,
|
|
1142
|
+
severity,
|
|
1143
|
+
source: source.toString()
|
|
1072
1144
|
});
|
|
1073
1145
|
return {
|
|
1074
|
-
result: TopicValidatorResult.Reject
|
|
1146
|
+
result: TopicValidatorResult.Reject,
|
|
1147
|
+
severity
|
|
1075
1148
|
};
|
|
1076
1149
|
}
|
|
1077
|
-
//
|
|
1150
|
+
// Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
|
|
1151
|
+
const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
|
|
1152
|
+
if (canAdd === 'ignored') {
|
|
1153
|
+
this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
|
|
1154
|
+
source: source.toString()
|
|
1155
|
+
});
|
|
1156
|
+
return {
|
|
1157
|
+
result: TopicValidatorResult.Ignore,
|
|
1158
|
+
obj: tx
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
// Stage 2: expensive proof verification
|
|
1162
|
+
const secondStageValidators = this.createSecondStageMessageValidators();
|
|
1163
|
+
const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
|
|
1164
|
+
if (!secondStageOutcome.allPassed) {
|
|
1165
|
+
const { severity, name } = secondStageOutcome.failure;
|
|
1166
|
+
this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
|
|
1167
|
+
validator: name,
|
|
1168
|
+
severity,
|
|
1169
|
+
source: source.toString()
|
|
1170
|
+
});
|
|
1171
|
+
return {
|
|
1172
|
+
result: TopicValidatorResult.Reject,
|
|
1173
|
+
severity
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
// Pool add: persist the tx
|
|
1078
1177
|
const txHash = tx.getTxHash();
|
|
1079
1178
|
const addResult = await this.mempools.txPool.addPendingTxs([
|
|
1080
1179
|
tx
|
|
@@ -1083,8 +1182,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1083
1182
|
});
|
|
1084
1183
|
const wasAccepted = addResult.accepted.some((h)=>h.equals(txHash));
|
|
1085
1184
|
const wasIgnored = addResult.ignored.some((h)=>h.equals(txHash));
|
|
1086
|
-
this.logger.
|
|
1087
|
-
isValid,
|
|
1185
|
+
this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
|
|
1088
1186
|
wasAccepted,
|
|
1089
1187
|
wasIgnored,
|
|
1090
1188
|
[Attributes.P2P_ID]: source.toString()
|
|
@@ -1100,8 +1198,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1100
1198
|
obj: tx
|
|
1101
1199
|
};
|
|
1102
1200
|
} else {
|
|
1201
|
+
this.logger.warn(`Gossiped tx ${txHash.toString()} unexpectedly rejected by pool`, {
|
|
1202
|
+
source: source.toString(),
|
|
1203
|
+
txHash: txHash.toString()
|
|
1204
|
+
});
|
|
1103
1205
|
return {
|
|
1104
|
-
result: TopicValidatorResult.Reject
|
|
1206
|
+
result: TopicValidatorResult.Reject,
|
|
1207
|
+
severity: PeerErrorSeverity.HighToleranceError
|
|
1105
1208
|
};
|
|
1106
1209
|
}
|
|
1107
1210
|
};
|
|
@@ -1122,7 +1225,16 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1122
1225
|
* Process a checkpoint attestation from a peer.
|
|
1123
1226
|
* Validates the attestation and adds it to the pool.
|
|
1124
1227
|
*/ async processCheckpointAttestationFromPeer(payloadData, msgId, source) {
|
|
1125
|
-
const { result, obj: attestation } = await this.validateReceivedMessage(()=>
|
|
1228
|
+
const { result, obj: attestation } = await this.validateReceivedMessage(()=>{
|
|
1229
|
+
const attestation = this.tryDeserialize(()=>CheckpointAttestation.fromBuffer(payloadData), msgId, source);
|
|
1230
|
+
if (!attestation) {
|
|
1231
|
+
return Promise.resolve({
|
|
1232
|
+
result: TopicValidatorResult.Reject,
|
|
1233
|
+
severity: PeerErrorSeverity.LowToleranceError
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
return this.validateAndStoreCheckpointAttestation(source, attestation);
|
|
1237
|
+
}, msgId, source, TopicType.checkpoint_attestation);
|
|
1126
1238
|
if (result !== TopicValidatorResult.Accept || !attestation) {
|
|
1127
1239
|
return;
|
|
1128
1240
|
}
|
|
@@ -1137,9 +1249,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1137
1249
|
const validationResult = await this.checkpointAttestationValidator.validate(attestation);
|
|
1138
1250
|
if (validationResult.result === 'reject') {
|
|
1139
1251
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1140
|
-
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1141
1252
|
return {
|
|
1142
|
-
result: TopicValidatorResult.Reject
|
|
1253
|
+
result: TopicValidatorResult.Reject,
|
|
1254
|
+
severity: validationResult.severity
|
|
1143
1255
|
};
|
|
1144
1256
|
}
|
|
1145
1257
|
if (validationResult.result === 'ignore') {
|
|
@@ -1166,9 +1278,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1166
1278
|
obj: attestation
|
|
1167
1279
|
};
|
|
1168
1280
|
}
|
|
1169
|
-
// Could not add (cap reached for signer),
|
|
1281
|
+
// Could not add (cap reached for signer), penalize and do not re-broadcast
|
|
1170
1282
|
if (!added) {
|
|
1171
|
-
this.logger.warn(`
|
|
1283
|
+
this.logger.warn(`Rejecting checkpoint attestation due to cap`, {
|
|
1172
1284
|
slot: slot.toString(),
|
|
1173
1285
|
archive: attestation.archive.toString(),
|
|
1174
1286
|
source: peerId.toString(),
|
|
@@ -1176,8 +1288,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1176
1288
|
count
|
|
1177
1289
|
});
|
|
1178
1290
|
return {
|
|
1179
|
-
result: TopicValidatorResult.
|
|
1180
|
-
|
|
1291
|
+
result: TopicValidatorResult.Reject,
|
|
1292
|
+
severity: PeerErrorSeverity.HighToleranceError
|
|
1181
1293
|
};
|
|
1182
1294
|
}
|
|
1183
1295
|
// Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
|
|
@@ -1215,9 +1327,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1215
1327
|
const validationResult = await this.blockProposalValidator.validate(block);
|
|
1216
1328
|
if (validationResult.result === 'reject') {
|
|
1217
1329
|
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1218
|
-
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1219
1330
|
return {
|
|
1220
|
-
result: TopicValidatorResult.Reject
|
|
1331
|
+
result: TopicValidatorResult.Reject,
|
|
1332
|
+
severity: validationResult.severity
|
|
1221
1333
|
};
|
|
1222
1334
|
}
|
|
1223
1335
|
if (validationResult.result === 'ignore') {
|
|
@@ -1247,7 +1359,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1247
1359
|
}
|
|
1248
1360
|
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1249
1361
|
if (!added) {
|
|
1250
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1251
1362
|
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1252
1363
|
...block.toBlockInfo(),
|
|
1253
1364
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
@@ -1259,7 +1370,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1259
1370
|
result: TopicValidatorResult.Reject,
|
|
1260
1371
|
metadata: {
|
|
1261
1372
|
isEquivocated
|
|
1262
|
-
}
|
|
1373
|
+
},
|
|
1374
|
+
severity: PeerErrorSeverity.HighToleranceError
|
|
1263
1375
|
};
|
|
1264
1376
|
}
|
|
1265
1377
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1308,7 +1420,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1308
1420
|
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1309
1421
|
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1310
1422
|
if (!isValid) {
|
|
1311
|
-
this.logger.
|
|
1423
|
+
this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1312
1424
|
}
|
|
1313
1425
|
}
|
|
1314
1426
|
/**
|
|
@@ -1333,9 +1445,9 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1333
1445
|
const validationResult = await this.checkpointProposalValidator.validate(checkpoint);
|
|
1334
1446
|
if (validationResult.result === 'reject') {
|
|
1335
1447
|
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1336
|
-
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1337
1448
|
return {
|
|
1338
|
-
result: TopicValidatorResult.Reject
|
|
1449
|
+
result: TopicValidatorResult.Reject,
|
|
1450
|
+
severity: validationResult.severity
|
|
1339
1451
|
};
|
|
1340
1452
|
}
|
|
1341
1453
|
if (validationResult.result === 'ignore') {
|
|
@@ -1352,18 +1464,20 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1352
1464
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1353
1465
|
[Attributes.P2P_ID]: peerId.toString()
|
|
1354
1466
|
});
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1467
|
+
const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1468
|
+
const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
|
|
1469
|
+
if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1357
1470
|
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1358
1471
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1359
1472
|
[Attributes.P2P_ID]: peerId.toString(),
|
|
1360
1473
|
isEquivocated,
|
|
1361
|
-
result
|
|
1474
|
+
result: blockProposalResult.result
|
|
1362
1475
|
});
|
|
1363
1476
|
return {
|
|
1364
|
-
result: TopicValidatorResult.Reject
|
|
1477
|
+
result: TopicValidatorResult.Reject,
|
|
1478
|
+
severity: 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError
|
|
1365
1479
|
};
|
|
1366
|
-
} else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1480
|
+
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1367
1481
|
processBlock = true;
|
|
1368
1482
|
}
|
|
1369
1483
|
}
|
|
@@ -1390,7 +1504,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1390
1504
|
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1391
1505
|
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1392
1506
|
if (!added) {
|
|
1393
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1394
1507
|
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1395
1508
|
...checkpoint.toCheckpointInfo(),
|
|
1396
1509
|
count,
|
|
@@ -1402,7 +1515,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1402
1515
|
metadata: {
|
|
1403
1516
|
isEquivocated,
|
|
1404
1517
|
processBlock
|
|
1405
|
-
}
|
|
1518
|
+
},
|
|
1519
|
+
severity: PeerErrorSeverity.HighToleranceError
|
|
1406
1520
|
};
|
|
1407
1521
|
}
|
|
1408
1522
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
@@ -1626,33 +1740,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1626
1740
|
}
|
|
1627
1741
|
}
|
|
1628
1742
|
createRequestedTxValidator() {
|
|
1629
|
-
return
|
|
1743
|
+
return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
|
|
1630
1744
|
l1ChainId: this.config.l1ChainId,
|
|
1631
1745
|
rollupVersion: this.config.rollupVersion
|
|
1632
1746
|
});
|
|
1633
1747
|
}
|
|
1634
|
-
async validatePropagatedTx(tx, peerId) {
|
|
1635
|
-
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1636
|
-
// We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
|
|
1637
|
-
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1638
|
-
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1639
|
-
for (const validator of messageValidators){
|
|
1640
|
-
const outcome = await this.runValidations(tx, validator);
|
|
1641
|
-
if (outcome.allPassed) {
|
|
1642
|
-
continue;
|
|
1643
|
-
}
|
|
1644
|
-
const { name } = outcome.failure;
|
|
1645
|
-
let { severity } = outcome.failure;
|
|
1646
|
-
// Double spend validator has a special case handler
|
|
1647
|
-
if (name === 'doubleSpendValidator') {
|
|
1648
|
-
const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
|
|
1649
|
-
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1650
|
-
}
|
|
1651
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
1652
|
-
return false;
|
|
1653
|
-
}
|
|
1654
|
-
return true;
|
|
1655
|
-
}
|
|
1656
1748
|
async getGasFees(blockNumber) {
|
|
1657
1749
|
if (blockNumber === this.feesCache?.blockNumber) {
|
|
1658
1750
|
return this.feesCache.gasFees;
|
|
@@ -1679,38 +1771,35 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1679
1771
|
peerScoring: this.peerManager
|
|
1680
1772
|
};
|
|
1681
1773
|
}
|
|
1682
|
-
async
|
|
1683
|
-
const
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
await Promise.all(txs.map(async (tx)=>{
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
if (!outcome.allPassed) {
|
|
1691
|
-
throw new Error('Invalid tx detected', {
|
|
1692
|
-
cause: {
|
|
1693
|
-
outcome
|
|
1694
|
-
}
|
|
1695
|
-
});
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1774
|
+
async validateTxsReceivedInBlockProposal(txs) {
|
|
1775
|
+
const validator = createTxValidatorForBlockProposalReceivedTxs(this.proofVerifier, {
|
|
1776
|
+
l1ChainId: this.config.l1ChainId,
|
|
1777
|
+
rollupVersion: this.config.rollupVersion
|
|
1778
|
+
}, this.logger.getBindings());
|
|
1779
|
+
const results = await Promise.all(txs.map(async (tx)=>{
|
|
1780
|
+
const result = await validator.validateTx(tx);
|
|
1781
|
+
return result.result !== 'invalid';
|
|
1698
1782
|
}));
|
|
1783
|
+
if (results.some((value)=>value === false)) {
|
|
1784
|
+
throw new Error('Invalid tx detected');
|
|
1785
|
+
}
|
|
1699
1786
|
}
|
|
1700
|
-
/**
|
|
1701
|
-
* Create message validators for the given block number and timestamp.
|
|
1702
|
-
*
|
|
1703
|
-
* Each validator is a pair of a validator and a severity.
|
|
1704
|
-
* If a validator fails, the peer is penalized with the severity of the validator.
|
|
1705
|
-
*
|
|
1706
|
-
* @param currentBlockNumber - The current synced block number.
|
|
1707
|
-
* @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
|
|
1708
|
-
* @returns The message validators.
|
|
1709
|
-
*/ async createMessageValidators(currentBlockNumber, nextSlotTimestamp) {
|
|
1787
|
+
/** Creates the first stage (fast) validators for gossiped transactions. */ async createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp) {
|
|
1710
1788
|
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
1711
|
-
const allowedInSetup =
|
|
1712
|
-
|
|
1713
|
-
|
|
1789
|
+
const allowedInSetup = [
|
|
1790
|
+
...await getDefaultAllowedSetupFunctions(),
|
|
1791
|
+
...this.config.txPublicSetupAllowListExtend ?? []
|
|
1792
|
+
];
|
|
1793
|
+
const blockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1794
|
+
const l1Constants = await this.archiver.getL1Constants();
|
|
1795
|
+
return createFirstStageTxValidationsForGossipedTransactions(nextSlotTimestamp, blockNumber, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings(), {
|
|
1796
|
+
rollupManaLimit: l1Constants.rollupManaLimit,
|
|
1797
|
+
maxBlockL2Gas: this.config.validateMaxL2BlockGas,
|
|
1798
|
+
maxBlockDAGas: this.config.validateMaxDABlockGas
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1801
|
+
/** Creates the second stage (expensive proof verification) validators for gossiped transactions. */ createSecondStageMessageValidators() {
|
|
1802
|
+
return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
|
|
1714
1803
|
}
|
|
1715
1804
|
/**
|
|
1716
1805
|
* Run validations on a tx.
|
|
@@ -1728,8 +1817,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1728
1817
|
});
|
|
1729
1818
|
// A promise that resolves when all validations have been run
|
|
1730
1819
|
const allValidations = await Promise.all(validationPromises);
|
|
1731
|
-
const
|
|
1732
|
-
if (
|
|
1820
|
+
const failures = allValidations.filter((x)=>!x.isValid);
|
|
1821
|
+
if (failures.length > 0) {
|
|
1822
|
+
// Pick the most severe failure (lowest tolerance = harshest penalty)
|
|
1823
|
+
const failed = maxBy(failures, (f)=>PeerErrorSeverityByHarshness.indexOf(f.severity));
|
|
1733
1824
|
return {
|
|
1734
1825
|
allPassed: false,
|
|
1735
1826
|
failure: {
|
|
@@ -1776,19 +1867,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1776
1867
|
}
|
|
1777
1868
|
return PeerErrorSeverity.HighToleranceError;
|
|
1778
1869
|
}
|
|
1779
|
-
/**
|
|
1780
|
-
* Validate a checkpoint attestation.
|
|
1781
|
-
*
|
|
1782
|
-
* @param attestation - The checkpoint attestation to validate.
|
|
1783
|
-
* @returns True if the checkpoint attestation is valid, false otherwise.
|
|
1784
|
-
*/ async validateCheckpointAttestation(peerId, attestation) {
|
|
1785
|
-
const result = await this.checkpointAttestationValidator.validate(attestation);
|
|
1786
|
-
if (result.result === 'reject') {
|
|
1787
|
-
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1788
|
-
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1789
|
-
}
|
|
1790
|
-
return result;
|
|
1791
|
-
}
|
|
1792
1870
|
getPeerScore(peerId) {
|
|
1793
1871
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
1794
1872
|
}
|