@aztec/prover-node 0.69.0 → 0.69.1-devnet
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/config.d.ts +4 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +17 -2
- package/dest/factory.d.ts +2 -0
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +8 -3
- package/dest/job/epoch-proving-job.d.ts +9 -4
- package/dest/job/epoch-proving-job.d.ts.map +1 -1
- package/dest/job/epoch-proving-job.js +72 -25
- package/dest/metrics.d.ts +2 -2
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +9 -4
- package/dest/prover-node.d.ts +23 -15
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +93 -14
- package/dest/test/index.d.ts +10 -0
- package/dest/test/index.d.ts.map +1 -0
- package/dest/test/index.js +4 -0
- package/package.json +20 -18
- package/src/config.ts +24 -6
- package/src/factory.ts +8 -2
- package/src/job/epoch-proving-job.ts +84 -36
- package/src/metrics.ts +9 -4
- package/src/prover-node.ts +130 -25
- package/src/test/index.ts +11 -0
package/dest/prover-node.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { __esDecorate, __runInitializers } from "tslib";
|
|
2
|
-
import { EpochProofQuotePayload, tryStop, } from '@aztec/circuit-types';
|
|
2
|
+
import { EpochProofQuotePayload, getTimestampRangeForEpoch, tryStop, } from '@aztec/circuit-types';
|
|
3
|
+
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
3
4
|
import { compact } from '@aztec/foundation/collection';
|
|
5
|
+
import { memoize } from '@aztec/foundation/decorators';
|
|
6
|
+
import { TimeoutError } from '@aztec/foundation/error';
|
|
4
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
5
9
|
import { DateProvider } from '@aztec/foundation/timer';
|
|
6
10
|
import { PublicProcessorFactory } from '@aztec/simulator';
|
|
7
11
|
import { Attributes, trackSpan } from '@aztec/telemetry-client';
|
|
@@ -17,6 +21,8 @@ let ProverNode = (() => {
|
|
|
17
21
|
var _a;
|
|
18
22
|
let _instanceExtraInitializers = [];
|
|
19
23
|
let _createProvingJob_decorators;
|
|
24
|
+
let _getL1Constants_decorators;
|
|
25
|
+
let _gatherEpochData_decorators;
|
|
20
26
|
return _a = class ProverNode {
|
|
21
27
|
constructor(prover, publisher, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, coordination, quoteProvider, quoteSigner, claimsMonitor, epochsMonitor, bondManager, telemetryClient, options = {}) {
|
|
22
28
|
this.prover = (__runInitializers(this, _instanceExtraInitializers), prover);
|
|
@@ -35,10 +41,14 @@ let ProverNode = (() => {
|
|
|
35
41
|
this.log = createLogger('prover-node');
|
|
36
42
|
this.dateProvider = new DateProvider();
|
|
37
43
|
this.jobs = new Map();
|
|
44
|
+
this.cachedEpochData = undefined;
|
|
38
45
|
this.options = {
|
|
39
46
|
pollingIntervalMs: 1000,
|
|
40
47
|
maxPendingJobs: 100,
|
|
41
48
|
maxParallelBlocksPerEpoch: 32,
|
|
49
|
+
txGatheringTimeoutMs: 60000,
|
|
50
|
+
txGatheringIntervalMs: 1000,
|
|
51
|
+
txGatheringMaxParallelRequests: 100,
|
|
42
52
|
...compact(options),
|
|
43
53
|
};
|
|
44
54
|
this.metrics = new ProverNodeMetrics(telemetryClient, 'ProverNode');
|
|
@@ -99,12 +109,11 @@ let ProverNode = (() => {
|
|
|
99
109
|
*/
|
|
100
110
|
async handleEpochCompleted(epochNumber) {
|
|
101
111
|
try {
|
|
112
|
+
// Gather data for the epoch
|
|
113
|
+
const epochData = await this.gatherEpochData(epochNumber);
|
|
114
|
+
const { blocks } = epochData;
|
|
115
|
+
this.cachedEpochData = { epochNumber, ...epochData };
|
|
102
116
|
// Construct a quote for the epoch
|
|
103
|
-
const blocks = await this.l2BlockSource.getBlocksForEpoch(epochNumber);
|
|
104
|
-
if (blocks.length === 0) {
|
|
105
|
-
this.log.info(`No blocks found for epoch ${epochNumber}`);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
117
|
const partialQuote = await this.quoteProvider.getQuote(Number(epochNumber), blocks);
|
|
109
118
|
if (!partialQuote) {
|
|
110
119
|
this.log.info(`No quote produced for epoch ${epochNumber}`);
|
|
@@ -198,10 +207,8 @@ let ProverNode = (() => {
|
|
|
198
207
|
throw new Error(`Maximum pending proving jobs ${this.options.maxPendingJobs} reached. Cannot create new job.`);
|
|
199
208
|
}
|
|
200
209
|
// Gather blocks for this epoch
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
throw new Error(`No blocks found for epoch ${epochNumber}`);
|
|
204
|
-
}
|
|
210
|
+
const cachedEpochData = this.cachedEpochData?.epochNumber === epochNumber ? this.cachedEpochData : undefined;
|
|
211
|
+
const { blocks, txs } = cachedEpochData ?? (await this.gatherEpochData(epochNumber));
|
|
205
212
|
const fromBlock = blocks[0].number;
|
|
206
213
|
const toBlock = blocks.at(-1).number;
|
|
207
214
|
// Fast forward world state to right before the target block and get a fork
|
|
@@ -213,13 +220,81 @@ let ProverNode = (() => {
|
|
|
213
220
|
this.jobs.delete(job.getId());
|
|
214
221
|
return Promise.resolve();
|
|
215
222
|
};
|
|
216
|
-
const
|
|
223
|
+
const [_, endTimestamp] = getTimestampRangeForEpoch(epochNumber + 1n, await this.getL1Constants());
|
|
224
|
+
const deadline = new Date(Number(endTimestamp) * 1000);
|
|
225
|
+
const job = this.doCreateEpochProvingJob(epochNumber, deadline, blocks, txs, publicProcessorFactory, cleanUp);
|
|
217
226
|
this.jobs.set(job.getId(), job);
|
|
218
227
|
return job;
|
|
219
228
|
}
|
|
229
|
+
getL1Constants() {
|
|
230
|
+
return this.l2BlockSource.getL1Constants();
|
|
231
|
+
}
|
|
232
|
+
async gatherEpochData(epochNumber) {
|
|
233
|
+
// Gather blocks for this epoch and their txs
|
|
234
|
+
const blocks = await this.gatherBlocks(epochNumber);
|
|
235
|
+
const txs = await this.gatherTxs(epochNumber, blocks);
|
|
236
|
+
return { blocks, txs };
|
|
237
|
+
}
|
|
238
|
+
async gatherBlocks(epochNumber) {
|
|
239
|
+
const blocks = await this.l2BlockSource.getBlocksForEpoch(epochNumber);
|
|
240
|
+
if (blocks.length === 0) {
|
|
241
|
+
throw new Error(`No blocks found for epoch ${epochNumber}`);
|
|
242
|
+
}
|
|
243
|
+
return blocks;
|
|
244
|
+
}
|
|
245
|
+
async gatherTxs(epochNumber, blocks) {
|
|
246
|
+
let txsToFind = [];
|
|
247
|
+
const txHashToBlock = new Map();
|
|
248
|
+
const results = new Map();
|
|
249
|
+
for (const block of blocks) {
|
|
250
|
+
for (const tx of block.body.txEffects) {
|
|
251
|
+
txsToFind.push(tx.txHash);
|
|
252
|
+
txHashToBlock.set(tx.txHash.toString(), block.number);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const totalTxsRequired = txsToFind.length;
|
|
256
|
+
this.log.info(`Gathering a total of ${totalTxsRequired} txs for epoch=${epochNumber} made up of ${blocks.length} blocks`, { epochNumber });
|
|
257
|
+
let iteration = 0;
|
|
258
|
+
try {
|
|
259
|
+
await retryUntil(async () => {
|
|
260
|
+
const batch = [...txsToFind];
|
|
261
|
+
txsToFind = [];
|
|
262
|
+
const batchResults = await asyncPool(this.options.txGatheringMaxParallelRequests, batch, async (txHash) => {
|
|
263
|
+
const tx = await this.coordination.getTxByHash(txHash);
|
|
264
|
+
return [txHash, tx];
|
|
265
|
+
});
|
|
266
|
+
let found = 0;
|
|
267
|
+
for (const [txHash, maybeTx] of batchResults) {
|
|
268
|
+
if (maybeTx) {
|
|
269
|
+
found++;
|
|
270
|
+
results.set(txHash.toString(), maybeTx);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
txsToFind.push(txHash);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
this.log.verbose(`Gathered ${found}/${batch.length} txs in iteration ${iteration} for epoch ${epochNumber}. In total ${results.size}/${totalTxsRequired} have been retrieved.`, { epochNumber });
|
|
277
|
+
iteration++;
|
|
278
|
+
// stop when we found all transactions
|
|
279
|
+
return txsToFind.length === 0;
|
|
280
|
+
}, 'Gather txs', this.options.txGatheringTimeoutMs / 1000, this.options.txGatheringIntervalMs / 1000);
|
|
281
|
+
}
|
|
282
|
+
catch (err) {
|
|
283
|
+
if (err && err instanceof TimeoutError) {
|
|
284
|
+
const notFoundList = txsToFind
|
|
285
|
+
.map(txHash => `${txHash.toString()} (block ${txHashToBlock.get(txHash.toString())})`)
|
|
286
|
+
.join(', ');
|
|
287
|
+
throw new Error(`Txs not found for epoch ${epochNumber}: ${notFoundList}`);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
throw err;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return Array.from(results.values());
|
|
294
|
+
}
|
|
220
295
|
/** Extracted for testing purposes. */
|
|
221
|
-
doCreateEpochProvingJob(epochNumber, blocks, publicProcessorFactory, cleanUp) {
|
|
222
|
-
return new EpochProvingJob(this.worldState, epochNumber, blocks, this.prover.createEpochProver(), publicProcessorFactory, this.publisher, this.l2BlockSource, this.l1ToL2MessageSource, this.
|
|
296
|
+
doCreateEpochProvingJob(epochNumber, deadline, blocks, txs, publicProcessorFactory, cleanUp) {
|
|
297
|
+
return new EpochProvingJob(this.worldState, epochNumber, blocks, txs, this.prover.createEpochProver(), publicProcessorFactory, this.publisher, this.l2BlockSource, this.l1ToL2MessageSource, this.metrics, deadline, { parallelBlockLimit: this.options.maxParallelBlocksPerEpoch }, cleanUp);
|
|
223
298
|
}
|
|
224
299
|
/** Extracted for testing purposes. */
|
|
225
300
|
async triggerMonitors() {
|
|
@@ -230,10 +305,14 @@ let ProverNode = (() => {
|
|
|
230
305
|
(() => {
|
|
231
306
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
232
307
|
_createProvingJob_decorators = [trackSpan('ProverNode.createProvingJob', epochNumber => ({ [Attributes.EPOCH_NUMBER]: Number(epochNumber) }))];
|
|
308
|
+
_getL1Constants_decorators = [memoize];
|
|
309
|
+
_gatherEpochData_decorators = [trackSpan('ProverNode.gatherEpochData', epochNumber => ({ [Attributes.EPOCH_NUMBER]: Number(epochNumber) }))];
|
|
233
310
|
__esDecorate(_a, null, _createProvingJob_decorators, { kind: "method", name: "createProvingJob", static: false, private: false, access: { has: obj => "createProvingJob" in obj, get: obj => obj.createProvingJob }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
311
|
+
__esDecorate(_a, null, _getL1Constants_decorators, { kind: "method", name: "getL1Constants", static: false, private: false, access: { has: obj => "getL1Constants" in obj, get: obj => obj.getL1Constants }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
312
|
+
__esDecorate(_a, null, _gatherEpochData_decorators, { kind: "method", name: "gatherEpochData", static: false, private: false, access: { has: obj => "gatherEpochData" in obj, get: obj => obj.gatherEpochData }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
234
313
|
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
235
314
|
})(),
|
|
236
315
|
_a;
|
|
237
316
|
})();
|
|
238
317
|
export { ProverNode };
|
|
239
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLW5vZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLW5vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFHTCxzQkFBc0IsRUFVdEIsT0FBTyxHQUNSLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFJdkQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFVBQVUsRUFBcUQsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHbkgsT0FBTyxFQUFFLGVBQWUsRUFBNkIsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFZakQ7Ozs7O0dBS0c7SUFDVSxVQUFVOzs7O3NCQUFWLFVBQVU7WUFXckIsWUFDbUIsTUFBMEIsRUFDMUIsU0FBc0IsRUFDdEIsYUFBNkMsRUFDN0MsbUJBQXdDLEVBQ3hDLGtCQUFzQyxFQUN0QyxVQUFrQyxFQUNsQyxZQUFpRCxFQUNqRCxhQUE0QixFQUM1QixXQUF3QixFQUN4QixhQUE0QixFQUM1QixhQUEyQixFQUMzQixXQUF3QixFQUN4QixlQUFnQyxFQUNqRCxVQUFzQyxFQUFFO2dCQWJ2QixXQUFNLElBWmQsbURBQVUsRUFZRixNQUFNLEVBQW9CO2dCQUMxQixjQUFTLEdBQVQsU0FBUyxDQUFhO2dCQUN0QixrQkFBYSxHQUFiLGFBQWEsQ0FBZ0M7Z0JBQzdDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7Z0JBQ3hDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7Z0JBQ3RDLGVBQVUsR0FBVixVQUFVLENBQXdCO2dCQUNsQyxp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
|
|
318
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLW5vZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLW5vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFHTCxzQkFBc0IsRUFZdEIseUJBQXlCLEVBQ3pCLE9BQU8sR0FDUixNQUFNLHNCQUFzQixDQUFDO0FBRTlCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUl2RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsVUFBVSxFQUFxRCxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUduSCxPQUFPLEVBQUUsZUFBZSxFQUE2QixNQUFNLDRCQUE0QixDQUFDO0FBQ3hGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQWVqRDs7Ozs7R0FLRztJQUNVLFVBQVU7Ozs7OztzQkFBVixVQUFVO1lBWXJCLFlBQ3FCLE1BQTBCLEVBQzFCLFNBQXNCLEVBQ3RCLGFBQTZDLEVBQzdDLG1CQUF3QyxFQUN4QyxrQkFBc0MsRUFDdEMsVUFBa0MsRUFDbEMsWUFBaUQsRUFDakQsYUFBNEIsRUFDNUIsV0FBd0IsRUFDeEIsYUFBNEIsRUFDNUIsYUFBMkIsRUFDM0IsV0FBd0IsRUFDeEIsZUFBZ0MsRUFDbkQsVUFBc0MsRUFBRTtnQkFickIsV0FB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
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type EpochProverManager } from '@aztec/circuit-types';
|
|
2
|
+
import { type L1Publisher } from '@aztec/sequencer-client';
|
|
3
|
+
import { ProverNode } from '../prover-node.js';
|
|
4
|
+
declare class TestProverNode_ extends ProverNode {
|
|
5
|
+
prover: EpochProverManager;
|
|
6
|
+
publisher: L1Publisher;
|
|
7
|
+
}
|
|
8
|
+
export type TestProverNode = TestProverNode_;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,cAAM,eAAgB,SAAQ,UAAU;IACtB,MAAM,EAAG,kBAAkB,CAAC;IAC5B,SAAS,EAAG,WAAW,CAAC;CACzC;AAED,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ProverNode } from '../prover-node.js';
|
|
2
|
+
class TestProverNode_ extends ProverNode {
|
|
3
|
+
}
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFL0MsTUFBTSxlQUFnQixTQUFRLFVBQVU7Q0FHdkMifQ==
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/prover-node",
|
|
3
|
-
"version": "0.69.
|
|
3
|
+
"version": "0.69.1-devnet",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
7
|
-
"./config": "./dest/config.js"
|
|
7
|
+
"./config": "./dest/config.js",
|
|
8
|
+
"./test": "./dest/test/index.js"
|
|
8
9
|
},
|
|
9
10
|
"inherits": [
|
|
10
11
|
"../package.common.json"
|
|
@@ -52,22 +53,23 @@
|
|
|
52
53
|
]
|
|
53
54
|
},
|
|
54
55
|
"dependencies": {
|
|
55
|
-
"@aztec/archiver": "0.69.
|
|
56
|
-
"@aztec/bb-prover": "0.69.
|
|
57
|
-
"@aztec/
|
|
58
|
-
"@aztec/
|
|
59
|
-
"@aztec/
|
|
60
|
-
"@aztec/
|
|
61
|
-
"@aztec/
|
|
62
|
-
"@aztec/
|
|
63
|
-
"@aztec/
|
|
64
|
-
"@aztec/
|
|
65
|
-
"@aztec/
|
|
66
|
-
"@aztec/
|
|
67
|
-
"@aztec/
|
|
68
|
-
"@aztec/
|
|
69
|
-
"@aztec/
|
|
70
|
-
"@aztec/
|
|
56
|
+
"@aztec/archiver": "0.69.1-devnet",
|
|
57
|
+
"@aztec/bb-prover": "0.69.1-devnet",
|
|
58
|
+
"@aztec/blob-sink": "0.69.1-devnet",
|
|
59
|
+
"@aztec/circuit-types": "0.69.1-devnet",
|
|
60
|
+
"@aztec/circuits.js": "0.69.1-devnet",
|
|
61
|
+
"@aztec/epoch-cache": "0.69.1-devnet",
|
|
62
|
+
"@aztec/ethereum": "0.69.1-devnet",
|
|
63
|
+
"@aztec/foundation": "0.69.1-devnet",
|
|
64
|
+
"@aztec/kv-store": "0.69.1-devnet",
|
|
65
|
+
"@aztec/l1-artifacts": "0.69.1-devnet",
|
|
66
|
+
"@aztec/p2p": "0.69.1-devnet",
|
|
67
|
+
"@aztec/prover-client": "0.69.1-devnet",
|
|
68
|
+
"@aztec/sequencer-client": "0.69.1-devnet",
|
|
69
|
+
"@aztec/simulator": "0.69.1-devnet",
|
|
70
|
+
"@aztec/telemetry-client": "0.69.1-devnet",
|
|
71
|
+
"@aztec/types": "0.69.1-devnet",
|
|
72
|
+
"@aztec/world-state": "0.69.1-devnet",
|
|
71
73
|
"source-map-support": "^0.5.21",
|
|
72
74
|
"tslib": "^2.4.0",
|
|
73
75
|
"viem": "^2.7.15"
|
package/src/config.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { type ArchiverConfig, archiverConfigMappings, getArchiverConfigFromEnv } from '@aztec/archiver/config';
|
|
2
2
|
import { type ACVMConfig, type BBConfig } from '@aztec/bb-prover/config';
|
|
3
|
-
import {
|
|
4
|
-
type ProverAgentConfig,
|
|
5
|
-
type ProverBrokerConfig,
|
|
6
|
-
proverAgentConfigMappings,
|
|
7
|
-
proverBrokerConfigMappings,
|
|
8
|
-
} from '@aztec/circuit-types/config';
|
|
9
3
|
import {
|
|
10
4
|
type ConfigMappingsType,
|
|
11
5
|
bigintConfigHelper,
|
|
@@ -14,6 +8,12 @@ import {
|
|
|
14
8
|
} from '@aztec/foundation/config';
|
|
15
9
|
import { type DataStoreConfig, dataConfigMappings, getDataConfigFromEnv } from '@aztec/kv-store/config';
|
|
16
10
|
import { type P2PConfig, getP2PConfigFromEnv, p2pConfigMappings } from '@aztec/p2p/config';
|
|
11
|
+
import {
|
|
12
|
+
type ProverAgentConfig,
|
|
13
|
+
type ProverBrokerConfig,
|
|
14
|
+
proverAgentConfigMappings,
|
|
15
|
+
proverBrokerConfigMappings,
|
|
16
|
+
} from '@aztec/prover-client/broker';
|
|
17
17
|
import {
|
|
18
18
|
type ProverClientConfig,
|
|
19
19
|
bbConfigMappings,
|
|
@@ -53,6 +53,9 @@ type SpecificProverNodeConfig = {
|
|
|
53
53
|
proverNodeMaxPendingJobs: number;
|
|
54
54
|
proverNodePollingIntervalMs: number;
|
|
55
55
|
proverNodeMaxParallelBlocksPerEpoch: number;
|
|
56
|
+
txGatheringTimeoutMs: number;
|
|
57
|
+
txGatheringIntervalMs: number;
|
|
58
|
+
txGatheringMaxParallelRequests: number;
|
|
56
59
|
};
|
|
57
60
|
|
|
58
61
|
export type QuoteProviderConfig = {
|
|
@@ -77,6 +80,21 @@ const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProverNodeCon
|
|
|
77
80
|
description: 'The Maximum number of blocks to process in parallel while proving an epoch',
|
|
78
81
|
...numberConfigHelper(32),
|
|
79
82
|
},
|
|
83
|
+
txGatheringTimeoutMs: {
|
|
84
|
+
env: 'PROVER_NODE_TX_GATHERING_TIMEOUT_MS',
|
|
85
|
+
description: 'The maximum amount of time to wait for tx data to be available',
|
|
86
|
+
...numberConfigHelper(60_000),
|
|
87
|
+
},
|
|
88
|
+
txGatheringIntervalMs: {
|
|
89
|
+
env: 'PROVER_NODE_TX_GATHERING_INTERVAL_MS',
|
|
90
|
+
description: 'How often to check that tx data is available',
|
|
91
|
+
...numberConfigHelper(1_000),
|
|
92
|
+
},
|
|
93
|
+
txGatheringMaxParallelRequests: {
|
|
94
|
+
env: 'PROVER_NODE_TX_GATHERING_MAX_PARALLEL_REQUESTS',
|
|
95
|
+
description: 'How many txs to load up a time',
|
|
96
|
+
...numberConfigHelper(100),
|
|
97
|
+
},
|
|
80
98
|
};
|
|
81
99
|
|
|
82
100
|
const quoteProviderConfigMappings: ConfigMappingsType<QuoteProviderConfig> = {
|
package/src/factory.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Archiver, createArchiver } from '@aztec/archiver';
|
|
2
|
+
import { type BlobSinkClientInterface, createBlobSinkClient } from '@aztec/blob-sink/client';
|
|
2
3
|
import { type ProverCoordination, type ProvingJobBroker } from '@aztec/circuit-types';
|
|
3
4
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
4
5
|
import { createEthereumChain } from '@aztec/ethereum';
|
|
@@ -34,12 +35,14 @@ export async function createProverNode(
|
|
|
34
35
|
aztecNodeTxProvider?: ProverCoordination;
|
|
35
36
|
archiver?: Archiver;
|
|
36
37
|
publisher?: L1Publisher;
|
|
38
|
+
blobSinkClient?: BlobSinkClientInterface;
|
|
37
39
|
broker?: ProvingJobBroker;
|
|
38
40
|
} = {},
|
|
39
41
|
) {
|
|
40
42
|
const telemetry = deps.telemetry ?? new NoopTelemetryClient();
|
|
43
|
+
const blobSinkClient = deps.blobSinkClient ?? createBlobSinkClient(config.blobSinkUrl);
|
|
41
44
|
const log = deps.log ?? createLogger('prover-node');
|
|
42
|
-
const archiver = deps.archiver ?? (await createArchiver(config, telemetry, { blockUntilSync: true }));
|
|
45
|
+
const archiver = deps.archiver ?? (await createArchiver(config, blobSinkClient, telemetry, { blockUntilSync: true }));
|
|
43
46
|
log.verbose(`Created archiver and synced to block ${await archiver.getBlockNumber()}`);
|
|
44
47
|
|
|
45
48
|
const worldStateConfig = { ...config, worldStateProvenBlocksOnly: false };
|
|
@@ -50,7 +53,7 @@ export async function createProverNode(
|
|
|
50
53
|
const prover = await createProverClient(config, worldStateSynchronizer, broker, telemetry);
|
|
51
54
|
|
|
52
55
|
// REFACTOR: Move publisher out of sequencer package and into an L1-related package
|
|
53
|
-
const publisher = deps.publisher ?? new L1Publisher(config, telemetry);
|
|
56
|
+
const publisher = deps.publisher ?? new L1Publisher(config, { telemetry, blobSinkClient });
|
|
54
57
|
|
|
55
58
|
const epochCache = await EpochCache.create(config.l1Contracts.rollupAddress, config);
|
|
56
59
|
|
|
@@ -71,6 +74,9 @@ export async function createProverNode(
|
|
|
71
74
|
maxPendingJobs: config.proverNodeMaxPendingJobs,
|
|
72
75
|
pollingIntervalMs: config.proverNodePollingIntervalMs,
|
|
73
76
|
maxParallelBlocksPerEpoch: config.proverNodeMaxParallelBlocksPerEpoch,
|
|
77
|
+
txGatheringMaxParallelRequests: config.txGatheringMaxParallelRequests,
|
|
78
|
+
txGatheringIntervalMs: config.txGatheringIntervalMs,
|
|
79
|
+
txGatheringTimeoutMs: config.txGatheringTimeoutMs,
|
|
74
80
|
};
|
|
75
81
|
|
|
76
82
|
const claimsMonitor = new ClaimsMonitor(publisher, telemetry, proverNodeConfig);
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
EmptyTxValidator,
|
|
3
2
|
type EpochProver,
|
|
4
3
|
type EpochProvingJobState,
|
|
4
|
+
EpochProvingJobTerminalState,
|
|
5
5
|
type ForkMerkleTreeOperations,
|
|
6
6
|
type L1ToL2MessageSource,
|
|
7
7
|
type L2Block,
|
|
8
8
|
type L2BlockSource,
|
|
9
9
|
type ProcessedTx,
|
|
10
|
-
type ProverCoordination,
|
|
11
10
|
type Tx,
|
|
12
|
-
type TxHash,
|
|
13
11
|
} from '@aztec/circuit-types';
|
|
14
12
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
15
13
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -34,6 +32,7 @@ export class EpochProvingJob implements Traceable {
|
|
|
34
32
|
private uuid: string;
|
|
35
33
|
|
|
36
34
|
private runPromise: Promise<void> | undefined;
|
|
35
|
+
private deadlineTimeoutHandler: NodeJS.Timeout | undefined;
|
|
37
36
|
|
|
38
37
|
public readonly tracer: Tracer;
|
|
39
38
|
|
|
@@ -41,13 +40,14 @@ export class EpochProvingJob implements Traceable {
|
|
|
41
40
|
private dbProvider: ForkMerkleTreeOperations,
|
|
42
41
|
private epochNumber: bigint,
|
|
43
42
|
private blocks: L2Block[],
|
|
43
|
+
private txs: Tx[],
|
|
44
44
|
private prover: EpochProver,
|
|
45
45
|
private publicProcessorFactory: PublicProcessorFactory,
|
|
46
46
|
private publisher: L1Publisher,
|
|
47
47
|
private l2BlockSource: L2BlockSource,
|
|
48
48
|
private l1ToL2MessageSource: L1ToL2MessageSource,
|
|
49
|
-
private coordination: ProverCoordination,
|
|
50
49
|
private metrics: ProverNodeMetrics,
|
|
50
|
+
private deadline: Date | undefined,
|
|
51
51
|
private config: { parallelBlockLimit: number } = { parallelBlockLimit: 32 },
|
|
52
52
|
private cleanUp: (job: EpochProvingJob) => Promise<void> = () => Promise.resolve(),
|
|
53
53
|
) {
|
|
@@ -70,9 +70,11 @@ export class EpochProvingJob implements Traceable {
|
|
|
70
70
|
return { [Attributes.EPOCH_NUMBER]: Number(this.epochNumber) };
|
|
71
71
|
})
|
|
72
72
|
public async run() {
|
|
73
|
+
this.scheduleDeadlineStop();
|
|
74
|
+
|
|
73
75
|
const epochNumber = Number(this.epochNumber);
|
|
74
76
|
const epochSizeBlocks = this.blocks.length;
|
|
75
|
-
const epochSizeTxs = this.blocks.reduce((total, current) => total + current.body.
|
|
77
|
+
const epochSizeTxs = this.blocks.reduce((total, current) => total + current.body.txEffects.length, 0);
|
|
76
78
|
const [fromBlock, toBlock] = [this.blocks[0].number, this.blocks.at(-1)!.number];
|
|
77
79
|
this.log.info(`Starting epoch ${epochNumber} proving job with blocks ${fromBlock} to ${toBlock}`, {
|
|
78
80
|
fromBlock,
|
|
@@ -81,21 +83,22 @@ export class EpochProvingJob implements Traceable {
|
|
|
81
83
|
epochNumber,
|
|
82
84
|
uuid: this.uuid,
|
|
83
85
|
});
|
|
84
|
-
this.state = 'processing';
|
|
85
|
-
const timer = new Timer();
|
|
86
86
|
|
|
87
|
+
this.progressState('processing');
|
|
88
|
+
const timer = new Timer();
|
|
87
89
|
const { promise, resolve } = promiseWithResolvers<void>();
|
|
88
90
|
this.runPromise = promise;
|
|
89
91
|
|
|
90
92
|
try {
|
|
91
93
|
this.prover.startNewEpoch(epochNumber, fromBlock, epochSizeBlocks);
|
|
94
|
+
this.prover.startTubeCircuits(this.txs);
|
|
92
95
|
|
|
93
96
|
await asyncPool(this.config.parallelBlockLimit, this.blocks, async block => {
|
|
97
|
+
this.checkState();
|
|
98
|
+
|
|
94
99
|
const globalVariables = block.header.globalVariables;
|
|
95
|
-
const
|
|
96
|
-
const txCount = block.body.numberOfTxsIncludingPadded;
|
|
100
|
+
const txs = this.getTxs(block);
|
|
97
101
|
const l1ToL2Messages = await this.getL1ToL2Messages(block);
|
|
98
|
-
const txs = await this.getTxs(txHashes, block.number);
|
|
99
102
|
const previousHeader = await this.getBlockHeader(block.number - 1);
|
|
100
103
|
|
|
101
104
|
this.log.verbose(`Starting processing block ${block.number}`, {
|
|
@@ -109,13 +112,14 @@ export class EpochProvingJob implements Traceable {
|
|
|
109
112
|
uuid: this.uuid,
|
|
110
113
|
...globalVariables,
|
|
111
114
|
});
|
|
115
|
+
|
|
112
116
|
// Start block proving
|
|
113
117
|
await this.prover.startNewBlock(globalVariables, l1ToL2Messages);
|
|
114
118
|
|
|
115
119
|
// Process public fns
|
|
116
120
|
const db = await this.dbProvider.fork(block.number - 1);
|
|
117
121
|
const publicProcessor = this.publicProcessorFactory.create(db, previousHeader, globalVariables, true);
|
|
118
|
-
const processed = await this.processTxs(publicProcessor, txs
|
|
122
|
+
const processed = await this.processTxs(publicProcessor, txs);
|
|
119
123
|
await this.prover.addTxs(processed);
|
|
120
124
|
await db.close();
|
|
121
125
|
this.log.verbose(`Processed all ${txs.length} txs for block ${block.number}`, {
|
|
@@ -128,32 +132,76 @@ export class EpochProvingJob implements Traceable {
|
|
|
128
132
|
await this.prover.setBlockCompleted(block.number, block.header);
|
|
129
133
|
});
|
|
130
134
|
|
|
131
|
-
|
|
135
|
+
const executionTime = timer.ms();
|
|
136
|
+
|
|
137
|
+
this.progressState('awaiting-prover');
|
|
132
138
|
const { publicInputs, proof } = await this.prover.finaliseEpoch();
|
|
133
139
|
this.log.info(`Finalised proof for epoch ${epochNumber}`, { epochNumber, uuid: this.uuid, duration: timer.ms() });
|
|
134
140
|
|
|
135
|
-
this.
|
|
136
|
-
await this.publisher.submitEpochProof({ fromBlock, toBlock, epochNumber, publicInputs, proof });
|
|
137
|
-
|
|
141
|
+
this.progressState('publishing-proof');
|
|
142
|
+
const success = await this.publisher.submitEpochProof({ fromBlock, toBlock, epochNumber, publicInputs, proof });
|
|
143
|
+
if (!success) {
|
|
144
|
+
throw new Error('Failed to submit epoch proof to L1');
|
|
145
|
+
}
|
|
138
146
|
|
|
147
|
+
this.log.info(`Submitted proof for epoch`, { epochNumber, uuid: this.uuid });
|
|
139
148
|
this.state = 'completed';
|
|
140
|
-
this.metrics.recordProvingJob(timer, epochSizeBlocks, epochSizeTxs);
|
|
141
|
-
} catch (err) {
|
|
149
|
+
this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeBlocks, epochSizeTxs);
|
|
150
|
+
} catch (err: any) {
|
|
151
|
+
if (err && err.name === 'HaltExecutionError') {
|
|
152
|
+
this.log.warn(`Halted execution of epoch ${epochNumber} prover job`, { uuid: this.uuid, epochNumber });
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
142
155
|
this.log.error(`Error running epoch ${epochNumber} prover job`, err, { uuid: this.uuid, epochNumber });
|
|
143
156
|
this.state = 'failed';
|
|
144
157
|
} finally {
|
|
158
|
+
clearTimeout(this.deadlineTimeoutHandler);
|
|
145
159
|
await this.cleanUp(this);
|
|
160
|
+
await this.prover.stop();
|
|
146
161
|
resolve();
|
|
147
162
|
}
|
|
148
163
|
}
|
|
149
164
|
|
|
150
|
-
|
|
165
|
+
private progressState(state: EpochProvingJobState) {
|
|
166
|
+
this.checkState();
|
|
167
|
+
this.state = state;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private checkState() {
|
|
171
|
+
if (this.state === 'timed-out' || this.state === 'stopped' || this.state === 'failed') {
|
|
172
|
+
throw new HaltExecutionError(this.state);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public async stop(state: EpochProvingJobState = 'stopped') {
|
|
177
|
+
this.state = state;
|
|
151
178
|
this.prover.cancel();
|
|
179
|
+
// TODO(palla/prover): Stop the publisher as well
|
|
152
180
|
if (this.runPromise) {
|
|
153
181
|
await this.runPromise;
|
|
154
182
|
}
|
|
155
183
|
}
|
|
156
184
|
|
|
185
|
+
private scheduleDeadlineStop() {
|
|
186
|
+
const deadline = this.deadline;
|
|
187
|
+
if (deadline) {
|
|
188
|
+
const timeout = deadline.getTime() - Date.now();
|
|
189
|
+
if (timeout <= 0) {
|
|
190
|
+
throw new Error('Cannot start job with deadline in the past');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
this.deadlineTimeoutHandler = setTimeout(() => {
|
|
194
|
+
if (EpochProvingJobTerminalState.includes(this.state)) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
this.log.warn('Stopping job due to deadline hit', { uuid: this.uuid, epochNumber: this.epochNumber });
|
|
198
|
+
this.stop('timed-out').catch(err => {
|
|
199
|
+
this.log.error('Error stopping job', err, { uuid: this.uuid, epochNumber: this.epochNumber });
|
|
200
|
+
});
|
|
201
|
+
}, timeout);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
157
205
|
/* Returns the header for the given block number, or undefined for block zero. */
|
|
158
206
|
private getBlockHeader(blockNumber: number) {
|
|
159
207
|
if (blockNumber === 0) {
|
|
@@ -162,38 +210,38 @@ export class EpochProvingJob implements Traceable {
|
|
|
162
210
|
return this.l2BlockSource.getBlockHeader(blockNumber);
|
|
163
211
|
}
|
|
164
212
|
|
|
165
|
-
private
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
);
|
|
169
|
-
const notFound = txs.filter(([_, tx]) => !tx);
|
|
170
|
-
if (notFound.length) {
|
|
171
|
-
throw new Error(
|
|
172
|
-
`Txs not found for block ${blockNumber}: ${notFound.map(([txHash]) => txHash.toString()).join(', ')}`,
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
return txs.map(([_, tx]) => tx!);
|
|
213
|
+
private getTxs(block: L2Block): Tx[] {
|
|
214
|
+
const txHashes = block.body.txEffects.map(tx => tx.txHash.toBigInt());
|
|
215
|
+
return this.txs.filter(tx => txHashes.includes(tx.getTxHash().toBigInt()));
|
|
176
216
|
}
|
|
177
217
|
|
|
178
218
|
private getL1ToL2Messages(block: L2Block) {
|
|
179
219
|
return this.l1ToL2MessageSource.getL1ToL2Messages(BigInt(block.number));
|
|
180
220
|
}
|
|
181
221
|
|
|
182
|
-
private async processTxs(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
totalNumberOfTxs: number,
|
|
186
|
-
): Promise<ProcessedTx[]> {
|
|
187
|
-
const [processedTxs, failedTxs] = await publicProcessor.process(txs, totalNumberOfTxs, new EmptyTxValidator());
|
|
222
|
+
private async processTxs(publicProcessor: PublicProcessor, txs: Tx[]): Promise<ProcessedTx[]> {
|
|
223
|
+
const { deadline } = this;
|
|
224
|
+
const [processedTxs, failedTxs] = await publicProcessor.process(txs, { deadline });
|
|
188
225
|
|
|
189
226
|
if (failedTxs.length) {
|
|
190
227
|
throw new Error(
|
|
191
|
-
`
|
|
228
|
+
`Txs failed processing: ${failedTxs.map(({ tx, error }) => `${tx.getTxHash()} (${error})`).join(', ')}`,
|
|
192
229
|
);
|
|
193
230
|
}
|
|
194
231
|
|
|
232
|
+
if (processedTxs.length !== txs.length) {
|
|
233
|
+
throw new Error(`Failed to process all txs: processed ${processedTxs.length} out of ${txs.length}`);
|
|
234
|
+
}
|
|
235
|
+
|
|
195
236
|
return processedTxs;
|
|
196
237
|
}
|
|
197
238
|
}
|
|
198
239
|
|
|
240
|
+
class HaltExecutionError extends Error {
|
|
241
|
+
constructor(state: EpochProvingJobState) {
|
|
242
|
+
super(`Halted execution due to state ${state}`);
|
|
243
|
+
this.name = 'HaltExecutionError';
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
199
247
|
export { type EpochProvingJobState };
|