@aztec/p2p 0.0.1-commit.9ef841308 → 0.0.1-commit.a89ec08
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 +1 -2
- package/dest/client/p2p_client.d.ts +1 -1
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +4 -6
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -17
- package/dest/config.d.ts +6 -6
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +6 -6
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +4 -8
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
- package/dest/mem_pools/index.d.ts +2 -1
- package/dest/mem_pools/index.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.d.ts +2 -4
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +14 -16
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +125 -0
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +596 -0
- 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 +123 -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 +3 -0
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/index.js +2 -0
- package/dest/mem_pools/tx_pool/priority.d.ts +12 -0
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/priority.js +15 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +127 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/tx_pool.js +3 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +7 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +402 -0
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +5 -7
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +0 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +6 -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 +1 -5
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
- 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 +43 -26
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +1 -1
- 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 +0 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -2
- 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 +1 -18
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +4 -5
- package/dest/msg_validators/clock_tolerance.d.ts +1 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +3 -4
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +5 -5
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +2 -4
- package/dest/services/libp2p/libp2p_service.d.ts +9 -7
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +59 -137
- package/dest/services/peer-manager/metrics.d.ts +1 -3
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +0 -6
- package/dest/services/peer-manager/peer_manager.d.ts +2 -6
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +9 -24
- package/dest/services/peer-manager/peer_scoring.d.ts +2 -5
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +10 -28
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +8 -11
- 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 +101 -82
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -3
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +4 -5
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +7 -13
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +11 -19
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +15 -52
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +3 -4
- package/dest/services/service.d.ts +1 -7
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +73 -57
- 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 +4 -4
- package/dest/services/tx_collection/slow_tx_collection.js +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +6 -3
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +1 -6
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +1 -9
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.d.ts +1 -1
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +2 -20
- package/dest/testbench/p2p_client_testbench_worker.js +15 -44
- 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 +2 -2
- package/dest/util.d.ts +4 -9
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +9 -2
- package/package.json +14 -14
- package/src/client/factory.ts +2 -3
- package/src/client/p2p_client.ts +4 -6
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +9 -19
- package/src/config.ts +10 -10
- package/src/index.ts +1 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +7 -8
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
- package/src/mem_pools/index.ts +3 -0
- package/src/mem_pools/instrumentation.ts +13 -17
- package/src/mem_pools/tx_pool/README.md +270 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +746 -0
- 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 +163 -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 +2 -0
- package/src/mem_pools/tx_pool/priority.ts +20 -0
- package/src/mem_pools/tx_pool/tx_pool.ts +141 -0
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +321 -0
- package/src/mem_pools/tx_pool_v2/interfaces.ts +4 -7
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +5 -11
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -29
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +0 -3
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1 -19
- package/src/msg_validators/attestation_validator/README.md +1 -1
- package/src/msg_validators/attestation_validator/attestation_validator.ts +4 -5
- package/src/msg_validators/clock_tolerance.ts +3 -4
- package/src/msg_validators/proposal_validator/README.md +4 -4
- package/src/msg_validators/proposal_validator/proposal_validator.ts +5 -6
- package/src/msg_validators/tx_validator/metadata_validator.ts +4 -12
- package/src/services/discv5/discV5_service.ts +2 -4
- package/src/services/libp2p/libp2p_service.ts +71 -135
- package/src/services/peer-manager/metrics.ts +0 -7
- package/src/services/peer-manager/peer_manager.ts +9 -28
- package/src/services/peer-manager/peer_scoring.ts +5 -21
- package/src/services/reqresp/batch-tx-requester/README.md +7 -46
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +111 -78
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -2
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +6 -13
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +24 -68
- package/src/services/reqresp/reqresp.ts +3 -5
- package/src/services/service.ts +0 -7
- package/src/services/tx_collection/fast_tx_collection.ts +83 -57
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +13 -8
- package/src/services/tx_collection/slow_tx_collection.ts +1 -1
- package/src/services/tx_collection/tx_collection.ts +5 -3
- package/src/test-helpers/make-test-p2p-clients.ts +1 -1
- package/src/test-helpers/mock-pubsub.ts +0 -9
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/test-helpers/testbench-utils.ts +3 -28
- package/src/testbench/p2p_client_testbench_worker.ts +15 -44
- package/src/testbench/worker_client_manager.ts +2 -2
- package/src/util.ts +13 -9
- package/dest/services/tx_collection/request_tracker.d.ts +0 -53
- package/dest/services/tx_collection/request_tracker.d.ts.map +0 -1
- package/dest/services/tx_collection/request_tracker.js +0 -84
- package/src/services/tx_collection/request_tracker.ts +0 -127
|
@@ -44,8 +44,6 @@ export type TxPoolV2Config = {
|
|
|
44
44
|
minTxPoolAgeMs: number;
|
|
45
45
|
/** Maximum number of evicted tx hashes to remember for metrics tracking */
|
|
46
46
|
evictedTxCacheSize: number;
|
|
47
|
-
/** The probability (0-1) that a transaction is discarded. 0 disables dropping. For testing purposes only. */
|
|
48
|
-
dropTransactionsProbability: number;
|
|
49
47
|
/** Minimum percentage fee increase required to replace an existing tx via RPC (0 = no bump). */
|
|
50
48
|
priceBumpPercentage: bigint;
|
|
51
49
|
};
|
|
@@ -58,7 +56,6 @@ export const DEFAULT_TX_POOL_V2_CONFIG: TxPoolV2Config = {
|
|
|
58
56
|
archivedTxLimit: 0, // 0 = disabled
|
|
59
57
|
minTxPoolAgeMs: 2_000,
|
|
60
58
|
evictedTxCacheSize: 10_000,
|
|
61
|
-
dropTransactionsProbability: 0,
|
|
62
59
|
priceBumpPercentage: 10n,
|
|
63
60
|
};
|
|
64
61
|
|
|
@@ -160,10 +157,10 @@ export interface TxPoolV2 extends TypedEventEmitter<TxPoolV2Events> {
|
|
|
160
157
|
handleMinedBlock(block: L2Block): Promise<void>;
|
|
161
158
|
|
|
162
159
|
/**
|
|
163
|
-
* Prepares the pool for a new slot
|
|
164
|
-
* slots and
|
|
165
|
-
*
|
|
166
|
-
*
|
|
160
|
+
* Prepares the pool for a new slot.
|
|
161
|
+
* Unprotects transactions from earlier slots and validates them before
|
|
162
|
+
* returning to pending state.
|
|
163
|
+
* @param slotNumber - The slot number to prepare for
|
|
167
164
|
*/
|
|
168
165
|
prepareForSlot(slotNumber: SlotNumber): Promise<void>;
|
|
169
166
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { minBigint } from '@aztec/foundation/bigint';
|
|
2
1
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
3
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
@@ -7,6 +6,7 @@ import { Gas } from '@aztec/stdlib/gas';
|
|
|
7
6
|
import { type Tx, TxHash } from '@aztec/stdlib/tx';
|
|
8
7
|
|
|
9
8
|
import { getFeePayerBalanceDelta } from '../../msg_validators/tx_validator/fee_payer_balance.js';
|
|
9
|
+
import { getTxPriorityFee } from '../tx_pool/priority.js';
|
|
10
10
|
import { type PreAddResult, TxPoolRejectionCode } from './eviction/interfaces.js';
|
|
11
11
|
|
|
12
12
|
/** Validator-compatible data interface, mirroring the subset of PrivateKernelTailCircuitPublicInputs used by validators. */
|
|
@@ -166,13 +166,13 @@ export function txHashFromBigInt(value: bigint): string {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
/** Minimal fields required for priority comparison. */
|
|
169
|
-
|
|
169
|
+
type PriorityComparable = Pick<TxMetaData, 'txHashBigInt' | 'priorityFee'>;
|
|
170
170
|
|
|
171
171
|
/**
|
|
172
172
|
* Compares two priority fees in ascending order.
|
|
173
173
|
* Returns negative if a < b, positive if a > b, 0 if equal.
|
|
174
174
|
*/
|
|
175
|
-
export function compareFee(a: bigint, b: bigint):
|
|
175
|
+
export function compareFee(a: bigint, b: bigint): number {
|
|
176
176
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -181,7 +181,7 @@ export function compareFee(a: bigint, b: bigint): -1 | 0 | 1 {
|
|
|
181
181
|
* Uses field element comparison for deterministic ordering.
|
|
182
182
|
* Returns negative if a < b, positive if a > b, 0 if equal.
|
|
183
183
|
*/
|
|
184
|
-
export function compareTxHash(a: bigint, b: bigint):
|
|
184
|
+
export function compareTxHash(a: bigint, b: bigint): number {
|
|
185
185
|
return Fr.cmpAsBigInt(a, b);
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -190,7 +190,7 @@ export function compareTxHash(a: bigint, b: bigint): -1 | 0 | 1 {
|
|
|
190
190
|
* Returns negative if a < b, positive if a > b, 0 if equal.
|
|
191
191
|
* Use with sort() for ascending order, or negate/reverse for descending.
|
|
192
192
|
*/
|
|
193
|
-
export function comparePriority(a: PriorityComparable, b: PriorityComparable):
|
|
193
|
+
export function comparePriority(a: PriorityComparable, b: PriorityComparable): number {
|
|
194
194
|
const feeComparison = compareFee(a.priorityFee, b.priorityFee);
|
|
195
195
|
if (feeComparison !== 0) {
|
|
196
196
|
return feeComparison;
|
|
@@ -335,9 +335,3 @@ export function stubTxMetaData(
|
|
|
335
335
|
data: stubTxMetaValidationData({ expirationTimestamp }),
|
|
336
336
|
};
|
|
337
337
|
}
|
|
338
|
-
|
|
339
|
-
/** Returns the priority fee for a tx, based on the L2 priority fee capped by the max fee per gas. */
|
|
340
|
-
function getTxPriorityFee(tx: Tx): bigint {
|
|
341
|
-
const { maxPriorityFeesPerGas: priorityFees, maxFeesPerGas } = tx.getGasSettings();
|
|
342
|
-
return minBigint(maxFeesPerGas.feePerL2Gas, priorityFees.feePerL2Gas);
|
|
343
|
-
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { insertIntoSortedArray, removeFromSortedArray } from '@aztec/foundation/array';
|
|
2
1
|
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
2
|
import type { L2BlockId } from '@aztec/stdlib/block';
|
|
4
3
|
|
|
5
|
-
import { type
|
|
4
|
+
import { type TxMetaData, type TxState, compareFee, compareTxHash, txHashFromBigInt } from './tx_metadata.js';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Manages in-memory indices for the transaction pool.
|
|
@@ -23,8 +22,8 @@ export class TxPoolIndices {
|
|
|
23
22
|
#nullifierToTxHash: Map<string, string> = new Map();
|
|
24
23
|
/** Fee payer to txHashes index (pending txs only) */
|
|
25
24
|
#feePayerToTxHashes: Map<string, Set<string>> = new Map();
|
|
26
|
-
/** Pending
|
|
27
|
-
#pendingByPriority:
|
|
25
|
+
/** Pending txHash bigints grouped by priority fee */
|
|
26
|
+
#pendingByPriority: Map<bigint, Set<bigint>> = new Map();
|
|
28
27
|
/** Protected transactions: txHash -> slotNumber */
|
|
29
28
|
#protectedTransactions: Map<string, SlotNumber> = new Map();
|
|
30
29
|
|
|
@@ -74,14 +73,20 @@ export class TxPoolIndices {
|
|
|
74
73
|
* @param order - 'desc' for highest priority first, 'asc' for lowest priority first
|
|
75
74
|
*/
|
|
76
75
|
*iteratePendingByPriority(order: 'asc' | 'desc', filter?: (hash: string) => boolean): Generator<string> {
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
76
|
+
const feeCompareFn = order === 'desc' ? (a: bigint, b: bigint) => compareFee(b, a) : compareFee;
|
|
77
|
+
const hashCompareFn =
|
|
78
|
+
order === 'desc' ? (a: bigint, b: bigint) => compareTxHash(b, a) : (a: bigint, b: bigint) => compareTxHash(a, b);
|
|
79
|
+
|
|
80
|
+
const sortedFees = [...this.#pendingByPriority.keys()].sort(feeCompareFn);
|
|
81
|
+
|
|
82
|
+
for (const fee of sortedFees) {
|
|
83
|
+
const hashesAtFee = this.#pendingByPriority.get(fee)!;
|
|
84
|
+
const sortedHashes = [...hashesAtFee].sort(hashCompareFn);
|
|
85
|
+
for (const hashBigInt of sortedHashes) {
|
|
86
|
+
const hash = txHashFromBigInt(hashBigInt);
|
|
87
|
+
if (filter === undefined || filter(hash)) {
|
|
88
|
+
yield hash;
|
|
89
|
+
}
|
|
85
90
|
}
|
|
86
91
|
}
|
|
87
92
|
}
|
|
@@ -222,7 +227,11 @@ export class TxPoolIndices {
|
|
|
222
227
|
|
|
223
228
|
/** Gets the count of pending transactions */
|
|
224
229
|
getPendingTxCount(): number {
|
|
225
|
-
|
|
230
|
+
let count = 0;
|
|
231
|
+
for (const hashes of this.#pendingByPriority.values()) {
|
|
232
|
+
count += hashes.size;
|
|
233
|
+
}
|
|
234
|
+
return count;
|
|
226
235
|
}
|
|
227
236
|
|
|
228
237
|
/** Gets the lowest priority pending transaction hashes (up to limit) */
|
|
@@ -255,10 +264,12 @@ export class TxPoolIndices {
|
|
|
255
264
|
/** Gets all pending transactions */
|
|
256
265
|
getPendingTxs(): TxMetaData[] {
|
|
257
266
|
const result: TxMetaData[] = [];
|
|
258
|
-
for (const
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
267
|
+
for (const hashSet of this.#pendingByPriority.values()) {
|
|
268
|
+
for (const txHashBigInt of hashSet) {
|
|
269
|
+
const meta = this.#metadata.get(txHashFromBigInt(txHashBigInt));
|
|
270
|
+
if (meta) {
|
|
271
|
+
result.push(meta);
|
|
272
|
+
}
|
|
262
273
|
}
|
|
263
274
|
}
|
|
264
275
|
return result;
|
|
@@ -397,12 +408,13 @@ export class TxPoolIndices {
|
|
|
397
408
|
}
|
|
398
409
|
feePayerSet.add(meta.txHash);
|
|
399
410
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
411
|
+
// Add to priority bucket
|
|
412
|
+
let prioritySet = this.#pendingByPriority.get(meta.priorityFee);
|
|
413
|
+
if (!prioritySet) {
|
|
414
|
+
prioritySet = new Set();
|
|
415
|
+
this.#pendingByPriority.set(meta.priorityFee, prioritySet);
|
|
416
|
+
}
|
|
417
|
+
prioritySet.add(meta.txHashBigInt);
|
|
406
418
|
}
|
|
407
419
|
|
|
408
420
|
#removeFromPendingIndices(meta: TxMetaData): void {
|
|
@@ -420,11 +432,13 @@ export class TxPoolIndices {
|
|
|
420
432
|
}
|
|
421
433
|
}
|
|
422
434
|
|
|
423
|
-
// Remove from priority
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
435
|
+
// Remove from priority map
|
|
436
|
+
const hashSet = this.#pendingByPriority.get(meta.priorityFee);
|
|
437
|
+
if (hashSet) {
|
|
438
|
+
hashSet.delete(meta.txHashBigInt);
|
|
439
|
+
if (hashSet.size === 0) {
|
|
440
|
+
this.#pendingByPriority.delete(meta.priorityFee);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
429
443
|
}
|
|
430
444
|
}
|
|
@@ -65,9 +65,6 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
|
|
|
65
65
|
const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : TxHash.fromBigInt(h)));
|
|
66
66
|
this.emit('txs-removed', { txHashes: hashes });
|
|
67
67
|
},
|
|
68
|
-
onTxsMined: (txHashes: string[]) => {
|
|
69
|
-
this.#metrics?.transactionsRemoved(txHashes);
|
|
70
|
-
},
|
|
71
68
|
};
|
|
72
69
|
|
|
73
70
|
// Create the implementation
|
|
@@ -45,7 +45,6 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
45
45
|
export interface TxPoolV2Callbacks {
|
|
46
46
|
onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
|
|
47
47
|
onTxsRemoved: (txHashes: string[] | bigint[]) => void;
|
|
48
|
-
onTxsMined: (txHashes: string[]) => void;
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
/**
|
|
@@ -340,12 +339,6 @@ export class TxPoolV2Impl {
|
|
|
340
339
|
}
|
|
341
340
|
}
|
|
342
341
|
|
|
343
|
-
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
344
|
-
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
345
|
-
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
346
|
-
return { status: 'accepted' };
|
|
347
|
-
}
|
|
348
|
-
|
|
349
342
|
// Add the transaction
|
|
350
343
|
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
351
344
|
return { status: 'accepted' };
|
|
@@ -356,7 +349,6 @@ export class TxPoolV2Impl {
|
|
|
356
349
|
|
|
357
350
|
// Check if already in pool
|
|
358
351
|
if (this.#indices.has(txHashStr)) {
|
|
359
|
-
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
|
|
360
352
|
return 'ignored';
|
|
361
353
|
}
|
|
362
354
|
|
|
@@ -365,13 +357,7 @@ export class TxPoolV2Impl {
|
|
|
365
357
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
366
358
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
367
359
|
|
|
368
|
-
|
|
369
|
-
this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
|
|
370
|
-
reason: preAddResult.reason?.message ?? 'no reason provided',
|
|
371
|
-
});
|
|
372
|
-
return 'ignored';
|
|
373
|
-
}
|
|
374
|
-
return 'accepted';
|
|
360
|
+
return preAddResult.shouldIgnore ? 'ignored' : 'accepted';
|
|
375
361
|
}
|
|
376
362
|
|
|
377
363
|
async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
|
|
@@ -515,10 +501,6 @@ export class TxPoolV2Impl {
|
|
|
515
501
|
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
516
502
|
});
|
|
517
503
|
|
|
518
|
-
if (found.length > 0) {
|
|
519
|
-
this.#callbacks.onTxsMined(found.map(m => m.txHash));
|
|
520
|
-
}
|
|
521
|
-
|
|
522
504
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
523
505
|
}
|
|
524
506
|
|
|
@@ -24,7 +24,7 @@ This module validates `CheckpointAttestation` gossipsub messages. Attestations a
|
|
|
24
24
|
|---|------|-------------|
|
|
25
25
|
| 8 | Sender recoverable (pool-side) | Silent drop |
|
|
26
26
|
| 9 | Not a duplicate (same slot + proposalId + signer) | IGNORE |
|
|
27
|
-
| 10 | Per-signer cap: `MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER` =
|
|
27
|
+
| 10 | Per-signer cap: `MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER` = 3 | IGNORE |
|
|
28
28
|
|
|
29
29
|
Own attestations added via `addOwnCheckpointAttestations` bypass the per-signer cap.
|
|
30
30
|
|
|
@@ -23,14 +23,13 @@ export class CheckpointAttestationValidator implements P2PValidator<CheckpointAt
|
|
|
23
23
|
const slotNumber = message.payload.header.slotNumber;
|
|
24
24
|
|
|
25
25
|
try {
|
|
26
|
-
|
|
27
|
-
const { targetSlot, nextSlot } = this.epochCache.getTargetAndNextSlot();
|
|
26
|
+
const { currentSlot, nextSlot } = this.epochCache.getCurrentAndNextSlot();
|
|
28
27
|
|
|
29
|
-
if (slotNumber !==
|
|
28
|
+
if (slotNumber !== currentSlot && slotNumber !== nextSlot) {
|
|
30
29
|
// Check if message is for previous slot and within clock tolerance
|
|
31
|
-
if (!isWithinClockTolerance(slotNumber,
|
|
30
|
+
if (!isWithinClockTolerance(slotNumber, currentSlot, this.epochCache)) {
|
|
32
31
|
this.logger.warn(
|
|
33
|
-
`Checkpoint attestation slot ${slotNumber} is not current (${
|
|
32
|
+
`Checkpoint attestation slot ${slotNumber} is not current (${currentSlot}) or next (${nextSlot}) slot`,
|
|
34
33
|
);
|
|
35
34
|
return { result: 'reject', severity: PeerErrorSeverity.HighToleranceError };
|
|
36
35
|
}
|
|
@@ -36,11 +36,10 @@ export function isWithinClockTolerance(
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// Check how far we are into the current slot (in milliseconds)
|
|
39
|
-
const { ts: slotStartTs, nowMs } = epochCache.getEpochAndSlotNow();
|
|
40
|
-
const targetSlot = epochCache.getTargetSlot();
|
|
39
|
+
const { ts: slotStartTs, nowMs, slot } = epochCache.getEpochAndSlotNow();
|
|
41
40
|
|
|
42
|
-
// Sanity check: ensure the epoch cache's
|
|
43
|
-
if (
|
|
41
|
+
// Sanity check: ensure the epoch cache's current slot matches the expected current slot
|
|
42
|
+
if (slot !== currentSlot) {
|
|
44
43
|
return false;
|
|
45
44
|
}
|
|
46
45
|
|
|
@@ -28,7 +28,7 @@ Deserialization guards: `BlockProposal.fromBuffer` and `SignedTxs.fromBuffer` bo
|
|
|
28
28
|
| # | Rule | Consequence |
|
|
29
29
|
|---|------|-------------|
|
|
30
30
|
| 9 | **Duplicate**: same archive root already stored | IGNORE (no penalty) |
|
|
31
|
-
| 10 | **Per-position cap**: max
|
|
31
|
+
| 10 | **Per-position cap**: max 3 proposals per (slot, indexWithinCheckpoint) | REJECT + HighToleranceError |
|
|
32
32
|
| 11 | **Equivocation**: >1 distinct proposal for same (slot, index) | ACCEPT (rebroadcast for detection). At count=2: `duplicateProposalCallback` fires -> slash event (`OffenseType.DUPLICATE_PROPOSAL`, configured via `slashDuplicateProposalPenalty`) |
|
|
33
33
|
|
|
34
34
|
### Stage 3: Validator-Client Processing (BlockProposalHandler)
|
|
@@ -53,7 +53,7 @@ Only runs on validator nodes. Non-validator nodes use a default handler that tri
|
|
|
53
53
|
|
|
54
54
|
**Escape hatch**: during escape hatch periods (`isEscapeHatchOpenAtSlot`), re-execution and slashing are both disabled, and the proposal is rejected locally.
|
|
55
55
|
|
|
56
|
-
**Conditional re-execution**: rules 22-24 only run when at least one condition is true: `fishermanMode` enabled, `slashBroadcastedInvalidBlockPenalty > 0`, committee membership
|
|
56
|
+
**Conditional re-execution**: rules 22-24 only run when at least one condition is true: `fishermanMode` enabled, `slashBroadcastedInvalidBlockPenalty > 0` with `validatorReexecute`, committee membership with `validatorReexecute`, `alwaysReexecuteBlockProposals`, or `blobClient.canUpload()`.
|
|
57
57
|
|
|
58
58
|
**Slashing**: only `state_mismatch` and `failed_txs` trigger on-chain slashing (`OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL`, gated by `slashBroadcastedInvalidBlockPenalty > 0`). Unknown errors during re-execution do NOT slash.
|
|
59
59
|
|
|
@@ -84,7 +84,7 @@ The checkpoint's embedded `lastBlock` is extracted via `getBlockProposal()` and
|
|
|
84
84
|
| Rule | Consequence | File |
|
|
85
85
|
|------|-------------|------|
|
|
86
86
|
| Block proposal must pass `BlockProposalValidator.validate()` | If REJECT: entire checkpoint REJECTED | `libp2p_service.ts` |
|
|
87
|
-
| Block proposal must not exceed per-position cap (
|
|
87
|
+
| Block proposal must not exceed per-position cap (3) | Checkpoint REJECTED + HighToleranceError | same |
|
|
88
88
|
| Block equivocation detected (>1 proposals for same slot+index) | Checkpoint REJECTED (block itself is ACCEPT for re-broadcast) | same |
|
|
89
89
|
|
|
90
90
|
### Stage 3: Mempool (Attestation Pool)
|
|
@@ -92,7 +92,7 @@ The checkpoint's embedded `lastBlock` is extracted via `getBlockProposal()` and
|
|
|
92
92
|
| Rule | Consequence | File |
|
|
93
93
|
|------|-------------|------|
|
|
94
94
|
| Duplicate (same archive ID) | IGNORE (no penalty). Embedded block still processed if valid. | `attestation_pool.ts` |
|
|
95
|
-
| Per-slot cap: `MAX_CHECKPOINT_PROPOSALS_PER_SLOT` =
|
|
95
|
+
| Per-slot cap: `MAX_CHECKPOINT_PROPOSALS_PER_SLOT` = 5 | REJECT + HighToleranceError. Embedded block still processed. | same |
|
|
96
96
|
|
|
97
97
|
### Stage 4: Equivocation Detection
|
|
98
98
|
|
|
@@ -31,14 +31,13 @@ export class ProposalValidator {
|
|
|
31
31
|
/** Validates header-level fields: slot, signature, and proposer. */
|
|
32
32
|
public async validate(proposal: BlockProposal | CheckpointProposalCore): Promise<ValidationResult> {
|
|
33
33
|
try {
|
|
34
|
-
// Slot check
|
|
35
|
-
const {
|
|
36
|
-
|
|
34
|
+
// Slot check
|
|
35
|
+
const { currentSlot, nextSlot } = this.epochCache.getCurrentAndNextSlot();
|
|
37
36
|
const slotNumber = proposal.slotNumber;
|
|
38
|
-
if (slotNumber !==
|
|
37
|
+
if (slotNumber !== currentSlot && slotNumber !== nextSlot) {
|
|
39
38
|
// Check if message is for previous slot and within clock tolerance
|
|
40
|
-
if (!isWithinClockTolerance(slotNumber,
|
|
41
|
-
this.logger.warn(`Penalizing peer for invalid slot number ${slotNumber}`, {
|
|
39
|
+
if (!isWithinClockTolerance(slotNumber, currentSlot, this.epochCache)) {
|
|
40
|
+
this.logger.warn(`Penalizing peer for invalid slot number ${slotNumber}`, { currentSlot, nextSlot });
|
|
42
41
|
return { result: 'reject', severity: PeerErrorSeverity.HighToleranceError };
|
|
43
42
|
}
|
|
44
43
|
this.logger.verbose(`Ignoring proposal for previous slot ${slotNumber} within clock tolerance`);
|
|
@@ -28,24 +28,16 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
28
28
|
validateTx(tx: T): Promise<TxValidationResult> {
|
|
29
29
|
const errors = [];
|
|
30
30
|
if (!this.#hasCorrectL1ChainId(tx)) {
|
|
31
|
-
errors.push(
|
|
32
|
-
`${TX_ERROR_INCORRECT_L1_CHAIN_ID} (tx: ${tx.data.constants.txContext.chainId.toNumber()}, expected: ${this.values.l1ChainId.toNumber()})`,
|
|
33
|
-
);
|
|
31
|
+
errors.push(TX_ERROR_INCORRECT_L1_CHAIN_ID);
|
|
34
32
|
}
|
|
35
33
|
if (!this.#hasCorrectRollupVersion(tx)) {
|
|
36
|
-
errors.push(
|
|
37
|
-
`${TX_ERROR_INCORRECT_ROLLUP_VERSION} (tx: ${tx.data.constants.txContext.version.toNumber()}, expected: ${this.values.rollupVersion.toNumber()})`,
|
|
38
|
-
);
|
|
34
|
+
errors.push(TX_ERROR_INCORRECT_ROLLUP_VERSION);
|
|
39
35
|
}
|
|
40
36
|
if (!this.#hasCorrectVkTreeRoot(tx)) {
|
|
41
|
-
errors.push(
|
|
42
|
-
`${TX_ERROR_INCORRECT_VK_TREE_ROOT} (tx: ${tx.data.constants.vkTreeRoot.toString()}, expected: ${this.values.vkTreeRoot.toString()})`,
|
|
43
|
-
);
|
|
37
|
+
errors.push(TX_ERROR_INCORRECT_VK_TREE_ROOT);
|
|
44
38
|
}
|
|
45
39
|
if (!this.#hasCorrectprotocolContractsHash(tx)) {
|
|
46
|
-
errors.push(
|
|
47
|
-
`${TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH} (tx: ${tx.data.constants.protocolContractsHash.toString()}, expected: ${this.values.protocolContractsHash.toString()})`,
|
|
48
|
-
);
|
|
40
|
+
errors.push(TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH);
|
|
49
41
|
}
|
|
50
42
|
return Promise.resolve(errors.length > 0 ? { result: 'invalid', reason: errors } : { result: 'valid' });
|
|
51
43
|
}
|
|
@@ -96,7 +96,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
96
96
|
lookupTimeout: 2000,
|
|
97
97
|
requestTimeout: 2000,
|
|
98
98
|
allowUnverifiedSessions: true,
|
|
99
|
-
enrUpdate:
|
|
99
|
+
enrUpdate: !p2pIp ? true : false, // If no p2p IP is set, enrUpdate can automatically resolve it
|
|
100
100
|
...configOverrides.config,
|
|
101
101
|
},
|
|
102
102
|
metricsRegistry,
|
|
@@ -129,11 +129,9 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
129
129
|
private onMultiaddrUpdated(m: Multiaddr) {
|
|
130
130
|
// We want to update our tcp port to match the udp port
|
|
131
131
|
// p2pBroadcastPort is optional on config, however it is set to default within the p2p client factory
|
|
132
|
-
const
|
|
133
|
-
const multiAddrTcp = multiaddr(convertToMultiaddr(address, this.config.p2pBroadcastPort!, 'tcp'));
|
|
132
|
+
const multiAddrTcp = multiaddr(convertToMultiaddr(m.nodeAddress().address, this.config.p2pBroadcastPort!, 'tcp'));
|
|
134
133
|
this.enr.setLocationMultiaddr(multiAddrTcp);
|
|
135
134
|
this.logger.info('Multiaddr updated', { multiaddr: multiAddrTcp.toString() });
|
|
136
|
-
this.emit('ip:changed', address);
|
|
137
135
|
}
|
|
138
136
|
|
|
139
137
|
public async start(): Promise<void> {
|