@aztec/prover-node 5.0.0-private.20260319 → 5.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +506 -0
- package/dest/actions/download-epoch-proving-job.js +1 -1
- package/dest/actions/rerun-epoch-proving-job.d.ts +4 -3
- package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -1
- package/dest/actions/rerun-epoch-proving-job.js +103 -21
- package/dest/bin/run-failed-epoch.js +1 -3
- package/dest/checkpoint-store.d.ts +83 -0
- package/dest/checkpoint-store.d.ts.map +1 -0
- package/dest/checkpoint-store.js +181 -0
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- 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 +22 -8
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/job/checkpoint-prover.d.ts +134 -0
- package/dest/job/checkpoint-prover.d.ts.map +1 -0
- package/dest/job/checkpoint-prover.js +350 -0
- package/dest/job/epoch-session.d.ts +146 -0
- package/dest/job/epoch-session.d.ts.map +1 -0
- package/dest/job/epoch-session.js +709 -0
- package/dest/job/top-tree-job.d.ts +82 -0
- package/dest/job/top-tree-job.d.ts.map +1 -0
- package/dest/job/top-tree-job.js +152 -0
- package/dest/metrics.d.ts +29 -5
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +73 -9
- package/dest/monitors/epoch-monitor.js +6 -2
- package/dest/proof-publishing-service.d.ts +159 -0
- package/dest/proof-publishing-service.d.ts.map +1 -0
- package/dest/proof-publishing-service.js +334 -0
- package/dest/prover-node-publisher.d.ts +18 -11
- package/dest/prover-node-publisher.d.ts.map +1 -1
- package/dest/prover-node-publisher.js +195 -57
- package/dest/prover-node.d.ts +96 -68
- package/dest/prover-node.d.ts.map +1 -1
- package/dest/prover-node.js +382 -227
- 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/dest/session-manager.d.ts +158 -0
- package/dest/session-manager.d.ts.map +1 -0
- package/dest/session-manager.js +452 -0
- package/dest/test/index.d.ts +7 -6
- package/dest/test/index.d.ts.map +1 -1
- package/package.json +23 -23
- package/src/actions/download-epoch-proving-job.ts +1 -1
- package/src/actions/rerun-epoch-proving-job.ts +114 -28
- package/src/bin/run-failed-epoch.ts +1 -2
- package/src/checkpoint-store.ts +213 -0
- package/src/config.ts +2 -1
- package/src/factory.ts +18 -10
- package/src/index.ts +1 -0
- package/src/job/checkpoint-prover.ts +465 -0
- package/src/job/epoch-session.ts +424 -0
- package/src/job/top-tree-job.ts +227 -0
- package/src/metrics.ts +88 -12
- package/src/monitors/epoch-monitor.ts +2 -2
- package/src/proof-publishing-service.ts +424 -0
- package/src/prover-node-publisher.ts +220 -67
- package/src/prover-node.ts +439 -249
- package/src/prover-publisher-factory.ts +3 -3
- package/src/session-manager.ts +552 -0
- package/src/test/index.ts +6 -6
- package/dest/job/epoch-proving-job.d.ts +0 -63
- package/dest/job/epoch-proving-job.d.ts.map +0 -1
- package/dest/job/epoch-proving-job.js +0 -762
- package/src/job/epoch-proving-job.ts +0 -465
|
@@ -1,40 +1,122 @@
|
|
|
1
|
-
import { createArchiverStore } from '@aztec/archiver';
|
|
1
|
+
import { createArchiverStore, createContractDataSource } from '@aztec/archiver';
|
|
2
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
2
4
|
import { createProverClient } from '@aztec/prover-client';
|
|
3
5
|
import { createAndStartProvingBroker } from '@aztec/prover-client/broker';
|
|
6
|
+
import { getLastSiblingPath } from '@aztec/prover-client/helpers';
|
|
7
|
+
import { ChonkCache } from '@aztec/prover-client/orchestrator';
|
|
4
8
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
9
|
+
import { getEpochAtSlot, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
10
|
+
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
5
11
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
6
12
|
import { createWorldState } from '@aztec/world-state';
|
|
7
13
|
import { readFileSync } from 'fs';
|
|
14
|
+
import { CheckpointProver } from '../job/checkpoint-prover.js';
|
|
8
15
|
import { deserializeEpochProvingJobData } from '../job/epoch-proving-job-data.js';
|
|
9
|
-
import {
|
|
16
|
+
import { EpochSession } from '../job/epoch-session.js';
|
|
10
17
|
import { ProverNodeJobMetrics } from '../metrics.js';
|
|
11
18
|
/**
|
|
12
19
|
* Given a local folder where `downloadEpochProvingJob` was called, creates a new archiver and world state
|
|
13
|
-
* using the state snapshots, and creates a new epoch proving
|
|
20
|
+
* using the state snapshots, and creates a new epoch proving session to prove the downloaded proving job.
|
|
14
21
|
* Proving is done with a local proving broker and agents as specified by the config.
|
|
15
|
-
*/ export async function rerunEpochProvingJob(localPath, log, config) {
|
|
22
|
+
*/ export async function rerunEpochProvingJob(localPath, log, config, genesis) {
|
|
16
23
|
const jobData = deserializeEpochProvingJobData(readFileSync(localPath));
|
|
17
24
|
log.info(`Loaded proving job data for epoch ${jobData.epochNumber}`);
|
|
18
25
|
const telemetry = getTelemetryClient();
|
|
19
26
|
const metrics = new ProverNodeJobMetrics(telemetry.getMeter('prover-job'), telemetry.getTracer('prover-job'));
|
|
20
|
-
const worldState = await createWorldState(config);
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
27
|
+
const worldState = await createWorldState(config, genesis);
|
|
28
|
+
const initialBlockHash = await worldState.getInitialHeader().hash();
|
|
29
|
+
const archiver = await createArchiverStore(config, initialBlockHash);
|
|
30
|
+
const publicProcessorFactory = new PublicProcessorFactory(createContractDataSource(archiver), undefined, undefined, log.getBindings());
|
|
31
|
+
// Local rerun never publishes — stub the service so submit() always resolves 'published'
|
|
32
|
+
// and withdraw is a no-op.
|
|
33
|
+
const publishingService = {
|
|
34
|
+
submit: ()=>Promise.resolve('published'),
|
|
35
|
+
withdraw: ()=>{}
|
|
25
36
|
};
|
|
26
|
-
const l2BlockSourceForReorgDetection = undefined;
|
|
27
|
-
const deadline = undefined;
|
|
28
|
-
// This starts a local proving broker that does not get exposed as a service. This should be good enough for
|
|
29
|
-
// smallish epochs to be proven if we run on a large machine, but as epochs grow larger, we may want to switch
|
|
30
|
-
// this out for a live proving broker with multiple agents that we can connect to.
|
|
31
37
|
const broker = await createAndStartProvingBroker(config, telemetry);
|
|
32
38
|
const prover = await createProverClient(config, worldState, broker, telemetry);
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
const chonkCache = new ChonkCache(log.getBindings());
|
|
40
|
+
const txProvider = makeReplayingTxProvider(jobData.txs);
|
|
41
|
+
log.info(`Rerunning epoch proving for epoch ${jobData.epochNumber}`);
|
|
42
|
+
const provers = [];
|
|
43
|
+
for(let i = 0; i < jobData.checkpoints.length; i++){
|
|
44
|
+
const checkpoint = jobData.checkpoints[i];
|
|
45
|
+
const previousBlockHeader = i === 0 ? jobData.previousBlockHeader : jobData.checkpoints[i - 1].blocks.at(-1).header;
|
|
46
|
+
const l1ToL2Messages = jobData.l1ToL2Messages[checkpoint.number] ?? [];
|
|
47
|
+
const previousArchiveSiblingPath = await getLastSiblingPath(MerkleTreeId.ARCHIVE, worldState.getSnapshot(BlockNumber(checkpoint.blocks[0].number - 1)));
|
|
48
|
+
const attestations = checkpoint.number === jobData.checkpoints.at(-1).number ? jobData.attestations : [];
|
|
49
|
+
provers.push(new CheckpointProver({
|
|
50
|
+
checkpoint,
|
|
51
|
+
epochNumber: jobData.epochNumber,
|
|
52
|
+
attestations,
|
|
53
|
+
previousBlockHeader,
|
|
54
|
+
l1ToL2Messages,
|
|
55
|
+
previousArchiveSiblingPath
|
|
56
|
+
}, {
|
|
57
|
+
proverFactory: prover,
|
|
58
|
+
chonkCache,
|
|
59
|
+
publicProcessorFactory,
|
|
60
|
+
dbProvider: worldState,
|
|
61
|
+
txProvider,
|
|
62
|
+
dateProvider: new DateProvider(),
|
|
63
|
+
proverId: prover.getProverId(),
|
|
64
|
+
metrics,
|
|
65
|
+
txGatheringTimeoutMs: 120_000,
|
|
66
|
+
deadline: undefined,
|
|
67
|
+
log
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
const l1Constants = {
|
|
71
|
+
epochDuration: config.aztecEpochDuration
|
|
72
|
+
};
|
|
73
|
+
const [fromSlot, toSlot] = getSlotRangeForEpoch(jobData.epochNumber, l1Constants);
|
|
74
|
+
const spec = {
|
|
75
|
+
kind: 'full',
|
|
76
|
+
epochNumber: jobData.epochNumber,
|
|
77
|
+
fromSlot,
|
|
78
|
+
toSlot
|
|
79
|
+
};
|
|
80
|
+
const session = new EpochSession(spec, provers, {
|
|
81
|
+
proverFactory: prover,
|
|
82
|
+
proverId: prover.getProverId(),
|
|
83
|
+
publishingService,
|
|
84
|
+
metrics,
|
|
85
|
+
dateProvider: new DateProvider(),
|
|
86
|
+
deadline: undefined,
|
|
87
|
+
config: {},
|
|
88
|
+
bindings: log.getBindings()
|
|
89
|
+
});
|
|
90
|
+
const finalState = await session.start();
|
|
91
|
+
log.info(`Completed proving for epoch ${jobData.epochNumber} with status ${finalState}`, {
|
|
92
|
+
derivedEpoch: getEpochAtSlot(provers[0].slotNumber, l1Constants)
|
|
93
|
+
});
|
|
94
|
+
return finalState;
|
|
95
|
+
}
|
|
96
|
+
/** Build a synthetic ITxProvider that returns the supplied txs map by lookup. */ function makeReplayingTxProvider(txs) {
|
|
97
|
+
const lookup = (hashes)=>{
|
|
98
|
+
const found = [];
|
|
99
|
+
const missing = [];
|
|
100
|
+
for (const hash of hashes){
|
|
101
|
+
const tx = txs.get(hash.toString());
|
|
102
|
+
if (tx) {
|
|
103
|
+
found.push(tx);
|
|
104
|
+
} else {
|
|
105
|
+
missing.push(hash);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
txs: found,
|
|
110
|
+
missingTxs: missing
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
return {
|
|
114
|
+
getAvailableTxs: (hashes)=>Promise.resolve(lookup(hashes)),
|
|
115
|
+
hasTxs: (hashes)=>Promise.resolve(hashes.map((h)=>txs.has(h.toString()))),
|
|
116
|
+
getTxsForBlockProposal: ()=>Promise.resolve({
|
|
117
|
+
txs: [],
|
|
118
|
+
missingTxs: []
|
|
119
|
+
}),
|
|
120
|
+
getTxsForBlock: (block)=>Promise.resolve(lookup(block.body.txEffects.map((e)=>e.txHash)))
|
|
121
|
+
};
|
|
40
122
|
}
|
|
@@ -41,9 +41,7 @@ async function rerunFailedEpoch(provingJobUrl, baseLocalDir) {
|
|
|
41
41
|
logger.info(`Rerunning proving job from ${jobPath} with state from ${dataDir}`, metadata);
|
|
42
42
|
const result = await rerunEpochProvingJob(jobPath, logger, {
|
|
43
43
|
...config,
|
|
44
|
-
|
|
45
|
-
rollupAddress: metadata.rollupAddress
|
|
46
|
-
},
|
|
44
|
+
rollupAddress: metadata.rollupAddress,
|
|
47
45
|
rollupVersion: metadata.rollupVersion
|
|
48
46
|
});
|
|
49
47
|
console.error(`Epoch proving job complete with result ${result}`);
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { type LoggerBindings } from '@aztec/foundation/log';
|
|
3
|
+
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
4
|
+
import type { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
5
|
+
import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
6
|
+
import { CheckpointProver, type CheckpointProverArgs, type CheckpointProverDeps } from './job/checkpoint-prover.js';
|
|
7
|
+
/** Register-time data needed to construct a `CheckpointProver` (everything except the checkpoint + epoch). */
|
|
8
|
+
export type RegisterCheckpointData = Omit<CheckpointProverArgs, 'checkpoint' | 'epochNumber'>;
|
|
9
|
+
/** Factory used by the store to construct new provers. Tests can inject a stub. */
|
|
10
|
+
export type CheckpointProverFactory = (args: CheckpointProverArgs, deps: CheckpointProverDeps) => CheckpointProver;
|
|
11
|
+
/**
|
|
12
|
+
* Prover-node-wide registry of `CheckpointProver` instances, content-addressed by
|
|
13
|
+
* `(checkpoint number, slot, checkpoint archive root)`.
|
|
14
|
+
*
|
|
15
|
+
* The store survives every epoch / session boundary. A prover lives from its first
|
|
16
|
+
* `addOrUpdate` call until either:
|
|
17
|
+
* - it has been pruned and the L2 chain has moved past its slot (no re-add possible), or
|
|
18
|
+
* - its epoch's proof-submission window has closed (`reapExpired`), so the proof could no
|
|
19
|
+
* longer be accepted on L1 even if produced.
|
|
20
|
+
*
|
|
21
|
+
* A re-add of a checkpoint that matches an existing prover's content key reuses the
|
|
22
|
+
* existing prover (and flips it back to canonical); the in-flight sub-tree work never
|
|
23
|
+
* stops, so a prune-then-re-add of the same content avoids re-proving entirely.
|
|
24
|
+
*/
|
|
25
|
+
export declare class CheckpointStore {
|
|
26
|
+
private readonly l2BlockSource;
|
|
27
|
+
private readonly proverDeps;
|
|
28
|
+
private readonly options;
|
|
29
|
+
private readonly proverFactoryFn;
|
|
30
|
+
private readonly provers;
|
|
31
|
+
private readonly slotWatcher;
|
|
32
|
+
private readonly log;
|
|
33
|
+
constructor(l2BlockSource: Pick<L2BlockSource, 'getSyncedL2SlotNumber' | 'getL1Constants'>, proverDeps: Omit<CheckpointProverDeps, 'log'>, options: {
|
|
34
|
+
slotWatcherPollIntervalMs: number;
|
|
35
|
+
}, bindings?: LoggerBindings, proverFactoryFn?: CheckpointProverFactory);
|
|
36
|
+
start(): Promise<void>;
|
|
37
|
+
stop(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Registers a checkpoint with the store. If a prover already exists for the
|
|
40
|
+
* `(number, slot, archive root)` content key, it is reused and marked canonical;
|
|
41
|
+
* otherwise a new prover is constructed.
|
|
42
|
+
*/
|
|
43
|
+
addOrUpdate(checkpoint: Checkpoint, data: RegisterCheckpointData): Promise<CheckpointProver>;
|
|
44
|
+
/**
|
|
45
|
+
* Marks every canonical prover whose checkpoint number is strictly greater than
|
|
46
|
+
* `prunedNumber` as pruned. Sub-tree work keeps running so a re-add of the same
|
|
47
|
+
* content can pick it up. Returns the affected provers.
|
|
48
|
+
*/
|
|
49
|
+
markPrunedAfter(prunedNumber: CheckpointNumber): CheckpointProver[];
|
|
50
|
+
/**
|
|
51
|
+
* Drops canonical (non-pruned) provers whose epoch is at or below the supplied expired
|
|
52
|
+
* epoch. Once an epoch's proof-submission window has closed, its proof can no longer be
|
|
53
|
+
* accepted on L1, so the prover is no longer needed.
|
|
54
|
+
*/
|
|
55
|
+
reapExpired(expiredEpoch: EpochNumber): void;
|
|
56
|
+
/** Returns the prover with the supplied id, or undefined. */
|
|
57
|
+
get(id: string): CheckpointProver | undefined;
|
|
58
|
+
/** Returns the prover for the supplied checkpoint (by its content-addressed id), or undefined. */
|
|
59
|
+
getByCheckpoint(checkpoint: Checkpoint): CheckpointProver | undefined;
|
|
60
|
+
/** Every prover currently in the store (canonical and pruned), in insertion order. */
|
|
61
|
+
listAll(): CheckpointProver[];
|
|
62
|
+
/** Canonical (non-pruned) provers in the store, sorted by checkpoint number. */
|
|
63
|
+
listCanonical(): CheckpointProver[];
|
|
64
|
+
/**
|
|
65
|
+
* Canonical provers whose slot is in the supplied epoch's slot range, sorted by
|
|
66
|
+
* checkpoint number.
|
|
67
|
+
*/
|
|
68
|
+
listCanonicalForEpoch(epoch: EpochNumber): Promise<CheckpointProver[]>;
|
|
69
|
+
/** Canonical provers whose slot falls within `[fromSlot, toSlot]`, sorted by checkpoint number. */
|
|
70
|
+
listCanonicalInSlotRange(fromSlot: SlotNumber, toSlot: SlotNumber): CheckpointProver[];
|
|
71
|
+
/**
|
|
72
|
+
* SlotWatcher tick: reap pruned provers whose slot has passed the chain's synced
|
|
73
|
+
* slot. Once the chain has moved past, no re-add can revive the prover and its
|
|
74
|
+
* content key is unique enough that an actual re-add would create a new entry.
|
|
75
|
+
*
|
|
76
|
+
* Protected so unit tests can drive a single tick without spinning up the
|
|
77
|
+
* `RunningPromise` and waiting on its interval.
|
|
78
|
+
*/
|
|
79
|
+
protected reapPrunedPastSlot(): Promise<void>;
|
|
80
|
+
}
|
|
81
|
+
/** Sub-set of `L1RollupConstants` actually consumed by the store's slot helpers. */
|
|
82
|
+
export type CheckpointStoreL1Constants = Pick<L1RollupConstants, 'epochDuration'>;
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludC1zdG9yZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NoZWNrcG9pbnQtc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pHLE9BQU8sRUFBZSxLQUFLLGNBQWMsRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUV2RixPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN6RCxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsS0FBSyxpQkFBaUIsRUFBd0MsTUFBTSw2QkFBNkIsQ0FBQztBQUUzRyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxvQkFBb0IsRUFBRSxLQUFLLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFcEgsOEdBQThHO0FBQzlHLE1BQU0sTUFBTSxzQkFBc0IsR0FBRyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsWUFBWSxHQUFHLGFBQWEsQ0FBQyxDQUFDO0FBRTlGLG1GQUFtRjtBQUNuRixNQUFNLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxJQUFJLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixLQUFLLGdCQUFnQixDQUFDO0FBRW5IOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxxQkFBYSxlQUFlO0lBTXhCLE9BQU8sQ0FBQyxRQUFRLENBQUMsYUFBYTtJQUM5QixPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVU7SUFDM0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPO0lBRXhCLE9BQU8sQ0FBQyxRQUFRLENBQUMsZUFBZTtJQVRsQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBdUM7SUFDL0QsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQWlCO0lBQzdDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFTO0lBRTdCLFlBQ21CLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLHVCQUF1QixHQUFHLGdCQUFnQixDQUFDLEVBQzlFLFVBQVUsRUFBRSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsS0FBSyxDQUFDLEVBQzdDLE9BQU8sRUFBRTtRQUFFLHlCQUF5QixFQUFFLE1BQU0sQ0FBQTtLQUFFLEVBQy9ELFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFDUixlQUFlLEdBQUUsdUJBQTBFLEVBUTdHO0lBRU0sS0FBSyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FHNUI7SUFFWSxJQUFJLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQVNqQztJQUVEOzs7O09BSUc7SUFDVSxXQUFXLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsc0JBQXNCLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBMEJ4RztJQUVEOzs7O09BSUc7SUFDSSxlQUFlLENBQUMsWUFBWSxFQUFFLGdCQUFnQixHQUFHLGdCQUFnQixFQUFFLENBU3pFO0lBRUQ7Ozs7T0FJRztJQUNJLFdBQVcsQ0FBQyxZQUFZLEVBQUUsV0FBVyxHQUFHLElBQUksQ0FvQmxEO0lBRUQsNkRBQTZEO0lBQ3RELEdBQUcsQ0FBQyxFQUFFLEVBQUUsTUFBTSxHQUFHLGdCQUFnQixHQUFHLFNBQVMsQ0FFbkQ7SUFFRCxrR0FBa0c7SUFDM0YsZUFBZSxDQUFDLFVBQVUsRUFBRSxVQUFVLEdBQUcsZ0JBQWdCLEdBQUcsU0FBUyxDQUUzRTtJQUVELHNGQUFzRjtJQUMvRSxPQUFPLElBQUksZ0JBQWdCLEVBQUUsQ0FFbkM7SUFFRCxnRkFBZ0Y7SUFDekUsYUFBYSxJQUFJLGdCQUFnQixFQUFFLENBSXpDO0lBRUQ7OztPQUdHO0lBQ1UscUJBQXFCLENBQUMsS0FBSyxFQUFFLFdBQVcsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUlsRjtJQUVELG1HQUFtRztJQUM1Rix3QkFBd0IsQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxVQUFVLEdBQUcsZ0JBQWdCLEVBQUUsQ0FFNUY7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsVUFBZ0Isa0JBQWtCLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQXNCbEQ7Q0FDRjtBQUVELG9GQUFvRjtBQUNwRixNQUFNLE1BQU0sMEJBQTBCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLGVBQWUsQ0FBQyxDQUFDIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../src/checkpoint-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACjG,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AAEvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,KAAK,iBAAiB,EAAwC,MAAM,6BAA6B,CAAC;AAE3G,OAAO,EAAE,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEpH,8GAA8G;AAC9G,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,oBAAoB,EAAE,YAAY,GAAG,aAAa,CAAC,CAAC;AAE9F,mFAAmF;AACnF,MAAM,MAAM,uBAAuB,GAAG,CAAC,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,oBAAoB,KAAK,gBAAgB,CAAC;AAEnH;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAe;IAMxB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,eAAe;IATlC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiB;IAC7C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YACmB,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,uBAAuB,GAAG,gBAAgB,CAAC,EAC9E,UAAU,EAAE,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,EAC7C,OAAO,EAAE;QAAE,yBAAyB,EAAE,MAAM,CAAA;KAAE,EAC/D,QAAQ,CAAC,EAAE,cAAc,EACR,eAAe,GAAE,uBAA0E,EAQ7G;IAEM,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG5B;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CASjC;IAED;;;;OAIG;IACU,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0BxG;IAED;;;;OAIG;IACI,eAAe,CAAC,YAAY,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CASzE;IAED;;;;OAIG;IACI,WAAW,CAAC,YAAY,EAAE,WAAW,GAAG,IAAI,CAoBlD;IAED,6DAA6D;IACtD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEnD;IAED,kGAAkG;IAC3F,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAE3E;IAED,sFAAsF;IAC/E,OAAO,IAAI,gBAAgB,EAAE,CAEnC;IAED,gFAAgF;IACzE,aAAa,IAAI,gBAAgB,EAAE,CAIzC;IAED;;;OAGG;IACU,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAIlF;IAED,mGAAmG;IAC5F,wBAAwB,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAE5F;IAED;;;;;;;OAOG;IACH,UAAgB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBlD;CACF;AAED,oFAAoF;AACpF,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { RunningPromise } from '@aztec/foundation/promise';
|
|
3
|
+
import { getEpochAtSlot, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
4
|
+
import { CheckpointProver } from './job/checkpoint-prover.js';
|
|
5
|
+
/**
|
|
6
|
+
* Prover-node-wide registry of `CheckpointProver` instances, content-addressed by
|
|
7
|
+
* `(checkpoint number, slot, checkpoint archive root)`.
|
|
8
|
+
*
|
|
9
|
+
* The store survives every epoch / session boundary. A prover lives from its first
|
|
10
|
+
* `addOrUpdate` call until either:
|
|
11
|
+
* - it has been pruned and the L2 chain has moved past its slot (no re-add possible), or
|
|
12
|
+
* - its epoch's proof-submission window has closed (`reapExpired`), so the proof could no
|
|
13
|
+
* longer be accepted on L1 even if produced.
|
|
14
|
+
*
|
|
15
|
+
* A re-add of a checkpoint that matches an existing prover's content key reuses the
|
|
16
|
+
* existing prover (and flips it back to canonical); the in-flight sub-tree work never
|
|
17
|
+
* stops, so a prune-then-re-add of the same content avoids re-proving entirely.
|
|
18
|
+
*/ export class CheckpointStore {
|
|
19
|
+
l2BlockSource;
|
|
20
|
+
proverDeps;
|
|
21
|
+
options;
|
|
22
|
+
proverFactoryFn;
|
|
23
|
+
provers;
|
|
24
|
+
slotWatcher;
|
|
25
|
+
log;
|
|
26
|
+
constructor(l2BlockSource, proverDeps, options, bindings, proverFactoryFn = (args, deps)=>new CheckpointProver(args, deps)){
|
|
27
|
+
this.l2BlockSource = l2BlockSource;
|
|
28
|
+
this.proverDeps = proverDeps;
|
|
29
|
+
this.options = options;
|
|
30
|
+
this.proverFactoryFn = proverFactoryFn;
|
|
31
|
+
this.provers = new Map();
|
|
32
|
+
this.log = createLogger('prover-node:checkpoint-store', bindings);
|
|
33
|
+
this.slotWatcher = new RunningPromise(()=>this.reapPrunedPastSlot(), this.log, this.options.slotWatcherPollIntervalMs);
|
|
34
|
+
}
|
|
35
|
+
start() {
|
|
36
|
+
this.slotWatcher.start();
|
|
37
|
+
return Promise.resolve();
|
|
38
|
+
}
|
|
39
|
+
async stop() {
|
|
40
|
+
await this.slotWatcher.stop();
|
|
41
|
+
// Cancel every live prover; await teardown.
|
|
42
|
+
const provers = Array.from(this.provers.values());
|
|
43
|
+
this.provers.clear();
|
|
44
|
+
for (const prover of provers){
|
|
45
|
+
prover.cancel();
|
|
46
|
+
}
|
|
47
|
+
await Promise.allSettled(provers.map((p)=>p.whenDone()));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Registers a checkpoint with the store. If a prover already exists for the
|
|
51
|
+
* `(number, slot, archive root)` content key, it is reused and marked canonical;
|
|
52
|
+
* otherwise a new prover is constructed.
|
|
53
|
+
*/ async addOrUpdate(checkpoint, data) {
|
|
54
|
+
const l1Constants = await this.l2BlockSource.getL1Constants();
|
|
55
|
+
const epochNumber = getEpochAtSlot(checkpoint.header.slotNumber, l1Constants);
|
|
56
|
+
const id = CheckpointProver.idFor(checkpoint);
|
|
57
|
+
const existing = this.provers.get(id);
|
|
58
|
+
if (existing) {
|
|
59
|
+
existing.markCanonical();
|
|
60
|
+
return existing;
|
|
61
|
+
}
|
|
62
|
+
// At most one canonical checkpoint per slot. A different canonical checkpoint at the
|
|
63
|
+
// same slot means the caller forgot to prune the old chain before adding the replacement
|
|
64
|
+
// — surface it rather than silently creating a parallel canonical chain.
|
|
65
|
+
for (const prover of this.provers.values()){
|
|
66
|
+
if (prover.slotNumber === checkpoint.header.slotNumber && !prover.isPruned()) {
|
|
67
|
+
throw new Error(`Cannot add checkpoint ${checkpoint.number} (archive ${checkpoint.archive.root}) at slot ${checkpoint.header.slotNumber}: ` + `a different canonical checkpoint already occupies this slot. Prune it first.`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const prover = this.proverFactoryFn({
|
|
71
|
+
...data,
|
|
72
|
+
checkpoint,
|
|
73
|
+
epochNumber
|
|
74
|
+
}, {
|
|
75
|
+
...this.proverDeps,
|
|
76
|
+
log: this.log
|
|
77
|
+
});
|
|
78
|
+
this.provers.set(id, prover);
|
|
79
|
+
return prover;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Marks every canonical prover whose checkpoint number is strictly greater than
|
|
83
|
+
* `prunedNumber` as pruned. Sub-tree work keeps running so a re-add of the same
|
|
84
|
+
* content can pick it up. Returns the affected provers.
|
|
85
|
+
*/ markPrunedAfter(prunedNumber) {
|
|
86
|
+
const affected = [];
|
|
87
|
+
for (const prover of this.provers.values()){
|
|
88
|
+
if (prover.checkpoint.number > prunedNumber && !prover.isPruned()) {
|
|
89
|
+
prover.markPruned();
|
|
90
|
+
affected.push(prover);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return affected;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Drops canonical (non-pruned) provers whose epoch is at or below the supplied expired
|
|
97
|
+
* epoch. Once an epoch's proof-submission window has closed, its proof can no longer be
|
|
98
|
+
* accepted on L1, so the prover is no longer needed.
|
|
99
|
+
*/ reapExpired(expiredEpoch) {
|
|
100
|
+
const reaped = [];
|
|
101
|
+
for (const [id, prover] of Array.from(this.provers.entries())){
|
|
102
|
+
if (prover.isPruned()) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (prover.epochNumber <= expiredEpoch) {
|
|
106
|
+
reaped.push({
|
|
107
|
+
id,
|
|
108
|
+
checkpointNumber: prover.checkpoint.number,
|
|
109
|
+
epochNumber: prover.epochNumber
|
|
110
|
+
});
|
|
111
|
+
prover.cancel({
|
|
112
|
+
routine: true
|
|
113
|
+
});
|
|
114
|
+
void prover.whenDone();
|
|
115
|
+
this.provers.delete(id);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (reaped.length > 0) {
|
|
119
|
+
this.log.info(`Reaped ${reaped.length} expired CheckpointProver(s) for expiredEpoch ${expiredEpoch}`, {
|
|
120
|
+
expiredEpoch,
|
|
121
|
+
reapedCount: reaped.length,
|
|
122
|
+
reaped
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Returns the prover with the supplied id, or undefined. */ get(id) {
|
|
127
|
+
return this.provers.get(id);
|
|
128
|
+
}
|
|
129
|
+
/** Returns the prover for the supplied checkpoint (by its content-addressed id), or undefined. */ getByCheckpoint(checkpoint) {
|
|
130
|
+
return this.provers.get(CheckpointProver.idFor(checkpoint));
|
|
131
|
+
}
|
|
132
|
+
/** Every prover currently in the store (canonical and pruned), in insertion order. */ listAll() {
|
|
133
|
+
return Array.from(this.provers.values());
|
|
134
|
+
}
|
|
135
|
+
/** Canonical (non-pruned) provers in the store, sorted by checkpoint number. */ listCanonical() {
|
|
136
|
+
return Array.from(this.provers.values()).filter((p)=>!p.isPruned()).sort((a, b)=>a.checkpoint.number - b.checkpoint.number);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Canonical provers whose slot is in the supplied epoch's slot range, sorted by
|
|
140
|
+
* checkpoint number.
|
|
141
|
+
*/ async listCanonicalForEpoch(epoch) {
|
|
142
|
+
const l1Constants = await this.l2BlockSource.getL1Constants();
|
|
143
|
+
const [fromSlot, toSlot] = getSlotRangeForEpoch(epoch, l1Constants);
|
|
144
|
+
return this.listCanonicalInSlotRange(fromSlot, toSlot);
|
|
145
|
+
}
|
|
146
|
+
/** Canonical provers whose slot falls within `[fromSlot, toSlot]`, sorted by checkpoint number. */ listCanonicalInSlotRange(fromSlot, toSlot) {
|
|
147
|
+
return this.listCanonical().filter((p)=>p.slotNumber >= fromSlot && p.slotNumber <= toSlot);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* SlotWatcher tick: reap pruned provers whose slot has passed the chain's synced
|
|
151
|
+
* slot. Once the chain has moved past, no re-add can revive the prover and its
|
|
152
|
+
* content key is unique enough that an actual re-add would create a new entry.
|
|
153
|
+
*
|
|
154
|
+
* Protected so unit tests can drive a single tick without spinning up the
|
|
155
|
+
* `RunningPromise` and waiting on its interval.
|
|
156
|
+
*/ async reapPrunedPastSlot() {
|
|
157
|
+
let syncedSlot;
|
|
158
|
+
try {
|
|
159
|
+
syncedSlot = await this.l2BlockSource.getSyncedL2SlotNumber();
|
|
160
|
+
} catch (err) {
|
|
161
|
+
this.log.debug(`SlotWatcher could not read synced slot`, {
|
|
162
|
+
error: `${err}`
|
|
163
|
+
});
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (syncedSlot === undefined) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
for (const [id, prover] of Array.from(this.provers.entries())){
|
|
170
|
+
if (prover.isPruned() && prover.slotNumber < syncedSlot) {
|
|
171
|
+
this.log.info(`Reaping pruned CheckpointProver ${id}: slot ${prover.slotNumber} < synced ${syncedSlot}`, {
|
|
172
|
+
checkpointNumber: prover.checkpoint.number,
|
|
173
|
+
slotNumber: prover.slotNumber
|
|
174
|
+
});
|
|
175
|
+
prover.cancel();
|
|
176
|
+
void prover.whenDone();
|
|
177
|
+
this.provers.delete(id);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
package/dest/config.d.ts
CHANGED
|
@@ -26,4 +26,4 @@ export declare function getProverNodeConfigFromEnv(): ProverNodeConfig;
|
|
|
26
26
|
export declare function getProverNodeBrokerConfigFromEnv(): ProverBrokerConfig;
|
|
27
27
|
export declare function getProverNodeAgentConfigFromEnv(): ProverAgentConfig & BBConfig & ACVMConfig;
|
|
28
28
|
export declare function createKeyStoreForProver(config: ProverNodeConfig): KeyStore | undefined;
|
|
29
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRSxPQUFPLEVBQ0wsS0FBSyxrQkFBa0IsRUFLeEIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQUUsS0FBSyxjQUFjLEVBQTBCLE1BQU0sNkJBQTZCLENBQUM7QUFFMUYsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFFLEtBQUssZ0JBQWdCLEVBQTRCLE1BQU0sd0JBQXdCLENBQUM7QUFDekYsT0FBTyxFQUNMLEtBQUssaUJBQWlCLEVBQ3RCLEtBQUssa0JBQWtCLEVBR3hCLE1BQU0sb0NBQW9DLENBQUM7QUFDNUMsT0FBTyxFQUFFLEtBQUssc0JBQXNCLEVBQWdELE1BQU0sNkJBQTZCLENBQUM7QUFDeEgsT0FBTyxFQUNMLEtBQUsscUJBQXFCLEVBQzFCLEtBQUssb0JBQW9CLEVBRzFCLE1BQU0sZ0NBQWdDLENBQUM7QUFDeEMsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFzQixNQUFNLHdCQUF3QixDQUFDO0FBRWxGLE1BQU0sTUFBTSxnQkFBZ0IsR0FBRyxzQkFBc0IsR0FDbkQscUJBQXFCLEdBQ3JCLG9CQUFvQixHQUNwQixlQUFlLEdBQ2YsY0FBYyxHQUNkLHdCQUF3QixHQUN4QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsZUFBZSxDQUFDLENBQUM7QUFFMUMsTUFBTSxNQUFNLHdCQUF3QixHQUFHO0lBQ3JDLHdCQUF3QixFQUFFLE1BQU0sQ0FBQztJQUNqQywyQkFBMkIsRUFBRSxNQUFNLENBQUM7SUFDcEMsbUNBQW1DLEVBQUUsTUFBTSxDQUFDO0lBQzVDLDBCQUEwQixFQUFFLE1BQU0sR0FBRyxTQUFTLENBQUM7SUFDL0MsNkJBQTZCLEVBQUUsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUNsRCw2QkFBNkIsQ0FBQyxFQUFFLE9BQU8sQ0FBQztJQUN4QyxvQkFBb0IsRUFBRSxNQUFNLENBQUM7SUFDN0IscUJBQXFCLEVBQUUsTUFBTSxDQUFDO0lBQzlCLG9CQUFvQixFQUFFLE1BQU0sQ0FBQztJQUM3QixxQ0FBcUMsRUFBRSxNQUFNLENBQUM7Q0FDL0MsQ0FBQztBQUVGLGVBQU8sTUFBTSxnQ0FBZ0MsRUFBRSxrQkFBa0IsQ0FBQyx3QkFBd0IsQ0FtRHpGLENBQUM7QUFFRixlQUFPLE1BQU0sd0JBQXdCLEVBQUUsa0JBQWtCLENBQUMsZ0JBQWdCLENBUXpFLENBQUM7QUFFRix3QkFBZ0IsMEJBQTBCLElBQUksZ0JBQWdCLENBRTdEO0FBRUQsd0JBQWdCLGdDQUFnQyxJQUFJLGtCQUFrQixDQUlyRTtBQUVELHdCQUFnQiwrQkFBK0IsSUFBSSxpQkFBaUIsR0FBRyxRQUFRLEdBQUcsVUFBVSxDQUszRjtBQTBERCx3QkFBZ0IsdUJBQXVCLENBQUMsTUFBTSxFQUFFLGdCQUFnQixHQUFHLFFBQVEsR0FBRyxTQUFTLENBU3RGIn0=
|
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,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,6BAA6B,CAAC;AAE1F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,wBAAwB,CAAC;AACzF,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EAGxB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,KAAK,sBAAsB,EAAgD,MAAM,6BAA6B,CAAC;AACxH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAG1B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,wBAAwB,CAAC;AAElF,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,GACnD,qBAAqB,GACrB,oBAAoB,GACpB,eAAe,GACf,cAAc,GACd,wBAAwB,GACxB,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;AAE1C,MAAM,MAAM,wBAAwB,GAAG;IACrC,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;IACpC,mCAAmC,EAAE,MAAM,CAAC;IAC5C,0BAA0B,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,6BAA6B,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qCAAqC,EAAE,MAAM,CAAC;CAC/C,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,kBAAkB,CAAC,wBAAwB,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,6BAA6B,CAAC;AAE1F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,wBAAwB,CAAC;AACzF,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EAGxB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,KAAK,sBAAsB,EAAgD,MAAM,6BAA6B,CAAC;AACxH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAG1B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,wBAAwB,CAAC;AAElF,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,GACnD,qBAAqB,GACrB,oBAAoB,GACpB,eAAe,GACf,cAAc,GACd,wBAAwB,GACxB,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;AAE1C,MAAM,MAAM,wBAAwB,GAAG;IACrC,wBAAwB,EAAE,MAAM,CAAC;IACjC,2BAA2B,EAAE,MAAM,CAAC;IACpC,mCAAmC,EAAE,MAAM,CAAC;IAC5C,0BAA0B,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,6BAA6B,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qCAAqC,EAAE,MAAM,CAAC;CAC/C,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,kBAAkB,CAAC,wBAAwB,CAmDzF,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,kBAAkB,CAAC,gBAAgB,CAQzE,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,gBAAgB,CAE7D;AAED,wBAAgB,gCAAgC,IAAI,kBAAkB,CAIrE;AAED,wBAAgB,+BAA+B,IAAI,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAK3F;AA0DD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,GAAG,QAAQ,GAAG,SAAS,CAStF"}
|
package/dest/config.js
CHANGED
|
@@ -28,7 +28,7 @@ export const specificProverNodeConfigMappings = {
|
|
|
28
28
|
defaultValue: undefined
|
|
29
29
|
},
|
|
30
30
|
proverNodeEpochProvingDelayMs: {
|
|
31
|
-
description: 'Optional delay in milliseconds to wait before proving
|
|
31
|
+
description: 'Optional delay in milliseconds to wait for late-arriving events (e.g. reorgs) to settle before starting top-tree proving for an epoch',
|
|
32
32
|
defaultValue: undefined
|
|
33
33
|
},
|
|
34
34
|
txGatheringIntervalMs: {
|
package/dest/factory.d.ts
CHANGED
|
@@ -30,4 +30,4 @@ export type ProverNodeDeps = {
|
|
|
30
30
|
};
|
|
31
31
|
/** Creates a new prover node subsystem given a config and dependencies */
|
|
32
32
|
export declare function createProverNode(userConfig: SpecificProverNodeConfig & ProverConfig & ProverClientUserConfig & ProverPublisherConfig & ProverTxSenderConfig, deps: ProverNodeDeps): Promise<ProverNode>;
|
|
33
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUVyRSxPQUFPLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBSTlELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUd4RCxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV2RCxPQUFPLEVBQTJCLEtBQUssc0JBQXNCLEVBQXNCLE1BQU0sc0JBQXNCLENBQUM7QUFFaEgsT0FBTyxFQUNMLEtBQUsscUJBQXFCLEVBQzFCLEtBQUssb0JBQW9CLEVBRTFCLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxLQUFLLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsT0FBTyxFQUNQLHNCQUFzQixFQUN2QixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBYSxLQUFLLGVBQWUsRUFBc0IsTUFBTSx5QkFBeUIsQ0FBQztBQUk5RixPQUFPLEtBQUssRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM1RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFdkUsTUFBTSxNQUFNLGNBQWMsR0FBRztJQUMzQixTQUFTLENBQUMsRUFBRSxlQUFlLENBQUM7SUFDNUIsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2IsUUFBUSxFQUFFLFFBQVEsQ0FBQztJQUNuQixnQkFBZ0IsQ0FBQyxFQUFFLHNCQUFzQixDQUFDO0lBQzFDLE1BQU0sQ0FBQyxFQUFFLGdCQUFnQixDQUFDO0lBQzFCLFNBQVMsQ0FBQyxFQUFFLFNBQVMsQ0FBQztJQUN0QixZQUFZLENBQUMsRUFBRSxZQUFZLENBQUM7SUFDNUIsc0JBQXNCLEVBQUUsc0JBQXNCLENBQUM7SUFDL0MsU0FBUyxFQUFFO1FBQUUsYUFBYSxJQUFJLFdBQVcsQ0FBQTtLQUFFLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9ELFVBQVUsRUFBRSxtQkFBbUIsQ0FBQztJQUNoQyxVQUFVLEVBQUUsbUJBQW1CLENBQUM7SUFDaEMsZUFBZSxDQUFDLEVBQUUsZUFBZSxDQUFDO0NBQ25DLENBQUM7QUFFRiwwRUFBMEU7QUFDMUUsd0JBQXNCLGdCQUFnQixDQUNwQyxVQUFVLEVBQUUsd0JBQXdCLEdBQ2xDLFlBQVksR0FDWixzQkFBc0IsR0FDdEIscUJBQXFCLEdBQ3JCLG9CQUFvQixFQUN0QixJQUFJLEVBQUUsY0FBYyx1QkFnSXJCIn0=
|
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,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAGxD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAA2B,KAAK,sBAAsB,EAAsB,MAAM,sBAAsB,CAAC;AAEhH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAa,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAI9F,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAGxD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAA2B,KAAK,sBAAsB,EAAsB,MAAM,sBAAsB,CAAC;AAEhH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAa,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAI9F,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,SAAS,EAAE;QAAE,aAAa,IAAI,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,UAAU,EAAE,mBAAmB,CAAC;IAChC,UAAU,EAAE,mBAAmB,CAAC;IAChC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF,0EAA0E;AAC1E,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,wBAAwB,GAClC,YAAY,GACZ,sBAAsB,GACtB,qBAAqB,GACrB,oBAAoB,EACtB,IAAI,EAAE,cAAc,uBAgIrB"}
|
package/dest/factory.js
CHANGED
|
@@ -12,7 +12,6 @@ import { createAndStartProvingBroker } from '@aztec/prover-client/broker';
|
|
|
12
12
|
import { getPublisherConfigFromProverConfig } from '@aztec/sequencer-client';
|
|
13
13
|
import { L1Metrics, getTelemetryClient } from '@aztec/telemetry-client';
|
|
14
14
|
import { createPublicClient } from 'viem';
|
|
15
|
-
import { EpochMonitor } from './monitors/epoch-monitor.js';
|
|
16
15
|
import { ProverNode } from './prover-node.js';
|
|
17
16
|
import { ProverPublisherFactory } from './prover-publisher-factory.js';
|
|
18
17
|
/** Creates a new prover node subsystem given a config and dependencies */ export async function createProverNode(userConfig, deps) {
|
|
@@ -52,7 +51,7 @@ import { ProverPublisherFactory } from './prover-publisher-factory.js';
|
|
|
52
51
|
}),
|
|
53
52
|
pollingInterval: config.viemPollingIntervalMS
|
|
54
53
|
});
|
|
55
|
-
const rollupContract = new RollupContract(publicClient, config.
|
|
54
|
+
const rollupContract = new RollupContract(publicClient, config.rollupAddress.toString());
|
|
56
55
|
const l1TxUtils = deps.l1TxUtils ? [
|
|
57
56
|
deps.l1TxUtils
|
|
58
57
|
] : config.proverPublisherForwarderAddress ? await createForwarderL1TxUtilsFromSigners(publicClient, proverSigners.signers, config.proverPublisherForwarderAddress, {
|
|
@@ -71,20 +70,35 @@ import { ProverPublisherFactory } from './prover-publisher-factory.js';
|
|
|
71
70
|
logger: log.createChild('l1-tx-utils'),
|
|
72
71
|
dateProvider
|
|
73
72
|
});
|
|
73
|
+
// Create a funder L1TxUtils from the keystore funding account (if configured)
|
|
74
|
+
const fundingSigner = keyStoreManager?.createFundingSigner();
|
|
75
|
+
let funderL1TxUtils;
|
|
76
|
+
if (fundingSigner) {
|
|
77
|
+
const [funder] = await createL1TxUtilsFromSigners(publicClient, [
|
|
78
|
+
fundingSigner
|
|
79
|
+
], {
|
|
80
|
+
...config,
|
|
81
|
+
scope: 'prover'
|
|
82
|
+
}, {
|
|
83
|
+
telemetry,
|
|
84
|
+
logger: log.createChild('l1-tx-utils:funder'),
|
|
85
|
+
dateProvider
|
|
86
|
+
});
|
|
87
|
+
funderL1TxUtils = funder;
|
|
88
|
+
}
|
|
74
89
|
const publisherFactory = deps.publisherFactory ?? new ProverPublisherFactory(config, {
|
|
75
90
|
rollupContract,
|
|
76
|
-
publisherManager: new PublisherManager(l1TxUtils, getPublisherConfigFromProverConfig(config),
|
|
91
|
+
publisherManager: new PublisherManager(l1TxUtils, getPublisherConfigFromProverConfig(config), {
|
|
92
|
+
bindings: log.getBindings(),
|
|
93
|
+
funder: funderL1TxUtils
|
|
94
|
+
}),
|
|
77
95
|
telemetry
|
|
78
96
|
});
|
|
79
97
|
const proverNodeConfig = {
|
|
80
98
|
...pick(config, 'proverNodeMaxPendingJobs', 'proverNodeMaxParallelBlocksPerEpoch', 'proverNodePollingIntervalMs', 'proverNodeEpochProvingDelayMs', 'txGatheringMaxParallelRequests', 'txGatheringIntervalMs', 'txGatheringTimeoutMs', 'proverNodeFailedEpochStore', 'proverNodeDisableProofPublish', 'dataDirectory', 'l1ChainId', 'rollupVersion')
|
|
81
99
|
};
|
|
82
|
-
const epochMonitor = await EpochMonitor.create(archiver, {
|
|
83
|
-
pollingIntervalMs: config.proverNodePollingIntervalMs,
|
|
84
|
-
provingDelayMs: config.proverNodeEpochProvingDelayMs
|
|
85
|
-
}, telemetry);
|
|
86
100
|
const l1Metrics = new L1Metrics(telemetry.getMeter('ProverNodeL1Metrics'), publicClient, l1TxUtils.map((utils)=>utils.getSenderAddress()));
|
|
87
101
|
// Extract the shared delayer from the first L1TxUtils instance (all instances share the same delayer)
|
|
88
102
|
const delayer = l1TxUtils[0]?.delayer;
|
|
89
|
-
return new ProverNode(prover, publisherFactory, archiver, archiver, archiver, worldStateSynchronizer, p2pClient,
|
|
103
|
+
return new ProverNode(prover, publisherFactory, archiver, archiver, archiver, worldStateSynchronizer, p2pClient, rollupContract, l1Metrics, proverNodeConfig, telemetry, delayer, dateProvider);
|
|
90
104
|
}
|
package/dest/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './actions/index.js';
|
|
|
2
2
|
export * from './config.js';
|
|
3
3
|
export * from './factory.js';
|
|
4
4
|
export * from './monitors/index.js';
|
|
5
|
+
export * from './proof-publishing-service.js';
|
|
5
6
|
export * from './prover-node-publisher.js';
|
|
6
7
|
export * from './prover-node.js';
|
|
7
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLG9CQUFvQixDQUFDO0FBQ25DLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYywrQkFBK0IsQ0FBQztBQUM5QyxjQUFjLDRCQUE0QixDQUFDO0FBQzNDLGNBQWMsa0JBQWtCLENBQUMifQ==
|
package/dest/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC"}
|
package/dest/index.js
CHANGED