@aztec/p2p 0.0.0-test.0 → 0.0.1-commit.24de95ac
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.map +1 -1
- package/dest/bootstrap/bootstrap.js +22 -9
- package/dest/client/factory.d.ts +13 -3
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +60 -24
- package/dest/client/index.d.ts +1 -0
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +1 -0
- package/dest/client/interface.d.ts +155 -0
- package/dest/client/interface.d.ts.map +1 -0
- package/dest/client/interface.js +9 -0
- package/dest/client/p2p_client.d.ts +72 -169
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +365 -174
- package/dest/config.d.ts +123 -103
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +173 -34
- package/dest/enr/generate-enr.d.ts +10 -2
- package/dest/enr/generate-enr.d.ts.map +1 -1
- package/dest/enr/generate-enr.js +27 -5
- package/dest/index.d.ts +3 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +42 -4
- 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.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +204 -54
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +10 -2
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +93 -15
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +10 -2
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +86 -18
- package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +9 -15
- package/dest/mem_pools/instrumentation.d.ts +7 -11
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +25 -37
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +93 -9
- 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 +469 -97
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +33 -9
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +133 -36
- package/dest/mem_pools/tx_pool/priority.js +1 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +64 -8
- 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.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +264 -39
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -0
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +45 -9
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +5 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +61 -12
- 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/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.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.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 +0 -2
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +21 -27
- package/dest/msg_validators/tx_validator/factory.d.ts +15 -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 +7 -0
- 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 +7 -3
- 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 +91 -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 +12 -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.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +6 -5
- package/dest/services/discv5/discV5_service.d.ts +9 -8
- 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 +49 -10
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +88 -5
- package/dest/services/encoding.d.ts +25 -6
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +73 -5
- package/dest/services/index.d.ts +4 -0
- package/dest/services/index.d.ts.map +1 -1
- package/dest/services/index.js +4 -0
- package/dest/services/libp2p/instrumentation.d.ts +18 -0
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -0
- package/dest/services/libp2p/instrumentation.js +157 -0
- package/dest/services/libp2p/libp2p_service.d.ts +87 -42
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +500 -218
- 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 +3 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +11 -2
- package/dest/services/peer-manager/peer_manager.d.ts +126 -15
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +547 -72
- package/dest/services/reqresp/config.d.ts +10 -8
- 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 +1 -1
- 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 +30 -13
- 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 +2 -1
- 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 +72 -23
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +45 -26
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- 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 +5 -0
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +28 -5
- 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 +49 -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 +2 -4
- 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 +2 -0
- 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 +0 -2
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +38 -6
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +72 -5
- package/dest/services/reqresp/protocols/tx.d.ts +12 -1
- 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/rate_limiter.d.ts +4 -2
- 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.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +21 -1
- package/dest/services/reqresp/reqresp.d.ts +45 -47
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +298 -207
- package/dest/services/reqresp/status.d.ts +9 -3
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/reqresp/status.js +9 -2
- package/dest/services/service.d.ts +22 -18
- 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 +56 -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 +34 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts +54 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/slow_tx_collection.js +176 -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 +49 -0
- package/dest/services/tx_provider.d.ts.map +1 -0
- package/dest/services/tx_provider.js +210 -0
- package/dest/services/tx_provider_instrumentation.d.ts +13 -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/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/index.d.ts +1 -0
- 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.map +1 -1
- package/dest/test-helpers/make-enrs.js +4 -5
- package/dest/test-helpers/make-test-p2p-clients.d.ts +32 -4
- 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 +14 -10
- 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.js +96 -25
- package/dest/testbench/parse_log_file.js +4 -4
- package/dest/testbench/testbench.js +4 -4
- package/dest/testbench/worker_client_manager.d.ts +0 -5
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +11 -19
- package/dest/types/index.d.ts +3 -1
- package/dest/types/index.d.ts.map +1 -1
- package/dest/types/index.js +2 -0
- package/dest/util.d.ts +22 -15
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +64 -67
- package/dest/versioning.d.ts +3 -3
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +8 -3
- package/package.json +28 -24
- package/src/bootstrap/bootstrap.ts +27 -11
- package/src/client/factory.ts +136 -45
- package/src/client/index.ts +1 -0
- package/src/client/interface.ts +195 -0
- package/src/client/p2p_client.ts +460 -327
- package/src/config.ts +288 -134
- package/src/enr/generate-enr.ts +39 -6
- package/src/index.ts +4 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +48 -4
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +241 -55
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +117 -20
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +114 -22
- package/src/mem_pools/attestation_pool/mocks.ts +11 -10
- package/src/mem_pools/instrumentation.ts +32 -46
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +549 -108
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +153 -44
- package/src/mem_pools/tx_pool/priority.ts +1 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +67 -8
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +217 -34
- package/src/msg_validators/attestation_validator/attestation_validator.ts +55 -10
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +66 -14
- package/src/msg_validators/msg_seen_validator/msg_seen_validator.ts +36 -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 +4 -4
- package/src/msg_validators/tx_validator/data_validator.ts +81 -69
- package/src/msg_validators/tx_validator/double_spend_validator.ts +19 -17
- package/src/msg_validators/tx_validator/factory.ts +109 -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 +58 -21
- package/src/msg_validators/tx_validator/phases_validator.ts +114 -0
- package/src/msg_validators/tx_validator/test_utils.ts +43 -0
- package/src/msg_validators/tx_validator/timestamp_validator.ts +46 -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 +147 -9
- package/src/services/encoding.ts +80 -5
- package/src/services/index.ts +4 -0
- package/src/services/libp2p/instrumentation.ts +158 -0
- package/src/services/libp2p/libp2p_service.ts +646 -263
- package/src/services/peer-manager/interface.ts +29 -0
- package/src/services/peer-manager/metrics.ts +16 -1
- package/src/services/peer-manager/peer_manager.ts +652 -78
- 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 +148 -95
- package/src/services/reqresp/index.ts +2 -0
- package/src/services/reqresp/interface.ts +91 -36
- package/src/services/reqresp/metrics.ts +4 -1
- package/src/services/reqresp/protocols/auth.ts +83 -0
- package/src/services/reqresp/protocols/block.ts +24 -3
- 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 +117 -5
- package/src/services/reqresp/protocols/tx.ts +35 -6
- 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 +45 -21
- package/src/services/tx_collection/config.ts +84 -0
- package/src/services/tx_collection/fast_tx_collection.ts +340 -0
- package/src/services/tx_collection/index.ts +2 -0
- package/src/services/tx_collection/instrumentation.ts +43 -0
- package/src/services/tx_collection/slow_tx_collection.ts +232 -0
- package/src/services/tx_collection/tx_collection.ts +215 -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 +216 -0
- package/src/services/tx_provider_instrumentation.ts +44 -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 +86 -35
- package/src/testbench/p2p_client_testbench_worker.ts +145 -22
- package/src/testbench/parse_log_file.ts +4 -4
- package/src/testbench/testbench.ts +4 -4
- package/src/testbench/worker_client_manager.ts +17 -23
- package/src/types/index.ts +2 -0
- package/src/util.ts +93 -89
- package/src/versioning.ts +11 -4
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
+
import { randomInt } from '@aztec/foundation/crypto';
|
|
2
3
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
-
import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
4
|
+
import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { SerialQueue } from '@aztec/foundation/queue';
|
|
5
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
6
8
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
7
|
-
import
|
|
9
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
10
|
+
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
11
|
+
import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
|
|
12
|
+
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
13
|
+
import { GasFees } from '@aztec/stdlib/gas';
|
|
8
14
|
import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
9
15
|
import {
|
|
10
16
|
BlockAttestation,
|
|
11
17
|
BlockProposal,
|
|
12
18
|
type Gossipable,
|
|
13
19
|
P2PClientType,
|
|
20
|
+
P2PMessage,
|
|
14
21
|
PeerErrorSeverity,
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
TopicType,
|
|
23
|
+
createTopicString,
|
|
24
|
+
getTopicsForClientAndConfig,
|
|
17
25
|
metricsTopicStrToLabels,
|
|
18
26
|
} from '@aztec/stdlib/p2p';
|
|
19
27
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
20
|
-
import { Tx, type TxHash, type TxValidationResult } from '@aztec/stdlib/tx';
|
|
28
|
+
import { Tx, type TxHash, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
29
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
30
|
+
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
21
31
|
import { Attributes, OtelMetricsAdapter, type TelemetryClient, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
22
32
|
|
|
23
|
-
import type { ENR } from '@chainsafe/enr';
|
|
24
33
|
import {
|
|
25
34
|
type GossipSub,
|
|
26
35
|
type GossipSubComponents,
|
|
@@ -33,17 +42,21 @@ import { noise } from '@chainsafe/libp2p-noise';
|
|
|
33
42
|
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
34
43
|
import { bootstrap } from '@libp2p/bootstrap';
|
|
35
44
|
import { identify } from '@libp2p/identify';
|
|
36
|
-
import { type Message, type PeerId, TopicValidatorResult } from '@libp2p/interface';
|
|
45
|
+
import { type Message, type MultiaddrConnection, type PeerId, TopicValidatorResult } from '@libp2p/interface';
|
|
37
46
|
import type { ConnectionManager } from '@libp2p/interface-internal';
|
|
38
|
-
import '@libp2p/kad-dht';
|
|
39
47
|
import { mplex } from '@libp2p/mplex';
|
|
40
48
|
import { tcp } from '@libp2p/tcp';
|
|
49
|
+
import { ENR } from '@nethermindeth/enr';
|
|
41
50
|
import { createLibp2p } from 'libp2p';
|
|
42
51
|
|
|
43
52
|
import type { P2PConfig } from '../../config.js';
|
|
44
53
|
import type { MemPools } from '../../mem_pools/interface.js';
|
|
45
54
|
import { AttestationValidator, BlockProposalValidator } from '../../msg_validators/index.js';
|
|
55
|
+
import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
|
|
56
|
+
import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
|
|
57
|
+
import { type MessageValidator, createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
|
|
46
58
|
import {
|
|
59
|
+
AggregateTxValidator,
|
|
47
60
|
DataTxValidator,
|
|
48
61
|
DoubleSpendTxValidator,
|
|
49
62
|
MetadataTxValidator,
|
|
@@ -51,23 +64,40 @@ import {
|
|
|
51
64
|
} from '../../msg_validators/tx_validator/index.js';
|
|
52
65
|
import { GossipSubEvent } from '../../types/index.js';
|
|
53
66
|
import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
|
|
67
|
+
import { getVersions } from '../../versioning.js';
|
|
54
68
|
import { AztecDatastore } from '../data_store.js';
|
|
69
|
+
import { DiscV5Service } from '../discv5/discV5_service.js';
|
|
55
70
|
import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
56
71
|
import { gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
72
|
+
import type { PeerManagerInterface } from '../peer-manager/interface.js';
|
|
57
73
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
58
74
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
59
|
-
import {
|
|
75
|
+
import type { P2PReqRespConfig } from '../reqresp/config.js';
|
|
76
|
+
import {
|
|
77
|
+
DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
78
|
+
type ReqRespInterface,
|
|
79
|
+
ReqRespSubProtocol,
|
|
80
|
+
type ReqRespSubProtocolHandler,
|
|
81
|
+
type ReqRespSubProtocolHandlers,
|
|
82
|
+
type ReqRespSubProtocolValidators,
|
|
83
|
+
type SubProtocolMap,
|
|
84
|
+
ValidationError,
|
|
85
|
+
} from '../reqresp/interface.js';
|
|
86
|
+
import { reqRespBlockTxsHandler } from '../reqresp/protocols/block_txs/block_txs_handler.js';
|
|
60
87
|
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
|
|
61
|
-
import {
|
|
88
|
+
import {
|
|
89
|
+
AuthRequest,
|
|
90
|
+
BlockTxsRequest,
|
|
91
|
+
BlockTxsResponse,
|
|
92
|
+
StatusMessage,
|
|
93
|
+
pingHandler,
|
|
94
|
+
reqRespBlockHandler,
|
|
95
|
+
reqRespStatusHandler,
|
|
96
|
+
reqRespTxHandler,
|
|
97
|
+
} from '../reqresp/protocols/index.js';
|
|
62
98
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
63
|
-
import type { P2PService, PeerDiscoveryService } from '../service.js';
|
|
64
|
-
|
|
65
|
-
interface MessageValidator {
|
|
66
|
-
validator: {
|
|
67
|
-
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
68
|
-
};
|
|
69
|
-
severity: PeerErrorSeverity;
|
|
70
|
-
}
|
|
99
|
+
import type { P2PBlockReceivedCallback, P2PService, PeerDiscoveryService } from '../service.js';
|
|
100
|
+
import { P2PInstrumentation } from './instrumentation.js';
|
|
71
101
|
|
|
72
102
|
interface ValidationResult {
|
|
73
103
|
name: string;
|
|
@@ -77,66 +107,79 @@ interface ValidationResult {
|
|
|
77
107
|
|
|
78
108
|
type ValidationOutcome = { allPassed: true } | { allPassed: false; failure: ValidationResult };
|
|
79
109
|
|
|
110
|
+
// REFACTOR: Unify with the type above
|
|
111
|
+
type ReceivedMessageValidationResult<T> =
|
|
112
|
+
| { obj: T; result: Exclude<TopicValidatorResult, TopicValidatorResult.Reject> }
|
|
113
|
+
| { obj?: undefined; result: TopicValidatorResult.Reject };
|
|
114
|
+
|
|
80
115
|
/**
|
|
81
116
|
* Lib P2P implementation of the P2PService interface.
|
|
82
117
|
*/
|
|
83
|
-
export class LibP2PService<T extends P2PClientType> extends WithTracer implements P2PService {
|
|
118
|
+
export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends WithTracer implements P2PService {
|
|
84
119
|
private jobQueue: SerialQueue = new SerialQueue();
|
|
85
|
-
private peerManager: PeerManager;
|
|
86
120
|
private discoveryRunningPromise?: RunningPromise;
|
|
121
|
+
private msgIdSeenValidators: Record<TopicType, MessageSeenValidator> = {} as Record<TopicType, MessageSeenValidator>;
|
|
87
122
|
|
|
88
123
|
// Message validators
|
|
89
124
|
private attestationValidator: AttestationValidator;
|
|
90
125
|
private blockProposalValidator: BlockProposalValidator;
|
|
91
126
|
|
|
92
|
-
|
|
93
|
-
|
|
127
|
+
private protocolVersion = '';
|
|
128
|
+
private topicStrings: Record<TopicType, string> = {} as Record<TopicType, string>;
|
|
129
|
+
|
|
130
|
+
private feesCache: { blockNumber: number; gasFees: GasFees } | undefined;
|
|
94
131
|
|
|
95
132
|
/**
|
|
96
133
|
* Callback for when a block is received from a peer.
|
|
97
134
|
* @param block - The block received from the peer.
|
|
98
135
|
* @returns The attestation for the block, if any.
|
|
99
136
|
*/
|
|
100
|
-
private blockReceivedCallback:
|
|
137
|
+
private blockReceivedCallback: P2PBlockReceivedCallback;
|
|
138
|
+
|
|
139
|
+
private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
|
|
140
|
+
|
|
141
|
+
private instrumentation: P2PInstrumentation;
|
|
101
142
|
|
|
102
143
|
constructor(
|
|
103
144
|
private clientType: T,
|
|
104
145
|
private config: P2PConfig,
|
|
105
|
-
|
|
146
|
+
protected node: PubSubLibp2p,
|
|
106
147
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
107
|
-
private
|
|
108
|
-
private
|
|
109
|
-
|
|
148
|
+
private reqresp: ReqRespInterface,
|
|
149
|
+
private peerManager: PeerManagerInterface,
|
|
150
|
+
protected mempools: MemPools<T>,
|
|
151
|
+
private archiver: L2BlockSource & ContractDataSource,
|
|
152
|
+
private epochCache: EpochCacheInterface,
|
|
110
153
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
111
154
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
112
155
|
telemetry: TelemetryClient,
|
|
113
|
-
|
|
156
|
+
protected logger = createLogger('p2p:libp2p_service'),
|
|
114
157
|
) {
|
|
115
158
|
super(telemetry, 'LibP2PService');
|
|
116
159
|
|
|
117
|
-
|
|
118
|
-
this.reqresp = new ReqResp(config, node, peerScoring);
|
|
160
|
+
this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
|
|
119
161
|
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
config,
|
|
124
|
-
telemetry,
|
|
125
|
-
createLogger(`${logger.module}:peer_manager`),
|
|
126
|
-
peerScoring,
|
|
127
|
-
this.reqresp,
|
|
128
|
-
);
|
|
162
|
+
this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
163
|
+
this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
164
|
+
this.msgIdSeenValidators[TopicType.block_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
|
|
129
165
|
|
|
130
|
-
|
|
131
|
-
this.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this.
|
|
166
|
+
const versions = getVersions(config);
|
|
167
|
+
this.protocolVersion = compressComponentVersions(versions);
|
|
168
|
+
logger.info(`Started libp2p service with protocol version ${this.protocolVersion}`);
|
|
169
|
+
|
|
170
|
+
this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
|
|
171
|
+
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
172
|
+
this.topicStrings[TopicType.block_attestation] = createTopicString(
|
|
173
|
+
TopicType.block_attestation,
|
|
174
|
+
this.protocolVersion,
|
|
175
|
+
);
|
|
135
176
|
|
|
136
177
|
this.attestationValidator = new AttestationValidator(epochCache);
|
|
137
|
-
this.blockProposalValidator = new BlockProposalValidator(epochCache);
|
|
178
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, { txsPermitted: !config.disableTransactions });
|
|
179
|
+
|
|
180
|
+
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
138
181
|
|
|
139
|
-
this.blockReceivedCallback = async (block: BlockProposal): Promise<BlockAttestation | undefined> => {
|
|
182
|
+
this.blockReceivedCallback = async (block: BlockProposal): Promise<BlockAttestation[] | undefined> => {
|
|
140
183
|
this.logger.debug(
|
|
141
184
|
`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber.toNumber()} from peer.`,
|
|
142
185
|
{ p2pMessageIdentifier: await block.p2pMessageIdentifier() },
|
|
@@ -145,6 +188,10 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
145
188
|
};
|
|
146
189
|
}
|
|
147
190
|
|
|
191
|
+
public updateConfig(config: Partial<P2PReqRespConfig>) {
|
|
192
|
+
this.reqresp.updateConfig(config);
|
|
193
|
+
}
|
|
194
|
+
|
|
148
195
|
/**
|
|
149
196
|
* Creates an instance of the LibP2P service.
|
|
150
197
|
* @param config - The configuration to use when creating the service.
|
|
@@ -154,69 +201,151 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
154
201
|
public static async new<T extends P2PClientType>(
|
|
155
202
|
clientType: T,
|
|
156
203
|
config: P2PConfig,
|
|
157
|
-
peerDiscoveryService: PeerDiscoveryService,
|
|
158
204
|
peerId: PeerId,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
205
|
+
deps: {
|
|
206
|
+
mempools: MemPools<T>;
|
|
207
|
+
l2BlockSource: L2BlockSource & ContractDataSource;
|
|
208
|
+
epochCache: EpochCacheInterface;
|
|
209
|
+
proofVerifier: ClientProtocolCircuitVerifier;
|
|
210
|
+
worldStateSynchronizer: WorldStateSynchronizer;
|
|
211
|
+
peerStore: AztecAsyncKVStore;
|
|
212
|
+
telemetry: TelemetryClient;
|
|
213
|
+
logger: Logger;
|
|
214
|
+
packageVersion: string;
|
|
215
|
+
},
|
|
167
216
|
) {
|
|
168
|
-
const {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
217
|
+
const {
|
|
218
|
+
worldStateSynchronizer,
|
|
219
|
+
epochCache,
|
|
220
|
+
l2BlockSource,
|
|
221
|
+
mempools,
|
|
222
|
+
proofVerifier,
|
|
223
|
+
peerStore,
|
|
224
|
+
telemetry,
|
|
225
|
+
logger,
|
|
226
|
+
packageVersion,
|
|
227
|
+
} = deps;
|
|
228
|
+
const { p2pPort, maxPeerCount, listenAddress } = config;
|
|
229
|
+
const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
|
|
172
230
|
|
|
173
|
-
const datastore = new AztecDatastore(
|
|
231
|
+
const datastore = new AztecDatastore(peerStore);
|
|
174
232
|
|
|
175
233
|
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry);
|
|
176
234
|
|
|
177
|
-
|
|
235
|
+
const peerDiscoveryService = new DiscV5Service(
|
|
236
|
+
peerId,
|
|
237
|
+
config,
|
|
238
|
+
packageVersion,
|
|
239
|
+
telemetry,
|
|
240
|
+
createLogger(`${logger.module}:discv5_service`),
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
// Seed libp2p's bootstrap discovery with private and trusted peers
|
|
244
|
+
const bootstrapNodes = [...config.privatePeers, ...config.trustedPeers];
|
|
245
|
+
|
|
178
246
|
const peerDiscovery = [];
|
|
179
|
-
if (
|
|
180
|
-
peerDiscovery.push(bootstrap({ list:
|
|
247
|
+
if (bootstrapNodes.length > 0) {
|
|
248
|
+
peerDiscovery.push(bootstrap({ list: bootstrapNodes }));
|
|
181
249
|
}
|
|
182
250
|
|
|
251
|
+
const versions = getVersions(config);
|
|
252
|
+
const protocolVersion = compressComponentVersions(versions);
|
|
253
|
+
|
|
254
|
+
const txTopic = createTopicString(TopicType.tx, protocolVersion);
|
|
255
|
+
const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
|
|
256
|
+
const blockAttestationTopic = createTopicString(TopicType.block_attestation, protocolVersion);
|
|
257
|
+
|
|
258
|
+
const preferredPeersEnrs: ENR[] = config.preferredPeers.map(enr => ENR.decodeTxt(enr));
|
|
259
|
+
const directPeers = (
|
|
260
|
+
await Promise.all(
|
|
261
|
+
preferredPeersEnrs.map(async enr => {
|
|
262
|
+
const peerId = await enr.peerId();
|
|
263
|
+
const address = enr.getLocationMultiaddr('tcp');
|
|
264
|
+
if (address === undefined) {
|
|
265
|
+
throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
id: peerId,
|
|
269
|
+
addrs: [address],
|
|
270
|
+
};
|
|
271
|
+
}),
|
|
272
|
+
)
|
|
273
|
+
).filter(peer => peer !== undefined);
|
|
274
|
+
|
|
275
|
+
const announceTcpMultiaddr = config.p2pIp ? [convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')] : [];
|
|
276
|
+
|
|
183
277
|
const node = await createLibp2p({
|
|
184
278
|
start: false,
|
|
185
279
|
peerId,
|
|
186
280
|
addresses: {
|
|
187
281
|
listen: [bindAddrTcp],
|
|
188
|
-
announce:
|
|
282
|
+
announce: announceTcpMultiaddr,
|
|
189
283
|
},
|
|
190
284
|
transports: [
|
|
191
285
|
tcp({
|
|
192
|
-
|
|
286
|
+
// It's better to have this number a bit higher than our maxPeerCount because it's sets the limit on transport (TCP) layer
|
|
287
|
+
// 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
|
|
288
|
+
// If we hit the limit, the connection will be temporarily accepted and immediately dropped.
|
|
289
|
+
// Docs: https://nodejs.org/api/net.html#servermaxconnections
|
|
290
|
+
maxConnections: maxPeerCount * 2,
|
|
193
291
|
// socket option: the maximum length of the queue of pending connections
|
|
194
|
-
// https://nodejs.org/dist/latest-
|
|
292
|
+
// https://nodejs.org/dist/latest-v22.x/docs/api/net.html#serverlisten
|
|
195
293
|
// it's not safe if we increase this number
|
|
196
294
|
backlog: 5,
|
|
197
295
|
closeServerOnMaxConnections: {
|
|
198
|
-
|
|
199
|
-
|
|
296
|
+
// The property `maxConnections` will protect us against the most DDOS attack
|
|
297
|
+
// This property protects us in case of burst of new connections where server is not able to close them quickly enough
|
|
298
|
+
// In case closeAbove is reached, the server stops listening altogether
|
|
299
|
+
// It's important that there is enough difference between closeAbove and listenAbove,
|
|
300
|
+
// otherwise the server.listener will flap between being closed and open potentially degrading perf even more
|
|
301
|
+
closeAbove: maxPeerCount * 3,
|
|
302
|
+
listenBelow: Math.floor(maxPeerCount * 0.9),
|
|
200
303
|
},
|
|
201
304
|
}),
|
|
202
305
|
],
|
|
203
306
|
datastore,
|
|
204
307
|
peerDiscovery,
|
|
205
|
-
streamMuxers: [
|
|
308
|
+
streamMuxers: [yamux(), mplex()],
|
|
206
309
|
connectionEncryption: [noise()],
|
|
207
310
|
connectionManager: {
|
|
208
|
-
minConnections: 0,
|
|
209
|
-
|
|
311
|
+
minConnections: 0, // Disable libp2p peer dialing, we do it manually
|
|
312
|
+
// We set maxConnections above maxPeerCount because if we hit limit of maxPeerCount
|
|
313
|
+
// libp2p will start aggressively rejecting all new connections, preventing network discovery and crawling.
|
|
314
|
+
maxConnections: maxPeerCount * 2,
|
|
210
315
|
maxParallelDials: 100,
|
|
211
316
|
dialTimeout: 30_000,
|
|
212
317
|
maxPeerAddrsToDial: 5,
|
|
213
318
|
maxIncomingPendingConnections: 5,
|
|
214
319
|
},
|
|
320
|
+
connectionGater: {
|
|
321
|
+
denyInboundConnection: (maConn: MultiaddrConnection) => {
|
|
322
|
+
const allowed = peerManager.isNodeAllowedToConnect(maConn.remoteAddr.nodeAddress().address);
|
|
323
|
+
if (allowed) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
logger.debug(`Connection gater: Denying inbound connection from ${maConn.remoteAddr.toString()}`);
|
|
328
|
+
return true;
|
|
329
|
+
},
|
|
330
|
+
denyInboundEncryptedConnection: (peerId: PeerId, _maConn: MultiaddrConnection) => {
|
|
331
|
+
//NOTE: it is not necessary to check address here because this was already done by
|
|
332
|
+
// denyInboundConnection
|
|
333
|
+
const allowed = peerManager.isNodeAllowedToConnect(peerId);
|
|
334
|
+
if (allowed) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
logger.debug(`Connection gater: Denying inbound encrypted connection from ${peerId.toString()}`);
|
|
339
|
+
return true;
|
|
340
|
+
},
|
|
341
|
+
},
|
|
215
342
|
services: {
|
|
216
343
|
identify: identify({
|
|
217
344
|
protocolPrefix: 'aztec',
|
|
345
|
+
runOnConnectionOpen: true,
|
|
218
346
|
}),
|
|
219
347
|
pubsub: gossipsub({
|
|
348
|
+
directPeers,
|
|
220
349
|
debugName: 'gossipsub',
|
|
221
350
|
globalSignaturePolicy: SignaturePolicy.StrictNoSign,
|
|
222
351
|
allowPublishToZeroTopicPeers: true,
|
|
@@ -228,29 +357,30 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
228
357
|
heartbeatInterval: config.gossipsubInterval,
|
|
229
358
|
mcacheLength: config.gossipsubMcacheLength,
|
|
230
359
|
mcacheGossip: config.gossipsubMcacheGossip,
|
|
360
|
+
seenTTL: config.gossipsubSeenTTL,
|
|
231
361
|
msgIdFn: getMsgIdFn,
|
|
232
362
|
msgIdToStrFn: msgIdToStrFn,
|
|
233
363
|
fastMsgIdFn: fastMsgIdFn,
|
|
234
364
|
dataTransform: new SnappyTransform(),
|
|
235
365
|
metricsRegister: otelMetricsAdapter,
|
|
236
|
-
metricsTopicStrToLabel: metricsTopicStrToLabels(),
|
|
366
|
+
metricsTopicStrToLabel: metricsTopicStrToLabels(protocolVersion),
|
|
237
367
|
asyncValidation: true,
|
|
238
368
|
scoreThresholds: gossipScoreThresholds,
|
|
239
369
|
scoreParams: createPeerScoreParams({
|
|
240
370
|
// IPColocation factor can be disabled for local testing - default to -5
|
|
241
371
|
IPColocationFactorWeight: config.debugDisableColocationPenalty ? 0 : -5.0,
|
|
242
372
|
topics: {
|
|
243
|
-
[
|
|
373
|
+
[txTopic]: createTopicScoreParams({
|
|
244
374
|
topicWeight: 1,
|
|
245
375
|
invalidMessageDeliveriesWeight: -20,
|
|
246
376
|
invalidMessageDeliveriesDecay: 0.5,
|
|
247
377
|
}),
|
|
248
|
-
[
|
|
378
|
+
[blockAttestationTopic]: createTopicScoreParams({
|
|
249
379
|
topicWeight: 1,
|
|
250
380
|
invalidMessageDeliveriesWeight: -20,
|
|
251
381
|
invalidMessageDeliveriesDecay: 0.5,
|
|
252
382
|
}),
|
|
253
|
-
[
|
|
383
|
+
[blockProposalTopic]: createTopicScoreParams({
|
|
254
384
|
topicWeight: 1,
|
|
255
385
|
invalidMessageDeliveriesWeight: -20,
|
|
256
386
|
invalidMessageDeliveriesDecay: 0.5,
|
|
@@ -265,11 +395,34 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
265
395
|
logger: createLibp2pComponentLogger(logger.module),
|
|
266
396
|
});
|
|
267
397
|
|
|
398
|
+
const peerScoring = new PeerScoring(config);
|
|
399
|
+
const reqresp = new ReqResp(config, node, peerScoring, createLogger(`${logger.module}:reqresp`));
|
|
400
|
+
|
|
401
|
+
const peerManager = new PeerManager(
|
|
402
|
+
node,
|
|
403
|
+
peerDiscoveryService,
|
|
404
|
+
config,
|
|
405
|
+
telemetry,
|
|
406
|
+
createLogger(`${logger.module}:peer_manager`),
|
|
407
|
+
peerScoring,
|
|
408
|
+
reqresp,
|
|
409
|
+
worldStateSynchronizer,
|
|
410
|
+
protocolVersion,
|
|
411
|
+
epochCache,
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
// Update gossipsub score params
|
|
415
|
+
node.services.pubsub.score.params.appSpecificWeight = 10;
|
|
416
|
+
node.services.pubsub.score.params.appSpecificScore = (peerId: string) =>
|
|
417
|
+
peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
|
|
418
|
+
|
|
268
419
|
return new LibP2PService(
|
|
269
420
|
clientType,
|
|
270
421
|
config,
|
|
271
422
|
node,
|
|
272
423
|
peerDiscoveryService,
|
|
424
|
+
reqresp,
|
|
425
|
+
peerManager,
|
|
273
426
|
mempools,
|
|
274
427
|
l2BlockSource,
|
|
275
428
|
epochCache,
|
|
@@ -291,37 +444,51 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
291
444
|
}
|
|
292
445
|
|
|
293
446
|
// Get listen & announce addresses for logging
|
|
294
|
-
const {
|
|
295
|
-
if (!
|
|
447
|
+
const { p2pIp, p2pPort } = this.config;
|
|
448
|
+
if (!p2pIp) {
|
|
296
449
|
throw new Error('Announce address not provided.');
|
|
297
450
|
}
|
|
298
|
-
const announceTcpMultiaddr = convertToMultiaddr(
|
|
451
|
+
const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
|
|
299
452
|
|
|
300
453
|
// Start job queue, peer discovery service and libp2p node
|
|
301
454
|
this.jobQueue.start();
|
|
302
|
-
|
|
455
|
+
|
|
456
|
+
await this.peerManager.initializePeers();
|
|
457
|
+
if (!this.config.p2pDiscoveryDisabled) {
|
|
458
|
+
await this.peerDiscoveryService.start();
|
|
459
|
+
}
|
|
303
460
|
await this.node.start();
|
|
304
461
|
|
|
305
462
|
// Subscribe to standard GossipSub topics by default
|
|
306
|
-
for (const topic of
|
|
307
|
-
this.subscribeToTopic(
|
|
463
|
+
for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)) {
|
|
464
|
+
this.subscribeToTopic(this.topicStrings[topic]);
|
|
308
465
|
}
|
|
309
466
|
|
|
310
467
|
// Create request response protocol handlers
|
|
311
468
|
const txHandler = reqRespTxHandler(this.mempools);
|
|
312
469
|
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
313
|
-
const blockHandler = reqRespBlockHandler(this.
|
|
470
|
+
const blockHandler = reqRespBlockHandler(this.archiver);
|
|
471
|
+
const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
|
|
314
472
|
|
|
315
|
-
const requestResponseHandlers = {
|
|
473
|
+
const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
|
|
316
474
|
[ReqRespSubProtocol.PING]: pingHandler,
|
|
317
|
-
[ReqRespSubProtocol.STATUS]: statusHandler,
|
|
318
|
-
[ReqRespSubProtocol.TX]: txHandler.bind(this),
|
|
475
|
+
[ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
|
|
319
476
|
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
320
477
|
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
321
478
|
};
|
|
322
479
|
|
|
480
|
+
// Only handle block transactions request if attestation pool is available to the client
|
|
481
|
+
if (this.mempools.attestationPool && !this.config.disableTransactions) {
|
|
482
|
+
const blockTxsHandler = reqRespBlockTxsHandler(this.mempools.attestationPool, this.mempools.txPool);
|
|
483
|
+
requestResponseHandlers[ReqRespSubProtocol.BLOCK_TXS] = blockTxsHandler.bind(this);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (!this.config.disableTransactions) {
|
|
487
|
+
requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this);
|
|
488
|
+
}
|
|
489
|
+
|
|
323
490
|
// add GossipSub listener
|
|
324
|
-
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.
|
|
491
|
+
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
325
492
|
|
|
326
493
|
// Start running promise for peer discovery
|
|
327
494
|
this.discoveryRunningPromise = new RunningPromise(
|
|
@@ -335,11 +502,13 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
335
502
|
const reqrespSubProtocolValidators = {
|
|
336
503
|
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
337
504
|
// TODO(#11336): A request validator for blocks
|
|
338
|
-
[ReqRespSubProtocol.TX]: this.
|
|
505
|
+
[ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
|
|
506
|
+
[ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
|
|
339
507
|
};
|
|
340
508
|
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
341
509
|
this.logger.info(`Started P2P service`, {
|
|
342
|
-
listen:
|
|
510
|
+
listen: this.config.listenAddress,
|
|
511
|
+
port: this.config.p2pPort,
|
|
343
512
|
announce: announceTcpMultiaddr,
|
|
344
513
|
peerId: this.node.peerId.toString(),
|
|
345
514
|
});
|
|
@@ -351,7 +520,7 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
351
520
|
*/
|
|
352
521
|
public async stop() {
|
|
353
522
|
// Remove gossip sub listener
|
|
354
|
-
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.
|
|
523
|
+
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
|
|
355
524
|
|
|
356
525
|
// Stop peer manager
|
|
357
526
|
this.logger.debug('Stopping peer manager...');
|
|
@@ -370,6 +539,18 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
370
539
|
this.logger.info('LibP2P service stopped');
|
|
371
540
|
}
|
|
372
541
|
|
|
542
|
+
addReqRespSubProtocol(
|
|
543
|
+
subProtocol: ReqRespSubProtocol,
|
|
544
|
+
handler: ReqRespSubProtocolHandler,
|
|
545
|
+
validator?: ReqRespSubProtocolValidators[ReqRespSubProtocol],
|
|
546
|
+
): Promise<void> {
|
|
547
|
+
return this.reqresp.addSubProtocol(subProtocol, handler, validator);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
public registerThisValidatorAddresses(address: EthAddress[]): void {
|
|
551
|
+
this.peerManager.registerThisValidatorAddresses(address);
|
|
552
|
+
}
|
|
553
|
+
|
|
373
554
|
public getPeers(includePending?: boolean): PeerInfo[] {
|
|
374
555
|
return this.peerManager.getPeers(includePending);
|
|
375
556
|
}
|
|
@@ -387,23 +568,6 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
387
568
|
setImmediate(() => void safeJob());
|
|
388
569
|
}
|
|
389
570
|
|
|
390
|
-
/**
|
|
391
|
-
* Send Request via the ReqResp service
|
|
392
|
-
* The subprotocol defined will determine the request and response types
|
|
393
|
-
*
|
|
394
|
-
* See the subProtocolMap for the mapping of subprotocols to request/response types in `interface.ts`
|
|
395
|
-
*
|
|
396
|
-
* @param protocol The request response protocol to use
|
|
397
|
-
* @param request The request type to send
|
|
398
|
-
* @returns
|
|
399
|
-
*/
|
|
400
|
-
sendRequest<SubProtocol extends ReqRespSubProtocol>(
|
|
401
|
-
protocol: SubProtocol,
|
|
402
|
-
request: InstanceType<SubProtocolMap[SubProtocol]['request']>,
|
|
403
|
-
): Promise<InstanceType<SubProtocolMap[SubProtocol]['response']> | undefined> {
|
|
404
|
-
return this.reqresp.sendRequest(protocol, request);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
571
|
/**
|
|
408
572
|
* Send a batch of requests to peers, and return the responses
|
|
409
573
|
* @param protocol - The request response protocol to use
|
|
@@ -413,8 +577,9 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
413
577
|
sendBatchRequest<SubProtocol extends ReqRespSubProtocol>(
|
|
414
578
|
protocol: SubProtocol,
|
|
415
579
|
requests: InstanceType<SubProtocolMap[SubProtocol]['request']>[],
|
|
416
|
-
|
|
417
|
-
|
|
580
|
+
pinnedPeerId: PeerId | undefined,
|
|
581
|
+
): Promise<InstanceType<SubProtocolMap[SubProtocol]['response']>[]> {
|
|
582
|
+
return this.reqresp.sendBatchRequest(protocol, requests, pinnedPeerId);
|
|
418
583
|
}
|
|
419
584
|
|
|
420
585
|
/**
|
|
@@ -425,9 +590,8 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
425
590
|
return this.peerDiscoveryService.getEnr();
|
|
426
591
|
}
|
|
427
592
|
|
|
428
|
-
public registerBlockReceivedCallback(callback:
|
|
593
|
+
public registerBlockReceivedCallback(callback: P2PBlockReceivedCallback) {
|
|
429
594
|
this.blockReceivedCallback = callback;
|
|
430
|
-
this.logger.verbose('Block received callback registered');
|
|
431
595
|
}
|
|
432
596
|
|
|
433
597
|
/**
|
|
@@ -444,160 +608,279 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
444
608
|
/**
|
|
445
609
|
* Publishes data to a topic.
|
|
446
610
|
* @param topic - The topic to publish to.
|
|
447
|
-
* @param data - The
|
|
611
|
+
* @param data - The message to publish.
|
|
448
612
|
* @returns The number of recipients the data was sent to.
|
|
449
613
|
*/
|
|
450
|
-
private async publishToTopic(topic: string,
|
|
614
|
+
private async publishToTopic(topic: string, message: Gossipable) {
|
|
451
615
|
if (!this.node.services.pubsub) {
|
|
452
616
|
throw new Error('Pubsub service not available.');
|
|
453
617
|
}
|
|
454
|
-
const
|
|
455
|
-
|
|
618
|
+
const p2pMessage = P2PMessage.fromGossipable(message);
|
|
619
|
+
const result = await this.node.services.pubsub.publish(topic, p2pMessage.toMessageData());
|
|
456
620
|
return result.recipients.length;
|
|
457
621
|
}
|
|
458
622
|
|
|
623
|
+
/**
|
|
624
|
+
* Checks if this message has already been seen, based on its msgId computed from hashing the message data.
|
|
625
|
+
* Note that we do not rely on the seenCache from gossipsub since we want to keep a longer history of seen
|
|
626
|
+
* messages to avoid tx echoes across the network.
|
|
627
|
+
*/
|
|
628
|
+
protected preValidateReceivedMessage(
|
|
629
|
+
msg: Message,
|
|
630
|
+
msgId: string,
|
|
631
|
+
source: PeerId,
|
|
632
|
+
): { result: boolean; topicType?: TopicType } {
|
|
633
|
+
let topicType: TopicType | undefined;
|
|
634
|
+
|
|
635
|
+
switch (msg.topic) {
|
|
636
|
+
case this.topicStrings[TopicType.tx]:
|
|
637
|
+
topicType = TopicType.tx;
|
|
638
|
+
break;
|
|
639
|
+
case this.topicStrings[TopicType.block_attestation]:
|
|
640
|
+
topicType = TopicType.block_attestation;
|
|
641
|
+
break;
|
|
642
|
+
case this.topicStrings[TopicType.block_proposal]:
|
|
643
|
+
topicType = TopicType.block_proposal;
|
|
644
|
+
break;
|
|
645
|
+
default:
|
|
646
|
+
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
|
|
647
|
+
break;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
const validator = topicType ? this.msgIdSeenValidators[topicType] : undefined;
|
|
651
|
+
|
|
652
|
+
if (!validator || !validator.addMessage(msgId)) {
|
|
653
|
+
this.instrumentation.incMessagePrevalidationStatus(false, topicType);
|
|
654
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
|
|
655
|
+
return { result: false, topicType };
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
this.instrumentation.incMessagePrevalidationStatus(true, topicType);
|
|
659
|
+
|
|
660
|
+
return { result: true, topicType };
|
|
661
|
+
}
|
|
662
|
+
|
|
459
663
|
/**
|
|
460
664
|
* Handles a new gossip message that was received by the client.
|
|
461
665
|
* @param topic - The message's topic.
|
|
462
666
|
* @param data - The message data
|
|
463
667
|
*/
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
668
|
+
protected async handleNewGossipMessage(msg: Message, msgId: string, source: PeerId) {
|
|
669
|
+
const p2pMessage = P2PMessage.fromMessageData(Buffer.from(msg.data));
|
|
670
|
+
|
|
671
|
+
const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
|
|
672
|
+
|
|
673
|
+
if (!preValidationResult.result) {
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
if (msg.topic === this.topicStrings[TopicType.tx]) {
|
|
678
|
+
await this.handleGossipedTx(p2pMessage.payload, msgId, source);
|
|
467
679
|
}
|
|
468
|
-
if (msg.topic ===
|
|
469
|
-
await this.processAttestationFromPeer(
|
|
680
|
+
if (msg.topic === this.topicStrings[TopicType.block_attestation] && this.clientType === P2PClientType.Full) {
|
|
681
|
+
await this.processAttestationFromPeer(p2pMessage.payload, msgId, source);
|
|
470
682
|
}
|
|
471
|
-
if (msg.topic
|
|
472
|
-
await this.processBlockFromPeer(
|
|
683
|
+
if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
|
|
684
|
+
await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
|
|
473
685
|
}
|
|
474
686
|
|
|
475
687
|
return;
|
|
476
688
|
}
|
|
477
689
|
|
|
478
|
-
|
|
479
|
-
validationFunc: () => Promise<
|
|
690
|
+
protected async validateReceivedMessage<T>(
|
|
691
|
+
validationFunc: () => Promise<ReceivedMessageValidationResult<T>>,
|
|
480
692
|
msgId: string,
|
|
481
693
|
source: PeerId,
|
|
482
|
-
|
|
483
|
-
|
|
694
|
+
topicType: TopicType,
|
|
695
|
+
): Promise<ReceivedMessageValidationResult<T>> {
|
|
696
|
+
let resultAndObj: ReceivedMessageValidationResult<T> = { result: TopicValidatorResult.Reject };
|
|
697
|
+
const timer = new Timer();
|
|
484
698
|
try {
|
|
485
699
|
resultAndObj = await validationFunc();
|
|
486
700
|
} catch (err) {
|
|
487
|
-
this.logger.error(`Error
|
|
701
|
+
this.logger.error(`Error deserializing and validating gossipsub message`, err, {
|
|
702
|
+
msgId,
|
|
703
|
+
source: source.toString(),
|
|
704
|
+
topicType,
|
|
705
|
+
});
|
|
488
706
|
}
|
|
489
707
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
);
|
|
708
|
+
if (resultAndObj.result === TopicValidatorResult.Accept) {
|
|
709
|
+
this.instrumentation.recordMessageValidation(topicType, timer);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), resultAndObj.result);
|
|
495
713
|
return resultAndObj;
|
|
496
714
|
}
|
|
497
715
|
|
|
498
|
-
|
|
499
|
-
const validationFunc = async () => {
|
|
500
|
-
const tx = Tx.fromBuffer(
|
|
501
|
-
const
|
|
502
|
-
|
|
716
|
+
protected async handleGossipedTx(payloadData: Buffer, msgId: string, source: PeerId) {
|
|
717
|
+
const validationFunc: () => Promise<ReceivedMessageValidationResult<Tx>> = async () => {
|
|
718
|
+
const tx = Tx.fromBuffer(payloadData);
|
|
719
|
+
const isValid = await this.validatePropagatedTx(tx, source);
|
|
720
|
+
const exists = isValid && (await this.mempools.txPool.hasTx(tx.getTxHash()));
|
|
721
|
+
|
|
722
|
+
this.logger.trace(`Validate propagated tx`, {
|
|
723
|
+
isValid,
|
|
724
|
+
exists,
|
|
725
|
+
[Attributes.P2P_ID]: source.toString(),
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
if (!isValid) {
|
|
729
|
+
return { result: TopicValidatorResult.Reject };
|
|
730
|
+
} else if (exists) {
|
|
731
|
+
return { result: TopicValidatorResult.Ignore, obj: tx };
|
|
732
|
+
} else {
|
|
733
|
+
return { result: TopicValidatorResult.Accept, obj: tx };
|
|
734
|
+
}
|
|
503
735
|
};
|
|
504
736
|
|
|
505
|
-
const { result, obj: tx } = await this.validateReceivedMessage<Tx>(validationFunc, msgId, source);
|
|
506
|
-
if (
|
|
737
|
+
const { result, obj: tx } = await this.validateReceivedMessage<Tx>(validationFunc, msgId, source, TopicType.tx);
|
|
738
|
+
if (result !== TopicValidatorResult.Accept || !tx) {
|
|
507
739
|
return;
|
|
508
740
|
}
|
|
509
|
-
|
|
741
|
+
|
|
742
|
+
const txHash = tx.getTxHash();
|
|
510
743
|
const txHashString = txHash.toString();
|
|
511
|
-
this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()}
|
|
744
|
+
this.logger.verbose(`Received tx ${txHashString} from external peer ${source.toString()} via gossip`, {
|
|
745
|
+
source: source.toString(),
|
|
746
|
+
txHash: txHashString,
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
if (this.config.dropTransactions && randomInt(1000) < this.config.dropTransactionsProbability * 1000) {
|
|
750
|
+
this.logger.warn(`Intentionally dropping tx ${txHashString} (probability rule)`);
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
|
|
512
754
|
await this.mempools.txPool.addTxs([tx]);
|
|
513
755
|
}
|
|
514
756
|
|
|
515
|
-
/**
|
|
757
|
+
/**
|
|
758
|
+
* Process Attestation From Peer
|
|
516
759
|
* When a proposal is received from a peer, we add it to the attestation pool, so it can be accessed by other services.
|
|
517
760
|
*
|
|
518
761
|
* @param attestation - The attestation to process.
|
|
519
762
|
*/
|
|
520
|
-
private async processAttestationFromPeer(
|
|
521
|
-
const validationFunc = async () => {
|
|
522
|
-
const attestation = BlockAttestation.fromBuffer(
|
|
523
|
-
const
|
|
524
|
-
this.
|
|
525
|
-
|
|
763
|
+
private async processAttestationFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
764
|
+
const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockAttestation>> = async () => {
|
|
765
|
+
const attestation = BlockAttestation.fromBuffer(payloadData);
|
|
766
|
+
const isValid = await this.validateAttestation(source, attestation);
|
|
767
|
+
const exists = isValid && (await this.mempools.attestationPool!.hasAttestation(attestation));
|
|
768
|
+
|
|
769
|
+
this.logger.trace(`Validate propagated block attestation`, {
|
|
770
|
+
isValid,
|
|
771
|
+
exists,
|
|
772
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString(),
|
|
526
773
|
[Attributes.P2P_ID]: source.toString(),
|
|
527
774
|
});
|
|
528
|
-
|
|
775
|
+
|
|
776
|
+
if (!isValid) {
|
|
777
|
+
return { result: TopicValidatorResult.Reject };
|
|
778
|
+
} else if (exists) {
|
|
779
|
+
return { result: TopicValidatorResult.Ignore, obj: attestation };
|
|
780
|
+
} else {
|
|
781
|
+
return { result: TopicValidatorResult.Accept, obj: attestation };
|
|
782
|
+
}
|
|
529
783
|
};
|
|
530
784
|
|
|
531
785
|
const { result, obj: attestation } = await this.validateReceivedMessage<BlockAttestation>(
|
|
532
786
|
validationFunc,
|
|
533
787
|
msgId,
|
|
534
788
|
source,
|
|
789
|
+
TopicType.block_attestation,
|
|
535
790
|
);
|
|
536
|
-
|
|
791
|
+
|
|
792
|
+
if (result !== TopicValidatorResult.Accept || !attestation) {
|
|
537
793
|
return;
|
|
538
794
|
}
|
|
795
|
+
|
|
539
796
|
this.logger.debug(
|
|
540
|
-
`Received attestation for
|
|
797
|
+
`Received attestation for slot ${attestation.slotNumber.toNumber()} from external peer ${source.toString()}`,
|
|
541
798
|
{
|
|
542
799
|
p2pMessageIdentifier: await attestation.p2pMessageIdentifier(),
|
|
543
800
|
slot: attestation.slotNumber.toNumber(),
|
|
544
801
|
archive: attestation.archive.toString(),
|
|
545
|
-
|
|
802
|
+
source: source.toString(),
|
|
546
803
|
},
|
|
547
804
|
);
|
|
805
|
+
|
|
548
806
|
await this.mempools.attestationPool!.addAttestations([attestation]);
|
|
549
807
|
}
|
|
550
808
|
|
|
551
|
-
private async processBlockFromPeer(
|
|
552
|
-
const validationFunc = async () => {
|
|
553
|
-
const block = BlockProposal.fromBuffer(
|
|
554
|
-
const
|
|
555
|
-
|
|
556
|
-
|
|
809
|
+
private async processBlockFromPeer(payloadData: Buffer, msgId: string, source: PeerId): Promise<void> {
|
|
810
|
+
const validationFunc: () => Promise<ReceivedMessageValidationResult<BlockProposal>> = async () => {
|
|
811
|
+
const block = BlockProposal.fromBuffer(payloadData);
|
|
812
|
+
const isValid = await this.validateBlockProposal(source, block);
|
|
813
|
+
|
|
814
|
+
// Note that we dont have an attestation pool if we're a prover node, but we still
|
|
815
|
+
// subscribe to block proposal topics in order to prevent their txs from being cleared.
|
|
816
|
+
const exists = isValid && (await this.mempools.attestationPool?.hasBlockProposal(block));
|
|
817
|
+
|
|
818
|
+
this.logger.trace(`Validate propagated block proposal`, {
|
|
819
|
+
isValid,
|
|
820
|
+
exists,
|
|
821
|
+
[Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString(),
|
|
557
822
|
[Attributes.P2P_ID]: source.toString(),
|
|
558
823
|
});
|
|
559
|
-
|
|
824
|
+
|
|
825
|
+
if (!isValid) {
|
|
826
|
+
return { result: TopicValidatorResult.Reject };
|
|
827
|
+
} else if (exists) {
|
|
828
|
+
return { result: TopicValidatorResult.Ignore, obj: block };
|
|
829
|
+
} else {
|
|
830
|
+
return { result: TopicValidatorResult.Accept, obj: block };
|
|
831
|
+
}
|
|
560
832
|
};
|
|
561
833
|
|
|
562
|
-
const { result, obj: block } = await this.validateReceivedMessage<BlockProposal>(
|
|
834
|
+
const { result, obj: block } = await this.validateReceivedMessage<BlockProposal>(
|
|
835
|
+
validationFunc,
|
|
836
|
+
msgId,
|
|
837
|
+
source,
|
|
838
|
+
TopicType.block_proposal,
|
|
839
|
+
);
|
|
840
|
+
|
|
563
841
|
if (!result || !block) {
|
|
564
842
|
return;
|
|
565
843
|
}
|
|
566
|
-
|
|
844
|
+
|
|
845
|
+
await this.processValidBlockProposal(block, source);
|
|
567
846
|
}
|
|
568
847
|
|
|
569
848
|
// REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
570
849
|
@trackSpan('Libp2pService.processValidBlockProposal', async block => ({
|
|
571
|
-
[Attributes.BLOCK_NUMBER]: block.blockNumber.toNumber(),
|
|
572
850
|
[Attributes.SLOT_NUMBER]: block.slotNumber.toNumber(),
|
|
573
851
|
[Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
|
|
574
852
|
[Attributes.P2P_ID]: await block.p2pMessageIdentifier().then(i => i.toString()),
|
|
575
853
|
}))
|
|
576
|
-
private async processValidBlockProposal(block: BlockProposal) {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
);
|
|
586
|
-
|
|
854
|
+
private async processValidBlockProposal(block: BlockProposal, sender: PeerId) {
|
|
855
|
+
const slot = block.slotNumber.toBigInt();
|
|
856
|
+
const previousSlot = slot - 1n;
|
|
857
|
+
this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
|
|
858
|
+
p2pMessageIdentifier: await block.p2pMessageIdentifier(),
|
|
859
|
+
slot: block.slotNumber.toNumber(),
|
|
860
|
+
archive: block.archive.toString(),
|
|
861
|
+
source: sender.toString(),
|
|
862
|
+
});
|
|
863
|
+
const attestationsForPreviousSlot = await this.mempools.attestationPool?.getAttestationsForSlot(previousSlot);
|
|
864
|
+
if (attestationsForPreviousSlot !== undefined) {
|
|
865
|
+
this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// Mark the txs in this proposal as non-evictable
|
|
869
|
+
await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
|
|
870
|
+
await this.mempools.attestationPool?.addBlockProposal(block);
|
|
871
|
+
const attestations = await this.blockReceivedCallback(block, sender);
|
|
587
872
|
|
|
588
873
|
// TODO: fix up this pattern - the abstraction is not nice
|
|
589
874
|
// The attestation can be undefined if no handler is registered / the validator deems the block invalid
|
|
590
|
-
if (
|
|
591
|
-
|
|
592
|
-
`Broadcasting attestation for
|
|
593
|
-
{
|
|
875
|
+
if (attestations?.length) {
|
|
876
|
+
for (const attestation of attestations) {
|
|
877
|
+
this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber.toNumber()}`, {
|
|
594
878
|
p2pMessageIdentifier: await attestation.p2pMessageIdentifier(),
|
|
595
879
|
slot: attestation.slotNumber.toNumber(),
|
|
596
880
|
archive: attestation.archive.toString(),
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
await this.broadcastAttestation(attestation);
|
|
881
|
+
});
|
|
882
|
+
await this.broadcastAttestation(attestation);
|
|
883
|
+
}
|
|
601
884
|
}
|
|
602
885
|
}
|
|
603
886
|
|
|
@@ -606,8 +889,7 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
606
889
|
* @param attestation - The attestation to broadcast.
|
|
607
890
|
*/
|
|
608
891
|
@trackSpan('Libp2pService.broadcastAttestation', async attestation => ({
|
|
609
|
-
[Attributes.
|
|
610
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.globalVariables.slotNumber.toNumber(),
|
|
892
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
|
|
611
893
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
612
894
|
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then(i => i.toString()),
|
|
613
895
|
}))
|
|
@@ -632,99 +914,198 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
632
914
|
}
|
|
633
915
|
|
|
634
916
|
/**
|
|
635
|
-
* Validate
|
|
917
|
+
* Validate the requested block transactions.
|
|
918
|
+
* @param request - The block transactions request.
|
|
919
|
+
* @param response - The block transactions response.
|
|
920
|
+
* @param peerId - The ID of the peer that made the request.
|
|
921
|
+
* @returns True if the requested block transactions are valid, false otherwise.
|
|
922
|
+
*/
|
|
923
|
+
@trackSpan('Libp2pService.validateRequestedBlockTxs', request => ({
|
|
924
|
+
[Attributes.BLOCK_HASH]: request.blockHash.toString(),
|
|
925
|
+
}))
|
|
926
|
+
private async validateRequestedBlockTxs(
|
|
927
|
+
_request: BlockTxsRequest,
|
|
928
|
+
response: BlockTxsResponse,
|
|
929
|
+
peerId: PeerId,
|
|
930
|
+
): Promise<boolean> {
|
|
931
|
+
const requestedTxValidator = this.createRequestedTxValidator();
|
|
932
|
+
|
|
933
|
+
try {
|
|
934
|
+
// TODO(palla/txs): Validate that this tx belongs to the block hash being requested
|
|
935
|
+
await Promise.all(response.txs.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator)));
|
|
936
|
+
return true;
|
|
937
|
+
} catch (e: any) {
|
|
938
|
+
if (e instanceof ValidationError) {
|
|
939
|
+
this.logger.warn(`Failed validation for requested block txs from peer ${peerId.toString()}`);
|
|
940
|
+
} else {
|
|
941
|
+
this.logger.error(`Error during validation of requested block txs`, e);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
return false;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* Validate a collection of txs that has been requested from a peer.
|
|
636
950
|
*
|
|
637
|
-
* The core component of this validator is that
|
|
951
|
+
* The core component of this validator is that each tx hash MUST match the requested tx hash,
|
|
638
952
|
* In order to perform this check, the tx proof must be verified.
|
|
639
953
|
*
|
|
640
954
|
* Note: This function is called from within `ReqResp.sendRequest` as part of the
|
|
641
955
|
* ReqRespSubProtocol.TX subprotocol validation.
|
|
642
956
|
*
|
|
643
|
-
* @param requestedTxHash - The
|
|
644
|
-
* @param responseTx - The
|
|
957
|
+
* @param requestedTxHash - The collection of the txs that was requested.
|
|
958
|
+
* @param responseTx - The collectin of txs that was received as a response to the request.
|
|
645
959
|
* @param peerId - The peer ID of the peer that sent the tx.
|
|
646
|
-
* @returns True if the
|
|
960
|
+
* @returns True if the whole collection of txs is valid, false otherwise.
|
|
647
961
|
*/
|
|
648
962
|
@trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx) => ({
|
|
649
963
|
[Attributes.TX_HASH]: requestedTxHash.toString(),
|
|
650
964
|
}))
|
|
651
|
-
private async
|
|
652
|
-
const
|
|
653
|
-
const
|
|
965
|
+
private async validateRequestedTxs(requestedTxHash: TxHash[], responseTx: Tx[], peerId: PeerId): Promise<boolean> {
|
|
966
|
+
const requested = new Set(requestedTxHash.map(h => h.toString()));
|
|
967
|
+
const requestedTxValidator = this.createRequestedTxValidator();
|
|
968
|
+
|
|
969
|
+
//TODO: (mralj) - this is somewhat naive implementation, if single tx is invlid we consider the whole response invalid.
|
|
970
|
+
// I think we should still extract the valid txs and return them, so that we can still use the response.
|
|
971
|
+
try {
|
|
972
|
+
await Promise.all(responseTx.map(tx => this.validateRequestedTx(tx, peerId, requestedTxValidator, requested)));
|
|
973
|
+
return true;
|
|
974
|
+
} catch (e: any) {
|
|
975
|
+
if (e instanceof ValidationError) {
|
|
976
|
+
this.logger.warn(`Failed to validate requested txs from peer ${peerId.toString()}, reason ${e.message}`);
|
|
977
|
+
} else {
|
|
978
|
+
this.logger.error(`Error during validation of requested txs`, e);
|
|
979
|
+
}
|
|
654
980
|
|
|
655
|
-
// If the node returns the wrong data, we penalize it
|
|
656
|
-
if (!requestedTxHash.equals(await responseTx.getTxHash())) {
|
|
657
|
-
// Returning the wrong data is a low tolerance error
|
|
658
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
659
981
|
return false;
|
|
660
982
|
}
|
|
983
|
+
}
|
|
661
984
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
985
|
+
private createRequestedTxValidator(): TxValidator {
|
|
986
|
+
return new AggregateTxValidator(
|
|
987
|
+
new DataTxValidator(),
|
|
988
|
+
new MetadataTxValidator({
|
|
989
|
+
l1ChainId: new Fr(this.config.l1ChainId),
|
|
990
|
+
rollupVersion: new Fr(this.config.rollupVersion),
|
|
991
|
+
protocolContractsHash,
|
|
992
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
993
|
+
}),
|
|
994
|
+
new TxProofValidator(this.proofVerifier),
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
private async validateRequestedTx(tx: Tx, peerId: PeerId, txValidator: TxValidator, requested?: Set<`0x${string}`>) {
|
|
999
|
+
if (!(await tx.validateTxHash())) {
|
|
1000
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1001
|
+
throw new ValidationError(`Received tx with invalid hash ${tx.getTxHash().toString()}.`);
|
|
666
1002
|
}
|
|
667
1003
|
|
|
668
|
-
|
|
1004
|
+
if (requested && !requested.has(tx.getTxHash().toString())) {
|
|
1005
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1006
|
+
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that was not requested.`);
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
const { result } = await txValidator.validateTx(tx);
|
|
1010
|
+
if (result === 'invalid') {
|
|
1011
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1012
|
+
throw new ValidationError(`Received tx with hash ${tx.getTxHash().toString()} that is invalid.`);
|
|
1013
|
+
}
|
|
669
1014
|
}
|
|
670
1015
|
|
|
671
|
-
@trackSpan('Libp2pService.validatePropagatedTx',
|
|
672
|
-
[Attributes.TX_HASH]:
|
|
1016
|
+
@trackSpan('Libp2pService.validatePropagatedTx', tx => ({
|
|
1017
|
+
[Attributes.TX_HASH]: tx.getTxHash().toString(),
|
|
673
1018
|
}))
|
|
674
1019
|
private async validatePropagatedTx(tx: Tx, peerId: PeerId): Promise<boolean> {
|
|
675
|
-
const
|
|
676
|
-
const messageValidators = this.createMessageValidators(blockNumber);
|
|
677
|
-
const outcome = await this.runValidations(tx, messageValidators);
|
|
1020
|
+
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
678
1021
|
|
|
679
|
-
if (
|
|
680
|
-
|
|
1022
|
+
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1023
|
+
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1024
|
+
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1025
|
+
|
|
1026
|
+
for (const validator of messageValidators) {
|
|
1027
|
+
const outcome = await this.runValidations(tx, validator);
|
|
1028
|
+
|
|
1029
|
+
if (outcome.allPassed) {
|
|
1030
|
+
continue;
|
|
1031
|
+
}
|
|
1032
|
+
const { name } = outcome.failure;
|
|
1033
|
+
let { severity } = outcome.failure;
|
|
1034
|
+
|
|
1035
|
+
// Double spend validator has a special case handler
|
|
1036
|
+
if (name === 'doubleSpendValidator') {
|
|
1037
|
+
const txBlockNumber = currentBlockNumber + 1; // tx is expected to be in the next block
|
|
1038
|
+
severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
this.peerManager.penalizePeer(peerId, severity);
|
|
1042
|
+
return false;
|
|
681
1043
|
}
|
|
682
|
-
|
|
683
|
-
|
|
1044
|
+
return true;
|
|
1045
|
+
}
|
|
684
1046
|
|
|
685
|
-
|
|
686
|
-
if (
|
|
687
|
-
|
|
1047
|
+
private async getGasFees(blockNumber: number): Promise<GasFees> {
|
|
1048
|
+
if (blockNumber === this.feesCache?.blockNumber) {
|
|
1049
|
+
return this.feesCache.gasFees;
|
|
688
1050
|
}
|
|
689
1051
|
|
|
690
|
-
this.
|
|
691
|
-
|
|
1052
|
+
const header = await this.archiver.getBlockHeader(blockNumber);
|
|
1053
|
+
const gasFees = header?.globalVariables.gasFees ?? GasFees.empty();
|
|
1054
|
+
this.feesCache = { blockNumber, gasFees };
|
|
1055
|
+
return gasFees;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
public async validate(txs: Tx[]): Promise<void> {
|
|
1059
|
+
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1060
|
+
|
|
1061
|
+
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
1062
|
+
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1063
|
+
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1064
|
+
|
|
1065
|
+
await Promise.all(
|
|
1066
|
+
txs.map(async tx => {
|
|
1067
|
+
for (const validator of messageValidators) {
|
|
1068
|
+
const outcome = await this.runValidations(tx, validator);
|
|
1069
|
+
if (!outcome.allPassed) {
|
|
1070
|
+
throw new Error('Invalid tx detected', { cause: { outcome } });
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
}),
|
|
1074
|
+
);
|
|
692
1075
|
}
|
|
693
1076
|
|
|
694
1077
|
/**
|
|
695
|
-
* Create message validators for the given block number.
|
|
1078
|
+
* Create message validators for the given block number and timestamp.
|
|
696
1079
|
*
|
|
697
1080
|
* Each validator is a pair of a validator and a severity.
|
|
698
1081
|
* If a validator fails, the peer is penalized with the severity of the validator.
|
|
699
1082
|
*
|
|
700
|
-
* @param
|
|
1083
|
+
* @param currentBlockNumber - The current synced block number.
|
|
1084
|
+
* @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
|
|
701
1085
|
* @returns The message validators.
|
|
702
1086
|
*/
|
|
703
|
-
private createMessageValidators(
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
severity: PeerErrorSeverity.HighToleranceError,
|
|
726
|
-
},
|
|
727
|
-
};
|
|
1087
|
+
private async createMessageValidators(
|
|
1088
|
+
currentBlockNumber: number,
|
|
1089
|
+
nextSlotTimestamp: UInt64,
|
|
1090
|
+
): Promise<Record<string, MessageValidator>[]> {
|
|
1091
|
+
const gasFees = await this.getGasFees(currentBlockNumber);
|
|
1092
|
+
const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
|
|
1093
|
+
|
|
1094
|
+
const blockNumberInWhichTheTxIsConsideredToBeIncluded = currentBlockNumber + 1;
|
|
1095
|
+
|
|
1096
|
+
return createTxMessageValidators(
|
|
1097
|
+
nextSlotTimestamp,
|
|
1098
|
+
blockNumberInWhichTheTxIsConsideredToBeIncluded,
|
|
1099
|
+
this.worldStateSynchronizer,
|
|
1100
|
+
gasFees,
|
|
1101
|
+
this.config.l1ChainId,
|
|
1102
|
+
this.config.rollupVersion,
|
|
1103
|
+
protocolContractsHash,
|
|
1104
|
+
this.archiver,
|
|
1105
|
+
this.proofVerifier,
|
|
1106
|
+
!this.config.disableTransactions,
|
|
1107
|
+
allowedInSetup,
|
|
1108
|
+
);
|
|
728
1109
|
}
|
|
729
1110
|
|
|
730
1111
|
/**
|
|
@@ -739,28 +1120,26 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
739
1120
|
): Promise<ValidationOutcome> {
|
|
740
1121
|
const validationPromises = Object.entries(messageValidators).map(async ([name, { validator, severity }]) => {
|
|
741
1122
|
const { result } = await validator.validateTx(tx);
|
|
742
|
-
return { name, isValid: result
|
|
1123
|
+
return { name, isValid: result !== 'invalid', severity };
|
|
743
1124
|
});
|
|
744
1125
|
|
|
745
1126
|
// A promise that resolves when all validations have been run
|
|
746
|
-
const allValidations = Promise.all(validationPromises);
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
// If all validations pass, allPassed will be true, if failed, then the failure will be the first validation to fail
|
|
763
|
-
return result;
|
|
1127
|
+
const allValidations = await Promise.all(validationPromises);
|
|
1128
|
+
const failed = allValidations.find(x => !x.isValid);
|
|
1129
|
+
if (failed) {
|
|
1130
|
+
return {
|
|
1131
|
+
allPassed: false,
|
|
1132
|
+
failure: {
|
|
1133
|
+
isValid: { result: 'invalid' as const, reason: ['Failed validation'] },
|
|
1134
|
+
name: failed.name,
|
|
1135
|
+
severity: failed.severity,
|
|
1136
|
+
},
|
|
1137
|
+
};
|
|
1138
|
+
} else {
|
|
1139
|
+
return {
|
|
1140
|
+
allPassed: true,
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
764
1143
|
}
|
|
765
1144
|
|
|
766
1145
|
/**
|
|
@@ -804,8 +1183,7 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
804
1183
|
* @returns True if the attestation is valid, false otherwise.
|
|
805
1184
|
*/
|
|
806
1185
|
@trackSpan('Libp2pService.validateAttestation', async (_, attestation) => ({
|
|
807
|
-
[Attributes.
|
|
808
|
-
[Attributes.SLOT_NUMBER]: attestation.payload.header.globalVariables.slotNumber.toNumber(),
|
|
1186
|
+
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toNumber(),
|
|
809
1187
|
[Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
|
|
810
1188
|
[Attributes.P2P_ID]: await attestation.p2pMessageIdentifier().then(i => i.toString()),
|
|
811
1189
|
}))
|
|
@@ -826,11 +1204,12 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
826
1204
|
* @returns True if the block proposal is valid, false otherwise.
|
|
827
1205
|
*/
|
|
828
1206
|
@trackSpan('Libp2pService.validateBlockProposal', (_peerId, block) => ({
|
|
829
|
-
[Attributes.SLOT_NUMBER]: block.payload.header.
|
|
1207
|
+
[Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString(),
|
|
830
1208
|
}))
|
|
831
1209
|
public async validateBlockProposal(peerId: PeerId, block: BlockProposal): Promise<boolean> {
|
|
832
1210
|
const severity = await this.blockProposalValidator.validate(block);
|
|
833
1211
|
if (severity) {
|
|
1212
|
+
this.logger.debug(`Penalizing peer ${peerId} for block proposal validation failure`);
|
|
834
1213
|
this.peerManager.penalizePeer(peerId, severity);
|
|
835
1214
|
return false;
|
|
836
1215
|
}
|
|
@@ -842,13 +1221,17 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
842
1221
|
return this.node.services.pubsub.score.score(peerId.toString());
|
|
843
1222
|
}
|
|
844
1223
|
|
|
1224
|
+
public handleAuthRequestFromPeer(authRequest: AuthRequest, peerId: PeerId): Promise<StatusMessage> {
|
|
1225
|
+
return this.peerManager.handleAuthRequestFromPeer(authRequest, peerId);
|
|
1226
|
+
}
|
|
1227
|
+
|
|
845
1228
|
private async sendToPeers<T extends Gossipable>(message: T) {
|
|
846
1229
|
const parent = message.constructor as typeof Gossipable;
|
|
847
1230
|
|
|
848
1231
|
const identifier = await message.p2pMessageIdentifier().then(i => i.toString());
|
|
849
1232
|
this.logger.trace(`Sending message ${identifier}`, { p2pMessageIdentifier: identifier });
|
|
850
1233
|
|
|
851
|
-
const recipientsNum = await this.publishToTopic(parent.p2pTopic, message
|
|
1234
|
+
const recipientsNum = await this.publishToTopic(this.topicStrings[parent.p2pTopic], message);
|
|
852
1235
|
this.logger.debug(`Sent message ${identifier} to ${recipientsNum} peers`, {
|
|
853
1236
|
p2pMessageIdentifier: identifier,
|
|
854
1237
|
sourcePeer: this.node.peerId.toString(),
|