@aztec/p2p 0.0.1-commit.e558bd1c → 0.0.1-commit.e5a3663dd
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/README.md +129 -3
- package/dest/client/factory.d.ts +10 -9
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +54 -15
- package/dest/client/interface.d.ts +47 -34
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +39 -51
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +173 -226
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +23 -10
- package/dest/config.d.ts +137 -92
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +113 -40
- package/dest/errors/p2p-service.error.d.ts +9 -0
- package/dest/errors/p2p-service.error.d.ts.map +1 -0
- package/dest/errors/p2p-service.error.js +10 -0
- 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 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +24 -13
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +80 -43
- 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 +57 -57
- 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 +7 -5
- package/dest/mem_pools/index.d.ts +2 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.d.ts +4 -2
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +33 -15
- 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_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 +7 -3
- 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 +3 -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 +2 -1
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +62 -0
- 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 +9 -7
- 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 +33 -12
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +5 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +81 -15
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +147 -19
- 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 +50 -45
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +12 -5
- 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 +17 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +14 -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 +365 -189
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +9 -3
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +37 -12
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +7 -3
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
- package/dest/msg_validators/clock_tolerance.d.ts +12 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +61 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -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 +9 -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 +19 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +88 -44
- 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/archive_cache.js +1 -1
- 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/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -2
- 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 +133 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +247 -60
- 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 +99 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +137 -53
- 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/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- 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 +22 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
- 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/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/data_store.js +5 -5
- package/dest/services/dummy_service.d.ts +13 -6
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +13 -5
- package/dest/services/encoding.d.ts +7 -3
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +18 -11
- 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 +184 -0
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
- package/dest/services/gossipsub/topic_score_params.js +363 -0
- package/dest/services/libp2p/instrumentation.d.ts +3 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +14 -0
- package/dest/services/libp2p/libp2p_service.d.ts +42 -39
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +336 -269
- package/dest/services/peer-manager/metrics.d.ts +3 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +6 -0
- package/dest/services/peer-manager/peer_manager.d.ts +6 -2
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +39 -11
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +57 -12
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +12 -8
- 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 +83 -106
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +4 -7
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +11 -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 +31 -46
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +19 -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 +52 -15
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- package/dest/services/reqresp/config.d.ts +3 -3
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/interface.d.ts +23 -9
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +23 -10
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +0 -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/index.d.ts +1 -2
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +0 -1
- 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 +21 -3
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
- package/dest/services/reqresp/reqresp.d.ts +4 -2
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +40 -15
- package/dest/services/service.d.ts +26 -4
- 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 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +80 -76
- 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 +38 -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 +100 -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/proposal_tx_collector.d.ts +7 -7
- 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/request_tracker.d.ts +53 -0
- package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/request_tracker.js +84 -0
- 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 -13
- 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 +13 -7
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +26 -7
- 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 +4 -2
- package/dest/test-helpers/mock-pubsub.d.ts +40 -6
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +139 -13
- 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 +8 -5
- 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 +125 -38
- 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 +84 -27
- package/dest/testbench/worker_client_manager.d.ts +10 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +55 -3
- package/dest/util.d.ts +3 -3
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +108 -26
- package/src/client/interface.ts +52 -34
- package/src/client/p2p_client.ts +201 -269
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +35 -14
- package/src/config.ts +181 -46
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +109 -53
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +61 -57
- package/src/mem_pools/attestation_pool/index.ts +3 -3
- package/src/mem_pools/attestation_pool/mocks.ts +14 -8
- package/src/mem_pools/index.ts +1 -1
- package/src/mem_pools/instrumentation.ts +22 -14
- package/src/mem_pools/interface.ts +2 -2
- 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 +7 -3
- 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 +5 -0
- package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +65 -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 +8 -8
- 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 +35 -12
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +215 -27
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +58 -45
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +34 -8
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +412 -187
- package/src/msg_validators/attestation_validator/README.md +49 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +41 -9
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +12 -2
- package/src/msg_validators/clock_tolerance.ts +79 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +23 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +34 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +111 -47
- package/src/msg_validators/tx_validator/README.md +127 -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/archive_cache.ts +1 -1
- 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/data_validator.ts +42 -1
- package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
- package/src/msg_validators/tx_validator/factory.ts +396 -78
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +199 -54
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
- package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
- package/src/services/data_store.ts +5 -13
- package/src/services/dummy_service.ts +19 -7
- package/src/services/encoding.ts +18 -10
- 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 +519 -0
- package/src/services/libp2p/instrumentation.ts +14 -0
- package/src/services/libp2p/libp2p_service.ts +358 -298
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +45 -11
- package/src/services/peer-manager/peer_scoring.ts +52 -5
- package/src/services/reqresp/README.md +229 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +79 -112
- package/src/services/reqresp/batch-tx-requester/interface.ts +3 -6
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +30 -71
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +68 -24
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/reqresp/config.ts +2 -2
- package/src/services/reqresp/interface.ts +45 -10
- package/src/services/reqresp/metrics.ts +0 -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/index.ts +0 -1
- package/src/services/reqresp/protocols/tx.ts +23 -3
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
- package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
- package/src/services/reqresp/reqresp.ts +53 -16
- package/src/services/service.ts +37 -3
- package/src/services/tx_collection/config.ts +68 -0
- package/src/services/tx_collection/fast_tx_collection.ts +83 -76
- package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
- package/src/services/tx_collection/file_store_tx_source.ts +129 -0
- package/src/services/tx_collection/index.ts +1 -0
- package/src/services/tx_collection/instrumentation.ts +7 -1
- package/src/services/tx_collection/proposal_tx_collector.ts +9 -13
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/slow_tx_collection.ts +66 -33
- package/src/services/tx_collection/tx_collection.ts +114 -19
- package/src/services/tx_collection/tx_collection_sink.ts +30 -34
- package/src/services/tx_collection/tx_source.ts +28 -8
- 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 +6 -6
- package/src/test-helpers/mock-pubsub.ts +180 -14
- package/src/test-helpers/reqresp-nodes.ts +9 -9
- package/src/test-helpers/testbench-utils.ts +147 -43
- package/src/testbench/p2p_client_testbench_worker.ts +93 -30
- package/src/testbench/worker_client_manager.ts +68 -6
- package/src/util.ts +8 -2
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -122
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
- package/dest/mem_pools/tx_pool/index.d.ts +0 -3
- package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/index.js +0 -2
- package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
- package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/priority.js +0 -15
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -400
- 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/dest/services/reqresp/protocols/block.d.ts +0 -9
- package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
- package/dest/services/reqresp/protocols/block.js +0 -32
- package/src/mem_pools/tx_pool/README.md +0 -270
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -162
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
- package/src/mem_pools/tx_pool/index.ts +0 -2
- package/src/mem_pools/tx_pool/priority.ts +0 -20
- package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -319
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
- package/src/services/reqresp/protocols/block.ts +0 -37
|
@@ -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, InsufficientFeePerGasEvictionRule, 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,35 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
19
22
|
// === Dependencies ===
|
|
20
23
|
#l2BlockSource;
|
|
21
24
|
#worldStateSynchronizer;
|
|
22
|
-
#
|
|
25
|
+
#createTxValidator;
|
|
26
|
+
#checkAllowedSetupCalls;
|
|
23
27
|
// === In-Memory Indices ===
|
|
24
28
|
#indices = new TxPoolIndices();
|
|
25
29
|
// === Config & Services ===
|
|
26
30
|
#config;
|
|
27
31
|
#archive;
|
|
32
|
+
#deletedPool;
|
|
28
33
|
#evictionManager;
|
|
34
|
+
#dateProvider;
|
|
35
|
+
#instrumentation;
|
|
36
|
+
#evictedTxHashes = new Set();
|
|
29
37
|
#log;
|
|
30
38
|
#callbacks;
|
|
31
|
-
constructor(store, archiveStore, deps, callbacks, config = {}, log){
|
|
39
|
+
constructor(store, archiveStore, deps, callbacks, telemetry, config = {}, dateProvider, log){
|
|
32
40
|
this.#store = store;
|
|
33
41
|
this.#txsDB = store.openMap('txs');
|
|
34
42
|
this.#l2BlockSource = deps.l2BlockSource;
|
|
35
43
|
this.#worldStateSynchronizer = deps.worldStateSynchronizer;
|
|
36
|
-
this.#
|
|
44
|
+
this.#createTxValidator = deps.createTxValidator;
|
|
45
|
+
this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
|
|
37
46
|
this.#config = {
|
|
38
47
|
...DEFAULT_TX_POOL_V2_CONFIG,
|
|
39
48
|
...config
|
|
40
49
|
};
|
|
41
50
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
51
|
+
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
52
|
+
this.#dateProvider = dateProvider;
|
|
53
|
+
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, ()=>this.#indices.getTotalMetadataBytes());
|
|
42
54
|
this.#log = log;
|
|
43
55
|
this.#callbacks = callbacks;
|
|
44
56
|
// Setup eviction manager with rules
|
|
@@ -51,6 +63,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
51
63
|
}));
|
|
52
64
|
// Post-event eviction rules (run after events to check ALL pending txs)
|
|
53
65
|
this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
|
|
66
|
+
this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
|
|
54
67
|
this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
|
|
55
68
|
this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
|
|
56
69
|
// LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
|
|
@@ -69,7 +82,9 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
69
82
|
* Note: Protected status is lost on restart. All non-mined txs are rebuilt as pending
|
|
70
83
|
* by running pre-add rules to resolve nullifier conflicts, balance checks, and pool size limits.
|
|
71
84
|
*/ async hydrateFromDatabase() {
|
|
72
|
-
// Step
|
|
85
|
+
// Step 0: Hydrate deleted pool state
|
|
86
|
+
await this.#deletedPool.hydrateFromDatabase();
|
|
87
|
+
// Step 1: Load all transactions from DB (excluding soft-deleted)
|
|
73
88
|
const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
|
|
74
89
|
// Step 2: Check mined status for each tx
|
|
75
90
|
await this.#markMinedStatusBatch(loaded.map((l)=>l.meta));
|
|
@@ -84,7 +99,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
84
99
|
}
|
|
85
100
|
}
|
|
86
101
|
// Step 4: Validate non-mined transactions
|
|
87
|
-
const { valid, invalid } = await this.#
|
|
102
|
+
const { valid, invalid } = await this.#revalidateMetadata(nonMined.map((e)=>e.meta), 'on startup');
|
|
88
103
|
// Step 5: Populate mined indices (these don't need conflict resolution)
|
|
89
104
|
for (const meta of mined){
|
|
90
105
|
this.#indices.addMined(meta);
|
|
@@ -106,14 +121,43 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
106
121
|
await this.#txsDB.delete(txHashStr);
|
|
107
122
|
}
|
|
108
123
|
});
|
|
109
|
-
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup
|
|
124
|
+
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, {
|
|
125
|
+
txHashes: toDelete
|
|
126
|
+
});
|
|
110
127
|
}
|
|
111
128
|
async addPendingTxs(txs, opts) {
|
|
112
129
|
const accepted = [];
|
|
113
130
|
const ignored = [];
|
|
114
131
|
const rejected = [];
|
|
132
|
+
const errors = new Map();
|
|
115
133
|
const acceptedPending = new Set();
|
|
134
|
+
// Phase 1: Pre-compute all throwable I/O outside the transaction.
|
|
135
|
+
// If any pre-computation throws, the entire call fails before mutations happen.
|
|
136
|
+
const precomputed = new Map();
|
|
137
|
+
const validator = await this.#createTxValidator();
|
|
138
|
+
for (const tx of txs){
|
|
139
|
+
const txHash = tx.getTxHash();
|
|
140
|
+
const txHashStr = txHash.toString();
|
|
141
|
+
const meta = await buildTxMetaData(tx);
|
|
142
|
+
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
143
|
+
// Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
|
|
144
|
+
let isValid = true;
|
|
145
|
+
if (!minedBlockId) {
|
|
146
|
+
isValid = await this.#validateMeta(meta, validator);
|
|
147
|
+
}
|
|
148
|
+
precomputed.set(txHashStr, {
|
|
149
|
+
meta,
|
|
150
|
+
minedBlockId,
|
|
151
|
+
isValid
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// Phase 2: Apply mutations inside the transaction using only pre-computed results,
|
|
155
|
+
// in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
|
|
116
156
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
157
|
+
const preAddContext = opts.feeComparisonOnly !== undefined ? {
|
|
158
|
+
feeComparisonOnly: opts.feeComparisonOnly,
|
|
159
|
+
priceBumpPercentage: this.#config.priceBumpPercentage
|
|
160
|
+
} : undefined;
|
|
117
161
|
await this.#store.transactionAsync(async ()=>{
|
|
118
162
|
for (const tx of txs){
|
|
119
163
|
const txHash = tx.getTxHash();
|
|
@@ -123,82 +167,112 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
123
167
|
ignored.push(txHash);
|
|
124
168
|
continue;
|
|
125
169
|
}
|
|
126
|
-
|
|
127
|
-
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
170
|
+
const { meta, minedBlockId, isValid } = precomputed.get(txHashStr);
|
|
128
171
|
const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
|
|
129
172
|
if (minedBlockId) {
|
|
130
173
|
// Already mined - add directly (protection already set if pre-protected)
|
|
131
174
|
await this.#addTx(tx, {
|
|
132
175
|
mined: minedBlockId
|
|
133
|
-
}, opts);
|
|
176
|
+
}, opts, meta);
|
|
134
177
|
accepted.push(txHash);
|
|
135
178
|
} else if (preProtectedSlot !== undefined) {
|
|
136
179
|
// Pre-protected and not mined - add as protected (bypass validation)
|
|
137
180
|
await this.#addTx(tx, {
|
|
138
181
|
protected: preProtectedSlot
|
|
139
|
-
}, opts);
|
|
182
|
+
}, opts, meta);
|
|
140
183
|
accepted.push(txHash);
|
|
184
|
+
} else if (!isValid) {
|
|
185
|
+
// Failed pre-computed validation
|
|
186
|
+
rejected.push(txHash);
|
|
141
187
|
} else {
|
|
142
|
-
// Regular pending tx -
|
|
143
|
-
const result = await this.#tryAddRegularPendingTx(tx, opts, poolAccess, acceptedPending, ignored);
|
|
188
|
+
// Regular pending tx - run pre-add rules using pre-computed metadata
|
|
189
|
+
const result = await this.#tryAddRegularPendingTx(tx, meta, opts, poolAccess, acceptedPending, ignored, errors, preAddContext);
|
|
144
190
|
if (result.status === 'accepted') {
|
|
145
191
|
acceptedPending.add(txHashStr);
|
|
146
|
-
} else if (result.status === 'rejected') {
|
|
147
|
-
rejected.push(txHash);
|
|
148
192
|
} else {
|
|
149
193
|
ignored.push(txHash);
|
|
150
194
|
}
|
|
151
195
|
}
|
|
152
196
|
}
|
|
197
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
198
|
+
if (acceptedPending.size > 0) {
|
|
199
|
+
const feePayers = Array.from(acceptedPending).map((txHash)=>this.#indices.getMetadata(txHash).feePayer);
|
|
200
|
+
const uniqueFeePayers = new Set(feePayers);
|
|
201
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [
|
|
202
|
+
...uniqueFeePayers
|
|
203
|
+
]);
|
|
204
|
+
}
|
|
153
205
|
});
|
|
154
206
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
155
207
|
for (const txHashStr of acceptedPending){
|
|
156
208
|
accepted.push(TxHash.fromString(txHashStr));
|
|
157
209
|
}
|
|
158
|
-
//
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
]);
|
|
210
|
+
// Record metrics
|
|
211
|
+
if (ignored.length > 0) {
|
|
212
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
213
|
+
}
|
|
214
|
+
if (rejected.length > 0) {
|
|
215
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
165
216
|
}
|
|
166
217
|
return {
|
|
167
218
|
accepted,
|
|
168
219
|
ignored,
|
|
169
|
-
rejected
|
|
220
|
+
rejected,
|
|
221
|
+
...errors.size > 0 ? {
|
|
222
|
+
errors
|
|
223
|
+
} : {}
|
|
170
224
|
};
|
|
171
225
|
}
|
|
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);
|
|
226
|
+
/** Adds a validated pending tx, running pre-add rules and evicting conflicts. */ async #tryAddRegularPendingTx(tx, precomputedMeta, opts, poolAccess, acceptedPending, ignored, errors, preAddContext) {
|
|
227
|
+
const txHashStr = tx.getTxHash().toString();
|
|
228
|
+
// Run pre-add rules
|
|
229
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
|
|
184
230
|
if (preAddResult.shouldIgnore) {
|
|
185
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
231
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
232
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
233
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
234
|
+
}
|
|
186
235
|
return {
|
|
187
236
|
status: 'ignored'
|
|
188
237
|
};
|
|
189
238
|
}
|
|
190
|
-
// Evict conflicts
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
239
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
240
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
241
|
+
const byReason = new Map();
|
|
242
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions){
|
|
243
|
+
const group = byReason.get(reason);
|
|
244
|
+
if (group) {
|
|
245
|
+
group.push(evictHash);
|
|
246
|
+
} else {
|
|
247
|
+
byReason.set(reason, [
|
|
248
|
+
evictHash
|
|
249
|
+
]);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
for (const [reason, hashes] of byReason){
|
|
253
|
+
await this.#evictTxs(hashes, reason);
|
|
254
|
+
}
|
|
255
|
+
for (const evictHashStr of preAddResult.txHashesToEvict){
|
|
256
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
257
|
+
evictedTxHash: evictHashStr,
|
|
258
|
+
replacementTxHash: txHashStr
|
|
259
|
+
});
|
|
260
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
261
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
262
|
+
acceptedPending.delete(evictHashStr);
|
|
263
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
264
|
+
}
|
|
198
265
|
}
|
|
199
266
|
}
|
|
267
|
+
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
268
|
+
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
269
|
+
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
270
|
+
return {
|
|
271
|
+
status: 'accepted'
|
|
272
|
+
};
|
|
273
|
+
}
|
|
200
274
|
// Add the transaction
|
|
201
|
-
await this.#addTx(tx, 'pending', opts);
|
|
275
|
+
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
202
276
|
return {
|
|
203
277
|
status: 'accepted'
|
|
204
278
|
};
|
|
@@ -207,38 +281,44 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
207
281
|
const txHashStr = tx.getTxHash().toString();
|
|
208
282
|
// Check if already in pool
|
|
209
283
|
if (this.#indices.has(txHashStr)) {
|
|
284
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
|
|
210
285
|
return 'ignored';
|
|
211
286
|
}
|
|
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
|
|
287
|
+
// Build metadata and check pre-add rules
|
|
218
288
|
const meta = await buildTxMetaData(tx);
|
|
219
289
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
220
290
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
221
|
-
|
|
291
|
+
if (preAddResult.shouldIgnore) {
|
|
292
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
|
|
293
|
+
reason: preAddResult.reason?.message ?? 'no reason provided'
|
|
294
|
+
});
|
|
295
|
+
return 'ignored';
|
|
296
|
+
}
|
|
297
|
+
return 'accepted';
|
|
222
298
|
}
|
|
223
299
|
async addProtectedTxs(txs, block, opts) {
|
|
224
300
|
const slotNumber = block.globalVariables.slotNumber;
|
|
301
|
+
// Precompute setup-call allow-list flags outside the store transaction
|
|
302
|
+
const allowedFlags = await Promise.all(txs.map((tx)=>this.#checkAllowedSetupCalls(tx)));
|
|
225
303
|
await this.#store.transactionAsync(async ()=>{
|
|
226
|
-
for
|
|
304
|
+
for(let i = 0; i < txs.length; i++){
|
|
305
|
+
const tx = txs[i];
|
|
227
306
|
const txHash = tx.getTxHash();
|
|
228
307
|
const txHashStr = txHash.toString();
|
|
229
308
|
const isNew = !this.#indices.has(txHashStr);
|
|
230
309
|
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
231
310
|
if (isNew) {
|
|
311
|
+
const meta = await buildTxMetaData(tx, allowedFlags[i]);
|
|
232
312
|
// New tx - add as mined or protected (callback emitted by #addTx)
|
|
233
313
|
if (minedBlockId) {
|
|
234
314
|
await this.#addTx(tx, {
|
|
235
315
|
mined: minedBlockId
|
|
236
|
-
}, opts);
|
|
316
|
+
}, opts, meta);
|
|
237
317
|
this.#indices.setProtection(txHashStr, slotNumber);
|
|
238
318
|
} else {
|
|
239
319
|
await this.#addTx(tx, {
|
|
240
320
|
protected: slotNumber
|
|
241
|
-
}, opts);
|
|
321
|
+
}, opts, meta);
|
|
242
322
|
}
|
|
243
323
|
} else {
|
|
244
324
|
// Existing tx - update protection and mined status
|
|
@@ -251,20 +331,53 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
251
331
|
}
|
|
252
332
|
});
|
|
253
333
|
}
|
|
254
|
-
protectTxs(txHashes, block) {
|
|
334
|
+
async protectTxs(txHashes, block) {
|
|
255
335
|
const slotNumber = block.globalVariables.slotNumber;
|
|
256
336
|
const missing = [];
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
337
|
+
let softDeletedHits = 0;
|
|
338
|
+
let missingPreviouslyEvicted = 0;
|
|
339
|
+
await this.#store.transactionAsync(async ()=>{
|
|
340
|
+
for (const txHash of txHashes){
|
|
341
|
+
const txHashStr = txHash.toString();
|
|
342
|
+
if (this.#indices.has(txHashStr)) {
|
|
343
|
+
// Update protection for existing tx
|
|
344
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
345
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
346
|
+
// Resurrect soft-deleted tx as protected
|
|
347
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
348
|
+
if (buffer) {
|
|
349
|
+
const tx = Tx.fromBuffer(buffer);
|
|
350
|
+
await this.#addTx(tx, {
|
|
351
|
+
protected: slotNumber
|
|
352
|
+
});
|
|
353
|
+
softDeletedHits++;
|
|
354
|
+
} else {
|
|
355
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
356
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
357
|
+
missing.push(txHash);
|
|
358
|
+
}
|
|
359
|
+
} else {
|
|
360
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
361
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
362
|
+
missing.push(txHash);
|
|
363
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
364
|
+
missingPreviouslyEvicted++;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
266
367
|
}
|
|
368
|
+
});
|
|
369
|
+
// Record metrics
|
|
370
|
+
if (softDeletedHits > 0) {
|
|
371
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
372
|
+
}
|
|
373
|
+
if (missing.length > 0) {
|
|
374
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map((h)=>h.toString()).join(', ')}`);
|
|
375
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
376
|
+
}
|
|
377
|
+
if (missingPreviouslyEvicted > 0) {
|
|
378
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
267
379
|
}
|
|
380
|
+
this.#log.info(`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`);
|
|
268
381
|
return missing;
|
|
269
382
|
}
|
|
270
383
|
async addMinedTxs(txs, block, opts) {
|
|
@@ -283,6 +396,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
283
396
|
mined: blockId
|
|
284
397
|
}, opts);
|
|
285
398
|
}
|
|
399
|
+
await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
|
|
286
400
|
}
|
|
287
401
|
});
|
|
288
402
|
}
|
|
@@ -302,44 +416,53 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
302
416
|
found.push(meta);
|
|
303
417
|
}
|
|
304
418
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
419
|
+
await this.#store.transactionAsync(async ()=>{
|
|
420
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
421
|
+
for (const meta of found){
|
|
422
|
+
this.#indices.markAsMined(meta, blockId);
|
|
423
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
424
|
+
}
|
|
425
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
426
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
427
|
+
});
|
|
428
|
+
if (found.length > 0) {
|
|
429
|
+
this.#callbacks.onTxsMined(found.map((m)=>m.txHash));
|
|
308
430
|
}
|
|
309
|
-
// Step 5: Run eviction rules (remove pending txs with conflicting nullifiers/expired timestamps)
|
|
310
|
-
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
311
431
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
312
432
|
}
|
|
313
433
|
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
|
-
|
|
434
|
+
await this.#store.transactionAsync(async ()=>{
|
|
435
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
436
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
437
|
+
// Step 1: Find expired protected txs
|
|
438
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
439
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
440
|
+
this.#indices.clearProtection(expiredProtected);
|
|
441
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
442
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
443
|
+
if (txsToRestore.length === 0) {
|
|
444
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
448
|
+
// Step 4: Validate for pending pool
|
|
449
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
450
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
451
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
452
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
453
|
+
await this.#deleteTxsBatch(invalid);
|
|
454
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
455
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
456
|
+
if (added.length > 0) {
|
|
457
|
+
const feePayers = added.map((meta)=>meta.feePayer);
|
|
458
|
+
const uniqueFeePayers = new Set(feePayers);
|
|
459
|
+
await this.#evictionManager.evictAfterNewTxs(added.map((m)=>m.txHash), [
|
|
460
|
+
...uniqueFeePayers
|
|
461
|
+
]);
|
|
462
|
+
}
|
|
463
|
+
});
|
|
341
464
|
}
|
|
342
|
-
async handlePrunedBlocks(latestBlock) {
|
|
465
|
+
async handlePrunedBlocks(latestBlock, options) {
|
|
343
466
|
// Step 1: Find transactions mined after the prune point
|
|
344
467
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
345
468
|
if (txsToUnmine.length === 0) {
|
|
@@ -347,54 +470,81 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
347
470
|
return;
|
|
348
471
|
}
|
|
349
472
|
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
|
-
|
|
473
|
+
await this.#store.transactionAsync(async ()=>{
|
|
474
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
475
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
476
|
+
// when their original mined block is finalized
|
|
477
|
+
await this.#deletedPool.markFromPrunedBlock(txsToUnmine.map((m)=>({
|
|
478
|
+
txHash: m.txHash,
|
|
479
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId.number)
|
|
480
|
+
})));
|
|
481
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
482
|
+
for (const meta of txsToUnmine){
|
|
483
|
+
this.#indices.markAsUnmined(meta);
|
|
484
|
+
}
|
|
485
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
486
|
+
if (options?.deleteAllTxs) {
|
|
487
|
+
const allTxHashes = txsToUnmine.map((m)=>m.txHash);
|
|
488
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
489
|
+
this.#log.info(`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
493
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
494
|
+
// Step 5: Validate for pending pool
|
|
495
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
496
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
497
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
498
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
499
|
+
await this.#deleteTxsBatch(invalid);
|
|
500
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
501
|
+
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`, {
|
|
502
|
+
txHashesRestored: valid.map((m)=>m.txHash),
|
|
503
|
+
txHashesInvalid: invalid,
|
|
504
|
+
txHashesEvicted: toEvict
|
|
505
|
+
});
|
|
506
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
507
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
508
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
509
|
+
});
|
|
368
510
|
}
|
|
369
511
|
async handleFailedExecution(txHashes) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
512
|
+
await this.#store.transactionAsync(async ()=>{
|
|
513
|
+
await this.#deleteTxsBatch(txHashes.map((h)=>h.toString()));
|
|
514
|
+
});
|
|
515
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, {
|
|
516
|
+
txHashes: txHashes.map((h)=>h.toString())
|
|
517
|
+
});
|
|
373
518
|
}
|
|
374
519
|
async handleFinalizedBlock(block) {
|
|
375
520
|
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));
|
|
521
|
+
// Step 1: Find mined txs at or before finalized block
|
|
522
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
523
|
+
await this.#store.transactionAsync(async ()=>{
|
|
524
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
525
|
+
const txsToArchive = [];
|
|
526
|
+
if (this.#archive.isEnabled()) {
|
|
527
|
+
for (const txHashStr of minedTxsToFinalize){
|
|
528
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
529
|
+
if (buffer) {
|
|
530
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
531
|
+
}
|
|
388
532
|
}
|
|
389
533
|
}
|
|
534
|
+
// Step 3: Delete mined txs from active pool
|
|
535
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
536
|
+
// Step 4: Finalize soft-deleted txs
|
|
537
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
538
|
+
// Step 5: Archive mined txs
|
|
539
|
+
if (txsToArchive.length > 0) {
|
|
540
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
if (minedTxsToFinalize.length > 0) {
|
|
544
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
545
|
+
txHashes: minedTxsToFinalize
|
|
546
|
+
});
|
|
390
547
|
}
|
|
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
548
|
}
|
|
399
549
|
// === Query Methods ===
|
|
400
550
|
async getTxByHash(txHash) {
|
|
@@ -410,20 +560,34 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
410
560
|
return results;
|
|
411
561
|
}
|
|
412
562
|
hasTxs(txHashes) {
|
|
413
|
-
return txHashes.map((h)=>
|
|
563
|
+
return txHashes.map((h)=>{
|
|
564
|
+
const hashStr = h.toString();
|
|
565
|
+
return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
|
|
566
|
+
});
|
|
414
567
|
}
|
|
415
568
|
getTxStatus(txHash) {
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
569
|
+
const txHashStr = txHash.toString();
|
|
570
|
+
const meta = this.#indices.getMetadata(txHashStr);
|
|
571
|
+
if (meta) {
|
|
572
|
+
return this.#indices.getTxState(meta);
|
|
573
|
+
}
|
|
574
|
+
// Check if soft-deleted
|
|
575
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
576
|
+
return 'deleted';
|
|
419
577
|
}
|
|
420
|
-
return
|
|
578
|
+
return undefined;
|
|
421
579
|
}
|
|
422
580
|
getPendingTxHashes() {
|
|
423
581
|
return [
|
|
424
582
|
...this.#indices.iteratePendingByPriority('desc')
|
|
425
583
|
].map((hash)=>TxHash.fromString(hash));
|
|
426
584
|
}
|
|
585
|
+
getEligiblePendingTxHashes() {
|
|
586
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
587
|
+
return [
|
|
588
|
+
...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)
|
|
589
|
+
].map((hash)=>TxHash.fromString(hash));
|
|
590
|
+
}
|
|
427
591
|
getPendingTxCount() {
|
|
428
592
|
return this.#indices.getPendingTxCount();
|
|
429
593
|
}
|
|
@@ -463,6 +627,9 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
463
627
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
464
628
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
465
629
|
}
|
|
630
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
631
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
632
|
+
}
|
|
466
633
|
// Update eviction rules with new config
|
|
467
634
|
this.#evictionManager.updateConfig(config);
|
|
468
635
|
}
|
|
@@ -477,7 +644,10 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
477
644
|
}
|
|
478
645
|
// === Metrics ===
|
|
479
646
|
countTxs() {
|
|
480
|
-
return
|
|
647
|
+
return {
|
|
648
|
+
...this.#indices.countTxs(),
|
|
649
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount()
|
|
650
|
+
};
|
|
481
651
|
}
|
|
482
652
|
// ============================================================================
|
|
483
653
|
// PRIVATE HELPERS - Transaction Management
|
|
@@ -485,10 +655,12 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
485
655
|
/**
|
|
486
656
|
* Adds a new transaction to the pool with the specified state.
|
|
487
657
|
* Emits onTxsAdded callback immediately after DB write.
|
|
488
|
-
*/ async #addTx(tx, state, opts = {}) {
|
|
658
|
+
*/ async #addTx(tx, state, opts = {}, precomputedMeta) {
|
|
489
659
|
const txHashStr = tx.getTxHash().toString();
|
|
490
|
-
const meta = await buildTxMetaData(tx);
|
|
660
|
+
const meta = precomputedMeta ?? await buildTxMetaData(tx);
|
|
661
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
491
662
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
663
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
492
664
|
this.#callbacks.onTxsAdded([
|
|
493
665
|
tx
|
|
494
666
|
], opts);
|
|
@@ -501,64 +673,74 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
501
673
|
this.#indices.addMined(meta);
|
|
502
674
|
}
|
|
503
675
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
504
|
-
this.#log.
|
|
676
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
505
677
|
eventName: 'tx-added-to-pool',
|
|
506
|
-
|
|
678
|
+
txHash: txHashStr,
|
|
679
|
+
state: stateStr,
|
|
680
|
+
source: opts.source
|
|
507
681
|
});
|
|
508
682
|
return meta;
|
|
509
683
|
}
|
|
510
684
|
/**
|
|
511
685
|
* Deletes a transaction from both indices and DB.
|
|
512
686
|
* Emits onTxsRemoved callback immediately after DB delete.
|
|
687
|
+
*/ /**
|
|
688
|
+
* Deletes a transaction from the pool.
|
|
689
|
+
* Delegates to DeletedPool which decides soft vs hard delete based on whether
|
|
690
|
+
* the tx is from a pruned block.
|
|
513
691
|
*/ async #deleteTx(txHashStr) {
|
|
514
692
|
this.#indices.remove(txHashStr);
|
|
515
|
-
await this.#txsDB.delete(txHashStr);
|
|
516
693
|
this.#callbacks.onTxsRemoved([
|
|
517
694
|
txHashStr
|
|
518
695
|
]);
|
|
696
|
+
await this.#deletedPool.deleteTx(txHashStr);
|
|
519
697
|
}
|
|
520
698
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */ async #deleteTxsBatch(txHashes) {
|
|
521
699
|
for (const txHashStr of txHashes){
|
|
522
700
|
await this.#deleteTx(txHashStr);
|
|
523
701
|
}
|
|
524
702
|
}
|
|
703
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */ async #evictTxs(txHashes, reason) {
|
|
704
|
+
if (txHashes.length === 0) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
708
|
+
for (const txHashStr of txHashes){
|
|
709
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, {
|
|
710
|
+
txHash: txHashStr,
|
|
711
|
+
reason
|
|
712
|
+
});
|
|
713
|
+
this.#addToEvictedCache(txHashStr);
|
|
714
|
+
}
|
|
715
|
+
await this.#deleteTxsBatch(txHashes);
|
|
716
|
+
}
|
|
717
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */ #addToEvictedCache(txHashStr) {
|
|
718
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
719
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
720
|
+
const oldest = this.#evictedTxHashes.values().next().value;
|
|
721
|
+
this.#evictedTxHashes.delete(oldest);
|
|
722
|
+
}
|
|
723
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
724
|
+
}
|
|
525
725
|
// ============================================================================
|
|
526
726
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
527
727
|
// ============================================================================
|
|
528
|
-
/** Validates
|
|
529
|
-
const
|
|
728
|
+
/** Validates transaction metadata, returning true if valid */ async #validateMeta(meta, validator, context) {
|
|
729
|
+
const txValidator = validator ?? await this.#createTxValidator();
|
|
730
|
+
const result = await txValidator.validateTx(meta);
|
|
530
731
|
if (result.result !== 'valid') {
|
|
531
732
|
const contextStr = context ? ` ${context}` : '';
|
|
532
|
-
this.#log.info(`Tx ${
|
|
733
|
+
this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
|
|
533
734
|
return false;
|
|
534
735
|
}
|
|
535
736
|
return true;
|
|
536
737
|
}
|
|
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) {
|
|
738
|
+
/** Validates metadata directly */ async #revalidateMetadata(metas, context) {
|
|
558
739
|
const valid = [];
|
|
559
740
|
const invalid = [];
|
|
560
|
-
|
|
561
|
-
|
|
741
|
+
const validator = await this.#createTxValidator();
|
|
742
|
+
for (const meta of metas){
|
|
743
|
+
if (await this.#validateMeta(meta, validator, context)) {
|
|
562
744
|
valid.push(meta);
|
|
563
745
|
} else {
|
|
564
746
|
invalid.push(meta.txHash);
|
|
@@ -569,17 +751,6 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
569
751
|
invalid
|
|
570
752
|
};
|
|
571
753
|
}
|
|
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
754
|
/**
|
|
584
755
|
* Resolves nullifier conflicts between incoming txs and existing pending txs.
|
|
585
756
|
* Modifies the pending indices during iteration to maintain consistent state
|
|
@@ -635,9 +806,14 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
635
806
|
const loaded = [];
|
|
636
807
|
const errors = [];
|
|
637
808
|
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()){
|
|
809
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
810
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
638
813
|
try {
|
|
639
814
|
const tx = Tx.fromBuffer(buffer);
|
|
640
|
-
const
|
|
815
|
+
const allowedSetupCalls = await this.#checkAllowedSetupCalls(tx);
|
|
816
|
+
const meta = await buildTxMetaData(tx, allowedSetupCalls);
|
|
641
817
|
loaded.push({
|
|
642
818
|
tx,
|
|
643
819
|
meta
|
|
@@ -685,7 +861,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
685
861
|
if (preAddResult.shouldIgnore) {
|
|
686
862
|
// Transaction rejected - mark for deletion from DB
|
|
687
863
|
rejected.push(meta.txHash);
|
|
688
|
-
this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason}`);
|
|
864
|
+
this.#log.debug(`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
689
865
|
continue;
|
|
690
866
|
}
|
|
691
867
|
// Evict any conflicting txs identified by pre-add rules
|
|
@@ -721,7 +897,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
721
897
|
getFeePayerPendingTxs: (feePayer)=>this.#indices.getFeePayerPendingTxs(feePayer),
|
|
722
898
|
getPendingTxCount: ()=>this.#indices.getPendingTxCount(),
|
|
723
899
|
getLowestPriorityPending: (limit)=>this.#indices.getLowestPriorityPending(limit),
|
|
724
|
-
deleteTxs: (txHashes)=>this.#
|
|
900
|
+
deleteTxs: (txHashes, reason)=>this.#evictTxs(txHashes, reason ?? 'unknown')
|
|
725
901
|
};
|
|
726
902
|
}
|
|
727
903
|
#createPreAddPoolAccess() {
|