@aztec/p2p 5.0.0-private.20260319 → 5.0.0-rc.2
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/README.md +4 -1
- package/dest/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +22 -6
- package/dest/client/factory.d.ts +4 -3
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +33 -24
- package/dest/client/interface.d.ts +43 -11
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +33 -19
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +100 -44
- package/dest/config.d.ts +137 -107
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +64 -23
- package/dest/errors/p2p-service.error.d.ts +9 -0
- package/dest/errors/p2p-service.error.d.ts.map +1 -0
- package/dest/errors/p2p-service.error.js +10 -0
- package/dest/errors/reqresp.error.d.ts +1 -20
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/errors/reqresp.error.js +0 -21
- package/dest/index.d.ts +1 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +0 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +98 -56
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +265 -196
- 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 +175 -59
- package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +6 -4
- package/dest/mem_pools/index.d.ts +1 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +17 -1
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +1 -5
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +1 -7
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +6 -6
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +22 -5
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +5 -2
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +13 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +7 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +10 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +8 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +7 -4
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +8 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +153 -111
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +10 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +38 -16
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +4 -5
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +8 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +2 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +8 -3
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +8 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +25 -3
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +77 -14
- 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/aggregate_tx_validator.js +8 -15
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +3 -3
- package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
- package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts +15 -0
- package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +2 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +36 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +14 -15
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +36 -17
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +47 -10
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +65 -48
- package/dest/msg_validators/tx_validator/index.d.ts +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -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 +2 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/data_store.js +5 -5
- package/dest/services/discv5/discV5_service.d.ts +13 -2
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +119 -23
- package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
- package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
- package/dest/services/discv5/persisted_enr_store.js +145 -0
- package/dest/services/dummy_service.d.ts +15 -15
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +15 -16
- package/dest/services/encoding.d.ts +8 -8
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +11 -15
- package/dest/services/gossipsub/topic_score_params.d.ts +6 -12
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +4 -14
- package/dest/services/libp2p/instrumentation.d.ts +3 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +14 -0
- package/dest/services/libp2p/libp2p_service.d.ts +44 -39
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +383 -278
- package/dest/services/peer-manager/peer_manager.d.ts +20 -3
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +79 -23
- package/dest/services/peer-manager/peer_scoring.d.ts +34 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +102 -13
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -8
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +38 -44
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +8 -5
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +5 -14
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
- package/dest/services/reqresp/config.d.ts +3 -3
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/interface.d.ts +16 -18
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +10 -20
- 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 +0 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +31 -28
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -7
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +42 -24
- package/dest/services/reqresp/protocols/index.d.ts +1 -2
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +0 -1
- package/dest/services/reqresp/protocols/tx.d.ts +1 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +1 -3
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
- 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 +0 -10
- package/dest/services/reqresp/reqresp.d.ts +7 -29
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +26 -207
- package/dest/services/service.d.ts +25 -12
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +2 -23
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +2 -55
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +12 -28
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.js +43 -83
- package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.js +39 -29
- package/dest/services/tx_collection/index.d.ts +2 -3
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +0 -1
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +0 -2
- package/dest/services/tx_collection/tx_collection.d.ts +35 -51
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +275 -119
- package/dest/services/tx_collection/tx_collection_sink.d.ts +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +2 -2
- package/dest/services/tx_collection/tx_source.d.ts +6 -5
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +13 -8
- package/dest/services/tx_file_store/tx_file_store.d.ts +1 -3
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
- package/dest/services/tx_file_store/tx_file_store.js +4 -14
- package/dest/services/tx_provider.d.ts +3 -1
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +3 -0
- package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +5 -2
- package/dest/test-helpers/mock-pubsub.d.ts +23 -9
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +44 -44
- package/dest/test-helpers/reqresp-nodes.d.ts +4 -5
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +16 -18
- package/dest/test-helpers/test_tx_provider.d.ts +3 -1
- package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
- package/dest/test-helpers/test_tx_provider.js +3 -0
- package/dest/test-helpers/testbench-utils.d.ts +14 -14
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +25 -13
- package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +102 -41
- package/dest/testbench/worker_client_manager.d.ts +10 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +51 -9
- package/dest/util.d.ts +11 -6
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +35 -14
- package/dest/versioning.d.ts +3 -6
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +3 -24
- package/package.json +16 -16
- package/src/bootstrap/bootstrap.ts +17 -3
- package/src/client/factory.ts +52 -24
- package/src/client/interface.ts +38 -17
- package/src/client/p2p_client.ts +118 -76
- package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
- package/src/config.ts +130 -31
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/errors/reqresp.error.ts +0 -25
- package/src/index.ts +0 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +319 -238
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +198 -62
- package/src/mem_pools/attestation_pool/mocks.ts +13 -8
- package/src/mem_pools/index.ts +0 -3
- package/src/mem_pools/instrumentation.ts +5 -1
- package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +7 -7
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +1 -0
- package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/interfaces.ts +18 -4
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +20 -8
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +12 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +8 -4
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +163 -117
- package/src/msg_validators/attestation_validator/attestation_validator.ts +46 -15
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +15 -7
- package/src/msg_validators/proposal_validator/README.md +1 -1
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +15 -3
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +26 -3
- package/src/msg_validators/proposal_validator/proposal_validator.ts +89 -11
- package/src/msg_validators/tx_validator/README.md +13 -3
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -12
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +3 -3
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/cached_tx_validator.ts +31 -0
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +44 -1
- package/src/msg_validators/tx_validator/factory.ts +44 -20
- package/src/msg_validators/tx_validator/gas_validator.ts +99 -54
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +3 -3
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
- package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
- package/src/services/data_store.ts +5 -13
- package/src/services/discv5/discV5_service.ts +126 -14
- package/src/services/discv5/persisted_enr_store.ts +158 -0
- package/src/services/dummy_service.ts +20 -39
- package/src/services/encoding.ts +11 -21
- package/src/services/gossipsub/README.md +33 -11
- package/src/services/gossipsub/topic_score_params.ts +9 -18
- package/src/services/libp2p/instrumentation.ts +14 -0
- package/src/services/libp2p/libp2p_service.ts +436 -311
- package/src/services/peer-manager/peer_manager.ts +86 -22
- package/src/services/peer-manager/peer_scoring.ts +102 -8
- package/src/services/reqresp/README.md +0 -14
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +42 -52
- package/src/services/reqresp/batch-tx-requester/interface.ts +11 -4
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +12 -25
- package/src/services/reqresp/config.ts +2 -2
- package/src/services/reqresp/interface.ts +21 -47
- package/src/services/reqresp/metrics.ts +0 -1
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -30
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
- package/src/services/reqresp/protocols/index.ts +0 -1
- package/src/services/reqresp/protocols/tx.ts +1 -3
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
- package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
- package/src/services/reqresp/reqresp.ts +29 -252
- package/src/services/service.ts +31 -28
- package/src/services/tx_collection/config.ts +3 -80
- package/src/services/tx_collection/file_store_tx_collection.ts +54 -103
- package/src/services/tx_collection/file_store_tx_source.ts +43 -31
- package/src/services/tx_collection/index.ts +1 -6
- package/src/services/tx_collection/instrumentation.ts +1 -7
- package/src/services/tx_collection/tx_collection.ts +330 -173
- package/src/services/tx_collection/tx_collection_sink.ts +2 -2
- package/src/services/tx_collection/tx_source.ts +10 -8
- package/src/services/tx_file_store/tx_file_store.ts +5 -17
- package/src/services/tx_provider.ts +5 -0
- package/src/test-helpers/make-test-p2p-clients.ts +3 -0
- package/src/test-helpers/mock-pubsub.ts +46 -60
- package/src/test-helpers/reqresp-nodes.ts +12 -22
- package/src/test-helpers/test_tx_provider.ts +5 -0
- package/src/test-helpers/testbench-utils.ts +31 -26
- package/src/testbench/p2p_client_testbench_worker.ts +110 -55
- package/src/testbench/worker_client_manager.ts +59 -20
- package/src/util.ts +32 -17
- package/src/versioning.ts +3 -33
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -305
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
- package/dest/mem_pools/tx_pool/index.d.ts +0 -3
- package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/index.js +0 -2
- package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
- package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/priority.js +0 -15
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
- package/dest/msg_validators/clock_tolerance.d.ts +0 -21
- package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
- package/dest/msg_validators/clock_tolerance.js +0 -38
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +0 -64
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
- package/dest/services/reqresp/protocols/block.d.ts +0 -9
- package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/block.js +0 -32
- package/dest/services/tx_collection/fast_tx_collection.d.ts +0 -51
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
- package/dest/services/tx_collection/fast_tx_collection.js +0 -311
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -48
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +0 -50
- package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -57
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
- package/dest/services/tx_collection/slow_tx_collection.js +0 -211
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -344
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
- package/src/mem_pools/tx_pool/README.md +0 -270
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
- package/src/mem_pools/tx_pool/index.ts +0 -2
- package/src/mem_pools/tx_pool/priority.ts +0 -20
- package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
- package/src/msg_validators/clock_tolerance.ts +0 -52
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +0 -161
- package/src/services/reqresp/protocols/block.ts +0 -37
- package/src/services/tx_collection/fast_tx_collection.ts +0 -361
- package/src/services/tx_collection/proposal_tx_collector.ts +0 -108
- package/src/services/tx_collection/slow_tx_collection.ts +0 -266
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
+
import { compactArray } from '@aztec/foundation/collection';
|
|
2
3
|
import { makeEthSignDigest, tryRecoverAddress } from '@aztec/foundation/crypto/secp256k1-signer';
|
|
3
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
5
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -164,6 +165,7 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
164
165
|
public async heartbeat() {
|
|
165
166
|
this.heartbeatCounter++;
|
|
166
167
|
this.peerScoring.decayAllScores();
|
|
168
|
+
this.peerScoring.pruneExpiredBans();
|
|
167
169
|
this.cleanupExpiredTimeouts();
|
|
168
170
|
|
|
169
171
|
await this.setupDirectPeersIfValidator();
|
|
@@ -198,21 +200,27 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
198
200
|
.then(peerIds => peerIds.forEach(peerId => this.preferredPeers.add(peerId.toString())))
|
|
199
201
|
.catch(e => this.logger.error('Error initializing preferred peers', e));
|
|
200
202
|
|
|
201
|
-
const directPeers = (
|
|
203
|
+
const directPeers = compactArray(
|
|
202
204
|
await Promise.all(
|
|
203
205
|
preferredPeersEnrs.map(async enr => {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
try {
|
|
207
|
+
const peerId = await enr.peerId();
|
|
208
|
+
const address = enr.getLocationMultiaddr('tcp');
|
|
209
|
+
if (address === undefined) {
|
|
210
|
+
throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
id: peerId,
|
|
214
|
+
addrs: [address],
|
|
215
|
+
};
|
|
216
|
+
} catch (err) {
|
|
217
|
+
// A malformed configured ENR shouldn't abort preferred-peer setup — skip it and log.
|
|
218
|
+
this.logger.warn(`Skipping preferred peer with invalid ENR`, { err });
|
|
219
|
+
return undefined;
|
|
208
220
|
}
|
|
209
|
-
return {
|
|
210
|
-
id: peerId,
|
|
211
|
-
addrs: [address],
|
|
212
|
-
};
|
|
213
221
|
}),
|
|
214
|
-
)
|
|
215
|
-
)
|
|
222
|
+
),
|
|
223
|
+
);
|
|
216
224
|
|
|
217
225
|
await Promise.all(
|
|
218
226
|
directPeers.map(peer => {
|
|
@@ -226,20 +234,30 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
226
234
|
}
|
|
227
235
|
|
|
228
236
|
/**
|
|
229
|
-
* Cleans up expired timeouts.
|
|
237
|
+
* Cleans up expired timeouts and stale failed-auth-handshake entries.
|
|
230
238
|
*
|
|
231
239
|
* When peers fail to dial after a number of retries, they are temporarily timed out.
|
|
232
240
|
* This function removes any peers that have been in the timed out state for too long.
|
|
233
241
|
* To give them a chance to reconnect.
|
|
242
|
+
*
|
|
243
|
+
* Also evicts entries from the failed-auth-handshake map whose expiry window has passed.
|
|
244
|
+
* Without this, peers that probe once and never reconnect would leave their entries in the
|
|
245
|
+
* map forever, causing an unbounded memory leak.
|
|
234
246
|
*/
|
|
235
247
|
private cleanupExpiredTimeouts() {
|
|
236
|
-
// Clean up expired timeouts
|
|
237
248
|
const now = this.dateProvider.now();
|
|
249
|
+
|
|
238
250
|
for (const [peerId, timedOutPeer] of this.timedOutPeers.entries()) {
|
|
239
251
|
if (now >= timedOutPeer.timeoutUntilMs) {
|
|
240
252
|
this.timedOutPeers.delete(peerId);
|
|
241
253
|
}
|
|
242
254
|
}
|
|
255
|
+
|
|
256
|
+
for (const [id, entry] of this.failedAuthHandshakes.entries()) {
|
|
257
|
+
if (now - entry.lastFailureTimestamp > FAILED_AUTH_HANDSHAKE_EXPIRY_MS) {
|
|
258
|
+
this.failedAuthHandshakes.delete(id);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
243
261
|
}
|
|
244
262
|
|
|
245
263
|
/**
|
|
@@ -303,15 +321,20 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
303
321
|
*/
|
|
304
322
|
private handleDisconnectedPeerEvent(e: CustomEvent<PeerId>) {
|
|
305
323
|
const peerId = e.detail;
|
|
324
|
+
const peerIdStr = peerId.toString();
|
|
306
325
|
this.metrics.peerDisconnected(peerId);
|
|
307
|
-
this.logger.verbose(`Disconnected from peer ${
|
|
308
|
-
const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(
|
|
326
|
+
this.logger.verbose(`Disconnected from peer ${peerIdStr}`);
|
|
327
|
+
const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerIdStr);
|
|
309
328
|
if (validatorAddress !== undefined) {
|
|
310
329
|
this.logger.info(
|
|
311
|
-
`Removing authentication for validator ${validatorAddress} at peer id ${
|
|
330
|
+
`Removing authentication for validator ${validatorAddress} at peer id ${peerIdStr} due to disconnection`,
|
|
312
331
|
);
|
|
313
332
|
this.authenticatedValidatorAddressToPeerId.delete(validatorAddress.toString());
|
|
314
|
-
this.authenticatedPeerIdToValidatorAddress.delete(
|
|
333
|
+
this.authenticatedPeerIdToValidatorAddress.delete(peerIdStr);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (this.peerScoring.getScoreState(peerIdStr) === PeerScoreState.Healthy) {
|
|
337
|
+
this.peerScoring.removePeer(peerIdStr);
|
|
315
338
|
}
|
|
316
339
|
}
|
|
317
340
|
|
|
@@ -479,15 +502,38 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
479
502
|
*
|
|
480
503
|
* @returns: True if node is allowed to connect, otherwise false
|
|
481
504
|
* */
|
|
482
|
-
|
|
483
|
-
|
|
505
|
+
/**
|
|
506
|
+
* Whether a peer is allowed to connect, given its peer id. Rejects peers serving an active ban and
|
|
507
|
+
* peers that have exceeded the failed auth-handshake limit. Use this once the peer id is known —
|
|
508
|
+
* i.e. for the encrypted-inbound gater and when dialing.
|
|
509
|
+
*/
|
|
510
|
+
public isPeerAllowedToConnect(peerId: string | PeerId): boolean {
|
|
511
|
+
const id = peerId.toString();
|
|
512
|
+
if (this.peerScoring.getScoreState(id) === PeerScoreState.Banned) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
return this.isWithinFailedAuthLimit(id);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Whether a connection from an address is allowed. Bans are keyed by peer id, which isn't known at
|
|
520
|
+
* the raw-inbound layer, so only the failed auth-handshake limit (also tracked per address) is
|
|
521
|
+
* enforced here; the ban is applied once the peer id is known via {@link isPeerAllowedToConnect}.
|
|
522
|
+
*/
|
|
523
|
+
public isAddressAllowedToConnect(address: string): boolean {
|
|
524
|
+
return this.isWithinFailedAuthLimit(address);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/** Whether the failed auth-handshake count for a peer id or address is below the configured limit. */
|
|
528
|
+
private isWithinFailedAuthLimit(key: string): boolean {
|
|
529
|
+
const entry = this.failedAuthHandshakes.get(key);
|
|
484
530
|
if (!entry) {
|
|
485
531
|
return true;
|
|
486
532
|
}
|
|
487
533
|
|
|
488
534
|
// In case entry is too old, remove it and allow connection
|
|
489
535
|
if (this.dateProvider.now() - entry.lastFailureTimestamp > FAILED_AUTH_HANDSHAKE_EXPIRY_MS) {
|
|
490
|
-
this.failedAuthHandshakes.delete(
|
|
536
|
+
this.failedAuthHandshakes.delete(key);
|
|
491
537
|
return true;
|
|
492
538
|
}
|
|
493
539
|
|
|
@@ -512,6 +558,7 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
512
558
|
protectedConnections: protectedPeerCount,
|
|
513
559
|
maxPeerCount: this.config.maxPeerCount,
|
|
514
560
|
cachedPeers: this.cachedPeers.size,
|
|
561
|
+
discv5KadPeers: this.peerDiscoveryService.getKadValues().length,
|
|
515
562
|
...this.peerScoring.getStats(),
|
|
516
563
|
});
|
|
517
564
|
|
|
@@ -713,6 +760,12 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
713
760
|
return;
|
|
714
761
|
}
|
|
715
762
|
|
|
763
|
+
// Don't dial banned peers or those that have exceeded the auth failure threshold
|
|
764
|
+
if (!this.isPeerAllowedToConnect(peerId)) {
|
|
765
|
+
this.logger.trace(`Skipping peer ${peerId} due to ban or failed auth handshake attempts`);
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
|
|
716
769
|
const [multiaddrTcp] = await Promise.all([enr.getFullMultiaddr('tcp')]);
|
|
717
770
|
|
|
718
771
|
this.logger.trace(`Handling discovered peer ${peerId} at ${multiaddrTcp?.toString() ?? 'undefined address'}`);
|
|
@@ -939,6 +992,8 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
939
992
|
`Received auth for validator ${sender.toString()} from peer ${peerIdString}, but this validator is already authenticated to peer ${peerForAddress.toString()}`,
|
|
940
993
|
{ ...logData, address: sender.toString() },
|
|
941
994
|
);
|
|
995
|
+
this.markAuthHandshakeFailed(peerId);
|
|
996
|
+
this.markPeerForDisconnect(peerId);
|
|
942
997
|
return;
|
|
943
998
|
}
|
|
944
999
|
|
|
@@ -968,14 +1023,14 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
968
1023
|
const peerIdStr = peerId.toString();
|
|
969
1024
|
|
|
970
1025
|
const existingEntry = this.failedAuthHandshakes.get(peerIdStr);
|
|
1026
|
+
const failureCount = (existingEntry?.count || 0) + 1;
|
|
971
1027
|
this.failedAuthHandshakes.set(peerIdStr, {
|
|
972
|
-
count:
|
|
1028
|
+
count: failureCount,
|
|
973
1029
|
lastFailureTimestamp: now,
|
|
974
1030
|
});
|
|
975
1031
|
|
|
976
1032
|
const connections = this.libP2PNode.getConnections(peerId);
|
|
977
1033
|
connections.forEach(conn => {
|
|
978
|
-
// We mark the IP address
|
|
979
1034
|
const address = conn.remoteAddr.nodeAddress().address;
|
|
980
1035
|
const existingAddressEntry = this.failedAuthHandshakes.get(address);
|
|
981
1036
|
this.failedAuthHandshakes.set(address, {
|
|
@@ -983,6 +1038,15 @@ export class PeerManager implements PeerManagerInterface {
|
|
|
983
1038
|
lastFailureTimestamp: now,
|
|
984
1039
|
});
|
|
985
1040
|
});
|
|
1041
|
+
|
|
1042
|
+
// Ban the peer from being re-dialed for a cooldown period (exponential backoff)
|
|
1043
|
+
const banTimeMs = this.config.peerFailedBanTimeMs ?? DEFAULT_FAILED_PEER_BAN_TIME_MS;
|
|
1044
|
+
const backoffMs = banTimeMs * Math.pow(2, Math.min(failureCount - 1, 5));
|
|
1045
|
+
this.timedOutPeers.set(peerIdStr, {
|
|
1046
|
+
peerId: peerIdStr,
|
|
1047
|
+
timeoutUntilMs: now + backoffMs,
|
|
1048
|
+
});
|
|
1049
|
+
this.cachedPeers.delete(peerIdStr);
|
|
986
1050
|
}
|
|
987
1051
|
|
|
988
1052
|
/*
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { median } from '@aztec/foundation/collection';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
3
4
|
import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
4
5
|
import {
|
|
5
6
|
Attributes,
|
|
@@ -54,6 +55,10 @@ export enum PeerScoreState {
|
|
|
54
55
|
// TODO: move into config / constants
|
|
55
56
|
const MIN_SCORE_BEFORE_BAN = -100;
|
|
56
57
|
const MIN_SCORE_BEFORE_DISCONNECT = -50;
|
|
58
|
+
const SCORE_CLEANUP_THRESHOLD = 0.1;
|
|
59
|
+
|
|
60
|
+
/** An active ban: the score the peer held when banned, and the timestamp at which the ban lifts. */
|
|
61
|
+
type BanRecord = { score: number; expiry: number };
|
|
57
62
|
|
|
58
63
|
export class PeerScoring {
|
|
59
64
|
private logger = createLogger('p2p:peer-scoring');
|
|
@@ -65,7 +70,21 @@ export class PeerScoring {
|
|
|
65
70
|
|
|
66
71
|
private peerStateCounter: UpDownCounter;
|
|
67
72
|
|
|
68
|
-
|
|
73
|
+
/** Active bans, keyed by peer id. Held in memory only, so they are cleared on restart. */
|
|
74
|
+
private bannedPeers: Map<string, BanRecord> = new Map();
|
|
75
|
+
/**
|
|
76
|
+
* How long a peer remains banned once its score crosses MIN_SCORE_BEFORE_BAN. While banned, the
|
|
77
|
+
* peer's ban score is returned by getScore regardless of decay, so it cannot recover its way out
|
|
78
|
+
* of the ban early. After the ban expires the live (decayed) score takes over again.
|
|
79
|
+
*/
|
|
80
|
+
private readonly banDurationMs: number;
|
|
81
|
+
|
|
82
|
+
constructor(
|
|
83
|
+
config: P2PConfig,
|
|
84
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
85
|
+
private readonly dateProvider: DateProvider = new DateProvider(),
|
|
86
|
+
) {
|
|
87
|
+
this.banDurationMs = config.peerBanDurationSeconds * 1000;
|
|
69
88
|
const orderedValues = config.peerPenaltyValues?.sort((a, b) => a - b);
|
|
70
89
|
this.peerPenalties = {
|
|
71
90
|
[PeerErrorSeverity.HighToleranceError]:
|
|
@@ -92,7 +111,7 @@ export class PeerScoring {
|
|
|
92
111
|
}
|
|
93
112
|
|
|
94
113
|
updateScore(peerId: string, scoreDelta: number): number {
|
|
95
|
-
const currentTime =
|
|
114
|
+
const currentTime = this.dateProvider.now();
|
|
96
115
|
const lastUpdate = this.lastUpdateTime.get(peerId) || currentTime;
|
|
97
116
|
const timePassed = currentTime - lastUpdate;
|
|
98
117
|
const decayPeriods = Math.floor(timePassed / this.decayInterval);
|
|
@@ -107,29 +126,102 @@ export class PeerScoring {
|
|
|
107
126
|
|
|
108
127
|
this.scores.set(peerId, currentScore);
|
|
109
128
|
this.lastUpdateTime.set(peerId, currentTime);
|
|
129
|
+
|
|
130
|
+
this.maybeBanPeer(peerId, currentScore);
|
|
131
|
+
|
|
110
132
|
return currentScore;
|
|
111
133
|
}
|
|
112
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Records a ban for a peer whose score has crossed the ban threshold, with an expiry banDurationMs
|
|
137
|
+
* in the future. No-op if the score is above the threshold or the peer is already serving an active
|
|
138
|
+
* ban (an existing ban is not extended; the original window stands). A previously expired ban does
|
|
139
|
+
* not block a fresh one — getActiveBanScore prunes it first.
|
|
140
|
+
*/
|
|
141
|
+
private maybeBanPeer(peerId: string, score: number): void {
|
|
142
|
+
if (score >= MIN_SCORE_BEFORE_BAN || this.getActiveBanScore(peerId) !== undefined) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const record: BanRecord = { score, expiry: this.dateProvider.now() + this.banDurationMs };
|
|
146
|
+
this.bannedPeers.set(peerId, record);
|
|
147
|
+
this.logger.verbose(`Banning peer ${peerId} until ${new Date(record.expiry).toISOString()}`, {
|
|
148
|
+
peerId,
|
|
149
|
+
score,
|
|
150
|
+
expiry: record.expiry,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
113
154
|
decayAllScores(): void {
|
|
114
|
-
const currentTime =
|
|
155
|
+
const currentTime = this.dateProvider.now();
|
|
115
156
|
for (const [peerId, lastUpdate] of this.lastUpdateTime.entries()) {
|
|
116
157
|
const timePassed = currentTime - lastUpdate;
|
|
117
158
|
const decayPeriods = Math.floor(timePassed / this.decayInterval);
|
|
118
159
|
if (decayPeriods > 0) {
|
|
119
160
|
let score = this.scores.get(peerId) || 0;
|
|
120
161
|
score *= Math.pow(this.decayFactor, decayPeriods);
|
|
121
|
-
|
|
122
|
-
|
|
162
|
+
if (Math.abs(score) < SCORE_CLEANUP_THRESHOLD) {
|
|
163
|
+
this.scores.delete(peerId);
|
|
164
|
+
this.lastUpdateTime.delete(peerId);
|
|
165
|
+
} else {
|
|
166
|
+
this.scores.set(peerId, score);
|
|
167
|
+
this.lastUpdateTime.set(peerId, currentTime);
|
|
168
|
+
}
|
|
123
169
|
}
|
|
124
170
|
}
|
|
125
171
|
}
|
|
126
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Removes bans whose window has elapsed. Expired bans are otherwise only pruned lazily when their
|
|
175
|
+
* peer's score is next queried, so a banned peer that disconnects and is never queried again would
|
|
176
|
+
* linger in the map. Called periodically (per heartbeat) to bound the ban map's size.
|
|
177
|
+
*/
|
|
178
|
+
pruneExpiredBans(): void {
|
|
179
|
+
const now = this.dateProvider.now();
|
|
180
|
+
const expired = [...this.bannedPeers.entries()].filter(([, ban]) => ban.expiry <= now).map(([peerId]) => peerId);
|
|
181
|
+
for (const peerId of expired) {
|
|
182
|
+
this.bannedPeers.delete(peerId);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Resets all peer scores. Useful for benchmarks to prevent cross-case contamination. */
|
|
187
|
+
resetAllScores(): void {
|
|
188
|
+
this.scores.clear();
|
|
189
|
+
this.lastUpdateTime.clear();
|
|
190
|
+
this.bannedPeers.clear();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
removePeer(peerId: string): void {
|
|
194
|
+
this.scores.delete(peerId);
|
|
195
|
+
this.lastUpdateTime.delete(peerId);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* The single source of truth for whether a peer is banned. Returns the ban score while the ban is
|
|
200
|
+
* active, or undefined if the peer is not banned. A ban that has expired is lazily lifted before
|
|
201
|
+
* returning undefined, so callers never see a stale ban.
|
|
202
|
+
*/
|
|
203
|
+
private getActiveBanScore(peerId: string): number | undefined {
|
|
204
|
+
const ban = this.bannedPeers.get(peerId);
|
|
205
|
+
if (ban === undefined) {
|
|
206
|
+
return undefined;
|
|
207
|
+
}
|
|
208
|
+
if (ban.expiry > this.dateProvider.now()) {
|
|
209
|
+
return ban.score;
|
|
210
|
+
}
|
|
211
|
+
// Ban expired: lift it so the peer can recover.
|
|
212
|
+
this.bannedPeers.delete(peerId);
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
|
|
127
216
|
getScore(peerId: string): number {
|
|
128
|
-
|
|
217
|
+
// While a ban is active its ban score is returned regardless of how the live score has decayed,
|
|
218
|
+
// so the peer stays banned for the full duration.
|
|
219
|
+
return this.getActiveBanScore(peerId) ?? this.scores.get(peerId) ?? 0;
|
|
129
220
|
}
|
|
130
221
|
|
|
131
222
|
public getScoreState(peerId: string): PeerScoreState {
|
|
132
|
-
//
|
|
223
|
+
// A banned peer stays banned for the full ban duration regardless of score decay (see getScore /
|
|
224
|
+
// maybeBanPeer), rather than silently recovering once its decayed score is cleaned up.
|
|
133
225
|
const score = this.getScore(peerId);
|
|
134
226
|
if (score < MIN_SCORE_BEFORE_BAN) {
|
|
135
227
|
return PeerScoreState.Banned;
|
|
@@ -143,7 +235,9 @@ export class PeerScoring {
|
|
|
143
235
|
getStats(): { medianScore: number; healthyCount: number; disconnectCount: number; bannedCount: number } {
|
|
144
236
|
const stateCounts = { healthy: 0, disconnect: 0, banned: 0 };
|
|
145
237
|
|
|
146
|
-
|
|
238
|
+
// Include banned peers whose live score may have been decayed away but whose ban is still active.
|
|
239
|
+
const peerIds = new Set([...this.scores.keys(), ...this.bannedPeers.keys()]);
|
|
240
|
+
for (const peerId of peerIds) {
|
|
147
241
|
const state = this.getScoreState(peerId);
|
|
148
242
|
switch (state) {
|
|
149
243
|
case PeerScoreState.Healthy:
|
|
@@ -46,7 +46,6 @@ Per-protocol size limits checked via preamble before decompression.
|
|
|
46
46
|
| Error Type | Severity |
|
|
47
47
|
|------------|----------|
|
|
48
48
|
| GOODBYE subprotocol errors | None |
|
|
49
|
-
| `CollectiveReqRespTimeoutError` / `InvalidResponseError` | None |
|
|
50
49
|
| `AbortError` / connection close / muxer closed | None |
|
|
51
50
|
| `ECONNRESET` / `EPIPE` / `ECONNREFUSED` / `ERR_UNEXPECTED_EOF` | HighToleranceError |
|
|
52
51
|
| `ERR_UNSUPPORTED_PROTOCOL` | HighToleranceError |
|
|
@@ -183,19 +182,6 @@ Protected peers (private/trusted/preferred) are always considered "authenticated
|
|
|
183
182
|
|
|
184
183
|
Conditional registration: BLOCK_TXS handler only registered when `config.disableTransactions` is false. Otherwise peers get `ERR_UNSUPPORTED_PROTOCOL`.
|
|
185
184
|
|
|
186
|
-
**Requester side via `sendBatchRequest`** (Snappy limit: `max(N, 1) * 512 + 1` KB):
|
|
187
|
-
|
|
188
|
-
| Rule | Consequence | File |
|
|
189
|
-
|------|-------------|------|
|
|
190
|
-
| Archive root must match request | MidToleranceError | `libp2p_service.ts` (`validateRequestedBlockTxs`) |
|
|
191
|
-
| BitVector length must match request | MidToleranceError | same |
|
|
192
|
-
| No duplicate tx hashes | MidToleranceError | same |
|
|
193
|
-
| Tx count within bounds | MidToleranceError | same |
|
|
194
|
-
| Local block proposal must exist for archive root | Rejected (no penalty) | same |
|
|
195
|
-
| All tx hashes must be in proposal's tx list at allowed indices | LowToleranceError | same |
|
|
196
|
-
| Txs in strictly increasing index order | LowToleranceError | same |
|
|
197
|
-
| Each tx passes well-formedness (Metadata [4 fields], Size, Data, Proof) | LowToleranceError | same |
|
|
198
|
-
|
|
199
185
|
**Requester side via `BatchTxRequester`** (separate validation path):
|
|
200
186
|
|
|
201
187
|
| Rule | Consequence | File |
|
|
@@ -4,9 +4,10 @@ import { FifoMemoryQueue, type ISemaphore, Semaphore } from '@aztec/foundation/q
|
|
|
4
4
|
import { sleep } from '@aztec/foundation/sleep';
|
|
5
5
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
6
6
|
import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
7
|
-
import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx';
|
|
7
|
+
import { Tx, TxArray, TxHash, type TxValidator } from '@aztec/stdlib/tx';
|
|
8
8
|
|
|
9
9
|
import type { PeerId } from '@libp2p/interface';
|
|
10
|
+
import { strict as assert } from 'assert';
|
|
10
11
|
|
|
11
12
|
import type { IRequestTracker } from '../../tx_collection/request_tracker.js';
|
|
12
13
|
import { ReqRespSubProtocol } from '.././interface.js';
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
import type { BatchTxRequesterLibP2PService, BatchTxRequesterOptions, ITxMetadataCollection } from './interface.js';
|
|
22
23
|
import { MissingTxMetadataCollection } from './missing_txs.js';
|
|
23
24
|
import { type IPeerCollection, PeerCollection } from './peer_collection.js';
|
|
24
|
-
import {
|
|
25
|
+
import { createBatchRequestTxValidator } from './tx_validator.js';
|
|
25
26
|
|
|
26
27
|
/*
|
|
27
28
|
* Tries to fetch all missing transaction until deadline is hit.
|
|
@@ -51,7 +52,7 @@ export class BatchTxRequester {
|
|
|
51
52
|
private readonly txsMetadata: ITxMetadataCollection;
|
|
52
53
|
private readonly smartRequesterSemaphore: ISemaphore;
|
|
53
54
|
private readonly txQueue: FifoMemoryQueue<Tx>;
|
|
54
|
-
private readonly txValidator:
|
|
55
|
+
private readonly txValidator: TxValidator;
|
|
55
56
|
private readonly smartParallelWorkerCount: number;
|
|
56
57
|
private readonly dumbParallelWorkerCount: number;
|
|
57
58
|
private readonly txBatchSize: number;
|
|
@@ -78,7 +79,7 @@ export class BatchTxRequester {
|
|
|
78
79
|
this.opts.dumbParallelWorkerCount ?? DEFAULT_BATCH_TX_REQUESTER_DUMB_PARALLEL_WORKER_COUNT;
|
|
79
80
|
this.txBatchSize = this.opts.txBatchSize ?? DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE;
|
|
80
81
|
this.txQueue = new FifoMemoryQueue(this.logger);
|
|
81
|
-
this.txValidator = this.opts.txValidator ??
|
|
82
|
+
this.txValidator = this.opts.txValidator ?? createBatchRequestTxValidator(this.p2pService.txValidatorConfig);
|
|
82
83
|
|
|
83
84
|
if (this.opts.peerCollection) {
|
|
84
85
|
this.peers = this.opts.peerCollection;
|
|
@@ -97,7 +98,7 @@ export class BatchTxRequester {
|
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
/*
|
|
100
|
-
* Fetches all missing transactions and yields them
|
|
101
|
+
* Fetches all missing transactions and yields them one by one
|
|
101
102
|
* */
|
|
102
103
|
public async *run(): AsyncGenerator<Tx, Tx | undefined, unknown> {
|
|
103
104
|
try {
|
|
@@ -428,6 +429,15 @@ export class BatchTxRequester {
|
|
|
428
429
|
}
|
|
429
430
|
|
|
430
431
|
const blockResponse = BlockTxsResponse.fromBuffer(response.data);
|
|
432
|
+
|
|
433
|
+
// Validate response. Peers will be penalised by the validator if they send invalid response.
|
|
434
|
+
const isValid = await this.p2pService.validateRequestedBlockTxsConsistency(request, blockResponse, peerId);
|
|
435
|
+
if (!isValid) {
|
|
436
|
+
this.logger.debug(`Peer ${peerId.toString()} sent invalid response`);
|
|
437
|
+
this.handleFailResponseFromPeer(peerId, ReqRespStatus.INTERNAL_ERROR);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
|
|
431
441
|
await this.handleSuccessResponseFromPeer(peerId, blockResponse);
|
|
432
442
|
} catch (err: any) {
|
|
433
443
|
this.logger.error(`Failed to get valid response from peer ${peerId.toString()}: ${err.message}`, {
|
|
@@ -445,27 +455,24 @@ export class BatchTxRequester {
|
|
|
445
455
|
* Handles failed response form the peer
|
|
446
456
|
* There are 3 scenarios
|
|
447
457
|
* - RATE_LIMIT_EXCEEDED: We mark this and don't query this peer again for some_time
|
|
458
|
+
* - INTERNAL_ERROR: We use this to cover cases where the request-response consistency validation fails.
|
|
448
459
|
* - FAILURE and UNKNOWN: We penalise this, if peer has been penalised this way N times they are not queried again
|
|
449
460
|
* this implies we will query these peers couple of more times and give them a chance to "redeem" themselves before completely ignoring them
|
|
450
461
|
*/
|
|
451
462
|
private handleFailResponseFromPeer(peerId: PeerId, responseStatus: ReqRespStatus) {
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
if (responseStatus === ReqRespStatus.RATE_LIMIT_EXCEEDED) {
|
|
468
|
-
this.peers.markPeerRateLimitExceeded(peerId);
|
|
463
|
+
switch (responseStatus) {
|
|
464
|
+
case ReqRespStatus.RATE_LIMIT_EXCEEDED:
|
|
465
|
+
this.peers.markPeerRateLimitExceeded(peerId);
|
|
466
|
+
return;
|
|
467
|
+
case ReqRespStatus.INTERNAL_ERROR:
|
|
468
|
+
this.peers.markPeerDumb(peerId);
|
|
469
|
+
this.txsMetadata.clearPeerData(peerId);
|
|
470
|
+
return;
|
|
471
|
+
default: // includes FAILURE, UNKNOWN
|
|
472
|
+
this.peers.penalisePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
473
|
+
this.peers.markPeerDumb(peerId);
|
|
474
|
+
this.txsMetadata.clearPeerData(peerId);
|
|
475
|
+
return;
|
|
469
476
|
}
|
|
470
477
|
}
|
|
471
478
|
|
|
@@ -485,7 +492,7 @@ export class BatchTxRequester {
|
|
|
485
492
|
* Handles received txs.
|
|
486
493
|
* Transactions are validated and then put on async queue
|
|
487
494
|
* to be yielded by main running loop
|
|
488
|
-
|
|
495
|
+
*/
|
|
489
496
|
private async handleReceivedTxs(peerId: PeerId, txs: TxArray) {
|
|
490
497
|
const newTxs = txs.filter(tx => !this.txsMetadata.alreadyFetched(tx.txHash));
|
|
491
498
|
|
|
@@ -493,12 +500,12 @@ export class BatchTxRequester {
|
|
|
493
500
|
return;
|
|
494
501
|
}
|
|
495
502
|
|
|
496
|
-
//TODO: this validation can be slow, maybe spawn worker just for validation
|
|
503
|
+
// TODO: this validation can be slow, maybe spawn worker just for validation
|
|
497
504
|
// We could use the async queue for communication.
|
|
498
505
|
const validationResults = await Promise.allSettled(
|
|
499
506
|
newTxs.map(async tx => ({
|
|
500
507
|
tx,
|
|
501
|
-
isValid: (await this.txValidator.
|
|
508
|
+
isValid: (await this.txValidator.validateTx(tx)).result === 'valid',
|
|
502
509
|
})),
|
|
503
510
|
);
|
|
504
511
|
|
|
@@ -514,6 +521,9 @@ export class BatchTxRequester {
|
|
|
514
521
|
});
|
|
515
522
|
|
|
516
523
|
if (hasInvalidTx) {
|
|
524
|
+
this.logger.warn(`Penalizing peer ${peerId.toString()} for sending invalid transactions in batch response`, {
|
|
525
|
+
peerId,
|
|
526
|
+
});
|
|
517
527
|
this.peers.penalisePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
518
528
|
} else {
|
|
519
529
|
// If we have received successful response from the peer, they have "redeemed" themselves and not considered bad anymore
|
|
@@ -550,9 +560,10 @@ export class BatchTxRequester {
|
|
|
550
560
|
return;
|
|
551
561
|
}
|
|
552
562
|
|
|
553
|
-
|
|
554
|
-
if (
|
|
555
|
-
this.
|
|
563
|
+
// If the peer doesn't have the block, we mark them as dumb.
|
|
564
|
+
if (!response.peerHasBlock()) {
|
|
565
|
+
this.peers.markPeerDumb(peerId);
|
|
566
|
+
this.txsMetadata.clearPeerData(peerId);
|
|
556
567
|
return;
|
|
557
568
|
}
|
|
558
569
|
|
|
@@ -570,21 +581,6 @@ export class BatchTxRequester {
|
|
|
570
581
|
this.smartRequesterSemaphore.release();
|
|
571
582
|
}
|
|
572
583
|
|
|
573
|
-
/**
|
|
574
|
-
* Handles an archive root mismatch between local state and peer response.
|
|
575
|
-
*
|
|
576
|
-
* - Response archive is Fr.ZERO (peer pruned proposal, legitimate): marks peer dumb.
|
|
577
|
-
* - Non-zero archive mismatch (malicious response): penalises + marks dumb.
|
|
578
|
-
*/
|
|
579
|
-
private handleArchiveRootMismatch(peerId: PeerId, response: BlockTxsResponse): void {
|
|
580
|
-
if (!response.archiveRoot.isZero()) {
|
|
581
|
-
this.peers.penalisePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
this.peers.markPeerDumb(peerId);
|
|
585
|
-
this.txsMetadata.clearPeerData(peerId);
|
|
586
|
-
}
|
|
587
|
-
|
|
588
584
|
private peerHasSomeTxsWeAreMissing(_peerId: PeerId, response: BlockTxsResponse): boolean {
|
|
589
585
|
if (response.txIndices.isEmpty()) {
|
|
590
586
|
return false;
|
|
@@ -600,15 +596,9 @@ export class BatchTxRequester {
|
|
|
600
596
|
}
|
|
601
597
|
|
|
602
598
|
private extractHashesPeerHasFromResponse(response: BlockTxsResponse): Array<TxHash> {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
if (indicesOfHashesPeerHas.has(idx)) {
|
|
607
|
-
hashes.push(hash);
|
|
608
|
-
}
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
return hashes;
|
|
599
|
+
// Should already have been validated, but just in case.
|
|
600
|
+
assert(response.txIndices.getLength() === this.blockTxsSource.txHashes.length);
|
|
601
|
+
return response.txIndices.getTrueIndices().map(idx => this.blockTxsSource.txHashes[idx]);
|
|
612
602
|
}
|
|
613
603
|
|
|
614
604
|
/*
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { ISemaphore } from '@aztec/foundation/queue';
|
|
2
2
|
import type { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
3
|
-
import type { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
3
|
+
import type { Tx, TxHash, TxValidator } from '@aztec/stdlib/tx';
|
|
4
4
|
|
|
5
5
|
import type { PeerId } from '@libp2p/interface';
|
|
6
6
|
|
|
7
7
|
import type { ConnectionSampler } from '../connection-sampler/connection_sampler.js';
|
|
8
|
+
import type { BlockTxsRequest, BlockTxsResponse } from '../index.js';
|
|
8
9
|
import type { ReqRespInterface } from '../interface.js';
|
|
9
10
|
import type { IPeerCollection } from './peer_collection.js';
|
|
10
|
-
import type { BatchRequestTxValidatorConfig
|
|
11
|
+
import type { BatchRequestTxValidatorConfig } from './tx_validator.js';
|
|
11
12
|
|
|
12
13
|
export interface IPeerPenalizer {
|
|
13
14
|
penalizePeer(peerId: PeerId, penalty: PeerErrorSeverity): void;
|
|
@@ -32,13 +33,19 @@ export interface ITxMetadataCollection {
|
|
|
32
33
|
*/
|
|
33
34
|
export interface BatchTxRequesterLibP2PService {
|
|
34
35
|
/** ReqResp interface for sending requests to peers */
|
|
35
|
-
reqResp: Pick<ReqRespInterface, '
|
|
36
|
+
reqResp: Pick<ReqRespInterface, 'sendRequestToPeer'>;
|
|
36
37
|
/** Connection sampler for getting peer lists */
|
|
37
38
|
connectionSampler: Pick<ConnectionSampler, 'getPeerListSortedByConnectionCountAsc'>;
|
|
38
39
|
/** Configuration needed for transaction validation */
|
|
39
40
|
txValidatorConfig: BatchRequestTxValidatorConfig;
|
|
40
41
|
/** Peer scoring for penalizing peers */
|
|
41
42
|
peerScoring: IPeerPenalizer;
|
|
43
|
+
/** Validate the requested block transactions request-response consistency */
|
|
44
|
+
validateRequestedBlockTxsConsistency: (
|
|
45
|
+
request: BlockTxsRequest,
|
|
46
|
+
response: BlockTxsResponse,
|
|
47
|
+
peerId: PeerId,
|
|
48
|
+
) => Promise<boolean>;
|
|
42
49
|
}
|
|
43
50
|
|
|
44
51
|
export interface BatchTxRequesterOptions {
|
|
@@ -50,5 +57,5 @@ export interface BatchTxRequesterOptions {
|
|
|
50
57
|
semaphore?: ISemaphore;
|
|
51
58
|
peerCollection?: IPeerCollection;
|
|
52
59
|
/** Optional tx validator for testing - if not provided, one is created from p2pService.txValidatorConfig */
|
|
53
|
-
txValidator?:
|
|
60
|
+
txValidator?: TxValidator;
|
|
54
61
|
}
|