@aztec/p2p 0.0.1-fake-c83136db25 → 0.0.2-commit.217f559981
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 +4 -4
- package/dest/client/factory.d.ts +7 -6
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +53 -15
- package/dest/client/index.d.ts +1 -1
- package/dest/client/interface.d.ts +58 -23
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +51 -74
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +613 -264
- 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 +95 -64
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +42 -21
- package/dest/enr/generate-enr.d.ts +1 -1
- 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/errors/tx-pool.error.d.ts +8 -0
- package/dest/errors/tx-pool.error.d.ts.map +1 -0
- package/dest/errors/tx-pool.error.js +9 -0
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +117 -45
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +441 -3
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
- 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 +530 -257
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts +234 -10
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +17 -13
- package/dest/mem_pools/index.d.ts +3 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/index.js +1 -1
- package/dest/mem_pools/instrumentation.d.ts +9 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +37 -10
- package/dest/mem_pools/interface.d.ts +6 -7
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +34 -58
- 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 +320 -335
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +32 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +112 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +157 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +52 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +122 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +78 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
- package/dest/mem_pools/tx_pool/index.d.ts +1 -2
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +6 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +17 -6
- 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 +30 -24
- package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
- package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +128 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +93 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +95 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +10 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +11 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +174 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +25 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +65 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +93 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +78 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +73 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
- package/dest/mem_pools/tx_pool_v2/index.d.ts +6 -0
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/index.js +5 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +211 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.js +9 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +97 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +152 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +108 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +355 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +60 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +161 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +77 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +896 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +7 -6
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +57 -24
- 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 +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
- package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/index.js +3 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.js +104 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +212 -0
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +3 -3
- 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 +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +3 -3
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +20 -6
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +4 -3
- 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 +4 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +15 -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 +7 -6
- package/dest/msg_validators/tx_validator/factory.d.ts +10 -4
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +22 -12
- 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 +3 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +11 -16
- package/dest/msg_validators/tx_validator/index.d.ts +2 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +4 -3
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +6 -4
- 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 +2 -2
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +23 -5
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +8 -8
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.js +2 -2
- 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 +2 -2
- 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 +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +1 -1
- package/dest/services/dummy_service.d.ts +28 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +51 -0
- package/dest/services/encoding.d.ts +25 -4
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +76 -6
- package/dest/services/gossipsub/index.d.ts +3 -0
- package/dest/services/gossipsub/index.d.ts.map +1 -0
- package/dest/services/gossipsub/index.js +2 -0
- package/dest/services/gossipsub/scoring.d.ts +21 -3
- package/dest/services/gossipsub/scoring.d.ts.map +1 -1
- package/dest/services/gossipsub/scoring.js +24 -7
- package/dest/services/gossipsub/topic_score_params.d.ts +173 -0
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
- package/dest/services/gossipsub/topic_score_params.js +346 -0
- package/dest/services/index.d.ts +2 -1
- package/dest/services/index.d.ts.map +1 -1
- package/dest/services/index.js +1 -0
- package/dest/services/libp2p/instrumentation.d.ts +3 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +36 -71
- package/dest/services/libp2p/libp2p_service.d.ts +116 -92
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +1153 -267
- package/dest/services/peer-manager/interface.d.ts +1 -1
- package/dest/services/peer-manager/metrics.d.ts +9 -2
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +39 -16
- package/dest/services/peer-manager/peer_manager.d.ts +2 -33
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +6 -12
- 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 +68 -4
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +48 -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 +562 -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 +46 -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 +34 -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 +130 -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 +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +22 -3
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +63 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +12 -0
- 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 +1 -1
- package/dest/services/reqresp/interface.d.ts +13 -2
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +16 -2
- 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 +2 -2
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.js +2 -2
- package/dest/services/reqresp/protocols/block.d.ts +1 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +3 -2
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +5 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +12 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +7 -5
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +27 -9
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +30 -9
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +60 -14
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/ping.d.ts +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +6 -5
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +7 -3
- package/dest/services/reqresp/protocols/tx.d.ts +8 -3
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +20 -0
- package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +2 -2
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts +6 -41
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +472 -51
- package/dest/services/reqresp/status.d.ts +2 -2
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/service.d.ts +55 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +22 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +56 -2
- package/dest/services/tx_collection/fast_tx_collection.d.ts +10 -12
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +71 -44
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_source.js +90 -0
- package/dest/services/tx_collection/index.d.ts +3 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +2 -0
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +11 -13
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +49 -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 +9 -6
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +61 -26
- package/dest/services/tx_collection/tx_collection.d.ts +31 -18
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +79 -7
- package/dest/services/tx_collection/tx_collection_sink.d.ts +19 -9
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +26 -29
- package/dest/services/tx_collection/tx_source.d.ts +8 -3
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +19 -2
- package/dest/services/tx_file_store/config.d.ts +16 -0
- package/dest/services/tx_file_store/config.d.ts.map +1 -0
- package/dest/services/tx_file_store/config.js +22 -0
- package/dest/services/tx_file_store/index.d.ts +4 -0
- package/dest/services/tx_file_store/index.d.ts.map +1 -0
- package/dest/services/tx_file_store/index.js +3 -0
- package/dest/services/tx_file_store/instrumentation.d.ts +15 -0
- package/dest/services/tx_file_store/instrumentation.d.ts.map +1 -0
- package/dest/services/tx_file_store/instrumentation.js +29 -0
- package/dest/services/tx_file_store/tx_file_store.d.ts +48 -0
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -0
- package/dest/services/tx_file_store/tx_file_store.js +152 -0
- package/dest/services/tx_provider.d.ts +6 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +16 -6
- package/dest/services/tx_provider_instrumentation.d.ts +5 -2
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +14 -14
- 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 +3 -1
- package/dest/test-helpers/index.d.ts.map +1 -1
- package/dest/test-helpers/index.js +2 -0
- package/dest/test-helpers/make-enrs.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +4 -4
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +31 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +103 -2
- package/dest/test-helpers/mock-tx-helpers.d.ts +2 -2
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -1
- package/dest/test-helpers/mock-tx-helpers.js +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -1
- 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 +163 -0
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
- package/dest/test-helpers/testbench-utils.js +366 -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 +221 -120
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts +51 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +226 -39
- package/dest/types/index.d.ts +1 -1
- package/dest/util.d.ts +3 -2
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +11 -2
- package/dest/versioning.d.ts +1 -1
- package/package.json +19 -18
- package/src/bootstrap/bootstrap.ts +7 -4
- package/src/client/factory.ts +98 -31
- package/src/client/interface.ts +77 -23
- package/src/client/p2p_client.ts +291 -309
- package/src/client/test/tx_proposal_collector/README.md +227 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +346 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
- package/src/config.ts +77 -30
- package/src/errors/attestation-pool.error.ts +13 -0
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +518 -45
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +618 -276
- package/src/mem_pools/attestation_pool/index.ts +9 -2
- package/src/mem_pools/attestation_pool/mocks.ts +22 -15
- package/src/mem_pools/index.ts +4 -1
- package/src/mem_pools/instrumentation.ts +48 -10
- package/src/mem_pools/interface.ts +5 -7
- package/src/mem_pools/tx_pool/README.md +270 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +372 -371
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +132 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +208 -0
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +162 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +93 -0
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
- package/src/mem_pools/tx_pool/index.ts +0 -1
- package/src/mem_pools/tx_pool/priority.ts +8 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +18 -5
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +23 -17
- package/src/mem_pools/tx_pool_v2/README.md +275 -0
- package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
- package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +160 -0
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +121 -0
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +122 -0
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +27 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +209 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +91 -0
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +90 -0
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +31 -0
- package/src/mem_pools/tx_pool_v2/index.ts +12 -0
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +242 -0
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +242 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +444 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +223 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1069 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +45 -32
- 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/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/aggregate_tx_validator.ts +2 -2
- package/src/msg_validators/tx_validator/archive_cache.ts +3 -3
- package/src/msg_validators/tx_validator/block_header_validator.ts +21 -8
- package/src/msg_validators/tx_validator/data_validator.ts +18 -6
- package/src/msg_validators/tx_validator/double_spend_validator.ts +15 -9
- package/src/msg_validators/tx_validator/factory.ts +67 -25
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +17 -28
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +19 -8
- package/src/msg_validators/tx_validator/phases_validator.ts +8 -4
- package/src/msg_validators/tx_validator/size_validator.ts +22 -0
- package/src/msg_validators/tx_validator/test_utils.ts +1 -1
- package/src/msg_validators/tx_validator/timestamp_validator.ts +30 -19
- package/src/msg_validators/tx_validator/tx_permitted_validator.ts +8 -3
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +8 -3
- package/src/services/data_store.ts +10 -7
- package/src/services/discv5/discV5_service.ts +1 -1
- package/src/services/dummy_service.ts +68 -1
- package/src/services/encoding.ts +83 -6
- package/src/services/gossipsub/README.md +641 -0
- package/src/services/gossipsub/index.ts +2 -0
- package/src/services/gossipsub/scoring.ts +29 -5
- package/src/services/gossipsub/topic_score_params.ts +487 -0
- package/src/services/index.ts +1 -0
- package/src/services/libp2p/instrumentation.ts +39 -71
- package/src/services/libp2p/libp2p_service.ts +865 -277
- package/src/services/peer-manager/metrics.ts +44 -16
- package/src/services/peer-manager/peer_manager.ts +7 -4
- package/src/services/peer-manager/peer_scoring.ts +70 -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 +53 -0
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +161 -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/connection-sampler/batch_connection_sampler.ts +65 -4
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +19 -1
- package/src/services/reqresp/constants.ts +14 -0
- package/src/services/reqresp/interface.ts +30 -2
- package/src/services/reqresp/metrics.ts +36 -27
- package/src/services/reqresp/protocols/auth.ts +2 -2
- package/src/services/reqresp/protocols/block.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +16 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +35 -12
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +75 -10
- package/src/services/reqresp/protocols/status.ts +16 -12
- package/src/services/reqresp/protocols/tx.ts +23 -2
- package/src/services/reqresp/reqresp.ts +80 -23
- package/src/services/service.ts +72 -4
- package/src/services/tx_collection/config.ts +84 -2
- package/src/services/tx_collection/fast_tx_collection.ts +96 -49
- package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
- package/src/services/tx_collection/file_store_tx_source.ts +117 -0
- package/src/services/tx_collection/index.ts +6 -0
- package/src/services/tx_collection/instrumentation.ts +11 -13
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +113 -0
- package/src/services/tx_collection/slow_tx_collection.ts +70 -36
- package/src/services/tx_collection/tx_collection.ts +122 -24
- package/src/services/tx_collection/tx_collection_sink.ts +30 -34
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_file_store/config.ts +37 -0
- package/src/services/tx_file_store/index.ts +3 -0
- package/src/services/tx_file_store/instrumentation.ts +36 -0
- package/src/services/tx_file_store/tx_file_store.ts +175 -0
- package/src/services/tx_provider.ts +27 -10
- package/src/services/tx_provider_instrumentation.ts +24 -14
- package/src/test-helpers/index.ts +2 -0
- package/src/test-helpers/make-test-p2p-clients.ts +3 -3
- package/src/test-helpers/mock-pubsub.ts +144 -4
- package/src/test-helpers/mock-tx-helpers.ts +1 -1
- package/src/test-helpers/reqresp-nodes.ts +3 -2
- package/src/test-helpers/test_tx_provider.ts +64 -0
- package/src/test-helpers/testbench-utils.ts +430 -0
- package/src/testbench/p2p_client_testbench_worker.ts +349 -117
- package/src/testbench/worker_client_manager.ts +304 -42
- package/src/util.ts +19 -3
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -28
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -174
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -23
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -175
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -79
- 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 -232
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -12
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +0 -70
- 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/attestation_pool/kv_attestation_pool.ts +0 -235
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -225
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -278
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -81
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -1,25 +1,389 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
function applyDecs2203RFactory() {
|
|
2
|
+
function createAddInitializerMethod(initializers, decoratorFinishedRef) {
|
|
3
|
+
return function addInitializer(initializer) {
|
|
4
|
+
assertNotFinished(decoratorFinishedRef, "addInitializer");
|
|
5
|
+
assertCallable(initializer, "An initializer");
|
|
6
|
+
initializers.push(initializer);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value) {
|
|
10
|
+
var kindStr;
|
|
11
|
+
switch(kind){
|
|
12
|
+
case 1:
|
|
13
|
+
kindStr = "accessor";
|
|
14
|
+
break;
|
|
15
|
+
case 2:
|
|
16
|
+
kindStr = "method";
|
|
17
|
+
break;
|
|
18
|
+
case 3:
|
|
19
|
+
kindStr = "getter";
|
|
20
|
+
break;
|
|
21
|
+
case 4:
|
|
22
|
+
kindStr = "setter";
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
kindStr = "field";
|
|
26
|
+
}
|
|
27
|
+
var ctx = {
|
|
28
|
+
kind: kindStr,
|
|
29
|
+
name: isPrivate ? "#" + name : name,
|
|
30
|
+
static: isStatic,
|
|
31
|
+
private: isPrivate,
|
|
32
|
+
metadata: metadata
|
|
33
|
+
};
|
|
34
|
+
var decoratorFinishedRef = {
|
|
35
|
+
v: false
|
|
36
|
+
};
|
|
37
|
+
ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
|
|
38
|
+
var get, set;
|
|
39
|
+
if (kind === 0) {
|
|
40
|
+
if (isPrivate) {
|
|
41
|
+
get = desc.get;
|
|
42
|
+
set = desc.set;
|
|
43
|
+
} else {
|
|
44
|
+
get = function() {
|
|
45
|
+
return this[name];
|
|
46
|
+
};
|
|
47
|
+
set = function(v) {
|
|
48
|
+
this[name] = v;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
} else if (kind === 2) {
|
|
52
|
+
get = function() {
|
|
53
|
+
return desc.value;
|
|
54
|
+
};
|
|
55
|
+
} else {
|
|
56
|
+
if (kind === 1 || kind === 3) {
|
|
57
|
+
get = function() {
|
|
58
|
+
return desc.get.call(this);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (kind === 1 || kind === 4) {
|
|
62
|
+
set = function(v) {
|
|
63
|
+
desc.set.call(this, v);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
ctx.access = get && set ? {
|
|
68
|
+
get: get,
|
|
69
|
+
set: set
|
|
70
|
+
} : get ? {
|
|
71
|
+
get: get
|
|
72
|
+
} : {
|
|
73
|
+
set: set
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
return dec(value, ctx);
|
|
77
|
+
} finally{
|
|
78
|
+
decoratorFinishedRef.v = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function assertNotFinished(decoratorFinishedRef, fnName) {
|
|
82
|
+
if (decoratorFinishedRef.v) {
|
|
83
|
+
throw new Error("attempted to call " + fnName + " after decoration was finished");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function assertCallable(fn, hint) {
|
|
87
|
+
if (typeof fn !== "function") {
|
|
88
|
+
throw new TypeError(hint + " must be a function");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function assertValidReturnValue(kind, value) {
|
|
92
|
+
var type = typeof value;
|
|
93
|
+
if (kind === 1) {
|
|
94
|
+
if (type !== "object" || value === null) {
|
|
95
|
+
throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
|
|
96
|
+
}
|
|
97
|
+
if (value.get !== undefined) {
|
|
98
|
+
assertCallable(value.get, "accessor.get");
|
|
99
|
+
}
|
|
100
|
+
if (value.set !== undefined) {
|
|
101
|
+
assertCallable(value.set, "accessor.set");
|
|
102
|
+
}
|
|
103
|
+
if (value.init !== undefined) {
|
|
104
|
+
assertCallable(value.init, "accessor.init");
|
|
105
|
+
}
|
|
106
|
+
} else if (type !== "function") {
|
|
107
|
+
var hint;
|
|
108
|
+
if (kind === 0) {
|
|
109
|
+
hint = "field";
|
|
110
|
+
} else if (kind === 10) {
|
|
111
|
+
hint = "class";
|
|
112
|
+
} else {
|
|
113
|
+
hint = "method";
|
|
114
|
+
}
|
|
115
|
+
throw new TypeError(hint + " decorators must return a function or void 0");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata) {
|
|
119
|
+
var decs = decInfo[0];
|
|
120
|
+
var desc, init, value;
|
|
121
|
+
if (isPrivate) {
|
|
122
|
+
if (kind === 0 || kind === 1) {
|
|
123
|
+
desc = {
|
|
124
|
+
get: decInfo[3],
|
|
125
|
+
set: decInfo[4]
|
|
126
|
+
};
|
|
127
|
+
} else if (kind === 3) {
|
|
128
|
+
desc = {
|
|
129
|
+
get: decInfo[3]
|
|
130
|
+
};
|
|
131
|
+
} else if (kind === 4) {
|
|
132
|
+
desc = {
|
|
133
|
+
set: decInfo[3]
|
|
134
|
+
};
|
|
135
|
+
} else {
|
|
136
|
+
desc = {
|
|
137
|
+
value: decInfo[3]
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
} else if (kind !== 0) {
|
|
141
|
+
desc = Object.getOwnPropertyDescriptor(base, name);
|
|
142
|
+
}
|
|
143
|
+
if (kind === 1) {
|
|
144
|
+
value = {
|
|
145
|
+
get: desc.get,
|
|
146
|
+
set: desc.set
|
|
147
|
+
};
|
|
148
|
+
} else if (kind === 2) {
|
|
149
|
+
value = desc.value;
|
|
150
|
+
} else if (kind === 3) {
|
|
151
|
+
value = desc.get;
|
|
152
|
+
} else if (kind === 4) {
|
|
153
|
+
value = desc.set;
|
|
154
|
+
}
|
|
155
|
+
var newValue, get, set;
|
|
156
|
+
if (typeof decs === "function") {
|
|
157
|
+
newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
158
|
+
if (newValue !== void 0) {
|
|
159
|
+
assertValidReturnValue(kind, newValue);
|
|
160
|
+
if (kind === 0) {
|
|
161
|
+
init = newValue;
|
|
162
|
+
} else if (kind === 1) {
|
|
163
|
+
init = newValue.init;
|
|
164
|
+
get = newValue.get || value.get;
|
|
165
|
+
set = newValue.set || value.set;
|
|
166
|
+
value = {
|
|
167
|
+
get: get,
|
|
168
|
+
set: set
|
|
169
|
+
};
|
|
170
|
+
} else {
|
|
171
|
+
value = newValue;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
for(var i = decs.length - 1; i >= 0; i--){
|
|
176
|
+
var dec = decs[i];
|
|
177
|
+
newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
178
|
+
if (newValue !== void 0) {
|
|
179
|
+
assertValidReturnValue(kind, newValue);
|
|
180
|
+
var newInit;
|
|
181
|
+
if (kind === 0) {
|
|
182
|
+
newInit = newValue;
|
|
183
|
+
} else if (kind === 1) {
|
|
184
|
+
newInit = newValue.init;
|
|
185
|
+
get = newValue.get || value.get;
|
|
186
|
+
set = newValue.set || value.set;
|
|
187
|
+
value = {
|
|
188
|
+
get: get,
|
|
189
|
+
set: set
|
|
190
|
+
};
|
|
191
|
+
} else {
|
|
192
|
+
value = newValue;
|
|
193
|
+
}
|
|
194
|
+
if (newInit !== void 0) {
|
|
195
|
+
if (init === void 0) {
|
|
196
|
+
init = newInit;
|
|
197
|
+
} else if (typeof init === "function") {
|
|
198
|
+
init = [
|
|
199
|
+
init,
|
|
200
|
+
newInit
|
|
201
|
+
];
|
|
202
|
+
} else {
|
|
203
|
+
init.push(newInit);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (kind === 0 || kind === 1) {
|
|
210
|
+
if (init === void 0) {
|
|
211
|
+
init = function(instance, init) {
|
|
212
|
+
return init;
|
|
213
|
+
};
|
|
214
|
+
} else if (typeof init !== "function") {
|
|
215
|
+
var ownInitializers = init;
|
|
216
|
+
init = function(instance, init) {
|
|
217
|
+
var value = init;
|
|
218
|
+
for(var i = 0; i < ownInitializers.length; i++){
|
|
219
|
+
value = ownInitializers[i].call(instance, value);
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
};
|
|
223
|
+
} else {
|
|
224
|
+
var originalInitializer = init;
|
|
225
|
+
init = function(instance, init) {
|
|
226
|
+
return originalInitializer.call(instance, init);
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
ret.push(init);
|
|
230
|
+
}
|
|
231
|
+
if (kind !== 0) {
|
|
232
|
+
if (kind === 1) {
|
|
233
|
+
desc.get = value.get;
|
|
234
|
+
desc.set = value.set;
|
|
235
|
+
} else if (kind === 2) {
|
|
236
|
+
desc.value = value;
|
|
237
|
+
} else if (kind === 3) {
|
|
238
|
+
desc.get = value;
|
|
239
|
+
} else if (kind === 4) {
|
|
240
|
+
desc.set = value;
|
|
241
|
+
}
|
|
242
|
+
if (isPrivate) {
|
|
243
|
+
if (kind === 1) {
|
|
244
|
+
ret.push(function(instance, args) {
|
|
245
|
+
return value.get.call(instance, args);
|
|
246
|
+
});
|
|
247
|
+
ret.push(function(instance, args) {
|
|
248
|
+
return value.set.call(instance, args);
|
|
249
|
+
});
|
|
250
|
+
} else if (kind === 2) {
|
|
251
|
+
ret.push(value);
|
|
252
|
+
} else {
|
|
253
|
+
ret.push(function(instance, args) {
|
|
254
|
+
return value.call(instance, args);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
Object.defineProperty(base, name, desc);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function applyMemberDecs(Class, decInfos, metadata) {
|
|
263
|
+
var ret = [];
|
|
264
|
+
var protoInitializers;
|
|
265
|
+
var staticInitializers;
|
|
266
|
+
var existingProtoNonFields = new Map();
|
|
267
|
+
var existingStaticNonFields = new Map();
|
|
268
|
+
for(var i = 0; i < decInfos.length; i++){
|
|
269
|
+
var decInfo = decInfos[i];
|
|
270
|
+
if (!Array.isArray(decInfo)) continue;
|
|
271
|
+
var kind = decInfo[1];
|
|
272
|
+
var name = decInfo[2];
|
|
273
|
+
var isPrivate = decInfo.length > 3;
|
|
274
|
+
var isStatic = kind >= 5;
|
|
275
|
+
var base;
|
|
276
|
+
var initializers;
|
|
277
|
+
if (isStatic) {
|
|
278
|
+
base = Class;
|
|
279
|
+
kind = kind - 5;
|
|
280
|
+
staticInitializers = staticInitializers || [];
|
|
281
|
+
initializers = staticInitializers;
|
|
282
|
+
} else {
|
|
283
|
+
base = Class.prototype;
|
|
284
|
+
protoInitializers = protoInitializers || [];
|
|
285
|
+
initializers = protoInitializers;
|
|
286
|
+
}
|
|
287
|
+
if (kind !== 0 && !isPrivate) {
|
|
288
|
+
var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
|
|
289
|
+
var existingKind = existingNonFields.get(name) || 0;
|
|
290
|
+
if (existingKind === true || existingKind === 3 && kind !== 4 || existingKind === 4 && kind !== 3) {
|
|
291
|
+
throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
|
|
292
|
+
} else if (!existingKind && kind > 2) {
|
|
293
|
+
existingNonFields.set(name, kind);
|
|
294
|
+
} else {
|
|
295
|
+
existingNonFields.set(name, true);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
|
|
299
|
+
}
|
|
300
|
+
pushInitializers(ret, protoInitializers);
|
|
301
|
+
pushInitializers(ret, staticInitializers);
|
|
302
|
+
return ret;
|
|
303
|
+
}
|
|
304
|
+
function pushInitializers(ret, initializers) {
|
|
305
|
+
if (initializers) {
|
|
306
|
+
ret.push(function(instance) {
|
|
307
|
+
for(var i = 0; i < initializers.length; i++){
|
|
308
|
+
initializers[i].call(instance);
|
|
309
|
+
}
|
|
310
|
+
return instance;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function applyClassDecs(targetClass, classDecs, metadata) {
|
|
315
|
+
if (classDecs.length > 0) {
|
|
316
|
+
var initializers = [];
|
|
317
|
+
var newClass = targetClass;
|
|
318
|
+
var name = targetClass.name;
|
|
319
|
+
for(var i = classDecs.length - 1; i >= 0; i--){
|
|
320
|
+
var decoratorFinishedRef = {
|
|
321
|
+
v: false
|
|
322
|
+
};
|
|
323
|
+
try {
|
|
324
|
+
var nextNewClass = classDecs[i](newClass, {
|
|
325
|
+
kind: "class",
|
|
326
|
+
name: name,
|
|
327
|
+
addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
|
|
328
|
+
metadata
|
|
329
|
+
});
|
|
330
|
+
} finally{
|
|
331
|
+
decoratorFinishedRef.v = true;
|
|
332
|
+
}
|
|
333
|
+
if (nextNewClass !== undefined) {
|
|
334
|
+
assertValidReturnValue(10, nextNewClass);
|
|
335
|
+
newClass = nextNewClass;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return [
|
|
339
|
+
defineMetadata(newClass, metadata),
|
|
340
|
+
function() {
|
|
341
|
+
for(var i = 0; i < initializers.length; i++){
|
|
342
|
+
initializers[i].call(newClass);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
];
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function defineMetadata(Class, metadata) {
|
|
349
|
+
return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
|
|
350
|
+
configurable: true,
|
|
351
|
+
enumerable: true,
|
|
352
|
+
value: metadata
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return function applyDecs2203R(targetClass, memberDecs, classDecs, parentClass) {
|
|
356
|
+
if (parentClass !== void 0) {
|
|
357
|
+
var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
|
|
358
|
+
}
|
|
359
|
+
var metadata = Object.create(parentMetadata === void 0 ? null : parentMetadata);
|
|
360
|
+
var e = applyMemberDecs(targetClass, memberDecs, metadata);
|
|
361
|
+
if (!classDecs.length) defineMetadata(targetClass, metadata);
|
|
362
|
+
return {
|
|
363
|
+
e: e,
|
|
364
|
+
get c () {
|
|
365
|
+
return applyClassDecs(targetClass, classDecs, metadata);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
371
|
+
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
6
372
|
}
|
|
7
|
-
|
|
8
|
-
import {
|
|
373
|
+
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _initProto;
|
|
374
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
9
375
|
import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
10
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
11
376
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
12
377
|
import { Timer } from '@aztec/foundation/timer';
|
|
13
|
-
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
14
378
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
15
379
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
16
|
-
import {
|
|
380
|
+
import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PClientType, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForClientAndConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
|
|
17
381
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
18
382
|
import { Tx } from '@aztec/stdlib/tx';
|
|
19
383
|
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
20
|
-
import { Attributes, OtelMetricsAdapter, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
384
|
+
import { Attributes, OtelMetricsAdapter, SpanStatusCode, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
21
385
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
22
|
-
import { createPeerScoreParams
|
|
386
|
+
import { createPeerScoreParams } from '@chainsafe/libp2p-gossipsub/score';
|
|
23
387
|
import { SignaturePolicy } from '@chainsafe/libp2p-gossipsub/types';
|
|
24
388
|
import { noise } from '@chainsafe/libp2p-noise';
|
|
25
389
|
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
@@ -30,26 +394,51 @@ import { mplex } from '@libp2p/mplex';
|
|
|
30
394
|
import { tcp } from '@libp2p/tcp';
|
|
31
395
|
import { ENR } from '@nethermindeth/enr';
|
|
32
396
|
import { createLibp2p } from 'libp2p';
|
|
33
|
-
import {
|
|
397
|
+
import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, DoubleSpendTxValidator, FishermanAttestationValidator, getDefaultAllowedSetupFunctions } from '../../msg_validators/index.js';
|
|
34
398
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
35
|
-
import {
|
|
36
|
-
import { createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
37
|
-
import { AggregateTxValidator, DataTxValidator, DoubleSpendTxValidator, MetadataTxValidator, TxProofValidator } from '../../msg_validators/tx_validator/index.js';
|
|
399
|
+
import { createTxMessageValidators, createTxReqRespValidator } from '../../msg_validators/tx_validator/factory.js';
|
|
38
400
|
import { GossipSubEvent } from '../../types/index.js';
|
|
39
401
|
import { convertToMultiaddr } from '../../util.js';
|
|
40
402
|
import { getVersions } from '../../versioning.js';
|
|
41
403
|
import { AztecDatastore } from '../data_store.js';
|
|
42
404
|
import { DiscV5Service } from '../discv5/discV5_service.js';
|
|
43
405
|
import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
44
|
-
import { gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
406
|
+
import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
407
|
+
import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
|
|
45
408
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
46
409
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
47
|
-
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError } from '../reqresp/
|
|
48
|
-
import { reqRespBlockTxsHandler } from '../reqresp/
|
|
49
|
-
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
|
|
50
|
-
import { pingHandler, reqRespBlockHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/protocols/index.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';
|
|
51
412
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
52
413
|
import { P2PInstrumentation } from './instrumentation.js';
|
|
414
|
+
_dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
|
|
415
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString()
|
|
416
|
+
})), _dec1 = trackSpan('Libp2pService.validateAndStoreBlockProposal', (_peerId, block)=>({
|
|
417
|
+
[Attributes.BLOCK_NUMBER]: block.blockNumber.toString(),
|
|
418
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber.toString()
|
|
419
|
+
})), _dec2 = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
|
|
420
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber,
|
|
421
|
+
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
422
|
+
[Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then((i)=>i.toString())
|
|
423
|
+
})), _dec3 = trackSpan('Libp2pService.validateAndStoreCheckpointProposal', (_peerId, checkpoint)=>({
|
|
424
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString()
|
|
425
|
+
})), _dec4 = trackSpan('Libp2pService.processValidCheckpointProposal', async (checkpoint)=>({
|
|
426
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber,
|
|
427
|
+
[Attributes.BLOCK_ARCHIVE]: checkpoint.archive.toString(),
|
|
428
|
+
[Attributes.P2P_ID]: await checkpoint.p2pMessageLoggingIdentifier().then((i)=>i.toString())
|
|
429
|
+
})), _dec5 = trackSpan('Libp2pService.validateRequestedBlockTxs', (request)=>({
|
|
430
|
+
[Attributes.BLOCK_ARCHIVE]: request.archiveRoot.toString()
|
|
431
|
+
})), _dec6 = trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx)=>({
|
|
432
|
+
[Attributes.TX_HASH]: requestedTxHash.toString()
|
|
433
|
+
})), _dec7 = trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock)=>({
|
|
434
|
+
[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
|
+
}));
|
|
53
442
|
/**
|
|
54
443
|
* Lib P2P implementation of the P2PService interface.
|
|
55
444
|
*/ export class LibP2PService extends WithTracer {
|
|
@@ -64,45 +453,119 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
64
453
|
epochCache;
|
|
65
454
|
proofVerifier;
|
|
66
455
|
worldStateSynchronizer;
|
|
67
|
-
|
|
68
|
-
|
|
456
|
+
static{
|
|
457
|
+
({ e: [_initProto] } = _apply_decs_2203_r(this, [
|
|
458
|
+
[
|
|
459
|
+
_dec,
|
|
460
|
+
2,
|
|
461
|
+
"validateAndStoreCheckpointAttestation"
|
|
462
|
+
],
|
|
463
|
+
[
|
|
464
|
+
_dec1,
|
|
465
|
+
2,
|
|
466
|
+
"validateAndStoreBlockProposal"
|
|
467
|
+
],
|
|
468
|
+
[
|
|
469
|
+
_dec2,
|
|
470
|
+
2,
|
|
471
|
+
"processValidBlockProposal"
|
|
472
|
+
],
|
|
473
|
+
[
|
|
474
|
+
_dec3,
|
|
475
|
+
2,
|
|
476
|
+
"validateAndStoreCheckpointProposal"
|
|
477
|
+
],
|
|
478
|
+
[
|
|
479
|
+
_dec4,
|
|
480
|
+
2,
|
|
481
|
+
"processValidCheckpointProposal"
|
|
482
|
+
],
|
|
483
|
+
[
|
|
484
|
+
_dec5,
|
|
485
|
+
2,
|
|
486
|
+
"validateRequestedBlockTxs"
|
|
487
|
+
],
|
|
488
|
+
[
|
|
489
|
+
_dec6,
|
|
490
|
+
2,
|
|
491
|
+
"validateRequestedTxs"
|
|
492
|
+
],
|
|
493
|
+
[
|
|
494
|
+
_dec7,
|
|
495
|
+
2,
|
|
496
|
+
"validateRequestedBlock"
|
|
497
|
+
],
|
|
498
|
+
[
|
|
499
|
+
_dec8,
|
|
500
|
+
2,
|
|
501
|
+
"validatePropagatedTx"
|
|
502
|
+
],
|
|
503
|
+
[
|
|
504
|
+
_dec9,
|
|
505
|
+
2,
|
|
506
|
+
"validateCheckpointAttestation"
|
|
507
|
+
]
|
|
508
|
+
], []));
|
|
509
|
+
}
|
|
69
510
|
discoveryRunningPromise;
|
|
70
511
|
msgIdSeenValidators;
|
|
71
512
|
// Message validators
|
|
72
|
-
attestationValidator;
|
|
73
513
|
blockProposalValidator;
|
|
514
|
+
checkpointProposalValidator;
|
|
515
|
+
checkpointAttestationValidator;
|
|
74
516
|
protocolVersion;
|
|
75
517
|
topicStrings;
|
|
76
518
|
feesCache;
|
|
519
|
+
/** Callback invoked when a duplicate proposal is detected (triggers slashing). */ duplicateProposalCallback;
|
|
520
|
+
/** Callback invoked when a duplicate attestation is detected (triggers slashing). */ duplicateAttestationCallback;
|
|
77
521
|
/**
|
|
78
522
|
* Callback for when a block is received from a peer.
|
|
79
523
|
* @param block - The block received from the peer.
|
|
80
524
|
* @returns The attestation for the block, if any.
|
|
81
525
|
*/ blockReceivedCallback;
|
|
526
|
+
/**
|
|
527
|
+
* Callback for when a checkpoint proposal is received from a peer.
|
|
528
|
+
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
529
|
+
* @returns The attestations for the checkpoint, if any.
|
|
530
|
+
*/ checkpointReceivedCallback;
|
|
82
531
|
gossipSubEventHandler;
|
|
83
532
|
instrumentation;
|
|
533
|
+
telemetry;
|
|
534
|
+
logger;
|
|
84
535
|
constructor(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
|
|
85
|
-
super(telemetry, 'LibP2PService'), this.clientType = clientType, 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.
|
|
536
|
+
super(telemetry, 'LibP2PService'), this.clientType = clientType, 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
|
+
this.telemetry = telemetry;
|
|
538
|
+
// Create child logger with fisherman prefix if in fisherman mode
|
|
539
|
+
this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
|
|
86
540
|
this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
|
|
87
541
|
this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
88
542
|
this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
89
|
-
this.msgIdSeenValidators[TopicType.
|
|
543
|
+
this.msgIdSeenValidators[TopicType.checkpoint_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
544
|
+
this.msgIdSeenValidators[TopicType.checkpoint_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
90
545
|
const versions = getVersions(config);
|
|
91
546
|
this.protocolVersion = compressComponentVersions(versions);
|
|
92
547
|
logger.info(`Started libp2p service with protocol version ${this.protocolVersion}`);
|
|
93
548
|
this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
|
|
94
549
|
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
95
|
-
this.topicStrings[TopicType.
|
|
96
|
-
this.
|
|
550
|
+
this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
|
|
551
|
+
this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
|
|
97
552
|
this.blockProposalValidator = new BlockProposalValidator(epochCache, {
|
|
98
553
|
txsPermitted: !config.disableTransactions
|
|
99
554
|
});
|
|
555
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
|
|
556
|
+
txsPermitted: !config.disableTransactions
|
|
557
|
+
});
|
|
558
|
+
this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new CheckpointAttestationValidator(epochCache);
|
|
100
559
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
101
560
|
this.blockReceivedCallback = async (block)=>{
|
|
102
|
-
this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber
|
|
103
|
-
p2pMessageIdentifier: await block.
|
|
561
|
+
this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`, {
|
|
562
|
+
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier()
|
|
104
563
|
});
|
|
105
|
-
return
|
|
564
|
+
return false;
|
|
565
|
+
};
|
|
566
|
+
this.checkpointReceivedCallback = (checkpoint)=>{
|
|
567
|
+
this.logger.debug(`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`);
|
|
568
|
+
return Promise.resolve(undefined);
|
|
106
569
|
};
|
|
107
570
|
}
|
|
108
571
|
updateConfig(config) {
|
|
@@ -118,8 +581,8 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
118
581
|
const { p2pPort, maxPeerCount, listenAddress } = config;
|
|
119
582
|
const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
|
|
120
583
|
const datastore = new AztecDatastore(peerStore);
|
|
121
|
-
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry);
|
|
122
|
-
const peerDiscoveryService = new DiscV5Service(peerId, config, packageVersion, telemetry, createLogger(`${logger.module}:discv5_service
|
|
584
|
+
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry, logger.getBindings());
|
|
585
|
+
const peerDiscoveryService = new DiscV5Service(peerId, config, packageVersion, telemetry, createLogger(`${logger.module}:discv5_service`, logger.getBindings()));
|
|
123
586
|
// Seed libp2p's bootstrap discovery with private and trusted peers
|
|
124
587
|
const bootstrapNodes = [
|
|
125
588
|
...config.privatePeers,
|
|
@@ -133,9 +596,6 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
133
596
|
}
|
|
134
597
|
const versions = getVersions(config);
|
|
135
598
|
const protocolVersion = compressComponentVersions(versions);
|
|
136
|
-
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
137
|
-
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
138
|
-
const blockAttestationTopic = createTopicString(TopicType.block_attestation, protocolVersion);
|
|
139
599
|
const preferredPeersEnrs = config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
140
600
|
const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
|
|
141
601
|
const peerId = await enr.peerId();
|
|
@@ -153,6 +613,15 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
153
613
|
const announceTcpMultiaddr = config.p2pIp ? [
|
|
154
614
|
convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')
|
|
155
615
|
] : [];
|
|
616
|
+
// Create dynamic topic score params based on network configuration
|
|
617
|
+
const l1Constants = epochCache.getL1Constants();
|
|
618
|
+
const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
|
|
619
|
+
slotDurationMs: l1Constants.slotDuration * 1000,
|
|
620
|
+
heartbeatIntervalMs: config.gossipsubInterval,
|
|
621
|
+
targetCommitteeSize: l1Constants.targetCommitteeSize,
|
|
622
|
+
blockDurationMs: config.blockDurationMs,
|
|
623
|
+
expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot
|
|
624
|
+
});
|
|
156
625
|
const node = await createLibp2p({
|
|
157
626
|
start: false,
|
|
158
627
|
peerId,
|
|
@@ -253,36 +722,24 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
253
722
|
scoreParams: createPeerScoreParams({
|
|
254
723
|
// IPColocation factor can be disabled for local testing - default to -5
|
|
255
724
|
IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
|
|
256
|
-
topics:
|
|
257
|
-
[txTopic]: createTopicScoreParams({
|
|
258
|
-
topicWeight: 1,
|
|
259
|
-
invalidMessageDeliveriesWeight: -20,
|
|
260
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
261
|
-
}),
|
|
262
|
-
[blockAttestationTopic]: createTopicScoreParams({
|
|
263
|
-
topicWeight: 1,
|
|
264
|
-
invalidMessageDeliveriesWeight: -20,
|
|
265
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
266
|
-
}),
|
|
267
|
-
[blockProposalTopic]: createTopicScoreParams({
|
|
268
|
-
topicWeight: 1,
|
|
269
|
-
invalidMessageDeliveriesWeight: -20,
|
|
270
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
271
|
-
})
|
|
272
|
-
}
|
|
725
|
+
topics: topicScoreParams
|
|
273
726
|
})
|
|
274
727
|
}),
|
|
275
728
|
components: (components)=>({
|
|
276
729
|
connectionManager: components.connectionManager
|
|
277
730
|
})
|
|
278
731
|
},
|
|
279
|
-
logger: createLibp2pComponentLogger(logger.module)
|
|
732
|
+
logger: createLibp2pComponentLogger(logger.module, logger.getBindings())
|
|
280
733
|
});
|
|
281
|
-
const peerScoring = new PeerScoring(config);
|
|
734
|
+
const peerScoring = new PeerScoring(config, telemetry);
|
|
282
735
|
const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
|
|
283
736
|
const peerManager = new PeerManager(node, peerDiscoveryService, config, telemetry, createLogger(`${logger.module}:peer_manager`), peerScoring, reqresp, worldStateSynchronizer, protocolVersion, epochCache);
|
|
284
|
-
//
|
|
285
|
-
|
|
737
|
+
// Configure application-specific scoring for gossipsub.
|
|
738
|
+
// The weight scales app score to align with gossipsub thresholds:
|
|
739
|
+
// - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
|
|
740
|
+
// - Ban (-100) × 10 = -1000 = publishThreshold (cannot publish)
|
|
741
|
+
// Note: positive topic scores can offset penalties, so alignment is best-effort.
|
|
742
|
+
node.services.pubsub.score.params.appSpecificWeight = APP_SPECIFIC_WEIGHT;
|
|
286
743
|
node.services.pubsub.score.params.appSpecificScore = (peerId)=>peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
287
744
|
return new LibP2PService(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
|
|
288
745
|
}
|
|
@@ -300,17 +757,6 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
300
757
|
throw new Error('Announce address not provided.');
|
|
301
758
|
}
|
|
302
759
|
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
303
|
-
// Start job queue, peer discovery service and libp2p node
|
|
304
|
-
this.jobQueue.start();
|
|
305
|
-
await this.peerManager.initializePeers();
|
|
306
|
-
if (!this.config.p2pDiscoveryDisabled) {
|
|
307
|
-
await this.peerDiscoveryService.start();
|
|
308
|
-
}
|
|
309
|
-
await this.node.start();
|
|
310
|
-
// Subscribe to standard GossipSub topics by default
|
|
311
|
-
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
|
|
312
|
-
this.subscribeToTopic(this.topicStrings[topic]);
|
|
313
|
-
}
|
|
314
760
|
// Create request response protocol handlers
|
|
315
761
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
316
762
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
@@ -322,27 +768,37 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
322
768
|
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
323
769
|
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this)
|
|
324
770
|
};
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
|
|
771
|
+
if (!this.config.disableTransactions) {
|
|
772
|
+
const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.archiver, this.mempools.txPool);
|
|
328
773
|
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
329
774
|
}
|
|
330
775
|
if (!this.config.disableTransactions) {
|
|
331
776
|
requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this);
|
|
332
777
|
}
|
|
333
|
-
// add GossipSub listener
|
|
334
|
-
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
335
|
-
// Start running promise for peer discovery
|
|
336
|
-
this.discoveryRunningPromise = new RunningPromise(()=>this.peerManager.heartbeat(), this.logger, this.config.peerCheckIntervalMS);
|
|
337
|
-
this.discoveryRunningPromise.start();
|
|
338
778
|
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
339
779
|
const reqrespSubProtocolValidators = {
|
|
340
780
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
341
|
-
// TODO(#11336): A request validator for blocks
|
|
342
781
|
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
343
|
-
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this)
|
|
782
|
+
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
783
|
+
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this)
|
|
344
784
|
};
|
|
785
|
+
await this.peerManager.initializePeers();
|
|
345
786
|
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
787
|
+
await this.node.start();
|
|
788
|
+
// Subscribe to standard GossipSub topics by default
|
|
789
|
+
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
|
|
790
|
+
this.subscribeToTopic(this.topicStrings[topic]);
|
|
791
|
+
}
|
|
792
|
+
// add GossipSub listener
|
|
793
|
+
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
794
|
+
// Start running promise for peer discovery and metrics collection
|
|
795
|
+
if (!this.config.p2pDiscoveryDisabled) {
|
|
796
|
+
await this.peerDiscoveryService.start();
|
|
797
|
+
}
|
|
798
|
+
this.discoveryRunningPromise = new RunningPromise(async ()=>{
|
|
799
|
+
await this.peerManager.heartbeat();
|
|
800
|
+
}, this.logger, this.config.peerCheckIntervalMS);
|
|
801
|
+
this.discoveryRunningPromise.start();
|
|
346
802
|
this.logger.info(`Started P2P service`, {
|
|
347
803
|
listen: this.config.listenAddress,
|
|
348
804
|
port: this.config.p2pPort,
|
|
@@ -359,8 +815,6 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
359
815
|
// Stop peer manager
|
|
360
816
|
this.logger.debug('Stopping peer manager...');
|
|
361
817
|
await this.peerManager.stop();
|
|
362
|
-
this.logger.debug('Stopping job queue...');
|
|
363
|
-
await this.jobQueue.end();
|
|
364
818
|
this.logger.debug('Stopping running promise...');
|
|
365
819
|
await this.discoveryRunningPromise?.stop();
|
|
366
820
|
this.logger.debug('Stopping peer discovery service...');
|
|
@@ -380,6 +834,9 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
380
834
|
getPeers(includePending) {
|
|
381
835
|
return this.peerManager.getPeers(includePending);
|
|
382
836
|
}
|
|
837
|
+
getGossipMeshPeerCount(topicType) {
|
|
838
|
+
return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
|
|
839
|
+
}
|
|
383
840
|
handleGossipSubEvent(e) {
|
|
384
841
|
this.logger.trace(`Received PUBSUB message.`);
|
|
385
842
|
const safeJob = async ()=>{
|
|
@@ -399,6 +856,9 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
399
856
|
*/ sendBatchRequest(protocol, requests, pinnedPeerId) {
|
|
400
857
|
return this.reqresp.sendBatchRequest(protocol, requests, pinnedPeerId);
|
|
401
858
|
}
|
|
859
|
+
sendRequestToPeer(peerId, subProtocol, payload, dialTimeout) {
|
|
860
|
+
return this.reqresp.sendRequestToPeer(peerId, subProtocol, payload, dialTimeout);
|
|
861
|
+
}
|
|
402
862
|
/**
|
|
403
863
|
* Get the ENR of the node
|
|
404
864
|
* @returns The ENR of the node
|
|
@@ -408,6 +868,22 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
408
868
|
registerBlockReceivedCallback(callback) {
|
|
409
869
|
this.blockReceivedCallback = callback;
|
|
410
870
|
}
|
|
871
|
+
registerCheckpointReceivedCallback(callback) {
|
|
872
|
+
this.checkpointReceivedCallback = callback;
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Registers a callback to be invoked when a duplicate proposal is detected.
|
|
876
|
+
* This callback is triggered on the first duplicate (when count goes from 1 to 2).
|
|
877
|
+
*/ registerDuplicateProposalCallback(callback) {
|
|
878
|
+
this.duplicateProposalCallback = callback;
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Registers a callback to be invoked when a duplicate attestation is detected.
|
|
882
|
+
* A validator signing attestations for different proposals at the same slot.
|
|
883
|
+
* This callback is triggered on the first duplicate (when count goes from 1 to 2).
|
|
884
|
+
*/ registerDuplicateAttestationCallback(callback) {
|
|
885
|
+
this.duplicateAttestationCallback = callback;
|
|
886
|
+
}
|
|
411
887
|
/**
|
|
412
888
|
* Subscribes to a topic.
|
|
413
889
|
* @param topic - The topic to subscribe to.
|
|
@@ -426,22 +902,31 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
426
902
|
if (!this.node.services.pubsub) {
|
|
427
903
|
throw new Error('Pubsub service not available.');
|
|
428
904
|
}
|
|
429
|
-
const
|
|
905
|
+
const isBlockProposal = topic === this.topicStrings[TopicType.block_proposal];
|
|
906
|
+
const traceContext = this.config.debugP2PInstrumentMessages && isBlockProposal ? this.telemetry.getTraceContext() : undefined;
|
|
907
|
+
const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages, traceContext);
|
|
430
908
|
const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
|
|
431
909
|
return result.recipients.length;
|
|
432
910
|
}
|
|
433
|
-
|
|
911
|
+
/**
|
|
912
|
+
* Checks if this message has already been seen, based on its msgId computed from hashing the message data.
|
|
913
|
+
* Note that we do not rely on the seenCache from gossipsub since we want to keep a longer history of seen
|
|
914
|
+
* messages to avoid tx echoes across the network.
|
|
915
|
+
*/ preValidateReceivedMessage(msg, msgId, source) {
|
|
434
916
|
let topicType;
|
|
435
917
|
switch(msg.topic){
|
|
436
918
|
case this.topicStrings[TopicType.tx]:
|
|
437
919
|
topicType = TopicType.tx;
|
|
438
920
|
break;
|
|
439
|
-
case this.topicStrings[TopicType.block_attestation]:
|
|
440
|
-
topicType = TopicType.block_attestation;
|
|
441
|
-
break;
|
|
442
921
|
case this.topicStrings[TopicType.block_proposal]:
|
|
443
922
|
topicType = TopicType.block_proposal;
|
|
444
923
|
break;
|
|
924
|
+
case this.topicStrings[TopicType.checkpoint_proposal]:
|
|
925
|
+
topicType = TopicType.checkpoint_proposal;
|
|
926
|
+
break;
|
|
927
|
+
case this.topicStrings[TopicType.checkpoint_attestation]:
|
|
928
|
+
topicType = TopicType.checkpoint_attestation;
|
|
929
|
+
break;
|
|
445
930
|
default:
|
|
446
931
|
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
447
932
|
break;
|
|
@@ -462,184 +947,592 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
462
947
|
};
|
|
463
948
|
}
|
|
464
949
|
/**
|
|
950
|
+
* Safely deserializes a P2PMessage from raw message data.
|
|
951
|
+
* @param msgId - The message ID.
|
|
952
|
+
* @param source - The peer ID of the message source.
|
|
953
|
+
* @param data - The raw message data.
|
|
954
|
+
* @returns The deserialized P2PMessage or undefined if deserialization fails.
|
|
955
|
+
*/ safelyDeserializeP2PMessage(msgId, source, data) {
|
|
956
|
+
try {
|
|
957
|
+
return P2PMessage.fromMessageData(Buffer.from(data), this.config.debugP2PInstrumentMessages);
|
|
958
|
+
} catch (err) {
|
|
959
|
+
this.logger.error(`Error deserializing P2PMessage`, err, {
|
|
960
|
+
msgId,
|
|
961
|
+
source: source.toString()
|
|
962
|
+
});
|
|
963
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Reject);
|
|
964
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
965
|
+
return undefined;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
465
969
|
* Handles a new gossip message that was received by the client.
|
|
466
970
|
* @param topic - The message's topic.
|
|
467
971
|
* @param data - The message data
|
|
468
972
|
*/ async handleNewGossipMessage(msg, msgId, source) {
|
|
469
|
-
const
|
|
973
|
+
const msgReceivedTime = Date.now();
|
|
974
|
+
let topicType;
|
|
975
|
+
const p2pMessage = this.safelyDeserializeP2PMessage(msgId, source, msg.data);
|
|
976
|
+
if (!p2pMessage) {
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
470
979
|
const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
|
|
471
980
|
if (!preValidationResult.result) {
|
|
472
981
|
return;
|
|
473
982
|
}
|
|
983
|
+
// Determine topic type for attributes
|
|
474
984
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
475
|
-
|
|
985
|
+
topicType = TopicType.tx;
|
|
986
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
987
|
+
topicType = TopicType.checkpoint_attestation;
|
|
988
|
+
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
989
|
+
topicType = TopicType.block_proposal;
|
|
990
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
991
|
+
topicType = TopicType.checkpoint_proposal;
|
|
476
992
|
}
|
|
477
|
-
|
|
478
|
-
|
|
993
|
+
// Process the message, optionally within a linked span for trace propagation
|
|
994
|
+
const processMessage = async ()=>{
|
|
995
|
+
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
996
|
+
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
997
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
998
|
+
if (this.clientType === P2PClientType.Full) {
|
|
999
|
+
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
1000
|
+
}
|
|
1001
|
+
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
1002
|
+
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
1003
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
1004
|
+
await this.handleGossipedCheckpointProposal(p2pMessage.payload, msgId, source);
|
|
1005
|
+
} else {
|
|
1006
|
+
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
const latency = p2pMessage.timestamp !== undefined ? msgReceivedTime - p2pMessage.timestamp.getTime() : undefined;
|
|
1010
|
+
const propagatedContext = p2pMessage.traceContext ? this.telemetry.extractPropagatedContext(p2pMessage.traceContext) : undefined;
|
|
1011
|
+
if (propagatedContext) {
|
|
1012
|
+
await this.tracer.startActiveSpan('LibP2PService.processMessage', {
|
|
1013
|
+
attributes: {
|
|
1014
|
+
[Attributes.TOPIC_NAME]: topicType,
|
|
1015
|
+
[Attributes.PEER_ID]: source.toString()
|
|
1016
|
+
}
|
|
1017
|
+
}, propagatedContext, async (span)=>{
|
|
1018
|
+
try {
|
|
1019
|
+
await processMessage();
|
|
1020
|
+
span.setStatus({
|
|
1021
|
+
code: SpanStatusCode.OK
|
|
1022
|
+
});
|
|
1023
|
+
} catch (err) {
|
|
1024
|
+
span.setStatus({
|
|
1025
|
+
code: SpanStatusCode.ERROR,
|
|
1026
|
+
message: String(err)
|
|
1027
|
+
});
|
|
1028
|
+
if (typeof err === 'string' || err && err instanceof Error) {
|
|
1029
|
+
span.recordException(err);
|
|
1030
|
+
}
|
|
1031
|
+
throw err;
|
|
1032
|
+
} finally{
|
|
1033
|
+
span.end();
|
|
1034
|
+
}
|
|
1035
|
+
});
|
|
1036
|
+
} else {
|
|
1037
|
+
await processMessage();
|
|
479
1038
|
}
|
|
480
|
-
if (
|
|
481
|
-
|
|
1039
|
+
if (latency !== undefined && topicType !== undefined) {
|
|
1040
|
+
this.instrumentation.recordMessageLatency(topicType, latency);
|
|
482
1041
|
}
|
|
483
1042
|
return;
|
|
484
1043
|
}
|
|
485
1044
|
async validateReceivedMessage(validationFunc, msgId, source, topicType) {
|
|
486
1045
|
let resultAndObj = {
|
|
487
|
-
result:
|
|
488
|
-
obj: undefined
|
|
1046
|
+
result: TopicValidatorResult.Reject
|
|
489
1047
|
};
|
|
490
1048
|
const timer = new Timer();
|
|
491
1049
|
try {
|
|
492
1050
|
resultAndObj = await validationFunc();
|
|
493
1051
|
} catch (err) {
|
|
494
|
-
this.
|
|
1052
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
1053
|
+
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
1054
|
+
msgId,
|
|
1055
|
+
source: source.toString(),
|
|
1056
|
+
topicType
|
|
1057
|
+
});
|
|
495
1058
|
}
|
|
496
|
-
if (resultAndObj.result) {
|
|
1059
|
+
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
497
1060
|
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
498
1061
|
}
|
|
499
|
-
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result
|
|
1062
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
500
1063
|
return resultAndObj;
|
|
501
1064
|
}
|
|
502
1065
|
async handleGossipedTx(payloadData, msgId, source) {
|
|
503
1066
|
const validationFunc = async ()=>{
|
|
504
1067
|
const tx = Tx.fromBuffer(payloadData);
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
1068
|
+
const isValid = await this.validatePropagatedTx(tx, source);
|
|
1069
|
+
if (!isValid) {
|
|
1070
|
+
this.logger.trace(`Rejecting invalid propagated tx`, {
|
|
1071
|
+
[Attributes.P2P_ID]: source.toString()
|
|
1072
|
+
});
|
|
1073
|
+
return {
|
|
1074
|
+
result: TopicValidatorResult.Reject
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
// Propagate only on pool acceptance
|
|
1078
|
+
const txHash = tx.getTxHash();
|
|
1079
|
+
const addResult = await this.mempools.txPool.addPendingTxs([
|
|
1080
|
+
tx
|
|
1081
|
+
], {
|
|
1082
|
+
source: 'gossip'
|
|
1083
|
+
});
|
|
1084
|
+
const wasAccepted = addResult.accepted.some((h)=>h.equals(txHash));
|
|
1085
|
+
const wasIgnored = addResult.ignored.some((h)=>h.equals(txHash));
|
|
1086
|
+
this.logger.trace(`Validate propagated tx`, {
|
|
1087
|
+
isValid,
|
|
1088
|
+
wasAccepted,
|
|
1089
|
+
wasIgnored,
|
|
1090
|
+
[Attributes.P2P_ID]: source.toString()
|
|
1091
|
+
});
|
|
1092
|
+
if (wasAccepted) {
|
|
1093
|
+
return {
|
|
1094
|
+
result: TopicValidatorResult.Accept,
|
|
1095
|
+
obj: tx
|
|
1096
|
+
};
|
|
1097
|
+
} else if (wasIgnored) {
|
|
1098
|
+
return {
|
|
1099
|
+
result: TopicValidatorResult.Ignore,
|
|
1100
|
+
obj: tx
|
|
1101
|
+
};
|
|
1102
|
+
} else {
|
|
1103
|
+
return {
|
|
1104
|
+
result: TopicValidatorResult.Reject
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
510
1107
|
};
|
|
511
1108
|
const { result, obj: tx } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.tx);
|
|
512
|
-
if (
|
|
1109
|
+
if (result !== TopicValidatorResult.Accept || !tx) {
|
|
513
1110
|
return;
|
|
514
1111
|
}
|
|
1112
|
+
// Tx was accepted into pool and will be propagated - just log and record metrics
|
|
515
1113
|
const txHash = tx.getTxHash();
|
|
516
1114
|
const txHashString = txHash.toString();
|
|
517
1115
|
this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
|
|
518
1116
|
source: source.toString(),
|
|
519
1117
|
txHash: txHashString
|
|
520
1118
|
});
|
|
521
|
-
|
|
522
|
-
this.logger.debug(`Intentionally dropping tx ${txHashString} (probability rule)`);
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
await this.mempools.txPool.addTxs([
|
|
526
|
-
tx
|
|
527
|
-
]);
|
|
1119
|
+
this.instrumentation.incrementTxReceived(1);
|
|
528
1120
|
}
|
|
529
1121
|
/**
|
|
530
|
-
* Process
|
|
531
|
-
*
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
const validationFunc = async ()=>{
|
|
536
|
-
const attestation = BlockAttestation.fromBuffer(payloadData);
|
|
537
|
-
const result = await this.validateAttestation(source, attestation);
|
|
538
|
-
this.logger.trace(`validatePropagatedAttestation: ${result}`, {
|
|
539
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
540
|
-
[Attributes.P2P_ID]: source.toString()
|
|
541
|
-
});
|
|
542
|
-
return {
|
|
543
|
-
result,
|
|
544
|
-
obj: attestation
|
|
545
|
-
};
|
|
546
|
-
};
|
|
547
|
-
const { result, obj: attestation } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.block_attestation);
|
|
548
|
-
if (!result || !attestation) {
|
|
1122
|
+
* Process a checkpoint attestation from a peer.
|
|
1123
|
+
* Validates the attestation and adds it to the pool.
|
|
1124
|
+
*/ async processCheckpointAttestationFromPeer(payloadData, msgId, source) {
|
|
1125
|
+
const { result, obj: attestation } = await this.validateReceivedMessage(()=>this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)), msgId, source, TopicType.checkpoint_attestation);
|
|
1126
|
+
if (result !== TopicValidatorResult.Accept || !attestation) {
|
|
549
1127
|
return;
|
|
550
1128
|
}
|
|
551
|
-
this.logger.
|
|
552
|
-
p2pMessageIdentifier: await attestation.
|
|
553
|
-
slot: attestation.slotNumber
|
|
1129
|
+
this.logger.verbose(`Received valid checkpoint attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`, {
|
|
1130
|
+
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
1131
|
+
slot: attestation.slotNumber,
|
|
554
1132
|
archive: attestation.archive.toString(),
|
|
555
1133
|
source: source.toString()
|
|
556
1134
|
});
|
|
557
|
-
await this.mempools.attestationPool.addAttestations([
|
|
558
|
-
attestation
|
|
559
|
-
]);
|
|
560
1135
|
}
|
|
561
|
-
async
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
this.
|
|
566
|
-
|
|
567
|
-
|
|
1136
|
+
/** Validates a checkpoint attestation and adds it to the pool. Penalizes the peer if validation fails. */ async validateAndStoreCheckpointAttestation(peerId, attestation) {
|
|
1137
|
+
const validationResult = await this.checkpointAttestationValidator.validate(attestation);
|
|
1138
|
+
if (validationResult.result === 'reject') {
|
|
1139
|
+
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1140
|
+
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1141
|
+
return {
|
|
1142
|
+
result: TopicValidatorResult.Reject
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
if (validationResult.result === 'ignore') {
|
|
1146
|
+
return {
|
|
1147
|
+
result: TopicValidatorResult.Ignore,
|
|
1148
|
+
obj: attestation
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
// Try to add the attestation: this handles existence check, cap check, and adding in one call
|
|
1152
|
+
// count is the number of attestations by this signer for this slot (for duplicate detection)
|
|
1153
|
+
const slot = attestation.payload.header.slotNumber;
|
|
1154
|
+
const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddCheckpointAttestation(attestation);
|
|
1155
|
+
this.logger.trace(`Validate propagated checkpoint attestation`, {
|
|
1156
|
+
added,
|
|
1157
|
+
alreadyExists,
|
|
1158
|
+
count,
|
|
1159
|
+
[Attributes.SLOT_NUMBER]: slot.toString(),
|
|
1160
|
+
[Attributes.P2P_ID]: peerId.toString()
|
|
1161
|
+
});
|
|
1162
|
+
// Exact same attestation received, no need to re-broadcast
|
|
1163
|
+
if (alreadyExists) {
|
|
1164
|
+
return {
|
|
1165
|
+
result: TopicValidatorResult.Ignore,
|
|
1166
|
+
obj: attestation
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
// Could not add (cap reached for signer), no need to re-broadcast
|
|
1170
|
+
if (!added) {
|
|
1171
|
+
this.logger.warn(`Dropping checkpoint attestation due to cap`, {
|
|
1172
|
+
slot: slot.toString(),
|
|
1173
|
+
archive: attestation.archive.toString(),
|
|
1174
|
+
source: peerId.toString(),
|
|
1175
|
+
attester: attestation.getSender()?.toString(),
|
|
1176
|
+
count
|
|
568
1177
|
});
|
|
569
1178
|
return {
|
|
570
|
-
result,
|
|
571
|
-
obj:
|
|
1179
|
+
result: TopicValidatorResult.Ignore,
|
|
1180
|
+
obj: attestation
|
|
572
1181
|
};
|
|
1182
|
+
}
|
|
1183
|
+
// Check if this is a duplicate attestation (signer attested to a different proposal at the same slot)
|
|
1184
|
+
// count is the number of attestations by this signer for this slot
|
|
1185
|
+
if (count === 2) {
|
|
1186
|
+
const attester = attestation.getSender();
|
|
1187
|
+
if (attester) {
|
|
1188
|
+
this.logger.warn(`Detected duplicate attestation (equivocation) at slot ${slot}`, {
|
|
1189
|
+
slot: slot.toString(),
|
|
1190
|
+
archive: attestation.archive.toString(),
|
|
1191
|
+
source: peerId.toString(),
|
|
1192
|
+
attester: attester.toString()
|
|
1193
|
+
});
|
|
1194
|
+
this.duplicateAttestationCallback?.({
|
|
1195
|
+
slot,
|
|
1196
|
+
attester
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
// Attestation was added successfully - accept it so other nodes can also detect the equivocation
|
|
1201
|
+
return {
|
|
1202
|
+
result: TopicValidatorResult.Accept,
|
|
1203
|
+
obj: attestation
|
|
573
1204
|
};
|
|
574
|
-
|
|
575
|
-
|
|
1205
|
+
}
|
|
1206
|
+
async processBlockFromPeer(payloadData, msgId, source) {
|
|
1207
|
+
const { result, obj: block, metadata: { isEquivocated } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreBlockProposal(source, BlockProposal.fromBuffer(payloadData)), msgId, source, TopicType.block_proposal);
|
|
1208
|
+
// If not accepted or equivocated, return
|
|
1209
|
+
if (result !== TopicValidatorResult.Accept || !block || isEquivocated) {
|
|
576
1210
|
return;
|
|
577
1211
|
}
|
|
578
1212
|
await this.processValidBlockProposal(block, source);
|
|
579
1213
|
}
|
|
580
|
-
|
|
1214
|
+
/** Validates a block proposal. Triggers a penalization to the peer that sent it if invalid. Adds to the mempool if valid. */ async validateAndStoreBlockProposal(peerId, block) {
|
|
1215
|
+
const validationResult = await this.blockProposalValidator.validate(block);
|
|
1216
|
+
if (validationResult.result === 'reject') {
|
|
1217
|
+
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1218
|
+
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1219
|
+
return {
|
|
1220
|
+
result: TopicValidatorResult.Reject
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
if (validationResult.result === 'ignore') {
|
|
1224
|
+
return {
|
|
1225
|
+
result: TopicValidatorResult.Ignore,
|
|
1226
|
+
obj: block
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
// Try to add the proposal: this handles existence check, cap check, and adding in one call
|
|
1230
|
+
const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddBlockProposal(block);
|
|
1231
|
+
const isEquivocated = count !== undefined && count > 1;
|
|
1232
|
+
// Duplicate proposal received, no need to re-broadcast
|
|
1233
|
+
if (alreadyExists) {
|
|
1234
|
+
this.logger.debug(`Ignoring duplicate block proposal received`, {
|
|
1235
|
+
...block.toBlockInfo(),
|
|
1236
|
+
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
1237
|
+
proposer: block.getSender()?.toString(),
|
|
1238
|
+
source: peerId.toString()
|
|
1239
|
+
});
|
|
1240
|
+
return {
|
|
1241
|
+
result: TopicValidatorResult.Ignore,
|
|
1242
|
+
obj: block,
|
|
1243
|
+
metadata: {
|
|
1244
|
+
isEquivocated
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1249
|
+
if (!added) {
|
|
1250
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1251
|
+
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1252
|
+
...block.toBlockInfo(),
|
|
1253
|
+
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
1254
|
+
count,
|
|
1255
|
+
proposer: block.getSender()?.toString(),
|
|
1256
|
+
source: peerId.toString()
|
|
1257
|
+
});
|
|
1258
|
+
return {
|
|
1259
|
+
result: TopicValidatorResult.Reject,
|
|
1260
|
+
metadata: {
|
|
1261
|
+
isEquivocated
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
1266
|
+
// and do re-broadcast it so other nodes in the network know to slash the proposer
|
|
1267
|
+
if (isEquivocated) {
|
|
1268
|
+
const proposer = block.getSender();
|
|
1269
|
+
this.logger.warn(`Detected duplicate block proposal (equivocation) at slot ${block.slotNumber}`, {
|
|
1270
|
+
...block.toBlockInfo(),
|
|
1271
|
+
source: peerId.toString(),
|
|
1272
|
+
proposer: proposer?.toString()
|
|
1273
|
+
});
|
|
1274
|
+
// Invoke the duplicate callback on the first duplicate spotted only
|
|
1275
|
+
if (proposer && count === 2) {
|
|
1276
|
+
this.duplicateProposalCallback?.({
|
|
1277
|
+
slot: block.slotNumber,
|
|
1278
|
+
proposer,
|
|
1279
|
+
type: 'block'
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
return {
|
|
1283
|
+
result: TopicValidatorResult.Accept,
|
|
1284
|
+
obj: block,
|
|
1285
|
+
metadata: {
|
|
1286
|
+
isEquivocated
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
// Otherwise, we're good to go!
|
|
1291
|
+
return {
|
|
1292
|
+
result: TopicValidatorResult.Accept,
|
|
1293
|
+
obj: block
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
// REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
|
|
1297
|
+
// should not be here as it does not deal with p2p networking.
|
|
581
1298
|
async processValidBlockProposal(block, sender) {
|
|
582
|
-
const slot = block.slotNumber
|
|
583
|
-
const previousSlot = slot - 1n;
|
|
1299
|
+
const slot = block.slotNumber;
|
|
584
1300
|
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
585
|
-
p2pMessageIdentifier: await block.
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
source: sender.toString()
|
|
1301
|
+
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
1302
|
+
source: sender.toString(),
|
|
1303
|
+
...block.toBlockInfo()
|
|
589
1304
|
});
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
1305
|
+
// Mark the txs in this proposal as protected
|
|
1306
|
+
await this.mempools.txPool.protectTxs(block.txHashes, block.blockHeader);
|
|
1307
|
+
// Call the block received callback to validate the proposal.
|
|
1308
|
+
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1309
|
+
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1310
|
+
if (!isValid) {
|
|
1311
|
+
this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Handle a gossiped checkpoint proposal.
|
|
1316
|
+
* Validates and processes the checkpoint proposal, then triggers the callback for attestation.
|
|
1317
|
+
*/ async handleGossipedCheckpointProposal(payloadData, msgId, source) {
|
|
1318
|
+
const { result, obj: checkpoint, metadata: { isEquivocated, processBlock } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreCheckpointProposal(source, CheckpointProposal.fromBuffer(payloadData)), msgId, source, TopicType.checkpoint_proposal);
|
|
1319
|
+
// If the checkpoint contained a valid last block, we process it even if the checkpoint itself is to be rejected
|
|
1320
|
+
// TODO(palla/mbps): Is this ok? Should we be considering a block from a checkpoint that was equivocated?
|
|
1321
|
+
if (processBlock && checkpoint?.getBlockProposal()) {
|
|
1322
|
+
await this.processValidBlockProposal(checkpoint.getBlockProposal(), source);
|
|
1323
|
+
}
|
|
1324
|
+
if (result !== TopicValidatorResult.Accept || !checkpoint || isEquivocated) {
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
await this.processValidCheckpointProposal(checkpoint.toCore(), source);
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Validates a checkpoint proposal. Penalizes peer if validation fails. Adds the checkpoint and
|
|
1331
|
+
* its last block (if present) to the mempool if valid. Triggers equivocation detection on both.
|
|
1332
|
+
*/ async validateAndStoreCheckpointProposal(peerId, checkpoint) {
|
|
1333
|
+
const validationResult = await this.checkpointProposalValidator.validate(checkpoint);
|
|
1334
|
+
if (validationResult.result === 'reject') {
|
|
1335
|
+
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1336
|
+
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1337
|
+
return {
|
|
1338
|
+
result: TopicValidatorResult.Reject
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
if (validationResult.result === 'ignore') {
|
|
1342
|
+
return {
|
|
1343
|
+
result: TopicValidatorResult.Ignore,
|
|
1344
|
+
obj: checkpoint
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
// Extract and try to add the block proposal first if present
|
|
1348
|
+
const blockProposal = checkpoint.getBlockProposal();
|
|
1349
|
+
let processBlock = false;
|
|
1350
|
+
if (blockProposal) {
|
|
1351
|
+
this.logger.debug(`Validating block proposal from propagated checkpoint`, {
|
|
1352
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1353
|
+
[Attributes.P2P_ID]: peerId.toString()
|
|
1354
|
+
});
|
|
1355
|
+
const { result, obj, metadata: { isEquivocated } = {} } = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1356
|
+
if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1357
|
+
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1358
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1359
|
+
[Attributes.P2P_ID]: peerId.toString(),
|
|
1360
|
+
isEquivocated,
|
|
1361
|
+
result
|
|
1362
|
+
});
|
|
1363
|
+
return {
|
|
1364
|
+
result: TopicValidatorResult.Reject
|
|
1365
|
+
};
|
|
1366
|
+
} else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1367
|
+
processBlock = true;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
// Try to add the checkpoint proposal core: this handles existence check, cap check, and adding in one call
|
|
1371
|
+
const checkpointCore = checkpoint.toCore();
|
|
1372
|
+
const tryAddResult = await this.mempools.attestationPool.tryAddCheckpointProposal(checkpointCore);
|
|
1373
|
+
const { added, alreadyExists, count } = tryAddResult;
|
|
1374
|
+
const isEquivocated = count !== undefined && count > 1;
|
|
1375
|
+
// Duplicate proposal received, do not re-broadcast
|
|
1376
|
+
if (alreadyExists) {
|
|
1377
|
+
this.logger.debug(`Ignoring duplicate checkpoint proposal received`, {
|
|
1378
|
+
...checkpoint.toCheckpointInfo(),
|
|
1379
|
+
source: peerId.toString()
|
|
1380
|
+
});
|
|
1381
|
+
return {
|
|
1382
|
+
result: TopicValidatorResult.Ignore,
|
|
1383
|
+
obj: checkpoint,
|
|
1384
|
+
metadata: {
|
|
1385
|
+
isEquivocated,
|
|
1386
|
+
processBlock
|
|
1387
|
+
}
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1391
|
+
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1392
|
+
if (!added) {
|
|
1393
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1394
|
+
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1395
|
+
...checkpoint.toCheckpointInfo(),
|
|
1396
|
+
count,
|
|
1397
|
+
source: peerId.toString()
|
|
1398
|
+
});
|
|
1399
|
+
return {
|
|
1400
|
+
result: TopicValidatorResult.Reject,
|
|
1401
|
+
obj: checkpoint,
|
|
1402
|
+
metadata: {
|
|
1403
|
+
isEquivocated,
|
|
1404
|
+
processBlock
|
|
1405
|
+
}
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
1409
|
+
// and do re-broadcast it so other nodes in the network know to slash the proposer
|
|
1410
|
+
if (isEquivocated) {
|
|
1411
|
+
const proposer = checkpoint.getSender();
|
|
1412
|
+
this.logger.warn(`Detected duplicate checkpoint proposal (equivocation) at slot ${checkpoint.slotNumber}`, {
|
|
1413
|
+
...checkpoint.toCheckpointInfo(),
|
|
1414
|
+
source: peerId.toString(),
|
|
1415
|
+
proposer: proposer?.toString()
|
|
1416
|
+
});
|
|
1417
|
+
// Invoke the duplicate callback on the first duplicate spotted only
|
|
1418
|
+
if (proposer && count === 2) {
|
|
1419
|
+
this.duplicateProposalCallback?.({
|
|
1420
|
+
slot: checkpoint.slotNumber,
|
|
1421
|
+
proposer,
|
|
1422
|
+
type: 'checkpoint'
|
|
606
1423
|
});
|
|
607
|
-
await this.broadcastAttestation(attestation);
|
|
608
1424
|
}
|
|
1425
|
+
return {
|
|
1426
|
+
result: TopicValidatorResult.Accept,
|
|
1427
|
+
obj: checkpoint,
|
|
1428
|
+
metadata: {
|
|
1429
|
+
isEquivocated,
|
|
1430
|
+
processBlock
|
|
1431
|
+
}
|
|
1432
|
+
};
|
|
609
1433
|
}
|
|
1434
|
+
// Otherwise, we're good to go!
|
|
1435
|
+
return {
|
|
1436
|
+
result: TopicValidatorResult.Accept,
|
|
1437
|
+
obj: checkpoint,
|
|
1438
|
+
metadata: {
|
|
1439
|
+
processBlock,
|
|
1440
|
+
isEquivocated
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
610
1443
|
}
|
|
611
1444
|
/**
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*/ async
|
|
615
|
-
|
|
1445
|
+
* Process a validated checkpoint proposal.
|
|
1446
|
+
* Note: The proposal was already added to the pool by tryAddCheckpointProposal in handleGossipedCheckpointProposal.
|
|
1447
|
+
*/ async processValidCheckpointProposal(checkpoint, sender) {
|
|
1448
|
+
const slot = checkpoint.slotNumber;
|
|
1449
|
+
this.logger.verbose(`Received checkpoint proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1450
|
+
p2pMessageIdentifier: await checkpoint.p2pMessageLoggingIdentifier(),
|
|
1451
|
+
slot: checkpoint.slotNumber,
|
|
1452
|
+
archive: checkpoint.archive.toString(),
|
|
1453
|
+
source: sender.toString()
|
|
1454
|
+
});
|
|
1455
|
+
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1456
|
+
// to validate and potentially generate attestations
|
|
1457
|
+
const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
|
|
1458
|
+
if (attestations && attestations.length > 0) {
|
|
1459
|
+
// If the callback returned attestations, add them to the pool and propagate them
|
|
1460
|
+
await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
1461
|
+
for (const attestation of attestations){
|
|
1462
|
+
await this.propagate(attestation);
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
616
1465
|
}
|
|
617
1466
|
/**
|
|
618
1467
|
* Propagates provided message to peers.
|
|
619
1468
|
* @param message - The message to propagate.
|
|
620
1469
|
*/ async propagate(message) {
|
|
621
|
-
const p2pMessageIdentifier = await message.
|
|
1470
|
+
const p2pMessageIdentifier = await message.p2pMessageLoggingIdentifier();
|
|
622
1471
|
this.logger.trace(`Message ${p2pMessageIdentifier} queued`, {
|
|
623
1472
|
p2pMessageIdentifier
|
|
624
1473
|
});
|
|
625
|
-
void this.
|
|
626
|
-
await this.sendToPeers(message);
|
|
627
|
-
}).catch((error)=>{
|
|
1474
|
+
void this.sendToPeers(message).catch((error)=>{
|
|
628
1475
|
this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, {
|
|
629
1476
|
error
|
|
630
1477
|
});
|
|
631
1478
|
});
|
|
632
1479
|
}
|
|
633
1480
|
/**
|
|
634
|
-
* Validate the requested block transactions.
|
|
1481
|
+
* Validate the requested block transactions. Allow partial returns.
|
|
635
1482
|
* @param request - The block transactions request.
|
|
636
1483
|
* @param response - The block transactions response.
|
|
637
1484
|
* @param peerId - The ID of the peer that made the request.
|
|
638
1485
|
* @returns True if the requested block transactions are valid, false otherwise.
|
|
639
|
-
*/ async validateRequestedBlockTxs(
|
|
1486
|
+
*/ async validateRequestedBlockTxs(request, response, peerId) {
|
|
640
1487
|
const requestedTxValidator = this.createRequestedTxValidator();
|
|
641
1488
|
try {
|
|
642
|
-
|
|
1489
|
+
if (!response.archiveRoot.equals(request.archiveRoot)) {
|
|
1490
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1491
|
+
throw new ValidationError(`Received block txs for unexpected archive root: expected ${request.archiveRoot.toString()}, got ${response.archiveRoot.toString()}`);
|
|
1492
|
+
}
|
|
1493
|
+
if (response.txIndices.getLength() !== request.txIndices.getLength()) {
|
|
1494
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1495
|
+
throw new ValidationError(`Received block txs with mismatched bitvector length: expected ${request.txIndices.getLength()}, got ${response.txIndices.getLength()}`);
|
|
1496
|
+
}
|
|
1497
|
+
// Check no duplicates and not exceeding returnable count
|
|
1498
|
+
const requestedIndices = new Set(request.txIndices.getTrueIndices());
|
|
1499
|
+
const availableIndices = new Set(response.txIndices.getTrueIndices());
|
|
1500
|
+
const maxReturnable = [
|
|
1501
|
+
...requestedIndices
|
|
1502
|
+
].filter((i)=>availableIndices.has(i)).length;
|
|
1503
|
+
const returnedHashes = await Promise.all(response.txs.map((tx)=>tx.getTxHash().toString()));
|
|
1504
|
+
const uniqueReturned = new Set(returnedHashes.map((h)=>h.toString()));
|
|
1505
|
+
if (uniqueReturned.size !== returnedHashes.length) {
|
|
1506
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1507
|
+
throw new ValidationError(`Received duplicate txs in block txs response`);
|
|
1508
|
+
}
|
|
1509
|
+
if (response.txs.length > maxReturnable) {
|
|
1510
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1511
|
+
throw new ValidationError(`Received more txs (${response.txs.length}) than requested-and-available (${maxReturnable})`);
|
|
1512
|
+
}
|
|
1513
|
+
// Given proposal (should have locally), ensure returned txs are valid subset and match request indices
|
|
1514
|
+
const proposal = await this.mempools.attestationPool.getBlockProposal(request.archiveRoot.toString());
|
|
1515
|
+
if (proposal) {
|
|
1516
|
+
// Build intersected indices
|
|
1517
|
+
const intersectIdx = request.txIndices.getTrueIndices().filter((i)=>response.txIndices.isSet(i));
|
|
1518
|
+
// Enforce subset membership and preserve increasing order by index.
|
|
1519
|
+
const hashToIndexInProposal = new Map(proposal.txHashes.map((h, i)=>[
|
|
1520
|
+
h.toString(),
|
|
1521
|
+
i
|
|
1522
|
+
]));
|
|
1523
|
+
const allowedIndexSet = new Set(intersectIdx);
|
|
1524
|
+
const indices = returnedHashes.map((h)=>hashToIndexInProposal.get(h));
|
|
1525
|
+
const allAllowed = indices.every((idx)=>idx !== undefined && allowedIndexSet.has(idx));
|
|
1526
|
+
const strictlyIncreasing = indices.every((idx, i)=>i === 0 ? idx !== undefined : idx > indices[i - 1]);
|
|
1527
|
+
if (!allAllowed || !strictlyIncreasing) {
|
|
1528
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1529
|
+
throw new ValidationError('Returned txs do not match expected subset/order for requested indices');
|
|
1530
|
+
}
|
|
1531
|
+
} else {
|
|
1532
|
+
// No local proposal, cannot check the membership/order of the returned txs
|
|
1533
|
+
this.logger.warn(`Block proposal not found for archive root ${request.archiveRoot.toString()}; cannot validate membership/order of returned txs`);
|
|
1534
|
+
return false;
|
|
1535
|
+
}
|
|
643
1536
|
await Promise.all(response.txs.map((tx)=>this.validateRequestedTx(tx, peerId, requestedTxValidator)));
|
|
644
1537
|
return true;
|
|
645
1538
|
} catch (e) {
|
|
@@ -661,13 +1554,13 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
661
1554
|
* ReqRespSubProtocol.TX subprotocol validation.
|
|
662
1555
|
*
|
|
663
1556
|
* @param requestedTxHash - The collection of the txs that was requested.
|
|
664
|
-
* @param responseTx - The
|
|
1557
|
+
* @param responseTx - The collection of txs that was received as a response to the request.
|
|
665
1558
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
666
1559
|
* @returns True if the whole collection of txs is valid, false otherwise.
|
|
667
1560
|
*/ async validateRequestedTxs(requestedTxHash, responseTx, peerId) {
|
|
668
1561
|
const requested = new Set(requestedTxHash.map((h)=>h.toString()));
|
|
669
1562
|
const requestedTxValidator = this.createRequestedTxValidator();
|
|
670
|
-
//TODO: (mralj) - this is somewhat naive implementation, if single tx is
|
|
1563
|
+
//TODO: (mralj) - this is somewhat naive implementation, if single tx is invalid we consider the whole response invalid.
|
|
671
1564
|
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
672
1565
|
try {
|
|
673
1566
|
await Promise.all(responseTx.map((tx)=>this.validateRequestedTx(tx, peerId, requestedTxValidator, requested)));
|
|
@@ -681,32 +1574,66 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
681
1574
|
return false;
|
|
682
1575
|
}
|
|
683
1576
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
1577
|
+
/**
|
|
1578
|
+
* Validates a BLOCK response.
|
|
1579
|
+
*
|
|
1580
|
+
* If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
|
|
1581
|
+
* Penalizes on block number mismatch or hash mismatch.
|
|
1582
|
+
*
|
|
1583
|
+
* @param requestedBlockNumber - The requested block number.
|
|
1584
|
+
* @param responseBlock - The block returned by the peer.
|
|
1585
|
+
* @param peerId - The peer that returned the block.
|
|
1586
|
+
* @returns True if the response is valid, false otherwise.
|
|
1587
|
+
*/ async validateRequestedBlock(requestedBlockNumber, responseBlock, peerId) {
|
|
1588
|
+
try {
|
|
1589
|
+
const reqNum = Number(requestedBlockNumber.toString());
|
|
1590
|
+
if (responseBlock.number !== reqNum) {
|
|
1591
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1592
|
+
return false;
|
|
1593
|
+
}
|
|
1594
|
+
const local = await this.archiver.getBlock(BlockNumber(reqNum));
|
|
1595
|
+
if (!local) {
|
|
1596
|
+
// We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
|
|
1597
|
+
// TODO: Consider extending this validator to accept an expected hash or
|
|
1598
|
+
// performing quorum-based checks when using P2P syncing prior to L1 sync.
|
|
1599
|
+
this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
|
|
1600
|
+
return false;
|
|
1601
|
+
}
|
|
1602
|
+
const [localHash, respHash] = await Promise.all([
|
|
1603
|
+
local.hash(),
|
|
1604
|
+
responseBlock.hash()
|
|
1605
|
+
]);
|
|
1606
|
+
if (!localHash.equals(respHash)) {
|
|
1607
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1608
|
+
return false;
|
|
1609
|
+
}
|
|
1610
|
+
return true;
|
|
1611
|
+
} catch (e) {
|
|
1612
|
+
this.logger.warn(`Error validating requested block`, e);
|
|
1613
|
+
return false;
|
|
1614
|
+
}
|
|
691
1615
|
}
|
|
692
1616
|
async validateRequestedTx(tx, peerId, txValidator, requested) {
|
|
693
|
-
|
|
694
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
695
|
-
throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
|
|
696
|
-
}
|
|
1617
|
+
const penalize = (severity)=>this.peerManager.penalizePeer(peerId, severity);
|
|
697
1618
|
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
698
|
-
|
|
1619
|
+
penalize(PeerErrorSeverity.MidToleranceError);
|
|
699
1620
|
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
700
1621
|
}
|
|
701
1622
|
const { result } = await txValidator.validateTx(tx);
|
|
702
1623
|
if (result === 'invalid') {
|
|
703
|
-
|
|
1624
|
+
penalize(PeerErrorSeverity.LowToleranceError);
|
|
704
1625
|
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
705
1626
|
}
|
|
706
1627
|
}
|
|
1628
|
+
createRequestedTxValidator() {
|
|
1629
|
+
return createTxReqRespValidator(this.proofVerifier, {
|
|
1630
|
+
l1ChainId: this.config.l1ChainId,
|
|
1631
|
+
rollupVersion: this.config.rollupVersion
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
707
1634
|
async validatePropagatedTx(tx, peerId) {
|
|
708
1635
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
709
|
-
// We accept transactions if they are not expired by the next slot (checked based on the
|
|
1636
|
+
// We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
|
|
710
1637
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
711
1638
|
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
712
1639
|
for (const validator of messageValidators){
|
|
@@ -718,7 +1645,7 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
718
1645
|
let { severity } = outcome.failure;
|
|
719
1646
|
// Double spend validator has a special case handler
|
|
720
1647
|
if (name === 'doubleSpendValidator') {
|
|
721
|
-
const txBlockNumber = currentBlockNumber + 1; // tx is expected to be in the next block
|
|
1648
|
+
const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
|
|
722
1649
|
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
723
1650
|
}
|
|
724
1651
|
this.peerManager.penalizePeer(peerId, severity);
|
|
@@ -738,9 +1665,23 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
738
1665
|
};
|
|
739
1666
|
return gasFees;
|
|
740
1667
|
}
|
|
1668
|
+
/**
|
|
1669
|
+
* Get the BatchTxRequesterLibP2PService dependencies for creating BatchTxRequester instances
|
|
1670
|
+
*/ getBatchTxRequesterService() {
|
|
1671
|
+
return {
|
|
1672
|
+
reqResp: this.reqresp,
|
|
1673
|
+
connectionSampler: this.reqresp.getConnectionSampler(),
|
|
1674
|
+
txValidatorConfig: {
|
|
1675
|
+
l1ChainId: this.config.l1ChainId,
|
|
1676
|
+
rollupVersion: this.config.rollupVersion,
|
|
1677
|
+
proofVerifier: this.proofVerifier
|
|
1678
|
+
},
|
|
1679
|
+
peerScoring: this.peerManager
|
|
1680
|
+
};
|
|
1681
|
+
}
|
|
741
1682
|
async validate(txs) {
|
|
742
1683
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
743
|
-
// We accept transactions if they are not expired by the next slot (checked based on the
|
|
1684
|
+
// We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
|
|
744
1685
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
745
1686
|
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
746
1687
|
await Promise.all(txs.map(async (tx)=>{
|
|
@@ -768,8 +1709,8 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
768
1709
|
*/ async createMessageValidators(currentBlockNumber, nextSlotTimestamp) {
|
|
769
1710
|
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
770
1711
|
const allowedInSetup = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
|
|
771
|
-
const blockNumberInWhichTheTxIsConsideredToBeIncluded = currentBlockNumber + 1;
|
|
772
|
-
return createTxMessageValidators(nextSlotTimestamp, blockNumberInWhichTheTxIsConsideredToBeIncluded, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, this.proofVerifier, !this.config.disableTransactions, allowedInSetup);
|
|
1712
|
+
const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
|
|
1713
|
+
return createTxMessageValidators(nextSlotTimestamp, blockNumberInWhichTheTxIsConsideredToBeIncluded, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, this.proofVerifier, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings());
|
|
773
1714
|
}
|
|
774
1715
|
/**
|
|
775
1716
|
* Run validations on a tx.
|
|
@@ -824,11 +1765,11 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
824
1765
|
}
|
|
825
1766
|
const snapshotValidator = new DoubleSpendTxValidator({
|
|
826
1767
|
nullifiersExist: async (nullifiers)=>{
|
|
827
|
-
const merkleTree = this.worldStateSynchronizer.getSnapshot(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow);
|
|
1768
|
+
const merkleTree = this.worldStateSynchronizer.getSnapshot(BlockNumber(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow));
|
|
828
1769
|
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
829
1770
|
return indices.map((index)=>index !== undefined);
|
|
830
1771
|
}
|
|
831
|
-
});
|
|
1772
|
+
}, this.logger.getBindings());
|
|
832
1773
|
const validSnapshot = await snapshotValidator.validateTx(tx);
|
|
833
1774
|
if (validSnapshot.result !== 'valid') {
|
|
834
1775
|
return PeerErrorSeverity.LowToleranceError;
|
|
@@ -836,31 +1777,17 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
836
1777
|
return PeerErrorSeverity.HighToleranceError;
|
|
837
1778
|
}
|
|
838
1779
|
/**
|
|
839
|
-
* Validate
|
|
1780
|
+
* Validate a checkpoint attestation.
|
|
840
1781
|
*
|
|
841
|
-
* @param attestation - The attestation to validate.
|
|
842
|
-
* @returns True if the attestation is valid, false otherwise.
|
|
843
|
-
*/ async
|
|
844
|
-
const
|
|
845
|
-
if (
|
|
846
|
-
this.
|
|
847
|
-
|
|
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);
|
|
848
1789
|
}
|
|
849
|
-
return
|
|
850
|
-
}
|
|
851
|
-
/**
|
|
852
|
-
* Validate a block proposal.
|
|
853
|
-
*
|
|
854
|
-
* @param block - The block proposal to validate.
|
|
855
|
-
* @returns True if the block proposal is valid, false otherwise.
|
|
856
|
-
*/ async validateBlockProposal(peerId, block) {
|
|
857
|
-
const severity = await this.blockProposalValidator.validate(block);
|
|
858
|
-
if (severity) {
|
|
859
|
-
this.logger.debug(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
860
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
861
|
-
return false;
|
|
862
|
-
}
|
|
863
|
-
return true;
|
|
1790
|
+
return result;
|
|
864
1791
|
}
|
|
865
1792
|
getPeerScore(peerId) {
|
|
866
1793
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
@@ -870,7 +1797,7 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
870
1797
|
}
|
|
871
1798
|
async sendToPeers(message) {
|
|
872
1799
|
const parent = message.constructor;
|
|
873
|
-
const identifier = await message.
|
|
1800
|
+
const identifier = await message.p2pMessageLoggingIdentifier().then((i)=>i.toString());
|
|
874
1801
|
this.logger.trace(`Sending message ${identifier}`, {
|
|
875
1802
|
p2pMessageIdentifier: identifier
|
|
876
1803
|
});
|
|
@@ -897,44 +1824,3 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
897
1824
|
}
|
|
898
1825
|
}
|
|
899
1826
|
}
|
|
900
|
-
_ts_decorate([
|
|
901
|
-
trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
|
|
902
|
-
[Attributes.SLOT_NUMBER]: block.slotNumber.toNumber(),
|
|
903
|
-
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
904
|
-
[Attributes.P2P_ID]: await block.p2pMessageIdentifier().then((i)=>i.toString())
|
|
905
|
-
}))
|
|
906
|
-
], LibP2PService.prototype, "processValidBlockProposal", null);
|
|
907
|
-
_ts_decorate([
|
|
908
|
-
trackSpan('Libp2pService.broadcastAttestation', async (attestation)=>({
|
|
909
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
|
|
910
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
911
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then((i)=>i.toString())
|
|
912
|
-
}))
|
|
913
|
-
], LibP2PService.prototype, "broadcastAttestation", null);
|
|
914
|
-
_ts_decorate([
|
|
915
|
-
trackSpan('Libp2pService.validateRequestedBlockTxs', (request)=>({
|
|
916
|
-
[Attributes.BLOCK_HASH]: request.blockHash.toString()
|
|
917
|
-
}))
|
|
918
|
-
], LibP2PService.prototype, "validateRequestedBlockTxs", null);
|
|
919
|
-
_ts_decorate([
|
|
920
|
-
trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx)=>({
|
|
921
|
-
[Attributes.TX_HASH]: requestedTxHash.toString()
|
|
922
|
-
}))
|
|
923
|
-
], LibP2PService.prototype, "validateRequestedTxs", null);
|
|
924
|
-
_ts_decorate([
|
|
925
|
-
trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
|
|
926
|
-
[Attributes.TX_HASH]: tx.getTxHash().toString()
|
|
927
|
-
}))
|
|
928
|
-
], LibP2PService.prototype, "validatePropagatedTx", null);
|
|
929
|
-
_ts_decorate([
|
|
930
|
-
trackSpan('Libp2pService.validateAttestation', async (_, attestation)=>({
|
|
931
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
|
|
932
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
933
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then((i)=>i.toString())
|
|
934
|
-
}))
|
|
935
|
-
], LibP2PService.prototype, "validateAttestation", null);
|
|
936
|
-
_ts_decorate([
|
|
937
|
-
trackSpan('Libp2pService.validateBlockProposal', (_peerId, block)=>({
|
|
938
|
-
[Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString()
|
|
939
|
-
}))
|
|
940
|
-
], LibP2PService.prototype, "validateBlockProposal", null);
|