@aztec/p2p 0.0.1-commit.f2ce05ee → 0.0.1-commit.f81dbcf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/client/factory.d.ts +8 -8
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +42 -13
- package/dest/client/interface.d.ts +39 -33
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +37 -50
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +144 -223
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
- package/dest/config.d.ts +47 -11
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +94 -31
- package/dest/errors/tx-pool.error.d.ts +8 -0
- package/dest/errors/tx-pool.error.d.ts.map +1 -0
- package/dest/errors/tx-pool.error.js +9 -0
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +21 -12
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +67 -37
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +53 -53
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -2
- package/dest/mem_pools/index.d.ts +2 -1
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/interface.d.ts +3 -3
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
- package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +4 -4
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +5 -2
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +12 -4
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +7 -5
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +14 -6
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +16 -4
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +3 -3
- package/dest/mem_pools/tx_pool_v2/index.d.ts +3 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +2 -1
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +22 -8
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +68 -11
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +132 -17
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +36 -14
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -4
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +11 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +13 -5
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +336 -185
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +4 -4
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +16 -3
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +13 -3
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +4 -4
- package/dest/msg_validators/tx_validator/factory.d.ts +125 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +233 -59
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +67 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +104 -37
- package/dest/msg_validators/tx_validator/index.d.ts +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +44 -23
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +20 -4
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
- package/dest/services/dummy_service.d.ts +9 -5
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +7 -4
- package/dest/services/encoding.d.ts +3 -3
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +11 -10
- package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +32 -10
- package/dest/services/libp2p/libp2p_service.d.ts +25 -14
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +158 -123
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +5 -9
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- package/dest/services/reqresp/interface.d.ts +10 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +15 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +3 -3
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +7 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +15 -0
- package/dest/services/reqresp/protocols/tx.d.ts +7 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +20 -0
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +11 -4
- package/dest/services/service.d.ts +22 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +19 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +46 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +3 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +56 -36
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_source.js +90 -0
- package/dest/services/tx_collection/index.d.ts +2 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -0
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +2 -1
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
- package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +60 -26
- package/dest/services/tx_collection/tx_collection.d.ts +23 -10
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +75 -3
- package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +26 -29
- package/dest/services/tx_collection/tx_source.d.ts +8 -3
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +19 -2
- package/dest/services/tx_file_store/config.d.ts +1 -3
- package/dest/services/tx_file_store/config.d.ts.map +1 -1
- package/dest/services/tx_file_store/config.js +0 -4
- package/dest/services/tx_file_store/tx_file_store.d.ts +4 -3
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
- package/dest/services/tx_file_store/tx_file_store.js +9 -6
- package/dest/services/tx_provider.d.ts +4 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +9 -8
- package/dest/test-helpers/make-test-p2p-clients.d.ts +7 -8
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +1 -2
- package/dest/test-helpers/mock-pubsub.d.ts +30 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +105 -4
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -2
- package/dest/test-helpers/testbench-utils.d.ts +35 -24
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +95 -36
- package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +16 -15
- package/dest/testbench/worker_client_manager.d.ts +3 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +4 -1
- package/dest/util.d.ts +2 -2
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +77 -23
- package/src/client/interface.ts +43 -33
- package/src/client/p2p_client.ts +165 -265
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -10
- package/src/config.ts +139 -33
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +95 -44
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +57 -53
- package/src/mem_pools/attestation_pool/index.ts +3 -3
- package/src/mem_pools/attestation_pool/mocks.ts +2 -1
- package/src/mem_pools/index.ts +3 -0
- package/src/mem_pools/interface.ts +2 -2
- package/src/mem_pools/tx_pool/README.md +1 -1
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
- package/src/mem_pools/tx_pool/priority.ts +4 -4
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
- package/src/mem_pools/tx_pool_v2/README.md +85 -11
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +5 -2
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +18 -4
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +14 -9
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +33 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +4 -3
- package/src/mem_pools/tx_pool_v2/index.ts +2 -1
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +23 -8
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +189 -23
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -16
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +18 -7
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +379 -182
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
- package/src/msg_validators/tx_validator/README.md +115 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +5 -5
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
- package/src/msg_validators/tx_validator/factory.ts +373 -77
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +123 -27
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +51 -26
- package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
- package/src/services/dummy_service.ts +12 -6
- package/src/services/encoding.ts +9 -9
- package/src/services/gossipsub/README.md +29 -14
- package/src/services/gossipsub/topic_score_params.ts +49 -13
- package/src/services/libp2p/libp2p_service.ts +170 -132
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +6 -6
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/reqresp/interface.ts +26 -1
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +2 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +17 -0
- package/src/services/reqresp/protocols/tx.ts +22 -0
- package/src/services/reqresp/reqresp.ts +13 -3
- package/src/services/service.ts +31 -2
- package/src/services/tx_collection/config.ts +68 -0
- package/src/services/tx_collection/fast_tx_collection.ts +65 -32
- package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
- package/src/services/tx_collection/file_store_tx_source.ts +117 -0
- package/src/services/tx_collection/index.ts +1 -0
- package/src/services/tx_collection/instrumentation.ts +7 -1
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
- package/src/services/tx_collection/slow_tx_collection.ts +66 -33
- package/src/services/tx_collection/tx_collection.ts +113 -16
- package/src/services/tx_collection/tx_collection_sink.ts +30 -34
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_file_store/config.ts +0 -6
- package/src/services/tx_file_store/tx_file_store.ts +10 -8
- package/src/services/tx_provider.ts +10 -9
- package/src/test-helpers/make-test-p2p-clients.ts +3 -5
- package/src/test-helpers/mock-pubsub.ts +146 -9
- package/src/test-helpers/reqresp-nodes.ts +2 -5
- package/src/test-helpers/testbench-utils.ts +109 -40
- package/src/testbench/p2p_client_testbench_worker.ts +24 -20
- package/src/testbench/worker_client_manager.ts +11 -4
- package/src/util.ts +7 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
|
@@ -1,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,43 @@ 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();
|
|
131
|
+
// Phase 1: Pre-compute all throwable I/O outside the transaction.
|
|
132
|
+
// If any pre-computation throws, the entire call fails before mutations happen.
|
|
133
|
+
const precomputed = new Map();
|
|
134
|
+
const validator = await this.#createTxValidator();
|
|
135
|
+
for (const tx of txs){
|
|
136
|
+
const txHash = tx.getTxHash();
|
|
137
|
+
const txHashStr = txHash.toString();
|
|
138
|
+
const meta = await buildTxMetaData(tx);
|
|
139
|
+
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
140
|
+
// Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
|
|
141
|
+
let isValid = true;
|
|
142
|
+
if (!minedBlockId) {
|
|
143
|
+
isValid = await this.#validateMeta(meta, validator);
|
|
144
|
+
}
|
|
145
|
+
precomputed.set(txHashStr, {
|
|
146
|
+
meta,
|
|
147
|
+
minedBlockId,
|
|
148
|
+
isValid
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
// Phase 2: Apply mutations inside the transaction using only pre-computed results,
|
|
152
|
+
// in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
|
|
116
153
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
154
|
+
const preAddContext = opts.feeComparisonOnly !== undefined ? {
|
|
155
|
+
feeComparisonOnly: opts.feeComparisonOnly,
|
|
156
|
+
priceBumpPercentage: this.#config.priceBumpPercentage
|
|
157
|
+
} : undefined;
|
|
117
158
|
await this.#store.transactionAsync(async ()=>{
|
|
118
159
|
for (const tx of txs){
|
|
119
160
|
const txHash = tx.getTxHash();
|
|
@@ -123,82 +164,105 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
123
164
|
ignored.push(txHash);
|
|
124
165
|
continue;
|
|
125
166
|
}
|
|
126
|
-
|
|
127
|
-
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
167
|
+
const { meta, minedBlockId, isValid } = precomputed.get(txHashStr);
|
|
128
168
|
const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
|
|
129
169
|
if (minedBlockId) {
|
|
130
170
|
// Already mined - add directly (protection already set if pre-protected)
|
|
131
171
|
await this.#addTx(tx, {
|
|
132
172
|
mined: minedBlockId
|
|
133
|
-
}, opts);
|
|
173
|
+
}, opts, meta);
|
|
134
174
|
accepted.push(txHash);
|
|
135
175
|
} else if (preProtectedSlot !== undefined) {
|
|
136
176
|
// Pre-protected and not mined - add as protected (bypass validation)
|
|
137
177
|
await this.#addTx(tx, {
|
|
138
178
|
protected: preProtectedSlot
|
|
139
|
-
}, opts);
|
|
179
|
+
}, opts, meta);
|
|
140
180
|
accepted.push(txHash);
|
|
181
|
+
} else if (!isValid) {
|
|
182
|
+
// Failed pre-computed validation
|
|
183
|
+
rejected.push(txHash);
|
|
141
184
|
} else {
|
|
142
|
-
// Regular pending tx -
|
|
143
|
-
const result = await this.#tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored);
|
|
185
|
+
// Regular pending tx - run pre-add rules using pre-computed metadata
|
|
186
|
+
const result = await this.#tryAddRegularPendingTx(tx, meta, opts, poolAccess, acceptedPending, ignored, errors, preAddContext);
|
|
144
187
|
if (result.status === 'accepted') {
|
|
145
188
|
acceptedPending.add(txHashStr);
|
|
146
|
-
} else if (result.status === 'rejected') {
|
|
147
|
-
rejected.push(txHash);
|
|
148
189
|
} else {
|
|
149
190
|
ignored.push(txHash);
|
|
150
191
|
}
|
|
151
192
|
}
|
|
152
193
|
}
|
|
194
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
195
|
+
if (acceptedPending.size > 0) {
|
|
196
|
+
const feePayers = Array.from(acceptedPending).map((txHash)=>this.#indices.getMetadata(txHash).feePayer);
|
|
197
|
+
const uniqueFeePayers = new Set(feePayers);
|
|
198
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [
|
|
199
|
+
...uniqueFeePayers
|
|
200
|
+
]);
|
|
201
|
+
}
|
|
153
202
|
});
|
|
154
203
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
155
204
|
for (const txHashStr of acceptedPending){
|
|
156
205
|
accepted.push(TxHash.fromString(txHashStr));
|
|
157
206
|
}
|
|
158
|
-
//
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
]);
|
|
207
|
+
// Record metrics
|
|
208
|
+
if (ignored.length > 0) {
|
|
209
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
210
|
+
}
|
|
211
|
+
if (rejected.length > 0) {
|
|
212
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
165
213
|
}
|
|
166
214
|
return {
|
|
167
215
|
accepted,
|
|
168
216
|
ignored,
|
|
169
|
-
rejected
|
|
217
|
+
rejected,
|
|
218
|
+
...errors.size > 0 ? {
|
|
219
|
+
errors
|
|
220
|
+
} : {}
|
|
170
221
|
};
|
|
171
222
|
}
|
|
172
|
-
/**
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (!await this.#validateTx(tx)) {
|
|
177
|
-
return {
|
|
178
|
-
status: 'rejected'
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
// Build metadata and run pre-add rules
|
|
182
|
-
const meta = await buildTxMetaData(tx);
|
|
183
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
223
|
+
/** Adds a validated pending tx, running pre-add rules and evicting conflicts. */ async #tryAddRegularPendingTx(tx, precomputedMeta, opts, poolAccess, acceptedPending, ignored, errors, preAddContext) {
|
|
224
|
+
const txHashStr = tx.getTxHash().toString();
|
|
225
|
+
// Run pre-add rules
|
|
226
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
|
|
184
227
|
if (preAddResult.shouldIgnore) {
|
|
185
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
228
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
229
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
230
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
231
|
+
}
|
|
186
232
|
return {
|
|
187
233
|
status: 'ignored'
|
|
188
234
|
};
|
|
189
235
|
}
|
|
190
|
-
// Evict conflicts
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
236
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
237
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
238
|
+
const byReason = new Map();
|
|
239
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions){
|
|
240
|
+
const group = byReason.get(reason);
|
|
241
|
+
if (group) {
|
|
242
|
+
group.push(evictHash);
|
|
243
|
+
} else {
|
|
244
|
+
byReason.set(reason, [
|
|
245
|
+
evictHash
|
|
246
|
+
]);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
for (const [reason, hashes] of byReason){
|
|
250
|
+
await this.#evictTxs(hashes, reason);
|
|
251
|
+
}
|
|
252
|
+
for (const evictHashStr of preAddResult.txHashesToEvict){
|
|
253
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
254
|
+
evictedTxHash: evictHashStr,
|
|
255
|
+
replacementTxHash: txHashStr
|
|
256
|
+
});
|
|
257
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
258
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
259
|
+
acceptedPending.delete(evictHashStr);
|
|
260
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
261
|
+
}
|
|
198
262
|
}
|
|
199
263
|
}
|
|
200
264
|
// Add the transaction
|
|
201
|
-
await this.#addTx(tx, 'pending', opts);
|
|
265
|
+
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
202
266
|
return {
|
|
203
267
|
status: 'accepted'
|
|
204
268
|
};
|
|
@@ -209,12 +273,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
209
273
|
if (this.#indices.has(txHashStr)) {
|
|
210
274
|
return 'ignored';
|
|
211
275
|
}
|
|
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
|
|
276
|
+
// Build metadata and check pre-add rules
|
|
218
277
|
const meta = await buildTxMetaData(tx);
|
|
219
278
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
220
279
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
@@ -251,20 +310,53 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
251
310
|
}
|
|
252
311
|
});
|
|
253
312
|
}
|
|
254
|
-
protectTxs(txHashes, block) {
|
|
313
|
+
async protectTxs(txHashes, block) {
|
|
255
314
|
const slotNumber = block.globalVariables.slotNumber;
|
|
256
315
|
const missing = [];
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
316
|
+
let softDeletedHits = 0;
|
|
317
|
+
let missingPreviouslyEvicted = 0;
|
|
318
|
+
await this.#store.transactionAsync(async ()=>{
|
|
319
|
+
for (const txHash of txHashes){
|
|
320
|
+
const txHashStr = txHash.toString();
|
|
321
|
+
if (this.#indices.has(txHashStr)) {
|
|
322
|
+
// Update protection for existing tx
|
|
323
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
324
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
325
|
+
// Resurrect soft-deleted tx as protected
|
|
326
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
327
|
+
if (buffer) {
|
|
328
|
+
const tx = Tx.fromBuffer(buffer);
|
|
329
|
+
await this.#addTx(tx, {
|
|
330
|
+
protected: slotNumber
|
|
331
|
+
});
|
|
332
|
+
softDeletedHits++;
|
|
333
|
+
} else {
|
|
334
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
335
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
336
|
+
missing.push(txHash);
|
|
337
|
+
}
|
|
338
|
+
} else {
|
|
339
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
340
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
341
|
+
missing.push(txHash);
|
|
342
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
343
|
+
missingPreviouslyEvicted++;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
266
346
|
}
|
|
347
|
+
});
|
|
348
|
+
// Record metrics
|
|
349
|
+
if (softDeletedHits > 0) {
|
|
350
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
267
351
|
}
|
|
352
|
+
if (missing.length > 0) {
|
|
353
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map((h)=>h.toString()).join(', ')}`);
|
|
354
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
355
|
+
}
|
|
356
|
+
if (missingPreviouslyEvicted > 0) {
|
|
357
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
358
|
+
}
|
|
359
|
+
this.#log.info(`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`);
|
|
268
360
|
return missing;
|
|
269
361
|
}
|
|
270
362
|
async addMinedTxs(txs, block, opts) {
|
|
@@ -283,6 +375,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
283
375
|
mined: blockId
|
|
284
376
|
}, opts);
|
|
285
377
|
}
|
|
378
|
+
await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
|
|
286
379
|
}
|
|
287
380
|
});
|
|
288
381
|
}
|
|
@@ -302,44 +395,50 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
302
395
|
found.push(meta);
|
|
303
396
|
}
|
|
304
397
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
398
|
+
await this.#store.transactionAsync(async ()=>{
|
|
399
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
400
|
+
for (const meta of found){
|
|
401
|
+
this.#indices.markAsMined(meta, blockId);
|
|
402
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
403
|
+
}
|
|
404
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
405
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
406
|
+
});
|
|
311
407
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
312
408
|
}
|
|
313
409
|
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
|
-
|
|
410
|
+
await this.#store.transactionAsync(async ()=>{
|
|
411
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
412
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
413
|
+
// Step 1: Find expired protected txs
|
|
414
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
415
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
416
|
+
this.#indices.clearProtection(expiredProtected);
|
|
417
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
418
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
419
|
+
if (txsToRestore.length === 0) {
|
|
420
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
424
|
+
// Step 4: Validate for pending pool
|
|
425
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
426
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
427
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
428
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
429
|
+
await this.#deleteTxsBatch(invalid);
|
|
430
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
431
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
432
|
+
if (added.length > 0) {
|
|
433
|
+
const feePayers = added.map((meta)=>meta.feePayer);
|
|
434
|
+
const uniqueFeePayers = new Set(feePayers);
|
|
435
|
+
await this.#evictionManager.evictAfterNewTxs(added.map((m)=>m.txHash), [
|
|
436
|
+
...uniqueFeePayers
|
|
437
|
+
]);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
341
440
|
}
|
|
342
|
-
async handlePrunedBlocks(latestBlock) {
|
|
441
|
+
async handlePrunedBlocks(latestBlock, options) {
|
|
343
442
|
// Step 1: Find transactions mined after the prune point
|
|
344
443
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
345
444
|
if (txsToUnmine.length === 0) {
|
|
@@ -347,54 +446,81 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
347
446
|
return;
|
|
348
447
|
}
|
|
349
448
|
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
|
-
|
|
449
|
+
await this.#store.transactionAsync(async ()=>{
|
|
450
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
451
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
452
|
+
// when their original mined block is finalized
|
|
453
|
+
await this.#deletedPool.markFromPrunedBlock(txsToUnmine.map((m)=>({
|
|
454
|
+
txHash: m.txHash,
|
|
455
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId.number)
|
|
456
|
+
})));
|
|
457
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
458
|
+
for (const meta of txsToUnmine){
|
|
459
|
+
this.#indices.markAsUnmined(meta);
|
|
460
|
+
}
|
|
461
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
462
|
+
if (options?.deleteAllTxs) {
|
|
463
|
+
const allTxHashes = txsToUnmine.map((m)=>m.txHash);
|
|
464
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
465
|
+
this.#log.info(`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
469
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
470
|
+
// Step 5: Validate for pending pool
|
|
471
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
472
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
473
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
474
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
475
|
+
await this.#deleteTxsBatch(invalid);
|
|
476
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
477
|
+
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`, {
|
|
478
|
+
txHashesRestored: valid.map((m)=>m.txHash),
|
|
479
|
+
txHashesInvalid: invalid,
|
|
480
|
+
txHashesEvicted: toEvict
|
|
481
|
+
});
|
|
482
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
483
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
484
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
485
|
+
});
|
|
368
486
|
}
|
|
369
487
|
async handleFailedExecution(txHashes) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
488
|
+
await this.#store.transactionAsync(async ()=>{
|
|
489
|
+
await this.#deleteTxsBatch(txHashes.map((h)=>h.toString()));
|
|
490
|
+
});
|
|
491
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, {
|
|
492
|
+
txHashes: txHashes.map((h)=>h.toString())
|
|
493
|
+
});
|
|
373
494
|
}
|
|
374
495
|
async handleFinalizedBlock(block) {
|
|
375
496
|
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));
|
|
497
|
+
// Step 1: Find mined txs at or before finalized block
|
|
498
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
499
|
+
await this.#store.transactionAsync(async ()=>{
|
|
500
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
501
|
+
const txsToArchive = [];
|
|
502
|
+
if (this.#archive.isEnabled()) {
|
|
503
|
+
for (const txHashStr of minedTxsToFinalize){
|
|
504
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
505
|
+
if (buffer) {
|
|
506
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
507
|
+
}
|
|
388
508
|
}
|
|
389
509
|
}
|
|
510
|
+
// Step 3: Delete mined txs from active pool
|
|
511
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
512
|
+
// Step 4: Finalize soft-deleted txs
|
|
513
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
514
|
+
// Step 5: Archive mined txs
|
|
515
|
+
if (txsToArchive.length > 0) {
|
|
516
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
if (minedTxsToFinalize.length > 0) {
|
|
520
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
521
|
+
txHashes: minedTxsToFinalize
|
|
522
|
+
});
|
|
390
523
|
}
|
|
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
524
|
}
|
|
399
525
|
// === Query Methods ===
|
|
400
526
|
async getTxByHash(txHash) {
|
|
@@ -410,20 +536,34 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
410
536
|
return results;
|
|
411
537
|
}
|
|
412
538
|
hasTxs(txHashes) {
|
|
413
|
-
return txHashes.map((h)=>
|
|
539
|
+
return txHashes.map((h)=>{
|
|
540
|
+
const hashStr = h.toString();
|
|
541
|
+
return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
|
|
542
|
+
});
|
|
414
543
|
}
|
|
415
544
|
getTxStatus(txHash) {
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
545
|
+
const txHashStr = txHash.toString();
|
|
546
|
+
const meta = this.#indices.getMetadata(txHashStr);
|
|
547
|
+
if (meta) {
|
|
548
|
+
return this.#indices.getTxState(meta);
|
|
549
|
+
}
|
|
550
|
+
// Check if soft-deleted
|
|
551
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
552
|
+
return 'deleted';
|
|
419
553
|
}
|
|
420
|
-
return
|
|
554
|
+
return undefined;
|
|
421
555
|
}
|
|
422
556
|
getPendingTxHashes() {
|
|
423
557
|
return [
|
|
424
558
|
...this.#indices.iteratePendingByPriority('desc')
|
|
425
559
|
].map((hash)=>TxHash.fromString(hash));
|
|
426
560
|
}
|
|
561
|
+
getEligiblePendingTxHashes() {
|
|
562
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
563
|
+
return [
|
|
564
|
+
...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)
|
|
565
|
+
].map((hash)=>TxHash.fromString(hash));
|
|
566
|
+
}
|
|
427
567
|
getPendingTxCount() {
|
|
428
568
|
return this.#indices.getPendingTxCount();
|
|
429
569
|
}
|
|
@@ -463,6 +603,9 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
463
603
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
464
604
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
465
605
|
}
|
|
606
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
607
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
608
|
+
}
|
|
466
609
|
// Update eviction rules with new config
|
|
467
610
|
this.#evictionManager.updateConfig(config);
|
|
468
611
|
}
|
|
@@ -477,7 +620,10 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
477
620
|
}
|
|
478
621
|
// === Metrics ===
|
|
479
622
|
countTxs() {
|
|
480
|
-
return
|
|
623
|
+
return {
|
|
624
|
+
...this.#indices.countTxs(),
|
|
625
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount()
|
|
626
|
+
};
|
|
481
627
|
}
|
|
482
628
|
// ============================================================================
|
|
483
629
|
// PRIVATE HELPERS - Transaction Management
|
|
@@ -485,10 +631,12 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
485
631
|
/**
|
|
486
632
|
* Adds a new transaction to the pool with the specified state.
|
|
487
633
|
* Emits onTxsAdded callback immediately after DB write.
|
|
488
|
-
*/ async #addTx(tx, state, opts = {}) {
|
|
634
|
+
*/ async #addTx(tx, state, opts = {}, precomputedMeta) {
|
|
489
635
|
const txHashStr = tx.getTxHash().toString();
|
|
490
|
-
const meta = await buildTxMetaData(tx);
|
|
636
|
+
const meta = precomputedMeta ?? await buildTxMetaData(tx);
|
|
637
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
491
638
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
639
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
492
640
|
this.#callbacks.onTxsAdded([
|
|
493
641
|
tx
|
|
494
642
|
], opts);
|
|
@@ -501,64 +649,74 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
501
649
|
this.#indices.addMined(meta);
|
|
502
650
|
}
|
|
503
651
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
504
|
-
this.#log.
|
|
652
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
505
653
|
eventName: 'tx-added-to-pool',
|
|
506
|
-
|
|
654
|
+
txHash: txHashStr,
|
|
655
|
+
state: stateStr,
|
|
656
|
+
source: opts.source
|
|
507
657
|
});
|
|
508
658
|
return meta;
|
|
509
659
|
}
|
|
510
660
|
/**
|
|
511
661
|
* Deletes a transaction from both indices and DB.
|
|
512
662
|
* Emits onTxsRemoved callback immediately after DB delete.
|
|
663
|
+
*/ /**
|
|
664
|
+
* Deletes a transaction from the pool.
|
|
665
|
+
* Delegates to DeletedPool which decides soft vs hard delete based on whether
|
|
666
|
+
* the tx is from a pruned block.
|
|
513
667
|
*/ async #deleteTx(txHashStr) {
|
|
514
668
|
this.#indices.remove(txHashStr);
|
|
515
|
-
await this.#txsDB.delete(txHashStr);
|
|
516
669
|
this.#callbacks.onTxsRemoved([
|
|
517
670
|
txHashStr
|
|
518
671
|
]);
|
|
672
|
+
await this.#deletedPool.deleteTx(txHashStr);
|
|
519
673
|
}
|
|
520
674
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */ async #deleteTxsBatch(txHashes) {
|
|
521
675
|
for (const txHashStr of txHashes){
|
|
522
676
|
await this.#deleteTx(txHashStr);
|
|
523
677
|
}
|
|
524
678
|
}
|
|
679
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */ async #evictTxs(txHashes, reason) {
|
|
680
|
+
if (txHashes.length === 0) {
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
684
|
+
for (const txHashStr of txHashes){
|
|
685
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, {
|
|
686
|
+
txHash: txHashStr,
|
|
687
|
+
reason
|
|
688
|
+
});
|
|
689
|
+
this.#addToEvictedCache(txHashStr);
|
|
690
|
+
}
|
|
691
|
+
await this.#deleteTxsBatch(txHashes);
|
|
692
|
+
}
|
|
693
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */ #addToEvictedCache(txHashStr) {
|
|
694
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
695
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
696
|
+
const oldest = this.#evictedTxHashes.values().next().value;
|
|
697
|
+
this.#evictedTxHashes.delete(oldest);
|
|
698
|
+
}
|
|
699
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
700
|
+
}
|
|
525
701
|
// ============================================================================
|
|
526
702
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
527
703
|
// ============================================================================
|
|
528
|
-
/** Validates
|
|
529
|
-
const
|
|
704
|
+
/** Validates transaction metadata, returning true if valid */ async #validateMeta(meta, validator, context) {
|
|
705
|
+
const txValidator = validator ?? await this.#createTxValidator();
|
|
706
|
+
const result = await txValidator.validateTx(meta);
|
|
530
707
|
if (result.result !== 'valid') {
|
|
531
708
|
const contextStr = context ? ` ${context}` : '';
|
|
532
|
-
this.#log.info(`Tx ${
|
|
709
|
+
this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
|
|
533
710
|
return false;
|
|
534
711
|
}
|
|
535
712
|
return true;
|
|
536
713
|
}
|
|
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) {
|
|
714
|
+
/** Validates metadata directly */ async #revalidateMetadata(metas, context) {
|
|
558
715
|
const valid = [];
|
|
559
716
|
const invalid = [];
|
|
560
|
-
|
|
561
|
-
|
|
717
|
+
const validator = await this.#createTxValidator();
|
|
718
|
+
for (const meta of metas){
|
|
719
|
+
if (await this.#validateMeta(meta, validator, context)) {
|
|
562
720
|
valid.push(meta);
|
|
563
721
|
} else {
|
|
564
722
|
invalid.push(meta.txHash);
|
|
@@ -569,17 +727,6 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
569
727
|
invalid
|
|
570
728
|
};
|
|
571
729
|
}
|
|
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
730
|
/**
|
|
584
731
|
* Resolves nullifier conflicts between incoming txs and existing pending txs.
|
|
585
732
|
* Modifies the pending indices during iteration to maintain consistent state
|
|
@@ -635,6 +782,10 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
635
782
|
const loaded = [];
|
|
636
783
|
const errors = [];
|
|
637
784
|
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()){
|
|
785
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
786
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
638
789
|
try {
|
|
639
790
|
const tx = Tx.fromBuffer(buffer);
|
|
640
791
|
const meta = await buildTxMetaData(tx);
|
|
@@ -685,7 +836,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
685
836
|
if (preAddResult.shouldIgnore) {
|
|
686
837
|
// Transaction rejected - mark for deletion from DB
|
|
687
838
|
rejected.push(meta.txHash);
|
|
688
|
-
this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason}`);
|
|
839
|
+
this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
689
840
|
continue;
|
|
690
841
|
}
|
|
691
842
|
// Evict any conflicting txs identified by pre-add rules
|
|
@@ -721,7 +872,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
721
872
|
getFeePayerPendingTxs: (feePayer)=>this.#indices.getFeePayerPendingTxs(feePayer),
|
|
722
873
|
getPendingTxCount: ()=>this.#indices.getPendingTxCount(),
|
|
723
874
|
getLowestPriorityPending: (limit)=>this.#indices.getLowestPriorityPending(limit),
|
|
724
|
-
deleteTxs: (txHashes)=>this.#
|
|
875
|
+
deleteTxs: (txHashes, reason)=>this.#evictTxs(txHashes, reason ?? 'unknown')
|
|
725
876
|
};
|
|
726
877
|
}
|
|
727
878
|
#createPreAddPoolAccess() {
|