@aztec/p2p 0.0.1-fake-ceab37513c → 0.0.6-commit.a2d1860fe9
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 +52 -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 -61
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +42 -16
- 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 +114 -57
- 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 +529 -288
- 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 +33 -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 +316 -337
- 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 +11 -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 +74 -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 +209 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.js +8 -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 +878 -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 +5 -4
- 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 +30 -14
- 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 +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +5 -7
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +8 -26
- 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 +30 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.js +32 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +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 +2 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +10 -8
- 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 +111 -84
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +1160 -284
- 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 +471 -50
- 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 +47 -20
- 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 +21 -4
- 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 +12 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -0
- package/dest/test-helpers/mock-tx-helpers.js +19 -0
- package/dest/test-helpers/reqresp-nodes.d.ts +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 -123
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/testbench.js +2 -2
- 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/dest/versioning.js +2 -2
- package/package.json +19 -18
- package/src/bootstrap/bootstrap.ts +7 -4
- package/src/client/factory.ts +97 -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 +76 -21
- 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 +514 -58
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +614 -309
- 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 +369 -373
- 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 +11 -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 +87 -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 +239 -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 +1052 -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 +22 -9
- 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 +72 -24
- 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 +2 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +25 -48
- 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 +57 -0
- 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 +9 -7
- 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 +883 -286
- 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 +79 -22
- 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 +48 -21
- package/src/services/tx_collection/tx_source.ts +24 -5
- 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 +24 -0
- 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 -120
- package/src/testbench/testbench.ts +2 -2
- package/src/testbench/worker_client_manager.ts +304 -42
- package/src/util.ts +19 -3
- package/src/versioning.ts +2 -2
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -30
- 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 -190
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -25
- 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 -197
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -80
- 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 -238
- 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 -62
- 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 -256
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -253
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -283
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -72
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -1,23 +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
|
+
};
|
|
6
369
|
}
|
|
7
|
-
|
|
370
|
+
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
371
|
+
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
372
|
+
}
|
|
373
|
+
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _initProto;
|
|
374
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
8
375
|
import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
9
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
10
376
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
11
377
|
import { Timer } from '@aztec/foundation/timer';
|
|
12
|
-
import {
|
|
378
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
13
379
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
14
|
-
import {
|
|
380
|
+
import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PClientType, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForClientAndConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
|
|
15
381
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
16
382
|
import { Tx } from '@aztec/stdlib/tx';
|
|
17
383
|
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
18
|
-
import { Attributes, OtelMetricsAdapter, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
384
|
+
import { Attributes, OtelMetricsAdapter, SpanStatusCode, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
19
385
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
20
|
-
import { createPeerScoreParams
|
|
386
|
+
import { createPeerScoreParams } from '@chainsafe/libp2p-gossipsub/score';
|
|
21
387
|
import { SignaturePolicy } from '@chainsafe/libp2p-gossipsub/types';
|
|
22
388
|
import { noise } from '@chainsafe/libp2p-noise';
|
|
23
389
|
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
@@ -28,26 +394,51 @@ import { mplex } from '@libp2p/mplex';
|
|
|
28
394
|
import { tcp } from '@libp2p/tcp';
|
|
29
395
|
import { ENR } from '@nethermindeth/enr';
|
|
30
396
|
import { createLibp2p } from 'libp2p';
|
|
31
|
-
import {
|
|
397
|
+
import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, DoubleSpendTxValidator, FishermanAttestationValidator, getDefaultAllowedSetupFunctions } from '../../msg_validators/index.js';
|
|
32
398
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
33
|
-
import {
|
|
34
|
-
import { createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
35
|
-
import { DoubleSpendTxValidator, TxProofValidator } from '../../msg_validators/tx_validator/index.js';
|
|
399
|
+
import { createTxMessageValidators, createTxReqRespValidator } from '../../msg_validators/tx_validator/factory.js';
|
|
36
400
|
import { GossipSubEvent } from '../../types/index.js';
|
|
37
401
|
import { convertToMultiaddr } from '../../util.js';
|
|
38
402
|
import { getVersions } from '../../versioning.js';
|
|
39
403
|
import { AztecDatastore } from '../data_store.js';
|
|
40
404
|
import { DiscV5Service } from '../discv5/discV5_service.js';
|
|
41
405
|
import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
42
|
-
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';
|
|
43
408
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
44
409
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
45
|
-
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError } from '../reqresp/
|
|
46
|
-
import { reqRespBlockTxsHandler } from '../reqresp/
|
|
47
|
-
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
|
|
48
|
-
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';
|
|
49
412
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
50
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
|
+
}));
|
|
51
442
|
/**
|
|
52
443
|
* Lib P2P implementation of the P2PService interface.
|
|
53
444
|
*/ export class LibP2PService extends WithTracer {
|
|
@@ -62,45 +453,119 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
62
453
|
epochCache;
|
|
63
454
|
proofVerifier;
|
|
64
455
|
worldStateSynchronizer;
|
|
65
|
-
|
|
66
|
-
|
|
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
|
+
}
|
|
67
510
|
discoveryRunningPromise;
|
|
68
511
|
msgIdSeenValidators;
|
|
69
512
|
// Message validators
|
|
70
|
-
attestationValidator;
|
|
71
513
|
blockProposalValidator;
|
|
514
|
+
checkpointProposalValidator;
|
|
515
|
+
checkpointAttestationValidator;
|
|
72
516
|
protocolVersion;
|
|
73
517
|
topicStrings;
|
|
74
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;
|
|
75
521
|
/**
|
|
76
522
|
* Callback for when a block is received from a peer.
|
|
77
523
|
* @param block - The block received from the peer.
|
|
78
524
|
* @returns The attestation for the block, if any.
|
|
79
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;
|
|
80
531
|
gossipSubEventHandler;
|
|
81
532
|
instrumentation;
|
|
533
|
+
telemetry;
|
|
534
|
+
logger;
|
|
82
535
|
constructor(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
|
|
83
|
-
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;
|
|
84
540
|
this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
|
|
85
541
|
this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
86
542
|
this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
87
|
-
this.msgIdSeenValidators[TopicType.
|
|
543
|
+
this.msgIdSeenValidators[TopicType.checkpoint_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
544
|
+
this.msgIdSeenValidators[TopicType.checkpoint_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
88
545
|
const versions = getVersions(config);
|
|
89
546
|
this.protocolVersion = compressComponentVersions(versions);
|
|
90
547
|
logger.info(`Started libp2p service with protocol version ${this.protocolVersion}`);
|
|
91
548
|
this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
|
|
92
549
|
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
93
|
-
this.topicStrings[TopicType.
|
|
94
|
-
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);
|
|
95
552
|
this.blockProposalValidator = new BlockProposalValidator(epochCache, {
|
|
96
553
|
txsPermitted: !config.disableTransactions
|
|
97
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);
|
|
98
559
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
99
560
|
this.blockReceivedCallback = async (block)=>{
|
|
100
|
-
this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber
|
|
101
|
-
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()
|
|
102
563
|
});
|
|
103
|
-
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);
|
|
104
569
|
};
|
|
105
570
|
}
|
|
106
571
|
updateConfig(config) {
|
|
@@ -116,8 +581,8 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
116
581
|
const { p2pPort, maxPeerCount, listenAddress } = config;
|
|
117
582
|
const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
|
|
118
583
|
const datastore = new AztecDatastore(peerStore);
|
|
119
|
-
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry);
|
|
120
|
-
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()));
|
|
121
586
|
// Seed libp2p's bootstrap discovery with private and trusted peers
|
|
122
587
|
const bootstrapNodes = [
|
|
123
588
|
...config.privatePeers,
|
|
@@ -131,9 +596,6 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
131
596
|
}
|
|
132
597
|
const versions = getVersions(config);
|
|
133
598
|
const protocolVersion = compressComponentVersions(versions);
|
|
134
|
-
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
135
|
-
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
136
|
-
const blockAttestationTopic = createTopicString(TopicType.block_attestation, protocolVersion);
|
|
137
599
|
const preferredPeersEnrs = config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
138
600
|
const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
|
|
139
601
|
const peerId = await enr.peerId();
|
|
@@ -151,6 +613,15 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
151
613
|
const announceTcpMultiaddr = config.p2pIp ? [
|
|
152
614
|
convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')
|
|
153
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
|
+
});
|
|
154
625
|
const node = await createLibp2p({
|
|
155
626
|
start: false,
|
|
156
627
|
peerId,
|
|
@@ -251,36 +722,24 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
251
722
|
scoreParams: createPeerScoreParams({
|
|
252
723
|
// IPColocation factor can be disabled for local testing - default to -5
|
|
253
724
|
IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
|
|
254
|
-
topics:
|
|
255
|
-
[txTopic]: createTopicScoreParams({
|
|
256
|
-
topicWeight: 1,
|
|
257
|
-
invalidMessageDeliveriesWeight: -20,
|
|
258
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
259
|
-
}),
|
|
260
|
-
[blockAttestationTopic]: createTopicScoreParams({
|
|
261
|
-
topicWeight: 1,
|
|
262
|
-
invalidMessageDeliveriesWeight: -20,
|
|
263
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
264
|
-
}),
|
|
265
|
-
[blockProposalTopic]: createTopicScoreParams({
|
|
266
|
-
topicWeight: 1,
|
|
267
|
-
invalidMessageDeliveriesWeight: -20,
|
|
268
|
-
invalidMessageDeliveriesDecay: 0.5
|
|
269
|
-
})
|
|
270
|
-
}
|
|
725
|
+
topics: topicScoreParams
|
|
271
726
|
})
|
|
272
727
|
}),
|
|
273
728
|
components: (components)=>({
|
|
274
729
|
connectionManager: components.connectionManager
|
|
275
730
|
})
|
|
276
731
|
},
|
|
277
|
-
logger: createLibp2pComponentLogger(logger.module)
|
|
732
|
+
logger: createLibp2pComponentLogger(logger.module, logger.getBindings())
|
|
278
733
|
});
|
|
279
|
-
const peerScoring = new PeerScoring(config);
|
|
734
|
+
const peerScoring = new PeerScoring(config, telemetry);
|
|
280
735
|
const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
|
|
281
736
|
const peerManager = new PeerManager(node, peerDiscoveryService, config, telemetry, createLogger(`${logger.module}:peer_manager`), peerScoring, reqresp, worldStateSynchronizer, protocolVersion, epochCache);
|
|
282
|
-
//
|
|
283
|
-
|
|
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;
|
|
284
743
|
node.services.pubsub.score.params.appSpecificScore = (peerId)=>peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
285
744
|
return new LibP2PService(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
|
|
286
745
|
}
|
|
@@ -298,17 +757,6 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
298
757
|
throw new Error('Announce address not provided.');
|
|
299
758
|
}
|
|
300
759
|
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
301
|
-
// Start job queue, peer discovery service and libp2p node
|
|
302
|
-
this.jobQueue.start();
|
|
303
|
-
await this.peerManager.initializePeers();
|
|
304
|
-
if (!this.config.p2pDiscoveryDisabled) {
|
|
305
|
-
await this.peerDiscoveryService.start();
|
|
306
|
-
}
|
|
307
|
-
await this.node.start();
|
|
308
|
-
// Subscribe to standard GossipSub topics by default
|
|
309
|
-
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
|
|
310
|
-
this.subscribeToTopic(this.topicStrings[topic]);
|
|
311
|
-
}
|
|
312
760
|
// Create request response protocol handlers
|
|
313
761
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
314
762
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
@@ -320,26 +768,37 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
320
768
|
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
321
769
|
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this)
|
|
322
770
|
};
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
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);
|
|
326
773
|
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
327
774
|
}
|
|
328
775
|
if (!this.config.disableTransactions) {
|
|
329
776
|
requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this);
|
|
330
777
|
}
|
|
331
|
-
// add GossipSub listener
|
|
332
|
-
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
333
|
-
// Start running promise for peer discovery
|
|
334
|
-
this.discoveryRunningPromise = new RunningPromise(()=>this.peerManager.heartbeat(), this.logger, this.config.peerCheckIntervalMS);
|
|
335
|
-
this.discoveryRunningPromise.start();
|
|
336
778
|
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
337
779
|
const reqrespSubProtocolValidators = {
|
|
338
780
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
339
|
-
|
|
340
|
-
[ReqRespSubProtocol.
|
|
781
|
+
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
782
|
+
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
783
|
+
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this)
|
|
341
784
|
};
|
|
785
|
+
await this.peerManager.initializePeers();
|
|
342
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();
|
|
343
802
|
this.logger.info(`Started P2P service`, {
|
|
344
803
|
listen: this.config.listenAddress,
|
|
345
804
|
port: this.config.p2pPort,
|
|
@@ -356,8 +815,6 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
356
815
|
// Stop peer manager
|
|
357
816
|
this.logger.debug('Stopping peer manager...');
|
|
358
817
|
await this.peerManager.stop();
|
|
359
|
-
this.logger.debug('Stopping job queue...');
|
|
360
|
-
await this.jobQueue.end();
|
|
361
818
|
this.logger.debug('Stopping running promise...');
|
|
362
819
|
await this.discoveryRunningPromise?.stop();
|
|
363
820
|
this.logger.debug('Stopping peer discovery service...');
|
|
@@ -377,6 +834,9 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
377
834
|
getPeers(includePending) {
|
|
378
835
|
return this.peerManager.getPeers(includePending);
|
|
379
836
|
}
|
|
837
|
+
getGossipMeshPeerCount(topicType) {
|
|
838
|
+
return this.node.services.pubsub.getMeshPeers(this.topicStrings[topicType]).length;
|
|
839
|
+
}
|
|
380
840
|
handleGossipSubEvent(e) {
|
|
381
841
|
this.logger.trace(`Received PUBSUB message.`);
|
|
382
842
|
const safeJob = async ()=>{
|
|
@@ -396,6 +856,9 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
396
856
|
*/ sendBatchRequest(protocol, requests, pinnedPeerId) {
|
|
397
857
|
return this.reqresp.sendBatchRequest(protocol, requests, pinnedPeerId);
|
|
398
858
|
}
|
|
859
|
+
sendRequestToPeer(peerId, subProtocol, payload, dialTimeout) {
|
|
860
|
+
return this.reqresp.sendRequestToPeer(peerId, subProtocol, payload, dialTimeout);
|
|
861
|
+
}
|
|
399
862
|
/**
|
|
400
863
|
* Get the ENR of the node
|
|
401
864
|
* @returns The ENR of the node
|
|
@@ -405,6 +868,22 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
405
868
|
registerBlockReceivedCallback(callback) {
|
|
406
869
|
this.blockReceivedCallback = callback;
|
|
407
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
|
+
}
|
|
408
887
|
/**
|
|
409
888
|
* Subscribes to a topic.
|
|
410
889
|
* @param topic - The topic to subscribe to.
|
|
@@ -423,7 +902,9 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
423
902
|
if (!this.node.services.pubsub) {
|
|
424
903
|
throw new Error('Pubsub service not available.');
|
|
425
904
|
}
|
|
426
|
-
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);
|
|
427
908
|
const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
|
|
428
909
|
return result.recipients.length;
|
|
429
910
|
}
|
|
@@ -437,12 +918,15 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
437
918
|
case this.topicStrings[TopicType.tx]:
|
|
438
919
|
topicType = TopicType.tx;
|
|
439
920
|
break;
|
|
440
|
-
case this.topicStrings[TopicType.block_attestation]:
|
|
441
|
-
topicType = TopicType.block_attestation;
|
|
442
|
-
break;
|
|
443
921
|
case this.topicStrings[TopicType.block_proposal]:
|
|
444
922
|
topicType = TopicType.block_proposal;
|
|
445
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;
|
|
446
930
|
default:
|
|
447
931
|
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
448
932
|
break;
|
|
@@ -463,23 +947,97 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
463
947
|
};
|
|
464
948
|
}
|
|
465
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
|
+
/**
|
|
466
969
|
* Handles a new gossip message that was received by the client.
|
|
467
970
|
* @param topic - The message's topic.
|
|
468
971
|
* @param data - The message data
|
|
469
972
|
*/ async handleNewGossipMessage(msg, msgId, source) {
|
|
470
|
-
const
|
|
973
|
+
const msgReceivedTime = Date.now();
|
|
974
|
+
let topicType;
|
|
975
|
+
const p2pMessage = this.safelyDeserializeP2PMessage(msgId, source, msg.data);
|
|
976
|
+
if (!p2pMessage) {
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
471
979
|
const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
|
|
472
980
|
if (!preValidationResult.result) {
|
|
473
981
|
return;
|
|
474
982
|
}
|
|
983
|
+
// Determine topic type for attributes
|
|
475
984
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
476
|
-
|
|
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;
|
|
477
992
|
}
|
|
478
|
-
|
|
479
|
-
|
|
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();
|
|
480
1038
|
}
|
|
481
|
-
if (
|
|
482
|
-
|
|
1039
|
+
if (latency !== undefined && topicType !== undefined) {
|
|
1040
|
+
this.instrumentation.recordMessageLatency(topicType, latency);
|
|
483
1041
|
}
|
|
484
1042
|
return;
|
|
485
1043
|
}
|
|
@@ -491,6 +1049,7 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
491
1049
|
try {
|
|
492
1050
|
resultAndObj = await validationFunc();
|
|
493
1051
|
} catch (err) {
|
|
1052
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
494
1053
|
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
495
1054
|
msgId,
|
|
496
1055
|
source: source.toString(),
|
|
@@ -507,25 +1066,42 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
507
1066
|
const validationFunc = async ()=>{
|
|
508
1067
|
const tx = Tx.fromBuffer(payloadData);
|
|
509
1068
|
const isValid = await this.validatePropagatedTx(tx, source);
|
|
510
|
-
|
|
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));
|
|
511
1086
|
this.logger.trace(`Validate propagated tx`, {
|
|
512
1087
|
isValid,
|
|
513
|
-
|
|
1088
|
+
wasAccepted,
|
|
1089
|
+
wasIgnored,
|
|
514
1090
|
[Attributes.P2P_ID]: source.toString()
|
|
515
1091
|
});
|
|
516
|
-
if (
|
|
1092
|
+
if (wasAccepted) {
|
|
517
1093
|
return {
|
|
518
|
-
result: TopicValidatorResult.
|
|
1094
|
+
result: TopicValidatorResult.Accept,
|
|
1095
|
+
obj: tx
|
|
519
1096
|
};
|
|
520
|
-
} else if (
|
|
1097
|
+
} else if (wasIgnored) {
|
|
521
1098
|
return {
|
|
522
1099
|
result: TopicValidatorResult.Ignore,
|
|
523
1100
|
obj: tx
|
|
524
1101
|
};
|
|
525
1102
|
} else {
|
|
526
1103
|
return {
|
|
527
|
-
result: TopicValidatorResult.
|
|
528
|
-
obj: tx
|
|
1104
|
+
result: TopicValidatorResult.Reject
|
|
529
1105
|
};
|
|
530
1106
|
}
|
|
531
1107
|
};
|
|
@@ -533,153 +1109,442 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
533
1109
|
if (result !== TopicValidatorResult.Accept || !tx) {
|
|
534
1110
|
return;
|
|
535
1111
|
}
|
|
1112
|
+
// Tx was accepted into pool and will be propagated - just log and record metrics
|
|
536
1113
|
const txHash = tx.getTxHash();
|
|
537
1114
|
const txHashString = txHash.toString();
|
|
538
1115
|
this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
|
|
539
1116
|
source: source.toString(),
|
|
540
1117
|
txHash: txHashString
|
|
541
1118
|
});
|
|
542
|
-
|
|
543
|
-
this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
|
-
await this.mempools.txPool.addTxs([
|
|
547
|
-
tx
|
|
548
|
-
]);
|
|
1119
|
+
this.instrumentation.incrementTxReceived(1);
|
|
549
1120
|
}
|
|
550
1121
|
/**
|
|
551
|
-
* Process
|
|
552
|
-
*
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
*/ async processAttestationFromPeer(payloadData, msgId, source) {
|
|
556
|
-
const validationFunc = async ()=>{
|
|
557
|
-
const attestation = BlockAttestation.fromBuffer(payloadData);
|
|
558
|
-
const isValid = await this.validateAttestation(source, attestation);
|
|
559
|
-
const exists = isValid && await this.mempools.attestationPool.hasAttestation(attestation);
|
|
560
|
-
this.logger.trace(`Validate propagated block attestation`, {
|
|
561
|
-
isValid,
|
|
562
|
-
exists,
|
|
563
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
564
|
-
[Attributes.P2P_ID]: source.toString()
|
|
565
|
-
});
|
|
566
|
-
if (!isValid) {
|
|
567
|
-
return {
|
|
568
|
-
result: TopicValidatorResult.Reject
|
|
569
|
-
};
|
|
570
|
-
} else if (exists) {
|
|
571
|
-
return {
|
|
572
|
-
result: TopicValidatorResult.Ignore,
|
|
573
|
-
obj: attestation
|
|
574
|
-
};
|
|
575
|
-
} else {
|
|
576
|
-
return {
|
|
577
|
-
result: TopicValidatorResult.Accept,
|
|
578
|
-
obj: attestation
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
};
|
|
582
|
-
const { result, obj: attestation } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.block_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);
|
|
583
1126
|
if (result !== TopicValidatorResult.Accept || !attestation) {
|
|
584
1127
|
return;
|
|
585
1128
|
}
|
|
586
|
-
this.logger.
|
|
587
|
-
p2pMessageIdentifier: await attestation.
|
|
588
|
-
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,
|
|
589
1132
|
archive: attestation.archive.toString(),
|
|
590
1133
|
source: source.toString()
|
|
591
1134
|
});
|
|
592
|
-
await this.mempools.attestationPool.addAttestations([
|
|
593
|
-
attestation
|
|
594
|
-
]);
|
|
595
1135
|
}
|
|
596
|
-
async
|
|
597
|
-
const
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
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
|
|
606
1177
|
});
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
1178
|
+
return {
|
|
1179
|
+
result: TopicValidatorResult.Ignore,
|
|
1180
|
+
obj: attestation
|
|
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
|
+
});
|
|
621
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
|
|
622
1204
|
};
|
|
623
|
-
|
|
624
|
-
|
|
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) {
|
|
625
1210
|
return;
|
|
626
1211
|
}
|
|
627
1212
|
await this.processValidBlockProposal(block, source);
|
|
628
1213
|
}
|
|
629
|
-
|
|
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.
|
|
630
1298
|
async processValidBlockProposal(block, sender) {
|
|
631
|
-
const slot = block.slotNumber
|
|
632
|
-
const previousSlot = slot - 1n;
|
|
1299
|
+
const slot = block.slotNumber;
|
|
633
1300
|
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
634
|
-
p2pMessageIdentifier: await block.
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
source: sender.toString()
|
|
1301
|
+
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
1302
|
+
source: sender.toString(),
|
|
1303
|
+
...block.toBlockInfo()
|
|
638
1304
|
});
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
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'
|
|
655
1423
|
});
|
|
656
|
-
await this.broadcastAttestation(attestation);
|
|
657
1424
|
}
|
|
1425
|
+
return {
|
|
1426
|
+
result: TopicValidatorResult.Accept,
|
|
1427
|
+
obj: checkpoint,
|
|
1428
|
+
metadata: {
|
|
1429
|
+
isEquivocated,
|
|
1430
|
+
processBlock
|
|
1431
|
+
}
|
|
1432
|
+
};
|
|
658
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
|
+
};
|
|
659
1443
|
}
|
|
660
1444
|
/**
|
|
661
|
-
*
|
|
662
|
-
*
|
|
663
|
-
*/ async
|
|
664
|
-
|
|
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
|
+
}
|
|
665
1465
|
}
|
|
666
1466
|
/**
|
|
667
1467
|
* Propagates provided message to peers.
|
|
668
1468
|
* @param message - The message to propagate.
|
|
669
1469
|
*/ async propagate(message) {
|
|
670
|
-
const p2pMessageIdentifier = await message.
|
|
1470
|
+
const p2pMessageIdentifier = await message.p2pMessageLoggingIdentifier();
|
|
671
1471
|
this.logger.trace(`Message ${p2pMessageIdentifier} queued`, {
|
|
672
1472
|
p2pMessageIdentifier
|
|
673
1473
|
});
|
|
674
|
-
void this.
|
|
675
|
-
await this.sendToPeers(message);
|
|
676
|
-
}).catch((error)=>{
|
|
1474
|
+
void this.sendToPeers(message).catch((error)=>{
|
|
677
1475
|
this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, {
|
|
678
1476
|
error
|
|
679
1477
|
});
|
|
680
1478
|
});
|
|
681
1479
|
}
|
|
682
1480
|
/**
|
|
1481
|
+
* Validate the requested block transactions. Allow partial returns.
|
|
1482
|
+
* @param request - The block transactions request.
|
|
1483
|
+
* @param response - The block transactions response.
|
|
1484
|
+
* @param peerId - The ID of the peer that made the request.
|
|
1485
|
+
* @returns True if the requested block transactions are valid, false otherwise.
|
|
1486
|
+
*/ async validateRequestedBlockTxs(request, response, peerId) {
|
|
1487
|
+
const requestedTxValidator = this.createRequestedTxValidator();
|
|
1488
|
+
try {
|
|
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
|
+
}
|
|
1536
|
+
await Promise.all(response.txs.map((tx)=>this.validateRequestedTx(tx, peerId, requestedTxValidator)));
|
|
1537
|
+
return true;
|
|
1538
|
+
} catch (e) {
|
|
1539
|
+
if (e instanceof ValidationError) {
|
|
1540
|
+
this.logger.warn(`Failed validation for requested block txs from peer ${peerId.toString()}`);
|
|
1541
|
+
} else {
|
|
1542
|
+
this.logger.error(`Error during validation of requested block txs`, e);
|
|
1543
|
+
}
|
|
1544
|
+
return false;
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
/**
|
|
683
1548
|
* Validate a collection of txs that has been requested from a peer.
|
|
684
1549
|
*
|
|
685
1550
|
* The core component of this validator is that each tx hash MUST match the requested tx hash,
|
|
@@ -689,39 +1554,86 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
689
1554
|
* ReqRespSubProtocol.TX subprotocol validation.
|
|
690
1555
|
*
|
|
691
1556
|
* @param requestedTxHash - The collection of the txs that was requested.
|
|
692
|
-
* @param responseTx - The
|
|
1557
|
+
* @param responseTx - The collection of txs that was received as a response to the request.
|
|
693
1558
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
694
1559
|
* @returns True if the whole collection of txs is valid, false otherwise.
|
|
695
|
-
*/
|
|
696
|
-
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
697
|
-
async validateRequestedTx(requestedTxHash, responseTx, peerId) {
|
|
1560
|
+
*/ async validateRequestedTxs(requestedTxHash, responseTx, peerId) {
|
|
698
1561
|
const requested = new Set(requestedTxHash.map((h)=>h.toString()));
|
|
699
|
-
const
|
|
1562
|
+
const requestedTxValidator = this.createRequestedTxValidator();
|
|
1563
|
+
//TODO: (mralj) - this is somewhat naive implementation, if single tx is invalid we consider the whole response invalid.
|
|
1564
|
+
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
700
1565
|
try {
|
|
701
|
-
await Promise.all(responseTx.map(
|
|
702
|
-
if (!requested.has(tx.getTxHash().toString())) {
|
|
703
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
704
|
-
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
705
|
-
}
|
|
706
|
-
const { result } = await proofValidator.validateTx(tx);
|
|
707
|
-
if (result === 'invalid') {
|
|
708
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
709
|
-
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
710
|
-
}
|
|
711
|
-
}));
|
|
1566
|
+
await Promise.all(responseTx.map((tx)=>this.validateRequestedTx(tx, peerId, requestedTxValidator, requested)));
|
|
712
1567
|
return true;
|
|
713
1568
|
} catch (e) {
|
|
714
1569
|
if (e instanceof ValidationError) {
|
|
715
|
-
this.logger.
|
|
1570
|
+
this.logger.warn(`Failed to validate requested txs from peer ${peerId.toString()}, reason ${e.message}`);
|
|
716
1571
|
} else {
|
|
717
|
-
this.logger.
|
|
1572
|
+
this.logger.error(`Error during validation of requested txs`, e);
|
|
1573
|
+
}
|
|
1574
|
+
return false;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
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;
|
|
718
1609
|
}
|
|
1610
|
+
return true;
|
|
1611
|
+
} catch (e) {
|
|
1612
|
+
this.logger.warn(`Error validating requested block`, e);
|
|
719
1613
|
return false;
|
|
720
1614
|
}
|
|
721
1615
|
}
|
|
1616
|
+
async validateRequestedTx(tx, peerId, txValidator, requested) {
|
|
1617
|
+
const penalize = (severity)=>this.peerManager.penalizePeer(peerId, severity);
|
|
1618
|
+
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
1619
|
+
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1620
|
+
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
1621
|
+
}
|
|
1622
|
+
const { result } = await txValidator.validateTx(tx);
|
|
1623
|
+
if (result === 'invalid') {
|
|
1624
|
+
penalize(PeerErrorSeverity.LowToleranceError);
|
|
1625
|
+
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
createRequestedTxValidator() {
|
|
1629
|
+
return createTxReqRespValidator(this.proofVerifier, {
|
|
1630
|
+
l1ChainId: this.config.l1ChainId,
|
|
1631
|
+
rollupVersion: this.config.rollupVersion
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
722
1634
|
async validatePropagatedTx(tx, peerId) {
|
|
723
1635
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
724
|
-
// 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)
|
|
725
1637
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
726
1638
|
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
727
1639
|
for (const validator of messageValidators){
|
|
@@ -733,7 +1645,7 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
733
1645
|
let { severity } = outcome.failure;
|
|
734
1646
|
// Double spend validator has a special case handler
|
|
735
1647
|
if (name === 'doubleSpendValidator') {
|
|
736
|
-
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
|
|
737
1649
|
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
738
1650
|
}
|
|
739
1651
|
this.peerManager.penalizePeer(peerId, severity);
|
|
@@ -753,9 +1665,23 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
753
1665
|
};
|
|
754
1666
|
return gasFees;
|
|
755
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
|
+
}
|
|
756
1682
|
async validate(txs) {
|
|
757
1683
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
758
|
-
// 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)
|
|
759
1685
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
760
1686
|
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
761
1687
|
await Promise.all(txs.map(async (tx)=>{
|
|
@@ -783,8 +1709,8 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
783
1709
|
*/ async createMessageValidators(currentBlockNumber, nextSlotTimestamp) {
|
|
784
1710
|
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
785
1711
|
const allowedInSetup = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
|
|
786
|
-
const blockNumberInWhichTheTxIsConsideredToBeIncluded = currentBlockNumber + 1;
|
|
787
|
-
return createTxMessageValidators(nextSlotTimestamp, blockNumberInWhichTheTxIsConsideredToBeIncluded, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion,
|
|
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());
|
|
788
1714
|
}
|
|
789
1715
|
/**
|
|
790
1716
|
* Run validations on a tx.
|
|
@@ -839,11 +1765,11 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
839
1765
|
}
|
|
840
1766
|
const snapshotValidator = new DoubleSpendTxValidator({
|
|
841
1767
|
nullifiersExist: async (nullifiers)=>{
|
|
842
|
-
const merkleTree = this.worldStateSynchronizer.getSnapshot(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow);
|
|
1768
|
+
const merkleTree = this.worldStateSynchronizer.getSnapshot(BlockNumber(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow));
|
|
843
1769
|
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
844
1770
|
return indices.map((index)=>index !== undefined);
|
|
845
1771
|
}
|
|
846
|
-
});
|
|
1772
|
+
}, this.logger.getBindings());
|
|
847
1773
|
const validSnapshot = await snapshotValidator.validateTx(tx);
|
|
848
1774
|
if (validSnapshot.result !== 'valid') {
|
|
849
1775
|
return PeerErrorSeverity.LowToleranceError;
|
|
@@ -851,31 +1777,17 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
851
1777
|
return PeerErrorSeverity.HighToleranceError;
|
|
852
1778
|
}
|
|
853
1779
|
/**
|
|
854
|
-
* Validate
|
|
1780
|
+
* Validate a checkpoint attestation.
|
|
855
1781
|
*
|
|
856
|
-
* @param attestation - The attestation to validate.
|
|
857
|
-
* @returns True if the attestation is valid, false otherwise.
|
|
858
|
-
*/ async
|
|
859
|
-
const
|
|
860
|
-
if (
|
|
861
|
-
this.
|
|
862
|
-
|
|
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);
|
|
863
1789
|
}
|
|
864
|
-
return
|
|
865
|
-
}
|
|
866
|
-
/**
|
|
867
|
-
* Validate a block proposal.
|
|
868
|
-
*
|
|
869
|
-
* @param block - The block proposal to validate.
|
|
870
|
-
* @returns True if the block proposal is valid, false otherwise.
|
|
871
|
-
*/ async validateBlockProposal(peerId, block) {
|
|
872
|
-
const severity = await this.blockProposalValidator.validate(block);
|
|
873
|
-
if (severity) {
|
|
874
|
-
this.logger.debug(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
875
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
876
|
-
return false;
|
|
877
|
-
}
|
|
878
|
-
return true;
|
|
1790
|
+
return result;
|
|
879
1791
|
}
|
|
880
1792
|
getPeerScore(peerId) {
|
|
881
1793
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
@@ -885,7 +1797,7 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
885
1797
|
}
|
|
886
1798
|
async sendToPeers(message) {
|
|
887
1799
|
const parent = message.constructor;
|
|
888
|
-
const identifier = await message.
|
|
1800
|
+
const identifier = await message.p2pMessageLoggingIdentifier().then((i)=>i.toString());
|
|
889
1801
|
this.logger.trace(`Sending message ${identifier}`, {
|
|
890
1802
|
p2pMessageIdentifier: identifier
|
|
891
1803
|
});
|
|
@@ -912,39 +1824,3 @@ import { P2PInstrumentation } from './instrumentation.js';
|
|
|
912
1824
|
}
|
|
913
1825
|
}
|
|
914
1826
|
}
|
|
915
|
-
_ts_decorate([
|
|
916
|
-
trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
|
|
917
|
-
[Attributes.SLOT_NUMBER]: block.slotNumber.toNumber(),
|
|
918
|
-
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
919
|
-
[Attributes.P2P_ID]: await block.p2pMessageIdentifier().then((i)=>i.toString())
|
|
920
|
-
}))
|
|
921
|
-
], LibP2PService.prototype, "processValidBlockProposal", null);
|
|
922
|
-
_ts_decorate([
|
|
923
|
-
trackSpan('Libp2pService.broadcastAttestation', async (attestation)=>({
|
|
924
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
|
|
925
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
926
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then((i)=>i.toString())
|
|
927
|
-
}))
|
|
928
|
-
], LibP2PService.prototype, "broadcastAttestation", null);
|
|
929
|
-
_ts_decorate([
|
|
930
|
-
trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx)=>({
|
|
931
|
-
[Attributes.TX_HASH]: requestedTxHash.toString()
|
|
932
|
-
}))
|
|
933
|
-
], LibP2PService.prototype, "validateRequestedTx", null);
|
|
934
|
-
_ts_decorate([
|
|
935
|
-
trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
|
|
936
|
-
[Attributes.TX_HASH]: tx.getTxHash().toString()
|
|
937
|
-
}))
|
|
938
|
-
], LibP2PService.prototype, "validatePropagatedTx", null);
|
|
939
|
-
_ts_decorate([
|
|
940
|
-
trackSpan('Libp2pService.validateAttestation', async (_, attestation)=>({
|
|
941
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
|
|
942
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
943
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then((i)=>i.toString())
|
|
944
|
-
}))
|
|
945
|
-
], LibP2PService.prototype, "validateAttestation", null);
|
|
946
|
-
_ts_decorate([
|
|
947
|
-
trackSpan('Libp2pService.validateBlockProposal', (_peerId, block)=>({
|
|
948
|
-
[Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString()
|
|
949
|
-
}))
|
|
950
|
-
], LibP2PService.prototype, "validateBlockProposal", null);
|