@aztec/prover-node 0.0.1-commit.04852196a → 0.0.1-commit.04d373f
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/actions/download-epoch-proving-job.js +1 -1
- package/dest/actions/rerun-epoch-proving-job.d.ts +3 -2
- package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
- package/dest/actions/rerun-epoch-proving-job.js +8 -8
- package/dest/bin/run-failed-epoch.js +1 -3
- package/dest/config.js +1 -1
- package/dest/factory.d.ts +1 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +26 -6
- package/dest/job/epoch-proving-job.d.ts +6 -2
- package/dest/job/epoch-proving-job.d.ts.map +1 -1
- package/dest/job/epoch-proving-job.js +198 -38
- package/dest/metrics.d.ts +21 -1
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +47 -0
- package/dest/monitors/epoch-monitor.d.ts +1 -1
- package/dest/monitors/epoch-monitor.d.ts.map +1 -1
- package/dest/monitors/epoch-monitor.js +11 -9
- package/dest/prover-node-publisher.d.ts +20 -1
- package/dest/prover-node-publisher.d.ts.map +1 -1
- package/dest/prover-node-publisher.js +200 -5
- package/dest/prover-node.d.ts +1 -2
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +21 -19
- package/dest/prover-publisher-factory.d.ts +2 -2
- package/dest/prover-publisher-factory.d.ts.map +1 -1
- package/dest/prover-publisher-factory.js +3 -3
- package/package.json +23 -22
- package/src/actions/download-epoch-proving-job.ts +1 -1
- package/src/actions/rerun-epoch-proving-job.ts +16 -5
- package/src/bin/run-failed-epoch.ts +1 -2
- package/src/config.ts +1 -1
- package/src/factory.ts +21 -4
- package/src/job/epoch-proving-job.ts +120 -38
- package/src/metrics.ts +71 -0
- package/src/monitors/epoch-monitor.ts +5 -6
- package/src/prover-node-publisher.ts +232 -9
- package/src/prover-node.ts +17 -23
- package/src/prover-publisher-factory.ts +3 -3
package/dest/prover-node.js
CHANGED
|
@@ -451,7 +451,7 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
|
|
|
451
451
|
this.config = {
|
|
452
452
|
proverNodePollingIntervalMs: 1_000,
|
|
453
453
|
proverNodeMaxPendingJobs: 100,
|
|
454
|
-
proverNodeMaxParallelBlocksPerEpoch:
|
|
454
|
+
proverNodeMaxParallelBlocksPerEpoch: 0,
|
|
455
455
|
txGatheringIntervalMs: 1_000,
|
|
456
456
|
txGatheringBatchSize: 10,
|
|
457
457
|
txGatheringMaxParallelRequestsPerNode: 100,
|
|
@@ -519,10 +519,10 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
|
|
|
519
519
|
*/ async stop() {
|
|
520
520
|
this.log.info('Stopping ProverNode');
|
|
521
521
|
await this.epochsMonitor.stop();
|
|
522
|
-
await this.prover.stop();
|
|
523
|
-
await tryStop(this.publisherFactory);
|
|
524
522
|
this.publisher?.interrupt();
|
|
525
523
|
await Promise.all(Array.from(this.jobs.values()).map((job)=>job.stop()));
|
|
524
|
+
await this.prover.stop();
|
|
525
|
+
await tryStop(this.publisherFactory);
|
|
526
526
|
this.rewardsMetrics.stop();
|
|
527
527
|
this.l1Metrics.stop();
|
|
528
528
|
await this.telemetryClient.stop();
|
|
@@ -606,10 +606,12 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
|
|
|
606
606
|
const fromCheckpoint = epochData.checkpoints[0].number;
|
|
607
607
|
const toCheckpoint = epochData.checkpoints.at(-1).number;
|
|
608
608
|
const fromBlock = epochData.checkpoints[0].blocks[0].number;
|
|
609
|
-
const
|
|
609
|
+
const lastBlock = epochData.checkpoints.at(-1).blocks.at(-1);
|
|
610
|
+
const toBlock = lastBlock.number;
|
|
610
611
|
this.log.verbose(`Creating proving job for epoch ${epochNumber} for checkpoint range ${fromCheckpoint} to ${toCheckpoint} and block range ${fromBlock} to ${toBlock}`);
|
|
611
612
|
// Fast forward world state to right before the target block and get a fork
|
|
612
|
-
await
|
|
613
|
+
const lastBlockHash = await lastBlock.header.hash();
|
|
614
|
+
await this.worldState.syncImmediate(toBlock, lastBlockHash);
|
|
613
615
|
// Create a processor factory
|
|
614
616
|
const publicProcessorFactory = new PublicProcessorFactory(this.contractDataSource, this.dateProvider, this.telemetryClient, this.log.getBindings());
|
|
615
617
|
// Set deadline for this job to run. It will abort if it takes too long.
|
|
@@ -623,7 +625,14 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
|
|
|
623
625
|
return this.l2BlockSource.getL1Constants();
|
|
624
626
|
}
|
|
625
627
|
async gatherEpochData(epochNumber) {
|
|
626
|
-
const
|
|
628
|
+
const publishedCheckpoints = await this.l2BlockSource.getCheckpoints({
|
|
629
|
+
epoch: epochNumber
|
|
630
|
+
});
|
|
631
|
+
if (publishedCheckpoints.length === 0) {
|
|
632
|
+
throw new EmptyEpochError(epochNumber);
|
|
633
|
+
}
|
|
634
|
+
const checkpoints = publishedCheckpoints.map((p)=>p.checkpoint);
|
|
635
|
+
const attestations = publishedCheckpoints.at(-1)?.attestations ?? [];
|
|
627
636
|
const txArray = await this.gatherTxs(epochNumber, checkpoints);
|
|
628
637
|
const txs = new Map(txArray.map((tx)=>[
|
|
629
638
|
tx.getTxHash().toString(),
|
|
@@ -632,8 +641,6 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
|
|
|
632
641
|
const l1ToL2Messages = await this.gatherMessages(epochNumber, checkpoints);
|
|
633
642
|
const [firstBlock] = checkpoints[0].blocks;
|
|
634
643
|
const previousBlockHeader = await this.gatherPreviousBlockHeader(epochNumber, firstBlock.number - 1);
|
|
635
|
-
const [lastPublishedCheckpoint] = await this.l2BlockSource.getCheckpoints(checkpoints.at(-1).number, 1);
|
|
636
|
-
const attestations = lastPublishedCheckpoint?.attestations ?? [];
|
|
637
644
|
return {
|
|
638
645
|
checkpoints,
|
|
639
646
|
txs,
|
|
@@ -643,13 +650,6 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
|
|
|
643
650
|
attestations
|
|
644
651
|
};
|
|
645
652
|
}
|
|
646
|
-
async gatherCheckpoints(epochNumber) {
|
|
647
|
-
const checkpoints = await this.l2BlockSource.getCheckpointsForEpoch(epochNumber);
|
|
648
|
-
if (checkpoints.length === 0) {
|
|
649
|
-
throw new EmptyEpochError(epochNumber);
|
|
650
|
-
}
|
|
651
|
-
return checkpoints;
|
|
652
|
-
}
|
|
653
653
|
async gatherTxs(epochNumber, checkpoints) {
|
|
654
654
|
const deadline = new Date(this.dateProvider.now() + this.config.txGatheringTimeoutMs);
|
|
655
655
|
const txProvider = this.p2pClient.getTxProvider();
|
|
@@ -680,12 +680,14 @@ _dec = trackSpan('ProverNode.createProvingJob', (epochNumber)=>({
|
|
|
680
680
|
return messagesByCheckpoint;
|
|
681
681
|
}
|
|
682
682
|
async gatherPreviousBlockHeader(epochNumber, previousBlockNumber) {
|
|
683
|
-
const
|
|
684
|
-
|
|
683
|
+
const data = await this.l2BlockSource.getBlockData({
|
|
684
|
+
number: BlockNumber(previousBlockNumber)
|
|
685
|
+
});
|
|
686
|
+
if (!data?.header) {
|
|
685
687
|
throw new Error(`Previous block header ${previousBlockNumber} not found for proving epoch ${epochNumber}`);
|
|
686
688
|
}
|
|
687
|
-
this.log.verbose(`Gathered previous block header ${header.getBlockNumber()} for epoch ${epochNumber}`);
|
|
688
|
-
return header;
|
|
689
|
+
this.log.verbose(`Gathered previous block header ${data.header.getBlockNumber()} for epoch ${epochNumber}`);
|
|
690
|
+
return data.header;
|
|
689
691
|
}
|
|
690
692
|
/** Extracted for testing purposes. */ doCreateEpochProvingJob(data, deadline, publicProcessorFactory, publisher, opts = {}) {
|
|
691
693
|
const { proverNodeMaxParallelBlocksPerEpoch: parallelBlockLimit, proverNodeDisableProofPublish } = this.config;
|
|
@@ -15,11 +15,11 @@ export declare class ProverPublisherFactory {
|
|
|
15
15
|
telemetry?: TelemetryClient;
|
|
16
16
|
}, bindings?: LoggerBindings | undefined);
|
|
17
17
|
start(): Promise<void>;
|
|
18
|
-
stop(): void
|
|
18
|
+
stop(): Promise<void>;
|
|
19
19
|
/**
|
|
20
20
|
* Creates a new Prover Publisher instance.
|
|
21
21
|
* @returns A new ProverNodePublisher instance.
|
|
22
22
|
*/
|
|
23
23
|
create(): Promise<ProverNodePublisher>;
|
|
24
24
|
}
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLXB1Ymxpc2hlci1mYWN0b3J5LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLXB1Ymxpc2hlci1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDMUUsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRixPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUUvRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVqRSxxQkFBYSxzQkFBc0I7SUFFL0IsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsSUFBSTtJQUtaLE9BQU8sQ0FBQyxRQUFRLENBQUM7SUFQbkIsWUFDVSxNQUFNLEVBQUUsb0JBQW9CLEdBQUcscUJBQXFCLEVBQ3BELElBQUksRUFBRTtRQUNaLGNBQWMsRUFBRSxjQUFjLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUMsU0FBUyxDQUFDLEVBQUUsZUFBZSxDQUFDO0tBQzdCLEVBQ08sUUFBUSxDQUFDLDRCQUFnQixFQUMvQjtJQUVTLEtBQUssa0JBRWpCO0lBRVksSUFBSSxrQkFFaEI7SUFFRDs7O09BR0c7SUFDVSxNQUFNLElBQUksT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBV2xEO0NBQ0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prover-publisher-factory.d.ts","sourceRoot":"","sources":["../src/prover-publisher-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,QAAQ,CAAC;IAPnB,YACU,MAAM,EAAE,oBAAoB,GAAG,qBAAqB,EACpD,IAAI,EAAE;QACZ,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC9C,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B,EACO,QAAQ,CAAC,4BAAgB,EAC/B;IAES,KAAK,kBAEjB;
|
|
1
|
+
{"version":3,"file":"prover-publisher-factory.d.ts","sourceRoot":"","sources":["../src/prover-publisher-factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,QAAQ,CAAC;IAPnB,YACU,MAAM,EAAE,oBAAoB,GAAG,qBAAqB,EACpD,IAAI,EAAE;QACZ,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC9C,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B,EACO,QAAQ,CAAC,4BAAgB,EAC/B;IAES,KAAK,kBAEjB;IAEY,IAAI,kBAEhB;IAED;;;OAGG;IACU,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAWlD;CACF"}
|
|
@@ -9,10 +9,10 @@ export class ProverPublisherFactory {
|
|
|
9
9
|
this.bindings = bindings;
|
|
10
10
|
}
|
|
11
11
|
async start() {
|
|
12
|
-
await this.deps.publisherManager.
|
|
12
|
+
await this.deps.publisherManager.start();
|
|
13
13
|
}
|
|
14
|
-
stop() {
|
|
15
|
-
this.deps.publisherManager.
|
|
14
|
+
async stop() {
|
|
15
|
+
await this.deps.publisherManager.stop();
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* Creates a new Prover Publisher instance.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/prover-node",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.04d373f",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -56,27 +56,28 @@
|
|
|
56
56
|
]
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
60
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
61
|
-
"@aztec/blob-client": "0.0.1-commit.
|
|
62
|
-
"@aztec/blob-lib": "0.0.1-commit.
|
|
63
|
-
"@aztec/constants": "0.0.1-commit.
|
|
64
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
65
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
66
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
67
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
68
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
69
|
-
"@aztec/
|
|
70
|
-
"@aztec/node-
|
|
71
|
-
"@aztec/
|
|
72
|
-
"@aztec/
|
|
73
|
-
"@aztec/
|
|
74
|
-
"@aztec/
|
|
75
|
-
"@aztec/
|
|
76
|
-
"@aztec/
|
|
77
|
-
"@aztec/
|
|
78
|
-
"@aztec/
|
|
79
|
-
"@aztec/
|
|
59
|
+
"@aztec/archiver": "0.0.1-commit.04d373f",
|
|
60
|
+
"@aztec/bb-prover": "0.0.1-commit.04d373f",
|
|
61
|
+
"@aztec/blob-client": "0.0.1-commit.04d373f",
|
|
62
|
+
"@aztec/blob-lib": "0.0.1-commit.04d373f",
|
|
63
|
+
"@aztec/constants": "0.0.1-commit.04d373f",
|
|
64
|
+
"@aztec/epoch-cache": "0.0.1-commit.04d373f",
|
|
65
|
+
"@aztec/ethereum": "0.0.1-commit.04d373f",
|
|
66
|
+
"@aztec/foundation": "0.0.1-commit.04d373f",
|
|
67
|
+
"@aztec/kv-store": "0.0.1-commit.04d373f",
|
|
68
|
+
"@aztec/l1-artifacts": "0.0.1-commit.04d373f",
|
|
69
|
+
"@aztec/native": "0.0.1-commit.04d373f",
|
|
70
|
+
"@aztec/node-keystore": "0.0.1-commit.04d373f",
|
|
71
|
+
"@aztec/node-lib": "0.0.1-commit.04d373f",
|
|
72
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.04d373f",
|
|
73
|
+
"@aztec/p2p": "0.0.1-commit.04d373f",
|
|
74
|
+
"@aztec/protocol-contracts": "0.0.1-commit.04d373f",
|
|
75
|
+
"@aztec/prover-client": "0.0.1-commit.04d373f",
|
|
76
|
+
"@aztec/sequencer-client": "0.0.1-commit.04d373f",
|
|
77
|
+
"@aztec/simulator": "0.0.1-commit.04d373f",
|
|
78
|
+
"@aztec/stdlib": "0.0.1-commit.04d373f",
|
|
79
|
+
"@aztec/telemetry-client": "0.0.1-commit.04d373f",
|
|
80
|
+
"@aztec/world-state": "0.0.1-commit.04d373f",
|
|
80
81
|
"source-map-support": "^0.5.21",
|
|
81
82
|
"tslib": "^2.4.0",
|
|
82
83
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
@@ -30,7 +30,7 @@ export async function downloadEpochProvingJob(
|
|
|
30
30
|
|
|
31
31
|
const dataUrls = makeSnapshotPaths(location);
|
|
32
32
|
log.info(`Downloading state snapshot from ${location} to local data directory`, { metadata, dataUrls });
|
|
33
|
-
await snapshotSync({ dataUrls }, log, { ...config, ...metadata,
|
|
33
|
+
await snapshotSync({ dataUrls }, log, { ...config, ...metadata, fileStore });
|
|
34
34
|
|
|
35
35
|
const dataPath = urlJoin(location, 'data.bin');
|
|
36
36
|
const localPath = config.jobDataDownloadPath;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { createArchiverStore } from '@aztec/archiver';
|
|
1
|
+
import { createArchiverStore, createContractDataSource } from '@aztec/archiver';
|
|
2
2
|
import type { L1ContractsConfig } from '@aztec/ethereum/config';
|
|
3
3
|
import type { Logger } from '@aztec/foundation/log';
|
|
4
4
|
import { type ProverClientConfig, createProverClient } from '@aztec/prover-client';
|
|
5
5
|
import { ProverBrokerConfig, createAndStartProvingBroker } from '@aztec/prover-client/broker';
|
|
6
6
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
7
7
|
import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
|
|
8
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
8
9
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
9
10
|
import { createWorldState } from '@aztec/world-state';
|
|
10
11
|
|
|
@@ -23,17 +24,27 @@ export async function rerunEpochProvingJob(
|
|
|
23
24
|
localPath: string,
|
|
24
25
|
log: Logger,
|
|
25
26
|
config: DataStoreConfig & ProverBrokerConfig & ProverClientConfig & Pick<L1ContractsConfig, 'aztecEpochDuration'>,
|
|
27
|
+
genesis?: GenesisData,
|
|
26
28
|
) {
|
|
27
29
|
const jobData = deserializeEpochProvingJobData(readFileSync(localPath));
|
|
28
30
|
log.info(`Loaded proving job data for epoch ${jobData.epochNumber}`);
|
|
29
31
|
|
|
30
32
|
const telemetry = getTelemetryClient();
|
|
31
33
|
const metrics = new ProverNodeJobMetrics(telemetry.getMeter('prover-job'), telemetry.getTracer('prover-job'));
|
|
32
|
-
const worldState = await createWorldState(config);
|
|
33
|
-
const
|
|
34
|
-
const
|
|
34
|
+
const worldState = await createWorldState(config, genesis);
|
|
35
|
+
const initialBlockHash = await worldState.getInitialHeader().hash();
|
|
36
|
+
const archiver = await createArchiverStore(config, initialBlockHash);
|
|
37
|
+
const publicProcessorFactory = new PublicProcessorFactory(
|
|
38
|
+
createContractDataSource(archiver),
|
|
39
|
+
undefined,
|
|
40
|
+
undefined,
|
|
41
|
+
log.getBindings(),
|
|
42
|
+
);
|
|
35
43
|
|
|
36
|
-
const publisher = {
|
|
44
|
+
const publisher = {
|
|
45
|
+
submitEpochProof: () => Promise.resolve(true),
|
|
46
|
+
analyzeEpochProofSubmission: () => Promise.resolve(),
|
|
47
|
+
};
|
|
37
48
|
const l2BlockSourceForReorgDetection = undefined;
|
|
38
49
|
const deadline = undefined;
|
|
39
50
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
3
|
-
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
4
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
4
|
import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
|
|
6
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -50,7 +49,7 @@ async function rerunFailedEpoch(provingJobUrl: string, baseLocalDir: string) {
|
|
|
50
49
|
logger.info(`Rerunning proving job from ${jobPath} with state from ${dataDir}`, metadata);
|
|
51
50
|
const result = await rerunEpochProvingJob(jobPath, logger, {
|
|
52
51
|
...config,
|
|
53
|
-
|
|
52
|
+
rollupAddress: metadata.rollupAddress,
|
|
54
53
|
rollupVersion: metadata.rollupVersion,
|
|
55
54
|
});
|
|
56
55
|
|
package/src/config.ts
CHANGED
|
@@ -60,7 +60,7 @@ export const specificProverNodeConfigMappings: ConfigMappingsType<SpecificProver
|
|
|
60
60
|
proverNodeMaxParallelBlocksPerEpoch: {
|
|
61
61
|
env: 'PROVER_NODE_MAX_PARALLEL_BLOCKS_PER_EPOCH',
|
|
62
62
|
description: 'The Maximum number of blocks to process in parallel while proving an epoch',
|
|
63
|
-
...numberConfigHelper(
|
|
63
|
+
...numberConfigHelper(0),
|
|
64
64
|
},
|
|
65
65
|
proverNodeFailedEpochStore: {
|
|
66
66
|
env: 'PROVER_NODE_FAILED_EPOCH_STORE',
|
package/src/factory.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { BlobClientInterface } from '@aztec/blob-client/client';
|
|
|
3
3
|
import { Blob } from '@aztec/blob-lib';
|
|
4
4
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
5
5
|
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
6
|
+
import { makeL1HttpTransport } from '@aztec/ethereum/client';
|
|
6
7
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
7
8
|
import { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
8
9
|
import { PublisherManager } from '@aztec/ethereum/publisher-manager';
|
|
@@ -27,7 +28,7 @@ import type {
|
|
|
27
28
|
} from '@aztec/stdlib/interfaces/server';
|
|
28
29
|
import { L1Metrics, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
29
30
|
|
|
30
|
-
import { createPublicClient
|
|
31
|
+
import { createPublicClient } from 'viem';
|
|
31
32
|
|
|
32
33
|
import type { SpecificProverNodeConfig } from './config.js';
|
|
33
34
|
import { EpochMonitor } from './monitors/epoch-monitor.js';
|
|
@@ -95,11 +96,11 @@ export async function createProverNode(
|
|
|
95
96
|
|
|
96
97
|
const publicClient = createPublicClient({
|
|
97
98
|
chain: chain.chainInfo,
|
|
98
|
-
transport:
|
|
99
|
+
transport: makeL1HttpTransport(config.l1RpcUrls, { timeout: config.l1HttpTimeoutMS }),
|
|
99
100
|
pollingInterval: config.viemPollingIntervalMS,
|
|
100
101
|
});
|
|
101
102
|
|
|
102
|
-
const rollupContract = new RollupContract(publicClient, config.
|
|
103
|
+
const rollupContract = new RollupContract(publicClient, config.rollupAddress.toString());
|
|
103
104
|
|
|
104
105
|
const l1TxUtils = deps.l1TxUtils
|
|
105
106
|
? [deps.l1TxUtils]
|
|
@@ -118,11 +119,27 @@ export async function createProverNode(
|
|
|
118
119
|
{ telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
|
|
119
120
|
);
|
|
120
121
|
|
|
122
|
+
// Create a funder L1TxUtils from the keystore funding account (if configured)
|
|
123
|
+
const fundingSigner = keyStoreManager?.createFundingSigner();
|
|
124
|
+
let funderL1TxUtils: L1TxUtils | undefined;
|
|
125
|
+
if (fundingSigner) {
|
|
126
|
+
const [funder] = await createL1TxUtilsFromSigners(
|
|
127
|
+
publicClient,
|
|
128
|
+
[fundingSigner],
|
|
129
|
+
{ ...config, scope: 'prover' },
|
|
130
|
+
{ telemetry, logger: log.createChild('l1-tx-utils:funder'), dateProvider },
|
|
131
|
+
);
|
|
132
|
+
funderL1TxUtils = funder;
|
|
133
|
+
}
|
|
134
|
+
|
|
121
135
|
const publisherFactory =
|
|
122
136
|
deps.publisherFactory ??
|
|
123
137
|
new ProverPublisherFactory(config, {
|
|
124
138
|
rollupContract,
|
|
125
|
-
publisherManager: new PublisherManager(l1TxUtils, getPublisherConfigFromProverConfig(config),
|
|
139
|
+
publisherManager: new PublisherManager(l1TxUtils, getPublisherConfigFromProverConfig(config), {
|
|
140
|
+
bindings: log.getBindings(),
|
|
141
|
+
funder: funderL1TxUtils,
|
|
142
|
+
}),
|
|
126
143
|
telemetry,
|
|
127
144
|
});
|
|
128
145
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
|
|
2
1
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
3
2
|
import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
4
|
-
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
5
3
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
6
4
|
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
7
5
|
import { RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
8
6
|
import { Timer } from '@aztec/foundation/timer';
|
|
7
|
+
import { AVM_MAX_CONCURRENT_SIMULATIONS } from '@aztec/native';
|
|
9
8
|
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
10
9
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
11
10
|
import { buildFinalBlobChallenges } from '@aztec/prover-client/helpers';
|
|
@@ -19,8 +18,8 @@ import {
|
|
|
19
18
|
EpochProvingJobTerminalState,
|
|
20
19
|
type ForkMerkleTreeOperations,
|
|
21
20
|
} from '@aztec/stdlib/interfaces/server';
|
|
21
|
+
import { appendL1ToL2MessagesToTree } from '@aztec/stdlib/messaging';
|
|
22
22
|
import { CheckpointConstantData } from '@aztec/stdlib/rollup';
|
|
23
|
-
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
24
23
|
import type { ProcessedTx, Tx } from '@aztec/stdlib/tx';
|
|
25
24
|
import { Attributes, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
|
|
26
25
|
|
|
@@ -47,6 +46,7 @@ export class EpochProvingJob implements Traceable {
|
|
|
47
46
|
private uuid: string;
|
|
48
47
|
|
|
49
48
|
private runPromise: Promise<void> | undefined;
|
|
49
|
+
private abortController = new AbortController();
|
|
50
50
|
private epochCheckPromise: RunningPromise | undefined;
|
|
51
51
|
private deadlineTimeoutHandler: NodeJS.Timeout | undefined;
|
|
52
52
|
|
|
@@ -57,7 +57,7 @@ export class EpochProvingJob implements Traceable {
|
|
|
57
57
|
private dbProvider: Pick<ForkMerkleTreeOperations, 'fork'>,
|
|
58
58
|
private prover: EpochProver,
|
|
59
59
|
private publicProcessorFactory: PublicProcessorFactory,
|
|
60
|
-
private publisher: Pick<ProverNodePublisher, 'submitEpochProof'>,
|
|
60
|
+
private publisher: Pick<ProverNodePublisher, 'submitEpochProof' | 'analyzeEpochProofSubmission'>,
|
|
61
61
|
private l2BlockSource: L2BlockSource | undefined,
|
|
62
62
|
private metrics: ProverNodeJobMetrics,
|
|
63
63
|
private deadline: Date | undefined,
|
|
@@ -148,21 +148,32 @@ export class EpochProvingJob implements Traceable {
|
|
|
148
148
|
this.runPromise = promise;
|
|
149
149
|
|
|
150
150
|
try {
|
|
151
|
+
const blobTimer = new Timer();
|
|
151
152
|
const blobFieldsPerCheckpoint = this.checkpoints.map(checkpoint => checkpoint.toBlobFields());
|
|
152
|
-
this.log.info(`Blob fields per checkpoint: ${timer.ms()}ms`);
|
|
153
153
|
const finalBlobBatchingChallenges = await buildFinalBlobChallenges(blobFieldsPerCheckpoint);
|
|
154
|
-
this.
|
|
154
|
+
this.metrics.recordBlobProcessing(blobTimer.ms());
|
|
155
155
|
|
|
156
156
|
this.prover.startNewEpoch(epochNumber, epochSizeCheckpoints, finalBlobBatchingChallenges);
|
|
157
|
+
const chonkTimer = new Timer();
|
|
157
158
|
await this.prover.startChonkVerifierCircuits(Array.from(this.txs.values()));
|
|
159
|
+
this.metrics.recordChonkVerifier(chonkTimer.ms());
|
|
158
160
|
|
|
159
161
|
// Everything in the epoch should have the same chainId and version.
|
|
160
162
|
const { chainId, version } = this.checkpoints[0].blocks[0].header.globalVariables;
|
|
161
163
|
|
|
162
164
|
const previousBlockHeaders = this.gatherPreviousBlockHeaders();
|
|
163
165
|
|
|
164
|
-
|
|
166
|
+
const allCheckpointsTimer = new Timer();
|
|
167
|
+
|
|
168
|
+
const parallelism = this.config.parallelBlockLimit
|
|
169
|
+
? this.config.parallelBlockLimit
|
|
170
|
+
: AVM_MAX_CONCURRENT_SIMULATIONS > 0
|
|
171
|
+
? AVM_MAX_CONCURRENT_SIMULATIONS
|
|
172
|
+
: this.checkpoints.length;
|
|
173
|
+
|
|
174
|
+
await this.processCheckpoints(parallelism, async checkpoint => {
|
|
165
175
|
this.checkState();
|
|
176
|
+
const checkpointTimer = new Timer();
|
|
166
177
|
|
|
167
178
|
const checkpointIndex = checkpoint.number - fromCheckpoint;
|
|
168
179
|
const checkpointConstants = CheckpointConstantData.from({
|
|
@@ -179,11 +190,12 @@ export class EpochProvingJob implements Traceable {
|
|
|
179
190
|
const previousHeader = previousBlockHeaders[checkpointIndex];
|
|
180
191
|
const l1ToL2Messages = this.getL1ToL2Messages(checkpoint);
|
|
181
192
|
|
|
182
|
-
this.log.
|
|
193
|
+
this.log.debug(`Starting processing checkpoint ${checkpoint.number}`, {
|
|
183
194
|
number: checkpoint.number,
|
|
184
195
|
checkpointHash: checkpoint.hash().toString(),
|
|
185
|
-
|
|
186
|
-
|
|
196
|
+
headerHash: checkpoint.header.hash().toString(),
|
|
197
|
+
numL1ToL2Messages: l1ToL2Messages.length,
|
|
198
|
+
previousBlockNumber: previousHeader.globalVariables.blockNumber,
|
|
187
199
|
uuid: this.uuid,
|
|
188
200
|
});
|
|
189
201
|
|
|
@@ -196,6 +208,7 @@ export class EpochProvingJob implements Traceable {
|
|
|
196
208
|
);
|
|
197
209
|
|
|
198
210
|
for (let blockIndex = 0; blockIndex < checkpoint.blocks.length; blockIndex++) {
|
|
211
|
+
const blockTimer = new Timer();
|
|
199
212
|
const block = checkpoint.blocks[blockIndex];
|
|
200
213
|
const globalVariables = block.header.globalVariables;
|
|
201
214
|
const txs = this.getTxs(block);
|
|
@@ -216,22 +229,26 @@ export class EpochProvingJob implements Traceable {
|
|
|
216
229
|
|
|
217
230
|
// Process public fns. L1 to L2 messages are only inserted for the first block of a checkpoint,
|
|
218
231
|
// as the fork for subsequent blocks already includes them from the previous block's synced state.
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
{
|
|
233
|
+
await using db = await this.createFork(
|
|
234
|
+
BlockNumber(block.number - 1),
|
|
235
|
+
blockIndex === 0 ? l1ToL2Messages : undefined,
|
|
236
|
+
);
|
|
237
|
+
this.checkState();
|
|
238
|
+
const config = PublicSimulatorConfig.from({
|
|
239
|
+
proverId: this.prover.getProverId().toField(),
|
|
240
|
+
skipFeeEnforcement: false,
|
|
241
|
+
collectDebugLogs: false,
|
|
242
|
+
collectHints: true,
|
|
243
|
+
collectPublicInputs: true,
|
|
244
|
+
collectStatistics: false,
|
|
245
|
+
});
|
|
246
|
+
const publicProcessor = this.publicProcessorFactory.create(db, globalVariables, config);
|
|
247
|
+
const processed = await this.processTxs(publicProcessor, txs);
|
|
248
|
+
this.checkState();
|
|
249
|
+
await this.prover.addTxs(processed);
|
|
250
|
+
}
|
|
251
|
+
this.checkState();
|
|
235
252
|
this.log.verbose(`Processed all ${txs.length} txs for block ${block.number}`, {
|
|
236
253
|
blockNumber: block.number,
|
|
237
254
|
blockHash: (await block.hash()).toString(),
|
|
@@ -241,8 +258,11 @@ export class EpochProvingJob implements Traceable {
|
|
|
241
258
|
// Mark block as completed to pad it
|
|
242
259
|
const expectedBlockHeader = block.header;
|
|
243
260
|
await this.prover.setBlockCompleted(block.number, expectedBlockHeader);
|
|
261
|
+
this.metrics.recordBlockProcessing(blockTimer.ms());
|
|
244
262
|
}
|
|
263
|
+
this.metrics.recordCheckpointProcessing(checkpointTimer.ms());
|
|
245
264
|
});
|
|
265
|
+
this.metrics.recordAllCheckpointsProcessing(allCheckpointsTimer.ms());
|
|
246
266
|
|
|
247
267
|
const executionTime = timer.ms();
|
|
248
268
|
|
|
@@ -254,8 +274,21 @@ export class EpochProvingJob implements Traceable {
|
|
|
254
274
|
|
|
255
275
|
if (this.config.skipSubmitProof) {
|
|
256
276
|
this.log.info(
|
|
257
|
-
`Proof publishing is disabled.
|
|
277
|
+
`Proof publishing is disabled. Analyzing estimated L1 fees for epoch ${epochNumber} (checkpoints ${fromCheckpoint} to ${toCheckpoint})`,
|
|
258
278
|
);
|
|
279
|
+
try {
|
|
280
|
+
await this.publisher.analyzeEpochProofSubmission({
|
|
281
|
+
fromCheckpoint,
|
|
282
|
+
toCheckpoint,
|
|
283
|
+
epochNumber,
|
|
284
|
+
publicInputs,
|
|
285
|
+
proof,
|
|
286
|
+
batchedBlobInputs,
|
|
287
|
+
attestations,
|
|
288
|
+
});
|
|
289
|
+
} catch (err) {
|
|
290
|
+
this.log.warn(`Failed to analyze estimated L1 fees for epoch ${epochNumber}`, err);
|
|
291
|
+
}
|
|
259
292
|
this.state = 'completed';
|
|
260
293
|
this.metrics.recordProvingJob(executionTime, timer.ms(), epochSizeCheckpoints, epochSizeBlocks, epochSizeTxs);
|
|
261
294
|
return;
|
|
@@ -309,25 +342,56 @@ export class EpochProvingJob implements Traceable {
|
|
|
309
342
|
*/
|
|
310
343
|
private async createFork(blockNumber: BlockNumber, l1ToL2Messages: Fr[] | undefined) {
|
|
311
344
|
this.log.verbose(`Creating fork at ${blockNumber}`, { blockNumber });
|
|
312
|
-
|
|
345
|
+
// temporary stack to control fork lifetime
|
|
346
|
+
await using cleanup = new AsyncDisposableStack();
|
|
347
|
+
const db = cleanup.use(await this.dbProvider.fork(blockNumber));
|
|
313
348
|
|
|
314
349
|
if (l1ToL2Messages !== undefined) {
|
|
315
350
|
this.log.verbose(`Inserting ${l1ToL2Messages.length} L1 to L2 messages in fork`, {
|
|
316
351
|
blockNumber,
|
|
317
352
|
l1ToL2Messages: l1ToL2Messages.map(m => m.toString()),
|
|
318
353
|
});
|
|
319
|
-
|
|
320
|
-
l1ToL2Messages,
|
|
321
|
-
Fr.ZERO,
|
|
322
|
-
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
323
|
-
'Too many L1 to L2 messages',
|
|
324
|
-
);
|
|
325
|
-
await db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
|
|
354
|
+
await appendL1ToL2MessagesToTree(db, l1ToL2Messages);
|
|
326
355
|
}
|
|
327
356
|
|
|
357
|
+
// everything run succesfully so we can release this stack and give control of the fork's lifetime to the caller
|
|
358
|
+
cleanup.move();
|
|
328
359
|
return db;
|
|
329
360
|
}
|
|
330
361
|
|
|
362
|
+
private async processCheckpoints(
|
|
363
|
+
parallelism: number,
|
|
364
|
+
processCheckpoint: (checkpoint: Checkpoint) => Promise<void>,
|
|
365
|
+
): Promise<void> {
|
|
366
|
+
let hasError = false;
|
|
367
|
+
let firstError: unknown;
|
|
368
|
+
|
|
369
|
+
await asyncPool(Math.max(parallelism, 1), this.checkpoints, async checkpoint => {
|
|
370
|
+
if (hasError || this.abortController.signal.aborted) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
try {
|
|
375
|
+
this.checkState();
|
|
376
|
+
await processCheckpoint(checkpoint);
|
|
377
|
+
} catch (err) {
|
|
378
|
+
if (!hasError) {
|
|
379
|
+
hasError = true;
|
|
380
|
+
firstError = err;
|
|
381
|
+
this.failProcessing();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
if (hasError) {
|
|
387
|
+
throw firstError;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (this.abortController.signal.aborted) {
|
|
391
|
+
this.checkState();
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
331
395
|
private progressState(state: EpochProvingJobState) {
|
|
332
396
|
this.checkState();
|
|
333
397
|
this.state = state;
|
|
@@ -341,12 +405,24 @@ export class EpochProvingJob implements Traceable {
|
|
|
341
405
|
|
|
342
406
|
public async stop(state: EpochProvingJobTerminalState = 'stopped') {
|
|
343
407
|
this.state = state;
|
|
344
|
-
this.
|
|
408
|
+
this.interruptProcessing();
|
|
345
409
|
if (this.runPromise) {
|
|
346
410
|
await this.runPromise;
|
|
347
411
|
}
|
|
348
412
|
}
|
|
349
413
|
|
|
414
|
+
private failProcessing() {
|
|
415
|
+
if (!EpochProvingJobTerminalState.includes(this.state)) {
|
|
416
|
+
this.state = 'failed';
|
|
417
|
+
}
|
|
418
|
+
this.interruptProcessing();
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
private interruptProcessing() {
|
|
422
|
+
this.abortController.abort();
|
|
423
|
+
this.prover.cancel();
|
|
424
|
+
}
|
|
425
|
+
|
|
350
426
|
private scheduleDeadlineStop() {
|
|
351
427
|
const deadline = this.deadline;
|
|
352
428
|
if (deadline) {
|
|
@@ -381,7 +457,9 @@ export class EpochProvingJob implements Traceable {
|
|
|
381
457
|
const intervalMs = Math.ceil((await l2BlockSource.getL1Constants()).ethereumSlotDuration / 2) * 1000;
|
|
382
458
|
this.epochCheckPromise = new RunningPromise(
|
|
383
459
|
async () => {
|
|
384
|
-
const blockHeaders =
|
|
460
|
+
const blockHeaders = (
|
|
461
|
+
await l2BlockSource.getBlocksData({ epoch: this.epochNumber, onlyCheckpointed: true })
|
|
462
|
+
).map(d => d.header);
|
|
385
463
|
const blockHashes = await Promise.all(blockHeaders.map(header => header.hash()));
|
|
386
464
|
const thisBlocks = this.checkpoints.flatMap(checkpoint => checkpoint.blocks);
|
|
387
465
|
const thisBlockHashes = await Promise.all(thisBlocks.map(block => block.hash()));
|
|
@@ -420,7 +498,11 @@ export class EpochProvingJob implements Traceable {
|
|
|
420
498
|
|
|
421
499
|
private async processTxs(publicProcessor: PublicProcessor, txs: Tx[]): Promise<ProcessedTx[]> {
|
|
422
500
|
const { deadline } = this;
|
|
423
|
-
const [processedTxs, failedTxs] = await publicProcessor.process(txs, {
|
|
501
|
+
const [processedTxs, failedTxs] = await publicProcessor.process(txs, {
|
|
502
|
+
deadline,
|
|
503
|
+
signal: this.abortController.signal,
|
|
504
|
+
});
|
|
505
|
+
this.checkState();
|
|
424
506
|
|
|
425
507
|
if (failedTxs.length) {
|
|
426
508
|
const failedTxHashes = await Promise.all(failedTxs.map(({ tx }) => tx.getTxHash()));
|