@aztec/p2p 0.0.0-test.1 → 0.0.1-commit.1142ef1
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/bootstrap/bootstrap.js +22 -9
- package/dest/client/factory.d.ts +15 -5
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +60 -25
- package/dest/client/index.d.ts +2 -1
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +1 -0
- package/dest/client/interface.d.ts +170 -0
- package/dest/client/interface.d.ts.map +1 -0
- package/dest/client/interface.js +9 -0
- package/dest/client/p2p_client.d.ts +75 -193
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +757 -228
- package/dest/config.d.ts +148 -125
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +180 -34
- package/dest/enr/generate-enr.d.ts +11 -3
- package/dest/enr/generate-enr.d.ts.map +1 -1
- package/dest/enr/generate-enr.js +27 -5
- 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 +4 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -25
- 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 +288 -174
- package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +29 -11
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +168 -62
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +24 -10
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +133 -82
- package/dest/mem_pools/attestation_pool/mocks.d.ts +232 -11
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +15 -20
- package/dest/mem_pools/index.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts +16 -12
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +55 -40
- 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 +70 -16
- 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 +452 -142
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +18 -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 +56 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +83 -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 +5 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.js +88 -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/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 +7 -2
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +72 -11
- 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 +276 -45
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +7 -5
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +48 -10
- 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 +10 -0
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -0
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.js +36 -0
- 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 +80 -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 +183 -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 +3 -0
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +27 -0
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/archive_cache.js +22 -0
- 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/block_header_validator.js +4 -4
- 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/data_validator.js +56 -86
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +1 -3
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +21 -27
- package/dest/msg_validators/tx_validator/factory.d.ts +16 -0
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/factory.js +74 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +11 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/gas_validator.js +115 -0
- package/dest/msg_validators/tx_validator/index.d.ts +8 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +7 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +9 -5
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +39 -20
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +14 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/phases_validator.js +93 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts +17 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/test_utils.js +22 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +13 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.js +32 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +8 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.js +24 -0
- 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/msg_validators/tx_validator/tx_proof_validator.js +6 -5
- 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 +10 -9
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +63 -36
- package/dest/services/dummy_service.d.ts +54 -11
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +91 -5
- package/dest/services/encoding.d.ts +26 -7
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +76 -6
- package/dest/services/gossipsub/scoring.d.ts +1 -1
- package/dest/services/index.d.ts +5 -1
- package/dest/services/index.d.ts.map +1 -1
- package/dest/services/index.js +4 -0
- package/dest/services/libp2p/instrumentation.d.ts +20 -0
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -0
- package/dest/services/libp2p/instrumentation.js +111 -0
- package/dest/services/libp2p/libp2p_service.d.ts +102 -96
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +1307 -301
- package/dest/services/peer-manager/interface.d.ts +23 -0
- package/dest/services/peer-manager/interface.d.ts.map +1 -0
- package/dest/services/peer-manager/interface.js +1 -0
- package/dest/services/peer-manager/metrics.d.ts +11 -2
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +29 -12
- package/dest/services/peer-manager/peer_manager.d.ts +103 -23
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +551 -82
- 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 +11 -9
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/config.js +18 -4
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +2 -2
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +10 -6
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +31 -17
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +142 -84
- package/dest/services/reqresp/index.d.ts +3 -2
- package/dest/services/reqresp/index.d.ts.map +1 -1
- package/dest/services/reqresp/index.js +2 -1
- package/dest/services/reqresp/interface.d.ts +73 -24
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +46 -27
- 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 +43 -0
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/auth.js +71 -0
- package/dest/services/reqresp/protocols/block.d.ts +6 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +30 -6
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +30 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +75 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +11 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +39 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +47 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +75 -0
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +4 -0
- package/dest/services/reqresp/protocols/block_txs/index.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/index.js +3 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts +3 -5
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/goodbye.js +7 -7
- package/dest/services/reqresp/protocols/index.d.ts +3 -1
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +2 -0
- package/dest/services/reqresp/protocols/ping.d.ts +1 -3
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +40 -7
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +75 -5
- package/dest/services/reqresp/protocols/tx.d.ts +14 -4
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +34 -6
- package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +6 -4
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -2
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +21 -1
- package/dest/services/reqresp/reqresp.d.ts +24 -66
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +699 -230
- package/dest/services/reqresp/status.d.ts +10 -4
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/reqresp/status.js +9 -2
- package/dest/services/service.d.ts +37 -20
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +25 -0
- package/dest/services/tx_collection/config.d.ts.map +1 -0
- package/dest/services/tx_collection/config.js +58 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +51 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/fast_tx_collection.js +300 -0
- package/dest/services/tx_collection/index.d.ts +3 -0
- package/dest/services/tx_collection/index.d.ts.map +1 -0
- package/dest/services/tx_collection/index.js +2 -0
- package/dest/services/tx_collection/instrumentation.d.ts +10 -0
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -0
- package/dest/services/tx_collection/instrumentation.js +24 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/slow_tx_collection.js +177 -0
- package/dest/services/tx_collection/tx_collection.d.ts +110 -0
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_collection.js +128 -0
- package/dest/services/tx_collection/tx_collection_sink.d.ts +30 -0
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_collection_sink.js +111 -0
- package/dest/services/tx_collection/tx_source.d.ts +18 -0
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_source.js +31 -0
- package/dest/services/tx_provider.d.ts +51 -0
- package/dest/services/tx_provider.d.ts.map +1 -0
- package/dest/services/tx_provider.js +219 -0
- package/dest/services/tx_provider_instrumentation.d.ts +16 -0
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -0
- package/dest/services/tx_provider_instrumentation.js +34 -0
- 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 +2 -1
- package/dest/test-helpers/index.d.ts.map +1 -1
- package/dest/test-helpers/index.js +1 -0
- package/dest/test-helpers/make-enrs.d.ts +1 -1
- package/dest/test-helpers/make-enrs.d.ts.map +1 -1
- package/dest/test-helpers/make-enrs.js +4 -5
- package/dest/test-helpers/make-test-p2p-clients.d.ts +33 -5
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +86 -16
- package/dest/test-helpers/mock-pubsub.d.ts +59 -0
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -0
- package/dest/test-helpers/mock-pubsub.js +130 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts +12 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -0
- package/dest/test-helpers/mock-tx-helpers.js +19 -0
- package/dest/test-helpers/reqresp-nodes.d.ts +15 -11
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +62 -28
- package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +124 -35
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/parse_log_file.js +4 -4
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/testbench.js +4 -4
- package/dest/testbench/worker_client_manager.d.ts +1 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +17 -20
- package/dest/types/index.d.ts +4 -2
- package/dest/types/index.d.ts.map +1 -1
- package/dest/types/index.js +2 -0
- package/dest/util.d.ts +24 -16
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +75 -69
- package/dest/versioning.d.ts +4 -4
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +8 -3
- package/package.json +32 -27
- package/src/bootstrap/bootstrap.ts +27 -11
- package/src/client/factory.ts +139 -53
- package/src/client/index.ts +1 -0
- package/src/client/interface.ts +213 -0
- package/src/client/p2p_client.ts +471 -385
- package/src/config.ts +299 -134
- package/src/enr/generate-enr.ts +39 -6
- package/src/errors/attestation-pool.error.ts +13 -0
- package/src/index.ts +4 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +119 -24
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +344 -201
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +233 -72
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +199 -96
- package/src/mem_pools/attestation_pool/mocks.ts +21 -16
- package/src/mem_pools/instrumentation.ts +71 -48
- package/src/mem_pools/interface.ts +2 -4
- package/src/mem_pools/tx_pool/README.md +255 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +537 -155
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +71 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +93 -0
- package/src/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.ts +108 -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/index.ts +0 -1
- package/src/mem_pools/tx_pool/priority.ts +9 -2
- package/src/mem_pools/tx_pool/tx_pool.ts +75 -10
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +225 -36
- package/src/msg_validators/attestation_validator/attestation_validator.ts +60 -14
- 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/msg_seen_validator/msg_seen_validator.ts +36 -0
- 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 +206 -0
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +35 -0
- package/src/msg_validators/tx_validator/archive_cache.ts +28 -0
- package/src/msg_validators/tx_validator/block_header_validator.ts +5 -5
- package/src/msg_validators/tx_validator/data_validator.ts +89 -69
- package/src/msg_validators/tx_validator/double_spend_validator.ts +19 -17
- package/src/msg_validators/tx_validator/factory.ts +110 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +134 -0
- package/src/msg_validators/tx_validator/index.ts +7 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +67 -22
- package/src/msg_validators/tx_validator/phases_validator.ts +116 -0
- package/src/msg_validators/tx_validator/test_utils.ts +43 -0
- package/src/msg_validators/tx_validator/timestamp_validator.ts +49 -0
- package/src/msg_validators/tx_validator/tx_permitted_validator.ts +17 -0
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +6 -5
- package/src/services/discv5/discV5_service.ts +84 -38
- package/src/services/dummy_service.ts +153 -9
- package/src/services/encoding.ts +83 -6
- package/src/services/index.ts +4 -0
- package/src/services/libp2p/instrumentation.ts +113 -0
- package/src/services/libp2p/libp2p_service.ts +1120 -329
- package/src/services/peer-manager/interface.ts +29 -0
- package/src/services/peer-manager/metrics.ts +38 -12
- package/src/services/peer-manager/peer_manager.ts +657 -80
- package/src/services/peer-manager/peer_scoring.ts +42 -3
- package/src/services/reqresp/config.ts +26 -9
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +12 -6
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +150 -95
- package/src/services/reqresp/index.ts +2 -0
- package/src/services/reqresp/interface.ts +92 -37
- package/src/services/reqresp/metrics.ts +11 -24
- package/src/services/reqresp/protocols/auth.ts +83 -0
- package/src/services/reqresp/protocols/block.ts +26 -4
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +90 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +53 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +79 -0
- package/src/services/reqresp/protocols/block_txs/index.ts +3 -0
- package/src/services/reqresp/protocols/goodbye.ts +9 -7
- package/src/services/reqresp/protocols/index.ts +2 -0
- package/src/services/reqresp/protocols/status.ts +119 -5
- package/src/services/reqresp/protocols/tx.ts +36 -8
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +12 -3
- package/src/services/reqresp/rate-limiter/rate_limits.ts +21 -1
- package/src/services/reqresp/reqresp.ts +387 -256
- package/src/services/reqresp/status.ts +12 -3
- package/src/services/service.ts +61 -22
- package/src/services/tx_collection/config.ts +84 -0
- package/src/services/tx_collection/fast_tx_collection.ts +341 -0
- package/src/services/tx_collection/index.ts +2 -0
- package/src/services/tx_collection/instrumentation.ts +26 -0
- package/src/services/tx_collection/slow_tx_collection.ts +233 -0
- package/src/services/tx_collection/tx_collection.ts +216 -0
- package/src/services/tx_collection/tx_collection_sink.ts +129 -0
- package/src/services/tx_collection/tx_source.ts +37 -0
- package/src/services/tx_provider.ts +232 -0
- package/src/services/tx_provider_instrumentation.ts +48 -0
- package/src/test-helpers/index.ts +1 -0
- package/src/test-helpers/make-enrs.ts +4 -5
- package/src/test-helpers/make-test-p2p-clients.ts +111 -21
- package/src/test-helpers/mock-pubsub.ts +188 -0
- package/src/test-helpers/mock-tx-helpers.ts +24 -0
- package/src/test-helpers/reqresp-nodes.ts +87 -36
- package/src/testbench/p2p_client_testbench_worker.ts +182 -32
- package/src/testbench/parse_log_file.ts +4 -4
- package/src/testbench/testbench.ts +4 -4
- package/src/testbench/worker_client_manager.ts +23 -24
- package/src/types/index.ts +2 -0
- package/src/util.ts +105 -91
- package/src/versioning.ts +11 -4
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -56
- 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 -141
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -8
- 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 -21
- 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 -174
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -29
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -1,17 +1,390 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
function applyDecs2203RFactory() {
|
|
2
|
+
function createAddInitializerMethod(initializers, decoratorFinishedRef) {
|
|
3
|
+
return function addInitializer(initializer) {
|
|
4
|
+
assertNotFinished(decoratorFinishedRef, "addInitializer");
|
|
5
|
+
assertCallable(initializer, "An initializer");
|
|
6
|
+
initializers.push(initializer);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value) {
|
|
10
|
+
var kindStr;
|
|
11
|
+
switch(kind){
|
|
12
|
+
case 1:
|
|
13
|
+
kindStr = "accessor";
|
|
14
|
+
break;
|
|
15
|
+
case 2:
|
|
16
|
+
kindStr = "method";
|
|
17
|
+
break;
|
|
18
|
+
case 3:
|
|
19
|
+
kindStr = "getter";
|
|
20
|
+
break;
|
|
21
|
+
case 4:
|
|
22
|
+
kindStr = "setter";
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
kindStr = "field";
|
|
26
|
+
}
|
|
27
|
+
var ctx = {
|
|
28
|
+
kind: kindStr,
|
|
29
|
+
name: isPrivate ? "#" + name : name,
|
|
30
|
+
static: isStatic,
|
|
31
|
+
private: isPrivate,
|
|
32
|
+
metadata: metadata
|
|
33
|
+
};
|
|
34
|
+
var decoratorFinishedRef = {
|
|
35
|
+
v: false
|
|
36
|
+
};
|
|
37
|
+
ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
|
|
38
|
+
var get, set;
|
|
39
|
+
if (kind === 0) {
|
|
40
|
+
if (isPrivate) {
|
|
41
|
+
get = desc.get;
|
|
42
|
+
set = desc.set;
|
|
43
|
+
} else {
|
|
44
|
+
get = function() {
|
|
45
|
+
return this[name];
|
|
46
|
+
};
|
|
47
|
+
set = function(v) {
|
|
48
|
+
this[name] = v;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
} else if (kind === 2) {
|
|
52
|
+
get = function() {
|
|
53
|
+
return desc.value;
|
|
54
|
+
};
|
|
55
|
+
} else {
|
|
56
|
+
if (kind === 1 || kind === 3) {
|
|
57
|
+
get = function() {
|
|
58
|
+
return desc.get.call(this);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (kind === 1 || kind === 4) {
|
|
62
|
+
set = function(v) {
|
|
63
|
+
desc.set.call(this, v);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
ctx.access = get && set ? {
|
|
68
|
+
get: get,
|
|
69
|
+
set: set
|
|
70
|
+
} : get ? {
|
|
71
|
+
get: get
|
|
72
|
+
} : {
|
|
73
|
+
set: set
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
return dec(value, ctx);
|
|
77
|
+
} finally{
|
|
78
|
+
decoratorFinishedRef.v = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function assertNotFinished(decoratorFinishedRef, fnName) {
|
|
82
|
+
if (decoratorFinishedRef.v) {
|
|
83
|
+
throw new Error("attempted to call " + fnName + " after decoration was finished");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function assertCallable(fn, hint) {
|
|
87
|
+
if (typeof fn !== "function") {
|
|
88
|
+
throw new TypeError(hint + " must be a function");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function assertValidReturnValue(kind, value) {
|
|
92
|
+
var type = typeof value;
|
|
93
|
+
if (kind === 1) {
|
|
94
|
+
if (type !== "object" || value === null) {
|
|
95
|
+
throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
|
|
96
|
+
}
|
|
97
|
+
if (value.get !== undefined) {
|
|
98
|
+
assertCallable(value.get, "accessor.get");
|
|
99
|
+
}
|
|
100
|
+
if (value.set !== undefined) {
|
|
101
|
+
assertCallable(value.set, "accessor.set");
|
|
102
|
+
}
|
|
103
|
+
if (value.init !== undefined) {
|
|
104
|
+
assertCallable(value.init, "accessor.init");
|
|
105
|
+
}
|
|
106
|
+
} else if (type !== "function") {
|
|
107
|
+
var hint;
|
|
108
|
+
if (kind === 0) {
|
|
109
|
+
hint = "field";
|
|
110
|
+
} else if (kind === 10) {
|
|
111
|
+
hint = "class";
|
|
112
|
+
} else {
|
|
113
|
+
hint = "method";
|
|
114
|
+
}
|
|
115
|
+
throw new TypeError(hint + " decorators must return a function or void 0");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata) {
|
|
119
|
+
var decs = decInfo[0];
|
|
120
|
+
var desc, init, value;
|
|
121
|
+
if (isPrivate) {
|
|
122
|
+
if (kind === 0 || kind === 1) {
|
|
123
|
+
desc = {
|
|
124
|
+
get: decInfo[3],
|
|
125
|
+
set: decInfo[4]
|
|
126
|
+
};
|
|
127
|
+
} else if (kind === 3) {
|
|
128
|
+
desc = {
|
|
129
|
+
get: decInfo[3]
|
|
130
|
+
};
|
|
131
|
+
} else if (kind === 4) {
|
|
132
|
+
desc = {
|
|
133
|
+
set: decInfo[3]
|
|
134
|
+
};
|
|
135
|
+
} else {
|
|
136
|
+
desc = {
|
|
137
|
+
value: decInfo[3]
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
} else if (kind !== 0) {
|
|
141
|
+
desc = Object.getOwnPropertyDescriptor(base, name);
|
|
142
|
+
}
|
|
143
|
+
if (kind === 1) {
|
|
144
|
+
value = {
|
|
145
|
+
get: desc.get,
|
|
146
|
+
set: desc.set
|
|
147
|
+
};
|
|
148
|
+
} else if (kind === 2) {
|
|
149
|
+
value = desc.value;
|
|
150
|
+
} else if (kind === 3) {
|
|
151
|
+
value = desc.get;
|
|
152
|
+
} else if (kind === 4) {
|
|
153
|
+
value = desc.set;
|
|
154
|
+
}
|
|
155
|
+
var newValue, get, set;
|
|
156
|
+
if (typeof decs === "function") {
|
|
157
|
+
newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
158
|
+
if (newValue !== void 0) {
|
|
159
|
+
assertValidReturnValue(kind, newValue);
|
|
160
|
+
if (kind === 0) {
|
|
161
|
+
init = newValue;
|
|
162
|
+
} else if (kind === 1) {
|
|
163
|
+
init = newValue.init;
|
|
164
|
+
get = newValue.get || value.get;
|
|
165
|
+
set = newValue.set || value.set;
|
|
166
|
+
value = {
|
|
167
|
+
get: get,
|
|
168
|
+
set: set
|
|
169
|
+
};
|
|
170
|
+
} else {
|
|
171
|
+
value = newValue;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
for(var i = decs.length - 1; i >= 0; i--){
|
|
176
|
+
var dec = decs[i];
|
|
177
|
+
newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
178
|
+
if (newValue !== void 0) {
|
|
179
|
+
assertValidReturnValue(kind, newValue);
|
|
180
|
+
var newInit;
|
|
181
|
+
if (kind === 0) {
|
|
182
|
+
newInit = newValue;
|
|
183
|
+
} else if (kind === 1) {
|
|
184
|
+
newInit = newValue.init;
|
|
185
|
+
get = newValue.get || value.get;
|
|
186
|
+
set = newValue.set || value.set;
|
|
187
|
+
value = {
|
|
188
|
+
get: get,
|
|
189
|
+
set: set
|
|
190
|
+
};
|
|
191
|
+
} else {
|
|
192
|
+
value = newValue;
|
|
193
|
+
}
|
|
194
|
+
if (newInit !== void 0) {
|
|
195
|
+
if (init === void 0) {
|
|
196
|
+
init = newInit;
|
|
197
|
+
} else if (typeof init === "function") {
|
|
198
|
+
init = [
|
|
199
|
+
init,
|
|
200
|
+
newInit
|
|
201
|
+
];
|
|
202
|
+
} else {
|
|
203
|
+
init.push(newInit);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (kind === 0 || kind === 1) {
|
|
210
|
+
if (init === void 0) {
|
|
211
|
+
init = function(instance, init) {
|
|
212
|
+
return init;
|
|
213
|
+
};
|
|
214
|
+
} else if (typeof init !== "function") {
|
|
215
|
+
var ownInitializers = init;
|
|
216
|
+
init = function(instance, init) {
|
|
217
|
+
var value = init;
|
|
218
|
+
for(var i = 0; i < ownInitializers.length; i++){
|
|
219
|
+
value = ownInitializers[i].call(instance, value);
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
};
|
|
223
|
+
} else {
|
|
224
|
+
var originalInitializer = init;
|
|
225
|
+
init = function(instance, init) {
|
|
226
|
+
return originalInitializer.call(instance, init);
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
ret.push(init);
|
|
230
|
+
}
|
|
231
|
+
if (kind !== 0) {
|
|
232
|
+
if (kind === 1) {
|
|
233
|
+
desc.get = value.get;
|
|
234
|
+
desc.set = value.set;
|
|
235
|
+
} else if (kind === 2) {
|
|
236
|
+
desc.value = value;
|
|
237
|
+
} else if (kind === 3) {
|
|
238
|
+
desc.get = value;
|
|
239
|
+
} else if (kind === 4) {
|
|
240
|
+
desc.set = value;
|
|
241
|
+
}
|
|
242
|
+
if (isPrivate) {
|
|
243
|
+
if (kind === 1) {
|
|
244
|
+
ret.push(function(instance, args) {
|
|
245
|
+
return value.get.call(instance, args);
|
|
246
|
+
});
|
|
247
|
+
ret.push(function(instance, args) {
|
|
248
|
+
return value.set.call(instance, args);
|
|
249
|
+
});
|
|
250
|
+
} else if (kind === 2) {
|
|
251
|
+
ret.push(value);
|
|
252
|
+
} else {
|
|
253
|
+
ret.push(function(instance, args) {
|
|
254
|
+
return value.call(instance, args);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
Object.defineProperty(base, name, desc);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function applyMemberDecs(Class, decInfos, metadata) {
|
|
263
|
+
var ret = [];
|
|
264
|
+
var protoInitializers;
|
|
265
|
+
var staticInitializers;
|
|
266
|
+
var existingProtoNonFields = new Map();
|
|
267
|
+
var existingStaticNonFields = new Map();
|
|
268
|
+
for(var i = 0; i < decInfos.length; i++){
|
|
269
|
+
var decInfo = decInfos[i];
|
|
270
|
+
if (!Array.isArray(decInfo)) continue;
|
|
271
|
+
var kind = decInfo[1];
|
|
272
|
+
var name = decInfo[2];
|
|
273
|
+
var isPrivate = decInfo.length > 3;
|
|
274
|
+
var isStatic = kind >= 5;
|
|
275
|
+
var base;
|
|
276
|
+
var initializers;
|
|
277
|
+
if (isStatic) {
|
|
278
|
+
base = Class;
|
|
279
|
+
kind = kind - 5;
|
|
280
|
+
staticInitializers = staticInitializers || [];
|
|
281
|
+
initializers = staticInitializers;
|
|
282
|
+
} else {
|
|
283
|
+
base = Class.prototype;
|
|
284
|
+
protoInitializers = protoInitializers || [];
|
|
285
|
+
initializers = protoInitializers;
|
|
286
|
+
}
|
|
287
|
+
if (kind !== 0 && !isPrivate) {
|
|
288
|
+
var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
|
|
289
|
+
var existingKind = existingNonFields.get(name) || 0;
|
|
290
|
+
if (existingKind === true || existingKind === 3 && kind !== 4 || existingKind === 4 && kind !== 3) {
|
|
291
|
+
throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
|
|
292
|
+
} else if (!existingKind && kind > 2) {
|
|
293
|
+
existingNonFields.set(name, kind);
|
|
294
|
+
} else {
|
|
295
|
+
existingNonFields.set(name, true);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
|
|
299
|
+
}
|
|
300
|
+
pushInitializers(ret, protoInitializers);
|
|
301
|
+
pushInitializers(ret, staticInitializers);
|
|
302
|
+
return ret;
|
|
303
|
+
}
|
|
304
|
+
function pushInitializers(ret, initializers) {
|
|
305
|
+
if (initializers) {
|
|
306
|
+
ret.push(function(instance) {
|
|
307
|
+
for(var i = 0; i < initializers.length; i++){
|
|
308
|
+
initializers[i].call(instance);
|
|
309
|
+
}
|
|
310
|
+
return instance;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function applyClassDecs(targetClass, classDecs, metadata) {
|
|
315
|
+
if (classDecs.length > 0) {
|
|
316
|
+
var initializers = [];
|
|
317
|
+
var newClass = targetClass;
|
|
318
|
+
var name = targetClass.name;
|
|
319
|
+
for(var i = classDecs.length - 1; i >= 0; i--){
|
|
320
|
+
var decoratorFinishedRef = {
|
|
321
|
+
v: false
|
|
322
|
+
};
|
|
323
|
+
try {
|
|
324
|
+
var nextNewClass = classDecs[i](newClass, {
|
|
325
|
+
kind: "class",
|
|
326
|
+
name: name,
|
|
327
|
+
addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
|
|
328
|
+
metadata
|
|
329
|
+
});
|
|
330
|
+
} finally{
|
|
331
|
+
decoratorFinishedRef.v = true;
|
|
332
|
+
}
|
|
333
|
+
if (nextNewClass !== undefined) {
|
|
334
|
+
assertValidReturnValue(10, nextNewClass);
|
|
335
|
+
newClass = nextNewClass;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return [
|
|
339
|
+
defineMetadata(newClass, metadata),
|
|
340
|
+
function() {
|
|
341
|
+
for(var i = 0; i < initializers.length; i++){
|
|
342
|
+
initializers[i].call(newClass);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
];
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function defineMetadata(Class, metadata) {
|
|
349
|
+
return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
|
|
350
|
+
configurable: true,
|
|
351
|
+
enumerable: true,
|
|
352
|
+
value: metadata
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return function applyDecs2203R(targetClass, memberDecs, classDecs, parentClass) {
|
|
356
|
+
if (parentClass !== void 0) {
|
|
357
|
+
var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
|
|
358
|
+
}
|
|
359
|
+
var metadata = Object.create(parentMetadata === void 0 ? null : parentMetadata);
|
|
360
|
+
var e = applyMemberDecs(targetClass, memberDecs, metadata);
|
|
361
|
+
if (!classDecs.length) defineMetadata(targetClass, metadata);
|
|
362
|
+
return {
|
|
363
|
+
e: e,
|
|
364
|
+
get c () {
|
|
365
|
+
return applyClassDecs(targetClass, classDecs, metadata);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
371
|
+
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
6
372
|
}
|
|
7
|
-
|
|
373
|
+
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto;
|
|
374
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
375
|
+
import { randomInt } from '@aztec/foundation/crypto/random';
|
|
376
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
8
377
|
import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
9
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
10
378
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
11
|
-
import {
|
|
379
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
380
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
381
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
382
|
+
import { GasFees } from '@aztec/stdlib/gas';
|
|
383
|
+
import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PClientType, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForClientAndConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
|
|
12
384
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
13
385
|
import { Tx } from '@aztec/stdlib/tx';
|
|
14
|
-
import {
|
|
386
|
+
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
387
|
+
import { Attributes, OtelMetricsAdapter, SpanStatusCode, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
15
388
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
16
389
|
import { createPeerScoreParams, createTopicScoreParams } from '@chainsafe/libp2p-gossipsub/score';
|
|
17
390
|
import { SignaturePolicy } from '@chainsafe/libp2p-gossipsub/types';
|
|
@@ -20,23 +393,56 @@ import { yamux } from '@chainsafe/libp2p-yamux';
|
|
|
20
393
|
import { bootstrap } from '@libp2p/bootstrap';
|
|
21
394
|
import { identify } from '@libp2p/identify';
|
|
22
395
|
import { TopicValidatorResult } from '@libp2p/interface';
|
|
23
|
-
import '@libp2p/kad-dht';
|
|
24
396
|
import { mplex } from '@libp2p/mplex';
|
|
25
397
|
import { tcp } from '@libp2p/tcp';
|
|
398
|
+
import { ENR } from '@nethermindeth/enr';
|
|
26
399
|
import { createLibp2p } from 'libp2p';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
400
|
+
import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
|
|
401
|
+
import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, FishermanAttestationValidator } from '../../msg_validators/index.js';
|
|
402
|
+
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
403
|
+
import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
|
|
404
|
+
import { createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
405
|
+
import { AggregateTxValidator, DataTxValidator, DoubleSpendTxValidator, MetadataTxValidator, TxProofValidator } from '../../msg_validators/tx_validator/index.js';
|
|
29
406
|
import { GossipSubEvent } from '../../types/index.js';
|
|
30
407
|
import { convertToMultiaddr } from '../../util.js';
|
|
408
|
+
import { getVersions } from '../../versioning.js';
|
|
31
409
|
import { AztecDatastore } from '../data_store.js';
|
|
410
|
+
import { DiscV5Service } from '../discv5/discV5_service.js';
|
|
32
411
|
import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
33
412
|
import { gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
34
413
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
35
414
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
36
|
-
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol } from '../reqresp/interface.js';
|
|
415
|
+
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError } from '../reqresp/interface.js';
|
|
416
|
+
import { reqRespBlockTxsHandler } from '../reqresp/protocols/block_txs/block_txs_handler.js';
|
|
37
417
|
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
|
|
38
|
-
import { pingHandler, reqRespBlockHandler,
|
|
418
|
+
import { pingHandler, reqRespBlockHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/protocols/index.js';
|
|
39
419
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
420
|
+
import { P2PInstrumentation } from './instrumentation.js';
|
|
421
|
+
_dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
|
|
422
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber,
|
|
423
|
+
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
424
|
+
[Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then((i)=>i.toString())
|
|
425
|
+
})), _dec1 = trackSpan('Libp2pService.processValidCheckpointProposal', async (checkpoint)=>({
|
|
426
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber,
|
|
427
|
+
[Attributes.BLOCK_ARCHIVE]: checkpoint.archive.toString(),
|
|
428
|
+
[Attributes.P2P_ID]: await checkpoint.p2pMessageLoggingIdentifier().then((i)=>i.toString())
|
|
429
|
+
})), _dec2 = trackSpan('Libp2pService.validateRequestedBlockTxs', (request)=>({
|
|
430
|
+
[Attributes.BLOCK_HASH]: request.blockHash.toString()
|
|
431
|
+
})), _dec3 = trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx)=>({
|
|
432
|
+
[Attributes.TX_HASH]: requestedTxHash.toString()
|
|
433
|
+
})), _dec4 = trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock)=>({
|
|
434
|
+
[Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString()
|
|
435
|
+
})), _dec5 = trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
|
|
436
|
+
[Attributes.TX_HASH]: tx.getTxHash().toString()
|
|
437
|
+
})), _dec6 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
|
|
438
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
|
|
439
|
+
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
440
|
+
[Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
|
|
441
|
+
})), _dec7 = trackSpan('Libp2pService.validateBlockProposal', (_peerId, block)=>({
|
|
442
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber.toString()
|
|
443
|
+
})), _dec8 = trackSpan('Libp2pService.validateCheckpointProposal', (_peerId, checkpoint)=>({
|
|
444
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString()
|
|
445
|
+
}));
|
|
40
446
|
/**
|
|
41
447
|
* Lib P2P implementation of the P2PService interface.
|
|
42
448
|
*/ export class LibP2PService extends WithTracer {
|
|
@@ -44,62 +450,170 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
44
450
|
config;
|
|
45
451
|
node;
|
|
46
452
|
peerDiscoveryService;
|
|
453
|
+
reqresp;
|
|
454
|
+
peerManager;
|
|
47
455
|
mempools;
|
|
48
|
-
|
|
456
|
+
archiver;
|
|
457
|
+
epochCache;
|
|
49
458
|
proofVerifier;
|
|
50
459
|
worldStateSynchronizer;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
460
|
+
static{
|
|
461
|
+
({ e: [_initProto] } = _apply_decs_2203_r(this, [
|
|
462
|
+
[
|
|
463
|
+
_dec,
|
|
464
|
+
2,
|
|
465
|
+
"processValidBlockProposal"
|
|
466
|
+
],
|
|
467
|
+
[
|
|
468
|
+
_dec1,
|
|
469
|
+
2,
|
|
470
|
+
"processValidCheckpointProposal"
|
|
471
|
+
],
|
|
472
|
+
[
|
|
473
|
+
_dec2,
|
|
474
|
+
2,
|
|
475
|
+
"validateRequestedBlockTxs"
|
|
476
|
+
],
|
|
477
|
+
[
|
|
478
|
+
_dec3,
|
|
479
|
+
2,
|
|
480
|
+
"validateRequestedTxs"
|
|
481
|
+
],
|
|
482
|
+
[
|
|
483
|
+
_dec4,
|
|
484
|
+
2,
|
|
485
|
+
"validateRequestedBlock"
|
|
486
|
+
],
|
|
487
|
+
[
|
|
488
|
+
_dec5,
|
|
489
|
+
2,
|
|
490
|
+
"validatePropagatedTx"
|
|
491
|
+
],
|
|
492
|
+
[
|
|
493
|
+
_dec6,
|
|
494
|
+
2,
|
|
495
|
+
"validateCheckpointAttestation"
|
|
496
|
+
],
|
|
497
|
+
[
|
|
498
|
+
_dec7,
|
|
499
|
+
2,
|
|
500
|
+
"validateBlockProposal"
|
|
501
|
+
],
|
|
502
|
+
[
|
|
503
|
+
_dec8,
|
|
504
|
+
2,
|
|
505
|
+
"validateCheckpointProposal"
|
|
506
|
+
]
|
|
507
|
+
], []));
|
|
508
|
+
}
|
|
54
509
|
discoveryRunningPromise;
|
|
510
|
+
msgIdSeenValidators;
|
|
55
511
|
// Message validators
|
|
56
|
-
attestationValidator;
|
|
57
512
|
blockProposalValidator;
|
|
58
|
-
|
|
59
|
-
|
|
513
|
+
checkpointProposalValidator;
|
|
514
|
+
checkpointAttestationValidator;
|
|
515
|
+
protocolVersion;
|
|
516
|
+
topicStrings;
|
|
517
|
+
feesCache;
|
|
60
518
|
/**
|
|
61
519
|
* Callback for when a block is received from a peer.
|
|
62
520
|
* @param block - The block received from the peer.
|
|
63
521
|
* @returns The attestation for the block, if any.
|
|
64
522
|
*/ blockReceivedCallback;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
523
|
+
/**
|
|
524
|
+
* Callback for when a checkpoint proposal is received from a peer.
|
|
525
|
+
* @param checkpoint - The checkpoint proposal received from the peer.
|
|
526
|
+
* @returns The attestations for the checkpoint, if any.
|
|
527
|
+
*/ checkpointReceivedCallback;
|
|
528
|
+
gossipSubEventHandler;
|
|
529
|
+
instrumentation;
|
|
530
|
+
telemetry;
|
|
531
|
+
logger;
|
|
532
|
+
constructor(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
|
|
533
|
+
super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.msgIdSeenValidators = (_initProto(this), {}), this.protocolVersion = '', this.topicStrings = {};
|
|
534
|
+
this.telemetry = telemetry;
|
|
535
|
+
// Create child logger with fisherman prefix if in fisherman mode
|
|
536
|
+
this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
|
|
537
|
+
this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
|
|
538
|
+
this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
539
|
+
this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
540
|
+
this.msgIdSeenValidators[TopicType.checkpoint_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
541
|
+
this.msgIdSeenValidators[TopicType.checkpoint_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
542
|
+
const versions = getVersions(config);
|
|
543
|
+
this.protocolVersion = compressComponentVersions(versions);
|
|
544
|
+
logger.info(`Started libp2p service with protocol version ${this.protocolVersion}`);
|
|
545
|
+
this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
|
|
546
|
+
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
547
|
+
this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
|
|
548
|
+
this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
|
|
549
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, {
|
|
550
|
+
txsPermitted: !config.disableTransactions
|
|
551
|
+
});
|
|
552
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
|
|
553
|
+
txsPermitted: !config.disableTransactions
|
|
554
|
+
});
|
|
555
|
+
this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new CheckpointAttestationValidator(epochCache);
|
|
556
|
+
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
77
557
|
this.blockReceivedCallback = async (block)=>{
|
|
78
|
-
this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber
|
|
79
|
-
p2pMessageIdentifier: await block.
|
|
558
|
+
this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`, {
|
|
559
|
+
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier()
|
|
80
560
|
});
|
|
81
|
-
return
|
|
561
|
+
return false;
|
|
562
|
+
};
|
|
563
|
+
this.checkpointReceivedCallback = (checkpoint)=>{
|
|
564
|
+
this.logger.debug(`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`);
|
|
565
|
+
return Promise.resolve(undefined);
|
|
82
566
|
};
|
|
83
567
|
}
|
|
568
|
+
updateConfig(config) {
|
|
569
|
+
this.reqresp.updateConfig(config);
|
|
570
|
+
}
|
|
84
571
|
/**
|
|
85
572
|
* Creates an instance of the LibP2P service.
|
|
86
573
|
* @param config - The configuration to use when creating the service.
|
|
87
574
|
* @param txPool - The transaction pool to be accessed by the service.
|
|
88
575
|
* @returns The new service.
|
|
89
|
-
*/ static async new(clientType, config,
|
|
90
|
-
const {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
const datastore = new AztecDatastore(store);
|
|
576
|
+
*/ static async new(clientType, config, peerId, deps) {
|
|
577
|
+
const { worldStateSynchronizer, epochCache, l2BlockSource, mempools, proofVerifier, peerStore, telemetry, logger, packageVersion } = deps;
|
|
578
|
+
const { p2pPort, maxPeerCount, listenAddress } = config;
|
|
579
|
+
const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
|
|
580
|
+
const datastore = new AztecDatastore(peerStore);
|
|
95
581
|
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry);
|
|
96
|
-
|
|
582
|
+
const peerDiscoveryService = new DiscV5Service(peerId, config, packageVersion, telemetry, createLogger(`${logger.module}:discv5_service`));
|
|
583
|
+
// Seed libp2p's bootstrap discovery with private and trusted peers
|
|
584
|
+
const bootstrapNodes = [
|
|
585
|
+
...config.privatePeers,
|
|
586
|
+
...config.trustedPeers
|
|
587
|
+
];
|
|
97
588
|
const peerDiscovery = [];
|
|
98
|
-
if (
|
|
589
|
+
if (bootstrapNodes.length > 0) {
|
|
99
590
|
peerDiscovery.push(bootstrap({
|
|
100
|
-
list:
|
|
591
|
+
list: bootstrapNodes
|
|
101
592
|
}));
|
|
102
593
|
}
|
|
594
|
+
const versions = getVersions(config);
|
|
595
|
+
const protocolVersion = compressComponentVersions(versions);
|
|
596
|
+
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
597
|
+
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
598
|
+
const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
|
|
599
|
+
const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
|
|
600
|
+
const preferredPeersEnrs = config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
601
|
+
const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
|
|
602
|
+
const peerId = await enr.peerId();
|
|
603
|
+
const address = enr.getLocationMultiaddr('tcp');
|
|
604
|
+
if (address === undefined) {
|
|
605
|
+
throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
|
|
606
|
+
}
|
|
607
|
+
return {
|
|
608
|
+
id: peerId,
|
|
609
|
+
addrs: [
|
|
610
|
+
address
|
|
611
|
+
]
|
|
612
|
+
};
|
|
613
|
+
}))).filter((peer)=>peer !== undefined);
|
|
614
|
+
const announceTcpMultiaddr = config.p2pIp ? [
|
|
615
|
+
convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')
|
|
616
|
+
] : [];
|
|
103
617
|
const node = await createLibp2p({
|
|
104
618
|
start: false,
|
|
105
619
|
peerId,
|
|
@@ -107,44 +621,76 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
107
621
|
listen: [
|
|
108
622
|
bindAddrTcp
|
|
109
623
|
],
|
|
110
|
-
announce:
|
|
111
|
-
announceAddrTcp
|
|
112
|
-
]
|
|
624
|
+
announce: announceTcpMultiaddr
|
|
113
625
|
},
|
|
114
626
|
transports: [
|
|
115
627
|
tcp({
|
|
116
|
-
|
|
628
|
+
// It's better to have this number a bit higher than our maxPeerCount because it's sets the limit on transport (TCP) layer
|
|
629
|
+
// The connection attempts to the node on TCP layer are not necessarily valid Aztec peers so we want to have a bit of leeway here
|
|
630
|
+
// If we hit the limit, the connection will be temporarily accepted and immediately dropped.
|
|
631
|
+
// Docs: https://nodejs.org/api/net.html#servermaxconnections
|
|
632
|
+
maxConnections: maxPeerCount * 2,
|
|
117
633
|
// socket option: the maximum length of the queue of pending connections
|
|
118
|
-
// https://nodejs.org/dist/latest-
|
|
634
|
+
// https://nodejs.org/dist/latest-v22.x/docs/api/net.html#serverlisten
|
|
119
635
|
// it's not safe if we increase this number
|
|
120
636
|
backlog: 5,
|
|
121
637
|
closeServerOnMaxConnections: {
|
|
122
|
-
|
|
123
|
-
|
|
638
|
+
// The property `maxConnections` will protect us against the most DDOS attack
|
|
639
|
+
// This property protects us in case of burst of new connections where server is not able to close them quickly enough
|
|
640
|
+
// In case closeAbove is reached, the server stops listening altogether
|
|
641
|
+
// It's important that there is enough difference between closeAbove and listenAbove,
|
|
642
|
+
// otherwise the server.listener will flap between being closed and open potentially degrading perf even more
|
|
643
|
+
closeAbove: maxPeerCount * 3,
|
|
644
|
+
listenBelow: Math.floor(maxPeerCount * 0.9)
|
|
124
645
|
}
|
|
125
646
|
})
|
|
126
647
|
],
|
|
127
648
|
datastore,
|
|
128
649
|
peerDiscovery,
|
|
129
650
|
streamMuxers: [
|
|
130
|
-
|
|
131
|
-
|
|
651
|
+
yamux(),
|
|
652
|
+
mplex()
|
|
132
653
|
],
|
|
133
654
|
connectionEncryption: [
|
|
134
655
|
noise()
|
|
135
656
|
],
|
|
136
657
|
connectionManager: {
|
|
137
658
|
minConnections: 0,
|
|
659
|
+
// We set maxConnections above maxPeerCount because if we hit limit of maxPeerCount
|
|
660
|
+
// libp2p will start aggressively rejecting all new connections, preventing network discovery and crawling.
|
|
661
|
+
maxConnections: maxPeerCount * 2,
|
|
138
662
|
maxParallelDials: 100,
|
|
139
663
|
dialTimeout: 30_000,
|
|
140
664
|
maxPeerAddrsToDial: 5,
|
|
141
665
|
maxIncomingPendingConnections: 5
|
|
142
666
|
},
|
|
667
|
+
connectionGater: {
|
|
668
|
+
denyInboundConnection: (maConn)=>{
|
|
669
|
+
const allowed = peerManager.isNodeAllowedToConnect(maConn.remoteAddr.nodeAddress().address);
|
|
670
|
+
if (allowed) {
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
logger.debug(`Connection gater: Denying inbound connection from ${maConn.remoteAddr.toString()}`);
|
|
674
|
+
return true;
|
|
675
|
+
},
|
|
676
|
+
denyInboundEncryptedConnection: (peerId, _maConn)=>{
|
|
677
|
+
//NOTE: it is not necessary to check address here because this was already done by
|
|
678
|
+
// denyInboundConnection
|
|
679
|
+
const allowed = peerManager.isNodeAllowedToConnect(peerId);
|
|
680
|
+
if (allowed) {
|
|
681
|
+
return false;
|
|
682
|
+
}
|
|
683
|
+
logger.debug(`Connection gater: Denying inbound encrypted connection from ${peerId.toString()}`);
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
},
|
|
143
687
|
services: {
|
|
144
688
|
identify: identify({
|
|
145
|
-
protocolPrefix: 'aztec'
|
|
689
|
+
protocolPrefix: 'aztec',
|
|
690
|
+
runOnConnectionOpen: true
|
|
146
691
|
}),
|
|
147
692
|
pubsub: gossipsub({
|
|
693
|
+
directPeers,
|
|
148
694
|
debugName: 'gossipsub',
|
|
149
695
|
globalSignaturePolicy: SignaturePolicy.StrictNoSign,
|
|
150
696
|
allowPublishToZeroTopicPeers: true,
|
|
@@ -156,29 +702,35 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
156
702
|
heartbeatInterval: config.gossipsubInterval,
|
|
157
703
|
mcacheLength: config.gossipsubMcacheLength,
|
|
158
704
|
mcacheGossip: config.gossipsubMcacheGossip,
|
|
705
|
+
seenTTL: config.gossipsubSeenTTL,
|
|
159
706
|
msgIdFn: getMsgIdFn,
|
|
160
707
|
msgIdToStrFn: msgIdToStrFn,
|
|
161
708
|
fastMsgIdFn: fastMsgIdFn,
|
|
162
709
|
dataTransform: new SnappyTransform(),
|
|
163
710
|
metricsRegister: otelMetricsAdapter,
|
|
164
|
-
metricsTopicStrToLabel: metricsTopicStrToLabels(),
|
|
711
|
+
metricsTopicStrToLabel: metricsTopicStrToLabels(protocolVersion),
|
|
165
712
|
asyncValidation: true,
|
|
166
713
|
scoreThresholds: gossipScoreThresholds,
|
|
167
714
|
scoreParams: createPeerScoreParams({
|
|
168
715
|
// IPColocation factor can be disabled for local testing - default to -5
|
|
169
716
|
IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
|
|
170
717
|
topics: {
|
|
171
|
-
[
|
|
718
|
+
[txTopic]: createTopicScoreParams({
|
|
172
719
|
topicWeight: 1,
|
|
173
720
|
invalidMessageDeliveriesWeight: -20,
|
|
174
721
|
invalidMessageDeliveriesDecay: 0.5
|
|
175
722
|
}),
|
|
176
|
-
[
|
|
723
|
+
[blockProposalTopic]: createTopicScoreParams({
|
|
177
724
|
topicWeight: 1,
|
|
178
725
|
invalidMessageDeliveriesWeight: -20,
|
|
179
726
|
invalidMessageDeliveriesDecay: 0.5
|
|
180
727
|
}),
|
|
181
|
-
[
|
|
728
|
+
[checkpointProposalTopic]: createTopicScoreParams({
|
|
729
|
+
topicWeight: 1,
|
|
730
|
+
invalidMessageDeliveriesWeight: -20,
|
|
731
|
+
invalidMessageDeliveriesDecay: 0.5
|
|
732
|
+
}),
|
|
733
|
+
[checkpointAttestationTopic]: createTopicScoreParams({
|
|
182
734
|
topicWeight: 1,
|
|
183
735
|
invalidMessageDeliveriesWeight: -20,
|
|
184
736
|
invalidMessageDeliveriesDecay: 0.5
|
|
@@ -192,7 +744,13 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
192
744
|
},
|
|
193
745
|
logger: createLibp2pComponentLogger(logger.module)
|
|
194
746
|
});
|
|
195
|
-
|
|
747
|
+
const peerScoring = new PeerScoring(config, telemetry);
|
|
748
|
+
const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
|
|
749
|
+
const peerManager = new PeerManager(node, peerDiscoveryService, config, telemetry, createLogger(`${logger.module}:peer_manager`), peerScoring, reqresp, worldStateSynchronizer, protocolVersion, epochCache);
|
|
750
|
+
// Update gossipsub score params
|
|
751
|
+
node.services.pubsub.score.params.appSpecificWeight = 10;
|
|
752
|
+
node.services.pubsub.score.params.appSpecificScore = (peerId)=>peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
753
|
+
return new LibP2PService(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
|
|
196
754
|
}
|
|
197
755
|
/**
|
|
198
756
|
* Starts the LibP2P service.
|
|
@@ -203,44 +761,56 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
203
761
|
throw new Error('P2P service already started');
|
|
204
762
|
}
|
|
205
763
|
// Get listen & announce addresses for logging
|
|
206
|
-
const {
|
|
207
|
-
if (!
|
|
764
|
+
const { p2pIp, p2pPort } = this.config;
|
|
765
|
+
if (!p2pIp) {
|
|
208
766
|
throw new Error('Announce address not provided.');
|
|
209
767
|
}
|
|
210
|
-
const announceTcpMultiaddr = convertToMultiaddr(
|
|
211
|
-
// Start job queue, peer discovery service and libp2p node
|
|
212
|
-
this.jobQueue.start();
|
|
213
|
-
await this.peerDiscoveryService.start();
|
|
214
|
-
await this.node.start();
|
|
215
|
-
// Subscribe to standard GossipSub topics by default
|
|
216
|
-
for (const topic of getTopicTypeForClientType(this.clientType)){
|
|
217
|
-
this.subscribeToTopic(TopicTypeMap[topic].p2pTopic);
|
|
218
|
-
}
|
|
768
|
+
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
219
769
|
// Create request response protocol handlers
|
|
220
770
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
221
771
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
222
|
-
const blockHandler = reqRespBlockHandler(this.
|
|
772
|
+
const blockHandler = reqRespBlockHandler(this.archiver);
|
|
773
|
+
const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
|
|
223
774
|
const requestResponseHandlers = {
|
|
224
775
|
[ReqRespSubProtocol.PING]: pingHandler,
|
|
225
|
-
[ReqRespSubProtocol.STATUS]: statusHandler,
|
|
226
|
-
[ReqRespSubProtocol.TX]: txHandler.bind(this),
|
|
776
|
+
[ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
|
|
227
777
|
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
228
778
|
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this)
|
|
229
779
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
this.
|
|
780
|
+
if (!this.config.disableTransactions) {
|
|
781
|
+
const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
|
|
782
|
+
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
783
|
+
}
|
|
784
|
+
if (!this.config.disableTransactions) {
|
|
785
|
+
requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this);
|
|
786
|
+
}
|
|
235
787
|
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
236
788
|
const reqrespSubProtocolValidators = {
|
|
237
789
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
238
|
-
|
|
239
|
-
[ReqRespSubProtocol.
|
|
790
|
+
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
791
|
+
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
792
|
+
[ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this)
|
|
240
793
|
};
|
|
794
|
+
await this.peerManager.initializePeers();
|
|
241
795
|
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
796
|
+
await this.node.start();
|
|
797
|
+
// Subscribe to standard GossipSub topics by default
|
|
798
|
+
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
|
|
799
|
+
this.subscribeToTopic(this.topicStrings[topic]);
|
|
800
|
+
}
|
|
801
|
+
// add GossipSub listener
|
|
802
|
+
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
803
|
+
// Start running promise for peer discovery and metrics collection
|
|
804
|
+
if (!this.config.p2pDiscoveryDisabled) {
|
|
805
|
+
await this.peerDiscoveryService.start();
|
|
806
|
+
}
|
|
807
|
+
this.discoveryRunningPromise = new RunningPromise(async ()=>{
|
|
808
|
+
await this.peerManager.heartbeat();
|
|
809
|
+
}, this.logger, this.config.peerCheckIntervalMS);
|
|
810
|
+
this.discoveryRunningPromise.start();
|
|
242
811
|
this.logger.info(`Started P2P service`, {
|
|
243
|
-
listen:
|
|
812
|
+
listen: this.config.listenAddress,
|
|
813
|
+
port: this.config.p2pPort,
|
|
244
814
|
announce: announceTcpMultiaddr,
|
|
245
815
|
peerId: this.node.peerId.toString()
|
|
246
816
|
});
|
|
@@ -250,12 +820,10 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
250
820
|
* @returns An empty promise.
|
|
251
821
|
*/ async stop() {
|
|
252
822
|
// Remove gossip sub listener
|
|
253
|
-
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.
|
|
823
|
+
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
254
824
|
// Stop peer manager
|
|
255
825
|
this.logger.debug('Stopping peer manager...');
|
|
256
826
|
await this.peerManager.stop();
|
|
257
|
-
this.logger.debug('Stopping job queue...');
|
|
258
|
-
await this.jobQueue.end();
|
|
259
827
|
this.logger.debug('Stopping running promise...');
|
|
260
828
|
await this.discoveryRunningPromise?.stop();
|
|
261
829
|
this.logger.debug('Stopping peer discovery service...');
|
|
@@ -266,6 +834,12 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
266
834
|
await this.stopLibP2P();
|
|
267
835
|
this.logger.info('LibP2P service stopped');
|
|
268
836
|
}
|
|
837
|
+
addReqRespSubProtocol(subProtocol, handler, validator) {
|
|
838
|
+
return this.reqresp.addSubProtocol(subProtocol, handler, validator);
|
|
839
|
+
}
|
|
840
|
+
registerThisValidatorAddresses(address) {
|
|
841
|
+
this.peerManager.registerThisValidatorAddresses(address);
|
|
842
|
+
}
|
|
269
843
|
getPeers(includePending) {
|
|
270
844
|
return this.peerManager.getPeers(includePending);
|
|
271
845
|
}
|
|
@@ -281,24 +855,12 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
281
855
|
setImmediate(()=>void safeJob());
|
|
282
856
|
}
|
|
283
857
|
/**
|
|
284
|
-
* Send Request via the ReqResp service
|
|
285
|
-
* The subprotocol defined will determine the request and response types
|
|
286
|
-
*
|
|
287
|
-
* See the subProtocolMap for the mapping of subprotocols to request/response types in `interface.ts`
|
|
288
|
-
*
|
|
289
|
-
* @param protocol The request response protocol to use
|
|
290
|
-
* @param request The request type to send
|
|
291
|
-
* @returns
|
|
292
|
-
*/ sendRequest(protocol, request) {
|
|
293
|
-
return this.reqresp.sendRequest(protocol, request);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
858
|
* Send a batch of requests to peers, and return the responses
|
|
297
859
|
* @param protocol - The request response protocol to use
|
|
298
860
|
* @param requests - The requests to send to the peers
|
|
299
861
|
* @returns The responses to the requests
|
|
300
|
-
*/ sendBatchRequest(protocol, requests) {
|
|
301
|
-
return this.reqresp.sendBatchRequest(protocol, requests);
|
|
862
|
+
*/ sendBatchRequest(protocol, requests, pinnedPeerId) {
|
|
863
|
+
return this.reqresp.sendBatchRequest(protocol, requests, pinnedPeerId);
|
|
302
864
|
}
|
|
303
865
|
/**
|
|
304
866
|
* Get the ENR of the node
|
|
@@ -308,7 +870,9 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
308
870
|
}
|
|
309
871
|
registerBlockReceivedCallback(callback) {
|
|
310
872
|
this.blockReceivedCallback = callback;
|
|
311
|
-
|
|
873
|
+
}
|
|
874
|
+
registerCheckpointReceivedCallback(callback) {
|
|
875
|
+
this.checkpointReceivedCallback = callback;
|
|
312
876
|
}
|
|
313
877
|
/**
|
|
314
878
|
* Subscribes to a topic.
|
|
@@ -322,235 +886,694 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
322
886
|
/**
|
|
323
887
|
* Publishes data to a topic.
|
|
324
888
|
* @param topic - The topic to publish to.
|
|
325
|
-
* @param data - The
|
|
889
|
+
* @param data - The message to publish.
|
|
326
890
|
* @returns The number of recipients the data was sent to.
|
|
327
|
-
*/ async publishToTopic(topic,
|
|
891
|
+
*/ async publishToTopic(topic, message) {
|
|
328
892
|
if (!this.node.services.pubsub) {
|
|
329
893
|
throw new Error('Pubsub service not available.');
|
|
330
894
|
}
|
|
331
|
-
const
|
|
895
|
+
const isBlockProposal = topic === this.topicStrings[TopicType.block_proposal];
|
|
896
|
+
const traceContext = this.config.debugP2PInstrumentMessages && isBlockProposal ? this.telemetry.getTraceContext() : undefined;
|
|
897
|
+
const p2pMessage = P2PMessage.fromGossipable(message, this.config.debugP2PInstrumentMessages, traceContext);
|
|
898
|
+
const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
|
|
332
899
|
return result.recipients.length;
|
|
333
900
|
}
|
|
334
901
|
/**
|
|
902
|
+
* Checks if this message has already been seen, based on its msgId computed from hashing the message data.
|
|
903
|
+
* Note that we do not rely on the seenCache from gossipsub since we want to keep a longer history of seen
|
|
904
|
+
* messages to avoid tx echoes across the network.
|
|
905
|
+
*/ preValidateReceivedMessage(msg, msgId, source) {
|
|
906
|
+
let topicType;
|
|
907
|
+
switch(msg.topic){
|
|
908
|
+
case this.topicStrings[TopicType.tx]:
|
|
909
|
+
topicType = TopicType.tx;
|
|
910
|
+
break;
|
|
911
|
+
case this.topicStrings[TopicType.block_proposal]:
|
|
912
|
+
topicType = TopicType.block_proposal;
|
|
913
|
+
break;
|
|
914
|
+
case this.topicStrings[TopicType.checkpoint_proposal]:
|
|
915
|
+
topicType = TopicType.checkpoint_proposal;
|
|
916
|
+
break;
|
|
917
|
+
case this.topicStrings[TopicType.checkpoint_attestation]:
|
|
918
|
+
topicType = TopicType.checkpoint_attestation;
|
|
919
|
+
break;
|
|
920
|
+
default:
|
|
921
|
+
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
922
|
+
break;
|
|
923
|
+
}
|
|
924
|
+
const validator = topicType ? this.msgIdSeenValidators[topicType] : undefined;
|
|
925
|
+
if (!validator || !validator.addMessage(msgId)) {
|
|
926
|
+
this.instrumentation.incMessagePrevalidationStatus(false, topicType);
|
|
927
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
928
|
+
return {
|
|
929
|
+
result: false,
|
|
930
|
+
topicType
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
this.instrumentation.incMessagePrevalidationStatus(true, topicType);
|
|
934
|
+
return {
|
|
935
|
+
result: true,
|
|
936
|
+
topicType
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
/**
|
|
940
|
+
* Safely deserializes a P2PMessage from raw message data.
|
|
941
|
+
* @param msgId - The message ID.
|
|
942
|
+
* @param source - The peer ID of the message source.
|
|
943
|
+
* @param data - The raw message data.
|
|
944
|
+
* @returns The deserialized P2PMessage or undefined if deserialization fails.
|
|
945
|
+
*/ safelyDeserializeP2PMessage(msgId, source, data) {
|
|
946
|
+
try {
|
|
947
|
+
return P2PMessage.fromMessageData(Buffer.from(data), this.config.debugP2PInstrumentMessages);
|
|
948
|
+
} catch (err) {
|
|
949
|
+
this.logger.error(`Error deserializing P2PMessage`, err, {
|
|
950
|
+
msgId,
|
|
951
|
+
source: source.toString()
|
|
952
|
+
});
|
|
953
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Reject);
|
|
954
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
955
|
+
return undefined;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
335
959
|
* Handles a new gossip message that was received by the client.
|
|
336
960
|
* @param topic - The message's topic.
|
|
337
961
|
* @param data - The message data
|
|
338
962
|
*/ async handleNewGossipMessage(msg, msgId, source) {
|
|
339
|
-
|
|
340
|
-
|
|
963
|
+
const msgReceivedTime = Date.now();
|
|
964
|
+
let topicType;
|
|
965
|
+
const p2pMessage = this.safelyDeserializeP2PMessage(msgId, source, msg.data);
|
|
966
|
+
if (!p2pMessage) {
|
|
967
|
+
return;
|
|
341
968
|
}
|
|
342
|
-
|
|
343
|
-
|
|
969
|
+
const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
|
|
970
|
+
if (!preValidationResult.result) {
|
|
971
|
+
return;
|
|
344
972
|
}
|
|
345
|
-
|
|
346
|
-
|
|
973
|
+
// Determine topic type for attributes
|
|
974
|
+
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
975
|
+
topicType = TopicType.tx;
|
|
976
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
977
|
+
topicType = TopicType.checkpoint_attestation;
|
|
978
|
+
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
979
|
+
topicType = TopicType.block_proposal;
|
|
980
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
981
|
+
topicType = TopicType.checkpoint_proposal;
|
|
982
|
+
}
|
|
983
|
+
// Process the message, optionally within a linked span for trace propagation
|
|
984
|
+
const processMessage = async ()=>{
|
|
985
|
+
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
986
|
+
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
987
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
|
|
988
|
+
if (this.clientType === P2PClientType.Full) {
|
|
989
|
+
await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
990
|
+
}
|
|
991
|
+
} else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
992
|
+
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
993
|
+
} else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
|
|
994
|
+
await this.handleGossipedCheckpointProposal(p2pMessage.payload, msgId, source);
|
|
995
|
+
} else {
|
|
996
|
+
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
const latency = p2pMessage.timestamp !== undefined ? msgReceivedTime - p2pMessage.timestamp.getTime() : undefined;
|
|
1000
|
+
const propagatedContext = p2pMessage.traceContext ? this.telemetry.extractPropagatedContext(p2pMessage.traceContext) : undefined;
|
|
1001
|
+
if (propagatedContext) {
|
|
1002
|
+
await this.tracer.startActiveSpan('LibP2PService.processMessage', {
|
|
1003
|
+
attributes: {
|
|
1004
|
+
[Attributes.TOPIC_NAME]: topicType,
|
|
1005
|
+
[Attributes.PEER_ID]: source.toString()
|
|
1006
|
+
}
|
|
1007
|
+
}, propagatedContext, async (span)=>{
|
|
1008
|
+
try {
|
|
1009
|
+
await processMessage();
|
|
1010
|
+
span.setStatus({
|
|
1011
|
+
code: SpanStatusCode.OK
|
|
1012
|
+
});
|
|
1013
|
+
} catch (err) {
|
|
1014
|
+
span.setStatus({
|
|
1015
|
+
code: SpanStatusCode.ERROR,
|
|
1016
|
+
message: String(err)
|
|
1017
|
+
});
|
|
1018
|
+
if (typeof err === 'string' || err && err instanceof Error) {
|
|
1019
|
+
span.recordException(err);
|
|
1020
|
+
}
|
|
1021
|
+
throw err;
|
|
1022
|
+
} finally{
|
|
1023
|
+
span.end();
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
} else {
|
|
1027
|
+
await processMessage();
|
|
1028
|
+
}
|
|
1029
|
+
if (latency !== undefined && topicType !== undefined) {
|
|
1030
|
+
this.instrumentation.recordMessageLatency(topicType, latency);
|
|
347
1031
|
}
|
|
348
1032
|
return;
|
|
349
1033
|
}
|
|
350
|
-
async validateReceivedMessage(validationFunc, msgId, source) {
|
|
1034
|
+
async validateReceivedMessage(validationFunc, msgId, source, topicType) {
|
|
351
1035
|
let resultAndObj = {
|
|
352
|
-
result:
|
|
353
|
-
obj: undefined
|
|
1036
|
+
result: TopicValidatorResult.Reject
|
|
354
1037
|
};
|
|
1038
|
+
const timer = new Timer();
|
|
355
1039
|
try {
|
|
356
1040
|
resultAndObj = await validationFunc();
|
|
357
1041
|
} catch (err) {
|
|
358
|
-
this.
|
|
1042
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.LowToleranceError);
|
|
1043
|
+
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
1044
|
+
msgId,
|
|
1045
|
+
source: source.toString(),
|
|
1046
|
+
topicType
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
1050
|
+
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
359
1051
|
}
|
|
360
|
-
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result
|
|
1052
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
361
1053
|
return resultAndObj;
|
|
362
1054
|
}
|
|
363
|
-
async handleGossipedTx(
|
|
1055
|
+
async handleGossipedTx(payloadData, msgId, source) {
|
|
364
1056
|
const validationFunc = async ()=>{
|
|
365
|
-
const tx = Tx.fromBuffer(
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
1057
|
+
const tx = Tx.fromBuffer(payloadData);
|
|
1058
|
+
const isValid = await this.validatePropagatedTx(tx, source);
|
|
1059
|
+
const exists = isValid && await this.mempools.txPool.hasTx(tx.getTxHash());
|
|
1060
|
+
this.logger.trace(`Validate propagated tx`, {
|
|
1061
|
+
isValid,
|
|
1062
|
+
exists,
|
|
1063
|
+
[Attributes.P2P_ID]: source.toString()
|
|
1064
|
+
});
|
|
1065
|
+
if (!isValid) {
|
|
1066
|
+
return {
|
|
1067
|
+
result: TopicValidatorResult.Reject
|
|
1068
|
+
};
|
|
1069
|
+
} else if (exists) {
|
|
1070
|
+
return {
|
|
1071
|
+
result: TopicValidatorResult.Ignore,
|
|
1072
|
+
obj: tx
|
|
1073
|
+
};
|
|
1074
|
+
} else {
|
|
1075
|
+
return {
|
|
1076
|
+
result: TopicValidatorResult.Accept,
|
|
1077
|
+
obj: tx
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
371
1080
|
};
|
|
372
|
-
const { result, obj: tx } = await this.validateReceivedMessage(validationFunc, msgId, source);
|
|
373
|
-
if (
|
|
1081
|
+
const { result, obj: tx } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.tx);
|
|
1082
|
+
if (result !== TopicValidatorResult.Accept || !tx) {
|
|
374
1083
|
return;
|
|
375
1084
|
}
|
|
376
|
-
const txHash =
|
|
1085
|
+
const txHash = tx.getTxHash();
|
|
377
1086
|
const txHashString = txHash.toString();
|
|
378
|
-
this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()}
|
|
1087
|
+
this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
|
|
1088
|
+
source: source.toString(),
|
|
1089
|
+
txHash: txHashString
|
|
1090
|
+
});
|
|
1091
|
+
if (this.config.dropTransactions && randomInt(1000) < this.config.dropTransactionsProbability * 1000) {
|
|
1092
|
+
this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
this.instrumentation.incrementTxReceived(1);
|
|
379
1096
|
await this.mempools.txPool.addTxs([
|
|
380
1097
|
tx
|
|
381
1098
|
]);
|
|
382
1099
|
}
|
|
383
|
-
/**
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
|
|
387
|
-
*/ async processAttestationFromPeer(msg, msgId, source) {
|
|
1100
|
+
/**
|
|
1101
|
+
* Process a checkpoint attestation from a peer.
|
|
1102
|
+
* Validates the attestation and adds it to the pool.
|
|
1103
|
+
*/ async processCheckpointAttestationFromPeer(payloadData, msgId, source) {
|
|
388
1104
|
const validationFunc = async ()=>{
|
|
389
|
-
const attestation =
|
|
390
|
-
const
|
|
391
|
-
this.
|
|
392
|
-
|
|
1105
|
+
const attestation = CheckpointAttestation.fromBuffer(payloadData);
|
|
1106
|
+
const pool = this.mempools.attestationPool;
|
|
1107
|
+
const isValid = await this.validateCheckpointAttestation(source, attestation);
|
|
1108
|
+
const exists = isValid && await pool.hasCheckpointAttestation(attestation);
|
|
1109
|
+
let canAdd = true;
|
|
1110
|
+
if (isValid && !exists) {
|
|
1111
|
+
const slot = attestation.payload.header.slotNumber;
|
|
1112
|
+
const { committee } = await this.epochCache.getCommittee(slot);
|
|
1113
|
+
const committeeSize = committee?.length ?? 0;
|
|
1114
|
+
canAdd = await pool.canAddCheckpointAttestation(attestation, committeeSize);
|
|
1115
|
+
}
|
|
1116
|
+
this.logger.trace(`Validate propagated checkpoint attestation`, {
|
|
1117
|
+
isValid,
|
|
1118
|
+
exists,
|
|
1119
|
+
canAdd,
|
|
1120
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
393
1121
|
[Attributes.P2P_ID]: source.toString()
|
|
394
1122
|
});
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
1123
|
+
if (!isValid) {
|
|
1124
|
+
return {
|
|
1125
|
+
result: TopicValidatorResult.Reject
|
|
1126
|
+
};
|
|
1127
|
+
} else if (exists) {
|
|
1128
|
+
return {
|
|
1129
|
+
result: TopicValidatorResult.Ignore,
|
|
1130
|
+
obj: attestation
|
|
1131
|
+
};
|
|
1132
|
+
} else if (!canAdd) {
|
|
1133
|
+
this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
|
|
1134
|
+
slot: attestation.payload.header.slotNumber.toString(),
|
|
1135
|
+
archive: attestation.archive.toString(),
|
|
1136
|
+
source: source.toString()
|
|
1137
|
+
});
|
|
1138
|
+
return {
|
|
1139
|
+
result: TopicValidatorResult.Ignore,
|
|
1140
|
+
obj: attestation
|
|
1141
|
+
};
|
|
1142
|
+
} else {
|
|
1143
|
+
return {
|
|
1144
|
+
result: TopicValidatorResult.Accept,
|
|
1145
|
+
obj: attestation
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
399
1148
|
};
|
|
400
|
-
const { result, obj: attestation } = await this.validateReceivedMessage(validationFunc, msgId, source);
|
|
401
|
-
if (
|
|
1149
|
+
const { result, obj: attestation } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.checkpoint_attestation);
|
|
1150
|
+
if (result !== TopicValidatorResult.Accept || !attestation) {
|
|
402
1151
|
return;
|
|
403
1152
|
}
|
|
404
|
-
this.logger.debug(`Received attestation for
|
|
405
|
-
p2pMessageIdentifier: await attestation.
|
|
406
|
-
slot: attestation.slotNumber
|
|
1153
|
+
this.logger.debug(`Received checkpoint attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`, {
|
|
1154
|
+
p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
|
|
1155
|
+
slot: attestation.slotNumber,
|
|
407
1156
|
archive: attestation.archive.toString(),
|
|
408
|
-
|
|
1157
|
+
source: source.toString()
|
|
409
1158
|
});
|
|
410
|
-
await this.mempools.attestationPool.
|
|
1159
|
+
await this.mempools.attestationPool.addCheckpointAttestations([
|
|
411
1160
|
attestation
|
|
412
1161
|
]);
|
|
413
1162
|
}
|
|
414
|
-
async processBlockFromPeer(
|
|
1163
|
+
async processBlockFromPeer(payloadData, msgId, source) {
|
|
415
1164
|
const validationFunc = async ()=>{
|
|
416
|
-
const block = BlockProposal.fromBuffer(
|
|
417
|
-
const
|
|
418
|
-
this.
|
|
419
|
-
|
|
1165
|
+
const block = BlockProposal.fromBuffer(payloadData);
|
|
1166
|
+
const isValid = await this.validateBlockProposal(source, block);
|
|
1167
|
+
const pool = this.mempools.attestationPool;
|
|
1168
|
+
const exists = isValid && await pool.hasBlockProposal(block);
|
|
1169
|
+
const canAdd = isValid && await pool.canAddProposal(block);
|
|
1170
|
+
this.logger.trace(`Validate propagated block proposal`, {
|
|
1171
|
+
isValid,
|
|
1172
|
+
exists,
|
|
1173
|
+
canAdd,
|
|
1174
|
+
[Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
|
|
420
1175
|
[Attributes.P2P_ID]: source.toString()
|
|
421
1176
|
});
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
1177
|
+
if (!isValid) {
|
|
1178
|
+
return {
|
|
1179
|
+
result: TopicValidatorResult.Reject
|
|
1180
|
+
};
|
|
1181
|
+
} else if (exists) {
|
|
1182
|
+
return {
|
|
1183
|
+
result: TopicValidatorResult.Ignore,
|
|
1184
|
+
obj: block
|
|
1185
|
+
};
|
|
1186
|
+
} else if (!canAdd) {
|
|
1187
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
|
|
1188
|
+
this.logger.warn(`Penalizing peer for block proposal exceeding per-slot cap`, {
|
|
1189
|
+
slot: block.slotNumber.toString(),
|
|
1190
|
+
archive: block.archive.toString(),
|
|
1191
|
+
source: source.toString()
|
|
1192
|
+
});
|
|
1193
|
+
return {
|
|
1194
|
+
result: TopicValidatorResult.Reject
|
|
1195
|
+
};
|
|
1196
|
+
} else {
|
|
1197
|
+
return {
|
|
1198
|
+
result: TopicValidatorResult.Accept,
|
|
1199
|
+
obj: block
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
426
1202
|
};
|
|
427
|
-
const { result, obj: block } = await this.validateReceivedMessage(validationFunc, msgId, source);
|
|
1203
|
+
const { result, obj: block } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.block_proposal);
|
|
428
1204
|
if (!result || !block) {
|
|
429
1205
|
return;
|
|
430
1206
|
}
|
|
431
|
-
await this.processValidBlockProposal(block);
|
|
1207
|
+
await this.processValidBlockProposal(block, source);
|
|
432
1208
|
}
|
|
433
1209
|
// REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
1210
|
+
// REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
|
|
1211
|
+
// should not be here as it does not deal with p2p networking.
|
|
1212
|
+
async processValidBlockProposal(block, sender) {
|
|
1213
|
+
const slot = block.slotNumber;
|
|
1214
|
+
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1215
|
+
p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
|
|
1216
|
+
source: sender.toString(),
|
|
1217
|
+
...block.toBlockInfo()
|
|
440
1218
|
});
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
1219
|
+
// Attempt to add proposal
|
|
1220
|
+
try {
|
|
1221
|
+
await this.mempools.attestationPool.addBlockProposal(block);
|
|
1222
|
+
} catch (err) {
|
|
1223
|
+
// Drop proposals if we hit per-slot cap in the attestation pool; rethrow unknown errors
|
|
1224
|
+
if (err instanceof ProposalSlotCapExceededError) {
|
|
1225
|
+
this.logger.warn(`Dropping block proposal due to per-slot proposal cap`, {
|
|
1226
|
+
slot: String(slot),
|
|
1227
|
+
archive: block.archive.toString(),
|
|
1228
|
+
error: err.message
|
|
1229
|
+
});
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
throw err;
|
|
1233
|
+
}
|
|
1234
|
+
// Mark the txs in this proposal as non-evictable
|
|
1235
|
+
await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
|
|
1236
|
+
// Call the block received callback to validate the proposal.
|
|
1237
|
+
// Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1238
|
+
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1239
|
+
if (!isValid) {
|
|
1240
|
+
this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Handle a gossiped checkpoint proposal.
|
|
1245
|
+
* Validates and processes the checkpoint proposal, then triggers the callback for attestation.
|
|
1246
|
+
*/ async handleGossipedCheckpointProposal(payloadData, msgId, source) {
|
|
1247
|
+
// TODO(palla/mbps): This pattern is repeated across multiple message handlers, consider abstracting it.
|
|
1248
|
+
const validationFunc = async ()=>{
|
|
1249
|
+
const checkpoint = CheckpointProposal.fromBuffer(payloadData);
|
|
1250
|
+
const isValid = await this.validateCheckpointProposal(source, checkpoint);
|
|
1251
|
+
const pool = this.mempools.attestationPool;
|
|
1252
|
+
const exists = isValid && await pool.hasCheckpointProposal(checkpoint);
|
|
1253
|
+
const canAdd = isValid && await pool.canAddCheckpointProposal(checkpoint);
|
|
1254
|
+
this.logger.trace(`Validate propagated checkpoint proposal`, {
|
|
1255
|
+
isValid,
|
|
1256
|
+
exists,
|
|
1257
|
+
canAdd,
|
|
1258
|
+
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1259
|
+
[Attributes.P2P_ID]: source.toString()
|
|
450
1260
|
});
|
|
451
|
-
|
|
1261
|
+
if (!isValid) {
|
|
1262
|
+
return {
|
|
1263
|
+
result: TopicValidatorResult.Reject
|
|
1264
|
+
};
|
|
1265
|
+
} else if (exists) {
|
|
1266
|
+
return {
|
|
1267
|
+
result: TopicValidatorResult.Ignore,
|
|
1268
|
+
obj: checkpoint
|
|
1269
|
+
};
|
|
1270
|
+
} else if (!canAdd) {
|
|
1271
|
+
this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
|
|
1272
|
+
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
1273
|
+
slot: checkpoint.slotNumber.toString(),
|
|
1274
|
+
archive: checkpoint.archive.toString(),
|
|
1275
|
+
source: source.toString()
|
|
1276
|
+
});
|
|
1277
|
+
return {
|
|
1278
|
+
result: TopicValidatorResult.Reject
|
|
1279
|
+
};
|
|
1280
|
+
} else {
|
|
1281
|
+
return {
|
|
1282
|
+
result: TopicValidatorResult.Accept,
|
|
1283
|
+
obj: checkpoint
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
};
|
|
1287
|
+
const { result, obj: checkpoint } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.checkpoint_proposal);
|
|
1288
|
+
if (result !== TopicValidatorResult.Accept || !checkpoint) {
|
|
1289
|
+
return;
|
|
452
1290
|
}
|
|
1291
|
+
await this.processValidCheckpointProposal(checkpoint, source);
|
|
453
1292
|
}
|
|
454
1293
|
/**
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
|
|
458
|
-
|
|
1294
|
+
* Process a validated checkpoint proposal.
|
|
1295
|
+
* Extracts and processes the last block proposal (if present) first, then processes the checkpoint.
|
|
1296
|
+
* The block callback is invoked before the checkpoint callback.
|
|
1297
|
+
*/ async processValidCheckpointProposal(checkpoint, sender) {
|
|
1298
|
+
const slot = checkpoint.slotNumber;
|
|
1299
|
+
this.logger.verbose(`Received checkpoint proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
1300
|
+
p2pMessageIdentifier: await checkpoint.p2pMessageLoggingIdentifier(),
|
|
1301
|
+
slot: checkpoint.slotNumber,
|
|
1302
|
+
archive: checkpoint.archive.toString(),
|
|
1303
|
+
source: sender.toString()
|
|
1304
|
+
});
|
|
1305
|
+
// Extract block proposal before adding to pool (pool stores them separately)
|
|
1306
|
+
const blockProposal = checkpoint.getBlockProposal();
|
|
1307
|
+
// Add proposal to the pool (this extracts and stores block proposal separately)
|
|
1308
|
+
await this.mempools.attestationPool.addCheckpointProposal(checkpoint);
|
|
1309
|
+
// Mark txs as non-evictable if present (from the last block)
|
|
1310
|
+
if (checkpoint.txHashes.length > 0) {
|
|
1311
|
+
await this.mempools.txPool.markTxsAsNonEvictable(checkpoint.txHashes);
|
|
1312
|
+
}
|
|
1313
|
+
// If there was a last block proposal, invoke the block callback first for validation.
|
|
1314
|
+
// Note: The block proposal is already stored in the pool by addCheckpointProposal.
|
|
1315
|
+
if (blockProposal) {
|
|
1316
|
+
const isValid = await this.blockReceivedCallback(blockProposal, sender);
|
|
1317
|
+
if (!isValid) {
|
|
1318
|
+
this.logger.warn(`Block proposal from checkpoint failed validation`, {
|
|
1319
|
+
slot: slot.toString(),
|
|
1320
|
+
archive: checkpoint.archive.toString(),
|
|
1321
|
+
blockNumber: blockProposal.blockNumber.toString()
|
|
1322
|
+
});
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
// Call the checkpoint received callback with the core version (without lastBlock)
|
|
1327
|
+
// to validate and potentially generate attestations
|
|
1328
|
+
const attestations = await this.checkpointReceivedCallback(checkpoint.toCore(), sender);
|
|
1329
|
+
if (attestations && attestations.length > 0) {
|
|
1330
|
+
// If the callback returned attestations, add them to the pool and propagate them
|
|
1331
|
+
await this.mempools.attestationPool.addCheckpointAttestations(attestations);
|
|
1332
|
+
for (const attestation of attestations){
|
|
1333
|
+
await this.propagate(attestation);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
459
1336
|
}
|
|
460
1337
|
/**
|
|
461
1338
|
* Propagates provided message to peers.
|
|
462
1339
|
* @param message - The message to propagate.
|
|
463
1340
|
*/ async propagate(message) {
|
|
464
|
-
const p2pMessageIdentifier = await message.
|
|
1341
|
+
const p2pMessageIdentifier = await message.p2pMessageLoggingIdentifier();
|
|
465
1342
|
this.logger.trace(`Message ${p2pMessageIdentifier} queued`, {
|
|
466
1343
|
p2pMessageIdentifier
|
|
467
1344
|
});
|
|
468
|
-
void this.
|
|
469
|
-
await this.sendToPeers(message);
|
|
470
|
-
}).catch((error)=>{
|
|
1345
|
+
void this.sendToPeers(message).catch((error)=>{
|
|
471
1346
|
this.logger.error(`Error propagating message ${p2pMessageIdentifier}`, {
|
|
472
1347
|
error
|
|
473
1348
|
});
|
|
474
1349
|
});
|
|
475
1350
|
}
|
|
476
1351
|
/**
|
|
477
|
-
* Validate
|
|
1352
|
+
* Validate the requested block transactions. Allow partial returns.
|
|
1353
|
+
* @param request - The block transactions request.
|
|
1354
|
+
* @param response - The block transactions response.
|
|
1355
|
+
* @param peerId - The ID of the peer that made the request.
|
|
1356
|
+
* @returns True if the requested block transactions are valid, false otherwise.
|
|
1357
|
+
*/ async validateRequestedBlockTxs(request, response, peerId) {
|
|
1358
|
+
const requestedTxValidator = this.createRequestedTxValidator();
|
|
1359
|
+
try {
|
|
1360
|
+
if (!response.blockHash.equals(request.blockHash)) {
|
|
1361
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1362
|
+
throw new ValidationError(`Received block txs for unexpected block: expected ${request.blockHash.toString()}, got ${response.blockHash.toString()}`);
|
|
1363
|
+
}
|
|
1364
|
+
if (response.txIndices.getLength() !== request.txIndices.getLength()) {
|
|
1365
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1366
|
+
throw new ValidationError(`Received block txs with mismatched bitvector length: expected ${request.txIndices.getLength()}, got ${response.txIndices.getLength()}`);
|
|
1367
|
+
}
|
|
1368
|
+
// Check no duplicates and not exceeding returnable count
|
|
1369
|
+
const requestedIndices = new Set(request.txIndices.getTrueIndices());
|
|
1370
|
+
const availableIndices = new Set(response.txIndices.getTrueIndices());
|
|
1371
|
+
const maxReturnable = [
|
|
1372
|
+
...requestedIndices
|
|
1373
|
+
].filter((i)=>availableIndices.has(i)).length;
|
|
1374
|
+
const returnedHashes = await Promise.all(response.txs.map((tx)=>tx.getTxHash().toString()));
|
|
1375
|
+
const uniqueReturned = new Set(returnedHashes.map((h)=>h.toString()));
|
|
1376
|
+
if (uniqueReturned.size !== returnedHashes.length) {
|
|
1377
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1378
|
+
throw new ValidationError(`Received duplicate txs in block txs response`);
|
|
1379
|
+
}
|
|
1380
|
+
if (response.txs.length > maxReturnable) {
|
|
1381
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1382
|
+
throw new ValidationError(`Received more txs (${response.txs.length}) than requested-and-available (${maxReturnable})`);
|
|
1383
|
+
}
|
|
1384
|
+
// Given proposal (should have locally), ensure returned txs are valid subset and match request indices
|
|
1385
|
+
const proposal = await this.mempools.attestationPool.getBlockProposal(request.blockHash.toString());
|
|
1386
|
+
if (proposal) {
|
|
1387
|
+
// Build intersected indices
|
|
1388
|
+
const intersectIdx = request.txIndices.getTrueIndices().filter((i)=>response.txIndices.isSet(i));
|
|
1389
|
+
// Enforce subset membership and preserve increasing order by index.
|
|
1390
|
+
const hashToIndexInProposal = new Map(proposal.txHashes.map((h, i)=>[
|
|
1391
|
+
h.toString(),
|
|
1392
|
+
i
|
|
1393
|
+
]));
|
|
1394
|
+
const allowedIndexSet = new Set(intersectIdx);
|
|
1395
|
+
const indices = returnedHashes.map((h)=>hashToIndexInProposal.get(h));
|
|
1396
|
+
const allAllowed = indices.every((idx)=>idx !== undefined && allowedIndexSet.has(idx));
|
|
1397
|
+
const strictlyIncreasing = indices.every((idx, i)=>i === 0 ? idx !== undefined : idx > indices[i - 1]);
|
|
1398
|
+
if (!allAllowed || !strictlyIncreasing) {
|
|
1399
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1400
|
+
throw new ValidationError('Returned txs do not match expected subset/order for requested indices');
|
|
1401
|
+
}
|
|
1402
|
+
} else {
|
|
1403
|
+
// No local proposal, cannot check the membership/order of the returned txs
|
|
1404
|
+
this.logger.warn(`Block proposal not found for block hash ${request.blockHash.toString()}; cannot validate membership/order of returned txs`);
|
|
1405
|
+
return false;
|
|
1406
|
+
}
|
|
1407
|
+
await Promise.all(response.txs.map((tx)=>this.validateRequestedTx(tx, peerId, requestedTxValidator)));
|
|
1408
|
+
return true;
|
|
1409
|
+
} catch (e) {
|
|
1410
|
+
if (e instanceof ValidationError) {
|
|
1411
|
+
this.logger.warn(`Failed validation for requested block txs from peer ${peerId.toString()}`);
|
|
1412
|
+
} else {
|
|
1413
|
+
this.logger.error(`Error during validation of requested block txs`, e);
|
|
1414
|
+
}
|
|
1415
|
+
return false;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Validate a collection of txs that has been requested from a peer.
|
|
478
1420
|
*
|
|
479
|
-
* The core component of this validator is that
|
|
1421
|
+
* The core component of this validator is that each tx hash MUST match the requested tx hash,
|
|
480
1422
|
* In order to perform this check, the tx proof must be verified.
|
|
481
1423
|
*
|
|
482
1424
|
* Note: This function is called from within `ReqResp.sendRequest` as part of the
|
|
483
1425
|
* ReqRespSubProtocol.TX subprotocol validation.
|
|
484
1426
|
*
|
|
485
|
-
* @param requestedTxHash - The
|
|
486
|
-
* @param responseTx - The
|
|
1427
|
+
* @param requestedTxHash - The collection of the txs that was requested.
|
|
1428
|
+
* @param responseTx - The collection of txs that was received as a response to the request.
|
|
487
1429
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
488
|
-
* @returns True if the
|
|
489
|
-
*/ async
|
|
490
|
-
const
|
|
491
|
-
const
|
|
492
|
-
//
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
1430
|
+
* @returns True if the whole collection of txs is valid, false otherwise.
|
|
1431
|
+
*/ async validateRequestedTxs(requestedTxHash, responseTx, peerId) {
|
|
1432
|
+
const requested = new Set(requestedTxHash.map((h)=>h.toString()));
|
|
1433
|
+
const requestedTxValidator = this.createRequestedTxValidator();
|
|
1434
|
+
//TODO: (mralj) - this is somewhat naive implementation, if single tx is invlid we consider the whole response invalid.
|
|
1435
|
+
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
1436
|
+
try {
|
|
1437
|
+
await Promise.all(responseTx.map((tx)=>this.validateRequestedTx(tx, peerId, requestedTxValidator, requested)));
|
|
1438
|
+
return true;
|
|
1439
|
+
} catch (e) {
|
|
1440
|
+
if (e instanceof ValidationError) {
|
|
1441
|
+
this.logger.warn(`Failed to validate requested txs from peer ${peerId.toString()}, reason ${e.message}`);
|
|
1442
|
+
} else {
|
|
1443
|
+
this.logger.error(`Error during validation of requested txs`, e);
|
|
1444
|
+
}
|
|
496
1445
|
return false;
|
|
497
1446
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* Validates a BLOCK response.
|
|
1450
|
+
*
|
|
1451
|
+
* If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
|
|
1452
|
+
* Penalizes on block number mismatch or hash mismatch.
|
|
1453
|
+
*
|
|
1454
|
+
* @param requestedBlockNumber - The requested block number.
|
|
1455
|
+
* @param responseBlock - The block returned by the peer.
|
|
1456
|
+
* @param peerId - The peer that returned the block.
|
|
1457
|
+
* @returns True if the response is valid, false otherwise.
|
|
1458
|
+
*/ async validateRequestedBlock(requestedBlockNumber, responseBlock, peerId) {
|
|
1459
|
+
try {
|
|
1460
|
+
const reqNum = Number(requestedBlockNumber.toString());
|
|
1461
|
+
if (responseBlock.number !== reqNum) {
|
|
1462
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1463
|
+
return false;
|
|
1464
|
+
}
|
|
1465
|
+
const local = await this.archiver.getBlock(BlockNumber(reqNum));
|
|
1466
|
+
if (!local) {
|
|
1467
|
+
// We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
|
|
1468
|
+
// TODO: Consider extending this validator to accept an expected hash or
|
|
1469
|
+
// performing quorum-based checks when using P2P syncing prior to L1 sync.
|
|
1470
|
+
this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
|
|
1471
|
+
return false;
|
|
1472
|
+
}
|
|
1473
|
+
const [localHash, respHash] = await Promise.all([
|
|
1474
|
+
local.hash(),
|
|
1475
|
+
responseBlock.hash()
|
|
1476
|
+
]);
|
|
1477
|
+
if (!localHash.equals(respHash)) {
|
|
1478
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1479
|
+
return false;
|
|
1480
|
+
}
|
|
1481
|
+
return true;
|
|
1482
|
+
} catch (e) {
|
|
1483
|
+
this.logger.warn(`Error validating requested block`, e);
|
|
501
1484
|
return false;
|
|
502
1485
|
}
|
|
503
|
-
|
|
1486
|
+
}
|
|
1487
|
+
createRequestedTxValidator() {
|
|
1488
|
+
return new AggregateTxValidator(new DataTxValidator(), new MetadataTxValidator({
|
|
1489
|
+
l1ChainId: new Fr(this.config.l1ChainId),
|
|
1490
|
+
rollupVersion: new Fr(this.config.rollupVersion),
|
|
1491
|
+
protocolContractsHash,
|
|
1492
|
+
vkTreeRoot: getVKTreeRoot()
|
|
1493
|
+
}), new TxProofValidator(this.proofVerifier));
|
|
1494
|
+
}
|
|
1495
|
+
async validateRequestedTx(tx, peerId, txValidator, requested) {
|
|
1496
|
+
const penalize = (severity)=>this.peerManager.penalizePeer(peerId, severity);
|
|
1497
|
+
if (!await tx.validateTxHash()) {
|
|
1498
|
+
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1499
|
+
throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
|
|
1500
|
+
}
|
|
1501
|
+
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
1502
|
+
penalize(PeerErrorSeverity.MidToleranceError);
|
|
1503
|
+
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
1504
|
+
}
|
|
1505
|
+
const { result } = await txValidator.validateTx(tx);
|
|
1506
|
+
if (result === 'invalid') {
|
|
1507
|
+
penalize(PeerErrorSeverity.LowToleranceError);
|
|
1508
|
+
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
1509
|
+
}
|
|
504
1510
|
}
|
|
505
1511
|
async validatePropagatedTx(tx, peerId) {
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
1512
|
+
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1513
|
+
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1514
|
+
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1515
|
+
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1516
|
+
for (const validator of messageValidators){
|
|
1517
|
+
const outcome = await this.runValidations(tx, validator);
|
|
1518
|
+
if (outcome.allPassed) {
|
|
1519
|
+
continue;
|
|
1520
|
+
}
|
|
1521
|
+
const { name } = outcome.failure;
|
|
1522
|
+
let { severity } = outcome.failure;
|
|
1523
|
+
// Double spend validator has a special case handler
|
|
1524
|
+
if (name === 'doubleSpendValidator') {
|
|
1525
|
+
const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
|
|
1526
|
+
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1527
|
+
}
|
|
1528
|
+
this.peerManager.penalizePeer(peerId, severity);
|
|
1529
|
+
return false;
|
|
511
1530
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
if (
|
|
516
|
-
|
|
1531
|
+
return true;
|
|
1532
|
+
}
|
|
1533
|
+
async getGasFees(blockNumber) {
|
|
1534
|
+
if (blockNumber === this.feesCache?.blockNumber) {
|
|
1535
|
+
return this.feesCache.gasFees;
|
|
517
1536
|
}
|
|
518
|
-
this.
|
|
519
|
-
|
|
1537
|
+
const header = await this.archiver.getBlockHeader(blockNumber);
|
|
1538
|
+
const gasFees = header?.globalVariables.gasFees ?? GasFees.empty();
|
|
1539
|
+
this.feesCache = {
|
|
1540
|
+
blockNumber,
|
|
1541
|
+
gasFees
|
|
1542
|
+
};
|
|
1543
|
+
return gasFees;
|
|
1544
|
+
}
|
|
1545
|
+
async validate(txs) {
|
|
1546
|
+
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1547
|
+
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1548
|
+
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1549
|
+
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1550
|
+
await Promise.all(txs.map(async (tx)=>{
|
|
1551
|
+
for (const validator of messageValidators){
|
|
1552
|
+
const outcome = await this.runValidations(tx, validator);
|
|
1553
|
+
if (!outcome.allPassed) {
|
|
1554
|
+
throw new Error('Invalid tx detected', {
|
|
1555
|
+
cause: {
|
|
1556
|
+
outcome
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}));
|
|
520
1562
|
}
|
|
521
1563
|
/**
|
|
522
|
-
* Create message validators for the given block number.
|
|
1564
|
+
* Create message validators for the given block number and timestamp.
|
|
523
1565
|
*
|
|
524
1566
|
* Each validator is a pair of a validator and a severity.
|
|
525
1567
|
* If a validator fails, the peer is penalized with the severity of the validator.
|
|
526
1568
|
*
|
|
527
|
-
* @param
|
|
1569
|
+
* @param currentBlockNumber - The current synced block number.
|
|
1570
|
+
* @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
|
|
528
1571
|
* @returns The message validators.
|
|
529
|
-
*/ createMessageValidators(
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
},
|
|
535
|
-
metadataValidator: {
|
|
536
|
-
validator: new MetadataTxValidator(new Fr(this.config.l1ChainId), new Fr(blockNumber)),
|
|
537
|
-
severity: PeerErrorSeverity.HighToleranceError
|
|
538
|
-
},
|
|
539
|
-
proofValidator: {
|
|
540
|
-
validator: new TxProofValidator(this.proofVerifier),
|
|
541
|
-
severity: PeerErrorSeverity.MidToleranceError
|
|
542
|
-
},
|
|
543
|
-
doubleSpendValidator: {
|
|
544
|
-
validator: new DoubleSpendTxValidator({
|
|
545
|
-
nullifiersExist: async (nullifiers)=>{
|
|
546
|
-
const merkleTree = this.worldStateSynchronizer.getCommitted();
|
|
547
|
-
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
548
|
-
return indices.map((index)=>index !== undefined);
|
|
549
|
-
}
|
|
550
|
-
}),
|
|
551
|
-
severity: PeerErrorSeverity.HighToleranceError
|
|
552
|
-
}
|
|
553
|
-
};
|
|
1572
|
+
*/ async createMessageValidators(currentBlockNumber, nextSlotTimestamp) {
|
|
1573
|
+
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
1574
|
+
const allowedInSetup = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
|
|
1575
|
+
const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
|
|
1576
|
+
return createTxMessageValidators(nextSlotTimestamp, blockNumberInWhichTheTxIsConsideredToBeIncluded, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, this.proofVerifier, !this.config.disableTransactions, allowedInSetup);
|
|
554
1577
|
}
|
|
555
1578
|
/**
|
|
556
1579
|
* Run validations on a tx.
|
|
@@ -562,29 +1585,32 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
562
1585
|
const { result } = await validator.validateTx(tx);
|
|
563
1586
|
return {
|
|
564
1587
|
name,
|
|
565
|
-
isValid: result
|
|
1588
|
+
isValid: result !== 'invalid',
|
|
566
1589
|
severity
|
|
567
1590
|
};
|
|
568
1591
|
});
|
|
569
1592
|
// A promise that resolves when all validations have been run
|
|
570
|
-
const allValidations = Promise.all(validationPromises);
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
1593
|
+
const allValidations = await Promise.all(validationPromises);
|
|
1594
|
+
const failed = allValidations.find((x)=>!x.isValid);
|
|
1595
|
+
if (failed) {
|
|
1596
|
+
return {
|
|
1597
|
+
allPassed: false,
|
|
1598
|
+
failure: {
|
|
1599
|
+
isValid: {
|
|
1600
|
+
result: 'invalid',
|
|
1601
|
+
reason: [
|
|
1602
|
+
'Failed validation'
|
|
1603
|
+
]
|
|
1604
|
+
},
|
|
1605
|
+
name: failed.name,
|
|
1606
|
+
severity: failed.severity
|
|
1607
|
+
}
|
|
1608
|
+
};
|
|
1609
|
+
} else {
|
|
1610
|
+
return {
|
|
1611
|
+
allPassed: true
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
588
1614
|
}
|
|
589
1615
|
/**
|
|
590
1616
|
* Handle a double spend failure.
|
|
@@ -602,7 +1628,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
602
1628
|
}
|
|
603
1629
|
const snapshotValidator = new DoubleSpendTxValidator({
|
|
604
1630
|
nullifiersExist: async (nullifiers)=>{
|
|
605
|
-
const merkleTree = this.worldStateSynchronizer.getSnapshot(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow);
|
|
1631
|
+
const merkleTree = this.worldStateSynchronizer.getSnapshot(BlockNumber(blockNumber - this.config.doubleSpendSeverePeerPenaltyWindow));
|
|
606
1632
|
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
607
1633
|
return indices.map((index)=>index !== undefined);
|
|
608
1634
|
}
|
|
@@ -614,13 +1640,14 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
614
1640
|
return PeerErrorSeverity.HighToleranceError;
|
|
615
1641
|
}
|
|
616
1642
|
/**
|
|
617
|
-
* Validate
|
|
1643
|
+
* Validate a checkpoint attestation.
|
|
618
1644
|
*
|
|
619
|
-
* @param attestation - The attestation to validate.
|
|
620
|
-
* @returns True if the attestation is valid, false otherwise.
|
|
621
|
-
*/ async
|
|
622
|
-
const severity = await this.
|
|
1645
|
+
* @param attestation - The checkpoint attestation to validate.
|
|
1646
|
+
* @returns True if the checkpoint attestation is valid, false otherwise.
|
|
1647
|
+
*/ async validateCheckpointAttestation(peerId, attestation) {
|
|
1648
|
+
const severity = await this.checkpointAttestationValidator.validate(attestation);
|
|
623
1649
|
if (severity) {
|
|
1650
|
+
this.logger.debug(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
|
|
624
1651
|
this.peerManager.penalizePeer(peerId, severity);
|
|
625
1652
|
return false;
|
|
626
1653
|
}
|
|
@@ -634,6 +1661,21 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
634
1661
|
*/ async validateBlockProposal(peerId, block) {
|
|
635
1662
|
const severity = await this.blockProposalValidator.validate(block);
|
|
636
1663
|
if (severity) {
|
|
1664
|
+
this.logger.debug(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
1665
|
+
this.peerManager.penalizePeer(peerId, severity);
|
|
1666
|
+
return false;
|
|
1667
|
+
}
|
|
1668
|
+
return true;
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Validate a checkpoint proposal.
|
|
1672
|
+
*
|
|
1673
|
+
* @param checkpoint - The checkpoint proposal to validate.
|
|
1674
|
+
* @returns True if the checkpoint proposal is valid, false otherwise.
|
|
1675
|
+
*/ async validateCheckpointProposal(peerId, checkpoint) {
|
|
1676
|
+
const severity = await this.checkpointProposalValidator.validate(checkpoint);
|
|
1677
|
+
if (severity) {
|
|
1678
|
+
this.logger.debug(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
|
|
637
1679
|
this.peerManager.penalizePeer(peerId, severity);
|
|
638
1680
|
return false;
|
|
639
1681
|
}
|
|
@@ -642,13 +1684,16 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
642
1684
|
getPeerScore(peerId) {
|
|
643
1685
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
644
1686
|
}
|
|
1687
|
+
handleAuthRequestFromPeer(authRequest, peerId) {
|
|
1688
|
+
return this.peerManager.handleAuthRequestFromPeer(authRequest, peerId);
|
|
1689
|
+
}
|
|
645
1690
|
async sendToPeers(message) {
|
|
646
1691
|
const parent = message.constructor;
|
|
647
|
-
const identifier = await message.
|
|
1692
|
+
const identifier = await message.p2pMessageLoggingIdentifier().then((i)=>i.toString());
|
|
648
1693
|
this.logger.trace(`Sending message ${identifier}`, {
|
|
649
1694
|
p2pMessageIdentifier: identifier
|
|
650
1695
|
});
|
|
651
|
-
const recipientsNum = await this.publishToTopic(parent.p2pTopic, message
|
|
1696
|
+
const recipientsNum = await this.publishToTopic(this.topicStrings[parent.p2pTopic], message);
|
|
652
1697
|
this.logger.debug(`Sent message ${identifier} to ${recipientsNum} peers`, {
|
|
653
1698
|
p2pMessageIdentifier: identifier,
|
|
654
1699
|
sourcePeer: this.node.peerId.toString()
|
|
@@ -671,42 +1716,3 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
671
1716
|
}
|
|
672
1717
|
}
|
|
673
1718
|
}
|
|
674
|
-
_ts_decorate([
|
|
675
|
-
trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
|
|
676
|
-
[Attributes.BLOCK_NUMBER]: block.blockNumber.toNumber(),
|
|
677
|
-
[Attributes.SLOT_NUMBER]: block.slotNumber.toNumber(),
|
|
678
|
-
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
679
|
-
[Attributes.P2P_ID]: await block.p2pMessageIdentifier().then((i)=>i.toString())
|
|
680
|
-
}))
|
|
681
|
-
], LibP2PService.prototype, "processValidBlockProposal", null);
|
|
682
|
-
_ts_decorate([
|
|
683
|
-
trackSpan('Libp2pService.broadcastAttestation', async (attestation)=>({
|
|
684
|
-
[Attributes.BLOCK_NUMBER]: attestation.payload.header.globalVariables.blockNumber.toNumber(),
|
|
685
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.globalVariables.slotNumber.toNumber(),
|
|
686
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
687
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then((i)=>i.toString())
|
|
688
|
-
}))
|
|
689
|
-
], LibP2PService.prototype, "broadcastAttestation", null);
|
|
690
|
-
_ts_decorate([
|
|
691
|
-
trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx)=>({
|
|
692
|
-
[Attributes.TX_HASH]: requestedTxHash.toString()
|
|
693
|
-
}))
|
|
694
|
-
], LibP2PService.prototype, "validateRequestedTx", null);
|
|
695
|
-
_ts_decorate([
|
|
696
|
-
trackSpan('Libp2pService.validatePropagatedTx', async (tx)=>({
|
|
697
|
-
[Attributes.TX_HASH]: (await tx.getTxHash()).toString()
|
|
698
|
-
}))
|
|
699
|
-
], LibP2PService.prototype, "validatePropagatedTx", null);
|
|
700
|
-
_ts_decorate([
|
|
701
|
-
trackSpan('Libp2pService.validateAttestation', async (_, attestation)=>({
|
|
702
|
-
[Attributes.BLOCK_NUMBER]: attestation.payload.header.globalVariables.blockNumber.toNumber(),
|
|
703
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.globalVariables.slotNumber.toNumber(),
|
|
704
|
-
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
705
|
-
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then((i)=>i.toString())
|
|
706
|
-
}))
|
|
707
|
-
], LibP2PService.prototype, "validateAttestation", null);
|
|
708
|
-
_ts_decorate([
|
|
709
|
-
trackSpan('Libp2pService.validateBlockProposal', (_peerId, block)=>({
|
|
710
|
-
[Attributes.SLOT_NUMBER]: block.payload.header.globalVariables.slotNumber.toString()
|
|
711
|
-
}))
|
|
712
|
-
], LibP2PService.prototype, "validateBlockProposal", null);
|