@aztec/p2p 4.0.0-devnet.1-patch.1 → 4.0.0-devnet.2-patch.0
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 +3 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +9 -5
- package/dest/client/interface.d.ts +8 -8
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +4 -6
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +46 -14
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -5
- package/dest/config.d.ts +10 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +5 -0
- package/dest/errors/tx-pool.error.d.ts +8 -0
- package/dest/errors/tx-pool.error.d.ts.map +1 -0
- package/dest/errors/tx-pool.error.js +9 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -2
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +5 -0
- package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +2 -2
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +3 -3
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +30 -13
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +91 -20
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +18 -9
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +4 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +10 -4
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +48 -5
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +8 -0
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +7 -5
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +5 -3
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +8 -4
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +4 -4
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +14 -4
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts +15 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool_v2/instrumentation.js +43 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +14 -2
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +9 -5
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +30 -5
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +12 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +27 -4
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +8 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +11 -6
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +12 -4
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +164 -37
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/timestamp_validator.js +6 -6
- package/dest/services/encoding.d.ts +1 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +2 -1
- package/dest/services/libp2p/libp2p_service.js +2 -2
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +5 -9
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
- package/dest/services/tx_collection/config.d.ts +13 -1
- package/dest/services/tx_collection/config.d.ts.map +1 -1
- package/dest/services/tx_collection/config.js +30 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +39 -33
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +38 -29
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.js +126 -77
- package/dest/services/tx_collection/file_store_tx_source.d.ts +16 -6
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.js +49 -16
- package/dest/services/tx_collection/instrumentation.d.ts +1 -1
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -1
- package/dest/services/tx_collection/instrumentation.js +2 -1
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
- package/dest/services/tx_collection/slow_tx_collection.d.ts +5 -3
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +17 -12
- package/dest/services/tx_collection/tx_collection.d.ts +9 -6
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection.js +26 -10
- package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +13 -22
- package/dest/services/tx_collection/tx_source.d.ts +8 -3
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +19 -2
- package/dest/services/tx_file_store/tx_file_store.d.ts +3 -2
- package/dest/services/tx_file_store/tx_file_store.d.ts.map +1 -1
- package/dest/services/tx_file_store/tx_file_store.js +9 -6
- package/dest/test-helpers/testbench-utils.d.ts +7 -2
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +7 -1
- package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +8 -8
- package/package.json +14 -14
- package/src/client/factory.ts +18 -3
- package/src/client/interface.ts +10 -8
- package/src/client/p2p_client.ts +52 -17
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +18 -8
- package/src/config.ts +8 -0
- package/src/errors/tx-pool.error.ts +12 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +8 -0
- package/src/mem_pools/attestation_pool/mocks.ts +2 -1
- package/src/mem_pools/tx_pool/README.md +1 -1
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/README.md +43 -27
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +109 -22
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +21 -8
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +4 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +15 -4
- package/src/mem_pools/tx_pool_v2/eviction/index.ts +4 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +49 -4
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +5 -5
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +8 -7
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +24 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +3 -3
- package/src/mem_pools/tx_pool_v2/instrumentation.ts +69 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +14 -2
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +44 -9
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +32 -5
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +17 -6
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +186 -29
- package/src/msg_validators/tx_validator/timestamp_validator.ts +7 -7
- package/src/services/encoding.ts +2 -1
- package/src/services/libp2p/libp2p_service.ts +2 -2
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +6 -6
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
- package/src/services/tx_collection/config.ts +42 -0
- package/src/services/tx_collection/fast_tx_collection.ts +51 -30
- package/src/services/tx_collection/file_store_tx_collection.ts +143 -93
- package/src/services/tx_collection/file_store_tx_source.ts +64 -17
- package/src/services/tx_collection/instrumentation.ts +7 -1
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
- package/src/services/tx_collection/slow_tx_collection.ts +17 -13
- package/src/services/tx_collection/tx_collection.ts +45 -14
- package/src/services/tx_collection/tx_collection_sink.ts +15 -29
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_file_store/tx_file_store.ts +6 -4
- package/src/test-helpers/testbench-utils.ts +10 -2
- package/src/testbench/p2p_client_testbench_worker.ts +20 -13
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import type { Logger } from '@aztec/foundation/log';
|
|
3
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
3
4
|
import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
|
|
4
5
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
5
6
|
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
@@ -8,6 +9,7 @@ import type { L2Block, L2BlockId, L2BlockSource } from '@aztec/stdlib/block';
|
|
|
8
9
|
import type { WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
9
10
|
import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
|
|
10
11
|
import { BlockHeader, Tx, TxHash, type TxValidator } from '@aztec/stdlib/tx';
|
|
12
|
+
import type { TelemetryClient } from '@aztec/telemetry-client';
|
|
11
13
|
|
|
12
14
|
import { TxArchive } from './archive/index.js';
|
|
13
15
|
import { DeletedPool } from './deleted_pool.js';
|
|
@@ -21,8 +23,12 @@ import {
|
|
|
21
23
|
LowPriorityPreAddRule,
|
|
22
24
|
NullifierConflictRule,
|
|
23
25
|
type PoolOperations,
|
|
26
|
+
type PreAddContext,
|
|
24
27
|
type PreAddPoolAccess,
|
|
28
|
+
TxPoolRejectionCode,
|
|
29
|
+
type TxPoolRejectionError,
|
|
25
30
|
} from './eviction/index.js';
|
|
31
|
+
import { TxPoolV2Instrumentation } from './instrumentation.js';
|
|
26
32
|
import {
|
|
27
33
|
type AddTxsResult,
|
|
28
34
|
DEFAULT_TX_POOL_V2_CONFIG,
|
|
@@ -64,6 +70,9 @@ export class TxPoolV2Impl {
|
|
|
64
70
|
#archive: TxArchive;
|
|
65
71
|
#deletedPool: DeletedPool;
|
|
66
72
|
#evictionManager: EvictionManager;
|
|
73
|
+
#dateProvider: DateProvider;
|
|
74
|
+
#instrumentation: TxPoolV2Instrumentation;
|
|
75
|
+
#evictedTxHashes: Set<string> = new Set();
|
|
67
76
|
#log: Logger;
|
|
68
77
|
#callbacks: TxPoolV2Callbacks;
|
|
69
78
|
|
|
@@ -72,7 +81,9 @@ export class TxPoolV2Impl {
|
|
|
72
81
|
archiveStore: AztecAsyncKVStore,
|
|
73
82
|
deps: TxPoolV2Dependencies,
|
|
74
83
|
callbacks: TxPoolV2Callbacks,
|
|
84
|
+
telemetry: TelemetryClient,
|
|
75
85
|
config: Partial<TxPoolV2Config> = {},
|
|
86
|
+
dateProvider: DateProvider,
|
|
76
87
|
log: Logger,
|
|
77
88
|
) {
|
|
78
89
|
this.#store = store;
|
|
@@ -85,6 +96,8 @@ export class TxPoolV2Impl {
|
|
|
85
96
|
this.#config = { ...DEFAULT_TX_POOL_V2_CONFIG, ...config };
|
|
86
97
|
this.#archive = new TxArchive(archiveStore, this.#config.archivedTxLimit, log);
|
|
87
98
|
this.#deletedPool = new DeletedPool(store, this.#txsDB, log);
|
|
99
|
+
this.#dateProvider = dateProvider;
|
|
100
|
+
this.#instrumentation = new TxPoolV2Instrumentation(telemetry, () => this.#indices.getTotalMetadataBytes());
|
|
88
101
|
this.#log = log;
|
|
89
102
|
this.#callbacks = callbacks;
|
|
90
103
|
|
|
@@ -164,16 +177,19 @@ export class TxPoolV2Impl {
|
|
|
164
177
|
await this.#txsDB.delete(txHashStr);
|
|
165
178
|
}
|
|
166
179
|
});
|
|
167
|
-
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup
|
|
180
|
+
this.#log.info(`Deleted ${toDelete.length} invalid/rejected transactions on startup`, { txHashes: toDelete });
|
|
168
181
|
}
|
|
169
182
|
|
|
170
|
-
async addPendingTxs(txs: Tx[], opts: { source?: string }): Promise<AddTxsResult> {
|
|
183
|
+
async addPendingTxs(txs: Tx[], opts: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult> {
|
|
171
184
|
const accepted: TxHash[] = [];
|
|
172
185
|
const ignored: TxHash[] = [];
|
|
173
186
|
const rejected: TxHash[] = [];
|
|
187
|
+
const errors = new Map<string, TxPoolRejectionError>();
|
|
174
188
|
const acceptedPending = new Set<string>();
|
|
175
189
|
|
|
176
190
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
191
|
+
const preAddContext: PreAddContext | undefined =
|
|
192
|
+
opts.feeComparisonOnly !== undefined ? { feeComparisonOnly: opts.feeComparisonOnly } : undefined;
|
|
177
193
|
|
|
178
194
|
await this.#store.transactionAsync(async () => {
|
|
179
195
|
for (const tx of txs) {
|
|
@@ -200,7 +216,15 @@ export class TxPoolV2Impl {
|
|
|
200
216
|
accepted.push(txHash);
|
|
201
217
|
} else {
|
|
202
218
|
// Regular pending tx - validate and run pre-add rules
|
|
203
|
-
const result = await this.#tryAddRegularPendingTx(
|
|
219
|
+
const result = await this.#tryAddRegularPendingTx(
|
|
220
|
+
tx,
|
|
221
|
+
opts,
|
|
222
|
+
poolAccess,
|
|
223
|
+
acceptedPending,
|
|
224
|
+
ignored,
|
|
225
|
+
errors,
|
|
226
|
+
preAddContext,
|
|
227
|
+
);
|
|
204
228
|
if (result.status === 'accepted') {
|
|
205
229
|
acceptedPending.add(txHashStr);
|
|
206
230
|
} else if (result.status === 'rejected') {
|
|
@@ -217,6 +241,14 @@ export class TxPoolV2Impl {
|
|
|
217
241
|
accepted.push(TxHash.fromString(txHashStr));
|
|
218
242
|
}
|
|
219
243
|
|
|
244
|
+
// Record metrics
|
|
245
|
+
if (ignored.length > 0) {
|
|
246
|
+
this.#instrumentation.recordIgnored(ignored.length);
|
|
247
|
+
}
|
|
248
|
+
if (rejected.length > 0) {
|
|
249
|
+
this.#instrumentation.recordRejected(rejected.length);
|
|
250
|
+
}
|
|
251
|
+
|
|
220
252
|
// Run post-add eviction rules for pending txs
|
|
221
253
|
if (acceptedPending.size > 0) {
|
|
222
254
|
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
@@ -224,7 +256,7 @@ export class TxPoolV2Impl {
|
|
|
224
256
|
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
225
257
|
}
|
|
226
258
|
|
|
227
|
-
return { accepted, ignored, rejected };
|
|
259
|
+
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
228
260
|
}
|
|
229
261
|
|
|
230
262
|
/** Validates and adds a regular pending tx. Returns status. */
|
|
@@ -234,6 +266,8 @@ export class TxPoolV2Impl {
|
|
|
234
266
|
poolAccess: PreAddPoolAccess,
|
|
235
267
|
acceptedPending: Set<string>,
|
|
236
268
|
ignored: TxHash[],
|
|
269
|
+
errors: Map<string, TxPoolRejectionError>,
|
|
270
|
+
preAddContext?: PreAddContext,
|
|
237
271
|
): Promise<{ status: 'accepted' | 'ignored' | 'rejected' }> {
|
|
238
272
|
const txHash = tx.getTxHash();
|
|
239
273
|
const txHashStr = txHash.toString();
|
|
@@ -245,21 +279,40 @@ export class TxPoolV2Impl {
|
|
|
245
279
|
}
|
|
246
280
|
|
|
247
281
|
// Run pre-add rules
|
|
248
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
282
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess, preAddContext);
|
|
249
283
|
|
|
250
284
|
if (preAddResult.shouldIgnore) {
|
|
251
|
-
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason}`);
|
|
285
|
+
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
286
|
+
if (preAddResult.reason && preAddResult.reason.code !== TxPoolRejectionCode.INTERNAL_ERROR) {
|
|
287
|
+
errors.set(txHashStr, preAddResult.reason);
|
|
288
|
+
}
|
|
252
289
|
return { status: 'ignored' };
|
|
253
290
|
}
|
|
254
291
|
|
|
255
|
-
// Evict conflicts
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
292
|
+
// Evict conflicts, grouped by rule name for metrics
|
|
293
|
+
if (preAddResult.evictions && preAddResult.evictions.length > 0) {
|
|
294
|
+
const byReason = new Map<string, string[]>();
|
|
295
|
+
for (const { txHash: evictHash, reason } of preAddResult.evictions) {
|
|
296
|
+
const group = byReason.get(reason);
|
|
297
|
+
if (group) {
|
|
298
|
+
group.push(evictHash);
|
|
299
|
+
} else {
|
|
300
|
+
byReason.set(reason, [evictHash]);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
for (const [reason, hashes] of byReason) {
|
|
304
|
+
await this.#evictTxs(hashes, reason);
|
|
305
|
+
}
|
|
306
|
+
for (const evictHashStr of preAddResult.txHashesToEvict) {
|
|
307
|
+
this.#log.debug(`Evicted tx ${evictHashStr} due to higher-fee tx ${txHashStr}`, {
|
|
308
|
+
evictedTxHash: evictHashStr,
|
|
309
|
+
replacementTxHash: txHashStr,
|
|
310
|
+
});
|
|
311
|
+
if (acceptedPending.has(evictHashStr)) {
|
|
312
|
+
// Evicted tx was from this batch - mark as ignored in result
|
|
313
|
+
acceptedPending.delete(evictHashStr);
|
|
314
|
+
ignored.push(TxHash.fromString(evictHashStr));
|
|
315
|
+
}
|
|
263
316
|
}
|
|
264
317
|
}
|
|
265
318
|
|
|
@@ -320,9 +373,11 @@ export class TxPoolV2Impl {
|
|
|
320
373
|
});
|
|
321
374
|
}
|
|
322
375
|
|
|
323
|
-
protectTxs(txHashes: TxHash[], block: BlockHeader): TxHash[] {
|
|
376
|
+
async protectTxs(txHashes: TxHash[], block: BlockHeader): Promise<TxHash[]> {
|
|
324
377
|
const slotNumber = block.globalVariables.slotNumber;
|
|
325
378
|
const missing: TxHash[] = [];
|
|
379
|
+
let softDeletedHits = 0;
|
|
380
|
+
let missingPreviouslyEvicted = 0;
|
|
326
381
|
|
|
327
382
|
for (const txHash of txHashes) {
|
|
328
383
|
const txHashStr = txHash.toString();
|
|
@@ -330,13 +385,44 @@ export class TxPoolV2Impl {
|
|
|
330
385
|
if (this.#indices.has(txHashStr)) {
|
|
331
386
|
// Update protection for existing tx
|
|
332
387
|
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
388
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
389
|
+
// Resurrect soft-deleted tx as protected
|
|
390
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
391
|
+
if (buffer) {
|
|
392
|
+
const tx = Tx.fromBuffer(buffer);
|
|
393
|
+
await this.#addTx(tx, { protected: slotNumber });
|
|
394
|
+
softDeletedHits++;
|
|
395
|
+
} else {
|
|
396
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
397
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
398
|
+
missing.push(txHash);
|
|
399
|
+
}
|
|
333
400
|
} else {
|
|
334
|
-
//
|
|
401
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
335
402
|
this.#indices.setProtection(txHashStr, slotNumber);
|
|
336
403
|
missing.push(txHash);
|
|
404
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
405
|
+
missingPreviouslyEvicted++;
|
|
406
|
+
}
|
|
337
407
|
}
|
|
338
408
|
}
|
|
339
409
|
|
|
410
|
+
// Record metrics
|
|
411
|
+
if (softDeletedHits > 0) {
|
|
412
|
+
this.#instrumentation.recordSoftDeletedHits(softDeletedHits);
|
|
413
|
+
}
|
|
414
|
+
if (missing.length > 0) {
|
|
415
|
+
this.#log.debug(`protectTxs missing tx hashes: ${missing.map(h => h.toString()).join(', ')}`);
|
|
416
|
+
this.#instrumentation.recordMissingOnProtect(missing.length);
|
|
417
|
+
}
|
|
418
|
+
if (missingPreviouslyEvicted > 0) {
|
|
419
|
+
this.#instrumentation.recordMissingPreviouslyEvicted(missingPreviouslyEvicted);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
this.#log.info(
|
|
423
|
+
`Protected ${txHashes.length} txs, missing: ${missing.length}, soft-deleted hits: ${softDeletedHits}`,
|
|
424
|
+
);
|
|
425
|
+
|
|
340
426
|
return missing;
|
|
341
427
|
}
|
|
342
428
|
|
|
@@ -393,6 +479,9 @@ export class TxPoolV2Impl {
|
|
|
393
479
|
}
|
|
394
480
|
|
|
395
481
|
async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
|
|
482
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
483
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
484
|
+
|
|
396
485
|
// Step 1: Find expired protected txs
|
|
397
486
|
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
398
487
|
|
|
@@ -402,6 +491,7 @@ export class TxPoolV2Impl {
|
|
|
402
491
|
// Step 3: Filter to only txs that have metadata and are not mined
|
|
403
492
|
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
404
493
|
if (txsToRestore.length === 0) {
|
|
494
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
405
495
|
return;
|
|
406
496
|
}
|
|
407
497
|
|
|
@@ -413,8 +503,9 @@ export class TxPoolV2Impl {
|
|
|
413
503
|
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
414
504
|
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
415
505
|
|
|
416
|
-
// Step 6: Delete invalid and
|
|
417
|
-
await this.#deleteTxsBatch(
|
|
506
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
507
|
+
await this.#deleteTxsBatch(invalid);
|
|
508
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
418
509
|
|
|
419
510
|
// Step 7: Run eviction rules (enforce pool size limit)
|
|
420
511
|
if (added.length > 0) {
|
|
@@ -427,7 +518,7 @@ export class TxPoolV2Impl {
|
|
|
427
518
|
}
|
|
428
519
|
}
|
|
429
520
|
|
|
430
|
-
async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
|
|
521
|
+
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
431
522
|
// Step 1: Find transactions mined after the prune point
|
|
432
523
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
433
524
|
if (txsToUnmine.length === 0) {
|
|
@@ -452,17 +543,33 @@ export class TxPoolV2Impl {
|
|
|
452
543
|
this.#indices.markAsUnmined(meta);
|
|
453
544
|
}
|
|
454
545
|
|
|
546
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
547
|
+
if (options?.deleteAllTxs) {
|
|
548
|
+
const allTxHashes = txsToUnmine.map(m => m.txHash);
|
|
549
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
550
|
+
this.#log.info(
|
|
551
|
+
`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
|
|
552
|
+
);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
|
|
455
556
|
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
456
557
|
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
457
558
|
|
|
458
|
-
// Step
|
|
559
|
+
// Step 5: Validate for pending pool
|
|
459
560
|
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
460
561
|
|
|
461
562
|
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
462
563
|
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
463
564
|
|
|
464
|
-
// Step 7: Delete invalid and
|
|
465
|
-
await this.#deleteTxsBatch(
|
|
565
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
566
|
+
await this.#deleteTxsBatch(invalid);
|
|
567
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
568
|
+
|
|
569
|
+
this.#log.info(
|
|
570
|
+
`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
|
|
571
|
+
{ txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
|
|
572
|
+
);
|
|
466
573
|
|
|
467
574
|
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
468
575
|
// This handles cases like existing pending txs with invalid fee payer balances
|
|
@@ -473,7 +580,7 @@ export class TxPoolV2Impl {
|
|
|
473
580
|
// Delete failed txs
|
|
474
581
|
await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
|
|
475
582
|
|
|
476
|
-
this.#log.info(`Deleted ${txHashes.length} failed txs
|
|
583
|
+
this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
|
|
477
584
|
}
|
|
478
585
|
|
|
479
586
|
async handleFinalizedBlock(block: BlockHeader): Promise<void> {
|
|
@@ -505,7 +612,9 @@ export class TxPoolV2Impl {
|
|
|
505
612
|
}
|
|
506
613
|
|
|
507
614
|
if (minedTxsToFinalize.length > 0) {
|
|
508
|
-
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}
|
|
615
|
+
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
616
|
+
txHashes: minedTxsToFinalize,
|
|
617
|
+
});
|
|
509
618
|
}
|
|
510
619
|
}
|
|
511
620
|
|
|
@@ -549,6 +658,13 @@ export class TxPoolV2Impl {
|
|
|
549
658
|
return [...this.#indices.iteratePendingByPriority('desc')].map(hash => TxHash.fromString(hash));
|
|
550
659
|
}
|
|
551
660
|
|
|
661
|
+
getEligiblePendingTxHashes(): TxHash[] {
|
|
662
|
+
const maxReceivedAt = this.#dateProvider.now() - this.#config.minTxPoolAgeMs;
|
|
663
|
+
return [...this.#indices.iterateEligiblePendingByPriority('desc', maxReceivedAt)].map(hash =>
|
|
664
|
+
TxHash.fromString(hash),
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
|
|
552
668
|
getPendingTxCount(): number {
|
|
553
669
|
return this.#indices.getPendingTxCount();
|
|
554
670
|
}
|
|
@@ -593,6 +709,9 @@ export class TxPoolV2Impl {
|
|
|
593
709
|
this.#config.archivedTxLimit = config.archivedTxLimit;
|
|
594
710
|
this.#archive.updateLimit(config.archivedTxLimit);
|
|
595
711
|
}
|
|
712
|
+
if (config.minTxPoolAgeMs !== undefined) {
|
|
713
|
+
this.#config.minTxPoolAgeMs = config.minTxPoolAgeMs;
|
|
714
|
+
}
|
|
596
715
|
// Update eviction rules with new config
|
|
597
716
|
this.#evictionManager.updateConfig(config);
|
|
598
717
|
}
|
|
@@ -610,8 +729,17 @@ export class TxPoolV2Impl {
|
|
|
610
729
|
|
|
611
730
|
// === Metrics ===
|
|
612
731
|
|
|
613
|
-
countTxs(): {
|
|
614
|
-
|
|
732
|
+
countTxs(): {
|
|
733
|
+
pending: number;
|
|
734
|
+
protected: number;
|
|
735
|
+
mined: number;
|
|
736
|
+
softDeleted: number;
|
|
737
|
+
totalMetadataBytes: number;
|
|
738
|
+
} {
|
|
739
|
+
return {
|
|
740
|
+
...this.#indices.countTxs(),
|
|
741
|
+
softDeleted: this.#deletedPool.getSoftDeletedCount(),
|
|
742
|
+
};
|
|
615
743
|
}
|
|
616
744
|
|
|
617
745
|
// ============================================================================
|
|
@@ -629,8 +757,10 @@ export class TxPoolV2Impl {
|
|
|
629
757
|
): Promise<TxMetaData> {
|
|
630
758
|
const txHashStr = tx.getTxHash().toString();
|
|
631
759
|
const meta = await buildTxMetaData(tx);
|
|
760
|
+
meta.receivedAt = this.#dateProvider.now();
|
|
632
761
|
|
|
633
762
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
763
|
+
await this.#deletedPool.clearSoftDeleted(txHashStr);
|
|
634
764
|
this.#callbacks.onTxsAdded([tx], opts);
|
|
635
765
|
|
|
636
766
|
if (state === 'pending') {
|
|
@@ -643,9 +773,11 @@ export class TxPoolV2Impl {
|
|
|
643
773
|
}
|
|
644
774
|
|
|
645
775
|
const stateStr = typeof state === 'string' ? state : Object.keys(state)[0];
|
|
646
|
-
this.#log.
|
|
776
|
+
this.#log.debug(`Added tx ${txHashStr} as ${stateStr}`, {
|
|
647
777
|
eventName: 'tx-added-to-pool',
|
|
778
|
+
txHash: txHashStr,
|
|
648
779
|
state: stateStr,
|
|
780
|
+
source: opts.source,
|
|
649
781
|
});
|
|
650
782
|
|
|
651
783
|
return meta;
|
|
@@ -673,6 +805,29 @@ export class TxPoolV2Impl {
|
|
|
673
805
|
}
|
|
674
806
|
}
|
|
675
807
|
|
|
808
|
+
/** Evicts transactions: records eviction metric with reason, caches hashes, then deletes. */
|
|
809
|
+
async #evictTxs(txHashes: string[], reason: string): Promise<void> {
|
|
810
|
+
if (txHashes.length === 0) {
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
this.#instrumentation.recordEvictions(txHashes.length, reason);
|
|
814
|
+
for (const txHashStr of txHashes) {
|
|
815
|
+
this.#log.debug(`Evicting tx ${txHashStr}`, { txHash: txHashStr, reason });
|
|
816
|
+
this.#addToEvictedCache(txHashStr);
|
|
817
|
+
}
|
|
818
|
+
await this.#deleteTxsBatch(txHashes);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/** Adds a tx hash to the bounded evicted cache, evicting the oldest entry if at capacity. */
|
|
822
|
+
#addToEvictedCache(txHashStr: string): void {
|
|
823
|
+
if (this.#evictedTxHashes.size >= this.#config.evictedTxCacheSize) {
|
|
824
|
+
// FIFO eviction: remove the first (oldest) entry
|
|
825
|
+
const oldest = this.#evictedTxHashes.values().next().value!;
|
|
826
|
+
this.#evictedTxHashes.delete(oldest);
|
|
827
|
+
}
|
|
828
|
+
this.#evictedTxHashes.add(txHashStr);
|
|
829
|
+
}
|
|
830
|
+
|
|
676
831
|
// ============================================================================
|
|
677
832
|
// PRIVATE HELPERS - Validation & Conflict Resolution
|
|
678
833
|
// ============================================================================
|
|
@@ -828,7 +983,9 @@ export class TxPoolV2Impl {
|
|
|
828
983
|
if (preAddResult.shouldIgnore) {
|
|
829
984
|
// Transaction rejected - mark for deletion from DB
|
|
830
985
|
rejected.push(meta.txHash);
|
|
831
|
-
this.#log.debug(
|
|
986
|
+
this.#log.debug(
|
|
987
|
+
`Rejected tx ${meta.txHash} during rebuild: ${preAddResult.reason?.message ?? 'unknown reason'}`,
|
|
988
|
+
);
|
|
832
989
|
continue;
|
|
833
990
|
}
|
|
834
991
|
|
|
@@ -864,7 +1021,7 @@ export class TxPoolV2Impl {
|
|
|
864
1021
|
getFeePayerPendingTxs: (feePayer: string) => this.#indices.getFeePayerPendingTxs(feePayer),
|
|
865
1022
|
getPendingTxCount: () => this.#indices.getPendingTxCount(),
|
|
866
1023
|
getLowestPriorityPending: (limit: number) => this.#indices.getLowestPriorityPending(limit),
|
|
867
|
-
deleteTxs: (txHashes: string[]) => this.#
|
|
1024
|
+
deleteTxs: (txHashes: string[], reason?: string) => this.#evictTxs(txHashes, reason ?? 'unknown'),
|
|
868
1025
|
};
|
|
869
1026
|
}
|
|
870
1027
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import {
|
|
3
|
+
import { TX_ERROR_INVALID_EXPIRATION_TIMESTAMP, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
4
4
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
5
5
|
|
|
6
6
|
/** Structural interface for timestamp validation. */
|
|
7
7
|
export interface HasTimestampData {
|
|
8
8
|
txHash: { toString(): string };
|
|
9
9
|
data: {
|
|
10
|
-
|
|
10
|
+
expirationTimestamp: bigint;
|
|
11
11
|
constants: {
|
|
12
12
|
anchorBlockHeader: {
|
|
13
13
|
globalVariables: {
|
|
@@ -35,21 +35,21 @@ export class TimestampTxValidator<T extends HasTimestampData> implements TxValid
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
validateTx(tx: T): Promise<TxValidationResult> {
|
|
38
|
-
const
|
|
39
|
-
// If building block 1, we skip the expiration check. For details on why see the `
|
|
38
|
+
const expirationTimestamp = tx.data.expirationTimestamp;
|
|
39
|
+
// If building block 1, we skip the expiration check. For details on why see the `validate_expiration_timestamp`
|
|
40
40
|
// function in `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/validation_requests.nr`.
|
|
41
41
|
const buildingBlock1 = this.values.blockNumber === 1;
|
|
42
42
|
|
|
43
|
-
if (!buildingBlock1 &&
|
|
43
|
+
if (!buildingBlock1 && expirationTimestamp < this.values.timestamp) {
|
|
44
44
|
if (tx.data.constants.anchorBlockHeader.globalVariables.blockNumber === 0) {
|
|
45
45
|
this.#log.warn(
|
|
46
46
|
`A tx built against a genesis block failed to be included in block 1 which is the only block in which txs built against a genesis block are allowed to be included.`,
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
49
|
this.#log.verbose(
|
|
50
|
-
`Rejecting tx ${tx.txHash} for low expiration timestamp. Tx expiration timestamp: ${
|
|
50
|
+
`Rejecting tx ${tx.txHash} for low expiration timestamp. Tx expiration timestamp: ${expirationTimestamp}, timestamp: ${this.values.timestamp}.`,
|
|
51
51
|
);
|
|
52
|
-
return Promise.resolve({ result: 'invalid', reason: [
|
|
52
|
+
return Promise.resolve({ result: 'invalid', reason: [TX_ERROR_INVALID_EXPIRATION_TIMESTAMP] });
|
|
53
53
|
} else {
|
|
54
54
|
return Promise.resolve({ result: 'valid' });
|
|
55
55
|
}
|
package/src/services/encoding.ts
CHANGED
|
@@ -58,7 +58,8 @@ const DefaultMaxSizesKb: Record<TopicType, number> = {
|
|
|
58
58
|
// Proposals may carry some tx objects, so we allow a larger size capped at 10mb
|
|
59
59
|
// Note this may not be enough for carrying all tx objects in a block
|
|
60
60
|
[TopicType.block_proposal]: 1024 * 10,
|
|
61
|
-
//
|
|
61
|
+
// Checkpoint proposals carry almost the same data as a block proposal (see the lastBlockProposal)
|
|
62
|
+
// Only diff is an additional header, which is pretty small compared to the 10mb limit
|
|
62
63
|
[TopicType.checkpoint_proposal]: 1024 * 10,
|
|
63
64
|
};
|
|
64
65
|
|
|
@@ -1544,7 +1544,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1544
1544
|
protected async validatePropagatedTx(tx: Tx, peerId: PeerId): Promise<boolean> {
|
|
1545
1545
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1546
1546
|
|
|
1547
|
-
// We accept transactions if they are not expired by the next slot (checked based on the
|
|
1547
|
+
// We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
|
|
1548
1548
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1549
1549
|
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1550
1550
|
|
|
@@ -1599,7 +1599,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
|
|
|
1599
1599
|
public async validate(txs: Tx[]): Promise<void> {
|
|
1600
1600
|
const currentBlockNumber = await this.archiver.getBlockNumber();
|
|
1601
1601
|
|
|
1602
|
-
// We accept transactions if they are not expired by the next slot (checked based on the
|
|
1602
|
+
// We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
|
|
1603
1603
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
1604
1604
|
const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
|
|
1605
1605
|
|
|
@@ -10,6 +10,7 @@ import { Tx, TxArray, TxHash } from '@aztec/stdlib/tx';
|
|
|
10
10
|
import type { PeerId } from '@libp2p/interface';
|
|
11
11
|
import { peerIdFromString } from '@libp2p/peer-id';
|
|
12
12
|
|
|
13
|
+
import type { IMissingTxsTracker } from '../../tx_collection/missing_txs_tracker.js';
|
|
13
14
|
import { ReqRespSubProtocol } from '.././interface.js';
|
|
14
15
|
import { BlockTxsRequest, BlockTxsResponse, type BlockTxsSource } from '.././protocols/index.js';
|
|
15
16
|
import { ReqRespStatus } from '.././status.js';
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
DEFAULT_BATCH_TX_REQUESTER_TX_BATCH_SIZE,
|
|
21
22
|
} from './config.js';
|
|
22
23
|
import type { BatchTxRequesterLibP2PService, BatchTxRequesterOptions, ITxMetadataCollection } from './interface.js';
|
|
23
|
-
import {
|
|
24
|
+
import { MissingTxMetadataCollection } from './missing_txs.js';
|
|
24
25
|
import { type IPeerCollection, PeerCollection } from './peer_collection.js';
|
|
25
26
|
import { BatchRequestTxValidator, type IBatchRequestTxValidator } from './tx_validator.js';
|
|
26
27
|
|
|
@@ -60,7 +61,7 @@ export class BatchTxRequester {
|
|
|
60
61
|
private readonly txBatchSize: number;
|
|
61
62
|
|
|
62
63
|
constructor(
|
|
63
|
-
|
|
64
|
+
missingTxsTracker: IMissingTxsTracker,
|
|
64
65
|
blockTxsSource: BlockTxsSource,
|
|
65
66
|
pinnedPeer: PeerId | undefined,
|
|
66
67
|
timeoutMs: number,
|
|
@@ -99,8 +100,7 @@ export class BatchTxRequester {
|
|
|
99
100
|
this.p2pService.peerScoring,
|
|
100
101
|
);
|
|
101
102
|
}
|
|
102
|
-
|
|
103
|
-
this.txsMetadata = new MissingTxMetadataCollection(entries, this.txBatchSize);
|
|
103
|
+
this.txsMetadata = new MissingTxMetadataCollection(missingTxsTracker, this.txBatchSize);
|
|
104
104
|
this.smartRequesterSemaphore = this.opts.semaphore ?? new Semaphore(0);
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -661,7 +661,7 @@ export class BatchTxRequester {
|
|
|
661
661
|
/*
|
|
662
662
|
* @returns true if all missing txs have been fetched */
|
|
663
663
|
private fetchedAllTxs() {
|
|
664
|
-
return
|
|
664
|
+
return this.txsMetadata.getMissingTxHashes().size == 0;
|
|
665
665
|
}
|
|
666
666
|
|
|
667
667
|
/*
|
|
@@ -679,7 +679,7 @@ export class BatchTxRequester {
|
|
|
679
679
|
this.unlockSmartRequesterSemaphores();
|
|
680
680
|
}
|
|
681
681
|
|
|
682
|
-
return aborted || this.
|
|
682
|
+
return aborted || this.fetchedAllTxs() || this.dateProvider.now() > this.deadline;
|
|
683
683
|
}
|
|
684
684
|
|
|
685
685
|
/*
|
|
@@ -6,7 +6,6 @@ import type { PeerId } from '@libp2p/interface';
|
|
|
6
6
|
|
|
7
7
|
import type { ConnectionSampler } from '../connection-sampler/connection_sampler.js';
|
|
8
8
|
import type { ReqRespInterface } from '../interface.js';
|
|
9
|
-
import type { MissingTxMetadata } from './missing_txs.js';
|
|
10
9
|
import type { IPeerCollection } from './peer_collection.js';
|
|
11
10
|
import type { BatchRequestTxValidatorConfig, IBatchRequestTxValidator } from './tx_validator.js';
|
|
12
11
|
|
|
@@ -15,18 +14,15 @@ export interface IPeerPenalizer {
|
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
export interface ITxMetadataCollection {
|
|
18
|
-
size: number;
|
|
19
|
-
values(): IterableIterator<MissingTxMetadata>;
|
|
20
17
|
getMissingTxHashes(): Set<string>;
|
|
18
|
+
markFetched(peerId: PeerId, tx: Tx): boolean;
|
|
21
19
|
getTxsToRequestFromThePeer(peer: PeerId): TxHash[];
|
|
22
20
|
markRequested(txHash: TxHash): void;
|
|
23
21
|
markInFlightBySmartPeer(txHash: TxHash): void;
|
|
24
22
|
markNotInFlightBySmartPeer(txHash: TxHash): void;
|
|
25
23
|
alreadyFetched(txHash: TxHash): boolean;
|
|
26
24
|
// Returns true if tx was marked as fetched, false if it was already marked as fetched
|
|
27
|
-
markFetched(peerId: PeerId, tx: Tx): boolean;
|
|
28
25
|
markPeerHas(peerId: PeerId, txHashes: TxHash[]): void;
|
|
29
|
-
getFetchedTxs(): Tx[];
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
/**
|