@aztec/p2p 0.0.1-commit.7cf39cb55 → 0.0.1-commit.7ffbba4
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 -7
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +19 -28
- package/dest/client/interface.d.ts +10 -19
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +7 -18
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +41 -96
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
- package/dest/config.d.ts +22 -15
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +66 -37
- 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/mem_pools/attestation_pool/attestation_pool.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +5 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -2
- package/dest/mem_pools/instrumentation.d.ts +4 -2
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +16 -14
- 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 +3 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +9 -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.js +3 -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 +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +54 -5
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +4 -4
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +5 -5
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +12 -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 +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +1 -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 +18 -6
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +4 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +46 -14
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +99 -17
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +5 -2
- 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 +38 -46
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +6 -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 +9 -5
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -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 +277 -148
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/factory.d.ts +114 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +219 -58
- 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 +58 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +73 -36
- package/dest/msg_validators/tx_validator/index.d.ts +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +44 -23
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +2 -2
- 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 +4 -4
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +4 -4
- package/dest/services/encoding.d.ts +2 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +9 -8
- package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +32 -10
- package/dest/services/libp2p/libp2p_service.d.ts +16 -13
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +84 -90
- 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 +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +2 -1
- 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 +19 -46
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +17 -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 +49 -15
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- 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 +2 -1
- package/dest/services/service.d.ts +5 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +39 -33
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
- package/dest/services/tx_collection/file_store_tx_source.d.ts +15 -6
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.js +47 -16
- 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 +2 -2
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +10 -8
- package/dest/services/tx_collection/tx_collection.d.ts +5 -4
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +13 -22
- 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/tx_file_store.js +1 -1
- 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 +4 -4
- package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +1 -2
- package/dest/test-helpers/mock-pubsub.d.ts +4 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +8 -2
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -2
- package/dest/test-helpers/testbench-utils.d.ts +6 -3
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +1 -1
- 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 +15 -14
- package/dest/testbench/worker_client_manager.d.ts +3 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +6 -2
- package/dest/util.d.ts +3 -3
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +29 -49
- package/src/client/interface.ts +11 -20
- package/src/client/p2p_client.ts +47 -126
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +20 -11
- package/src/config.ts +92 -43
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +5 -4
- package/src/mem_pools/attestation_pool/mocks.ts +2 -1
- package/src/mem_pools/instrumentation.ts +17 -13
- 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 +10 -2
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +11 -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 +3 -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 +4 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +59 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +4 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +5 -5
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +12 -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 +1 -1
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +18 -6
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +141 -25
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -46
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +15 -7
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +310 -144
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
- package/src/msg_validators/tx_validator/README.md +115 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
- 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/factory.ts +353 -77
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +90 -27
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +51 -26
- package/src/msg_validators/tx_validator/timestamp_validator.ts +7 -7
- package/src/services/dummy_service.ts +6 -6
- package/src/services/encoding.ts +7 -7
- package/src/services/gossipsub/README.md +29 -14
- package/src/services/gossipsub/topic_score_params.ts +49 -13
- package/src/services/libp2p/libp2p_service.ts +95 -96
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +2 -1
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +20 -48
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +63 -24
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/reqresp/reqresp.ts +3 -1
- package/src/services/service.ts +11 -2
- package/src/services/tx_collection/fast_tx_collection.ts +51 -30
- package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
- package/src/services/tx_collection/file_store_tx_source.ts +61 -17
- 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 +8 -9
- package/src/services/tx_collection/tx_collection.ts +4 -3
- package/src/services/tx_collection/tx_collection_sink.ts +15 -29
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_file_store/tx_file_store.ts +1 -1
- package/src/services/tx_provider.ts +2 -2
- package/src/test-helpers/make-test-p2p-clients.ts +1 -3
- package/src/test-helpers/mock-pubsub.ts +13 -6
- package/src/test-helpers/reqresp-nodes.ts +3 -6
- package/src/test-helpers/testbench-utils.ts +3 -3
- package/src/testbench/p2p_client_testbench_worker.ts +24 -20
- package/src/testbench/worker_client_manager.ts +13 -5
- package/src/util.ts +8 -2
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
|
@@ -9,6 +9,7 @@ import type { L2Block, L2BlockId, L2BlockSource } from '@aztec/stdlib/block';
|
|
|
9
9
|
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
10
10
|
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
11
11
|
import { BlockHeader, Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx';
|
|
12
|
+
import type { TelemetryClient } from '@aztec/telemetry-client';
|
|
12
13
|
|
|
13
14
|
import { TxArchive } from './archive/index.js';
|
|
14
15
|
import { DeletedPool } from './deleted_pool.js';
|
|
@@ -22,8 +23,12 @@ import {
|
|
|
22
23
|
LowPriorityPreAddRule,
|
|
23
24
|
NullifierConflictRule,
|
|
24
25
|
type PoolOperations,
|
|
26
|
+
type PreAddContext,
|
|
25
27
|
type PreAddPoolAccess,
|
|
28
|
+
TxPoolRejectionCode,
|
|
29
|
+
type TxPoolRejectionError,
|
|
26
30
|
} from './eviction/index.js';
|
|
31
|
+
import { TxPoolV2Instrumentation } from './instrumentation.js';
|
|
27
32
|
import {
|
|
28
33
|
type AddTxsResult,
|
|
29
34
|
DEFAULT_TX_POOL_V2_CONFIG,
|
|
@@ -40,6 +45,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
40
45
|
export interface TxPoolV2Callbacks {
|
|
41
46
|
onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
|
|
42
47
|
onTxsRemoved: (txHashes: string[] | bigint[]) => void;
|
|
48
|
+
onTxsMined: (txHashes: string[]) => void;
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
/**
|
|
@@ -66,6 +72,8 @@ export class TxPoolV2Impl {
|
|
|
66
72
|
#deletedPool: DeletedPool;
|
|
67
73
|
#evictionManager: EvictionManager;
|
|
68
74
|
#dateProvider: DateProvider;
|
|
75
|
+
#instrumentation: TxPoolV2Instrumentation;
|
|
76
|
+
#evictedTxHashes: Set<string> = new Set();
|
|
69
77
|
#log: Logger;
|
|
70
78
|
#callbacks: TxPoolV2Callbacks;
|
|
71
79
|
|
|
@@ -74,6 +82,7 @@ export class TxPoolV2Impl {
|
|
|
74
82
|
archiveStore: AztecAsyncKVStore,
|
|
75
83
|
deps: TxPoolV2Dependencies,
|
|
76
84
|
callbacks: TxPoolV2Callbacks,
|
|
85
|
+
telemetry: TelemetryClient,
|
|
77
86
|
config: Partial<TxPoolV2Config> = {},
|
|
78
87
|
dateProvider: DateProvider,
|
|
79
88
|
log: Logger,
|
|
@@ -89,6 +98,7 @@ export class TxPoolV2Impl {
|
|
|
89
98
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
90
99
|
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
91
100
|
this.#dateProvider = dateProvider;
|
|
101
|
+
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
|
|
92
102
|
this.#log = log;
|
|
93
103
|
this.#callbacks = callbacks;
|
|
94
104
|
|
|
@@ -171,13 +181,42 @@ export class TxPoolV2Impl {
|
|
|
171
181
|
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
|
|
172
182
|
}
|
|
173
183
|
|
|
174
|
-
async addPendingTxs(txs: Tx[], opts: { source?: string }): Promise<AddTxsResult> {
|
|
184
|
+
async addPendingTxs(txs: Tx[], opts: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult> {
|
|
175
185
|
const accepted: TxHash[] = [];
|
|
176
186
|
const ignored: TxHash[] = [];
|
|
177
187
|
const rejected: TxHash[] = [];
|
|
188
|
+
const errors = new Map<string, TxPoolRejectionError>();
|
|
178
189
|
const acceptedPending = new Set<string>();
|
|
179
190
|
|
|
191
|
+
// Phase 1: Pre-compute all throwable I/O outside the transaction.
|
|
192
|
+
// If any pre-computation throws, the entire call fails before mutations happen.
|
|
193
|
+
const precomputed = new Map<string, { meta: TxMetaData; minedBlockId: L2BlockId | undefined; isValid: boolean }>();
|
|
194
|
+
|
|
195
|
+
const validator = await this.#createTxValidator();
|
|
196
|
+
|
|
197
|
+
for (const tx of txs) {
|
|
198
|
+
const txHash = tx.getTxHash();
|
|
199
|
+
const txHashStr = txHash.toString();
|
|
200
|
+
|
|
201
|
+
const meta = await buildTxMetaData(tx);
|
|
202
|
+
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
203
|
+
|
|
204
|
+
// Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
|
|
205
|
+
let isValid = true;
|
|
206
|
+
if (!minedBlockId) {
|
|
207
|
+
isValid = await this.#validateMeta(meta, validator);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
precomputed.set(txHashStr, { meta, minedBlockId, isValid });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Phase 2: Apply mutations inside the transaction using only pre-computed results,
|
|
214
|
+
// in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
|
|
180
215
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
216
|
+
const preAddContext: PreAddContext | undefined =
|
|
217
|
+
opts.feeComparisonOnly !== undefined
|
|
218
|
+
? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
|
|
219
|
+
: undefined;
|
|
181
220
|
|
|
182
221
|
await this.#store.transactionAsync(async () => {
|
|
183
222
|
for (const tx of txs) {
|
|
@@ -190,30 +229,46 @@ export class TxPoolV2Impl {
|
|
|
190
229
|
continue;
|
|
191
230
|
}
|
|
192
231
|
|
|
193
|
-
|
|
194
|
-
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
232
|
+
const { meta, minedBlockId, isValid } = precomputed.get(txHashStr)!;
|
|
195
233
|
const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
|
|
196
234
|
|
|
197
235
|
if (minedBlockId) {
|
|
198
236
|
// Already mined - add directly (protection already set if pre-protected)
|
|
199
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
237
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
200
238
|
accepted.push(txHash);
|
|
201
239
|
} else if (preProtectedSlot !== undefined) {
|
|
202
240
|
// Pre-protected and not mined - add as protected (bypass validation)
|
|
203
|
-
await this.#addTx(tx, { protected: preProtectedSlot }, opts);
|
|
241
|
+
await this.#addTx(tx, { protected: preProtectedSlot }, opts, meta);
|
|
204
242
|
accepted.push(txHash);
|
|
243
|
+
} else if (!isValid) {
|
|
244
|
+
// Failed pre-computed validation
|
|
245
|
+
rejected.push(txHash);
|
|
205
246
|
} else {
|
|
206
|
-
// Regular pending tx -
|
|
207
|
-
const result = await this.#tryAddRegularPendingTx(
|
|
247
|
+
// Regular pending tx - run pre-add rules using pre-computed metadata
|
|
248
|
+
const result = await this.#tryAddRegularPendingTx(
|
|
249
|
+
tx,
|
|
250
|
+
meta,
|
|
251
|
+
opts,
|
|
252
|
+
poolAccess,
|
|
253
|
+
acceptedPending,
|
|
254
|
+
ignored,
|
|
255
|
+
errors,
|
|
256
|
+
preAddContext,
|
|
257
|
+
);
|
|
208
258
|
if (result.status === 'accepted') {
|
|
209
259
|
acceptedPending.add(txHashStr);
|
|
210
|
-
} else if (result.status === 'rejected') {
|
|
211
|
-
rejected.push(txHash);
|
|
212
260
|
} else {
|
|
213
261
|
ignored.push(txHash);
|
|
214
262
|
}
|
|
215
263
|
}
|
|
216
264
|
}
|
|
265
|
+
|
|
266
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
267
|
+
if (acceptedPending.size > 0) {
|
|
268
|
+
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
269
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
270
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
271
|
+
}
|
|
217
272
|
});
|
|
218
273
|
|
|
219
274
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
@@ -221,61 +276,80 @@ export class TxPoolV2Impl {
|
|
|
221
276
|
accepted.push(TxHash.fromString(txHashStr));
|
|
222
277
|
}
|
|
223
278
|
|
|
224
|
-
//
|
|
225
|
-
if (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
279
|
+
// Record metrics
|
|
280
|
+
if (ignored.length > 0) {
|
|
281
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
282
|
+
}
|
|
283
|
+
if (rejected.length > 0) {
|
|
284
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
229
285
|
}
|
|
230
286
|
|
|
231
|
-
return { accepted, ignored, rejected };
|
|
287
|
+
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
232
288
|
}
|
|
233
289
|
|
|
234
|
-
/**
|
|
290
|
+
/** Adds a validated pending tx, running pre-add rules and evicting conflicts. */
|
|
235
291
|
async #tryAddRegularPendingTx(
|
|
236
292
|
tx: Tx,
|
|
293
|
+
precomputedMeta: TxMetaData,
|
|
237
294
|
opts: { source?: string },
|
|
238
295
|
poolAccess: PreAddPoolAccess,
|
|
239
296
|
acceptedPending: Set<string>,
|
|
240
297
|
ignored: TxHash[],
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
// Build metadata and validate using metadata
|
|
246
|
-
const meta = await buildTxMetaData(tx);
|
|
247
|
-
if (!(await this.#validateMeta(meta))) {
|
|
248
|
-
return { status: 'rejected' };
|
|
249
|
-
}
|
|
298
|
+
errors: Map<string, TxPoolRejectionError>,
|
|
299
|
+
preAddContext?: PreAddContext,
|
|
300
|
+
): Promise<{ status: 'accepted' | 'ignored' }> {
|
|
301
|
+
const txHashStr = tx.getTxHash().toString();
|
|
250
302
|
|
|
251
303
|
// Run pre-add rules
|
|
252
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(
|
|
304
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
|
|
253
305
|
|
|
254
306
|
if (preAddResult.shouldIgnore) {
|
|
255
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
307
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
308
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
309
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
310
|
+
}
|
|
256
311
|
return { status: 'ignored' };
|
|
257
312
|
}
|
|
258
313
|
|
|
259
|
-
// Evict conflicts
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
314
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
315
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
316
|
+
const byReason = new Map<string, string[]>();
|
|
317
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions) {
|
|
318
|
+
const group = byReason.get(reason);
|
|
319
|
+
if (group) {
|
|
320
|
+
group.push(evictHash);
|
|
321
|
+
} else {
|
|
322
|
+
byReason.set(reason, [evictHash]);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
for (const [reason, hashes] of byReason) {
|
|
326
|
+
await this.#evictTxs(hashes, reason);
|
|
327
|
+
}
|
|
328
|
+
for (const evictHashStr of preAddResult.txHashesToEvict) {
|
|
329
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
330
|
+
evictedTxHash: evictHashStr,
|
|
331
|
+
replacementTxHash: txHashStr,
|
|
332
|
+
});
|
|
333
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
334
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
335
|
+
acceptedPending.delete(evictHashStr);
|
|
336
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
337
|
+
}
|
|
270
338
|
}
|
|
271
339
|
}
|
|
272
340
|
|
|
341
|
+
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
342
|
+
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
343
|
+
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
344
|
+
return { status: 'accepted' };
|
|
345
|
+
}
|
|
346
|
+
|
|
273
347
|
// Add the transaction
|
|
274
|
-
await this.#addTx(tx, 'pending', opts);
|
|
348
|
+
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
275
349
|
return { status: 'accepted' };
|
|
276
350
|
}
|
|
277
351
|
|
|
278
|
-
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'
|
|
352
|
+
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
|
|
279
353
|
const txHashStr = tx.getTxHash().toString();
|
|
280
354
|
|
|
281
355
|
// Check if already in pool
|
|
@@ -283,14 +357,8 @@ export class TxPoolV2Impl {
|
|
|
283
357
|
return 'ignored';
|
|
284
358
|
}
|
|
285
359
|
|
|
286
|
-
// Build metadata and
|
|
360
|
+
// Build metadata and check pre-add rules
|
|
287
361
|
const meta = await buildTxMetaData(tx);
|
|
288
|
-
const validationResult = await this.#validateMeta(meta, undefined, 'can add pending');
|
|
289
|
-
if (validationResult !== true) {
|
|
290
|
-
return 'rejected';
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Use pre-add rules
|
|
294
362
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
295
363
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
296
364
|
|
|
@@ -327,22 +395,57 @@ export class TxPoolV2Impl {
|
|
|
327
395
|
});
|
|
328
396
|
}
|
|
329
397
|
|
|
330
|
-
protectTxs(txHashes: TxHash[], block: BlockHeader): TxHash[] {
|
|
398
|
+
async protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
|
|
331
399
|
const slotNumber = block.globalVariables.slotNumber;
|
|
332
400
|
const missing: TxHash[] = [];
|
|
401
|
+
let softDeletedHits = 0;
|
|
402
|
+
let missingPreviouslyEvicted = 0;
|
|
333
403
|
|
|
334
|
-
|
|
335
|
-
const
|
|
404
|
+
await this.#store.transactionAsync(async () => {
|
|
405
|
+
for (const txHash of txHashes) {
|
|
406
|
+
const txHashStr = txHash.toString();
|
|
336
407
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
408
|
+
if (this.#indices.has(txHashStr)) {
|
|
409
|
+
// Update protection for existing tx
|
|
410
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
411
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
412
|
+
// Resurrect soft-deleted tx as protected
|
|
413
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
414
|
+
if (buffer) {
|
|
415
|
+
const tx = Tx.fromBuffer(buffer);
|
|
416
|
+
await this.#addTx(tx, { protected: slotNumber });
|
|
417
|
+
softDeletedHits++;
|
|
418
|
+
} else {
|
|
419
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
420
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
421
|
+
missing.push(txHash);
|
|
422
|
+
}
|
|
423
|
+
} else {
|
|
424
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
425
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
426
|
+
missing.push(txHash);
|
|
427
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
428
|
+
missingPreviouslyEvicted++;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
344
431
|
}
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
// Record metrics
|
|
435
|
+
if (softDeletedHits > 0) {
|
|
436
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
345
437
|
}
|
|
438
|
+
if (missing.length > 0) {
|
|
439
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map(h => h.toString()).join(', ')}`);
|
|
440
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
441
|
+
}
|
|
442
|
+
if (missingPreviouslyEvicted > 0) {
|
|
443
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
this.#log.info(
|
|
447
|
+
`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`,
|
|
448
|
+
);
|
|
346
449
|
|
|
347
450
|
return missing;
|
|
348
451
|
}
|
|
@@ -387,57 +490,67 @@ export class TxPoolV2Impl {
|
|
|
387
490
|
}
|
|
388
491
|
}
|
|
389
492
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
493
|
+
await this.#store.transactionAsync(async () => {
|
|
494
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
495
|
+
for (const meta of found) {
|
|
496
|
+
this.#indices.markAsMined(meta, blockId);
|
|
497
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
498
|
+
}
|
|
395
499
|
|
|
396
|
-
|
|
397
|
-
|
|
500
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
501
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
if (found.length > 0) {
|
|
505
|
+
this.#callbacks.onTxsMined(found.map(m => m.txHash));
|
|
506
|
+
}
|
|
398
507
|
|
|
399
508
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
400
509
|
}
|
|
401
510
|
|
|
402
511
|
async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
|
|
403
|
-
|
|
404
|
-
|
|
512
|
+
await this.#store.transactionAsync(async () => {
|
|
513
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
514
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
405
515
|
|
|
406
|
-
|
|
407
|
-
|
|
516
|
+
// Step 1: Find expired protected txs
|
|
517
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
408
518
|
|
|
409
|
-
|
|
410
|
-
|
|
519
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
520
|
+
this.#indices.clearProtection(expiredProtected);
|
|
411
521
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
522
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
523
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
524
|
+
if (txsToRestore.length === 0) {
|
|
525
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
417
528
|
|
|
418
|
-
|
|
529
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
419
530
|
|
|
420
|
-
|
|
421
|
-
|
|
531
|
+
// Step 4: Validate for pending pool
|
|
532
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
422
533
|
|
|
423
|
-
|
|
424
|
-
|
|
534
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
535
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
425
536
|
|
|
426
|
-
|
|
427
|
-
|
|
537
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
538
|
+
await this.#deleteTxsBatch(invalid);
|
|
539
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
428
540
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
541
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
542
|
+
if (added.length > 0) {
|
|
543
|
+
const feePayers = added.map(meta => meta.feePayer);
|
|
544
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
545
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
546
|
+
added.map(m => m.txHash),
|
|
547
|
+
[...uniqueFeePayers],
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
});
|
|
438
551
|
}
|
|
439
552
|
|
|
440
|
-
async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
|
|
553
|
+
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
441
554
|
// Step 1: Find transactions mined after the prune point
|
|
442
555
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
443
556
|
if (txsToUnmine.length === 0) {
|
|
@@ -447,46 +560,60 @@ export class TxPoolV2Impl {
|
|
|
447
560
|
|
|
448
561
|
this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
|
|
449
562
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
563
|
+
await this.#store.transactionAsync(async () => {
|
|
564
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
565
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
566
|
+
// when their original mined block is finalized
|
|
567
|
+
await this.#deletedPool.markFromPrunedBlock(
|
|
568
|
+
txsToUnmine.map(m => ({
|
|
569
|
+
txHash: m.txHash,
|
|
570
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
|
|
571
|
+
})),
|
|
572
|
+
);
|
|
459
573
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
574
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
575
|
+
for (const meta of txsToUnmine) {
|
|
576
|
+
this.#indices.markAsUnmined(meta);
|
|
577
|
+
}
|
|
464
578
|
|
|
465
|
-
|
|
466
|
-
|
|
579
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
580
|
+
if (options?.deleteAllTxs) {
|
|
581
|
+
const allTxHashes = txsToUnmine.map(m => m.txHash);
|
|
582
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
583
|
+
this.#log.info(
|
|
584
|
+
`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
|
|
585
|
+
);
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
467
588
|
|
|
468
|
-
|
|
469
|
-
|
|
589
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
590
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
470
591
|
|
|
471
|
-
|
|
472
|
-
|
|
592
|
+
// Step 5: Validate for pending pool
|
|
593
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
473
594
|
|
|
474
|
-
|
|
475
|
-
|
|
595
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
596
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
476
597
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
598
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
599
|
+
await this.#deleteTxsBatch(invalid);
|
|
600
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
601
|
+
|
|
602
|
+
this.#log.info(
|
|
603
|
+
`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
|
|
604
|
+
{ txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
|
|
605
|
+
);
|
|
481
606
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
607
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
608
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
609
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
610
|
+
});
|
|
485
611
|
}
|
|
486
612
|
|
|
487
613
|
async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
|
|
488
|
-
|
|
489
|
-
|
|
614
|
+
await this.#store.transactionAsync(async () => {
|
|
615
|
+
await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
|
|
616
|
+
});
|
|
490
617
|
|
|
491
618
|
this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
|
|
492
619
|
}
|
|
@@ -497,27 +624,29 @@ export class TxPoolV2Impl {
|
|
|
497
624
|
// Step 1: Find mined txs at or before finalized block
|
|
498
625
|
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
499
626
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
627
|
+
await this.#store.transactionAsync(async () => {
|
|
628
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
629
|
+
const txsToArchive: Tx[] = [];
|
|
630
|
+
if (this.#archive.isEnabled()) {
|
|
631
|
+
for (const txHashStr of minedTxsToFinalize) {
|
|
632
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
633
|
+
if (buffer) {
|
|
634
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
635
|
+
}
|
|
507
636
|
}
|
|
508
637
|
}
|
|
509
|
-
}
|
|
510
638
|
|
|
511
|
-
|
|
512
|
-
|
|
639
|
+
// Step 3: Delete mined txs from active pool
|
|
640
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
513
641
|
|
|
514
|
-
|
|
515
|
-
|
|
642
|
+
// Step 4: Finalize soft-deleted txs
|
|
643
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
516
644
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
645
|
+
// Step 5: Archive mined txs
|
|
646
|
+
if (txsToArchive.length > 0) {
|
|
647
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
648
|
+
}
|
|
649
|
+
});
|
|
521
650
|
|
|
522
651
|
if (minedTxsToFinalize.length > 0) {
|
|
523
652
|
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
@@ -637,8 +766,17 @@ export class TxPoolV2Impl {
|
|
|
637
766
|
|
|
638
767
|
// === Metrics ===
|
|
639
768
|
|
|
640
|
-
countTxs(): {
|
|
641
|
-
|
|
769
|
+
countTxs(): {
|
|
770
|
+
pending: number;
|
|
771
|
+
protected: number;
|
|
772
|
+
mined: number;
|
|
773
|
+
softDeleted: number;
|
|
774
|
+
totalMetadataBytes: number;
|
|
775
|
+
} {
|
|
776
|
+
return {
|
|
777
|
+
...this.#indices.countTxs(),
|
|
778
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount(),
|
|
779
|
+
};
|
|
642
780
|
}
|
|
643
781
|
|
|
644
782
|
// ============================================================================
|
|
@@ -653,9 +791,10 @@ export class TxPoolV2Impl {
|
|
|
653
791
|
tx: Tx,
|
|
654
792
|
state: 'pending' | { protected: SlotNumber } | { mined: L2BlockId },
|
|
655
793
|
opts: { source?: string } = {},
|
|
794
|
+
precomputedMeta?: TxMetaData,
|
|
656
795
|
): Promise<TxMetaData> {
|
|
657
796
|
const txHashStr = tx.getTxHash().toString();
|
|
658
|
-
const meta = await buildTxMetaData(tx);
|
|
797
|
+
const meta = precomputedMeta ?? (await buildTxMetaData(tx));
|
|
659
798
|
meta.receivedAt = this.#dateProvider.now();
|
|
660
799
|
|
|
661
800
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
@@ -672,9 +811,11 @@ export class TxPoolV2Impl {
|
|
|
672
811
|
}
|
|
673
812
|
|
|
674
813
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
675
|
-
this.#log.
|
|
814
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
676
815
|
eventName: 'tx-added-to-pool',
|
|
816
|
+
txHash: txHashStr,
|
|
677
817
|
state: stateStr,
|
|
818
|
+
source: opts.source,
|
|
678
819
|
});
|
|
679
820
|
|
|
680
821
|
return meta;
|
|
@@ -702,6 +843,29 @@ export class TxPoolV2Impl {
|
|
|
702
843
|
}
|
|
703
844
|
}
|
|
704
845
|
|
|
846
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */
|
|
847
|
+
async #evictTxs(txHashes: string[], reason: string): Promise<void> {
|
|
848
|
+
if (txHashes.length === 0) {
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
852
|
+
for (const txHashStr of txHashes) {
|
|
853
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
854
|
+
this.#addToEvictedCache(txHashStr);
|
|
855
|
+
}
|
|
856
|
+
await this.#deleteTxsBatch(txHashes);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
|
|
860
|
+
#addToEvictedCache(txHashStr: string): void {
|
|
861
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
862
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
863
|
+
const oldest = this.#evictedTxHashes.values().next().value!;
|
|
864
|
+
this.#evictedTxHashes.delete(oldest);
|
|
865
|
+
}
|
|
866
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
867
|
+
}
|
|
868
|
+
|
|
705
869
|
// ============================================================================
|
|
706
870
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
707
871
|
// ============================================================================
|
|
@@ -857,7 +1021,9 @@ export class TxPoolV2Impl {
|
|
|
857
1021
|
if (preAddResult.shouldIgnore) {
|
|
858
1022
|
// Transaction rejected - mark for deletion from DB
|
|
859
1023
|
rejected.push(meta.txHash);
|
|
860
|
-
this.#log.debug(
|
|
1024
|
+
this.#log.debug(
|
|
1025
|
+
`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`,
|
|
1026
|
+
);
|
|
861
1027
|
continue;
|
|
862
1028
|
}
|
|
863
1029
|
|
|
@@ -893,7 +1059,7 @@ export class TxPoolV2Impl {
|
|
|
893
1059
|
getFeePayerPendingTxs: (feePayer: string) => this.#indices.getFeePayerPendingTxs(feePayer),
|
|
894
1060
|
getPendingTxCount: () => this.#indices.getPendingTxCount(),
|
|
895
1061
|
getLowestPriorityPending: (limit: number) => this.#indices.getLowestPriorityPending(limit),
|
|
896
|
-
deleteTxs: (txHashes: string[]) => this.#
|
|
1062
|
+
deleteTxs: (txHashes: string[], reason?: string) => this.#evictTxs(txHashes, reason ?? 'unknown'),
|
|
897
1063
|
};
|
|
898
1064
|
}
|
|
899
1065
|
|