@aztec/p2p 0.0.1-commit.2ed92850 → 0.0.1-commit.43597cc1
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 +4 -3
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +4 -4
- package/dest/client/factory.d.ts +3 -3
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +11 -8
- package/dest/client/interface.d.ts +9 -2
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +7 -4
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +24 -7
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +2 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +1 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +305 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +73 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +1 -0
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +8 -0
- package/dest/config.d.ts +16 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +7 -2
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +94 -87
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +411 -3
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
- 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 +351 -85
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -2
- package/dest/mem_pools/index.d.ts +2 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/index.js +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 +2 -2
- package/dest/mem_pools/interface.d.ts +3 -3
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/archive/index.d.ts +2 -0
- package/dest/mem_pools/tx_pool_v2/archive/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/index.js +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +43 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +103 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +47 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +119 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +90 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +89 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +10 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +11 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +131 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +17 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +63 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +91 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +70 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +20 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +63 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +19 -0
- package/dest/mem_pools/tx_pool_v2/index.d.ts +5 -0
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/index.js +4 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +197 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.js +6 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +71 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +95 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts +26 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_bench_metrics.js +70 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +99 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +332 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +55 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +156 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +69 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +748 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +3 -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 +7 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.js +5 -5
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +3 -3
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.js +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +5 -4
- 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 -3
- package/dest/msg_validators/tx_validator/data_validator.d.ts +3 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +4 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +3 -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 +3 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +8 -3
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +21 -11
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +3 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -3
- package/dest/msg_validators/tx_validator/size_validator.d.ts +3 -1
- package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/size_validator.js +4 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +2 -2
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.js +2 -2
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +3 -2
- 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 -2
- 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 +10 -6
- package/dest/services/discv5/discV5_service.js +1 -1
- package/dest/services/dummy_service.d.ts +18 -2
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +42 -0
- package/dest/services/gossipsub/index.d.ts +3 -0
- package/dest/services/gossipsub/index.d.ts.map +1 -0
- package/dest/services/gossipsub/index.js +2 -0
- package/dest/services/gossipsub/scoring.d.ts +21 -3
- package/dest/services/gossipsub/scoring.d.ts.map +1 -1
- package/dest/services/gossipsub/scoring.js +24 -7
- package/dest/services/gossipsub/topic_score_params.d.ts +161 -0
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
- package/dest/services/gossipsub/topic_score_params.js +324 -0
- package/dest/services/index.d.ts +2 -1
- package/dest/services/index.d.ts.map +1 -1
- package/dest/services/index.js +1 -0
- package/dest/services/libp2p/instrumentation.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +14 -3
- package/dest/services/libp2p/libp2p_service.d.ts +80 -33
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +352 -284
- package/dest/services/peer-manager/metrics.d.ts +2 -2
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +20 -5
- package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +33 -4
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +47 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +566 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts +17 -0
- package/dest/services/reqresp/batch-tx-requester/config.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/config.js +27 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +50 -0
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/interface.js +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +37 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +151 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +54 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +139 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts +20 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -0
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +21 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +22 -3
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +63 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +12 -0
- package/dest/services/reqresp/interface.d.ts +3 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.d.ts +6 -5
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +17 -5
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +5 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +5 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +6 -4
- 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 +27 -9
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +23 -6
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +44 -13
- package/dest/services/reqresp/reqresp.d.ts +6 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +58 -22
- package/dest/services/service.d.ts +21 -1
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +4 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +9 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +5 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +17 -10
- package/dest/services/tx_collection/index.d.ts +2 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -0
- 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 +9 -2
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +48 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -0
- package/dest/services/tx_collection/proposal_tx_collector.js +49 -0
- package/dest/services/tx_collection/tx_collection.d.ts +4 -4
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +5 -5
- package/dest/services/tx_file_store/config.d.ts +18 -0
- package/dest/services/tx_file_store/config.d.ts.map +1 -0
- package/dest/services/tx_file_store/config.js +26 -0
- package/dest/services/tx_file_store/index.d.ts +4 -0
- package/dest/services/tx_file_store/index.d.ts.map +1 -0
- package/dest/services/tx_file_store/index.js +3 -0
- package/dest/services/tx_file_store/instrumentation.d.ts +15 -0
- package/dest/services/tx_file_store/instrumentation.d.ts.map +1 -0
- package/dest/services/tx_file_store/instrumentation.js +29 -0
- package/dest/services/tx_file_store/tx_file_store.d.ts +47 -0
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -0
- package/dest/services/tx_file_store/tx_file_store.js +149 -0
- package/dest/services/tx_provider_instrumentation.d.ts +1 -1
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +5 -5
- package/dest/test-helpers/index.d.ts +3 -1
- package/dest/test-helpers/index.d.ts.map +1 -1
- package/dest/test-helpers/index.js +2 -0
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -1
- package/dest/test-helpers/test_tx_provider.d.ts +40 -0
- package/dest/test-helpers/test_tx_provider.d.ts.map +1 -0
- package/dest/test-helpers/test_tx_provider.js +41 -0
- package/dest/test-helpers/testbench-utils.d.ts +152 -0
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -0
- package/dest/test-helpers/testbench-utils.js +308 -0
- package/dest/testbench/p2p_client_testbench_worker.d.ts +28 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +212 -131
- package/dest/testbench/worker_client_manager.d.ts +51 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +226 -44
- package/package.json +14 -14
- package/src/bootstrap/bootstrap.ts +7 -4
- package/src/client/factory.ts +13 -14
- package/src/client/interface.ts +13 -1
- package/src/client/p2p_client.ts +32 -8
- package/src/client/test/tx_proposal_collector/README.md +227 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +336 -0
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +43 -0
- package/src/config.ts +22 -2
- package/src/mem_pools/attestation_pool/attestation_pool.ts +444 -90
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +436 -100
- package/src/mem_pools/attestation_pool/index.ts +9 -2
- package/src/mem_pools/index.ts +1 -1
- package/src/mem_pools/instrumentation.ts +2 -1
- package/src/mem_pools/interface.ts +2 -2
- package/src/mem_pools/tx_pool_v2/README.md +209 -0
- package/src/mem_pools/tx_pool_v2/archive/index.ts +1 -0
- package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +120 -0
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +147 -0
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +118 -0
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +111 -0
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +23 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +164 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +74 -0
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +101 -0
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +86 -0
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +72 -0
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +31 -0
- package/src/mem_pools/tx_pool_v2/index.ts +11 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +227 -0
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +161 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_bench_metrics.ts +77 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +417 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +212 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +882 -0
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +10 -4
- package/src/msg_validators/proposal_validator/proposal_validator.ts +5 -5
- package/src/msg_validators/tx_validator/archive_cache.ts +3 -3
- package/src/msg_validators/tx_validator/block_header_validator.ts +7 -8
- package/src/msg_validators/tx_validator/data_validator.ts +6 -2
- package/src/msg_validators/tx_validator/double_spend_validator.ts +4 -3
- package/src/msg_validators/tx_validator/factory.ts +64 -23
- package/src/msg_validators/tx_validator/gas_validator.ts +9 -3
- package/src/msg_validators/tx_validator/metadata_validator.ts +6 -3
- package/src/msg_validators/tx_validator/phases_validator.ts +5 -3
- package/src/msg_validators/tx_validator/size_validator.ts +6 -2
- package/src/msg_validators/tx_validator/timestamp_validator.ts +6 -3
- package/src/msg_validators/tx_validator/tx_permitted_validator.ts +8 -3
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +8 -3
- package/src/services/data_store.ts +10 -7
- package/src/services/discv5/discV5_service.ts +1 -1
- package/src/services/dummy_service.ts +51 -0
- package/src/services/gossipsub/README.md +626 -0
- package/src/services/gossipsub/index.ts +2 -0
- package/src/services/gossipsub/scoring.ts +29 -5
- package/src/services/gossipsub/topic_score_params.ts +451 -0
- package/src/services/index.ts +1 -0
- package/src/services/libp2p/instrumentation.ts +15 -2
- package/src/services/libp2p/libp2p_service.ts +381 -305
- package/src/services/peer-manager/metrics.ts +21 -4
- package/src/services/peer-manager/peer_scoring.ts +29 -1
- package/src/services/reqresp/batch-tx-requester/README.md +305 -0
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +706 -0
- package/src/services/reqresp/batch-tx-requester/config.ts +40 -0
- package/src/services/reqresp/batch-tx-requester/interface.ts +57 -0
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +209 -0
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +205 -0
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +37 -0
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +65 -4
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +16 -0
- package/src/services/reqresp/interface.ts +3 -0
- package/src/services/reqresp/metrics.ts +34 -9
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +7 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +34 -11
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +57 -9
- package/src/services/reqresp/reqresp.ts +66 -19
- package/src/services/service.ts +24 -0
- package/src/services/tx_collection/config.ts +15 -1
- package/src/services/tx_collection/fast_tx_collection.ts +30 -17
- package/src/services/tx_collection/index.ts +5 -0
- package/src/services/tx_collection/instrumentation.ts +11 -2
- package/src/services/tx_collection/proposal_tx_collector.ts +112 -0
- package/src/services/tx_collection/tx_collection.ts +4 -4
- package/src/services/tx_file_store/config.ts +43 -0
- package/src/services/tx_file_store/index.ts +3 -0
- package/src/services/tx_file_store/instrumentation.ts +36 -0
- package/src/services/tx_file_store/tx_file_store.ts +173 -0
- package/src/services/tx_provider_instrumentation.ts +11 -5
- package/src/test-helpers/index.ts +2 -0
- package/src/test-helpers/reqresp-nodes.ts +2 -1
- package/src/test-helpers/test_tx_provider.ts +64 -0
- package/src/test-helpers/testbench-utils.ts +362 -0
- package/src/testbench/p2p_client_testbench_worker.ts +321 -122
- package/src/testbench/worker_client_manager.ts +304 -47
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
package/src/client/p2p_client.ts
CHANGED
|
@@ -29,7 +29,7 @@ import type { PeerId } from '@libp2p/interface';
|
|
|
29
29
|
import type { ENR } from '@nethermindeth/enr';
|
|
30
30
|
|
|
31
31
|
import { type P2PConfig, getP2PDefaultConfig } from '../config.js';
|
|
32
|
-
import type {
|
|
32
|
+
import type { AttestationPoolApi } from '../mem_pools/attestation_pool/attestation_pool.js';
|
|
33
33
|
import type { MemPools } from '../mem_pools/interface.js';
|
|
34
34
|
import type { TxPool } from '../mem_pools/tx_pool/index.js';
|
|
35
35
|
import type { AuthRequest, StatusMessage } from '../services/index.js';
|
|
@@ -39,8 +39,14 @@ import {
|
|
|
39
39
|
type ReqRespSubProtocolValidators,
|
|
40
40
|
} from '../services/reqresp/interface.js';
|
|
41
41
|
import { chunkTxHashesRequest } from '../services/reqresp/protocols/tx.js';
|
|
42
|
-
import type {
|
|
42
|
+
import type {
|
|
43
|
+
DuplicateProposalInfo,
|
|
44
|
+
P2PBlockReceivedCallback,
|
|
45
|
+
P2PCheckpointReceivedCallback,
|
|
46
|
+
P2PService,
|
|
47
|
+
} from '../services/service.js';
|
|
43
48
|
import { TxCollection } from '../services/tx_collection/tx_collection.js';
|
|
49
|
+
import type { TxFileStore } from '../services/tx_file_store/tx_file_store.js';
|
|
44
50
|
import { TxProvider } from '../services/tx_provider.js';
|
|
45
51
|
import { type P2P, P2PClientState, type P2PSyncState } from './interface.js';
|
|
46
52
|
|
|
@@ -65,7 +71,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
65
71
|
private synchedLatestSlot: AztecAsyncSingleton<bigint>;
|
|
66
72
|
|
|
67
73
|
private txPool: TxPool;
|
|
68
|
-
private attestationPool:
|
|
74
|
+
private attestationPool: AttestationPoolApi;
|
|
69
75
|
|
|
70
76
|
private config: P2PConfig;
|
|
71
77
|
|
|
@@ -90,6 +96,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
90
96
|
mempools: MemPools,
|
|
91
97
|
private p2pService: P2PService,
|
|
92
98
|
private txCollection: TxCollection,
|
|
99
|
+
private txFileStore: TxFileStore | undefined,
|
|
93
100
|
config: Partial<P2PConfig> = {},
|
|
94
101
|
private _dateProvider: DateProvider = new DateProvider(),
|
|
95
102
|
private telemetry: TelemetryClient = getTelemetryClient(),
|
|
@@ -274,6 +281,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
274
281
|
|
|
275
282
|
this.blockStream!.start();
|
|
276
283
|
await this.txCollection.start();
|
|
284
|
+
this.txFileStore?.start();
|
|
277
285
|
return this.syncPromise;
|
|
278
286
|
}
|
|
279
287
|
|
|
@@ -306,6 +314,8 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
306
314
|
this.log.debug('Stopping p2p client...');
|
|
307
315
|
await tryStop(this.txCollection);
|
|
308
316
|
this.log.debug('Stopped tx collection service');
|
|
317
|
+
await this.txFileStore?.stop();
|
|
318
|
+
this.log.debug('Stopped tx file store');
|
|
309
319
|
await this.p2pService.stop();
|
|
310
320
|
this.log.debug('Stopped p2p service');
|
|
311
321
|
await this.blockStream?.stop();
|
|
@@ -326,8 +336,13 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
326
336
|
[Attributes.BLOCK_ARCHIVE]: proposal.archive.toString(),
|
|
327
337
|
[Attributes.P2P_ID]: (await proposal.p2pMessageLoggingIdentifier()).toString(),
|
|
328
338
|
}))
|
|
329
|
-
public broadcastProposal(proposal: BlockProposal): Promise<void> {
|
|
339
|
+
public async broadcastProposal(proposal: BlockProposal): Promise<void> {
|
|
330
340
|
this.log.verbose(`Broadcasting proposal for slot ${proposal.slotNumber} to peers`);
|
|
341
|
+
// Store our own proposal so we can respond to req/resp requests for it
|
|
342
|
+
const { totalForPosition } = await this.attestationPool.tryAddBlockProposal(proposal);
|
|
343
|
+
if (totalForPosition > 1) {
|
|
344
|
+
throw new Error(`Attempted to broadcast a duplicate block proposal for slot ${proposal.slotNumber}`);
|
|
345
|
+
}
|
|
331
346
|
return this.p2pService.propagate(proposal);
|
|
332
347
|
}
|
|
333
348
|
|
|
@@ -336,8 +351,13 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
336
351
|
[Attributes.BLOCK_ARCHIVE]: proposal.archive.toString(),
|
|
337
352
|
[Attributes.P2P_ID]: (await proposal.p2pMessageLoggingIdentifier()).toString(),
|
|
338
353
|
}))
|
|
339
|
-
public broadcastCheckpointProposal(proposal: CheckpointProposal): Promise<void> {
|
|
354
|
+
public async broadcastCheckpointProposal(proposal: CheckpointProposal): Promise<void> {
|
|
340
355
|
this.log.verbose(`Broadcasting checkpoint proposal for slot ${proposal.slotNumber} to peers`);
|
|
356
|
+
const blockProposal = proposal.getBlockProposal();
|
|
357
|
+
if (blockProposal) {
|
|
358
|
+
// Store our own last-block proposal so we can respond to req/resp requests for it.
|
|
359
|
+
await this.attestationPool.tryAddBlockProposal(blockProposal);
|
|
360
|
+
}
|
|
341
361
|
return this.p2pService.propagate(proposal);
|
|
342
362
|
}
|
|
343
363
|
|
|
@@ -355,8 +375,8 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
355
375
|
: this.attestationPool.getCheckpointAttestationsForSlot(slot));
|
|
356
376
|
}
|
|
357
377
|
|
|
358
|
-
public
|
|
359
|
-
return this.attestationPool.
|
|
378
|
+
public addOwnCheckpointAttestations(attestations: CheckpointAttestation[]): Promise<void> {
|
|
379
|
+
return this.attestationPool.addOwnCheckpointAttestations(attestations);
|
|
360
380
|
}
|
|
361
381
|
|
|
362
382
|
// REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
@@ -369,6 +389,10 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
369
389
|
this.p2pService.registerCheckpointReceivedCallback(handler);
|
|
370
390
|
}
|
|
371
391
|
|
|
392
|
+
public registerDuplicateProposalCallback(callback: (info: DuplicateProposalInfo) => void): void {
|
|
393
|
+
this.p2pService.registerDuplicateProposalCallback(callback);
|
|
394
|
+
}
|
|
395
|
+
|
|
372
396
|
/**
|
|
373
397
|
* Uses the batched Request Response protocol to request a set of transactions from the network.
|
|
374
398
|
*/
|
|
@@ -733,7 +757,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
|
733
757
|
await this.txPool.deleteTxs(txHashes, { permanently: true });
|
|
734
758
|
await this.txPool.cleanupDeletedMinedTxs(lastBlockNum);
|
|
735
759
|
|
|
736
|
-
await this.attestationPool.
|
|
760
|
+
await this.attestationPool.deleteOlderThan(lastBlockSlot);
|
|
737
761
|
|
|
738
762
|
this.log.debug(`Synched to finalized block ${lastBlockNum} at slot ${lastBlockSlot}`);
|
|
739
763
|
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# ProposalTxCollector Benchmarks
|
|
2
|
+
|
|
3
|
+
This benchmark suite measures **how quickly a proposer node can fetch missing transactions from P2P peers** when building a block proposal. It compares two alternative transaction-collection implementations under several controlled "who-has-which-txs" distributions.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
When proposing a block, the node may have a block proposal containing a list of `txHashes`, but may be **missing the full `Tx` objects** locally. The node must fetch those missing txs from peers via the P2P req/resp layer.
|
|
8
|
+
|
|
9
|
+
This benchmark answers:
|
|
10
|
+
|
|
11
|
+
- How long does it take to fetch **N missing txs** (N ∈ **{10, 50, 100, 500}**)?
|
|
12
|
+
- How do different **peer availability patterns** affect performance?
|
|
13
|
+
- Which collector strategy performs better under each pattern?
|
|
14
|
+
|
|
15
|
+
The suite compares two collectors:
|
|
16
|
+
|
|
17
|
+
- **`BatchTxRequesterCollector`** (collector type: `batch-requester`)
|
|
18
|
+
- **`SendBatchRequestCollector`** (collector type: `send-batch-request`)
|
|
19
|
+
|
|
20
|
+
## Architecture
|
|
21
|
+
|
|
22
|
+
The benchmark runs a small simulated network on localhost:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
26
|
+
│ Test Process (Driver) │
|
|
27
|
+
│ p2p_client.proposal_tx_collector.bench.test.ts │
|
|
28
|
+
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
29
|
+
│ │ WorkerClientManager │ │
|
|
30
|
+
│ │ (src/testbench/worker_client_manager.ts) │ │
|
|
31
|
+
│ └─────────────────────────────────────────────────────────────┘ │
|
|
32
|
+
│ │ IPC │
|
|
33
|
+
│ ┌────────────────────┼────────────────────┐ │
|
|
34
|
+
│ ▼ ▼ ▼ │
|
|
35
|
+
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
|
|
36
|
+
│ │ Worker 0 │◄──────►│ Worker 1 │◄──────►│ Worker N-1│ │
|
|
37
|
+
│ │ (Collector│ P2P │(Responder)│ P2P │(Responder)│ │
|
|
38
|
+
│ │ Node) │ │ │ │ │ │
|
|
39
|
+
│ │ TxPool:[] │ │ TxPool: │ │ TxPool: │ │
|
|
40
|
+
│ │ │ │ [txs...] │ │ [txs...] │ │
|
|
41
|
+
│ └───────────┘ └───────────┘ └───────────┘ │
|
|
42
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- **N worker processes** are spawned using Node's **`child_process.fork()`**
|
|
46
|
+
- Each worker runs a "light" **`P2PClient.Full`** node (enough to exercise the real P2P req/resp machinery)
|
|
47
|
+
- Workers communicate with the test process via **IPC messages** defined in `p2p_client_testbench_worker.ts`
|
|
48
|
+
|
|
49
|
+
### Why multiple processes?
|
|
50
|
+
|
|
51
|
+
Using separate OS processes makes the setup closer to real networking behavior (independent event loops, scheduling, IPC boundaries), and avoids many artifacts you'd get by running everything in one process.
|
|
52
|
+
|
|
53
|
+
### Worker roles
|
|
54
|
+
|
|
55
|
+
The network is intentionally asymmetric:
|
|
56
|
+
|
|
57
|
+
- **Worker 0 is the collector/proposer node**
|
|
58
|
+
- Starts with an **empty tx pool** (`[]`)
|
|
59
|
+
- Is the only worker instructed to run the collector for each `BENCH_REQRESP` command
|
|
60
|
+
- **Workers 1..N-1 are responder peers**
|
|
61
|
+
- Locally generate and filter txs according to the distribution pattern
|
|
62
|
+
- Respond to req/resp queries made by Worker 0's collector
|
|
63
|
+
|
|
64
|
+
This models a proposer that has only `txHashes` in a proposal and must fetch the full tx bodies from the network.
|
|
65
|
+
|
|
66
|
+
## Transaction Distribution Patterns
|
|
67
|
+
|
|
68
|
+
Each benchmark case generates `missingTxCount` mock txs and assigns them to peers using one of these patterns:
|
|
69
|
+
|
|
70
|
+
### `uniform`
|
|
71
|
+
|
|
72
|
+
**Every responder peer has every transaction.**
|
|
73
|
+
|
|
74
|
+
- Simulates the best-case: high replication / high gossip success
|
|
75
|
+
- Expectation: collector should quickly succeed; differences mostly reflect collector overhead and batching strategy
|
|
76
|
+
|
|
77
|
+
### `sparse`
|
|
78
|
+
|
|
79
|
+
**Each transaction exists on only a small subset of peers.**
|
|
80
|
+
|
|
81
|
+
Each responder is bucketed and holds txs whose index falls into its bucket or the "next" bucket (striped by tx index).
|
|
82
|
+
|
|
83
|
+
- Simulates partial propagation, churn, or uneven mempool convergence
|
|
84
|
+
- Expectation: collector must query multiple peers and cope with "misses"
|
|
85
|
+
|
|
86
|
+
### `pinned-only`
|
|
87
|
+
|
|
88
|
+
**Only a single "pinned" peer has the transactions; all other peers have none.**
|
|
89
|
+
|
|
90
|
+
- Simulates "I know exactly who has the txs" (or a topology where one peer is the source of truth)
|
|
91
|
+
- Useful to test whether "pinned peer" fast-paths work as intended
|
|
92
|
+
|
|
93
|
+
> **Guardrail:** the pinned peer index must be within `(0, numberOfPeers)` (Worker 0 cannot be pinned).
|
|
94
|
+
|
|
95
|
+
## Collectors Under Test
|
|
96
|
+
|
|
97
|
+
### `BatchTxRequesterCollector` (`batch-requester`)
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
new BatchTxRequesterCollector(p2pService, logger, new DateProvider())
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Uses the P2P service plus internal logic to fetch missing txs, coordinating requests in a batched or staged way.
|
|
104
|
+
|
|
105
|
+
### `SendBatchRequestCollector` (`send-batch-request`)
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const maxPeers = 10;
|
|
109
|
+
const maxRetryAttempts = Math.max(peerIds.length, 3);
|
|
110
|
+
new SendBatchRequestCollector(p2pService, maxPeers, maxRetryAttempts)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Explicitly caps the number of peers it will involve (`maxPeers`) and uses a retry budget derived from peer count.
|
|
114
|
+
|
|
115
|
+
## Test Parameters
|
|
116
|
+
|
|
117
|
+
| Parameter | Value | Description |
|
|
118
|
+
|-----------|-------|-------------|
|
|
119
|
+
| `PEERS_PER_RUN` | 30 | Number of worker processes spawned |
|
|
120
|
+
| `MISSING_TX_COUNTS` | 10, 50, 100, 500 | Number of missing transactions to fetch |
|
|
121
|
+
| `TIMEOUT_MS` | 30,000 ms | Collector timeout per case |
|
|
122
|
+
| `TEST_TIMEOUT_MS` | 600,000 ms | Overall Jest timeout (10 minutes) |
|
|
123
|
+
|
|
124
|
+
## Running
|
|
125
|
+
|
|
126
|
+
From the p2p package:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
cd yarn-project/p2p
|
|
130
|
+
yarn test src/client/test/tx_proposal_collector/p2p_client.proposal_tx_collector.bench.test.ts
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Or from repo root:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
yarn test p2p_client.proposal_tx_collector.bench.test.ts
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The benchmark is intentionally long due to spawning many processes and running multiple cases.
|
|
140
|
+
|
|
141
|
+
## Output Formats
|
|
142
|
+
|
|
143
|
+
### Default: Markdown table to stdout
|
|
144
|
+
|
|
145
|
+
If no env vars are set, the suite prints a table:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
| Collector | Distribution | Missing | Duration (ms) | Fetched | Success |
|
|
149
|
+
|---------------------|--------------|---------|---------------|---------|---------|
|
|
150
|
+
| batch-requester | pinned-only | 10 | 123 | 10 | Yes |
|
|
151
|
+
| send-batch-request | pinned-only | 10 | 145 | 10 | Yes |
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Plus a comparison summary stating which collector was faster per `(distribution, missing)` pair.
|
|
155
|
+
|
|
156
|
+
### JSON metrics (for CI/dashboards)
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
BENCH_OUTPUT=/path/results.json yarn test ...
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Writes JSON metrics like:
|
|
163
|
+
- `ProposalTxCollector/<collector>/<distribution>/missing_<N>/duration` (ms)
|
|
164
|
+
- `ProposalTxCollector/<collector>/<distribution>/missing_<N>/fetched` (txs)
|
|
165
|
+
|
|
166
|
+
### Markdown file output
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
BENCH_OUTPUT_MD=/path/results.md yarn test ...
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Writes the pretty table + summary to disk.
|
|
173
|
+
|
|
174
|
+
## Interpreting Results
|
|
175
|
+
|
|
176
|
+
For each case the benchmark records:
|
|
177
|
+
|
|
178
|
+
- `durationMs`: wall-clock time spent inside the collector call
|
|
179
|
+
- `fetchedCount`: how many txs were returned by the collector
|
|
180
|
+
- `success`: `fetchedCount === missingTxCount`
|
|
181
|
+
|
|
182
|
+
**Guidelines:**
|
|
183
|
+
|
|
184
|
+
- **Always check `Success` first.** A faster run that fetched fewer txs is not a win.
|
|
185
|
+
- Compare collectors **within the same distribution + missing count** only.
|
|
186
|
+
- Expect `pinned-only` to highlight pinned-peer behavior (fast if pinned peer is used effectively; slow if the algorithm wastes time sampling other peers).
|
|
187
|
+
- Expect `sparse` to be the most "network-like" stress case, since many peers won't have each requested tx.
|
|
188
|
+
|
|
189
|
+
## Determinism / Noise Reduction
|
|
190
|
+
|
|
191
|
+
Inside each worker, the benchmark intentionally reduces variability:
|
|
192
|
+
|
|
193
|
+
- **Unlimited rate limits** are installed so the req/resp rate limiter doesn't dominate results
|
|
194
|
+
- **Deterministic tx generation** ensures all workers see the same tx set without large IPC payloads
|
|
195
|
+
|
|
196
|
+
This makes the benchmark better for *comparing collectors* (A vs B), but it is **not** a perfect model of production networking conditions.
|
|
197
|
+
|
|
198
|
+
## Limitations
|
|
199
|
+
|
|
200
|
+
This benchmark does **not** measure:
|
|
201
|
+
|
|
202
|
+
- Real internet latency, NAT traversal, or adversarial peers (everything runs on localhost)
|
|
203
|
+
- End-to-end proposer behavior beyond tx fetching (block construction, proving, etc.)
|
|
204
|
+
- Gossip-based mempool convergence—tx availability is injected directly into each worker's in-memory tx pool
|
|
205
|
+
|
|
206
|
+
## Files
|
|
207
|
+
|
|
208
|
+
| File | Purpose |
|
|
209
|
+
|------|---------|
|
|
210
|
+
| `p2p_client.proposal_tx_collector.bench.test.ts` | Test suite (cases, distributions, output formatting) |
|
|
211
|
+
| `proposal_tx_collector_worker.ts` | Collector-specific worker implementation |
|
|
212
|
+
| `proposal_tx_collector_worker_protocol.ts` | IPC message types and serialization |
|
|
213
|
+
| `src/testbench/worker_client_manager.ts` | Worker process manager (forking, IPC, orchestration) |
|
|
214
|
+
| `src/testbench/p2p_client_testbench_worker.ts` | General testbench worker implementation |
|
|
215
|
+
| `src/test-helpers/testbench-utils.ts` | Shared mocks and utilities (InMemoryTxPool, InMemoryAttestationPool, etc.) |
|
|
216
|
+
|
|
217
|
+
## Implementation Notes
|
|
218
|
+
|
|
219
|
+
- Workers run TypeScript via `ts-node/esm` unless a compiled JS worker exists at `dest/testbench/p2p_client_testbench_worker.js`
|
|
220
|
+
- Request/response rate limits are overridden so the benchmark is not throttled
|
|
221
|
+
- Workers generate txs locally from a shared seed to avoid sending large tx payloads over IPC
|
|
222
|
+
|
|
223
|
+
## Practical Tips
|
|
224
|
+
|
|
225
|
+
- Run on an otherwise idle machine; CPU scheduling noise matters when spawning 30 node processes
|
|
226
|
+
- If you see intermittent failures, increase `TIMEOUT_MS` or reduce `PEERS_PER_RUN` for local iteration
|
|
227
|
+
- Use `BENCH_OUTPUT` in CI to track performance regressions over time
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { MockL2BlockSource } from '@aztec/archiver/test';
|
|
2
|
+
import { SecretValue } from '@aztec/foundation/config';
|
|
3
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
5
|
+
import { DateProvider, Timer, executeTimeout } from '@aztec/foundation/timer';
|
|
6
|
+
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
7
|
+
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
8
|
+
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
9
|
+
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
10
|
+
import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
|
|
11
|
+
import { P2PClientType, PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
12
|
+
import type { Tx, TxValidationResult } from '@aztec/stdlib/tx';
|
|
13
|
+
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
14
|
+
|
|
15
|
+
import type { PeerId } from '@libp2p/interface';
|
|
16
|
+
import { peerIdFromString } from '@libp2p/peer-id';
|
|
17
|
+
|
|
18
|
+
import type { P2PConfig } from '../../../config.js';
|
|
19
|
+
import type { IBatchRequestTxValidator } from '../../../services/reqresp/batch-tx-requester/tx_validator.js';
|
|
20
|
+
import { RateLimitStatus } from '../../../services/reqresp/rate-limiter/rate_limiter.js';
|
|
21
|
+
import {
|
|
22
|
+
BatchTxRequesterCollector,
|
|
23
|
+
SendBatchRequestCollector,
|
|
24
|
+
} from '../../../services/tx_collection/proposal_tx_collector.js';
|
|
25
|
+
import { AlwaysTrueCircuitVerifier } from '../../../test-helpers/reqresp-nodes.js';
|
|
26
|
+
import {
|
|
27
|
+
BENCHMARK_CONSTANTS,
|
|
28
|
+
InMemoryAttestationPool,
|
|
29
|
+
InMemoryTxPool,
|
|
30
|
+
UNLIMITED_RATE_LIMIT_QUOTA,
|
|
31
|
+
calculateInternalTimeout,
|
|
32
|
+
createMockEpochCache,
|
|
33
|
+
createMockWorldStateSynchronizer,
|
|
34
|
+
} from '../../../test-helpers/testbench-utils.js';
|
|
35
|
+
import { createP2PClient } from '../../index.js';
|
|
36
|
+
import type { P2PClient } from '../../p2p_client.js';
|
|
37
|
+
import {
|
|
38
|
+
type WorkerCommand,
|
|
39
|
+
type WorkerResponse,
|
|
40
|
+
deserializeBlockProposal,
|
|
41
|
+
deserializeTx,
|
|
42
|
+
deserializeTxHash,
|
|
43
|
+
} from './proposal_tx_collector_worker_protocol.js';
|
|
44
|
+
|
|
45
|
+
let client: P2PClient | undefined;
|
|
46
|
+
let txPool: InMemoryTxPool | undefined;
|
|
47
|
+
let attestationPool: InMemoryAttestationPool | undefined;
|
|
48
|
+
let logger = createLogger('p2p:proposal-bench');
|
|
49
|
+
let kvStore: Awaited<ReturnType<typeof openTmpStore>> | undefined;
|
|
50
|
+
let ipcDisconnected = false;
|
|
51
|
+
|
|
52
|
+
function ensureClient(): P2PClient {
|
|
53
|
+
if (!client || !txPool) {
|
|
54
|
+
throw new Error('Worker client not started');
|
|
55
|
+
}
|
|
56
|
+
return client;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isIpcDisconnectError(err: unknown): boolean {
|
|
60
|
+
const code = (err as NodeJS.ErrnoException | undefined)?.code;
|
|
61
|
+
return code === 'EPIPE' || code === 'ERR_IPC_CHANNEL_CLOSED';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function sendMessage(message: WorkerResponse): Promise<void> {
|
|
65
|
+
const send = process.send;
|
|
66
|
+
if (!send || !process.connected || ipcDisconnected) {
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return new Promise(resolve => {
|
|
71
|
+
const fallbackTimeout = setTimeout(() => resolve(), 2000);
|
|
72
|
+
try {
|
|
73
|
+
send.call(process, message, undefined, undefined, err => {
|
|
74
|
+
clearTimeout(fallbackTimeout);
|
|
75
|
+
if (!err) {
|
|
76
|
+
resolve();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (isIpcDisconnectError(err)) {
|
|
80
|
+
ipcDisconnected = true;
|
|
81
|
+
resolve();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
logger.warn('Failed to send IPC message', { error: err?.message ?? String(err) });
|
|
85
|
+
resolve();
|
|
86
|
+
});
|
|
87
|
+
} catch (err: any) {
|
|
88
|
+
clearTimeout(fallbackTimeout);
|
|
89
|
+
if (isIpcDisconnectError(err)) {
|
|
90
|
+
ipcDisconnected = true;
|
|
91
|
+
resolve();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
logger.warn('Failed to send IPC message', { error: err?.message ?? String(err) });
|
|
95
|
+
resolve();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function startClient(config: P2PConfig, clientIndex: number) {
|
|
101
|
+
txPool = new InMemoryTxPool();
|
|
102
|
+
attestationPool = new InMemoryAttestationPool();
|
|
103
|
+
const epochCache = createMockEpochCache();
|
|
104
|
+
const worldState = createMockWorldStateSynchronizer();
|
|
105
|
+
const l2BlockSource = new MockL2BlockSource();
|
|
106
|
+
const proofVerifier = new AlwaysTrueCircuitVerifier();
|
|
107
|
+
kvStore = await openTmpStore(`proposal-bench-${clientIndex}`, true, BENCHMARK_CONSTANTS.KV_STORE_MAP_SIZE_KB);
|
|
108
|
+
logger = createLogger(`p2p:proposal-bench:${clientIndex}`);
|
|
109
|
+
|
|
110
|
+
const telemetry = getTelemetryClient();
|
|
111
|
+
const deps = {
|
|
112
|
+
txPool,
|
|
113
|
+
attestationPool,
|
|
114
|
+
store: kvStore,
|
|
115
|
+
logger,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
client = await createP2PClient(
|
|
119
|
+
P2PClientType.Full,
|
|
120
|
+
config as P2PConfig & DataStoreConfig,
|
|
121
|
+
l2BlockSource as L2BlockSource & ContractDataSource,
|
|
122
|
+
proofVerifier as ClientProtocolCircuitVerifier,
|
|
123
|
+
worldState,
|
|
124
|
+
epochCache,
|
|
125
|
+
'proposal-tx-collector-bench-worker',
|
|
126
|
+
new DateProvider(),
|
|
127
|
+
telemetry as TelemetryClient,
|
|
128
|
+
deps,
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
await client.start();
|
|
132
|
+
installUnlimitedRateLimits();
|
|
133
|
+
|
|
134
|
+
for (let i = 0; i < 120; i++) {
|
|
135
|
+
if (client.isReady()) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
await sleep(500);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
throw new Error('Timed out waiting for P2P client readiness');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function installSamplerOverrides(peerList: ReturnType<typeof peerIdFromString>[]) {
|
|
145
|
+
const reqResp = (ensureClient() as any).p2pService.reqresp as any;
|
|
146
|
+
const sampler = reqResp.connectionSampler as any;
|
|
147
|
+
|
|
148
|
+
sampler.getPeerListSortedByConnectionCountAsc = (excluding?: Set<string>) => {
|
|
149
|
+
if (!excluding || excluding.size === 0) {
|
|
150
|
+
return peerList;
|
|
151
|
+
}
|
|
152
|
+
return peerList.filter(peerId => !excluding.has(peerId.toString()));
|
|
153
|
+
};
|
|
154
|
+
sampler.samplePeersBatch = (numberToSample: number, excluding?: Map<string, boolean>) => {
|
|
155
|
+
const filtered = peerList.filter(peerId => !excluding?.has(peerId.toString()));
|
|
156
|
+
return filtered.slice(0, Math.min(numberToSample, filtered.length));
|
|
157
|
+
};
|
|
158
|
+
sampler.getPeer = (excluding?: Map<string, boolean>) => {
|
|
159
|
+
const filtered = peerList.filter(peerId => !excluding?.has(peerId.toString()));
|
|
160
|
+
return filtered[0];
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function installUnlimitedRateLimits() {
|
|
165
|
+
const reqResp = (ensureClient() as any).p2pService.reqresp as any;
|
|
166
|
+
const rateLimiter = reqResp.rateLimiter as any;
|
|
167
|
+
|
|
168
|
+
rateLimiter.getRateLimits = () => UNLIMITED_RATE_LIMIT_QUOTA;
|
|
169
|
+
rateLimiter.allow = () => RateLimitStatus.Allowed;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async function runCollector(cmd: Extract<WorkerCommand, { type: 'RUN_COLLECTOR' }>) {
|
|
173
|
+
const { collectorType, txHashes, blockProposal, pinnedPeerId, peerIds, timeoutMs } = cmd;
|
|
174
|
+
const reqResp = (ensureClient() as any).p2pService.reqresp as any;
|
|
175
|
+
const peerList = peerIds.map(peerId => peerIdFromString(peerId));
|
|
176
|
+
|
|
177
|
+
installSamplerOverrides(peerList);
|
|
178
|
+
installUnlimitedRateLimits();
|
|
179
|
+
|
|
180
|
+
const p2pService = {
|
|
181
|
+
reqResp,
|
|
182
|
+
connectionSampler: {
|
|
183
|
+
getPeerListSortedByConnectionCountAsc: () => peerList,
|
|
184
|
+
},
|
|
185
|
+
txValidatorConfig: {
|
|
186
|
+
l1ChainId: 1,
|
|
187
|
+
rollupVersion: 1,
|
|
188
|
+
proofVerifier: {
|
|
189
|
+
verifyProof: () => Promise.resolve({ valid: true, durationMs: 0, totalDurationMs: 0 }),
|
|
190
|
+
stop: () => Promise.resolve(),
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
peerScoring: {
|
|
194
|
+
penalizePeer: (_peerId: PeerId, _penalty: PeerErrorSeverity) => {},
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const parsedTxHashes = txHashes.map(deserializeTxHash);
|
|
199
|
+
const parsedProposal = deserializeBlockProposal(blockProposal);
|
|
200
|
+
const pinnedPeer = pinnedPeerId ? peerIdFromString(pinnedPeerId) : undefined;
|
|
201
|
+
|
|
202
|
+
const timer = new Timer();
|
|
203
|
+
let fetchedCount = 0;
|
|
204
|
+
|
|
205
|
+
const internalTimeoutMs = calculateInternalTimeout(timeoutMs);
|
|
206
|
+
|
|
207
|
+
const noopTxValidator: IBatchRequestTxValidator = {
|
|
208
|
+
validateRequestedTx: (_tx: Tx): Promise<TxValidationResult> => Promise.resolve({ result: 'valid' }),
|
|
209
|
+
validateRequestedTxs: (txs: Tx[]): Promise<TxValidationResult[]> =>
|
|
210
|
+
Promise.resolve(txs.map(() => ({ result: 'valid' }))),
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
if (collectorType === 'batch-requester') {
|
|
215
|
+
const collector = new BatchTxRequesterCollector(p2pService, logger, new DateProvider(), noopTxValidator);
|
|
216
|
+
const fetched = await executeTimeout(
|
|
217
|
+
(_signal: AbortSignal) => collector.collectTxs(parsedTxHashes, parsedProposal, pinnedPeer, internalTimeoutMs),
|
|
218
|
+
timeoutMs,
|
|
219
|
+
() => new Error(`Collector timed out after ${timeoutMs}ms`),
|
|
220
|
+
);
|
|
221
|
+
fetchedCount = fetched.length;
|
|
222
|
+
} else {
|
|
223
|
+
const collector = new SendBatchRequestCollector(
|
|
224
|
+
p2pService,
|
|
225
|
+
BENCHMARK_CONSTANTS.FIXED_MAX_PEERS,
|
|
226
|
+
BENCHMARK_CONSTANTS.FIXED_MAX_RETRY_ATTEMPTS,
|
|
227
|
+
);
|
|
228
|
+
const fetched = await executeTimeout(
|
|
229
|
+
(_signal: AbortSignal) => collector.collectTxs(parsedTxHashes, parsedProposal, pinnedPeer, internalTimeoutMs),
|
|
230
|
+
timeoutMs,
|
|
231
|
+
() => new Error(`Collector timed out after ${timeoutMs}ms`),
|
|
232
|
+
);
|
|
233
|
+
fetchedCount = fetched.length;
|
|
234
|
+
}
|
|
235
|
+
} catch (err: any) {
|
|
236
|
+
logger.warn(`Collector error: ${err?.message ?? String(err)}`);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return { durationMs: timer.ms(), fetchedCount };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async function stopClient() {
|
|
243
|
+
if (!client) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
await client.stop();
|
|
247
|
+
if (kvStore?.close) {
|
|
248
|
+
await kvStore.close();
|
|
249
|
+
}
|
|
250
|
+
client = undefined;
|
|
251
|
+
txPool = undefined;
|
|
252
|
+
attestationPool = undefined;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
process.on('disconnect', () => {
|
|
256
|
+
ipcDisconnected = true;
|
|
257
|
+
void stopClient().finally(() => process.exit(0));
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
process.on('error', err => {
|
|
261
|
+
if (isIpcDisconnectError(err)) {
|
|
262
|
+
ipcDisconnected = true;
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
logger.warn('Worker process error', { error: err?.message ?? String(err) });
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
process.on('message', (msg: WorkerCommand) => {
|
|
269
|
+
void (async () => {
|
|
270
|
+
if (!msg || typeof msg !== 'object') {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const requestId = msg.requestId;
|
|
275
|
+
|
|
276
|
+
try {
|
|
277
|
+
switch (msg.type) {
|
|
278
|
+
case 'START': {
|
|
279
|
+
const rawConfig = msg.config;
|
|
280
|
+
const config: P2PConfig = {
|
|
281
|
+
...rawConfig,
|
|
282
|
+
peerIdPrivateKey: rawConfig.peerIdPrivateKey ? new SecretValue(rawConfig.peerIdPrivateKey) : undefined,
|
|
283
|
+
} as P2PConfig;
|
|
284
|
+
|
|
285
|
+
await startClient(config, msg.clientIndex);
|
|
286
|
+
const peerId = (ensureClient() as any).p2pService.node.peerId.toString();
|
|
287
|
+
await sendMessage({ type: 'READY', requestId, peerId });
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case 'SET_TXS': {
|
|
291
|
+
if (!txPool) {
|
|
292
|
+
throw new Error('Tx pool not initialized');
|
|
293
|
+
}
|
|
294
|
+
const txs = msg.txs.map(deserializeTx);
|
|
295
|
+
const count = msg.mode === 'append' ? txPool.appendTxs(txs) : txPool.setTxs(txs);
|
|
296
|
+
await sendMessage({ type: 'TXS_SET', requestId, count });
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
case 'SET_BLOCK_PROPOSAL': {
|
|
300
|
+
if (!attestationPool) {
|
|
301
|
+
throw new Error('Attestation pool not initialized');
|
|
302
|
+
}
|
|
303
|
+
const proposal = deserializeBlockProposal(msg.blockProposal);
|
|
304
|
+
await attestationPool.tryAddBlockProposal(proposal);
|
|
305
|
+
await sendMessage({ type: 'BLOCK_PROPOSAL_SET', requestId, archiveRoot: proposal.archive.toString() });
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
case 'RUN_COLLECTOR': {
|
|
309
|
+
const { durationMs, fetchedCount } = await runCollector(msg);
|
|
310
|
+
await sendMessage({ type: 'COLLECTOR_RESULT', requestId, durationMs, fetchedCount });
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
case 'GET_PEER_COUNT': {
|
|
314
|
+
const peers = await ensureClient().getPeers();
|
|
315
|
+
await sendMessage({ type: 'PEER_COUNT', requestId, count: peers.length });
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
case 'STOP': {
|
|
319
|
+
await stopClient();
|
|
320
|
+
await sendMessage({ type: 'STOPPED', requestId });
|
|
321
|
+
process.exit(0);
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
default: {
|
|
325
|
+
const _exhaustive: never = msg;
|
|
326
|
+
throw new Error(`Unknown command: ${(msg as { type?: string }).type}`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
} catch (err: any) {
|
|
330
|
+
await sendMessage({ type: 'ERROR', requestId, error: err?.message ?? String(err) });
|
|
331
|
+
if (msg.type === 'START') {
|
|
332
|
+
process.exit(1);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
})();
|
|
336
|
+
});
|