@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,5 +1,6 @@
|
|
|
1
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
|
+
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import type { Logger } from '@aztec/foundation/log';
|
|
3
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
3
4
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
4
5
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
5
6
|
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
@@ -8,20 +9,27 @@ import type { L2Block, L2BlockId, L2BlockSource } from '@aztec/stdlib/block';
|
|
|
8
9
|
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
9
10
|
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
10
11
|
import { BlockHeader, Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx';
|
|
12
|
+
import type { TelemetryClient } from '@aztec/telemetry-client';
|
|
11
13
|
|
|
12
14
|
import { TxArchive } from './archive/index.js';
|
|
15
|
+
import { DeletedPool } from './deleted_pool.js';
|
|
13
16
|
import {
|
|
14
17
|
EvictionManager,
|
|
15
18
|
FeePayerBalanceEvictionRule,
|
|
16
19
|
FeePayerBalancePreAddRule,
|
|
20
|
+
InsufficientFeePerGasEvictionRule,
|
|
17
21
|
InvalidTxsAfterMiningRule,
|
|
18
22
|
InvalidTxsAfterReorgRule,
|
|
19
23
|
LowPriorityEvictionRule,
|
|
20
24
|
LowPriorityPreAddRule,
|
|
21
25
|
NullifierConflictRule,
|
|
22
26
|
type PoolOperations,
|
|
27
|
+
type PreAddContext,
|
|
23
28
|
type PreAddPoolAccess,
|
|
29
|
+
TxPoolRejectionCode,
|
|
30
|
+
type TxPoolRejectionError,
|
|
24
31
|
} from './eviction/index.js';
|
|
32
|
+
import { TxPoolV2Instrumentation } from './instrumentation.js';
|
|
25
33
|
import {
|
|
26
34
|
type AddTxsResult,
|
|
27
35
|
DEFAULT_TX_POOL_V2_CONFIG,
|
|
@@ -38,6 +46,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
38
46
|
export interface TxPoolV2Callbacks {
|
|
39
47
|
onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
|
|
40
48
|
onTxsRemoved: (txHashes: string[] | bigint[]) => void;
|
|
49
|
+
onTxsMined: (txHashes: string[]) => void;
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
/**
|
|
@@ -53,7 +62,8 @@ export class TxPoolV2Impl {
|
|
|
53
62
|
// === Dependencies ===
|
|
54
63
|
#l2BlockSource: L2BlockSource;
|
|
55
64
|
#worldStateSynchronizer: WorldStateSynchronizer;
|
|
56
|
-
#
|
|
65
|
+
#createTxValidator: TxPoolV2Dependencies['createTxValidator'];
|
|
66
|
+
#checkAllowedSetupCalls: TxPoolV2Dependencies['checkAllowedSetupCalls'];
|
|
57
67
|
|
|
58
68
|
// === In-Memory Indices ===
|
|
59
69
|
#indices: TxPoolIndices = new TxPoolIndices();
|
|
@@ -61,7 +71,11 @@ export class TxPoolV2Impl {
|
|
|
61
71
|
// === Config & Services ===
|
|
62
72
|
#config: TxPoolV2Config;
|
|
63
73
|
#archive: TxArchive;
|
|
74
|
+
#deletedPool: DeletedPool;
|
|
64
75
|
#evictionManager: EvictionManager;
|
|
76
|
+
#dateProvider: DateProvider;
|
|
77
|
+
#instrumentation: TxPoolV2Instrumentation;
|
|
78
|
+
#evictedTxHashes: Set<string> = new Set();
|
|
65
79
|
#log: Logger;
|
|
66
80
|
#callbacks: TxPoolV2Callbacks;
|
|
67
81
|
|
|
@@ -70,7 +84,9 @@ export class TxPoolV2Impl {
|
|
|
70
84
|
archiveStore: AztecAsyncKVStore,
|
|
71
85
|
deps: TxPoolV2Dependencies,
|
|
72
86
|
callbacks: TxPoolV2Callbacks,
|
|
87
|
+
telemetry: TelemetryClient,
|
|
73
88
|
config: Partial<TxPoolV2Config> = {},
|
|
89
|
+
dateProvider: DateProvider,
|
|
74
90
|
log: Logger,
|
|
75
91
|
) {
|
|
76
92
|
this.#store = store;
|
|
@@ -78,10 +94,14 @@ export class TxPoolV2Impl {
|
|
|
78
94
|
|
|
79
95
|
this.#l2BlockSource = deps.l2BlockSource;
|
|
80
96
|
this.#worldStateSynchronizer = deps.worldStateSynchronizer;
|
|
81
|
-
this.#
|
|
97
|
+
this.#createTxValidator = deps.createTxValidator;
|
|
98
|
+
this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
|
|
82
99
|
|
|
83
100
|
this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
|
|
84
101
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
102
|
+
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
103
|
+
this.#dateProvider = dateProvider;
|
|
104
|
+
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
|
|
85
105
|
this.#log = log;
|
|
86
106
|
this.#callbacks = callbacks;
|
|
87
107
|
|
|
@@ -97,6 +117,7 @@ export class TxPoolV2Impl {
|
|
|
97
117
|
|
|
98
118
|
// Post-event eviction rules (run after events to check ALL pending txs)
|
|
99
119
|
this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
|
|
120
|
+
this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
|
|
100
121
|
this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
|
|
101
122
|
this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
|
|
102
123
|
// LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
|
|
@@ -116,7 +137,10 @@ export class TxPoolV2Impl {
|
|
|
116
137
|
* by running pre-add rules to resolve nullifier conflicts, balance checks, and pool size limits.
|
|
117
138
|
*/
|
|
118
139
|
async hydrateFromDatabase(): Promise<void> {
|
|
119
|
-
// Step
|
|
140
|
+
// Step 0: Hydrate deleted pool state
|
|
141
|
+
await this.#deletedPool.hydrateFromDatabase();
|
|
142
|
+
|
|
143
|
+
// Step 1: Load all transactions from DB (excluding soft-deleted)
|
|
120
144
|
const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
|
|
121
145
|
|
|
122
146
|
// Step 2: Check mined status for each tx
|
|
@@ -134,7 +158,10 @@ export class TxPoolV2Impl {
|
|
|
134
158
|
}
|
|
135
159
|
|
|
136
160
|
// Step 4: Validate non-mined transactions
|
|
137
|
-
const { valid, invalid } = await this.#
|
|
161
|
+
const { valid, invalid } = await this.#revalidateMetadata(
|
|
162
|
+
nonMined.map(e => e.meta),
|
|
163
|
+
'on startup',
|
|
164
|
+
);
|
|
138
165
|
|
|
139
166
|
// Step 5: Populate mined indices (these don't need conflict resolution)
|
|
140
167
|
for (const meta of mined) {
|
|
@@ -155,16 +182,45 @@ export class TxPoolV2Impl {
|
|
|
155
182
|
await this.#txsDB.delete(txHashStr);
|
|
156
183
|
}
|
|
157
184
|
});
|
|
158
|
-
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup
|
|
185
|
+
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
|
|
159
186
|
}
|
|
160
187
|
|
|
161
|
-
async addPendingTxs(txs: Tx[], opts: { source?: string }): Promise<AddTxsResult> {
|
|
188
|
+
async addPendingTxs(txs: Tx[], opts: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult> {
|
|
162
189
|
const accepted: TxHash[] = [];
|
|
163
190
|
const ignored: TxHash[] = [];
|
|
164
191
|
const rejected: TxHash[] = [];
|
|
192
|
+
const errors = new Map<string, TxPoolRejectionError>();
|
|
165
193
|
const acceptedPending = new Set<string>();
|
|
166
194
|
|
|
195
|
+
// Phase 1: Pre-compute all throwable I/O outside the transaction.
|
|
196
|
+
// If any pre-computation throws, the entire call fails before mutations happen.
|
|
197
|
+
const precomputed = new Map<string, { meta: TxMetaData; minedBlockId: L2BlockId | undefined; isValid: boolean }>();
|
|
198
|
+
|
|
199
|
+
const validator = await this.#createTxValidator();
|
|
200
|
+
|
|
201
|
+
for (const tx of txs) {
|
|
202
|
+
const txHash = tx.getTxHash();
|
|
203
|
+
const txHashStr = txHash.toString();
|
|
204
|
+
|
|
205
|
+
const meta = await buildTxMetaData(tx);
|
|
206
|
+
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
207
|
+
|
|
208
|
+
// Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
|
|
209
|
+
let isValid = true;
|
|
210
|
+
if (!minedBlockId) {
|
|
211
|
+
isValid = await this.#validateMeta(meta, validator);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
precomputed.set(txHashStr, { meta, minedBlockId, isValid });
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Phase 2: Apply mutations inside the transaction using only pre-computed results,
|
|
218
|
+
// in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
|
|
167
219
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
220
|
+
const preAddContext: PreAddContext | undefined =
|
|
221
|
+
opts.feeComparisonOnly !== undefined
|
|
222
|
+
? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
|
|
223
|
+
: undefined;
|
|
168
224
|
|
|
169
225
|
await this.#store.transactionAsync(async () => {
|
|
170
226
|
for (const tx of txs) {
|
|
@@ -177,30 +233,46 @@ export class TxPoolV2Impl {
|
|
|
177
233
|
continue;
|
|
178
234
|
}
|
|
179
235
|
|
|
180
|
-
|
|
181
|
-
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
236
|
+
const { meta, minedBlockId, isValid } = precomputed.get(txHashStr)!;
|
|
182
237
|
const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
|
|
183
238
|
|
|
184
239
|
if (minedBlockId) {
|
|
185
240
|
// Already mined - add directly (protection already set if pre-protected)
|
|
186
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
241
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
187
242
|
accepted.push(txHash);
|
|
188
243
|
} else if (preProtectedSlot !== undefined) {
|
|
189
244
|
// Pre-protected and not mined - add as protected (bypass validation)
|
|
190
|
-
await this.#addTx(tx, { protected: preProtectedSlot }, opts);
|
|
245
|
+
await this.#addTx(tx, { protected: preProtectedSlot }, opts, meta);
|
|
191
246
|
accepted.push(txHash);
|
|
247
|
+
} else if (!isValid) {
|
|
248
|
+
// Failed pre-computed validation
|
|
249
|
+
rejected.push(txHash);
|
|
192
250
|
} else {
|
|
193
|
-
// Regular pending tx -
|
|
194
|
-
const result = await this.#tryAddRegularPendingTx(
|
|
251
|
+
// Regular pending tx - run pre-add rules using pre-computed metadata
|
|
252
|
+
const result = await this.#tryAddRegularPendingTx(
|
|
253
|
+
tx,
|
|
254
|
+
meta,
|
|
255
|
+
opts,
|
|
256
|
+
poolAccess,
|
|
257
|
+
acceptedPending,
|
|
258
|
+
ignored,
|
|
259
|
+
errors,
|
|
260
|
+
preAddContext,
|
|
261
|
+
);
|
|
195
262
|
if (result.status === 'accepted') {
|
|
196
263
|
acceptedPending.add(txHashStr);
|
|
197
|
-
} else if (result.status === 'rejected') {
|
|
198
|
-
rejected.push(txHash);
|
|
199
264
|
} else {
|
|
200
265
|
ignored.push(txHash);
|
|
201
266
|
}
|
|
202
267
|
}
|
|
203
268
|
}
|
|
269
|
+
|
|
270
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
271
|
+
if (acceptedPending.size > 0) {
|
|
272
|
+
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
273
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
274
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
275
|
+
}
|
|
204
276
|
});
|
|
205
277
|
|
|
206
278
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
@@ -208,96 +280,124 @@ export class TxPoolV2Impl {
|
|
|
208
280
|
accepted.push(TxHash.fromString(txHashStr));
|
|
209
281
|
}
|
|
210
282
|
|
|
211
|
-
//
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
283
|
+
// Record metrics
|
|
284
|
+
if (ignored.length > 0) {
|
|
285
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
286
|
+
}
|
|
287
|
+
if (rejected.length > 0) {
|
|
288
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
216
289
|
}
|
|
217
290
|
|
|
218
|
-
return { accepted, ignored, rejected };
|
|
291
|
+
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
219
292
|
}
|
|
220
293
|
|
|
221
|
-
/**
|
|
294
|
+
/** Adds a validated pending tx, running pre-add rules and evicting conflicts. */
|
|
222
295
|
async #tryAddRegularPendingTx(
|
|
223
296
|
tx: Tx,
|
|
297
|
+
precomputedMeta: TxMetaData,
|
|
224
298
|
opts: { source?: string },
|
|
225
299
|
poolAccess: PreAddPoolAccess,
|
|
226
300
|
acceptedPending: Set<string>,
|
|
227
301
|
ignored: TxHash[],
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
// Validate transaction
|
|
233
|
-
if (!(await this.#validateTx(tx))) {
|
|
234
|
-
return { status: 'rejected' };
|
|
235
|
-
}
|
|
302
|
+
errors: Map<string, TxPoolRejectionError>,
|
|
303
|
+
preAddContext?: PreAddContext,
|
|
304
|
+
): Promise<{ status: 'accepted' | 'ignored' }> {
|
|
305
|
+
const txHashStr = tx.getTxHash().toString();
|
|
236
306
|
|
|
237
|
-
//
|
|
238
|
-
const
|
|
239
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
307
|
+
// Run pre-add rules
|
|
308
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
|
|
240
309
|
|
|
241
310
|
if (preAddResult.shouldIgnore) {
|
|
242
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
311
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
312
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
313
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
314
|
+
}
|
|
243
315
|
return { status: 'ignored' };
|
|
244
316
|
}
|
|
245
317
|
|
|
246
|
-
// Evict conflicts
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
318
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
319
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
320
|
+
const byReason = new Map<string, string[]>();
|
|
321
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions) {
|
|
322
|
+
const group = byReason.get(reason);
|
|
323
|
+
if (group) {
|
|
324
|
+
group.push(evictHash);
|
|
325
|
+
} else {
|
|
326
|
+
byReason.set(reason, [evictHash]);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
for (const [reason, hashes] of byReason) {
|
|
330
|
+
await this.#evictTxs(hashes, reason);
|
|
254
331
|
}
|
|
332
|
+
for (const evictHashStr of preAddResult.txHashesToEvict) {
|
|
333
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
334
|
+
evictedTxHash: evictHashStr,
|
|
335
|
+
replacementTxHash: txHashStr,
|
|
336
|
+
});
|
|
337
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
338
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
339
|
+
acceptedPending.delete(evictHashStr);
|
|
340
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
346
|
+
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
347
|
+
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
348
|
+
return { status: 'accepted' };
|
|
255
349
|
}
|
|
256
350
|
|
|
257
351
|
// Add the transaction
|
|
258
|
-
await this.#addTx(tx, 'pending', opts);
|
|
352
|
+
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
259
353
|
return { status: 'accepted' };
|
|
260
354
|
}
|
|
261
355
|
|
|
262
|
-
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'
|
|
356
|
+
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
|
|
263
357
|
const txHashStr = tx.getTxHash().toString();
|
|
264
358
|
|
|
265
359
|
// Check if already in pool
|
|
266
360
|
if (this.#indices.has(txHashStr)) {
|
|
361
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
|
|
267
362
|
return 'ignored';
|
|
268
363
|
}
|
|
269
364
|
|
|
270
|
-
//
|
|
271
|
-
const validationResult = await this.#pendingTxValidator.validateTx(tx);
|
|
272
|
-
if (validationResult.result !== 'valid') {
|
|
273
|
-
return 'rejected';
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// Build metadata and use pre-add rules
|
|
365
|
+
// Build metadata and check pre-add rules
|
|
277
366
|
const meta = await buildTxMetaData(tx);
|
|
278
367
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
279
368
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
280
369
|
|
|
281
|
-
|
|
370
|
+
if (preAddResult.shouldIgnore) {
|
|
371
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
|
|
372
|
+
reason: preAddResult.reason?.message ?? 'no reason provided',
|
|
373
|
+
});
|
|
374
|
+
return 'ignored';
|
|
375
|
+
}
|
|
376
|
+
return 'accepted';
|
|
282
377
|
}
|
|
283
378
|
|
|
284
379
|
async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
|
|
285
380
|
const slotNumber = block.globalVariables.slotNumber;
|
|
286
381
|
|
|
382
|
+
// Precompute setup-call allow-list flags outside the store transaction
|
|
383
|
+
const allowedFlags = await Promise.all(txs.map(tx => this.#checkAllowedSetupCalls(tx)));
|
|
384
|
+
|
|
287
385
|
await this.#store.transactionAsync(async () => {
|
|
288
|
-
for (
|
|
386
|
+
for (let i = 0; i < txs.length; i++) {
|
|
387
|
+
const tx = txs[i];
|
|
289
388
|
const txHash = tx.getTxHash();
|
|
290
389
|
const txHashStr = txHash.toString();
|
|
291
390
|
const isNew = !this.#indices.has(txHashStr);
|
|
292
391
|
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
293
392
|
|
|
294
393
|
if (isNew) {
|
|
394
|
+
const meta = await buildTxMetaData(tx, allowedFlags[i]);
|
|
295
395
|
// New tx - add as mined or protected (callback emitted by #addTx)
|
|
296
396
|
if (minedBlockId) {
|
|
297
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
397
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
298
398
|
this.#indices.setProtection(txHashStr, slotNumber);
|
|
299
399
|
} else {
|
|
300
|
-
await this.#addTx(tx, { protected: slotNumber }, opts);
|
|
400
|
+
await this.#addTx(tx, { protected: slotNumber }, opts, meta);
|
|
301
401
|
}
|
|
302
402
|
} else {
|
|
303
403
|
// Existing tx - update protection and mined status
|
|
@@ -311,22 +411,57 @@ export class TxPoolV2Impl {
|
|
|
311
411
|
});
|
|
312
412
|
}
|
|
313
413
|
|
|
314
|
-
protectTxs(txHashes: TxHash[], block: BlockHeader): TxHash[] {
|
|
414
|
+
async protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
|
|
315
415
|
const slotNumber = block.globalVariables.slotNumber;
|
|
316
416
|
const missing: TxHash[] = [];
|
|
417
|
+
let softDeletedHits = 0;
|
|
418
|
+
let missingPreviouslyEvicted = 0;
|
|
317
419
|
|
|
318
|
-
|
|
319
|
-
const
|
|
420
|
+
await this.#store.transactionAsync(async () => {
|
|
421
|
+
for (const txHash of txHashes) {
|
|
422
|
+
const txHashStr = txHash.toString();
|
|
320
423
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
424
|
+
if (this.#indices.has(txHashStr)) {
|
|
425
|
+
// Update protection for existing tx
|
|
426
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
427
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
428
|
+
// Resurrect soft-deleted tx as protected
|
|
429
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
430
|
+
if (buffer) {
|
|
431
|
+
const tx = Tx.fromBuffer(buffer);
|
|
432
|
+
await this.#addTx(tx, { protected: slotNumber });
|
|
433
|
+
softDeletedHits++;
|
|
434
|
+
} else {
|
|
435
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
436
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
437
|
+
missing.push(txHash);
|
|
438
|
+
}
|
|
439
|
+
} else {
|
|
440
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
441
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
442
|
+
missing.push(txHash);
|
|
443
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
444
|
+
missingPreviouslyEvicted++;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
328
447
|
}
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
// Record metrics
|
|
451
|
+
if (softDeletedHits > 0) {
|
|
452
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
453
|
+
}
|
|
454
|
+
if (missing.length > 0) {
|
|
455
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map(h => h.toString()).join(', ')}`);
|
|
456
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
329
457
|
}
|
|
458
|
+
if (missingPreviouslyEvicted > 0) {
|
|
459
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
this.#log.info(
|
|
463
|
+
`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`,
|
|
464
|
+
);
|
|
330
465
|
|
|
331
466
|
return missing;
|
|
332
467
|
}
|
|
@@ -347,6 +482,7 @@ export class TxPoolV2Impl {
|
|
|
347
482
|
// Add new mined tx (callback emitted by #addTx)
|
|
348
483
|
await this.#addTx(tx, { mined: blockId }, opts);
|
|
349
484
|
}
|
|
485
|
+
await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
|
|
350
486
|
}
|
|
351
487
|
});
|
|
352
488
|
}
|
|
@@ -370,53 +506,67 @@ export class TxPoolV2Impl {
|
|
|
370
506
|
}
|
|
371
507
|
}
|
|
372
508
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
509
|
+
await this.#store.transactionAsync(async () => {
|
|
510
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
511
|
+
for (const meta of found) {
|
|
512
|
+
this.#indices.markAsMined(meta, blockId);
|
|
513
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
517
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
518
|
+
});
|
|
377
519
|
|
|
378
|
-
|
|
379
|
-
|
|
520
|
+
if (found.length > 0) {
|
|
521
|
+
this.#callbacks.onTxsMined(found.map(m => m.txHash));
|
|
522
|
+
}
|
|
380
523
|
|
|
381
524
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
382
525
|
}
|
|
383
526
|
|
|
384
527
|
async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
|
|
385
|
-
|
|
386
|
-
|
|
528
|
+
await this.#store.transactionAsync(async () => {
|
|
529
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
530
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
387
531
|
|
|
388
|
-
|
|
389
|
-
|
|
532
|
+
// Step 1: Find expired protected txs
|
|
533
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
390
534
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
535
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
536
|
+
this.#indices.clearProtection(expiredProtected);
|
|
537
|
+
|
|
538
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
539
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
540
|
+
if (txsToRestore.length === 0) {
|
|
541
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
396
544
|
|
|
397
|
-
|
|
545
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
398
546
|
|
|
399
|
-
|
|
400
|
-
|
|
547
|
+
// Step 4: Validate for pending pool
|
|
548
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
401
549
|
|
|
402
|
-
|
|
403
|
-
|
|
550
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
551
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
404
552
|
|
|
405
|
-
|
|
406
|
-
|
|
553
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
554
|
+
await this.#deleteTxsBatch(invalid);
|
|
555
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
407
556
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
557
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
558
|
+
if (added.length > 0) {
|
|
559
|
+
const feePayers = added.map(meta => meta.feePayer);
|
|
560
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
561
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
562
|
+
added.map(m => m.txHash),
|
|
563
|
+
[...uniqueFeePayers],
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
});
|
|
417
567
|
}
|
|
418
568
|
|
|
419
|
-
async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
|
|
569
|
+
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
420
570
|
// Step 1: Find transactions mined after the prune point
|
|
421
571
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
422
572
|
if (txsToUnmine.length === 0) {
|
|
@@ -426,64 +576,99 @@ export class TxPoolV2Impl {
|
|
|
426
576
|
|
|
427
577
|
this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
|
|
428
578
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
579
|
+
await this.#store.transactionAsync(async () => {
|
|
580
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
581
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
582
|
+
// when their original mined block is finalized
|
|
583
|
+
await this.#deletedPool.markFromPrunedBlock(
|
|
584
|
+
txsToUnmine.map(m => ({
|
|
585
|
+
txHash: m.txHash,
|
|
586
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
|
|
587
|
+
})),
|
|
588
|
+
);
|
|
589
|
+
|
|
590
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
591
|
+
for (const meta of txsToUnmine) {
|
|
592
|
+
this.#indices.markAsUnmined(meta);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
596
|
+
if (options?.deleteAllTxs) {
|
|
597
|
+
const allTxHashes = txsToUnmine.map(m => m.txHash);
|
|
598
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
599
|
+
this.#log.info(
|
|
600
|
+
`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
|
|
601
|
+
);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
606
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
433
607
|
|
|
434
|
-
|
|
435
|
-
|
|
608
|
+
// Step 5: Validate for pending pool
|
|
609
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
436
610
|
|
|
437
|
-
|
|
438
|
-
|
|
611
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
612
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
439
613
|
|
|
440
|
-
|
|
441
|
-
|
|
614
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
615
|
+
await this.#deleteTxsBatch(invalid);
|
|
616
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
442
617
|
|
|
443
|
-
|
|
444
|
-
|
|
618
|
+
this.#log.info(
|
|
619
|
+
`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
|
|
620
|
+
{ txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
|
|
621
|
+
);
|
|
445
622
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
623
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
624
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
625
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
626
|
+
});
|
|
449
627
|
}
|
|
450
628
|
|
|
451
629
|
async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
|
|
452
|
-
|
|
453
|
-
|
|
630
|
+
await this.#store.transactionAsync(async () => {
|
|
631
|
+
await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
|
|
632
|
+
});
|
|
454
633
|
|
|
455
|
-
this.#log.info(`Deleted ${txHashes.length} failed txs
|
|
634
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
|
|
456
635
|
}
|
|
457
636
|
|
|
458
637
|
async handleFinalizedBlock(block: BlockHeader): Promise<void> {
|
|
459
638
|
const blockNumber = block.globalVariables.blockNumber;
|
|
460
639
|
|
|
461
|
-
// Step 1: Find txs
|
|
462
|
-
const
|
|
463
|
-
if (txsToFinalize.length === 0) {
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
640
|
+
// Step 1: Find mined txs at or before finalized block
|
|
641
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
466
642
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
643
|
+
await this.#store.transactionAsync(async () => {
|
|
644
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
645
|
+
const txsToArchive: Tx[] = [];
|
|
646
|
+
if (this.#archive.isEnabled()) {
|
|
647
|
+
for (const txHashStr of minedTxsToFinalize) {
|
|
648
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
649
|
+
if (buffer) {
|
|
650
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
651
|
+
}
|
|
474
652
|
}
|
|
475
653
|
}
|
|
476
|
-
}
|
|
477
654
|
|
|
478
|
-
|
|
479
|
-
|
|
655
|
+
// Step 3: Delete mined txs from active pool
|
|
656
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
480
657
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
await this.#archive.archiveTxs(txsToArchive);
|
|
484
|
-
}
|
|
658
|
+
// Step 4: Finalize soft-deleted txs
|
|
659
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
485
660
|
|
|
486
|
-
|
|
661
|
+
// Step 5: Archive mined txs
|
|
662
|
+
if (txsToArchive.length > 0) {
|
|
663
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
if (minedTxsToFinalize.length > 0) {
|
|
668
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
669
|
+
txHashes: minedTxsToFinalize,
|
|
670
|
+
});
|
|
671
|
+
}
|
|
487
672
|
}
|
|
488
673
|
|
|
489
674
|
// === Query Methods ===
|
|
@@ -503,21 +688,36 @@ export class TxPoolV2Impl {
|
|
|
503
688
|
}
|
|
504
689
|
|
|
505
690
|
hasTxs(txHashes: TxHash[]): boolean[] {
|
|
506
|
-
return txHashes.map(h =>
|
|
691
|
+
return txHashes.map(h => {
|
|
692
|
+
const hashStr = h.toString();
|
|
693
|
+
return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
|
|
694
|
+
});
|
|
507
695
|
}
|
|
508
696
|
|
|
509
697
|
getTxStatus(txHash: TxHash): TxState | undefined {
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
698
|
+
const txHashStr = txHash.toString();
|
|
699
|
+
const meta = this.#indices.getMetadata(txHashStr);
|
|
700
|
+
if (meta) {
|
|
701
|
+
return this.#indices.getTxState(meta);
|
|
702
|
+
}
|
|
703
|
+
// Check if soft-deleted
|
|
704
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
705
|
+
return 'deleted';
|
|
513
706
|
}
|
|
514
|
-
return
|
|
707
|
+
return undefined;
|
|
515
708
|
}
|
|
516
709
|
|
|
517
710
|
getPendingTxHashes(): TxHash[] {
|
|
518
711
|
return [...this.#indices.iteratePendingByPriority('desc')].map(hash => TxHash.fromString(hash));
|
|
519
712
|
}
|
|
520
713
|
|
|
714
|
+
getEligiblePendingTxHashes(): TxHash[] {
|
|
715
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
716
|
+
return [...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)].map(hash =>
|
|
717
|
+
TxHash.fromString(hash),
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
|
|
521
721
|
getPendingTxCount(): number {
|
|
522
722
|
return this.#indices.getPendingTxCount();
|
|
523
723
|
}
|
|
@@ -562,6 +762,9 @@ export class TxPoolV2Impl {
|
|
|
562
762
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
563
763
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
564
764
|
}
|
|
765
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
766
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
767
|
+
}
|
|
565
768
|
// Update eviction rules with new config
|
|
566
769
|
this.#evictionManager.updateConfig(config);
|
|
567
770
|
}
|
|
@@ -579,8 +782,17 @@ export class TxPoolV2Impl {
|
|
|
579
782
|
|
|
580
783
|
// === Metrics ===
|
|
581
784
|
|
|
582
|
-
countTxs(): {
|
|
583
|
-
|
|
785
|
+
countTxs(): {
|
|
786
|
+
pending: number;
|
|
787
|
+
protected: number;
|
|
788
|
+
mined: number;
|
|
789
|
+
softDeleted: number;
|
|
790
|
+
totalMetadataBytes: number;
|
|
791
|
+
} {
|
|
792
|
+
return {
|
|
793
|
+
...this.#indices.countTxs(),
|
|
794
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount(),
|
|
795
|
+
};
|
|
584
796
|
}
|
|
585
797
|
|
|
586
798
|
// ============================================================================
|
|
@@ -595,11 +807,14 @@ export class TxPoolV2Impl {
|
|
|
595
807
|
tx: Tx,
|
|
596
808
|
state: 'pending' | { protected: SlotNumber } | { mined: L2BlockId },
|
|
597
809
|
opts: { source?: string } = {},
|
|
810
|
+
precomputedMeta?: TxMetaData,
|
|
598
811
|
): Promise<TxMetaData> {
|
|
599
812
|
const txHashStr = tx.getTxHash().toString();
|
|
600
|
-
const meta = await buildTxMetaData(tx);
|
|
813
|
+
const meta = precomputedMeta ?? (await buildTxMetaData(tx));
|
|
814
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
601
815
|
|
|
602
816
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
817
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
603
818
|
this.#callbacks.onTxsAdded([tx], opts);
|
|
604
819
|
|
|
605
820
|
if (state === 'pending') {
|
|
@@ -612,9 +827,11 @@ export class TxPoolV2Impl {
|
|
|
612
827
|
}
|
|
613
828
|
|
|
614
829
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
615
|
-
this.#log.
|
|
830
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
616
831
|
eventName: 'tx-added-to-pool',
|
|
832
|
+
txHash: txHashStr,
|
|
617
833
|
state: stateStr,
|
|
834
|
+
source: opts.source,
|
|
618
835
|
});
|
|
619
836
|
|
|
620
837
|
return meta;
|
|
@@ -624,10 +841,15 @@ export class TxPoolV2Impl {
|
|
|
624
841
|
* Deletes a transaction from both indices and DB.
|
|
625
842
|
* Emits onTxsRemoved callback immediately after DB delete.
|
|
626
843
|
*/
|
|
844
|
+
/**
|
|
845
|
+
* Deletes a transaction from the pool.
|
|
846
|
+
* Delegates to DeletedPool which decides soft vs hard delete based on whether
|
|
847
|
+
* the tx is from a pruned block.
|
|
848
|
+
*/
|
|
627
849
|
async #deleteTx(txHashStr: string): Promise<void> {
|
|
628
850
|
this.#indices.remove(txHashStr);
|
|
629
|
-
await this.#txsDB.delete(txHashStr);
|
|
630
851
|
this.#callbacks.onTxsRemoved([txHashStr]);
|
|
852
|
+
await this.#deletedPool.deleteTx(txHashStr);
|
|
631
853
|
}
|
|
632
854
|
|
|
633
855
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */
|
|
@@ -637,68 +859,63 @@ export class TxPoolV2Impl {
|
|
|
637
859
|
}
|
|
638
860
|
}
|
|
639
861
|
|
|
862
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */
|
|
863
|
+
async #evictTxs(txHashes: string[], reason: string): Promise<void> {
|
|
864
|
+
if (txHashes.length === 0) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
868
|
+
for (const txHashStr of txHashes) {
|
|
869
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
870
|
+
this.#addToEvictedCache(txHashStr);
|
|
871
|
+
}
|
|
872
|
+
await this.#deleteTxsBatch(txHashes);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
|
|
876
|
+
#addToEvictedCache(txHashStr: string): void {
|
|
877
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
878
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
879
|
+
const oldest = this.#evictedTxHashes.values().next().value!;
|
|
880
|
+
this.#evictedTxHashes.delete(oldest);
|
|
881
|
+
}
|
|
882
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
883
|
+
}
|
|
884
|
+
|
|
640
885
|
// ============================================================================
|
|
641
886
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
642
887
|
// ============================================================================
|
|
643
888
|
|
|
644
|
-
/** Validates
|
|
645
|
-
async #
|
|
646
|
-
const
|
|
889
|
+
/** Validates transaction metadata, returning true if valid */
|
|
890
|
+
async #validateMeta(meta: TxMetaData, validator?: TxValidator<TxMetaData>, context?: string): Promise<boolean> {
|
|
891
|
+
const txValidator = validator ?? (await this.#createTxValidator());
|
|
892
|
+
const result = await txValidator.validateTx(meta);
|
|
647
893
|
if (result.result !== 'valid') {
|
|
648
894
|
const contextStr = context ? ` ${context}` : '';
|
|
649
|
-
this.#log.info(`Tx ${
|
|
895
|
+
this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
|
|
650
896
|
return false;
|
|
651
897
|
}
|
|
652
898
|
return true;
|
|
653
899
|
}
|
|
654
900
|
|
|
655
|
-
/**
|
|
656
|
-
async #
|
|
657
|
-
|
|
658
|
-
const missing: string[] = [];
|
|
659
|
-
|
|
660
|
-
for (const meta of metas) {
|
|
661
|
-
const buffer = await this.#txsDB.getAsync(meta.txHash);
|
|
662
|
-
if (!buffer) {
|
|
663
|
-
this.#log.warn(`Tx ${meta.txHash} not found in DB`);
|
|
664
|
-
missing.push(meta.txHash);
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
loaded.push({ tx: Tx.fromBuffer(buffer), meta });
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
return { loaded, missing };
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
/** Validates a batch of transactions, returning valid and invalid groups */
|
|
674
|
-
async #validateTxBatch(
|
|
675
|
-
txs: { tx: Tx; meta: TxMetaData }[],
|
|
901
|
+
/** Validates metadata directly */
|
|
902
|
+
async #revalidateMetadata(
|
|
903
|
+
metas: TxMetaData[],
|
|
676
904
|
context?: string,
|
|
677
905
|
): Promise<{ valid: TxMetaData[]; invalid: string[] }> {
|
|
678
906
|
const valid: TxMetaData[] = [];
|
|
679
907
|
const invalid: string[] = [];
|
|
680
|
-
|
|
681
|
-
for (const
|
|
682
|
-
if (await this.#
|
|
908
|
+
const validator = await this.#createTxValidator();
|
|
909
|
+
for (const meta of metas) {
|
|
910
|
+
if (await this.#validateMeta(meta, validator, context)) {
|
|
683
911
|
valid.push(meta);
|
|
684
912
|
} else {
|
|
685
913
|
invalid.push(meta.txHash);
|
|
686
914
|
}
|
|
687
915
|
}
|
|
688
|
-
|
|
689
916
|
return { valid, invalid };
|
|
690
917
|
}
|
|
691
918
|
|
|
692
|
-
/** Loads transactions from DB and validates them */
|
|
693
|
-
async #loadAndValidateTxs(
|
|
694
|
-
metas: TxMetaData[],
|
|
695
|
-
context?: string,
|
|
696
|
-
): Promise<{ valid: TxMetaData[]; invalid: string[] }> {
|
|
697
|
-
const { loaded, missing } = await this.#loadTxsFromDb(metas);
|
|
698
|
-
const { valid, invalid } = await this.#validateTxBatch(loaded, context);
|
|
699
|
-
return { valid, invalid: [...missing, ...invalid] };
|
|
700
|
-
}
|
|
701
|
-
|
|
702
919
|
/**
|
|
703
920
|
* Resolves nullifier conflicts between incoming txs and existing pending txs.
|
|
704
921
|
* Modifies the pending indices during iteration to maintain consistent state
|
|
@@ -768,9 +985,15 @@ export class TxPoolV2Impl {
|
|
|
768
985
|
const errors: string[] = [];
|
|
769
986
|
|
|
770
987
|
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
988
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
989
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
|
|
771
993
|
try {
|
|
772
994
|
const tx = Tx.fromBuffer(buffer);
|
|
773
|
-
const
|
|
995
|
+
const allowedSetupCalls = await this.#checkAllowedSetupCalls(tx);
|
|
996
|
+
const meta = await buildTxMetaData(tx, allowedSetupCalls);
|
|
774
997
|
loaded.push({ tx, meta });
|
|
775
998
|
} catch (err) {
|
|
776
999
|
this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
|
|
@@ -815,7 +1038,9 @@ export class TxPoolV2Impl {
|
|
|
815
1038
|
if (preAddResult.shouldIgnore) {
|
|
816
1039
|
// Transaction rejected - mark for deletion from DB
|
|
817
1040
|
rejected.push(meta.txHash);
|
|
818
|
-
this.#log.debug(
|
|
1041
|
+
this.#log.debug(
|
|
1042
|
+
`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`,
|
|
1043
|
+
);
|
|
819
1044
|
continue;
|
|
820
1045
|
}
|
|
821
1046
|
|
|
@@ -851,7 +1076,7 @@ export class TxPoolV2Impl {
|
|
|
851
1076
|
getFeePayerPendingTxs: (feePayer: string) => this.#indices.getFeePayerPendingTxs(feePayer),
|
|
852
1077
|
getPendingTxCount: () => this.#indices.getPendingTxCount(),
|
|
853
1078
|
getLowestPriorityPending: (limit: number) => this.#indices.getLowestPriorityPending(limit),
|
|
854
|
-
deleteTxs: (txHashes: string[]) => this.#
|
|
1079
|
+
deleteTxs: (txHashes: string[], reason?: string) => this.#evictTxs(txHashes, reason ?? 'unknown'),
|
|
855
1080
|
};
|
|
856
1081
|
}
|
|
857
1082
|
|