@aztec/p2p 4.0.0-nightly.20250907 → 4.0.0-nightly.20260108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +14 -4
- package/dest/client/factory.d.ts +3 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +9 -5
- package/dest/client/index.d.ts +1 -1
- package/dest/client/interface.d.ts +8 -6
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +13 -36
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +460 -63
- package/dest/config.d.ts +67 -61
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +28 -15
- package/dest/enr/generate-enr.d.ts +2 -2
- package/dest/enr/generate-enr.d.ts.map +1 -1
- package/dest/enr/generate-enr.js +1 -1
- package/dest/enr/index.d.ts +1 -1
- package/dest/errors/attestation-pool.error.d.ts +7 -0
- package/dest/errors/attestation-pool.error.d.ts.map +1 -0
- package/dest/errors/attestation-pool.error.js +12 -0
- package/dest/errors/reqresp.error.d.ts +1 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +43 -6
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +72 -46
- package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +15 -6
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +73 -18
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +13 -6
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +69 -11
- package/dest/mem_pools/attestation_pool/mocks.d.ts +226 -5
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +9 -7
- package/dest/mem_pools/index.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts +9 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +38 -2
- package/dest/mem_pools/interface.d.ts +3 -4
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +39 -58
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +314 -317
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +18 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +56 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +83 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +5 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.js +88 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +76 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
- package/dest/mem_pools/tx_pool/index.d.ts +1 -2
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +6 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +28 -9
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +155 -25
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -2
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +32 -5
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +20 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +67 -0
- package/dest/msg_validators/attestation_validator/index.d.ts +2 -1
- package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/index.js +1 -0
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +5 -2
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +44 -12
- package/dest/msg_validators/block_proposal_validator/index.d.ts +1 -1
- package/dest/msg_validators/index.d.ts +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +1 -1
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +1 -1
- package/dest/msg_validators/tx_validator/factory.d.ts +4 -3
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +11 -5
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.d.ts +2 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +3 -6
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +6 -24
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +3 -1
- package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +13 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.js +32 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.d.ts +3 -3
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +2 -2
- package/dest/services/dummy_service.d.ts +2 -2
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/encoding.d.ts +25 -4
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +74 -6
- package/dest/services/gossipsub/scoring.d.ts +1 -1
- package/dest/services/index.d.ts +1 -1
- 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 +9 -2
- package/dest/services/libp2p/libp2p_service.d.ts +33 -72
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +841 -175
- package/dest/services/peer-manager/interface.d.ts +1 -1
- package/dest/services/peer-manager/metrics.d.ts +8 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +28 -0
- package/dest/services/peer-manager/peer_manager.d.ts +2 -33
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +29 -22
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +40 -2
- package/dest/services/reqresp/config.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -4
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/index.d.ts +1 -1
- package/dest/services/reqresp/interface.d.ts +2 -11
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +1 -18
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.d.ts +2 -2
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.js +2 -2
- package/dest/services/reqresp/protocols/block.d.ts +1 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +3 -2
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +4 -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 +1 -1
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.d.ts +1 -1
- package/dest/services/reqresp/protocols/ping.d.ts +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +6 -5
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +4 -3
- package/dest/services/reqresp/protocols/tx.d.ts +2 -3
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +2 -2
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts +1 -41
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +416 -34
- package/dest/services/reqresp/status.d.ts +2 -2
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/service.d.ts +2 -2
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +1 -1
- package/dest/services/tx_collection/config.js +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -9
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +6 -1
- package/dest/services/tx_collection/index.d.ts +1 -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/slow_tx_collection.d.ts +6 -7
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +2 -1
- package/dest/services/tx_collection/tx_collection.d.ts +12 -11
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +3 -2
- package/dest/services/tx_collection/tx_collection_sink.d.ts +3 -3
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +34 -4
- package/dest/services/tx_collection/tx_source.d.ts +1 -1
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +2 -2
- package/dest/services/tx_provider.d.ts +6 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +19 -6
- package/dest/services/tx_provider_instrumentation.d.ts +5 -2
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +14 -1
- package/dest/test-helpers/generate-peer-id-private-keys.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/index.d.ts +1 -1
- package/dest/test-helpers/make-enrs.d.ts +1 -1
- package/dest/test-helpers/make-enrs.js +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +2 -2
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +4 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-tx-helpers.d.ts +12 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -0
- package/dest/test-helpers/mock-tx-helpers.js +19 -0
- package/dest/test-helpers/reqresp-nodes.d.ts +3 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +4 -3
- package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +17 -9
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/testbench.js +2 -2
- package/dest/testbench/worker_client_manager.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/types/index.d.ts +1 -1
- package/dest/util.d.ts +2 -1
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +11 -2
- package/dest/versioning.d.ts +2 -2
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +2 -2
- package/package.json +21 -21
- package/src/bootstrap/bootstrap.ts +15 -4
- package/src/client/factory.ts +21 -12
- package/src/client/interface.ts +8 -5
- package/src/client/p2p_client.ts +106 -106
- package/src/config.ts +42 -21
- package/src/enr/generate-enr.ts +1 -1
- package/src/errors/attestation-pool.error.ts +13 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +46 -5
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +89 -48
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +107 -24
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +98 -19
- package/src/mem_pools/attestation_pool/mocks.ts +11 -8
- package/src/mem_pools/instrumentation.ts +46 -0
- package/src/mem_pools/interface.ts +2 -4
- package/src/mem_pools/tx_pool/README.md +255 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +368 -360
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +71 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +93 -0
- package/src/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.ts +108 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +91 -0
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
- package/src/mem_pools/tx_pool/index.ts +0 -1
- package/src/mem_pools/tx_pool/priority.ts +8 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +28 -8
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +131 -18
- package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -6
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +91 -0
- package/src/msg_validators/attestation_validator/index.ts +1 -0
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +53 -12
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +2 -2
- package/src/msg_validators/tx_validator/double_spend_validator.ts +1 -1
- package/src/msg_validators/tx_validator/factory.ts +13 -6
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +8 -42
- package/src/msg_validators/tx_validator/phases_validator.ts +3 -1
- package/src/msg_validators/tx_validator/test_utils.ts +1 -1
- package/src/msg_validators/tx_validator/timestamp_validator.ts +47 -0
- package/src/services/discv5/discV5_service.ts +2 -2
- package/src/services/dummy_service.ts +1 -1
- package/src/services/encoding.ts +81 -6
- package/src/services/libp2p/instrumentation.ts +10 -1
- package/src/services/libp2p/libp2p_service.ts +494 -169
- package/src/services/peer-manager/metrics.ts +32 -0
- package/src/services/peer-manager/peer_manager.ts +25 -16
- package/src/services/peer-manager/peer_scoring.ts +46 -3
- package/src/services/reqresp/interface.ts +1 -22
- package/src/services/reqresp/protocols/auth.ts +2 -2
- package/src/services/reqresp/protocols/block.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
- package/src/services/reqresp/protocols/status.ts +9 -8
- package/src/services/reqresp/protocols/tx.ts +1 -2
- package/src/services/reqresp/reqresp.ts +15 -11
- package/src/services/service.ts +1 -1
- package/src/services/tx_collection/config.ts +1 -1
- package/src/services/tx_collection/fast_tx_collection.ts +8 -5
- package/src/services/tx_collection/slow_tx_collection.ts +7 -6
- package/src/services/tx_collection/tx_collection.ts +12 -10
- package/src/services/tx_collection/tx_collection_sink.ts +34 -3
- package/src/services/tx_collection/tx_source.ts +2 -2
- package/src/services/tx_provider.ts +26 -9
- package/src/services/tx_provider_instrumentation.ts +19 -2
- package/src/test-helpers/make-enrs.ts +1 -1
- package/src/test-helpers/mock-pubsub.ts +1 -1
- package/src/test-helpers/mock-tx-helpers.ts +24 -0
- package/src/test-helpers/reqresp-nodes.ts +4 -3
- package/src/testbench/p2p_client_testbench_worker.ts +14 -6
- package/src/testbench/testbench.ts +2 -2
- package/src/util.ts +12 -2
- package/src/versioning.ts +3 -3
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -68
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -160
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -199
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { insertIntoSortedArray } from '@aztec/foundation/array';
|
|
2
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
4
|
import { toArray } from '@aztec/foundation/iterable';
|
|
3
5
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
6
|
import type { TypedEventEmitter } from '@aztec/foundation/types';
|
|
5
|
-
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import { ClientIvcProof } from '@aztec/stdlib/proofs';
|
|
7
|
+
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
|
|
8
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
|
+
import type { MerkleTreeReadOperations, ReadonlyWorldStateAccess } from '@aztec/stdlib/interfaces/server';
|
|
10
|
+
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
10
11
|
import type { TxAddedToPoolStats } from '@aztec/stdlib/stats';
|
|
11
|
-
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
12
12
|
import { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
|
|
13
13
|
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
14
14
|
|
|
@@ -16,43 +16,46 @@ import assert from 'assert';
|
|
|
16
16
|
import EventEmitter from 'node:events';
|
|
17
17
|
|
|
18
18
|
import { ArchiveCache } from '../../msg_validators/tx_validator/archive_cache.js';
|
|
19
|
-
import { GasTxValidator } from '../../msg_validators/tx_validator/gas_validator.js';
|
|
20
19
|
import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instrumentation.js';
|
|
20
|
+
import { EvictionManager } from './eviction/eviction_manager.js';
|
|
21
|
+
import type { PendingTxInfo, TxBlockReference, TxPoolOperations } from './eviction/eviction_strategy.js';
|
|
22
|
+
import { InsufficientFeePayerBalanceRule } from './eviction/insufficient_fee_payer_balance_rule.js';
|
|
23
|
+
import { InvalidTxsAfterMiningRule } from './eviction/invalid_txs_after_mining_rule.js';
|
|
24
|
+
import { InvalidTxsAfterReorgRule } from './eviction/invalid_txs_after_reorg_rule.js';
|
|
25
|
+
import { LowPriorityEvictionRule } from './eviction/low_priority_eviction_rule.js';
|
|
21
26
|
import { getPendingTxPriority } from './priority.js';
|
|
22
27
|
import type { TxPool, TxPoolEvents, TxPoolOptions } from './tx_pool.js';
|
|
23
28
|
|
|
24
29
|
/**
|
|
25
30
|
* KV implementation of the Transaction Pool.
|
|
26
31
|
*/
|
|
27
|
-
export class AztecKVTxPool
|
|
32
|
+
export class AztecKVTxPool
|
|
33
|
+
extends (EventEmitter as new () => TypedEventEmitter<TxPoolEvents>)
|
|
34
|
+
implements TxPool, TxPoolOperations
|
|
35
|
+
{
|
|
28
36
|
#store: AztecAsyncKVStore;
|
|
29
37
|
|
|
30
38
|
/** Our tx pool, stored as a Map, with K: tx hash and V: the transaction. */
|
|
31
39
|
#txs: AztecAsyncMap<string, Buffer>;
|
|
32
40
|
|
|
33
|
-
/**
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
/** The tx evicion logic will kick after pool size is greater than maxTxPoolSize * txPoolOverflowFactor */
|
|
37
|
-
txPoolOverflowFactor: number = 1;
|
|
41
|
+
/** Holds the historical block for each tx */
|
|
42
|
+
#pendingTxHashToHistoricalBlockHeaderHash: AztecAsyncMap<string, string>;
|
|
38
43
|
|
|
39
44
|
/** Index from tx hash to the block number in which they were mined, filtered by mined txs. */
|
|
40
|
-
#minedTxHashToBlock: AztecAsyncMap<string,
|
|
45
|
+
#minedTxHashToBlock: AztecAsyncMap<string, BlockNumber>;
|
|
41
46
|
|
|
42
47
|
/** Index from tx priority (stored as hex) to its tx hash, filtered by pending txs. */
|
|
43
48
|
#pendingTxPriorityToHash: AztecAsyncMultiMap<string, string>;
|
|
44
49
|
|
|
45
|
-
/**
|
|
46
|
-
#
|
|
50
|
+
/** Map from tx hash to the block number it was originally mined in (for soft-deleted txs). */
|
|
51
|
+
#deletedMinedTxHashes: AztecAsyncMap<string, BlockNumber>;
|
|
47
52
|
|
|
48
|
-
/**
|
|
49
|
-
#
|
|
53
|
+
/** MultiMap from block number to deleted mined tx hashes for efficient cleanup. */
|
|
54
|
+
#blockToDeletedMinedTxHash: AztecAsyncMultiMap<BlockNumber, string>;
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
#pendingTxSize: AztecAsyncSingleton<number>;
|
|
56
|
+
#historicalHeaderToTxHash: AztecAsyncMultiMap<string, string>;
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
#pendingTxs: Map<string, Tx>;
|
|
58
|
+
#feePayerToTxHash: AztecAsyncMultiMap<string, string>;
|
|
56
59
|
|
|
57
60
|
/** In-memory set of txs that should not be evicted from the pool. */
|
|
58
61
|
#nonEvictableTxs: Set<string>;
|
|
@@ -69,8 +72,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
69
72
|
/** Number of txs to archive. */
|
|
70
73
|
#archivedTxLimit: number = 0;
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
#worldStateSynchronizer: WorldStateSynchronizer;
|
|
75
|
+
#evictionManager: EvictionManager;
|
|
74
76
|
|
|
75
77
|
#log: Logger;
|
|
76
78
|
|
|
@@ -87,7 +89,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
87
89
|
constructor(
|
|
88
90
|
store: AztecAsyncKVStore,
|
|
89
91
|
archive: AztecAsyncKVStore,
|
|
90
|
-
|
|
92
|
+
worldState: ReadonlyWorldStateAccess,
|
|
91
93
|
telemetry: TelemetryClient = getTelemetryClient(),
|
|
92
94
|
config: TxPoolOptions = {},
|
|
93
95
|
log = createLogger('p2p:tx_pool'),
|
|
@@ -95,16 +97,30 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
95
97
|
super();
|
|
96
98
|
|
|
97
99
|
this.#log = log;
|
|
100
|
+
|
|
101
|
+
this.#evictionManager = new EvictionManager(this);
|
|
102
|
+
this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
|
|
103
|
+
this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(worldState));
|
|
104
|
+
this.#evictionManager.registerRule(new InsufficientFeePayerBalanceRule(worldState));
|
|
105
|
+
this.#evictionManager.registerRule(
|
|
106
|
+
new LowPriorityEvictionRule({
|
|
107
|
+
//NOTE: 0 effectively disables low priority eviction
|
|
108
|
+
maxPoolSize: config.maxPendingTxCount ?? 0,
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
|
|
98
112
|
this.updateConfig(config);
|
|
99
113
|
|
|
100
114
|
this.#txs = store.openMap('txs');
|
|
101
115
|
this.#minedTxHashToBlock = store.openMap('txHashToBlockMined');
|
|
102
116
|
this.#pendingTxPriorityToHash = store.openMultiMap('pendingTxFeeToHash');
|
|
103
|
-
this.#
|
|
104
|
-
this.#
|
|
105
|
-
|
|
117
|
+
this.#deletedMinedTxHashes = store.openMap('deletedMinedTxHashes');
|
|
118
|
+
this.#blockToDeletedMinedTxHash = store.openMultiMap('blockToDeletedMinedTxHash');
|
|
119
|
+
|
|
120
|
+
this.#pendingTxHashToHistoricalBlockHeaderHash = store.openMap('txHistoricalBlock');
|
|
121
|
+
this.#historicalHeaderToTxHash = store.openMultiMap('historicalHeaderToPendingTxHash');
|
|
122
|
+
this.#feePayerToTxHash = store.openMultiMap('feePayerToPendingTxHash');
|
|
106
123
|
|
|
107
|
-
this.#pendingTxs = new Map<string, Tx>();
|
|
108
124
|
this.#nonEvictableTxs = new Set<string>();
|
|
109
125
|
|
|
110
126
|
this.#archivedTxs = archive.openMap('archivedTxs');
|
|
@@ -112,7 +128,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
112
128
|
|
|
113
129
|
this.#store = store;
|
|
114
130
|
this.#archive = archive;
|
|
115
|
-
|
|
131
|
+
|
|
116
132
|
this.#metrics = new PoolInstrumentation(telemetry, PoolName.TX_POOL, this.countTxs, () => store.estimateSize());
|
|
117
133
|
}
|
|
118
134
|
|
|
@@ -133,6 +149,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
133
149
|
}
|
|
134
150
|
return true;
|
|
135
151
|
}
|
|
152
|
+
|
|
136
153
|
/**
|
|
137
154
|
* Marks transactions as mined in a block and updates the pool state accordingly.
|
|
138
155
|
* Removes the transactions from the pending set and adds them to the mined set.
|
|
@@ -145,88 +162,77 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
145
162
|
return Promise.resolve();
|
|
146
163
|
}
|
|
147
164
|
|
|
148
|
-
const
|
|
149
|
-
const
|
|
165
|
+
const uniqueMinedNullifiers: Fr[] = [];
|
|
166
|
+
const uniqueMinedFeePayers: AztecAddress[] = [];
|
|
150
167
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
try {
|
|
169
|
+
await this.#store.transactionAsync(async () => {
|
|
170
|
+
for (const hash of txHashes) {
|
|
171
|
+
const key = hash.toString();
|
|
172
|
+
await this.#minedTxHashToBlock.set(key, blockHeader.globalVariables.blockNumber);
|
|
173
|
+
|
|
174
|
+
const tx = await this.getPendingTxByHash(hash);
|
|
175
|
+
if (tx) {
|
|
176
|
+
const nullifiers = tx.data.getNonEmptyNullifiers();
|
|
177
|
+
|
|
178
|
+
nullifiers.forEach(nullifier => insertIntoSortedArray(uniqueMinedNullifiers, nullifier, Fr.cmp, false));
|
|
179
|
+
insertIntoSortedArray(
|
|
180
|
+
uniqueMinedFeePayers,
|
|
181
|
+
tx.data.feePayer,
|
|
182
|
+
(a, b) => a.toField().cmp(b.toField()),
|
|
183
|
+
false,
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
await this.removePendingTxIndicesInDbTx(tx, key);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// If this tx was previously soft-deleted, remove it from the deleted sets
|
|
190
|
+
if (await this.#deletedMinedTxHashes.hasAsync(key)) {
|
|
191
|
+
const originalBlock = await this.#deletedMinedTxHashes.getAsync(key);
|
|
192
|
+
await this.#deletedMinedTxHashes.delete(key);
|
|
193
|
+
// Remove from block-to-hash mapping
|
|
194
|
+
if (originalBlock !== undefined) {
|
|
195
|
+
await this.#blockToDeletedMinedTxHash.deleteValue(originalBlock, key);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
164
198
|
}
|
|
165
|
-
}
|
|
166
|
-
await this.#pendingTxSize.set(pendingTxSize);
|
|
199
|
+
});
|
|
167
200
|
|
|
168
|
-
await this.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
201
|
+
await this.#evictionManager.evictAfterNewBlock(blockHeader, uniqueMinedNullifiers, uniqueMinedFeePayers);
|
|
202
|
+
|
|
203
|
+
this.#metrics.transactionsRemoved(txHashes.map(hash => hash.toBigInt()));
|
|
204
|
+
} catch (err) {
|
|
205
|
+
this.#log.warn('Unexpected error when marking txs as mined', { err });
|
|
206
|
+
}
|
|
174
207
|
}
|
|
175
208
|
|
|
176
|
-
public async markMinedAsPending(txHashes: TxHash[]): Promise<void> {
|
|
209
|
+
public async markMinedAsPending(txHashes: TxHash[], latestBlock: BlockNumber): Promise<void> {
|
|
177
210
|
if (txHashes.length === 0) {
|
|
178
211
|
return Promise.resolve();
|
|
179
212
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
213
|
+
try {
|
|
214
|
+
await this.#store.transactionAsync(async () => {
|
|
215
|
+
for (const hash of txHashes) {
|
|
216
|
+
const key = hash.toString();
|
|
217
|
+
await this.#minedTxHashToBlock.delete(key);
|
|
185
218
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
219
|
+
// Rehydrate the tx in the in-memory pending txs mapping
|
|
220
|
+
const tx = await this.getPendingTxByHash(hash);
|
|
221
|
+
if (tx) {
|
|
222
|
+
await this.addPendingTxIndicesInDbTx(tx, key);
|
|
223
|
+
}
|
|
191
224
|
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
await this.#pendingTxSize.set(pendingTxSize);
|
|
195
|
-
});
|
|
225
|
+
});
|
|
196
226
|
|
|
197
|
-
|
|
198
|
-
|
|
227
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock);
|
|
228
|
+
} catch (err) {
|
|
229
|
+
this.#log.warn('Unexpected error when marking mined txs as pending', { err });
|
|
230
|
+
}
|
|
199
231
|
}
|
|
200
232
|
|
|
201
233
|
public async getPendingTxHashes(): Promise<TxHash[]> {
|
|
202
234
|
const vals = await toArray(this.#pendingTxPriorityToHash.valuesAsync({ reverse: true }));
|
|
203
|
-
return vals.map(
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
public async getMinedTxHashes(): Promise<[TxHash, number][]> {
|
|
207
|
-
const vals = await toArray(this.#minedTxHashToBlock.entriesAsync());
|
|
208
|
-
return vals.map(([txHash, blockNumber]) => [TxHash.fromString(txHash), blockNumber]);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
public async getPendingTxCount(): Promise<number> {
|
|
212
|
-
return (await this.#pendingTxHashToHeaderHash.sizeAsync()) ?? 0;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
public async getMinedTxCount(): Promise<number> {
|
|
216
|
-
return (await this.#minedTxHashToBlock.sizeAsync()) ?? 0;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
public async getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
|
|
220
|
-
const key = txHash.toString();
|
|
221
|
-
const [isMined, isKnown] = await Promise.all([this.#minedTxHashToBlock.hasAsync(key), this.#txs.hasAsync(key)]);
|
|
222
|
-
|
|
223
|
-
if (isMined) {
|
|
224
|
-
return 'mined';
|
|
225
|
-
} else if (isKnown) {
|
|
226
|
-
return 'pending';
|
|
227
|
-
} else {
|
|
228
|
-
return undefined;
|
|
229
|
-
}
|
|
235
|
+
return vals.map(TxHash.fromString);
|
|
230
236
|
}
|
|
231
237
|
|
|
232
238
|
/**
|
|
@@ -236,30 +242,23 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
236
242
|
*/
|
|
237
243
|
public async getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
|
|
238
244
|
const buffer = await this.#txs.getAsync(txHash.toString());
|
|
239
|
-
|
|
240
|
-
const tx = Tx.fromBuffer(buffer);
|
|
241
|
-
tx.setTxHash(txHash);
|
|
242
|
-
return tx;
|
|
243
|
-
}
|
|
244
|
-
return undefined;
|
|
245
|
+
return buffer ? Tx.fromBuffer(buffer) : undefined;
|
|
245
246
|
}
|
|
246
247
|
|
|
247
248
|
async getTxsByHash(txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
|
|
248
249
|
const txs = await Promise.all(txHashes.map(txHash => this.#txs.getAsync(txHash.toString())));
|
|
249
|
-
return txs.map((buffer
|
|
250
|
-
if (buffer) {
|
|
251
|
-
const tx = Tx.fromBuffer(buffer);
|
|
252
|
-
tx.setTxHash(txHashes[index]);
|
|
253
|
-
return tx;
|
|
254
|
-
}
|
|
255
|
-
return undefined;
|
|
256
|
-
});
|
|
250
|
+
return txs.map(buffer => (buffer ? Tx.fromBuffer(buffer) : undefined));
|
|
257
251
|
}
|
|
258
252
|
|
|
259
253
|
async hasTxs(txHashes: TxHash[]): Promise<boolean[]> {
|
|
260
254
|
return await Promise.all(txHashes.map(txHash => this.#txs.hasAsync(txHash.toString())));
|
|
261
255
|
}
|
|
262
256
|
|
|
257
|
+
async hasTx(txHash: TxHash): Promise<boolean> {
|
|
258
|
+
const result = await this.hasTxs([txHash]);
|
|
259
|
+
return result[0];
|
|
260
|
+
}
|
|
261
|
+
|
|
263
262
|
/**
|
|
264
263
|
* Checks if an archived tx exists and returns it.
|
|
265
264
|
* @param txHash - The tx hash.
|
|
@@ -267,54 +266,59 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
267
266
|
*/
|
|
268
267
|
public async getArchivedTxByHash(txHash: TxHash): Promise<Tx | undefined> {
|
|
269
268
|
const buffer = await this.#archivedTxs.getAsync(txHash.toString());
|
|
270
|
-
|
|
271
|
-
const tx = Tx.fromBuffer(buffer);
|
|
272
|
-
tx.setTxHash(txHash);
|
|
273
|
-
return tx;
|
|
274
|
-
}
|
|
275
|
-
return undefined;
|
|
269
|
+
return buffer ? Tx.fromBuffer(buffer) : undefined;
|
|
276
270
|
}
|
|
277
271
|
|
|
278
272
|
/**
|
|
279
273
|
* Adds a list of transactions to the pool. Duplicates are ignored.
|
|
280
274
|
* @param txs - An array of txs to be added to the pool.
|
|
281
|
-
* @returns
|
|
275
|
+
* @returns count of added transactions
|
|
282
276
|
*/
|
|
283
277
|
public async addTxs(txs: Tx[], opts: { source?: string } = {}): Promise<number> {
|
|
278
|
+
if (txs.length === 0) {
|
|
279
|
+
return Promise.resolve(0);
|
|
280
|
+
}
|
|
281
|
+
|
|
284
282
|
const addedTxs: Tx[] = [];
|
|
285
283
|
const hashesAndStats = txs.map(tx => ({ txHash: tx.getTxHash(), txStats: tx.getStats() }));
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
this.#log.verbose(`Adding tx ${txHash.toString()} to pool`, {
|
|
298
|
-
eventName: 'tx-added-to-pool',
|
|
299
|
-
...txStats,
|
|
300
|
-
} satisfies TxAddedToPoolStats);
|
|
301
|
-
|
|
302
|
-
await this.#txs.set(key, tx.toBuffer());
|
|
303
|
-
addedTxs.push(tx as Tx);
|
|
284
|
+
try {
|
|
285
|
+
await this.#store.transactionAsync(async () => {
|
|
286
|
+
await Promise.all(
|
|
287
|
+
txs.map(async (tx, i) => {
|
|
288
|
+
const { txHash, txStats } = hashesAndStats[i];
|
|
289
|
+
const key = txHash.toString();
|
|
290
|
+
if (await this.#txs.hasAsync(key)) {
|
|
291
|
+
this.#log.debug(`Tx ${txHash.toString()} already exists in the pool`);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
304
294
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
295
|
+
this.#log.verbose(`Adding tx ${txHash.toString()} to pool`, {
|
|
296
|
+
eventName: 'tx-added-to-pool',
|
|
297
|
+
...txStats,
|
|
298
|
+
} satisfies TxAddedToPoolStats);
|
|
299
|
+
|
|
300
|
+
await this.#txs.set(key, tx.toBuffer());
|
|
301
|
+
addedTxs.push(tx as Tx);
|
|
302
|
+
await this.#pendingTxHashToHistoricalBlockHeaderHash.set(
|
|
303
|
+
key,
|
|
304
|
+
(await tx.data.constants.anchorBlockHeader.hash()).toString(),
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
if (!(await this.#minedTxHashToBlock.hasAsync(key))) {
|
|
308
|
+
await this.addPendingTxIndicesInDbTx(tx, key);
|
|
309
|
+
this.#metrics.recordSize(tx);
|
|
310
|
+
}
|
|
311
|
+
}),
|
|
312
|
+
);
|
|
313
|
+
});
|
|
312
314
|
|
|
313
|
-
await this.#
|
|
314
|
-
|
|
315
|
-
|
|
315
|
+
await this.#evictionManager.evictAfterNewTxs(addedTxs.map(({ txHash }) => txHash));
|
|
316
|
+
} catch (err) {
|
|
317
|
+
this.#log.warn('Unexpected error when adding txs', { err });
|
|
318
|
+
}
|
|
316
319
|
|
|
317
320
|
if (addedTxs.length > 0) {
|
|
321
|
+
this.#metrics.transactionsAdded(addedTxs);
|
|
318
322
|
this.emit('txs-added', { ...opts, txs: addedTxs });
|
|
319
323
|
}
|
|
320
324
|
return addedTxs.length;
|
|
@@ -322,53 +326,73 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
322
326
|
|
|
323
327
|
/**
|
|
324
328
|
* Deletes transactions from the pool. Tx hashes that are not present are ignored.
|
|
325
|
-
*
|
|
329
|
+
* Mined transactions are soft-deleted with a timestamp, pending transactions are permanently deleted.
|
|
330
|
+
* @param txHashes - An array of tx hashes to be deleted from the tx pool.
|
|
326
331
|
* @returns Empty promise.
|
|
327
332
|
*/
|
|
328
|
-
public deleteTxs(txHashes: TxHash[],
|
|
333
|
+
public deleteTxs(txHashes: TxHash[], opts?: { permanently?: boolean }): Promise<void> {
|
|
329
334
|
if (txHashes.length === 0) {
|
|
330
335
|
return Promise.resolve();
|
|
331
336
|
}
|
|
337
|
+
|
|
332
338
|
const deletedTxs: Tx[] = [];
|
|
333
339
|
const poolDbTx = this.#store.transactionAsync(async () => {
|
|
334
|
-
let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
335
340
|
for (const hash of txHashes) {
|
|
336
341
|
const key = hash.toString();
|
|
337
342
|
const tx = await this.getTxByHash(hash);
|
|
343
|
+
if (!tx) {
|
|
344
|
+
this.#log.trace(`Skipping deletion of missing tx ${key} from pool`);
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
338
347
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (
|
|
348
|
+
const minedBlockNumber = await this.#minedTxHashToBlock.getAsync(key);
|
|
349
|
+
const txIsPending = minedBlockNumber === undefined;
|
|
350
|
+
if (txIsPending) {
|
|
351
|
+
await this.deletePendingTx(tx, key);
|
|
352
|
+
} else {
|
|
353
|
+
await this.deleteMinedTx(key, minedBlockNumber!, opts?.permanently ?? false);
|
|
354
|
+
const shouldArchiveTx = this.#archivedTxLimit && !opts?.permanently;
|
|
355
|
+
if (shouldArchiveTx) {
|
|
347
356
|
deletedTxs.push(tx);
|
|
348
357
|
}
|
|
349
|
-
|
|
350
|
-
await this.#txs.delete(key);
|
|
351
|
-
await this.#minedTxHashToBlock.delete(key);
|
|
352
358
|
}
|
|
353
359
|
}
|
|
354
|
-
|
|
355
|
-
await this.#pendingTxSize.set(pendingTxSize);
|
|
356
360
|
});
|
|
361
|
+
this.#metrics.transactionsRemoved(txHashes.map(hash => hash.toBigInt()));
|
|
357
362
|
this.#log.debug(`Deleted ${txHashes.length} txs from pool`, { txHashes });
|
|
363
|
+
|
|
358
364
|
return this.#archivedTxLimit ? poolDbTx.then(() => this.archiveTxs(deletedTxs)) : poolDbTx;
|
|
359
365
|
}
|
|
360
366
|
|
|
367
|
+
private async deleteMinedTx(txHash: `0x${string}`, minedBlockNumber: BlockNumber, permanently: boolean) {
|
|
368
|
+
await this.#minedTxHashToBlock.delete(txHash);
|
|
369
|
+
if (permanently) {
|
|
370
|
+
this.#log.trace(`Deleting mined tx ${txHash} from pool`);
|
|
371
|
+
await this.#txs.delete(txHash);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Soft-delete mined transactions: remove from mined set but keep in storage
|
|
376
|
+
this.#log.trace(`Soft-deleting mined tx ${txHash} from pool`);
|
|
377
|
+
await this.#deletedMinedTxHashes.set(txHash, minedBlockNumber);
|
|
378
|
+
await this.#blockToDeletedMinedTxHash.set(minedBlockNumber, txHash);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
private async deletePendingTx(tx: Tx, txHash: `0x${string}`) {
|
|
382
|
+
// We always permanently delete pending transactions
|
|
383
|
+
this.#log.trace(`Deleting pending tx ${txHash} from pool`);
|
|
384
|
+
await this.removePendingTxIndices(tx, txHash);
|
|
385
|
+
await this.#txs.delete(txHash);
|
|
386
|
+
await this.#pendingTxHashToHistoricalBlockHeaderHash.delete(txHash);
|
|
387
|
+
}
|
|
388
|
+
|
|
361
389
|
/**
|
|
362
390
|
* Gets all the transactions stored in the pool.
|
|
363
391
|
* @returns Array of tx objects in the order they were added to the pool.
|
|
364
392
|
*/
|
|
365
393
|
public async getAllTxs(): Promise<Tx[]> {
|
|
366
|
-
const vals = await toArray(this.#txs.
|
|
367
|
-
return vals.map(
|
|
368
|
-
const tx = Tx.fromBuffer(buffer);
|
|
369
|
-
tx.setTxHash(TxHash.fromString(hash));
|
|
370
|
-
return tx;
|
|
371
|
-
});
|
|
394
|
+
const vals = await toArray(this.#txs.valuesAsync());
|
|
395
|
+
return vals.map(buffer => Tx.fromBuffer(buffer));
|
|
372
396
|
}
|
|
373
397
|
|
|
374
398
|
/**
|
|
@@ -380,27 +404,100 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
380
404
|
return vals.map(x => TxHash.fromString(x));
|
|
381
405
|
}
|
|
382
406
|
|
|
383
|
-
public
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
407
|
+
public async getPendingTxInfos(): Promise<PendingTxInfo[]> {
|
|
408
|
+
const vals = await toArray(this.#pendingTxPriorityToHash.valuesAsync());
|
|
409
|
+
const results = await Promise.all(vals.map(val => this.getPendingTxInfo(TxHash.fromString(val))));
|
|
410
|
+
return results.filter((info): info is PendingTxInfo => info !== undefined);
|
|
411
|
+
}
|
|
387
412
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
413
|
+
private async getPendingTxInfo(txHash: TxHash): Promise<PendingTxInfo | undefined> {
|
|
414
|
+
let historicalBlockHash = await this.#pendingTxHashToHistoricalBlockHeaderHash.getAsync(txHash.toString());
|
|
415
|
+
// Not all tx might have this index created.
|
|
416
|
+
if (!historicalBlockHash) {
|
|
417
|
+
const tx = await this.getPendingTxByHash(txHash);
|
|
418
|
+
if (!tx) {
|
|
419
|
+
this.#log.warn(`PendingTxInfo:tx ${txHash} not found`);
|
|
420
|
+
return undefined;
|
|
392
421
|
}
|
|
422
|
+
|
|
423
|
+
historicalBlockHash = (await tx.data.constants.anchorBlockHeader.hash()).toString();
|
|
424
|
+
await this.#pendingTxHashToHistoricalBlockHeaderHash.set(txHash.toString(), historicalBlockHash);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return {
|
|
428
|
+
txHash,
|
|
429
|
+
blockHash: Fr.fromString(historicalBlockHash),
|
|
430
|
+
isEvictable: !this.#nonEvictableTxs.has(txHash.toString()),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
public async getPendingTxsReferencingBlocks(blockHashes: Fr[]): Promise<TxBlockReference[]> {
|
|
435
|
+
const result: TxBlockReference[] = [];
|
|
436
|
+
for (const blockHash of blockHashes) {
|
|
437
|
+
const chunk = await toArray(this.#historicalHeaderToTxHash.getValuesAsync(blockHash.toString()));
|
|
438
|
+
result.push(
|
|
439
|
+
...chunk.map(txHash => ({
|
|
440
|
+
txHash: TxHash.fromString(txHash),
|
|
441
|
+
blockHash,
|
|
442
|
+
isEvictable: !this.#nonEvictableTxs.has(txHash),
|
|
443
|
+
})),
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return result;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
public async getPendingTxsWithFeePayer(feePayers: AztecAddress[]): Promise<PendingTxInfo[]> {
|
|
451
|
+
const result: PendingTxInfo[] = [];
|
|
452
|
+
for (const feePayer of feePayers) {
|
|
453
|
+
const chunk = await toArray(this.#feePayerToTxHash.getValuesAsync(feePayer.toString()));
|
|
454
|
+
const infos = await Promise.all(chunk.map(txHash => this.getPendingTxInfo(TxHash.fromString(txHash))));
|
|
455
|
+
result.push(...infos.filter((info): info is PendingTxInfo => info !== undefined));
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return result;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
public async getMinedTxHashes(): Promise<[TxHash, BlockNumber][]> {
|
|
462
|
+
const vals = await toArray(this.#minedTxHashToBlock.entriesAsync());
|
|
463
|
+
return vals.map(([txHash, blockNumber]) => [TxHash.fromString(txHash), blockNumber]);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
public async getPendingTxCount(): Promise<number> {
|
|
467
|
+
return (await this.#pendingTxPriorityToHash.sizeAsync()) ?? 0;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
public async getMinedTxCount(): Promise<number> {
|
|
471
|
+
return (await this.#minedTxHashToBlock.sizeAsync()) ?? 0;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
public async getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | 'deleted' | undefined> {
|
|
475
|
+
const key = txHash.toString();
|
|
476
|
+
const [isMined, isKnown, isDeleted] = await Promise.all([
|
|
477
|
+
this.#minedTxHashToBlock.hasAsync(key),
|
|
478
|
+
this.#txs.hasAsync(key),
|
|
479
|
+
this.#deletedMinedTxHashes.hasAsync(key),
|
|
480
|
+
]);
|
|
481
|
+
|
|
482
|
+
if (isDeleted) {
|
|
483
|
+
return 'deleted';
|
|
484
|
+
} else if (isMined) {
|
|
485
|
+
return 'mined';
|
|
486
|
+
} else if (isKnown) {
|
|
487
|
+
return 'pending';
|
|
488
|
+
} else {
|
|
489
|
+
return undefined;
|
|
393
490
|
}
|
|
491
|
+
}
|
|
394
492
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
this.#
|
|
493
|
+
public updateConfig(cfg: TxPoolOptions): void {
|
|
494
|
+
if (typeof cfg.archivedTxLimit === 'number') {
|
|
495
|
+
assert(cfg.archivedTxLimit >= 0, 'archivedTxLimit must be greater or equal to 0');
|
|
496
|
+
this.#archivedTxLimit = cfg.archivedTxLimit;
|
|
399
497
|
}
|
|
400
498
|
|
|
401
|
-
if (
|
|
402
|
-
|
|
403
|
-
this.#archivedTxLimit = archivedTxLimit;
|
|
499
|
+
if (this.#evictionManager) {
|
|
500
|
+
this.#evictionManager.updateConfig(cfg);
|
|
404
501
|
}
|
|
405
502
|
}
|
|
406
503
|
|
|
@@ -409,13 +506,54 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
409
506
|
return Promise.resolve();
|
|
410
507
|
}
|
|
411
508
|
|
|
509
|
+
public clearNonEvictableTxs(): Promise<void> {
|
|
510
|
+
// Clear the non-evictable set after completing the DB updates above.
|
|
511
|
+
// This ensures pinned (non-evictable) txs are protected while we mark mined txs,
|
|
512
|
+
// but they won't remain pinned indefinitely across blocks. Note that eviction rules
|
|
513
|
+
// (including post-mining invalidation) respect the non-evictable flag while it is set.
|
|
514
|
+
this.#nonEvictableTxs.clear();
|
|
515
|
+
return Promise.resolve();
|
|
516
|
+
}
|
|
517
|
+
|
|
412
518
|
/**
|
|
413
|
-
*
|
|
414
|
-
* @param
|
|
415
|
-
* @returns
|
|
519
|
+
* Permanently deletes deleted mined transactions from blocks up to and including the specified block number.
|
|
520
|
+
* @param blockNumber - Block number threshold. Deleted mined txs from this block or earlier will be permanently deleted.
|
|
521
|
+
* @returns The number of transactions permanently deleted.
|
|
416
522
|
*/
|
|
417
|
-
|
|
418
|
-
|
|
523
|
+
public async cleanupDeletedMinedTxs(blockNumber: BlockNumber): Promise<number> {
|
|
524
|
+
let deletedCount = 0;
|
|
525
|
+
await this.#store.transactionAsync(async () => {
|
|
526
|
+
const txHashesToDelete: string[] = [];
|
|
527
|
+
const blocksToDelete: BlockNumber[] = [];
|
|
528
|
+
|
|
529
|
+
// Iterate through all entries and check block numbers
|
|
530
|
+
for await (const [block, txHash] of this.#blockToDeletedMinedTxHash.entriesAsync()) {
|
|
531
|
+
if (block <= blockNumber) {
|
|
532
|
+
// Permanently delete the transaction
|
|
533
|
+
await this.#txs.delete(txHash);
|
|
534
|
+
await this.#deletedMinedTxHashes.delete(txHash);
|
|
535
|
+
txHashesToDelete.push(txHash);
|
|
536
|
+
if (!blocksToDelete.includes(block)) {
|
|
537
|
+
blocksToDelete.push(block);
|
|
538
|
+
}
|
|
539
|
+
deletedCount++;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
this.#metrics.transactionsRemoved(txHashesToDelete);
|
|
543
|
+
|
|
544
|
+
// Clean up block-to-hash mapping - delete all values for each block
|
|
545
|
+
for (const block of blocksToDelete) {
|
|
546
|
+
const txHashesForBlock = await toArray(this.#blockToDeletedMinedTxHash.getValuesAsync(block));
|
|
547
|
+
for (const txHash of txHashesForBlock) {
|
|
548
|
+
await this.#blockToDeletedMinedTxHash.deleteValue(block, txHash);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
if (deletedCount > 0) {
|
|
554
|
+
this.#log.debug(`Permanently deleted ${deletedCount} deleted mined txs from blocks up to ${blockNumber}`);
|
|
555
|
+
}
|
|
556
|
+
return deletedCount;
|
|
419
557
|
}
|
|
420
558
|
|
|
421
559
|
/**
|
|
@@ -434,20 +572,12 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
434
572
|
* @returns The transaction, if found, 'undefined' otherwise.
|
|
435
573
|
*/
|
|
436
574
|
private async getPendingTxByHash(txHash: TxHash | string): Promise<Tx | undefined> {
|
|
437
|
-
let key;
|
|
438
575
|
if (typeof txHash === 'string') {
|
|
439
|
-
key = txHash;
|
|
440
576
|
txHash = TxHash.fromString(txHash);
|
|
441
|
-
} else {
|
|
442
|
-
key = txHash.toString();
|
|
443
577
|
}
|
|
444
578
|
|
|
445
|
-
if (this.#pendingTxs.has(key)) {
|
|
446
|
-
return this.#pendingTxs.get(key);
|
|
447
|
-
}
|
|
448
579
|
const tx = await this.getTxByHash(txHash);
|
|
449
580
|
if (tx) {
|
|
450
|
-
this.#pendingTxs.set(key, tx);
|
|
451
581
|
return tx;
|
|
452
582
|
}
|
|
453
583
|
return undefined;
|
|
@@ -455,6 +585,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
455
585
|
|
|
456
586
|
/**
|
|
457
587
|
* Archives a list of txs for future reference. The number of archived txs is limited by the specified archivedTxLimit.
|
|
588
|
+
* Note: Pending txs should not be archived, only finalized txs
|
|
458
589
|
* @param txs - The list of transactions to archive.
|
|
459
590
|
* @returns Empty promise.
|
|
460
591
|
*/
|
|
@@ -462,6 +593,10 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
462
593
|
if (txs.length === 0) {
|
|
463
594
|
return;
|
|
464
595
|
}
|
|
596
|
+
if (this.#archivedTxLimit === 0) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
|
|
465
600
|
try {
|
|
466
601
|
const txHashes = await Promise.all(txs.map(tx => tx.getTxHash()));
|
|
467
602
|
await this.#archive.transactionAsync(async () => {
|
|
@@ -484,7 +619,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
484
619
|
const archivedTx: Tx = new Tx(
|
|
485
620
|
tx.txHash,
|
|
486
621
|
tx.data,
|
|
487
|
-
|
|
622
|
+
ChonkProof.empty(),
|
|
488
623
|
tx.contractClassLogFields,
|
|
489
624
|
tx.publicFunctionCalldata,
|
|
490
625
|
);
|
|
@@ -501,183 +636,56 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
501
636
|
}
|
|
502
637
|
}
|
|
503
638
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
* @returns The total number of txs evicted from the pool and the number of new txs that were evicted.
|
|
510
|
-
*/
|
|
511
|
-
private async evictLowPriorityTxs(
|
|
512
|
-
newTxHashes: TxHash[],
|
|
513
|
-
): Promise<{ numLowPriorityTxsEvicted: number; numNewTxsEvicted: number }> {
|
|
514
|
-
if (this.#maxTxPoolSize === undefined || this.#maxTxPoolSize === 0) {
|
|
515
|
-
return { numLowPriorityTxsEvicted: 0, numNewTxsEvicted: 0 };
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
let numNewTxsEvicted = 0;
|
|
519
|
-
const txsToEvict: TxHash[] = [];
|
|
520
|
-
|
|
521
|
-
let pendingTxsSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
522
|
-
if (pendingTxsSize > this.#maxTxPoolSize * this.txPoolOverflowFactor) {
|
|
523
|
-
for await (const txHash of this.#pendingTxPriorityToHash.valuesAsync()) {
|
|
524
|
-
if (this.#nonEvictableTxs.has(txHash.toString())) {
|
|
525
|
-
continue;
|
|
526
|
-
}
|
|
527
|
-
const txSize =
|
|
528
|
-
(await this.#pendingTxHashToSize.getAsync(txHash.toString())) ??
|
|
529
|
-
(await this.getPendingTxByHash(txHash))?.getSize();
|
|
530
|
-
|
|
531
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to low priority to satisfy max tx size limit`, {
|
|
532
|
-
txHash,
|
|
533
|
-
txSize,
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
537
|
-
|
|
538
|
-
if (txSize) {
|
|
539
|
-
pendingTxsSize -= txSize;
|
|
540
|
-
if (pendingTxsSize <= this.#maxTxPoolSize) {
|
|
541
|
-
break;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
numNewTxsEvicted += newTxHashes.filter(txHash => txsToEvict.includes(txHash)).length;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
if (txsToEvict.length > 0) {
|
|
549
|
-
await this.deleteTxs(txsToEvict, true);
|
|
550
|
-
}
|
|
551
|
-
return {
|
|
552
|
-
numLowPriorityTxsEvicted: txsToEvict.length,
|
|
553
|
-
numNewTxsEvicted,
|
|
554
|
-
};
|
|
639
|
+
// Assumes being called within a DB transaction
|
|
640
|
+
private async addPendingTxIndicesInDbTx(tx: Tx, txHash: string): Promise<void> {
|
|
641
|
+
await this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), txHash);
|
|
642
|
+
await this.#historicalHeaderToTxHash.set((await tx.data.constants.anchorBlockHeader.hash()).toString(), txHash);
|
|
643
|
+
await this.#feePayerToTxHash.set(tx.data.feePayer.toString(), txHash);
|
|
555
644
|
}
|
|
556
645
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
* - txs with an expiration timestamp lower than that of the mined block
|
|
563
|
-
*
|
|
564
|
-
* @param minedTxHashes - The tx hashes of the txs mined in the block.
|
|
565
|
-
* @param blockHeader - The header of the mined block.
|
|
566
|
-
* @returns The total number of txs evicted from the pool.
|
|
567
|
-
*/
|
|
568
|
-
private async evictInvalidTxsAfterMining(
|
|
569
|
-
minedTxHashes: TxHash[],
|
|
570
|
-
blockHeader: BlockHeader,
|
|
571
|
-
minedNullifiers: Set<string>,
|
|
572
|
-
minedFeePayers: Set<string>,
|
|
573
|
-
): Promise<number> {
|
|
574
|
-
if (minedTxHashes.length === 0) {
|
|
575
|
-
return 0;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
const { blockNumber, timestamp } = blockHeader.globalVariables;
|
|
579
|
-
|
|
580
|
-
// Wait for world state to be synced to at least the mined block number
|
|
581
|
-
await this.#worldStateSynchronizer.syncImmediate(blockNumber);
|
|
582
|
-
|
|
583
|
-
const db = this.#worldStateSynchronizer.getCommitted();
|
|
584
|
-
const gasTxValidator = this.createGasTxValidator(db);
|
|
585
|
-
|
|
586
|
-
const txsToEvict: TxHash[] = [];
|
|
587
|
-
for await (const txHash of this.#pendingTxPriorityToHash.valuesAsync()) {
|
|
588
|
-
const tx = await this.getPendingTxByHash(txHash);
|
|
589
|
-
if (!tx) {
|
|
590
|
-
continue;
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
// Evict pending txs that share nullifiers with mined txs
|
|
594
|
-
const txNullifiers = tx.data.getNonEmptyNullifiers();
|
|
595
|
-
if (txNullifiers.some(nullifier => minedNullifiers.has(nullifier.toString()))) {
|
|
596
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to a duplicate nullifier with a mined tx`);
|
|
597
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
598
|
-
continue;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// Evict pending txs with an insufficient fee payer balance
|
|
602
|
-
if (
|
|
603
|
-
minedFeePayers.has(tx.data.feePayer.toString()) &&
|
|
604
|
-
(await gasTxValidator.validateTxFee(tx)).result === 'invalid'
|
|
605
|
-
) {
|
|
606
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to an insufficient fee payer balance`);
|
|
607
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
608
|
-
continue;
|
|
609
|
-
}
|
|
646
|
+
private async addPendingTxIndices(tx: Tx, txHash: string): Promise<void> {
|
|
647
|
+
return await this.#store.transactionAsync(async () => {
|
|
648
|
+
await this.addPendingTxIndicesInDbTx(tx, txHash);
|
|
649
|
+
});
|
|
650
|
+
}
|
|
610
651
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
}
|
|
652
|
+
// Assumes being called within a DB transaction
|
|
653
|
+
private async removePendingTxIndicesInDbTx(tx: Tx, txHash: string): Promise<void> {
|
|
654
|
+
await this.#pendingTxPriorityToHash.deleteValue(getPendingTxPriority(tx), txHash);
|
|
655
|
+
await this.#historicalHeaderToTxHash.deleteValue(
|
|
656
|
+
(await tx.data.constants.anchorBlockHeader.hash()).toString(),
|
|
657
|
+
txHash,
|
|
658
|
+
);
|
|
659
|
+
await this.#feePayerToTxHash.deleteValue(tx.data.feePayer.toString(), txHash);
|
|
660
|
+
}
|
|
621
661
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
662
|
+
private async removePendingTxIndices(tx: Tx, txHash: string): Promise<void> {
|
|
663
|
+
return await this.#store.transactionAsync(async () => {
|
|
664
|
+
await this.removePendingTxIndicesInDbTx(tx, txHash);
|
|
665
|
+
});
|
|
626
666
|
}
|
|
627
667
|
|
|
628
668
|
/**
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
* @param txHashes - The tx hashes of the txs that were moved from mined to pending.
|
|
632
|
-
* @returns The total number of txs evicted from the pool.
|
|
669
|
+
* Returns up to `limit` lowest-priority evictable pending tx hashes without hydrating transactions.
|
|
670
|
+
* Iterates the priority index in ascending order and skips non-evictable txs.
|
|
633
671
|
*/
|
|
634
|
-
|
|
635
|
-
if (txHashes.length === 0) {
|
|
636
|
-
return 0;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
await this.#worldStateSynchronizer.syncImmediate();
|
|
640
|
-
const db = this.#worldStateSynchronizer.getCommitted();
|
|
641
|
-
const archiveCache = this.createArchiveCache(db);
|
|
642
|
-
const gasTxValidator = this.createGasTxValidator(db);
|
|
643
|
-
|
|
672
|
+
public async getLowestPriorityEvictable(limit: number): Promise<TxHash[]> {
|
|
644
673
|
const txsToEvict: TxHash[] = [];
|
|
674
|
+
if (limit <= 0) {
|
|
675
|
+
return txsToEvict;
|
|
676
|
+
}
|
|
645
677
|
|
|
646
|
-
for await (const
|
|
647
|
-
|
|
648
|
-
if (!tx) {
|
|
649
|
-
continue;
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
const [index] = await archiveCache.getArchiveIndices([Fr.fromString(headerHash)]);
|
|
653
|
-
if (index === undefined) {
|
|
654
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to an invalid archive root`);
|
|
655
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
678
|
+
for await (const txHashStr of this.#pendingTxPriorityToHash.valuesAsync()) {
|
|
679
|
+
if (this.#nonEvictableTxs.has(txHashStr)) {
|
|
656
680
|
continue;
|
|
657
681
|
}
|
|
658
682
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
683
|
+
txsToEvict.push(TxHash.fromString(txHashStr));
|
|
684
|
+
if (txsToEvict.length >= limit) {
|
|
685
|
+
break;
|
|
662
686
|
}
|
|
663
687
|
}
|
|
664
688
|
|
|
665
|
-
|
|
666
|
-
await this.deleteTxs(txsToEvict, true);
|
|
667
|
-
}
|
|
668
|
-
return txsToEvict.length;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
private async addPendingTxIndices(tx: Tx, txHash: string): Promise<void> {
|
|
672
|
-
await this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), txHash);
|
|
673
|
-
await this.#pendingTxHashToSize.set(txHash, tx.getSize());
|
|
674
|
-
await this.#pendingTxHashToHeaderHash.set(txHash, (await tx.data.constants.historicalHeader.hash()).toString());
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
private async removePendingTxIndices(tx: Tx, txHash: string): Promise<void> {
|
|
678
|
-
await this.#pendingTxPriorityToHash.deleteValue(getPendingTxPriority(tx), txHash);
|
|
679
|
-
await this.#pendingTxHashToSize.delete(txHash);
|
|
680
|
-
await this.#pendingTxHashToHeaderHash.delete(txHash);
|
|
681
|
-
this.#pendingTxs.delete(txHash);
|
|
689
|
+
return txsToEvict;
|
|
682
690
|
}
|
|
683
691
|
}
|