@aztec/prover-client 0.0.1-commit.96bb3f7 → 0.0.1-commit.993d240
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 +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +16 -2
- package/dest/light/lightweight_checkpoint_builder.d.ts +16 -7
- package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -1
- package/dest/light/lightweight_checkpoint_builder.js +75 -27
- package/dest/mocks/fixtures.d.ts +1 -1
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +2 -1
- package/dest/mocks/test_context.d.ts +5 -2
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +23 -9
- package/dest/orchestrator/block-building-helpers.d.ts +5 -5
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +3 -3
- package/dest/orchestrator/block-proving-state.d.ts +4 -1
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +7 -0
- package/dest/orchestrator/checkpoint-proving-state.d.ts +24 -4
- package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/checkpoint-proving-state.js +47 -5
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.d.ts +107 -0
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.d.ts.map +1 -0
- package/dest/orchestrator/checkpoint-sub-tree-orchestrator.js +151 -0
- package/dest/orchestrator/epoch-proving-context.d.ts +51 -0
- package/dest/orchestrator/epoch-proving-context.d.ts.map +1 -0
- package/dest/orchestrator/epoch-proving-context.js +81 -0
- package/dest/orchestrator/epoch-proving-state.d.ts +7 -6
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +37 -1
- package/dest/orchestrator/index.d.ts +4 -1
- package/dest/orchestrator/index.d.ts.map +1 -1
- package/dest/orchestrator/index.js +3 -0
- package/dest/orchestrator/orchestrator.d.ts +29 -24
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +137 -225
- package/dest/orchestrator/proving-scheduler.d.ts +72 -0
- package/dest/orchestrator/proving-scheduler.d.ts.map +1 -0
- package/dest/orchestrator/proving-scheduler.js +117 -0
- package/dest/orchestrator/top-tree-orchestrator.d.ts +83 -0
- package/dest/orchestrator/top-tree-orchestrator.d.ts.map +1 -0
- package/dest/orchestrator/top-tree-orchestrator.js +182 -0
- package/dest/orchestrator/top-tree-proving-scheduler.d.ts +62 -0
- package/dest/orchestrator/top-tree-proving-scheduler.d.ts.map +1 -0
- package/dest/orchestrator/top-tree-proving-scheduler.js +73 -0
- package/dest/orchestrator/top-tree-proving-state.d.ts +61 -0
- package/dest/orchestrator/top-tree-proving-state.d.ts.map +1 -0
- package/dest/orchestrator/top-tree-proving-state.js +185 -0
- package/dest/prover-client/prover-client.d.ts +64 -5
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +64 -11
- package/dest/proving_broker/broker_prover_facade.d.ts +4 -3
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +16 -22
- package/dest/proving_broker/config.d.ts +12 -64
- package/dest/proving_broker/config.d.ts.map +1 -1
- package/dest/proving_broker/config.js +22 -5
- package/dest/proving_broker/index.d.ts +2 -1
- package/dest/proving_broker/index.d.ts.map +1 -1
- package/dest/proving_broker/index.js +1 -0
- package/dest/proving_broker/proof_store/factory.d.ts +2 -5
- package/dest/proving_broker/proof_store/factory.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/factory.js +7 -30
- package/dest/proving_broker/proof_store/file_store_proof_store.d.ts +18 -0
- package/dest/proving_broker/proof_store/file_store_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/file_store_proof_store.js +60 -0
- package/dest/proving_broker/proof_store/index.d.ts +2 -2
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -1
- package/dest/proving_broker/proof_store/index.js +1 -1
- package/dest/proving_broker/proving_agent.d.ts +4 -3
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +4 -4
- package/dest/proving_broker/proving_broker.d.ts +8 -5
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +68 -11
- package/dest/proving_broker/proving_broker_database/persisted.js +2 -2
- package/dest/proving_broker/proving_broker_instrumentation.d.ts +3 -1
- package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_instrumentation.js +18 -7
- package/dest/proving_broker/proving_job_controller.d.ts +4 -3
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +6 -3
- package/dest/proving_broker/rpc.d.ts +6 -2
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +87 -23
- package/dest/test/mock_proof_store.d.ts +3 -3
- package/dest/test/mock_proof_store.d.ts.map +1 -1
- package/dest/test/mock_prover.d.ts +4 -4
- package/package.json +19 -21
- package/src/config.ts +18 -2
- package/src/light/lightweight_checkpoint_builder.ts +107 -36
- package/src/mocks/fixtures.ts +2 -1
- package/src/mocks/test_context.ts +18 -10
- package/src/orchestrator/block-building-helpers.ts +3 -3
- package/src/orchestrator/block-proving-state.ts +9 -0
- package/src/orchestrator/checkpoint-proving-state.ts +65 -6
- package/src/orchestrator/checkpoint-sub-tree-orchestrator.ts +271 -0
- package/src/orchestrator/epoch-proving-context.ts +101 -0
- package/src/orchestrator/epoch-proving-state.ts +59 -9
- package/src/orchestrator/index.ts +8 -0
- package/src/orchestrator/orchestrator.ts +161 -290
- package/src/orchestrator/proving-scheduler.ts +156 -0
- package/src/orchestrator/top-tree-orchestrator.ts +314 -0
- package/src/orchestrator/top-tree-proving-scheduler.ts +154 -0
- package/src/orchestrator/top-tree-proving-state.ts +220 -0
- package/src/prover-client/prover-client.ts +155 -15
- package/src/proving_broker/broker_prover_facade.ts +23 -23
- package/src/proving_broker/config.ts +25 -2
- package/src/proving_broker/index.ts +1 -0
- package/src/proving_broker/proof_store/factory.ts +10 -32
- package/src/proving_broker/proof_store/file_store_proof_store.ts +78 -0
- package/src/proving_broker/proof_store/index.ts +1 -1
- package/src/proving_broker/proving_agent.ts +5 -2
- package/src/proving_broker/proving_broker.ts +64 -8
- package/src/proving_broker/proving_broker_database/persisted.ts +2 -2
- package/src/proving_broker/proving_broker_instrumentation.ts +19 -6
- package/src/proving_broker/proving_job_controller.ts +9 -3
- package/src/proving_broker/rpc.ts +46 -20
- package/dest/block-factory/index.d.ts +0 -2
- package/dest/block-factory/index.d.ts.map +0 -1
- package/dest/block-factory/index.js +0 -1
- package/dest/block-factory/light.d.ts +0 -38
- package/dest/block-factory/light.d.ts.map +0 -1
- package/dest/block-factory/light.js +0 -106
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +0 -14
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +0 -1
- package/dest/proving_broker/proof_store/gcs_proof_store.js +0 -52
- package/src/block-factory/index.ts +0 -1
- package/src/block-factory/light.ts +0 -136
- package/src/proving_broker/proof_store/gcs_proof_store.ts +0 -76
|
@@ -3,14 +3,11 @@ import {
|
|
|
3
3
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
4
4
|
L1_TO_L2_MSG_SUBTREE_ROOT_SIBLING_PATH_LENGTH,
|
|
5
5
|
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
6
|
-
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
7
6
|
NUM_BASE_PARITY_PER_ROOT_PARITY,
|
|
8
7
|
} from '@aztec/constants';
|
|
9
8
|
import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
10
|
-
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
11
9
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
12
|
-
import {
|
|
13
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
10
|
+
import type { LoggerBindings } from '@aztec/foundation/log';
|
|
14
11
|
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
15
12
|
import { assertLength } from '@aztec/foundation/serialize';
|
|
16
13
|
import { pushTestData } from '@aztec/foundation/testing';
|
|
@@ -25,6 +22,7 @@ import type {
|
|
|
25
22
|
ReadonlyWorldStateAccess,
|
|
26
23
|
ServerCircuitProver,
|
|
27
24
|
} from '@aztec/stdlib/interfaces/server';
|
|
25
|
+
import { appendL1ToL2MessagesToTree } from '@aztec/stdlib/messaging';
|
|
28
26
|
import type { Proof } from '@aztec/stdlib/proofs';
|
|
29
27
|
import {
|
|
30
28
|
type BaseRollupHints,
|
|
@@ -69,10 +67,9 @@ import type { BlockProvingState } from './block-proving-state.js';
|
|
|
69
67
|
import type { CheckpointProvingState } from './checkpoint-proving-state.js';
|
|
70
68
|
import { EpochProvingState, type ProvingResult, type TreeSnapshots } from './epoch-proving-state.js';
|
|
71
69
|
import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
|
|
70
|
+
import { TopTreeProvingScheduler } from './top-tree-proving-scheduler.js';
|
|
72
71
|
import { TxProvingState } from './tx-proving-state.js';
|
|
73
72
|
|
|
74
|
-
const logger = createLogger('prover-client:orchestrator');
|
|
75
|
-
|
|
76
73
|
/**
|
|
77
74
|
* Implements an event driven proving scheduler to build the recursive proof tree. The idea being:
|
|
78
75
|
* 1. Transactions are provided to the scheduler post simulation.
|
|
@@ -87,21 +84,24 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
87
84
|
/**
|
|
88
85
|
* The orchestrator, managing the flow of recursive proving operations required to build the rollup proof tree.
|
|
89
86
|
*/
|
|
90
|
-
export class ProvingOrchestrator implements EpochProver {
|
|
91
|
-
|
|
92
|
-
private pendingProvingJobs: AbortController[] = [];
|
|
87
|
+
export class ProvingOrchestrator extends TopTreeProvingScheduler implements EpochProver {
|
|
88
|
+
protected provingState: EpochProvingState | undefined = undefined;
|
|
93
89
|
|
|
94
|
-
|
|
90
|
+
protected provingPromise: Promise<ProvingResult> | undefined = undefined;
|
|
95
91
|
private metrics: ProvingOrchestratorMetrics;
|
|
96
|
-
|
|
92
|
+
|
|
97
93
|
private dbs: Map<BlockNumber, MerkleTreeWriteOperations> = new Map();
|
|
98
94
|
|
|
99
95
|
constructor(
|
|
100
96
|
private dbProvider: ReadonlyWorldStateAccess & ForkMerkleTreeOperations,
|
|
101
|
-
|
|
97
|
+
prover: ServerCircuitProver,
|
|
102
98
|
private readonly proverId: EthAddress,
|
|
99
|
+
private readonly cancelJobsOnStop: boolean = false,
|
|
100
|
+
enqueueConcurrency: number,
|
|
103
101
|
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
102
|
+
bindings?: LoggerBindings,
|
|
104
103
|
) {
|
|
104
|
+
super(prover, enqueueConcurrency, 'prover-client:orchestrator', bindings);
|
|
105
105
|
this.metrics = new ProvingOrchestratorMetrics(telemetryClient, 'ProvingOrchestrator');
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -113,9 +113,28 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
113
113
|
return this.proverId;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
public
|
|
116
|
+
public getNumActiveForks() {
|
|
117
|
+
return this.dbs.size;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
protected override cancelInternal(): void {
|
|
117
121
|
this.cancel();
|
|
118
|
-
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
protected override wrapCircuitCall<T>(
|
|
125
|
+
circuitName: string,
|
|
126
|
+
fn: (signal: AbortSignal) => Promise<T>,
|
|
127
|
+
): (signal: AbortSignal) => Promise<T> {
|
|
128
|
+
return wrapCallbackInSpan(
|
|
129
|
+
this.tracer,
|
|
130
|
+
`ProvingOrchestrator.prover.${circuitName}`,
|
|
131
|
+
{ [Attributes.PROTOCOL_CIRCUIT_NAME]: circuitName as CircuitName },
|
|
132
|
+
fn,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
protected override onRootRollupComplete(state: EpochProvingState) {
|
|
137
|
+
state.resolve({ status: 'success' });
|
|
119
138
|
}
|
|
120
139
|
|
|
121
140
|
public startNewEpoch(
|
|
@@ -131,7 +150,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
131
150
|
|
|
132
151
|
const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
|
|
133
152
|
const promise = _promise.catch((reason): ProvingResult => ({ status: 'failure', reason }));
|
|
134
|
-
logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
|
|
153
|
+
this.logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
|
|
135
154
|
this.provingState = new EpochProvingState(
|
|
136
155
|
epochNumber,
|
|
137
156
|
totalNumCheckpoints,
|
|
@@ -143,6 +162,14 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
143
162
|
this.provingPromise = promise;
|
|
144
163
|
}
|
|
145
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Starts a new checkpoint.
|
|
167
|
+
* @param checkpointIndex - The index of the checkpoint in the epoch.
|
|
168
|
+
* @param constants - The constants for this checkpoint.
|
|
169
|
+
* @param l1ToL2Messages - The set of L1 to L2 messages to be inserted at the beginning of this checkpoint.
|
|
170
|
+
* @param totalNumBlocks - The total number of blocks expected in the checkpoint (must be at least one).
|
|
171
|
+
* @param headerOfLastBlockInPreviousCheckpoint - The header of the last block in the previous checkpoint.
|
|
172
|
+
*/
|
|
146
173
|
public async startNewCheckpoint(
|
|
147
174
|
checkpointIndex: number,
|
|
148
175
|
constants: CheckpointConstantData,
|
|
@@ -215,7 +242,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
215
242
|
}
|
|
216
243
|
|
|
217
244
|
const constants = checkpointProvingState.constants;
|
|
218
|
-
logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber}.`);
|
|
245
|
+
this.logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber}.`);
|
|
219
246
|
|
|
220
247
|
// Fork the db only when it's not already set. The db for the first block is set in `startNewCheckpoint`.
|
|
221
248
|
if (!this.dbs.has(blockNumber)) {
|
|
@@ -223,7 +250,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
223
250
|
const db = await this.dbProvider.fork(BlockNumber(blockNumber - 1));
|
|
224
251
|
this.dbs.set(blockNumber, db);
|
|
225
252
|
}
|
|
226
|
-
const db = this.
|
|
253
|
+
const db = this.getDbForBlock(blockNumber);
|
|
227
254
|
|
|
228
255
|
// Get archive snapshot and sibling path before any txs in this block lands.
|
|
229
256
|
const lastArchiveTreeSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
@@ -255,7 +282,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
255
282
|
await endSpongeBlob.absorb(blockEndBlobFields);
|
|
256
283
|
blockProvingState.setEndSpongeBlob(endSpongeBlob);
|
|
257
284
|
|
|
258
|
-
//
|
|
285
|
+
// Try to accumulate the out hashes and blobs as far as we can:
|
|
286
|
+
await this.provingState.accumulateCheckpointOutHashes();
|
|
259
287
|
await this.provingState.setBlobAccumulators();
|
|
260
288
|
}
|
|
261
289
|
}
|
|
@@ -275,7 +303,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
275
303
|
if (!txs.length) {
|
|
276
304
|
// To avoid an ugly throw below. If we require an empty block, we can just call setBlockCompleted
|
|
277
305
|
// on a block with no txs. We cannot do that here because we cannot find the blockNumber without any txs.
|
|
278
|
-
logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
306
|
+
this.logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
279
307
|
return;
|
|
280
308
|
}
|
|
281
309
|
|
|
@@ -295,9 +323,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
295
323
|
throw new Error(`Block ${blockNumber} has been initialized with transactions.`);
|
|
296
324
|
}
|
|
297
325
|
|
|
298
|
-
logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
|
|
326
|
+
this.logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
|
|
299
327
|
|
|
300
|
-
const db = this.
|
|
328
|
+
const db = this.getDbForBlock(blockNumber);
|
|
301
329
|
const lastArchive = provingState.lastArchiveTreeSnapshot;
|
|
302
330
|
const newL1ToL2MessageTreeSnapshot = provingState.newL1ToL2MessageTreeSnapshot;
|
|
303
331
|
const spongeBlobState = provingState.getStartSpongeBlob().clone();
|
|
@@ -310,7 +338,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
310
338
|
|
|
311
339
|
validateTx(tx);
|
|
312
340
|
|
|
313
|
-
logger.debug(`Received transaction: ${tx.hash}`);
|
|
341
|
+
this.logger.debug(`Received transaction: ${tx.hash}`);
|
|
314
342
|
|
|
315
343
|
const startSpongeBlob = spongeBlobState.clone();
|
|
316
344
|
const [hints, treeSnapshots] = await this.prepareBaseRollupInputs(
|
|
@@ -331,10 +359,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
331
359
|
const txIndex = provingState.addNewTx(txProvingState);
|
|
332
360
|
if (txProvingState.requireAvmProof) {
|
|
333
361
|
this.getOrEnqueueChonkVerifier(provingState, txIndex);
|
|
334
|
-
logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
362
|
+
this.logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
335
363
|
this.enqueueVM(provingState, txIndex);
|
|
336
364
|
} else {
|
|
337
|
-
logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
|
|
365
|
+
this.logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
|
|
338
366
|
this.enqueueBaseRollup(provingState, txIndex);
|
|
339
367
|
}
|
|
340
368
|
} catch (err: any) {
|
|
@@ -352,7 +380,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
352
380
|
|
|
353
381
|
provingState.setEndSpongeBlob(spongeBlobState);
|
|
354
382
|
|
|
355
|
-
// Txs have been added to the block. Now try to accumulate the blobs as far as we can:
|
|
383
|
+
// Txs have been added to the block. Now try to accumulate the out hashes and blobs as far as we can:
|
|
384
|
+
await this.provingState.accumulateCheckpointOutHashes();
|
|
356
385
|
await this.provingState.setBlobAccumulators();
|
|
357
386
|
}
|
|
358
387
|
|
|
@@ -376,7 +405,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
376
405
|
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
377
406
|
>
|
|
378
407
|
>();
|
|
379
|
-
logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
|
|
408
|
+
this.logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
|
|
380
409
|
this.doEnqueueChonkVerifier(txHash, privateInputs, proof => {
|
|
381
410
|
tubeProof.resolve(proof);
|
|
382
411
|
});
|
|
@@ -416,22 +445,28 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
416
445
|
}
|
|
417
446
|
|
|
418
447
|
// Given we've applied every change from this block, now assemble the block header:
|
|
419
|
-
logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
448
|
+
this.logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
420
449
|
const header = await provingState.buildBlockHeader();
|
|
421
450
|
|
|
422
451
|
if (expectedHeader && !header.equals(expectedHeader)) {
|
|
423
|
-
logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
452
|
+
this.logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
424
453
|
throw new Error('Block header mismatch');
|
|
425
454
|
}
|
|
426
455
|
|
|
427
|
-
// Get db for this block
|
|
428
|
-
const db = this.
|
|
456
|
+
// Get db for this block and remove from map — no other code should use it after this point.
|
|
457
|
+
const db = this.getDbForBlock(provingState.blockNumber);
|
|
458
|
+
this.dbs.delete(provingState.blockNumber);
|
|
429
459
|
|
|
430
|
-
// Update the archive tree,
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
460
|
+
// Update the archive tree, capture the snapshot, and close the fork deterministically.
|
|
461
|
+
try {
|
|
462
|
+
this.logger.verbose(
|
|
463
|
+
`Updating archive tree with block ${provingState.blockNumber} header ${(await header.hash()).toString()}`,
|
|
464
|
+
);
|
|
465
|
+
await db.updateArchive(header);
|
|
466
|
+
provingState.setBuiltArchive(await getTreeSnapshot(MerkleTreeId.ARCHIVE, db));
|
|
467
|
+
} finally {
|
|
468
|
+
await db.close();
|
|
469
|
+
}
|
|
435
470
|
|
|
436
471
|
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
437
472
|
|
|
@@ -442,31 +477,34 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
442
477
|
protected async verifyBuiltBlockAgainstSyncedState(provingState: BlockProvingState) {
|
|
443
478
|
const builtBlockHeader = provingState.getBuiltBlockHeader();
|
|
444
479
|
if (!builtBlockHeader) {
|
|
445
|
-
logger.debug('Block header not built yet, skipping header check.');
|
|
480
|
+
this.logger.debug('Block header not built yet, skipping header check.');
|
|
446
481
|
return;
|
|
447
482
|
}
|
|
448
483
|
|
|
449
484
|
const output = provingState.getBlockRootRollupOutput();
|
|
450
485
|
if (!output) {
|
|
451
|
-
logger.debug('Block root rollup proof not built yet, skipping header check.');
|
|
486
|
+
this.logger.debug('Block root rollup proof not built yet, skipping header check.');
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const newArchive = provingState.getBuiltArchive();
|
|
491
|
+
if (!newArchive) {
|
|
492
|
+
this.logger.debug('Archive snapshot not yet captured, skipping header check.');
|
|
452
493
|
return;
|
|
453
494
|
}
|
|
495
|
+
|
|
454
496
|
const header = await buildHeaderFromCircuitOutputs(output);
|
|
455
497
|
|
|
456
498
|
if (!(await header.hash()).equals(await builtBlockHeader.hash())) {
|
|
457
|
-
logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
|
|
499
|
+
this.logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
|
|
458
500
|
provingState.reject(`Block header hash mismatch.`);
|
|
459
501
|
return;
|
|
460
502
|
}
|
|
461
503
|
|
|
462
|
-
// Get db for this block
|
|
463
504
|
const blockNumber = provingState.blockNumber;
|
|
464
|
-
const db = this.dbs.get(blockNumber)!;
|
|
465
|
-
|
|
466
|
-
const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
467
505
|
const syncedArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.dbProvider.getSnapshot(blockNumber));
|
|
468
506
|
if (!syncedArchive.equals(newArchive)) {
|
|
469
|
-
logger.error(
|
|
507
|
+
this.logger.error(
|
|
470
508
|
`Archive tree mismatch for block ${blockNumber}: world state synced to ${inspect(
|
|
471
509
|
syncedArchive,
|
|
472
510
|
)} but built ${inspect(newArchive)}`,
|
|
@@ -477,32 +515,34 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
477
515
|
|
|
478
516
|
const circuitArchive = output.newArchive;
|
|
479
517
|
if (!newArchive.equals(circuitArchive)) {
|
|
480
|
-
logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
|
|
518
|
+
this.logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
|
|
481
519
|
provingState.reject(`New archive mismatch.`);
|
|
482
520
|
return;
|
|
483
521
|
}
|
|
484
|
-
|
|
485
|
-
// TODO(palla/prover): This closes the fork only on the happy path. If this epoch orchestrator
|
|
486
|
-
// is aborted and never reaches this point, it will leak the fork. We need to add a global cleanup,
|
|
487
|
-
// but have to make sure it only runs once all operations are completed, otherwise some function here
|
|
488
|
-
// will attempt to access the fork after it was closed.
|
|
489
|
-
logger.debug(`Cleaning up world state fork for ${blockNumber}`);
|
|
490
|
-
void this.dbs
|
|
491
|
-
.get(blockNumber)
|
|
492
|
-
?.close()
|
|
493
|
-
.then(() => this.dbs.delete(blockNumber))
|
|
494
|
-
.catch(err => logger.error(`Error closing db for block ${blockNumber}`, err));
|
|
495
522
|
}
|
|
496
523
|
|
|
497
524
|
/**
|
|
498
|
-
* Cancel any further proving
|
|
525
|
+
* Cancel any further proving.
|
|
526
|
+
* If cancelJobsOnStop is true, aborts all pending jobs with the broker (which marks them as 'Aborted').
|
|
527
|
+
* If cancelJobsOnStop is false (default), jobs remain in the broker queue and can be reused on restart/reorg.
|
|
499
528
|
*/
|
|
500
529
|
public cancel() {
|
|
501
|
-
|
|
502
|
-
controller.abort();
|
|
503
|
-
}
|
|
530
|
+
this.resetSchedulerState(this.cancelJobsOnStop);
|
|
504
531
|
|
|
505
532
|
this.provingState?.cancel();
|
|
533
|
+
|
|
534
|
+
for (const [blockNumber, db] of this.dbs.entries()) {
|
|
535
|
+
void db.close().catch(err => this.logger.error(`Error closing db for block ${blockNumber}`, err));
|
|
536
|
+
}
|
|
537
|
+
this.dbs.clear();
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
private getDbForBlock(blockNumber: BlockNumber): MerkleTreeWriteOperations {
|
|
541
|
+
const db = this.dbs.get(blockNumber);
|
|
542
|
+
if (!db) {
|
|
543
|
+
throw new Error(`World state fork for block ${blockNumber} not found.`);
|
|
544
|
+
}
|
|
545
|
+
return db;
|
|
506
546
|
}
|
|
507
547
|
|
|
508
548
|
/**
|
|
@@ -534,76 +574,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
534
574
|
return epochProofResult;
|
|
535
575
|
}
|
|
536
576
|
|
|
537
|
-
/**
|
|
538
|
-
* Enqueue a job to be scheduled
|
|
539
|
-
* @param provingState - The proving state object being operated on
|
|
540
|
-
* @param jobType - The type of job to be queued
|
|
541
|
-
* @param job - The actual job, returns a promise notifying of the job's completion
|
|
542
|
-
*/
|
|
543
|
-
private deferredProving<T>(
|
|
544
|
-
provingState: EpochProvingState | CheckpointProvingState | BlockProvingState,
|
|
545
|
-
request: (signal: AbortSignal) => Promise<T>,
|
|
546
|
-
callback: (result: T) => void | Promise<void>,
|
|
547
|
-
) {
|
|
548
|
-
if (!provingState.verifyState()) {
|
|
549
|
-
logger.debug(`Not enqueuing job, state no longer valid`);
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
const controller = new AbortController();
|
|
554
|
-
this.pendingProvingJobs.push(controller);
|
|
555
|
-
|
|
556
|
-
// We use a 'safeJob'. We don't want promise rejections in the proving pool, we want to capture the error here
|
|
557
|
-
// and reject the proving job whilst keeping the event loop free of rejections
|
|
558
|
-
const safeJob = async () => {
|
|
559
|
-
try {
|
|
560
|
-
// there's a delay between enqueueing this job and it actually running
|
|
561
|
-
if (controller.signal.aborted) {
|
|
562
|
-
return;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
const result = await request(controller.signal);
|
|
566
|
-
if (!provingState.verifyState()) {
|
|
567
|
-
logger.debug(`State no longer valid, discarding result`);
|
|
568
|
-
return;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// we could have been cancelled whilst waiting for the result
|
|
572
|
-
// and the prover ignored the signal. Drop the result in that case
|
|
573
|
-
if (controller.signal.aborted) {
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
await callback(result);
|
|
578
|
-
} catch (err) {
|
|
579
|
-
if (err instanceof AbortError) {
|
|
580
|
-
// operation was cancelled, probably because the block was cancelled
|
|
581
|
-
// drop this result
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
logger.error(`Error thrown when proving job`, err);
|
|
586
|
-
provingState!.reject(`${err}`);
|
|
587
|
-
} finally {
|
|
588
|
-
const index = this.pendingProvingJobs.indexOf(controller);
|
|
589
|
-
if (index > -1) {
|
|
590
|
-
this.pendingProvingJobs.splice(index, 1);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
};
|
|
594
|
-
|
|
595
|
-
// let the callstack unwind before adding the job to the queue
|
|
596
|
-
setImmediate(() => void safeJob());
|
|
597
|
-
}
|
|
598
|
-
|
|
599
577
|
private async updateL1ToL2MessageTree(l1ToL2Messages: Fr[], db: MerkleTreeWriteOperations) {
|
|
600
|
-
const l1ToL2MessagesPadded = padArrayEnd<Fr, number>(
|
|
601
|
-
l1ToL2Messages,
|
|
602
|
-
Fr.ZERO,
|
|
603
|
-
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
604
|
-
'Too many L1 to L2 messages',
|
|
605
|
-
);
|
|
606
|
-
|
|
607
578
|
const lastL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
608
579
|
const lastL1ToL2MessageSubtreeRootSiblingPath = assertLength(
|
|
609
580
|
await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, db),
|
|
@@ -611,7 +582,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
611
582
|
);
|
|
612
583
|
|
|
613
584
|
// Update the local trees to include the new l1 to l2 messages
|
|
614
|
-
await db
|
|
585
|
+
await appendL1ToL2MessagesToTree(db, l1ToL2Messages);
|
|
615
586
|
|
|
616
587
|
const newL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
617
588
|
const newL1ToL2MessageSubtreeRootSiblingPath = assertLength(
|
|
@@ -667,12 +638,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
667
638
|
// Executes the next level of merge if all inputs are available
|
|
668
639
|
private enqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
|
|
669
640
|
if (!provingState.verifyState()) {
|
|
670
|
-
logger.debug('Not running base rollup, state invalid');
|
|
641
|
+
this.logger.debug('Not running base rollup, state invalid');
|
|
671
642
|
return;
|
|
672
643
|
}
|
|
673
644
|
|
|
674
645
|
if (!provingState.tryStartProvingBase(txIndex)) {
|
|
675
|
-
logger.debug(`Base rollup for tx ${txIndex} already started.`);
|
|
646
|
+
this.logger.debug(`Base rollup for tx ${txIndex} already started.`);
|
|
676
647
|
return;
|
|
677
648
|
}
|
|
678
649
|
|
|
@@ -680,7 +651,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
680
651
|
const { processedTx } = txProvingState;
|
|
681
652
|
const { rollupType, inputs } = txProvingState.getBaseRollupTypeAndInputs();
|
|
682
653
|
|
|
683
|
-
logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
654
|
+
this.logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
684
655
|
|
|
685
656
|
this.deferredProving(
|
|
686
657
|
provingState,
|
|
@@ -704,7 +675,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
704
675
|
},
|
|
705
676
|
),
|
|
706
677
|
result => {
|
|
707
|
-
logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
678
|
+
this.logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
708
679
|
validatePartialState(result.inputs.endTreeSnapshots, txProvingState.treeSnapshots);
|
|
709
680
|
const leafLocation = provingState.setBaseRollupProof(txIndex, result);
|
|
710
681
|
if (provingState.totalNumTxs === 1) {
|
|
@@ -718,34 +689,33 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
718
689
|
|
|
719
690
|
// Enqueues the public chonk verifier circuit for a given transaction index, or reuses the one already enqueued.
|
|
720
691
|
// Once completed, will enqueue the the public tx base rollup.
|
|
721
|
-
|
|
692
|
+
protected getOrEnqueueChonkVerifier(provingState: BlockProvingState, txIndex: number) {
|
|
722
693
|
if (!provingState.verifyState()) {
|
|
723
|
-
logger.debug('Not running chonk verifier circuit, state invalid');
|
|
694
|
+
this.logger.debug('Not running chonk verifier circuit, state invalid');
|
|
724
695
|
return;
|
|
725
696
|
}
|
|
726
697
|
|
|
727
698
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
728
699
|
const txHash = txProvingState.processedTx.hash.toString();
|
|
729
|
-
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH;
|
|
730
700
|
const handleResult = (
|
|
731
701
|
result: PublicInputsAndRecursiveProof<
|
|
732
702
|
PublicChonkVerifierPublicInputs,
|
|
733
703
|
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
734
704
|
>,
|
|
735
705
|
) => {
|
|
736
|
-
logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
|
|
706
|
+
this.logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
|
|
737
707
|
txProvingState.setPublicChonkVerifierProof(result);
|
|
738
708
|
this.provingState?.cachedChonkVerifierProofs.delete(txHash);
|
|
739
709
|
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
740
710
|
};
|
|
741
711
|
|
|
742
712
|
if (this.provingState?.cachedChonkVerifierProofs.has(txHash)) {
|
|
743
|
-
logger.debug(`Chonk verifier proof already enqueued for tx index: ${txIndex}`, { txHash });
|
|
713
|
+
this.logger.debug(`Chonk verifier proof already enqueued for tx index: ${txIndex}`, { txHash });
|
|
744
714
|
void this.provingState!.cachedChonkVerifierProofs.get(txHash)!.then(handleResult);
|
|
745
715
|
return;
|
|
746
716
|
}
|
|
747
717
|
|
|
748
|
-
logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
|
|
718
|
+
this.logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
|
|
749
719
|
this.doEnqueueChonkVerifier(txHash, txProvingState.getPublicChonkVerifierPrivateInputs(), handleResult);
|
|
750
720
|
}
|
|
751
721
|
|
|
@@ -761,7 +731,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
761
731
|
provingState: EpochProvingState | BlockProvingState = this.provingState!,
|
|
762
732
|
) {
|
|
763
733
|
if (!provingState.verifyState()) {
|
|
764
|
-
logger.debug('Not running chonk verifier circuit, state invalid');
|
|
734
|
+
this.logger.debug('Not running chonk verifier circuit, state invalid');
|
|
765
735
|
return;
|
|
766
736
|
}
|
|
767
737
|
|
|
@@ -784,12 +754,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
784
754
|
// Enqueues the next level of merge if all inputs are available
|
|
785
755
|
private enqueueMergeRollup(provingState: BlockProvingState, location: TreeNodeLocation) {
|
|
786
756
|
if (!provingState.verifyState()) {
|
|
787
|
-
logger.debug('Not running merge rollup. State no longer valid.');
|
|
757
|
+
this.logger.debug('Not running merge rollup. State no longer valid.');
|
|
788
758
|
return;
|
|
789
759
|
}
|
|
790
760
|
|
|
791
761
|
if (!provingState.tryStartProvingMerge(location)) {
|
|
792
|
-
logger.debug('Merge rollup already started.');
|
|
762
|
+
this.logger.debug('Merge rollup already started.');
|
|
793
763
|
return;
|
|
794
764
|
}
|
|
795
765
|
|
|
@@ -815,18 +785,18 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
815
785
|
// Executes the block root rollup circuit
|
|
816
786
|
private enqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
817
787
|
if (!provingState.verifyState()) {
|
|
818
|
-
logger.debug('Not running block root rollup, state no longer valid');
|
|
788
|
+
this.logger.debug('Not running block root rollup, state no longer valid');
|
|
819
789
|
return;
|
|
820
790
|
}
|
|
821
791
|
|
|
822
792
|
if (!provingState.tryStartProvingBlockRoot()) {
|
|
823
|
-
logger.debug('Block root rollup already started.');
|
|
793
|
+
this.logger.debug('Block root rollup already started.');
|
|
824
794
|
return;
|
|
825
795
|
}
|
|
826
796
|
|
|
827
797
|
const { rollupType, inputs } = provingState.getBlockRootRollupTypeAndInputs();
|
|
828
798
|
|
|
829
|
-
logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
|
|
799
|
+
this.logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
|
|
830
800
|
|
|
831
801
|
this.deferredProving(
|
|
832
802
|
provingState,
|
|
@@ -851,18 +821,23 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
851
821
|
},
|
|
852
822
|
),
|
|
853
823
|
async result => {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
824
|
+
this.logger.debug(`Completed ${rollupType} proof for block ${provingState.blockNumber}`, {
|
|
825
|
+
blockNumber: provingState.blockNumber,
|
|
826
|
+
checkpointIndex: provingState.parentCheckpoint.index,
|
|
827
|
+
...result.inputs.toInspect(),
|
|
828
|
+
});
|
|
858
829
|
|
|
859
830
|
const leafLocation = provingState.setBlockRootRollupProof(result);
|
|
860
831
|
const checkpointProvingState = provingState.parentCheckpoint;
|
|
861
832
|
|
|
833
|
+
// Verification is called from both here and setBlockCompleted. Whichever runs last
|
|
834
|
+
// will be the first to see all three pieces (header, proof output, archive) and run the checks.
|
|
835
|
+
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
836
|
+
|
|
862
837
|
if (checkpointProvingState.totalNumBlocks === 1) {
|
|
863
|
-
this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
|
|
838
|
+
await this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
|
|
864
839
|
} else {
|
|
865
|
-
this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
|
|
840
|
+
await this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
|
|
866
841
|
}
|
|
867
842
|
},
|
|
868
843
|
);
|
|
@@ -876,12 +851,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
876
851
|
baseParityIndex: number,
|
|
877
852
|
) {
|
|
878
853
|
if (!provingState.verifyState()) {
|
|
879
|
-
logger.debug('Not running base parity. State no longer valid.');
|
|
854
|
+
this.logger.debug('Not running base parity. State no longer valid.');
|
|
880
855
|
return;
|
|
881
856
|
}
|
|
882
857
|
|
|
883
858
|
if (!provingState.tryStartProvingBaseParity(baseParityIndex)) {
|
|
884
|
-
logger.warn(`Base parity ${baseParityIndex} already started.`);
|
|
859
|
+
this.logger.warn(`Base parity ${baseParityIndex} already started.`);
|
|
885
860
|
return;
|
|
886
861
|
}
|
|
887
862
|
|
|
@@ -916,12 +891,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
916
891
|
// Enqueues the root rollup proof if all inputs are available
|
|
917
892
|
private enqueueRootParityCircuit(provingState: BlockProvingState) {
|
|
918
893
|
if (!provingState.verifyState()) {
|
|
919
|
-
logger.debug('Not running root parity. State no longer valid.');
|
|
894
|
+
this.logger.debug('Not running root parity. State no longer valid.');
|
|
920
895
|
return;
|
|
921
896
|
}
|
|
922
897
|
|
|
923
898
|
if (!provingState.tryStartProvingRootParity()) {
|
|
924
|
-
logger.debug('Root parity already started.');
|
|
899
|
+
this.logger.debug('Root parity already started.');
|
|
925
900
|
return;
|
|
926
901
|
}
|
|
927
902
|
|
|
@@ -948,12 +923,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
948
923
|
// Enqueues the next level of merge if all inputs are available
|
|
949
924
|
private enqueueBlockMergeRollup(provingState: CheckpointProvingState, location: TreeNodeLocation) {
|
|
950
925
|
if (!provingState.verifyState()) {
|
|
951
|
-
logger.debug('Not running block merge rollup. State no longer valid.');
|
|
926
|
+
this.logger.debug('Not running block merge rollup. State no longer valid.');
|
|
952
927
|
return;
|
|
953
928
|
}
|
|
954
929
|
|
|
955
930
|
if (!provingState.tryStartProvingBlockMerge(location)) {
|
|
956
|
-
logger.debug('Block merge rollup already started.');
|
|
931
|
+
this.logger.debug('Block merge rollup already started.');
|
|
957
932
|
return;
|
|
958
933
|
}
|
|
959
934
|
|
|
@@ -968,29 +943,34 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
968
943
|
},
|
|
969
944
|
signal => this.prover.getBlockMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
970
945
|
),
|
|
971
|
-
result => {
|
|
946
|
+
async result => {
|
|
947
|
+
this.logger.debug(`Completed block merge rollup proof for checkpoint ${provingState.index}`, {
|
|
948
|
+
checkpointIndex: provingState.index,
|
|
949
|
+
mergeLocation: location,
|
|
950
|
+
...result.inputs.toInspect(),
|
|
951
|
+
});
|
|
972
952
|
provingState.setBlockMergeRollupProof(location, result);
|
|
973
|
-
this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
|
|
953
|
+
await this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
|
|
974
954
|
},
|
|
975
955
|
);
|
|
976
956
|
}
|
|
977
957
|
|
|
978
|
-
private enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
958
|
+
private async enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
979
959
|
if (!provingState.verifyState()) {
|
|
980
|
-
logger.debug('Not running checkpoint root rollup. State no longer valid.');
|
|
960
|
+
this.logger.debug('Not running checkpoint root rollup. State no longer valid.');
|
|
981
961
|
return;
|
|
982
962
|
}
|
|
983
963
|
|
|
984
964
|
if (!provingState.tryStartProvingCheckpointRoot()) {
|
|
985
|
-
logger.debug('Checkpoint root rollup already started.');
|
|
965
|
+
this.logger.debug('Checkpoint root rollup already started.');
|
|
986
966
|
return;
|
|
987
967
|
}
|
|
988
968
|
|
|
989
969
|
const rollupType = provingState.getCheckpointRootRollupType();
|
|
990
970
|
|
|
991
|
-
logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
|
|
971
|
+
this.logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
|
|
992
972
|
|
|
993
|
-
const inputs = provingState.getCheckpointRootRollupInputs();
|
|
973
|
+
const inputs = await provingState.getCheckpointRootRollupInputs();
|
|
994
974
|
|
|
995
975
|
this.deferredProving(
|
|
996
976
|
provingState,
|
|
@@ -1012,7 +992,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1012
992
|
const computedEndBlobAccumulatorState = provingState.getEndBlobAccumulator()!.toBlobAccumulator();
|
|
1013
993
|
const circuitEndBlobAccumulatorState = result.inputs.endBlobAccumulator;
|
|
1014
994
|
if (!circuitEndBlobAccumulatorState.equals(computedEndBlobAccumulatorState)) {
|
|
1015
|
-
logger.error(
|
|
995
|
+
this.logger.error(
|
|
1016
996
|
`Blob accumulator state mismatch.\nCircuit: ${inspect(circuitEndBlobAccumulatorState)}\nComputed: ${inspect(
|
|
1017
997
|
computedEndBlobAccumulatorState,
|
|
1018
998
|
)}`,
|
|
@@ -1021,7 +1001,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1021
1001
|
return;
|
|
1022
1002
|
}
|
|
1023
1003
|
|
|
1024
|
-
logger.debug(`Completed ${rollupType} proof for checkpoint ${provingState.index}
|
|
1004
|
+
this.logger.debug(`Completed ${rollupType} proof for checkpoint ${provingState.index}`, {
|
|
1005
|
+
checkpointIndex: provingState.index,
|
|
1006
|
+
...result.inputs.toInspect(),
|
|
1007
|
+
});
|
|
1025
1008
|
|
|
1026
1009
|
const leafLocation = provingState.setCheckpointRootRollupProof(result);
|
|
1027
1010
|
const epochProvingState = provingState.parentEpoch;
|
|
@@ -1035,99 +1018,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1035
1018
|
);
|
|
1036
1019
|
}
|
|
1037
1020
|
|
|
1038
|
-
private enqueueCheckpointMergeRollup(provingState: EpochProvingState, location: TreeNodeLocation) {
|
|
1039
|
-
if (!provingState.verifyState()) {
|
|
1040
|
-
logger.debug('Not running checkpoint merge rollup. State no longer valid.');
|
|
1041
|
-
return;
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
if (!provingState.tryStartProvingCheckpointMerge(location)) {
|
|
1045
|
-
logger.debug('Checkpoint merge rollup already started.');
|
|
1046
|
-
return;
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
const inputs = provingState.getCheckpointMergeRollupInputs(location);
|
|
1050
|
-
|
|
1051
|
-
this.deferredProving(
|
|
1052
|
-
provingState,
|
|
1053
|
-
wrapCallbackInSpan(
|
|
1054
|
-
this.tracer,
|
|
1055
|
-
'ProvingOrchestrator.prover.getCheckpointMergeRollupProof',
|
|
1056
|
-
{
|
|
1057
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-checkpoint-merge' satisfies CircuitName,
|
|
1058
|
-
},
|
|
1059
|
-
signal => this.prover.getCheckpointMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
1060
|
-
),
|
|
1061
|
-
result => {
|
|
1062
|
-
logger.debug('Completed proof for checkpoint merge rollup.');
|
|
1063
|
-
provingState.setCheckpointMergeRollupProof(location, result);
|
|
1064
|
-
this.checkAndEnqueueNextCheckpointMergeRollup(provingState, location);
|
|
1065
|
-
},
|
|
1066
|
-
);
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
private enqueueEpochPadding(provingState: EpochProvingState) {
|
|
1070
|
-
if (!provingState.verifyState()) {
|
|
1071
|
-
logger.debug('Not running epoch padding. State no longer valid.');
|
|
1072
|
-
return;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
if (!provingState.tryStartProvingPaddingCheckpoint()) {
|
|
1076
|
-
logger.debug('Padding checkpoint already started.');
|
|
1077
|
-
return;
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
logger.debug('Padding epoch proof with a padding block root proof.');
|
|
1081
|
-
|
|
1082
|
-
const inputs = provingState.getPaddingCheckpointInputs();
|
|
1083
|
-
|
|
1084
|
-
this.deferredProving(
|
|
1085
|
-
provingState,
|
|
1086
|
-
wrapCallbackInSpan(
|
|
1087
|
-
this.tracer,
|
|
1088
|
-
'ProvingOrchestrator.prover.getCheckpointPaddingRollupProof',
|
|
1089
|
-
{
|
|
1090
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-checkpoint-padding' satisfies CircuitName,
|
|
1091
|
-
},
|
|
1092
|
-
signal => this.prover.getCheckpointPaddingRollupProof(inputs, signal, provingState.epochNumber),
|
|
1093
|
-
),
|
|
1094
|
-
result => {
|
|
1095
|
-
logger.debug('Completed proof for padding checkpoint.');
|
|
1096
|
-
provingState.setCheckpointPaddingProof(result);
|
|
1097
|
-
this.checkAndEnqueueRootRollup(provingState);
|
|
1098
|
-
},
|
|
1099
|
-
);
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
// Executes the root rollup circuit
|
|
1103
|
-
private enqueueRootRollup(provingState: EpochProvingState) {
|
|
1104
|
-
if (!provingState.verifyState()) {
|
|
1105
|
-
logger.debug('Not running root rollup, state no longer valid');
|
|
1106
|
-
return;
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
logger.debug(`Preparing root rollup`);
|
|
1110
|
-
|
|
1111
|
-
const inputs = provingState.getRootRollupInputs();
|
|
1112
|
-
|
|
1113
|
-
this.deferredProving(
|
|
1114
|
-
provingState,
|
|
1115
|
-
wrapCallbackInSpan(
|
|
1116
|
-
this.tracer,
|
|
1117
|
-
'ProvingOrchestrator.prover.getRootRollupProof',
|
|
1118
|
-
{
|
|
1119
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-root' satisfies CircuitName,
|
|
1120
|
-
},
|
|
1121
|
-
signal => this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
1122
|
-
),
|
|
1123
|
-
result => {
|
|
1124
|
-
logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1125
|
-
provingState.setRootRollupProof(result);
|
|
1126
|
-
provingState.resolve({ status: 'success' });
|
|
1127
|
-
},
|
|
1128
|
-
);
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
1021
|
private checkAndEnqueueNextMergeRollup(provingState: BlockProvingState, currentLocation: TreeNodeLocation) {
|
|
1132
1022
|
if (!provingState.isReadyForMergeRollup(currentLocation)) {
|
|
1133
1023
|
return;
|
|
@@ -1143,54 +1033,35 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1143
1033
|
|
|
1144
1034
|
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
1145
1035
|
if (!provingState.isReadyForBlockRootRollup()) {
|
|
1146
|
-
logger.debug('Not ready for block root rollup');
|
|
1036
|
+
this.logger.debug('Not ready for block root rollup');
|
|
1147
1037
|
return;
|
|
1148
1038
|
}
|
|
1149
1039
|
|
|
1150
1040
|
this.enqueueBlockRootRollup(provingState);
|
|
1151
1041
|
}
|
|
1152
1042
|
|
|
1153
|
-
private checkAndEnqueueNextBlockMergeRollup(
|
|
1043
|
+
private async checkAndEnqueueNextBlockMergeRollup(
|
|
1044
|
+
provingState: CheckpointProvingState,
|
|
1045
|
+
currentLocation: TreeNodeLocation,
|
|
1046
|
+
) {
|
|
1154
1047
|
if (!provingState.isReadyForBlockMerge(currentLocation)) {
|
|
1155
1048
|
return;
|
|
1156
1049
|
}
|
|
1157
1050
|
|
|
1158
1051
|
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
1159
1052
|
if (parentLocation.level === 0) {
|
|
1160
|
-
this.checkAndEnqueueCheckpointRootRollup(provingState);
|
|
1053
|
+
await this.checkAndEnqueueCheckpointRootRollup(provingState);
|
|
1161
1054
|
} else {
|
|
1162
1055
|
this.enqueueBlockMergeRollup(provingState, parentLocation);
|
|
1163
1056
|
}
|
|
1164
1057
|
}
|
|
1165
1058
|
|
|
1166
|
-
|
|
1059
|
+
protected async checkAndEnqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
1167
1060
|
if (!provingState.isReadyForCheckpointRoot()) {
|
|
1168
1061
|
return;
|
|
1169
1062
|
}
|
|
1170
1063
|
|
|
1171
|
-
this.enqueueCheckpointRootRollup(provingState);
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
private checkAndEnqueueNextCheckpointMergeRollup(provingState: EpochProvingState, currentLocation: TreeNodeLocation) {
|
|
1175
|
-
if (!provingState.isReadyForCheckpointMerge(currentLocation)) {
|
|
1176
|
-
return;
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
1180
|
-
if (parentLocation.level === 0) {
|
|
1181
|
-
this.checkAndEnqueueRootRollup(provingState);
|
|
1182
|
-
} else {
|
|
1183
|
-
this.enqueueCheckpointMergeRollup(provingState, parentLocation);
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
private checkAndEnqueueRootRollup(provingState: EpochProvingState) {
|
|
1188
|
-
if (!provingState.isReadyForRootRollup()) {
|
|
1189
|
-
logger.debug('Not ready for root rollup');
|
|
1190
|
-
return;
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
this.enqueueRootRollup(provingState);
|
|
1064
|
+
await this.enqueueCheckpointRootRollup(provingState);
|
|
1194
1065
|
}
|
|
1195
1066
|
|
|
1196
1067
|
/**
|
|
@@ -1201,7 +1072,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1201
1072
|
*/
|
|
1202
1073
|
private enqueueVM(provingState: BlockProvingState, txIndex: number) {
|
|
1203
1074
|
if (!provingState.verifyState()) {
|
|
1204
|
-
logger.debug(`Not running VM circuit as state is no longer valid`);
|
|
1075
|
+
this.logger.debug(`Not running VM circuit as state is no longer valid`);
|
|
1205
1076
|
return;
|
|
1206
1077
|
}
|
|
1207
1078
|
|
|
@@ -1220,20 +1091,20 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1220
1091
|
);
|
|
1221
1092
|
|
|
1222
1093
|
this.deferredProving(provingState, doAvmProving, proof => {
|
|
1223
|
-
logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1094
|
+
this.logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1224
1095
|
txProvingState.setAvmProof(proof);
|
|
1225
1096
|
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
1226
1097
|
});
|
|
1227
1098
|
}
|
|
1228
1099
|
|
|
1229
|
-
|
|
1100
|
+
protected checkAndEnqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
|
|
1230
1101
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
1231
1102
|
if (!txProvingState.ready()) {
|
|
1232
1103
|
return;
|
|
1233
1104
|
}
|
|
1234
1105
|
|
|
1235
1106
|
// We must have completed all proving (chonk verifier proof and (if required) vm proof are generated), we now move to the base rollup.
|
|
1236
|
-
logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
1107
|
+
this.logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
1237
1108
|
|
|
1238
1109
|
this.enqueueBaseRollup(provingState, txIndex);
|
|
1239
1110
|
}
|