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