@aztec/p2p 0.0.1-commit.24de95ac → 0.0.1-commit.3469e52
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 +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/client/factory.d.ts +2 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +2 -3
- package/dest/client/index.d.ts +1 -1
- package/dest/client/interface.d.ts +18 -3
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +16 -37
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +464 -126
- package/dest/config.d.ts +62 -59
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +21 -14
- package/dest/enr/generate-enr.d.ts +1 -1
- package/dest/enr/index.d.ts +1 -1
- package/dest/errors/attestation-pool.error.d.ts +7 -0
- package/dest/errors/attestation-pool.error.d.ts.map +1 -0
- package/dest/errors/attestation-pool.error.js +12 -0
- package/dest/errors/reqresp.error.d.ts +1 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +77 -36
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +241 -266
- package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +24 -14
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +123 -95
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +18 -12
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +91 -108
- package/dest/mem_pools/attestation_pool/mocks.d.ts +234 -10
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +17 -13
- package/dest/mem_pools/index.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts +9 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +36 -9
- package/dest/mem_pools/interface.d.ts +3 -4
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +34 -59
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +314 -335
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +31 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +112 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +156 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +52 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +115 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +76 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
- package/dest/mem_pools/tx_pool/index.d.ts +1 -2
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +6 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +11 -6
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +30 -24
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +7 -6
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +18 -16
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +20 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +64 -0
- package/dest/msg_validators/attestation_validator/index.d.ts +2 -1
- package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/index.js +1 -0
- package/dest/msg_validators/index.d.ts +2 -2
- package/dest/msg_validators/index.d.ts.map +1 -1
- package/dest/msg_validators/index.js +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
- package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/index.js +3 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.js +73 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +157 -0
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.d.ts +4 -3
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +10 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +20 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +8 -14
- 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 +2 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -1
- package/dest/msg_validators/tx_validator/size_validator.d.ts +6 -0
- package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/size_validator.js +20 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/dummy_service.d.ts +6 -2
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +3 -0
- package/dest/services/encoding.d.ts +1 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -6
- package/dest/services/gossipsub/scoring.d.ts +1 -1
- package/dest/services/index.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts +3 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +26 -72
- package/dest/services/libp2p/libp2p_service.d.ts +40 -79
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +885 -161
- package/dest/services/peer-manager/interface.d.ts +1 -1
- package/dest/services/peer-manager/metrics.d.ts +8 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +24 -16
- package/dest/services/peer-manager/peer_manager.d.ts +2 -33
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +6 -12
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +37 -2
- package/dest/services/reqresp/config.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/constants.d.ts +12 -0
- package/dest/services/reqresp/constants.d.ts.map +1 -0
- package/dest/services/reqresp/constants.js +7 -0
- package/dest/services/reqresp/index.d.ts +1 -1
- package/dest/services/reqresp/interface.d.ts +4 -4
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +3 -3
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +5 -21
- package/dest/services/reqresp/protocols/auth.d.ts +2 -2
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.js +2 -2
- package/dest/services/reqresp/protocols/block.d.ts +1 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +3 -2
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +7 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +4 -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 +1 -1
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/ping.d.ts +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +6 -5
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +7 -3
- package/dest/services/reqresp/protocols/tx.d.ts +2 -3
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +2 -2
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts +1 -41
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +402 -24
- package/dest/services/reqresp/status.d.ts +2 -2
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/service.d.ts +16 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +1 -1
- package/dest/services/tx_collection/config.js +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -9
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/index.d.ts +1 -1
- 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 +4 -14
- package/dest/services/tx_collection/slow_tx_collection.d.ts +6 -7
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +2 -1
- package/dest/services/tx_collection/tx_collection.d.ts +11 -11
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.d.ts +3 -3
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.d.ts +1 -1
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_provider.d.ts +6 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +11 -2
- package/dest/services/tx_provider_instrumentation.d.ts +5 -2
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +13 -13
- package/dest/test-helpers/generate-peer-id-private-keys.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/index.d.ts +1 -1
- package/dest/test-helpers/make-enrs.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +2 -2
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +4 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-tx-helpers.d.ts +2 -2
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -1
- package/dest/test-helpers/mock-tx-helpers.js +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +37 -21
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +6 -1
- package/dest/types/index.d.ts +1 -1
- package/dest/util.d.ts +2 -1
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +11 -2
- package/dest/versioning.d.ts +1 -1
- package/package.json +19 -18
- package/src/client/factory.ts +5 -10
- package/src/client/interface.ts +20 -2
- package/src/client/p2p_client.ts +111 -158
- package/src/config.ts +30 -19
- package/src/errors/attestation-pool.error.ts +13 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +86 -35
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +243 -278
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +175 -111
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +147 -136
- package/src/mem_pools/attestation_pool/mocks.ts +21 -15
- package/src/mem_pools/instrumentation.ts +47 -10
- package/src/mem_pools/interface.ts +2 -4
- package/src/mem_pools/tx_pool/README.md +270 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +368 -372
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +131 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +207 -0
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +159 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +91 -0
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
- package/src/mem_pools/tx_pool/index.ts +0 -1
- package/src/mem_pools/tx_pool/priority.ts +8 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +11 -5
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +23 -17
- package/src/msg_validators/attestation_validator/attestation_validator.ts +23 -22
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +88 -0
- package/src/msg_validators/attestation_validator/index.ts +1 -0
- package/src/msg_validators/index.ts +1 -1
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
- package/src/msg_validators/proposal_validator/index.ts +3 -0
- package/src/msg_validators/proposal_validator/proposal_validator.ts +85 -0
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +191 -0
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
- package/src/msg_validators/tx_validator/data_validator.ts +12 -4
- package/src/msg_validators/tx_validator/factory.ts +3 -2
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +8 -25
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +13 -5
- package/src/msg_validators/tx_validator/phases_validator.ts +3 -1
- package/src/msg_validators/tx_validator/size_validator.ts +18 -0
- package/src/msg_validators/tx_validator/test_utils.ts +1 -1
- package/src/msg_validators/tx_validator/timestamp_validator.ts +5 -2
- package/src/services/dummy_service.ts +6 -0
- package/src/services/encoding.ts +6 -5
- package/src/services/libp2p/instrumentation.ts +26 -71
- package/src/services/libp2p/libp2p_service.ts +555 -145
- package/src/services/peer-manager/metrics.ts +27 -16
- package/src/services/peer-manager/peer_manager.ts +7 -4
- package/src/services/peer-manager/peer_scoring.ts +42 -3
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +3 -1
- package/src/services/reqresp/constants.ts +14 -0
- package/src/services/reqresp/interface.ts +3 -3
- package/src/services/reqresp/metrics.ts +7 -23
- package/src/services/reqresp/protocols/auth.ts +2 -2
- package/src/services/reqresp/protocols/block.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +9 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
- package/src/services/reqresp/protocols/status.ts +16 -12
- package/src/services/reqresp/protocols/tx.ts +1 -2
- package/src/services/service.ts +19 -4
- package/src/services/tx_collection/config.ts +1 -1
- package/src/services/tx_collection/fast_tx_collection.ts +3 -2
- package/src/services/tx_collection/instrumentation.ts +4 -21
- package/src/services/tx_collection/slow_tx_collection.ts +7 -6
- package/src/services/tx_collection/tx_collection.ts +10 -9
- package/src/services/tx_provider.ts +21 -5
- package/src/services/tx_provider_instrumentation.ts +18 -14
- package/src/test-helpers/mock-pubsub.ts +1 -1
- package/src/test-helpers/mock-tx-helpers.ts +1 -1
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/testbench/p2p_client_testbench_worker.ts +45 -22
- package/src/testbench/worker_client_manager.ts +6 -1
- package/src/util.ts +12 -2
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -80
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -238
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -12
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +0 -70
- package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/index.js +0 -1
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -283
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -81
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { randomInt } from '@aztec/foundation/crypto/random';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
5
|
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
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
9
|
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
10
10
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
11
|
-
import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
|
|
11
|
+
import type { EthAddress, L2BlockNew, L2BlockSource } from '@aztec/stdlib/block';
|
|
12
12
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
13
13
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
14
14
|
import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
15
15
|
import {
|
|
16
|
-
BlockAttestation,
|
|
17
16
|
BlockProposal,
|
|
17
|
+
CheckpointAttestation,
|
|
18
|
+
CheckpointProposal,
|
|
19
|
+
type CheckpointProposalCore,
|
|
18
20
|
type Gossipable,
|
|
19
21
|
P2PClientType,
|
|
20
22
|
P2PMessage,
|
|
@@ -28,7 +30,14 @@ import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
|
28
30
|
import { Tx, type TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
29
31
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
30
32
|
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
31
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
Attributes,
|
|
35
|
+
OtelMetricsAdapter,
|
|
36
|
+
SpanStatusCode,
|
|
37
|
+
type TelemetryClient,
|
|
38
|
+
WithTracer,
|
|
39
|
+
trackSpan,
|
|
40
|
+
} from '@aztec/telemetry-client';
|
|
32
41
|
|
|
33
42
|
import {
|
|
34
43
|
type GossipSub,
|
|
@@ -50,8 +59,15 @@ import { ENR } from '@nethermindeth/enr';
|
|
|
50
59
|
import { createLibp2p } from 'libp2p';
|
|
51
60
|
|
|
52
61
|
import type { P2PConfig } from '../../config.js';
|
|
62
|
+
import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
|
|
53
63
|
import type { MemPools } from '../../mem_pools/interface.js';
|
|
54
|
-
import {
|
|
64
|
+
import {
|
|
65
|
+
BlockProposalValidator,
|
|
66
|
+
CheckpointAttestationValidator,
|
|
67
|
+
CheckpointProposalValidator,
|
|
68
|
+
FishermanAttestationValidator,
|
|
69
|
+
SizeTxValidator,
|
|
70
|
+
} from '../../msg_validators/index.js';
|
|
55
71
|
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
56
72
|
import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
|
|
57
73
|
import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
@@ -96,7 +112,12 @@ import {
|
|
|
96
112
|
reqRespTxHandler,
|
|
97
113
|
} from '../reqresp/protocols/index.js';
|
|
98
114
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
99
|
-
import type {
|
|
115
|
+
import type {
|
|
116
|
+
P2PBlockReceivedCallback,
|
|
117
|
+
P2PCheckpointReceivedCallback,
|
|
118
|
+
P2PService,
|
|
119
|
+
PeerDiscoveryService,
|
|
120
|
+
} from '../service.js';
|
|
100
121
|
import { P2PInstrumentation } from './instrumentation.js';
|
|
101
122
|
|
|
102
123
|
interface ValidationResult {
|
|
@@ -116,18 +137,18 @@ type ReceivedMessageValidationResult<T> =
|
|
|
116
137
|
* Lib P2P implementation of the P2PService interface.
|
|
117
138
|
*/
|
|
118
139
|
export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends WithTracer implements P2PService {
|
|
119
|
-
private jobQueue: SerialQueue = new SerialQueue();
|
|
120
140
|
private discoveryRunningPromise?: RunningPromise;
|
|
121
141
|
private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
|
|
122
142
|
|
|
123
143
|
// Message validators
|
|
124
|
-
private attestationValidator: AttestationValidator;
|
|
125
144
|
private blockProposalValidator: BlockProposalValidator;
|
|
145
|
+
private checkpointProposalValidator: CheckpointProposalValidator;
|
|
146
|
+
private checkpointAttestationValidator: CheckpointAttestationValidator;
|
|
126
147
|
|
|
127
148
|
private protocolVersion = '';
|
|
128
149
|
private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
|
|
129
150
|
|
|
130
|
-
private feesCache: { blockNumber:
|
|
151
|
+
private feesCache: { blockNumber: BlockNumber; gasFees: GasFees } | undefined;
|
|
131
152
|
|
|
132
153
|
/**
|
|
133
154
|
* Callback for when a block is received from a peer.
|
|
@@ -136,10 +157,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
136
157
|
*/
|
|
137
158
|
private blockReceivedCallback: P2PBlockReceivedCallback;
|
|
138
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Callback for when a checkpoint proposal is received from a peer.
|
|
162
|
+
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
163
|
+
* @returns The attestations for the checkpoint, if any.
|
|
164
|
+
*/
|
|
165
|
+
private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
|
|
166
|
+
|
|
139
167
|
private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
|
|
140
168
|
|
|
141
169
|
private instrumentation: P2PInstrumentation;
|
|
142
170
|
|
|
171
|
+
private telemetry: TelemetryClient;
|
|
172
|
+
|
|
173
|
+
protected logger: Logger;
|
|
174
|
+
|
|
143
175
|
constructor(
|
|
144
176
|
private clientType: T,
|
|
145
177
|
private config: P2PConfig,
|
|
@@ -147,21 +179,26 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
147
179
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
148
180
|
private reqresp: ReqRespInterface,
|
|
149
181
|
private peerManager: PeerManagerInterface,
|
|
150
|
-
protected mempools: MemPools
|
|
182
|
+
protected mempools: MemPools,
|
|
151
183
|
private archiver: L2BlockSource & ContractDataSource,
|
|
152
184
|
private epochCache: EpochCacheInterface,
|
|
153
185
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
154
186
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
155
187
|
telemetry: TelemetryClient,
|
|
156
|
-
|
|
188
|
+
logger: Logger = createLogger('p2p:libp2p_service'),
|
|
157
189
|
) {
|
|
158
190
|
super(telemetry, 'LibP2PService');
|
|
191
|
+
this.telemetry = telemetry;
|
|
192
|
+
|
|
193
|
+
// Create child logger with fisherman prefix if in fisherman mode
|
|
194
|
+
this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
|
|
159
195
|
|
|
160
196
|
this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
|
|
161
197
|
|
|
162
198
|
this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
163
199
|
this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
164
|
-
this.msgIdSeenValidators[TopicType.
|
|
200
|
+
this.msgIdSeenValidators[TopicType.checkpoint_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
201
|
+
this.msgIdSeenValidators[TopicType.checkpoint_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
165
202
|
|
|
166
203
|
const versions = getVersions(config);
|
|
167
204
|
this.protocolVersion = compressComponentVersions(versions);
|
|
@@ -169,22 +206,40 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
169
206
|
|
|
170
207
|
this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
|
|
171
208
|
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
172
|
-
this.topicStrings[TopicType.
|
|
173
|
-
TopicType.
|
|
209
|
+
this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(
|
|
210
|
+
TopicType.checkpoint_proposal,
|
|
211
|
+
this.protocolVersion,
|
|
212
|
+
);
|
|
213
|
+
this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(
|
|
214
|
+
TopicType.checkpoint_attestation,
|
|
174
215
|
this.protocolVersion,
|
|
175
216
|
);
|
|
176
217
|
|
|
177
|
-
this.attestationValidator = new AttestationValidator(epochCache);
|
|
178
218
|
this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
|
|
219
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
|
|
220
|
+
txsPermitted: !config.disableTransactions,
|
|
221
|
+
});
|
|
222
|
+
this.checkpointAttestationValidator = config.fishermanMode
|
|
223
|
+
? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry)
|
|
224
|
+
: new CheckpointAttestationValidator(epochCache);
|
|
179
225
|
|
|
180
226
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
181
227
|
|
|
182
|
-
this.blockReceivedCallback = async (block: BlockProposal): Promise<
|
|
228
|
+
this.blockReceivedCallback = async (block: BlockProposal): Promise<boolean> => {
|
|
183
229
|
this.logger.debug(
|
|
184
|
-
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber
|
|
185
|
-
{ p2pMessageIdentifier: await block.
|
|
230
|
+
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`,
|
|
231
|
+
{ p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier() },
|
|
186
232
|
);
|
|
187
|
-
return
|
|
233
|
+
return false;
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
this.checkpointReceivedCallback = (
|
|
237
|
+
checkpoint: CheckpointProposalCore,
|
|
238
|
+
): Promise<CheckpointAttestation[] | undefined> => {
|
|
239
|
+
this.logger.debug(
|
|
240
|
+
`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
|
|
241
|
+
);
|
|
242
|
+
return Promise.resolve(undefined);
|
|
188
243
|
};
|
|
189
244
|
}
|
|
190
245
|
|
|
@@ -203,7 +258,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
203
258
|
config: P2PConfig,
|
|
204
259
|
peerId: PeerId,
|
|
205
260
|
deps: {
|
|
206
|
-
mempools: MemPools
|
|
261
|
+
mempools: MemPools;
|
|
207
262
|
l2BlockSource: L2BlockSource & ContractDataSource;
|
|
208
263
|
epochCache: EpochCacheInterface;
|
|
209
264
|
proofVerifier: ClientProtocolCircuitVerifier;
|
|
@@ -253,7 +308,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
253
308
|
|
|
254
309
|
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
255
310
|
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
256
|
-
const
|
|
311
|
+
const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
|
|
312
|
+
const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
|
|
257
313
|
|
|
258
314
|
const preferredPeersEnrs: ENR[] = config.preferredPeers.map(enr => ENR.decodeTxt(enr));
|
|
259
315
|
const directPeers = (
|
|
@@ -375,12 +431,17 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
375
431
|
invalidMessageDeliveriesWeight: -20,
|
|
376
432
|
invalidMessageDeliveriesDecay: 0.5,
|
|
377
433
|
}),
|
|
378
|
-
[
|
|
434
|
+
[blockProposalTopic]: createTopicScoreParams({
|
|
379
435
|
topicWeight: 1,
|
|
380
436
|
invalidMessageDeliveriesWeight: -20,
|
|
381
437
|
invalidMessageDeliveriesDecay: 0.5,
|
|
382
438
|
}),
|
|
383
|
-
[
|
|
439
|
+
[checkpointProposalTopic]: createTopicScoreParams({
|
|
440
|
+
topicWeight: 1,
|
|
441
|
+
invalidMessageDeliveriesWeight: -20,
|
|
442
|
+
invalidMessageDeliveriesDecay: 0.5,
|
|
443
|
+
}),
|
|
444
|
+
[checkpointAttestationTopic]: createTopicScoreParams({
|
|
384
445
|
topicWeight: 1,
|
|
385
446
|
invalidMessageDeliveriesWeight: -20,
|
|
386
447
|
invalidMessageDeliveriesDecay: 0.5,
|
|
@@ -395,7 +456,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
395
456
|
logger: createLibp2pComponentLogger(logger.module),
|
|
396
457
|
});
|
|
397
458
|
|
|
398
|
-
const peerScoring = new PeerScoring(config);
|
|
459
|
+
const peerScoring = new PeerScoring(config, telemetry);
|
|
399
460
|
const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
|
|
400
461
|
|
|
401
462
|
const peerManager = new PeerManager(
|
|
@@ -450,20 +511,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
450
511
|
}
|
|
451
512
|
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
452
513
|
|
|
453
|
-
// Start job queue, peer discovery service and libp2p node
|
|
454
|
-
this.jobQueue.start();
|
|
455
|
-
|
|
456
|
-
await this.peerManager.initializePeers();
|
|
457
|
-
if (!this.config.p2pDiscoveryDisabled) {
|
|
458
|
-
await this.peerDiscoveryService.start();
|
|
459
|
-
}
|
|
460
|
-
await this.node.start();
|
|
461
|
-
|
|
462
|
-
// Subscribe to standard GossipSub topics by default
|
|
463
|
-
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
|
|
464
|
-
this.subscribeToTopic(this.topicStrings[topic]);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
514
|
// Create request response protocol handlers
|
|
468
515
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
469
516
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
@@ -477,8 +524,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
477
524
|
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
478
525
|
};
|
|
479
526
|
|
|
480
|
-
|
|
481
|
-
if (this.mempools.attestationPool && !this.config.disableTransactions) {
|
|
527
|
+
if (!this.config.disableTransactions) {
|
|
482
528
|
const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
|
|
483
529
|
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
484
530
|
}
|
|
@@ -487,25 +533,41 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
487
533
|
requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this);
|
|
488
534
|
}
|
|
489
535
|
|
|
536
|
+
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
537
|
+
const reqrespSubProtocolValidators = {
|
|
538
|
+
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
539
|
+
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
540
|
+
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
541
|
+
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
await this.peerManager.initializePeers();
|
|
545
|
+
|
|
546
|
+
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
547
|
+
|
|
548
|
+
await this.node.start();
|
|
549
|
+
|
|
550
|
+
// Subscribe to standard GossipSub topics by default
|
|
551
|
+
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
|
|
552
|
+
this.subscribeToTopic(this.topicStrings[topic]);
|
|
553
|
+
}
|
|
554
|
+
|
|
490
555
|
// add GossipSub listener
|
|
491
556
|
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
492
557
|
|
|
493
|
-
// Start running promise for peer discovery
|
|
558
|
+
// Start running promise for peer discovery and metrics collection
|
|
559
|
+
if (!this.config.p2pDiscoveryDisabled) {
|
|
560
|
+
await this.peerDiscoveryService.start();
|
|
561
|
+
}
|
|
494
562
|
this.discoveryRunningPromise = new RunningPromise(
|
|
495
|
-
() =>
|
|
563
|
+
async () => {
|
|
564
|
+
await this.peerManager.heartbeat();
|
|
565
|
+
},
|
|
496
566
|
this.logger,
|
|
497
567
|
this.config.peerCheckIntervalMS,
|
|
498
568
|
);
|
|
499
569
|
this.discoveryRunningPromise.start();
|
|
500
570
|
|
|
501
|
-
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
502
|
-
const reqrespSubProtocolValidators = {
|
|
503
|
-
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
504
|
-
// TODO(#11336): A request validator for blocks
|
|
505
|
-
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
506
|
-
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
507
|
-
};
|
|
508
|
-
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
509
571
|
this.logger.info(`Started P2P service`, {
|
|
510
572
|
listen: this.config.listenAddress,
|
|
511
573
|
port: this.config.p2pPort,
|
|
@@ -525,9 +587,6 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
525
587
|
// Stop peer manager
|
|
526
588
|
this.logger.debug('Stopping peer manager...');
|
|
527
589
|
await this.peerManager.stop();
|
|
528
|
-
|
|
529
|
-
this.logger.debug('Stopping job queue...');
|
|
530
|
-
await this.jobQueue.end();
|
|
531
590
|
this.logger.debug('Stopping running promise...');
|
|
532
591
|
await this.discoveryRunningPromise?.stop();
|
|
533
592
|
this.logger.debug('Stopping peer discovery service...');
|
|
@@ -594,6 +653,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
594
653
|
this.blockReceivedCallback = callback;
|
|
595
654
|
}
|
|
596
655
|
|
|
656
|
+
public registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
|
|
657
|
+
this.checkpointReceivedCallback = callback;
|
|
658
|
+
}
|
|
659
|
+
|
|
597
660
|
/**
|
|
598
661
|
* Subscribes to a topic.
|
|
599
662
|
* @param topic - The topic to subscribe to.
|
|
@@ -615,7 +678,10 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
615
678
|
if (!this.node.services.pubsub) {
|
|
616
679
|
throw new Error('Pubsub service not available.');
|
|
617
680
|
}
|
|
618
|
-
const
|
|
681
|
+
const isBlockProposal = topic === this.topicStrings[TopicType.block_proposal];
|
|
682
|
+
const traceContext =
|
|
683
|
+
this.config.debugP2PInstrumentMessages && isBlockProposal ? this.telemetry.getTraceContext() : undefined;
|
|
684
|
+
const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages, traceContext);
|
|
619
685
|
const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
|
|
620
686
|
return result.recipients.length;
|
|
621
687
|
}
|
|
@@ -636,12 +702,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
636
702
|
case this.topicStrings[TopicType.tx]:
|
|
637
703
|
topicType = TopicType.tx;
|
|
638
704
|
break;
|
|
639
|
-
case this.topicStrings[TopicType.block_attestation]:
|
|
640
|
-
topicType = TopicType.block_attestation;
|
|
641
|
-
break;
|
|
642
705
|
case this.topicStrings[TopicType.block_proposal]:
|
|
643
706
|
topicType = TopicType.block_proposal;
|
|
644
707
|
break;
|
|
708
|
+
case this.topicStrings[TopicType.checkpoint_proposal]:
|
|
709
|
+
topicType = TopicType.checkpoint_proposal;
|
|
710
|
+
break;
|
|
711
|
+
case this.topicStrings[TopicType.checkpoint_attestation]:
|
|
712
|
+
topicType = TopicType.checkpoint_attestation;
|
|
713
|
+
break;
|
|
645
714
|
default:
|
|
646
715
|
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
647
716
|
break;
|
|
@@ -660,13 +729,39 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
660
729
|
return { result: true, topicType };
|
|
661
730
|
}
|
|
662
731
|
|
|
732
|
+
/**
|
|
733
|
+
* Safely deserializes a P2PMessage from raw message data.
|
|
734
|
+
* @param msgId - The message ID.
|
|
735
|
+
* @param source - The peer ID of the message source.
|
|
736
|
+
* @param data - The raw message data.
|
|
737
|
+
* @returns The deserialized P2PMessage or undefined if deserialization fails.
|
|
738
|
+
*/
|
|
739
|
+
private safelyDeserializeP2PMessage(msgId: string, source: PeerId, data: Uint8Array): P2PMessage | undefined {
|
|
740
|
+
try {
|
|
741
|
+
return P2PMessage.fromMessageData(Buffer.from(data), this.config.debugP2PInstrumentMessages);
|
|
742
|
+
} catch (err) {
|
|
743
|
+
this.logger.error(`Error deserializing P2PMessage`, err, {
|
|
744
|
+
msgId,
|
|
745
|
+
source: source.toString(),
|
|
746
|
+
});
|
|
747
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Reject);
|
|
748
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
749
|
+
return undefined;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
663
753
|
/**
|
|
664
754
|
* Handles a new gossip message that was received by the client.
|
|
665
755
|
* @param topic - The message's topic.
|
|
666
756
|
* @param data - The message data
|
|
667
757
|
*/
|
|
668
758
|
protected async handleNewGossipMessage(msg: Message, msgId: string, source: PeerId) {
|
|
669
|
-
const
|
|
759
|
+
const msgReceivedTime = Date.now();
|
|
760
|
+
let topicType: TopicType | undefined;
|
|
761
|
+
const p2pMessage = this.safelyDeserializeP2PMessage(msgId, source, msg.data);
|
|
762
|
+
if (!p2pMessage) {
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
670
765
|
|
|
671
766
|
const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
|
|
672
767
|
|
|
@@ -674,14 +769,75 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
674
769
|
return;
|
|
675
770
|
}
|
|
676
771
|
|
|
772
|
+
// Determine topic type for attributes
|
|
677
773
|
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
678
|
-
|
|
774
|
+
topicType = TopicType.tx;
|
|
775
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
776
|
+
topicType = TopicType.checkpoint_attestation;
|
|
777
|
+
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
778
|
+
topicType = TopicType.block_proposal;
|
|
779
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
780
|
+
topicType = TopicType.checkpoint_proposal;
|
|
679
781
|
}
|
|
680
|
-
|
|
681
|
-
|
|
782
|
+
|
|
783
|
+
// Process the message, optionally within a linked span for trace propagation
|
|
784
|
+
const processMessage = async () => {
|
|
785
|
+
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
786
|
+
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
787
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
788
|
+
if (this.clientType === P2PClientType.Full) {
|
|
789
|
+
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
790
|
+
}
|
|
791
|
+
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
792
|
+
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
793
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
794
|
+
await this.handleGossipedCheckpointProposal(p2pMessage.payload, msgId, source);
|
|
795
|
+
} else {
|
|
796
|
+
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
const latency = p2pMessage.timestamp !== undefined ? msgReceivedTime - p2pMessage.timestamp.getTime() : undefined;
|
|
801
|
+
const propagatedContext = p2pMessage.traceContext
|
|
802
|
+
? this.telemetry.extractPropagatedContext(p2pMessage.traceContext)
|
|
803
|
+
: undefined;
|
|
804
|
+
|
|
805
|
+
if (propagatedContext) {
|
|
806
|
+
await this.tracer.startActiveSpan(
|
|
807
|
+
'LibP2PService.processMessage',
|
|
808
|
+
{
|
|
809
|
+
attributes: {
|
|
810
|
+
[Attributes.TOPIC_NAME]: topicType!,
|
|
811
|
+
[Attributes.PEER_ID]: source.toString(),
|
|
812
|
+
},
|
|
813
|
+
},
|
|
814
|
+
propagatedContext,
|
|
815
|
+
async span => {
|
|
816
|
+
try {
|
|
817
|
+
await processMessage();
|
|
818
|
+
span.setStatus({
|
|
819
|
+
code: SpanStatusCode.OK,
|
|
820
|
+
});
|
|
821
|
+
} catch (err) {
|
|
822
|
+
span.setStatus({
|
|
823
|
+
code: SpanStatusCode.ERROR,
|
|
824
|
+
message: String(err),
|
|
825
|
+
});
|
|
826
|
+
if (typeof err === 'string' || (err && err instanceof Error)) {
|
|
827
|
+
span.recordException(err);
|
|
828
|
+
}
|
|
829
|
+
throw err;
|
|
830
|
+
} finally {
|
|
831
|
+
span.end();
|
|
832
|
+
}
|
|
833
|
+
},
|
|
834
|
+
);
|
|
835
|
+
} else {
|
|
836
|
+
await processMessage();
|
|
682
837
|
}
|
|
683
|
-
|
|
684
|
-
|
|
838
|
+
|
|
839
|
+
if (latency !== undefined && topicType !== undefined) {
|
|
840
|
+
this.instrumentation.recordMessageLatency(topicType, latency);
|
|
685
841
|
}
|
|
686
842
|
|
|
687
843
|
return;
|
|
@@ -698,6 +854,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
698
854
|
try {
|
|
699
855
|
resultAndObj = await validationFunc();
|
|
700
856
|
} catch (err) {
|
|
857
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
701
858
|
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
702
859
|
msgId,
|
|
703
860
|
source: source.toString(),
|
|
@@ -751,24 +908,37 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
751
908
|
return;
|
|
752
909
|
}
|
|
753
910
|
|
|
911
|
+
this.instrumentation.incrementTxReceived(1);
|
|
754
912
|
await this.mempools.txPool.addTxs([tx]);
|
|
755
913
|
}
|
|
756
914
|
|
|
757
915
|
/**
|
|
758
|
-
* Process
|
|
759
|
-
*
|
|
760
|
-
*
|
|
761
|
-
* @param attestation - The attestation to process.
|
|
916
|
+
* Process a checkpoint attestation from a peer.
|
|
917
|
+
* Validates the attestation and adds it to the pool.
|
|
762
918
|
*/
|
|
763
|
-
private async
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
919
|
+
private async processCheckpointAttestationFromPeer(
|
|
920
|
+
payloadData: Buffer,
|
|
921
|
+
msgId: string,
|
|
922
|
+
source: PeerId,
|
|
923
|
+
): 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
|
+
}
|
|
768
937
|
|
|
769
|
-
this.logger.trace(`Validate propagated
|
|
938
|
+
this.logger.trace(`Validate propagated checkpoint attestation`, {
|
|
770
939
|
isValid,
|
|
771
940
|
exists,
|
|
941
|
+
canAdd,
|
|
772
942
|
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
773
943
|
[Attributes.P2P_ID]: source.toString(),
|
|
774
944
|
});
|
|
@@ -777,16 +947,23 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
777
947
|
return { result: TopicValidatorResult.Reject };
|
|
778
948
|
} else if (exists) {
|
|
779
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 };
|
|
780
957
|
} else {
|
|
781
958
|
return { result: TopicValidatorResult.Accept, obj: attestation };
|
|
782
959
|
}
|
|
783
960
|
};
|
|
784
961
|
|
|
785
|
-
const { result, obj: attestation } = await this.validateReceivedMessage<
|
|
962
|
+
const { result, obj: attestation } = await this.validateReceivedMessage<CheckpointAttestation>(
|
|
786
963
|
validationFunc,
|
|
787
964
|
msgId,
|
|
788
965
|
source,
|
|
789
|
-
TopicType.
|
|
966
|
+
TopicType.checkpoint_attestation,
|
|
790
967
|
);
|
|
791
968
|
|
|
792
969
|
if (result !== TopicValidatorResult.Accept || !attestation) {
|
|
@@ -794,31 +971,32 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
794
971
|
}
|
|
795
972
|
|
|
796
973
|
this.logger.debug(
|
|
797
|
-
`Received attestation for slot ${attestation.slotNumber
|
|
974
|
+
`Received checkpoint attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`,
|
|
798
975
|
{
|
|
799
|
-
p2pMessageIdentifier: await attestation.
|
|
800
|
-
slot: attestation.slotNumber
|
|
976
|
+
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
977
|
+
slot: attestation.slotNumber,
|
|
801
978
|
archive: attestation.archive.toString(),
|
|
802
979
|
source: source.toString(),
|
|
803
980
|
},
|
|
804
981
|
);
|
|
805
982
|
|
|
806
|
-
await this.mempools.attestationPool
|
|
983
|
+
await this.mempools.attestationPool.addCheckpointAttestations([attestation]);
|
|
807
984
|
}
|
|
808
985
|
|
|
809
986
|
private async processBlockFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
810
987
|
const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockProposal>> = async () => {
|
|
811
988
|
const block = BlockProposal.fromBuffer(payloadData);
|
|
812
989
|
const isValid = await this.validateBlockProposal(source, block);
|
|
990
|
+
const pool = this.mempools.attestationPool;
|
|
813
991
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
const exists = isValid && (await this.mempools.attestationPool?.hasBlockProposal(block));
|
|
992
|
+
const exists = isValid && (await pool.hasBlockProposal(block));
|
|
993
|
+
const canAdd = isValid && (await pool.canAddProposal(block));
|
|
817
994
|
|
|
818
995
|
this.logger.trace(`Validate propagated block proposal`, {
|
|
819
996
|
isValid,
|
|
820
997
|
exists,
|
|
821
|
-
|
|
998
|
+
canAdd,
|
|
999
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
|
|
822
1000
|
[Attributes.P2P_ID]: source.toString(),
|
|
823
1001
|
});
|
|
824
1002
|
|
|
@@ -826,6 +1004,14 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
826
1004
|
return { result: TopicValidatorResult.Reject };
|
|
827
1005
|
} else if (exists) {
|
|
828
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 };
|
|
829
1015
|
} else {
|
|
830
1016
|
return { result: TopicValidatorResult.Accept, obj: block };
|
|
831
1017
|
}
|
|
@@ -846,55 +1032,155 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
846
1032
|
}
|
|
847
1033
|
|
|
848
1034
|
// REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
1035
|
+
// REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
|
|
1036
|
+
// should not be here as it does not deal with p2p networking.
|
|
849
1037
|
@trackSpan('Libp2pService.processValidBlockProposal', async block => ({
|
|
850
|
-
[Attributes.SLOT_NUMBER]: block.slotNumber
|
|
1038
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber,
|
|
851
1039
|
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
852
|
-
[Attributes.P2P_ID]: await block.
|
|
1040
|
+
[Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
853
1041
|
}))
|
|
854
1042
|
private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
|
|
855
|
-
const slot = block.slotNumber
|
|
856
|
-
const previousSlot = slot - 1n;
|
|
1043
|
+
const slot = block.slotNumber;
|
|
857
1044
|
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
858
|
-
p2pMessageIdentifier: await block.
|
|
859
|
-
slot: block.slotNumber.toNumber(),
|
|
860
|
-
archive: block.archive.toString(),
|
|
1045
|
+
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
861
1046
|
source: sender.toString(),
|
|
1047
|
+
...block.toBlockInfo(),
|
|
862
1048
|
});
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
1049
|
+
|
|
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;
|
|
866
1064
|
}
|
|
867
1065
|
|
|
868
1066
|
// Mark the txs in this proposal as non-evictable
|
|
869
1067
|
await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
|
|
870
|
-
await this.mempools.attestationPool?.addBlockProposal(block);
|
|
871
|
-
const attestations = await this.blockReceivedCallback(block, sender);
|
|
872
1068
|
|
|
873
|
-
//
|
|
874
|
-
//
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
1069
|
+
// Call the block received callback to validate the proposal.
|
|
1070
|
+
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1071
|
+
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1072
|
+
if (!isValid) {
|
|
1073
|
+
this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Handle a gossiped checkpoint proposal.
|
|
1079
|
+
* Validates and processes the checkpoint proposal, then triggers the callback for attestation.
|
|
1080
|
+
*/
|
|
1081
|
+
private async handleGossipedCheckpointProposal(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
1082
|
+
// TODO(palla/mbps): This pattern is repeated across multiple message handlers, consider abstracting it.
|
|
1083
|
+
const validationFunc: () => Promise<ReceivedMessageValidationResult<CheckpointProposal>> = async () => {
|
|
1084
|
+
const checkpoint = CheckpointProposal.fromBuffer(payloadData);
|
|
1085
|
+
const isValid = await this.validateCheckpointProposal(source, checkpoint);
|
|
1086
|
+
const pool = this.mempools.attestationPool;
|
|
1087
|
+
|
|
1088
|
+
const exists = isValid && (await pool.hasCheckpointProposal(checkpoint));
|
|
1089
|
+
const canAdd = isValid && (await pool.canAddCheckpointProposal(checkpoint));
|
|
1090
|
+
|
|
1091
|
+
this.logger.trace(`Validate propagated checkpoint proposal`, {
|
|
1092
|
+
isValid,
|
|
1093
|
+
exists,
|
|
1094
|
+
canAdd,
|
|
1095
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1096
|
+
[Attributes.P2P_ID]: source.toString(),
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
if (!isValid) {
|
|
1100
|
+
return { result: TopicValidatorResult.Reject };
|
|
1101
|
+
} else if (exists) {
|
|
1102
|
+
return { result: TopicValidatorResult.Ignore, obj: checkpoint };
|
|
1103
|
+
} else if (!canAdd) {
|
|
1104
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
|
|
1105
|
+
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1106
|
+
slot: checkpoint.slotNumber.toString(),
|
|
1107
|
+
archive: checkpoint.archive.toString(),
|
|
1108
|
+
source: source.toString(),
|
|
881
1109
|
});
|
|
882
|
-
|
|
1110
|
+
return { result: TopicValidatorResult.Reject };
|
|
1111
|
+
} else {
|
|
1112
|
+
return { result: TopicValidatorResult.Accept, obj: checkpoint };
|
|
883
1113
|
}
|
|
1114
|
+
};
|
|
1115
|
+
|
|
1116
|
+
const { result, obj: checkpoint } = await this.validateReceivedMessage<CheckpointProposal>(
|
|
1117
|
+
validationFunc,
|
|
1118
|
+
msgId,
|
|
1119
|
+
source,
|
|
1120
|
+
TopicType.checkpoint_proposal,
|
|
1121
|
+
);
|
|
1122
|
+
|
|
1123
|
+
if (result !== TopicValidatorResult.Accept || !checkpoint) {
|
|
1124
|
+
return;
|
|
884
1125
|
}
|
|
1126
|
+
|
|
1127
|
+
await this.processValidCheckpointProposal(checkpoint, source);
|
|
885
1128
|
}
|
|
886
1129
|
|
|
887
1130
|
/**
|
|
888
|
-
*
|
|
889
|
-
*
|
|
1131
|
+
* Process a validated checkpoint proposal.
|
|
1132
|
+
* Extracts and processes the last block proposal (if present) first, then processes the checkpoint.
|
|
1133
|
+
* The block callback is invoked before the checkpoint callback.
|
|
890
1134
|
*/
|
|
891
|
-
@trackSpan('Libp2pService.
|
|
892
|
-
[Attributes.SLOT_NUMBER]:
|
|
893
|
-
[Attributes.BLOCK_ARCHIVE]:
|
|
894
|
-
[Attributes.P2P_ID]: await
|
|
1135
|
+
@trackSpan('Libp2pService.processValidCheckpointProposal', async checkpoint => ({
|
|
1136
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber,
|
|
1137
|
+
[Attributes.BLOCK_ARCHIVE]: checkpoint.archive.toString(),
|
|
1138
|
+
[Attributes.P2P_ID]: await checkpoint.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
895
1139
|
}))
|
|
896
|
-
private async
|
|
897
|
-
|
|
1140
|
+
private async processValidCheckpointProposal(checkpoint: CheckpointProposal, sender: PeerId) {
|
|
1141
|
+
const slot = checkpoint.slotNumber;
|
|
1142
|
+
this.logger.verbose(`Received checkpoint proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1143
|
+
p2pMessageIdentifier: await checkpoint.p2pMessageLoggingIdentifier(),
|
|
1144
|
+
slot: checkpoint.slotNumber,
|
|
1145
|
+
archive: checkpoint.archive.toString(),
|
|
1146
|
+
source: sender.toString(),
|
|
1147
|
+
});
|
|
1148
|
+
|
|
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
|
+
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1175
|
+
// to validate and potentially generate attestations
|
|
1176
|
+
const attestations = await this.checkpointReceivedCallback(checkpoint.toCore(), sender);
|
|
1177
|
+
if (attestations && attestations.length > 0) {
|
|
1178
|
+
// If the callback returned attestations, add them to the pool and propagate them
|
|
1179
|
+
await this.mempools.attestationPool.addCheckpointAttestations(attestations);
|
|
1180
|
+
for (const attestation of attestations) {
|
|
1181
|
+
await this.propagate(attestation);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
898
1184
|
}
|
|
899
1185
|
|
|
900
1186
|
/**
|
|
@@ -902,19 +1188,15 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
902
1188
|
* @param message - The message to propagate.
|
|
903
1189
|
*/
|
|
904
1190
|
public async propagate<T extends Gossipable>(message: T) {
|
|
905
|
-
const p2pMessageIdentifier = await message.
|
|
1191
|
+
const p2pMessageIdentifier = await message.p2pMessageLoggingIdentifier();
|
|
906
1192
|
this.logger.trace(`Message ${p2pMessageIdentifier} queued`, { p2pMessageIdentifier });
|
|
907
|
-
void this.
|
|
908
|
-
.
|
|
909
|
-
|
|
910
|
-
})
|
|
911
|
-
.catch(error => {
|
|
912
|
-
this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, { error });
|
|
913
|
-
});
|
|
1193
|
+
void this.sendToPeers(message).catch(error => {
|
|
1194
|
+
this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, { error });
|
|
1195
|
+
});
|
|
914
1196
|
}
|
|
915
1197
|
|
|
916
1198
|
/**
|
|
917
|
-
* Validate the requested block transactions.
|
|
1199
|
+
* Validate the requested block transactions. Allow partial returns.
|
|
918
1200
|
* @param request - The block transactions request.
|
|
919
1201
|
* @param response - The block transactions response.
|
|
920
1202
|
* @param peerId - The ID of the peer that made the request.
|
|
@@ -924,14 +1206,71 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
924
1206
|
[Attributes.BLOCK_HASH]: request.blockHash.toString(),
|
|
925
1207
|
}))
|
|
926
1208
|
private async validateRequestedBlockTxs(
|
|
927
|
-
|
|
1209
|
+
request: BlockTxsRequest,
|
|
928
1210
|
response: BlockTxsResponse,
|
|
929
1211
|
peerId: PeerId,
|
|
930
1212
|
): Promise<boolean> {
|
|
931
1213
|
const requestedTxValidator = this.createRequestedTxValidator();
|
|
932
1214
|
|
|
933
1215
|
try {
|
|
934
|
-
|
|
1216
|
+
if (!response.blockHash.equals(request.blockHash)) {
|
|
1217
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1218
|
+
throw new ValidationError(
|
|
1219
|
+
`Received block txs for unexpected block: expected ${request.blockHash.toString()}, got ${response.blockHash.toString()}`,
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
if (response.txIndices.getLength() !== request.txIndices.getLength()) {
|
|
1224
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1225
|
+
throw new ValidationError(
|
|
1226
|
+
`Received block txs with mismatched bitvector length: expected ${request.txIndices.getLength()}, got ${response.txIndices.getLength()}`,
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// Check no duplicates and not exceeding returnable count
|
|
1231
|
+
const requestedIndices = new Set(request.txIndices.getTrueIndices());
|
|
1232
|
+
const availableIndices = new Set(response.txIndices.getTrueIndices());
|
|
1233
|
+
const maxReturnable = [...requestedIndices].filter(i => availableIndices.has(i)).length;
|
|
1234
|
+
|
|
1235
|
+
const returnedHashes = await Promise.all(response.txs.map(tx => tx.getTxHash().toString()));
|
|
1236
|
+
const uniqueReturned = new Set(returnedHashes.map(h => h.toString()));
|
|
1237
|
+
if (uniqueReturned.size !== returnedHashes.length) {
|
|
1238
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1239
|
+
throw new ValidationError(`Received duplicate txs in block txs response`);
|
|
1240
|
+
}
|
|
1241
|
+
if (response.txs.length > maxReturnable) {
|
|
1242
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1243
|
+
throw new ValidationError(
|
|
1244
|
+
`Received more txs (${response.txs.length}) than requested-and-available (${maxReturnable})`,
|
|
1245
|
+
);
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
// Given proposal (should have locally), ensure returned txs are valid subset and match request indices
|
|
1249
|
+
const proposal = await this.mempools.attestationPool.getBlockProposal(request.blockHash.toString());
|
|
1250
|
+
if (proposal) {
|
|
1251
|
+
// Build intersected indices
|
|
1252
|
+
const intersectIdx = request.txIndices.getTrueIndices().filter(i => response.txIndices.isSet(i));
|
|
1253
|
+
|
|
1254
|
+
// Enforce subset membership and preserve increasing order by index.
|
|
1255
|
+
const hashToIndexInProposal = new Map<string, number>(
|
|
1256
|
+
proposal.txHashes.map((h, i) => [h.toString(), i] as [string, number]),
|
|
1257
|
+
);
|
|
1258
|
+
const allowedIndexSet = new Set(intersectIdx);
|
|
1259
|
+
const indices = returnedHashes.map(h => hashToIndexInProposal.get(h));
|
|
1260
|
+
const allAllowed = indices.every(idx => idx !== undefined && allowedIndexSet.has(idx));
|
|
1261
|
+
const strictlyIncreasing = indices.every((idx, i) => (i === 0 ? idx !== undefined : idx! > indices[i - 1]!));
|
|
1262
|
+
if (!allAllowed || !strictlyIncreasing) {
|
|
1263
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1264
|
+
throw new ValidationError('Returned txs do not match expected subset/order for requested indices');
|
|
1265
|
+
}
|
|
1266
|
+
} else {
|
|
1267
|
+
// No local proposal, cannot check the membership/order of the returned txs
|
|
1268
|
+
this.logger.warn(
|
|
1269
|
+
`Block proposal not found for block hash ${request.blockHash.toString()}; cannot validate membership/order of returned txs`,
|
|
1270
|
+
);
|
|
1271
|
+
return false;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
935
1274
|
await Promise.all(response.txs.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator)));
|
|
936
1275
|
return true;
|
|
937
1276
|
} catch (e: any) {
|
|
@@ -955,7 +1294,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
955
1294
|
* ReqRespSubProtocol.TX subprotocol validation.
|
|
956
1295
|
*
|
|
957
1296
|
* @param requestedTxHash - The collection of the txs that was requested.
|
|
958
|
-
* @param responseTx - The
|
|
1297
|
+
* @param responseTx - The collection of txs that was received as a response to the request.
|
|
959
1298
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
960
1299
|
* @returns True if the whole collection of txs is valid, false otherwise.
|
|
961
1300
|
*/
|
|
@@ -982,9 +1321,57 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
982
1321
|
}
|
|
983
1322
|
}
|
|
984
1323
|
|
|
1324
|
+
/**
|
|
1325
|
+
* Validates a BLOCK response.
|
|
1326
|
+
*
|
|
1327
|
+
* If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
|
|
1328
|
+
* Penalizes on block number mismatch or hash mismatch.
|
|
1329
|
+
*
|
|
1330
|
+
* @param requestedBlockNumber - The requested block number.
|
|
1331
|
+
* @param responseBlock - The block returned by the peer.
|
|
1332
|
+
* @param peerId - The peer that returned the block.
|
|
1333
|
+
* @returns True if the response is valid, false otherwise.
|
|
1334
|
+
*/
|
|
1335
|
+
@trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
|
|
1336
|
+
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
|
|
1337
|
+
}))
|
|
1338
|
+
private async validateRequestedBlock(
|
|
1339
|
+
requestedBlockNumber: Fr,
|
|
1340
|
+
responseBlock: L2BlockNew,
|
|
1341
|
+
peerId: PeerId,
|
|
1342
|
+
): Promise<boolean> {
|
|
1343
|
+
try {
|
|
1344
|
+
const reqNum = Number(requestedBlockNumber.toString());
|
|
1345
|
+
if (responseBlock.number !== reqNum) {
|
|
1346
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1347
|
+
return false;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
const local = await this.archiver.getBlock(BlockNumber(reqNum));
|
|
1351
|
+
if (!local) {
|
|
1352
|
+
// We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
|
|
1353
|
+
// TODO: Consider extending this validator to accept an expected hash or
|
|
1354
|
+
// performing quorum-based checks when using P2P syncing prior to L1 sync.
|
|
1355
|
+
this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
|
|
1356
|
+
return false;
|
|
1357
|
+
}
|
|
1358
|
+
const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
|
|
1359
|
+
if (!localHash.equals(respHash)) {
|
|
1360
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1361
|
+
return false;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
return true;
|
|
1365
|
+
} catch (e) {
|
|
1366
|
+
this.logger.warn(`Error validating requested block`, e);
|
|
1367
|
+
return false;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
|
|
985
1371
|
private createRequestedTxValidator(): TxValidator {
|
|
986
1372
|
return new AggregateTxValidator(
|
|
987
1373
|
new DataTxValidator(),
|
|
1374
|
+
new SizeTxValidator(),
|
|
988
1375
|
new MetadataTxValidator({
|
|
989
1376
|
l1ChainId: new Fr(this.config.l1ChainId),
|
|
990
1377
|
rollupVersion: new Fr(this.config.rollupVersion),
|
|
@@ -996,19 +1383,21 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
996
1383
|
}
|
|
997
1384
|
|
|
998
1385
|
private async validateRequestedTx(tx: Tx, peerId: PeerId, txValidator: TxValidator, requested?: Set<`0x${string}`>) {
|
|
1386
|
+
const penalize = (severity: PeerErrorSeverity) => this.peerManager.penalizePeer(peerId, severity);
|
|
1387
|
+
|
|
999
1388
|
if (!(await tx.validateTxHash())) {
|
|
1000
|
-
|
|
1389
|
+
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1001
1390
|
throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
|
|
1002
1391
|
}
|
|
1003
1392
|
|
|
1004
1393
|
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
1005
|
-
|
|
1394
|
+
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1006
1395
|
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
1007
1396
|
}
|
|
1008
1397
|
|
|
1009
1398
|
const { result } = await txValidator.validateTx(tx);
|
|
1010
1399
|
if (result === 'invalid') {
|
|
1011
|
-
|
|
1400
|
+
penalize(PeerErrorSeverity.LowToleranceError);
|
|
1012
1401
|
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
1013
1402
|
}
|
|
1014
1403
|
}
|
|
@@ -1034,7 +1423,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1034
1423
|
|
|
1035
1424
|
// Double spend validator has a special case handler
|
|
1036
1425
|
if (name === 'doubleSpendValidator') {
|
|
1037
|
-
const txBlockNumber = currentBlockNumber + 1; // tx is expected to be in the next block
|
|
1426
|
+
const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
|
|
1038
1427
|
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1039
1428
|
}
|
|
1040
1429
|
|
|
@@ -1044,7 +1433,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1044
1433
|
return true;
|
|
1045
1434
|
}
|
|
1046
1435
|
|
|
1047
|
-
private async getGasFees(blockNumber:
|
|
1436
|
+
private async getGasFees(blockNumber: BlockNumber): Promise<GasFees> {
|
|
1048
1437
|
if (blockNumber === this.feesCache?.blockNumber) {
|
|
1049
1438
|
return this.feesCache.gasFees;
|
|
1050
1439
|
}
|
|
@@ -1085,13 +1474,13 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1085
1474
|
* @returns The message validators.
|
|
1086
1475
|
*/
|
|
1087
1476
|
private async createMessageValidators(
|
|
1088
|
-
currentBlockNumber:
|
|
1477
|
+
currentBlockNumber: BlockNumber,
|
|
1089
1478
|
nextSlotTimestamp: UInt64,
|
|
1090
1479
|
): Promise<Record<string, MessageValidator>[]> {
|
|
1091
1480
|
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
1092
1481
|
const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
1093
1482
|
|
|
1094
|
-
const blockNumberInWhichTheTxIsConsideredToBeIncluded = currentBlockNumber + 1;
|
|
1483
|
+
const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
|
|
1095
1484
|
|
|
1096
1485
|
return createTxMessageValidators(
|
|
1097
1486
|
nextSlotTimestamp,
|
|
@@ -1153,7 +1542,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1153
1542
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
1154
1543
|
* @returns Severity
|
|
1155
1544
|
*/
|
|
1156
|
-
private async handleDoubleSpendFailure(tx: Tx, blockNumber:
|
|
1545
|
+
private async handleDoubleSpendFailure(tx: Tx, blockNumber: BlockNumber): Promise<PeerErrorSeverity> {
|
|
1157
1546
|
if (blockNumber <= this.config.doubleSpendSeverePeerPenaltyWindow) {
|
|
1158
1547
|
return PeerErrorSeverity.HighToleranceError;
|
|
1159
1548
|
}
|
|
@@ -1161,7 +1550,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1161
1550
|
const snapshotValidator = new DoubleSpendTxValidator({
|
|
1162
1551
|
nullifiersExist: async (nullifiers: Buffer[]) => {
|
|
1163
1552
|
const merkleTree = this.worldStateSynchronizer.getSnapshot(
|
|
1164
|
-
blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow,
|
|
1553
|
+
BlockNumber(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow),
|
|
1165
1554
|
);
|
|
1166
1555
|
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
1167
1556
|
return indices.map(index => index !== undefined);
|
|
@@ -1177,19 +1566,20 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1177
1566
|
}
|
|
1178
1567
|
|
|
1179
1568
|
/**
|
|
1180
|
-
* Validate
|
|
1569
|
+
* Validate a checkpoint attestation.
|
|
1181
1570
|
*
|
|
1182
|
-
* @param attestation - The attestation to validate.
|
|
1183
|
-
* @returns True if the attestation is valid, false otherwise.
|
|
1571
|
+
* @param attestation - The checkpoint attestation to validate.
|
|
1572
|
+
* @returns True if the checkpoint attestation is valid, false otherwise.
|
|
1184
1573
|
*/
|
|
1185
|
-
@trackSpan('Libp2pService.
|
|
1186
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber
|
|
1574
|
+
@trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
|
|
1575
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
1187
1576
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
1188
|
-
[Attributes.P2P_ID]: await attestation.
|
|
1577
|
+
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
|
|
1189
1578
|
}))
|
|
1190
|
-
public async
|
|
1191
|
-
const severity = await this.
|
|
1579
|
+
public async validateCheckpointAttestation(peerId: PeerId, attestation: CheckpointAttestation): Promise<boolean> {
|
|
1580
|
+
const severity = await this.checkpointAttestationValidator.validate(attestation);
|
|
1192
1581
|
if (severity) {
|
|
1582
|
+
this.logger.debug(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
1193
1583
|
this.peerManager.penalizePeer(peerId, severity);
|
|
1194
1584
|
return false;
|
|
1195
1585
|
}
|
|
@@ -1204,7 +1594,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1204
1594
|
* @returns True if the block proposal is valid, false otherwise.
|
|
1205
1595
|
*/
|
|
1206
1596
|
@trackSpan('Libp2pService.validateBlockProposal', (_peerId, block) => ({
|
|
1207
|
-
[Attributes.SLOT_NUMBER]: block.
|
|
1597
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
|
|
1208
1598
|
}))
|
|
1209
1599
|
public async validateBlockProposal(peerId: PeerId, block: BlockProposal): Promise<boolean> {
|
|
1210
1600
|
const severity = await this.blockProposalValidator.validate(block);
|
|
@@ -1217,6 +1607,26 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1217
1607
|
return true;
|
|
1218
1608
|
}
|
|
1219
1609
|
|
|
1610
|
+
/**
|
|
1611
|
+
* Validate a checkpoint proposal.
|
|
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;
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
return true;
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1220
1630
|
public getPeerScore(peerId: PeerId): number {
|
|
1221
1631
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
1222
1632
|
}
|
|
@@ -1228,7 +1638,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1228
1638
|
private async sendToPeers<T extends Gossipable>(message: T) {
|
|
1229
1639
|
const parent = message.constructor as typeof Gossipable;
|
|
1230
1640
|
|
|
1231
|
-
const identifier = await message.
|
|
1641
|
+
const identifier = await message.p2pMessageLoggingIdentifier().then(i => i.toString());
|
|
1232
1642
|
this.logger.trace(`Sending message ${identifier}`, { p2pMessageIdentifier: identifier });
|
|
1233
1643
|
|
|
1234
1644
|
const recipientsNum = await this.publishToTopic(this.topicStrings[parent.p2pTopic], message);
|