@aztec/p2p 0.0.1-commit.f295ac2 → 0.0.1-commit.f2ce05ee
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 +41 -10
- 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 +55 -31
- 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 +93 -64
- 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/index.d.ts +2 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +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 +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/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/encoding.d.ts +1 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +2 -3
- 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 -133
- 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 +26 -14
- 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 +31 -31
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +91 -67
- 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/index.ts +1 -0
- 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 +22 -0
- 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/encoding.ts +2 -3
- 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 -302
- 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 -126
- 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,57 +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
|
+
getDefaultAllowedSetupFunctions,
|
|
69
70
|
} from '../../msg_validators/index.js';
|
|
70
71
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
71
|
-
import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
|
|
72
|
-
import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
73
72
|
import {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
TxProofValidator,
|
|
79
|
-
} from '../../msg_validators/tx_validator/index.js';
|
|
73
|
+
type MessageValidator,
|
|
74
|
+
createTxMessageValidators,
|
|
75
|
+
createTxReqRespValidator,
|
|
76
|
+
} from '../../msg_validators/tx_validator/factory.js';
|
|
80
77
|
import { GossipSubEvent } from '../../types/index.js';
|
|
81
78
|
import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
|
|
82
79
|
import { getVersions } from '../../versioning.js';
|
|
83
80
|
import { AztecDatastore } from '../data_store.js';
|
|
84
81
|
import { DiscV5Service } from '../discv5/discV5_service.js';
|
|
85
82
|
import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
86
|
-
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';
|
|
87
85
|
import type { PeerManagerInterface } from '../peer-manager/interface.js';
|
|
88
86
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
89
87
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
88
|
+
import type { BatchTxRequesterLibP2PService } from '../reqresp/batch-tx-requester/interface.js';
|
|
90
89
|
import type { P2PReqRespConfig } from '../reqresp/config.js';
|
|
91
90
|
import {
|
|
92
91
|
DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
93
92
|
type ReqRespInterface,
|
|
93
|
+
type ReqRespResponse,
|
|
94
94
|
ReqRespSubProtocol,
|
|
95
95
|
type ReqRespSubProtocolHandler,
|
|
96
96
|
type ReqRespSubProtocolHandlers,
|
|
97
97
|
type ReqRespSubProtocolValidators,
|
|
98
98
|
type SubProtocolMap,
|
|
99
99
|
ValidationError,
|
|
100
|
-
} from '../reqresp/
|
|
101
|
-
import { reqRespBlockTxsHandler } from '../reqresp/protocols/block_txs/block_txs_handler.js';
|
|
102
|
-
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
|
|
100
|
+
} from '../reqresp/index.js';
|
|
103
101
|
import {
|
|
104
102
|
AuthRequest,
|
|
105
103
|
BlockTxsRequest,
|
|
106
104
|
BlockTxsResponse,
|
|
107
105
|
StatusMessage,
|
|
108
106
|
pingHandler,
|
|
107
|
+
reqGoodbyeHandler,
|
|
109
108
|
reqRespBlockHandler,
|
|
109
|
+
reqRespBlockTxsHandler,
|
|
110
110
|
reqRespStatusHandler,
|
|
111
111
|
reqRespTxHandler,
|
|
112
|
-
} from '../reqresp/
|
|
112
|
+
} from '../reqresp/index.js';
|
|
113
113
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
114
114
|
import type {
|
|
115
115
|
P2PBlockReceivedCallback,
|
|
@@ -128,9 +128,9 @@ interface ValidationResult {
|
|
|
128
128
|
type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: ValidationResult };
|
|
129
129
|
|
|
130
130
|
// REFACTOR: Unify with the type above
|
|
131
|
-
type ReceivedMessageValidationResult<T> =
|
|
132
|
-
| { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject
|
|
133
|
-
| { 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 };
|
|
134
134
|
|
|
135
135
|
/**
|
|
136
136
|
* Lib P2P implementation of the P2PService interface.
|
|
@@ -149,6 +149,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
149
149
|
|
|
150
150
|
private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
|
|
151
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
|
+
|
|
152
159
|
/**
|
|
153
160
|
* Callback for when a block is received from a peer.
|
|
154
161
|
* @param block - The block received from the peer.
|
|
@@ -177,9 +184,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
177
184
|
protected node: PubSubLibp2p,
|
|
178
185
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
179
186
|
private reqresp: ReqRespInterface,
|
|
180
|
-
|
|
187
|
+
protected peerManager: PeerManagerInterface,
|
|
181
188
|
protected mempools: MemPools,
|
|
182
|
-
|
|
189
|
+
protected archiver: L2BlockSource & ContractDataSource,
|
|
183
190
|
private epochCache: EpochCacheInterface,
|
|
184
191
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
185
192
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
@@ -284,14 +291,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
284
291
|
|
|
285
292
|
const datastore = new AztecDatastore(peerStore);
|
|
286
293
|
|
|
287
|
-
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry);
|
|
294
|
+
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry, logger.getBindings());
|
|
288
295
|
|
|
289
296
|
const peerDiscoveryService = new DiscV5Service(
|
|
290
297
|
peerId,
|
|
291
298
|
config,
|
|
292
299
|
packageVersion,
|
|
293
300
|
telemetry,
|
|
294
|
-
createLogger(`${logger.module}:discv5_service
|
|
301
|
+
createLogger(`${logger.module}:discv5_service`, logger.getBindings()),
|
|
295
302
|
);
|
|
296
303
|
|
|
297
304
|
// Seed libp2p's bootstrap discovery with private and trusted peers
|
|
@@ -305,11 +312,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
305
312
|
const versions = getVersions(config);
|
|
306
313
|
const protocolVersion = compressComponentVersions(versions);
|
|
307
314
|
|
|
308
|
-
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
309
|
-
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
310
|
-
const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
|
|
311
|
-
const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
|
|
312
|
-
|
|
313
315
|
const preferredPeersEnrs: ENR[] = config.preferredPeers.map(enr => ENR.decodeTxt(enr));
|
|
314
316
|
const directPeers = (
|
|
315
317
|
await Promise.all(
|
|
@@ -329,6 +331,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
329
331
|
|
|
330
332
|
const announceTcpMultiaddr = config.p2pIp ? [convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')] : [];
|
|
331
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
|
+
|
|
332
343
|
const node = await createLibp2p({
|
|
333
344
|
start: false,
|
|
334
345
|
peerId,
|
|
@@ -424,35 +435,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
424
435
|
scoreParams: createPeerScoreParams({
|
|
425
436
|
// IPColocation factor can be disabled for local testing - default to -5
|
|
426
437
|
IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
|
|
427
|
-
topics:
|
|
428
|
-
[txTopic]: createTopicScoreParams({
|
|
429
|
-
topicWeight: 1,
|
|
430
|
-
invalidMessageDeliveriesWeight: -20,
|
|
431
|
-
invalidMessageDeliveriesDecay: 0.5,
|
|
432
|
-
}),
|
|
433
|
-
[blockProposalTopic]: createTopicScoreParams({
|
|
434
|
-
topicWeight: 1,
|
|
435
|
-
invalidMessageDeliveriesWeight: -20,
|
|
436
|
-
invalidMessageDeliveriesDecay: 0.5,
|
|
437
|
-
}),
|
|
438
|
-
[checkpointProposalTopic]: createTopicScoreParams({
|
|
439
|
-
topicWeight: 1,
|
|
440
|
-
invalidMessageDeliveriesWeight: -20,
|
|
441
|
-
invalidMessageDeliveriesDecay: 0.5,
|
|
442
|
-
}),
|
|
443
|
-
[checkpointAttestationTopic]: createTopicScoreParams({
|
|
444
|
-
topicWeight: 1,
|
|
445
|
-
invalidMessageDeliveriesWeight: -20,
|
|
446
|
-
invalidMessageDeliveriesDecay: 0.5,
|
|
447
|
-
}),
|
|
448
|
-
},
|
|
438
|
+
topics: topicScoreParams,
|
|
449
439
|
}),
|
|
450
440
|
}) as (components: GossipSubComponents) => GossipSub,
|
|
451
441
|
components: (components: { connectionManager: ConnectionManager }) => ({
|
|
452
442
|
connectionManager: components.connectionManager,
|
|
453
443
|
}),
|
|
454
444
|
},
|
|
455
|
-
logger: createLibp2pComponentLogger(logger.module),
|
|
445
|
+
logger: createLibp2pComponentLogger(logger.module, logger.getBindings()),
|
|
456
446
|
});
|
|
457
447
|
|
|
458
448
|
const peerScoring = new PeerScoring(config, telemetry);
|
|
@@ -471,8 +461,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
471
461
|
epochCache,
|
|
472
462
|
);
|
|
473
463
|
|
|
474
|
-
//
|
|
475
|
-
|
|
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;
|
|
476
470
|
node.services.pubsub.score.params.appSpecificScore = (peerId: string) =>
|
|
477
471
|
peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
478
472
|
|
|
@@ -524,7 +518,11 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
524
518
|
};
|
|
525
519
|
|
|
526
520
|
if (!this.config.disableTransactions) {
|
|
527
|
-
const blockTxsHandler = reqRespBlockTxsHandler(
|
|
521
|
+
const blockTxsHandler = reqRespBlockTxsHandler(
|
|
522
|
+
this.mempools.attestationPool,
|
|
523
|
+
this.archiver,
|
|
524
|
+
this.mempools.txPool,
|
|
525
|
+
);
|
|
528
526
|
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
529
527
|
}
|
|
530
528
|
|
|
@@ -640,6 +638,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
640
638
|
return this.reqresp.sendBatchRequest(protocol, requests, pinnedPeerId);
|
|
641
639
|
}
|
|
642
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
|
+
|
|
643
650
|
/**
|
|
644
651
|
* Get the ENR of the node
|
|
645
652
|
* @returns The ENR of the node
|
|
@@ -656,6 +663,16 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
656
663
|
this.checkpointReceivedCallback = callback;
|
|
657
664
|
}
|
|
658
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
|
+
|
|
659
676
|
/**
|
|
660
677
|
* Subscribes to a topic.
|
|
661
678
|
* @param topic - The topic to subscribe to.
|
|
@@ -842,13 +859,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
842
859
|
return;
|
|
843
860
|
}
|
|
844
861
|
|
|
845
|
-
protected async validateReceivedMessage<T>(
|
|
846
|
-
validationFunc: () => Promise<ReceivedMessageValidationResult<T>>,
|
|
862
|
+
protected async validateReceivedMessage<T, M = undefined>(
|
|
863
|
+
validationFunc: () => Promise<ReceivedMessageValidationResult<T, M>>,
|
|
847
864
|
msgId: string,
|
|
848
865
|
source: PeerId,
|
|
849
866
|
topicType: TopicType,
|
|
850
|
-
): Promise<ReceivedMessageValidationResult<T>> {
|
|
851
|
-
let resultAndObj: ReceivedMessageValidationResult<T> = { result: TopicValidatorResult.Reject };
|
|
867
|
+
): Promise<ReceivedMessageValidationResult<T, M>> {
|
|
868
|
+
let resultAndObj: ReceivedMessageValidationResult<T, M> = { result: TopicValidatorResult.Reject };
|
|
852
869
|
const timer = new Timer();
|
|
853
870
|
try {
|
|
854
871
|
resultAndObj = await validationFunc();
|
|
@@ -920,46 +937,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
920
937
|
msgId: string,
|
|
921
938
|
source: PeerId,
|
|
922
939
|
): Promise<void> {
|
|
923
|
-
const validationFunc: () => Promise<ReceivedMessageValidationResult<CheckpointAttestation>> = async () => {
|
|
924
|
-
const attestation = CheckpointAttestation.fromBuffer(payloadData);
|
|
925
|
-
const pool = this.mempools.attestationPool;
|
|
926
|
-
const isValid = await this.validateCheckpointAttestation(source, attestation);
|
|
927
|
-
const exists = isValid && (await pool.hasCheckpointAttestation(attestation));
|
|
928
|
-
|
|
929
|
-
let canAdd = true;
|
|
930
|
-
if (isValid && !exists) {
|
|
931
|
-
const slot = attestation.payload.header.slotNumber;
|
|
932
|
-
const { committee } = await this.epochCache.getCommittee(slot);
|
|
933
|
-
const committeeSize = committee?.length ?? 0;
|
|
934
|
-
canAdd = await pool.canAddCheckpointAttestation(attestation, committeeSize);
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
this.logger.trace(`Validate propagated checkpoint attestation`, {
|
|
938
|
-
isValid,
|
|
939
|
-
exists,
|
|
940
|
-
canAdd,
|
|
941
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
942
|
-
[Attributes.P2P_ID]: source.toString(),
|
|
943
|
-
});
|
|
944
|
-
|
|
945
|
-
if (!isValid) {
|
|
946
|
-
return { result: TopicValidatorResult.Reject };
|
|
947
|
-
} else if (exists) {
|
|
948
|
-
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
949
|
-
} else if (!canAdd) {
|
|
950
|
-
this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
|
|
951
|
-
slot: attestation.payload.header.slotNumber.toString(),
|
|
952
|
-
archive: attestation.archive.toString(),
|
|
953
|
-
source: source.toString(),
|
|
954
|
-
});
|
|
955
|
-
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
956
|
-
} else {
|
|
957
|
-
return { result: TopicValidatorResult.Accept, obj: attestation };
|
|
958
|
-
}
|
|
959
|
-
};
|
|
960
|
-
|
|
961
940
|
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
962
|
-
|
|
941
|
+
() => this.validateAndStoreCheckpointAttestation(source, CheckpointAttestation.fromBuffer(payloadData)),
|
|
963
942
|
msgId,
|
|
964
943
|
source,
|
|
965
944
|
TopicType.checkpoint_attestation,
|
|
@@ -969,8 +948,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
969
948
|
return;
|
|
970
949
|
}
|
|
971
950
|
|
|
972
|
-
this.logger.
|
|
973
|
-
`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()}`,
|
|
974
953
|
{
|
|
975
954
|
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
976
955
|
slot: attestation.slotNumber,
|
|
@@ -978,59 +957,154 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
978
957
|
source: source.toString(),
|
|
979
958
|
},
|
|
980
959
|
);
|
|
981
|
-
|
|
982
|
-
await this.mempools.attestationPool.addCheckpointAttestations([attestation]);
|
|
983
960
|
}
|
|
984
961
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
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
|
+
}
|
|
990
977
|
|
|
991
|
-
|
|
992
|
-
|
|
978
|
+
if (validationResult.result === 'ignore') {
|
|
979
|
+
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
980
|
+
}
|
|
993
981
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
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(),
|
|
1000
1011
|
});
|
|
1012
|
+
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
1013
|
+
}
|
|
1001
1014
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
return { result: TopicValidatorResult.Ignore, obj: block };
|
|
1006
|
-
} else if (!canAdd) {
|
|
1007
|
-
this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
|
|
1008
|
-
this.logger.warn(`Penalizing peer for block proposal exceeding per-slot cap`, {
|
|
1009
|
-
slot: block.slotNumber.toString(),
|
|
1010
|
-
archive: block.archive.toString(),
|
|
1011
|
-
source: source.toString(),
|
|
1012
|
-
});
|
|
1013
|
-
return { result: TopicValidatorResult.Reject };
|
|
1014
|
-
} else {
|
|
1015
|
-
return { result: TopicValidatorResult.Accept, obj: block };
|
|
1016
|
-
}
|
|
1017
|
-
};
|
|
1015
|
+
// Attestation was added successfully
|
|
1016
|
+
return { result: TopicValidatorResult.Accept, obj: attestation };
|
|
1017
|
+
}
|
|
1018
1018
|
|
|
1019
|
-
|
|
1020
|
-
|
|
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)),
|
|
1021
1026
|
msgId,
|
|
1022
1027
|
source,
|
|
1023
1028
|
TopicType.block_proposal,
|
|
1024
1029
|
);
|
|
1025
1030
|
|
|
1026
|
-
|
|
1031
|
+
// If not accepted or equivocated, return
|
|
1032
|
+
if (result !== TopicValidatorResult.Accept || !block || isEquivocated) {
|
|
1027
1033
|
return;
|
|
1028
1034
|
}
|
|
1029
1035
|
|
|
1030
1036
|
await this.processValidBlockProposal(block, source);
|
|
1031
1037
|
}
|
|
1032
1038
|
|
|
1033
|
-
|
|
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
|
+
|
|
1034
1108
|
// REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
|
|
1035
1109
|
// should not be here as it does not deal with p2p networking.
|
|
1036
1110
|
@trackSpan('Libp2pService.processValidBlockProposal', async block => ({
|
|
@@ -1038,7 +1112,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1038
1112
|
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
1039
1113
|
[Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1040
1114
|
}))
|
|
1041
|
-
|
|
1115
|
+
protected async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
|
|
1042
1116
|
const slot = block.slotNumber;
|
|
1043
1117
|
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1044
1118
|
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
@@ -1046,22 +1120,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1046
1120
|
...block.toBlockInfo(),
|
|
1047
1121
|
});
|
|
1048
1122
|
|
|
1049
|
-
// Attempt to add proposal
|
|
1050
|
-
try {
|
|
1051
|
-
await this.mempools.attestationPool.addBlockProposal(block);
|
|
1052
|
-
} catch (err: unknown) {
|
|
1053
|
-
// Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
|
|
1054
|
-
if (err instanceof ProposalSlotCapExceededError) {
|
|
1055
|
-
this.logger.warn(`Dropping block proposal due to per-slot proposal cap`, {
|
|
1056
|
-
slot: String(slot),
|
|
1057
|
-
archive: block.archive.toString(),
|
|
1058
|
-
error: (err as Error).message,
|
|
1059
|
-
});
|
|
1060
|
-
return;
|
|
1061
|
-
}
|
|
1062
|
-
throw err;
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
1123
|
// Mark the txs in this proposal as non-evictable
|
|
1066
1124
|
await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
|
|
1067
1125
|
|
|
@@ -1077,66 +1135,145 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1077
1135
|
* Handle a gossiped checkpoint proposal.
|
|
1078
1136
|
* Validates and processes the checkpoint proposal, then triggers the callback for attestation.
|
|
1079
1137
|
*/
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
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
|
+
);
|
|
1086
1149
|
|
|
1087
|
-
|
|
1088
|
-
|
|
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
|
+
}
|
|
1089
1155
|
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
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`, {
|
|
1094
1191
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1095
|
-
[Attributes.P2P_ID]:
|
|
1192
|
+
[Attributes.P2P_ID]: peerId.toString(),
|
|
1096
1193
|
});
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
this.
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
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,
|
|
1108
1205
|
});
|
|
1109
1206
|
return { result: TopicValidatorResult.Reject };
|
|
1110
|
-
} else {
|
|
1111
|
-
|
|
1207
|
+
} else if (result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1208
|
+
processBlock = true;
|
|
1112
1209
|
}
|
|
1113
|
-
}
|
|
1210
|
+
}
|
|
1114
1211
|
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
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
|
+
}
|
|
1121
1230
|
|
|
1122
|
-
|
|
1123
|
-
|
|
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
|
+
};
|
|
1124
1261
|
}
|
|
1125
1262
|
|
|
1126
|
-
|
|
1263
|
+
// Otherwise, we're good to go!
|
|
1264
|
+
return { result: TopicValidatorResult.Accept, obj: checkpoint, metadata: { processBlock, isEquivocated } };
|
|
1127
1265
|
}
|
|
1128
1266
|
|
|
1129
1267
|
/**
|
|
1130
1268
|
* Process a validated checkpoint proposal.
|
|
1131
|
-
*
|
|
1132
|
-
* The block callback is invoked before the checkpoint callback.
|
|
1269
|
+
* Note: The proposal was already added to the pool by tryAddCheckpointProposal in handleGossipedCheckpointProposal.
|
|
1133
1270
|
*/
|
|
1134
1271
|
@trackSpan('Libp2pService.processValidCheckpointProposal', async checkpoint => ({
|
|
1135
1272
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber,
|
|
1136
1273
|
[Attributes.BLOCK_ARCHIVE]: checkpoint.archive.toString(),
|
|
1137
1274
|
[Attributes.P2P_ID]: await checkpoint.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1138
1275
|
}))
|
|
1139
|
-
|
|
1276
|
+
protected async processValidCheckpointProposal(checkpoint: CheckpointProposalCore, sender: PeerId) {
|
|
1140
1277
|
const slot = checkpoint.slotNumber;
|
|
1141
1278
|
this.logger.verbose(`Received checkpoint proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1142
1279
|
p2pMessageIdentifier: await checkpoint.p2pMessageLoggingIdentifier(),
|
|
@@ -1145,37 +1282,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1145
1282
|
source: sender.toString(),
|
|
1146
1283
|
});
|
|
1147
1284
|
|
|
1148
|
-
// Extract block proposal before adding to pool (pool stores them separately)
|
|
1149
|
-
const blockProposal = checkpoint.getBlockProposal();
|
|
1150
|
-
|
|
1151
|
-
// Add proposal to the pool (this extracts and stores block proposal separately)
|
|
1152
|
-
await this.mempools.attestationPool.addCheckpointProposal(checkpoint);
|
|
1153
|
-
|
|
1154
|
-
// Mark txs as non-evictable if present (from the last block)
|
|
1155
|
-
if (checkpoint.txHashes.length > 0) {
|
|
1156
|
-
await this.mempools.txPool.markTxsAsNonEvictable(checkpoint.txHashes);
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
// If there was a last block proposal, invoke the block callback first for validation.
|
|
1160
|
-
// Note: The block proposal is already stored in the pool by addCheckpointProposal.
|
|
1161
|
-
if (blockProposal) {
|
|
1162
|
-
const isValid = await this.blockReceivedCallback(blockProposal, sender);
|
|
1163
|
-
if (!isValid) {
|
|
1164
|
-
this.logger.warn(`Block proposal from checkpoint failed validation`, {
|
|
1165
|
-
slot: slot.toString(),
|
|
1166
|
-
archive: checkpoint.archive.toString(),
|
|
1167
|
-
blockNumber: blockProposal.blockNumber.toString(),
|
|
1168
|
-
});
|
|
1169
|
-
return;
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
1285
|
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1174
1286
|
// to validate and potentially generate attestations
|
|
1175
|
-
const attestations = await this.checkpointReceivedCallback(checkpoint
|
|
1287
|
+
const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
|
|
1176
1288
|
if (attestations && attestations.length > 0) {
|
|
1177
1289
|
// If the callback returned attestations, add them to the pool and propagate them
|
|
1178
|
-
await this.mempools.attestationPool.
|
|
1290
|
+
await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
1179
1291
|
for (const attestation of attestations) {
|
|
1180
1292
|
await this.propagate(attestation);
|
|
1181
1293
|
}
|
|
@@ -1202,9 +1314,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1202
1314
|
* @returns True if the requested block transactions are valid, false otherwise.
|
|
1203
1315
|
*/
|
|
1204
1316
|
@trackSpan('Libp2pService.validateRequestedBlockTxs', request => ({
|
|
1205
|
-
[Attributes.
|
|
1317
|
+
[Attributes.BLOCK_ARCHIVE]: request.archiveRoot.toString(),
|
|
1206
1318
|
}))
|
|
1207
|
-
|
|
1319
|
+
protected async validateRequestedBlockTxs(
|
|
1208
1320
|
request: BlockTxsRequest,
|
|
1209
1321
|
response: BlockTxsResponse,
|
|
1210
1322
|
peerId: PeerId,
|
|
@@ -1212,10 +1324,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1212
1324
|
const requestedTxValidator = this.createRequestedTxValidator();
|
|
1213
1325
|
|
|
1214
1326
|
try {
|
|
1215
|
-
if (!response.
|
|
1327
|
+
if (!response.archiveRoot.equals(request.archiveRoot)) {
|
|
1216
1328
|
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1217
1329
|
throw new ValidationError(
|
|
1218
|
-
`Received block txs for unexpected
|
|
1330
|
+
`Received block txs for unexpected archive root: expected ${request.archiveRoot.toString()}, got ${response.archiveRoot.toString()}`,
|
|
1219
1331
|
);
|
|
1220
1332
|
}
|
|
1221
1333
|
|
|
@@ -1245,7 +1357,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1245
1357
|
}
|
|
1246
1358
|
|
|
1247
1359
|
// Given proposal (should have locally), ensure returned txs are valid subset and match request indices
|
|
1248
|
-
const proposal = await this.mempools.attestationPool.getBlockProposal(request.
|
|
1360
|
+
const proposal = await this.mempools.attestationPool.getBlockProposal(request.archiveRoot.toString());
|
|
1249
1361
|
if (proposal) {
|
|
1250
1362
|
// Build intersected indices
|
|
1251
1363
|
const intersectIdx = request.txIndices.getTrueIndices().filter(i => response.txIndices.isSet(i));
|
|
@@ -1265,7 +1377,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1265
1377
|
} else {
|
|
1266
1378
|
// No local proposal, cannot check the membership/order of the returned txs
|
|
1267
1379
|
this.logger.warn(
|
|
1268
|
-
`Block proposal not found for
|
|
1380
|
+
`Block proposal not found for archive root ${request.archiveRoot.toString()}; cannot validate membership/order of returned txs`,
|
|
1269
1381
|
);
|
|
1270
1382
|
return false;
|
|
1271
1383
|
}
|
|
@@ -1304,7 +1416,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1304
1416
|
const requested = new Set(requestedTxHash.map(h => h.toString()));
|
|
1305
1417
|
const requestedTxValidator = this.createRequestedTxValidator();
|
|
1306
1418
|
|
|
1307
|
-
//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.
|
|
1308
1420
|
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
1309
1421
|
try {
|
|
1310
1422
|
await Promise.all(responseTx.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator, requested)));
|
|
@@ -1334,9 +1446,9 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1334
1446
|
@trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
|
|
1335
1447
|
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
|
|
1336
1448
|
}))
|
|
1337
|
-
|
|
1449
|
+
protected async validateRequestedBlock(
|
|
1338
1450
|
requestedBlockNumber: Fr,
|
|
1339
|
-
responseBlock:
|
|
1451
|
+
responseBlock: L2Block,
|
|
1340
1452
|
peerId: PeerId,
|
|
1341
1453
|
): Promise<boolean> {
|
|
1342
1454
|
try {
|
|
@@ -1367,27 +1479,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1367
1479
|
}
|
|
1368
1480
|
}
|
|
1369
1481
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
protocolContractsHash,
|
|
1377
|
-
vkTreeRoot: getVKTreeRoot(),
|
|
1378
|
-
}),
|
|
1379
|
-
new TxProofValidator(this.proofVerifier),
|
|
1380
|
-
);
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
|
-
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
|
+
) {
|
|
1384
1488
|
const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity);
|
|
1385
|
-
|
|
1386
|
-
if (!(await tx.validateTxHash())) {
|
|
1387
|
-
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1388
|
-
throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
1489
|
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
1392
1490
|
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1393
1491
|
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
@@ -1400,6 +1498,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1400
1498
|
}
|
|
1401
1499
|
}
|
|
1402
1500
|
|
|
1501
|
+
protected createRequestedTxValidator(): TxValidator {
|
|
1502
|
+
return createTxReqRespValidator(this.proofVerifier, {
|
|
1503
|
+
l1ChainId: this.config.l1ChainId,
|
|
1504
|
+
rollupVersion: this.config.rollupVersion,
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1403
1508
|
@trackSpan('Libp2pService.validatePropagatedTx', tx => ({
|
|
1404
1509
|
[Attributes.TX_HASH]: tx.getTxHash().toString(),
|
|
1405
1510
|
}))
|
|
@@ -1442,6 +1547,22 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1442
1547
|
return gasFees;
|
|
1443
1548
|
}
|
|
1444
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
|
+
|
|
1445
1566
|
public async validate(txs: Tx[]): Promise<void> {
|
|
1446
1567
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1447
1568
|
|
|
@@ -1492,6 +1613,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1492
1613
|
this.proofVerifier,
|
|
1493
1614
|
!this.config.disableTransactions,
|
|
1494
1615
|
allowedInSetup,
|
|
1616
|
+
this.logger.getBindings(),
|
|
1495
1617
|
);
|
|
1496
1618
|
}
|
|
1497
1619
|
|
|
@@ -1545,15 +1667,18 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1545
1667
|
return PeerErrorSeverity.HighToleranceError;
|
|
1546
1668
|
}
|
|
1547
1669
|
|
|
1548
|
-
const snapshotValidator = new DoubleSpendTxValidator(
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
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
|
+
},
|
|
1555
1679
|
},
|
|
1556
|
-
|
|
1680
|
+
this.logger.getBindings(),
|
|
1681
|
+
);
|
|
1557
1682
|
|
|
1558
1683
|
const validSnapshot = await snapshotValidator.validateTx(tx);
|
|
1559
1684
|
if (validSnapshot.result !== 'valid') {
|
|
@@ -1574,55 +1699,18 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1574
1699
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1575
1700
|
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1576
1701
|
}))
|
|
1577
|
-
public async validateCheckpointAttestation(
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
return false;
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
|
-
return true;
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
/**
|
|
1589
|
-
* Validate a block proposal.
|
|
1590
|
-
*
|
|
1591
|
-
* @param block - The block proposal to validate.
|
|
1592
|
-
* @returns True if the block proposal is valid, false otherwise.
|
|
1593
|
-
*/
|
|
1594
|
-
@trackSpan('Libp2pService.validateBlockProposal', (_peerId, block) => ({
|
|
1595
|
-
[Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
|
|
1596
|
-
}))
|
|
1597
|
-
public async validateBlockProposal(peerId: PeerId, block: BlockProposal): Promise<boolean> {
|
|
1598
|
-
const severity = await this.blockProposalValidator.validate(block);
|
|
1599
|
-
if (severity) {
|
|
1600
|
-
this.logger.debug(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1601
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
1602
|
-
return false;
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
|
-
return true;
|
|
1606
|
-
}
|
|
1702
|
+
public async validateCheckpointAttestation(
|
|
1703
|
+
peerId: PeerId,
|
|
1704
|
+
attestation: CheckpointAttestation,
|
|
1705
|
+
): Promise<P2PValidationResult> {
|
|
1706
|
+
const result = await this.checkpointAttestationValidator.validate(attestation);
|
|
1607
1707
|
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
* @param checkpoint - The checkpoint proposal to validate.
|
|
1612
|
-
* @returns True if the checkpoint proposal is valid, false otherwise.
|
|
1613
|
-
*/
|
|
1614
|
-
@trackSpan('Libp2pService.validateCheckpointProposal', (_peerId, checkpoint) => ({
|
|
1615
|
-
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1616
|
-
}))
|
|
1617
|
-
public async validateCheckpointProposal(peerId: PeerId, checkpoint: CheckpointProposal): Promise<boolean> {
|
|
1618
|
-
const severity = await this.checkpointProposalValidator.validate(checkpoint);
|
|
1619
|
-
if (severity) {
|
|
1620
|
-
this.logger.debug(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
1621
|
-
this.peerManager.penalizePeer(peerId, severity);
|
|
1622
|
-
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);
|
|
1623
1711
|
}
|
|
1624
1712
|
|
|
1625
|
-
return
|
|
1713
|
+
return result;
|
|
1626
1714
|
}
|
|
1627
1715
|
|
|
1628
1716
|
public getPeerScore(peerId: PeerId): number {
|