@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.
- package/dest/bootstrap/bootstrap.d.ts +2 -2
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +1 -1
- package/dest/client/factory.js +4 -4
- package/dest/client/p2p_client.d.ts +13 -16
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +55 -67
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +11 -19
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +6 -13
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +74 -80
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +5 -5
- package/dest/mem_pools/attestation_pool/mocks.d.ts +3 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +3 -3
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +9 -9
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +60 -54
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +7 -7
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +17 -18
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +7 -7
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +48 -47
- package/dest/mocks/index.d.ts +3 -3
- package/dest/mocks/index.d.ts.map +1 -1
- package/dest/mocks/index.js +19 -18
- package/dest/msg_validators/attestation_validator/attestation_validator.js +2 -2
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +2 -2
- package/dest/msg_validators/tx_validator/block_header_validator.js +3 -3
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +7 -7
- package/dest/msg_validators/tx_validator/double_spend_validator.js +3 -3
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +9 -9
- package/dest/services/data_store.d.ts +4 -4
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/data_store.js +7 -7
- package/dest/services/dummy_service.d.ts +7 -0
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +10 -1
- package/dest/services/libp2p/libp2p_service.d.ts +19 -15
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +163 -134
- package/dest/services/peer-manager/metrics.d.ts +12 -0
- package/dest/services/peer-manager/metrics.d.ts.map +1 -0
- package/dest/services/peer-manager/metrics.js +26 -0
- package/dest/services/{peer_manager.d.ts → peer-manager/peer_manager.d.ts} +24 -8
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -0
- package/dest/services/peer-manager/peer_manager.js +395 -0
- package/dest/services/{peer-scoring → peer-manager}/peer_scoring.d.ts +3 -0
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -0
- package/dest/services/peer-manager/peer_scoring.js +84 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +45 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +81 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +61 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +175 -0
- package/dest/services/reqresp/interface.d.ts +17 -4
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +34 -11
- package/dest/services/reqresp/metrics.d.ts +15 -0
- package/dest/services/reqresp/metrics.d.ts.map +1 -0
- package/dest/services/reqresp/metrics.js +42 -0
- package/dest/services/reqresp/protocols/block.d.ts +4 -0
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block.js +9 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts +51 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/goodbye.js +92 -0
- package/dest/services/reqresp/protocols/index.d.ts +9 -0
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/index.js +9 -0
- package/dest/services/reqresp/protocols/ping.d.ts +9 -0
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/ping.js +9 -0
- package/dest/services/reqresp/{handlers.d.ts → protocols/status.d.ts} +1 -7
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/status.js +9 -0
- package/dest/services/reqresp/protocols/tx.d.ts +13 -0
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/tx.js +23 -0
- package/dest/services/reqresp/rate-limiter/index.d.ts.map +1 -0
- package/dest/services/reqresp/{rate_limiter → rate-limiter}/index.js +1 -1
- package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.d.ts +3 -3
- package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.js +4 -4
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -0
- package/dest/services/reqresp/rate-limiter/rate_limits.js +55 -0
- package/dest/services/reqresp/reqresp.d.ts +33 -6
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +414 -249
- package/dest/services/service.d.ts +8 -0
- package/dest/services/service.d.ts.map +1 -1
- package/dest/util.d.ts +6 -2
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +2 -2
- package/package.json +8 -8
- package/src/bootstrap/bootstrap.ts +2 -2
- package/src/client/factory.ts +3 -3
- package/src/client/p2p_client.ts +68 -80
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +14 -22
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +100 -94
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +4 -4
- package/src/mem_pools/attestation_pool/mocks.ts +5 -5
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +84 -73
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +26 -23
- package/src/mem_pools/tx_pool/tx_pool.ts +7 -7
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +50 -47
- package/src/mocks/index.ts +19 -20
- package/src/msg_validators/attestation_validator/attestation_validator.ts +1 -1
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +1 -1
- package/src/msg_validators/tx_validator/block_header_validator.ts +2 -2
- package/src/msg_validators/tx_validator/data_validator.ts +12 -9
- package/src/msg_validators/tx_validator/double_spend_validator.ts +2 -2
- package/src/msg_validators/tx_validator/metadata_validator.ts +8 -8
- package/src/services/data_store.ts +9 -9
- package/src/services/dummy_service.ts +13 -0
- package/src/services/libp2p/libp2p_service.ts +212 -163
- package/src/services/peer-manager/metrics.ts +41 -0
- package/src/services/{peer_manager.ts → peer-manager/peer_manager.ts} +73 -23
- package/src/services/{peer-scoring → peer-manager}/peer_scoring.ts +16 -3
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +94 -0
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +211 -0
- package/src/services/reqresp/interface.ts +39 -16
- package/src/services/reqresp/metrics.ts +57 -0
- package/src/services/reqresp/protocols/block.ts +15 -0
- package/src/services/reqresp/protocols/goodbye.ts +101 -0
- package/src/services/reqresp/protocols/index.ts +8 -0
- package/src/services/reqresp/protocols/ping.ts +8 -0
- package/src/services/reqresp/{handlers.ts → protocols/status.ts} +0 -9
- package/src/services/reqresp/protocols/tx.ts +29 -0
- package/src/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.ts +3 -3
- package/src/services/reqresp/{rate_limiter → rate-limiter}/rate_limits.ts +24 -4
- package/src/services/reqresp/reqresp.ts +231 -26
- package/src/services/service.ts +12 -0
- package/src/util.ts +11 -4
- package/dest/services/peer-scoring/peer_scoring.d.ts.map +0 -1
- package/dest/services/peer-scoring/peer_scoring.js +0 -75
- package/dest/services/peer_manager.d.ts.map +0 -1
- package/dest/services/peer_manager.js +0 -358
- package/dest/services/reqresp/handlers.d.ts.map +0 -1
- package/dest/services/reqresp/handlers.js +0 -17
- package/dest/services/reqresp/rate_limiter/index.d.ts.map +0 -1
- package/dest/services/reqresp/rate_limiter/rate_limits.d.ts.map +0 -1
- package/dest/services/reqresp/rate_limiter/rate_limits.js +0 -35
- /package/dest/services/reqresp/{rate_limiter → rate-limiter}/index.d.ts +0 -0
- /package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limits.d.ts +0 -0
- /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 {
|
|
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:
|
|
17
|
+
#store: AztecAsyncKVStore;
|
|
17
18
|
|
|
18
19
|
/** Our tx pool, stored as a Map, with K: tx hash and V: the transaction. */
|
|
19
|
-
#txs:
|
|
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:
|
|
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:
|
|
26
|
+
#pendingTxPriorityToHash: AztecAsyncMultiMap<string, string>;
|
|
26
27
|
|
|
27
28
|
/** KV store for archived txs. */
|
|
28
|
-
#archive:
|
|
29
|
+
#archive: AztecAsyncKVStore;
|
|
29
30
|
|
|
30
31
|
/** Archived txs map for future lookup. */
|
|
31
|
-
#archivedTxs:
|
|
32
|
+
#archivedTxs: AztecAsyncMap<string, Buffer>;
|
|
32
33
|
|
|
33
34
|
/** Indexes of the archived txs by insertion order. */
|
|
34
|
-
#archivedTxIndices:
|
|
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:
|
|
53
|
-
archive:
|
|
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.
|
|
79
|
+
return this.#store.transactionAsync(async () => {
|
|
79
80
|
for (const hash of txHashes) {
|
|
80
81
|
const key = hash.toString();
|
|
81
|
-
|
|
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
|
-
|
|
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.
|
|
102
|
+
return this.#store.transactionAsync(async () => {
|
|
102
103
|
for (const hash of txHashes) {
|
|
103
104
|
const key = hash.toString();
|
|
104
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
124
|
-
|
|
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
|
-
|
|
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 (
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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.
|
|
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
|
-
|
|
224
|
+
await this.#pendingTxPriorityToHash.deleteValue(fee, key);
|
|
218
225
|
|
|
219
|
-
const isMined = this.#minedTxHashToBlock.
|
|
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
|
-
|
|
231
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
271
|
-
|
|
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 (
|
|
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.
|
|
287
|
+
const txHash = await this.#archivedTxIndices.getAsync(tailIdx);
|
|
276
288
|
if (txHash) {
|
|
277
|
-
|
|
278
|
-
|
|
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 =
|
|
292
|
-
|
|
293
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
73
|
-
|
|
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(
|
|
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
|
}
|