@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,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,19 @@ 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
|
|
|
167
190
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
191
|
+
const preAddContext: PreAddContext | undefined =
|
|
192
|
+
opts.feeComparisonOnly !== undefined ? { feeComparisonOnly: opts.feeComparisonOnly } : undefined;
|
|
168
193
|
|
|
169
194
|
await this.#store.transactionAsync(async () => {
|
|
170
195
|
for (const tx of txs) {
|
|
@@ -191,7 +216,15 @@ export class TxPoolV2Impl {
|
|
|
191
216
|
accepted.push(txHash);
|
|
192
217
|
} else {
|
|
193
218
|
// Regular pending tx - validate and run pre-add rules
|
|
194
|
-
const result = await this.#tryAddRegularPendingTx(
|
|
219
|
+
const result = await this.#tryAddRegularPendingTx(
|
|
220
|
+
tx,
|
|
221
|
+
opts,
|
|
222
|
+
poolAccess,
|
|
223
|
+
acceptedPending,
|
|
224
|
+
ignored,
|
|
225
|
+
errors,
|
|
226
|
+
preAddContext,
|
|
227
|
+
);
|
|
195
228
|
if (result.status === 'accepted') {
|
|
196
229
|
acceptedPending.add(txHashStr);
|
|
197
230
|
} else if (result.status === 'rejected') {
|
|
@@ -201,6 +234,13 @@ export class TxPoolV2Impl {
|
|
|
201
234
|
}
|
|
202
235
|
}
|
|
203
236
|
}
|
|
237
|
+
|
|
238
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
239
|
+
if (acceptedPending.size > 0) {
|
|
240
|
+
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
241
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
242
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
243
|
+
}
|
|
204
244
|
});
|
|
205
245
|
|
|
206
246
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
@@ -208,14 +248,15 @@ export class TxPoolV2Impl {
|
|
|
208
248
|
accepted.push(TxHash.fromString(txHashStr));
|
|
209
249
|
}
|
|
210
250
|
|
|
211
|
-
//
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
251
|
+
// Record metrics
|
|
252
|
+
if (ignored.length > 0) {
|
|
253
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
254
|
+
}
|
|
255
|
+
if (rejected.length > 0) {
|
|
256
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
216
257
|
}
|
|
217
258
|
|
|
218
|
-
return { accepted, ignored, rejected };
|
|
259
|
+
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
219
260
|
}
|
|
220
261
|
|
|
221
262
|
/** Validates and adds a regular pending tx. Returns status. */
|
|
@@ -225,41 +266,68 @@ export class TxPoolV2Impl {
|
|
|
225
266
|
poolAccess: PreAddPoolAccess,
|
|
226
267
|
acceptedPending: Set<string>,
|
|
227
268
|
ignored: TxHash[],
|
|
269
|
+
errors: Map<string, TxPoolRejectionError>,
|
|
270
|
+
preAddContext?: PreAddContext,
|
|
228
271
|
): Promise<{ status: 'accepted' | 'ignored' | 'rejected' }> {
|
|
229
272
|
const txHash = tx.getTxHash();
|
|
230
273
|
const txHashStr = txHash.toString();
|
|
231
274
|
|
|
232
|
-
//
|
|
233
|
-
|
|
275
|
+
// Build metadata and validate using metadata
|
|
276
|
+
const meta = await buildTxMetaData(tx);
|
|
277
|
+
if (!(await this.#validateMeta(meta))) {
|
|
234
278
|
return { status: 'rejected' };
|
|
235
279
|
}
|
|
236
280
|
|
|
237
|
-
//
|
|
238
|
-
const
|
|
239
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
281
|
+
// Run pre-add rules
|
|
282
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess, preAddContext);
|
|
240
283
|
|
|
241
284
|
if (preAddResult.shouldIgnore) {
|
|
242
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
285
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
286
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
287
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
288
|
+
}
|
|
243
289
|
return { status: 'ignored' };
|
|
244
290
|
}
|
|
245
291
|
|
|
246
|
-
// Evict conflicts
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
292
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
293
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
294
|
+
const byReason = new Map<string, string[]>();
|
|
295
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions) {
|
|
296
|
+
const group = byReason.get(reason);
|
|
297
|
+
if (group) {
|
|
298
|
+
group.push(evictHash);
|
|
299
|
+
} else {
|
|
300
|
+
byReason.set(reason, [evictHash]);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
for (const [reason, hashes] of byReason) {
|
|
304
|
+
await this.#evictTxs(hashes, reason);
|
|
305
|
+
}
|
|
306
|
+
for (const evictHashStr of preAddResult.txHashesToEvict) {
|
|
307
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
308
|
+
evictedTxHash: evictHashStr,
|
|
309
|
+
replacementTxHash: txHashStr,
|
|
310
|
+
});
|
|
311
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
312
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
313
|
+
acceptedPending.delete(evictHashStr);
|
|
314
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
315
|
+
}
|
|
254
316
|
}
|
|
255
317
|
}
|
|
256
318
|
|
|
319
|
+
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
320
|
+
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
321
|
+
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
322
|
+
return { status: 'accepted' };
|
|
323
|
+
}
|
|
324
|
+
|
|
257
325
|
// Add the transaction
|
|
258
326
|
await this.#addTx(tx, 'pending', opts);
|
|
259
327
|
return { status: 'accepted' };
|
|
260
328
|
}
|
|
261
329
|
|
|
262
|
-
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'
|
|
330
|
+
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
|
|
263
331
|
const txHashStr = tx.getTxHash().toString();
|
|
264
332
|
|
|
265
333
|
// Check if already in pool
|
|
@@ -267,13 +335,7 @@ export class TxPoolV2Impl {
|
|
|
267
335
|
return 'ignored';
|
|
268
336
|
}
|
|
269
337
|
|
|
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
|
|
338
|
+
// Build metadata and check pre-add rules
|
|
277
339
|
const meta = await buildTxMetaData(tx);
|
|
278
340
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
279
341
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
@@ -311,22 +373,57 @@ export class TxPoolV2Impl {
|
|
|
311
373
|
});
|
|
312
374
|
}
|
|
313
375
|
|
|
314
|
-
protectTxs(txHashes: TxHash[], block: BlockHeader): TxHash[] {
|
|
376
|
+
async protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
|
|
315
377
|
const slotNumber = block.globalVariables.slotNumber;
|
|
316
378
|
const missing: TxHash[] = [];
|
|
379
|
+
let softDeletedHits = 0;
|
|
380
|
+
let missingPreviouslyEvicted = 0;
|
|
317
381
|
|
|
318
|
-
|
|
319
|
-
const
|
|
382
|
+
await this.#store.transactionAsync(async () => {
|
|
383
|
+
for (const txHash of txHashes) {
|
|
384
|
+
const txHashStr = txHash.toString();
|
|
320
385
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
386
|
+
if (this.#indices.has(txHashStr)) {
|
|
387
|
+
// Update protection for existing tx
|
|
388
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
389
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
390
|
+
// Resurrect soft-deleted tx as protected
|
|
391
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
392
|
+
if (buffer) {
|
|
393
|
+
const tx = Tx.fromBuffer(buffer);
|
|
394
|
+
await this.#addTx(tx, { protected: slotNumber });
|
|
395
|
+
softDeletedHits++;
|
|
396
|
+
} else {
|
|
397
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
398
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
399
|
+
missing.push(txHash);
|
|
400
|
+
}
|
|
401
|
+
} else {
|
|
402
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
403
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
404
|
+
missing.push(txHash);
|
|
405
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
406
|
+
missingPreviouslyEvicted++;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
328
409
|
}
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// Record metrics
|
|
413
|
+
if (softDeletedHits > 0) {
|
|
414
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
415
|
+
}
|
|
416
|
+
if (missing.length > 0) {
|
|
417
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map(h => h.toString()).join(', ')}`);
|
|
418
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
329
419
|
}
|
|
420
|
+
if (missingPreviouslyEvicted > 0) {
|
|
421
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
this.#log.info(
|
|
425
|
+
`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`,
|
|
426
|
+
);
|
|
330
427
|
|
|
331
428
|
return missing;
|
|
332
429
|
}
|
|
@@ -347,6 +444,7 @@ export class TxPoolV2Impl {
|
|
|
347
444
|
// Add new mined tx (callback emitted by #addTx)
|
|
348
445
|
await this.#addTx(tx, { mined: blockId }, opts);
|
|
349
446
|
}
|
|
447
|
+
await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
|
|
350
448
|
}
|
|
351
449
|
});
|
|
352
450
|
}
|
|
@@ -370,53 +468,63 @@ export class TxPoolV2Impl {
|
|
|
370
468
|
}
|
|
371
469
|
}
|
|
372
470
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
471
|
+
await this.#store.transactionAsync(async () => {
|
|
472
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
473
|
+
for (const meta of found) {
|
|
474
|
+
this.#indices.markAsMined(meta, blockId);
|
|
475
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
476
|
+
}
|
|
377
477
|
|
|
378
|
-
|
|
379
|
-
|
|
478
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
479
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
480
|
+
});
|
|
380
481
|
|
|
381
482
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
382
483
|
}
|
|
383
484
|
|
|
384
485
|
async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
|
|
385
|
-
|
|
386
|
-
|
|
486
|
+
await this.#store.transactionAsync(async () => {
|
|
487
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
488
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
387
489
|
|
|
388
|
-
|
|
389
|
-
|
|
490
|
+
// Step 1: Find expired protected txs
|
|
491
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
390
492
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
if (txsToRestore.length === 0) {
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
493
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
494
|
+
this.#indices.clearProtection(expiredProtected);
|
|
396
495
|
|
|
397
|
-
|
|
496
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
497
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
498
|
+
if (txsToRestore.length === 0) {
|
|
499
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
398
502
|
|
|
399
|
-
|
|
400
|
-
const { valid, invalid } = await this.#loadAndValidateTxs(txsToRestore, 'during prepareForSlot');
|
|
503
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
401
504
|
|
|
402
|
-
|
|
403
|
-
|
|
505
|
+
// Step 4: Validate for pending pool
|
|
506
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
404
507
|
|
|
405
|
-
|
|
406
|
-
|
|
508
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
509
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
407
510
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
511
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
512
|
+
await this.#deleteTxsBatch(invalid);
|
|
513
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
514
|
+
|
|
515
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
516
|
+
if (added.length > 0) {
|
|
517
|
+
const feePayers = added.map(meta => meta.feePayer);
|
|
518
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
519
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
520
|
+
added.map(m => m.txHash),
|
|
521
|
+
[...uniqueFeePayers],
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
});
|
|
417
525
|
}
|
|
418
526
|
|
|
419
|
-
async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
|
|
527
|
+
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
420
528
|
// Step 1: Find transactions mined after the prune point
|
|
421
529
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
422
530
|
if (txsToUnmine.length === 0) {
|
|
@@ -426,64 +534,99 @@ export class TxPoolV2Impl {
|
|
|
426
534
|
|
|
427
535
|
this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
|
|
428
536
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
537
|
+
await this.#store.transactionAsync(async () => {
|
|
538
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
539
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
540
|
+
// when their original mined block is finalized
|
|
541
|
+
await this.#deletedPool.markFromPrunedBlock(
|
|
542
|
+
txsToUnmine.map(m => ({
|
|
543
|
+
txHash: m.txHash,
|
|
544
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
|
|
545
|
+
})),
|
|
546
|
+
);
|
|
547
|
+
|
|
548
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
549
|
+
for (const meta of txsToUnmine) {
|
|
550
|
+
this.#indices.markAsUnmined(meta);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
554
|
+
if (options?.deleteAllTxs) {
|
|
555
|
+
const allTxHashes = txsToUnmine.map(m => m.txHash);
|
|
556
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
557
|
+
this.#log.info(
|
|
558
|
+
`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
|
|
559
|
+
);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
433
562
|
|
|
434
|
-
|
|
435
|
-
|
|
563
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
564
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
436
565
|
|
|
437
|
-
|
|
438
|
-
|
|
566
|
+
// Step 5: Validate for pending pool
|
|
567
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
439
568
|
|
|
440
|
-
|
|
441
|
-
|
|
569
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
570
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
442
571
|
|
|
443
|
-
|
|
444
|
-
|
|
572
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
573
|
+
await this.#deleteTxsBatch(invalid);
|
|
574
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
445
575
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
576
|
+
this.#log.info(
|
|
577
|
+
`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
|
|
578
|
+
{ txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
|
|
579
|
+
);
|
|
580
|
+
|
|
581
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
582
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
583
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
584
|
+
});
|
|
449
585
|
}
|
|
450
586
|
|
|
451
587
|
async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
|
|
452
|
-
|
|
453
|
-
|
|
588
|
+
await this.#store.transactionAsync(async () => {
|
|
589
|
+
await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
|
|
590
|
+
});
|
|
454
591
|
|
|
455
|
-
this.#log.info(`Deleted ${txHashes.length} failed txs
|
|
592
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
|
|
456
593
|
}
|
|
457
594
|
|
|
458
595
|
async handleFinalizedBlock(block: BlockHeader): Promise<void> {
|
|
459
596
|
const blockNumber = block.globalVariables.blockNumber;
|
|
460
597
|
|
|
461
|
-
// Step 1: Find txs
|
|
462
|
-
const
|
|
463
|
-
if (txsToFinalize.length === 0) {
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
598
|
+
// Step 1: Find mined txs at or before finalized block
|
|
599
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
466
600
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
601
|
+
await this.#store.transactionAsync(async () => {
|
|
602
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
603
|
+
const txsToArchive: Tx[] = [];
|
|
604
|
+
if (this.#archive.isEnabled()) {
|
|
605
|
+
for (const txHashStr of minedTxsToFinalize) {
|
|
606
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
607
|
+
if (buffer) {
|
|
608
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
609
|
+
}
|
|
474
610
|
}
|
|
475
611
|
}
|
|
476
|
-
}
|
|
477
612
|
|
|
478
|
-
|
|
479
|
-
|
|
613
|
+
// Step 3: Delete mined txs from active pool
|
|
614
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
480
615
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
await this.#archive.archiveTxs(txsToArchive);
|
|
484
|
-
}
|
|
616
|
+
// Step 4: Finalize soft-deleted txs
|
|
617
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
485
618
|
|
|
486
|
-
|
|
619
|
+
// Step 5: Archive mined txs
|
|
620
|
+
if (txsToArchive.length > 0) {
|
|
621
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
if (minedTxsToFinalize.length > 0) {
|
|
626
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
627
|
+
txHashes: minedTxsToFinalize,
|
|
628
|
+
});
|
|
629
|
+
}
|
|
487
630
|
}
|
|
488
631
|
|
|
489
632
|
// === Query Methods ===
|
|
@@ -503,21 +646,36 @@ export class TxPoolV2Impl {
|
|
|
503
646
|
}
|
|
504
647
|
|
|
505
648
|
hasTxs(txHashes: TxHash[]): boolean[] {
|
|
506
|
-
return txHashes.map(h =>
|
|
649
|
+
return txHashes.map(h => {
|
|
650
|
+
const hashStr = h.toString();
|
|
651
|
+
return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
|
|
652
|
+
});
|
|
507
653
|
}
|
|
508
654
|
|
|
509
655
|
getTxStatus(txHash: TxHash): TxState | undefined {
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
656
|
+
const txHashStr = txHash.toString();
|
|
657
|
+
const meta = this.#indices.getMetadata(txHashStr);
|
|
658
|
+
if (meta) {
|
|
659
|
+
return this.#indices.getTxState(meta);
|
|
660
|
+
}
|
|
661
|
+
// Check if soft-deleted
|
|
662
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
663
|
+
return 'deleted';
|
|
513
664
|
}
|
|
514
|
-
return
|
|
665
|
+
return undefined;
|
|
515
666
|
}
|
|
516
667
|
|
|
517
668
|
getPendingTxHashes(): TxHash[] {
|
|
518
669
|
return [...this.#indices.iteratePendingByPriority('desc')].map(hash => TxHash.fromString(hash));
|
|
519
670
|
}
|
|
520
671
|
|
|
672
|
+
getEligiblePendingTxHashes(): TxHash[] {
|
|
673
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
674
|
+
return [...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)].map(hash =>
|
|
675
|
+
TxHash.fromString(hash),
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
|
|
521
679
|
getPendingTxCount(): number {
|
|
522
680
|
return this.#indices.getPendingTxCount();
|
|
523
681
|
}
|
|
@@ -562,6 +720,9 @@ export class TxPoolV2Impl {
|
|
|
562
720
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
563
721
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
564
722
|
}
|
|
723
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
724
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
725
|
+
}
|
|
565
726
|
// Update eviction rules with new config
|
|
566
727
|
this.#evictionManager.updateConfig(config);
|
|
567
728
|
}
|
|
@@ -579,8 +740,17 @@ export class TxPoolV2Impl {
|
|
|
579
740
|
|
|
580
741
|
// === Metrics ===
|
|
581
742
|
|
|
582
|
-
countTxs(): {
|
|
583
|
-
|
|
743
|
+
countTxs(): {
|
|
744
|
+
pending: number;
|
|
745
|
+
protected: number;
|
|
746
|
+
mined: number;
|
|
747
|
+
softDeleted: number;
|
|
748
|
+
totalMetadataBytes: number;
|
|
749
|
+
} {
|
|
750
|
+
return {
|
|
751
|
+
...this.#indices.countTxs(),
|
|
752
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount(),
|
|
753
|
+
};
|
|
584
754
|
}
|
|
585
755
|
|
|
586
756
|
// ============================================================================
|
|
@@ -598,8 +768,10 @@ export class TxPoolV2Impl {
|
|
|
598
768
|
): Promise<TxMetaData> {
|
|
599
769
|
const txHashStr = tx.getTxHash().toString();
|
|
600
770
|
const meta = await buildTxMetaData(tx);
|
|
771
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
601
772
|
|
|
602
773
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
774
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
603
775
|
this.#callbacks.onTxsAdded([tx], opts);
|
|
604
776
|
|
|
605
777
|
if (state === 'pending') {
|
|
@@ -612,9 +784,11 @@ export class TxPoolV2Impl {
|
|
|
612
784
|
}
|
|
613
785
|
|
|
614
786
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
615
|
-
this.#log.
|
|
787
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
616
788
|
eventName: 'tx-added-to-pool',
|
|
789
|
+
txHash: txHashStr,
|
|
617
790
|
state: stateStr,
|
|
791
|
+
source: opts.source,
|
|
618
792
|
});
|
|
619
793
|
|
|
620
794
|
return meta;
|
|
@@ -624,10 +798,15 @@ export class TxPoolV2Impl {
|
|
|
624
798
|
* Deletes a transaction from both indices and DB.
|
|
625
799
|
* Emits onTxsRemoved callback immediately after DB delete.
|
|
626
800
|
*/
|
|
801
|
+
/**
|
|
802
|
+
* Deletes a transaction from the pool.
|
|
803
|
+
* Delegates to DeletedPool which decides soft vs hard delete based on whether
|
|
804
|
+
* the tx is from a pruned block.
|
|
805
|
+
*/
|
|
627
806
|
async #deleteTx(txHashStr: string): Promise<void> {
|
|
628
807
|
this.#indices.remove(txHashStr);
|
|
629
|
-
await this.#txsDB.delete(txHashStr);
|
|
630
808
|
this.#callbacks.onTxsRemoved([txHashStr]);
|
|
809
|
+
await this.#deletedPool.deleteTx(txHashStr);
|
|
631
810
|
}
|
|
632
811
|
|
|
633
812
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */
|
|
@@ -637,68 +816,63 @@ export class TxPoolV2Impl {
|
|
|
637
816
|
}
|
|
638
817
|
}
|
|
639
818
|
|
|
819
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */
|
|
820
|
+
async #evictTxs(txHashes: string[], reason: string): Promise<void> {
|
|
821
|
+
if (txHashes.length === 0) {
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
825
|
+
for (const txHashStr of txHashes) {
|
|
826
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
827
|
+
this.#addToEvictedCache(txHashStr);
|
|
828
|
+
}
|
|
829
|
+
await this.#deleteTxsBatch(txHashes);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
|
|
833
|
+
#addToEvictedCache(txHashStr: string): void {
|
|
834
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
835
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
836
|
+
const oldest = this.#evictedTxHashes.values().next().value!;
|
|
837
|
+
this.#evictedTxHashes.delete(oldest);
|
|
838
|
+
}
|
|
839
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
840
|
+
}
|
|
841
|
+
|
|
640
842
|
// ============================================================================
|
|
641
843
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
642
844
|
// ============================================================================
|
|
643
845
|
|
|
644
|
-
/** Validates
|
|
645
|
-
async #
|
|
646
|
-
const
|
|
846
|
+
/** Validates transaction metadata, returning true if valid */
|
|
847
|
+
async #validateMeta(meta: TxMetaData, validator?: TxValidator<TxMetaData>, context?: string): Promise<boolean> {
|
|
848
|
+
const txValidator = validator ?? (await this.#createTxValidator());
|
|
849
|
+
const result = await txValidator.validateTx(meta);
|
|
647
850
|
if (result.result !== 'valid') {
|
|
648
851
|
const contextStr = context ? ` ${context}` : '';
|
|
649
|
-
this.#log.info(`Tx ${
|
|
852
|
+
this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
|
|
650
853
|
return false;
|
|
651
854
|
}
|
|
652
855
|
return true;
|
|
653
856
|
}
|
|
654
857
|
|
|
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 }[],
|
|
858
|
+
/** Validates metadata directly */
|
|
859
|
+
async #revalidateMetadata(
|
|
860
|
+
metas: TxMetaData[],
|
|
676
861
|
context?: string,
|
|
677
862
|
): Promise<{ valid: TxMetaData[]; invalid: string[] }> {
|
|
678
863
|
const valid: TxMetaData[] = [];
|
|
679
864
|
const invalid: string[] = [];
|
|
680
|
-
|
|
681
|
-
for (const
|
|
682
|
-
if (await this.#
|
|
865
|
+
const validator = await this.#createTxValidator();
|
|
866
|
+
for (const meta of metas) {
|
|
867
|
+
if (await this.#validateMeta(meta, validator, context)) {
|
|
683
868
|
valid.push(meta);
|
|
684
869
|
} else {
|
|
685
870
|
invalid.push(meta.txHash);
|
|
686
871
|
}
|
|
687
872
|
}
|
|
688
|
-
|
|
689
873
|
return { valid, invalid };
|
|
690
874
|
}
|
|
691
875
|
|
|
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
876
|
/**
|
|
703
877
|
* Resolves nullifier conflicts between incoming txs and existing pending txs.
|
|
704
878
|
* Modifies the pending indices during iteration to maintain consistent state
|
|
@@ -768,6 +942,11 @@ export class TxPoolV2Impl {
|
|
|
768
942
|
const errors: string[] = [];
|
|
769
943
|
|
|
770
944
|
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
945
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
946
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
|
|
771
950
|
try {
|
|
772
951
|
const tx = Tx.fromBuffer(buffer);
|
|
773
952
|
const meta = await buildTxMetaData(tx);
|
|
@@ -815,7 +994,9 @@ export class TxPoolV2Impl {
|
|
|
815
994
|
if (preAddResult.shouldIgnore) {
|
|
816
995
|
// Transaction rejected - mark for deletion from DB
|
|
817
996
|
rejected.push(meta.txHash);
|
|
818
|
-
this.#log.debug(
|
|
997
|
+
this.#log.debug(
|
|
998
|
+
`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`,
|
|
999
|
+
);
|
|
819
1000
|
continue;
|
|
820
1001
|
}
|
|
821
1002
|
|
|
@@ -851,7 +1032,7 @@ export class TxPoolV2Impl {
|
|
|
851
1032
|
getFeePayerPendingTxs: (feePayer: string) => this.#indices.getFeePayerPendingTxs(feePayer),
|
|
852
1033
|
getPendingTxCount: () => this.#indices.getPendingTxCount(),
|
|
853
1034
|
getLowestPriorityPending: (limit: number) => this.#indices.getLowestPriorityPending(limit),
|
|
854
|
-
deleteTxs: (txHashes: string[]) => this.#
|
|
1035
|
+
deleteTxs: (txHashes: string[], reason?: string) => this.#evictTxs(txHashes, reason ?? 'unknown'),
|
|
855
1036
|
};
|
|
856
1037
|
}
|
|
857
1038
|
|