@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.
- package/dest/client/index.d.ts +1 -1
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +3 -3
- package/dest/client/mocks.d.ts +5 -3
- package/dest/client/mocks.d.ts.map +1 -1
- package/dest/client/mocks.js +18 -9
- package/dest/client/p2p_client.d.ts +52 -22
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +125 -37
- package/dest/config.d.ts +2 -0
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +3 -2
- package/dest/service/libp2p_service.d.ts +1 -1
- package/dest/service/libp2p_service.d.ts.map +1 -1
- package/dest/service/libp2p_service.js +4 -3
- package/dest/service/tx_messages.d.ts +1 -19
- package/dest/service/tx_messages.d.ts.map +1 -1
- package/dest/service/tx_messages.js +2 -109
- package/dest/tx_pool/aztec_kv_tx_pool.d.ts +4 -6
- package/dest/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/tx_pool/aztec_kv_tx_pool.js +47 -16
- package/dest/tx_pool/memory_tx_pool.d.ts +6 -6
- package/dest/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/tx_pool/memory_tx_pool.js +36 -11
- package/dest/tx_pool/tx_pool.d.ts +19 -4
- package/dest/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/tx_pool/tx_pool_test_suite.js +16 -4
- package/package.json +6 -6
- package/src/client/index.ts +2 -2
- package/src/client/mocks.ts +20 -7
- package/src/client/p2p_client.ts +149 -48
- package/src/config.ts +5 -0
- package/src/service/libp2p_service.ts +3 -3
- package/src/service/tx_messages.ts +2 -123
- package/src/tx_pool/aztec_kv_tx_pool.ts +49 -15
- package/src/tx_pool/memory_tx_pool.ts +42 -11
- package/src/tx_pool/tx_pool.ts +22 -4
- 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
|
-
|
|
22
|
-
expect(
|
|
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,
|
|
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.
|
|
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.
|
|
60
|
-
"@aztec/circuits.js": "0.
|
|
61
|
-
"@aztec/foundation": "0.
|
|
62
|
-
"@aztec/kv-store": "0.
|
|
63
|
-
"@aztec/telemetry-client": "0.
|
|
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",
|
package/src/client/index.ts
CHANGED
|
@@ -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
|
};
|
package/src/client/mocks.ts
CHANGED
|
@@ -8,14 +8,23 @@ export class MockBlockSource implements L2BlockSource {
|
|
|
8
8
|
private l2Blocks: L2Block[] = [];
|
|
9
9
|
private txEffects: TxEffect[] = [];
|
|
10
10
|
|
|
11
|
-
constructor(
|
|
12
|
-
|
|
13
|
-
|
|
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(
|
|
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
|
/**
|
package/src/client/p2p_client.ts
CHANGED
|
@@ -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():
|
|
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):
|
|
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
|
-
|
|
94
|
-
*/
|
|
95
|
-
private blockDownloader: L2BlockDownloader;
|
|
99
|
+
/** L2 block download to stay in sync with latest blocks. */
|
|
100
|
+
private latestBlockDownloader: L2BlockDownloader;
|
|
96
101
|
|
|
97
|
-
/**
|
|
98
|
-
|
|
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
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
this.
|
|
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
|
|
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
|
|
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 (
|
|
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 ${
|
|
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
|
|
187
|
+
const processLatest = async () => {
|
|
175
188
|
while (!this.stopping) {
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
181
|
-
this.
|
|
182
|
-
this.
|
|
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.
|
|
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():
|
|
208
|
-
|
|
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):
|
|
217
|
-
return
|
|
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
|
|
261
|
-
return this.
|
|
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.
|
|
323
|
+
syncedToL2Block: this.getSyncedLatestBlockNum(),
|
|
272
324
|
} as P2PSyncState);
|
|
273
325
|
}
|
|
274
326
|
|
|
275
327
|
/**
|
|
276
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
|
357
|
+
private async handleLatestL2Blocks(blocks: L2Block[]): Promise<void> {
|
|
293
358
|
if (!blocks.length) {
|
|
294
359
|
return Promise.resolve();
|
|
295
360
|
}
|
|
296
|
-
await this.
|
|
361
|
+
await this.markTxsAsMinedFromBlocks(blocks);
|
|
297
362
|
const lastBlockNum = blocks[blocks.length - 1].number;
|
|
298
|
-
await this.
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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 =
|
|
242
|
+
const tx = Tx.fromBuffer(Buffer.from(data));
|
|
243
243
|
await this.processTxFromPeer(tx);
|
|
244
244
|
}
|
|
245
245
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
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 =
|
|
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
|
-
}
|