@aztec/p2p 0.0.1-commit.6d63667d → 0.0.1-commit.733c4a3
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 +7 -6
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +35 -11
- package/dest/client/interface.d.ts +45 -32
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +38 -50
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +145 -200
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -6
- package/dest/config.d.ts +24 -8
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +16 -6
- 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 +104 -88
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +441 -3
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +353 -87
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -2
- package/dest/mem_pools/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 +3 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/index.js +1 -1
- package/dest/mem_pools/interface.d.ts +5 -5
- 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_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 +10 -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 +48 -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 +14 -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 +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -1
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +1 -0
- 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 +39 -5
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +74 -5
- 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 +27 -4
- 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 +312 -169
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +3 -3
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/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/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/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 +114 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +219 -58
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +58 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +73 -36
- 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/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/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 +13 -5
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +10 -4
- package/dest/services/encoding.d.ts +2 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +4 -3
- package/dest/services/gossipsub/index.d.ts +3 -0
- package/dest/services/gossipsub/index.d.ts.map +1 -0
- package/dest/services/gossipsub/index.js +2 -0
- package/dest/services/gossipsub/scoring.d.ts +21 -3
- package/dest/services/gossipsub/scoring.d.ts.map +1 -1
- package/dest/services/gossipsub/scoring.js +24 -7
- package/dest/services/gossipsub/topic_score_params.d.ts +173 -0
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
- package/dest/services/gossipsub/topic_score_params.js +346 -0
- package/dest/services/libp2p/libp2p_service.d.ts +91 -38
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +411 -321
- package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +25 -2
- 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 +19 -46
- 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/peer_collection.d.ts +17 -11
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +49 -15
- 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 +4 -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 +39 -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 +3 -3
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +29 -2
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +103 -2
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -1
- package/dest/test-helpers/testbench-utils.d.ts +43 -38
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +128 -59
- 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 +10 -10
- 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 +66 -14
- package/src/client/interface.ts +61 -33
- package/src/client/p2p_client.ts +179 -236
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -9
- package/src/config.ts +35 -11
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +496 -91
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +442 -102
- package/src/mem_pools/attestation_pool/index.ts +9 -2
- package/src/mem_pools/attestation_pool/mocks.ts +2 -1
- package/src/mem_pools/index.ts +4 -1
- package/src/mem_pools/interface.ts +4 -4
- 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_v2/README.md +76 -10
- 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 +15 -4
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +49 -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 +24 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/index.ts +1 -0
- 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 +103 -9
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +32 -5
- 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 +347 -166
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +2 -2
- 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/block_header_validator.ts +15 -3
- package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
- package/src/msg_validators/tx_validator/factory.ts +353 -77
- package/src/msg_validators/tx_validator/gas_validator.ts +90 -27
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
- package/src/services/dummy_service.ts +18 -6
- package/src/services/encoding.ts +4 -3
- package/src/services/gossipsub/README.md +641 -0
- package/src/services/gossipsub/index.ts +2 -0
- package/src/services/gossipsub/scoring.ts +29 -5
- package/src/services/gossipsub/topic_score_params.ts +487 -0
- package/src/services/libp2p/libp2p_service.ts +431 -344
- package/src/services/peer-manager/peer_scoring.ts +25 -0
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +20 -48
- 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/peer_collection.ts +63 -24
- 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 +4 -3
- 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 +51 -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 -3
- package/src/test-helpers/mock-pubsub.ts +143 -3
- package/src/test-helpers/reqresp-nodes.ts +2 -1
- package/src/test-helpers/testbench-utils.ts +127 -71
- package/src/testbench/p2p_client_testbench_worker.ts +22 -15
- package/src/util.ts +7 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
2
3
|
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
3
4
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
5
|
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
5
6
|
import { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
6
7
|
import { TxArchive } from './archive/index.js';
|
|
7
|
-
import {
|
|
8
|
+
import { DeletedPool } from './deleted_pool.js';
|
|
9
|
+
import { EvictionManager, FeePayerBalanceEvictionRule, FeePayerBalancePreAddRule, InvalidTxsAfterMiningRule, InvalidTxsAfterReorgRule, LowPriorityEvictionRule, LowPriorityPreAddRule, NullifierConflictRule, TxPoolRejectionCode } from './eviction/index.js';
|
|
10
|
+
import { TxPoolV2Instrumentation } from './instrumentation.js';
|
|
8
11
|
import { DEFAULT_TX_POOL_V2_CONFIG } from './interfaces.js';
|
|
9
12
|
import { buildTxMetaData, checkNullifierConflict } from './tx_metadata.js';
|
|
10
13
|
import { TxPoolIndices } from './tx_pool_indices.js';
|
|
@@ -19,26 +22,33 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
19
22
|
// === Dependencies ===
|
|
20
23
|
#l2BlockSource;
|
|
21
24
|
#worldStateSynchronizer;
|
|
22
|
-
#
|
|
25
|
+
#createTxValidator;
|
|
23
26
|
// === In-Memory Indices ===
|
|
24
27
|
#indices = new TxPoolIndices();
|
|
25
28
|
// === Config & Services ===
|
|
26
29
|
#config;
|
|
27
30
|
#archive;
|
|
31
|
+
#deletedPool;
|
|
28
32
|
#evictionManager;
|
|
33
|
+
#dateProvider;
|
|
34
|
+
#instrumentation;
|
|
35
|
+
#evictedTxHashes = new Set();
|
|
29
36
|
#log;
|
|
30
37
|
#callbacks;
|
|
31
|
-
constructor(store, archiveStore, deps, callbacks, config = {}, log){
|
|
38
|
+
constructor(store, archiveStore, deps, callbacks, telemetry, config = {}, dateProvider, log){
|
|
32
39
|
this.#store = store;
|
|
33
40
|
this.#txsDB = store.openMap('txs');
|
|
34
41
|
this.#l2BlockSource = deps.l2BlockSource;
|
|
35
42
|
this.#worldStateSynchronizer = deps.worldStateSynchronizer;
|
|
36
|
-
this.#
|
|
43
|
+
this.#createTxValidator = deps.createTxValidator;
|
|
37
44
|
this.#config = {
|
|
38
45
|
...DEFAULT_TX_POOL_V2_CONFIG,
|
|
39
46
|
...config
|
|
40
47
|
};
|
|
41
48
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
49
|
+
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
50
|
+
this.#dateProvider = dateProvider;
|
|
51
|
+
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, ()=>this.#indices.getTotalMetadataBytes());
|
|
42
52
|
this.#log = log;
|
|
43
53
|
this.#callbacks = callbacks;
|
|
44
54
|
// Setup eviction manager with rules
|
|
@@ -69,7 +79,9 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
69
79
|
* Note: Protected status is lost on restart. All non-mined txs are rebuilt as pending
|
|
70
80
|
* by running pre-add rules to resolve nullifier conflicts, balance checks, and pool size limits.
|
|
71
81
|
*/ async hydrateFromDatabase() {
|
|
72
|
-
// Step
|
|
82
|
+
// Step 0: Hydrate deleted pool state
|
|
83
|
+
await this.#deletedPool.hydrateFromDatabase();
|
|
84
|
+
// Step 1: Load all transactions from DB (excluding soft-deleted)
|
|
73
85
|
const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
|
|
74
86
|
// Step 2: Check mined status for each tx
|
|
75
87
|
await this.#markMinedStatusBatch(loaded.map((l)=>l.meta));
|
|
@@ -84,7 +96,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
84
96
|
}
|
|
85
97
|
}
|
|
86
98
|
// Step 4: Validate non-mined transactions
|
|
87
|
-
const { valid, invalid } = await this.#
|
|
99
|
+
const { valid, invalid } = await this.#revalidateMetadata(nonMined.map((e)=>e.meta), 'on startup');
|
|
88
100
|
// Step 5: Populate mined indices (these don't need conflict resolution)
|
|
89
101
|
for (const meta of mined){
|
|
90
102
|
this.#indices.addMined(meta);
|
|
@@ -106,14 +118,20 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
106
118
|
await this.#txsDB.delete(txHashStr);
|
|
107
119
|
}
|
|
108
120
|
});
|
|
109
|
-
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup
|
|
121
|
+
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, {
|
|
122
|
+
txHashes: toDelete
|
|
123
|
+
});
|
|
110
124
|
}
|
|
111
125
|
async addPendingTxs(txs, opts) {
|
|
112
126
|
const accepted = [];
|
|
113
127
|
const ignored = [];
|
|
114
128
|
const rejected = [];
|
|
129
|
+
const errors = new Map();
|
|
115
130
|
const acceptedPending = new Set();
|
|
116
131
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
132
|
+
const preAddContext = opts.feeComparisonOnly !== undefined ? {
|
|
133
|
+
feeComparisonOnly: opts.feeComparisonOnly
|
|
134
|
+
} : undefined;
|
|
117
135
|
await this.#store.transactionAsync(async ()=>{
|
|
118
136
|
for (const tx of txs){
|
|
119
137
|
const txHash = tx.getTxHash();
|
|
@@ -140,7 +158,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
140
158
|
accepted.push(txHash);
|
|
141
159
|
} else {
|
|
142
160
|
// Regular pending tx - validate and run pre-add rules
|
|
143
|
-
const result = await this.#tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored);
|
|
161
|
+
const result = await this.#tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored, errors, preAddContext);
|
|
144
162
|
if (result.status === 'accepted') {
|
|
145
163
|
acceptedPending.add(txHashStr);
|
|
146
164
|
} else if (result.status === 'rejected') {
|
|
@@ -150,53 +168,91 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
150
168
|
}
|
|
151
169
|
}
|
|
152
170
|
}
|
|
171
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
172
|
+
if (acceptedPending.size > 0) {
|
|
173
|
+
const feePayers = Array.from(acceptedPending).map((txHash)=>this.#indices.getMetadata(txHash).feePayer);
|
|
174
|
+
const uniqueFeePayers = new Set(feePayers);
|
|
175
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [
|
|
176
|
+
...uniqueFeePayers
|
|
177
|
+
]);
|
|
178
|
+
}
|
|
153
179
|
});
|
|
154
180
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
155
181
|
for (const txHashStr of acceptedPending){
|
|
156
182
|
accepted.push(TxHash.fromString(txHashStr));
|
|
157
183
|
}
|
|
158
|
-
//
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
]);
|
|
184
|
+
// Record metrics
|
|
185
|
+
if (ignored.length > 0) {
|
|
186
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
187
|
+
}
|
|
188
|
+
if (rejected.length > 0) {
|
|
189
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
165
190
|
}
|
|
166
191
|
return {
|
|
167
192
|
accepted,
|
|
168
193
|
ignored,
|
|
169
|
-
rejected
|
|
194
|
+
rejected,
|
|
195
|
+
...errors.size > 0 ? {
|
|
196
|
+
errors
|
|
197
|
+
} : {}
|
|
170
198
|
};
|
|
171
199
|
}
|
|
172
|
-
/** Validates and adds a regular pending tx. Returns status. */ async #tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored) {
|
|
200
|
+
/** Validates and adds a regular pending tx. Returns status. */ async #tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored, errors, preAddContext) {
|
|
173
201
|
const txHash = tx.getTxHash();
|
|
174
202
|
const txHashStr = txHash.toString();
|
|
175
|
-
//
|
|
176
|
-
|
|
203
|
+
// Build metadata and validate using metadata
|
|
204
|
+
const meta = await buildTxMetaData(tx);
|
|
205
|
+
if (!await this.#validateMeta(meta)) {
|
|
177
206
|
return {
|
|
178
207
|
status: 'rejected'
|
|
179
208
|
};
|
|
180
209
|
}
|
|
181
|
-
//
|
|
182
|
-
const
|
|
183
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
210
|
+
// Run pre-add rules
|
|
211
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess, preAddContext);
|
|
184
212
|
if (preAddResult.shouldIgnore) {
|
|
185
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
213
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
214
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
215
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
216
|
+
}
|
|
186
217
|
return {
|
|
187
218
|
status: 'ignored'
|
|
188
219
|
};
|
|
189
220
|
}
|
|
190
|
-
// Evict conflicts
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
221
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
222
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
223
|
+
const byReason = new Map();
|
|
224
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions){
|
|
225
|
+
const group = byReason.get(reason);
|
|
226
|
+
if (group) {
|
|
227
|
+
group.push(evictHash);
|
|
228
|
+
} else {
|
|
229
|
+
byReason.set(reason, [
|
|
230
|
+
evictHash
|
|
231
|
+
]);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
for (const [reason, hashes] of byReason){
|
|
235
|
+
await this.#evictTxs(hashes, reason);
|
|
236
|
+
}
|
|
237
|
+
for (const evictHashStr of preAddResult.txHashesToEvict){
|
|
238
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
239
|
+
evictedTxHash: evictHashStr,
|
|
240
|
+
replacementTxHash: txHashStr
|
|
241
|
+
});
|
|
242
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
243
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
244
|
+
acceptedPending.delete(evictHashStr);
|
|
245
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
246
|
+
}
|
|
198
247
|
}
|
|
199
248
|
}
|
|
249
|
+
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
250
|
+
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
251
|
+
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
252
|
+
return {
|
|
253
|
+
status: 'accepted'
|
|
254
|
+
};
|
|
255
|
+
}
|
|
200
256
|
// Add the transaction
|
|
201
257
|
await this.#addTx(tx, 'pending', opts);
|
|
202
258
|
return {
|
|
@@ -209,12 +265,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
209
265
|
if (this.#indices.has(txHashStr)) {
|
|
210
266
|
return 'ignored';
|
|
211
267
|
}
|
|
212
|
-
//
|
|
213
|
-
const validationResult = await this.#pendingTxValidator.validateTx(tx);
|
|
214
|
-
if (validationResult.result !== 'valid') {
|
|
215
|
-
return 'rejected';
|
|
216
|
-
}
|
|
217
|
-
// Build metadata and use pre-add rules
|
|
268
|
+
// Build metadata and check pre-add rules
|
|
218
269
|
const meta = await buildTxMetaData(tx);
|
|
219
270
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
220
271
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
@@ -251,20 +302,53 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
251
302
|
}
|
|
252
303
|
});
|
|
253
304
|
}
|
|
254
|
-
protectTxs(txHashes, block) {
|
|
305
|
+
async protectTxs(txHashes, block) {
|
|
255
306
|
const slotNumber = block.globalVariables.slotNumber;
|
|
256
307
|
const missing = [];
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
308
|
+
let softDeletedHits = 0;
|
|
309
|
+
let missingPreviouslyEvicted = 0;
|
|
310
|
+
await this.#store.transactionAsync(async ()=>{
|
|
311
|
+
for (const txHash of txHashes){
|
|
312
|
+
const txHashStr = txHash.toString();
|
|
313
|
+
if (this.#indices.has(txHashStr)) {
|
|
314
|
+
// Update protection for existing tx
|
|
315
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
316
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
317
|
+
// Resurrect soft-deleted tx as protected
|
|
318
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
319
|
+
if (buffer) {
|
|
320
|
+
const tx = Tx.fromBuffer(buffer);
|
|
321
|
+
await this.#addTx(tx, {
|
|
322
|
+
protected: slotNumber
|
|
323
|
+
});
|
|
324
|
+
softDeletedHits++;
|
|
325
|
+
} else {
|
|
326
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
327
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
328
|
+
missing.push(txHash);
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
332
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
333
|
+
missing.push(txHash);
|
|
334
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
335
|
+
missingPreviouslyEvicted++;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
266
338
|
}
|
|
339
|
+
});
|
|
340
|
+
// Record metrics
|
|
341
|
+
if (softDeletedHits > 0) {
|
|
342
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
343
|
+
}
|
|
344
|
+
if (missing.length > 0) {
|
|
345
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map((h)=>h.toString()).join(', ')}`);
|
|
346
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
347
|
+
}
|
|
348
|
+
if (missingPreviouslyEvicted > 0) {
|
|
349
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
267
350
|
}
|
|
351
|
+
this.#log.info(`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`);
|
|
268
352
|
return missing;
|
|
269
353
|
}
|
|
270
354
|
async addMinedTxs(txs, block, opts) {
|
|
@@ -283,6 +367,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
283
367
|
mined: blockId
|
|
284
368
|
}, opts);
|
|
285
369
|
}
|
|
370
|
+
await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
|
|
286
371
|
}
|
|
287
372
|
});
|
|
288
373
|
}
|
|
@@ -302,44 +387,50 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
302
387
|
found.push(meta);
|
|
303
388
|
}
|
|
304
389
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
390
|
+
await this.#store.transactionAsync(async ()=>{
|
|
391
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
392
|
+
for (const meta of found){
|
|
393
|
+
this.#indices.markAsMined(meta, blockId);
|
|
394
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
395
|
+
}
|
|
396
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
397
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
398
|
+
});
|
|
311
399
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
312
400
|
}
|
|
313
401
|
async prepareForSlot(slotNumber) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
402
|
+
await this.#store.transactionAsync(async ()=>{
|
|
403
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
404
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
405
|
+
// Step 1: Find expired protected txs
|
|
406
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
407
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
408
|
+
this.#indices.clearProtection(expiredProtected);
|
|
409
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
410
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
411
|
+
if (txsToRestore.length === 0) {
|
|
412
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
416
|
+
// Step 4: Validate for pending pool
|
|
417
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
418
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
419
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
420
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
421
|
+
await this.#deleteTxsBatch(invalid);
|
|
422
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
423
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
424
|
+
if (added.length > 0) {
|
|
425
|
+
const feePayers = added.map((meta)=>meta.feePayer);
|
|
426
|
+
const uniqueFeePayers = new Set(feePayers);
|
|
427
|
+
await this.#evictionManager.evictAfterNewTxs(added.map((m)=>m.txHash), [
|
|
428
|
+
...uniqueFeePayers
|
|
429
|
+
]);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
341
432
|
}
|
|
342
|
-
async handlePrunedBlocks(latestBlock) {
|
|
433
|
+
async handlePrunedBlocks(latestBlock, options) {
|
|
343
434
|
// Step 1: Find transactions mined after the prune point
|
|
344
435
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
345
436
|
if (txsToUnmine.length === 0) {
|
|
@@ -347,54 +438,81 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
347
438
|
return;
|
|
348
439
|
}
|
|
349
440
|
this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
441
|
+
await this.#store.transactionAsync(async ()=>{
|
|
442
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
443
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
444
|
+
// when their original mined block is finalized
|
|
445
|
+
await this.#deletedPool.markFromPrunedBlock(txsToUnmine.map((m)=>({
|
|
446
|
+
txHash: m.txHash,
|
|
447
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId.number)
|
|
448
|
+
})));
|
|
449
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
450
|
+
for (const meta of txsToUnmine){
|
|
451
|
+
this.#indices.markAsUnmined(meta);
|
|
452
|
+
}
|
|
453
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
454
|
+
if (options?.deleteAllTxs) {
|
|
455
|
+
const allTxHashes = txsToUnmine.map((m)=>m.txHash);
|
|
456
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
457
|
+
this.#log.info(`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`);
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
461
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
462
|
+
// Step 5: Validate for pending pool
|
|
463
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
464
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
465
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
466
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
467
|
+
await this.#deleteTxsBatch(invalid);
|
|
468
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
469
|
+
this.#log.info(`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`, {
|
|
470
|
+
txHashesRestored: valid.map((m)=>m.txHash),
|
|
471
|
+
txHashesInvalid: invalid,
|
|
472
|
+
txHashesEvicted: toEvict
|
|
473
|
+
});
|
|
474
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
475
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
476
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
477
|
+
});
|
|
368
478
|
}
|
|
369
479
|
async handleFailedExecution(txHashes) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
480
|
+
await this.#store.transactionAsync(async ()=>{
|
|
481
|
+
await this.#deleteTxsBatch(txHashes.map((h)=>h.toString()));
|
|
482
|
+
});
|
|
483
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, {
|
|
484
|
+
txHashes: txHashes.map((h)=>h.toString())
|
|
485
|
+
});
|
|
373
486
|
}
|
|
374
487
|
async handleFinalizedBlock(block) {
|
|
375
488
|
const blockNumber = block.globalVariables.blockNumber;
|
|
376
|
-
// Step 1: Find txs
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
489
|
+
// Step 1: Find mined txs at or before finalized block
|
|
490
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
491
|
+
await this.#store.transactionAsync(async ()=>{
|
|
492
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
493
|
+
const txsToArchive = [];
|
|
494
|
+
if (this.#archive.isEnabled()) {
|
|
495
|
+
for (const txHashStr of minedTxsToFinalize){
|
|
496
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
497
|
+
if (buffer) {
|
|
498
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
499
|
+
}
|
|
388
500
|
}
|
|
389
501
|
}
|
|
502
|
+
// Step 3: Delete mined txs from active pool
|
|
503
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
504
|
+
// Step 4: Finalize soft-deleted txs
|
|
505
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
506
|
+
// Step 5: Archive mined txs
|
|
507
|
+
if (txsToArchive.length > 0) {
|
|
508
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
if (minedTxsToFinalize.length > 0) {
|
|
512
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
513
|
+
txHashes: minedTxsToFinalize
|
|
514
|
+
});
|
|
390
515
|
}
|
|
391
|
-
// Step 3: Delete from active pool
|
|
392
|
-
await this.#deleteTxsBatch(txsToFinalize);
|
|
393
|
-
// Step 4: Archive
|
|
394
|
-
if (txsToArchive.length > 0) {
|
|
395
|
-
await this.#archive.archiveTxs(txsToArchive);
|
|
396
|
-
}
|
|
397
|
-
this.#log.info(`Finalized ${txsToFinalize.length} txs from blocks up to ${blockNumber}`);
|
|
398
516
|
}
|
|
399
517
|
// === Query Methods ===
|
|
400
518
|
async getTxByHash(txHash) {
|
|
@@ -410,20 +528,34 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
410
528
|
return results;
|
|
411
529
|
}
|
|
412
530
|
hasTxs(txHashes) {
|
|
413
|
-
return txHashes.map((h)=>
|
|
531
|
+
return txHashes.map((h)=>{
|
|
532
|
+
const hashStr = h.toString();
|
|
533
|
+
return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
|
|
534
|
+
});
|
|
414
535
|
}
|
|
415
536
|
getTxStatus(txHash) {
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
537
|
+
const txHashStr = txHash.toString();
|
|
538
|
+
const meta = this.#indices.getMetadata(txHashStr);
|
|
539
|
+
if (meta) {
|
|
540
|
+
return this.#indices.getTxState(meta);
|
|
541
|
+
}
|
|
542
|
+
// Check if soft-deleted
|
|
543
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
544
|
+
return 'deleted';
|
|
419
545
|
}
|
|
420
|
-
return
|
|
546
|
+
return undefined;
|
|
421
547
|
}
|
|
422
548
|
getPendingTxHashes() {
|
|
423
549
|
return [
|
|
424
550
|
...this.#indices.iteratePendingByPriority('desc')
|
|
425
551
|
].map((hash)=>TxHash.fromString(hash));
|
|
426
552
|
}
|
|
553
|
+
getEligiblePendingTxHashes() {
|
|
554
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
555
|
+
return [
|
|
556
|
+
...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)
|
|
557
|
+
].map((hash)=>TxHash.fromString(hash));
|
|
558
|
+
}
|
|
427
559
|
getPendingTxCount() {
|
|
428
560
|
return this.#indices.getPendingTxCount();
|
|
429
561
|
}
|
|
@@ -463,6 +595,9 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
463
595
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
464
596
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
465
597
|
}
|
|
598
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
599
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
600
|
+
}
|
|
466
601
|
// Update eviction rules with new config
|
|
467
602
|
this.#evictionManager.updateConfig(config);
|
|
468
603
|
}
|
|
@@ -477,7 +612,10 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
477
612
|
}
|
|
478
613
|
// === Metrics ===
|
|
479
614
|
countTxs() {
|
|
480
|
-
return
|
|
615
|
+
return {
|
|
616
|
+
...this.#indices.countTxs(),
|
|
617
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount()
|
|
618
|
+
};
|
|
481
619
|
}
|
|
482
620
|
// ============================================================================
|
|
483
621
|
// PRIVATE HELPERS - Transaction Management
|
|
@@ -488,7 +626,9 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
488
626
|
*/ async #addTx(tx, state, opts = {}) {
|
|
489
627
|
const txHashStr = tx.getTxHash().toString();
|
|
490
628
|
const meta = await buildTxMetaData(tx);
|
|
629
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
491
630
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
631
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
492
632
|
this.#callbacks.onTxsAdded([
|
|
493
633
|
tx
|
|
494
634
|
], opts);
|
|
@@ -501,64 +641,74 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
501
641
|
this.#indices.addMined(meta);
|
|
502
642
|
}
|
|
503
643
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
504
|
-
this.#log.
|
|
644
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
505
645
|
eventName: 'tx-added-to-pool',
|
|
506
|
-
|
|
646
|
+
txHash: txHashStr,
|
|
647
|
+
state: stateStr,
|
|
648
|
+
source: opts.source
|
|
507
649
|
});
|
|
508
650
|
return meta;
|
|
509
651
|
}
|
|
510
652
|
/**
|
|
511
653
|
* Deletes a transaction from both indices and DB.
|
|
512
654
|
* Emits onTxsRemoved callback immediately after DB delete.
|
|
655
|
+
*/ /**
|
|
656
|
+
* Deletes a transaction from the pool.
|
|
657
|
+
* Delegates to DeletedPool which decides soft vs hard delete based on whether
|
|
658
|
+
* the tx is from a pruned block.
|
|
513
659
|
*/ async #deleteTx(txHashStr) {
|
|
514
660
|
this.#indices.remove(txHashStr);
|
|
515
|
-
await this.#txsDB.delete(txHashStr);
|
|
516
661
|
this.#callbacks.onTxsRemoved([
|
|
517
662
|
txHashStr
|
|
518
663
|
]);
|
|
664
|
+
await this.#deletedPool.deleteTx(txHashStr);
|
|
519
665
|
}
|
|
520
666
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */ async #deleteTxsBatch(txHashes) {
|
|
521
667
|
for (const txHashStr of txHashes){
|
|
522
668
|
await this.#deleteTx(txHashStr);
|
|
523
669
|
}
|
|
524
670
|
}
|
|
671
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */ async #evictTxs(txHashes, reason) {
|
|
672
|
+
if (txHashes.length === 0) {
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
676
|
+
for (const txHashStr of txHashes){
|
|
677
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, {
|
|
678
|
+
txHash: txHashStr,
|
|
679
|
+
reason
|
|
680
|
+
});
|
|
681
|
+
this.#addToEvictedCache(txHashStr);
|
|
682
|
+
}
|
|
683
|
+
await this.#deleteTxsBatch(txHashes);
|
|
684
|
+
}
|
|
685
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */ #addToEvictedCache(txHashStr) {
|
|
686
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
687
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
688
|
+
const oldest = this.#evictedTxHashes.values().next().value;
|
|
689
|
+
this.#evictedTxHashes.delete(oldest);
|
|
690
|
+
}
|
|
691
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
692
|
+
}
|
|
525
693
|
// ============================================================================
|
|
526
694
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
527
695
|
// ============================================================================
|
|
528
|
-
/** Validates
|
|
529
|
-
const
|
|
696
|
+
/** Validates transaction metadata, returning true if valid */ async #validateMeta(meta, validator, context) {
|
|
697
|
+
const txValidator = validator ?? await this.#createTxValidator();
|
|
698
|
+
const result = await txValidator.validateTx(meta);
|
|
530
699
|
if (result.result !== 'valid') {
|
|
531
700
|
const contextStr = context ? ` ${context}` : '';
|
|
532
|
-
this.#log.info(`Tx ${
|
|
701
|
+
this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
|
|
533
702
|
return false;
|
|
534
703
|
}
|
|
535
704
|
return true;
|
|
536
705
|
}
|
|
537
|
-
/**
|
|
538
|
-
const loaded = [];
|
|
539
|
-
const missing = [];
|
|
540
|
-
for (const meta of metas){
|
|
541
|
-
const buffer = await this.#txsDB.getAsync(meta.txHash);
|
|
542
|
-
if (!buffer) {
|
|
543
|
-
this.#log.warn(`Tx ${meta.txHash} not found in DB`);
|
|
544
|
-
missing.push(meta.txHash);
|
|
545
|
-
continue;
|
|
546
|
-
}
|
|
547
|
-
loaded.push({
|
|
548
|
-
tx: Tx.fromBuffer(buffer),
|
|
549
|
-
meta
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
return {
|
|
553
|
-
loaded,
|
|
554
|
-
missing
|
|
555
|
-
};
|
|
556
|
-
}
|
|
557
|
-
/** Validates a batch of transactions, returning valid and invalid groups */ async #validateTxBatch(txs, context) {
|
|
706
|
+
/** Validates metadata directly */ async #revalidateMetadata(metas, context) {
|
|
558
707
|
const valid = [];
|
|
559
708
|
const invalid = [];
|
|
560
|
-
|
|
561
|
-
|
|
709
|
+
const validator = await this.#createTxValidator();
|
|
710
|
+
for (const meta of metas){
|
|
711
|
+
if (await this.#validateMeta(meta, validator, context)) {
|
|
562
712
|
valid.push(meta);
|
|
563
713
|
} else {
|
|
564
714
|
invalid.push(meta.txHash);
|
|
@@ -569,17 +719,6 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
569
719
|
invalid
|
|
570
720
|
};
|
|
571
721
|
}
|
|
572
|
-
/** Loads transactions from DB and validates them */ async #loadAndValidateTxs(metas, context) {
|
|
573
|
-
const { loaded, missing } = await this.#loadTxsFromDb(metas);
|
|
574
|
-
const { valid, invalid } = await this.#validateTxBatch(loaded, context);
|
|
575
|
-
return {
|
|
576
|
-
valid,
|
|
577
|
-
invalid: [
|
|
578
|
-
...missing,
|
|
579
|
-
...invalid
|
|
580
|
-
]
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
722
|
/**
|
|
584
723
|
* Resolves nullifier conflicts between incoming txs and existing pending txs.
|
|
585
724
|
* Modifies the pending indices during iteration to maintain consistent state
|
|
@@ -635,6 +774,10 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
635
774
|
const loaded = [];
|
|
636
775
|
const errors = [];
|
|
637
776
|
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()){
|
|
777
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
778
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
638
781
|
try {
|
|
639
782
|
const tx = Tx.fromBuffer(buffer);
|
|
640
783
|
const meta = await buildTxMetaData(tx);
|
|
@@ -685,7 +828,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
685
828
|
if (preAddResult.shouldIgnore) {
|
|
686
829
|
// Transaction rejected - mark for deletion from DB
|
|
687
830
|
rejected.push(meta.txHash);
|
|
688
|
-
this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason}`);
|
|
831
|
+
this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
689
832
|
continue;
|
|
690
833
|
}
|
|
691
834
|
// Evict any conflicting txs identified by pre-add rules
|
|
@@ -721,7 +864,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
721
864
|
getFeePayerPendingTxs: (feePayer)=>this.#indices.getFeePayerPendingTxs(feePayer),
|
|
722
865
|
getPendingTxCount: ()=>this.#indices.getPendingTxCount(),
|
|
723
866
|
getLowestPriorityPending: (limit)=>this.#indices.getLowestPriorityPending(limit),
|
|
724
|
-
deleteTxs: (txHashes)=>this.#
|
|
867
|
+
deleteTxs: (txHashes, reason)=>this.#evictTxs(txHashes, reason ?? 'unknown')
|
|
725
868
|
};
|
|
726
869
|
}
|
|
727
870
|
#createPreAddPoolAccess() {
|