@aztec/p2p 0.0.1-commit.e558bd1c → 0.0.1-commit.e57c76e
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/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +9 -1
- package/dest/client/factory.d.ts +11 -10
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +58 -16
- package/dest/client/interface.d.ts +51 -36
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +48 -57
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +219 -236
- package/dest/config.d.ts +161 -94
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +150 -41
- 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/reqresp.error.d.ts +1 -20
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/errors/reqresp.error.js +0 -21
- 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 +104 -55
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +295 -195
- 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 +231 -115
- 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/archive/tx_archive.d.ts +1 -5
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +1 -7
- 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 +407 -241
- 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 +4 -5
- 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 +56 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +10 -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 +10 -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 +21 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +90 -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 +11 -18
- 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 +25 -21
- 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/cached_tx_validator.d.ts +15 -0
- package/dest/msg_validators/tx_validator/cached_tx_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/cached_tx_validator.js +19 -0
- 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 +2 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +36 -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 +135 -7
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +252 -61
- 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 +5 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +4 -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/msg_validators/tx_validator/tx_proof_validator.d.ts +2 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +2 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +48 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/tx_validation_cache.js +68 -0
- 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/discv5/discV5_service.d.ts +2 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +35 -8
- package/dest/services/dummy_service.d.ts +18 -18
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +19 -20
- 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 +56 -55
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +449 -397
- 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 +40 -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 +5 -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 +95 -127
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +11 -11
- 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.d.ts +5 -14
- package/dest/services/reqresp/batch-tx-requester/tx_validator.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +6 -20
- 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 +25 -18
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +23 -19
- 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/bitvector.d.ts +4 -3
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
- 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_handler.js +31 -28
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +18 -7
- 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 +57 -24
- 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 +7 -29
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +53 -218
- package/dest/services/service.d.ts +30 -14
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +11 -14
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +26 -33
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +37 -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 +127 -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 +3 -3
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -1
- package/dest/services/tx_collection/instrumentation.js +1 -2
- 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/tx_collection.d.ts +45 -51
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +296 -68
- package/dest/services/tx_collection/tx_collection_sink.d.ts +19 -9
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +28 -31
- 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 -5
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
- package/dest/services/tx_file_store/tx_file_store.js +13 -20
- package/dest/services/tx_provider.d.ts +6 -4
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +12 -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 +5 -3
- package/dest/test-helpers/mock-pubsub.d.ts +46 -6
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +115 -14
- package/dest/test-helpers/reqresp-nodes.d.ts +5 -7
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +19 -20
- package/dest/test-helpers/test_tx_provider.d.ts +3 -1
- package/dest/test-helpers/test_tx_provider.d.ts.map +1 -1
- package/dest/test-helpers/test_tx_provider.js +3 -0
- package/dest/test-helpers/testbench-utils.d.ts +46 -37
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +142 -50
- package/dest/testbench/p2p_client_testbench_worker.d.ts +3 -5
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +93 -47
- package/dest/testbench/worker_client_manager.d.ts +12 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +57 -11
- package/dest/util.d.ts +13 -8
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +35 -14
- package/dest/versioning.d.ts +3 -6
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +3 -24
- package/package.json +15 -14
- package/src/bootstrap/bootstrap.ts +9 -1
- package/src/client/factory.ts +124 -27
- package/src/client/interface.ts +58 -44
- package/src/client/p2p_client.ts +256 -299
- package/src/client/test/{tx_proposal_collector/README.md → p2p_client.batch_tx_requester.bench.README.md} +23 -53
- package/src/config.ts +260 -46
- package/src/errors/p2p-service.error.ts +11 -0
- package/src/errors/reqresp.error.ts +0 -25
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +363 -236
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +258 -118
- 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/archive/tx_archive.ts +1 -9
- 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 +448 -240
- 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 +14 -7
- package/src/msg_validators/clock_tolerance.ts +73 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +24 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +35 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +114 -47
- package/src/msg_validators/tx_validator/README.md +127 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +8 -17
- 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/cached_tx_validator.ts +31 -0
- package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +44 -1
- package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
- package/src/msg_validators/tx_validator/factory.ts +407 -80
- 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 +4 -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/msg_validators/tx_validator/tx_proof_validator.ts +2 -0
- package/src/msg_validators/tx_validator/tx_validation_cache.ts +101 -0
- package/src/services/data_store.ts +5 -13
- package/src/services/discv5/discV5_service.ts +38 -5
- package/src/services/dummy_service.ts +26 -45
- 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 +497 -453
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +46 -11
- package/src/services/peer-manager/peer_scoring.ts +52 -5
- package/src/services/reqresp/README.md +215 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +92 -138
- package/src/services/reqresp/batch-tx-requester/interface.ts +14 -10
- 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 +12 -25
- package/src/services/reqresp/config.ts +2 -2
- package/src/services/reqresp/interface.ts +45 -46
- package/src/services/reqresp/metrics.ts +0 -1
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +36 -32
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +64 -20
- 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 +61 -264
- package/src/services/service.ts +43 -30
- package/src/services/tx_collection/config.ts +40 -49
- package/src/services/tx_collection/file_store_tx_collection.ts +153 -0
- package/src/services/tx_collection/file_store_tx_source.ts +129 -0
- package/src/services/tx_collection/index.ts +2 -6
- package/src/services/tx_collection/instrumentation.ts +1 -1
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/tx_collection.ts +362 -110
- package/src/services/tx_collection/tx_collection_sink.ts +32 -36
- 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 +15 -25
- package/src/services/tx_provider.ts +15 -9
- package/src/test-helpers/make-test-p2p-clients.ts +7 -6
- package/src/test-helpers/mock-pubsub.ts +137 -14
- package/src/test-helpers/reqresp-nodes.ts +17 -29
- package/src/test-helpers/test_tx_provider.ts +5 -0
- package/src/test-helpers/testbench-utils.ts +168 -68
- package/src/testbench/p2p_client_testbench_worker.ts +99 -62
- package/src/testbench/worker_client_manager.ts +72 -25
- package/src/util.ts +40 -19
- package/src/versioning.ts +3 -33
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts +0 -2
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.d.ts.map +0 -1
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +0 -305
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts +0 -73
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.d.ts.map +0 -1
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.js +0 -8
- 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/connection-sampler/batch_connection_sampler.d.ts +0 -64
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +0 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +0 -151
- 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/dest/services/tx_collection/fast_tx_collection.d.ts +0 -52
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +0 -1
- package/dest/services/tx_collection/fast_tx_collection.js +0 -307
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +0 -48
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +0 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +0 -49
- package/dest/services/tx_collection/slow_tx_collection.d.ts +0 -53
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +0 -1
- package/dest/services/tx_collection/slow_tx_collection.js +0 -177
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +0 -336
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker_protocol.ts +0 -43
- 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/connection-sampler/batch_connection_sampler.ts +0 -161
- package/src/services/reqresp/protocols/block.ts +0 -37
- package/src/services/tx_collection/fast_tx_collection.ts +0 -354
- package/src/services/tx_collection/proposal_tx_collector.ts +0 -112
- package/src/services/tx_collection/slow_tx_collection.ts +0 -233
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
|
+
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { FifoSet } from '@aztec/foundation/fifo-set';
|
|
2
3
|
import type { Logger } from '@aztec/foundation/log';
|
|
4
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
3
5
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
4
6
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
5
7
|
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
@@ -8,20 +10,27 @@ import type { L2Block, L2BlockId, L2BlockSource } from '@aztec/stdlib/block';
|
|
|
8
10
|
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
9
11
|
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
10
12
|
import { BlockHeader, Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx';
|
|
13
|
+
import type { TelemetryClient } from '@aztec/telemetry-client';
|
|
11
14
|
|
|
12
15
|
import { TxArchive } from './archive/index.js';
|
|
16
|
+
import { DeletedPool } from './deleted_pool.js';
|
|
13
17
|
import {
|
|
14
18
|
EvictionManager,
|
|
15
19
|
FeePayerBalanceEvictionRule,
|
|
16
20
|
FeePayerBalancePreAddRule,
|
|
21
|
+
InsufficientFeePerGasEvictionRule,
|
|
17
22
|
InvalidTxsAfterMiningRule,
|
|
18
23
|
InvalidTxsAfterReorgRule,
|
|
19
24
|
LowPriorityEvictionRule,
|
|
20
25
|
LowPriorityPreAddRule,
|
|
21
26
|
NullifierConflictRule,
|
|
22
27
|
type PoolOperations,
|
|
28
|
+
type PreAddContext,
|
|
23
29
|
type PreAddPoolAccess,
|
|
30
|
+
TxPoolRejectionCode,
|
|
31
|
+
type TxPoolRejectionError,
|
|
24
32
|
} from './eviction/index.js';
|
|
33
|
+
import { TxPoolV2Instrumentation } from './instrumentation.js';
|
|
25
34
|
import {
|
|
26
35
|
type AddTxsResult,
|
|
27
36
|
DEFAULT_TX_POOL_V2_CONFIG,
|
|
@@ -32,12 +41,20 @@ import {
|
|
|
32
41
|
import { type TxMetaData, type TxState, buildTxMetaData, checkNullifierConflict } from './tx_metadata.js';
|
|
33
42
|
import { TxPoolIndices } from './tx_pool_indices.js';
|
|
34
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Maximum number of full transactions to load into memory at once when finalizing a block.
|
|
46
|
+
* Bounds peak memory while archiving and hard-deleting mined txs (~23k txs/epoch at 10 TPS would
|
|
47
|
+
* otherwise OOM the node).
|
|
48
|
+
*/
|
|
49
|
+
const FINALIZE_BLOCK_CHUNK_SIZE = 100;
|
|
50
|
+
|
|
35
51
|
/**
|
|
36
52
|
* Callbacks for the implementation to notify the outer class about events and metrics.
|
|
37
53
|
*/
|
|
38
54
|
export interface TxPoolV2Callbacks {
|
|
39
55
|
onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
|
|
40
56
|
onTxsRemoved: (txHashes: string[] | bigint[]) => void;
|
|
57
|
+
onTxsMined: (txHashes: string[]) => void;
|
|
41
58
|
}
|
|
42
59
|
|
|
43
60
|
/**
|
|
@@ -53,7 +70,8 @@ export class TxPoolV2Impl {
|
|
|
53
70
|
// === Dependencies ===
|
|
54
71
|
#l2BlockSource: L2BlockSource;
|
|
55
72
|
#worldStateSynchronizer: WorldStateSynchronizer;
|
|
56
|
-
#
|
|
73
|
+
#createTxValidator: TxPoolV2Dependencies['createTxValidator'];
|
|
74
|
+
#checkAllowedSetupCalls: TxPoolV2Dependencies['checkAllowedSetupCalls'];
|
|
57
75
|
|
|
58
76
|
// === In-Memory Indices ===
|
|
59
77
|
#indices: TxPoolIndices = new TxPoolIndices();
|
|
@@ -61,7 +79,11 @@ export class TxPoolV2Impl {
|
|
|
61
79
|
// === Config & Services ===
|
|
62
80
|
#config: TxPoolV2Config;
|
|
63
81
|
#archive: TxArchive;
|
|
82
|
+
#deletedPool: DeletedPool;
|
|
64
83
|
#evictionManager: EvictionManager;
|
|
84
|
+
#dateProvider: DateProvider;
|
|
85
|
+
#instrumentation: TxPoolV2Instrumentation;
|
|
86
|
+
#evictedTxHashes: FifoSet<string>;
|
|
65
87
|
#log: Logger;
|
|
66
88
|
#callbacks: TxPoolV2Callbacks;
|
|
67
89
|
|
|
@@ -70,7 +92,9 @@ export class TxPoolV2Impl {
|
|
|
70
92
|
archiveStore: AztecAsyncKVStore,
|
|
71
93
|
deps: TxPoolV2Dependencies,
|
|
72
94
|
callbacks: TxPoolV2Callbacks,
|
|
95
|
+
telemetry: TelemetryClient,
|
|
73
96
|
config: Partial<TxPoolV2Config> = {},
|
|
97
|
+
dateProvider: DateProvider,
|
|
74
98
|
log: Logger,
|
|
75
99
|
) {
|
|
76
100
|
this.#store = store;
|
|
@@ -78,10 +102,15 @@ export class TxPoolV2Impl {
|
|
|
78
102
|
|
|
79
103
|
this.#l2BlockSource = deps.l2BlockSource;
|
|
80
104
|
this.#worldStateSynchronizer = deps.worldStateSynchronizer;
|
|
81
|
-
this.#
|
|
105
|
+
this.#createTxValidator = deps.createTxValidator;
|
|
106
|
+
this.#checkAllowedSetupCalls = deps.checkAllowedSetupCalls;
|
|
82
107
|
|
|
83
108
|
this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
|
|
109
|
+
this.#evictedTxHashes = FifoSet.withLimit<string>(this.#config.evictedTxCacheSize);
|
|
84
110
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
111
|
+
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
112
|
+
this.#dateProvider = dateProvider;
|
|
113
|
+
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
|
|
85
114
|
this.#log = log;
|
|
86
115
|
this.#callbacks = callbacks;
|
|
87
116
|
|
|
@@ -97,6 +126,7 @@ export class TxPoolV2Impl {
|
|
|
97
126
|
|
|
98
127
|
// Post-event eviction rules (run after events to check ALL pending txs)
|
|
99
128
|
this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
|
|
129
|
+
this.#evictionManager.registerRule(new InsufficientFeePerGasEvictionRule(deps.blockMinFeesProvider));
|
|
100
130
|
this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(deps.worldStateSynchronizer));
|
|
101
131
|
this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(deps.worldStateSynchronizer));
|
|
102
132
|
// LowPriorityEvictionRule handles cases where txs become pending via prepareForSlot (unprotect)
|
|
@@ -116,36 +146,70 @@ export class TxPoolV2Impl {
|
|
|
116
146
|
* by running pre-add rules to resolve nullifier conflicts, balance checks, and pool size limits.
|
|
117
147
|
*/
|
|
118
148
|
async hydrateFromDatabase(): Promise<void> {
|
|
119
|
-
// Step
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// Step
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (
|
|
130
|
-
|
|
149
|
+
// Step 0: Hydrate deleted pool state
|
|
150
|
+
await this.#deletedPool.hydrateFromDatabase();
|
|
151
|
+
|
|
152
|
+
// Step 1: Stream txs from DB, building metadata and mined status one at a time.
|
|
153
|
+
const minedMetas: TxMetaData[] = [];
|
|
154
|
+
const pendingMetas: TxMetaData[] = [];
|
|
155
|
+
const deserializationErrors: string[] = [];
|
|
156
|
+
|
|
157
|
+
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
158
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
159
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let meta: TxMetaData;
|
|
164
|
+
let txEffect: Awaited<ReturnType<L2BlockSource['getTxEffect']>>;
|
|
165
|
+
try {
|
|
166
|
+
const tx = Tx.fromBuffer(buffer);
|
|
167
|
+
// Resolve allowed-setup-calls and the tx effect concurrently
|
|
168
|
+
// getTxEffect failures are non-fatal (we just treat the tx as not-yet-mined), so
|
|
169
|
+
// its rejection is swallowed before the Promise.all so it can't fail-fast the batch.
|
|
170
|
+
const txEffectPromise = this.#l2BlockSource.getTxEffect(tx.getTxHash()).catch(err => {
|
|
171
|
+
this.#log.warn(`Failed to check mined status for tx ${txHashStr}`, { err });
|
|
172
|
+
return undefined;
|
|
173
|
+
});
|
|
174
|
+
const [allowedSetupCalls, fetchedTxEffect] = await Promise.all([
|
|
175
|
+
this.#checkAllowedSetupCalls(tx),
|
|
176
|
+
txEffectPromise,
|
|
177
|
+
]);
|
|
178
|
+
meta = await buildTxMetaData(tx, allowedSetupCalls);
|
|
179
|
+
txEffect = fetchedTxEffect;
|
|
180
|
+
} catch (err) {
|
|
181
|
+
this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
|
|
182
|
+
deserializationErrors.push(txHashStr);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (txEffect) {
|
|
187
|
+
meta.minedL2BlockId = {
|
|
188
|
+
number: txEffect.l2BlockNumber,
|
|
189
|
+
hash: txEffect.l2BlockHash.toString(),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (meta.minedL2BlockId !== undefined) {
|
|
194
|
+
minedMetas.push(meta);
|
|
131
195
|
} else {
|
|
132
|
-
|
|
196
|
+
pendingMetas.push(meta);
|
|
133
197
|
}
|
|
134
198
|
}
|
|
135
199
|
|
|
136
|
-
// Step
|
|
137
|
-
const { valid, invalid } = await this.#
|
|
200
|
+
// Step 2: Validate non-mined transactions
|
|
201
|
+
const { valid, invalid } = await this.#revalidateMetadata(pendingMetas, 'on startup');
|
|
138
202
|
|
|
139
|
-
// Step
|
|
140
|
-
for (const meta of
|
|
203
|
+
// Step 3: Populate mined indices (these don't need conflict resolution)
|
|
204
|
+
for (const meta of minedMetas) {
|
|
141
205
|
this.#indices.addMined(meta);
|
|
142
206
|
}
|
|
143
207
|
|
|
144
|
-
// Step
|
|
208
|
+
// Step 4: Rebuild pending pool by running pre-add rules for each tx
|
|
145
209
|
// This resolves nullifier conflicts, fee payer balance issues, and pool size limits
|
|
146
210
|
const { rejected } = await this.#rebuildPendingPool(valid);
|
|
147
211
|
|
|
148
|
-
// Step
|
|
212
|
+
// Step 5: Delete invalid and rejected txs from DB only (indices were never populated for these)
|
|
149
213
|
const toDelete = [...deserializationErrors, ...invalid, ...rejected];
|
|
150
214
|
if (toDelete.length === 0) {
|
|
151
215
|
return;
|
|
@@ -155,16 +219,45 @@ export class TxPoolV2Impl {
|
|
|
155
219
|
await this.#txsDB.delete(txHashStr);
|
|
156
220
|
}
|
|
157
221
|
});
|
|
158
|
-
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup
|
|
222
|
+
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
|
|
159
223
|
}
|
|
160
224
|
|
|
161
|
-
async addPendingTxs(txs: Tx[], opts: { source?: string }): Promise<AddTxsResult> {
|
|
225
|
+
async addPendingTxs(txs: Tx[], opts: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult> {
|
|
162
226
|
const accepted: TxHash[] = [];
|
|
163
227
|
const ignored: TxHash[] = [];
|
|
164
228
|
const rejected: TxHash[] = [];
|
|
229
|
+
const errors = new Map<string, TxPoolRejectionError>();
|
|
165
230
|
const acceptedPending = new Set<string>();
|
|
166
231
|
|
|
232
|
+
// Phase 1: Pre-compute all throwable I/O outside the transaction.
|
|
233
|
+
// If any pre-computation throws, the entire call fails before mutations happen.
|
|
234
|
+
const precomputed = new Map<string, { meta: TxMetaData; minedBlockId: L2BlockId | undefined; isValid: boolean }>();
|
|
235
|
+
|
|
236
|
+
const validator = await this.#createTxValidator();
|
|
237
|
+
|
|
238
|
+
for (const tx of txs) {
|
|
239
|
+
const txHash = tx.getTxHash();
|
|
240
|
+
const txHashStr = txHash.toString();
|
|
241
|
+
|
|
242
|
+
const meta = await buildTxMetaData(tx);
|
|
243
|
+
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
244
|
+
|
|
245
|
+
// Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
|
|
246
|
+
let isValid = true;
|
|
247
|
+
if (!minedBlockId) {
|
|
248
|
+
isValid = await this.#validateMeta(meta, validator);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
precomputed.set(txHashStr, { meta, minedBlockId, isValid });
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Phase 2: Apply mutations inside the transaction using only pre-computed results,
|
|
255
|
+
// in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
|
|
167
256
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
257
|
+
const preAddContext: PreAddContext | undefined =
|
|
258
|
+
opts.feeComparisonOnly !== undefined
|
|
259
|
+
? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
|
|
260
|
+
: undefined;
|
|
168
261
|
|
|
169
262
|
await this.#store.transactionAsync(async () => {
|
|
170
263
|
for (const tx of txs) {
|
|
@@ -177,30 +270,46 @@ export class TxPoolV2Impl {
|
|
|
177
270
|
continue;
|
|
178
271
|
}
|
|
179
272
|
|
|
180
|
-
|
|
181
|
-
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
273
|
+
const { meta, minedBlockId, isValid } = precomputed.get(txHashStr)!;
|
|
182
274
|
const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
|
|
183
275
|
|
|
184
276
|
if (minedBlockId) {
|
|
185
277
|
// Already mined - add directly (protection already set if pre-protected)
|
|
186
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
278
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
187
279
|
accepted.push(txHash);
|
|
188
280
|
} else if (preProtectedSlot !== undefined) {
|
|
189
281
|
// Pre-protected and not mined - add as protected (bypass validation)
|
|
190
|
-
await this.#addTx(tx, { protected: preProtectedSlot }, opts);
|
|
282
|
+
await this.#addTx(tx, { protected: preProtectedSlot }, opts, meta);
|
|
191
283
|
accepted.push(txHash);
|
|
284
|
+
} else if (!isValid) {
|
|
285
|
+
// Failed pre-computed validation
|
|
286
|
+
rejected.push(txHash);
|
|
192
287
|
} else {
|
|
193
|
-
// Regular pending tx -
|
|
194
|
-
const result = await this.#tryAddRegularPendingTx(
|
|
288
|
+
// Regular pending tx - run pre-add rules using pre-computed metadata
|
|
289
|
+
const result = await this.#tryAddRegularPendingTx(
|
|
290
|
+
tx,
|
|
291
|
+
meta,
|
|
292
|
+
opts,
|
|
293
|
+
poolAccess,
|
|
294
|
+
acceptedPending,
|
|
295
|
+
ignored,
|
|
296
|
+
errors,
|
|
297
|
+
preAddContext,
|
|
298
|
+
);
|
|
195
299
|
if (result.status === 'accepted') {
|
|
196
300
|
acceptedPending.add(txHashStr);
|
|
197
|
-
} else if (result.status === 'rejected') {
|
|
198
|
-
rejected.push(txHash);
|
|
199
301
|
} else {
|
|
200
302
|
ignored.push(txHash);
|
|
201
303
|
}
|
|
202
304
|
}
|
|
203
305
|
}
|
|
306
|
+
|
|
307
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
308
|
+
if (acceptedPending.size > 0) {
|
|
309
|
+
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
310
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
311
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
312
|
+
}
|
|
204
313
|
});
|
|
205
314
|
|
|
206
315
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
@@ -208,96 +317,124 @@ export class TxPoolV2Impl {
|
|
|
208
317
|
accepted.push(TxHash.fromString(txHashStr));
|
|
209
318
|
}
|
|
210
319
|
|
|
211
|
-
//
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
320
|
+
// Record metrics
|
|
321
|
+
if (ignored.length > 0) {
|
|
322
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
323
|
+
}
|
|
324
|
+
if (rejected.length > 0) {
|
|
325
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
216
326
|
}
|
|
217
327
|
|
|
218
|
-
return { accepted, ignored, rejected };
|
|
328
|
+
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
219
329
|
}
|
|
220
330
|
|
|
221
|
-
/**
|
|
331
|
+
/** Adds a validated pending tx, running pre-add rules and evicting conflicts. */
|
|
222
332
|
async #tryAddRegularPendingTx(
|
|
223
333
|
tx: Tx,
|
|
334
|
+
precomputedMeta: TxMetaData,
|
|
224
335
|
opts: { source?: string },
|
|
225
336
|
poolAccess: PreAddPoolAccess,
|
|
226
337
|
acceptedPending: Set<string>,
|
|
227
338
|
ignored: TxHash[],
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
// Validate transaction
|
|
233
|
-
if (!(await this.#validateTx(tx))) {
|
|
234
|
-
return { status: 'rejected' };
|
|
235
|
-
}
|
|
339
|
+
errors: Map<string, TxPoolRejectionError>,
|
|
340
|
+
preAddContext?: PreAddContext,
|
|
341
|
+
): Promise<{ status: 'accepted' | 'ignored' }> {
|
|
342
|
+
const txHashStr = tx.getTxHash().toString();
|
|
236
343
|
|
|
237
|
-
//
|
|
238
|
-
const
|
|
239
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
344
|
+
// Run pre-add rules
|
|
345
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
|
|
240
346
|
|
|
241
347
|
if (preAddResult.shouldIgnore) {
|
|
242
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
348
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
349
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
350
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
351
|
+
}
|
|
243
352
|
return { status: 'ignored' };
|
|
244
353
|
}
|
|
245
354
|
|
|
246
|
-
// Evict conflicts
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
355
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
356
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
357
|
+
const byReason = new Map<string, string[]>();
|
|
358
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions) {
|
|
359
|
+
const group = byReason.get(reason);
|
|
360
|
+
if (group) {
|
|
361
|
+
group.push(evictHash);
|
|
362
|
+
} else {
|
|
363
|
+
byReason.set(reason, [evictHash]);
|
|
364
|
+
}
|
|
254
365
|
}
|
|
366
|
+
for (const [reason, hashes] of byReason) {
|
|
367
|
+
await this.#evictTxs(hashes, reason);
|
|
368
|
+
}
|
|
369
|
+
for (const evictHashStr of preAddResult.txHashesToEvict) {
|
|
370
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
371
|
+
evictedTxHash: evictHashStr,
|
|
372
|
+
replacementTxHash: txHashStr,
|
|
373
|
+
});
|
|
374
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
375
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
376
|
+
acceptedPending.delete(evictHashStr);
|
|
377
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
383
|
+
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
384
|
+
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
385
|
+
return { status: 'accepted' };
|
|
255
386
|
}
|
|
256
387
|
|
|
257
388
|
// Add the transaction
|
|
258
|
-
await this.#addTx(tx, 'pending', opts);
|
|
389
|
+
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
259
390
|
return { status: 'accepted' };
|
|
260
391
|
}
|
|
261
392
|
|
|
262
|
-
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'
|
|
393
|
+
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
|
|
263
394
|
const txHashStr = tx.getTxHash().toString();
|
|
264
395
|
|
|
265
396
|
// Check if already in pool
|
|
266
397
|
if (this.#indices.has(txHashStr)) {
|
|
398
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
|
|
267
399
|
return 'ignored';
|
|
268
400
|
}
|
|
269
401
|
|
|
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
|
|
402
|
+
// Build metadata and check pre-add rules
|
|
277
403
|
const meta = await buildTxMetaData(tx);
|
|
278
404
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
279
405
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
280
406
|
|
|
281
|
-
|
|
407
|
+
if (preAddResult.shouldIgnore) {
|
|
408
|
+
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
|
|
409
|
+
reason: preAddResult.reason?.message ?? 'no reason provided',
|
|
410
|
+
});
|
|
411
|
+
return 'ignored';
|
|
412
|
+
}
|
|
413
|
+
return 'accepted';
|
|
282
414
|
}
|
|
283
415
|
|
|
284
416
|
async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
|
|
285
417
|
const slotNumber = block.globalVariables.slotNumber;
|
|
286
418
|
|
|
419
|
+
// Precompute setup-call allow-list flags outside the store transaction
|
|
420
|
+
const allowedFlags = await Promise.all(txs.map(tx => this.#checkAllowedSetupCalls(tx)));
|
|
421
|
+
|
|
287
422
|
await this.#store.transactionAsync(async () => {
|
|
288
|
-
for (
|
|
423
|
+
for (let i = 0; i < txs.length; i++) {
|
|
424
|
+
const tx = txs[i];
|
|
289
425
|
const txHash = tx.getTxHash();
|
|
290
426
|
const txHashStr = txHash.toString();
|
|
291
427
|
const isNew = !this.#indices.has(txHashStr);
|
|
292
428
|
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
293
429
|
|
|
294
430
|
if (isNew) {
|
|
431
|
+
const meta = await buildTxMetaData(tx, allowedFlags[i]);
|
|
295
432
|
// New tx - add as mined or protected (callback emitted by #addTx)
|
|
296
433
|
if (minedBlockId) {
|
|
297
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
434
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
298
435
|
this.#indices.setProtection(txHashStr, slotNumber);
|
|
299
436
|
} else {
|
|
300
|
-
await this.#addTx(tx, { protected: slotNumber }, opts);
|
|
437
|
+
await this.#addTx(tx, { protected: slotNumber }, opts, meta);
|
|
301
438
|
}
|
|
302
439
|
} else {
|
|
303
440
|
// Existing tx - update protection and mined status
|
|
@@ -311,22 +448,57 @@ export class TxPoolV2Impl {
|
|
|
311
448
|
});
|
|
312
449
|
}
|
|
313
450
|
|
|
314
|
-
protectTxs(txHashes: TxHash[], block: BlockHeader): TxHash[] {
|
|
451
|
+
async protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
|
|
315
452
|
const slotNumber = block.globalVariables.slotNumber;
|
|
316
453
|
const missing: TxHash[] = [];
|
|
454
|
+
let softDeletedHits = 0;
|
|
455
|
+
let missingPreviouslyEvicted = 0;
|
|
317
456
|
|
|
318
|
-
|
|
319
|
-
const
|
|
457
|
+
await this.#store.transactionAsync(async () => {
|
|
458
|
+
for (const txHash of txHashes) {
|
|
459
|
+
const txHashStr = txHash.toString();
|
|
320
460
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
461
|
+
if (this.#indices.has(txHashStr)) {
|
|
462
|
+
// Update protection for existing tx
|
|
463
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
464
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
465
|
+
// Resurrect soft-deleted tx as protected
|
|
466
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
467
|
+
if (buffer) {
|
|
468
|
+
const tx = Tx.fromBuffer(buffer);
|
|
469
|
+
await this.#addTx(tx, { protected: slotNumber });
|
|
470
|
+
softDeletedHits++;
|
|
471
|
+
} else {
|
|
472
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
473
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
474
|
+
missing.push(txHash);
|
|
475
|
+
}
|
|
476
|
+
} else {
|
|
477
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
478
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
479
|
+
missing.push(txHash);
|
|
480
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
481
|
+
missingPreviouslyEvicted++;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
328
484
|
}
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// Record metrics
|
|
488
|
+
if (softDeletedHits > 0) {
|
|
489
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
490
|
+
}
|
|
491
|
+
if (missing.length > 0) {
|
|
492
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map(h => h.toString()).join(', ')}`);
|
|
493
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
329
494
|
}
|
|
495
|
+
if (missingPreviouslyEvicted > 0) {
|
|
496
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
this.#log.info(
|
|
500
|
+
`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`,
|
|
501
|
+
);
|
|
330
502
|
|
|
331
503
|
return missing;
|
|
332
504
|
}
|
|
@@ -347,6 +519,7 @@ export class TxPoolV2Impl {
|
|
|
347
519
|
// Add new mined tx (callback emitted by #addTx)
|
|
348
520
|
await this.#addTx(tx, { mined: blockId }, opts);
|
|
349
521
|
}
|
|
522
|
+
await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
|
|
350
523
|
}
|
|
351
524
|
});
|
|
352
525
|
}
|
|
@@ -370,53 +543,67 @@ export class TxPoolV2Impl {
|
|
|
370
543
|
}
|
|
371
544
|
}
|
|
372
545
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
546
|
+
await this.#store.transactionAsync(async () => {
|
|
547
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
548
|
+
for (const meta of found) {
|
|
549
|
+
this.#indices.markAsMined(meta, blockId);
|
|
550
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
554
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
555
|
+
});
|
|
377
556
|
|
|
378
|
-
|
|
379
|
-
|
|
557
|
+
if (found.length > 0) {
|
|
558
|
+
this.#callbacks.onTxsMined(found.map(m => m.txHash));
|
|
559
|
+
}
|
|
380
560
|
|
|
381
561
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
382
562
|
}
|
|
383
563
|
|
|
384
564
|
async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
|
|
385
|
-
|
|
386
|
-
|
|
565
|
+
await this.#store.transactionAsync(async () => {
|
|
566
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
567
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
387
568
|
|
|
388
|
-
|
|
389
|
-
|
|
569
|
+
// Step 1: Find expired protected txs
|
|
570
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
390
571
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
if (txsToRestore.length === 0) {
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
572
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
573
|
+
this.#indices.clearProtection(expiredProtected);
|
|
396
574
|
|
|
397
|
-
|
|
575
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
576
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
577
|
+
if (txsToRestore.length === 0) {
|
|
578
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
398
581
|
|
|
399
|
-
|
|
400
|
-
const { valid, invalid } = await this.#loadAndValidateTxs(txsToRestore, 'during prepareForSlot');
|
|
582
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
401
583
|
|
|
402
|
-
|
|
403
|
-
|
|
584
|
+
// Step 4: Validate for pending pool
|
|
585
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
404
586
|
|
|
405
|
-
|
|
406
|
-
|
|
587
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
588
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
407
589
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
590
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
591
|
+
await this.#deleteTxsBatch(invalid);
|
|
592
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
593
|
+
|
|
594
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
595
|
+
if (added.length > 0) {
|
|
596
|
+
const feePayers = added.map(meta => meta.feePayer);
|
|
597
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
598
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
599
|
+
added.map(m => m.txHash),
|
|
600
|
+
[...uniqueFeePayers],
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
});
|
|
417
604
|
}
|
|
418
605
|
|
|
419
|
-
async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
|
|
606
|
+
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
420
607
|
// Step 1: Find transactions mined after the prune point
|
|
421
608
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
422
609
|
if (txsToUnmine.length === 0) {
|
|
@@ -426,64 +613,100 @@ export class TxPoolV2Impl {
|
|
|
426
613
|
|
|
427
614
|
this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
|
|
428
615
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
616
|
+
await this.#store.transactionAsync(async () => {
|
|
617
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
618
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
619
|
+
// when their original mined block is finalized
|
|
620
|
+
await this.#deletedPool.markFromPrunedBlock(
|
|
621
|
+
txsToUnmine.map(m => ({
|
|
622
|
+
txHash: m.txHash,
|
|
623
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
|
|
624
|
+
})),
|
|
625
|
+
);
|
|
433
626
|
|
|
434
|
-
|
|
435
|
-
|
|
627
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
628
|
+
for (const meta of txsToUnmine) {
|
|
629
|
+
this.#indices.markAsUnmined(meta);
|
|
630
|
+
}
|
|
436
631
|
|
|
437
|
-
|
|
438
|
-
|
|
632
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
633
|
+
if (options?.deleteAllTxs) {
|
|
634
|
+
const allTxHashes = txsToUnmine.map(m => m.txHash);
|
|
635
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
636
|
+
this.#log.info(
|
|
637
|
+
`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
|
|
638
|
+
);
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
643
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
644
|
+
|
|
645
|
+
// Step 5: Validate for pending pool
|
|
646
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
647
|
+
|
|
648
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
649
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
439
650
|
|
|
440
|
-
|
|
441
|
-
|
|
651
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
652
|
+
await this.#deleteTxsBatch(invalid);
|
|
653
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
442
654
|
|
|
443
|
-
|
|
444
|
-
|
|
655
|
+
this.#log.info(
|
|
656
|
+
`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
|
|
657
|
+
{ txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
|
|
658
|
+
);
|
|
445
659
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
660
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
661
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
662
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
663
|
+
});
|
|
449
664
|
}
|
|
450
665
|
|
|
451
666
|
async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
|
|
452
|
-
|
|
453
|
-
|
|
667
|
+
await this.#store.transactionAsync(async () => {
|
|
668
|
+
await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
|
|
669
|
+
});
|
|
454
670
|
|
|
455
|
-
this.#log.info(`Deleted ${txHashes.length} failed txs
|
|
671
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
|
|
456
672
|
}
|
|
457
673
|
|
|
458
674
|
async handleFinalizedBlock(block: BlockHeader): Promise<void> {
|
|
459
675
|
const blockNumber = block.globalVariables.blockNumber;
|
|
460
676
|
|
|
461
|
-
// Step 1: Find txs
|
|
462
|
-
const
|
|
463
|
-
if (txsToFinalize.length === 0) {
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
677
|
+
// Step 1: Find mined txs at or before finalized block
|
|
678
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
466
679
|
|
|
467
|
-
// Step 2:
|
|
468
|
-
|
|
680
|
+
// Step 2: Archive in chunks if archiving is enabled. Hydrating an entire epoch's worth of
|
|
681
|
+
// mined txs at once would OOM under load. When archiving is disabled there is no need to hydrate the txs at all.
|
|
469
682
|
if (this.#archive.isEnabled()) {
|
|
470
|
-
for (
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
683
|
+
for (let i = 0; i < minedTxsToFinalize.length; i += FINALIZE_BLOCK_CHUNK_SIZE) {
|
|
684
|
+
const chunk = minedTxsToFinalize.slice(i, i + FINALIZE_BLOCK_CHUNK_SIZE);
|
|
685
|
+
const txsToArchive: Tx[] = [];
|
|
686
|
+
for (const txHashStr of chunk) {
|
|
687
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
688
|
+
if (buffer) {
|
|
689
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
if (txsToArchive.length > 0) {
|
|
693
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
474
694
|
}
|
|
475
695
|
}
|
|
476
696
|
}
|
|
477
697
|
|
|
478
|
-
// Step 3: Delete from active pool
|
|
479
|
-
|
|
698
|
+
// Step 3: Delete mined txs from the active pool and finalize soft-deleted txs in one
|
|
699
|
+
// transaction. Only tx hashes are touched here, so memory is bounded and atomicity is preserved.
|
|
700
|
+
await this.#store.transactionAsync(async () => {
|
|
701
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
702
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
703
|
+
});
|
|
480
704
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
705
|
+
if (minedTxsToFinalize.length > 0) {
|
|
706
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
707
|
+
txHashes: minedTxsToFinalize,
|
|
708
|
+
});
|
|
484
709
|
}
|
|
485
|
-
|
|
486
|
-
this.#log.info(`Finalized ${txsToFinalize.length} txs from blocks up to ${blockNumber}`);
|
|
487
710
|
}
|
|
488
711
|
|
|
489
712
|
// === Query Methods ===
|
|
@@ -503,21 +726,36 @@ export class TxPoolV2Impl {
|
|
|
503
726
|
}
|
|
504
727
|
|
|
505
728
|
hasTxs(txHashes: TxHash[]): boolean[] {
|
|
506
|
-
return txHashes.map(h =>
|
|
729
|
+
return txHashes.map(h => {
|
|
730
|
+
const hashStr = h.toString();
|
|
731
|
+
return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
|
|
732
|
+
});
|
|
507
733
|
}
|
|
508
734
|
|
|
509
735
|
getTxStatus(txHash: TxHash): TxState | undefined {
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
736
|
+
const txHashStr = txHash.toString();
|
|
737
|
+
const meta = this.#indices.getMetadata(txHashStr);
|
|
738
|
+
if (meta) {
|
|
739
|
+
return this.#indices.getTxState(meta);
|
|
513
740
|
}
|
|
514
|
-
|
|
741
|
+
// Check if soft-deleted
|
|
742
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
743
|
+
return 'deleted';
|
|
744
|
+
}
|
|
745
|
+
return undefined;
|
|
515
746
|
}
|
|
516
747
|
|
|
517
748
|
getPendingTxHashes(): TxHash[] {
|
|
518
749
|
return [...this.#indices.iteratePendingByPriority('desc')].map(hash => TxHash.fromString(hash));
|
|
519
750
|
}
|
|
520
751
|
|
|
752
|
+
getEligiblePendingTxHashes(): TxHash[] {
|
|
753
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
754
|
+
return [...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)].map(hash =>
|
|
755
|
+
TxHash.fromString(hash),
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
|
|
521
759
|
getPendingTxCount(): number {
|
|
522
760
|
return this.#indices.getPendingTxCount();
|
|
523
761
|
}
|
|
@@ -562,6 +800,9 @@ export class TxPoolV2Impl {
|
|
|
562
800
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
563
801
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
564
802
|
}
|
|
803
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
804
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
805
|
+
}
|
|
565
806
|
// Update eviction rules with new config
|
|
566
807
|
this.#evictionManager.updateConfig(config);
|
|
567
808
|
}
|
|
@@ -579,8 +820,17 @@ export class TxPoolV2Impl {
|
|
|
579
820
|
|
|
580
821
|
// === Metrics ===
|
|
581
822
|
|
|
582
|
-
countTxs(): {
|
|
583
|
-
|
|
823
|
+
countTxs(): {
|
|
824
|
+
pending: number;
|
|
825
|
+
protected: number;
|
|
826
|
+
mined: number;
|
|
827
|
+
softDeleted: number;
|
|
828
|
+
totalMetadataBytes: number;
|
|
829
|
+
} {
|
|
830
|
+
return {
|
|
831
|
+
...this.#indices.countTxs(),
|
|
832
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount(),
|
|
833
|
+
};
|
|
584
834
|
}
|
|
585
835
|
|
|
586
836
|
// ============================================================================
|
|
@@ -595,11 +845,14 @@ export class TxPoolV2Impl {
|
|
|
595
845
|
tx: Tx,
|
|
596
846
|
state: 'pending' | { protected: SlotNumber } | { mined: L2BlockId },
|
|
597
847
|
opts: { source?: string } = {},
|
|
848
|
+
precomputedMeta?: TxMetaData,
|
|
598
849
|
): Promise<TxMetaData> {
|
|
599
850
|
const txHashStr = tx.getTxHash().toString();
|
|
600
|
-
const meta = await buildTxMetaData(tx);
|
|
851
|
+
const meta = precomputedMeta ?? (await buildTxMetaData(tx));
|
|
852
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
601
853
|
|
|
602
854
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
855
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
603
856
|
this.#callbacks.onTxsAdded([tx], opts);
|
|
604
857
|
|
|
605
858
|
if (state === 'pending') {
|
|
@@ -612,9 +865,11 @@ export class TxPoolV2Impl {
|
|
|
612
865
|
}
|
|
613
866
|
|
|
614
867
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
615
|
-
this.#log.
|
|
868
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
616
869
|
eventName: 'tx-added-to-pool',
|
|
870
|
+
txHash: txHashStr,
|
|
617
871
|
state: stateStr,
|
|
872
|
+
source: opts.source,
|
|
618
873
|
});
|
|
619
874
|
|
|
620
875
|
return meta;
|
|
@@ -624,10 +879,15 @@ export class TxPoolV2Impl {
|
|
|
624
879
|
* Deletes a transaction from both indices and DB.
|
|
625
880
|
* Emits onTxsRemoved callback immediately after DB delete.
|
|
626
881
|
*/
|
|
882
|
+
/**
|
|
883
|
+
* Deletes a transaction from the pool.
|
|
884
|
+
* Delegates to DeletedPool which decides soft vs hard delete based on whether
|
|
885
|
+
* the tx is from a pruned block.
|
|
886
|
+
*/
|
|
627
887
|
async #deleteTx(txHashStr: string): Promise<void> {
|
|
628
888
|
this.#indices.remove(txHashStr);
|
|
629
|
-
await this.#txsDB.delete(txHashStr);
|
|
630
889
|
this.#callbacks.onTxsRemoved([txHashStr]);
|
|
890
|
+
await this.#deletedPool.deleteTx(txHashStr);
|
|
631
891
|
}
|
|
632
892
|
|
|
633
893
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */
|
|
@@ -637,68 +897,53 @@ export class TxPoolV2Impl {
|
|
|
637
897
|
}
|
|
638
898
|
}
|
|
639
899
|
|
|
900
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */
|
|
901
|
+
async #evictTxs(txHashes: string[], reason: string): Promise<void> {
|
|
902
|
+
if (txHashes.length === 0) {
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
906
|
+
for (const txHashStr of txHashes) {
|
|
907
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
908
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
909
|
+
}
|
|
910
|
+
await this.#deleteTxsBatch(txHashes);
|
|
911
|
+
}
|
|
912
|
+
|
|
640
913
|
// ============================================================================
|
|
641
914
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
642
915
|
// ============================================================================
|
|
643
916
|
|
|
644
|
-
/** Validates
|
|
645
|
-
async #
|
|
646
|
-
const
|
|
917
|
+
/** Validates transaction metadata, returning true if valid */
|
|
918
|
+
async #validateMeta(meta: TxMetaData, validator?: TxValidator<TxMetaData>, context?: string): Promise<boolean> {
|
|
919
|
+
const txValidator = validator ?? (await this.#createTxValidator());
|
|
920
|
+
const result = await txValidator.validateTx(meta);
|
|
647
921
|
if (result.result !== 'valid') {
|
|
648
922
|
const contextStr = context ? ` ${context}` : '';
|
|
649
|
-
this.#log.info(`Tx ${
|
|
923
|
+
this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
|
|
650
924
|
return false;
|
|
651
925
|
}
|
|
652
926
|
return true;
|
|
653
927
|
}
|
|
654
928
|
|
|
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 }[],
|
|
929
|
+
/** Validates metadata directly */
|
|
930
|
+
async #revalidateMetadata(
|
|
931
|
+
metas: TxMetaData[],
|
|
676
932
|
context?: string,
|
|
677
933
|
): Promise<{ valid: TxMetaData[]; invalid: string[] }> {
|
|
678
934
|
const valid: TxMetaData[] = [];
|
|
679
935
|
const invalid: string[] = [];
|
|
680
|
-
|
|
681
|
-
for (const
|
|
682
|
-
if (await this.#
|
|
936
|
+
const validator = await this.#createTxValidator();
|
|
937
|
+
for (const meta of metas) {
|
|
938
|
+
if (await this.#validateMeta(meta, validator, context)) {
|
|
683
939
|
valid.push(meta);
|
|
684
940
|
} else {
|
|
685
941
|
invalid.push(meta.txHash);
|
|
686
942
|
}
|
|
687
943
|
}
|
|
688
|
-
|
|
689
944
|
return { valid, invalid };
|
|
690
945
|
}
|
|
691
946
|
|
|
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
947
|
/**
|
|
703
948
|
* Resolves nullifier conflicts between incoming txs and existing pending txs.
|
|
704
949
|
* Modifies the pending indices during iteration to maintain consistent state
|
|
@@ -759,45 +1004,6 @@ export class TxPoolV2Impl {
|
|
|
759
1004
|
};
|
|
760
1005
|
}
|
|
761
1006
|
|
|
762
|
-
/** Loads all transactions from the database, returning loaded txs and deserialization errors */
|
|
763
|
-
async #loadAllTxsFromDb(): Promise<{
|
|
764
|
-
loaded: { tx: Tx; meta: TxMetaData }[];
|
|
765
|
-
errors: string[];
|
|
766
|
-
}> {
|
|
767
|
-
const loaded: { tx: Tx; meta: TxMetaData }[] = [];
|
|
768
|
-
const errors: string[] = [];
|
|
769
|
-
|
|
770
|
-
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
771
|
-
try {
|
|
772
|
-
const tx = Tx.fromBuffer(buffer);
|
|
773
|
-
const meta = await buildTxMetaData(tx);
|
|
774
|
-
loaded.push({ tx, meta });
|
|
775
|
-
} catch (err) {
|
|
776
|
-
this.#log.warn(`Failed to deserialize tx ${txHashStr}, deleting`, { err });
|
|
777
|
-
errors.push(txHashStr);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
return { loaded, errors };
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
/** Queries block source and marks mined status on transaction metadata */
|
|
785
|
-
async #markMinedStatusBatch(metas: TxMetaData[]): Promise<void> {
|
|
786
|
-
for (const meta of metas) {
|
|
787
|
-
try {
|
|
788
|
-
const txEffect = await this.#l2BlockSource.getTxEffect(TxHash.fromString(meta.txHash));
|
|
789
|
-
if (txEffect) {
|
|
790
|
-
meta.minedL2BlockId = {
|
|
791
|
-
number: txEffect.l2BlockNumber,
|
|
792
|
-
hash: txEffect.l2BlockHash.toString(),
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
|
-
} catch (err) {
|
|
796
|
-
this.#log.warn(`Failed to check mined status for tx ${meta.txHash}`, { err });
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
|
|
801
1007
|
/**
|
|
802
1008
|
* Rebuilds the pending pool by processing each tx through pre-add rules.
|
|
803
1009
|
* Starts with an empty pending pool and adds txs one by one, resolving conflicts.
|
|
@@ -815,7 +1021,9 @@ export class TxPoolV2Impl {
|
|
|
815
1021
|
if (preAddResult.shouldIgnore) {
|
|
816
1022
|
// Transaction rejected - mark for deletion from DB
|
|
817
1023
|
rejected.push(meta.txHash);
|
|
818
|
-
this.#log.debug(
|
|
1024
|
+
this.#log.debug(
|
|
1025
|
+
`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`,
|
|
1026
|
+
);
|
|
819
1027
|
continue;
|
|
820
1028
|
}
|
|
821
1029
|
|
|
@@ -851,7 +1059,7 @@ export class TxPoolV2Impl {
|
|
|
851
1059
|
getFeePayerPendingTxs: (feePayer: string) => this.#indices.getFeePayerPendingTxs(feePayer),
|
|
852
1060
|
getPendingTxCount: () => this.#indices.getPendingTxCount(),
|
|
853
1061
|
getLowestPriorityPending: (limit: number) => this.#indices.getLowestPriorityPending(limit),
|
|
854
|
-
deleteTxs: (txHashes: string[]) => this.#
|
|
1062
|
+
deleteTxs: (txHashes: string[], reason?: string) => this.#evictTxs(txHashes, reason ?? 'unknown'),
|
|
855
1063
|
};
|
|
856
1064
|
}
|
|
857
1065
|
|