@aztec/p2p 0.0.1-commit.f2ce05ee → 0.0.1-commit.f81dbcf
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/client/factory.d.ts +8 -8
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +42 -13
- package/dest/client/interface.d.ts +39 -33
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +37 -50
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +144 -223
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
- package/dest/config.d.ts +47 -11
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +94 -31
- package/dest/errors/tx-pool.error.d.ts +8 -0
- package/dest/errors/tx-pool.error.d.ts.map +1 -0
- package/dest/errors/tx-pool.error.js +9 -0
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +21 -12
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +67 -37
- 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 +53 -53
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -2
- package/dest/mem_pools/index.d.ts +2 -1
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/interface.d.ts +3 -3
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
- package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +4 -4
- 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 +3 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +5 -2
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
- 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 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +7 -5
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +14 -6
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
- package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +2 -1
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +22 -8
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +68 -11
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +132 -17
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
- 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 +36 -14
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -4
- 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 +11 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +13 -5
- 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 +336 -185
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
- 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/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/double_spend_validator.d.ts +13 -3
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
- package/dest/msg_validators/tx_validator/factory.d.ts +125 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +233 -59
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
- 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/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +44 -23
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
- package/dest/services/dummy_service.d.ts +9 -5
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +7 -4
- package/dest/services/encoding.d.ts +3 -3
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +11 -10
- package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +32 -10
- package/dest/services/libp2p/libp2p_service.d.ts +25 -14
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +158 -123
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
- 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 +5 -9
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- package/dest/services/reqresp/interface.d.ts +10 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +15 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +7 -1
- 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 +15 -0
- package/dest/services/reqresp/protocols/tx.d.ts +7 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +20 -0
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +11 -4
- package/dest/services/service.d.ts +22 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +19 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +46 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +3 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +56 -36
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_source.js +90 -0
- package/dest/services/tx_collection/index.d.ts +2 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -0
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +2 -1
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
- package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +60 -26
- package/dest/services/tx_collection/tx_collection.d.ts +23 -10
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +75 -3
- package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +26 -29
- package/dest/services/tx_collection/tx_source.d.ts +8 -3
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +19 -2
- package/dest/services/tx_file_store/config.d.ts +1 -3
- package/dest/services/tx_file_store/config.d.ts.map +1 -1
- package/dest/services/tx_file_store/config.js +0 -4
- package/dest/services/tx_file_store/tx_file_store.d.ts +4 -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 +9 -6
- package/dest/services/tx_provider.d.ts +4 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +9 -8
- package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +1 -2
- package/dest/test-helpers/mock-pubsub.d.ts +30 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +105 -4
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -2
- package/dest/test-helpers/testbench-utils.d.ts +35 -24
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +95 -36
- package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +16 -15
- package/dest/testbench/worker_client_manager.d.ts +3 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +4 -1
- package/dest/util.d.ts +2 -2
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +77 -23
- package/src/client/interface.ts +43 -33
- package/src/client/p2p_client.ts +165 -265
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -10
- package/src/config.ts +139 -33
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +95 -44
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +57 -53
- package/src/mem_pools/attestation_pool/index.ts +3 -3
- package/src/mem_pools/attestation_pool/mocks.ts +2 -1
- package/src/mem_pools/index.ts +3 -0
- package/src/mem_pools/interface.ts +2 -2
- package/src/mem_pools/tx_pool/README.md +1 -1
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
- package/src/mem_pools/tx_pool/priority.ts +4 -4
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
- package/src/mem_pools/tx_pool_v2/README.md +85 -11
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +5 -2
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -9
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
- package/src/mem_pools/tx_pool_v2/index.ts +2 -1
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +23 -8
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +189 -23
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -16
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +18 -7
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +379 -182
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
- package/src/msg_validators/tx_validator/README.md +115 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
- package/src/msg_validators/tx_validator/factory.ts +373 -77
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +51 -26
- package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
- package/src/services/dummy_service.ts +12 -6
- package/src/services/encoding.ts +9 -9
- package/src/services/gossipsub/README.md +29 -14
- package/src/services/gossipsub/topic_score_params.ts +49 -13
- package/src/services/libp2p/libp2p_service.ts +170 -132
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +6 -6
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/reqresp/interface.ts +26 -1
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +2 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +17 -0
- package/src/services/reqresp/protocols/tx.ts +22 -0
- package/src/services/reqresp/reqresp.ts +13 -3
- package/src/services/service.ts +31 -2
- package/src/services/tx_collection/config.ts +68 -0
- package/src/services/tx_collection/fast_tx_collection.ts +65 -32
- package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
- package/src/services/tx_collection/file_store_tx_source.ts +117 -0
- package/src/services/tx_collection/index.ts +1 -0
- package/src/services/tx_collection/instrumentation.ts +7 -1
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
- package/src/services/tx_collection/slow_tx_collection.ts +66 -33
- package/src/services/tx_collection/tx_collection.ts +113 -16
- package/src/services/tx_collection/tx_collection_sink.ts +30 -34
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_file_store/config.ts +0 -6
- package/src/services/tx_file_store/tx_file_store.ts +10 -8
- package/src/services/tx_provider.ts +10 -9
- package/src/test-helpers/make-test-p2p-clients.ts +3 -5
- package/src/test-helpers/mock-pubsub.ts +146 -9
- package/src/test-helpers/reqresp-nodes.ts +2 -5
- package/src/test-helpers/testbench-utils.ts +109 -40
- package/src/testbench/p2p_client_testbench_worker.ts +24 -20
- package/src/testbench/worker_client_manager.ts +11 -4
- package/src/util.ts +7 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
|
+
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import type { Logger } from '@aztec/foundation/log';
|
|
3
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
3
4
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
4
5
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
5
6
|
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
@@ -8,8 +9,10 @@ import type { L2Block, L2BlockId, L2BlockSource } from '@aztec/stdlib/block';
|
|
|
8
9
|
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
9
10
|
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
10
11
|
import { BlockHeader, Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx';
|
|
12
|
+
import type { TelemetryClient } from '@aztec/telemetry-client';
|
|
11
13
|
|
|
12
14
|
import { TxArchive } from './archive/index.js';
|
|
15
|
+
import { DeletedPool } from './deleted_pool.js';
|
|
13
16
|
import {
|
|
14
17
|
EvictionManager,
|
|
15
18
|
FeePayerBalanceEvictionRule,
|
|
@@ -20,8 +23,12 @@ import {
|
|
|
20
23
|
LowPriorityPreAddRule,
|
|
21
24
|
NullifierConflictRule,
|
|
22
25
|
type PoolOperations,
|
|
26
|
+
type PreAddContext,
|
|
23
27
|
type PreAddPoolAccess,
|
|
28
|
+
TxPoolRejectionCode,
|
|
29
|
+
type TxPoolRejectionError,
|
|
24
30
|
} from './eviction/index.js';
|
|
31
|
+
import { TxPoolV2Instrumentation } from './instrumentation.js';
|
|
25
32
|
import {
|
|
26
33
|
type AddTxsResult,
|
|
27
34
|
DEFAULT_TX_POOL_V2_CONFIG,
|
|
@@ -53,7 +60,7 @@ export class TxPoolV2Impl {
|
|
|
53
60
|
// === Dependencies ===
|
|
54
61
|
#l2BlockSource: L2BlockSource;
|
|
55
62
|
#worldStateSynchronizer: WorldStateSynchronizer;
|
|
56
|
-
#
|
|
63
|
+
#createTxValidator: TxPoolV2Dependencies['createTxValidator'];
|
|
57
64
|
|
|
58
65
|
// === In-Memory Indices ===
|
|
59
66
|
#indices: TxPoolIndices = new TxPoolIndices();
|
|
@@ -61,7 +68,11 @@ export class TxPoolV2Impl {
|
|
|
61
68
|
// === Config & Services ===
|
|
62
69
|
#config: TxPoolV2Config;
|
|
63
70
|
#archive: TxArchive;
|
|
71
|
+
#deletedPool: DeletedPool;
|
|
64
72
|
#evictionManager: EvictionManager;
|
|
73
|
+
#dateProvider: DateProvider;
|
|
74
|
+
#instrumentation: TxPoolV2Instrumentation;
|
|
75
|
+
#evictedTxHashes: Set<string> = new Set();
|
|
65
76
|
#log: Logger;
|
|
66
77
|
#callbacks: TxPoolV2Callbacks;
|
|
67
78
|
|
|
@@ -70,7 +81,9 @@ export class TxPoolV2Impl {
|
|
|
70
81
|
archiveStore: AztecAsyncKVStore,
|
|
71
82
|
deps: TxPoolV2Dependencies,
|
|
72
83
|
callbacks: TxPoolV2Callbacks,
|
|
84
|
+
telemetry: TelemetryClient,
|
|
73
85
|
config: Partial<TxPoolV2Config> = {},
|
|
86
|
+
dateProvider: DateProvider,
|
|
74
87
|
log: Logger,
|
|
75
88
|
) {
|
|
76
89
|
this.#store = store;
|
|
@@ -78,10 +91,13 @@ export class TxPoolV2Impl {
|
|
|
78
91
|
|
|
79
92
|
this.#l2BlockSource = deps.l2BlockSource;
|
|
80
93
|
this.#worldStateSynchronizer = deps.worldStateSynchronizer;
|
|
81
|
-
this.#
|
|
94
|
+
this.#createTxValidator = deps.createTxValidator;
|
|
82
95
|
|
|
83
96
|
this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
|
|
84
97
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
98
|
+
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
99
|
+
this.#dateProvider = dateProvider;
|
|
100
|
+
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
|
|
85
101
|
this.#log = log;
|
|
86
102
|
this.#callbacks = callbacks;
|
|
87
103
|
|
|
@@ -116,7 +132,10 @@ export class TxPoolV2Impl {
|
|
|
116
132
|
* by running pre-add rules to resolve nullifier conflicts, balance checks, and pool size limits.
|
|
117
133
|
*/
|
|
118
134
|
async hydrateFromDatabase(): Promise<void> {
|
|
119
|
-
// Step
|
|
135
|
+
// Step 0: Hydrate deleted pool state
|
|
136
|
+
await this.#deletedPool.hydrateFromDatabase();
|
|
137
|
+
|
|
138
|
+
// Step 1: Load all transactions from DB (excluding soft-deleted)
|
|
120
139
|
const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
|
|
121
140
|
|
|
122
141
|
// Step 2: Check mined status for each tx
|
|
@@ -134,7 +153,10 @@ export class TxPoolV2Impl {
|
|
|
134
153
|
}
|
|
135
154
|
|
|
136
155
|
// Step 4: Validate non-mined transactions
|
|
137
|
-
const { valid, invalid } = await this.#
|
|
156
|
+
const { valid, invalid } = await this.#revalidateMetadata(
|
|
157
|
+
nonMined.map(e => e.meta),
|
|
158
|
+
'on startup',
|
|
159
|
+
);
|
|
138
160
|
|
|
139
161
|
// Step 5: Populate mined indices (these don't need conflict resolution)
|
|
140
162
|
for (const meta of mined) {
|
|
@@ -155,16 +177,45 @@ export class TxPoolV2Impl {
|
|
|
155
177
|
await this.#txsDB.delete(txHashStr);
|
|
156
178
|
}
|
|
157
179
|
});
|
|
158
|
-
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup
|
|
180
|
+
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
|
|
159
181
|
}
|
|
160
182
|
|
|
161
|
-
async addPendingTxs(txs: Tx[], opts: { source?: string }): Promise<AddTxsResult> {
|
|
183
|
+
async addPendingTxs(txs: Tx[], opts: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult> {
|
|
162
184
|
const accepted: TxHash[] = [];
|
|
163
185
|
const ignored: TxHash[] = [];
|
|
164
186
|
const rejected: TxHash[] = [];
|
|
187
|
+
const errors = new Map<string, TxPoolRejectionError>();
|
|
165
188
|
const acceptedPending = new Set<string>();
|
|
166
189
|
|
|
190
|
+
// Phase 1: Pre-compute all throwable I/O outside the transaction.
|
|
191
|
+
// If any pre-computation throws, the entire call fails before mutations happen.
|
|
192
|
+
const precomputed = new Map<string, { meta: TxMetaData; minedBlockId: L2BlockId | undefined; isValid: boolean }>();
|
|
193
|
+
|
|
194
|
+
const validator = await this.#createTxValidator();
|
|
195
|
+
|
|
196
|
+
for (const tx of txs) {
|
|
197
|
+
const txHash = tx.getTxHash();
|
|
198
|
+
const txHashStr = txHash.toString();
|
|
199
|
+
|
|
200
|
+
const meta = await buildTxMetaData(tx);
|
|
201
|
+
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
202
|
+
|
|
203
|
+
// Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
|
|
204
|
+
let isValid = true;
|
|
205
|
+
if (!minedBlockId) {
|
|
206
|
+
isValid = await this.#validateMeta(meta, validator);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
precomputed.set(txHashStr, { meta, minedBlockId, isValid });
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Phase 2: Apply mutations inside the transaction using only pre-computed results,
|
|
213
|
+
// in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
|
|
167
214
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
215
|
+
const preAddContext: PreAddContext | undefined =
|
|
216
|
+
opts.feeComparisonOnly !== undefined
|
|
217
|
+
? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
|
|
218
|
+
: undefined;
|
|
168
219
|
|
|
169
220
|
await this.#store.transactionAsync(async () => {
|
|
170
221
|
for (const tx of txs) {
|
|
@@ -177,30 +228,46 @@ export class TxPoolV2Impl {
|
|
|
177
228
|
continue;
|
|
178
229
|
}
|
|
179
230
|
|
|
180
|
-
|
|
181
|
-
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
231
|
+
const { meta, minedBlockId, isValid } = precomputed.get(txHashStr)!;
|
|
182
232
|
const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
|
|
183
233
|
|
|
184
234
|
if (minedBlockId) {
|
|
185
235
|
// Already mined - add directly (protection already set if pre-protected)
|
|
186
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
236
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
187
237
|
accepted.push(txHash);
|
|
188
238
|
} else if (preProtectedSlot !== undefined) {
|
|
189
239
|
// Pre-protected and not mined - add as protected (bypass validation)
|
|
190
|
-
await this.#addTx(tx, { protected: preProtectedSlot }, opts);
|
|
240
|
+
await this.#addTx(tx, { protected: preProtectedSlot }, opts, meta);
|
|
191
241
|
accepted.push(txHash);
|
|
242
|
+
} else if (!isValid) {
|
|
243
|
+
// Failed pre-computed validation
|
|
244
|
+
rejected.push(txHash);
|
|
192
245
|
} else {
|
|
193
|
-
// Regular pending tx -
|
|
194
|
-
const result = await this.#tryAddRegularPendingTx(
|
|
246
|
+
// Regular pending tx - run pre-add rules using pre-computed metadata
|
|
247
|
+
const result = await this.#tryAddRegularPendingTx(
|
|
248
|
+
tx,
|
|
249
|
+
meta,
|
|
250
|
+
opts,
|
|
251
|
+
poolAccess,
|
|
252
|
+
acceptedPending,
|
|
253
|
+
ignored,
|
|
254
|
+
errors,
|
|
255
|
+
preAddContext,
|
|
256
|
+
);
|
|
195
257
|
if (result.status === 'accepted') {
|
|
196
258
|
acceptedPending.add(txHashStr);
|
|
197
|
-
} else if (result.status === 'rejected') {
|
|
198
|
-
rejected.push(txHash);
|
|
199
259
|
} else {
|
|
200
260
|
ignored.push(txHash);
|
|
201
261
|
}
|
|
202
262
|
}
|
|
203
263
|
}
|
|
264
|
+
|
|
265
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
266
|
+
if (acceptedPending.size > 0) {
|
|
267
|
+
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
268
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
269
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
270
|
+
}
|
|
204
271
|
});
|
|
205
272
|
|
|
206
273
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
@@ -208,58 +275,74 @@ export class TxPoolV2Impl {
|
|
|
208
275
|
accepted.push(TxHash.fromString(txHashStr));
|
|
209
276
|
}
|
|
210
277
|
|
|
211
|
-
//
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
278
|
+
// Record metrics
|
|
279
|
+
if (ignored.length > 0) {
|
|
280
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
281
|
+
}
|
|
282
|
+
if (rejected.length > 0) {
|
|
283
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
216
284
|
}
|
|
217
285
|
|
|
218
|
-
return { accepted, ignored, rejected };
|
|
286
|
+
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
219
287
|
}
|
|
220
288
|
|
|
221
|
-
/**
|
|
289
|
+
/** Adds a validated pending tx, running pre-add rules and evicting conflicts. */
|
|
222
290
|
async #tryAddRegularPendingTx(
|
|
223
291
|
tx: Tx,
|
|
292
|
+
precomputedMeta: TxMetaData,
|
|
224
293
|
opts: { source?: string },
|
|
225
294
|
poolAccess: PreAddPoolAccess,
|
|
226
295
|
acceptedPending: Set<string>,
|
|
227
296
|
ignored: TxHash[],
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
// Validate transaction
|
|
233
|
-
if (!(await this.#validateTx(tx))) {
|
|
234
|
-
return { status: 'rejected' };
|
|
235
|
-
}
|
|
297
|
+
errors: Map<string, TxPoolRejectionError>,
|
|
298
|
+
preAddContext?: PreAddContext,
|
|
299
|
+
): Promise<{ status: 'accepted' | 'ignored' }> {
|
|
300
|
+
const txHashStr = tx.getTxHash().toString();
|
|
236
301
|
|
|
237
|
-
//
|
|
238
|
-
const
|
|
239
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
302
|
+
// Run pre-add rules
|
|
303
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
|
|
240
304
|
|
|
241
305
|
if (preAddResult.shouldIgnore) {
|
|
242
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
306
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
307
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
308
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
309
|
+
}
|
|
243
310
|
return { status: 'ignored' };
|
|
244
311
|
}
|
|
245
312
|
|
|
246
|
-
// Evict conflicts
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
313
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
314
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
315
|
+
const byReason = new Map<string, string[]>();
|
|
316
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions) {
|
|
317
|
+
const group = byReason.get(reason);
|
|
318
|
+
if (group) {
|
|
319
|
+
group.push(evictHash);
|
|
320
|
+
} else {
|
|
321
|
+
byReason.set(reason, [evictHash]);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
for (const [reason, hashes] of byReason) {
|
|
325
|
+
await this.#evictTxs(hashes, reason);
|
|
326
|
+
}
|
|
327
|
+
for (const evictHashStr of preAddResult.txHashesToEvict) {
|
|
328
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
329
|
+
evictedTxHash: evictHashStr,
|
|
330
|
+
replacementTxHash: txHashStr,
|
|
331
|
+
});
|
|
332
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
333
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
334
|
+
acceptedPending.delete(evictHashStr);
|
|
335
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
336
|
+
}
|
|
254
337
|
}
|
|
255
338
|
}
|
|
256
339
|
|
|
257
340
|
// Add the transaction
|
|
258
|
-
await this.#addTx(tx, 'pending', opts);
|
|
341
|
+
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
259
342
|
return { status: 'accepted' };
|
|
260
343
|
}
|
|
261
344
|
|
|
262
|
-
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'
|
|
345
|
+
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
|
|
263
346
|
const txHashStr = tx.getTxHash().toString();
|
|
264
347
|
|
|
265
348
|
// Check if already in pool
|
|
@@ -267,13 +350,7 @@ export class TxPoolV2Impl {
|
|
|
267
350
|
return 'ignored';
|
|
268
351
|
}
|
|
269
352
|
|
|
270
|
-
//
|
|
271
|
-
const validationResult = await this.#pendingTxValidator.validateTx(tx);
|
|
272
|
-
if (validationResult.result !== 'valid') {
|
|
273
|
-
return 'rejected';
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// Build metadata and use pre-add rules
|
|
353
|
+
// Build metadata and check pre-add rules
|
|
277
354
|
const meta = await buildTxMetaData(tx);
|
|
278
355
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
279
356
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
@@ -311,22 +388,57 @@ export class TxPoolV2Impl {
|
|
|
311
388
|
});
|
|
312
389
|
}
|
|
313
390
|
|
|
314
|
-
protectTxs(txHashes: TxHash[], block: BlockHeader): TxHash[] {
|
|
391
|
+
async protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
|
|
315
392
|
const slotNumber = block.globalVariables.slotNumber;
|
|
316
393
|
const missing: TxHash[] = [];
|
|
394
|
+
let softDeletedHits = 0;
|
|
395
|
+
let missingPreviouslyEvicted = 0;
|
|
317
396
|
|
|
318
|
-
|
|
319
|
-
const
|
|
397
|
+
await this.#store.transactionAsync(async () => {
|
|
398
|
+
for (const txHash of txHashes) {
|
|
399
|
+
const txHashStr = txHash.toString();
|
|
320
400
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
401
|
+
if (this.#indices.has(txHashStr)) {
|
|
402
|
+
// Update protection for existing tx
|
|
403
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
404
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
405
|
+
// Resurrect soft-deleted tx as protected
|
|
406
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
407
|
+
if (buffer) {
|
|
408
|
+
const tx = Tx.fromBuffer(buffer);
|
|
409
|
+
await this.#addTx(tx, { protected: slotNumber });
|
|
410
|
+
softDeletedHits++;
|
|
411
|
+
} else {
|
|
412
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
413
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
414
|
+
missing.push(txHash);
|
|
415
|
+
}
|
|
416
|
+
} else {
|
|
417
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
418
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
419
|
+
missing.push(txHash);
|
|
420
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
421
|
+
missingPreviouslyEvicted++;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
328
424
|
}
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
// Record metrics
|
|
428
|
+
if (softDeletedHits > 0) {
|
|
429
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
329
430
|
}
|
|
431
|
+
if (missing.length > 0) {
|
|
432
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map(h => h.toString()).join(', ')}`);
|
|
433
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
434
|
+
}
|
|
435
|
+
if (missingPreviouslyEvicted > 0) {
|
|
436
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
this.#log.info(
|
|
440
|
+
`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`,
|
|
441
|
+
);
|
|
330
442
|
|
|
331
443
|
return missing;
|
|
332
444
|
}
|
|
@@ -347,6 +459,7 @@ export class TxPoolV2Impl {
|
|
|
347
459
|
// Add new mined tx (callback emitted by #addTx)
|
|
348
460
|
await this.#addTx(tx, { mined: blockId }, opts);
|
|
349
461
|
}
|
|
462
|
+
await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
|
|
350
463
|
}
|
|
351
464
|
});
|
|
352
465
|
}
|
|
@@ -370,53 +483,63 @@ export class TxPoolV2Impl {
|
|
|
370
483
|
}
|
|
371
484
|
}
|
|
372
485
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
486
|
+
await this.#store.transactionAsync(async () => {
|
|
487
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
488
|
+
for (const meta of found) {
|
|
489
|
+
this.#indices.markAsMined(meta, blockId);
|
|
490
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
491
|
+
}
|
|
377
492
|
|
|
378
|
-
|
|
379
|
-
|
|
493
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
494
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
495
|
+
});
|
|
380
496
|
|
|
381
497
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
382
498
|
}
|
|
383
499
|
|
|
384
500
|
async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
|
|
385
|
-
|
|
386
|
-
|
|
501
|
+
await this.#store.transactionAsync(async () => {
|
|
502
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
503
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
387
504
|
|
|
388
|
-
|
|
389
|
-
|
|
505
|
+
// Step 1: Find expired protected txs
|
|
506
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
390
507
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
508
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
509
|
+
this.#indices.clearProtection(expiredProtected);
|
|
510
|
+
|
|
511
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
512
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
513
|
+
if (txsToRestore.length === 0) {
|
|
514
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
396
517
|
|
|
397
|
-
|
|
518
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
398
519
|
|
|
399
|
-
|
|
400
|
-
|
|
520
|
+
// Step 4: Validate for pending pool
|
|
521
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
401
522
|
|
|
402
|
-
|
|
403
|
-
|
|
523
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
524
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
404
525
|
|
|
405
|
-
|
|
406
|
-
|
|
526
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
527
|
+
await this.#deleteTxsBatch(invalid);
|
|
528
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
407
529
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
530
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
531
|
+
if (added.length > 0) {
|
|
532
|
+
const feePayers = added.map(meta => meta.feePayer);
|
|
533
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
534
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
535
|
+
added.map(m => m.txHash),
|
|
536
|
+
[...uniqueFeePayers],
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
});
|
|
417
540
|
}
|
|
418
541
|
|
|
419
|
-
async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
|
|
542
|
+
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
420
543
|
// Step 1: Find transactions mined after the prune point
|
|
421
544
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
422
545
|
if (txsToUnmine.length === 0) {
|
|
@@ -426,64 +549,99 @@ export class TxPoolV2Impl {
|
|
|
426
549
|
|
|
427
550
|
this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
|
|
428
551
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
552
|
+
await this.#store.transactionAsync(async () => {
|
|
553
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
554
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
555
|
+
// when their original mined block is finalized
|
|
556
|
+
await this.#deletedPool.markFromPrunedBlock(
|
|
557
|
+
txsToUnmine.map(m => ({
|
|
558
|
+
txHash: m.txHash,
|
|
559
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
|
|
560
|
+
})),
|
|
561
|
+
);
|
|
562
|
+
|
|
563
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
564
|
+
for (const meta of txsToUnmine) {
|
|
565
|
+
this.#indices.markAsUnmined(meta);
|
|
566
|
+
}
|
|
433
567
|
|
|
434
|
-
|
|
435
|
-
|
|
568
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
569
|
+
if (options?.deleteAllTxs) {
|
|
570
|
+
const allTxHashes = txsToUnmine.map(m => m.txHash);
|
|
571
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
572
|
+
this.#log.info(
|
|
573
|
+
`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
|
|
574
|
+
);
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
436
577
|
|
|
437
|
-
|
|
438
|
-
|
|
578
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
579
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
439
580
|
|
|
440
|
-
|
|
441
|
-
|
|
581
|
+
// Step 5: Validate for pending pool
|
|
582
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
442
583
|
|
|
443
|
-
|
|
444
|
-
|
|
584
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
585
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
445
586
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
587
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
588
|
+
await this.#deleteTxsBatch(invalid);
|
|
589
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
590
|
+
|
|
591
|
+
this.#log.info(
|
|
592
|
+
`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
|
|
593
|
+
{ txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
597
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
598
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
599
|
+
});
|
|
449
600
|
}
|
|
450
601
|
|
|
451
602
|
async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
|
|
452
|
-
|
|
453
|
-
|
|
603
|
+
await this.#store.transactionAsync(async () => {
|
|
604
|
+
await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
|
|
605
|
+
});
|
|
454
606
|
|
|
455
|
-
this.#log.info(`Deleted ${txHashes.length} failed txs
|
|
607
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
|
|
456
608
|
}
|
|
457
609
|
|
|
458
610
|
async handleFinalizedBlock(block: BlockHeader): Promise<void> {
|
|
459
611
|
const blockNumber = block.globalVariables.blockNumber;
|
|
460
612
|
|
|
461
|
-
// Step 1: Find txs
|
|
462
|
-
const
|
|
463
|
-
if (txsToFinalize.length === 0) {
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
613
|
+
// Step 1: Find mined txs at or before finalized block
|
|
614
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
466
615
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
616
|
+
await this.#store.transactionAsync(async () => {
|
|
617
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
618
|
+
const txsToArchive: Tx[] = [];
|
|
619
|
+
if (this.#archive.isEnabled()) {
|
|
620
|
+
for (const txHashStr of minedTxsToFinalize) {
|
|
621
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
622
|
+
if (buffer) {
|
|
623
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
624
|
+
}
|
|
474
625
|
}
|
|
475
626
|
}
|
|
476
|
-
}
|
|
477
627
|
|
|
478
|
-
|
|
479
|
-
|
|
628
|
+
// Step 3: Delete mined txs from active pool
|
|
629
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
480
630
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
await this.#archive.archiveTxs(txsToArchive);
|
|
484
|
-
}
|
|
631
|
+
// Step 4: Finalize soft-deleted txs
|
|
632
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
485
633
|
|
|
486
|
-
|
|
634
|
+
// Step 5: Archive mined txs
|
|
635
|
+
if (txsToArchive.length > 0) {
|
|
636
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
if (minedTxsToFinalize.length > 0) {
|
|
641
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
642
|
+
txHashes: minedTxsToFinalize,
|
|
643
|
+
});
|
|
644
|
+
}
|
|
487
645
|
}
|
|
488
646
|
|
|
489
647
|
// === Query Methods ===
|
|
@@ -503,21 +661,36 @@ export class TxPoolV2Impl {
|
|
|
503
661
|
}
|
|
504
662
|
|
|
505
663
|
hasTxs(txHashes: TxHash[]): boolean[] {
|
|
506
|
-
return txHashes.map(h =>
|
|
664
|
+
return txHashes.map(h => {
|
|
665
|
+
const hashStr = h.toString();
|
|
666
|
+
return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
|
|
667
|
+
});
|
|
507
668
|
}
|
|
508
669
|
|
|
509
670
|
getTxStatus(txHash: TxHash): TxState | undefined {
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
671
|
+
const txHashStr = txHash.toString();
|
|
672
|
+
const meta = this.#indices.getMetadata(txHashStr);
|
|
673
|
+
if (meta) {
|
|
674
|
+
return this.#indices.getTxState(meta);
|
|
675
|
+
}
|
|
676
|
+
// Check if soft-deleted
|
|
677
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
678
|
+
return 'deleted';
|
|
513
679
|
}
|
|
514
|
-
return
|
|
680
|
+
return undefined;
|
|
515
681
|
}
|
|
516
682
|
|
|
517
683
|
getPendingTxHashes(): TxHash[] {
|
|
518
684
|
return [...this.#indices.iteratePendingByPriority('desc')].map(hash => TxHash.fromString(hash));
|
|
519
685
|
}
|
|
520
686
|
|
|
687
|
+
getEligiblePendingTxHashes(): TxHash[] {
|
|
688
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
689
|
+
return [...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)].map(hash =>
|
|
690
|
+
TxHash.fromString(hash),
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
|
|
521
694
|
getPendingTxCount(): number {
|
|
522
695
|
return this.#indices.getPendingTxCount();
|
|
523
696
|
}
|
|
@@ -562,6 +735,9 @@ export class TxPoolV2Impl {
|
|
|
562
735
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
563
736
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
564
737
|
}
|
|
738
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
739
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
740
|
+
}
|
|
565
741
|
// Update eviction rules with new config
|
|
566
742
|
this.#evictionManager.updateConfig(config);
|
|
567
743
|
}
|
|
@@ -579,8 +755,17 @@ export class TxPoolV2Impl {
|
|
|
579
755
|
|
|
580
756
|
// === Metrics ===
|
|
581
757
|
|
|
582
|
-
countTxs(): {
|
|
583
|
-
|
|
758
|
+
countTxs(): {
|
|
759
|
+
pending: number;
|
|
760
|
+
protected: number;
|
|
761
|
+
mined: number;
|
|
762
|
+
softDeleted: number;
|
|
763
|
+
totalMetadataBytes: number;
|
|
764
|
+
} {
|
|
765
|
+
return {
|
|
766
|
+
...this.#indices.countTxs(),
|
|
767
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount(),
|
|
768
|
+
};
|
|
584
769
|
}
|
|
585
770
|
|
|
586
771
|
// ============================================================================
|
|
@@ -595,11 +780,14 @@ export class TxPoolV2Impl {
|
|
|
595
780
|
tx: Tx,
|
|
596
781
|
state: 'pending' | { protected: SlotNumber } | { mined: L2BlockId },
|
|
597
782
|
opts: { source?: string } = {},
|
|
783
|
+
precomputedMeta?: TxMetaData,
|
|
598
784
|
): Promise<TxMetaData> {
|
|
599
785
|
const txHashStr = tx.getTxHash().toString();
|
|
600
|
-
const meta = await buildTxMetaData(tx);
|
|
786
|
+
const meta = precomputedMeta ?? (await buildTxMetaData(tx));
|
|
787
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
601
788
|
|
|
602
789
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
790
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
603
791
|
this.#callbacks.onTxsAdded([tx], opts);
|
|
604
792
|
|
|
605
793
|
if (state === 'pending') {
|
|
@@ -612,9 +800,11 @@ export class TxPoolV2Impl {
|
|
|
612
800
|
}
|
|
613
801
|
|
|
614
802
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
615
|
-
this.#log.
|
|
803
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
616
804
|
eventName: 'tx-added-to-pool',
|
|
805
|
+
txHash: txHashStr,
|
|
617
806
|
state: stateStr,
|
|
807
|
+
source: opts.source,
|
|
618
808
|
});
|
|
619
809
|
|
|
620
810
|
return meta;
|
|
@@ -624,10 +814,15 @@ export class TxPoolV2Impl {
|
|
|
624
814
|
* Deletes a transaction from both indices and DB.
|
|
625
815
|
* Emits onTxsRemoved callback immediately after DB delete.
|
|
626
816
|
*/
|
|
817
|
+
/**
|
|
818
|
+
* Deletes a transaction from the pool.
|
|
819
|
+
* Delegates to DeletedPool which decides soft vs hard delete based on whether
|
|
820
|
+
* the tx is from a pruned block.
|
|
821
|
+
*/
|
|
627
822
|
async #deleteTx(txHashStr: string): Promise<void> {
|
|
628
823
|
this.#indices.remove(txHashStr);
|
|
629
|
-
await this.#txsDB.delete(txHashStr);
|
|
630
824
|
this.#callbacks.onTxsRemoved([txHashStr]);
|
|
825
|
+
await this.#deletedPool.deleteTx(txHashStr);
|
|
631
826
|
}
|
|
632
827
|
|
|
633
828
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */
|
|
@@ -637,68 +832,63 @@ export class TxPoolV2Impl {
|
|
|
637
832
|
}
|
|
638
833
|
}
|
|
639
834
|
|
|
835
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */
|
|
836
|
+
async #evictTxs(txHashes: string[], reason: string): Promise<void> {
|
|
837
|
+
if (txHashes.length === 0) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
841
|
+
for (const txHashStr of txHashes) {
|
|
842
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
843
|
+
this.#addToEvictedCache(txHashStr);
|
|
844
|
+
}
|
|
845
|
+
await this.#deleteTxsBatch(txHashes);
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
|
|
849
|
+
#addToEvictedCache(txHashStr: string): void {
|
|
850
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
851
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
852
|
+
const oldest = this.#evictedTxHashes.values().next().value!;
|
|
853
|
+
this.#evictedTxHashes.delete(oldest);
|
|
854
|
+
}
|
|
855
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
856
|
+
}
|
|
857
|
+
|
|
640
858
|
// ============================================================================
|
|
641
859
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
642
860
|
// ============================================================================
|
|
643
861
|
|
|
644
|
-
/** Validates
|
|
645
|
-
async #
|
|
646
|
-
const
|
|
862
|
+
/** Validates transaction metadata, returning true if valid */
|
|
863
|
+
async #validateMeta(meta: TxMetaData, validator?: TxValidator<TxMetaData>, context?: string): Promise<boolean> {
|
|
864
|
+
const txValidator = validator ?? (await this.#createTxValidator());
|
|
865
|
+
const result = await txValidator.validateTx(meta);
|
|
647
866
|
if (result.result !== 'valid') {
|
|
648
867
|
const contextStr = context ? ` ${context}` : '';
|
|
649
|
-
this.#log.info(`Tx ${
|
|
868
|
+
this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
|
|
650
869
|
return false;
|
|
651
870
|
}
|
|
652
871
|
return true;
|
|
653
872
|
}
|
|
654
873
|
|
|
655
|
-
/**
|
|
656
|
-
async #
|
|
657
|
-
|
|
658
|
-
const missing: string[] = [];
|
|
659
|
-
|
|
660
|
-
for (const meta of metas) {
|
|
661
|
-
const buffer = await this.#txsDB.getAsync(meta.txHash);
|
|
662
|
-
if (!buffer) {
|
|
663
|
-
this.#log.warn(`Tx ${meta.txHash} not found in DB`);
|
|
664
|
-
missing.push(meta.txHash);
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
loaded.push({ tx: Tx.fromBuffer(buffer), meta });
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
return { loaded, missing };
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
/** Validates a batch of transactions, returning valid and invalid groups */
|
|
674
|
-
async #validateTxBatch(
|
|
675
|
-
txs: { tx: Tx; meta: TxMetaData }[],
|
|
874
|
+
/** Validates metadata directly */
|
|
875
|
+
async #revalidateMetadata(
|
|
876
|
+
metas: TxMetaData[],
|
|
676
877
|
context?: string,
|
|
677
878
|
): Promise<{ valid: TxMetaData[]; invalid: string[] }> {
|
|
678
879
|
const valid: TxMetaData[] = [];
|
|
679
880
|
const invalid: string[] = [];
|
|
680
|
-
|
|
681
|
-
for (const
|
|
682
|
-
if (await this.#
|
|
881
|
+
const validator = await this.#createTxValidator();
|
|
882
|
+
for (const meta of metas) {
|
|
883
|
+
if (await this.#validateMeta(meta, validator, context)) {
|
|
683
884
|
valid.push(meta);
|
|
684
885
|
} else {
|
|
685
886
|
invalid.push(meta.txHash);
|
|
686
887
|
}
|
|
687
888
|
}
|
|
688
|
-
|
|
689
889
|
return { valid, invalid };
|
|
690
890
|
}
|
|
691
891
|
|
|
692
|
-
/** Loads transactions from DB and validates them */
|
|
693
|
-
async #loadAndValidateTxs(
|
|
694
|
-
metas: TxMetaData[],
|
|
695
|
-
context?: string,
|
|
696
|
-
): Promise<{ valid: TxMetaData[]; invalid: string[] }> {
|
|
697
|
-
const { loaded, missing } = await this.#loadTxsFromDb(metas);
|
|
698
|
-
const { valid, invalid } = await this.#validateTxBatch(loaded, context);
|
|
699
|
-
return { valid, invalid: [...missing, ...invalid] };
|
|
700
|
-
}
|
|
701
|
-
|
|
702
892
|
/**
|
|
703
893
|
* Resolves nullifier conflicts between incoming txs and existing pending txs.
|
|
704
894
|
* Modifies the pending indices during iteration to maintain consistent state
|
|
@@ -768,6 +958,11 @@ export class TxPoolV2Impl {
|
|
|
768
958
|
const errors: string[] = [];
|
|
769
959
|
|
|
770
960
|
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
961
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
962
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
963
|
+
continue;
|
|
964
|
+
}
|
|
965
|
+
|
|
771
966
|
try {
|
|
772
967
|
const tx = Tx.fromBuffer(buffer);
|
|
773
968
|
const meta = await buildTxMetaData(tx);
|
|
@@ -815,7 +1010,9 @@ export class TxPoolV2Impl {
|
|
|
815
1010
|
if (preAddResult.shouldIgnore) {
|
|
816
1011
|
// Transaction rejected - mark for deletion from DB
|
|
817
1012
|
rejected.push(meta.txHash);
|
|
818
|
-
this.#log.debug(
|
|
1013
|
+
this.#log.debug(
|
|
1014
|
+
`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`,
|
|
1015
|
+
);
|
|
819
1016
|
continue;
|
|
820
1017
|
}
|
|
821
1018
|
|
|
@@ -851,7 +1048,7 @@ export class TxPoolV2Impl {
|
|
|
851
1048
|
getFeePayerPendingTxs: (feePayer: string) => this.#indices.getFeePayerPendingTxs(feePayer),
|
|
852
1049
|
getPendingTxCount: () => this.#indices.getPendingTxCount(),
|
|
853
1050
|
getLowestPriorityPending: (limit: number) => this.#indices.getLowestPriorityPending(limit),
|
|
854
|
-
deleteTxs: (txHashes: string[]) => this.#
|
|
1051
|
+
deleteTxs: (txHashes: string[], reason?: string) => this.#evictTxs(txHashes, reason ?? 'unknown'),
|
|
855
1052
|
};
|
|
856
1053
|
}
|
|
857
1054
|
|