@aztec/p2p 0.0.1-commit.6d63667d → 0.0.1-commit.7ac86ea28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/client/factory.d.ts +7 -6
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +46 -11
- package/dest/client/interface.d.ts +43 -23
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +38 -42
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +145 -145
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -6
- package/dest/config.d.ts +23 -4
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +16 -1
- package/dest/errors/tx-pool.error.d.ts +8 -0
- package/dest/errors/tx-pool.error.d.ts.map +1 -0
- package/dest/errors/tx-pool.error.js +9 -0
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -88
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +441 -3
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +353 -87
- package/dest/mem_pools/attestation_pool/index.d.ts +2 -3
- package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/index.js +1 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -2
- package/dest/mem_pools/index.d.ts +3 -2
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/index.js +1 -1
- package/dest/mem_pools/interface.d.ts +5 -5
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +104 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +251 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +4 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +10 -4
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +48 -5
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +5 -3
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +1 -1
- 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 +8 -4
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +14 -4
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -1
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +16 -4
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +31 -5
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +62 -5
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +27 -4
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +8 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +11 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -4
- 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 +239 -109
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +3 -3
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +3 -3
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +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/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/timestamp_validator.d.ts +20 -4
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
- package/dest/services/dummy_service.d.ts +12 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +9 -0
- package/dest/services/encoding.d.ts +2 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +4 -3
- package/dest/services/gossipsub/index.d.ts +3 -0
- package/dest/services/gossipsub/index.d.ts.map +1 -0
- package/dest/services/gossipsub/index.js +2 -0
- package/dest/services/gossipsub/scoring.d.ts +21 -3
- package/dest/services/gossipsub/scoring.d.ts.map +1 -1
- package/dest/services/gossipsub/scoring.js +24 -7
- package/dest/services/gossipsub/topic_score_params.d.ts +173 -0
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -0
- package/dest/services/gossipsub/topic_score_params.js +346 -0
- package/dest/services/libp2p/libp2p_service.d.ts +85 -35
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +370 -267
- package/dest/services/peer-manager/peer_scoring.d.ts +1 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +25 -2
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +5 -9
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
- package/dest/services/reqresp/interface.d.ts +10 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +15 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +4 -3
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +7 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +15 -0
- package/dest/services/reqresp/protocols/tx.d.ts +7 -1
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +20 -0
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +11 -4
- package/dest/services/service.d.ts +38 -2
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +19 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +46 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +3 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +56 -36
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_collection.js +167 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts +37 -0
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/file_store_tx_source.js +90 -0
- package/dest/services/tx_collection/index.d.ts +2 -1
- package/dest/services/tx_collection/index.d.ts.map +1 -1
- package/dest/services/tx_collection/index.js +1 -0
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +2 -1
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
- package/dest/services/tx_collection/slow_tx_collection.d.ts +7 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +60 -26
- package/dest/services/tx_collection/tx_collection.d.ts +23 -10
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +75 -3
- package/dest/services/tx_collection/tx_collection_sink.d.ts +18 -8
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +26 -29
- package/dest/services/tx_collection/tx_source.d.ts +8 -3
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +19 -2
- package/dest/services/tx_file_store/config.d.ts +1 -3
- package/dest/services/tx_file_store/config.d.ts.map +1 -1
- package/dest/services/tx_file_store/config.js +0 -4
- package/dest/services/tx_file_store/tx_file_store.d.ts +4 -3
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
- package/dest/services/tx_file_store/tx_file_store.js +9 -6
- package/dest/services/tx_provider.d.ts +3 -3
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +5 -4
- package/dest/test-helpers/make-test-p2p-clients.d.ts +3 -3
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +29 -2
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +103 -2
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -1
- package/dest/test-helpers/testbench-utils.d.ts +43 -38
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +128 -59
- package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +10 -10
- package/dest/util.d.ts +2 -2
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +86 -15
- package/src/client/interface.ts +59 -23
- package/src/client/p2p_client.ts +184 -167
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +19 -9
- package/src/config.ts +34 -2
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +496 -91
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +442 -102
- package/src/mem_pools/attestation_pool/index.ts +9 -2
- package/src/mem_pools/attestation_pool/mocks.ts +2 -1
- package/src/mem_pools/index.ts +4 -1
- package/src/mem_pools/interface.ts +4 -4
- package/src/mem_pools/tx_pool/README.md +1 -1
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/README.md +76 -10
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +321 -0
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +4 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +15 -4
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +49 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +8 -7
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +24 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/index.ts +1 -0
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +16 -4
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +90 -9
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +32 -5
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +17 -6
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +274 -104
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +2 -2
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +2 -2
- package/src/msg_validators/tx_validator/block_header_validator.ts +15 -3
- package/src/msg_validators/tx_validator/double_spend_validator.ts +11 -6
- package/src/msg_validators/tx_validator/timestamp_validator.ts +23 -18
- package/src/services/dummy_service.ts +17 -1
- package/src/services/encoding.ts +4 -3
- package/src/services/gossipsub/README.md +641 -0
- package/src/services/gossipsub/index.ts +2 -0
- package/src/services/gossipsub/scoring.ts +29 -5
- package/src/services/gossipsub/topic_score_params.ts +487 -0
- package/src/services/libp2p/libp2p_service.ts +367 -271
- package/src/services/peer-manager/peer_scoring.ts +25 -0
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +6 -6
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
- package/src/services/reqresp/interface.ts +26 -1
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +4 -3
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +17 -0
- package/src/services/reqresp/protocols/tx.ts +22 -0
- package/src/services/reqresp/reqresp.ts +13 -3
- package/src/services/service.ts +50 -1
- package/src/services/tx_collection/config.ts +68 -0
- package/src/services/tx_collection/fast_tx_collection.ts +65 -32
- package/src/services/tx_collection/file_store_tx_collection.ts +202 -0
- package/src/services/tx_collection/file_store_tx_source.ts +117 -0
- package/src/services/tx_collection/index.ts +1 -0
- package/src/services/tx_collection/instrumentation.ts +7 -1
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
- package/src/services/tx_collection/slow_tx_collection.ts +66 -33
- package/src/services/tx_collection/tx_collection.ts +113 -16
- package/src/services/tx_collection/tx_collection_sink.ts +30 -34
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_file_store/config.ts +0 -6
- package/src/services/tx_file_store/tx_file_store.ts +10 -8
- package/src/services/tx_provider.ts +8 -7
- package/src/test-helpers/make-test-p2p-clients.ts +3 -3
- package/src/test-helpers/mock-pubsub.ts +143 -3
- package/src/test-helpers/reqresp-nodes.ts +2 -1
- package/src/test-helpers/testbench-utils.ts +127 -71
- package/src/testbench/p2p_client_testbench_worker.ts +22 -15
- package/src/util.ts +7 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +0 -40
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +0 -218
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +0 -31
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +0 -180
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +0 -320
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +0 -264
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
|
+
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import type { Logger } from '@aztec/foundation/log';
|
|
3
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
3
4
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
4
5
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
5
6
|
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
@@ -8,8 +9,10 @@ import type { L2Block, L2BlockId, L2BlockSource } from '@aztec/stdlib/block';
|
|
|
8
9
|
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
9
10
|
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
10
11
|
import { BlockHeader, Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx';
|
|
12
|
+
import type { TelemetryClient } from '@aztec/telemetry-client';
|
|
11
13
|
|
|
12
14
|
import { TxArchive } from './archive/index.js';
|
|
15
|
+
import { DeletedPool } from './deleted_pool.js';
|
|
13
16
|
import {
|
|
14
17
|
EvictionManager,
|
|
15
18
|
FeePayerBalanceEvictionRule,
|
|
@@ -20,8 +23,12 @@ import {
|
|
|
20
23
|
LowPriorityPreAddRule,
|
|
21
24
|
NullifierConflictRule,
|
|
22
25
|
type PoolOperations,
|
|
26
|
+
type PreAddContext,
|
|
23
27
|
type PreAddPoolAccess,
|
|
28
|
+
TxPoolRejectionCode,
|
|
29
|
+
type TxPoolRejectionError,
|
|
24
30
|
} from './eviction/index.js';
|
|
31
|
+
import { TxPoolV2Instrumentation } from './instrumentation.js';
|
|
25
32
|
import {
|
|
26
33
|
type AddTxsResult,
|
|
27
34
|
DEFAULT_TX_POOL_V2_CONFIG,
|
|
@@ -53,7 +60,7 @@ export class TxPoolV2Impl {
|
|
|
53
60
|
// === Dependencies ===
|
|
54
61
|
#l2BlockSource: L2BlockSource;
|
|
55
62
|
#worldStateSynchronizer: WorldStateSynchronizer;
|
|
56
|
-
#
|
|
63
|
+
#createTxValidator: TxPoolV2Dependencies['createTxValidator'];
|
|
57
64
|
|
|
58
65
|
// === In-Memory Indices ===
|
|
59
66
|
#indices: TxPoolIndices = new TxPoolIndices();
|
|
@@ -61,7 +68,11 @@ export class TxPoolV2Impl {
|
|
|
61
68
|
// === Config & Services ===
|
|
62
69
|
#config: TxPoolV2Config;
|
|
63
70
|
#archive: TxArchive;
|
|
71
|
+
#deletedPool: DeletedPool;
|
|
64
72
|
#evictionManager: EvictionManager;
|
|
73
|
+
#dateProvider: DateProvider;
|
|
74
|
+
#instrumentation: TxPoolV2Instrumentation;
|
|
75
|
+
#evictedTxHashes: Set<string> = new Set();
|
|
65
76
|
#log: Logger;
|
|
66
77
|
#callbacks: TxPoolV2Callbacks;
|
|
67
78
|
|
|
@@ -70,7 +81,9 @@ export class TxPoolV2Impl {
|
|
|
70
81
|
archiveStore: AztecAsyncKVStore,
|
|
71
82
|
deps: TxPoolV2Dependencies,
|
|
72
83
|
callbacks: TxPoolV2Callbacks,
|
|
84
|
+
telemetry: TelemetryClient,
|
|
73
85
|
config: Partial<TxPoolV2Config> = {},
|
|
86
|
+
dateProvider: DateProvider,
|
|
74
87
|
log: Logger,
|
|
75
88
|
) {
|
|
76
89
|
this.#store = store;
|
|
@@ -78,10 +91,13 @@ export class TxPoolV2Impl {
|
|
|
78
91
|
|
|
79
92
|
this.#l2BlockSource = deps.l2BlockSource;
|
|
80
93
|
this.#worldStateSynchronizer = deps.worldStateSynchronizer;
|
|
81
|
-
this.#
|
|
94
|
+
this.#createTxValidator = deps.createTxValidator;
|
|
82
95
|
|
|
83
96
|
this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
|
|
84
97
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
98
|
+
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
99
|
+
this.#dateProvider = dateProvider;
|
|
100
|
+
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
|
|
85
101
|
this.#log = log;
|
|
86
102
|
this.#callbacks = callbacks;
|
|
87
103
|
|
|
@@ -116,7 +132,10 @@ export class TxPoolV2Impl {
|
|
|
116
132
|
* by running pre-add rules to resolve nullifier conflicts, balance checks, and pool size limits.
|
|
117
133
|
*/
|
|
118
134
|
async hydrateFromDatabase(): Promise<void> {
|
|
119
|
-
// Step
|
|
135
|
+
// Step 0: Hydrate deleted pool state
|
|
136
|
+
await this.#deletedPool.hydrateFromDatabase();
|
|
137
|
+
|
|
138
|
+
// Step 1: Load all transactions from DB (excluding soft-deleted)
|
|
120
139
|
const { loaded, errors: deserializationErrors } = await this.#loadAllTxsFromDb();
|
|
121
140
|
|
|
122
141
|
// Step 2: Check mined status for each tx
|
|
@@ -134,7 +153,10 @@ export class TxPoolV2Impl {
|
|
|
134
153
|
}
|
|
135
154
|
|
|
136
155
|
// Step 4: Validate non-mined transactions
|
|
137
|
-
const { valid, invalid } = await this.#
|
|
156
|
+
const { valid, invalid } = await this.#revalidateMetadata(
|
|
157
|
+
nonMined.map(e => e.meta),
|
|
158
|
+
'on startup',
|
|
159
|
+
);
|
|
138
160
|
|
|
139
161
|
// Step 5: Populate mined indices (these don't need conflict resolution)
|
|
140
162
|
for (const meta of mined) {
|
|
@@ -155,16 +177,19 @@ export class TxPoolV2Impl {
|
|
|
155
177
|
await this.#txsDB.delete(txHashStr);
|
|
156
178
|
}
|
|
157
179
|
});
|
|
158
|
-
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup
|
|
180
|
+
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
|
|
159
181
|
}
|
|
160
182
|
|
|
161
|
-
async addPendingTxs(txs: Tx[], opts: { source?: string }): Promise<AddTxsResult> {
|
|
183
|
+
async addPendingTxs(txs: Tx[], opts: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult> {
|
|
162
184
|
const accepted: TxHash[] = [];
|
|
163
185
|
const ignored: TxHash[] = [];
|
|
164
186
|
const rejected: TxHash[] = [];
|
|
187
|
+
const errors = new Map<string, TxPoolRejectionError>();
|
|
165
188
|
const acceptedPending = new Set<string>();
|
|
166
189
|
|
|
167
190
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
191
|
+
const preAddContext: PreAddContext | undefined =
|
|
192
|
+
opts.feeComparisonOnly !== undefined ? { feeComparisonOnly: opts.feeComparisonOnly } : undefined;
|
|
168
193
|
|
|
169
194
|
await this.#store.transactionAsync(async () => {
|
|
170
195
|
for (const tx of txs) {
|
|
@@ -191,7 +216,15 @@ export class TxPoolV2Impl {
|
|
|
191
216
|
accepted.push(txHash);
|
|
192
217
|
} else {
|
|
193
218
|
// Regular pending tx - validate and run pre-add rules
|
|
194
|
-
const result = await this.#tryAddRegularPendingTx(
|
|
219
|
+
const result = await this.#tryAddRegularPendingTx(
|
|
220
|
+
tx,
|
|
221
|
+
opts,
|
|
222
|
+
poolAccess,
|
|
223
|
+
acceptedPending,
|
|
224
|
+
ignored,
|
|
225
|
+
errors,
|
|
226
|
+
preAddContext,
|
|
227
|
+
);
|
|
195
228
|
if (result.status === 'accepted') {
|
|
196
229
|
acceptedPending.add(txHashStr);
|
|
197
230
|
} else if (result.status === 'rejected') {
|
|
@@ -208,6 +241,14 @@ export class TxPoolV2Impl {
|
|
|
208
241
|
accepted.push(TxHash.fromString(txHashStr));
|
|
209
242
|
}
|
|
210
243
|
|
|
244
|
+
// Record metrics
|
|
245
|
+
if (ignored.length > 0) {
|
|
246
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
247
|
+
}
|
|
248
|
+
if (rejected.length > 0) {
|
|
249
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
250
|
+
}
|
|
251
|
+
|
|
211
252
|
// Run post-add eviction rules for pending txs
|
|
212
253
|
if (acceptedPending.size > 0) {
|
|
213
254
|
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
@@ -215,7 +256,7 @@ export class TxPoolV2Impl {
|
|
|
215
256
|
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
216
257
|
}
|
|
217
258
|
|
|
218
|
-
return { accepted, ignored, rejected };
|
|
259
|
+
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
219
260
|
}
|
|
220
261
|
|
|
221
262
|
/** Validates and adds a regular pending tx. Returns status. */
|
|
@@ -225,32 +266,53 @@ export class TxPoolV2Impl {
|
|
|
225
266
|
poolAccess: PreAddPoolAccess,
|
|
226
267
|
acceptedPending: Set<string>,
|
|
227
268
|
ignored: TxHash[],
|
|
269
|
+
errors: Map<string, TxPoolRejectionError>,
|
|
270
|
+
preAddContext?: PreAddContext,
|
|
228
271
|
): Promise<{ status: 'accepted' | 'ignored' | 'rejected' }> {
|
|
229
272
|
const txHash = tx.getTxHash();
|
|
230
273
|
const txHashStr = txHash.toString();
|
|
231
274
|
|
|
232
|
-
//
|
|
233
|
-
|
|
275
|
+
// Build metadata and validate using metadata
|
|
276
|
+
const meta = await buildTxMetaData(tx);
|
|
277
|
+
if (!(await this.#validateMeta(meta))) {
|
|
234
278
|
return { status: 'rejected' };
|
|
235
279
|
}
|
|
236
280
|
|
|
237
|
-
//
|
|
238
|
-
const
|
|
239
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
281
|
+
// Run pre-add rules
|
|
282
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess, preAddContext);
|
|
240
283
|
|
|
241
284
|
if (preAddResult.shouldIgnore) {
|
|
242
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
285
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
286
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
287
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
288
|
+
}
|
|
243
289
|
return { status: 'ignored' };
|
|
244
290
|
}
|
|
245
291
|
|
|
246
|
-
// Evict conflicts
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
292
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
293
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
294
|
+
const byReason = new Map<string, string[]>();
|
|
295
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions) {
|
|
296
|
+
const group = byReason.get(reason);
|
|
297
|
+
if (group) {
|
|
298
|
+
group.push(evictHash);
|
|
299
|
+
} else {
|
|
300
|
+
byReason.set(reason, [evictHash]);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
for (const [reason, hashes] of byReason) {
|
|
304
|
+
await this.#evictTxs(hashes, reason);
|
|
305
|
+
}
|
|
306
|
+
for (const evictHashStr of preAddResult.txHashesToEvict) {
|
|
307
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
308
|
+
evictedTxHash: evictHashStr,
|
|
309
|
+
replacementTxHash: txHashStr,
|
|
310
|
+
});
|
|
311
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
312
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
313
|
+
acceptedPending.delete(evictHashStr);
|
|
314
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
315
|
+
}
|
|
254
316
|
}
|
|
255
317
|
}
|
|
256
318
|
|
|
@@ -267,14 +329,14 @@ export class TxPoolV2Impl {
|
|
|
267
329
|
return 'ignored';
|
|
268
330
|
}
|
|
269
331
|
|
|
270
|
-
//
|
|
271
|
-
const
|
|
272
|
-
|
|
332
|
+
// Build metadata and validate using metadata
|
|
333
|
+
const meta = await buildTxMetaData(tx);
|
|
334
|
+
const validationResult = await this.#validateMeta(meta, undefined, 'can add pending');
|
|
335
|
+
if (validationResult !== true) {
|
|
273
336
|
return 'rejected';
|
|
274
337
|
}
|
|
275
338
|
|
|
276
|
-
//
|
|
277
|
-
const meta = await buildTxMetaData(tx);
|
|
339
|
+
// Use pre-add rules
|
|
278
340
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
279
341
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
280
342
|
|
|
@@ -311,9 +373,11 @@ export class TxPoolV2Impl {
|
|
|
311
373
|
});
|
|
312
374
|
}
|
|
313
375
|
|
|
314
|
-
protectTxs(txHashes: TxHash[], block: BlockHeader): TxHash[] {
|
|
376
|
+
async protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
|
|
315
377
|
const slotNumber = block.globalVariables.slotNumber;
|
|
316
378
|
const missing: TxHash[] = [];
|
|
379
|
+
let softDeletedHits = 0;
|
|
380
|
+
let missingPreviouslyEvicted = 0;
|
|
317
381
|
|
|
318
382
|
for (const txHash of txHashes) {
|
|
319
383
|
const txHashStr = txHash.toString();
|
|
@@ -321,13 +385,44 @@ export class TxPoolV2Impl {
|
|
|
321
385
|
if (this.#indices.has(txHashStr)) {
|
|
322
386
|
// Update protection for existing tx
|
|
323
387
|
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
388
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
389
|
+
// Resurrect soft-deleted tx as protected
|
|
390
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
391
|
+
if (buffer) {
|
|
392
|
+
const tx = Tx.fromBuffer(buffer);
|
|
393
|
+
await this.#addTx(tx, { protected: slotNumber });
|
|
394
|
+
softDeletedHits++;
|
|
395
|
+
} else {
|
|
396
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
397
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
398
|
+
missing.push(txHash);
|
|
399
|
+
}
|
|
324
400
|
} else {
|
|
325
|
-
//
|
|
401
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
326
402
|
this.#indices.setProtection(txHashStr, slotNumber);
|
|
327
403
|
missing.push(txHash);
|
|
404
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
405
|
+
missingPreviouslyEvicted++;
|
|
406
|
+
}
|
|
328
407
|
}
|
|
329
408
|
}
|
|
330
409
|
|
|
410
|
+
// Record metrics
|
|
411
|
+
if (softDeletedHits > 0) {
|
|
412
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
413
|
+
}
|
|
414
|
+
if (missing.length > 0) {
|
|
415
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map(h => h.toString()).join(', ')}`);
|
|
416
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
417
|
+
}
|
|
418
|
+
if (missingPreviouslyEvicted > 0) {
|
|
419
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
this.#log.info(
|
|
423
|
+
`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`,
|
|
424
|
+
);
|
|
425
|
+
|
|
331
426
|
return missing;
|
|
332
427
|
}
|
|
333
428
|
|
|
@@ -347,6 +442,7 @@ export class TxPoolV2Impl {
|
|
|
347
442
|
// Add new mined tx (callback emitted by #addTx)
|
|
348
443
|
await this.#addTx(tx, { mined: blockId }, opts);
|
|
349
444
|
}
|
|
445
|
+
await this.#deletedPool.clearIfMinedHigher(txHashStr, blockId.number);
|
|
350
446
|
}
|
|
351
447
|
});
|
|
352
448
|
}
|
|
@@ -373,6 +469,7 @@ export class TxPoolV2Impl {
|
|
|
373
469
|
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
374
470
|
for (const meta of found) {
|
|
375
471
|
this.#indices.markAsMined(meta, blockId);
|
|
472
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
376
473
|
}
|
|
377
474
|
|
|
378
475
|
// Step 5: Run eviction rules (remove pending txs with conflicting nullifiers/expired timestamps)
|
|
@@ -382,6 +479,9 @@ export class TxPoolV2Impl {
|
|
|
382
479
|
}
|
|
383
480
|
|
|
384
481
|
async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
|
|
482
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
483
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
484
|
+
|
|
385
485
|
// Step 1: Find expired protected txs
|
|
386
486
|
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
387
487
|
|
|
@@ -391,19 +491,21 @@ export class TxPoolV2Impl {
|
|
|
391
491
|
// Step 3: Filter to only txs that have metadata and are not mined
|
|
392
492
|
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
393
493
|
if (txsToRestore.length === 0) {
|
|
494
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
394
495
|
return;
|
|
395
496
|
}
|
|
396
497
|
|
|
397
498
|
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
398
499
|
|
|
399
500
|
// Step 4: Validate for pending pool
|
|
400
|
-
const { valid, invalid } = await this.#
|
|
501
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
401
502
|
|
|
402
503
|
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
403
504
|
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
404
505
|
|
|
405
|
-
// Step 6: Delete invalid and
|
|
406
|
-
await this.#deleteTxsBatch(
|
|
506
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
507
|
+
await this.#deleteTxsBatch(invalid);
|
|
508
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
407
509
|
|
|
408
510
|
// Step 7: Run eviction rules (enforce pool size limit)
|
|
409
511
|
if (added.length > 0) {
|
|
@@ -416,7 +518,7 @@ export class TxPoolV2Impl {
|
|
|
416
518
|
}
|
|
417
519
|
}
|
|
418
520
|
|
|
419
|
-
async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
|
|
521
|
+
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
420
522
|
// Step 1: Find transactions mined after the prune point
|
|
421
523
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
422
524
|
if (txsToUnmine.length === 0) {
|
|
@@ -426,24 +528,50 @@ export class TxPoolV2Impl {
|
|
|
426
528
|
|
|
427
529
|
this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
|
|
428
530
|
|
|
429
|
-
// Step 2:
|
|
531
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
532
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
533
|
+
// when their original mined block is finalized
|
|
534
|
+
await this.#deletedPool.markFromPrunedBlock(
|
|
535
|
+
txsToUnmine.map(m => ({
|
|
536
|
+
txHash: m.txHash,
|
|
537
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
|
|
538
|
+
})),
|
|
539
|
+
);
|
|
540
|
+
|
|
541
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
430
542
|
for (const meta of txsToUnmine) {
|
|
431
543
|
this.#indices.markAsUnmined(meta);
|
|
432
544
|
}
|
|
433
545
|
|
|
434
|
-
//
|
|
546
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
547
|
+
if (options?.deleteAllTxs) {
|
|
548
|
+
const allTxHashes = txsToUnmine.map(m => m.txHash);
|
|
549
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
550
|
+
this.#log.info(
|
|
551
|
+
`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
|
|
552
|
+
);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
435
557
|
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
436
558
|
|
|
437
|
-
// Step
|
|
438
|
-
const { valid, invalid } = await this.#
|
|
559
|
+
// Step 5: Validate for pending pool
|
|
560
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
439
561
|
|
|
440
|
-
// Step
|
|
562
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
441
563
|
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
442
564
|
|
|
443
|
-
// Step
|
|
444
|
-
await this.#deleteTxsBatch(
|
|
565
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
566
|
+
await this.#deleteTxsBatch(invalid);
|
|
567
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
568
|
+
|
|
569
|
+
this.#log.info(
|
|
570
|
+
`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
|
|
571
|
+
{ txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
|
|
572
|
+
);
|
|
445
573
|
|
|
446
|
-
// Step
|
|
574
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
447
575
|
// This handles cases like existing pending txs with invalid fee payer balances
|
|
448
576
|
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
449
577
|
}
|
|
@@ -452,22 +580,19 @@ export class TxPoolV2Impl {
|
|
|
452
580
|
// Delete failed txs
|
|
453
581
|
await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
|
|
454
582
|
|
|
455
|
-
this.#log.info(`Deleted ${txHashes.length} failed txs
|
|
583
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
|
|
456
584
|
}
|
|
457
585
|
|
|
458
586
|
async handleFinalizedBlock(block: BlockHeader): Promise<void> {
|
|
459
587
|
const blockNumber = block.globalVariables.blockNumber;
|
|
460
588
|
|
|
461
|
-
// Step 1: Find txs
|
|
462
|
-
const
|
|
463
|
-
if (txsToFinalize.length === 0) {
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
589
|
+
// Step 1: Find mined txs at or before finalized block
|
|
590
|
+
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
466
591
|
|
|
467
|
-
// Step 2: Collect txs for archiving (before deletion)
|
|
592
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
468
593
|
const txsToArchive: Tx[] = [];
|
|
469
594
|
if (this.#archive.isEnabled()) {
|
|
470
|
-
for (const txHashStr of
|
|
595
|
+
for (const txHashStr of minedTxsToFinalize) {
|
|
471
596
|
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
472
597
|
if (buffer) {
|
|
473
598
|
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
@@ -475,15 +600,22 @@ export class TxPoolV2Impl {
|
|
|
475
600
|
}
|
|
476
601
|
}
|
|
477
602
|
|
|
478
|
-
// Step 3: Delete from active pool
|
|
479
|
-
await this.#deleteTxsBatch(
|
|
603
|
+
// Step 3: Delete mined txs from active pool
|
|
604
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
480
605
|
|
|
481
|
-
// Step 4:
|
|
606
|
+
// Step 4: Finalize soft-deleted txs
|
|
607
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
608
|
+
|
|
609
|
+
// Step 5: Archive mined txs
|
|
482
610
|
if (txsToArchive.length > 0) {
|
|
483
611
|
await this.#archive.archiveTxs(txsToArchive);
|
|
484
612
|
}
|
|
485
613
|
|
|
486
|
-
|
|
614
|
+
if (minedTxsToFinalize.length > 0) {
|
|
615
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
616
|
+
txHashes: minedTxsToFinalize,
|
|
617
|
+
});
|
|
618
|
+
}
|
|
487
619
|
}
|
|
488
620
|
|
|
489
621
|
// === Query Methods ===
|
|
@@ -503,21 +635,36 @@ export class TxPoolV2Impl {
|
|
|
503
635
|
}
|
|
504
636
|
|
|
505
637
|
hasTxs(txHashes: TxHash[]): boolean[] {
|
|
506
|
-
return txHashes.map(h =>
|
|
638
|
+
return txHashes.map(h => {
|
|
639
|
+
const hashStr = h.toString();
|
|
640
|
+
return this.#indices.has(hashStr) || this.#deletedPool.isSoftDeleted(hashStr);
|
|
641
|
+
});
|
|
507
642
|
}
|
|
508
643
|
|
|
509
644
|
getTxStatus(txHash: TxHash): TxState | undefined {
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
645
|
+
const txHashStr = txHash.toString();
|
|
646
|
+
const meta = this.#indices.getMetadata(txHashStr);
|
|
647
|
+
if (meta) {
|
|
648
|
+
return this.#indices.getTxState(meta);
|
|
513
649
|
}
|
|
514
|
-
|
|
650
|
+
// Check if soft-deleted
|
|
651
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
652
|
+
return 'deleted';
|
|
653
|
+
}
|
|
654
|
+
return undefined;
|
|
515
655
|
}
|
|
516
656
|
|
|
517
657
|
getPendingTxHashes(): TxHash[] {
|
|
518
658
|
return [...this.#indices.iteratePendingByPriority('desc')].map(hash => TxHash.fromString(hash));
|
|
519
659
|
}
|
|
520
660
|
|
|
661
|
+
getEligiblePendingTxHashes(): TxHash[] {
|
|
662
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
663
|
+
return [...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)].map(hash =>
|
|
664
|
+
TxHash.fromString(hash),
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
|
|
521
668
|
getPendingTxCount(): number {
|
|
522
669
|
return this.#indices.getPendingTxCount();
|
|
523
670
|
}
|
|
@@ -562,6 +709,9 @@ export class TxPoolV2Impl {
|
|
|
562
709
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
563
710
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
564
711
|
}
|
|
712
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
713
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
714
|
+
}
|
|
565
715
|
// Update eviction rules with new config
|
|
566
716
|
this.#evictionManager.updateConfig(config);
|
|
567
717
|
}
|
|
@@ -579,8 +729,17 @@ export class TxPoolV2Impl {
|
|
|
579
729
|
|
|
580
730
|
// === Metrics ===
|
|
581
731
|
|
|
582
|
-
countTxs(): {
|
|
583
|
-
|
|
732
|
+
countTxs(): {
|
|
733
|
+
pending: number;
|
|
734
|
+
protected: number;
|
|
735
|
+
mined: number;
|
|
736
|
+
softDeleted: number;
|
|
737
|
+
totalMetadataBytes: number;
|
|
738
|
+
} {
|
|
739
|
+
return {
|
|
740
|
+
...this.#indices.countTxs(),
|
|
741
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount(),
|
|
742
|
+
};
|
|
584
743
|
}
|
|
585
744
|
|
|
586
745
|
// ============================================================================
|
|
@@ -598,8 +757,10 @@ export class TxPoolV2Impl {
|
|
|
598
757
|
): Promise<TxMetaData> {
|
|
599
758
|
const txHashStr = tx.getTxHash().toString();
|
|
600
759
|
const meta = await buildTxMetaData(tx);
|
|
760
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
601
761
|
|
|
602
762
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
763
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
603
764
|
this.#callbacks.onTxsAdded([tx], opts);
|
|
604
765
|
|
|
605
766
|
if (state === 'pending') {
|
|
@@ -612,9 +773,11 @@ export class TxPoolV2Impl {
|
|
|
612
773
|
}
|
|
613
774
|
|
|
614
775
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
615
|
-
this.#log.
|
|
776
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
616
777
|
eventName: 'tx-added-to-pool',
|
|
778
|
+
txHash: txHashStr,
|
|
617
779
|
state: stateStr,
|
|
780
|
+
source: opts.source,
|
|
618
781
|
});
|
|
619
782
|
|
|
620
783
|
return meta;
|
|
@@ -624,10 +787,15 @@ export class TxPoolV2Impl {
|
|
|
624
787
|
* Deletes a transaction from both indices and DB.
|
|
625
788
|
* Emits onTxsRemoved callback immediately after DB delete.
|
|
626
789
|
*/
|
|
790
|
+
/**
|
|
791
|
+
* Deletes a transaction from the pool.
|
|
792
|
+
* Delegates to DeletedPool which decides soft vs hard delete based on whether
|
|
793
|
+
* the tx is from a pruned block.
|
|
794
|
+
*/
|
|
627
795
|
async #deleteTx(txHashStr: string): Promise<void> {
|
|
628
796
|
this.#indices.remove(txHashStr);
|
|
629
|
-
await this.#txsDB.delete(txHashStr);
|
|
630
797
|
this.#callbacks.onTxsRemoved([txHashStr]);
|
|
798
|
+
await this.#deletedPool.deleteTx(txHashStr);
|
|
631
799
|
}
|
|
632
800
|
|
|
633
801
|
/** Deletes a batch of transactions, emitting callbacks individually for each. */
|
|
@@ -637,68 +805,63 @@ export class TxPoolV2Impl {
|
|
|
637
805
|
}
|
|
638
806
|
}
|
|
639
807
|
|
|
808
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */
|
|
809
|
+
async #evictTxs(txHashes: string[], reason: string): Promise<void> {
|
|
810
|
+
if (txHashes.length === 0) {
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
814
|
+
for (const txHashStr of txHashes) {
|
|
815
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
816
|
+
this.#addToEvictedCache(txHashStr);
|
|
817
|
+
}
|
|
818
|
+
await this.#deleteTxsBatch(txHashes);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
|
|
822
|
+
#addToEvictedCache(txHashStr: string): void {
|
|
823
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
824
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
825
|
+
const oldest = this.#evictedTxHashes.values().next().value!;
|
|
826
|
+
this.#evictedTxHashes.delete(oldest);
|
|
827
|
+
}
|
|
828
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
829
|
+
}
|
|
830
|
+
|
|
640
831
|
// ============================================================================
|
|
641
832
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
642
833
|
// ============================================================================
|
|
643
834
|
|
|
644
|
-
/** Validates
|
|
645
|
-
async #
|
|
646
|
-
const
|
|
835
|
+
/** Validates transaction metadata, returning true if valid */
|
|
836
|
+
async #validateMeta(meta: TxMetaData, validator?: TxValidator<TxMetaData>, context?: string): Promise<boolean> {
|
|
837
|
+
const txValidator = validator ?? (await this.#createTxValidator());
|
|
838
|
+
const result = await txValidator.validateTx(meta);
|
|
647
839
|
if (result.result !== 'valid') {
|
|
648
840
|
const contextStr = context ? ` ${context}` : '';
|
|
649
|
-
this.#log.info(`Tx ${
|
|
841
|
+
this.#log.info(`Tx ${meta.txHash}${contextStr} failed validation: ${result.reason?.join(', ')}`);
|
|
650
842
|
return false;
|
|
651
843
|
}
|
|
652
844
|
return true;
|
|
653
845
|
}
|
|
654
846
|
|
|
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 }[],
|
|
847
|
+
/** Validates metadata directly */
|
|
848
|
+
async #revalidateMetadata(
|
|
849
|
+
metas: TxMetaData[],
|
|
676
850
|
context?: string,
|
|
677
851
|
): Promise<{ valid: TxMetaData[]; invalid: string[] }> {
|
|
678
852
|
const valid: TxMetaData[] = [];
|
|
679
853
|
const invalid: string[] = [];
|
|
680
|
-
|
|
681
|
-
for (const
|
|
682
|
-
if (await this.#
|
|
854
|
+
const validator = await this.#createTxValidator();
|
|
855
|
+
for (const meta of metas) {
|
|
856
|
+
if (await this.#validateMeta(meta, validator, context)) {
|
|
683
857
|
valid.push(meta);
|
|
684
858
|
} else {
|
|
685
859
|
invalid.push(meta.txHash);
|
|
686
860
|
}
|
|
687
861
|
}
|
|
688
|
-
|
|
689
862
|
return { valid, invalid };
|
|
690
863
|
}
|
|
691
864
|
|
|
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
865
|
/**
|
|
703
866
|
* Resolves nullifier conflicts between incoming txs and existing pending txs.
|
|
704
867
|
* Modifies the pending indices during iteration to maintain consistent state
|
|
@@ -768,6 +931,11 @@ export class TxPoolV2Impl {
|
|
|
768
931
|
const errors: string[] = [];
|
|
769
932
|
|
|
770
933
|
for await (const [txHashStr, buffer] of this.#txsDB.entriesAsync()) {
|
|
934
|
+
// Skip soft-deleted transactions - they stay in DB but not in indices
|
|
935
|
+
if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
|
|
771
939
|
try {
|
|
772
940
|
const tx = Tx.fromBuffer(buffer);
|
|
773
941
|
const meta = await buildTxMetaData(tx);
|
|
@@ -815,7 +983,9 @@ export class TxPoolV2Impl {
|
|
|
815
983
|
if (preAddResult.shouldIgnore) {
|
|
816
984
|
// Transaction rejected - mark for deletion from DB
|
|
817
985
|
rejected.push(meta.txHash);
|
|
818
|
-
this.#log.debug(
|
|
986
|
+
this.#log.debug(
|
|
987
|
+
`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`,
|
|
988
|
+
);
|
|
819
989
|
continue;
|
|
820
990
|
}
|
|
821
991
|
|
|
@@ -851,7 +1021,7 @@ export class TxPoolV2Impl {
|
|
|
851
1021
|
getFeePayerPendingTxs: (feePayer: string) => this.#indices.getFeePayerPendingTxs(feePayer),
|
|
852
1022
|
getPendingTxCount: () => this.#indices.getPendingTxCount(),
|
|
853
1023
|
getLowestPriorityPending: (limit: number) => this.#indices.getLowestPriorityPending(limit),
|
|
854
|
-
deleteTxs: (txHashes: string[]) => this.#
|
|
1024
|
+
deleteTxs: (txHashes: string[], reason?: string) => this.#evictTxs(txHashes, reason ?? 'unknown'),
|
|
855
1025
|
};
|
|
856
1026
|
}
|
|
857
1027
|
|