@aztec/p2p 0.0.0-test.0 → 0.0.1-commit.023c3e5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.d.ts +4 -3
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +26 -13
- package/dest/client/factory.d.ts +15 -5
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +61 -25
- package/dest/client/index.d.ts +2 -1
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +1 -0
- package/dest/client/interface.d.ts +170 -0
- package/dest/client/interface.d.ts.map +1 -0
- package/dest/client/interface.js +9 -0
- package/dest/client/p2p_client.d.ts +75 -193
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +765 -229
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +2 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +1 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +305 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +73 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +1 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +8 -0
- package/dest/config.d.ts +154 -125
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +182 -34
- package/dest/enr/generate-enr.d.ts +11 -3
- package/dest/enr/generate-enr.d.ts.map +1 -1
- package/dest/enr/generate-enr.js +27 -5
- package/dest/enr/index.d.ts +1 -1
- package/dest/errors/attestation-pool.error.d.ts +7 -0
- package/dest/errors/attestation-pool.error.d.ts.map +1 -0
- package/dest/errors/attestation-pool.error.js +12 -0
- package/dest/errors/reqresp.error.d.ts +1 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/index.d.ts +4 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -25
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +299 -174
- package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +29 -11
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +168 -62
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +24 -10
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +133 -82
- package/dest/mem_pools/attestation_pool/mocks.d.ts +234 -11
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +19 -21
- package/dest/mem_pools/index.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts +16 -12
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +56 -41
- package/dest/mem_pools/interface.d.ts +3 -4
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +75 -16
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +493 -142
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +32 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +112 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +157 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +52 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +122 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +78 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
- package/dest/mem_pools/tx_pool/index.d.ts +1 -2
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +7 -2
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +72 -11
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +276 -45
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +7 -5
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +79 -10
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +20 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +76 -0
- package/dest/msg_validators/attestation_validator/index.d.ts +2 -1
- package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/index.js +1 -0
- package/dest/msg_validators/clock_tolerance.d.ts +21 -0
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -0
- package/dest/msg_validators/clock_tolerance.js +37 -0
- package/dest/msg_validators/index.d.ts +2 -2
- package/dest/msg_validators/index.d.ts.map +1 -1
- package/dest/msg_validators/index.js +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +10 -0
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -0
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.js +36 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
- package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/index.js +3 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.js +104 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +212 -0
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +3 -0
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +27 -0
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/archive_cache.js +22 -0
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +5 -4
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +7 -6
- package/dest/msg_validators/tx_validator/data_validator.d.ts +3 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +60 -87
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +3 -4
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +24 -29
- package/dest/msg_validators/tx_validator/factory.d.ts +21 -0
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/factory.js +84 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +10 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +20 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +12 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/gas_validator.js +110 -0
- package/dest/msg_validators/tx_validator/index.d.ts +9 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +8 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +10 -5
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +40 -21
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +15 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/phases_validator.js +93 -0
- package/dest/msg_validators/tx_validator/size_validator.d.ts +8 -0
- package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/size_validator.js +23 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts +17 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/test_utils.js +22 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +14 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.js +32 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.js +24 -0
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +8 -7
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/data_store.js +10 -6
- package/dest/services/discv5/discV5_service.d.ts +10 -9
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +64 -37
- package/dest/services/dummy_service.d.ts +66 -11
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +130 -5
- package/dest/services/encoding.d.ts +26 -7
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +75 -6
- package/dest/services/gossipsub/scoring.d.ts +1 -1
- package/dest/services/index.d.ts +5 -1
- package/dest/services/index.d.ts.map +1 -1
- package/dest/services/index.js +4 -0
- package/dest/services/libp2p/instrumentation.d.ts +20 -0
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -0
- package/dest/services/libp2p/instrumentation.js +122 -0
- package/dest/services/libp2p/libp2p_service.d.ts +107 -95
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +1328 -313
- package/dest/services/peer-manager/interface.d.ts +23 -0
- package/dest/services/peer-manager/interface.d.ts.map +1 -0
- package/dest/services/peer-manager/interface.js +1 -0
- package/dest/services/peer-manager/metrics.d.ts +12 -3
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +44 -12
- package/dest/services/peer-manager/peer_manager.d.ts +103 -23
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +551 -82
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +43 -2
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +47 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +566 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +50 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +37 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +151 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +54 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +139 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
- package/dest/services/reqresp/config.d.ts +11 -9
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/config.js +18 -4
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +23 -4
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +73 -10
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +32 -17
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +154 -84
- package/dest/services/reqresp/constants.d.ts +12 -0
- package/dest/services/reqresp/constants.d.ts.map +1 -0
- package/dest/services/reqresp/constants.js +7 -0
- package/dest/services/reqresp/index.d.ts +3 -2
- package/dest/services/reqresp/index.d.ts.map +1 -1
- package/dest/services/reqresp/index.js +2 -1
- package/dest/services/reqresp/interface.d.ts +75 -24
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +46 -27
- package/dest/services/reqresp/metrics.d.ts +6 -5
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +17 -21
- package/dest/services/reqresp/protocols/auth.d.ts +43 -0
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/auth.js +71 -0
- package/dest/services/reqresp/protocols/block.d.ts +6 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +30 -6
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +34 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +87 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +11 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +52 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +59 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +105 -0
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +4 -0
- package/dest/services/reqresp/protocols/block_txs/index.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/index.js +3 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts +3 -5
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/goodbye.js +7 -7
- package/dest/services/reqresp/protocols/index.d.ts +3 -1
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +2 -0
- package/dest/services/reqresp/protocols/ping.d.ts +1 -3
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +40 -7
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +76 -5
- package/dest/services/reqresp/protocols/tx.d.ts +14 -4
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +34 -6
- package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +6 -4
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -2
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +21 -1
- package/dest/services/reqresp/reqresp.d.ts +29 -66
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +753 -248
- package/dest/services/reqresp/status.d.ts +10 -4
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/reqresp/status.js +9 -2
- package/dest/services/service.d.ts +40 -20
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +28 -0
- package/dest/services/tx_collection/config.d.ts.map +1 -0
- package/dest/services/tx_collection/config.js +66 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/fast_tx_collection.js +311 -0
- package/dest/services/tx_collection/index.d.ts +4 -0
- package/dest/services/tx_collection/index.d.ts.map +1 -0
- package/dest/services/tx_collection/index.js +3 -0
- package/dest/services/tx_collection/instrumentation.d.ts +10 -0
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -0
- package/dest/services/tx_collection/instrumentation.js +31 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +48 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
- package/dest/services/tx_collection/proposal_tx_collector.js +50 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/slow_tx_collection.js +177 -0
- package/dest/services/tx_collection/tx_collection.d.ts +110 -0
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_collection.js +128 -0
- package/dest/services/tx_collection/tx_collection_sink.d.ts +30 -0
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_collection_sink.js +111 -0
- package/dest/services/tx_collection/tx_source.d.ts +18 -0
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_source.js +31 -0
- package/dest/services/tx_provider.d.ts +51 -0
- package/dest/services/tx_provider.d.ts.map +1 -0
- package/dest/services/tx_provider.js +219 -0
- package/dest/services/tx_provider_instrumentation.d.ts +16 -0
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -0
- package/dest/services/tx_provider_instrumentation.js +34 -0
- package/dest/test-helpers/generate-peer-id-private-keys.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/index.d.ts +4 -1
- package/dest/test-helpers/index.d.ts.map +1 -1
- package/dest/test-helpers/index.js +3 -0
- package/dest/test-helpers/make-enrs.d.ts +1 -1
- package/dest/test-helpers/make-enrs.d.ts.map +1 -1
- package/dest/test-helpers/make-enrs.js +4 -5
- package/dest/test-helpers/make-test-p2p-clients.d.ts +33 -5
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +86 -16
- package/dest/test-helpers/mock-pubsub.d.ts +59 -0
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -0
- package/dest/test-helpers/mock-pubsub.js +130 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts +12 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -0
- package/dest/test-helpers/mock-tx-helpers.js +19 -0
- package/dest/test-helpers/reqresp-nodes.d.ts +15 -11
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +62 -28
- package/dest/test-helpers/test_tx_provider.d.ts +40 -0
- package/dest/test-helpers/test_tx_provider.d.ts.map +1 -0
- package/dest/test-helpers/test_tx_provider.js +41 -0
- package/dest/test-helpers/testbench-utils.d.ts +158 -0
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
- package/dest/test-helpers/testbench-utils.js +297 -0
- package/dest/testbench/p2p_client_testbench_worker.d.ts +28 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +259 -90
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/parse_log_file.js +4 -4
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/testbench.js +4 -4
- package/dest/testbench/worker_client_manager.d.ts +51 -11
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +232 -53
- package/dest/types/index.d.ts +4 -2
- package/dest/types/index.d.ts.map +1 -1
- package/dest/types/index.js +2 -0
- package/dest/util.d.ts +24 -16
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +75 -69
- package/dest/versioning.d.ts +4 -4
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +8 -3
- package/package.json +32 -27
- package/src/bootstrap/bootstrap.ts +34 -15
- package/src/client/factory.ts +135 -53
- package/src/client/index.ts +1 -0
- package/src/client/interface.ts +213 -0
- package/src/client/p2p_client.ts +476 -383
- package/src/client/test/tx_proposal_collector/README.md +227 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +336 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
- package/src/config.ts +304 -134
- package/src/enr/generate-enr.ts +39 -6
- package/src/errors/attestation-pool.error.ts +13 -0
- package/src/index.ts +4 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +119 -24
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +352 -201
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +233 -72
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +199 -96
- package/src/mem_pools/attestation_pool/mocks.ts +24 -17
- package/src/mem_pools/instrumentation.ts +72 -48
- package/src/mem_pools/interface.ts +2 -4
- package/src/mem_pools/tx_pool/README.md +270 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +580 -143
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +132 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +208 -0
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +162 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +93 -0
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
- package/src/mem_pools/tx_pool/index.ts +0 -1
- package/src/mem_pools/tx_pool/priority.ts +9 -2
- package/src/mem_pools/tx_pool/tx_pool.ts +75 -10
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +225 -36
- package/src/msg_validators/attestation_validator/attestation_validator.ts +72 -14
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +94 -0
- package/src/msg_validators/attestation_validator/index.ts +1 -0
- package/src/msg_validators/clock_tolerance.ts +51 -0
- package/src/msg_validators/index.ts +1 -1
- package/src/msg_validators/msg_seen_validator/msg_seen_validator.ts +36 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
- package/src/msg_validators/proposal_validator/index.ts +3 -0
- package/src/msg_validators/proposal_validator/proposal_validator.ts +92 -0
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +230 -0
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +35 -0
- package/src/msg_validators/tx_validator/archive_cache.ts +28 -0
- package/src/msg_validators/tx_validator/block_header_validator.ts +10 -9
- package/src/msg_validators/tx_validator/data_validator.ts +95 -71
- package/src/msg_validators/tx_validator/double_spend_validator.ts +23 -20
- package/src/msg_validators/tx_validator/factory.ts +151 -0
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +123 -0
- package/src/msg_validators/tx_validator/index.ts +8 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +72 -24
- package/src/msg_validators/tx_validator/phases_validator.ts +118 -0
- package/src/msg_validators/tx_validator/size_validator.ts +22 -0
- package/src/msg_validators/tx_validator/test_utils.ts +43 -0
- package/src/msg_validators/tx_validator/timestamp_validator.ts +52 -0
- package/src/msg_validators/tx_validator/tx_permitted_validator.ts +22 -0
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +14 -8
- package/src/services/data_store.ts +10 -7
- package/src/services/discv5/discV5_service.ts +85 -39
- package/src/services/dummy_service.ts +198 -9
- package/src/services/encoding.ts +82 -6
- package/src/services/index.ts +4 -0
- package/src/services/libp2p/instrumentation.ts +126 -0
- package/src/services/libp2p/libp2p_service.ts +1170 -353
- package/src/services/peer-manager/interface.ts +29 -0
- package/src/services/peer-manager/metrics.ts +55 -12
- package/src/services/peer-manager/peer_manager.ts +657 -80
- package/src/services/peer-manager/peer_scoring.ts +45 -3
- package/src/services/reqresp/batch-tx-requester/README.md +305 -0
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +706 -0
- package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
- package/src/services/reqresp/batch-tx-requester/interface.ts +57 -0
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +209 -0
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +205 -0
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
- package/src/services/reqresp/config.ts +26 -9
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +77 -10
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +166 -95
- package/src/services/reqresp/constants.ts +14 -0
- package/src/services/reqresp/index.ts +2 -0
- package/src/services/reqresp/interface.ts +95 -37
- package/src/services/reqresp/metrics.ts +40 -28
- package/src/services/reqresp/protocols/auth.ts +83 -0
- package/src/services/reqresp/protocols/block.ts +26 -4
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +106 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +67 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +121 -0
- package/src/services/reqresp/protocols/block_txs/index.ts +3 -0
- package/src/services/reqresp/protocols/goodbye.ts +9 -7
- package/src/services/reqresp/protocols/index.ts +2 -0
- package/src/services/reqresp/protocols/status.ts +121 -5
- package/src/services/reqresp/protocols/tx.ts +36 -8
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +12 -3
- package/src/services/reqresp/rate-limiter/rate_limits.ts +21 -1
- package/src/services/reqresp/reqresp.ts +449 -271
- package/src/services/reqresp/status.ts +12 -3
- package/src/services/service.ts +65 -22
- package/src/services/tx_collection/config.ts +98 -0
- package/src/services/tx_collection/fast_tx_collection.ts +364 -0
- package/src/services/tx_collection/index.ts +7 -0
- package/src/services/tx_collection/instrumentation.ts +35 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +114 -0
- package/src/services/tx_collection/slow_tx_collection.ts +233 -0
- package/src/services/tx_collection/tx_collection.ts +216 -0
- package/src/services/tx_collection/tx_collection_sink.ts +129 -0
- package/src/services/tx_collection/tx_source.ts +37 -0
- package/src/services/tx_provider.ts +232 -0
- package/src/services/tx_provider_instrumentation.ts +54 -0
- package/src/test-helpers/index.ts +3 -0
- package/src/test-helpers/make-enrs.ts +4 -5
- package/src/test-helpers/make-test-p2p-clients.ts +111 -21
- package/src/test-helpers/mock-pubsub.ts +188 -0
- package/src/test-helpers/mock-tx-helpers.ts +24 -0
- package/src/test-helpers/reqresp-nodes.ts +87 -36
- package/src/test-helpers/test_tx_provider.ts +64 -0
- package/src/test-helpers/testbench-utils.ts +374 -0
- package/src/testbench/p2p_client_testbench_worker.ts +434 -89
- package/src/testbench/parse_log_file.ts +4 -4
- package/src/testbench/testbench.ts +4 -4
- package/src/testbench/worker_client_manager.ts +315 -59
- package/src/types/index.ts +2 -0
- package/src/util.ts +105 -91
- package/src/versioning.ts +11 -4
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -56
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -141
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -8
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +0 -21
- package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/index.js +0 -1
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -174
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -29
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
}
|
|
1
|
+
import { makeEthSignDigest, tryRecoverAddress } from '@aztec/foundation/crypto/secp256k1-signer';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
7
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
|
-
import {
|
|
4
|
+
import { bufferToHex } from '@aztec/foundation/string';
|
|
5
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
6
|
+
import { peerIdFromString } from '@libp2p/peer-id';
|
|
7
|
+
import { ENR } from '@nethermindeth/enr';
|
|
9
8
|
import { inspect } from 'util';
|
|
10
9
|
import { PeerEvent } from '../../types/index.js';
|
|
11
10
|
import { ReqRespSubProtocol } from '../reqresp/interface.js';
|
|
11
|
+
import { AuthRequest, AuthResponse } from '../reqresp/protocols/auth.js';
|
|
12
12
|
import { GoodByeReason, prettyGoodbyeReason } from '../reqresp/protocols/goodbye.js';
|
|
13
|
+
import { StatusMessage } from '../reqresp/protocols/status.js';
|
|
14
|
+
import { ReqRespStatus } from '../reqresp/status.js';
|
|
13
15
|
import { PeerManagerMetrics } from './metrics.js';
|
|
14
16
|
import { PeerScoreState } from './peer_scoring.js';
|
|
15
17
|
const MAX_DIAL_ATTEMPTS = 3;
|
|
16
18
|
const MAX_CACHED_PEERS = 100;
|
|
17
19
|
const MAX_CACHED_PEER_AGE_MS = 5 * 60 * 1000; // 5 minutes
|
|
18
20
|
const FAILED_PEER_BAN_TIME_MS = 5 * 60 * 1000; // 5 minutes timeout after failing MAX_DIAL_ATTEMPTS
|
|
21
|
+
const GOODBYE_DIAL_TIMEOUT_MS = 1000;
|
|
22
|
+
const FAILED_AUTH_HANDSHAKE_EXPIRY_MS = 60 * 60 * 1000; // 1 hour
|
|
19
23
|
export class PeerManager {
|
|
20
24
|
libP2PNode;
|
|
21
25
|
peerDiscoveryService;
|
|
@@ -23,44 +27,150 @@ export class PeerManager {
|
|
|
23
27
|
logger;
|
|
24
28
|
peerScoring;
|
|
25
29
|
reqresp;
|
|
30
|
+
worldStateSynchronizer;
|
|
31
|
+
protocolVersion;
|
|
32
|
+
epochCache;
|
|
33
|
+
dateProvider;
|
|
26
34
|
cachedPeers;
|
|
27
35
|
heartbeatCounter;
|
|
28
36
|
displayPeerCountsPeerHeartbeat;
|
|
29
37
|
timedOutPeers;
|
|
38
|
+
trustedPeers;
|
|
39
|
+
trustedPeersInitialized;
|
|
40
|
+
privatePeers;
|
|
41
|
+
privatePeersInitialized;
|
|
42
|
+
preferredPeers;
|
|
43
|
+
authenticatedPeerIdToValidatorAddress;
|
|
44
|
+
authenticatedValidatorAddressToPeerId;
|
|
45
|
+
peersToBeDisconnected;
|
|
46
|
+
failedAuthHandshakes;
|
|
47
|
+
validatorAddresses;
|
|
48
|
+
initializedPreferredPeers;
|
|
30
49
|
metrics;
|
|
31
|
-
|
|
32
|
-
constructor(libP2PNode, peerDiscoveryService, config, telemetryClient, logger = createLogger('p2p:peer-manager'), peerScoring, reqresp){
|
|
50
|
+
handlers;
|
|
51
|
+
constructor(libP2PNode, peerDiscoveryService, config, telemetryClient, logger = createLogger('p2p:peer-manager'), peerScoring, reqresp, worldStateSynchronizer, protocolVersion, epochCache, dateProvider = new DateProvider()){
|
|
33
52
|
this.libP2PNode = libP2PNode;
|
|
34
53
|
this.peerDiscoveryService = peerDiscoveryService;
|
|
35
54
|
this.config = config;
|
|
36
55
|
this.logger = logger;
|
|
37
56
|
this.peerScoring = peerScoring;
|
|
38
57
|
this.reqresp = reqresp;
|
|
58
|
+
this.worldStateSynchronizer = worldStateSynchronizer;
|
|
59
|
+
this.protocolVersion = protocolVersion;
|
|
60
|
+
this.epochCache = epochCache;
|
|
61
|
+
this.dateProvider = dateProvider;
|
|
39
62
|
this.cachedPeers = new Map();
|
|
40
63
|
this.heartbeatCounter = 0;
|
|
41
64
|
this.displayPeerCountsPeerHeartbeat = 0;
|
|
42
65
|
this.timedOutPeers = new Map();
|
|
66
|
+
this.trustedPeers = new Set();
|
|
67
|
+
this.trustedPeersInitialized = false;
|
|
68
|
+
this.privatePeers = new Set();
|
|
69
|
+
this.privatePeersInitialized = false;
|
|
70
|
+
this.preferredPeers = new Set();
|
|
71
|
+
this.authenticatedPeerIdToValidatorAddress = new Map();
|
|
72
|
+
this.authenticatedValidatorAddressToPeerId = new Map();
|
|
73
|
+
this.peersToBeDisconnected = new Set();
|
|
74
|
+
this.failedAuthHandshakes = new Map();
|
|
75
|
+
this.validatorAddresses = [];
|
|
76
|
+
this.initializedPreferredPeers = false;
|
|
77
|
+
if (this.config.p2pDisableStatusHandshake && this.config.p2pAllowOnlyValidators) {
|
|
78
|
+
throw new Error('Status handshake disabled but is required to allow only validators to connect.');
|
|
79
|
+
}
|
|
43
80
|
this.metrics = new PeerManagerMetrics(telemetryClient, 'PeerManager');
|
|
81
|
+
// Handle Discovered peers
|
|
82
|
+
this.handlers = {
|
|
83
|
+
handleConnectedPeerEvent: this.handleConnectedPeerEvent.bind(this),
|
|
84
|
+
handleDisconnectedPeerEvent: this.handleDisconnectedPeerEvent.bind(this),
|
|
85
|
+
handleDiscoveredPeer: (enr)=>this.handleDiscoveredPeer(enr).catch((e)=>this.logger.error('Error handling discovered peer', e))
|
|
86
|
+
};
|
|
44
87
|
// Handle new established connections
|
|
45
|
-
this.libP2PNode.addEventListener(PeerEvent.CONNECTED, this.handleConnectedPeerEvent
|
|
88
|
+
this.libP2PNode.addEventListener(PeerEvent.CONNECTED, this.handlers.handleConnectedPeerEvent);
|
|
46
89
|
// Handle lost connections
|
|
47
|
-
this.libP2PNode.addEventListener(PeerEvent.DISCONNECTED, this.handleDisconnectedPeerEvent
|
|
48
|
-
// Handle Discovered peers
|
|
49
|
-
this.discoveredPeerHandler = (enr)=>this.handleDiscoveredPeer(enr).catch((e)=>this.logger.error('Error handling discovered peer', e));
|
|
90
|
+
this.libP2PNode.addEventListener(PeerEvent.DISCONNECTED, this.handlers.handleDisconnectedPeerEvent);
|
|
50
91
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
51
|
-
this.peerDiscoveryService
|
|
92
|
+
this.peerDiscoveryService?.on(PeerEvent.DISCOVERED, this.handlers.handleDiscoveredPeer);
|
|
52
93
|
// Display peer counts every 60 seconds
|
|
53
94
|
this.displayPeerCountsPeerHeartbeat = Math.floor(60_000 / this.config.peerCheckIntervalMS);
|
|
54
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Initializes the trusted peers.
|
|
98
|
+
*
|
|
99
|
+
* This function is called when the peer manager is initialized.
|
|
100
|
+
*/ async initializePeers() {
|
|
101
|
+
if (this.config.trustedPeers) {
|
|
102
|
+
const trustedPeersEnrs = this.config.trustedPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
103
|
+
await Promise.all(trustedPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.trustedPeers.add(peerId.toString()))).finally(()=>{
|
|
104
|
+
this.trustedPeersInitialized = true;
|
|
105
|
+
}).catch((e)=>this.logger.error('Error initializing trusted peers', e));
|
|
106
|
+
}
|
|
107
|
+
if (this.config.privatePeers) {
|
|
108
|
+
const privatePeersEnrs = this.config.privatePeers.map((enr)=>ENR.decodeTxt(enr));
|
|
109
|
+
await Promise.all(privatePeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>{
|
|
110
|
+
this.trustedPeers.add(peerId.toString());
|
|
111
|
+
this.privatePeers.add(peerId.toString());
|
|
112
|
+
})).finally(()=>{
|
|
113
|
+
if (!this.config.trustedPeers) {
|
|
114
|
+
this.trustedPeersInitialized = true;
|
|
115
|
+
}
|
|
116
|
+
this.privatePeersInitialized = true;
|
|
117
|
+
}).catch((e)=>this.logger.error('Error initializing private peers', e));
|
|
118
|
+
}
|
|
119
|
+
if (this.config.preferredPeers) {
|
|
120
|
+
const preferredPeersEnrs = this.config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
121
|
+
await Promise.all(preferredPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.preferredPeers.add(peerId.toString()))).catch((e)=>this.logger.error('Error initializing preferred peers', e));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
55
124
|
get tracer() {
|
|
56
125
|
return this.metrics.tracer;
|
|
57
126
|
}
|
|
58
|
-
heartbeat() {
|
|
127
|
+
async heartbeat() {
|
|
59
128
|
this.heartbeatCounter++;
|
|
60
129
|
this.peerScoring.decayAllScores();
|
|
61
130
|
this.cleanupExpiredTimeouts();
|
|
131
|
+
await this.setupDirectPeersIfValidator();
|
|
132
|
+
await this.updateAuthenticatedPeers();
|
|
133
|
+
await this.processScheduledDisconnects();
|
|
62
134
|
this.discover();
|
|
63
135
|
}
|
|
136
|
+
/*
|
|
137
|
+
* If this node is connecting to preferred peers, make sure it is registered validator */ async setupDirectPeersIfValidator() {
|
|
138
|
+
if (!this.config.preferredPeers) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// Already initialized preferred peers, don't wastefully repeat the same work
|
|
142
|
+
if (this.initializedPreferredPeers) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const registeredValidators = await this.epochCache.getRegisteredValidators();
|
|
146
|
+
const validatorSet = new Set(registeredValidators.map((v)=>v.toString()));
|
|
147
|
+
const isThisNodePartOfValidatorSet = this.validatorAddresses.some((v)=>validatorSet.has(v.toString()));
|
|
148
|
+
if (!isThisNodePartOfValidatorSet) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const preferredPeersEnrs = this.config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
152
|
+
await Promise.all(preferredPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.preferredPeers.add(peerId.toString()))).catch((e)=>this.logger.error('Error initializing preferred peers', e));
|
|
153
|
+
const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
|
|
154
|
+
const peerId = await enr.peerId();
|
|
155
|
+
const address = enr.getLocationMultiaddr('tcp');
|
|
156
|
+
if (address === undefined) {
|
|
157
|
+
throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
id: peerId,
|
|
161
|
+
addrs: [
|
|
162
|
+
address
|
|
163
|
+
]
|
|
164
|
+
};
|
|
165
|
+
}))).filter((peer)=>peer !== undefined);
|
|
166
|
+
await Promise.all(directPeers.map((peer)=>{
|
|
167
|
+
this.libP2PNode.services.pubsub.direct.add(peer.id.toString());
|
|
168
|
+
return this.libP2PNode.peerStore.merge(peer.id, {
|
|
169
|
+
multiaddrs: peer.addrs
|
|
170
|
+
});
|
|
171
|
+
}));
|
|
172
|
+
this.initializedPreferredPeers = true;
|
|
173
|
+
}
|
|
64
174
|
/**
|
|
65
175
|
* Cleans up expired timeouts.
|
|
66
176
|
*
|
|
@@ -69,7 +179,7 @@ export class PeerManager {
|
|
|
69
179
|
* To give them a chance to reconnect.
|
|
70
180
|
*/ cleanupExpiredTimeouts() {
|
|
71
181
|
// Clean up expired timeouts
|
|
72
|
-
const now =
|
|
182
|
+
const now = this.dateProvider.now();
|
|
73
183
|
for (const [peerId, timedOutPeer] of this.timedOutPeers.entries()){
|
|
74
184
|
if (now >= timedOutPeer.timeoutUntilMs) {
|
|
75
185
|
this.timedOutPeers.delete(peerId);
|
|
@@ -77,26 +187,135 @@ export class PeerManager {
|
|
|
77
187
|
}
|
|
78
188
|
}
|
|
79
189
|
/**
|
|
80
|
-
*
|
|
190
|
+
* Processes scheduled disconnects during heartbeat.
|
|
191
|
+
*
|
|
192
|
+
* This batch processes all peers that have been marked for disconnect.
|
|
193
|
+
* preventing immediate disconnects that could cause libp2p state corruption.
|
|
194
|
+
*/ async processScheduledDisconnects() {
|
|
195
|
+
if (this.peersToBeDisconnected.size === 0) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const peersToDisconnect = Array.from(this.peersToBeDisconnected);
|
|
199
|
+
this.logger.debug(`Processing ${peersToDisconnect.length} scheduled disconnects`);
|
|
200
|
+
try {
|
|
201
|
+
await Promise.all(peersToDisconnect.map(async (peerIdStr)=>{
|
|
202
|
+
if (await this.disconnectPeer(peerIdFromString(peerIdStr))) {
|
|
203
|
+
this.peersToBeDisconnected.delete(peerIdStr);
|
|
204
|
+
}
|
|
205
|
+
}));
|
|
206
|
+
this.logger.verbose(`Disconnected ${peersToDisconnect.length} peers`, {
|
|
207
|
+
peersToDisconnect
|
|
208
|
+
});
|
|
209
|
+
} catch (error) {
|
|
210
|
+
this.logger.error('Error when disconnecting from peers', error);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Performs Status Handshake with a connected peer.
|
|
81
215
|
* @param e - The connected peer event.
|
|
82
216
|
*/ handleConnectedPeerEvent(e) {
|
|
83
217
|
const peerId = e.detail;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
218
|
+
this.logger.verbose(`Connected to peer ${peerId.toString()}`);
|
|
219
|
+
this.metrics.peerConnected(peerId);
|
|
220
|
+
if (this.config.p2pDisableStatusHandshake) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// If we are not configured to only allow validators then perform a status handshake
|
|
224
|
+
if (!this.config.p2pAllowOnlyValidators) {
|
|
225
|
+
void this.exchangeStatusHandshake(peerId);
|
|
226
|
+
return;
|
|
88
227
|
}
|
|
228
|
+
// We are configured to only allow validators, but this doesn't apply to trusted, private peers or preferred peers
|
|
229
|
+
if (this.isProtectedPeer(peerId)) {
|
|
230
|
+
void this.exchangeStatusHandshake(peerId);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// Initiate auth handshake
|
|
234
|
+
void this.exchangeAuthHandshake(peerId);
|
|
89
235
|
}
|
|
90
236
|
/**
|
|
91
237
|
* Simply logs the type of disconnected peer.
|
|
92
238
|
* @param e - The disconnected peer event.
|
|
93
239
|
*/ handleDisconnectedPeerEvent(e) {
|
|
94
240
|
const peerId = e.detail;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
241
|
+
this.metrics.peerDisconnected(peerId);
|
|
242
|
+
this.logger.verbose(`Disconnected from peer ${peerId.toString()}`);
|
|
243
|
+
const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerId.toString());
|
|
244
|
+
if (validatorAddress !== undefined) {
|
|
245
|
+
this.logger.info(`Removing authentication for validator ${validatorAddress} at peer id ${peerId.toString()} due to disconnection`);
|
|
246
|
+
this.authenticatedValidatorAddressToPeerId.delete(validatorAddress.toString());
|
|
247
|
+
this.authenticatedPeerIdToValidatorAddress.delete(peerId.toString());
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
registerThisValidatorAddresses(address) {
|
|
251
|
+
this.validatorAddresses = [
|
|
252
|
+
...address
|
|
253
|
+
];
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Checks if a peer is trusted.
|
|
257
|
+
* @param peerId - The peer ID.
|
|
258
|
+
* @returns True if the peer is trusted, false otherwise.
|
|
259
|
+
* Note: This function will return false and log a warning if the trusted peers are not initialized.
|
|
260
|
+
*/ isTrustedPeer(peerId) {
|
|
261
|
+
if (!this.trustedPeersInitialized) {
|
|
262
|
+
this.logger.warn('Trusted peers not initialized, returning false');
|
|
263
|
+
return false;
|
|
99
264
|
}
|
|
265
|
+
return this.trustedPeers.has(peerId.toString());
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Adds a peer to the trusted peers set.
|
|
269
|
+
* @param peerId - The peer ID to add to trusted peers.
|
|
270
|
+
*/ addTrustedPeer(peerId) {
|
|
271
|
+
const peerIdStr = peerId.toString();
|
|
272
|
+
this.trustedPeers.add(peerIdStr);
|
|
273
|
+
this.trustedPeersInitialized = true;
|
|
274
|
+
this.logger.verbose(`Added trusted peer ${peerIdStr}`);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Adds a peer to the private peers set.
|
|
278
|
+
* @param peerId - The peer ID to add to private peers.
|
|
279
|
+
*/ addPrivatePeer(peerId) {
|
|
280
|
+
const peerIdStr = peerId.toString();
|
|
281
|
+
this.trustedPeers.add(peerIdStr);
|
|
282
|
+
this.privatePeers.add(peerIdStr);
|
|
283
|
+
this.trustedPeersInitialized = true;
|
|
284
|
+
this.privatePeersInitialized = true;
|
|
285
|
+
this.logger.verbose(`Added private peer ${peerIdStr}`);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Checks if a peer is private.
|
|
289
|
+
* @param peerId - The peer ID.
|
|
290
|
+
* @returns True if the peer is private, false otherwise.
|
|
291
|
+
*/ isPrivatePeer(peerId) {
|
|
292
|
+
if (!this.privatePeersInitialized) {
|
|
293
|
+
this.logger.warn('Private peers not initialized, returning false');
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
return this.privatePeers.has(peerId.toString());
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Adds a peer to the preferred peers set.
|
|
300
|
+
* @param peerId - The peer ID to add to preferred peers.
|
|
301
|
+
*/ addPreferredPeer(peerId) {
|
|
302
|
+
const peerIdStr = peerId.toString();
|
|
303
|
+
this.preferredPeers.add(peerIdStr);
|
|
304
|
+
this.logger.verbose(`Added preferred peer ${peerIdStr}`);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Checks if a peer is preferred.
|
|
308
|
+
* @param peerId - The peer ID.
|
|
309
|
+
* @returns True if the peer is preferred, false otherwise.
|
|
310
|
+
*/ isPreferredPeer(peerId) {
|
|
311
|
+
return this.preferredPeers.has(peerId.toString());
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Checks if a peer is protected (either trusted or private).
|
|
315
|
+
* @param peerId - The peer ID.
|
|
316
|
+
* @returns True if the peer is protected, false otherwise.
|
|
317
|
+
*/ isProtectedPeer(peerId) {
|
|
318
|
+
return this.isTrustedPeer(peerId) || this.isPrivatePeer(peerId) || this.isPreferredPeer(peerId);
|
|
100
319
|
}
|
|
101
320
|
/**
|
|
102
321
|
* Handles a goodbye received from a peer.
|
|
@@ -107,7 +326,7 @@ export class PeerManager {
|
|
|
107
326
|
*/ goodbyeReceived(peerId, reason) {
|
|
108
327
|
this.logger.debug(`Goodbye received from peer ${peerId.toString()} with reason ${prettyGoodbyeReason(reason)}`);
|
|
109
328
|
this.metrics.recordGoodbyeReceived(reason);
|
|
110
|
-
|
|
329
|
+
this.markPeerForDisconnect(peerId);
|
|
111
330
|
}
|
|
112
331
|
penalizePeer(peerId, penalty) {
|
|
113
332
|
this.peerScoring.penalizePeer(peerId, penalty);
|
|
@@ -115,6 +334,10 @@ export class PeerManager {
|
|
|
115
334
|
getPeerScore(peerId) {
|
|
116
335
|
return this.peerScoring.getScore(peerId);
|
|
117
336
|
}
|
|
337
|
+
shouldDisableP2PGossip(peerId) {
|
|
338
|
+
const isAuthenticated = this.isAuthenticatedPeer(peerIdFromString(peerId));
|
|
339
|
+
return (this.config.p2pAllowOnlyValidators ?? false) && !isAuthenticated;
|
|
340
|
+
}
|
|
118
341
|
getPeers(includePending = false) {
|
|
119
342
|
const connected = this.libP2PNode.getPeers().map((peer)=>({
|
|
120
343
|
id: peer.toString(),
|
|
@@ -145,30 +368,56 @@ export class PeerManager {
|
|
|
145
368
|
...cachedPeers
|
|
146
369
|
];
|
|
147
370
|
}
|
|
371
|
+
isAuthenticatedPeer(peerId) {
|
|
372
|
+
const peerIdAsString = peerId.toString();
|
|
373
|
+
return this.privatePeers.has(peerIdAsString) || this.trustedPeers.has(peerIdAsString) || this.preferredPeers.has(peerIdAsString) || this.authenticatedPeerIdToValidatorAddress.has(peerIdAsString);
|
|
374
|
+
}
|
|
375
|
+
/*
|
|
376
|
+
* Checks whether peer is allowed to connect
|
|
377
|
+
*
|
|
378
|
+
* @param id: Address of the node or it's peerId
|
|
379
|
+
*
|
|
380
|
+
* @returns: True if node is allowed to connect, otherwise false
|
|
381
|
+
* */ isNodeAllowedToConnect(id) {
|
|
382
|
+
const entry = this.failedAuthHandshakes.get(id.toString());
|
|
383
|
+
if (!entry) {
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
// In case entry is too old, remove it and allow connection
|
|
387
|
+
if (this.dateProvider.now() - entry.lastFailureTimestamp > FAILED_AUTH_HANDSHAKE_EXPIRY_MS) {
|
|
388
|
+
this.failedAuthHandshakes.delete(id.toString());
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
return entry.count <= this.config.p2pMaxFailedAuthAttemptsAllowed;
|
|
392
|
+
}
|
|
148
393
|
/**
|
|
149
394
|
* Discovers peers.
|
|
150
395
|
*/ discover() {
|
|
151
396
|
const connections = this.libP2PNode.getConnections();
|
|
152
|
-
const healthyConnections = this.prioritizePeers(this.pruneUnhealthyPeers(this.
|
|
397
|
+
const healthyConnections = this.prioritizePeers(this.pruneUnhealthyPeers(this.getNonProtectedPeers(connections)));
|
|
153
398
|
// Calculate how many connections we're looking to make
|
|
154
|
-
const
|
|
399
|
+
const protectedPeerCount = this.getProtectedPeerCount();
|
|
400
|
+
const peersToConnect = this.config.maxPeerCount - healthyConnections.length - protectedPeerCount;
|
|
155
401
|
const logLevel = this.heartbeatCounter % this.displayPeerCountsPeerHeartbeat === 0 ? 'info' : 'debug';
|
|
156
|
-
this.logger[logLevel](`Connected to ${healthyConnections.length} peers`, {
|
|
157
|
-
|
|
402
|
+
this.logger[logLevel](`Connected to ${healthyConnections.length + this.trustedPeers.size} peers`, {
|
|
403
|
+
discoveredConnections: healthyConnections.length,
|
|
404
|
+
protectedConnections: protectedPeerCount,
|
|
158
405
|
maxPeerCount: this.config.maxPeerCount,
|
|
159
406
|
cachedPeers: this.cachedPeers.size,
|
|
160
407
|
...this.peerScoring.getStats()
|
|
161
408
|
});
|
|
409
|
+
this.metrics.recordPeerCount(healthyConnections.length);
|
|
162
410
|
// Exit if no peers to connect
|
|
163
411
|
if (peersToConnect <= 0) {
|
|
164
412
|
return;
|
|
165
413
|
}
|
|
166
414
|
const cachedPeersToDial = [];
|
|
167
415
|
const pendingDials = new Set(this.libP2PNode.getDialQueue().map((pendingDial)=>pendingDial.peerId?.toString()).filter(Boolean));
|
|
416
|
+
const now = this.dateProvider.now();
|
|
168
417
|
for (const [id, peerData] of this.cachedPeers.entries()){
|
|
169
418
|
// if already dialling or connected to, remove from cache
|
|
170
419
|
if (pendingDials.has(id) || healthyConnections.some((conn)=>conn.remotePeer.equals(peerData.peerId)) || // if peer has been in cache for the max cache age, remove from cache
|
|
171
|
-
|
|
420
|
+
now - peerData.addedUnixMs > MAX_CACHED_PEER_AGE_MS) {
|
|
172
421
|
this.cachedPeers.delete(id);
|
|
173
422
|
} else {
|
|
174
423
|
// cachedPeersToDial.set(id, enr);
|
|
@@ -188,15 +437,23 @@ export class PeerManager {
|
|
|
188
437
|
void this.peerDiscoveryService.runRandomNodesQuery();
|
|
189
438
|
}
|
|
190
439
|
}
|
|
440
|
+
getNonProtectedPeers(connections) {
|
|
441
|
+
return connections.filter((conn)=>!this.isProtectedPeer(conn.remotePeer));
|
|
442
|
+
}
|
|
443
|
+
getProtectedPeerCount() {
|
|
444
|
+
return this.trustedPeers.size + this.privatePeers.size + this.preferredPeers.size;
|
|
445
|
+
}
|
|
191
446
|
pruneUnhealthyPeers(connections) {
|
|
192
447
|
const connectedHealthyPeers = [];
|
|
193
448
|
for (const peer of connections){
|
|
194
449
|
const score = this.peerScoring.getScoreState(peer.remotePeer.toString());
|
|
195
450
|
switch(score){
|
|
196
451
|
case PeerScoreState.Banned:
|
|
452
|
+
this.metrics.recordLowScoreDisconnect('Banned');
|
|
197
453
|
void this.goodbyeAndDisconnectPeer(peer.remotePeer, GoodByeReason.BANNED);
|
|
198
454
|
break;
|
|
199
455
|
case PeerScoreState.Disconnect:
|
|
456
|
+
this.metrics.recordLowScoreDisconnect('Disconnect');
|
|
200
457
|
void this.goodbyeAndDisconnectPeer(peer.remotePeer, GoodByeReason.LOW_SCORE);
|
|
201
458
|
break;
|
|
202
459
|
case PeerScoreState.Healthy:
|
|
@@ -211,72 +468,69 @@ export class PeerManager {
|
|
|
211
468
|
* @param connections - The list of connections to prune low scoring peers above the max peer count from.
|
|
212
469
|
* @returns The pruned list of connections.
|
|
213
470
|
*/ prioritizePeers(connections) {
|
|
214
|
-
|
|
215
|
-
|
|
471
|
+
const protectedPeerCount = this.getProtectedPeerCount();
|
|
472
|
+
if (connections.length > this.config.maxPeerCount - protectedPeerCount) {
|
|
473
|
+
// Sort the regular peer scores from highest to lowest
|
|
216
474
|
const prioritizedConnections = connections.sort((connectionA, connectionB)=>{
|
|
217
475
|
const connectionScoreA = this.peerScoring.getScore(connectionA.remotePeer.toString());
|
|
218
476
|
const connectionScoreB = this.peerScoring.getScore(connectionB.remotePeer.toString());
|
|
219
477
|
return connectionScoreB - connectionScoreA;
|
|
220
478
|
});
|
|
221
|
-
//
|
|
222
|
-
|
|
479
|
+
// Calculate how many regular peers we can keep
|
|
480
|
+
const peersToKeep = Math.max(0, this.config.maxPeerCount - protectedPeerCount);
|
|
481
|
+
// Disconnect from the lowest scoring regular connections that exceed our limit
|
|
482
|
+
for (const conn of prioritizedConnections.slice(peersToKeep)){
|
|
223
483
|
void this.goodbyeAndDisconnectPeer(conn.remotePeer, GoodByeReason.MAX_PEERS);
|
|
224
484
|
}
|
|
225
|
-
|
|
485
|
+
// Return trusted connections plus the highest scoring regular connections up to the max peer count
|
|
486
|
+
return prioritizedConnections.slice(0, peersToKeep);
|
|
226
487
|
} else {
|
|
227
488
|
return connections;
|
|
228
489
|
}
|
|
229
490
|
}
|
|
230
|
-
/**
|
|
231
|
-
* If multiple connections to the same peer are found, the oldest connection is kept and the duplicates are pruned.
|
|
232
|
-
*
|
|
233
|
-
* This is necessary to resolve a race condition where multiple connections to the same peer are established if
|
|
234
|
-
* they are discovered at the same time.
|
|
235
|
-
*
|
|
236
|
-
* @param connections - The list of connections to prune duplicate peers from.
|
|
237
|
-
* @returns The pruned list of connections.
|
|
238
|
-
*/ pruneDuplicatePeers(connections) {
|
|
239
|
-
const peerConnections = new Map();
|
|
240
|
-
for (const conn of connections){
|
|
241
|
-
const peerId = conn.remotePeer.toString();
|
|
242
|
-
const existingConnection = peerConnections.get(peerId);
|
|
243
|
-
if (!existingConnection) {
|
|
244
|
-
peerConnections.set(peerId, conn);
|
|
245
|
-
} else {
|
|
246
|
-
// Keep the oldest connection for each peer
|
|
247
|
-
this.logger.debug(`Found duplicate connection to peer ${peerId}, keeping oldest connection`);
|
|
248
|
-
if (conn.timeline.open < existingConnection.timeline.open) {
|
|
249
|
-
peerConnections.set(peerId, conn);
|
|
250
|
-
void existingConnection.close();
|
|
251
|
-
} else {
|
|
252
|
-
void conn.close();
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
return [
|
|
257
|
-
...peerConnections.values()
|
|
258
|
-
];
|
|
259
|
-
}
|
|
260
491
|
async goodbyeAndDisconnectPeer(peer, reason) {
|
|
261
492
|
this.logger.debug(`Disconnecting peer ${peer.toString()} with reason ${prettyGoodbyeReason(reason)}`);
|
|
262
493
|
this.metrics.recordGoodbyeSent(reason);
|
|
263
494
|
try {
|
|
264
|
-
await this.reqresp.sendRequestToPeer(peer, ReqRespSubProtocol.GOODBYE, Buffer.from([
|
|
495
|
+
const resp = await this.reqresp.sendRequestToPeer(peer, ReqRespSubProtocol.GOODBYE, Buffer.from([
|
|
265
496
|
reason
|
|
266
|
-
]));
|
|
497
|
+
]), GOODBYE_DIAL_TIMEOUT_MS);
|
|
498
|
+
if (resp.status === ReqRespStatus.FAILURE) {
|
|
499
|
+
this.logger.debug(`Failed to send goodbye to peer ${peer.toString()}`);
|
|
500
|
+
} else if (resp.status === ReqRespStatus.SUCCESS) {
|
|
501
|
+
this.logger.verbose(`Sent goodbye to peer ${peer.toString()}`);
|
|
502
|
+
} else {
|
|
503
|
+
this.logger.debug(`Unexpected status sending goodbye to peer ${peer.toString()}: ${ReqRespStatus[resp.status]}`);
|
|
504
|
+
}
|
|
267
505
|
} catch (error) {
|
|
268
506
|
this.logger.debug(`Failed to send goodbye to peer ${peer.toString()}: ${error}`);
|
|
269
507
|
} finally{
|
|
270
|
-
|
|
508
|
+
this.markPeerForDisconnect(peer);
|
|
271
509
|
}
|
|
272
510
|
}
|
|
273
|
-
|
|
511
|
+
/*
|
|
512
|
+
* Marks peer to be disconnected on the next heartbeat
|
|
513
|
+
* */ markPeerForDisconnect(peer) {
|
|
514
|
+
const peerIdStr = peer.toString();
|
|
515
|
+
this.logger.debug(`Scheduling peer ${peerIdStr} for disconnection`);
|
|
516
|
+
this.peersToBeDisconnected.add(peerIdStr);
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Performs the actual disconnection of a peer.
|
|
520
|
+
* This is called during heartbeat processing to avoid immediate disconnections.
|
|
521
|
+
*
|
|
522
|
+
* @returns True if peer was disconnect, otherwise false
|
|
523
|
+
*/ async disconnectPeer(peer) {
|
|
524
|
+
const peerIdStr = peer.toString();
|
|
274
525
|
try {
|
|
275
526
|
await this.libP2PNode.hangUp(peer);
|
|
527
|
+
this.logger.debug(`Successfully disconnected peer ${peerIdStr}`);
|
|
528
|
+
return true;
|
|
276
529
|
} catch (error) {
|
|
277
|
-
this.logger.
|
|
278
|
-
error
|
|
530
|
+
this.logger.warn(`Failed to disconnect peer ${peerIdStr}`, {
|
|
531
|
+
error
|
|
279
532
|
});
|
|
533
|
+
return false;
|
|
280
534
|
}
|
|
281
535
|
}
|
|
282
536
|
/**
|
|
@@ -286,10 +540,15 @@ export class PeerManager {
|
|
|
286
540
|
// Check that the peer has not already been banned
|
|
287
541
|
const peerId = await enr.peerId();
|
|
288
542
|
const peerIdString = peerId.toString();
|
|
543
|
+
// Don't attempt to connect to peers scheduled for disconnection
|
|
544
|
+
if (this.peersToBeDisconnected.has(peerIdString)) {
|
|
545
|
+
this.logger.trace(`Skipping peer scheduled for disconnection ${peerId}`);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
289
548
|
// Check if peer is temporarily timed out
|
|
290
549
|
const timedOutPeer = this.timedOutPeers.get(peerIdString);
|
|
291
550
|
if (timedOutPeer) {
|
|
292
|
-
if (
|
|
551
|
+
if (this.dateProvider.now() < timedOutPeer.timeoutUntilMs) {
|
|
293
552
|
this.logger.trace(`Skipping timed out peer ${peerId}`);
|
|
294
553
|
return;
|
|
295
554
|
}
|
|
@@ -325,7 +584,7 @@ export class PeerManager {
|
|
|
325
584
|
enr,
|
|
326
585
|
multiaddrTcp,
|
|
327
586
|
dialAttempts: 0,
|
|
328
|
-
addedUnixMs:
|
|
587
|
+
addedUnixMs: this.dateProvider.now()
|
|
329
588
|
};
|
|
330
589
|
// Determine if we should dial immediately or not
|
|
331
590
|
if (this.shouldDialPeer()) {
|
|
@@ -364,7 +623,7 @@ export class PeerManager {
|
|
|
364
623
|
// Add to timed out peers
|
|
365
624
|
this.timedOutPeers.set(id, {
|
|
366
625
|
peerId: id,
|
|
367
|
-
timeoutUntilMs:
|
|
626
|
+
timeoutUntilMs: this.dateProvider.now() + FAILED_PEER_BAN_TIME_MS
|
|
368
627
|
});
|
|
369
628
|
}
|
|
370
629
|
}
|
|
@@ -383,7 +642,11 @@ export class PeerManager {
|
|
|
383
642
|
return;
|
|
384
643
|
}
|
|
385
644
|
// Remove the oldest peers
|
|
386
|
-
for (const key of this.cachedPeers.
|
|
645
|
+
for (const [key, value] of this.cachedPeers.entries()){
|
|
646
|
+
if (this.isProtectedPeer(value.peerId)) {
|
|
647
|
+
this.logger.debug(`Not pruning trusted peer ${key}`);
|
|
648
|
+
continue;
|
|
649
|
+
}
|
|
387
650
|
this.cachedPeers.delete(key);
|
|
388
651
|
this.logger.trace(`Pruning peer ${key} from cache`);
|
|
389
652
|
peersToDelete--;
|
|
@@ -392,21 +655,227 @@ export class PeerManager {
|
|
|
392
655
|
}
|
|
393
656
|
}
|
|
394
657
|
}
|
|
658
|
+
async createStatusMessage() {
|
|
659
|
+
const syncSummary = (await this.worldStateSynchronizer.status()).syncSummary;
|
|
660
|
+
return StatusMessage.fromWorldStateSyncStatus(this.protocolVersion, syncSummary);
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Performs status Handshake with the Peer
|
|
664
|
+
* The way the protocol is designed is that each peer will call this method on newly established p2p connection.
|
|
665
|
+
* Both peers request Status message and both peers perform validation of the received Status message.
|
|
666
|
+
* If this validation fails on any end that peer will initiate disconnect.
|
|
667
|
+
* Note: It's important for both peers to request and perform Status validation,
|
|
668
|
+
* Because one of the peers can be _bad peer_ and this peer can simply skip the check.
|
|
669
|
+
* If we don't implement validation on both ends the _bad peer_ remains connected.
|
|
670
|
+
* @param: peerId The Id of the peer to request the Status from.
|
|
671
|
+
* */ async exchangeStatusHandshake(peerId) {
|
|
672
|
+
try {
|
|
673
|
+
const ourStatus = await this.createStatusMessage();
|
|
674
|
+
//Note: Technically we don't have to send out status to peer as well, but we do.
|
|
675
|
+
//It will be easier to update protocol in the future this way if need be.
|
|
676
|
+
this.logger.trace(`Initiating status handshake with peer ${peerId}`);
|
|
677
|
+
const response = await this.reqresp.sendRequestToPeer(peerId, ReqRespSubProtocol.STATUS, ourStatus.toBuffer());
|
|
678
|
+
const { status } = response;
|
|
679
|
+
if (status !== ReqRespStatus.SUCCESS) {
|
|
680
|
+
//TODO: maybe hard ban these peers in the future.
|
|
681
|
+
//We could allow this to happen up to N times, and then hard ban?
|
|
682
|
+
//Hard ban: Disallow connection via e.g. libp2p's Gater
|
|
683
|
+
this.logger.debug(`Disconnecting peer ${peerId} who failed to respond status handshake`, {
|
|
684
|
+
peerId,
|
|
685
|
+
status: ReqRespStatus[status]
|
|
686
|
+
});
|
|
687
|
+
this.markPeerForDisconnect(peerId);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
const { data } = response;
|
|
691
|
+
const logData = {
|
|
692
|
+
peerId,
|
|
693
|
+
status: ReqRespStatus[status],
|
|
694
|
+
data: data ? bufferToHex(data) : undefined
|
|
695
|
+
};
|
|
696
|
+
const peerStatusMessage = StatusMessage.fromBuffer(data);
|
|
697
|
+
if (!ourStatus.validate(peerStatusMessage)) {
|
|
698
|
+
this.logger.debug(`Disconnecting peer ${peerId} due to failed status handshake.`, logData);
|
|
699
|
+
this.markPeerForDisconnect(peerId);
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
this.logger.debug(`Successfully completed status handshake with peer ${peerId}`, logData);
|
|
703
|
+
} catch (err) {
|
|
704
|
+
//TODO: maybe hard ban these peers in the future
|
|
705
|
+
this.logger.debug(`Disconnecting peer ${peerId} due to error during status handshake: ${err.message ?? err}`, {
|
|
706
|
+
peerId
|
|
707
|
+
});
|
|
708
|
+
this.markPeerForDisconnect(peerId);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Performs auth Handshake with the Peer
|
|
713
|
+
* A superset of the status handshake. Also includes a challenge that needs to be signed by the peer's validator key.
|
|
714
|
+
* @param: peerId The Id of the peer to request the Status from.
|
|
715
|
+
* */ async exchangeAuthHandshake(peerId) {
|
|
716
|
+
const peerIdString = peerId.toString();
|
|
717
|
+
try {
|
|
718
|
+
const ourStatus = await this.createStatusMessage();
|
|
719
|
+
const authRequest = new AuthRequest(ourStatus, Fr.random());
|
|
720
|
+
// Note: Technically we don't have to send our status to peer as well, but we do.
|
|
721
|
+
// It will be easier to update protocol in the future this way if need be.
|
|
722
|
+
// We also need to send the challenge at least, so that the peer can sign it.
|
|
723
|
+
this.logger.debug(`Initiating auth handshake with peer ${peerId}`);
|
|
724
|
+
const response = await this.reqresp.sendRequestToPeer(peerId, ReqRespSubProtocol.AUTH, authRequest.toBuffer());
|
|
725
|
+
const { status } = response;
|
|
726
|
+
if (status !== ReqRespStatus.SUCCESS) {
|
|
727
|
+
this.logger.verbose(`Disconnecting peer ${peerId} who failed to respond auth handshake`, {
|
|
728
|
+
peerId,
|
|
729
|
+
status: ReqRespStatus[status]
|
|
730
|
+
});
|
|
731
|
+
this.markAuthHandshakeFailed(peerId);
|
|
732
|
+
this.markPeerForDisconnect(peerId);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
const { data } = response;
|
|
736
|
+
const logData = {
|
|
737
|
+
peerId,
|
|
738
|
+
status: ReqRespStatus[status],
|
|
739
|
+
data: data ? bufferToHex(data) : undefined
|
|
740
|
+
};
|
|
741
|
+
const peerAuthResponse = AuthResponse.fromBuffer(data);
|
|
742
|
+
const peerStatusMessage = peerAuthResponse.status;
|
|
743
|
+
if (!ourStatus.validate(peerStatusMessage)) {
|
|
744
|
+
this.logger.verbose(`Disconnecting peer ${peerId} due to failed status handshake as part of auth.`, logData);
|
|
745
|
+
this.markAuthHandshakeFailed(peerId);
|
|
746
|
+
this.markPeerForDisconnect(peerId);
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
const hashToRecover = authRequest.getPayloadToSign();
|
|
750
|
+
const ethSignedHash = makeEthSignDigest(hashToRecover);
|
|
751
|
+
const sender = tryRecoverAddress(ethSignedHash, peerAuthResponse.signature);
|
|
752
|
+
if (!sender) {
|
|
753
|
+
this.logger.verbose(`Disconnecting peer ${peerId} due to failed auth handshake, invalid signature.`, logData);
|
|
754
|
+
this.markAuthHandshakeFailed(peerId);
|
|
755
|
+
this.markPeerForDisconnect(peerId);
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
const registeredValidators = await this.epochCache.getRegisteredValidators();
|
|
759
|
+
const found = registeredValidators.find((v)=>v.toString() === sender.toString()) !== undefined;
|
|
760
|
+
if (!found) {
|
|
761
|
+
this.logger.verbose(`Disconnecting peer ${peerId} due to failed auth handshake, peer is not a registered validator.`, {
|
|
762
|
+
...logData,
|
|
763
|
+
address: sender.toString()
|
|
764
|
+
});
|
|
765
|
+
this.markAuthHandshakeFailed(peerId);
|
|
766
|
+
this.markPeerForDisconnect(peerId);
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
// Check to see that this validator address isn't already allocated to a different peer
|
|
770
|
+
const peerForAddress = this.authenticatedValidatorAddressToPeerId.get(sender.toString());
|
|
771
|
+
if (peerForAddress !== undefined && peerForAddress.toString() !== peerIdString) {
|
|
772
|
+
this.logger.verbose(`Received auth for validator ${sender.toString()} from peer ${peerIdString}, but this validator is already authenticated to peer ${peerForAddress.toString()}`, {
|
|
773
|
+
...logData,
|
|
774
|
+
address: sender.toString()
|
|
775
|
+
});
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
this.markAuthHandshakeSuccess(peerId);
|
|
779
|
+
this.authenticatedPeerIdToValidatorAddress.set(peerIdString, sender);
|
|
780
|
+
this.authenticatedValidatorAddressToPeerId.set(sender.toString(), peerId);
|
|
781
|
+
this.logger.info(`Successfully completed auth handshake with peer ${peerId}, validator address ${sender.toString()}`, {
|
|
782
|
+
...logData,
|
|
783
|
+
address: sender.toString()
|
|
784
|
+
});
|
|
785
|
+
} catch (err) {
|
|
786
|
+
//TODO: maybe hard ban these peers in the future
|
|
787
|
+
this.logger.verbose(`Disconnecting peer ${peerId} due to error during auth handshake: ${err.message}`, {
|
|
788
|
+
peerId,
|
|
789
|
+
err
|
|
790
|
+
});
|
|
791
|
+
this.markAuthHandshakeFailed(peerId);
|
|
792
|
+
this.markPeerForDisconnect(peerId);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
/*
|
|
796
|
+
* Marks when peer fails auth handshake
|
|
797
|
+
* */ markAuthHandshakeFailed(peerId) {
|
|
798
|
+
const now = this.dateProvider.now();
|
|
799
|
+
const peerIdStr = peerId.toString();
|
|
800
|
+
const existingEntry = this.failedAuthHandshakes.get(peerIdStr);
|
|
801
|
+
this.failedAuthHandshakes.set(peerIdStr, {
|
|
802
|
+
count: (existingEntry?.count || 0) + 1,
|
|
803
|
+
lastFailureTimestamp: now
|
|
804
|
+
});
|
|
805
|
+
const connections = this.libP2PNode.getConnections(peerId);
|
|
806
|
+
connections.forEach((conn)=>{
|
|
807
|
+
// We mark the IP address
|
|
808
|
+
const address = conn.remoteAddr.nodeAddress().address;
|
|
809
|
+
const existingAddressEntry = this.failedAuthHandshakes.get(address);
|
|
810
|
+
this.failedAuthHandshakes.set(address, {
|
|
811
|
+
count: (existingAddressEntry?.count || 0) + 1,
|
|
812
|
+
lastFailureTimestamp: now
|
|
813
|
+
});
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
/*
|
|
817
|
+
* Marks when peer exchanges auth handshake
|
|
818
|
+
* Removes any failed previous attempts
|
|
819
|
+
* */ markAuthHandshakeSuccess(peerId) {
|
|
820
|
+
this.failedAuthHandshakes.delete(peerId.toString());
|
|
821
|
+
const connections = this.libP2PNode.getConnections(peerId);
|
|
822
|
+
connections.forEach((conn)=>{
|
|
823
|
+
const address = conn.remoteAddr.nodeAddress().address;
|
|
824
|
+
this.failedAuthHandshakes.delete(address);
|
|
825
|
+
});
|
|
826
|
+
}
|
|
395
827
|
/**
|
|
396
828
|
* Stops the peer manager.
|
|
397
829
|
* Removing all event listeners.
|
|
398
830
|
*/ async stop() {
|
|
399
831
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
400
|
-
this.peerDiscoveryService.off(PeerEvent.DISCOVERED, this.
|
|
832
|
+
this.peerDiscoveryService.off(PeerEvent.DISCOVERED, this.handlers.handleDiscoveredPeer);
|
|
401
833
|
// Send goodbyes to all peers
|
|
402
834
|
await Promise.all(this.libP2PNode.getPeers().map((peer)=>this.goodbyeAndDisconnectPeer(peer, GoodByeReason.SHUTDOWN)));
|
|
403
|
-
this.libP2PNode.removeEventListener(PeerEvent.CONNECTED, this.handleConnectedPeerEvent);
|
|
404
|
-
this.libP2PNode.removeEventListener(PeerEvent.DISCONNECTED, this.handleDisconnectedPeerEvent);
|
|
835
|
+
this.libP2PNode.removeEventListener(PeerEvent.CONNECTED, this.handlers.handleConnectedPeerEvent);
|
|
836
|
+
this.libP2PNode.removeEventListener(PeerEvent.DISCONNECTED, this.handlers.handleDisconnectedPeerEvent);
|
|
837
|
+
}
|
|
838
|
+
shouldTrustWithIdentity(peerId) {
|
|
839
|
+
return this.isProtectedPeer(peerId);
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Performs auth request verification from peer. An auth request is valid if requested by an authorized peer (a peer we trust).
|
|
843
|
+
*
|
|
844
|
+
* @param: _authRequest - Auth request (unused)
|
|
845
|
+
* @param: peerId - The ID of the peer that requested the auth handshake
|
|
846
|
+
*
|
|
847
|
+
* @returns: StatusMessage if peer is trusted
|
|
848
|
+
*
|
|
849
|
+
* @throws: If peer is unauthorized
|
|
850
|
+
* */ async handleAuthRequestFromPeer(_authRequest, peerId) {
|
|
851
|
+
if (!this.shouldTrustWithIdentity(peerId)) {
|
|
852
|
+
this.logger.warn(`Received auth request from untrusted peer ${peerId.toString()}`);
|
|
853
|
+
throw new Error('Unauthorised');
|
|
854
|
+
}
|
|
855
|
+
this.logger.debug(`Received auth request from trusted peer ${peerId.toString()}`);
|
|
856
|
+
return await this.createStatusMessage();
|
|
857
|
+
}
|
|
858
|
+
async updateAuthenticatedPeers() {
|
|
859
|
+
const registeredValidators = await this.epochCache.getRegisteredValidators();
|
|
860
|
+
const validatorSet = new Set(registeredValidators.map((v)=>v.toString()));
|
|
861
|
+
const peersToDelete = new Set();
|
|
862
|
+
const addressesToDelete = new Set();
|
|
863
|
+
for (const [peer, address] of this.authenticatedPeerIdToValidatorAddress.entries()){
|
|
864
|
+
const addressString = address.toString();
|
|
865
|
+
if (!validatorSet.has(addressString)) {
|
|
866
|
+
peersToDelete.add(peer);
|
|
867
|
+
addressesToDelete.add(addressString);
|
|
868
|
+
this.logger.info(`Removing authentication for peer ${peer.toString()} at address ${addressString} due to no longer being a registered validator`);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
for (const peer of peersToDelete){
|
|
872
|
+
this.authenticatedPeerIdToValidatorAddress.delete(peer);
|
|
873
|
+
}
|
|
874
|
+
for (const address of addressesToDelete){
|
|
875
|
+
this.authenticatedValidatorAddressToPeerId.delete(address);
|
|
876
|
+
}
|
|
405
877
|
}
|
|
406
878
|
}
|
|
407
|
-
_ts_decorate([
|
|
408
|
-
trackSpan('PeerManager.heartbeat')
|
|
409
|
-
], PeerManager.prototype, "heartbeat", null);
|
|
410
879
|
/**
|
|
411
880
|
* copied from github.com/ChainSafe/lodestar
|
|
412
881
|
* libp2p errors with extremely noisy errors here, which are deeply nested taking 30-50 lines.
|