@aztec/p2p 0.71.0 → 0.73.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.
Files changed (153) hide show
  1. package/dest/bootstrap/bootstrap.d.ts +2 -2
  2. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  3. package/dest/bootstrap/bootstrap.js +1 -1
  4. package/dest/client/factory.js +4 -4
  5. package/dest/client/p2p_client.d.ts +13 -16
  6. package/dest/client/p2p_client.d.ts.map +1 -1
  7. package/dest/client/p2p_client.js +55 -67
  8. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  9. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +11 -19
  10. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +6 -13
  11. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
  12. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +74 -80
  13. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  14. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +5 -5
  15. package/dest/mem_pools/attestation_pool/mocks.d.ts +3 -2
  16. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  17. package/dest/mem_pools/attestation_pool/mocks.js +3 -3
  18. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +9 -9
  19. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  20. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +60 -54
  21. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +7 -7
  22. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
  23. package/dest/mem_pools/tx_pool/memory_tx_pool.js +17 -18
  24. package/dest/mem_pools/tx_pool/tx_pool.d.ts +7 -7
  25. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  26. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  27. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +48 -47
  28. package/dest/mocks/index.d.ts +3 -3
  29. package/dest/mocks/index.d.ts.map +1 -1
  30. package/dest/mocks/index.js +19 -18
  31. package/dest/msg_validators/attestation_validator/attestation_validator.js +2 -2
  32. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +2 -2
  33. package/dest/msg_validators/tx_validator/block_header_validator.js +3 -3
  34. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  35. package/dest/msg_validators/tx_validator/data_validator.js +7 -7
  36. package/dest/msg_validators/tx_validator/double_spend_validator.js +3 -3
  37. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  38. package/dest/msg_validators/tx_validator/metadata_validator.js +9 -9
  39. package/dest/services/data_store.d.ts +4 -4
  40. package/dest/services/data_store.d.ts.map +1 -1
  41. package/dest/services/data_store.js +7 -7
  42. package/dest/services/dummy_service.d.ts +7 -0
  43. package/dest/services/dummy_service.d.ts.map +1 -1
  44. package/dest/services/dummy_service.js +10 -1
  45. package/dest/services/libp2p/libp2p_service.d.ts +19 -15
  46. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  47. package/dest/services/libp2p/libp2p_service.js +163 -134
  48. package/dest/services/peer-manager/metrics.d.ts +12 -0
  49. package/dest/services/peer-manager/metrics.d.ts.map +1 -0
  50. package/dest/services/peer-manager/metrics.js +26 -0
  51. package/dest/services/{peer_manager.d.ts → peer-manager/peer_manager.d.ts} +24 -8
  52. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -0
  53. package/dest/services/peer-manager/peer_manager.js +395 -0
  54. package/dest/services/{peer-scoring → peer-manager}/peer_scoring.d.ts +3 -0
  55. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -0
  56. package/dest/services/peer-manager/peer_scoring.js +84 -0
  57. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +45 -0
  58. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -0
  59. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +81 -0
  60. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +61 -0
  61. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -0
  62. package/dest/services/reqresp/connection-sampler/connection_sampler.js +175 -0
  63. package/dest/services/reqresp/interface.d.ts +17 -4
  64. package/dest/services/reqresp/interface.d.ts.map +1 -1
  65. package/dest/services/reqresp/interface.js +34 -11
  66. package/dest/services/reqresp/metrics.d.ts +15 -0
  67. package/dest/services/reqresp/metrics.d.ts.map +1 -0
  68. package/dest/services/reqresp/metrics.js +42 -0
  69. package/dest/services/reqresp/protocols/block.d.ts +4 -0
  70. package/dest/services/reqresp/protocols/block.d.ts.map +1 -0
  71. package/dest/services/reqresp/protocols/block.js +9 -0
  72. package/dest/services/reqresp/protocols/goodbye.d.ts +51 -0
  73. package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -0
  74. package/dest/services/reqresp/protocols/goodbye.js +92 -0
  75. package/dest/services/reqresp/protocols/index.d.ts +9 -0
  76. package/dest/services/reqresp/protocols/index.d.ts.map +1 -0
  77. package/dest/services/reqresp/protocols/index.js +9 -0
  78. package/dest/services/reqresp/protocols/ping.d.ts +9 -0
  79. package/dest/services/reqresp/protocols/ping.d.ts.map +1 -0
  80. package/dest/services/reqresp/protocols/ping.js +9 -0
  81. package/dest/services/reqresp/{handlers.d.ts → protocols/status.d.ts} +1 -7
  82. package/dest/services/reqresp/protocols/status.d.ts.map +1 -0
  83. package/dest/services/reqresp/protocols/status.js +9 -0
  84. package/dest/services/reqresp/protocols/tx.d.ts +13 -0
  85. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -0
  86. package/dest/services/reqresp/protocols/tx.js +23 -0
  87. package/dest/services/reqresp/rate-limiter/index.d.ts.map +1 -0
  88. package/dest/services/reqresp/{rate_limiter → rate-limiter}/index.js +1 -1
  89. package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.d.ts +3 -3
  90. package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.d.ts.map +1 -1
  91. package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.js +4 -4
  92. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -0
  93. package/dest/services/reqresp/rate-limiter/rate_limits.js +55 -0
  94. package/dest/services/reqresp/reqresp.d.ts +33 -6
  95. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  96. package/dest/services/reqresp/reqresp.js +414 -249
  97. package/dest/services/service.d.ts +8 -0
  98. package/dest/services/service.d.ts.map +1 -1
  99. package/dest/util.d.ts +6 -2
  100. package/dest/util.d.ts.map +1 -1
  101. package/dest/util.js +2 -2
  102. package/package.json +8 -8
  103. package/src/bootstrap/bootstrap.ts +2 -2
  104. package/src/client/factory.ts +3 -3
  105. package/src/client/p2p_client.ts +68 -80
  106. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +14 -22
  107. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +100 -94
  108. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +4 -4
  109. package/src/mem_pools/attestation_pool/mocks.ts +5 -5
  110. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +84 -73
  111. package/src/mem_pools/tx_pool/memory_tx_pool.ts +26 -23
  112. package/src/mem_pools/tx_pool/tx_pool.ts +7 -7
  113. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +50 -47
  114. package/src/mocks/index.ts +19 -20
  115. package/src/msg_validators/attestation_validator/attestation_validator.ts +1 -1
  116. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +1 -1
  117. package/src/msg_validators/tx_validator/block_header_validator.ts +2 -2
  118. package/src/msg_validators/tx_validator/data_validator.ts +12 -9
  119. package/src/msg_validators/tx_validator/double_spend_validator.ts +2 -2
  120. package/src/msg_validators/tx_validator/metadata_validator.ts +8 -8
  121. package/src/services/data_store.ts +9 -9
  122. package/src/services/dummy_service.ts +13 -0
  123. package/src/services/libp2p/libp2p_service.ts +212 -163
  124. package/src/services/peer-manager/metrics.ts +41 -0
  125. package/src/services/{peer_manager.ts → peer-manager/peer_manager.ts} +73 -23
  126. package/src/services/{peer-scoring → peer-manager}/peer_scoring.ts +16 -3
  127. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +94 -0
  128. package/src/services/reqresp/connection-sampler/connection_sampler.ts +211 -0
  129. package/src/services/reqresp/interface.ts +39 -16
  130. package/src/services/reqresp/metrics.ts +57 -0
  131. package/src/services/reqresp/protocols/block.ts +15 -0
  132. package/src/services/reqresp/protocols/goodbye.ts +101 -0
  133. package/src/services/reqresp/protocols/index.ts +8 -0
  134. package/src/services/reqresp/protocols/ping.ts +8 -0
  135. package/src/services/reqresp/{handlers.ts → protocols/status.ts} +0 -9
  136. package/src/services/reqresp/protocols/tx.ts +29 -0
  137. package/src/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.ts +3 -3
  138. package/src/services/reqresp/{rate_limiter → rate-limiter}/rate_limits.ts +24 -4
  139. package/src/services/reqresp/reqresp.ts +231 -26
  140. package/src/services/service.ts +12 -0
  141. package/src/util.ts +11 -4
  142. package/dest/services/peer-scoring/peer_scoring.d.ts.map +0 -1
  143. package/dest/services/peer-scoring/peer_scoring.js +0 -75
  144. package/dest/services/peer_manager.d.ts.map +0 -1
  145. package/dest/services/peer_manager.js +0 -358
  146. package/dest/services/reqresp/handlers.d.ts.map +0 -1
  147. package/dest/services/reqresp/handlers.js +0 -17
  148. package/dest/services/reqresp/rate_limiter/index.d.ts.map +0 -1
  149. package/dest/services/reqresp/rate_limiter/rate_limits.d.ts.map +0 -1
  150. package/dest/services/reqresp/rate_limiter/rate_limits.js +0 -35
  151. /package/dest/services/reqresp/{rate_limiter → rate-limiter}/index.d.ts +0 -0
  152. /package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limits.d.ts +0 -0
  153. /package/src/services/reqresp/{rate_limiter → rate-limiter}/index.ts +0 -0
@@ -1,8 +1,9 @@
1
1
  import { Tx, TxHash } from '@aztec/circuit-types';
2
2
  import { type TxAddedToPoolStats } from '@aztec/circuit-types/stats';
3
3
  import { ClientIvcProof } from '@aztec/circuits.js';
4
+ import { toArray } from '@aztec/foundation/iterable';
4
5
  import { type Logger, createLogger } from '@aztec/foundation/log';
5
- import { type AztecKVStore, type AztecMap, type AztecMultiMap } from '@aztec/kv-store';
6
+ import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncMultiMap } from '@aztec/kv-store';
6
7
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
7
8
 
8
9
  import { PoolInstrumentation, PoolName } from '../instrumentation.js';
@@ -13,25 +14,25 @@ import { type TxPool } from './tx_pool.js';
13
14
  * KV implementation of the Transaction Pool.
14
15
  */
15
16
  export class AztecKVTxPool implements TxPool {
16
- #store: AztecKVStore;
17
+ #store: AztecAsyncKVStore;
17
18
 
18
19
  /** Our tx pool, stored as a Map, with K: tx hash and V: the transaction. */
19
- #txs: AztecMap<string, Buffer>;
20
+ #txs: AztecAsyncMap<string, Buffer>;
20
21
 
21
22
  /** Index from tx hash to the block number in which they were mined, filtered by mined txs. */
22
- #minedTxHashToBlock: AztecMap<string, number>;
23
+ #minedTxHashToBlock: AztecAsyncMap<string, number>;
23
24
 
24
25
  /** Index from tx priority (stored as hex) to its tx hash, filtered by pending txs. */
25
- #pendingTxPriorityToHash: AztecMultiMap<string, string>;
26
+ #pendingTxPriorityToHash: AztecAsyncMultiMap<string, string>;
26
27
 
27
28
  /** KV store for archived txs. */
28
- #archive: AztecKVStore;
29
+ #archive: AztecAsyncKVStore;
29
30
 
30
31
  /** Archived txs map for future lookup. */
31
- #archivedTxs: AztecMap<string, Buffer>;
32
+ #archivedTxs: AztecAsyncMap<string, Buffer>;
32
33
 
33
34
  /** Indexes of the archived txs by insertion order. */
34
- #archivedTxIndices: AztecMap<number, string>;
35
+ #archivedTxIndices: AztecAsyncMap<number, string>;
35
36
 
36
37
  /** Number of txs to archive. */
37
38
  #archivedTxLimit: number;
@@ -49,8 +50,8 @@ export class AztecKVTxPool implements TxPool {
49
50
  * @param log - A logger.
50
51
  */
51
52
  constructor(
52
- store: AztecKVStore,
53
- archive: AztecKVStore,
53
+ store: AztecAsyncKVStore,
54
+ archive: AztecAsyncKVStore,
54
55
  telemetry: TelemetryClient = getTelemetryClient(),
55
56
  archivedTxLimit: number = 0,
56
57
  log = createLogger('p2p:tx_pool'),
@@ -75,16 +76,16 @@ export class AztecKVTxPool implements TxPool {
75
76
  }
76
77
 
77
78
  let deletedPending = 0;
78
- return this.#store.transaction(() => {
79
+ return this.#store.transactionAsync(async () => {
79
80
  for (const hash of txHashes) {
80
81
  const key = hash.toString();
81
- void this.#minedTxHashToBlock.set(key, blockNumber);
82
+ await this.#minedTxHashToBlock.set(key, blockNumber);
82
83
 
83
- const tx = this.getTxByHash(hash);
84
+ const tx = await this.getTxByHash(hash);
84
85
  if (tx) {
85
86
  deletedPending++;
86
87
  const fee = getPendingTxPriority(tx);
87
- void this.#pendingTxPriorityToHash.deleteValue(fee, key);
88
+ await this.#pendingTxPriorityToHash.deleteValue(fee, key);
88
89
  }
89
90
  }
90
91
  this.#metrics.recordAddedObjects(txHashes.length, 'mined');
@@ -98,14 +99,14 @@ export class AztecKVTxPool implements TxPool {
98
99
  }
99
100
 
100
101
  let markedAsPending = 0;
101
- return this.#store.transaction(() => {
102
+ return this.#store.transactionAsync(async () => {
102
103
  for (const hash of txHashes) {
103
104
  const key = hash.toString();
104
- void this.#minedTxHashToBlock.delete(key);
105
+ await this.#minedTxHashToBlock.delete(key);
105
106
 
106
- const tx = this.getTxByHash(hash);
107
+ const tx = await this.getTxByHash(hash);
107
108
  if (tx) {
108
- void this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), key);
109
+ await this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), key);
109
110
  markedAsPending++;
110
111
  }
111
112
  }
@@ -115,22 +116,23 @@ export class AztecKVTxPool implements TxPool {
115
116
  });
116
117
  }
117
118
 
118
- public getPendingTxHashes(): TxHash[] {
119
- return Array.from(this.#pendingTxPriorityToHash.values({ reverse: true })).map(x => TxHash.fromString(x));
119
+ public async getPendingTxHashes(): Promise<TxHash[]> {
120
+ const vals = await toArray(this.#pendingTxPriorityToHash.valuesAsync({ reverse: true }));
121
+ return vals.map(x => TxHash.fromString(x));
120
122
  }
121
123
 
122
- public getMinedTxHashes(): [TxHash, number][] {
123
- return Array.from(this.#minedTxHashToBlock.entries()).map(([txHash, blockNumber]) => [
124
- TxHash.fromString(txHash),
125
- blockNumber,
126
- ]);
124
+ public async getMinedTxHashes(): Promise<[TxHash, number][]> {
125
+ const vals = await toArray(this.#minedTxHashToBlock.entriesAsync());
126
+ return vals.map(([txHash, blockNumber]) => [TxHash.fromString(txHash), blockNumber]);
127
127
  }
128
128
 
129
- public getTxStatus(txHash: TxHash): 'pending' | 'mined' | undefined {
129
+ public async getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
130
130
  const key = txHash.toString();
131
- if (this.#minedTxHashToBlock.has(key)) {
131
+ const [isMined, isKnown] = await Promise.all([this.#minedTxHashToBlock.hasAsync(key), this.#txs.hasAsync(key)]);
132
+
133
+ if (isMined) {
132
134
  return 'mined';
133
- } else if (this.#txs.has(key)) {
135
+ } else if (isKnown) {
134
136
  return 'pending';
135
137
  } else {
136
138
  return undefined;
@@ -142,8 +144,8 @@ export class AztecKVTxPool implements TxPool {
142
144
  * @param txHash - The generated tx hash.
143
145
  * @returns The transaction, if found, 'undefined' otherwise.
144
146
  */
145
- public getTxByHash(txHash: TxHash): Tx | undefined {
146
- const buffer = this.#txs.get(txHash.toString());
147
+ public async getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
148
+ const buffer = await this.#txs.getAsync(txHash.toString());
147
149
  if (buffer) {
148
150
  const tx = Tx.fromBuffer(buffer);
149
151
  tx.setTxHash(txHash);
@@ -157,8 +159,8 @@ export class AztecKVTxPool implements TxPool {
157
159
  * @param txHash - The tx hash.
158
160
  * @returns The transaction metadata, if found, 'undefined' otherwise.
159
161
  */
160
- public getArchivedTxByHash(txHash: TxHash): Tx | undefined {
161
- const buffer = this.#archivedTxs.get(txHash.toString());
162
+ public async getArchivedTxByHash(txHash: TxHash): Promise<Tx | undefined> {
163
+ const buffer = await this.#archivedTxs.getAsync(txHash.toString());
162
164
  if (buffer) {
163
165
  const tx = Tx.fromBuffer(buffer);
164
166
  tx.setTxHash(txHash);
@@ -172,26 +174,31 @@ export class AztecKVTxPool implements TxPool {
172
174
  * @param txs - An array of txs to be added to the pool.
173
175
  * @returns Empty promise.
174
176
  */
175
- public addTxs(txs: Tx[]): Promise<void> {
176
- return this.#store.transaction(() => {
177
+ public async addTxs(txs: Tx[]): Promise<void> {
178
+ const hashesAndStats = await Promise.all(
179
+ txs.map(async tx => ({ txHash: await tx.getTxHash(), txStats: await tx.getStats() })),
180
+ );
181
+ await this.#store.transactionAsync(async () => {
177
182
  let pendingCount = 0;
178
- for (const tx of txs) {
179
- const txHash = tx.getTxHash();
180
- this.#log.verbose(`Adding tx ${txHash.toString()} to pool`, {
181
- eventName: 'tx-added-to-pool',
182
- ...tx.getStats(),
183
- } satisfies TxAddedToPoolStats);
184
-
185
- const key = txHash.toString();
186
- void this.#txs.set(key, tx.toBuffer());
187
-
188
- if (!this.#minedTxHashToBlock.has(key)) {
189
- pendingCount++;
190
- // REFACTOR: Use an lmdb conditional write to avoid race conditions with this write tx
191
- void this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), key);
192
- this.#metrics.recordSize(tx);
193
- }
194
- }
183
+ await Promise.all(
184
+ txs.map(async (tx, i) => {
185
+ const { txHash, txStats } = hashesAndStats[i];
186
+ this.#log.verbose(`Adding tx ${txHash.toString()} to pool`, {
187
+ eventName: 'tx-added-to-pool',
188
+ ...txStats,
189
+ } satisfies TxAddedToPoolStats);
190
+
191
+ const key = txHash.toString();
192
+ await this.#txs.set(key, tx.toBuffer());
193
+
194
+ if (!(await this.#minedTxHashToBlock.hasAsync(key))) {
195
+ pendingCount++;
196
+ // REFACTOR: Use an lmdb conditional write to avoid race conditions with this write tx
197
+ await this.#pendingTxPriorityToHash.set(getPendingTxPriority(tx), key);
198
+ this.#metrics.recordSize(tx);
199
+ }
200
+ }),
201
+ );
195
202
 
196
203
  this.#metrics.recordAddedObjects(pendingCount, 'pending');
197
204
  });
@@ -207,16 +214,16 @@ export class AztecKVTxPool implements TxPool {
207
214
  let minedDeleted = 0;
208
215
 
209
216
  const deletedTxs: Tx[] = [];
210
- const poolDbTx = this.#store.transaction(() => {
217
+ const poolDbTx = this.#store.transactionAsync(async () => {
211
218
  for (const hash of txHashes) {
212
219
  const key = hash.toString();
213
- const tx = this.getTxByHash(hash);
220
+ const tx = await this.getTxByHash(hash);
214
221
 
215
222
  if (tx) {
216
223
  const fee = getPendingTxPriority(tx);
217
- void this.#pendingTxPriorityToHash.deleteValue(fee, key);
224
+ await this.#pendingTxPriorityToHash.deleteValue(fee, key);
218
225
 
219
- const isMined = this.#minedTxHashToBlock.has(key);
226
+ const isMined = await this.#minedTxHashToBlock.hasAsync(key);
220
227
  if (isMined) {
221
228
  minedDeleted++;
222
229
  } else {
@@ -227,8 +234,8 @@ export class AztecKVTxPool implements TxPool {
227
234
  deletedTxs.push(tx);
228
235
  }
229
236
 
230
- void this.#txs.delete(key);
231
- void this.#minedTxHashToBlock.delete(key);
237
+ await this.#txs.delete(key);
238
+ await this.#minedTxHashToBlock.delete(key);
232
239
  }
233
240
  }
234
241
 
@@ -243,8 +250,9 @@ export class AztecKVTxPool implements TxPool {
243
250
  * Gets all the transactions stored in the pool.
244
251
  * @returns Array of tx objects in the order they were added to the pool.
245
252
  */
246
- public getAllTxs(): Tx[] {
247
- return Array.from(this.#txs.entries()).map(([hash, buffer]) => {
253
+ public async getAllTxs(): Promise<Tx[]> {
254
+ const vals = await toArray(this.#txs.entriesAsync());
255
+ return vals.map(([hash, buffer]) => {
248
256
  const tx = Tx.fromBuffer(buffer);
249
257
  tx.setTxHash(TxHash.fromString(hash));
250
258
  return tx;
@@ -255,8 +263,9 @@ export class AztecKVTxPool implements TxPool {
255
263
  * Gets the hashes of all transactions currently in the tx pool.
256
264
  * @returns An array of transaction hashes found in the tx pool.
257
265
  */
258
- public getAllTxHashes(): TxHash[] {
259
- return Array.from(this.#txs.keys()).map(x => TxHash.fromString(x));
266
+ public async getAllTxHashes(): Promise<TxHash[]> {
267
+ const vals = await toArray(this.#txs.keysAsync());
268
+ return vals.map(x => TxHash.fromString(x));
260
269
  }
261
270
 
262
271
  /**
@@ -264,18 +273,21 @@ export class AztecKVTxPool implements TxPool {
264
273
  * @param txs - The list of transactions to archive.
265
274
  * @returns Empty promise.
266
275
  */
267
- private archiveTxs(txs: Tx[]): Promise<void> {
268
- return this.#archive.transaction(() => {
276
+ private async archiveTxs(txs: Tx[]): Promise<void> {
277
+ const txHashes = await Promise.all(txs.map(tx => tx.getTxHash()));
278
+ await this.#archive.transactionAsync(async () => {
269
279
  // calcualte the head and tail indices of the archived txs by insertion order.
270
- let headIdx = (this.#archivedTxIndices.entries({ limit: 1, reverse: true }).next().value?.[0] ?? -1) + 1;
271
- let tailIdx = this.#archivedTxIndices.entries({ limit: 1 }).next().value?.[0] ?? 0;
280
+ let headIdx =
281
+ ((await this.#archivedTxIndices.entriesAsync({ limit: 1, reverse: true }).next()).value?.[0] ?? -1) + 1;
282
+ let tailIdx = (await this.#archivedTxIndices.entriesAsync({ limit: 1 }).next()).value?.[0] ?? 0;
272
283
 
273
- for (const tx of txs) {
284
+ for (let i = 0; i < txs.length; i++) {
285
+ const tx = txs[i];
274
286
  while (headIdx - tailIdx >= this.#archivedTxLimit) {
275
- const txHash = this.#archivedTxIndices.get(tailIdx);
287
+ const txHash = await this.#archivedTxIndices.getAsync(tailIdx);
276
288
  if (txHash) {
277
- void this.#archivedTxs.delete(txHash);
278
- void this.#archivedTxIndices.delete(tailIdx);
289
+ await this.#archivedTxs.delete(txHash);
290
+ await this.#archivedTxIndices.delete(tailIdx);
279
291
  }
280
292
  tailIdx++;
281
293
  }
@@ -283,14 +295,13 @@ export class AztecKVTxPool implements TxPool {
283
295
  const archivedTx: Tx = new Tx(
284
296
  tx.data,
285
297
  ClientIvcProof.empty(),
286
- tx.unencryptedLogs,
287
298
  tx.contractClassLogs,
288
299
  tx.enqueuedPublicFunctionCalls,
289
300
  tx.publicTeardownFunctionCall,
290
301
  );
291
- const txHash = tx.getTxHash().toString();
292
- void this.#archivedTxs.set(txHash, archivedTx.toBuffer());
293
- void this.#archivedTxIndices.set(headIdx, txHash);
302
+ const txHash = txHashes[i].toString();
303
+ await this.#archivedTxs.set(txHash, archivedTx.toBuffer());
304
+ await this.#archivedTxIndices.set(headIdx, txHash);
294
305
  headIdx++;
295
306
  }
296
307
  });
@@ -68,26 +68,29 @@ export class InMemoryTxPool implements TxPool {
68
68
  return Promise.resolve();
69
69
  }
70
70
 
71
- public getPendingTxHashes(): TxHash[] {
72
- return this.getAllTxs()
73
- .sort((tx1, tx2) => -getPendingTxPriority(tx1).localeCompare(getPendingTxPriority(tx2)))
74
- .map(tx => tx.getTxHash())
75
- .filter(txHash => this.pendingTxs.has(txHash.toBigInt()));
71
+ public async getPendingTxHashes(): Promise<TxHash[]> {
72
+ const txs = (await this.getAllTxs()).sort(
73
+ (tx1, tx2) => -getPendingTxPriority(tx1).localeCompare(getPendingTxPriority(tx2)),
74
+ );
75
+ const txHashes = await Promise.all(txs.map(tx => tx.getTxHash()));
76
+ return txHashes.filter(txHash => this.pendingTxs.has(txHash.toBigInt()));
76
77
  }
77
78
 
78
- public getMinedTxHashes(): [TxHash, number][] {
79
- return Array.from(this.minedTxs.entries()).map(([txHash, blockNumber]) => [TxHash.fromBigInt(txHash), blockNumber]);
79
+ public getMinedTxHashes(): Promise<[TxHash, number][]> {
80
+ return Promise.resolve(
81
+ Array.from(this.minedTxs.entries()).map(([txHash, blockNumber]) => [TxHash.fromBigInt(txHash), blockNumber]),
82
+ );
80
83
  }
81
84
 
82
- public getTxStatus(txHash: TxHash): 'pending' | 'mined' | undefined {
85
+ public getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
83
86
  const key = txHash.toBigInt();
84
87
  if (this.pendingTxs.has(key)) {
85
- return 'pending';
88
+ return Promise.resolve('pending');
86
89
  }
87
90
  if (this.minedTxs.has(key)) {
88
- return 'mined';
91
+ return Promise.resolve('mined');
89
92
  }
90
- return undefined;
93
+ return Promise.resolve(undefined);
91
94
  }
92
95
 
93
96
  /**
@@ -95,13 +98,13 @@ export class InMemoryTxPool implements TxPool {
95
98
  * @param txHash - The generated tx hash.
96
99
  * @returns The transaction, if found, 'undefined' otherwise.
97
100
  */
98
- public getTxByHash(txHash: TxHash): Tx | undefined {
101
+ public getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
99
102
  const result = this.txs.get(txHash.toBigInt());
100
- return result === undefined ? undefined : Tx.clone(result);
103
+ return Promise.resolve(result === undefined ? undefined : Tx.clone(result));
101
104
  }
102
105
 
103
- public getArchivedTxByHash(): Tx | undefined {
104
- return undefined;
106
+ public getArchivedTxByHash(): Promise<Tx | undefined> {
107
+ return Promise.resolve(undefined);
105
108
  }
106
109
 
107
110
  /**
@@ -109,13 +112,13 @@ export class InMemoryTxPool implements TxPool {
109
112
  * @param txs - An array of txs to be added to the pool.
110
113
  * @returns Empty promise.
111
114
  */
112
- public addTxs(txs: Tx[]): Promise<void> {
115
+ public async addTxs(txs: Tx[]): Promise<void> {
113
116
  let pending = 0;
114
117
  for (const tx of txs) {
115
- const txHash = tx.getTxHash();
118
+ const txHash = await tx.getTxHash();
116
119
  this.log.verbose(`Adding tx ${txHash.toString()} to pool`, {
117
120
  eventName: 'tx-added-to-pool',
118
- ...tx.getStats(),
121
+ ...(await tx.getStats()),
119
122
  } satisfies TxAddedToPoolStats);
120
123
 
121
124
  const key = txHash.toBigInt();
@@ -128,7 +131,7 @@ export class InMemoryTxPool implements TxPool {
128
131
  }
129
132
 
130
133
  this.metrics.recordAddedObjects(pending, 'pending');
131
- return Promise.resolve();
134
+ return;
132
135
  }
133
136
 
134
137
  /**
@@ -157,15 +160,15 @@ export class InMemoryTxPool implements TxPool {
157
160
  * Gets all the transactions stored in the pool.
158
161
  * @returns Array of tx objects in the order they were added to the pool.
159
162
  */
160
- public getAllTxs(): Tx[] {
161
- return Array.from(this.txs.values()).map(x => Tx.clone(x));
163
+ public getAllTxs(): Promise<Tx[]> {
164
+ return Promise.resolve(Array.from(this.txs.values()).map(x => Tx.clone(x)));
162
165
  }
163
166
 
164
167
  /**
165
168
  * Gets the hashes of all transactions currently in the tx pool.
166
169
  * @returns An array of transaction hashes found in the tx pool.
167
170
  */
168
- public getAllTxHashes(): TxHash[] {
169
- return Array.from(this.txs.keys()).map(x => TxHash.fromBigInt(x));
171
+ public getAllTxHashes(): Promise<TxHash[]> {
172
+ return Promise.resolve(Array.from(this.txs.keys()).map(x => TxHash.fromBigInt(x)));
170
173
  }
171
174
  }
@@ -15,14 +15,14 @@ export interface TxPool {
15
15
  * @param txHash - The hash of the transaction, used as an ID.
16
16
  * @returns The transaction, if found, 'undefined' otherwise.
17
17
  */
18
- getTxByHash(txHash: TxHash): Tx | undefined;
18
+ getTxByHash(txHash: TxHash): Promise<Tx | undefined>;
19
19
 
20
20
  /**
21
21
  * Checks if an archived transaction exists in the pool and returns it.
22
22
  * @param txHash - The hash of the transaction, used as an ID.
23
23
  * @returns The transaction, if found, 'undefined' otherwise.
24
24
  */
25
- getArchivedTxByHash(txHash: TxHash): Tx | undefined;
25
+ getArchivedTxByHash(txHash: TxHash): Promise<Tx | undefined>;
26
26
 
27
27
  /**
28
28
  * Marks the set of txs as mined, as opposed to pending.
@@ -47,30 +47,30 @@ export interface TxPool {
47
47
  * Gets all transactions currently in the tx pool.
48
48
  * @returns An array of transaction objects found in the tx pool.
49
49
  */
50
- getAllTxs(): Tx[];
50
+ getAllTxs(): Promise<Tx[]>;
51
51
 
52
52
  /**
53
53
  * Gets the hashes of all transactions currently in the tx pool.
54
54
  * @returns An array of transaction hashes found in the tx pool.
55
55
  */
56
- getAllTxHashes(): TxHash[];
56
+ getAllTxHashes(): Promise<TxHash[]>;
57
57
 
58
58
  /**
59
59
  * Gets the hashes of pending transactions currently in the tx pool sorted by priority (see getPendingTxPriority).
60
60
  * @returns An array of pending transaction hashes found in the tx pool.
61
61
  */
62
- getPendingTxHashes(): TxHash[];
62
+ getPendingTxHashes(): Promise<TxHash[]>;
63
63
 
64
64
  /**
65
65
  * Gets the hashes of mined transactions currently in the tx pool.
66
66
  * @returns An array of mined transaction hashes found in the tx pool.
67
67
  */
68
- getMinedTxHashes(): [tx: TxHash, blockNumber: number][];
68
+ getMinedTxHashes(): Promise<[tx: TxHash, blockNumber: number][]>;
69
69
 
70
70
  /**
71
71
  * Returns whether the given tx hash is flagged as pending or mined.
72
72
  * @param txHash - Hash of the tx to query.
73
73
  * @returns Pending or mined depending on its status, or undefined if not found.
74
74
  */
75
- getTxStatus(txHash: TxHash): 'pending' | 'mined' | undefined;
75
+ getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined>;
76
76
  }
@@ -16,94 +16,97 @@ export function describeTxPool(getTxPool: () => TxPool) {
16
16
  });
17
17
 
18
18
  it('Adds txs to the pool as pending', async () => {
19
- const tx1 = mockTx();
19
+ const tx1 = await mockTx();
20
20
 
21
21
  await pool.addTxs([tx1]);
22
- const poolTx = pool.getTxByHash(tx1.getTxHash());
23
- expect(poolTx!.getTxHash()).toEqual(tx1.getTxHash());
24
- expect(pool.getTxStatus(tx1.getTxHash())).toEqual('pending');
25
- expect(pool.getPendingTxHashes()).toEqual([tx1.getTxHash()]);
22
+ const poolTx = await pool.getTxByHash(await tx1.getTxHash());
23
+ expect(await poolTx!.getTxHash()).toEqual(await tx1.getTxHash());
24
+ await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toEqual('pending');
25
+ await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx1.getTxHash()]);
26
26
  });
27
27
 
28
28
  it('Removes txs from the pool', async () => {
29
- const tx1 = mockTx();
29
+ const tx1 = await mockTx();
30
30
 
31
31
  await pool.addTxs([tx1]);
32
- await pool.deleteTxs([tx1.getTxHash()]);
32
+ await pool.deleteTxs([await tx1.getTxHash()]);
33
33
 
34
- expect(pool.getTxByHash(tx1.getTxHash())).toBeFalsy();
35
- expect(pool.getTxStatus(tx1.getTxHash())).toBeUndefined();
34
+ await expect(pool.getTxByHash(await tx1.getTxHash())).resolves.toBeFalsy();
35
+ await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toBeUndefined();
36
36
  });
37
37
 
38
38
  it('Marks txs as mined', async () => {
39
- const tx1 = mockTx(1);
40
- const tx2 = mockTx(2);
39
+ const tx1 = await mockTx(1);
40
+ const tx2 = await mockTx(2);
41
41
 
42
42
  await pool.addTxs([tx1, tx2]);
43
- await pool.markAsMined([tx1.getTxHash()], 1);
43
+ await pool.markAsMined([await tx1.getTxHash()], 1);
44
44
 
45
- expect(pool.getTxByHash(tx1.getTxHash())).toEqual(tx1);
46
- expect(pool.getTxStatus(tx1.getTxHash())).toEqual('mined');
47
- expect(pool.getMinedTxHashes()).toEqual([[tx1.getTxHash(), 1]]);
48
- expect(pool.getPendingTxHashes()).toEqual([tx2.getTxHash()]);
45
+ await expect(pool.getTxByHash(await tx1.getTxHash())).resolves.toEqual(tx1);
46
+ await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toEqual('mined');
47
+ await expect(pool.getMinedTxHashes()).resolves.toEqual([[await tx1.getTxHash(), 1]]);
48
+ await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx2.getTxHash()]);
49
49
  });
50
50
 
51
51
  it('Marks txs as pending after being mined', async () => {
52
- const tx1 = mockTx(1);
53
- const tx2 = mockTx(2);
52
+ const tx1 = await mockTx(1);
53
+ const tx2 = await mockTx(2);
54
54
 
55
55
  await pool.addTxs([tx1, tx2]);
56
- await pool.markAsMined([tx1.getTxHash()], 1);
56
+ await pool.markAsMined([await tx1.getTxHash()], 1);
57
57
 
58
- await pool.markMinedAsPending([tx1.getTxHash()]);
59
- expect(pool.getMinedTxHashes()).toEqual([]);
60
- const pending = pool.getPendingTxHashes();
58
+ await pool.markMinedAsPending([await tx1.getTxHash()]);
59
+ await expect(pool.getMinedTxHashes()).resolves.toEqual([]);
60
+ const pending = await pool.getPendingTxHashes();
61
61
  expect(pending).toHaveLength(2);
62
- expect(pending).toEqual(expect.arrayContaining([tx1.getTxHash(), tx2.getTxHash()]));
62
+ expect(pending).toEqual(expect.arrayContaining([await tx1.getTxHash(), await tx2.getTxHash()]));
63
63
  });
64
64
 
65
65
  it('Only marks txs as pending if they are known', async () => {
66
- const tx1 = mockTx(1);
66
+ const tx1 = await mockTx(1);
67
67
  // simulate a situation where not all peers have all the txs
68
- const someTxHashThatThisPeerDidNotSee = mockTx(2).getTxHash();
68
+ const tx2 = await mockTx(2);
69
+ const someTxHashThatThisPeerDidNotSee = await tx2.getTxHash();
69
70
  await pool.addTxs([tx1]);
70
71
  // this peer knows that tx2 was mined, but it does not have the tx object
71
- await pool.markAsMined([tx1.getTxHash(), someTxHashThatThisPeerDidNotSee], 1);
72
- expect(new Set(pool.getMinedTxHashes())).toEqual(
73
- new Set([
74
- [tx1.getTxHash(), 1],
72
+ await pool.markAsMined([await tx1.getTxHash(), someTxHashThatThisPeerDidNotSee], 1);
73
+ expect(await pool.getMinedTxHashes()).toEqual(
74
+ expect.arrayContaining([
75
+ [await tx1.getTxHash(), 1],
75
76
  [someTxHashThatThisPeerDidNotSee, 1],
76
77
  ]),
77
78
  );
78
79
 
79
80
  // reorg: both txs should now become available again
80
- await pool.markMinedAsPending([tx1.getTxHash(), someTxHashThatThisPeerDidNotSee]);
81
- expect(pool.getMinedTxHashes()).toEqual([]);
82
- expect(pool.getPendingTxHashes()).toEqual([tx1.getTxHash()]); // tx2 is not in the pool
81
+ await pool.markMinedAsPending([await tx1.getTxHash(), someTxHashThatThisPeerDidNotSee]);
82
+ await expect(pool.getMinedTxHashes()).resolves.toEqual([]);
83
+ await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx1.getTxHash()]); // tx2 is not in the pool
83
84
  });
84
85
 
85
86
  it('Returns all transactions in the pool', async () => {
86
- const tx1 = mockTx(1);
87
- const tx2 = mockTx(2);
88
- const tx3 = mockTx(3);
87
+ const tx1 = await mockTx(1);
88
+ const tx2 = await mockTx(2);
89
+ const tx3 = await mockTx(3);
89
90
 
90
91
  await pool.addTxs([tx1, tx2, tx3]);
91
92
 
92
- const poolTxs = pool.getAllTxs();
93
+ const poolTxs = await pool.getAllTxs();
93
94
  expect(poolTxs).toHaveLength(3);
94
95
  expect(poolTxs).toEqual(expect.arrayContaining([tx1, tx2, tx3]));
95
96
  });
96
97
 
97
98
  it('Returns all txHashes in the pool', async () => {
98
- const tx1 = mockTx(1);
99
- const tx2 = mockTx(2);
100
- const tx3 = mockTx(3);
99
+ const tx1 = await mockTx(1);
100
+ const tx2 = await mockTx(2);
101
+ const tx3 = await mockTx(3);
101
102
 
102
103
  await pool.addTxs([tx1, tx2, tx3]);
103
104
 
104
- const poolTxHashes = pool.getAllTxHashes();
105
+ const poolTxHashes = await pool.getAllTxHashes();
105
106
  expect(poolTxHashes).toHaveLength(3);
106
- expect(poolTxHashes).toEqual(expect.arrayContaining([tx1.getTxHash(), tx2.getTxHash(), tx3.getTxHash()]));
107
+ expect(poolTxHashes).toEqual(
108
+ expect.arrayContaining([await tx1.getTxHash(), await tx2.getTxHash(), await tx3.getTxHash()]),
109
+ );
107
110
  });
108
111
 
109
112
  it('Returns pending tx hashes sorted by priority', async () => {
@@ -112,15 +115,15 @@ export function describeTxPool(getTxPool: () => TxPool) {
112
115
  return tx;
113
116
  };
114
117
 
115
- const tx1 = withPriorityFee(mockTx(0), 1000);
116
- const tx2 = withPriorityFee(mockTx(1), 100);
117
- const tx3 = withPriorityFee(mockTx(2), 200);
118
- const tx4 = withPriorityFee(mockTx(3), 3000);
118
+ const tx1 = withPriorityFee(await mockTx(0), 1000);
119
+ const tx2 = withPriorityFee(await mockTx(1), 100);
120
+ const tx3 = withPriorityFee(await mockTx(2), 200);
121
+ const tx4 = withPriorityFee(await mockTx(3), 3000);
119
122
 
120
123
  await pool.addTxs([tx1, tx2, tx3, tx4]);
121
124
 
122
- const poolTxHashes = pool.getPendingTxHashes();
125
+ const poolTxHashes = await pool.getPendingTxHashes();
123
126
  expect(poolTxHashes).toHaveLength(4);
124
- expect(poolTxHashes).toEqual([tx4, tx1, tx3, tx2].map(tx => tx.getTxHash()));
127
+ expect(poolTxHashes).toEqual(await Promise.all([tx4, tx1, tx3, tx2].map(tx => tx.getTxHash())));
125
128
  });
126
129
  }