@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,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT,
|
|
3
2
|
MAX_PROCESSABLE_L2_GAS,
|
|
3
|
+
MAX_TX_DA_GAS,
|
|
4
4
|
PRIVATE_TX_L2_GAS_OVERHEAD,
|
|
5
5
|
PUBLIC_TX_L2_GAS_OVERHEAD,
|
|
6
6
|
TX_DA_GAS_OVERHEAD,
|
|
@@ -36,6 +36,18 @@ export interface HasGasLimitData {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/** Structural interface for types that carry max fee per gas data, used by {@link MaxFeePerGasValidator}. */
|
|
40
|
+
export interface HasMaxFeePerGasData {
|
|
41
|
+
txHash: { toString(): string };
|
|
42
|
+
data: {
|
|
43
|
+
constants: {
|
|
44
|
+
txContext: {
|
|
45
|
+
gasSettings: { maxFeesPerGas: GasFees };
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
39
51
|
/**
|
|
40
52
|
* Validates that a transaction's gas limits are within acceptable bounds.
|
|
41
53
|
*
|
|
@@ -52,22 +64,21 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
|
|
|
52
64
|
#log: Logger;
|
|
53
65
|
#effectiveMaxL2Gas: number;
|
|
54
66
|
#effectiveMaxDAGas: number;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}) {
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param maxTxL2Gas - The network admission limit on L2 gas a single tx may declare (the per-block mana
|
|
70
|
+
* allocation, see {@link computeNetworkTxGasLimits}). Defaults to the per-tx protocol maximum, so callers
|
|
71
|
+
* that pass nothing (e.g. block building) enforce only the protocol ceiling.
|
|
72
|
+
* @param maxTxDAGas - The network admission limit on DA gas a single tx may declare. Defaults to the
|
|
73
|
+
* per-tx protocol maximum {@link MAX_TX_DA_GAS}.
|
|
74
|
+
*/
|
|
75
|
+
constructor(opts?: { maxTxL2Gas?: number; maxTxDAGas?: number; bindings?: LoggerBindings }) {
|
|
65
76
|
this.#log = createLogger('sequencer:tx_validator:tx_gas', opts?.bindings);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.#effectiveMaxL2Gas = Math.min(MAX_PROCESSABLE_L2_GAS,
|
|
70
|
-
this.#effectiveMaxDAGas = Math.min(
|
|
77
|
+
// The passed limits are network admission limits; clamp to the per-tx protocol maxima as a hard ceiling.
|
|
78
|
+
// MAX_TX_DA_GAS bounds DA by what a single tx can actually post to a blob; declaring more is meaningless
|
|
79
|
+
// and would let a tx reserve checkpoint/block DA budget during proposal building it can't use.
|
|
80
|
+
this.#effectiveMaxL2Gas = Math.min(MAX_PROCESSABLE_L2_GAS, opts?.maxTxL2Gas ?? Infinity);
|
|
81
|
+
this.#effectiveMaxDAGas = Math.min(MAX_TX_DA_GAS, opts?.maxTxDAGas ?? Infinity);
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
validateTx(tx: T): Promise<TxValidationResult> {
|
|
@@ -87,41 +98,94 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
|
|
|
87
98
|
gasLimits,
|
|
88
99
|
minGasLimits,
|
|
89
100
|
});
|
|
90
|
-
return {
|
|
101
|
+
return {
|
|
102
|
+
result: 'invalid',
|
|
103
|
+
reason: [
|
|
104
|
+
`${TX_ERROR_INSUFFICIENT_GAS_LIMIT} (required=da:${minGasLimits.daGas},l2:${minGasLimits.l2Gas} got=da:${gasLimits.daGas},l2:${gasLimits.l2Gas})`,
|
|
105
|
+
],
|
|
106
|
+
};
|
|
91
107
|
}
|
|
92
108
|
|
|
93
109
|
if (gasLimits.l2Gas > this.#effectiveMaxL2Gas) {
|
|
94
110
|
this.#log.verbose(`Rejecting transaction due to the L2 gas limit being higher than the effective maximum`, {
|
|
95
111
|
gasLimits,
|
|
96
112
|
effectiveMaxL2Gas: this.#effectiveMaxL2Gas,
|
|
97
|
-
rollupManaLimit: this.#rollupManaLimit,
|
|
98
|
-
maxBlockL2Gas: this.#maxBlockL2Gas,
|
|
99
113
|
});
|
|
100
|
-
return {
|
|
114
|
+
return {
|
|
115
|
+
result: 'invalid',
|
|
116
|
+
reason: [`${TX_ERROR_GAS_LIMIT_TOO_HIGH} (l2Gas=${gasLimits.l2Gas}, max=${this.#effectiveMaxL2Gas})`],
|
|
117
|
+
};
|
|
101
118
|
}
|
|
102
119
|
|
|
103
120
|
if (gasLimits.daGas > this.#effectiveMaxDAGas) {
|
|
104
121
|
this.#log.verbose(`Rejecting transaction due to the DA gas limit being higher than the effective maximum`, {
|
|
105
122
|
gasLimits,
|
|
106
123
|
effectiveMaxDAGas: this.#effectiveMaxDAGas,
|
|
107
|
-
maxBlockDAGas: this.#maxBlockDAGas,
|
|
108
124
|
});
|
|
109
|
-
return {
|
|
125
|
+
return {
|
|
126
|
+
result: 'invalid',
|
|
127
|
+
reason: [`${TX_ERROR_GAS_LIMIT_TOO_HIGH} (daGas=${gasLimits.daGas}, max=${this.#effectiveMaxDAGas})`],
|
|
128
|
+
};
|
|
110
129
|
}
|
|
111
130
|
|
|
112
131
|
return { result: 'valid' };
|
|
113
132
|
}
|
|
114
133
|
}
|
|
115
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Validates that a transaction's max fee per gas meets the current block's gas fees.
|
|
137
|
+
*
|
|
138
|
+
* Rejects transactions whose maxFeesPerGas is below the current block's gas fees
|
|
139
|
+
* on either dimension (DA or L2). This is a cheap, stateless check.
|
|
140
|
+
*
|
|
141
|
+
* Generic over T so it can validate both full {@link Tx} objects and {@link TxMetaData}
|
|
142
|
+
* (used during pending pool migration).
|
|
143
|
+
*
|
|
144
|
+
* Used by: pending pool migration (via factory), and indirectly by {@link GasTxValidator}.
|
|
145
|
+
*/
|
|
146
|
+
export class MaxFeePerGasValidator<T extends HasMaxFeePerGasData> implements TxValidator<T> {
|
|
147
|
+
#log: Logger;
|
|
148
|
+
#gasFees: GasFees;
|
|
149
|
+
|
|
150
|
+
constructor(gasFees: GasFees, bindings?: LoggerBindings) {
|
|
151
|
+
this.#log = createLogger('sequencer:tx_validator:tx_gas', bindings);
|
|
152
|
+
this.#gasFees = gasFees;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
validateTx(tx: T): Promise<TxValidationResult> {
|
|
156
|
+
return Promise.resolve(this.validateMaxFeePerGas(tx));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Checks maxFeesPerGas >= current block gas fees on both dimensions. */
|
|
160
|
+
validateMaxFeePerGas(tx: T): TxValidationResult {
|
|
161
|
+
const maxFeesPerGas = tx.data.constants.txContext.gasSettings.maxFeesPerGas;
|
|
162
|
+
const notEnoughMaxFees =
|
|
163
|
+
maxFeesPerGas.feePerDaGas < this.#gasFees.feePerDaGas || maxFeesPerGas.feePerL2Gas < this.#gasFees.feePerL2Gas;
|
|
164
|
+
|
|
165
|
+
if (notEnoughMaxFees) {
|
|
166
|
+
this.#log.verbose(`Rejecting transaction ${tx.txHash.toString()} due to insufficient fee per gas`, {
|
|
167
|
+
txMaxFeesPerGas: maxFeesPerGas.toInspect(),
|
|
168
|
+
currentGasFees: this.#gasFees.toInspect(),
|
|
169
|
+
});
|
|
170
|
+
return {
|
|
171
|
+
result: 'invalid',
|
|
172
|
+
reason: [
|
|
173
|
+
`${TX_ERROR_INSUFFICIENT_FEE_PER_GAS} (maxFee=da:${maxFeesPerGas.feePerDaGas},l2:${maxFeesPerGas.feePerL2Gas} required=da:${this.#gasFees.feePerDaGas},l2:${this.#gasFees.feePerL2Gas})`,
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return { result: 'valid' };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
116
181
|
/**
|
|
117
182
|
* Validates that a transaction can pay its gas fees.
|
|
118
183
|
*
|
|
119
184
|
* Runs three checks in order:
|
|
120
185
|
* 1. **Gas limits** (delegates to {@link GasLimitsValidator}) — rejects if limits are
|
|
121
186
|
* out of bounds.
|
|
122
|
-
* 2. **Max fee per gas** —
|
|
123
|
-
* the current block's gas fees.
|
|
124
|
-
* become eligible in a later block with lower fees.
|
|
187
|
+
* 2. **Max fee per gas** — rejects the tx if its maxFeesPerGas is below
|
|
188
|
+
* the current block's gas fees.
|
|
125
189
|
* 3. **Fee payer balance** — reads the fee payer's FeeJuice balance from public state,
|
|
126
190
|
* adds any pending claim from a setup-phase `_increase_public_balance` call, and
|
|
127
191
|
* rejects if the total is less than the tx's fee limit (gasLimits * maxFeePerGas).
|
|
@@ -133,14 +197,14 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
133
197
|
#publicDataSource: PublicStateSource;
|
|
134
198
|
#feeJuiceAddress: AztecAddress;
|
|
135
199
|
#gasFees: GasFees;
|
|
136
|
-
#gasLimitOpts?: {
|
|
200
|
+
#gasLimitOpts?: { maxTxL2Gas?: number; maxTxDAGas?: number };
|
|
137
201
|
|
|
138
202
|
constructor(
|
|
139
203
|
publicDataSource: PublicStateSource,
|
|
140
204
|
feeJuiceAddress: AztecAddress,
|
|
141
205
|
gasFees: GasFees,
|
|
142
206
|
private bindings?: LoggerBindings,
|
|
143
|
-
opts?: {
|
|
207
|
+
opts?: { maxTxL2Gas?: number; maxTxDAGas?: number },
|
|
144
208
|
) {
|
|
145
209
|
this.#log = createLogger('sequencer:tx_validator:tx_gas', bindings);
|
|
146
210
|
this.#publicDataSource = publicDataSource;
|
|
@@ -155,37 +219,15 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
155
219
|
bindings: this.bindings,
|
|
156
220
|
}).validateGasLimit(tx);
|
|
157
221
|
if (gasLimitValidation.result === 'invalid') {
|
|
158
|
-
return
|
|
222
|
+
return gasLimitValidation;
|
|
159
223
|
}
|
|
160
|
-
|
|
161
|
-
|
|
224
|
+
const maxFeeValidation = new MaxFeePerGasValidator(this.#gasFees, this.bindings).validateMaxFeePerGas(tx);
|
|
225
|
+
if (maxFeeValidation.result === 'invalid') {
|
|
226
|
+
return maxFeeValidation;
|
|
162
227
|
}
|
|
163
228
|
return await this.validateTxFee(tx);
|
|
164
229
|
}
|
|
165
230
|
|
|
166
|
-
/**
|
|
167
|
-
* Check whether the tx's max fees are valid for the current block, and skip if not.
|
|
168
|
-
* We skip instead of invalidating since the tx may become eligible later.
|
|
169
|
-
* Note that circuits check max fees even if fee payer is unset, so we
|
|
170
|
-
* keep this validation even if the tx does not pay fees.
|
|
171
|
-
*/
|
|
172
|
-
#shouldSkip(tx: Tx): boolean {
|
|
173
|
-
const gasSettings = tx.data.constants.txContext.gasSettings;
|
|
174
|
-
|
|
175
|
-
// Skip the tx if its max fees are not enough for the current block's gas fees.
|
|
176
|
-
const maxFeesPerGas = gasSettings.maxFeesPerGas;
|
|
177
|
-
const notEnoughMaxFees =
|
|
178
|
-
maxFeesPerGas.feePerDaGas < this.#gasFees.feePerDaGas || maxFeesPerGas.feePerL2Gas < this.#gasFees.feePerL2Gas;
|
|
179
|
-
|
|
180
|
-
if (notEnoughMaxFees) {
|
|
181
|
-
this.#log.verbose(`Skipping transaction ${tx.getTxHash().toString()} due to insufficient fee per gas`, {
|
|
182
|
-
txMaxFeesPerGas: maxFeesPerGas.toInspect(),
|
|
183
|
-
currentGasFees: this.#gasFees.toInspect(),
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
return notEnoughMaxFees;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
231
|
/**
|
|
190
232
|
* Checks the fee payer has enough FeeJuice balance to cover the tx's fee limit.
|
|
191
233
|
* Accounts for any pending claim from a setup-phase `_increase_public_balance` call.
|
|
@@ -212,7 +254,10 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
212
254
|
balance,
|
|
213
255
|
feeLimit,
|
|
214
256
|
});
|
|
215
|
-
return {
|
|
257
|
+
return {
|
|
258
|
+
result: 'invalid',
|
|
259
|
+
reason: [`${TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE} (required=${feeLimit}, available=${balance})`],
|
|
260
|
+
};
|
|
216
261
|
}
|
|
217
262
|
return { result: 'valid' };
|
|
218
263
|
}
|
|
@@ -40,7 +40,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
40
40
|
// which are needed for public FPC flows, but fail if the account contract hasnt been deployed yet,
|
|
41
41
|
// which is what we're trying to do as part of the current txs.
|
|
42
42
|
// We only need to create/revert checkpoint here because of this addNewContracts call.
|
|
43
|
-
|
|
43
|
+
this.contractsDB.addNewContracts(tx);
|
|
44
44
|
|
|
45
45
|
if (!tx.data.forPublic) {
|
|
46
46
|
this.#log.debug(
|
|
@@ -97,7 +97,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
97
97
|
}
|
|
98
98
|
if (
|
|
99
99
|
entry.rejectNullMsgSender &&
|
|
100
|
-
publicCall.request.msgSender.equals(AztecAddress.
|
|
100
|
+
publicCall.request.msgSender.equals(AztecAddress.fromBigIntUnsafe(NULL_MSG_SENDER_CONTRACT_ADDRESS))
|
|
101
101
|
) {
|
|
102
102
|
return TX_ERROR_SETUP_NULL_MSG_SENDER;
|
|
103
103
|
}
|
|
@@ -130,7 +130,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
130
130
|
}
|
|
131
131
|
if (
|
|
132
132
|
entry.rejectNullMsgSender &&
|
|
133
|
-
publicCall.request.msgSender.equals(AztecAddress.
|
|
133
|
+
publicCall.request.msgSender.equals(AztecAddress.fromBigIntUnsafe(NULL_MSG_SENDER_CONTRACT_ADDRESS))
|
|
134
134
|
) {
|
|
135
135
|
return TX_ERROR_SETUP_NULL_MSG_SENDER;
|
|
136
136
|
}
|
|
@@ -3,6 +3,8 @@ import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/ser
|
|
|
3
3
|
import { TX_ERROR_INVALID_PROOF, Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
4
4
|
|
|
5
5
|
export class TxProofValidator implements TxValidator<Tx> {
|
|
6
|
+
public readonly identifier: symbol = Symbol('TxProofValidator');
|
|
7
|
+
|
|
6
8
|
#log: Logger;
|
|
7
9
|
|
|
8
10
|
constructor(
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { LruMap } from '@aztec/foundation/collection';
|
|
2
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import type { Tx, TxValidationResult } from '@aztec/stdlib/tx';
|
|
4
|
+
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Minimal interface consumed by {@link CachedTxValidator}.
|
|
9
|
+
* Keeping the dependency on an interface lets callers (and tests) substitute any cache implementation.
|
|
10
|
+
*/
|
|
11
|
+
export interface ITxValidationCache {
|
|
12
|
+
/** Returns the cached promise if present, otherwise calls `validate`, caches its promise, and returns it. */
|
|
13
|
+
getOrValidate(
|
|
14
|
+
validatorSymbol: symbol,
|
|
15
|
+
tx: Tx,
|
|
16
|
+
validate: () => Promise<TxValidationResult>,
|
|
17
|
+
): Promise<TxValidationResult>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Caches per-validator tx validation results to avoid redundant work across repeated validation calls.
|
|
22
|
+
*
|
|
23
|
+
* The cache key is composed from the validator symbol and tx hash, ensuring results are
|
|
24
|
+
* scoped to the specific validator that produced them.
|
|
25
|
+
*
|
|
26
|
+
* Promises are stored before they are awaited, so concurrent calls for the same pair share
|
|
27
|
+
* a single in-flight validation rather than launching duplicate work.
|
|
28
|
+
*
|
|
29
|
+
* Entries are evicted in least-recently-used order once the cache reaches `maxSize`.
|
|
30
|
+
*/
|
|
31
|
+
export class TxValidationCache implements ITxValidationCache {
|
|
32
|
+
#log: Logger;
|
|
33
|
+
|
|
34
|
+
private readonly entries: LruMap<string, Promise<TxValidationResult>>;
|
|
35
|
+
// Remember hashes for known Tx object references to skip rehashing on subsequent lookups.
|
|
36
|
+
// WeakMap holds keys weakly, so an entry doesn't keep the Tx alive once nothing else references it.
|
|
37
|
+
private readonly txHashesCache: WeakMap<Tx, string> = new WeakMap();
|
|
38
|
+
|
|
39
|
+
constructor(maxSize: number) {
|
|
40
|
+
this.entries = new LruMap(maxSize);
|
|
41
|
+
this.#log = createLogger('p2p:tx_validation_cache');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Computes the cache key scoping a validation result to a specific validator and tx.
|
|
46
|
+
*
|
|
47
|
+
* @param validatorSymbol - The symbol of the validator.
|
|
48
|
+
* @param tx - The tx to compute the key for.
|
|
49
|
+
* @returns The cache key.
|
|
50
|
+
*
|
|
51
|
+
* Note: the key should NOT use the tx.hash because it can't be trusted at this point.
|
|
52
|
+
*/
|
|
53
|
+
public key(validatorSymbol: symbol, tx: Tx): string {
|
|
54
|
+
// Serializing the tx dominates cost (~5 ms). If we have already hashed this object, skip toBuffer + hash.
|
|
55
|
+
let hash = this.txHashesCache.get(tx);
|
|
56
|
+
if (hash === undefined) {
|
|
57
|
+
hash = createHash('sha256').update(tx.toBuffer()).digest('hex');
|
|
58
|
+
this.txHashesCache.set(tx, hash);
|
|
59
|
+
}
|
|
60
|
+
return `${Symbol.keyFor(validatorSymbol) ?? validatorSymbol.toString()}:${hash}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Returns the cached promise for the given key, or undefined if not cached. Refreshes recency. */
|
|
64
|
+
public get(key: string): Promise<TxValidationResult> | undefined {
|
|
65
|
+
return this.entries.get(key);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Stores a validation promise under the given key, evicting the LRU entry if at capacity. */
|
|
69
|
+
public set(key: string, result: Promise<TxValidationResult>): void {
|
|
70
|
+
this.entries.set(key, result);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Removes the cached validation promise for the given key. */
|
|
74
|
+
public delete(key: string): void {
|
|
75
|
+
this.entries.delete(key);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Returns the cached promise if present, otherwise calls `validate`, stores its promise
|
|
80
|
+
* immediately (before awaiting), and returns it.
|
|
81
|
+
*/
|
|
82
|
+
public getOrValidate(
|
|
83
|
+
validatorSymbol: symbol,
|
|
84
|
+
tx: Tx,
|
|
85
|
+
validate: () => Promise<TxValidationResult>,
|
|
86
|
+
): Promise<TxValidationResult> {
|
|
87
|
+
const key = this.key(validatorSymbol, tx);
|
|
88
|
+
const cached = this.get(key);
|
|
89
|
+
if (cached !== undefined) {
|
|
90
|
+
this.#log.debug('Returning cached tx validation result', {
|
|
91
|
+
validator: validatorSymbol.toString(),
|
|
92
|
+
txHash: tx.txHash.toString(),
|
|
93
|
+
key: key,
|
|
94
|
+
});
|
|
95
|
+
return cached;
|
|
96
|
+
}
|
|
97
|
+
const promise = validate();
|
|
98
|
+
this.set(key, promise);
|
|
99
|
+
return promise;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -28,8 +28,6 @@ export class AztecDatastore implements Datastore {
|
|
|
28
28
|
#memoryDatastore: Map<string, MemoryItem>;
|
|
29
29
|
#dbDatastore: AztecAsyncMap<string, Uint8Array>;
|
|
30
30
|
|
|
31
|
-
#batchOps: BatchOp[] = [];
|
|
32
|
-
|
|
33
31
|
private maxMemoryItems: number;
|
|
34
32
|
|
|
35
33
|
constructor(db: AztecAsyncKVStore, { maxMemoryItems } = { maxMemoryItems: 50 }) {
|
|
@@ -92,23 +90,17 @@ export class AztecDatastore implements Datastore {
|
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
batch(): Batch {
|
|
93
|
+
const ops: BatchOp[] = [];
|
|
95
94
|
return {
|
|
96
95
|
put: (key, value) => {
|
|
97
|
-
|
|
98
|
-
type: 'put',
|
|
99
|
-
key,
|
|
100
|
-
value,
|
|
101
|
-
});
|
|
96
|
+
ops.push({ type: 'put', key, value });
|
|
102
97
|
},
|
|
103
98
|
delete: key => {
|
|
104
|
-
|
|
105
|
-
type: 'del',
|
|
106
|
-
key,
|
|
107
|
-
});
|
|
99
|
+
ops.push({ type: 'del', key });
|
|
108
100
|
},
|
|
109
101
|
commit: async () => {
|
|
110
102
|
await this.#db.transactionAsync(async () => {
|
|
111
|
-
for (const op of
|
|
103
|
+
for (const op of ops) {
|
|
112
104
|
if (op.type === 'put' && op.value) {
|
|
113
105
|
await this.put(op.key, op.value);
|
|
114
106
|
} else if (op.type === 'del') {
|
|
@@ -116,7 +108,7 @@ export class AztecDatastore implements Datastore {
|
|
|
116
108
|
}
|
|
117
109
|
}
|
|
118
110
|
});
|
|
119
|
-
|
|
111
|
+
ops.length = 0;
|
|
120
112
|
},
|
|
121
113
|
};
|
|
122
114
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
2
|
import { sleep } from '@aztec/foundation/sleep';
|
|
3
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
4
|
+
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
3
5
|
import { type ComponentsVersions, checkCompressedComponentVersion } from '@aztec/stdlib/versioning';
|
|
4
6
|
import { OtelMetricsAdapter, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
5
7
|
|
|
@@ -14,9 +16,13 @@ import { createNodeENR } from '../../enr/generate-enr.js';
|
|
|
14
16
|
import { AZTEC_ENR_KEY, Discv5Event, PeerEvent } from '../../types/index.js';
|
|
15
17
|
import { convertToMultiaddr } from '../../util.js';
|
|
16
18
|
import { type PeerDiscoveryService, PeerDiscoveryState } from '../service.js';
|
|
19
|
+
import { PersistedEnrStore } from './persisted_enr_store.js';
|
|
17
20
|
|
|
18
21
|
const delayBeforeStart = 2000; // 2sec
|
|
19
22
|
|
|
23
|
+
/** Upper bound on persisted peer ENRs, to keep the store bounded as peers churn. */
|
|
24
|
+
const MAX_PERSISTED_PEER_ENRS = 100;
|
|
25
|
+
|
|
20
26
|
/**
|
|
21
27
|
* Peer discovery service using Discv5.
|
|
22
28
|
*/
|
|
@@ -35,12 +41,19 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
35
41
|
private bootstrapNodePeerIds: PeerId[] = [];
|
|
36
42
|
public bootstrapNodeEnrs: ENR[] = [];
|
|
37
43
|
private trustedPeerEnrs: ENR[] = [];
|
|
44
|
+
/** Node IDs of all config-provided peers (bootstrap, trusted, private); these are never persisted. */
|
|
45
|
+
private readonly configProvidedNodeIds: Set<string>;
|
|
38
46
|
|
|
39
47
|
private startTime = 0;
|
|
40
48
|
|
|
49
|
+
private currentIp: string | undefined;
|
|
50
|
+
|
|
51
|
+
/** Persistent store of discovered peer ENRs, used to re-seed discovery after a restart. */
|
|
52
|
+
private readonly persistedEnrs?: PersistedEnrStore;
|
|
53
|
+
|
|
41
54
|
private handlers = {
|
|
42
55
|
onMultiaddrUpdated: this.onMultiaddrUpdated.bind(this),
|
|
43
|
-
|
|
56
|
+
onPeerDiscovered: this.onPeerDiscovered.bind(this),
|
|
44
57
|
onEnrAdded: this.onEnrAdded.bind(this),
|
|
45
58
|
};
|
|
46
59
|
|
|
@@ -50,14 +63,27 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
50
63
|
private readonly packageVersion: string,
|
|
51
64
|
telemetry: TelemetryClient = getTelemetryClient(),
|
|
52
65
|
private logger = createLogger('p2p:discv5_service'),
|
|
66
|
+
store?: AztecAsyncKVStore,
|
|
53
67
|
configOverrides: Partial<IDiscv5CreateOptions> = {},
|
|
68
|
+
private readonly dateProvider: DateProvider = new DateProvider(),
|
|
54
69
|
) {
|
|
55
70
|
super();
|
|
71
|
+
|
|
72
|
+
this.persistedEnrs = store
|
|
73
|
+
? new PersistedEnrStore(store, MAX_PERSISTED_PEER_ENRS, createLogger(`${this.logger.module}:enr-store`))
|
|
74
|
+
: undefined;
|
|
75
|
+
|
|
56
76
|
const { p2pIp, p2pPort, p2pBroadcastPort, bootstrapNodes, trustedPeers, privatePeers } = config;
|
|
57
77
|
|
|
78
|
+
this.currentIp = p2pIp;
|
|
58
79
|
this.bootstrapNodeEnrs = bootstrapNodes.map(x => ENR.decodeTxt(x));
|
|
59
80
|
const privatePeerEnrs = new Set(privatePeers);
|
|
60
81
|
this.trustedPeerEnrs = trustedPeers.filter(x => !privatePeerEnrs.has(x)).map(x => ENR.decodeTxt(x));
|
|
82
|
+
// Peers supplied via config are re-injected from config on every start, so they must never end up
|
|
83
|
+
// in the persisted (discovered-peer) store — private peers especially must not be written there.
|
|
84
|
+
this.configProvidedNodeIds = new Set(
|
|
85
|
+
[...bootstrapNodes, ...trustedPeers, ...privatePeers].map(x => ENR.decodeTxt(x).nodeId),
|
|
86
|
+
);
|
|
61
87
|
|
|
62
88
|
// If no overridden broadcast port is provided, use the p2p port as the broadcast port
|
|
63
89
|
if (!p2pBroadcastPort) {
|
|
@@ -96,7 +122,8 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
96
122
|
lookupTimeout: 2000,
|
|
97
123
|
requestTimeout: 2000,
|
|
98
124
|
allowUnverifiedSessions: true,
|
|
99
|
-
enrUpdate: !p2pIp
|
|
125
|
+
enrUpdate: config.queryForIp || !p2pIp,
|
|
126
|
+
pingInterval: config.queryForIp ? 10_000 : 300_000,
|
|
100
127
|
...configOverrides.config,
|
|
101
128
|
},
|
|
102
129
|
metricsRegistry,
|
|
@@ -121,17 +148,40 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
121
148
|
}
|
|
122
149
|
};
|
|
123
150
|
|
|
124
|
-
this.discv5.on(Discv5Event.DISCOVERED, this.handlers.
|
|
151
|
+
this.discv5.on(Discv5Event.DISCOVERED, this.handlers.onPeerDiscovered);
|
|
125
152
|
this.discv5.on(Discv5Event.ENR_ADDED, this.handlers.onEnrAdded);
|
|
126
153
|
this.discv5.on(Discv5Event.MULTIADDR_UPDATED, this.handlers.onMultiaddrUpdated);
|
|
127
154
|
}
|
|
128
155
|
|
|
129
156
|
private onMultiaddrUpdated(m: Multiaddr) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
157
|
+
const newIp = m.nodeAddress().address;
|
|
158
|
+
const previousIp = this.currentIp;
|
|
159
|
+
|
|
160
|
+
if (newIp === previousIp) {
|
|
161
|
+
this.logger.debug('Discv5 confirmed current IP (no change)', { ip: newIp });
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const multiAddrTcp = multiaddr(convertToMultiaddr(newIp, this.config.p2pBroadcastPort!, 'tcp'));
|
|
133
166
|
this.enr.setLocationMultiaddr(multiAddrTcp);
|
|
134
|
-
this.
|
|
167
|
+
this.currentIp = newIp;
|
|
168
|
+
|
|
169
|
+
if (previousIp) {
|
|
170
|
+
this.logger.info('IP address changed, ENR updated', {
|
|
171
|
+
previousIp,
|
|
172
|
+
newIp,
|
|
173
|
+
multiaddr: multiAddrTcp.toString(),
|
|
174
|
+
enr: this.enr.encodeTxt(),
|
|
175
|
+
});
|
|
176
|
+
} else {
|
|
177
|
+
this.logger.info('Initial IP discovered via discv5, ENR updated', {
|
|
178
|
+
ip: newIp,
|
|
179
|
+
multiaddr: multiAddrTcp.toString(),
|
|
180
|
+
enr: this.enr.encodeTxt(),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
this.emit('ip:changed', newIp);
|
|
135
185
|
}
|
|
136
186
|
|
|
137
187
|
public async start(): Promise<void> {
|
|
@@ -140,14 +190,19 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
140
190
|
}
|
|
141
191
|
this.logger.debug('Starting DiscV5');
|
|
142
192
|
await this.discv5.start();
|
|
143
|
-
this.startTime =
|
|
193
|
+
this.startTime = this.dateProvider.now();
|
|
144
194
|
|
|
195
|
+
const enrUpdateEnabled = this.config.queryForIp || !this.config.p2pIp;
|
|
145
196
|
this.logger.info(`DiscV5 service started`, {
|
|
146
197
|
nodeId: this.enr.nodeId,
|
|
147
198
|
peerId: this.peerId,
|
|
148
199
|
enrUdp: await this.enr.getFullMultiaddr('udp'),
|
|
149
200
|
enrTcp: await this.enr.getFullMultiaddr('tcp'),
|
|
150
201
|
versions: this.versions,
|
|
202
|
+
enrUpdateEnabled,
|
|
203
|
+
queryForIp: this.config.queryForIp,
|
|
204
|
+
configuredIp: this.config.p2pIp ?? 'none',
|
|
205
|
+
pingIntervalMs: this.config.queryForIp ? 10_000 : 300_000,
|
|
151
206
|
});
|
|
152
207
|
this.currentState = PeerDiscoveryState.RUNNING;
|
|
153
208
|
|
|
@@ -187,6 +242,26 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
187
242
|
this.discv5.addEnr(enr);
|
|
188
243
|
}
|
|
189
244
|
}
|
|
245
|
+
|
|
246
|
+
// Re-seed discovery from peers persisted on previous runs. This lets a node rejoin the network
|
|
247
|
+
// after a restart even when no bootstrap node is reachable: discv5 has no on-disk routing table,
|
|
248
|
+
// so without this its DHT would start empty and rediscovery would depend on inbound dials alone.
|
|
249
|
+
if (this.persistedEnrs) {
|
|
250
|
+
// Drop peers that are now config-provided (re-injected above) or fail version checks.
|
|
251
|
+
const enrs = await this.persistedEnrs.load(
|
|
252
|
+
enr => this.validateEnr(enr) && !this.configProvidedNodeIds.has(enr.nodeId),
|
|
253
|
+
);
|
|
254
|
+
for (const enr of enrs) {
|
|
255
|
+
try {
|
|
256
|
+
this.discv5.addEnr(enr);
|
|
257
|
+
} catch (err) {
|
|
258
|
+
this.logger.debug(`Error re-seeding persisted ENR ${enr.nodeId}`, err);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (enrs.length > 0) {
|
|
262
|
+
this.logger.info(`Re-seeded discovery with ${enrs.length} persisted peer ENRs`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
190
265
|
}
|
|
191
266
|
|
|
192
267
|
public async runRandomNodesQuery(): Promise<void> {
|
|
@@ -196,8 +271,8 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
196
271
|
|
|
197
272
|
// First, wait some time before starting the peer discovery
|
|
198
273
|
// reference: https://github.com/ChainSafe/lodestar/issues/3423
|
|
199
|
-
const msSinceStart =
|
|
200
|
-
if (
|
|
274
|
+
const msSinceStart = this.dateProvider.now() - this.startTime;
|
|
275
|
+
if (this.dateProvider.now() - this.startTime <= delayBeforeStart) {
|
|
201
276
|
await sleep(delayBeforeStart - msSinceStart);
|
|
202
277
|
}
|
|
203
278
|
|
|
@@ -232,7 +307,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
232
307
|
if (this.currentState !== PeerDiscoveryState.RUNNING) {
|
|
233
308
|
return;
|
|
234
309
|
}
|
|
235
|
-
await this.discv5.off(Discv5Event.DISCOVERED, this.handlers.
|
|
310
|
+
await this.discv5.off(Discv5Event.DISCOVERED, this.handlers.onPeerDiscovered);
|
|
236
311
|
await this.discv5.off(Discv5Event.ENR_ADDED, this.handlers.onEnrAdded);
|
|
237
312
|
await this.discv5.off(Discv5Event.MULTIADDR_UPDATED, this.handlers.onMultiaddrUpdated);
|
|
238
313
|
|
|
@@ -242,12 +317,38 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
242
317
|
}
|
|
243
318
|
|
|
244
319
|
private async onEnrAdded(enr: ENR) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
320
|
+
try {
|
|
321
|
+
const multiAddrTcp = await enr.getFullMultiaddr('tcp');
|
|
322
|
+
const multiAddrUdp = await enr.getFullMultiaddr('udp');
|
|
323
|
+
this.logger.debug(`Added ENR ${enr.encodeTxt()}`, { multiAddrTcp, multiAddrUdp, nodeId: enr.nodeId });
|
|
324
|
+
// A peer just entered the routing table — persist it so we can re-seed discovery after a restart.
|
|
325
|
+
if (this.persistedEnrs && this.shouldPersist(enr)) {
|
|
326
|
+
await this.persistedEnrs.persist(enr);
|
|
327
|
+
}
|
|
328
|
+
this.onDiscovered(enr);
|
|
329
|
+
} catch (err) {
|
|
330
|
+
// A malformed ENR address field (e.g. a 3-byte TCP port) makes @nethermindeth/enr throw while
|
|
331
|
+
// parsing the multiaddr. This is an async event listener, so an unhandled rejection would crash
|
|
332
|
+
// the process — catch, log, and drop the ENR instead.
|
|
333
|
+
this.logger.warn(`Dropping ENR with unparseable address`, { nodeId: enr.nodeId, err });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
private async onPeerDiscovered(enr: ENR) {
|
|
338
|
+
// discv5 updates an existing routing-table entry on an ENR sequence bump without emitting enrAdded,
|
|
339
|
+
// so DISCOVERED is our only signal that a peer we already track may have changed address. Refresh
|
|
340
|
+
// the persisted copy (a no-op for peers we don't already store) so we don't keep dialing a stale ENR.
|
|
341
|
+
if (this.persistedEnrs && this.shouldPersist(enr)) {
|
|
342
|
+
await this.persistedEnrs.refresh(enr);
|
|
343
|
+
}
|
|
248
344
|
this.onDiscovered(enr);
|
|
249
345
|
}
|
|
250
346
|
|
|
347
|
+
/** Whether an ENR belongs in the persisted store: a validated, non-config peer that isn't ourselves. */
|
|
348
|
+
private shouldPersist(enr: ENR): boolean {
|
|
349
|
+
return !this.configProvidedNodeIds.has(enr.nodeId) && enr.nodeId !== this.enr.nodeId && this.validateEnr(enr);
|
|
350
|
+
}
|
|
351
|
+
|
|
251
352
|
private isOurBootnode(enr: ENR) {
|
|
252
353
|
return this.bootstrapNodeEnrs.some(x => x.nodeId === enr.nodeId);
|
|
253
354
|
}
|
|
@@ -281,6 +382,17 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
281
382
|
return false;
|
|
282
383
|
}
|
|
283
384
|
|
|
385
|
+
// A malformed TCP field (e.g. a non-2-byte port) makes @nethermindeth/enr throw while building the
|
|
386
|
+
// multiaddr. Reject such an ENR here so it's never emitted as a full peer or re-parsed by an
|
|
387
|
+
// unguarded listener (which would crash the process). A missing TCP addr is allowed — those peers
|
|
388
|
+
// are simply skipped at dial time.
|
|
389
|
+
try {
|
|
390
|
+
enr.getLocationMultiaddr('tcp');
|
|
391
|
+
} catch (err) {
|
|
392
|
+
this.logger.debug(`Peer node ${enr.nodeId} has an unparseable TCP address`, { err });
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
|
|
284
396
|
// And check it has the correct version
|
|
285
397
|
let compressedVersion;
|
|
286
398
|
try {
|