@aztec/p2p 0.0.1-commit.fce3e4f → 0.0.1-commit.fffb133c
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 +2 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +2 -3
- package/dest/client/interface.d.ts +18 -5
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +16 -19
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +460 -127
- package/dest/config.d.ts +4 -7
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +10 -13
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +61 -42
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +239 -265
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +21 -18
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +114 -109
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +17 -16
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +89 -128
- package/dest/mem_pools/attestation_pool/mocks.d.ts +11 -8
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +17 -13
- package/dest/mem_pools/instrumentation.d.ts +7 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +30 -12
- package/dest/mem_pools/interface.d.ts +3 -4
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +37 -27
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +314 -335
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +32 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +112 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +157 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +52 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +16 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +122 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +78 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +25 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +57 -0
- package/dest/mem_pools/tx_pool/index.d.ts +1 -2
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +6 -1
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +11 -6
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +30 -24
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -4
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +52 -19
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +18 -14
- package/dest/msg_validators/clock_tolerance.d.ts +21 -0
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -0
- package/dest/msg_validators/clock_tolerance.js +37 -0
- package/dest/msg_validators/index.d.ts +2 -2
- package/dest/msg_validators/index.d.ts.map +1 -1
- package/dest/msg_validators/index.js +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
- package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/index.js +3 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.js +104 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +212 -0
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +2 -2
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
- 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/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.d.ts +4 -3
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +10 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +20 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +8 -14
- package/dest/msg_validators/tx_validator/index.d.ts +2 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/size_validator.d.ts +6 -0
- package/dest/msg_validators/tx_validator/size_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/size_validator.js +20 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts +2 -2
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +3 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/services/dummy_service.d.ts +6 -2
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +3 -0
- package/dest/services/encoding.d.ts +1 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -6
- package/dest/services/libp2p/instrumentation.d.ts +1 -1
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
- package/dest/services/libp2p/instrumentation.js +20 -73
- package/dest/services/libp2p/libp2p_service.d.ts +31 -14
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +722 -168
- package/dest/services/peer-manager/metrics.d.ts +6 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +18 -21
- package/dest/services/peer-manager/peer_manager.d.ts +2 -2
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +4 -12
- 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 +2 -5
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/constants.d.ts +12 -0
- package/dest/services/reqresp/constants.d.ts.map +1 -0
- package/dest/services/reqresp/constants.js +7 -0
- package/dest/services/reqresp/interface.d.ts +2 -2
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +1 -1
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +5 -21
- package/dest/services/reqresp/protocols/auth.d.ts +2 -2
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/auth.js +2 -2
- package/dest/services/reqresp/protocols/block.d.ts +1 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +3 -2
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +7 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +2 -2
- 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 +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +5 -4
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +7 -3
- package/dest/services/reqresp/protocols/tx.d.ts +2 -3
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +402 -24
- package/dest/services/service.d.ts +16 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -3
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- 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 +4 -14
- package/dest/services/tx_collection/slow_tx_collection.d.ts +4 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +7 -6
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_provider.d.ts +4 -2
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +11 -2
- package/dest/services/tx_provider_instrumentation.d.ts +5 -2
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +13 -13
- package/dest/test-helpers/mock-tx-helpers.js +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -2
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +31 -17
- package/dest/testbench/worker_client_manager.d.ts +1 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +6 -1
- package/package.json +18 -18
- package/src/client/factory.ts +5 -10
- package/src/client/interface.ts +19 -4
- package/src/client/p2p_client.ts +101 -154
- package/src/config.ts +12 -18
- package/src/mem_pools/attestation_pool/attestation_pool.ts +68 -41
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +241 -289
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +163 -141
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +141 -164
- package/src/mem_pools/attestation_pool/mocks.ts +21 -15
- package/src/mem_pools/instrumentation.ts +38 -14
- package/src/mem_pools/interface.ts +2 -4
- package/src/mem_pools/tx_pool/README.md +270 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +367 -371
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +132 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +208 -0
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +162 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +93 -0
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
- package/src/mem_pools/tx_pool/index.ts +0 -1
- package/src/mem_pools/tx_pool/priority.ts +8 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +11 -5
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +23 -17
- package/src/msg_validators/attestation_validator/attestation_validator.ts +37 -22
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +13 -16
- package/src/msg_validators/clock_tolerance.ts +51 -0
- package/src/msg_validators/index.ts +1 -1
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
- package/src/msg_validators/proposal_validator/index.ts +3 -0
- package/src/msg_validators/proposal_validator/proposal_validator.ts +92 -0
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +230 -0
- package/src/msg_validators/tx_validator/archive_cache.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +4 -2
- package/src/msg_validators/tx_validator/data_validator.ts +12 -4
- package/src/msg_validators/tx_validator/factory.ts +3 -2
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +40 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +8 -25
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +13 -5
- package/src/msg_validators/tx_validator/size_validator.ts +18 -0
- package/src/msg_validators/tx_validator/test_utils.ts +1 -1
- package/src/msg_validators/tx_validator/timestamp_validator.ts +5 -2
- package/src/services/dummy_service.ts +6 -0
- package/src/services/encoding.ts +6 -5
- package/src/services/libp2p/instrumentation.ts +19 -73
- package/src/services/libp2p/libp2p_service.ts +369 -138
- package/src/services/peer-manager/metrics.ts +22 -21
- package/src/services/peer-manager/peer_manager.ts +5 -4
- package/src/services/peer-manager/peer_scoring.ts +1 -5
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +3 -1
- package/src/services/reqresp/constants.ts +14 -0
- package/src/services/reqresp/interface.ts +1 -1
- package/src/services/reqresp/metrics.ts +7 -23
- package/src/services/reqresp/protocols/auth.ts +2 -2
- package/src/services/reqresp/protocols/block.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +9 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +1 -1
- package/src/services/reqresp/protocols/status.ts +16 -12
- package/src/services/reqresp/protocols/tx.ts +1 -2
- package/src/services/service.ts +19 -4
- package/src/services/tx_collection/config.ts +1 -1
- package/src/services/tx_collection/fast_tx_collection.ts +3 -2
- package/src/services/tx_collection/instrumentation.ts +4 -21
- package/src/services/tx_collection/slow_tx_collection.ts +3 -3
- package/src/services/tx_collection/tx_collection.ts +6 -5
- package/src/services/tx_provider.ts +19 -3
- package/src/services/tx_provider_instrumentation.ts +18 -14
- package/src/test-helpers/mock-pubsub.ts +1 -1
- package/src/test-helpers/mock-tx-helpers.ts +1 -1
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/testbench/p2p_client_testbench_worker.ts +42 -22
- package/src/testbench/worker_client_manager.ts +6 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -80
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -238
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -12
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +0 -82
- package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/index.js +0 -1
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -283
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -97
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { insertIntoSortedArray } from '@aztec/foundation/array';
|
|
2
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
4
|
import { toArray } from '@aztec/foundation/iterable';
|
|
3
5
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
6
|
import type { TypedEventEmitter } from '@aztec/foundation/types';
|
|
5
|
-
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap
|
|
6
|
-
import {
|
|
7
|
-
import { GasFees } from '@aztec/stdlib/gas';
|
|
7
|
+
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
|
|
8
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
9
|
import type { MerkleTreeReadOperations, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
9
10
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
10
11
|
import type { TxAddedToPoolStats } from '@aztec/stdlib/stats';
|
|
11
|
-
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
12
12
|
import { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
|
|
13
13
|
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
14
14
|
|
|
@@ -16,49 +16,56 @@ import assert from 'assert';
|
|
|
16
16
|
import EventEmitter from 'node:events';
|
|
17
17
|
|
|
18
18
|
import { ArchiveCache } from '../../msg_validators/tx_validator/archive_cache.js';
|
|
19
|
-
import { GasTxValidator } from '../../msg_validators/tx_validator/gas_validator.js';
|
|
20
19
|
import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instrumentation.js';
|
|
20
|
+
import { EvictionManager } from './eviction/eviction_manager.js';
|
|
21
|
+
import {
|
|
22
|
+
FeePayerTxInfo,
|
|
23
|
+
type PendingTxInfo,
|
|
24
|
+
type PreAddPoolAccess,
|
|
25
|
+
type TxBlockReference,
|
|
26
|
+
type TxPoolOperations,
|
|
27
|
+
} from './eviction/eviction_strategy.js';
|
|
28
|
+
import { FeePayerBalanceEvictionRule } from './eviction/fee_payer_balance_eviction_rule.js';
|
|
29
|
+
import { InvalidTxsAfterMiningRule } from './eviction/invalid_txs_after_mining_rule.js';
|
|
30
|
+
import { InvalidTxsAfterReorgRule } from './eviction/invalid_txs_after_reorg_rule.js';
|
|
31
|
+
import { LowPriorityEvictionRule } from './eviction/low_priority_eviction_rule.js';
|
|
32
|
+
import { NullifierConflictPreAddRule } from './eviction/nullifier_conflict_pre_add_rule.js';
|
|
21
33
|
import { getPendingTxPriority } from './priority.js';
|
|
22
34
|
import type { TxPool, TxPoolEvents, TxPoolOptions } from './tx_pool.js';
|
|
23
35
|
|
|
24
36
|
/**
|
|
25
37
|
* KV implementation of the Transaction Pool.
|
|
26
38
|
*/
|
|
27
|
-
export class AztecKVTxPool
|
|
39
|
+
export class AztecKVTxPool
|
|
40
|
+
extends (EventEmitter as new () => TypedEventEmitter<TxPoolEvents>)
|
|
41
|
+
implements TxPool, TxPoolOperations
|
|
42
|
+
{
|
|
28
43
|
#store: AztecAsyncKVStore;
|
|
29
44
|
|
|
30
45
|
/** Our tx pool, stored as a Map, with K: tx hash and V: the transaction. */
|
|
31
46
|
#txs: AztecAsyncMap<string, Buffer>;
|
|
32
47
|
|
|
33
|
-
/**
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
/** The tx evicion logic will kick after pool size is greater than maxTxPoolSize * txPoolOverflowFactor */
|
|
37
|
-
txPoolOverflowFactor: number = 1;
|
|
48
|
+
/** Holds the historical block for each tx */
|
|
49
|
+
#pendingTxHashToHistoricalBlockHeaderHash: AztecAsyncMap<string, string>;
|
|
38
50
|
|
|
39
51
|
/** Index from tx hash to the block number in which they were mined, filtered by mined txs. */
|
|
40
|
-
#minedTxHashToBlock: AztecAsyncMap<string,
|
|
52
|
+
#minedTxHashToBlock: AztecAsyncMap<string, BlockNumber>;
|
|
41
53
|
|
|
42
54
|
/** Index from tx priority (stored as hex) to its tx hash, filtered by pending txs. */
|
|
43
55
|
#pendingTxPriorityToHash: AztecAsyncMultiMap<string, string>;
|
|
44
56
|
|
|
45
|
-
/** Index from tx hash to its tx size (in bytes), filtered by pending txs. */
|
|
46
|
-
#pendingTxHashToSize: AztecAsyncMap<string, number>;
|
|
47
|
-
|
|
48
|
-
/** Index from tx hash to its header hash, filtered by pending txs. */
|
|
49
|
-
#pendingTxHashToHeaderHash: AztecAsyncMap<string, string>;
|
|
50
|
-
|
|
51
57
|
/** Map from tx hash to the block number it was originally mined in (for soft-deleted txs). */
|
|
52
|
-
#deletedMinedTxHashes: AztecAsyncMap<string,
|
|
58
|
+
#deletedMinedTxHashes: AztecAsyncMap<string, BlockNumber>;
|
|
53
59
|
|
|
54
60
|
/** MultiMap from block number to deleted mined tx hashes for efficient cleanup. */
|
|
55
|
-
#blockToDeletedMinedTxHash: AztecAsyncMultiMap<
|
|
61
|
+
#blockToDeletedMinedTxHash: AztecAsyncMultiMap<BlockNumber, string>;
|
|
62
|
+
|
|
63
|
+
#historicalHeaderToTxHash: AztecAsyncMultiMap<string, string>;
|
|
56
64
|
|
|
57
|
-
|
|
58
|
-
#pendingTxSize: AztecAsyncSingleton<number>;
|
|
65
|
+
#feePayerToBalanceEntry: AztecAsyncMultiMap<string, Buffer>;
|
|
59
66
|
|
|
60
|
-
/**
|
|
61
|
-
#
|
|
67
|
+
/** Index from nullifier to pending tx hash */
|
|
68
|
+
#pendingNullifierToTxHash: AztecAsyncMap<string, string>;
|
|
62
69
|
|
|
63
70
|
/** In-memory set of txs that should not be evicted from the pool. */
|
|
64
71
|
#nonEvictableTxs: Set<string>;
|
|
@@ -75,8 +82,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
75
82
|
/** Number of txs to archive. */
|
|
76
83
|
#archivedTxLimit: number = 0;
|
|
77
84
|
|
|
78
|
-
|
|
79
|
-
#worldStateSynchronizer: WorldStateSynchronizer;
|
|
85
|
+
#evictionManager: EvictionManager;
|
|
80
86
|
|
|
81
87
|
#log: Logger;
|
|
82
88
|
|
|
@@ -93,7 +99,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
93
99
|
constructor(
|
|
94
100
|
store: AztecAsyncKVStore,
|
|
95
101
|
archive: AztecAsyncKVStore,
|
|
96
|
-
|
|
102
|
+
worldState: WorldStateSynchronizer,
|
|
97
103
|
telemetry: TelemetryClient = getTelemetryClient(),
|
|
98
104
|
config: TxPoolOptions = {},
|
|
99
105
|
log = createLogger('p2p:tx_pool'),
|
|
@@ -101,18 +107,32 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
101
107
|
super();
|
|
102
108
|
|
|
103
109
|
this.#log = log;
|
|
110
|
+
|
|
111
|
+
this.#evictionManager = new EvictionManager(this);
|
|
112
|
+
this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
|
|
113
|
+
this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(worldState));
|
|
114
|
+
this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(worldState));
|
|
115
|
+
this.#evictionManager.registerRule(
|
|
116
|
+
new LowPriorityEvictionRule({
|
|
117
|
+
//NOTE: 0 effectively disables low priority eviction
|
|
118
|
+
maxPoolSize: config.maxPendingTxCount ?? 0,
|
|
119
|
+
}),
|
|
120
|
+
);
|
|
121
|
+
this.#evictionManager.registerPreAddRule(new NullifierConflictPreAddRule());
|
|
122
|
+
|
|
104
123
|
this.updateConfig(config);
|
|
105
124
|
|
|
106
125
|
this.#txs = store.openMap('txs');
|
|
107
126
|
this.#minedTxHashToBlock = store.openMap('txHashToBlockMined');
|
|
108
127
|
this.#pendingTxPriorityToHash = store.openMultiMap('pendingTxFeeToHash');
|
|
109
|
-
this.#pendingTxHashToSize = store.openMap('pendingTxHashToSize');
|
|
110
|
-
this.#pendingTxHashToHeaderHash = store.openMap('pendingTxHashToHeaderHash');
|
|
111
|
-
this.#pendingTxSize = store.openSingleton('pendingTxSize');
|
|
112
128
|
this.#deletedMinedTxHashes = store.openMap('deletedMinedTxHashes');
|
|
113
129
|
this.#blockToDeletedMinedTxHash = store.openMultiMap('blockToDeletedMinedTxHash');
|
|
114
130
|
|
|
115
|
-
this.#
|
|
131
|
+
this.#pendingTxHashToHistoricalBlockHeaderHash = store.openMap('txHistoricalBlock');
|
|
132
|
+
this.#historicalHeaderToTxHash = store.openMultiMap('historicalHeaderToPendingTxHash');
|
|
133
|
+
this.#feePayerToBalanceEntry = store.openMultiMap('feePayerToBalanceEntry');
|
|
134
|
+
this.#pendingNullifierToTxHash = store.openMap('pendingNullifierToTxHash');
|
|
135
|
+
|
|
116
136
|
this.#nonEvictableTxs = new Set<string>();
|
|
117
137
|
|
|
118
138
|
this.#archivedTxs = archive.openMap('archivedTxs');
|
|
@@ -120,7 +140,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
120
140
|
|
|
121
141
|
this.#store = store;
|
|
122
142
|
this.#archive = archive;
|
|
123
|
-
|
|
143
|
+
|
|
124
144
|
this.#metrics = new PoolInstrumentation(telemetry, PoolName.TX_POOL, this.countTxs, () => store.estimateSize());
|
|
125
145
|
}
|
|
126
146
|
|
|
@@ -141,6 +161,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
141
161
|
}
|
|
142
162
|
return true;
|
|
143
163
|
}
|
|
164
|
+
|
|
144
165
|
/**
|
|
145
166
|
* Marks transactions as mined in a block and updates the pool state accordingly.
|
|
146
167
|
* Removes the transactions from the pending set and adds them to the mined set.
|
|
@@ -153,68 +174,80 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
153
174
|
return Promise.resolve();
|
|
154
175
|
}
|
|
155
176
|
|
|
156
|
-
const
|
|
157
|
-
const
|
|
177
|
+
const uniqueMinedNullifiers: Fr[] = [];
|
|
178
|
+
const uniqueMinedFeePayers: AztecAddress[] = [];
|
|
158
179
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
180
|
+
try {
|
|
181
|
+
await this.#store.transactionAsync(async () => {
|
|
182
|
+
for (const hash of txHashes) {
|
|
183
|
+
const key = hash.toString();
|
|
184
|
+
await this.#minedTxHashToBlock.set(key, blockHeader.globalVariables.blockNumber);
|
|
185
|
+
|
|
186
|
+
const tx = await this.getTxByHash(hash);
|
|
187
|
+
if (tx) {
|
|
188
|
+
const nullifiers = tx.data.getNonEmptyNullifiers();
|
|
189
|
+
|
|
190
|
+
nullifiers.forEach(nullifier => insertIntoSortedArray(uniqueMinedNullifiers, nullifier, Fr.cmp, false));
|
|
191
|
+
insertIntoSortedArray(
|
|
192
|
+
uniqueMinedFeePayers,
|
|
193
|
+
tx.data.feePayer,
|
|
194
|
+
(a, b) => a.toField().cmp(b.toField()),
|
|
195
|
+
false,
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
await this.removePendingTxIndicesInDbTx(tx, key);
|
|
199
|
+
}
|
|
163
200
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
201
|
+
// If this tx was previously soft-deleted, remove it from the deleted sets
|
|
202
|
+
if (await this.#deletedMinedTxHashes.hasAsync(key)) {
|
|
203
|
+
const originalBlock = await this.#deletedMinedTxHashes.getAsync(key);
|
|
204
|
+
await this.#deletedMinedTxHashes.delete(key);
|
|
205
|
+
// Remove from block-to-hash mapping
|
|
206
|
+
if (originalBlock !== undefined) {
|
|
207
|
+
await this.#blockToDeletedMinedTxHash.deleteValue(originalBlock, key);
|
|
208
|
+
}
|
|
171
209
|
}
|
|
172
210
|
}
|
|
211
|
+
});
|
|
173
212
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const tx = await this.getPendingTxByHash(hash);
|
|
177
|
-
if (tx) {
|
|
178
|
-
const nullifiers = tx.data.getNonEmptyNullifiers();
|
|
179
|
-
nullifiers.forEach(nullifier => minedNullifiers.add(nullifier.toString()));
|
|
180
|
-
minedFeePayers.add(tx.data.feePayer.toString());
|
|
181
|
-
pendingTxSize -= tx.getSize();
|
|
182
|
-
await this.removePendingTxIndices(tx, key);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
await this.#pendingTxSize.set(pendingTxSize);
|
|
213
|
+
await this.#evictionManager.evictAfterNewBlock(blockHeader, uniqueMinedNullifiers, uniqueMinedFeePayers);
|
|
186
214
|
|
|
187
|
-
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
// The non-evictable set is not considered when evicting transactions that are invalid after a block is mined.
|
|
192
|
-
this.#nonEvictableTxs.clear();
|
|
215
|
+
this.#metrics.transactionsRemoved(txHashes.map(hash => hash.toBigInt()));
|
|
216
|
+
} catch (err) {
|
|
217
|
+
this.#log.warn('Unexpected error when marking txs as mined', { err });
|
|
218
|
+
}
|
|
193
219
|
}
|
|
194
220
|
|
|
195
|
-
public async markMinedAsPending(txHashes: TxHash[]): Promise<void> {
|
|
221
|
+
public async markMinedAsPending(txHashes: TxHash[], latestBlock: BlockNumber): Promise<void> {
|
|
196
222
|
if (txHashes.length === 0) {
|
|
197
223
|
return Promise.resolve();
|
|
198
224
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
225
|
+
try {
|
|
226
|
+
await this.#store.transactionAsync(async () => {
|
|
227
|
+
for (const hash of txHashes) {
|
|
228
|
+
const key = hash.toString();
|
|
229
|
+
await this.#minedTxHashToBlock.delete(key);
|
|
230
|
+
|
|
231
|
+
// Clear soft-delete metadata if this tx was previously soft-deleted,
|
|
232
|
+
// so cleanupDeletedMinedTxs won't later hard-delete it while it's pending
|
|
233
|
+
const deletedBlock = await this.#deletedMinedTxHashes.getAsync(key);
|
|
234
|
+
if (deletedBlock !== undefined) {
|
|
235
|
+
await this.#deletedMinedTxHashes.delete(key);
|
|
236
|
+
await this.#blockToDeletedMinedTxHash.deleteValue(deletedBlock, key);
|
|
237
|
+
}
|
|
204
238
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
239
|
+
// Rehydrate the tx in the in-memory pending txs mapping
|
|
240
|
+
const tx = await this.getTxByHash(hash);
|
|
241
|
+
if (tx) {
|
|
242
|
+
await this.addPendingTxIndicesInDbTx(tx, key);
|
|
243
|
+
}
|
|
210
244
|
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
await this.#pendingTxSize.set(pendingTxSize);
|
|
214
|
-
});
|
|
245
|
+
});
|
|
215
246
|
|
|
216
|
-
|
|
217
|
-
|
|
247
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock);
|
|
248
|
+
} catch (err) {
|
|
249
|
+
this.#log.warn('Unexpected error when marking mined txs as pending', { err });
|
|
250
|
+
}
|
|
218
251
|
}
|
|
219
252
|
|
|
220
253
|
public async getPendingTxHashes(): Promise<TxHash[]> {
|
|
@@ -222,38 +255,6 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
222
255
|
return vals.map(TxHash.fromString);
|
|
223
256
|
}
|
|
224
257
|
|
|
225
|
-
public async getMinedTxHashes(): Promise<[TxHash, number][]> {
|
|
226
|
-
const vals = await toArray(this.#minedTxHashToBlock.entriesAsync());
|
|
227
|
-
return vals.map(([txHash, blockNumber]) => [TxHash.fromString(txHash), blockNumber]);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
public async getPendingTxCount(): Promise<number> {
|
|
231
|
-
return (await this.#pendingTxHashToHeaderHash.sizeAsync()) ?? 0;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
public async getMinedTxCount(): Promise<number> {
|
|
235
|
-
return (await this.#minedTxHashToBlock.sizeAsync()) ?? 0;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
public async getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | 'deleted' | undefined> {
|
|
239
|
-
const key = txHash.toString();
|
|
240
|
-
const [isMined, isKnown, isDeleted] = await Promise.all([
|
|
241
|
-
this.#minedTxHashToBlock.hasAsync(key),
|
|
242
|
-
this.#txs.hasAsync(key),
|
|
243
|
-
this.#deletedMinedTxHashes.hasAsync(key),
|
|
244
|
-
]);
|
|
245
|
-
|
|
246
|
-
if (isDeleted) {
|
|
247
|
-
return 'deleted';
|
|
248
|
-
} else if (isMined) {
|
|
249
|
-
return 'mined';
|
|
250
|
-
} else if (isKnown) {
|
|
251
|
-
return 'pending';
|
|
252
|
-
} else {
|
|
253
|
-
return undefined;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
258
|
/**
|
|
258
259
|
* Checks if a transaction exists in the pool and returns it.
|
|
259
260
|
* @param txHash - The generated tx hash.
|
|
@@ -290,44 +291,82 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
290
291
|
|
|
291
292
|
/**
|
|
292
293
|
* Adds a list of transactions to the pool. Duplicates are ignored.
|
|
294
|
+
* Handles nullifier deduplication: if an incoming tx has a nullifier conflict with
|
|
295
|
+
* existing pending txs, it will either replace them (if higher fee) or be rejected.
|
|
293
296
|
* @param txs - An array of txs to be added to the pool.
|
|
294
|
-
* @returns
|
|
297
|
+
* @returns count of added transactions
|
|
295
298
|
*/
|
|
296
299
|
public async addTxs(txs: Tx[], opts: { source?: string } = {}): Promise<number> {
|
|
300
|
+
if (txs.length === 0) {
|
|
301
|
+
return Promise.resolve(0);
|
|
302
|
+
}
|
|
303
|
+
|
|
297
304
|
const addedTxs: Tx[] = [];
|
|
305
|
+
const uniqueFeePayers: AztecAddress[] = [];
|
|
306
|
+
const replacedTxHashes: TxHash[] = [];
|
|
298
307
|
const hashesAndStats = txs.map(tx => ({ txHash: tx.getTxHash(), txStats: tx.getStats() }));
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
308
|
+
try {
|
|
309
|
+
await this.#store.transactionAsync(async () => {
|
|
310
|
+
for (let i = 0; i < txs.length; i++) {
|
|
311
|
+
const tx = txs[i];
|
|
303
312
|
const { txHash, txStats } = hashesAndStats[i];
|
|
304
313
|
const key = txHash.toString();
|
|
305
314
|
if (await this.#txs.hasAsync(key)) {
|
|
306
|
-
this.#log.debug(`Tx ${
|
|
307
|
-
|
|
315
|
+
this.#log.debug(`Tx ${key} already exists in the pool`);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const poolAccess = this.getPreAddPoolAccess();
|
|
320
|
+
const { shouldReject, txHashesToEvict } = await this.#evictionManager.runPreAddRules(tx, poolAccess);
|
|
321
|
+
if (shouldReject) {
|
|
322
|
+
continue;
|
|
308
323
|
}
|
|
309
324
|
|
|
310
|
-
|
|
325
|
+
for (const txHashToEvict of txHashesToEvict) {
|
|
326
|
+
const txToDelete = await this.getTxByHash(txHashToEvict);
|
|
327
|
+
if (txToDelete) {
|
|
328
|
+
const evictedKey = txHashToEvict.toString();
|
|
329
|
+
await this.deletePendingTxInDbTx(txToDelete, evictedKey);
|
|
330
|
+
replacedTxHashes.push(txHashToEvict);
|
|
331
|
+
this.#log.verbose(`Evicted tx ${evictedKey} due to higher-fee tx ${key}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
this.#log.verbose(`Adding tx ${key} to pool`, {
|
|
311
336
|
eventName: 'tx-added-to-pool',
|
|
312
337
|
...txStats,
|
|
313
338
|
} satisfies TxAddedToPoolStats);
|
|
314
339
|
|
|
315
340
|
await this.#txs.set(key, tx.toBuffer());
|
|
316
|
-
addedTxs.push(tx
|
|
341
|
+
addedTxs.push(tx);
|
|
342
|
+
insertIntoSortedArray(uniqueFeePayers, tx.data.feePayer, (a, b) => a.toField().cmp(b.toField()), false);
|
|
343
|
+
|
|
344
|
+
await this.#pendingTxHashToHistoricalBlockHeaderHash.set(
|
|
345
|
+
key,
|
|
346
|
+
(await tx.data.constants.anchorBlockHeader.hash()).toString(),
|
|
347
|
+
);
|
|
317
348
|
|
|
318
349
|
if (!(await this.#minedTxHashToBlock.hasAsync(key))) {
|
|
319
|
-
|
|
320
|
-
await this.addPendingTxIndices(tx, key);
|
|
350
|
+
await this.addPendingTxIndicesInDbTx(tx, key);
|
|
321
351
|
this.#metrics.recordSize(tx);
|
|
322
352
|
}
|
|
323
|
-
}
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
357
|
+
addedTxs.map(({ txHash }) => txHash),
|
|
358
|
+
uniqueFeePayers,
|
|
324
359
|
);
|
|
360
|
+
} catch (err) {
|
|
361
|
+
this.#log.warn('Unexpected error when adding txs', { err });
|
|
362
|
+
}
|
|
325
363
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
364
|
+
if (replacedTxHashes.length > 0) {
|
|
365
|
+
this.#metrics.transactionsRemoved(replacedTxHashes.map(hash => hash.toBigInt()));
|
|
366
|
+
}
|
|
329
367
|
|
|
330
368
|
if (addedTxs.length > 0) {
|
|
369
|
+
this.#metrics.transactionsAdded(addedTxs);
|
|
331
370
|
this.emit('txs-added', { ...opts, txs: addedTxs });
|
|
332
371
|
}
|
|
333
372
|
return addedTxs.length;
|
|
@@ -339,54 +378,63 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
339
378
|
* @param txHashes - An array of tx hashes to be deleted from the tx pool.
|
|
340
379
|
* @returns Empty promise.
|
|
341
380
|
*/
|
|
342
|
-
public deleteTxs(txHashes: TxHash[], opts
|
|
381
|
+
public deleteTxs(txHashes: TxHash[], opts?: { permanently?: boolean }): Promise<void> {
|
|
343
382
|
if (txHashes.length === 0) {
|
|
344
383
|
return Promise.resolve();
|
|
345
384
|
}
|
|
385
|
+
|
|
346
386
|
const deletedTxs: Tx[] = [];
|
|
347
387
|
const poolDbTx = this.#store.transactionAsync(async () => {
|
|
348
|
-
let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
349
388
|
for (const hash of txHashes) {
|
|
350
389
|
const key = hash.toString();
|
|
351
390
|
const tx = await this.getTxByHash(hash);
|
|
391
|
+
if (!tx) {
|
|
392
|
+
this.#log.trace(`Skipping deletion of missing tx ${key} from pool`);
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
352
395
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
await this.#txs.delete(key);
|
|
362
|
-
} else {
|
|
363
|
-
// Soft-delete mined transactions: remove from mined set but keep in storage
|
|
364
|
-
this.#log.trace(`Soft-deleting mined tx ${key} from pool`);
|
|
365
|
-
await this.#deletedMinedTxHashes.set(key, minedBlockNumber);
|
|
366
|
-
await this.#blockToDeletedMinedTxHash.set(minedBlockNumber, key);
|
|
367
|
-
}
|
|
368
|
-
} else {
|
|
369
|
-
// Permanently delete pending transactions
|
|
370
|
-
this.#log.trace(`Deleting pending tx ${key} from pool`);
|
|
371
|
-
pendingTxSize -= tx.getSize();
|
|
372
|
-
await this.removePendingTxIndices(tx, key);
|
|
373
|
-
await this.#txs.delete(key);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
if (!opts.eviction && this.#archivedTxLimit) {
|
|
396
|
+
const minedBlockNumber = await this.#minedTxHashToBlock.getAsync(key);
|
|
397
|
+
const txIsPending = minedBlockNumber === undefined;
|
|
398
|
+
if (txIsPending) {
|
|
399
|
+
await this.deletePendingTxInDbTx(tx, key);
|
|
400
|
+
} else {
|
|
401
|
+
await this.deleteMinedTx(key, minedBlockNumber!, opts?.permanently ?? false);
|
|
402
|
+
const shouldArchiveTx = this.#archivedTxLimit && !opts?.permanently;
|
|
403
|
+
if (shouldArchiveTx) {
|
|
377
404
|
deletedTxs.push(tx);
|
|
378
405
|
}
|
|
379
|
-
} else {
|
|
380
|
-
this.#log.trace(`Skipping deletion of missing tx ${key} from pool`);
|
|
381
406
|
}
|
|
382
407
|
}
|
|
383
|
-
|
|
384
|
-
await this.#pendingTxSize.set(pendingTxSize);
|
|
385
408
|
});
|
|
409
|
+
this.#metrics.transactionsRemoved(txHashes.map(hash => hash.toBigInt()));
|
|
386
410
|
this.#log.debug(`Deleted ${txHashes.length} txs from pool`, { txHashes });
|
|
411
|
+
|
|
387
412
|
return this.#archivedTxLimit ? poolDbTx.then(() => this.archiveTxs(deletedTxs)) : poolDbTx;
|
|
388
413
|
}
|
|
389
414
|
|
|
415
|
+
private async deleteMinedTx(txHash: `0x${string}`, minedBlockNumber: BlockNumber, permanently: boolean) {
|
|
416
|
+
await this.#minedTxHashToBlock.delete(txHash);
|
|
417
|
+
if (permanently) {
|
|
418
|
+
this.#log.trace(`Deleting mined tx ${txHash} from pool`);
|
|
419
|
+
await this.#txs.delete(txHash);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Soft-delete mined transactions: remove from mined set but keep in storage
|
|
424
|
+
this.#log.trace(`Soft-deleting mined tx ${txHash} from pool`);
|
|
425
|
+
await this.#deletedMinedTxHashes.set(txHash, minedBlockNumber);
|
|
426
|
+
await this.#blockToDeletedMinedTxHash.set(minedBlockNumber, txHash);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Assumes being called within a DB transaction
|
|
430
|
+
private async deletePendingTxInDbTx(tx: Tx, txHash: `0x${string}`) {
|
|
431
|
+
// We always permanently delete pending transactions
|
|
432
|
+
this.#log.trace(`Deleting pending tx ${txHash} from pool`);
|
|
433
|
+
await this.removePendingTxIndicesInDbTx(tx, txHash);
|
|
434
|
+
await this.#txs.delete(txHash);
|
|
435
|
+
await this.#pendingTxHashToHistoricalBlockHeaderHash.delete(txHash);
|
|
436
|
+
}
|
|
437
|
+
|
|
390
438
|
/**
|
|
391
439
|
* Gets all the transactions stored in the pool.
|
|
392
440
|
* @returns Array of tx objects in the order they were added to the pool.
|
|
@@ -405,30 +453,107 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
405
453
|
return vals.map(x => TxHash.fromString(x));
|
|
406
454
|
}
|
|
407
455
|
|
|
408
|
-
public
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
456
|
+
public async getPendingTxInfos(): Promise<PendingTxInfo[]> {
|
|
457
|
+
const vals = await toArray(this.#pendingTxPriorityToHash.valuesAsync());
|
|
458
|
+
const results = await Promise.all(vals.map(val => this.getPendingTxInfo(TxHash.fromString(val))));
|
|
459
|
+
return results.filter((info): info is PendingTxInfo => info !== undefined);
|
|
460
|
+
}
|
|
412
461
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
462
|
+
private async getPendingTxInfo(txHash: TxHash): Promise<PendingTxInfo | undefined> {
|
|
463
|
+
let historicalBlockHash = await this.#pendingTxHashToHistoricalBlockHeaderHash.getAsync(txHash.toString());
|
|
464
|
+
// Not all tx might have this index created.
|
|
465
|
+
if (!historicalBlockHash) {
|
|
466
|
+
const tx = await this.getTxByHash(txHash);
|
|
467
|
+
if (!tx) {
|
|
468
|
+
this.#log.warn(`PendingTxInfo:tx ${txHash} not found`);
|
|
469
|
+
return undefined;
|
|
417
470
|
}
|
|
471
|
+
|
|
472
|
+
historicalBlockHash = (await tx.data.constants.anchorBlockHeader.hash()).toString();
|
|
473
|
+
await this.#pendingTxHashToHistoricalBlockHeaderHash.set(txHash.toString(), historicalBlockHash);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return {
|
|
477
|
+
txHash,
|
|
478
|
+
blockHash: Fr.fromString(historicalBlockHash),
|
|
479
|
+
isEvictable: !this.#nonEvictableTxs.has(txHash.toString()),
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
public async getPendingTxsReferencingBlocks(blockHashes: Fr[]): Promise<TxBlockReference[]> {
|
|
484
|
+
const result: TxBlockReference[] = [];
|
|
485
|
+
for (const blockHash of blockHashes) {
|
|
486
|
+
const chunk = await toArray(this.#historicalHeaderToTxHash.getValuesAsync(blockHash.toString()));
|
|
487
|
+
result.push(
|
|
488
|
+
...chunk.map(txHash => ({
|
|
489
|
+
txHash: TxHash.fromString(txHash),
|
|
490
|
+
blockHash,
|
|
491
|
+
isEvictable: !this.#nonEvictableTxs.has(txHash),
|
|
492
|
+
})),
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
return result;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
public async getPendingFeePayers(): Promise<AztecAddress[]> {
|
|
500
|
+
const feePayers: AztecAddress[] = [];
|
|
501
|
+
for await (const feePayer of this.#feePayerToBalanceEntry.keysAsync()) {
|
|
502
|
+
const address = AztecAddress.fromString(feePayer);
|
|
503
|
+
insertIntoSortedArray(feePayers, address, (a, b) => a.toField().cmp(b.toField()), false);
|
|
504
|
+
}
|
|
505
|
+
return feePayers;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
public async *getFeePayerTxInfos(feePayer: AztecAddress): AsyncIterable<FeePayerTxInfo> {
|
|
509
|
+
for await (const value of this.#feePayerToBalanceEntry.getValuesAsync(feePayer.toString())) {
|
|
510
|
+
const info = FeePayerTxInfo.decode(value);
|
|
511
|
+
info.isEvictable = !this.#nonEvictableTxs.has(info.txHash.toString());
|
|
512
|
+
yield info;
|
|
418
513
|
}
|
|
514
|
+
}
|
|
419
515
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
516
|
+
public async getMinedTxHashes(): Promise<[TxHash, BlockNumber][]> {
|
|
517
|
+
const vals = await toArray(this.#minedTxHashToBlock.entriesAsync());
|
|
518
|
+
return vals.map(([txHash, blockNumber]) => [TxHash.fromString(txHash), blockNumber]);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
public async getPendingTxCount(): Promise<number> {
|
|
522
|
+
return (await this.#pendingTxPriorityToHash.sizeAsync()) ?? 0;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
public async getMinedTxCount(): Promise<number> {
|
|
526
|
+
return (await this.#minedTxHashToBlock.sizeAsync()) ?? 0;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
public async getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | 'deleted' | undefined> {
|
|
530
|
+
const key = txHash.toString();
|
|
531
|
+
const [isMined, isKnown, isDeleted] = await Promise.all([
|
|
532
|
+
this.#minedTxHashToBlock.hasAsync(key),
|
|
533
|
+
this.#txs.hasAsync(key),
|
|
534
|
+
this.#deletedMinedTxHashes.hasAsync(key),
|
|
535
|
+
]);
|
|
536
|
+
|
|
537
|
+
if (isDeleted) {
|
|
538
|
+
return 'deleted';
|
|
539
|
+
} else if (isMined) {
|
|
540
|
+
return 'mined';
|
|
541
|
+
} else if (isKnown) {
|
|
542
|
+
return 'pending';
|
|
543
|
+
} else {
|
|
544
|
+
return undefined;
|
|
424
545
|
}
|
|
546
|
+
}
|
|
425
547
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
548
|
+
public updateConfig(cfg: TxPoolOptions): void {
|
|
549
|
+
if (typeof cfg.archivedTxLimit === 'number') {
|
|
550
|
+
assert(cfg.archivedTxLimit >= 0, 'archivedTxLimit must be greater or equal to 0');
|
|
551
|
+
this.#archivedTxLimit = cfg.archivedTxLimit;
|
|
429
552
|
}
|
|
430
553
|
|
|
431
|
-
|
|
554
|
+
if (this.#evictionManager) {
|
|
555
|
+
this.#evictionManager.updateConfig(cfg);
|
|
556
|
+
}
|
|
432
557
|
}
|
|
433
558
|
|
|
434
559
|
public markTxsAsNonEvictable(txHashes: TxHash[]): Promise<void> {
|
|
@@ -436,17 +561,26 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
436
561
|
return Promise.resolve();
|
|
437
562
|
}
|
|
438
563
|
|
|
564
|
+
public clearNonEvictableTxs(): Promise<void> {
|
|
565
|
+
// Clear the non-evictable set after completing the DB updates above.
|
|
566
|
+
// This ensures pinned (non-evictable) txs are protected while we mark mined txs,
|
|
567
|
+
// but they won't remain pinned indefinitely across blocks. Note that eviction rules
|
|
568
|
+
// (including post-mining invalidation) respect the non-evictable flag while it is set.
|
|
569
|
+
this.#nonEvictableTxs.clear();
|
|
570
|
+
return Promise.resolve();
|
|
571
|
+
}
|
|
572
|
+
|
|
439
573
|
/**
|
|
440
574
|
* Permanently deletes deleted mined transactions from blocks up to and including the specified block number.
|
|
441
575
|
* @param blockNumber - Block number threshold. Deleted mined txs from this block or earlier will be permanently deleted.
|
|
442
576
|
* @returns The number of transactions permanently deleted.
|
|
443
577
|
*/
|
|
444
|
-
public async cleanupDeletedMinedTxs(blockNumber:
|
|
578
|
+
public async cleanupDeletedMinedTxs(blockNumber: BlockNumber): Promise<number> {
|
|
445
579
|
let deletedCount = 0;
|
|
446
|
-
const txHashesToDelete: string[] = [];
|
|
447
|
-
const blocksToDelete: number[] = [];
|
|
448
|
-
|
|
449
580
|
await this.#store.transactionAsync(async () => {
|
|
581
|
+
const txHashesToDelete: string[] = [];
|
|
582
|
+
const blocksToDelete: BlockNumber[] = [];
|
|
583
|
+
|
|
450
584
|
// Iterate through all entries and check block numbers
|
|
451
585
|
for await (const [block, txHash] of this.#blockToDeletedMinedTxHash.entriesAsync()) {
|
|
452
586
|
if (block <= blockNumber) {
|
|
@@ -460,6 +594,7 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
460
594
|
deletedCount++;
|
|
461
595
|
}
|
|
462
596
|
}
|
|
597
|
+
this.#metrics.transactionsRemoved(txHashesToDelete);
|
|
463
598
|
|
|
464
599
|
// Clean up block-to-hash mapping - delete all values for each block
|
|
465
600
|
for (const block of blocksToDelete) {
|
|
@@ -476,15 +611,6 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
476
611
|
return deletedCount;
|
|
477
612
|
}
|
|
478
613
|
|
|
479
|
-
/**
|
|
480
|
-
* Creates a GasTxValidator instance.
|
|
481
|
-
* @param db - DB for the validator to use
|
|
482
|
-
* @returns A GasTxValidator instance
|
|
483
|
-
*/
|
|
484
|
-
protected createGasTxValidator(db: MerkleTreeReadOperations): GasTxValidator {
|
|
485
|
-
return new GasTxValidator(new DatabasePublicStateSource(db), ProtocolContractAddress.FeeJuice, GasFees.empty());
|
|
486
|
-
}
|
|
487
|
-
|
|
488
614
|
/**
|
|
489
615
|
* Creates an ArchiveCache instance.
|
|
490
616
|
* @param db - DB for the cache to use
|
|
@@ -494,34 +620,9 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
494
620
|
return new ArchiveCache(db);
|
|
495
621
|
}
|
|
496
622
|
|
|
497
|
-
/**
|
|
498
|
-
* Checks if a cached transaction exists in the in-memory pending tx pool and returns it.
|
|
499
|
-
* Otherwise, it checks the tx pool, updates the pending tx pool, and returns the tx.
|
|
500
|
-
* @param txHash - The generated tx hash.
|
|
501
|
-
* @returns The transaction, if found, 'undefined' otherwise.
|
|
502
|
-
*/
|
|
503
|
-
private async getPendingTxByHash(txHash: TxHash | string): Promise<Tx | undefined> {
|
|
504
|
-
let key;
|
|
505
|
-
if (typeof txHash === 'string') {
|
|
506
|
-
key = txHash;
|
|
507
|
-
txHash = TxHash.fromString(txHash);
|
|
508
|
-
} else {
|
|
509
|
-
key = txHash.toString();
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
if (this.#pendingTxs.has(key)) {
|
|
513
|
-
return this.#pendingTxs.get(key);
|
|
514
|
-
}
|
|
515
|
-
const tx = await this.getTxByHash(txHash);
|
|
516
|
-
if (tx) {
|
|
517
|
-
this.#pendingTxs.set(key, tx);
|
|
518
|
-
return tx;
|
|
519
|
-
}
|
|
520
|
-
return undefined;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
623
|
/**
|
|
524
624
|
* Archives a list of txs for future reference. The number of archived txs is limited by the specified archivedTxLimit.
|
|
625
|
+
* Note: Pending txs should not be archived, only finalized txs
|
|
525
626
|
* @param txs - The list of transactions to archive.
|
|
526
627
|
* @returns Empty promise.
|
|
527
628
|
*/
|
|
@@ -529,6 +630,10 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
529
630
|
if (txs.length === 0) {
|
|
530
631
|
return;
|
|
531
632
|
}
|
|
633
|
+
if (this.#archivedTxLimit === 0) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
|
|
532
637
|
try {
|
|
533
638
|
const txHashes = await Promise.all(txs.map(tx => tx.getTxHash()));
|
|
534
639
|
await this.#archive.transactionAsync(async () => {
|
|
@@ -568,183 +673,74 @@ export class AztecKVTxPool extends (EventEmitter as new () => TypedEventEmitter<
|
|
|
568
673
|
}
|
|
569
674
|
}
|
|
570
675
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
* @returns The total number of txs evicted from the pool and the number of new txs that were evicted.
|
|
577
|
-
*/
|
|
578
|
-
private async evictLowPriorityTxs(
|
|
579
|
-
newTxHashes: TxHash[],
|
|
580
|
-
): Promise<{ numLowPriorityTxsEvicted: number; numNewTxsEvicted: number }> {
|
|
581
|
-
if (this.#maxTxPoolSize === undefined || this.#maxTxPoolSize === 0) {
|
|
582
|
-
return { numLowPriorityTxsEvicted: 0, numNewTxsEvicted: 0 };
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
let numNewTxsEvicted = 0;
|
|
586
|
-
const txsToEvict: TxHash[] = [];
|
|
587
|
-
|
|
588
|
-
let pendingTxsSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
589
|
-
if (pendingTxsSize > this.#maxTxPoolSize * this.txPoolOverflowFactor) {
|
|
590
|
-
for await (const txHash of this.#pendingTxPriorityToHash.valuesAsync()) {
|
|
591
|
-
if (this.#nonEvictableTxs.has(txHash.toString())) {
|
|
592
|
-
continue;
|
|
593
|
-
}
|
|
594
|
-
const txSize =
|
|
595
|
-
(await this.#pendingTxHashToSize.getAsync(txHash.toString())) ??
|
|
596
|
-
(await this.getPendingTxByHash(txHash))?.getSize();
|
|
597
|
-
|
|
598
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to low priority to satisfy max tx size limit`, {
|
|
599
|
-
txHash,
|
|
600
|
-
txSize,
|
|
601
|
-
});
|
|
602
|
-
|
|
603
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
676
|
+
// Assumes being called within a DB transaction
|
|
677
|
+
private async addPendingTxIndicesInDbTx(tx: Tx, txHash: string): Promise<void> {
|
|
678
|
+
await this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), txHash);
|
|
679
|
+
await this.#historicalHeaderToTxHash.set((await tx.data.constants.anchorBlockHeader.hash()).toString(), txHash);
|
|
680
|
+
await this.#feePayerToBalanceEntry.set(tx.data.feePayer.toString(), await FeePayerTxInfo.encode(tx, txHash));
|
|
604
681
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
numNewTxsEvicted += newTxHashes.filter(txHash => txsToEvict.includes(txHash)).length;
|
|
682
|
+
// Add nullifier entries for conflict detection
|
|
683
|
+
const nullifiers = tx.data.getNonEmptyNullifiers();
|
|
684
|
+
for (const nullifier of nullifiers) {
|
|
685
|
+
await this.#pendingNullifierToTxHash.set(nullifier.toString(), txHash);
|
|
613
686
|
}
|
|
687
|
+
}
|
|
614
688
|
|
|
615
|
-
|
|
616
|
-
|
|
689
|
+
// Assumes being called within a DB transaction
|
|
690
|
+
private async removePendingTxIndicesInDbTx(tx: Tx, txHash: string): Promise<void> {
|
|
691
|
+
await this.#pendingTxPriorityToHash.deleteValue(getPendingTxPriority(tx), txHash);
|
|
692
|
+
await this.#historicalHeaderToTxHash.deleteValue(
|
|
693
|
+
(await tx.data.constants.anchorBlockHeader.hash()).toString(),
|
|
694
|
+
txHash,
|
|
695
|
+
);
|
|
696
|
+
await this.#feePayerToBalanceEntry.deleteValue(
|
|
697
|
+
tx.data.feePayer.toString(),
|
|
698
|
+
await FeePayerTxInfo.encode(tx, txHash),
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
// Remove nullifier entries
|
|
702
|
+
const nullifiers = tx.data.getNonEmptyNullifiers();
|
|
703
|
+
for (const nullifier of nullifiers) {
|
|
704
|
+
await this.#pendingNullifierToTxHash.delete(nullifier.toString());
|
|
617
705
|
}
|
|
618
|
-
return {
|
|
619
|
-
numLowPriorityTxsEvicted: txsToEvict.length,
|
|
620
|
-
numNewTxsEvicted,
|
|
621
|
-
};
|
|
622
706
|
}
|
|
623
707
|
|
|
624
708
|
/**
|
|
625
|
-
*
|
|
626
|
-
*
|
|
627
|
-
* - txs with nullifiers that are already included in the mined block
|
|
628
|
-
* - txs with an insufficient fee payer balance
|
|
629
|
-
* - txs with an expiration timestamp lower than that of the mined block
|
|
630
|
-
*
|
|
631
|
-
* @param minedTxHashes - The tx hashes of the txs mined in the block.
|
|
632
|
-
* @param blockHeader - The header of the mined block.
|
|
633
|
-
* @returns The total number of txs evicted from the pool.
|
|
709
|
+
* Returns up to `limit` lowest-priority evictable pending tx hashes without hydrating transactions.
|
|
710
|
+
* Iterates the priority index in ascending order and skips non-evictable txs.
|
|
634
711
|
*/
|
|
635
|
-
|
|
636
|
-
minedTxHashes: TxHash[],
|
|
637
|
-
blockHeader: BlockHeader,
|
|
638
|
-
minedNullifiers: Set<string>,
|
|
639
|
-
minedFeePayers: Set<string>,
|
|
640
|
-
): Promise<number> {
|
|
641
|
-
if (minedTxHashes.length === 0) {
|
|
642
|
-
return 0;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
const { blockNumber, timestamp } = blockHeader.globalVariables;
|
|
646
|
-
|
|
647
|
-
// Wait for world state to be synced to at least the mined block number
|
|
648
|
-
await this.#worldStateSynchronizer.syncImmediate(blockNumber);
|
|
649
|
-
|
|
650
|
-
const db = this.#worldStateSynchronizer.getCommitted();
|
|
651
|
-
const gasTxValidator = this.createGasTxValidator(db);
|
|
652
|
-
|
|
712
|
+
public async getLowestPriorityEvictable(limit: number): Promise<TxHash[]> {
|
|
653
713
|
const txsToEvict: TxHash[] = [];
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
continue;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
// Evict pending txs that share nullifiers with mined txs
|
|
661
|
-
const txNullifiers = tx.data.getNonEmptyNullifiers();
|
|
662
|
-
if (txNullifiers.some(nullifier => minedNullifiers.has(nullifier.toString()))) {
|
|
663
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to a duplicate nullifier with a mined tx`);
|
|
664
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
714
|
+
if (limit <= 0) {
|
|
715
|
+
return txsToEvict;
|
|
716
|
+
}
|
|
667
717
|
|
|
668
|
-
|
|
669
|
-
if (
|
|
670
|
-
minedFeePayers.has(tx.data.feePayer.toString()) &&
|
|
671
|
-
(await gasTxValidator.validateTxFee(tx)).result === 'invalid'
|
|
672
|
-
) {
|
|
673
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to an insufficient fee payer balance`);
|
|
674
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
718
|
+
for await (const txHashStr of this.#pendingTxPriorityToHash.valuesAsync()) {
|
|
719
|
+
if (this.#nonEvictableTxs.has(txHashStr)) {
|
|
675
720
|
continue;
|
|
676
721
|
}
|
|
677
722
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
this.#log.verbose(
|
|
682
|
-
`Evicting tx ${txHash} from pool due to the tx being expired (includeByTimestamp: ${includeByTimestamp}, mined block timestamp: ${timestamp})`,
|
|
683
|
-
);
|
|
684
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
685
|
-
continue;
|
|
723
|
+
txsToEvict.push(TxHash.fromString(txHashStr));
|
|
724
|
+
if (txsToEvict.length >= limit) {
|
|
725
|
+
break;
|
|
686
726
|
}
|
|
687
727
|
}
|
|
688
728
|
|
|
689
|
-
|
|
690
|
-
await this.deleteTxs(txsToEvict, { eviction: true });
|
|
691
|
-
}
|
|
692
|
-
return txsToEvict.length;
|
|
729
|
+
return txsToEvict;
|
|
693
730
|
}
|
|
694
731
|
|
|
695
732
|
/**
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
* @param txHashes - The tx hashes of the txs that were moved from mined to pending.
|
|
699
|
-
* @returns The total number of txs evicted from the pool.
|
|
733
|
+
* Creates a PreAddPoolAccess object for use by pre-add eviction rules.
|
|
734
|
+
* Provides read-only access to pool state during addTxs transaction.
|
|
700
735
|
*/
|
|
701
|
-
private
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
const txsToEvict: TxHash[] = [];
|
|
712
|
-
|
|
713
|
-
for await (const [txHash, headerHash] of this.#pendingTxHashToHeaderHash.entriesAsync()) {
|
|
714
|
-
const tx = await this.getPendingTxByHash(txHash);
|
|
715
|
-
if (!tx) {
|
|
716
|
-
continue;
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
const [index] = await archiveCache.getArchiveIndices([Fr.fromString(headerHash)]);
|
|
720
|
-
if (index === undefined) {
|
|
721
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to an invalid archive root`);
|
|
722
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
723
|
-
continue;
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
if ((await gasTxValidator.validateTxFee(tx)).result === 'invalid') {
|
|
727
|
-
this.#log.verbose(`Evicting tx ${txHash} from pool due to an insufficient fee payer balance`);
|
|
728
|
-
txsToEvict.push(TxHash.fromString(txHash));
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
if (txsToEvict.length > 0) {
|
|
733
|
-
await this.deleteTxs(txsToEvict, { eviction: true });
|
|
734
|
-
}
|
|
735
|
-
return txsToEvict.length;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
private async addPendingTxIndices(tx: Tx, txHash: string): Promise<void> {
|
|
739
|
-
await this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), txHash);
|
|
740
|
-
await this.#pendingTxHashToSize.set(txHash, tx.getSize());
|
|
741
|
-
await this.#pendingTxHashToHeaderHash.set(txHash, (await tx.data.constants.anchorBlockHeader.hash()).toString());
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
private async removePendingTxIndices(tx: Tx, txHash: string): Promise<void> {
|
|
745
|
-
await this.#pendingTxPriorityToHash.deleteValue(getPendingTxPriority(tx), txHash);
|
|
746
|
-
await this.#pendingTxHashToSize.delete(txHash);
|
|
747
|
-
await this.#pendingTxHashToHeaderHash.delete(txHash);
|
|
748
|
-
this.#pendingTxs.delete(txHash);
|
|
736
|
+
private getPreAddPoolAccess(): PreAddPoolAccess {
|
|
737
|
+
return {
|
|
738
|
+
getTxHashByNullifier: async nullifier => {
|
|
739
|
+
const hashStr = await this.#pendingNullifierToTxHash.getAsync(nullifier.toString());
|
|
740
|
+
return hashStr ? TxHash.fromString(hashStr) : undefined;
|
|
741
|
+
},
|
|
742
|
+
getPendingTxByHash: this.getTxByHash.bind(this),
|
|
743
|
+
getTxPriority: getPendingTxPriority,
|
|
744
|
+
};
|
|
749
745
|
}
|
|
750
746
|
}
|