@aztec/p2p 0.0.1-commit.c7c42ec → 0.0.1-commit.f295ac2
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/interface.d.ts +18 -5
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +10 -13
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +449 -118
- package/dest/config.js +2 -2
- 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 +237 -263
- 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 +113 -108
- 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 +9 -6
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +16 -12
- package/dest/mem_pools/instrumentation.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +4 -13
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +13 -8
- 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 +91 -50
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +17 -4
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +59 -3
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +77 -4
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +47 -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 +115 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- 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/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 +12 -10
- 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 +7 -10
- 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/{block_proposal_validator/block_proposal_validator.js → proposal_validator/proposal_validator.js} +19 -21
- 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 +183 -0
- 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/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/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/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 +4 -2
- 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 +27 -10
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +696 -137
- package/dest/services/peer-manager/metrics.d.ts +1 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +6 -26
- 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 +0 -10
- 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 +3 -3
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +2 -2
- 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/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/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/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/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_provider_instrumentation.d.ts +1 -1
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -1
- package/dest/services/tx_provider_instrumentation.js +6 -19
- package/dest/testbench/p2p_client_testbench_worker.js +27 -12
- 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/interface.ts +19 -4
- package/src/client/p2p_client.ts +78 -128
- package/src/config.ts +2 -2
- package/src/mem_pools/attestation_pool/attestation_pool.ts +68 -41
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +239 -287
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +162 -140
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +141 -164
- package/src/mem_pools/attestation_pool/mocks.ts +19 -13
- package/src/mem_pools/instrumentation.ts +9 -18
- package/src/mem_pools/tx_pool/README.md +28 -13
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +128 -73
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +64 -4
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +117 -3
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +159 -0
- package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +75 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +16 -13
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +9 -12
- 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/{block_proposal_validator/block_proposal_validator.ts → proposal_validator/proposal_validator.ts} +23 -28
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +206 -0
- package/src/msg_validators/tx_validator/data_validator.ts +12 -4
- 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/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/timestamp_validator.ts +3 -1
- package/src/services/dummy_service.ts +6 -0
- package/src/services/encoding.ts +3 -1
- package/src/services/libp2p/instrumentation.ts +19 -73
- package/src/services/libp2p/libp2p_service.ts +326 -102
- package/src/services/peer-manager/metrics.ts +5 -26
- package/src/services/peer-manager/peer_manager.ts +1 -2
- 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 +2 -2
- package/src/services/reqresp/metrics.ts +7 -23
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +9 -0
- package/src/services/reqresp/protocols/status.ts +7 -4
- package/src/services/service.ts +19 -4
- package/src/services/tx_collection/instrumentation.ts +4 -21
- package/src/services/tx_provider_instrumentation.ts +11 -24
- package/src/testbench/p2p_client_testbench_worker.ts +35 -12
- package/src/testbench/worker_client_manager.ts +6 -1
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts +0 -15
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.js +0 -88
- 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/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/eviction/insufficient_fee_payer_balance_rule.ts +0 -108
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -5,7 +5,7 @@ import { toArray } from '@aztec/foundation/iterable';
|
|
|
5
5
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import type { TypedEventEmitter } from '@aztec/foundation/types';
|
|
7
7
|
import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
|
|
8
|
-
import
|
|
8
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
9
|
import type { MerkleTreeReadOperations, ReadonlyWorldStateAccess } from '@aztec/stdlib/interfaces/server';
|
|
10
10
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
11
11
|
import type { TxAddedToPoolStats } from '@aztec/stdlib/stats';
|
|
@@ -18,11 +18,18 @@ import EventEmitter from 'node:events';
|
|
|
18
18
|
import { ArchiveCache } from '../../msg_validators/tx_validator/archive_cache.js';
|
|
19
19
|
import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instrumentation.js';
|
|
20
20
|
import { EvictionManager } from './eviction/eviction_manager.js';
|
|
21
|
-
import
|
|
22
|
-
|
|
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';
|
|
23
29
|
import { InvalidTxsAfterMiningRule } from './eviction/invalid_txs_after_mining_rule.js';
|
|
24
30
|
import { InvalidTxsAfterReorgRule } from './eviction/invalid_txs_after_reorg_rule.js';
|
|
25
31
|
import { LowPriorityEvictionRule } from './eviction/low_priority_eviction_rule.js';
|
|
32
|
+
import { NullifierConflictPreAddRule } from './eviction/nullifier_conflict_pre_add_rule.js';
|
|
26
33
|
import { getPendingTxPriority } from './priority.js';
|
|
27
34
|
import type { TxPool, TxPoolEvents, TxPoolOptions } from './tx_pool.js';
|
|
28
35
|
|
|
@@ -55,7 +62,10 @@ export class AztecKVTxPool
|
|
|
55
62
|
|
|
56
63
|
#historicalHeaderToTxHash: AztecAsyncMultiMap<string, string>;
|
|
57
64
|
|
|
58
|
-
#
|
|
65
|
+
#feePayerToBalanceEntry: AztecAsyncMultiMap<string, Buffer>;
|
|
66
|
+
|
|
67
|
+
/** Index from nullifier to pending tx hash */
|
|
68
|
+
#pendingNullifierToTxHash: AztecAsyncMap<string, string>;
|
|
59
69
|
|
|
60
70
|
/** In-memory set of txs that should not be evicted from the pool. */
|
|
61
71
|
#nonEvictableTxs: Set<string>;
|
|
@@ -101,13 +111,14 @@ export class AztecKVTxPool
|
|
|
101
111
|
this.#evictionManager = new EvictionManager(this);
|
|
102
112
|
this.#evictionManager.registerRule(new InvalidTxsAfterMiningRule());
|
|
103
113
|
this.#evictionManager.registerRule(new InvalidTxsAfterReorgRule(worldState));
|
|
104
|
-
this.#evictionManager.registerRule(new
|
|
114
|
+
this.#evictionManager.registerRule(new FeePayerBalanceEvictionRule(worldState));
|
|
105
115
|
this.#evictionManager.registerRule(
|
|
106
116
|
new LowPriorityEvictionRule({
|
|
107
117
|
//NOTE: 0 effectively disables low priority eviction
|
|
108
118
|
maxPoolSize: config.maxPendingTxCount ?? 0,
|
|
109
119
|
}),
|
|
110
120
|
);
|
|
121
|
+
this.#evictionManager.registerPreAddRule(new NullifierConflictPreAddRule());
|
|
111
122
|
|
|
112
123
|
this.updateConfig(config);
|
|
113
124
|
|
|
@@ -119,7 +130,8 @@ export class AztecKVTxPool
|
|
|
119
130
|
|
|
120
131
|
this.#pendingTxHashToHistoricalBlockHeaderHash = store.openMap('txHistoricalBlock');
|
|
121
132
|
this.#historicalHeaderToTxHash = store.openMultiMap('historicalHeaderToPendingTxHash');
|
|
122
|
-
this.#
|
|
133
|
+
this.#feePayerToBalanceEntry = store.openMultiMap('feePayerToBalanceEntry');
|
|
134
|
+
this.#pendingNullifierToTxHash = store.openMap('pendingNullifierToTxHash');
|
|
123
135
|
|
|
124
136
|
this.#nonEvictableTxs = new Set<string>();
|
|
125
137
|
|
|
@@ -171,7 +183,7 @@ export class AztecKVTxPool
|
|
|
171
183
|
const key = hash.toString();
|
|
172
184
|
await this.#minedTxHashToBlock.set(key, blockHeader.globalVariables.blockNumber);
|
|
173
185
|
|
|
174
|
-
const tx = await this.
|
|
186
|
+
const tx = await this.getTxByHash(hash);
|
|
175
187
|
if (tx) {
|
|
176
188
|
const nullifiers = tx.data.getNonEmptyNullifiers();
|
|
177
189
|
|
|
@@ -216,8 +228,16 @@ export class AztecKVTxPool
|
|
|
216
228
|
const key = hash.toString();
|
|
217
229
|
await this.#minedTxHashToBlock.delete(key);
|
|
218
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
|
+
}
|
|
238
|
+
|
|
219
239
|
// Rehydrate the tx in the in-memory pending txs mapping
|
|
220
|
-
const tx = await this.
|
|
240
|
+
const tx = await this.getTxByHash(hash);
|
|
221
241
|
if (tx) {
|
|
222
242
|
await this.addPendingTxIndicesInDbTx(tx, key);
|
|
223
243
|
}
|
|
@@ -271,6 +291,8 @@ export class AztecKVTxPool
|
|
|
271
291
|
|
|
272
292
|
/**
|
|
273
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.
|
|
274
296
|
* @param txs - An array of txs to be added to the pool.
|
|
275
297
|
* @returns count of added transactions
|
|
276
298
|
*/
|
|
@@ -280,43 +302,69 @@ export class AztecKVTxPool
|
|
|
280
302
|
}
|
|
281
303
|
|
|
282
304
|
const addedTxs: Tx[] = [];
|
|
305
|
+
const uniqueFeePayers: AztecAddress[] = [];
|
|
306
|
+
const replacedTxHashes: TxHash[] = [];
|
|
283
307
|
const hashesAndStats = txs.map(tx => ({ txHash: tx.getTxHash(), txStats: tx.getStats() }));
|
|
284
308
|
try {
|
|
285
309
|
await this.#store.transactionAsync(async () => {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
310
|
+
for (let i = 0; i < txs.length; i++) {
|
|
311
|
+
const tx = txs[i];
|
|
312
|
+
const { txHash, txStats } = hashesAndStats[i];
|
|
313
|
+
const key = txHash.toString();
|
|
314
|
+
if (await this.#txs.hasAsync(key)) {
|
|
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;
|
|
323
|
+
}
|
|
324
|
+
|
|
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}`);
|
|
293
332
|
}
|
|
333
|
+
}
|
|
294
334
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
335
|
+
this.#log.verbose(`Adding tx ${key} to pool`, {
|
|
336
|
+
eventName: 'tx-added-to-pool',
|
|
337
|
+
...txStats,
|
|
338
|
+
} satisfies TxAddedToPoolStats);
|
|
299
339
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
key,
|
|
304
|
-
(await tx.data.constants.anchorBlockHeader.hash()).toString(),
|
|
305
|
-
);
|
|
340
|
+
await this.#txs.set(key, tx.toBuffer());
|
|
341
|
+
addedTxs.push(tx);
|
|
342
|
+
insertIntoSortedArray(uniqueFeePayers, tx.data.feePayer, (a, b) => a.toField().cmp(b.toField()), false);
|
|
306
343
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
344
|
+
await this.#pendingTxHashToHistoricalBlockHeaderHash.set(
|
|
345
|
+
key,
|
|
346
|
+
(await tx.data.constants.anchorBlockHeader.hash()).toString(),
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
if (!(await this.#minedTxHashToBlock.hasAsync(key))) {
|
|
350
|
+
await this.addPendingTxIndicesInDbTx(tx, key);
|
|
351
|
+
this.#metrics.recordSize(tx);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
313
354
|
});
|
|
314
355
|
|
|
315
|
-
await this.#evictionManager.evictAfterNewTxs(
|
|
356
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
357
|
+
addedTxs.map(({ txHash }) => txHash),
|
|
358
|
+
uniqueFeePayers,
|
|
359
|
+
);
|
|
316
360
|
} catch (err) {
|
|
317
361
|
this.#log.warn('Unexpected error when adding txs', { err });
|
|
318
362
|
}
|
|
319
363
|
|
|
364
|
+
if (replacedTxHashes.length > 0) {
|
|
365
|
+
this.#metrics.transactionsRemoved(replacedTxHashes.map(hash => hash.toBigInt()));
|
|
366
|
+
}
|
|
367
|
+
|
|
320
368
|
if (addedTxs.length > 0) {
|
|
321
369
|
this.#metrics.transactionsAdded(addedTxs);
|
|
322
370
|
this.emit('txs-added', { ...opts, txs: addedTxs });
|
|
@@ -348,7 +396,7 @@ export class AztecKVTxPool
|
|
|
348
396
|
const minedBlockNumber = await this.#minedTxHashToBlock.getAsync(key);
|
|
349
397
|
const txIsPending = minedBlockNumber === undefined;
|
|
350
398
|
if (txIsPending) {
|
|
351
|
-
await this.
|
|
399
|
+
await this.deletePendingTxInDbTx(tx, key);
|
|
352
400
|
} else {
|
|
353
401
|
await this.deleteMinedTx(key, minedBlockNumber!, opts?.permanently ?? false);
|
|
354
402
|
const shouldArchiveTx = this.#archivedTxLimit && !opts?.permanently;
|
|
@@ -378,10 +426,11 @@ export class AztecKVTxPool
|
|
|
378
426
|
await this.#blockToDeletedMinedTxHash.set(minedBlockNumber, txHash);
|
|
379
427
|
}
|
|
380
428
|
|
|
381
|
-
|
|
429
|
+
// Assumes being called within a DB transaction
|
|
430
|
+
private async deletePendingTxInDbTx(tx: Tx, txHash: `0x${string}`) {
|
|
382
431
|
// We always permanently delete pending transactions
|
|
383
432
|
this.#log.trace(`Deleting pending tx ${txHash} from pool`);
|
|
384
|
-
await this.
|
|
433
|
+
await this.removePendingTxIndicesInDbTx(tx, txHash);
|
|
385
434
|
await this.#txs.delete(txHash);
|
|
386
435
|
await this.#pendingTxHashToHistoricalBlockHeaderHash.delete(txHash);
|
|
387
436
|
}
|
|
@@ -414,7 +463,7 @@ export class AztecKVTxPool
|
|
|
414
463
|
let historicalBlockHash = await this.#pendingTxHashToHistoricalBlockHeaderHash.getAsync(txHash.toString());
|
|
415
464
|
// Not all tx might have this index created.
|
|
416
465
|
if (!historicalBlockHash) {
|
|
417
|
-
const tx = await this.
|
|
466
|
+
const tx = await this.getTxByHash(txHash);
|
|
418
467
|
if (!tx) {
|
|
419
468
|
this.#log.warn(`PendingTxInfo:tx ${txHash} not found`);
|
|
420
469
|
return undefined;
|
|
@@ -447,15 +496,21 @@ export class AztecKVTxPool
|
|
|
447
496
|
return result;
|
|
448
497
|
}
|
|
449
498
|
|
|
450
|
-
public async
|
|
451
|
-
const
|
|
452
|
-
for (const feePayer of
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
result.push(...infos.filter((info): info is PendingTxInfo => info !== undefined));
|
|
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);
|
|
456
504
|
}
|
|
505
|
+
return feePayers;
|
|
506
|
+
}
|
|
457
507
|
|
|
458
|
-
|
|
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;
|
|
513
|
+
}
|
|
459
514
|
}
|
|
460
515
|
|
|
461
516
|
public async getMinedTxHashes(): Promise<[TxHash, BlockNumber][]> {
|
|
@@ -565,24 +620,6 @@ export class AztecKVTxPool
|
|
|
565
620
|
return new ArchiveCache(db);
|
|
566
621
|
}
|
|
567
622
|
|
|
568
|
-
/**
|
|
569
|
-
* Checks if a cached transaction exists in the in-memory pending tx pool and returns it.
|
|
570
|
-
* Otherwise, it checks the tx pool, updates the pending tx pool, and returns the tx.
|
|
571
|
-
* @param txHash - The generated tx hash.
|
|
572
|
-
* @returns The transaction, if found, 'undefined' otherwise.
|
|
573
|
-
*/
|
|
574
|
-
private async getPendingTxByHash(txHash: TxHash | string): Promise<Tx | undefined> {
|
|
575
|
-
if (typeof txHash === 'string') {
|
|
576
|
-
txHash = TxHash.fromString(txHash);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
const tx = await this.getTxByHash(txHash);
|
|
580
|
-
if (tx) {
|
|
581
|
-
return tx;
|
|
582
|
-
}
|
|
583
|
-
return undefined;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
623
|
/**
|
|
587
624
|
* Archives a list of txs for future reference. The number of archived txs is limited by the specified archivedTxLimit.
|
|
588
625
|
* Note: Pending txs should not be archived, only finalized txs
|
|
@@ -640,13 +677,13 @@ export class AztecKVTxPool
|
|
|
640
677
|
private async addPendingTxIndicesInDbTx(tx: Tx, txHash: string): Promise<void> {
|
|
641
678
|
await this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), txHash);
|
|
642
679
|
await this.#historicalHeaderToTxHash.set((await tx.data.constants.anchorBlockHeader.hash()).toString(), txHash);
|
|
643
|
-
await this.#
|
|
644
|
-
}
|
|
680
|
+
await this.#feePayerToBalanceEntry.set(tx.data.feePayer.toString(), await FeePayerTxInfo.encode(tx, txHash));
|
|
645
681
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
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);
|
|
686
|
+
}
|
|
650
687
|
}
|
|
651
688
|
|
|
652
689
|
// Assumes being called within a DB transaction
|
|
@@ -656,13 +693,16 @@ export class AztecKVTxPool
|
|
|
656
693
|
(await tx.data.constants.anchorBlockHeader.hash()).toString(),
|
|
657
694
|
txHash,
|
|
658
695
|
);
|
|
659
|
-
await this.#
|
|
660
|
-
|
|
696
|
+
await this.#feePayerToBalanceEntry.deleteValue(
|
|
697
|
+
tx.data.feePayer.toString(),
|
|
698
|
+
await FeePayerTxInfo.encode(tx, txHash),
|
|
699
|
+
);
|
|
661
700
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
701
|
+
// Remove nullifier entries
|
|
702
|
+
const nullifiers = tx.data.getNonEmptyNullifiers();
|
|
703
|
+
for (const nullifier of nullifiers) {
|
|
704
|
+
await this.#pendingNullifierToTxHash.delete(nullifier.toString());
|
|
705
|
+
}
|
|
666
706
|
}
|
|
667
707
|
|
|
668
708
|
/**
|
|
@@ -688,4 +728,19 @@ export class AztecKVTxPool
|
|
|
688
728
|
|
|
689
729
|
return txsToEvict;
|
|
690
730
|
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Creates a PreAddPoolAccess object for use by pre-add eviction rules.
|
|
734
|
+
* Provides read-only access to pool state during addTxs transaction.
|
|
735
|
+
*/
|
|
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
|
+
};
|
|
745
|
+
}
|
|
691
746
|
}
|
|
@@ -1,23 +1,36 @@
|
|
|
1
|
+
import { findIndexInSortedArray, insertIntoSortedArray } from '@aztec/foundation/array';
|
|
1
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
-
import { BlockHeader, TxHash } from '@aztec/stdlib/tx';
|
|
5
|
+
import { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
|
|
5
6
|
|
|
6
7
|
import type { TxPoolOptions } from '../tx_pool.js';
|
|
7
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type EvictionContext,
|
|
10
|
+
EvictionEvent,
|
|
11
|
+
type EvictionRule,
|
|
12
|
+
type PreAddEvictionResult,
|
|
13
|
+
type PreAddEvictionRule,
|
|
14
|
+
type PreAddPoolAccess,
|
|
15
|
+
type TxPoolOperations,
|
|
16
|
+
} from './eviction_strategy.js';
|
|
8
17
|
|
|
9
18
|
export class EvictionManager {
|
|
10
19
|
private rules: EvictionRule[] = [];
|
|
11
20
|
|
|
21
|
+
/** Pre-add eviction rules (run inside addTxs transaction) */
|
|
22
|
+
private preAddRules: PreAddEvictionRule[] = [];
|
|
23
|
+
|
|
12
24
|
constructor(
|
|
13
25
|
private txPool: TxPoolOperations,
|
|
14
26
|
private log = createLogger('p2p:mempool:tx_pool:eviction_manager'),
|
|
15
27
|
) {}
|
|
16
28
|
|
|
17
|
-
public async evictAfterNewTxs(newTxs: TxHash[]): Promise<void> {
|
|
29
|
+
public async evictAfterNewTxs(newTxs: TxHash[], feePayers: AztecAddress[]): Promise<void> {
|
|
18
30
|
const ctx: EvictionContext = {
|
|
19
31
|
event: EvictionEvent.TXS_ADDED,
|
|
20
32
|
newTxs,
|
|
33
|
+
feePayers,
|
|
21
34
|
};
|
|
22
35
|
await this.runEvictionRules(ctx);
|
|
23
36
|
}
|
|
@@ -31,7 +44,7 @@ export class EvictionManager {
|
|
|
31
44
|
event: EvictionEvent.BLOCK_MINED,
|
|
32
45
|
block,
|
|
33
46
|
newNullifiers,
|
|
34
|
-
minedFeePayers,
|
|
47
|
+
feePayers: minedFeePayers,
|
|
35
48
|
};
|
|
36
49
|
|
|
37
50
|
await this.runEvictionRules(ctx);
|
|
@@ -45,14 +58,61 @@ export class EvictionManager {
|
|
|
45
58
|
await this.runEvictionRules(ctx);
|
|
46
59
|
}
|
|
47
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Runs pre-add eviction rules to determine if an incoming tx should be added
|
|
63
|
+
* and which existing txs should be evicted.
|
|
64
|
+
* Called from inside the addTxs database transaction for atomicity.
|
|
65
|
+
*
|
|
66
|
+
* @param tx - The incoming transaction
|
|
67
|
+
* @param poolAccess - Read-only access to pool state
|
|
68
|
+
* @returns Combined result from all pre-add rules
|
|
69
|
+
*/
|
|
70
|
+
public async runPreAddRules(tx: Tx, poolAccess: PreAddPoolAccess): Promise<PreAddEvictionResult> {
|
|
71
|
+
const allTxHashesToEvict: TxHash[] = [];
|
|
72
|
+
const cmpTxHash = (a: TxHash, b: TxHash) => Fr.cmp(a.hash, b.hash);
|
|
73
|
+
|
|
74
|
+
for (const rule of this.preAddRules) {
|
|
75
|
+
try {
|
|
76
|
+
const result = await rule.check(tx, poolAccess);
|
|
77
|
+
|
|
78
|
+
if (result.shouldReject) {
|
|
79
|
+
return { shouldReject: true, txHashesToEvict: [], reason: result.reason };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
for (const txHashToEvict of result.txHashesToEvict) {
|
|
83
|
+
// Only add if not already present (dedup)
|
|
84
|
+
if (findIndexInSortedArray(allTxHashesToEvict, txHashToEvict, cmpTxHash) === -1) {
|
|
85
|
+
insertIntoSortedArray(allTxHashesToEvict, txHashToEvict, cmpTxHash);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} catch (err) {
|
|
89
|
+
this.log.warn(`Pre-add eviction rule ${rule.name} unexpected error: ${String(err)}`, {
|
|
90
|
+
err,
|
|
91
|
+
preAddRule: rule.name,
|
|
92
|
+
});
|
|
93
|
+
// On error, reject the tx to be safe
|
|
94
|
+
return { shouldReject: true, txHashesToEvict: [], reason: `rule error: ${String(err)}` };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { shouldReject: false, txHashesToEvict: allTxHashesToEvict };
|
|
99
|
+
}
|
|
100
|
+
|
|
48
101
|
public registerRule(rule: EvictionRule) {
|
|
49
102
|
this.rules.push(rule);
|
|
50
103
|
}
|
|
51
104
|
|
|
105
|
+
public registerPreAddRule(rule: PreAddEvictionRule) {
|
|
106
|
+
this.preAddRules.push(rule);
|
|
107
|
+
}
|
|
108
|
+
|
|
52
109
|
public updateConfig(config: TxPoolOptions): void {
|
|
53
110
|
for (const rule of this.rules) {
|
|
54
111
|
rule.updateConfig(config);
|
|
55
112
|
}
|
|
113
|
+
for (const rule of this.preAddRules) {
|
|
114
|
+
rule.updateConfig?.(config);
|
|
115
|
+
}
|
|
56
116
|
}
|
|
57
117
|
|
|
58
118
|
private async runEvictionRules(ctx: EvictionContext): Promise<void> {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
1
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
+
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
2
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
|
-
import type
|
|
5
|
+
import { type BlockHeader, type Tx, TxHash } from '@aztec/stdlib/tx';
|
|
4
6
|
|
|
7
|
+
import { getFeePayerBalanceDelta } from '../../../msg_validators/tx_validator/fee_payer_balance.js';
|
|
8
|
+
import { getTxPriorityFee } from '../priority.js';
|
|
5
9
|
import type { TxPoolOptions } from '../tx_pool.js';
|
|
6
10
|
|
|
7
11
|
export const EvictionEvent = {
|
|
@@ -16,6 +20,7 @@ export type EvictionContext =
|
|
|
16
20
|
| {
|
|
17
21
|
event: typeof EvictionEvent.TXS_ADDED;
|
|
18
22
|
newTxs: TxHash[];
|
|
23
|
+
feePayers: AztecAddress[];
|
|
19
24
|
}
|
|
20
25
|
| {
|
|
21
26
|
event: typeof EvictionEvent.CHAIN_PRUNED;
|
|
@@ -25,7 +30,7 @@ export type EvictionContext =
|
|
|
25
30
|
event: typeof EvictionEvent.BLOCK_MINED;
|
|
26
31
|
block: BlockHeader;
|
|
27
32
|
newNullifiers: Fr[];
|
|
28
|
-
|
|
33
|
+
feePayers: AztecAddress[];
|
|
29
34
|
};
|
|
30
35
|
|
|
31
36
|
/**
|
|
@@ -63,7 +68,8 @@ export interface TxPoolOperations {
|
|
|
63
68
|
getTxByHash(txHash: TxHash): Promise<Tx | undefined>;
|
|
64
69
|
getPendingTxInfos(): Promise<PendingTxInfo[]>;
|
|
65
70
|
getPendingTxsReferencingBlocks(blockHashes: Fr[]): Promise<TxBlockReference[]>;
|
|
66
|
-
|
|
71
|
+
getPendingFeePayers(): Promise<AztecAddress[]>;
|
|
72
|
+
getFeePayerTxInfos(feePayer: AztecAddress): AsyncIterable<FeePayerTxInfo>;
|
|
67
73
|
/** Cheap count of current pending transactions. */
|
|
68
74
|
getPendingTxCount(): Promise<number>;
|
|
69
75
|
/**
|
|
@@ -91,3 +97,111 @@ export interface EvictionRule {
|
|
|
91
97
|
*/
|
|
92
98
|
updateConfig(config: TxPoolOptions): void;
|
|
93
99
|
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Balance-related information about a transaction for a fee payer.
|
|
103
|
+
*/
|
|
104
|
+
export class FeePayerTxInfo {
|
|
105
|
+
txHash: TxHash;
|
|
106
|
+
priority: bigint;
|
|
107
|
+
feeLimit: bigint;
|
|
108
|
+
claimAmount: bigint;
|
|
109
|
+
isEvictable: boolean;
|
|
110
|
+
|
|
111
|
+
constructor(fields: {
|
|
112
|
+
txHash: TxHash;
|
|
113
|
+
priority: bigint;
|
|
114
|
+
feeLimit: bigint;
|
|
115
|
+
claimAmount: bigint;
|
|
116
|
+
isEvictable: boolean;
|
|
117
|
+
}) {
|
|
118
|
+
this.txHash = fields.txHash;
|
|
119
|
+
this.priority = fields.priority;
|
|
120
|
+
this.feeLimit = fields.feeLimit;
|
|
121
|
+
this.claimAmount = fields.claimAmount;
|
|
122
|
+
this.isEvictable = fields.isEvictable;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
static async encode(tx: Tx, txHash: string | TxHash): Promise<Buffer> {
|
|
126
|
+
const { feeLimit, claimAmount } = await getFeePayerBalanceDelta(tx, ProtocolContractAddress.FeeJuice);
|
|
127
|
+
const priority = Buffer32.fromBigInt(getTxPriorityFee(tx)).toBuffer();
|
|
128
|
+
const hashBuffer = (typeof txHash === 'string' ? TxHash.fromString(txHash) : txHash).toBuffer();
|
|
129
|
+
const feeLimitBuffer = Buffer32.fromBigInt(feeLimit).toBuffer();
|
|
130
|
+
const claimAmountBuffer = Buffer32.fromBigInt(claimAmount).toBuffer();
|
|
131
|
+
return Buffer.concat([priority, hashBuffer, feeLimitBuffer, claimAmountBuffer]);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
static decode(value: Buffer, isEvictable = true): FeePayerTxInfo {
|
|
135
|
+
const priority = Buffer32.fromBuffer(value.subarray(0, Buffer32.SIZE)).toBigInt();
|
|
136
|
+
const hashOffset = Buffer32.SIZE;
|
|
137
|
+
const feeLimitOffset = hashOffset + TxHash.SIZE;
|
|
138
|
+
const claimOffset = feeLimitOffset + Buffer32.SIZE;
|
|
139
|
+
|
|
140
|
+
return new FeePayerTxInfo({
|
|
141
|
+
txHash: TxHash.fromBuffer(value.subarray(hashOffset, feeLimitOffset)),
|
|
142
|
+
priority,
|
|
143
|
+
feeLimit: Buffer32.fromBuffer(value.subarray(feeLimitOffset, claimOffset)).toBigInt(),
|
|
144
|
+
claimAmount: Buffer32.fromBuffer(value.subarray(claimOffset, claimOffset + Buffer32.SIZE)).toBigInt(),
|
|
145
|
+
isEvictable,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Read-only access to pool state for pre-add eviction checks.
|
|
152
|
+
* Passed to pre-add rules during the addTxs transaction.
|
|
153
|
+
*/
|
|
154
|
+
export interface PreAddPoolAccess {
|
|
155
|
+
/**
|
|
156
|
+
* Get the pending tx hash that uses a specific nullifier, if any.
|
|
157
|
+
* Returns undefined if no pending tx uses this nullifier.
|
|
158
|
+
*/
|
|
159
|
+
getTxHashByNullifier(nullifier: Fr): Promise<TxHash | undefined>;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Get a pending transaction by its hash.
|
|
163
|
+
*/
|
|
164
|
+
getPendingTxByHash(hash: TxHash): Promise<Tx | undefined>;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Get the priority string for a transaction (for fee comparison).
|
|
168
|
+
*/
|
|
169
|
+
getTxPriority(tx: Tx): string;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Result of a pre-add eviction check for a single transaction.
|
|
174
|
+
*/
|
|
175
|
+
export interface PreAddEvictionResult {
|
|
176
|
+
/** Whether the incoming tx should be rejected */
|
|
177
|
+
readonly shouldReject: boolean;
|
|
178
|
+
/** Sorted array of existing tx hashes that should be evicted if this tx is added */
|
|
179
|
+
readonly txHashesToEvict: TxHash[];
|
|
180
|
+
/** Optional reason for rejection */
|
|
181
|
+
readonly reason?: string;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Strategy interface for pre-add eviction rules.
|
|
186
|
+
* These run inside the addTxs transaction before a tx is added,
|
|
187
|
+
* deciding whether to evict existing txs or reject the incoming tx.
|
|
188
|
+
*/
|
|
189
|
+
export interface PreAddEvictionRule {
|
|
190
|
+
readonly name: string;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Check if incoming tx should be added and which existing txs to evict.
|
|
194
|
+
* Called inside the addTxs database transaction for atomicity.
|
|
195
|
+
*
|
|
196
|
+
* @param tx - The incoming transaction to check
|
|
197
|
+
* @param poolAccess - Read-only access to current pool state
|
|
198
|
+
* @returns Result indicating whether to reject and what to evict
|
|
199
|
+
*/
|
|
200
|
+
check(tx: Tx, poolAccess: PreAddPoolAccess): Promise<PreAddEvictionResult>;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Updates the configuration for this rule.
|
|
204
|
+
* Rules should ignore config options that don't apply to them.
|
|
205
|
+
*/
|
|
206
|
+
updateConfig?(config: TxPoolOptions): void;
|
|
207
|
+
}
|