@aztec/p2p 0.0.1-commit.4eabbdb → 0.0.1-commit.5358163d3

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.
Files changed (163) hide show
  1. package/dest/client/factory.d.ts +4 -5
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +15 -26
  4. package/dest/client/interface.d.ts +6 -13
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +5 -13
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +3 -58
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +1 -2
  10. package/dest/config.d.ts +10 -14
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +25 -35
  13. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +1 -1
  14. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  15. package/dest/mem_pools/attestation_pool/attestation_pool.js +5 -1
  16. package/dest/mem_pools/instrumentation.d.ts +4 -2
  17. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  18. package/dest/mem_pools/instrumentation.js +16 -14
  19. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
  20. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
  21. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  22. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +2 -0
  23. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  24. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  25. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  26. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +10 -6
  27. package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
  28. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  29. package/dest/mem_pools/tx_pool_v2/index.js +1 -1
  30. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +7 -5
  31. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  32. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  33. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +26 -4
  34. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  35. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +48 -7
  36. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  37. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  38. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +9 -10
  39. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +2 -2
  40. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  41. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +3 -0
  42. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +3 -2
  43. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  44. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +175 -145
  45. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +2 -1
  46. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
  47. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +2 -1
  48. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
  49. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +3 -1
  50. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  51. package/dest/msg_validators/proposal_validator/proposal_validator.js +10 -0
  52. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +2 -1
  53. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -1
  54. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +166 -0
  55. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
  56. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  57. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  58. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
  59. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
  60. package/dest/msg_validators/tx_validator/allowed_public_setup.js +25 -10
  61. package/dest/msg_validators/tx_validator/factory.d.ts +114 -6
  62. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  63. package/dest/msg_validators/tx_validator/factory.js +219 -58
  64. package/dest/msg_validators/tx_validator/gas_validator.d.ts +58 -3
  65. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  66. package/dest/msg_validators/tx_validator/gas_validator.js +73 -36
  67. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  68. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  69. package/dest/msg_validators/tx_validator/index.js +1 -0
  70. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  71. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  72. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  73. package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
  74. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  75. package/dest/msg_validators/tx_validator/phases_validator.js +25 -24
  76. package/dest/services/dummy_service.d.ts +2 -3
  77. package/dest/services/dummy_service.d.ts.map +1 -1
  78. package/dest/services/dummy_service.js +1 -4
  79. package/dest/services/encoding.d.ts +2 -2
  80. package/dest/services/encoding.d.ts.map +1 -1
  81. package/dest/services/encoding.js +7 -7
  82. package/dest/services/libp2p/libp2p_service.d.ts +15 -13
  83. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  84. package/dest/services/libp2p/libp2p_service.js +72 -83
  85. package/dest/services/peer-manager/metrics.d.ts +3 -1
  86. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  87. package/dest/services/peer-manager/metrics.js +6 -0
  88. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  89. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  90. package/dest/services/peer-manager/peer_manager.js +2 -1
  91. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -1
  92. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  93. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +14 -37
  94. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +17 -11
  95. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  96. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +49 -15
  97. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  98. package/dest/services/reqresp/reqresp.d.ts +1 -1
  99. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  100. package/dest/services/reqresp/reqresp.js +2 -1
  101. package/dest/services/service.d.ts +2 -2
  102. package/dest/services/service.d.ts.map +1 -1
  103. package/dest/services/tx_provider.d.ts +3 -3
  104. package/dest/services/tx_provider.d.ts.map +1 -1
  105. package/dest/services/tx_provider.js +4 -4
  106. package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
  107. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  108. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  109. package/dest/test-helpers/mock-pubsub.d.ts +2 -3
  110. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  111. package/dest/test-helpers/mock-pubsub.js +2 -2
  112. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  113. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  114. package/dest/test-helpers/reqresp-nodes.js +2 -2
  115. package/dest/test-helpers/testbench-utils.d.ts +2 -2
  116. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  117. package/dest/testbench/p2p_client_testbench_worker.js +5 -5
  118. package/package.json +14 -14
  119. package/src/client/factory.ts +22 -46
  120. package/src/client/interface.ts +5 -19
  121. package/src/client/p2p_client.ts +4 -88
  122. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +1 -2
  123. package/src/config.ts +36 -42
  124. package/src/mem_pools/attestation_pool/attestation_pool.ts +5 -4
  125. package/src/mem_pools/instrumentation.ts +17 -13
  126. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
  127. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
  128. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +2 -2
  129. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +10 -6
  130. package/src/mem_pools/tx_pool_v2/index.ts +1 -1
  131. package/src/mem_pools/tx_pool_v2/interfaces.ts +7 -4
  132. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +65 -10
  133. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +11 -11
  134. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +4 -1
  135. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +184 -148
  136. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +1 -1
  137. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +1 -1
  138. package/src/msg_validators/proposal_validator/proposal_validator.ts +15 -1
  139. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +144 -1
  140. package/src/msg_validators/tx_validator/README.md +115 -0
  141. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
  142. package/src/msg_validators/tx_validator/allowed_public_setup.ts +27 -13
  143. package/src/msg_validators/tx_validator/factory.ts +353 -77
  144. package/src/msg_validators/tx_validator/gas_validator.ts +90 -27
  145. package/src/msg_validators/tx_validator/index.ts +1 -0
  146. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  147. package/src/msg_validators/tx_validator/phases_validator.ts +25 -29
  148. package/src/services/dummy_service.ts +1 -5
  149. package/src/services/encoding.ts +5 -6
  150. package/src/services/libp2p/libp2p_service.ts +84 -92
  151. package/src/services/peer-manager/metrics.ts +7 -0
  152. package/src/services/peer-manager/peer_manager.ts +2 -1
  153. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +14 -42
  154. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +63 -24
  155. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  156. package/src/services/reqresp/reqresp.ts +3 -1
  157. package/src/services/service.ts +1 -1
  158. package/src/services/tx_provider.ts +2 -2
  159. package/src/test-helpers/make-test-p2p-clients.ts +0 -2
  160. package/src/test-helpers/mock-pubsub.ts +3 -6
  161. package/src/test-helpers/reqresp-nodes.ts +2 -5
  162. package/src/test-helpers/testbench-utils.ts +1 -1
  163. package/src/testbench/p2p_client_testbench_worker.ts +2 -6
@@ -73,7 +73,7 @@ export class PoolInstrumentation<PoolObject extends Gossipable> {
73
73
  private defaultAttributes;
74
74
  private meter: Meter;
75
75
 
76
- private txAddedTimestamp: Map<bigint, number> = new Map<bigint, number>();
76
+ private mempoolItemAddedTimestamp: Map<bigint | string, number> = new Map<bigint | string, number>();
77
77
 
78
78
  constructor(
79
79
  telemetry: TelemetryClient,
@@ -114,22 +114,26 @@ export class PoolInstrumentation<PoolObject extends Gossipable> {
114
114
  }
115
115
 
116
116
  public transactionsAdded(transactions: Tx[]) {
117
- const timestamp = Date.now();
118
- for (const transaction of transactions) {
119
- this.txAddedTimestamp.set(transaction.txHash.toBigInt(), timestamp);
120
- }
117
+ transactions.forEach(tx => this.trackMempoolItemAdded(tx.txHash.toBigInt()));
121
118
  }
122
119
 
123
120
  public transactionsRemoved(hashes: Iterable<bigint> | Iterable<string>) {
124
- const timestamp = Date.now();
125
121
  for (const hash of hashes) {
126
- const key = BigInt(hash);
127
- const addedAt = this.txAddedTimestamp.get(key);
128
- if (addedAt !== undefined) {
129
- this.txAddedTimestamp.delete(key);
130
- if (addedAt < timestamp) {
131
- this.minedDelay.record(timestamp - addedAt);
132
- }
122
+ this.trackMempoolItemRemoved(BigInt(hash));
123
+ }
124
+ }
125
+
126
+ public trackMempoolItemAdded(key: bigint | string): void {
127
+ this.mempoolItemAddedTimestamp.set(key, Date.now());
128
+ }
129
+
130
+ public trackMempoolItemRemoved(key: bigint | string): void {
131
+ const timestamp = Date.now();
132
+ const addedAt = this.mempoolItemAddedTimestamp.get(key);
133
+ if (addedAt !== undefined) {
134
+ this.mempoolItemAddedTimestamp.delete(key);
135
+ if (addedAt < timestamp) {
136
+ this.minedDelay.record(timestamp - addedAt);
133
137
  }
134
138
  }
135
139
  }
@@ -34,7 +34,7 @@ export class FeePayerBalanceEvictionRule implements EvictionRule {
34
34
  }
35
35
 
36
36
  if (context.event === EvictionEvent.CHAIN_PRUNED) {
37
- await this.worldState.syncImmediate(context.blockNumber);
37
+ await this.worldState.syncImmediate();
38
38
  const feePayers = pool.getPendingFeePayers();
39
39
  return await this.evictForFeePayers(feePayers, this.worldState.getSnapshot(context.blockNumber), pool);
40
40
  }
@@ -35,6 +35,7 @@ export class FeePayerBalancePreAddRule implements PreAddRule {
35
35
  // Create combined list with incoming tx
36
36
  const allTxs: Array<{
37
37
  txHash: string;
38
+ txHashBigInt: bigint;
38
39
  priorityFee: bigint;
39
40
  feeLimit: bigint;
40
41
  claimAmount: bigint;
@@ -42,6 +43,7 @@ export class FeePayerBalancePreAddRule implements PreAddRule {
42
43
  }> = [
43
44
  ...existingTxs.map(t => ({
44
45
  txHash: t.txHash,
46
+ txHashBigInt: t.txHashBigInt,
45
47
  priorityFee: t.priorityFee,
46
48
  feeLimit: t.feeLimit,
47
49
  claimAmount: t.claimAmount,
@@ -49,6 +51,7 @@ export class FeePayerBalancePreAddRule implements PreAddRule {
49
51
  })),
50
52
  {
51
53
  txHash: incomingMeta.txHash,
54
+ txHashBigInt: incomingMeta.txHashBigInt,
52
55
  priorityFee: incomingMeta.priorityFee,
53
56
  feeLimit: incomingMeta.feeLimit,
54
57
  claimAmount: incomingMeta.claimAmount,
@@ -45,8 +45,8 @@ export class InvalidTxsAfterReorgRule implements EvictionRule {
45
45
  txsByBlockHash.get(blockHashStr)!.push(meta.txHash);
46
46
  }
47
47
 
48
- // Ensure world state is synced to this block before accessing the snapshot
49
- await this.worldState.syncImmediate(context.blockNumber);
48
+ // Sync without a block number to ensure the world state processes the prune event.
49
+ await this.worldState.syncImmediate();
50
50
  const db = this.worldState.getSnapshot(context.blockNumber);
51
51
 
52
52
  // Check which blocks exist in the archive
@@ -5,7 +5,7 @@ import { EvictionEvent } from './interfaces.js';
5
5
 
6
6
  /**
7
7
  * Eviction rule that removes low-priority transactions when the pool exceeds configured limits.
8
- * Only triggers on TXS_ADDED events.
8
+ * Triggers on TXS_ADDED and CHAIN_PRUNED events.
9
9
  */
10
10
  export class LowPriorityEvictionRule implements EvictionRule {
11
11
  public readonly name = 'LowPriorityEviction';
@@ -18,7 +18,7 @@ export class LowPriorityEvictionRule implements EvictionRule {
18
18
  }
19
19
 
20
20
  async evict(context: EvictionContext, pool: PoolOperations): Promise<EvictionResult> {
21
- if (context.event !== EvictionEvent.TXS_ADDED) {
21
+ if (context.event !== EvictionEvent.TXS_ADDED && context.event !== EvictionEvent.CHAIN_PRUNED) {
22
22
  return {
23
23
  reason: 'low_priority',
24
24
  success: true,
@@ -51,15 +51,19 @@ export class LowPriorityEvictionRule implements EvictionRule {
51
51
  this.log.info(`Evicting low priority txs. Pending tx count above limit: ${currentTxCount} > ${this.maxPoolSize}`);
52
52
  const numberToEvict = currentTxCount - this.maxPoolSize;
53
53
  const txsToEvict = pool.getLowestPriorityPending(numberToEvict);
54
- const toEvictSet = new Set(txsToEvict);
55
- const numNewTxsEvicted = context.newTxHashes.filter(newTxHash => toEvictSet.has(newTxHash)).length;
56
54
 
57
55
  if (txsToEvict.length > 0) {
58
- this.log.info(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`);
56
+ if (context.event === EvictionEvent.TXS_ADDED) {
57
+ const toEvictSet = new Set(txsToEvict);
58
+ const numNewTxsEvicted = context.newTxHashes.filter(newTxHash => toEvictSet.has(newTxHash)).length;
59
+ this.log.info(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`);
60
+ } else {
61
+ this.log.info(`Evicted ${txsToEvict.length} low priority txs after chain prune`);
62
+ }
59
63
  await pool.deleteTxs(txsToEvict, this.name);
60
64
  }
61
65
 
62
- this.log.debug(`Evicted ${txsToEvict.length} low priority txs, including ${numNewTxsEvicted} newly added txs`, {
66
+ this.log.debug(`Evicted ${txsToEvict.length} low priority txs`, {
63
67
  txHashes: txsToEvict,
64
68
  });
65
69
 
@@ -7,6 +7,6 @@ export {
7
7
  type PoolReadAccess,
8
8
  DEFAULT_TX_POOL_V2_CONFIG,
9
9
  } from './interfaces.js';
10
- export { type TxMetaData, type TxState, buildTxMetaData, comparePriority } from './tx_metadata.js';
10
+ export { type TxMetaData, type TxState, buildTxMetaData, comparePriority, stubTxMetaData } from './tx_metadata.js';
11
11
  export { TxArchive } from './archive/index.js';
12
12
  export { DeletedPool } from './deleted_pool.js';
@@ -44,6 +44,8 @@ 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;
47
49
  };
48
50
 
49
51
  /**
@@ -54,6 +56,7 @@ export const DEFAULT_TX_POOL_V2_CONFIG: TxPoolV2Config = {
54
56
  archivedTxLimit: 0, // 0 = disabled
55
57
  minTxPoolAgeMs: 2_000,
56
58
  evictedTxCacheSize: 10_000,
59
+ dropTransactionsProbability: 0,
57
60
  };
58
61
 
59
62
  /**
@@ -107,12 +110,12 @@ export interface TxPoolV2 extends TypedEventEmitter<TxPoolV2Events> {
107
110
  addPendingTxs(txs: Tx[], opts?: { source?: string; feeComparisonOnly?: boolean }): Promise<AddTxsResult>;
108
111
 
109
112
  /**
110
- * Checks if a transaction can be added without modifying the pool.
111
- * Performs the same validation as addPendingTxs but doesn't persist changes.
113
+ * Checks if the pool would accept a transaction without modifying state.
114
+ * Used as a pre-check before expensive proof verification.
112
115
  * @param tx - Transaction to check
113
- * @returns Result: 'accepted', 'ignored' (if already in pool or undesirable), or 'rejected' (if validation fails)
116
+ * @returns 'accepted' if the pool would accept, 'ignored' if already in pool or undesirable
114
117
  */
115
- canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored' | 'rejected'>;
118
+ canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'>;
116
119
 
117
120
  /**
118
121
  * Adds transactions as immediately protected for a given slot.
@@ -2,7 +2,8 @@ import { BlockNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
3
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
4
4
  import { BlockHash, type L2BlockId } from '@aztec/stdlib/block';
5
- import type { Tx } from '@aztec/stdlib/tx';
5
+ import { Gas } from '@aztec/stdlib/gas';
6
+ import { type Tx, TxHash } from '@aztec/stdlib/tx';
6
7
 
7
8
  import { getFeePayerBalanceDelta } from '../../msg_validators/tx_validator/fee_payer_balance.js';
8
9
  import { getTxPriorityFee } from '../tx_pool/priority.js';
@@ -12,6 +13,8 @@ import { type PreAddResult, TxPoolRejectionCode } from './eviction/interfaces.js
12
13
  export type TxMetaValidationData = {
13
14
  getNonEmptyNullifiers(): Fr[];
14
15
  expirationTimestamp: bigint;
16
+ /** Whether the tx has public calls. Used to select the correct L2 gas minimum. */
17
+ forPublic?: unknown;
15
18
  constants: {
16
19
  anchorBlockHeader: {
17
20
  hash(): Promise<BlockHash>;
@@ -19,6 +22,9 @@ export type TxMetaValidationData = {
19
22
  blockNumber: BlockNumber;
20
23
  };
21
24
  };
25
+ txContext: {
26
+ gasSettings: { gasLimits: Gas };
27
+ };
22
28
  };
23
29
  };
24
30
 
@@ -34,6 +40,9 @@ export type TxMetaData = {
34
40
  /** The transaction hash as hex string */
35
41
  readonly txHash: string;
36
42
 
43
+ /** The transaction hash as bigint (for efficient Fr conversion in comparisons) */
44
+ readonly txHashBigInt: bigint;
45
+
37
46
  /** Block ID (number and hash) in which the transaction was mined (undefined if not mined) */
38
47
  minedL2BlockId?: L2BlockId;
39
48
 
@@ -77,7 +86,9 @@ export type TxState = 'pending' | 'protected' | 'mined' | 'deleted';
77
86
  * Fr values are captured in closures for zero-cost re-validation.
78
87
  */
79
88
  export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
80
- const txHash = tx.getTxHash().toString();
89
+ const txHashObj = tx.getTxHash();
90
+ const txHash = txHashObj.toString();
91
+ const txHashBigInt = txHashObj.toBigInt();
81
92
  const nullifierFrs = tx.data.getNonEmptyNullifiers();
82
93
  const nullifiers = nullifierFrs.map(n => n.toString());
83
94
  const anchorBlockHeaderHashFr = await tx.data.constants.anchorBlockHeader.hash();
@@ -93,6 +104,7 @@ export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
93
104
 
94
105
  return {
95
106
  txHash,
107
+ txHashBigInt,
96
108
  anchorBlockHeaderHash,
97
109
  priorityFee,
98
110
  feePayer,
@@ -105,11 +117,15 @@ export async function buildTxMetaData(tx: Tx): Promise<TxMetaData> {
105
117
  data: {
106
118
  getNonEmptyNullifiers: () => nullifierFrs,
107
119
  expirationTimestamp,
120
+ forPublic: !!tx.data.forPublic,
108
121
  constants: {
109
122
  anchorBlockHeader: {
110
123
  hash: () => Promise.resolve(anchorBlockHeaderHashFr),
111
124
  globalVariables: { blockNumber: anchorBlockNumber },
112
125
  },
126
+ txContext: {
127
+ gasSettings: { gasLimits: tx.data.constants.txContext.gasSettings.gasLimits },
128
+ },
113
129
  },
114
130
  },
115
131
  };
@@ -124,11 +140,11 @@ const HEX_STRING_BYTES = 98;
124
140
  const BIGINT_BYTES = 32;
125
141
  const FR_BYTES = 80;
126
142
  // Fixed cost: object shell + txHash + anchorBlockHeaderHash + feePayer (3 hex strings)
127
- // + priorityFee + claimAmount + feeLimit + includeByTimestamp (4 bigints)
143
+ // + txHashBigInt + priorityFee + claimAmount + feeLimit + includeByTimestamp (5 bigints)
128
144
  // + receivedAt (number, 8 bytes) + estimatedSizeBytes (number, 8 bytes)
129
145
  // + data closure object (~OBJECT_OVERHEAD + anchorBlockHeaderHashFr Fr + anchorBlockNumber number)
130
146
  const FIXED_METADATA_BYTES =
131
- OBJECT_OVERHEAD + 3 * HEX_STRING_BYTES + 4 * BIGINT_BYTES + 8 + 8 + OBJECT_OVERHEAD + FR_BYTES + 8;
147
+ OBJECT_OVERHEAD + 3 * HEX_STRING_BYTES + 5 * BIGINT_BYTES + 8 + 8 + OBJECT_OVERHEAD + FR_BYTES + 8;
132
148
 
133
149
  /** Estimates the in-memory size of a TxMetaData object based on the number of nullifiers. */
134
150
  function estimateTxMetaDataSize(nullifierCount: number): number {
@@ -136,8 +152,13 @@ function estimateTxMetaDataSize(nullifierCount: number): number {
136
152
  return FIXED_METADATA_BYTES + nullifierCount * (HEX_STRING_BYTES + FR_BYTES);
137
153
  }
138
154
 
155
+ /** Converts a txHash bigint back to the canonical 0x-prefixed 64-char hex string. */
156
+ export function txHashFromBigInt(value: bigint): string {
157
+ return TxHash.fromBigInt(value).toString();
158
+ }
159
+
139
160
  /** Minimal fields required for priority comparison. */
140
- type PriorityComparable = Pick<TxMetaData, 'txHash' | 'priorityFee'>;
161
+ type PriorityComparable = Pick<TxMetaData, 'txHashBigInt' | 'priorityFee'>;
141
162
 
142
163
  /**
143
164
  * Compares two priority fees in ascending order.
@@ -152,10 +173,8 @@ export function compareFee(a: bigint, b: bigint): number {
152
173
  * Uses field element comparison for deterministic ordering.
153
174
  * Returns negative if a < b, positive if a > b, 0 if equal.
154
175
  */
155
- export function compareTxHash(a: string, b: string): number {
156
- const fieldA = Fr.fromHexString(a);
157
- const fieldB = Fr.fromHexString(b);
158
- return fieldA.cmp(fieldB);
176
+ export function compareTxHash(a: bigint, b: bigint): number {
177
+ return Fr.cmpAsBigInt(a, b);
159
178
  }
160
179
 
161
180
  /**
@@ -168,7 +187,7 @@ export function comparePriority(a: PriorityComparable, b: PriorityComparable): n
168
187
  if (feeComparison !== 0) {
169
188
  return feeComparison;
170
189
  }
171
- return compareTxHash(a.txHash, b.txHash);
190
+ return compareTxHash(a.txHashBigInt, b.txHashBigInt);
172
191
  }
173
192
 
174
193
  /**
@@ -237,6 +256,42 @@ export function stubTxMetaValidationData(overrides: { expirationTimestamp?: bigi
237
256
  hash: () => Promise.resolve(new BlockHash(Fr.ZERO)),
238
257
  globalVariables: { blockNumber: BlockNumber(0) },
239
258
  },
259
+ txContext: {
260
+ gasSettings: { gasLimits: Gas.empty() },
261
+ },
240
262
  },
241
263
  };
242
264
  }
265
+
266
+ /** Creates a stub TxMetaData for tests. All fields have sensible defaults and can be overridden. */
267
+ export function stubTxMetaData(
268
+ txHash: string,
269
+ overrides: {
270
+ priorityFee?: bigint;
271
+ feePayer?: string;
272
+ claimAmount?: bigint;
273
+ feeLimit?: bigint;
274
+ nullifiers?: string[];
275
+ expirationTimestamp?: bigint;
276
+ anchorBlockHeaderHash?: string;
277
+ } = {},
278
+ ): TxMetaData {
279
+ const txHashBigInt = Fr.fromHexString(txHash).toBigInt();
280
+ // Normalize to canonical zero-padded hex so txHashFromBigInt(txHashBigInt) === normalizedTxHash
281
+ const normalizedTxHash = txHashFromBigInt(txHashBigInt);
282
+ const expirationTimestamp = overrides.expirationTimestamp ?? 0n;
283
+ return {
284
+ txHash: normalizedTxHash,
285
+ txHashBigInt,
286
+ anchorBlockHeaderHash: overrides.anchorBlockHeaderHash ?? '0x1234',
287
+ priorityFee: overrides.priorityFee ?? 100n,
288
+ feePayer: overrides.feePayer ?? '0xfeepayer',
289
+ claimAmount: overrides.claimAmount ?? 0n,
290
+ feeLimit: overrides.feeLimit ?? 100n,
291
+ nullifiers: overrides.nullifiers ?? [`0x${normalizedTxHash.slice(2)}null1`],
292
+ expirationTimestamp,
293
+ receivedAt: 0,
294
+ estimatedSizeBytes: 0,
295
+ data: stubTxMetaValidationData({ expirationTimestamp }),
296
+ };
297
+ }
@@ -1,7 +1,7 @@
1
1
  import { SlotNumber } from '@aztec/foundation/branded-types';
2
2
  import type { L2BlockId } from '@aztec/stdlib/block';
3
3
 
4
- import { type TxMetaData, type TxState, compareFee, compareTxHash } from './tx_metadata.js';
4
+ import { type TxMetaData, type TxState, compareFee, compareTxHash, txHashFromBigInt } from './tx_metadata.js';
5
5
 
6
6
  /**
7
7
  * Manages in-memory indices for the transaction pool.
@@ -22,8 +22,8 @@ export class TxPoolIndices {
22
22
  #nullifierToTxHash: Map<string, string> = new Map();
23
23
  /** Fee payer to txHashes index (pending txs only) */
24
24
  #feePayerToTxHashes: Map<string, Set<string>> = new Map();
25
- /** Pending txHashes grouped by priority fee */
26
- #pendingByPriority: Map<bigint, Set<string>> = new Map();
25
+ /** Pending txHash bigints grouped by priority fee */
26
+ #pendingByPriority: Map<bigint, Set<bigint>> = new Map();
27
27
  /** Protected transactions: txHash -> slotNumber */
28
28
  #protectedTransactions: Map<string, SlotNumber> = new Map();
29
29
 
@@ -73,17 +73,17 @@ export class TxPoolIndices {
73
73
  * @param order - 'desc' for highest priority first, 'asc' for lowest priority first
74
74
  */
75
75
  *iteratePendingByPriority(order: 'asc' | 'desc', filter?: (hash: string) => boolean): Generator<string> {
76
- // Use compareFee from tx_metadata, swap args for descending order
77
76
  const feeCompareFn = order === 'desc' ? (a: bigint, b: bigint) => compareFee(b, a) : compareFee;
78
- const hashCompareFn = order === 'desc' ? (a: string, b: string) => compareTxHash(b, a) : compareTxHash;
77
+ const hashCompareFn =
78
+ order === 'desc' ? (a: bigint, b: bigint) => compareTxHash(b, a) : (a: bigint, b: bigint) => compareTxHash(a, b);
79
79
 
80
80
  const sortedFees = [...this.#pendingByPriority.keys()].sort(feeCompareFn);
81
81
 
82
82
  for (const fee of sortedFees) {
83
83
  const hashesAtFee = this.#pendingByPriority.get(fee)!;
84
- // Use compareTxHash from tx_metadata, swap args for descending order
85
84
  const sortedHashes = [...hashesAtFee].sort(hashCompareFn);
86
- for (const hash of sortedHashes) {
85
+ for (const hashBigInt of sortedHashes) {
86
+ const hash = txHashFromBigInt(hashBigInt);
87
87
  if (filter === undefined || filter(hash)) {
88
88
  yield hash;
89
89
  }
@@ -265,8 +265,8 @@ export class TxPoolIndices {
265
265
  getPendingTxs(): TxMetaData[] {
266
266
  const result: TxMetaData[] = [];
267
267
  for (const hashSet of this.#pendingByPriority.values()) {
268
- for (const txHash of hashSet) {
269
- const meta = this.#metadata.get(txHash);
268
+ for (const txHashBigInt of hashSet) {
269
+ const meta = this.#metadata.get(txHashFromBigInt(txHashBigInt));
270
270
  if (meta) {
271
271
  result.push(meta);
272
272
  }
@@ -414,7 +414,7 @@ export class TxPoolIndices {
414
414
  prioritySet = new Set();
415
415
  this.#pendingByPriority.set(meta.priorityFee, prioritySet);
416
416
  }
417
- prioritySet.add(meta.txHash);
417
+ prioritySet.add(meta.txHashBigInt);
418
418
  }
419
419
 
420
420
  #removeFromPendingIndices(meta: TxMetaData): void {
@@ -435,7 +435,7 @@ export class TxPoolIndices {
435
435
  // Remove from priority map
436
436
  const hashSet = this.#pendingByPriority.get(meta.priorityFee);
437
437
  if (hashSet) {
438
- hashSet.delete(meta.txHash);
438
+ hashSet.delete(meta.txHashBigInt);
439
439
  if (hashSet.size === 0) {
440
440
  this.#pendingByPriority.delete(meta.priorityFee);
441
441
  }
@@ -58,6 +58,9 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
58
58
  const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : TxHash.fromBigInt(h)));
59
59
  this.emit('txs-removed', { txHashes: hashes });
60
60
  },
61
+ onTxsMined: (txHashes: string[]) => {
62
+ this.#metrics?.transactionsRemoved(txHashes);
63
+ },
61
64
  };
62
65
 
63
66
  // Create the implementation
@@ -74,7 +77,7 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
74
77
  return this.#queue.put(() => this.#impl.addPendingTxs(txs, opts));
75
78
  }
76
79
 
77
- canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored' | 'rejected'> {
80
+ canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
78
81
  return this.#queue.put(() => this.#impl.canAddPendingTx(tx));
79
82
  }
80
83