@aztec/p2p 0.46.7 → 0.47.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.
Files changed (39) hide show
  1. package/dest/client/index.d.ts +1 -1
  2. package/dest/client/index.d.ts.map +1 -1
  3. package/dest/client/index.js +3 -3
  4. package/dest/client/mocks.d.ts +5 -3
  5. package/dest/client/mocks.d.ts.map +1 -1
  6. package/dest/client/mocks.js +18 -9
  7. package/dest/client/p2p_client.d.ts +52 -22
  8. package/dest/client/p2p_client.d.ts.map +1 -1
  9. package/dest/client/p2p_client.js +125 -37
  10. package/dest/config.d.ts +2 -0
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +3 -2
  13. package/dest/service/libp2p_service.d.ts +1 -1
  14. package/dest/service/libp2p_service.d.ts.map +1 -1
  15. package/dest/service/libp2p_service.js +4 -3
  16. package/dest/service/tx_messages.d.ts +1 -19
  17. package/dest/service/tx_messages.d.ts.map +1 -1
  18. package/dest/service/tx_messages.js +2 -109
  19. package/dest/tx_pool/aztec_kv_tx_pool.d.ts +4 -6
  20. package/dest/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  21. package/dest/tx_pool/aztec_kv_tx_pool.js +47 -16
  22. package/dest/tx_pool/memory_tx_pool.d.ts +6 -6
  23. package/dest/tx_pool/memory_tx_pool.d.ts.map +1 -1
  24. package/dest/tx_pool/memory_tx_pool.js +36 -11
  25. package/dest/tx_pool/tx_pool.d.ts +19 -4
  26. package/dest/tx_pool/tx_pool.d.ts.map +1 -1
  27. package/dest/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  28. package/dest/tx_pool/tx_pool_test_suite.js +16 -4
  29. package/package.json +6 -6
  30. package/src/client/index.ts +2 -2
  31. package/src/client/mocks.ts +20 -7
  32. package/src/client/p2p_client.ts +149 -48
  33. package/src/config.ts +5 -0
  34. package/src/service/libp2p_service.ts +3 -3
  35. package/src/service/tx_messages.ts +2 -123
  36. package/src/tx_pool/aztec_kv_tx_pool.ts +49 -15
  37. package/src/tx_pool/memory_tx_pool.ts +42 -11
  38. package/src/tx_pool/tx_pool.ts +22 -4
  39. package/src/tx_pool/tx_pool_test_suite.ts +18 -3
@@ -8,18 +8,30 @@ export function describeTxPool(getTxPool) {
8
8
  beforeEach(() => {
9
9
  pool = getTxPool();
10
10
  });
11
- it('Adds txs to the pool', async () => {
11
+ it('Adds txs to the pool as pending', async () => {
12
12
  const tx1 = mockTx();
13
13
  await pool.addTxs([tx1]);
14
14
  const poolTx = pool.getTxByHash(tx1.getTxHash());
15
15
  expect(poolTx.getTxHash()).toEqual(tx1.getTxHash());
16
+ expect(pool.getTxStatus(tx1.getTxHash())).toEqual('pending');
17
+ expect(pool.getPendingTxHashes()).toEqual([tx1.getTxHash()]);
16
18
  });
17
19
  it('Removes txs from the pool', async () => {
18
20
  const tx1 = mockTx();
19
21
  await pool.addTxs([tx1]);
20
22
  await pool.deleteTxs([tx1.getTxHash()]);
21
- const poolTx = pool.getTxByHash(tx1.getTxHash());
22
- expect(poolTx).toBeFalsy();
23
+ expect(pool.getTxByHash(tx1.getTxHash())).toBeFalsy();
24
+ expect(pool.getTxStatus(tx1.getTxHash())).toBeUndefined();
25
+ });
26
+ it('Marks txs as mined', async () => {
27
+ const tx1 = mockTx(1);
28
+ const tx2 = mockTx(2);
29
+ await pool.addTxs([tx1, tx2]);
30
+ await pool.markAsMined([tx1.getTxHash()]);
31
+ expect(pool.getTxByHash(tx1.getTxHash())).toEqual(tx1);
32
+ expect(pool.getTxStatus(tx1.getTxHash())).toEqual('mined');
33
+ expect(pool.getMinedTxHashes()).toEqual([tx1.getTxHash()]);
34
+ expect(pool.getPendingTxHashes()).toEqual([tx2.getTxHash()]);
23
35
  });
24
36
  it('Returns all transactions in the pool', async () => {
25
37
  const tx1 = mockTx(1);
@@ -40,4 +52,4 @@ export function describeTxPool(getTxPool) {
40
52
  expect(poolTxHashes).toEqual(expect.arrayContaining([tx1.getTxHash(), tx2.getTxHash(), tx3.getTxHash()]));
41
53
  });
42
54
  }
43
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfcG9vbF90ZXN0X3N1aXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R4X3Bvb2wvdHhfcG9vbF90ZXN0X3N1aXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUk5Qzs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLFNBQXVCO0lBQ3BELElBQUksSUFBWSxDQUFDO0lBRWpCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxJQUFJLEdBQUcsU0FBUyxFQUFFLENBQUM7SUFDckIsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsc0JBQXNCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEMsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUM7UUFFckIsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN6QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sQ0FBQyxNQUFPLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDdkQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsMkJBQTJCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDekMsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUM7UUFFckIsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN6QixNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXhDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDakQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQzdCLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNDQUFzQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3BELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXRCLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUVuQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxrQ0FBa0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNoRCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0QixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFbkMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzNDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUUsRUFBRSxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUcsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIn0=
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfcG9vbF90ZXN0X3N1aXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R4X3Bvb2wvdHhfcG9vbF90ZXN0X3N1aXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUk5Qzs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLFNBQXVCO0lBQ3BELElBQUksSUFBWSxDQUFDO0lBRWpCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxJQUFJLEdBQUcsU0FBUyxFQUFFLENBQUM7SUFDckIsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDL0MsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUM7UUFFckIsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN6QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sQ0FBQyxNQUFPLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDckQsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0QsTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMvRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywyQkFBMkIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN6QyxNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUs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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.46.7",
3
+ "version": "0.47.1",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -56,11 +56,11 @@
56
56
  "testTimeout": 15000
57
57
  },
58
58
  "dependencies": {
59
- "@aztec/circuit-types": "0.46.7",
60
- "@aztec/circuits.js": "0.46.7",
61
- "@aztec/foundation": "0.46.7",
62
- "@aztec/kv-store": "0.46.7",
63
- "@aztec/telemetry-client": "0.46.7",
59
+ "@aztec/circuit-types": "0.47.1",
60
+ "@aztec/circuits.js": "0.47.1",
61
+ "@aztec/foundation": "0.47.1",
62
+ "@aztec/kv-store": "0.47.1",
63
+ "@aztec/telemetry-client": "0.47.1",
64
64
  "@chainsafe/discv5": "9.0.0",
65
65
  "@chainsafe/enr": "3.0.0",
66
66
  "@chainsafe/libp2p-gossipsub": "13.0.0",
@@ -12,8 +12,8 @@ import { getPublicIp, splitAddressPort } from '../util.js';
12
12
  export * from './p2p_client.js';
13
13
 
14
14
  export const createP2PClient = async (
15
- store: AztecKVStore,
16
15
  config: P2PConfig,
16
+ store: AztecKVStore,
17
17
  txPool: TxPool,
18
18
  l2BlockSource: L2BlockSource,
19
19
  ) => {
@@ -63,5 +63,5 @@ export const createP2PClient = async (
63
63
  } else {
64
64
  p2pService = new DummyP2PService();
65
65
  }
66
- return new P2PClient(store, l2BlockSource, txPool, p2pService);
66
+ return new P2PClient(store, l2BlockSource, txPool, p2pService, config.keepProvenTxsInPoolFor);
67
67
  };
@@ -8,14 +8,23 @@ export class MockBlockSource implements L2BlockSource {
8
8
  private l2Blocks: L2Block[] = [];
9
9
  private txEffects: TxEffect[] = [];
10
10
 
11
- constructor(private numBlocks = 100) {
12
- for (let i = 0; i < this.numBlocks; i++) {
13
- const block = L2Block.random(i);
11
+ constructor(numBlocks = 100, private provenBlockNumber?: number) {
12
+ this.addBlocks(numBlocks);
13
+ }
14
+
15
+ public addBlocks(numBlocks: number) {
16
+ for (let i = 0; i < numBlocks; i++) {
17
+ const blockNum = this.l2Blocks.length;
18
+ const block = L2Block.random(blockNum);
14
19
  this.l2Blocks.push(block);
15
20
  this.txEffects.push(...block.body.txEffects);
16
21
  }
17
22
  }
18
23
 
24
+ public setProvenBlockNumber(provenBlockNumber: number) {
25
+ this.provenBlockNumber = provenBlockNumber;
26
+ }
27
+
19
28
  /**
20
29
  * Method to fetch the rollup contract address at the base-layer.
21
30
  * @returns The rollup address.
@@ -40,8 +49,8 @@ export class MockBlockSource implements L2BlockSource {
40
49
  return Promise.resolve(this.l2Blocks.length - 1);
41
50
  }
42
51
 
43
- public getProvenBlockNumber(): Promise<number> {
44
- return this.getBlockNumber();
52
+ public async getProvenBlockNumber(): Promise<number> {
53
+ return this.provenBlockNumber ?? (await this.getBlockNumber());
45
54
  }
46
55
 
47
56
  /**
@@ -59,8 +68,12 @@ export class MockBlockSource implements L2BlockSource {
59
68
  * @param limit - The maximum number of blocks to return.
60
69
  * @returns The requested mocked L2 blocks.
61
70
  */
62
- public getBlocks(from: number, limit: number) {
63
- return Promise.resolve(this.l2Blocks.slice(from, from + limit));
71
+ public getBlocks(from: number, limit: number, proven?: boolean) {
72
+ return Promise.resolve(
73
+ this.l2Blocks
74
+ .slice(from, from + limit)
75
+ .filter(b => !proven || this.provenBlockNumber === undefined || b.number <= this.provenBlockNumber),
76
+ );
64
77
  }
65
78
 
66
79
  /**
@@ -52,14 +52,21 @@ export interface P2P {
52
52
  * Returns all transactions in the transaction pool.
53
53
  * @returns An array of Txs.
54
54
  */
55
- getTxs(): Promise<Tx[]>;
55
+ getTxs(filter: 'all' | 'pending' | 'mined'): Tx[];
56
56
 
57
57
  /**
58
58
  * Returns a transaction in the transaction pool by its hash.
59
59
  * @param txHash - Hash of tx to return.
60
60
  * @returns A single tx or undefined.
61
61
  */
62
- getTxByHash(txHash: TxHash): Promise<Tx | undefined>;
62
+ getTxByHash(txHash: TxHash): Tx | undefined;
63
+
64
+ /**
65
+ * Returns whether the given tx hash is flagged as pending or mined.
66
+ * @param txHash - Hash of the tx to query.
67
+ * @returns Pending or mined depending on its status, or undefined if not found.
68
+ */
69
+ getTxStatus(txHash: TxHash): 'pending' | 'mined' | undefined;
63
70
 
64
71
  /**
65
72
  * Starts the p2p client.
@@ -89,26 +96,26 @@ export interface P2P {
89
96
  * The P2P client implementation.
90
97
  */
91
98
  export class P2PClient implements P2P {
92
- /**
93
- * L2 Block download that p2p client uses to stay in sync with latest blocks.
94
- */
95
- private blockDownloader: L2BlockDownloader;
99
+ /** L2 block download to stay in sync with latest blocks. */
100
+ private latestBlockDownloader: L2BlockDownloader;
96
101
 
97
- /**
98
- * Property that indicates whether the client is running.
99
- */
102
+ /** L2 block download to stay in sync with proven blocks. */
103
+ private provenBlockDownloader: L2BlockDownloader;
104
+
105
+ /** Property that indicates whether the client is running. */
100
106
  private stopping = false;
101
107
 
102
- /**
103
- * The JS promise that will be running to keep the client's data in sync. Can be interrupted if the client is stopped.
104
- */
108
+ /** The JS promise that will be running to keep the client's data in sync. Can be interrupted if the client is stopped. */
105
109
  private runningPromise!: Promise<void>;
106
110
 
107
111
  private currentState = P2PClientState.IDLE;
108
112
  private syncPromise = Promise.resolve();
109
- private latestBlockNumberAtStart = -1;
110
113
  private syncResolve?: () => void = undefined;
111
- private synchedBlockNumber: AztecSingleton<number>;
114
+ private latestBlockNumberAtStart = -1;
115
+ private provenBlockNumberAtStart = -1;
116
+
117
+ private synchedLatestBlockNumber: AztecSingleton<number>;
118
+ private synchedProvenBlockNumber: AztecSingleton<number>;
112
119
 
113
120
  /**
114
121
  * In-memory P2P client constructor.
@@ -116,6 +123,7 @@ export class P2PClient implements P2P {
116
123
  * @param l2BlockSource - P2P client's source for fetching existing blocks.
117
124
  * @param txPool - The client's instance of a transaction pool. Defaults to in-memory implementation.
118
125
  * @param p2pService - The concrete instance of p2p networking to use.
126
+ * @param keepProvenTxsFor - How many blocks have to pass after a block is proven before its txs are deleted (zero to delete immediately once proven).
119
127
  * @param log - A logger.
120
128
  */
121
129
  constructor(
@@ -123,14 +131,19 @@ export class P2PClient implements P2P {
123
131
  private l2BlockSource: L2BlockSource,
124
132
  private txPool: TxPool,
125
133
  private p2pService: P2PService,
134
+ private keepProvenTxsFor: number,
126
135
  private log = createDebugLogger('aztec:p2p'),
127
136
  ) {
128
137
  const { p2pBlockCheckIntervalMS: checkInterval, p2pL2QueueSize } = getP2PConfigEnvVars();
129
- this.blockDownloader = new L2BlockDownloader(l2BlockSource, {
130
- maxQueueSize: p2pL2QueueSize,
131
- pollIntervalMS: checkInterval,
132
- });
133
- this.synchedBlockNumber = store.openSingleton('p2p_pool_last_l2_block');
138
+ const l2DownloaderOpts = { maxQueueSize: p2pL2QueueSize, pollIntervalMS: checkInterval };
139
+ // TODO(palla/prover-node): This effectively downloads blocks twice from the archiver, which is an issue
140
+ // if the archiver is remote. We should refactor this so the downloader keeps a single queue and handles
141
+ // latest/proven metadata, as well as block reorgs.
142
+ this.latestBlockDownloader = new L2BlockDownloader(l2BlockSource, l2DownloaderOpts);
143
+ this.provenBlockDownloader = new L2BlockDownloader(l2BlockSource, { ...l2DownloaderOpts, proven: true });
144
+
145
+ this.synchedLatestBlockNumber = store.openSingleton('p2p_pool_last_l2_block');
146
+ this.synchedProvenBlockNumber = store.openSingleton('p2p_pool_last_proven_l2_block');
134
147
  }
135
148
 
136
149
  /**
@@ -145,41 +158,47 @@ export class P2PClient implements P2P {
145
158
  return this.syncPromise;
146
159
  }
147
160
 
148
- // get the current latest block number
161
+ // get the current latest block numbers
149
162
  this.latestBlockNumberAtStart = await this.l2BlockSource.getBlockNumber();
163
+ this.provenBlockNumberAtStart = await this.l2BlockSource.getProvenBlockNumber();
150
164
 
151
- const blockToDownloadFrom = this.getSyncedBlockNum() + 1;
165
+ const syncedLatestBlock = this.getSyncedLatestBlockNum() + 1;
166
+ const syncedProvenBlock = this.getSyncedProvenBlockNum() + 1;
152
167
 
153
168
  // if there are blocks to be retrieved, go to a synching state
154
- if (blockToDownloadFrom <= this.latestBlockNumberAtStart) {
169
+ if (syncedLatestBlock <= this.latestBlockNumberAtStart || syncedProvenBlock <= this.provenBlockNumberAtStart) {
155
170
  this.setCurrentState(P2PClientState.SYNCHING);
156
171
  this.syncPromise = new Promise(resolve => {
157
172
  this.syncResolve = resolve;
158
173
  });
159
- this.log.verbose(`Starting sync from ${blockToDownloadFrom}, latest block ${this.latestBlockNumberAtStart}`);
174
+ this.log.verbose(`Starting sync from ${syncedLatestBlock} (last proven ${syncedProvenBlock})`);
160
175
  } else {
161
176
  // if no blocks to be retrieved, go straight to running
162
177
  this.setCurrentState(P2PClientState.RUNNING);
163
178
  this.syncPromise = Promise.resolve();
164
179
  await this.p2pService.start();
165
- this.log.verbose(
166
- `Next block ${blockToDownloadFrom} already beyond latest block at ${this.latestBlockNumberAtStart}`,
167
- );
180
+ this.log.verbose(`Block ${syncedLatestBlock} (proven ${syncedProvenBlock}) already beyond current block`);
168
181
  }
169
182
 
170
183
  // publish any txs in TxPool after its doing initial sync
171
184
  this.syncPromise = this.syncPromise.then(() => this.publishStoredTxs());
172
185
 
173
186
  // start looking for further blocks
174
- const blockProcess = async () => {
187
+ const processLatest = async () => {
175
188
  while (!this.stopping) {
176
- const blocks = await this.blockDownloader.getBlocks();
177
- await this.handleL2Blocks(blocks);
189
+ await this.latestBlockDownloader.getBlocks(1).then(this.handleLatestL2Blocks.bind(this));
190
+ }
191
+ };
192
+ const processProven = async () => {
193
+ while (!this.stopping) {
194
+ await this.provenBlockDownloader.getBlocks(1).then(this.handleProvenL2Blocks.bind(this));
178
195
  }
179
196
  };
180
- this.runningPromise = blockProcess();
181
- this.blockDownloader.start(blockToDownloadFrom);
182
- this.log.verbose(`Started block downloader from block ${blockToDownloadFrom}`);
197
+
198
+ this.runningPromise = Promise.all([processLatest(), processProven()]).then(() => {});
199
+ this.latestBlockDownloader.start(syncedLatestBlock);
200
+ this.provenBlockDownloader.start(syncedLatestBlock);
201
+ this.log.verbose(`Started block downloader from block ${syncedLatestBlock}`);
183
202
 
184
203
  return this.syncPromise;
185
204
  }
@@ -193,7 +212,8 @@ export class P2PClient implements P2P {
193
212
  this.stopping = true;
194
213
  await this.p2pService.stop();
195
214
  this.log.debug('Stopped p2p service');
196
- await this.blockDownloader.stop();
215
+ await this.latestBlockDownloader.stop();
216
+ await this.provenBlockDownloader.stop();
197
217
  this.log.debug('Stopped block downloader');
198
218
  await this.runningPromise;
199
219
  this.setCurrentState(P2PClientState.STOPPED);
@@ -204,8 +224,23 @@ export class P2PClient implements P2P {
204
224
  * Returns all transactions in the transaction pool.
205
225
  * @returns An array of Txs.
206
226
  */
207
- public getTxs(): Promise<Tx[]> {
208
- return Promise.resolve(this.txPool.getAllTxs());
227
+ public getTxs(filter: 'all' | 'pending' | 'mined'): Tx[] {
228
+ if (filter === 'all') {
229
+ return this.txPool.getAllTxs();
230
+ } else if (filter === 'mined') {
231
+ return this.txPool
232
+ .getMinedTxHashes()
233
+ .map(txHash => this.txPool.getTxByHash(txHash))
234
+ .filter((tx): tx is Tx => !!tx);
235
+ } else if (filter === 'pending') {
236
+ return this.txPool
237
+ .getPendingTxHashes()
238
+ .map(txHash => this.txPool.getTxByHash(txHash))
239
+ .filter((tx): tx is Tx => !!tx);
240
+ } else {
241
+ const _: never = filter;
242
+ throw new Error(`Unknown filter ${filter}`);
243
+ }
209
244
  }
210
245
 
211
246
  /**
@@ -213,8 +248,8 @@ export class P2PClient implements P2P {
213
248
  * @param txHash - Hash of the transaction to look for in the pool.
214
249
  * @returns A single tx or undefined.
215
250
  */
216
- getTxByHash(txHash: TxHash): Promise<Tx | undefined> {
217
- return Promise.resolve(this.txPool.getTxByHash(txHash));
251
+ getTxByHash(txHash: TxHash): Tx | undefined {
252
+ return this.txPool.getTxByHash(txHash);
218
253
  }
219
254
 
220
255
  /**
@@ -231,6 +266,15 @@ export class P2PClient implements P2P {
231
266
  this.p2pService.propagateTx(tx);
232
267
  }
233
268
 
269
+ /**
270
+ * Returns whether the given tx hash is flagged as pending or mined.
271
+ * @param txHash - Hash of the tx to query.
272
+ * @returns Pending or mined depending on its status, or undefined if not found.
273
+ */
274
+ public getTxStatus(txHash: TxHash): 'pending' | 'mined' | undefined {
275
+ return this.txPool.getTxStatus(txHash);
276
+ }
277
+
234
278
  /**
235
279
  * Deletes the 'txs' from the pool.
236
280
  * NOT used if we use sendTx as reconcileTxPool will handle this.
@@ -257,8 +301,16 @@ export class P2PClient implements P2P {
257
301
  * Public function to check the latest block number that the P2P client is synced to.
258
302
  * @returns Block number of latest L2 Block we've synced with.
259
303
  */
260
- public getSyncedBlockNum() {
261
- return this.synchedBlockNumber.get() ?? INITIAL_L2_BLOCK_NUM - 1;
304
+ public getSyncedLatestBlockNum() {
305
+ return this.synchedLatestBlockNumber.get() ?? INITIAL_L2_BLOCK_NUM - 1;
306
+ }
307
+
308
+ /**
309
+ * Public function to check the latest proven block number that the P2P client is synced to.
310
+ * @returns Block number of latest proven L2 Block we've synced with.
311
+ */
312
+ public getSyncedProvenBlockNum() {
313
+ return this.synchedProvenBlockNumber.get() ?? INITIAL_L2_BLOCK_NUM - 1;
262
314
  }
263
315
 
264
316
  /**
@@ -268,16 +320,29 @@ export class P2PClient implements P2P {
268
320
  public getStatus(): Promise<P2PSyncState> {
269
321
  return Promise.resolve({
270
322
  state: this.currentState,
271
- syncedToL2Block: this.getSyncedBlockNum(),
323
+ syncedToL2Block: this.getSyncedLatestBlockNum(),
272
324
  } as P2PSyncState);
273
325
  }
274
326
 
275
327
  /**
276
- * Internal method that uses the provided blocks to check against the client's tx pool.
328
+ * Mark all txs from these blocks as mined.
277
329
  * @param blocks - A list of existing blocks with txs that the P2P client needs to ensure the tx pool is reconciled with.
278
330
  * @returns Empty promise.
279
331
  */
280
- private async reconcileTxPool(blocks: L2Block[]): Promise<void> {
332
+ private async markTxsAsMinedFromBlocks(blocks: L2Block[]): Promise<void> {
333
+ for (const block of blocks) {
334
+ const txHashes = block.body.txEffects.map(txEffect => txEffect.txHash);
335
+ await this.txPool.markAsMined(txHashes);
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Deletes txs from these blocks.
341
+ * @param blocks - A list of existing blocks with txs that the P2P client needs to ensure the tx pool is reconciled with.
342
+ * @returns Empty promise.
343
+ */
344
+ private async deleteTxsFromBlocks(blocks: L2Block[]): Promise<void> {
345
+ this.log.debug(`Deleting txs from blocks ${blocks[0].number} to ${blocks[blocks.length - 1].number}`);
281
346
  for (const block of blocks) {
282
347
  const txHashes = block.body.txEffects.map(txEffect => txEffect.txHash);
283
348
  await this.txPool.deleteTxs(txHashes);
@@ -285,20 +350,56 @@ export class P2PClient implements P2P {
285
350
  }
286
351
 
287
352
  /**
288
- * Method for processing new blocks.
353
+ * Handles new mined blocks by marking the txs in them as mined.
289
354
  * @param blocks - A list of existing blocks with txs that the P2P client needs to ensure the tx pool is reconciled with.
290
355
  * @returns Empty promise.
291
356
  */
292
- private async handleL2Blocks(blocks: L2Block[]): Promise<void> {
357
+ private async handleLatestL2Blocks(blocks: L2Block[]): Promise<void> {
293
358
  if (!blocks.length) {
294
359
  return Promise.resolve();
295
360
  }
296
- await this.reconcileTxPool(blocks);
361
+ await this.markTxsAsMinedFromBlocks(blocks);
297
362
  const lastBlockNum = blocks[blocks.length - 1].number;
298
- await this.synchedBlockNumber.set(lastBlockNum);
299
- this.log.debug(`Synched to block ${lastBlockNum}`);
363
+ await this.synchedLatestBlockNumber.set(lastBlockNum);
364
+ this.log.debug(`Synched to latest block ${lastBlockNum}`);
365
+ await this.startServiceIfSynched();
366
+ }
367
+
368
+ /**
369
+ * Handles new proven blocks by deleting the txs in them, or by deleting the txs in blocks `keepProvenTxsFor` ago.
370
+ * @param blocks - A list of proven L2 blocks.
371
+ * @returns Empty promise.
372
+ */
373
+ private async handleProvenL2Blocks(blocks: L2Block[]): Promise<void> {
374
+ if (!blocks.length) {
375
+ return Promise.resolve();
376
+ }
377
+
378
+ const firstBlockNum = blocks[0].number;
379
+ const lastBlockNum = blocks[blocks.length - 1].number;
380
+
381
+ if (this.keepProvenTxsFor === 0) {
382
+ await this.deleteTxsFromBlocks(blocks);
383
+ } else if (lastBlockNum - this.keepProvenTxsFor >= INITIAL_L2_BLOCK_NUM) {
384
+ const fromBlock = Math.max(INITIAL_L2_BLOCK_NUM, firstBlockNum - this.keepProvenTxsFor);
385
+ const toBlock = lastBlockNum - this.keepProvenTxsFor;
386
+ const limit = toBlock - fromBlock + 1;
387
+ const blocksToDeleteTxsFrom = await this.l2BlockSource.getBlocks(fromBlock, limit, true);
388
+ await this.deleteTxsFromBlocks(blocksToDeleteTxsFrom);
389
+ }
390
+
391
+ await this.synchedProvenBlockNumber.set(lastBlockNum);
392
+ this.log.debug(`Synched to proven block ${lastBlockNum}`);
393
+ await this.startServiceIfSynched();
394
+ }
300
395
 
301
- if (this.currentState === P2PClientState.SYNCHING && lastBlockNum >= this.latestBlockNumberAtStart) {
396
+ private async startServiceIfSynched() {
397
+ if (
398
+ this.currentState === P2PClientState.SYNCHING &&
399
+ this.getSyncedLatestBlockNum() >= this.latestBlockNumberAtStart &&
400
+ this.getSyncedProvenBlockNum() >= this.provenBlockNumberAtStart
401
+ ) {
402
+ this.log.debug(`Synched to blocks at start`);
302
403
  this.setCurrentState(P2PClientState.RUNNING);
303
404
  if (this.syncResolve !== undefined) {
304
405
  this.syncResolve();
package/src/config.ts CHANGED
@@ -88,6 +88,9 @@ export interface P2PConfig {
88
88
  * If announceUdpAddress or announceTcpAddress are not provided, query for the IP address of the machine. Default is false.
89
89
  */
90
90
  queryForIp: boolean;
91
+
92
+ /** How many blocks have to pass after a block is proven before its txs are deleted (zero to delete immediately once proven) */
93
+ keepProvenTxsInPoolFor: number;
91
94
  }
92
95
 
93
96
  /**
@@ -113,6 +116,7 @@ export function getP2PConfigEnvVars(): P2PConfig {
113
116
  TX_GOSSIP_VERSION,
114
117
  P2P_TX_PROTOCOL,
115
118
  P2P_QUERY_FOR_IP,
119
+ P2P_TX_POOL_KEEP_PROVEN_FOR,
116
120
  } = process.env;
117
121
  // P2P listen & announce addresses passed in format: <IP_ADDRESS>:<PORT>
118
122
  // P2P announce multiaddrs passed in format: /ip4/<IP_ADDRESS>/<protocol>/<PORT>
@@ -134,6 +138,7 @@ export function getP2PConfigEnvVars(): P2PConfig {
134
138
  dataDirectory: DATA_DIRECTORY,
135
139
  txGossipVersion: TX_GOSSIP_VERSION ? new SemVer(TX_GOSSIP_VERSION) : new SemVer('0.1.0'),
136
140
  queryForIp: P2P_QUERY_FOR_IP === 'true',
141
+ keepProvenTxsInPoolFor: P2P_TX_POOL_KEEP_PROVEN_FOR ? +P2P_TX_POOL_KEEP_PROVEN_FOR : 0,
137
142
  };
138
143
  return envVars;
139
144
  }
@@ -1,4 +1,4 @@
1
- import { type Tx } from '@aztec/circuit-types';
1
+ import { Tx } from '@aztec/circuit-types';
2
2
  import { SerialQueue } from '@aztec/foundation/fifo';
3
3
  import { createDebugLogger } from '@aztec/foundation/log';
4
4
  import { RunningPromise } from '@aztec/foundation/running-promise';
@@ -21,7 +21,7 @@ import { convertToMultiaddr } from '../util.js';
21
21
  import { AztecDatastore } from './data_store.js';
22
22
  import { PeerManager } from './peer_manager.js';
23
23
  import type { P2PService, PeerDiscoveryService } from './service.js';
24
- import { AztecTxMessageCreator, fromTxMessage } from './tx_messages.js';
24
+ import { AztecTxMessageCreator } from './tx_messages.js';
25
25
 
26
26
  export interface PubSubLibp2p extends Libp2p {
27
27
  services: {
@@ -239,7 +239,7 @@ export class LibP2PService implements P2PService {
239
239
  return;
240
240
  }
241
241
 
242
- const tx = fromTxMessage(Buffer.from(data));
242
+ const tx = Tx.fromBuffer(Buffer.from(data));
243
243
  await this.processTxFromPeer(tx);
244
244
  }
245
245
 
@@ -1,6 +1,4 @@
1
- import { EncryptedNoteTxL2Logs, EncryptedTxL2Logs, Tx, UnencryptedTxL2Logs } from '@aztec/circuit-types';
2
- import { ClientIvcProof, PrivateKernelTailCircuitPublicInputs, PublicCallRequest } from '@aztec/circuits.js';
3
- import { numToUInt32BE } from '@aztec/foundation/serialize';
1
+ import { type Tx } from '@aztec/circuit-types';
4
2
 
5
3
  import { type SemVer } from 'semver';
6
4
 
@@ -13,7 +11,7 @@ export class AztecTxMessageCreator {
13
11
  }
14
12
 
15
13
  createTxMessage(tx: Tx) {
16
- const messageData = toTxMessage(tx);
14
+ const messageData = tx.toBuffer();
17
15
 
18
16
  return { topic: this.topic, data: messageData };
19
17
  }
@@ -22,122 +20,3 @@ export class AztecTxMessageCreator {
22
20
  return this.topic;
23
21
  }
24
22
  }
25
-
26
- /**
27
- * Decode a POOLED_TRANSACTIONS message into the original transaction objects.
28
- * @param message - The binary message to be decoded.
29
- * @returns - The array of transactions originally encoded into the message.
30
- */
31
- export function decodeTransactionsMessage(message: Buffer) {
32
- const lengthSize = 4;
33
- let offset = 0;
34
- const txs: Tx[] = [];
35
- while (offset < message.length) {
36
- const dataSize = message.readUInt32BE(offset);
37
- const totalSizeOfMessage = lengthSize + dataSize;
38
- txs.push(fromTxMessage(message.subarray(offset, offset + totalSizeOfMessage)));
39
- offset += totalSizeOfMessage;
40
- }
41
- return txs;
42
- }
43
-
44
- /**
45
- * Creates a tx 'message' for sending to a peer.
46
- * @param tx - The transaction to convert to a message.
47
- * @returns - The message.
48
- */
49
- export function toTxMessage(tx: Tx): Buffer {
50
- // eslint-disable-next-line jsdoc/require-jsdoc
51
- const createMessageComponent = (obj?: { toBuffer: () => Buffer }) => {
52
- if (!obj) {
53
- // specify a length of 0 bytes
54
- return numToUInt32BE(0);
55
- }
56
- const buffer = obj.toBuffer();
57
- return Buffer.concat([numToUInt32BE(buffer.length), buffer]);
58
- };
59
- // eslint-disable-next-line jsdoc/require-jsdoc
60
- const createMessageComponents = (obj?: { toBuffer: () => Buffer }[]) => {
61
- if (!obj || !obj.length) {
62
- // specify a length of 0 bytes
63
- return numToUInt32BE(0);
64
- }
65
- const allComponents = Buffer.concat(obj.map(createMessageComponent));
66
- return Buffer.concat([numToUInt32BE(obj.length), allComponents]);
67
- };
68
- const messageBuffer = Buffer.concat([
69
- createMessageComponent(tx.data),
70
- createMessageComponent(tx.clientIvcProof),
71
- createMessageComponent(tx.noteEncryptedLogs),
72
- createMessageComponent(tx.encryptedLogs),
73
- createMessageComponent(tx.unencryptedLogs),
74
- createMessageComponents(tx.enqueuedPublicFunctionCalls),
75
- createMessageComponent(tx.publicTeardownFunctionCall),
76
- ]);
77
- const messageLength = numToUInt32BE(messageBuffer.length);
78
- return Buffer.concat([messageLength, messageBuffer]);
79
- }
80
-
81
- /**
82
- * Reproduces a transaction from a transaction 'message'
83
- * @param buffer - The message buffer to convert to a tx.
84
- * @returns - The reproduced transaction.
85
- */
86
- export function fromTxMessage(buffer: Buffer): Tx {
87
- // eslint-disable-next-line jsdoc/require-jsdoc
88
- const toObject = <T>(objectBuffer: Buffer, factory: { fromBuffer: (b: Buffer) => T }) => {
89
- const objectSize = objectBuffer.readUint32BE(0);
90
- return {
91
- remainingData: objectBuffer.subarray(objectSize + 4),
92
- obj: objectSize === 0 ? undefined : factory.fromBuffer(objectBuffer.subarray(4, objectSize + 4)),
93
- };
94
- };
95
-
96
- // eslint-disable-next-line jsdoc/require-jsdoc
97
- const toObjectArray = <T>(objectBuffer: Buffer, factory: { fromBuffer: (b: Buffer) => T }) => {
98
- const output: T[] = [];
99
- const numItems = objectBuffer.readUint32BE(0);
100
- let workingBuffer = objectBuffer.subarray(4);
101
- for (let i = 0; i < numItems; i++) {
102
- const obj = toObject<T>(workingBuffer, factory);
103
- workingBuffer = obj.remainingData;
104
- if (obj !== undefined) {
105
- output.push(obj.obj!);
106
- }
107
- }
108
- return {
109
- remainingData: workingBuffer,
110
- objects: output,
111
- };
112
- };
113
- // this is the opposite of the 'toMessage' function
114
- // so the first 4 bytes is the complete length, skip it
115
- const publicInputs = toObject(buffer.subarray(4), PrivateKernelTailCircuitPublicInputs);
116
- const clientIvcProof = toObject(publicInputs.remainingData, ClientIvcProof);
117
-
118
- const noteEncryptedLogs = toObject(clientIvcProof.remainingData, EncryptedNoteTxL2Logs);
119
- if (!noteEncryptedLogs.obj) {
120
- noteEncryptedLogs.obj = new EncryptedNoteTxL2Logs([]);
121
- }
122
- const encryptedLogs = toObject(noteEncryptedLogs.remainingData, EncryptedTxL2Logs);
123
- if (!encryptedLogs.obj) {
124
- encryptedLogs.obj = new EncryptedTxL2Logs([]);
125
- }
126
- const unencryptedLogs = toObject(encryptedLogs.remainingData, UnencryptedTxL2Logs);
127
- if (!unencryptedLogs.obj) {
128
- unencryptedLogs.obj = new UnencryptedTxL2Logs([]);
129
- }
130
-
131
- const publicCalls = toObjectArray(unencryptedLogs.remainingData, PublicCallRequest);
132
-
133
- const publicTeardownCall = toObject(publicCalls.remainingData, PublicCallRequest);
134
- return new Tx(
135
- publicInputs.obj!,
136
- clientIvcProof.obj!,
137
- noteEncryptedLogs.obj,
138
- encryptedLogs.obj,
139
- unencryptedLogs.obj,
140
- publicCalls.objects,
141
- publicTeardownCall.obj!,
142
- );
143
- }