@aztec/p2p 0.23.0 → 0.26.1

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.
@@ -0,0 +1,99 @@
1
+ import { Tx, TxHash } from '@aztec/circuit-types';
2
+ import { TxAddedToPoolStats } from '@aztec/circuit-types/stats';
3
+ import { Logger, createDebugLogger } from '@aztec/foundation/log';
4
+ import { AztecKVStore, AztecMap } from '@aztec/kv-store';
5
+
6
+ import { TxPool } from './tx_pool.js';
7
+
8
+ /**
9
+ * In-memory implementation of the Transaction Pool.
10
+ */
11
+ export class AztecKVTxPool implements TxPool {
12
+ #store: AztecKVStore;
13
+
14
+ /**
15
+ * Our tx pool, stored as a Map in-memory, with K: tx hash and V: the transaction.
16
+ */
17
+ #txs: AztecMap<string, Buffer>;
18
+
19
+ #log: Logger;
20
+
21
+ /**
22
+ * Class constructor for in-memory TxPool. Initiates our transaction pool as a JS Map.
23
+ * @param store - A KV store.
24
+ * @param log - A logger.
25
+ */
26
+ constructor(store: AztecKVStore, log = createDebugLogger('aztec:tx_pool')) {
27
+ this.#txs = store.openMap('txs');
28
+ this.#store = store;
29
+ this.#log = log;
30
+ }
31
+
32
+ /**
33
+ * Checks if a transaction exists in the pool and returns it.
34
+ * @param txHash - The generated tx hash.
35
+ * @returns The transaction, if found, 'undefined' otherwise.
36
+ */
37
+ public getTxByHash(txHash: TxHash): Tx | undefined {
38
+ const buffer = this.#txs.get(txHash.toString());
39
+ return buffer ? Tx.fromBuffer(buffer) : undefined;
40
+ }
41
+
42
+ /**
43
+ * Adds a list of transactions to the pool. Duplicates are ignored.
44
+ * @param txs - An array of txs to be added to the pool.
45
+ * @returns Empty promise.
46
+ */
47
+ public async addTxs(txs: Tx[]): Promise<void> {
48
+ const txHashes = await Promise.all(txs.map(tx => tx.getTxHash()));
49
+ return this.#store.transaction(() => {
50
+ for (const [i, tx] of txs.entries()) {
51
+ const txHash = txHashes[i];
52
+ this.#log.info(`Adding tx with id ${txHash.toString()}`, {
53
+ eventName: 'tx-added-to-pool',
54
+ ...tx.getStats(),
55
+ } satisfies TxAddedToPoolStats);
56
+
57
+ void this.#txs.set(txHash.toString(), tx.toBuffer());
58
+ }
59
+ });
60
+ }
61
+
62
+ /**
63
+ * Deletes transactions from the pool. Tx hashes that are not present are ignored.
64
+ * @param txHashes - An array of tx hashes to be removed from the tx pool.
65
+ * @returns The number of transactions that was deleted from the pool.
66
+ */
67
+ public deleteTxs(txHashes: TxHash[]): Promise<void> {
68
+ return this.#store.transaction(() => {
69
+ for (const hash of txHashes) {
70
+ void this.#txs.delete(hash.toString());
71
+ }
72
+ });
73
+ }
74
+
75
+ /**
76
+ * Gets all the transactions stored in the pool.
77
+ * @returns Array of tx objects in the order they were added to the pool.
78
+ */
79
+ public getAllTxs(): Tx[] {
80
+ return Array.from(this.#txs.values()).map(buffer => Tx.fromBuffer(buffer));
81
+ }
82
+
83
+ /**
84
+ * Gets the hashes of all transactions currently in the tx pool.
85
+ * @returns An array of transaction hashes found in the tx pool.
86
+ */
87
+ public getAllTxHashes(): TxHash[] {
88
+ return Array.from(this.#txs.keys()).map(x => TxHash.fromString(x));
89
+ }
90
+
91
+ /**
92
+ * Returns a boolean indicating if the transaction is present in the pool.
93
+ * @param txHash - The hash of the transaction to be queried.
94
+ * @returns True if the transaction present, false otherwise.
95
+ */
96
+ public hasTx(txHash: TxHash): boolean {
97
+ return this.#txs.has(txHash.toString());
98
+ }
99
+ }
@@ -0,0 +1,3 @@
1
+ export * from './tx_pool.js';
2
+ export * from './memory_tx_pool.js';
3
+ export * from './aztec_kv_tx_pool.js';
@@ -0,0 +1,87 @@
1
+ import { Tx, TxHash } from '@aztec/circuit-types';
2
+ import { TxAddedToPoolStats } from '@aztec/circuit-types/stats';
3
+ import { createDebugLogger } from '@aztec/foundation/log';
4
+
5
+ import { TxPool } from './tx_pool.js';
6
+
7
+ /**
8
+ * In-memory implementation of the Transaction Pool.
9
+ */
10
+ export class InMemoryTxPool implements TxPool {
11
+ /**
12
+ * Our tx pool, stored as a Map in-memory, with K: tx hash and V: the transaction.
13
+ */
14
+ private txs: Map<bigint, Tx>;
15
+
16
+ /**
17
+ * Class constructor for in-memory TxPool. Initiates our transaction pool as a JS Map.
18
+ * @param log - A logger.
19
+ */
20
+ constructor(private log = createDebugLogger('aztec:tx_pool')) {
21
+ this.txs = new Map<bigint, Tx>();
22
+ }
23
+
24
+ /**
25
+ * Checks if a transaction exists in the pool and returns it.
26
+ * @param txHash - The generated tx hash.
27
+ * @returns The transaction, if found, 'undefined' otherwise.
28
+ */
29
+ public getTxByHash(txHash: TxHash): Tx | undefined {
30
+ const result = this.txs.get(txHash.toBigInt());
31
+ return result === undefined ? undefined : Tx.clone(result);
32
+ }
33
+
34
+ /**
35
+ * Adds a list of transactions to the pool. Duplicates are ignored.
36
+ * @param txs - An array of txs to be added to the pool.
37
+ * @returns Empty promise.
38
+ */
39
+ public addTxs(txs: Tx[]): Promise<void> {
40
+ for (const tx of txs) {
41
+ const txHash = tx.getTxHash();
42
+ this.log(`Adding tx with id ${txHash.toString()}`, {
43
+ eventName: 'tx-added-to-pool',
44
+ ...tx.getStats(),
45
+ } satisfies TxAddedToPoolStats);
46
+ this.txs.set(txHash.toBigInt(), tx);
47
+ }
48
+ return Promise.resolve();
49
+ }
50
+
51
+ /**
52
+ * Deletes transactions from the pool. Tx hashes that are not present are ignored.
53
+ * @param txHashes - An array of tx hashes to be removed from the tx pool.
54
+ * @returns The number of transactions that was deleted from the pool.
55
+ */
56
+ public deleteTxs(txHashes: TxHash[]): Promise<void> {
57
+ for (const txHash of txHashes) {
58
+ this.txs.delete(txHash.toBigInt());
59
+ }
60
+ return Promise.resolve();
61
+ }
62
+
63
+ /**
64
+ * Gets all the transactions stored in the pool.
65
+ * @returns Array of tx objects in the order they were added to the pool.
66
+ */
67
+ public getAllTxs(): Tx[] {
68
+ return Array.from(this.txs.values()).map(x => Tx.clone(x));
69
+ }
70
+
71
+ /**
72
+ * Gets the hashes of all transactions currently in the tx pool.
73
+ * @returns An array of transaction hashes found in the tx pool.
74
+ */
75
+ public getAllTxHashes(): TxHash[] {
76
+ return Array.from(this.txs.keys()).map(x => TxHash.fromBigInt(x));
77
+ }
78
+
79
+ /**
80
+ * Returns a boolean indicating if the transaction is present in the pool.
81
+ * @param txHash - The hash of the transaction to be queried.
82
+ * @returns True if the transaction present, false otherwise.
83
+ */
84
+ public hasTx(txHash: TxHash): boolean {
85
+ return this.txs.has(txHash.toBigInt());
86
+ }
87
+ }
@@ -0,0 +1,44 @@
1
+ import { Tx, TxHash } from '@aztec/circuit-types';
2
+
3
+ /**
4
+ * Interface of a transaction pool. The pool includes tx requests and is kept up-to-date by a P2P client.
5
+ */
6
+ export interface TxPool {
7
+ /**
8
+ * Adds a list of transactions to the pool. Duplicates are ignored.
9
+ * @param txs - An array of txs to be added to the pool.
10
+ */
11
+ addTxs(txs: Tx[]): Promise<void>;
12
+
13
+ /**
14
+ * Checks if a transaction exists in the pool and returns it.
15
+ * @param txHash - The hash of the transaction, used as an ID.
16
+ * @returns The transaction, if found, 'undefined' otherwise.
17
+ */
18
+ getTxByHash(txHash: TxHash): Tx | undefined;
19
+
20
+ /**
21
+ * Deletes transactions from the pool. Tx hashes that are not present are ignored.
22
+ * @param txHashes - An array of tx hashes to be removed from the tx pool.
23
+ */
24
+ deleteTxs(txHashes: TxHash[]): Promise<void>;
25
+
26
+ /**
27
+ * Gets all transactions currently in the tx pool.
28
+ * @returns An array of transaction objects found in the tx pool.
29
+ */
30
+ getAllTxs(): Tx[];
31
+
32
+ /**
33
+ * Gets the hashes of all transactions currently in the tx pool.
34
+ * @returns An array of transaction hashes found in the tx pool.
35
+ */
36
+ getAllTxHashes(): TxHash[];
37
+
38
+ /**
39
+ * Returns a boolean indicating if the transaction is present in the pool.
40
+ * @param txHash - The hash of the transaction to be queried.
41
+ * @returns True if the transaction present, false otherwise.
42
+ */
43
+ hasTx(txHash: TxHash): boolean;
44
+ }
@@ -0,0 +1,57 @@
1
+ import { mockTx } from '@aztec/circuit-types';
2
+
3
+ import { TxPool } from './tx_pool.js';
4
+
5
+ /**
6
+ * Tests a TxPool implementation.
7
+ * @param getTxPool - Gets a fresh TxPool
8
+ */
9
+ export function describeTxPool(getTxPool: () => TxPool) {
10
+ let pool: TxPool;
11
+
12
+ beforeEach(() => {
13
+ pool = getTxPool();
14
+ });
15
+
16
+ it('Adds txs to the pool', async () => {
17
+ const tx1 = mockTx();
18
+
19
+ await pool.addTxs([tx1]);
20
+ const poolTx = pool.getTxByHash(tx1.getTxHash());
21
+ expect(poolTx!.getTxHash()).toEqual(tx1.getTxHash());
22
+ });
23
+
24
+ it('Removes txs from the pool', async () => {
25
+ const tx1 = mockTx();
26
+
27
+ await pool.addTxs([tx1]);
28
+ await pool.deleteTxs([tx1.getTxHash()]);
29
+
30
+ const poolTx = pool.getTxByHash(tx1.getTxHash());
31
+ expect(poolTx).toBeFalsy();
32
+ });
33
+
34
+ it('Returns all transactions in the pool', async () => {
35
+ const tx1 = mockTx(1);
36
+ const tx2 = mockTx(2);
37
+ const tx3 = mockTx(3);
38
+
39
+ await pool.addTxs([tx1, tx2, tx3]);
40
+
41
+ const poolTxs = pool.getAllTxs();
42
+ expect(poolTxs).toHaveLength(3);
43
+ expect(poolTxs).toEqual(expect.arrayContaining([tx1, tx2, tx3]));
44
+ });
45
+
46
+ it('Returns all txHashes in the pool', async () => {
47
+ const tx1 = mockTx(1);
48
+ const tx2 = mockTx(2);
49
+ const tx3 = mockTx(3);
50
+
51
+ await pool.addTxs([tx1, tx2, tx3]);
52
+
53
+ const poolTxHashes = pool.getAllTxHashes();
54
+ expect(poolTxHashes).toHaveLength(3);
55
+ expect(poolTxHashes).toEqual(expect.arrayContaining([tx1.getTxHash(), tx2.getTxHash(), tx3.getTxHash()]));
56
+ });
57
+ }