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