@aztec/prover-node 0.49.2 → 0.51.0
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 +16 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +8 -5
- package/dest/job/block-proving-job.d.ts +6 -1
- package/dest/job/block-proving-job.d.ts.map +1 -1
- package/dest/job/block-proving-job.js +21 -7
- package/dest/metrics.d.ts +8 -0
- package/dest/metrics.d.ts.map +1 -0
- package/dest/metrics.js +19 -0
- package/dest/prover-node.d.ts +20 -6
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +53 -10
- package/package.json +12 -11
- package/src/config.ts +27 -2
- package/src/factory.ts +7 -3
- package/src/job/block-proving-job.ts +28 -7
- package/src/metrics.ts +23 -0
- package/src/prover-node.ts +74 -10
package/dest/config.d.ts
CHANGED
|
@@ -4,7 +4,10 @@ import { type ProverClientConfig } from '@aztec/prover-client';
|
|
|
4
4
|
import { type PublisherConfig, type TxSenderConfig } from '@aztec/sequencer-client';
|
|
5
5
|
import { type WorldStateConfig } from '@aztec/world-state';
|
|
6
6
|
import { type TxProviderConfig } from './tx-provider/config.js';
|
|
7
|
-
export type ProverNodeConfig = ArchiverConfig & ProverClientConfig & WorldStateConfig & PublisherConfig & TxSenderConfig & TxProviderConfig
|
|
7
|
+
export type ProverNodeConfig = ArchiverConfig & ProverClientConfig & WorldStateConfig & PublisherConfig & TxSenderConfig & TxProviderConfig & {
|
|
8
|
+
proverNodeDisableAutomaticProving?: boolean;
|
|
9
|
+
proverNodeMaxPendingJobs?: number;
|
|
10
|
+
};
|
|
8
11
|
export declare const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConfig>;
|
|
9
12
|
export declare function getProverNodeConfigFromEnv(): ProverNodeConfig;
|
|
10
13
|
//# sourceMappingURL=config.d.ts.map
|
package/dest/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAoD,MAAM,iBAAiB,CAAC;AACxG,OAAO,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAoD,MAAM,iBAAiB,CAAC;AACxG,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,kBAAkB,EAAgD,MAAM,sBAAsB,CAAC;AAC7G,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EAKpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,gBAAgB,EAAwD,MAAM,oBAAoB,CAAC;AAEjH,OAAO,EAAE,KAAK,gBAAgB,EAAwD,MAAM,yBAAyB,CAAC;AAEtH,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAC3C,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,cAAc,GACd,gBAAgB,GAAG;IACjB,iCAAiC,CAAC,EAAE,OAAO,CAAC;IAC5C,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC,CAAC;AAiBJ,eAAO,MAAM,wBAAwB,EAAE,kBAAkB,CAAC,gBAAgB,CAQzE,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,gBAAgB,CAU7D"}
|
package/dest/config.js
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import { archiverConfigMappings, getArchiverConfigFromEnv } from '@aztec/archiver';
|
|
2
|
+
import { booleanConfigHelper, getConfigFromMappings, numberConfigHelper, } from '@aztec/foundation/config';
|
|
2
3
|
import { getProverEnvVars, proverClientConfigMappings } from '@aztec/prover-client';
|
|
3
4
|
import { getPublisherConfigFromEnv, getPublisherConfigMappings, getTxSenderConfigFromEnv, getTxSenderConfigMappings, } from '@aztec/sequencer-client';
|
|
4
5
|
import { getWorldStateConfigFromEnv, worldStateConfigMappings } from '@aztec/world-state';
|
|
5
6
|
import { getTxProviderConfigFromEnv, txProviderConfigMappings } from './tx-provider/config.js';
|
|
7
|
+
const specificProverNodeConfigMappings = {
|
|
8
|
+
proverNodeDisableAutomaticProving: {
|
|
9
|
+
env: 'PROVER_NODE_DISABLE_AUTOMATIC_PROVING',
|
|
10
|
+
description: 'Whether to disable automatic proving of pending blocks seen on L1',
|
|
11
|
+
...booleanConfigHelper(false),
|
|
12
|
+
},
|
|
13
|
+
proverNodeMaxPendingJobs: {
|
|
14
|
+
env: 'PROVER_NODE_MAX_PENDING_JOBS',
|
|
15
|
+
description: 'The maximum number of pending jobs for the prover node',
|
|
16
|
+
...numberConfigHelper(100),
|
|
17
|
+
},
|
|
18
|
+
};
|
|
6
19
|
export const proverNodeConfigMappings = {
|
|
7
20
|
...archiverConfigMappings,
|
|
8
21
|
...proverClientConfigMappings,
|
|
@@ -10,6 +23,7 @@ export const proverNodeConfigMappings = {
|
|
|
10
23
|
...getPublisherConfigMappings('PROVER'),
|
|
11
24
|
...getTxSenderConfigMappings('PROVER'),
|
|
12
25
|
...txProviderConfigMappings,
|
|
26
|
+
...specificProverNodeConfigMappings,
|
|
13
27
|
};
|
|
14
28
|
export function getProverNodeConfigFromEnv() {
|
|
15
29
|
return {
|
|
@@ -19,6 +33,7 @@ export function getProverNodeConfigFromEnv() {
|
|
|
19
33
|
...getPublisherConfigFromEnv('PROVER'),
|
|
20
34
|
...getTxSenderConfigFromEnv('PROVER'),
|
|
21
35
|
...getTxProviderConfigFromEnv(),
|
|
36
|
+
...getConfigFromMappings(specificProverNodeConfigMappings),
|
|
22
37
|
};
|
|
23
38
|
}
|
|
24
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXVCLHNCQUFzQixFQUFFLHdCQUF3QixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEcsT0FBTyxFQUVMLG1CQUFtQixFQUNuQixxQkFBcUIsRUFDckIsa0JBQWtCLEdBQ25CLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUEyQixnQkFBZ0IsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzdHLE9BQU8sRUFHTCx5QkFBeUIsRUFDekIsMEJBQTBCLEVBQzFCLHdCQUF3QixFQUN4Qix5QkFBeUIsR0FDMUIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQXlCLDBCQUEwQixFQUFFLHdCQUF3QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFakgsT0FBTyxFQUF5QiwwQkFBMEIsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBWXRILE1BQU0sZ0NBQWdDLEdBRWxDO0lBQ0YsaUNBQWlDLEVBQUU7UUFDakMsR0FBRyxFQUFFLHVDQUF1QztRQUM1QyxXQUFXLEVBQUUsbUVBQW1FO1FBQ2hGLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDO0tBQzlCO0lBQ0Qsd0JBQXdCLEVBQUU7UUFDeEIsR0FBRyxFQUFFLDhCQUE4QjtRQUNuQyxXQUFXLEVBQUUsd0RBQXdEO1FBQ3JFLEdBQUcsa0JBQWtCLENBQUMsR0FBRyxDQUFDO0tBQzNCO0NBQ0YsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUF5QztJQUM1RSxHQUFHLHNCQUFzQjtJQUN6QixHQUFHLDBCQUEwQjtJQUM3QixHQUFHLHdCQUF3QjtJQUMzQixHQUFHLDBCQUEwQixDQUFDLFFBQVEsQ0FBQztJQUN2QyxHQUFHLHlCQUF5QixDQUFDLFFBQVEsQ0FBQztJQUN0QyxHQUFHLHdCQUF3QjtJQUMzQixHQUFHLGdDQUFnQztDQUNwQyxDQUFDO0FBRUYsTUFBTSxVQUFVLDBCQUEwQjtJQUN4QyxPQUFPO1FBQ0wsR0FBRyx3QkFBd0IsRUFBRTtRQUM3QixHQUFHLGdCQUFnQixFQUFFO1FBQ3JCLEdBQUcsMEJBQTBCLEVBQUU7UUFDL0IsR0FBRyx5QkFBeUIsQ0FBQyxRQUFRLENBQUM7UUFDdEMsR0FBRyx3QkFBd0IsQ0FBQyxRQUFRLENBQUM7UUFDckMsR0FBRywwQkFBMEIsRUFBRTtRQUMvQixHQUFHLHFCQUFxQixDQUFDLGdDQUFnQyxDQUFDO0tBQzNELENBQUM7QUFDSixDQUFDIn0=
|
package/dest/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,uBAAuB,CAAC;AAK5E,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAI/D,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,gDAAgD;AAChD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,gBAAgB,EACxB,IAAI,GAAE;IACJ,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAChB,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,uBAAuB,CAAC;AAK5E,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAI/D,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,gDAAgD;AAChD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,gBAAgB,EACxB,IAAI,GAAE;IACJ,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAChB,uBAyCP"}
|
package/dest/factory.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createArchiver } from '@aztec/archiver';
|
|
|
2
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { createStore } from '@aztec/kv-store/utils';
|
|
4
4
|
import { createProverClient } from '@aztec/prover-client';
|
|
5
|
-
import {
|
|
5
|
+
import { L1Publisher } from '@aztec/sequencer-client';
|
|
6
6
|
import { createSimulationProvider } from '@aztec/simulator';
|
|
7
7
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
8
8
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
@@ -18,15 +18,18 @@ export async function createProverNode(config, deps = {}) {
|
|
|
18
18
|
const archiver = deps.archiver ?? (await createArchiver(config, store, telemetry, { blockUntilSync: true }));
|
|
19
19
|
log.verbose(`Created archiver and synced to block ${await archiver.getBlockNumber()}`);
|
|
20
20
|
const worldStateConfig = { ...config, worldStateProvenBlocksOnly: true };
|
|
21
|
-
const worldStateSynchronizer = await createWorldStateSynchronizer(worldStateConfig, store, archiver);
|
|
21
|
+
const worldStateSynchronizer = await createWorldStateSynchronizer(worldStateConfig, store, archiver, telemetry);
|
|
22
22
|
await worldStateSynchronizer.start();
|
|
23
23
|
const simulationProvider = await createSimulationProvider(config, log);
|
|
24
24
|
const prover = await createProverClient(config, telemetry);
|
|
25
25
|
// REFACTOR: Move publisher out of sequencer package and into an L1-related package
|
|
26
|
-
const publisher =
|
|
26
|
+
const publisher = new L1Publisher(config, telemetry);
|
|
27
27
|
const txProvider = deps.aztecNodeTxProvider
|
|
28
28
|
? new AztecNodeTxProvider(deps.aztecNodeTxProvider)
|
|
29
29
|
: createTxProvider(config);
|
|
30
|
-
return new ProverNode(prover, publisher, archiver, archiver, archiver, worldStateSynchronizer, txProvider, simulationProvider, telemetry
|
|
30
|
+
return new ProverNode(prover, publisher, archiver, archiver, archiver, worldStateSynchronizer, txProvider, simulationProvider, telemetry, {
|
|
31
|
+
disableAutomaticProving: config.proverNodeDisableAutomaticProving,
|
|
32
|
+
maxPendingJobs: config.proverNodeMaxPendingJobs,
|
|
33
|
+
});
|
|
31
34
|
}
|
|
32
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFaEUsT0FBTyxFQUFvQixpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzVFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdEQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFNUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbkUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFHbEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTVELGdEQUFnRDtBQUNoRCxNQUFNLENBQUMsS0FBSyxVQUFVLGdCQUFnQixDQUNwQyxNQUF3QixFQUN4QixPQU1JLEVBQUU7SUFFTixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksbUJBQW1CLEVBQUUsQ0FBQztJQUM5RCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxJQUFJLGlCQUFpQixDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzFELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksaUJBQWlCLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUV6RSxNQUFNLEtBQUssR0FBRyxNQUFNLFdBQVcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFcEYsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLE1BQU0sY0FBYyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM3RyxHQUFHLENBQUMsT0FBTyxDQUFDLHdDQUF3QyxNQUFNLFFBQVEsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFdkYsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLEdBQUcsTUFBTSxFQUFFLDBCQUEwQixFQUFFLElBQUksRUFBRSxDQUFDO0lBQ3pFLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSw0QkFBNEIsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ2hILE1BQU0sc0JBQXNCLENBQUMsS0FBSyxFQUFFLENBQUM7SUFFckMsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztJQUV2RSxNQUFNLE1BQU0sR0FBRyxNQUFNLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztJQUUzRCxtRkFBbUY7SUFDbkYsTUFBTSxTQUFTLEdBQUcsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBRXJELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUI7UUFDekMsQ0FBQyxDQUFDLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDO1FBQ25ELENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUU3QixPQUFPLElBQUksVUFBVSxDQUNuQixNQUFPLEVBQ1AsU0FBUyxFQUNULFFBQVEsRUFDUixRQUFRLEVBQ1IsUUFBUSxFQUNSLHNCQUFzQixFQUN0QixVQUFVLEVBQ1Ysa0JBQWtCLEVBQ2xCLFNBQVMsRUFDVDtRQUNFLHVCQUF1QixFQUFFLE1BQU0sQ0FBQyxpQ0FBaUM7UUFDakUsY0FBYyxFQUFFLE1BQU0sQ0FBQyx3QkFBd0I7S0FDaEQsQ0FDRixDQUFDO0FBQ0osQ0FBQyJ9
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type BlockProver, type L1ToL2MessageSource, type L2BlockSource, type TxProvider } from '@aztec/circuit-types';
|
|
2
2
|
import { type L1Publisher } from '@aztec/sequencer-client';
|
|
3
3
|
import { type PublicProcessorFactory } from '@aztec/simulator';
|
|
4
|
+
import { type ProverNodeMetrics } from '../metrics.js';
|
|
4
5
|
/**
|
|
5
6
|
* Job that grabs a range of blocks from the unfinalised chain from L1, gets their txs given their hashes,
|
|
6
7
|
* re-executes their public calls, generates a rollup proof, and submits it to L1. This job will update the
|
|
@@ -13,12 +14,16 @@ export declare class BlockProvingJob {
|
|
|
13
14
|
private l2BlockSource;
|
|
14
15
|
private l1ToL2MessageSource;
|
|
15
16
|
private txProvider;
|
|
17
|
+
private metrics;
|
|
16
18
|
private cleanUp;
|
|
17
19
|
private state;
|
|
18
20
|
private log;
|
|
19
|
-
|
|
21
|
+
private uuid;
|
|
22
|
+
constructor(prover: BlockProver, publicProcessorFactory: PublicProcessorFactory, publisher: L1Publisher, l2BlockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: TxProvider, metrics: ProverNodeMetrics, cleanUp?: (job: BlockProvingJob) => Promise<void>);
|
|
23
|
+
getId(): string;
|
|
20
24
|
getState(): BlockProvingJobState;
|
|
21
25
|
run(fromBlock: number, toBlock: number): Promise<void>;
|
|
26
|
+
stop(): void;
|
|
22
27
|
private getBlock;
|
|
23
28
|
private getTxs;
|
|
24
29
|
private getL1ToL2Messages;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-proving-job.d.ts","sourceRoot":"","sources":["../../src/job/block-proving-job.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,mBAAmB,EAExB,KAAK,aAAa,EAKlB,KAAK,UAAU,EAChB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"block-proving-job.d.ts","sourceRoot":"","sources":["../../src/job/block-proving-job.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,mBAAmB,EAExB,KAAK,aAAa,EAKlB,KAAK,UAAU,EAChB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAwB,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAIrF,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD;;;;GAIG;AACH,qBAAa,eAAe;IAMxB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;IAZjB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,GAAG,CAAgD;IAC3D,OAAO,CAAC,IAAI,CAAS;gBAGX,MAAM,EAAE,WAAW,EACnB,sBAAsB,EAAE,sBAAsB,EAC9C,SAAS,EAAE,WAAW,EACtB,aAAa,EAAE,aAAa,EAC5B,mBAAmB,EAAE,mBAAmB,EACxC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAA2B;IAK7E,KAAK,IAAI,MAAM;IAIf,QAAQ,IAAI,oBAAoB;IAI1B,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IA8E5C,IAAI;YAIG,QAAQ;YAQR,MAAM;IAWpB,OAAO,CAAC,iBAAiB;YAIX,UAAU;CAoBzB;AAED,MAAM,MAAM,oBAAoB,GAC5B,aAAa,GACb,YAAY,GACZ,iBAAiB,GACjB,kBAAkB,GAClB,WAAW,GACX,QAAQ,CAAC"}
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { EmptyTxValidator, PROVING_STATUS, } from '@aztec/circuit-types';
|
|
2
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
4
|
+
import * as crypto from 'node:crypto';
|
|
3
5
|
/**
|
|
4
6
|
* Job that grabs a range of blocks from the unfinalised chain from L1, gets their txs given their hashes,
|
|
5
7
|
* re-executes their public calls, generates a rollup proof, and submits it to L1. This job will update the
|
|
6
8
|
* world state as part of public call execution via the public processor.
|
|
7
9
|
*/
|
|
8
10
|
export class BlockProvingJob {
|
|
9
|
-
constructor(prover, publicProcessorFactory, publisher, l2BlockSource, l1ToL2MessageSource, txProvider, cleanUp = () => Promise.resolve()) {
|
|
11
|
+
constructor(prover, publicProcessorFactory, publisher, l2BlockSource, l1ToL2MessageSource, txProvider, metrics, cleanUp = () => Promise.resolve()) {
|
|
10
12
|
this.prover = prover;
|
|
11
13
|
this.publicProcessorFactory = publicProcessorFactory;
|
|
12
14
|
this.publisher = publisher;
|
|
13
15
|
this.l2BlockSource = l2BlockSource;
|
|
14
16
|
this.l1ToL2MessageSource = l1ToL2MessageSource;
|
|
15
17
|
this.txProvider = txProvider;
|
|
18
|
+
this.metrics = metrics;
|
|
16
19
|
this.cleanUp = cleanUp;
|
|
17
20
|
this.state = 'initialized';
|
|
18
21
|
this.log = createDebugLogger('aztec:block-proving-job');
|
|
22
|
+
this.uuid = crypto.randomUUID();
|
|
23
|
+
}
|
|
24
|
+
getId() {
|
|
25
|
+
return this.uuid;
|
|
19
26
|
}
|
|
20
27
|
getState() {
|
|
21
28
|
return this.state;
|
|
@@ -24,8 +31,9 @@ export class BlockProvingJob {
|
|
|
24
31
|
if (fromBlock !== toBlock) {
|
|
25
32
|
throw new Error(`Block ranges are not yet supported`);
|
|
26
33
|
}
|
|
27
|
-
this.log.info(`Starting block proving job`, { fromBlock, toBlock });
|
|
34
|
+
this.log.info(`Starting block proving job`, { fromBlock, toBlock, uuid: this.uuid });
|
|
28
35
|
this.state = 'processing';
|
|
36
|
+
const timer = new Timer();
|
|
29
37
|
try {
|
|
30
38
|
let historicalHeader = (await this.l2BlockSource.getBlock(fromBlock - 1))?.header;
|
|
31
39
|
for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {
|
|
@@ -42,6 +50,7 @@ export class BlockProvingJob {
|
|
|
42
50
|
nullifierTreeRoot: block.header.state.partial.nullifierTree.root,
|
|
43
51
|
publicDataTreeRoot: block.header.state.partial.publicDataTree.root,
|
|
44
52
|
historicalHeader: historicalHeader?.hash(),
|
|
53
|
+
uuid: this.uuid,
|
|
45
54
|
...globalVariables,
|
|
46
55
|
});
|
|
47
56
|
// When we move to proving epochs, this should change into a startNewEpoch and be lifted outside the loop.
|
|
@@ -52,6 +61,7 @@ export class BlockProvingJob {
|
|
|
52
61
|
this.log.verbose(`Processed all txs for block`, {
|
|
53
62
|
blockNumber: block.number,
|
|
54
63
|
blockHash: block.hash().toString(),
|
|
64
|
+
uuid: this.uuid,
|
|
55
65
|
});
|
|
56
66
|
await this.prover.setBlockCompleted();
|
|
57
67
|
// This should be moved outside the loop to match the creation of the proving ticket when we move to epochs.
|
|
@@ -63,20 +73,24 @@ export class BlockProvingJob {
|
|
|
63
73
|
historicalHeader = block.header;
|
|
64
74
|
}
|
|
65
75
|
const { block, aggregationObject, proof } = await this.prover.finaliseBlock();
|
|
66
|
-
this.log.info(`Finalised proof for block range`, { fromBlock, toBlock });
|
|
76
|
+
this.log.info(`Finalised proof for block range`, { fromBlock, toBlock, uuid: this.uuid });
|
|
67
77
|
this.state = 'publishing-proof';
|
|
68
78
|
await this.publisher.submitProof(block.header, block.archive.root, this.prover.getProverId(), aggregationObject, proof);
|
|
69
|
-
this.log.info(`Submitted proof for block range`, { fromBlock, toBlock });
|
|
79
|
+
this.log.info(`Submitted proof for block range`, { fromBlock, toBlock, uuid: this.uuid });
|
|
70
80
|
this.state = 'completed';
|
|
81
|
+
this.metrics.recordProvingJob(timer);
|
|
71
82
|
}
|
|
72
83
|
catch (err) {
|
|
73
|
-
this.log.error(`Error running block prover job:
|
|
84
|
+
this.log.error(`Error running block prover job`, err, { uuid: this.uuid });
|
|
74
85
|
this.state = 'failed';
|
|
75
86
|
}
|
|
76
87
|
finally {
|
|
77
|
-
await this.cleanUp();
|
|
88
|
+
await this.cleanUp(this);
|
|
78
89
|
}
|
|
79
90
|
}
|
|
91
|
+
stop() {
|
|
92
|
+
this.prover.cancelBlock();
|
|
93
|
+
}
|
|
80
94
|
async getBlock(blockNumber) {
|
|
81
95
|
const block = await this.l2BlockSource.getBlock(blockNumber);
|
|
82
96
|
if (!block) {
|
|
@@ -103,4 +117,4 @@ export class BlockProvingJob {
|
|
|
103
117
|
return processedTxs;
|
|
104
118
|
}
|
|
105
119
|
}
|
|
106
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
120
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2stcHJvdmluZy1qb2IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvam9iL2Jsb2NrLXByb3Zpbmctam9iLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxnQkFBZ0IsRUFJaEIsY0FBYyxHQUtmLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBSWhELE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBSXRDOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUsxQixZQUNVLE1BQW1CLEVBQ25CLHNCQUE4QyxFQUM5QyxTQUFzQixFQUN0QixhQUE0QixFQUM1QixtQkFBd0MsRUFDeEMsVUFBc0IsRUFDdEIsT0FBMEIsRUFDMUIsVUFBbUQsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRTtRQVAxRSxXQUFNLEdBQU4sTUFBTSxDQUFhO1FBQ25CLDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFDOUMsY0FBUyxHQUFULFNBQVMsQ0FBYTtRQUN0QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1Qix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsWUFBTyxHQUFQLE9BQU8sQ0FBbUI7UUFDMUIsWUFBTyxHQUFQLE9BQU8sQ0FBbUU7UUFaNUUsVUFBSyxHQUF5QixhQUFhLENBQUM7UUFDNUMsUUFBRyxHQUFHLGlCQUFpQixDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFhekQsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUVNLEtBQUs7UUFDVixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkIsQ0FBQztJQUVNLFFBQVE7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
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Timer } from '@aztec/foundation/timer';
|
|
2
|
+
import { type Histogram, type TelemetryClient } from '@aztec/telemetry-client';
|
|
3
|
+
export declare class ProverNodeMetrics {
|
|
4
|
+
provingJobDuration: Histogram;
|
|
5
|
+
constructor(client: TelemetryClient, name?: string);
|
|
6
|
+
recordProvingJob(timerOrMs: Timer | number): void;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,KAAK,SAAS,EAAW,KAAK,eAAe,EAAiC,MAAM,yBAAyB,CAAC;AAEvH,qBAAa,iBAAiB;IAC5B,kBAAkB,EAAE,SAAS,CAAC;gBAElB,MAAM,EAAE,eAAe,EAAE,IAAI,SAAe;IAYjD,gBAAgB,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM;CAIlD"}
|
package/dest/metrics.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Metrics, ValueType, millisecondBuckets } from '@aztec/telemetry-client';
|
|
2
|
+
export class ProverNodeMetrics {
|
|
3
|
+
constructor(client, name = 'ProverNode') {
|
|
4
|
+
const meter = client.getMeter(name);
|
|
5
|
+
this.provingJobDuration = meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION, {
|
|
6
|
+
description: 'Duration of proving job',
|
|
7
|
+
unit: 'ms',
|
|
8
|
+
valueType: ValueType.INT,
|
|
9
|
+
advice: {
|
|
10
|
+
explicitBucketBoundaries: millisecondBuckets(2), // 60 buckets spanning an interval of ~100ms to ~1hour
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
recordProvingJob(timerOrMs) {
|
|
15
|
+
const ms = Math.ceil(typeof timerOrMs === 'number' ? timerOrMs : timerOrMs.ms());
|
|
16
|
+
this.provingJobDuration.record(ms);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBa0IsT0FBTyxFQUF3QixTQUFTLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV2SCxNQUFNLE9BQU8saUJBQWlCO0lBRzVCLFlBQVksTUFBdUIsRUFBRSxJQUFJLEdBQUcsWUFBWTtRQUN0RCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyx3QkFBd0IsRUFBRTtZQUNoRixXQUFXLEVBQUUseUJBQXlCO1lBQ3RDLElBQUksRUFBRSxJQUFJO1lBQ1YsU0FBUyxFQUFFLFNBQVMsQ0FBQyxHQUFHO1lBQ3hCLE1BQU0sRUFBRTtnQkFDTix3QkFBd0IsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxzREFBc0Q7YUFDeEc7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sZ0JBQWdCLENBQUMsU0FBeUI7UUFDL0MsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLFNBQVMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakYsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNyQyxDQUFDO0NBQ0YifQ==
|
package/dest/prover-node.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { type L1ToL2MessageSource, type L2BlockSource, type ProverClient, type TxProvider } from '@aztec/circuit-types';
|
|
1
|
+
import { type L1ToL2MessageSource, type L2BlockSource, type MerkleTreeOperations, type ProverClient, type TxProvider } from '@aztec/circuit-types';
|
|
2
2
|
import { type L1Publisher } from '@aztec/sequencer-client';
|
|
3
|
-
import { type SimulationProvider } from '@aztec/simulator';
|
|
3
|
+
import { PublicProcessorFactory, type SimulationProvider } from '@aztec/simulator';
|
|
4
4
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
5
|
+
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
5
6
|
import { type WorldStateSynchronizer } from '@aztec/world-state';
|
|
6
|
-
import { type
|
|
7
|
+
import { BlockProvingJob, type BlockProvingJobState } from './job/block-proving-job.js';
|
|
7
8
|
/**
|
|
8
9
|
* An Aztec Prover Node is a standalone process that monitors the unfinalised chain on L1 for unproven blocks,
|
|
9
10
|
* fetches their txs from a tx source in the p2p network or an external node, re-executes their public functions,
|
|
@@ -19,13 +20,16 @@ export declare class ProverNode {
|
|
|
19
20
|
private txProvider;
|
|
20
21
|
private simulator;
|
|
21
22
|
private telemetryClient;
|
|
22
|
-
private options;
|
|
23
23
|
private log;
|
|
24
24
|
private runningPromise;
|
|
25
25
|
private latestBlockWeAreProving;
|
|
26
|
+
private jobs;
|
|
27
|
+
private options;
|
|
28
|
+
private metrics;
|
|
26
29
|
constructor(prover: ProverClient, publisher: L1Publisher, l2BlockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, contractDataSource: ContractDataSource, worldState: WorldStateSynchronizer, txProvider: TxProvider, simulator: SimulationProvider, telemetryClient: TelemetryClient, options?: {
|
|
27
|
-
pollingIntervalMs
|
|
28
|
-
disableAutomaticProving
|
|
30
|
+
pollingIntervalMs?: number;
|
|
31
|
+
disableAutomaticProving?: boolean;
|
|
32
|
+
maxPendingJobs?: number;
|
|
29
33
|
});
|
|
30
34
|
/**
|
|
31
35
|
* Starts the prover node so it periodically checks for unproven blocks in the unfinalised chain from L1 and proves them.
|
|
@@ -53,6 +57,16 @@ export declare class ProverNode {
|
|
|
53
57
|
* Returns the prover instance.
|
|
54
58
|
*/
|
|
55
59
|
getProver(): ProverClient;
|
|
60
|
+
/**
|
|
61
|
+
* Returns an array of jobs being processed.
|
|
62
|
+
*/
|
|
63
|
+
getJobs(): {
|
|
64
|
+
uuid: string;
|
|
65
|
+
status: BlockProvingJobState;
|
|
66
|
+
}[];
|
|
67
|
+
private checkMaximumPendingJobs;
|
|
56
68
|
private createProvingJob;
|
|
69
|
+
/** Extracted for testing purposes. */
|
|
70
|
+
protected doCreateBlockProvingJob(db: MerkleTreeOperations, publicProcessorFactory: PublicProcessorFactory, cleanUp: () => Promise<void>): BlockProvingJob;
|
|
57
71
|
}
|
|
58
72
|
//# sourceMappingURL=prover-node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prover-node.d.ts","sourceRoot":"","sources":["../src/prover-node.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"prover-node.d.ts","sourceRoot":"","sources":["../src/prover-node.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGxF;;;;GAIG;AACH,qBAAa,UAAU;IASnB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe;IAhBzB,OAAO,CAAC,GAAG,CAA0C;IACrD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,uBAAuB,CAAqB;IACpD,OAAO,CAAC,IAAI,CAA2C;IACvD,OAAO,CAAC,OAAO,CAA0F;IACzG,OAAO,CAAC,OAAO,CAAoB;gBAGzB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,WAAW,EACtB,aAAa,EAAE,aAAa,EAC5B,mBAAmB,EAAE,mBAAmB,EACxC,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EAAE,sBAAsB,EAClC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,kBAAkB,EAC7B,eAAe,EAAE,eAAe,EACxC,OAAO,GAAE;QAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAO;IAY1G;;;OAGG;IACH,KAAK;IAML;;OAEG;IACG,IAAI;IAWV;;;OAGG;cACa,IAAI;IA8CpB;;OAEG;IACU,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAKrD;;OAEG;IACU,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAK1D;;OAEG;IACI,SAAS;IAIhB;;OAEG;IACI,OAAO,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,oBAAoB,CAAA;KAAE,EAAE;IAIlE,OAAO,CAAC,uBAAuB;YAKjB,gBAAgB;IA+B9B,sCAAsC;IACtC,SAAS,CAAC,uBAAuB,CAC/B,EAAE,EAAE,oBAAoB,EACxB,sBAAsB,EAAE,sBAAsB,EAC9C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC;CAa/B"}
|
package/dest/prover-node.js
CHANGED
|
@@ -2,16 +2,14 @@ import { createDebugLogger } from '@aztec/foundation/log';
|
|
|
2
2
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
3
3
|
import { PublicProcessorFactory } from '@aztec/simulator';
|
|
4
4
|
import { BlockProvingJob } from './job/block-proving-job.js';
|
|
5
|
+
import { ProverNodeMetrics } from './metrics.js';
|
|
5
6
|
/**
|
|
6
7
|
* An Aztec Prover Node is a standalone process that monitors the unfinalised chain on L1 for unproven blocks,
|
|
7
8
|
* fetches their txs from a tx source in the p2p network or an external node, re-executes their public functions,
|
|
8
9
|
* creates a rollup proof, and submits it to L1.
|
|
9
10
|
*/
|
|
10
11
|
export class ProverNode {
|
|
11
|
-
constructor(prover, publisher, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, txProvider, simulator, telemetryClient, options = {
|
|
12
|
-
pollingIntervalMs: 1000,
|
|
13
|
-
disableAutomaticProving: false,
|
|
14
|
-
}) {
|
|
12
|
+
constructor(prover, publisher, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, txProvider, simulator, telemetryClient, options = {}) {
|
|
15
13
|
this.prover = prover;
|
|
16
14
|
this.publisher = publisher;
|
|
17
15
|
this.l2BlockSource = l2BlockSource;
|
|
@@ -21,8 +19,15 @@ export class ProverNode {
|
|
|
21
19
|
this.txProvider = txProvider;
|
|
22
20
|
this.simulator = simulator;
|
|
23
21
|
this.telemetryClient = telemetryClient;
|
|
24
|
-
this.options = options;
|
|
25
22
|
this.log = createDebugLogger('aztec:prover-node');
|
|
23
|
+
this.jobs = new Map();
|
|
24
|
+
this.options = {
|
|
25
|
+
pollingIntervalMs: 1000,
|
|
26
|
+
disableAutomaticProving: false,
|
|
27
|
+
maxPendingJobs: 100,
|
|
28
|
+
...options,
|
|
29
|
+
};
|
|
30
|
+
this.metrics = new ProverNodeMetrics(telemetryClient, 'ProverNode');
|
|
26
31
|
}
|
|
27
32
|
/**
|
|
28
33
|
* Starts the prover node so it periodically checks for unproven blocks in the unfinalised chain from L1 and proves them.
|
|
@@ -42,8 +47,9 @@ export class ProverNode {
|
|
|
42
47
|
await this.prover.stop();
|
|
43
48
|
await this.l2BlockSource.stop();
|
|
44
49
|
this.publisher.interrupt();
|
|
50
|
+
this.jobs.forEach(job => job.stop());
|
|
51
|
+
await this.worldState.stop();
|
|
45
52
|
this.log.info('Stopped ProverNode');
|
|
46
|
-
// TODO(palla/prover-node): Keep a reference to all ongoing ProvingJobs and stop them.
|
|
47
53
|
}
|
|
48
54
|
/**
|
|
49
55
|
* Single iteration of recurring work. This method is called periodically by the running promise.
|
|
@@ -54,6 +60,13 @@ export class ProverNode {
|
|
|
54
60
|
if (this.options.disableAutomaticProving) {
|
|
55
61
|
return;
|
|
56
62
|
}
|
|
63
|
+
if (!this.checkMaximumPendingJobs()) {
|
|
64
|
+
this.log.debug(`Maximum pending proving jobs reached. Skipping work.`, {
|
|
65
|
+
maxPendingJobs: this.options.maxPendingJobs,
|
|
66
|
+
pendingJobs: this.jobs.size,
|
|
67
|
+
});
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
57
70
|
const [latestBlockNumber, latestProvenBlockNumber] = await Promise.all([
|
|
58
71
|
this.l2BlockSource.getBlockNumber(),
|
|
59
72
|
this.l2BlockSource.getProvenBlockNumber(),
|
|
@@ -71,8 +84,14 @@ export class ProverNode {
|
|
|
71
84
|
}
|
|
72
85
|
const fromBlock = latestProven + 1;
|
|
73
86
|
const toBlock = fromBlock; // We only prove one block at a time for now
|
|
74
|
-
|
|
75
|
-
|
|
87
|
+
try {
|
|
88
|
+
await this.startProof(fromBlock, toBlock);
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
// If we fail to create a proving job for the given block, skip it instead of getting stuck on it.
|
|
92
|
+
this.log.verbose(`Setting ${toBlock} as latest block we are proving`);
|
|
93
|
+
this.latestBlockWeAreProving = toBlock;
|
|
94
|
+
}
|
|
76
95
|
}
|
|
77
96
|
catch (err) {
|
|
78
97
|
this.log.error(`Error in prover node work`, err);
|
|
@@ -98,15 +117,39 @@ export class ProverNode {
|
|
|
98
117
|
getProver() {
|
|
99
118
|
return this.prover;
|
|
100
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Returns an array of jobs being processed.
|
|
122
|
+
*/
|
|
123
|
+
getJobs() {
|
|
124
|
+
return Array.from(this.jobs.entries()).map(([uuid, job]) => ({ uuid, status: job.getState() }));
|
|
125
|
+
}
|
|
126
|
+
checkMaximumPendingJobs() {
|
|
127
|
+
const { maxPendingJobs } = this.options;
|
|
128
|
+
return maxPendingJobs === 0 || this.jobs.size < maxPendingJobs;
|
|
129
|
+
}
|
|
101
130
|
async createProvingJob(fromBlock) {
|
|
131
|
+
if (!this.checkMaximumPendingJobs()) {
|
|
132
|
+
throw new Error(`Maximum pending proving jobs ${this.options.maxPendingJobs} reached. Cannot create new job.`);
|
|
133
|
+
}
|
|
102
134
|
if ((await this.worldState.status()).syncedToL2Block >= fromBlock) {
|
|
103
135
|
throw new Error(`Cannot create proving job for block ${fromBlock} as it is behind the current world state`);
|
|
104
136
|
}
|
|
105
137
|
// Fast forward world state to right before the target block and get a fork
|
|
138
|
+
this.log.verbose(`Creating proving job for block ${fromBlock}`);
|
|
106
139
|
const db = await this.worldState.syncImmediateAndFork(fromBlock - 1, true);
|
|
107
140
|
// Create a processor using the forked world state
|
|
108
141
|
const publicProcessorFactory = new PublicProcessorFactory(db, this.contractDataSource, this.simulator, this.telemetryClient);
|
|
109
|
-
|
|
142
|
+
const cleanUp = async () => {
|
|
143
|
+
await db.delete();
|
|
144
|
+
this.jobs.delete(job.getId());
|
|
145
|
+
};
|
|
146
|
+
const job = this.doCreateBlockProvingJob(db, publicProcessorFactory, cleanUp);
|
|
147
|
+
this.jobs.set(job.getId(), job);
|
|
148
|
+
return job;
|
|
149
|
+
}
|
|
150
|
+
/** Extracted for testing purposes. */
|
|
151
|
+
doCreateBlockProvingJob(db, publicProcessorFactory, cleanUp) {
|
|
152
|
+
return new BlockProvingJob(this.prover.createBlockProver(db), publicProcessorFactory, this.publisher, this.l2BlockSource, this.l1ToL2MessageSource, this.txProvider, this.metrics, cleanUp);
|
|
110
153
|
}
|
|
111
154
|
}
|
|
112
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
155
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLW5vZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLW5vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBT0EsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRW5FLE9BQU8sRUFBRSxzQkFBc0IsRUFBMkIsTUFBTSxrQkFBa0IsQ0FBQztBQUtuRixPQUFPLEVBQUUsZUFBZSxFQUE2QixNQUFNLDRCQUE0QixDQUFDO0FBQ3hGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFRckIsWUFDVSxNQUFvQixFQUNwQixTQUFzQixFQUN0QixhQUE0QixFQUM1QixtQkFBd0MsRUFDeEMsa0JBQXNDLEVBQ3RDLFVBQWtDLEVBQ2xDLFVBQXNCLEVBQ3RCLFNBQTZCLEVBQzdCLGVBQWdDLEVBQ3hDLFVBQXNHLEVBQUU7UUFUaEcsV0FBTSxHQUFOLE1BQU0sQ0FBYztRQUNwQixjQUFTLEdBQVQsU0FBUyxDQUFhO1FBQ3RCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxlQUFVLEdBQVYsVUFBVSxDQUF3QjtRQUNsQyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLGNBQVMsR0FBVCxTQUFTLENBQW9CO1FBQzdCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQWhCbEMsUUFBRyxHQUFHLGlCQUFpQixDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFHN0MsU0FBSSxHQUFpQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBZ0JyRCxJQUFJLENBQUMsT0FBTyxHQUFHO1lBQ2IsaUJBQWlCLEVBQUUsSUFBSztZQUN4Qix1QkFBdUIsRUFBRSxLQUFLO1lBQzlCLGNBQWMsRUFBRSxHQUFHO1lBQ25CLEdBQUcsT0FBTztTQUNYLENBQUM7UUFFRixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksaUJBQWlCLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLO1FBQ0gsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDL0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxJQUFJO1FBQ1IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNyQyxNQUFNLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDbEMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3pCLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDckMsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7T0FHRztJQUNPLEtBQUssQ0FBQyxJQUFJO1FBQ2xCLElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO2dCQUN6QyxPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsRUFBRSxDQUFDO2dCQUNwQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxzREFBc0QsRUFBRTtvQkFDckUsY0FBYyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYztvQkFDM0MsV0FBVyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTtpQkFDNUIsQ0FBQyxDQUFDO2dCQUNILE9BQU87WUFDVCxDQUFDO1lBRUQsTUFBTSxDQUFDLGlCQUFpQixFQUFFLHVCQUF1QixDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO2dCQUNyRSxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBRTtnQkFDbkMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsRUFBRTthQUMxQyxDQUFDLENBQUM7WUFFSCx1RkFBdUY7WUFDdkYsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLElBQUksQ0FBQyxDQUFDO1lBQ2pFLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsc0JBQXNCLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztZQUMvRSxJQUFJLFlBQVksSUFBSSxpQkFBaUIsRUFBRSxDQUFDO2dCQUN0QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsRUFBRTtvQkFDdkMsaUJBQWlCO29CQUNqQix1QkFBdUI7b0JBQ3ZCLHNCQUFzQjtpQkFDdkIsQ0FBQyxDQUFDO2dCQUNILE9BQU87WUFDVCxDQUFDO1lBRUQsTUFBTSxTQUFTLEdBQUcsWUFBWSxHQUFHLENBQUMsQ0FBQztZQUNuQyxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQyw0Q0FBNEM7WUFFdkUsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDNUMsQ0FBQztvQkFBUyxDQUFDO2dCQUNULGtHQUFrRztnQkFDbEcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsV0FBVyxPQUFPLGlDQUFpQyxDQUFDLENBQUM7Z0JBQ3RFLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxPQUFPLENBQUM7WUFDekMsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDbkQsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBaUIsRUFBRSxPQUFlO1FBQ25ELE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFVBQVUsQ0FBQyxTQUFpQixFQUFFLE9BQWU7UUFDeEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkQsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7T0FFRztJQUNJLE9BQU87UUFDWixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbEcsQ0FBQztJQUVPLHVCQUF1QjtRQUM3QixNQUFNLEVBQUUsY0FBYyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUN4QyxPQUFPLGNBQWMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsY0FBYyxDQUFDO0lBQ2pFLENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsU0FBaUI7UUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLENBQUM7WUFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLGtDQUFrQyxDQUFDLENBQUM7UUFDakgsQ0FBQztRQUVELElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxlQUFlLElBQUksU0FBUyxFQUFFLENBQUM7WUFDbEUsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsU0FBUywwQ0FBMEMsQ0FBQyxDQUFDO1FBQzlHLENBQUM7UUFFRCwyRUFBMkU7UUFDM0UsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsa0NBQWtDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDaEUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFM0Usa0RBQWtEO1FBQ2xELE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxzQkFBc0IsQ0FDdkQsRUFBRSxFQUNGLElBQUksQ0FBQyxrQkFBa0IsRUFDdkIsSUFBSSxDQUFDLFNBQVMsRUFDZCxJQUFJLENBQUMsZUFBZSxDQUNyQixDQUFDO1FBRUYsTUFBTSxPQUFPLEdBQUcsS0FBSyxJQUFJLEVBQUU7WUFDekIsTUFBTSxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDO1FBRUYsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEVBQUUsRUFBRSxzQkFBc0IsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM5RSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDaEMsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsc0NBQXNDO0lBQzVCLHVCQUF1QixDQUMvQixFQUF3QixFQUN4QixzQkFBOEMsRUFDOUMsT0FBNEI7UUFFNUIsT0FBTyxJQUFJLGVBQWUsQ0FDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsRUFDakMsc0JBQXNCLEVBQ3RCLElBQUksQ0FBQyxTQUFTLEVBQ2QsSUFBSSxDQUFDLGFBQWEsRUFDbEIsSUFBSSxDQUFDLG1CQUFtQixFQUN4QixJQUFJLENBQUMsVUFBVSxFQUNmLElBQUksQ0FBQyxPQUFPLEVBQ1osT0FBTyxDQUNSLENBQUM7SUFDSixDQUFDO0NBQ0YifQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/prover-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js"
|
|
@@ -49,16 +49,17 @@
|
|
|
49
49
|
]
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@aztec/archiver": "0.
|
|
53
|
-
"@aztec/circuit-types": "0.
|
|
54
|
-
"@aztec/circuits.js": "0.
|
|
55
|
-
"@aztec/foundation": "0.
|
|
56
|
-
"@aztec/kv-store": "0.
|
|
57
|
-
"@aztec/prover-client": "0.
|
|
58
|
-
"@aztec/sequencer-client": "0.
|
|
59
|
-
"@aztec/simulator": "0.
|
|
60
|
-
"@aztec/telemetry-client": "0.
|
|
61
|
-
"@aztec/
|
|
52
|
+
"@aztec/archiver": "0.51.0",
|
|
53
|
+
"@aztec/circuit-types": "0.51.0",
|
|
54
|
+
"@aztec/circuits.js": "0.51.0",
|
|
55
|
+
"@aztec/foundation": "0.51.0",
|
|
56
|
+
"@aztec/kv-store": "0.51.0",
|
|
57
|
+
"@aztec/prover-client": "0.51.0",
|
|
58
|
+
"@aztec/sequencer-client": "0.51.0",
|
|
59
|
+
"@aztec/simulator": "0.51.0",
|
|
60
|
+
"@aztec/telemetry-client": "0.51.0",
|
|
61
|
+
"@aztec/types": "0.51.0",
|
|
62
|
+
"@aztec/world-state": "0.51.0",
|
|
62
63
|
"source-map-support": "^0.5.21",
|
|
63
64
|
"tslib": "^2.4.0"
|
|
64
65
|
},
|
package/src/config.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { type ArchiverConfig, archiverConfigMappings, getArchiverConfigFromEnv } from '@aztec/archiver';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type ConfigMappingsType,
|
|
4
|
+
booleanConfigHelper,
|
|
5
|
+
getConfigFromMappings,
|
|
6
|
+
numberConfigHelper,
|
|
7
|
+
} from '@aztec/foundation/config';
|
|
3
8
|
import { type ProverClientConfig, getProverEnvVars, proverClientConfigMappings } from '@aztec/prover-client';
|
|
4
9
|
import {
|
|
5
10
|
type PublisherConfig,
|
|
@@ -18,7 +23,25 @@ export type ProverNodeConfig = ArchiverConfig &
|
|
|
18
23
|
WorldStateConfig &
|
|
19
24
|
PublisherConfig &
|
|
20
25
|
TxSenderConfig &
|
|
21
|
-
TxProviderConfig
|
|
26
|
+
TxProviderConfig & {
|
|
27
|
+
proverNodeDisableAutomaticProving?: boolean;
|
|
28
|
+
proverNodeMaxPendingJobs?: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const specificProverNodeConfigMappings: ConfigMappingsType<
|
|
32
|
+
Pick<ProverNodeConfig, 'proverNodeDisableAutomaticProving' | 'proverNodeMaxPendingJobs'>
|
|
33
|
+
> = {
|
|
34
|
+
proverNodeDisableAutomaticProving: {
|
|
35
|
+
env: 'PROVER_NODE_DISABLE_AUTOMATIC_PROVING',
|
|
36
|
+
description: 'Whether to disable automatic proving of pending blocks seen on L1',
|
|
37
|
+
...booleanConfigHelper(false),
|
|
38
|
+
},
|
|
39
|
+
proverNodeMaxPendingJobs: {
|
|
40
|
+
env: 'PROVER_NODE_MAX_PENDING_JOBS',
|
|
41
|
+
description: 'The maximum number of pending jobs for the prover node',
|
|
42
|
+
...numberConfigHelper(100),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
22
45
|
|
|
23
46
|
export const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConfig> = {
|
|
24
47
|
...archiverConfigMappings,
|
|
@@ -27,6 +50,7 @@ export const proverNodeConfigMappings: ConfigMappingsType<ProverNodeConfig> = {
|
|
|
27
50
|
...getPublisherConfigMappings('PROVER'),
|
|
28
51
|
...getTxSenderConfigMappings('PROVER'),
|
|
29
52
|
...txProviderConfigMappings,
|
|
53
|
+
...specificProverNodeConfigMappings,
|
|
30
54
|
};
|
|
31
55
|
|
|
32
56
|
export function getProverNodeConfigFromEnv(): ProverNodeConfig {
|
|
@@ -37,5 +61,6 @@ export function getProverNodeConfigFromEnv(): ProverNodeConfig {
|
|
|
37
61
|
...getPublisherConfigFromEnv('PROVER'),
|
|
38
62
|
...getTxSenderConfigFromEnv('PROVER'),
|
|
39
63
|
...getTxProviderConfigFromEnv(),
|
|
64
|
+
...getConfigFromMappings(specificProverNodeConfigMappings),
|
|
40
65
|
};
|
|
41
66
|
}
|
package/src/factory.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type AztecNode } from '@aztec/circuit-types';
|
|
|
3
3
|
import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { createStore } from '@aztec/kv-store/utils';
|
|
5
5
|
import { createProverClient } from '@aztec/prover-client';
|
|
6
|
-
import {
|
|
6
|
+
import { L1Publisher } from '@aztec/sequencer-client';
|
|
7
7
|
import { createSimulationProvider } from '@aztec/simulator';
|
|
8
8
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
9
9
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
@@ -35,7 +35,7 @@ export async function createProverNode(
|
|
|
35
35
|
log.verbose(`Created archiver and synced to block ${await archiver.getBlockNumber()}`);
|
|
36
36
|
|
|
37
37
|
const worldStateConfig = { ...config, worldStateProvenBlocksOnly: true };
|
|
38
|
-
const worldStateSynchronizer = await createWorldStateSynchronizer(worldStateConfig, store, archiver);
|
|
38
|
+
const worldStateSynchronizer = await createWorldStateSynchronizer(worldStateConfig, store, archiver, telemetry);
|
|
39
39
|
await worldStateSynchronizer.start();
|
|
40
40
|
|
|
41
41
|
const simulationProvider = await createSimulationProvider(config, log);
|
|
@@ -43,7 +43,7 @@ export async function createProverNode(
|
|
|
43
43
|
const prover = await createProverClient(config, telemetry);
|
|
44
44
|
|
|
45
45
|
// REFACTOR: Move publisher out of sequencer package and into an L1-related package
|
|
46
|
-
const publisher =
|
|
46
|
+
const publisher = new L1Publisher(config, telemetry);
|
|
47
47
|
|
|
48
48
|
const txProvider = deps.aztecNodeTxProvider
|
|
49
49
|
? new AztecNodeTxProvider(deps.aztecNodeTxProvider)
|
|
@@ -59,5 +59,9 @@ export async function createProverNode(
|
|
|
59
59
|
txProvider,
|
|
60
60
|
simulationProvider,
|
|
61
61
|
telemetry,
|
|
62
|
+
{
|
|
63
|
+
disableAutomaticProving: config.proverNodeDisableAutomaticProving,
|
|
64
|
+
maxPendingJobs: config.proverNodeMaxPendingJobs,
|
|
65
|
+
},
|
|
62
66
|
);
|
|
63
67
|
}
|
|
@@ -11,9 +11,14 @@ import {
|
|
|
11
11
|
type TxProvider,
|
|
12
12
|
} from '@aztec/circuit-types';
|
|
13
13
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
14
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
14
15
|
import { type L1Publisher } from '@aztec/sequencer-client';
|
|
15
16
|
import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simulator';
|
|
16
17
|
|
|
18
|
+
import * as crypto from 'node:crypto';
|
|
19
|
+
|
|
20
|
+
import { type ProverNodeMetrics } from '../metrics.js';
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
* Job that grabs a range of blocks from the unfinalised chain from L1, gets their txs given their hashes,
|
|
19
24
|
* re-executes their public calls, generates a rollup proof, and submits it to L1. This job will update the
|
|
@@ -22,6 +27,7 @@ import { type PublicProcessor, type PublicProcessorFactory } from '@aztec/simula
|
|
|
22
27
|
export class BlockProvingJob {
|
|
23
28
|
private state: BlockProvingJobState = 'initialized';
|
|
24
29
|
private log = createDebugLogger('aztec:block-proving-job');
|
|
30
|
+
private uuid: string;
|
|
25
31
|
|
|
26
32
|
constructor(
|
|
27
33
|
private prover: BlockProver,
|
|
@@ -30,8 +36,15 @@ export class BlockProvingJob {
|
|
|
30
36
|
private l2BlockSource: L2BlockSource,
|
|
31
37
|
private l1ToL2MessageSource: L1ToL2MessageSource,
|
|
32
38
|
private txProvider: TxProvider,
|
|
33
|
-
private
|
|
34
|
-
|
|
39
|
+
private metrics: ProverNodeMetrics,
|
|
40
|
+
private cleanUp: (job: BlockProvingJob) => Promise<void> = () => Promise.resolve(),
|
|
41
|
+
) {
|
|
42
|
+
this.uuid = crypto.randomUUID();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public getId(): string {
|
|
46
|
+
return this.uuid;
|
|
47
|
+
}
|
|
35
48
|
|
|
36
49
|
public getState(): BlockProvingJobState {
|
|
37
50
|
return this.state;
|
|
@@ -42,8 +55,9 @@ export class BlockProvingJob {
|
|
|
42
55
|
throw new Error(`Block ranges are not yet supported`);
|
|
43
56
|
}
|
|
44
57
|
|
|
45
|
-
this.log.info(`Starting block proving job`, { fromBlock, toBlock });
|
|
58
|
+
this.log.info(`Starting block proving job`, { fromBlock, toBlock, uuid: this.uuid });
|
|
46
59
|
this.state = 'processing';
|
|
60
|
+
const timer = new Timer();
|
|
47
61
|
try {
|
|
48
62
|
let historicalHeader = (await this.l2BlockSource.getBlock(fromBlock - 1))?.header;
|
|
49
63
|
for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {
|
|
@@ -61,6 +75,7 @@ export class BlockProvingJob {
|
|
|
61
75
|
nullifierTreeRoot: block.header.state.partial.nullifierTree.root,
|
|
62
76
|
publicDataTreeRoot: block.header.state.partial.publicDataTree.root,
|
|
63
77
|
historicalHeader: historicalHeader?.hash(),
|
|
78
|
+
uuid: this.uuid,
|
|
64
79
|
...globalVariables,
|
|
65
80
|
});
|
|
66
81
|
|
|
@@ -75,6 +90,7 @@ export class BlockProvingJob {
|
|
|
75
90
|
this.log.verbose(`Processed all txs for block`, {
|
|
76
91
|
blockNumber: block.number,
|
|
77
92
|
blockHash: block.hash().toString(),
|
|
93
|
+
uuid: this.uuid,
|
|
78
94
|
});
|
|
79
95
|
|
|
80
96
|
await this.prover.setBlockCompleted();
|
|
@@ -90,7 +106,7 @@ export class BlockProvingJob {
|
|
|
90
106
|
}
|
|
91
107
|
|
|
92
108
|
const { block, aggregationObject, proof } = await this.prover.finaliseBlock();
|
|
93
|
-
this.log.info(`Finalised proof for block range`, { fromBlock, toBlock });
|
|
109
|
+
this.log.info(`Finalised proof for block range`, { fromBlock, toBlock, uuid: this.uuid });
|
|
94
110
|
|
|
95
111
|
this.state = 'publishing-proof';
|
|
96
112
|
await this.publisher.submitProof(
|
|
@@ -100,17 +116,22 @@ export class BlockProvingJob {
|
|
|
100
116
|
aggregationObject,
|
|
101
117
|
proof,
|
|
102
118
|
);
|
|
103
|
-
this.log.info(`Submitted proof for block range`, { fromBlock, toBlock });
|
|
119
|
+
this.log.info(`Submitted proof for block range`, { fromBlock, toBlock, uuid: this.uuid });
|
|
104
120
|
|
|
105
121
|
this.state = 'completed';
|
|
122
|
+
this.metrics.recordProvingJob(timer);
|
|
106
123
|
} catch (err) {
|
|
107
|
-
this.log.error(`Error running block prover job:
|
|
124
|
+
this.log.error(`Error running block prover job`, err, { uuid: this.uuid });
|
|
108
125
|
this.state = 'failed';
|
|
109
126
|
} finally {
|
|
110
|
-
await this.cleanUp();
|
|
127
|
+
await this.cleanUp(this);
|
|
111
128
|
}
|
|
112
129
|
}
|
|
113
130
|
|
|
131
|
+
public stop() {
|
|
132
|
+
this.prover.cancelBlock();
|
|
133
|
+
}
|
|
134
|
+
|
|
114
135
|
private async getBlock(blockNumber: number): Promise<L2Block> {
|
|
115
136
|
const block = await this.l2BlockSource.getBlock(blockNumber);
|
|
116
137
|
if (!block) {
|
package/src/metrics.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Timer } from '@aztec/foundation/timer';
|
|
2
|
+
import { type Histogram, Metrics, type TelemetryClient, ValueType, millisecondBuckets } from '@aztec/telemetry-client';
|
|
3
|
+
|
|
4
|
+
export class ProverNodeMetrics {
|
|
5
|
+
provingJobDuration: Histogram;
|
|
6
|
+
|
|
7
|
+
constructor(client: TelemetryClient, name = 'ProverNode') {
|
|
8
|
+
const meter = client.getMeter(name);
|
|
9
|
+
this.provingJobDuration = meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION, {
|
|
10
|
+
description: 'Duration of proving job',
|
|
11
|
+
unit: 'ms',
|
|
12
|
+
valueType: ValueType.INT,
|
|
13
|
+
advice: {
|
|
14
|
+
explicitBucketBoundaries: millisecondBuckets(2), // 60 buckets spanning an interval of ~100ms to ~1hour
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public recordProvingJob(timerOrMs: Timer | number) {
|
|
20
|
+
const ms = Math.ceil(typeof timerOrMs === 'number' ? timerOrMs : timerOrMs.ms());
|
|
21
|
+
this.provingJobDuration.record(ms);
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/prover-node.ts
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type L1ToL2MessageSource,
|
|
3
|
+
type L2BlockSource,
|
|
4
|
+
type MerkleTreeOperations,
|
|
5
|
+
type ProverClient,
|
|
6
|
+
type TxProvider,
|
|
7
|
+
} from '@aztec/circuit-types';
|
|
2
8
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
9
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
4
10
|
import { type L1Publisher } from '@aztec/sequencer-client';
|
|
5
11
|
import { PublicProcessorFactory, type SimulationProvider } from '@aztec/simulator';
|
|
6
12
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
13
|
+
import { type ContractDataSource } from '@aztec/types/contracts';
|
|
7
14
|
import { type WorldStateSynchronizer } from '@aztec/world-state';
|
|
8
15
|
|
|
9
|
-
import { type
|
|
10
|
-
import {
|
|
16
|
+
import { BlockProvingJob, type BlockProvingJobState } from './job/block-proving-job.js';
|
|
17
|
+
import { ProverNodeMetrics } from './metrics.js';
|
|
11
18
|
|
|
12
19
|
/**
|
|
13
20
|
* An Aztec Prover Node is a standalone process that monitors the unfinalised chain on L1 for unproven blocks,
|
|
@@ -18,6 +25,9 @@ export class ProverNode {
|
|
|
18
25
|
private log = createDebugLogger('aztec:prover-node');
|
|
19
26
|
private runningPromise: RunningPromise | undefined;
|
|
20
27
|
private latestBlockWeAreProving: number | undefined;
|
|
28
|
+
private jobs: Map<string, BlockProvingJob> = new Map();
|
|
29
|
+
private options: { pollingIntervalMs: number; disableAutomaticProving: boolean; maxPendingJobs: number };
|
|
30
|
+
private metrics: ProverNodeMetrics;
|
|
21
31
|
|
|
22
32
|
constructor(
|
|
23
33
|
private prover: ProverClient,
|
|
@@ -29,11 +39,17 @@ export class ProverNode {
|
|
|
29
39
|
private txProvider: TxProvider,
|
|
30
40
|
private simulator: SimulationProvider,
|
|
31
41
|
private telemetryClient: TelemetryClient,
|
|
32
|
-
|
|
42
|
+
options: { pollingIntervalMs?: number; disableAutomaticProving?: boolean; maxPendingJobs?: number } = {},
|
|
43
|
+
) {
|
|
44
|
+
this.options = {
|
|
33
45
|
pollingIntervalMs: 1_000,
|
|
34
46
|
disableAutomaticProving: false,
|
|
35
|
-
|
|
36
|
-
|
|
47
|
+
maxPendingJobs: 100,
|
|
48
|
+
...options,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
this.metrics = new ProverNodeMetrics(telemetryClient, 'ProverNode');
|
|
52
|
+
}
|
|
37
53
|
|
|
38
54
|
/**
|
|
39
55
|
* Starts the prover node so it periodically checks for unproven blocks in the unfinalised chain from L1 and proves them.
|
|
@@ -54,8 +70,9 @@ export class ProverNode {
|
|
|
54
70
|
await this.prover.stop();
|
|
55
71
|
await this.l2BlockSource.stop();
|
|
56
72
|
this.publisher.interrupt();
|
|
73
|
+
this.jobs.forEach(job => job.stop());
|
|
74
|
+
await this.worldState.stop();
|
|
57
75
|
this.log.info('Stopped ProverNode');
|
|
58
|
-
// TODO(palla/prover-node): Keep a reference to all ongoing ProvingJobs and stop them.
|
|
59
76
|
}
|
|
60
77
|
|
|
61
78
|
/**
|
|
@@ -68,6 +85,14 @@ export class ProverNode {
|
|
|
68
85
|
return;
|
|
69
86
|
}
|
|
70
87
|
|
|
88
|
+
if (!this.checkMaximumPendingJobs()) {
|
|
89
|
+
this.log.debug(`Maximum pending proving jobs reached. Skipping work.`, {
|
|
90
|
+
maxPendingJobs: this.options.maxPendingJobs,
|
|
91
|
+
pendingJobs: this.jobs.size,
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
71
96
|
const [latestBlockNumber, latestProvenBlockNumber] = await Promise.all([
|
|
72
97
|
this.l2BlockSource.getBlockNumber(),
|
|
73
98
|
this.l2BlockSource.getProvenBlockNumber(),
|
|
@@ -88,8 +113,13 @@ export class ProverNode {
|
|
|
88
113
|
const fromBlock = latestProven + 1;
|
|
89
114
|
const toBlock = fromBlock; // We only prove one block at a time for now
|
|
90
115
|
|
|
91
|
-
|
|
92
|
-
|
|
116
|
+
try {
|
|
117
|
+
await this.startProof(fromBlock, toBlock);
|
|
118
|
+
} finally {
|
|
119
|
+
// If we fail to create a proving job for the given block, skip it instead of getting stuck on it.
|
|
120
|
+
this.log.verbose(`Setting ${toBlock} as latest block we are proving`);
|
|
121
|
+
this.latestBlockWeAreProving = toBlock;
|
|
122
|
+
}
|
|
93
123
|
} catch (err) {
|
|
94
124
|
this.log.error(`Error in prover node work`, err);
|
|
95
125
|
}
|
|
@@ -118,12 +148,29 @@ export class ProverNode {
|
|
|
118
148
|
return this.prover;
|
|
119
149
|
}
|
|
120
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Returns an array of jobs being processed.
|
|
153
|
+
*/
|
|
154
|
+
public getJobs(): { uuid: string; status: BlockProvingJobState }[] {
|
|
155
|
+
return Array.from(this.jobs.entries()).map(([uuid, job]) => ({ uuid, status: job.getState() }));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private checkMaximumPendingJobs() {
|
|
159
|
+
const { maxPendingJobs } = this.options;
|
|
160
|
+
return maxPendingJobs === 0 || this.jobs.size < maxPendingJobs;
|
|
161
|
+
}
|
|
162
|
+
|
|
121
163
|
private async createProvingJob(fromBlock: number) {
|
|
164
|
+
if (!this.checkMaximumPendingJobs()) {
|
|
165
|
+
throw new Error(`Maximum pending proving jobs ${this.options.maxPendingJobs} reached. Cannot create new job.`);
|
|
166
|
+
}
|
|
167
|
+
|
|
122
168
|
if ((await this.worldState.status()).syncedToL2Block >= fromBlock) {
|
|
123
169
|
throw new Error(`Cannot create proving job for block ${fromBlock} as it is behind the current world state`);
|
|
124
170
|
}
|
|
125
171
|
|
|
126
172
|
// Fast forward world state to right before the target block and get a fork
|
|
173
|
+
this.log.verbose(`Creating proving job for block ${fromBlock}`);
|
|
127
174
|
const db = await this.worldState.syncImmediateAndFork(fromBlock - 1, true);
|
|
128
175
|
|
|
129
176
|
// Create a processor using the forked world state
|
|
@@ -134,6 +181,22 @@ export class ProverNode {
|
|
|
134
181
|
this.telemetryClient,
|
|
135
182
|
);
|
|
136
183
|
|
|
184
|
+
const cleanUp = async () => {
|
|
185
|
+
await db.delete();
|
|
186
|
+
this.jobs.delete(job.getId());
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const job = this.doCreateBlockProvingJob(db, publicProcessorFactory, cleanUp);
|
|
190
|
+
this.jobs.set(job.getId(), job);
|
|
191
|
+
return job;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Extracted for testing purposes. */
|
|
195
|
+
protected doCreateBlockProvingJob(
|
|
196
|
+
db: MerkleTreeOperations,
|
|
197
|
+
publicProcessorFactory: PublicProcessorFactory,
|
|
198
|
+
cleanUp: () => Promise<void>,
|
|
199
|
+
) {
|
|
137
200
|
return new BlockProvingJob(
|
|
138
201
|
this.prover.createBlockProver(db),
|
|
139
202
|
publicProcessorFactory,
|
|
@@ -141,7 +204,8 @@ export class ProverNode {
|
|
|
141
204
|
this.l2BlockSource,
|
|
142
205
|
this.l1ToL2MessageSource,
|
|
143
206
|
this.txProvider,
|
|
144
|
-
|
|
207
|
+
this.metrics,
|
|
208
|
+
cleanUp,
|
|
145
209
|
);
|
|
146
210
|
}
|
|
147
211
|
}
|