@aztec/p2p 0.0.1-commit.3469e52 → 0.0.1-commit.43597cc1
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 +3 -3
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +11 -8
- package/dest/client/interface.d.ts +9 -2
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +7 -4
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +24 -7
- 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 +16 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +7 -2
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +94 -87
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +411 -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 +351 -85
- 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/index.d.ts +2 -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 +1 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +2 -2
- package/dest/mem_pools/interface.d.ts +3 -3
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +3 -3
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +3 -2
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +3 -2
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +8 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +2 -0
- 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/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 +119 -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 +90 -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 +89 -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 +131 -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 +17 -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 +63 -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 +91 -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 +70 -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 +63 -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 +5 -0
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/index.js +4 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +197 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.js +6 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +71 -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 +95 -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 +99 -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 +332 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +55 -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 +156 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +69 -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 +748 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +3 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +40 -9
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +18 -6
- 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/proposal_validator/proposal_validator.d.ts +3 -3
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +46 -15
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +3 -3
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +66 -11
- 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 +5 -4
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +3 -2
- 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 +3 -2
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +3 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +8 -3
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +21 -11
- 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 +3 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
- package/dest/msg_validators/tx_validator/size_validator.d.ts +3 -1
- package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/size_validator.js +4 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +2 -2
- 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.js +1 -1
- package/dest/services/dummy_service.d.ts +18 -2
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +42 -0
- 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 +161 -0
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
- package/dest/services/gossipsub/topic_score_params.js +324 -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 +1 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +14 -3
- package/dest/services/libp2p/libp2p_service.d.ts +81 -34
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +356 -288
- package/dest/services/peer-manager/metrics.d.ts +2 -2
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +20 -5
- package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +33 -4
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +47 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +566 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +50 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +37 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +151 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +54 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +139 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
- package/dest/services/reqresp/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 -1
- 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/interface.d.ts +5 -3
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +2 -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 -5
- 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 +5 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +6 -4
- 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 +23 -6
- 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 +44 -13
- package/dest/services/reqresp/reqresp.d.ts +6 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +58 -22
- package/dest/services/service.d.ts +21 -1
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +4 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +9 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +5 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +17 -10
- package/dest/services/tx_collection/index.d.ts +2 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -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 +9 -2
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +48 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
- package/dest/services/tx_collection/proposal_tx_collector.js +49 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts +3 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +8 -8
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +5 -5
- package/dest/services/tx_file_store/config.d.ts +18 -0
- package/dest/services/tx_file_store/config.d.ts.map +1 -0
- package/dest/services/tx_file_store/config.js +26 -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 +47 -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 +149 -0
- package/dest/services/tx_provider.d.ts +3 -3
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.d.ts +1 -1
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +5 -5
- 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/reqresp-nodes.d.ts +1 -1
- 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 +152 -0
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
- package/dest/test-helpers/testbench-utils.js +308 -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 +212 -130
- 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 -44
- package/package.json +14 -14
- package/src/bootstrap/bootstrap.ts +7 -4
- package/src/client/factory.ts +13 -14
- package/src/client/interface.ts +13 -1
- package/src/client/p2p_client.ts +37 -13
- package/src/client/test/tx_proposal_collector/README.md +227 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +336 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
- package/src/config.ts +22 -2
- package/src/mem_pools/attestation_pool/attestation_pool.ts +444 -90
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +436 -100
- package/src/mem_pools/attestation_pool/index.ts +9 -2
- package/src/mem_pools/index.ts +1 -1
- package/src/mem_pools/instrumentation.ts +2 -1
- package/src/mem_pools/interface.ts +2 -2
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +2 -2
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +2 -1
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +2 -1
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +10 -7
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +4 -2
- package/src/mem_pools/tx_pool_v2/README.md +209 -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/eviction/eviction_manager.ts +147 -0
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +118 -0
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +111 -0
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +23 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +164 -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 +86 -0
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +72 -0
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +31 -0
- package/src/mem_pools/tx_pool_v2/index.ts +11 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +227 -0
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +161 -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 +417 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +212 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +882 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +25 -13
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +16 -10
- package/src/msg_validators/clock_tolerance.ts +51 -0
- package/src/msg_validators/proposal_validator/proposal_validator.ts +21 -14
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +53 -14
- package/src/msg_validators/tx_validator/archive_cache.ts +3 -3
- package/src/msg_validators/tx_validator/block_header_validator.ts +6 -5
- package/src/msg_validators/tx_validator/data_validator.ts +6 -2
- package/src/msg_validators/tx_validator/double_spend_validator.ts +4 -3
- package/src/msg_validators/tx_validator/factory.ts +64 -23
- package/src/msg_validators/tx_validator/gas_validator.ts +9 -3
- package/src/msg_validators/tx_validator/metadata_validator.ts +6 -3
- package/src/msg_validators/tx_validator/phases_validator.ts +5 -3
- package/src/msg_validators/tx_validator/size_validator.ts +6 -2
- package/src/msg_validators/tx_validator/timestamp_validator.ts +6 -3
- 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 +51 -0
- package/src/services/gossipsub/README.md +626 -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 +451 -0
- package/src/services/index.ts +1 -0
- package/src/services/libp2p/instrumentation.ts +15 -2
- package/src/services/libp2p/libp2p_service.ts +390 -304
- package/src/services/peer-manager/metrics.ts +21 -4
- package/src/services/peer-manager/peer_scoring.ts +29 -1
- package/src/services/reqresp/batch-tx-requester/README.md +305 -0
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +706 -0
- package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
- package/src/services/reqresp/batch-tx-requester/interface.ts +57 -0
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +209 -0
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +205 -0
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +65 -4
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +16 -0
- package/src/services/reqresp/interface.ts +5 -2
- package/src/services/reqresp/metrics.ts +34 -9
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +7 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -11
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +57 -9
- package/src/services/reqresp/reqresp.ts +66 -19
- package/src/services/service.ts +24 -0
- package/src/services/tx_collection/config.ts +15 -1
- package/src/services/tx_collection/fast_tx_collection.ts +30 -17
- package/src/services/tx_collection/index.ts +5 -0
- package/src/services/tx_collection/instrumentation.ts +11 -2
- package/src/services/tx_collection/proposal_tx_collector.ts +112 -0
- package/src/services/tx_collection/slow_tx_collection.ts +2 -2
- package/src/services/tx_collection/tx_collection.ts +8 -8
- package/src/services/tx_file_store/config.ts +43 -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 +173 -0
- package/src/services/tx_provider.ts +2 -2
- package/src/services/tx_provider_instrumentation.ts +11 -5
- package/src/test-helpers/index.ts +2 -0
- package/src/test-helpers/reqresp-nodes.ts +2 -1
- package/src/test-helpers/test_tx_provider.ts +64 -0
- package/src/test-helpers/testbench-utils.ts +362 -0
- package/src/testbench/p2p_client_testbench_worker.ts +321 -122
- package/src/testbench/worker_client_manager.ts +304 -47
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
- 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 -218
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
- 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 -180
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
-
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { randomInt } from '@aztec/foundation/crypto/random';
|
|
4
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
7
|
import { Timer } from '@aztec/foundation/timer';
|
|
8
8
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
9
|
-
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
10
9
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
11
|
-
import type { EthAddress,
|
|
10
|
+
import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
|
|
12
11
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
13
12
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
14
13
|
import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
@@ -20,6 +19,7 @@ import {
|
|
|
20
19
|
type Gossipable,
|
|
21
20
|
P2PClientType,
|
|
22
21
|
P2PMessage,
|
|
22
|
+
type ValidationResult as P2PValidationResult,
|
|
23
23
|
PeerErrorSeverity,
|
|
24
24
|
TopicType,
|
|
25
25
|
createTopicString,
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
type GossipsubMessage,
|
|
46
46
|
gossipsub,
|
|
47
47
|
} from '@chainsafe/libp2p-gossipsub';
|
|
48
|
-
import { createPeerScoreParams
|
|
48
|
+
import { createPeerScoreParams } from '@chainsafe/libp2p-gossipsub/score';
|
|
49
49
|
import { SignaturePolicy } from '@chainsafe/libp2p-gossipsub/types';
|
|
50
50
|
import { noise } from '@chainsafe/libp2p-noise';
|
|
51
51
|
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
@@ -59,58 +59,57 @@ import { ENR } from '@nethermindeth/enr';
|
|
|
59
59
|
import { createLibp2p } from 'libp2p';
|
|
60
60
|
|
|
61
61
|
import type { P2PConfig } from '../../config.js';
|
|
62
|
-
import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
|
|
63
62
|
import type { MemPools } from '../../mem_pools/interface.js';
|
|
64
63
|
import {
|
|
65
64
|
BlockProposalValidator,
|
|
66
65
|
CheckpointAttestationValidator,
|
|
67
66
|
CheckpointProposalValidator,
|
|
67
|
+
DoubleSpendTxValidator,
|
|
68
68
|
FishermanAttestationValidator,
|
|
69
|
-
|
|
69
|
+
getDefaultAllowedSetupFunctions,
|
|
70
70
|
} from '../../msg_validators/index.js';
|
|
71
71
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
72
|
-
import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
|
|
73
|
-
import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
74
72
|
import {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
TxProofValidator,
|
|
80
|
-
} from '../../msg_validators/tx_validator/index.js';
|
|
73
|
+
type MessageValidator,
|
|
74
|
+
createTxMessageValidators,
|
|
75
|
+
createTxReqRespValidator,
|
|
76
|
+
} from '../../msg_validators/tx_validator/factory.js';
|
|
81
77
|
import { GossipSubEvent } from '../../types/index.js';
|
|
82
78
|
import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
|
|
83
79
|
import { getVersions } from '../../versioning.js';
|
|
84
80
|
import { AztecDatastore } from '../data_store.js';
|
|
85
81
|
import { DiscV5Service } from '../discv5/discV5_service.js';
|
|
86
82
|
import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
87
|
-
import { gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
83
|
+
import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
84
|
+
import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
|
|
88
85
|
import type { PeerManagerInterface } from '../peer-manager/interface.js';
|
|
89
86
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
90
87
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
88
|
+
import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
|
|
91
89
|
import type { P2PReqRespConfig } from '../reqresp/config.js';
|
|
92
90
|
import {
|
|
93
91
|
DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
94
92
|
type ReqRespInterface,
|
|
93
|
+
type ReqRespResponse,
|
|
95
94
|
ReqRespSubProtocol,
|
|
96
95
|
type ReqRespSubProtocolHandler,
|
|
97
96
|
type ReqRespSubProtocolHandlers,
|
|
98
97
|
type ReqRespSubProtocolValidators,
|
|
99
98
|
type SubProtocolMap,
|
|
100
99
|
ValidationError,
|
|
101
|
-
} from '../reqresp/
|
|
102
|
-
import { reqRespBlockTxsHandler } from '../reqresp/protocols/block_txs/block_txs_handler.js';
|
|
103
|
-
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
|
|
100
|
+
} from '../reqresp/index.js';
|
|
104
101
|
import {
|
|
105
102
|
AuthRequest,
|
|
106
103
|
BlockTxsRequest,
|
|
107
104
|
BlockTxsResponse,
|
|
108
105
|
StatusMessage,
|
|
109
106
|
pingHandler,
|
|
107
|
+
reqGoodbyeHandler,
|
|
110
108
|
reqRespBlockHandler,
|
|
109
|
+
reqRespBlockTxsHandler,
|
|
111
110
|
reqRespStatusHandler,
|
|
112
111
|
reqRespTxHandler,
|
|
113
|
-
} from '../reqresp/
|
|
112
|
+
} from '../reqresp/index.js';
|
|
114
113
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
115
114
|
import type {
|
|
116
115
|
P2PBlockReceivedCallback,
|
|
@@ -129,9 +128,9 @@ interface ValidationResult {
|
|
|
129
128
|
type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: ValidationResult };
|
|
130
129
|
|
|
131
130
|
// REFACTOR: Unify with the type above
|
|
132
|
-
type ReceivedMessageValidationResult<T> =
|
|
133
|
-
| { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject
|
|
134
|
-
| { obj?:
|
|
131
|
+
type ReceivedMessageValidationResult<T, M = undefined> =
|
|
132
|
+
| { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject>; metadata?: M }
|
|
133
|
+
| { obj?: T; result: TopicValidatorResult.Reject; metadata?: M };
|
|
135
134
|
|
|
136
135
|
/**
|
|
137
136
|
* Lib P2P implementation of the P2PService interface.
|
|
@@ -150,6 +149,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
150
149
|
|
|
151
150
|
private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
|
|
152
151
|
|
|
152
|
+
/** Callback invoked when a duplicate proposal is detected (triggers slashing). */
|
|
153
|
+
private duplicateProposalCallback?: (info: {
|
|
154
|
+
slot: SlotNumber;
|
|
155
|
+
proposer: EthAddress;
|
|
156
|
+
type: 'checkpoint' | 'block';
|
|
157
|
+
}) => void;
|
|
158
|
+
|
|
153
159
|
/**
|
|
154
160
|
* Callback for when a block is received from a peer.
|
|
155
161
|
* @param block - The block received from the peer.
|
|
@@ -178,9 +184,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
178
184
|
protected node: PubSubLibp2p,
|
|
179
185
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
180
186
|
private reqresp: ReqRespInterface,
|
|
181
|
-
|
|
187
|
+
protected peerManager: PeerManagerInterface,
|
|
182
188
|
protected mempools: MemPools,
|
|
183
|
-
|
|
189
|
+
protected archiver: L2BlockSource & ContractDataSource,
|
|
184
190
|
private epochCache: EpochCacheInterface,
|
|
185
191
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
186
192
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
@@ -285,14 +291,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
285
291
|
|
|
286
292
|
const datastore = new AztecDatastore(peerStore);
|
|
287
293
|
|
|
288
|
-
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry);
|
|
294
|
+
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry, logger.getBindings());
|
|
289
295
|
|
|
290
296
|
const peerDiscoveryService = new DiscV5Service(
|
|
291
297
|
peerId,
|
|
292
298
|
config,
|
|
293
299
|
packageVersion,
|
|
294
300
|
telemetry,
|
|
295
|
-
createLogger(`${logger.module}:discv5_service
|
|
301
|
+
createLogger(`${logger.module}:discv5_service`, logger.getBindings()),
|
|
296
302
|
);
|
|
297
303
|
|
|
298
304
|
// Seed libp2p's bootstrap discovery with private and trusted peers
|
|
@@ -306,11 +312,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
306
312
|
const versions = getVersions(config);
|
|
307
313
|
const protocolVersion = compressComponentVersions(versions);
|
|
308
314
|
|
|
309
|
-
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
310
|
-
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
311
|
-
const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
|
|
312
|
-
const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
|
|
313
|
-
|
|
314
315
|
const preferredPeersEnrs: ENR[] = config.preferredPeers.map(enr => ENR.decodeTxt(enr));
|
|
315
316
|
const directPeers = (
|
|
316
317
|
await Promise.all(
|
|
@@ -330,6 +331,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
330
331
|
|
|
331
332
|
const announceTcpMultiaddr = config.p2pIp ? [convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')] : [];
|
|
332
333
|
|
|
334
|
+
// Create dynamic topic score params based on network configuration
|
|
335
|
+
const l1Constants = epochCache.getL1Constants();
|
|
336
|
+
const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
|
|
337
|
+
slotDurationMs: l1Constants.slotDuration * 1000,
|
|
338
|
+
heartbeatIntervalMs: config.gossipsubInterval,
|
|
339
|
+
targetCommitteeSize: l1Constants.targetCommitteeSize,
|
|
340
|
+
blockDurationMs: config.blockDurationMs,
|
|
341
|
+
});
|
|
342
|
+
|
|
333
343
|
const node = await createLibp2p({
|
|
334
344
|
start: false,
|
|
335
345
|
peerId,
|
|
@@ -425,35 +435,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
425
435
|
scoreParams: createPeerScoreParams({
|
|
426
436
|
// IPColocation factor can be disabled for local testing - default to -5
|
|
427
437
|
IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
|
|
428
|
-
topics:
|
|
429
|
-
[txTopic]: createTopicScoreParams({
|
|
430
|
-
topicWeight: 1,
|
|
431
|
-
invalidMessageDeliveriesWeight: -20,
|
|
432
|
-
invalidMessageDeliveriesDecay: 0.5,
|
|
433
|
-
}),
|
|
434
|
-
[blockProposalTopic]: createTopicScoreParams({
|
|
435
|
-
topicWeight: 1,
|
|
436
|
-
invalidMessageDeliveriesWeight: -20,
|
|
437
|
-
invalidMessageDeliveriesDecay: 0.5,
|
|
438
|
-
}),
|
|
439
|
-
[checkpointProposalTopic]: createTopicScoreParams({
|
|
440
|
-
topicWeight: 1,
|
|
441
|
-
invalidMessageDeliveriesWeight: -20,
|
|
442
|
-
invalidMessageDeliveriesDecay: 0.5,
|
|
443
|
-
}),
|
|
444
|
-
[checkpointAttestationTopic]: createTopicScoreParams({
|
|
445
|
-
topicWeight: 1,
|
|
446
|
-
invalidMessageDeliveriesWeight: -20,
|
|
447
|
-
invalidMessageDeliveriesDecay: 0.5,
|
|
448
|
-
}),
|
|
449
|
-
},
|
|
438
|
+
topics: topicScoreParams,
|
|
450
439
|
}),
|
|
451
440
|
}) as (components: GossipSubComponents) => GossipSub,
|
|
452
441
|
components: (components: { connectionManager: ConnectionManager }) => ({
|
|
453
442
|
connectionManager: components.connectionManager,
|
|
454
443
|
}),
|
|
455
444
|
},
|
|
456
|
-
logger: createLibp2pComponentLogger(logger.module),
|
|
445
|
+
logger: createLibp2pComponentLogger(logger.module, logger.getBindings()),
|
|
457
446
|
});
|
|
458
447
|
|
|
459
448
|
const peerScoring = new PeerScoring(config, telemetry);
|
|
@@ -472,8 +461,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
472
461
|
epochCache,
|
|
473
462
|
);
|
|
474
463
|
|
|
475
|
-
//
|
|
476
|
-
|
|
464
|
+
// Configure application-specific scoring for gossipsub.
|
|
465
|
+
// The weight scales app score to align with gossipsub thresholds:
|
|
466
|
+
// - Disconnect (-50) × 10 = -500 = gossipThreshold (stops receiving gossip)
|
|
467
|
+
// - Ban (-100) × 10 = -1000 = publishThreshold (cannot publish)
|
|
468
|
+
// Note: positive topic scores can offset penalties, so alignment is best-effort.
|
|
469
|
+
node.services.pubsub.score.params.appSpecificWeight = APP_SPECIFIC_WEIGHT;
|
|
477
470
|
node.services.pubsub.score.params.appSpecificScore = (peerId: string) =>
|
|
478
471
|
peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
479
472
|
|
|
@@ -525,7 +518,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
525
518
|
};
|
|
526
519
|
|
|
527
520
|
if (!this.config.disableTransactions) {
|
|
528
|
-
const blockTxsHandler = reqRespBlockTxsHandler(
|
|
521
|
+
const blockTxsHandler = reqRespBlockTxsHandler(
|
|
522
|
+
this.mempools.attestationPool,
|
|
523
|
+
this.archiver,
|
|
524
|
+
this.mempools.txPool,
|
|
525
|
+
);
|
|
529
526
|
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
530
527
|
}
|
|
531
528
|
|
|
@@ -641,6 +638,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
641
638
|
return this.reqresp.sendBatchRequest(protocol, requests, pinnedPeerId);
|
|
642
639
|
}
|
|
643
640
|
|
|
641
|
+
public sendRequestToPeer(
|
|
642
|
+
peerId: PeerId,
|
|
643
|
+
subProtocol: ReqRespSubProtocol,
|
|
644
|
+
payload: Buffer,
|
|
645
|
+
dialTimeout?: number,
|
|
646
|
+
): Promise<ReqRespResponse> {
|
|
647
|
+
return this.reqresp.sendRequestToPeer(peerId, subProtocol, payload, dialTimeout);
|
|
648
|
+
}
|
|
649
|
+
|
|
644
650
|
/**
|
|
645
651
|
* Get the ENR of the node
|
|
646
652
|
* @returns The ENR of the node
|
|
@@ -657,6 +663,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
657
663
|
this.checkpointReceivedCallback = callback;
|
|
658
664
|
}
|
|
659
665
|
|
|
666
|
+
/**
|
|
667
|
+
* Registers a callback to be invoked when a duplicate proposal is detected.
|
|
668
|
+
* This callback is triggered on the first duplicate (when count goes from 1 to 2).
|
|
669
|
+
*/
|
|
670
|
+
public registerDuplicateProposalCallback(
|
|
671
|
+
callback: (info: { slot: SlotNumber; proposer: EthAddress; type: 'checkpoint' | 'block' }) => void,
|
|
672
|
+
): void {
|
|
673
|
+
this.duplicateProposalCallback = callback;
|
|
674
|
+
}
|
|
675
|
+
|
|
660
676
|
/**
|
|
661
677
|
* Subscribes to a topic.
|
|
662
678
|
* @param topic - The topic to subscribe to.
|
|
@@ -843,13 +859,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
843
859
|
return;
|
|
844
860
|
}
|
|
845
861
|
|
|
846
|
-
protected async validateReceivedMessage<T>(
|
|
847
|
-
validationFunc: () => Promise<ReceivedMessageValidationResult<T>>,
|
|
862
|
+
protected async validateReceivedMessage<T, M = undefined>(
|
|
863
|
+
validationFunc: () => Promise<ReceivedMessageValidationResult<T, M>>,
|
|
848
864
|
msgId: string,
|
|
849
865
|
source: PeerId,
|
|
850
866
|
topicType: TopicType,
|
|
851
|
-
): Promise<ReceivedMessageValidationResult<T>> {
|
|
852
|
-
let resultAndObj: ReceivedMessageValidationResult<T> = { result: TopicValidatorResult.Reject };
|
|
867
|
+
): Promise<ReceivedMessageValidationResult<T, M>> {
|
|
868
|
+
let resultAndObj: ReceivedMessageValidationResult<T, M> = { result: TopicValidatorResult.Reject };
|
|
853
869
|
const timer = new Timer();
|
|
854
870
|
try {
|
|
855
871
|
resultAndObj = await validationFunc();
|
|
@@ -921,46 +937,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
921
937
|
msgId: string,
|
|
922
938
|
source: PeerId,
|
|
923
939
|
): Promise<void> {
|
|
924
|
-
const validationFunc: () => Promise<ReceivedMessageValidationResult<CheckpointAttestation>> = async () => {
|
|
925
|
-
const attestation = CheckpointAttestation.fromBuffer(payloadData);
|
|
926
|
-
const pool = this.mempools.attestationPool;
|
|
927
|
-
const isValid = await this.validateCheckpointAttestation(source, attestation);
|
|
928
|
-
const exists = isValid && (await pool.hasCheckpointAttestation(attestation));
|
|
929
|
-
|
|
930
|
-
let canAdd = true;
|
|
931
|
-
if (isValid && !exists) {
|
|
932
|
-
const slot = attestation.payload.header.slotNumber;
|
|
933
|
-
const { committee } = await this.epochCache.getCommittee(slot);
|
|
934
|
-
const committeeSize = committee?.length ?? 0;
|
|
935
|
-
canAdd = await pool.canAddCheckpointAttestation(attestation, committeeSize);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
this.logger.trace(`Validate propagated checkpoint attestation`, {
|
|
939
|
-
isValid,
|
|
940
|
-
exists,
|
|
941
|
-
canAdd,
|
|
942
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
943
|
-
[Attributes.P2P_ID]: source.toString(),
|
|
944
|
-
});
|
|
945
|
-
|
|
946
|
-
if (!isValid) {
|
|
947
|
-
return { result: TopicValidatorResult.Reject };
|
|
948
|
-
} else if (exists) {
|
|
949
|
-
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
950
|
-
} else if (!canAdd) {
|
|
951
|
-
this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
|
|
952
|
-
slot: attestation.payload.header.slotNumber.toString(),
|
|
953
|
-
archive: attestation.archive.toString(),
|
|
954
|
-
source: source.toString(),
|
|
955
|
-
});
|
|
956
|
-
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
957
|
-
} else {
|
|
958
|
-
return { result: TopicValidatorResult.Accept, obj: attestation };
|
|
959
|
-
}
|
|
960
|
-
};
|
|
961
|
-
|
|
962
940
|
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
963
|
-
|
|
941
|
+
() => this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)),
|
|
964
942
|
msgId,
|
|
965
943
|
source,
|
|
966
944
|
TopicType.checkpoint_attestation,
|
|
@@ -970,8 +948,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
970
948
|
return;
|
|
971
949
|
}
|
|
972
950
|
|
|
973
|
-
this.logger.
|
|
974
|
-
`Received checkpoint attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
|
|
951
|
+
this.logger.verbose(
|
|
952
|
+
`Received valid checkpoint attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
|
|
975
953
|
{
|
|
976
954
|
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
977
955
|
slot: attestation.slotNumber,
|
|
@@ -979,59 +957,154 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
979
957
|
source: source.toString(),
|
|
980
958
|
},
|
|
981
959
|
);
|
|
982
|
-
|
|
983
|
-
await this.mempools.attestationPool.addCheckpointAttestations([attestation]);
|
|
984
960
|
}
|
|
985
961
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
962
|
+
/** Validates a checkpoint attestation and adds it to the pool. Penalizes the peer if validation fails. */
|
|
963
|
+
@trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation) => ({
|
|
964
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
965
|
+
}))
|
|
966
|
+
protected async validateAndStoreCheckpointAttestation(
|
|
967
|
+
peerId: PeerId,
|
|
968
|
+
attestation: CheckpointAttestation,
|
|
969
|
+
): Promise<ReceivedMessageValidationResult<CheckpointAttestation>> {
|
|
970
|
+
const validationResult = await this.checkpointAttestationValidator.validate(attestation);
|
|
971
|
+
|
|
972
|
+
if (validationResult.result === 'reject') {
|
|
973
|
+
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
974
|
+
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
975
|
+
return { result: TopicValidatorResult.Reject };
|
|
976
|
+
}
|
|
991
977
|
|
|
992
|
-
|
|
993
|
-
|
|
978
|
+
if (validationResult.result === 'ignore') {
|
|
979
|
+
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
980
|
+
}
|
|
994
981
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
982
|
+
// Get committee size for the attestation's slot
|
|
983
|
+
const slot = attestation.payload.header.slotNumber;
|
|
984
|
+
const { committee } = await this.epochCache.getCommittee(slot);
|
|
985
|
+
const committeeSize = committee?.length ?? 0;
|
|
986
|
+
|
|
987
|
+
// Try to add the attestation: this handles existence check, cap check, and adding in one call
|
|
988
|
+
const { added, alreadyExists } = await this.mempools.attestationPool.tryAddCheckpointAttestation(
|
|
989
|
+
attestation,
|
|
990
|
+
committeeSize,
|
|
991
|
+
);
|
|
992
|
+
|
|
993
|
+
this.logger.trace(`Validate propagated checkpoint attestation`, {
|
|
994
|
+
added,
|
|
995
|
+
alreadyExists,
|
|
996
|
+
[Attributes.SLOT_NUMBER]: slot.toString(),
|
|
997
|
+
[Attributes.P2P_ID]: peerId.toString(),
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
// Duplicate attestation received, no need to re-broadcast
|
|
1001
|
+
if (alreadyExists) {
|
|
1002
|
+
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// Could not add (cap reached), no need to re-broadcast
|
|
1006
|
+
if (!added) {
|
|
1007
|
+
this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
|
|
1008
|
+
slot: slot.toString(),
|
|
1009
|
+
archive: attestation.archive.toString(),
|
|
1010
|
+
source: peerId.toString(),
|
|
1001
1011
|
});
|
|
1012
|
+
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
1013
|
+
}
|
|
1002
1014
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
return { result: TopicValidatorResult.Ignore, obj: block };
|
|
1007
|
-
} else if (!canAdd) {
|
|
1008
|
-
this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
|
|
1009
|
-
this.logger.warn(`Penalizing peer for block proposal exceeding per-slot cap`, {
|
|
1010
|
-
slot: block.slotNumber.toString(),
|
|
1011
|
-
archive: block.archive.toString(),
|
|
1012
|
-
source: source.toString(),
|
|
1013
|
-
});
|
|
1014
|
-
return { result: TopicValidatorResult.Reject };
|
|
1015
|
-
} else {
|
|
1016
|
-
return { result: TopicValidatorResult.Accept, obj: block };
|
|
1017
|
-
}
|
|
1018
|
-
};
|
|
1015
|
+
// Attestation was added successfully
|
|
1016
|
+
return { result: TopicValidatorResult.Accept, obj: attestation };
|
|
1017
|
+
}
|
|
1019
1018
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1019
|
+
protected async processBlockFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
1020
|
+
const {
|
|
1021
|
+
result,
|
|
1022
|
+
obj: block,
|
|
1023
|
+
metadata: { isEquivocated } = {},
|
|
1024
|
+
} = await this.validateReceivedMessage<BlockProposal, { isEquivocated: boolean }>(
|
|
1025
|
+
() => this.validateAndStoreBlockProposal(source, BlockProposal.fromBuffer(payloadData)),
|
|
1022
1026
|
msgId,
|
|
1023
1027
|
source,
|
|
1024
1028
|
TopicType.block_proposal,
|
|
1025
1029
|
);
|
|
1026
1030
|
|
|
1027
|
-
|
|
1031
|
+
// If not accepted or equivocated, return
|
|
1032
|
+
if (result !== TopicValidatorResult.Accept || !block || isEquivocated) {
|
|
1028
1033
|
return;
|
|
1029
1034
|
}
|
|
1030
1035
|
|
|
1031
1036
|
await this.processValidBlockProposal(block, source);
|
|
1032
1037
|
}
|
|
1033
1038
|
|
|
1034
|
-
|
|
1039
|
+
/** Validates a block proposal. Triggers a penalization to the peer that sent it if invalid. Adds to the mempool if valid. */
|
|
1040
|
+
@trackSpan('Libp2pService.validateAndStoreBlockProposal', (_peerId, block) => ({
|
|
1041
|
+
[Attributes.BLOCK_NUMBER]: block.blockNumber.toString(),
|
|
1042
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
|
|
1043
|
+
}))
|
|
1044
|
+
protected async validateAndStoreBlockProposal(
|
|
1045
|
+
peerId: PeerId,
|
|
1046
|
+
block: BlockProposal,
|
|
1047
|
+
): Promise<ReceivedMessageValidationResult<BlockProposal, { isEquivocated: boolean }>> {
|
|
1048
|
+
const validationResult = await this.blockProposalValidator.validate(block);
|
|
1049
|
+
|
|
1050
|
+
if (validationResult.result === 'reject') {
|
|
1051
|
+
this.logger.warn(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1052
|
+
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1053
|
+
return { result: TopicValidatorResult.Reject };
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
if (validationResult.result === 'ignore') {
|
|
1057
|
+
return { result: TopicValidatorResult.Ignore, obj: block };
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// Try to add the proposal: this handles existence check, cap check, and adding in one call
|
|
1061
|
+
const { added, alreadyExists, totalForPosition } = await this.mempools.attestationPool.tryAddBlockProposal(block);
|
|
1062
|
+
const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
|
|
1063
|
+
|
|
1064
|
+
// Duplicate proposal received, no need to re-broadcast
|
|
1065
|
+
if (alreadyExists) {
|
|
1066
|
+
this.logger.debug(`Ignoring duplicate block proposal received`, {
|
|
1067
|
+
...block.toBlockInfo(),
|
|
1068
|
+
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
1069
|
+
proposer: block.getSender()?.toString(),
|
|
1070
|
+
source: peerId.toString(),
|
|
1071
|
+
});
|
|
1072
|
+
return { result: TopicValidatorResult.Ignore, obj: block, metadata: { isEquivocated } };
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// Too many blocks received for this slot and index, penalize peer and do not re-broadcast
|
|
1076
|
+
if (!added) {
|
|
1077
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1078
|
+
this.logger.warn(`Penalizing peer for block proposal exceeding per-position cap`, {
|
|
1079
|
+
...block.toBlockInfo(),
|
|
1080
|
+
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
1081
|
+
totalForPosition,
|
|
1082
|
+
proposer: block.getSender()?.toString(),
|
|
1083
|
+
source: peerId.toString(),
|
|
1084
|
+
});
|
|
1085
|
+
return { result: TopicValidatorResult.Reject, metadata: { isEquivocated } };
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
1089
|
+
// and do re-broadcast it so other nodes in the network know to slash the proposer
|
|
1090
|
+
if (isEquivocated) {
|
|
1091
|
+
const proposer = block.getSender();
|
|
1092
|
+
this.logger.warn(`Detected duplicate block proposal (equivocation) at slot ${block.slotNumber}`, {
|
|
1093
|
+
...block.toBlockInfo(),
|
|
1094
|
+
source: peerId.toString(),
|
|
1095
|
+
proposer: proposer?.toString(),
|
|
1096
|
+
});
|
|
1097
|
+
// Invoke the duplicate callback on the first duplicate spotted only
|
|
1098
|
+
if (proposer && totalForPosition === 2) {
|
|
1099
|
+
this.duplicateProposalCallback?.({ slot: block.slotNumber, proposer, type: 'block' });
|
|
1100
|
+
}
|
|
1101
|
+
return { result: TopicValidatorResult.Accept, obj: block, metadata: { isEquivocated } };
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// Otherwise, we're good to go!
|
|
1105
|
+
return { result: TopicValidatorResult.Accept, obj: block };
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1035
1108
|
// REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
|
|
1036
1109
|
// should not be here as it does not deal with p2p networking.
|
|
1037
1110
|
@trackSpan('Libp2pService.processValidBlockProposal', async block => ({
|
|
@@ -1039,7 +1112,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1039
1112
|
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
1040
1113
|
[Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1041
1114
|
}))
|
|
1042
|
-
|
|
1115
|
+
protected async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
|
|
1043
1116
|
const slot = block.slotNumber;
|
|
1044
1117
|
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1045
1118
|
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
@@ -1047,22 +1120,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1047
1120
|
...block.toBlockInfo(),
|
|
1048
1121
|
});
|
|
1049
1122
|
|
|
1050
|
-
// Attempt to add proposal
|
|
1051
|
-
try {
|
|
1052
|
-
await this.mempools.attestationPool.addBlockProposal(block);
|
|
1053
|
-
} catch (err: unknown) {
|
|
1054
|
-
// Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
|
|
1055
|
-
if (err instanceof ProposalSlotCapExceededError) {
|
|
1056
|
-
this.logger.warn(`Dropping block proposal due to per-slot proposal cap`, {
|
|
1057
|
-
slot: String(slot),
|
|
1058
|
-
archive: block.archive.toString(),
|
|
1059
|
-
error: (err as Error).message,
|
|
1060
|
-
});
|
|
1061
|
-
return;
|
|
1062
|
-
}
|
|
1063
|
-
throw err;
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
1123
|
// Mark the txs in this proposal as non-evictable
|
|
1067
1124
|
await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
|
|
1068
1125
|
|
|
@@ -1078,66 +1135,145 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1078
1135
|
* Handle a gossiped checkpoint proposal.
|
|
1079
1136
|
* Validates and processes the checkpoint proposal, then triggers the callback for attestation.
|
|
1080
1137
|
*/
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1138
|
+
protected async handleGossipedCheckpointProposal(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
1139
|
+
const {
|
|
1140
|
+
result,
|
|
1141
|
+
obj: checkpoint,
|
|
1142
|
+
metadata: { isEquivocated, processBlock } = {},
|
|
1143
|
+
} = await this.validateReceivedMessage<CheckpointProposal, { isEquivocated: boolean; processBlock: boolean }>(
|
|
1144
|
+
() => this.validateAndStoreCheckpointProposal(source, CheckpointProposal.fromBuffer(payloadData)),
|
|
1145
|
+
msgId,
|
|
1146
|
+
source,
|
|
1147
|
+
TopicType.checkpoint_proposal,
|
|
1148
|
+
);
|
|
1087
1149
|
|
|
1088
|
-
|
|
1089
|
-
|
|
1150
|
+
// If the checkpoint contained a valid last block, we process it even if the checkpoint itself is to be rejected
|
|
1151
|
+
// TODO(palla/mbps): Is this ok? Should we be considering a block from a checkpoint that was equivocated?
|
|
1152
|
+
if (processBlock && checkpoint?.getBlockProposal()) {
|
|
1153
|
+
await this.processValidBlockProposal(checkpoint.getBlockProposal()!, source);
|
|
1154
|
+
}
|
|
1090
1155
|
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1156
|
+
if (result !== TopicValidatorResult.Accept || !checkpoint || isEquivocated) {
|
|
1157
|
+
return;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
await this.processValidCheckpointProposal(checkpoint.toCore(), source);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
/**
|
|
1164
|
+
* Validates a checkpoint proposal. Penalizes peer if validation fails. Adds the checkpoint and
|
|
1165
|
+
* its last block (if present) to the mempool if valid. Triggers equivocation detection on both.
|
|
1166
|
+
*/
|
|
1167
|
+
@trackSpan('Libp2pService.validateAndStoreCheckpointProposal', (_peerId, checkpoint) => ({
|
|
1168
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1169
|
+
}))
|
|
1170
|
+
protected async validateAndStoreCheckpointProposal(
|
|
1171
|
+
peerId: PeerId,
|
|
1172
|
+
checkpoint: CheckpointProposal,
|
|
1173
|
+
): Promise<ReceivedMessageValidationResult<CheckpointProposal, { isEquivocated: boolean; processBlock: boolean }>> {
|
|
1174
|
+
const validationResult = await this.checkpointProposalValidator.validate(checkpoint);
|
|
1175
|
+
|
|
1176
|
+
if (validationResult.result === 'reject') {
|
|
1177
|
+
this.logger.warn(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1178
|
+
this.peerManager.penalizePeer(peerId, validationResult.severity);
|
|
1179
|
+
return { result: TopicValidatorResult.Reject };
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
if (validationResult.result === 'ignore') {
|
|
1183
|
+
return { result: TopicValidatorResult.Ignore, obj: checkpoint };
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// Extract and try to add the block proposal first if present
|
|
1187
|
+
const blockProposal = checkpoint.getBlockProposal();
|
|
1188
|
+
let processBlock = false;
|
|
1189
|
+
if (blockProposal) {
|
|
1190
|
+
this.logger.debug(`Validating block proposal from propagated checkpoint`, {
|
|
1095
1191
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1096
|
-
[Attributes.P2P_ID]:
|
|
1192
|
+
[Attributes.P2P_ID]: peerId.toString(),
|
|
1097
1193
|
});
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
this.
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1194
|
+
const {
|
|
1195
|
+
result,
|
|
1196
|
+
obj,
|
|
1197
|
+
metadata: { isEquivocated } = {},
|
|
1198
|
+
} = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1199
|
+
if (result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1200
|
+
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1201
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1202
|
+
[Attributes.P2P_ID]: peerId.toString(),
|
|
1203
|
+
isEquivocated,
|
|
1204
|
+
result,
|
|
1109
1205
|
});
|
|
1110
1206
|
return { result: TopicValidatorResult.Reject };
|
|
1111
|
-
} else {
|
|
1112
|
-
|
|
1207
|
+
} else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1208
|
+
processBlock = true;
|
|
1113
1209
|
}
|
|
1114
|
-
}
|
|
1210
|
+
}
|
|
1115
1211
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1212
|
+
// Try to add the checkpoint proposal core: this handles existence check, cap check, and adding in one call
|
|
1213
|
+
const checkpointCore = checkpoint.toCore();
|
|
1214
|
+
const tryAddResult = await this.mempools.attestationPool.tryAddCheckpointProposal(checkpointCore);
|
|
1215
|
+
const { added, alreadyExists, totalForPosition } = tryAddResult;
|
|
1216
|
+
const isEquivocated = totalForPosition !== undefined && totalForPosition > 1;
|
|
1217
|
+
|
|
1218
|
+
// Duplicate proposal received, do not re-broadcast
|
|
1219
|
+
if (alreadyExists) {
|
|
1220
|
+
this.logger.debug(`Ignoring duplicate checkpoint proposal received`, {
|
|
1221
|
+
...checkpoint.toCheckpointInfo(),
|
|
1222
|
+
source: peerId.toString(),
|
|
1223
|
+
});
|
|
1224
|
+
return {
|
|
1225
|
+
result: TopicValidatorResult.Ignore,
|
|
1226
|
+
obj: checkpoint,
|
|
1227
|
+
metadata: { isEquivocated, processBlock },
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1122
1230
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1231
|
+
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1232
|
+
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1233
|
+
if (!added) {
|
|
1234
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
1235
|
+
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1236
|
+
...checkpoint.toCheckpointInfo(),
|
|
1237
|
+
totalForPosition,
|
|
1238
|
+
source: peerId.toString(),
|
|
1239
|
+
});
|
|
1240
|
+
return { result: TopicValidatorResult.Reject, obj: checkpoint, metadata: { isEquivocated, processBlock } };
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
1244
|
+
// and do re-broadcast it so other nodes in the network know to slash the proposer
|
|
1245
|
+
if (isEquivocated) {
|
|
1246
|
+
const proposer = checkpoint.getSender();
|
|
1247
|
+
this.logger.warn(`Detected duplicate checkpoint proposal (equivocation) at slot ${checkpoint.slotNumber}`, {
|
|
1248
|
+
...checkpoint.toCheckpointInfo(),
|
|
1249
|
+
source: peerId.toString(),
|
|
1250
|
+
proposer: proposer?.toString(),
|
|
1251
|
+
});
|
|
1252
|
+
// Invoke the duplicate callback on the first duplicate spotted only
|
|
1253
|
+
if (proposer && totalForPosition === 2) {
|
|
1254
|
+
this.duplicateProposalCallback?.({ slot: checkpoint.slotNumber, proposer, type: 'checkpoint' });
|
|
1255
|
+
}
|
|
1256
|
+
return {
|
|
1257
|
+
result: TopicValidatorResult.Accept,
|
|
1258
|
+
obj: checkpoint,
|
|
1259
|
+
metadata: { isEquivocated, processBlock },
|
|
1260
|
+
};
|
|
1125
1261
|
}
|
|
1126
1262
|
|
|
1127
|
-
|
|
1263
|
+
// Otherwise, we're good to go!
|
|
1264
|
+
return { result: TopicValidatorResult.Accept, obj: checkpoint, metadata: { processBlock, isEquivocated } };
|
|
1128
1265
|
}
|
|
1129
1266
|
|
|
1130
1267
|
/**
|
|
1131
1268
|
* Process a validated checkpoint proposal.
|
|
1132
|
-
*
|
|
1133
|
-
* The block callback is invoked before the checkpoint callback.
|
|
1269
|
+
* Note: The proposal was already added to the pool by tryAddCheckpointProposal in handleGossipedCheckpointProposal.
|
|
1134
1270
|
*/
|
|
1135
1271
|
@trackSpan('Libp2pService.processValidCheckpointProposal', async checkpoint => ({
|
|
1136
1272
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber,
|
|
1137
1273
|
[Attributes.BLOCK_ARCHIVE]: checkpoint.archive.toString(),
|
|
1138
1274
|
[Attributes.P2P_ID]: await checkpoint.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1139
1275
|
}))
|
|
1140
|
-
|
|
1276
|
+
protected async processValidCheckpointProposal(checkpoint: CheckpointProposalCore, sender: PeerId) {
|
|
1141
1277
|
const slot = checkpoint.slotNumber;
|
|
1142
1278
|
this.logger.verbose(`Received checkpoint proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1143
1279
|
p2pMessageIdentifier: await checkpoint.p2pMessageLoggingIdentifier(),
|
|
@@ -1146,37 +1282,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1146
1282
|
source: sender.toString(),
|
|
1147
1283
|
});
|
|
1148
1284
|
|
|
1149
|
-
// Extract block proposal before adding to pool (pool stores them separately)
|
|
1150
|
-
const blockProposal = checkpoint.getBlockProposal();
|
|
1151
|
-
|
|
1152
|
-
// Add proposal to the pool (this extracts and stores block proposal separately)
|
|
1153
|
-
await this.mempools.attestationPool.addCheckpointProposal(checkpoint);
|
|
1154
|
-
|
|
1155
|
-
// Mark txs as non-evictable if present (from the last block)
|
|
1156
|
-
if (checkpoint.txHashes.length > 0) {
|
|
1157
|
-
await this.mempools.txPool.markTxsAsNonEvictable(checkpoint.txHashes);
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
// If there was a last block proposal, invoke the block callback first for validation.
|
|
1161
|
-
// Note: The block proposal is already stored in the pool by addCheckpointProposal.
|
|
1162
|
-
if (blockProposal) {
|
|
1163
|
-
const isValid = await this.blockReceivedCallback(blockProposal, sender);
|
|
1164
|
-
if (!isValid) {
|
|
1165
|
-
this.logger.warn(`Block proposal from checkpoint failed validation`, {
|
|
1166
|
-
slot: slot.toString(),
|
|
1167
|
-
archive: checkpoint.archive.toString(),
|
|
1168
|
-
blockNumber: blockProposal.blockNumber.toString(),
|
|
1169
|
-
});
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
1285
|
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1175
1286
|
// to validate and potentially generate attestations
|
|
1176
|
-
const attestations = await this.checkpointReceivedCallback(checkpoint
|
|
1287
|
+
const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
|
|
1177
1288
|
if (attestations && attestations.length > 0) {
|
|
1178
1289
|
// If the callback returned attestations, add them to the pool and propagate them
|
|
1179
|
-
await this.mempools.attestationPool.
|
|
1290
|
+
await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
1180
1291
|
for (const attestation of attestations) {
|
|
1181
1292
|
await this.propagate(attestation);
|
|
1182
1293
|
}
|
|
@@ -1203,9 +1314,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1203
1314
|
* @returns True if the requested block transactions are valid, false otherwise.
|
|
1204
1315
|
*/
|
|
1205
1316
|
@trackSpan('Libp2pService.validateRequestedBlockTxs', request => ({
|
|
1206
|
-
[Attributes.
|
|
1317
|
+
[Attributes.BLOCK_ARCHIVE]: request.archiveRoot.toString(),
|
|
1207
1318
|
}))
|
|
1208
|
-
|
|
1319
|
+
protected async validateRequestedBlockTxs(
|
|
1209
1320
|
request: BlockTxsRequest,
|
|
1210
1321
|
response: BlockTxsResponse,
|
|
1211
1322
|
peerId: PeerId,
|
|
@@ -1213,10 +1324,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1213
1324
|
const requestedTxValidator = this.createRequestedTxValidator();
|
|
1214
1325
|
|
|
1215
1326
|
try {
|
|
1216
|
-
if (!response.
|
|
1327
|
+
if (!response.archiveRoot.equals(request.archiveRoot)) {
|
|
1217
1328
|
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1218
1329
|
throw new ValidationError(
|
|
1219
|
-
`Received block txs for unexpected
|
|
1330
|
+
`Received block txs for unexpected archive root: expected ${request.archiveRoot.toString()}, got ${response.archiveRoot.toString()}`,
|
|
1220
1331
|
);
|
|
1221
1332
|
}
|
|
1222
1333
|
|
|
@@ -1246,7 +1357,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1246
1357
|
}
|
|
1247
1358
|
|
|
1248
1359
|
// Given proposal (should have locally), ensure returned txs are valid subset and match request indices
|
|
1249
|
-
const proposal = await this.mempools.attestationPool.getBlockProposal(request.
|
|
1360
|
+
const proposal = await this.mempools.attestationPool.getBlockProposal(request.archiveRoot.toString());
|
|
1250
1361
|
if (proposal) {
|
|
1251
1362
|
// Build intersected indices
|
|
1252
1363
|
const intersectIdx = request.txIndices.getTrueIndices().filter(i => response.txIndices.isSet(i));
|
|
@@ -1266,7 +1377,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1266
1377
|
} else {
|
|
1267
1378
|
// No local proposal, cannot check the membership/order of the returned txs
|
|
1268
1379
|
this.logger.warn(
|
|
1269
|
-
`Block proposal not found for
|
|
1380
|
+
`Block proposal not found for archive root ${request.archiveRoot.toString()}; cannot validate membership/order of returned txs`,
|
|
1270
1381
|
);
|
|
1271
1382
|
return false;
|
|
1272
1383
|
}
|
|
@@ -1305,7 +1416,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1305
1416
|
const requested = new Set(requestedTxHash.map(h => h.toString()));
|
|
1306
1417
|
const requestedTxValidator = this.createRequestedTxValidator();
|
|
1307
1418
|
|
|
1308
|
-
//TODO: (mralj) - this is somewhat naive implementation, if single tx is
|
|
1419
|
+
//TODO: (mralj) - this is somewhat naive implementation, if single tx is invalid we consider the whole response invalid.
|
|
1309
1420
|
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
1310
1421
|
try {
|
|
1311
1422
|
await Promise.all(responseTx.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator, requested)));
|
|
@@ -1335,9 +1446,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1335
1446
|
@trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
|
|
1336
1447
|
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
|
|
1337
1448
|
}))
|
|
1338
|
-
|
|
1449
|
+
protected async validateRequestedBlock(
|
|
1339
1450
|
requestedBlockNumber: Fr,
|
|
1340
|
-
responseBlock:
|
|
1451
|
+
responseBlock: L2Block,
|
|
1341
1452
|
peerId: PeerId,
|
|
1342
1453
|
): Promise<boolean> {
|
|
1343
1454
|
try {
|
|
@@ -1368,28 +1479,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1368
1479
|
}
|
|
1369
1480
|
}
|
|
1370
1481
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
rollupVersion: new Fr(this.config.rollupVersion),
|
|
1378
|
-
protocolContractsHash,
|
|
1379
|
-
vkTreeRoot: getVKTreeRoot(),
|
|
1380
|
-
}),
|
|
1381
|
-
new TxProofValidator(this.proofVerifier),
|
|
1382
|
-
);
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
private async validateRequestedTx(tx: Tx, peerId: PeerId, txValidator: TxValidator, requested?: Set<`0x${string}`>) {
|
|
1482
|
+
protected async validateRequestedTx(
|
|
1483
|
+
tx: Tx,
|
|
1484
|
+
peerId: PeerId,
|
|
1485
|
+
txValidator: TxValidator,
|
|
1486
|
+
requested?: Set<`0x${string}`>,
|
|
1487
|
+
) {
|
|
1386
1488
|
const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity);
|
|
1387
|
-
|
|
1388
|
-
if (!(await tx.validateTxHash())) {
|
|
1389
|
-
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1390
|
-
throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
1489
|
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
1394
1490
|
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1395
1491
|
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
@@ -1402,6 +1498,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1402
1498
|
}
|
|
1403
1499
|
}
|
|
1404
1500
|
|
|
1501
|
+
protected createRequestedTxValidator(): TxValidator {
|
|
1502
|
+
return createTxReqRespValidator(this.proofVerifier, {
|
|
1503
|
+
l1ChainId: this.config.l1ChainId,
|
|
1504
|
+
rollupVersion: this.config.rollupVersion,
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1405
1508
|
@trackSpan('Libp2pService.validatePropagatedTx', tx => ({
|
|
1406
1509
|
[Attributes.TX_HASH]: tx.getTxHash().toString(),
|
|
1407
1510
|
}))
|
|
@@ -1444,6 +1547,22 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1444
1547
|
return gasFees;
|
|
1445
1548
|
}
|
|
1446
1549
|
|
|
1550
|
+
/**
|
|
1551
|
+
* Get the BatchTxRequesterLibP2PService dependencies for creating BatchTxRequester instances
|
|
1552
|
+
*/
|
|
1553
|
+
public getBatchTxRequesterService(): BatchTxRequesterLibP2PService {
|
|
1554
|
+
return {
|
|
1555
|
+
reqResp: this.reqresp,
|
|
1556
|
+
connectionSampler: this.reqresp.getConnectionSampler(),
|
|
1557
|
+
txValidatorConfig: {
|
|
1558
|
+
l1ChainId: this.config.l1ChainId,
|
|
1559
|
+
rollupVersion: this.config.rollupVersion,
|
|
1560
|
+
proofVerifier: this.proofVerifier,
|
|
1561
|
+
},
|
|
1562
|
+
peerScoring: this.peerManager,
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1447
1566
|
public async validate(txs: Tx[]): Promise<void> {
|
|
1448
1567
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1449
1568
|
|
|
@@ -1494,6 +1613,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1494
1613
|
this.proofVerifier,
|
|
1495
1614
|
!this.config.disableTransactions,
|
|
1496
1615
|
allowedInSetup,
|
|
1616
|
+
this.logger.getBindings(),
|
|
1497
1617
|
);
|
|
1498
1618
|
}
|
|
1499
1619
|
|
|
@@ -1547,15 +1667,18 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1547
1667
|
return PeerErrorSeverity.HighToleranceError;
|
|
1548
1668
|
}
|
|
1549
1669
|
|
|
1550
|
-
const snapshotValidator = new DoubleSpendTxValidator(
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1670
|
+
const snapshotValidator = new DoubleSpendTxValidator(
|
|
1671
|
+
{
|
|
1672
|
+
nullifiersExist: async (nullifiers: Buffer[]) => {
|
|
1673
|
+
const merkleTree = this.worldStateSynchronizer.getSnapshot(
|
|
1674
|
+
BlockNumber(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow),
|
|
1675
|
+
);
|
|
1676
|
+
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
1677
|
+
return indices.map(index => index !== undefined);
|
|
1678
|
+
},
|
|
1557
1679
|
},
|
|
1558
|
-
|
|
1680
|
+
this.logger.getBindings(),
|
|
1681
|
+
);
|
|
1559
1682
|
|
|
1560
1683
|
const validSnapshot = await snapshotValidator.validateTx(tx);
|
|
1561
1684
|
if (validSnapshot.result !== 'valid') {
|
|
@@ -1576,55 +1699,18 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1576
1699
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1577
1700
|
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1578
1701
|
}))
|
|
1579
|
-
public async validateCheckpointAttestation(
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
return false;
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
return true;
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
/**
|
|
1591
|
-
* Validate a block proposal.
|
|
1592
|
-
*
|
|
1593
|
-
* @param block - The block proposal to validate.
|
|
1594
|
-
* @returns True if the block proposal is valid, false otherwise.
|
|
1595
|
-
*/
|
|
1596
|
-
@trackSpan('Libp2pService.validateBlockProposal', (_peerId, block) => ({
|
|
1597
|
-
[Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
|
|
1598
|
-
}))
|
|
1599
|
-
public async validateBlockProposal(peerId: PeerId, block: BlockProposal): Promise<boolean> {
|
|
1600
|
-
const severity = await this.blockProposalValidator.validate(block);
|
|
1601
|
-
if (severity) {
|
|
1602
|
-
this.logger.debug(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1603
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
1604
|
-
return false;
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
return true;
|
|
1608
|
-
}
|
|
1702
|
+
public async validateCheckpointAttestation(
|
|
1703
|
+
peerId: PeerId,
|
|
1704
|
+
attestation: CheckpointAttestation,
|
|
1705
|
+
): Promise<P2PValidationResult> {
|
|
1706
|
+
const result = await this.checkpointAttestationValidator.validate(attestation);
|
|
1609
1707
|
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
* @param checkpoint - The checkpoint proposal to validate.
|
|
1614
|
-
* @returns True if the checkpoint proposal is valid, false otherwise.
|
|
1615
|
-
*/
|
|
1616
|
-
@trackSpan('Libp2pService.validateCheckpointProposal', (_peerId, checkpoint) => ({
|
|
1617
|
-
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1618
|
-
}))
|
|
1619
|
-
public async validateCheckpointProposal(peerId: PeerId, checkpoint: CheckpointProposal): Promise<boolean> {
|
|
1620
|
-
const severity = await this.checkpointProposalValidator.validate(checkpoint);
|
|
1621
|
-
if (severity) {
|
|
1622
|
-
this.logger.debug(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1623
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
1624
|
-
return false;
|
|
1708
|
+
if (result.result === 'reject') {
|
|
1709
|
+
this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1710
|
+
this.peerManager.penalizePeer(peerId, result.severity);
|
|
1625
1711
|
}
|
|
1626
1712
|
|
|
1627
|
-
return
|
|
1713
|
+
return result;
|
|
1628
1714
|
}
|
|
1629
1715
|
|
|
1630
1716
|
public getPeerScore(peerId: PeerId): number {
|