@aztec/prover-client 0.0.1-commit.2ed92850 → 0.0.1-commit.2f68f620
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 +13 -5
- package/dest/light/lightweight_checkpoint_builder.d.ts.map +1 -1
- package/dest/light/lightweight_checkpoint_builder.js +61 -24
- 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 +3 -1
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +19 -9
- package/dest/orchestrator/block-building-helpers.d.ts +4 -4
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +4 -4
- 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 +10 -3
- package/dest/orchestrator/checkpoint-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/checkpoint-proving-state.js +13 -4
- 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 +3 -3
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +5 -3
- 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 +16 -24
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +119 -248
- 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 +11 -67
- package/dest/proving_broker/config.d.ts.map +1 -1
- package/dest/proving_broker/config.js +16 -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_prover.d.ts +4 -4
- package/package.json +18 -19
- package/src/config.ts +18 -2
- package/src/light/lightweight_checkpoint_builder.ts +73 -27
- package/src/mocks/fixtures.ts +2 -1
- package/src/mocks/test_context.ts +14 -10
- package/src/orchestrator/block-building-helpers.ts +4 -4
- package/src/orchestrator/block-proving-state.ts +9 -0
- package/src/orchestrator/checkpoint-proving-state.ts +18 -5
- 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 +6 -4
- package/src/orchestrator/index.ts +8 -0
- package/src/orchestrator/orchestrator.ts +142 -311
- 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 +148 -14
- package/src/proving_broker/broker_prover_facade.ts +23 -23
- package/src/proving_broker/config.ts +16 -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/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/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,15 +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
|
-
type WorldStateFork = {
|
|
77
|
-
fork: MerkleTreeWriteOperations;
|
|
78
|
-
cleanupPromise: Promise<void> | undefined;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
73
|
/**
|
|
82
74
|
* Implements an event driven proving scheduler to build the recursive proof tree. The idea being:
|
|
83
75
|
* 1. Transactions are provided to the scheduler post simulation.
|
|
@@ -92,22 +84,24 @@ type WorldStateFork = {
|
|
|
92
84
|
/**
|
|
93
85
|
* The orchestrator, managing the flow of recursive proving operations required to build the rollup proof tree.
|
|
94
86
|
*/
|
|
95
|
-
export class ProvingOrchestrator implements EpochProver {
|
|
96
|
-
|
|
97
|
-
private pendingProvingJobs: AbortController[] = [];
|
|
87
|
+
export class ProvingOrchestrator extends TopTreeProvingScheduler implements EpochProver {
|
|
88
|
+
protected provingState: EpochProvingState | undefined = undefined;
|
|
98
89
|
|
|
99
|
-
|
|
90
|
+
protected provingPromise: Promise<ProvingResult> | undefined = undefined;
|
|
100
91
|
private metrics: ProvingOrchestratorMetrics;
|
|
101
|
-
|
|
102
|
-
private dbs: Map<BlockNumber,
|
|
92
|
+
|
|
93
|
+
private dbs: Map<BlockNumber, MerkleTreeWriteOperations> = new Map();
|
|
103
94
|
|
|
104
95
|
constructor(
|
|
105
96
|
private dbProvider: ReadonlyWorldStateAccess & ForkMerkleTreeOperations,
|
|
106
|
-
|
|
97
|
+
prover: ServerCircuitProver,
|
|
107
98
|
private readonly proverId: EthAddress,
|
|
108
99
|
private readonly cancelJobsOnStop: boolean = false,
|
|
100
|
+
enqueueConcurrency: number,
|
|
109
101
|
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
102
|
+
bindings?: LoggerBindings,
|
|
110
103
|
) {
|
|
104
|
+
super(prover, enqueueConcurrency, 'prover-client:orchestrator', bindings);
|
|
111
105
|
this.metrics = new ProvingOrchestratorMetrics(telemetryClient, 'ProvingOrchestrator');
|
|
112
106
|
}
|
|
113
107
|
|
|
@@ -123,9 +117,24 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
123
117
|
return this.dbs.size;
|
|
124
118
|
}
|
|
125
119
|
|
|
126
|
-
|
|
120
|
+
protected override cancelInternal(): void {
|
|
127
121
|
this.cancel();
|
|
128
|
-
|
|
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' });
|
|
129
138
|
}
|
|
130
139
|
|
|
131
140
|
public startNewEpoch(
|
|
@@ -141,7 +150,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
141
150
|
|
|
142
151
|
const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
|
|
143
152
|
const promise = _promise.catch((reason): ProvingResult => ({ status: 'failure', reason }));
|
|
144
|
-
logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
|
|
153
|
+
this.logger.info(`Starting epoch ${epochNumber} with ${totalNumCheckpoints} checkpoints.`);
|
|
145
154
|
this.provingState = new EpochProvingState(
|
|
146
155
|
epochNumber,
|
|
147
156
|
totalNumCheckpoints,
|
|
@@ -181,7 +190,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
181
190
|
const db = await this.dbProvider.fork(lastBlockNumber);
|
|
182
191
|
|
|
183
192
|
const firstBlockNumber = BlockNumber(lastBlockNumber + 1);
|
|
184
|
-
this.dbs.set(firstBlockNumber,
|
|
193
|
+
this.dbs.set(firstBlockNumber, db);
|
|
185
194
|
|
|
186
195
|
// Get archive sibling path before any block in this checkpoint lands.
|
|
187
196
|
const lastArchiveSiblingPath = await getLastSiblingPath(MerkleTreeId.ARCHIVE, db);
|
|
@@ -233,15 +242,15 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
233
242
|
}
|
|
234
243
|
|
|
235
244
|
const constants = checkpointProvingState.constants;
|
|
236
|
-
logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber}.`);
|
|
245
|
+
this.logger.info(`Starting block ${blockNumber} for slot ${constants.slotNumber}.`);
|
|
237
246
|
|
|
238
247
|
// Fork the db only when it's not already set. The db for the first block is set in `startNewCheckpoint`.
|
|
239
248
|
if (!this.dbs.has(blockNumber)) {
|
|
240
249
|
// Fork world state at the end of the immediately previous block
|
|
241
250
|
const db = await this.dbProvider.fork(BlockNumber(blockNumber - 1));
|
|
242
|
-
this.dbs.set(blockNumber,
|
|
251
|
+
this.dbs.set(blockNumber, db);
|
|
243
252
|
}
|
|
244
|
-
const db = this.
|
|
253
|
+
const db = this.getDbForBlock(blockNumber);
|
|
245
254
|
|
|
246
255
|
// Get archive snapshot and sibling path before any txs in this block lands.
|
|
247
256
|
const lastArchiveTreeSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
@@ -294,7 +303,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
294
303
|
if (!txs.length) {
|
|
295
304
|
// To avoid an ugly throw below. If we require an empty block, we can just call setBlockCompleted
|
|
296
305
|
// on a block with no txs. We cannot do that here because we cannot find the blockNumber without any txs.
|
|
297
|
-
logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
306
|
+
this.logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
298
307
|
return;
|
|
299
308
|
}
|
|
300
309
|
|
|
@@ -314,9 +323,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
314
323
|
throw new Error(`Block ${blockNumber} has been initialized with transactions.`);
|
|
315
324
|
}
|
|
316
325
|
|
|
317
|
-
logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
|
|
326
|
+
this.logger.info(`Adding ${txs.length} transactions to block ${blockNumber}`);
|
|
318
327
|
|
|
319
|
-
const db = this.
|
|
328
|
+
const db = this.getDbForBlock(blockNumber);
|
|
320
329
|
const lastArchive = provingState.lastArchiveTreeSnapshot;
|
|
321
330
|
const newL1ToL2MessageTreeSnapshot = provingState.newL1ToL2MessageTreeSnapshot;
|
|
322
331
|
const spongeBlobState = provingState.getStartSpongeBlob().clone();
|
|
@@ -329,7 +338,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
329
338
|
|
|
330
339
|
validateTx(tx);
|
|
331
340
|
|
|
332
|
-
logger.debug(`Received transaction: ${tx.hash}`);
|
|
341
|
+
this.logger.debug(`Received transaction: ${tx.hash}`);
|
|
333
342
|
|
|
334
343
|
const startSpongeBlob = spongeBlobState.clone();
|
|
335
344
|
const [hints, treeSnapshots] = await this.prepareBaseRollupInputs(
|
|
@@ -350,10 +359,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
350
359
|
const txIndex = provingState.addNewTx(txProvingState);
|
|
351
360
|
if (txProvingState.requireAvmProof) {
|
|
352
361
|
this.getOrEnqueueChonkVerifier(provingState, txIndex);
|
|
353
|
-
logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
362
|
+
this.logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
354
363
|
this.enqueueVM(provingState, txIndex);
|
|
355
364
|
} else {
|
|
356
|
-
logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
|
|
365
|
+
this.logger.debug(`Enqueueing base rollup for private-only tx ${txIndex}`);
|
|
357
366
|
this.enqueueBaseRollup(provingState, txIndex);
|
|
358
367
|
}
|
|
359
368
|
} catch (err: any) {
|
|
@@ -396,7 +405,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
396
405
|
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
397
406
|
>
|
|
398
407
|
>();
|
|
399
|
-
logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
|
|
408
|
+
this.logger.debug(`Starting chonk verifier circuit for tx ${txHash}`);
|
|
400
409
|
this.doEnqueueChonkVerifier(txHash, privateInputs, proof => {
|
|
401
410
|
tubeProof.resolve(proof);
|
|
402
411
|
});
|
|
@@ -436,22 +445,28 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
436
445
|
}
|
|
437
446
|
|
|
438
447
|
// Given we've applied every change from this block, now assemble the block header:
|
|
439
|
-
logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
448
|
+
this.logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
440
449
|
const header = await provingState.buildBlockHeader();
|
|
441
450
|
|
|
442
451
|
if (expectedHeader && !header.equals(expectedHeader)) {
|
|
443
|
-
logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
452
|
+
this.logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
444
453
|
throw new Error('Block header mismatch');
|
|
445
454
|
}
|
|
446
455
|
|
|
447
|
-
// Get db for this block
|
|
448
|
-
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);
|
|
449
459
|
|
|
450
|
-
// Update the archive tree,
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
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
|
+
}
|
|
455
470
|
|
|
456
471
|
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
457
472
|
|
|
@@ -462,31 +477,34 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
462
477
|
protected async verifyBuiltBlockAgainstSyncedState(provingState: BlockProvingState) {
|
|
463
478
|
const builtBlockHeader = provingState.getBuiltBlockHeader();
|
|
464
479
|
if (!builtBlockHeader) {
|
|
465
|
-
logger.debug('Block header not built yet, skipping header check.');
|
|
480
|
+
this.logger.debug('Block header not built yet, skipping header check.');
|
|
466
481
|
return;
|
|
467
482
|
}
|
|
468
483
|
|
|
469
484
|
const output = provingState.getBlockRootRollupOutput();
|
|
470
485
|
if (!output) {
|
|
471
|
-
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.');
|
|
472
487
|
return;
|
|
473
488
|
}
|
|
489
|
+
|
|
490
|
+
const newArchive = provingState.getBuiltArchive();
|
|
491
|
+
if (!newArchive) {
|
|
492
|
+
this.logger.debug('Archive snapshot not yet captured, skipping header check.');
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
474
496
|
const header = await buildHeaderFromCircuitOutputs(output);
|
|
475
497
|
|
|
476
498
|
if (!(await header.hash()).equals(await builtBlockHeader.hash())) {
|
|
477
|
-
logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
|
|
499
|
+
this.logger.error(`Block header mismatch.\nCircuit: ${inspect(header)}\nComputed: ${inspect(builtBlockHeader)}`);
|
|
478
500
|
provingState.reject(`Block header hash mismatch.`);
|
|
479
501
|
return;
|
|
480
502
|
}
|
|
481
503
|
|
|
482
|
-
// Get db for this block
|
|
483
504
|
const blockNumber = provingState.blockNumber;
|
|
484
|
-
const db = this.dbs.get(blockNumber)!.fork;
|
|
485
|
-
|
|
486
|
-
const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
487
505
|
const syncedArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.dbProvider.getSnapshot(blockNumber));
|
|
488
506
|
if (!syncedArchive.equals(newArchive)) {
|
|
489
|
-
logger.error(
|
|
507
|
+
this.logger.error(
|
|
490
508
|
`Archive tree mismatch for block ${blockNumber}: world state synced to ${inspect(
|
|
491
509
|
syncedArchive,
|
|
492
510
|
)} but built ${inspect(newArchive)}`,
|
|
@@ -497,16 +515,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
497
515
|
|
|
498
516
|
const circuitArchive = output.newArchive;
|
|
499
517
|
if (!newArchive.equals(circuitArchive)) {
|
|
500
|
-
logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
|
|
518
|
+
this.logger.error(`New archive mismatch.\nCircuit: ${output.newArchive}\nComputed: ${newArchive}`);
|
|
501
519
|
provingState.reject(`New archive mismatch.`);
|
|
502
520
|
return;
|
|
503
521
|
}
|
|
504
|
-
|
|
505
|
-
// TODO(palla/prover): This closes the fork only on the happy path. If this epoch orchestrator
|
|
506
|
-
// is aborted and never reaches this point, it will leak the fork. We need to add a global cleanup,
|
|
507
|
-
// but have to make sure it only runs once all operations are completed, otherwise some function here
|
|
508
|
-
// will attempt to access the fork after it was closed.
|
|
509
|
-
void this.cleanupDBFork(blockNumber);
|
|
510
522
|
}
|
|
511
523
|
|
|
512
524
|
/**
|
|
@@ -515,13 +527,22 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
515
527
|
* If cancelJobsOnStop is false (default), jobs remain in the broker queue and can be reused on restart/reorg.
|
|
516
528
|
*/
|
|
517
529
|
public cancel() {
|
|
518
|
-
|
|
519
|
-
for (const controller of this.pendingProvingJobs) {
|
|
520
|
-
controller.abort();
|
|
521
|
-
}
|
|
522
|
-
}
|
|
530
|
+
this.resetSchedulerState(this.cancelJobsOnStop);
|
|
523
531
|
|
|
524
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;
|
|
525
546
|
}
|
|
526
547
|
|
|
527
548
|
/**
|
|
@@ -553,94 +574,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
553
574
|
return epochProofResult;
|
|
554
575
|
}
|
|
555
576
|
|
|
556
|
-
private async cleanupDBFork(blockNumber: BlockNumber): Promise<void> {
|
|
557
|
-
logger.debug(`Cleaning up world state fork for ${blockNumber}`);
|
|
558
|
-
const fork = this.dbs.get(blockNumber);
|
|
559
|
-
if (!fork) {
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
try {
|
|
564
|
-
if (!fork.cleanupPromise) {
|
|
565
|
-
fork.cleanupPromise = fork.fork.close();
|
|
566
|
-
}
|
|
567
|
-
await fork.cleanupPromise;
|
|
568
|
-
this.dbs.delete(blockNumber);
|
|
569
|
-
} catch (err) {
|
|
570
|
-
logger.error(`Error closing db for block ${blockNumber}`, err);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Enqueue a job to be scheduled
|
|
576
|
-
* @param provingState - The proving state object being operated on
|
|
577
|
-
* @param jobType - The type of job to be queued
|
|
578
|
-
* @param job - The actual job, returns a promise notifying of the job's completion
|
|
579
|
-
*/
|
|
580
|
-
private deferredProving<T>(
|
|
581
|
-
provingState: EpochProvingState | CheckpointProvingState | BlockProvingState,
|
|
582
|
-
request: (signal: AbortSignal) => Promise<T>,
|
|
583
|
-
callback: (result: T) => void | Promise<void>,
|
|
584
|
-
) {
|
|
585
|
-
if (!provingState.verifyState()) {
|
|
586
|
-
logger.debug(`Not enqueuing job, state no longer valid`);
|
|
587
|
-
return;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
const controller = new AbortController();
|
|
591
|
-
this.pendingProvingJobs.push(controller);
|
|
592
|
-
|
|
593
|
-
// We use a 'safeJob'. We don't want promise rejections in the proving pool, we want to capture the error here
|
|
594
|
-
// and reject the proving job whilst keeping the event loop free of rejections
|
|
595
|
-
const safeJob = async () => {
|
|
596
|
-
try {
|
|
597
|
-
// there's a delay between enqueueing this job and it actually running
|
|
598
|
-
if (controller.signal.aborted) {
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
const result = await request(controller.signal);
|
|
603
|
-
if (!provingState.verifyState()) {
|
|
604
|
-
logger.debug(`State no longer valid, discarding result`);
|
|
605
|
-
return;
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
// we could have been cancelled whilst waiting for the result
|
|
609
|
-
// and the prover ignored the signal. Drop the result in that case
|
|
610
|
-
if (controller.signal.aborted) {
|
|
611
|
-
return;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
await callback(result);
|
|
615
|
-
} catch (err) {
|
|
616
|
-
if (err instanceof AbortError) {
|
|
617
|
-
// operation was cancelled, probably because the block was cancelled
|
|
618
|
-
// drop this result
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
logger.error(`Error thrown when proving job`, err);
|
|
623
|
-
provingState!.reject(`${err}`);
|
|
624
|
-
} finally {
|
|
625
|
-
const index = this.pendingProvingJobs.indexOf(controller);
|
|
626
|
-
if (index > -1) {
|
|
627
|
-
this.pendingProvingJobs.splice(index, 1);
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
// let the callstack unwind before adding the job to the queue
|
|
633
|
-
setImmediate(() => void safeJob());
|
|
634
|
-
}
|
|
635
|
-
|
|
636
577
|
private async updateL1ToL2MessageTree(l1ToL2Messages: Fr[], db: MerkleTreeWriteOperations) {
|
|
637
|
-
const l1ToL2MessagesPadded = padArrayEnd<Fr, number>(
|
|
638
|
-
l1ToL2Messages,
|
|
639
|
-
Fr.ZERO,
|
|
640
|
-
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
641
|
-
'Too many L1 to L2 messages',
|
|
642
|
-
);
|
|
643
|
-
|
|
644
578
|
const lastL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
645
579
|
const lastL1ToL2MessageSubtreeRootSiblingPath = assertLength(
|
|
646
580
|
await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, db),
|
|
@@ -648,7 +582,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
648
582
|
);
|
|
649
583
|
|
|
650
584
|
// Update the local trees to include the new l1 to l2 messages
|
|
651
|
-
await db
|
|
585
|
+
await appendL1ToL2MessagesToTree(db, l1ToL2Messages);
|
|
652
586
|
|
|
653
587
|
const newL1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
654
588
|
const newL1ToL2MessageSubtreeRootSiblingPath = assertLength(
|
|
@@ -704,12 +638,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
704
638
|
// Executes the next level of merge if all inputs are available
|
|
705
639
|
private enqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
|
|
706
640
|
if (!provingState.verifyState()) {
|
|
707
|
-
logger.debug('Not running base rollup, state invalid');
|
|
641
|
+
this.logger.debug('Not running base rollup, state invalid');
|
|
708
642
|
return;
|
|
709
643
|
}
|
|
710
644
|
|
|
711
645
|
if (!provingState.tryStartProvingBase(txIndex)) {
|
|
712
|
-
logger.debug(`Base rollup for tx ${txIndex} already started.`);
|
|
646
|
+
this.logger.debug(`Base rollup for tx ${txIndex} already started.`);
|
|
713
647
|
return;
|
|
714
648
|
}
|
|
715
649
|
|
|
@@ -717,7 +651,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
717
651
|
const { processedTx } = txProvingState;
|
|
718
652
|
const { rollupType, inputs } = txProvingState.getBaseRollupTypeAndInputs();
|
|
719
653
|
|
|
720
|
-
logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
654
|
+
this.logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
721
655
|
|
|
722
656
|
this.deferredProving(
|
|
723
657
|
provingState,
|
|
@@ -741,7 +675,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
741
675
|
},
|
|
742
676
|
),
|
|
743
677
|
result => {
|
|
744
|
-
logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
678
|
+
this.logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
745
679
|
validatePartialState(result.inputs.endTreeSnapshots, txProvingState.treeSnapshots);
|
|
746
680
|
const leafLocation = provingState.setBaseRollupProof(txIndex, result);
|
|
747
681
|
if (provingState.totalNumTxs === 1) {
|
|
@@ -755,34 +689,33 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
755
689
|
|
|
756
690
|
// Enqueues the public chonk verifier circuit for a given transaction index, or reuses the one already enqueued.
|
|
757
691
|
// Once completed, will enqueue the the public tx base rollup.
|
|
758
|
-
|
|
692
|
+
protected getOrEnqueueChonkVerifier(provingState: BlockProvingState, txIndex: number) {
|
|
759
693
|
if (!provingState.verifyState()) {
|
|
760
|
-
logger.debug('Not running chonk verifier circuit, state invalid');
|
|
694
|
+
this.logger.debug('Not running chonk verifier circuit, state invalid');
|
|
761
695
|
return;
|
|
762
696
|
}
|
|
763
697
|
|
|
764
698
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
765
699
|
const txHash = txProvingState.processedTx.hash.toString();
|
|
766
|
-
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH;
|
|
767
700
|
const handleResult = (
|
|
768
701
|
result: PublicInputsAndRecursiveProof<
|
|
769
702
|
PublicChonkVerifierPublicInputs,
|
|
770
703
|
typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH
|
|
771
704
|
>,
|
|
772
705
|
) => {
|
|
773
|
-
logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
|
|
706
|
+
this.logger.debug(`Got chonk verifier proof for tx index: ${txIndex}`, { txHash });
|
|
774
707
|
txProvingState.setPublicChonkVerifierProof(result);
|
|
775
708
|
this.provingState?.cachedChonkVerifierProofs.delete(txHash);
|
|
776
709
|
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
777
710
|
};
|
|
778
711
|
|
|
779
712
|
if (this.provingState?.cachedChonkVerifierProofs.has(txHash)) {
|
|
780
|
-
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 });
|
|
781
714
|
void this.provingState!.cachedChonkVerifierProofs.get(txHash)!.then(handleResult);
|
|
782
715
|
return;
|
|
783
716
|
}
|
|
784
717
|
|
|
785
|
-
logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
|
|
718
|
+
this.logger.debug(`Enqueuing chonk verifier circuit for tx index: ${txIndex}`);
|
|
786
719
|
this.doEnqueueChonkVerifier(txHash, txProvingState.getPublicChonkVerifierPrivateInputs(), handleResult);
|
|
787
720
|
}
|
|
788
721
|
|
|
@@ -798,7 +731,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
798
731
|
provingState: EpochProvingState | BlockProvingState = this.provingState!,
|
|
799
732
|
) {
|
|
800
733
|
if (!provingState.verifyState()) {
|
|
801
|
-
logger.debug('Not running chonk verifier circuit, state invalid');
|
|
734
|
+
this.logger.debug('Not running chonk verifier circuit, state invalid');
|
|
802
735
|
return;
|
|
803
736
|
}
|
|
804
737
|
|
|
@@ -821,12 +754,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
821
754
|
// Enqueues the next level of merge if all inputs are available
|
|
822
755
|
private enqueueMergeRollup(provingState: BlockProvingState, location: TreeNodeLocation) {
|
|
823
756
|
if (!provingState.verifyState()) {
|
|
824
|
-
logger.debug('Not running merge rollup. State no longer valid.');
|
|
757
|
+
this.logger.debug('Not running merge rollup. State no longer valid.');
|
|
825
758
|
return;
|
|
826
759
|
}
|
|
827
760
|
|
|
828
761
|
if (!provingState.tryStartProvingMerge(location)) {
|
|
829
|
-
logger.debug('Merge rollup already started.');
|
|
762
|
+
this.logger.debug('Merge rollup already started.');
|
|
830
763
|
return;
|
|
831
764
|
}
|
|
832
765
|
|
|
@@ -852,18 +785,18 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
852
785
|
// Executes the block root rollup circuit
|
|
853
786
|
private enqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
854
787
|
if (!provingState.verifyState()) {
|
|
855
|
-
logger.debug('Not running block root rollup, state no longer valid');
|
|
788
|
+
this.logger.debug('Not running block root rollup, state no longer valid');
|
|
856
789
|
return;
|
|
857
790
|
}
|
|
858
791
|
|
|
859
792
|
if (!provingState.tryStartProvingBlockRoot()) {
|
|
860
|
-
logger.debug('Block root rollup already started.');
|
|
793
|
+
this.logger.debug('Block root rollup already started.');
|
|
861
794
|
return;
|
|
862
795
|
}
|
|
863
796
|
|
|
864
797
|
const { rollupType, inputs } = provingState.getBlockRootRollupTypeAndInputs();
|
|
865
798
|
|
|
866
|
-
logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
|
|
799
|
+
this.logger.debug(`Enqueuing ${rollupType} for block ${provingState.blockNumber}.`);
|
|
867
800
|
|
|
868
801
|
this.deferredProving(
|
|
869
802
|
provingState,
|
|
@@ -888,22 +821,24 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
888
821
|
},
|
|
889
822
|
),
|
|
890
823
|
async result => {
|
|
891
|
-
logger.debug(`Completed ${rollupType} proof for block ${provingState.blockNumber}
|
|
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
|
+
});
|
|
892
829
|
|
|
893
830
|
const leafLocation = provingState.setBlockRootRollupProof(result);
|
|
894
831
|
const checkpointProvingState = provingState.parentCheckpoint;
|
|
895
832
|
|
|
896
|
-
//
|
|
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.
|
|
897
835
|
await this.verifyBuiltBlockAgainstSyncedState(provingState);
|
|
898
836
|
|
|
899
837
|
if (checkpointProvingState.totalNumBlocks === 1) {
|
|
900
|
-
this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
|
|
838
|
+
await this.checkAndEnqueueCheckpointRootRollup(checkpointProvingState);
|
|
901
839
|
} else {
|
|
902
|
-
this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
|
|
840
|
+
await this.checkAndEnqueueNextBlockMergeRollup(checkpointProvingState, leafLocation);
|
|
903
841
|
}
|
|
904
|
-
|
|
905
|
-
// We are finished with the block at this point, ensure the fork is cleaned up
|
|
906
|
-
void this.cleanupDBFork(provingState.blockNumber);
|
|
907
842
|
},
|
|
908
843
|
);
|
|
909
844
|
}
|
|
@@ -916,12 +851,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
916
851
|
baseParityIndex: number,
|
|
917
852
|
) {
|
|
918
853
|
if (!provingState.verifyState()) {
|
|
919
|
-
logger.debug('Not running base parity. State no longer valid.');
|
|
854
|
+
this.logger.debug('Not running base parity. State no longer valid.');
|
|
920
855
|
return;
|
|
921
856
|
}
|
|
922
857
|
|
|
923
858
|
if (!provingState.tryStartProvingBaseParity(baseParityIndex)) {
|
|
924
|
-
logger.warn(`Base parity ${baseParityIndex} already started.`);
|
|
859
|
+
this.logger.warn(`Base parity ${baseParityIndex} already started.`);
|
|
925
860
|
return;
|
|
926
861
|
}
|
|
927
862
|
|
|
@@ -956,12 +891,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
956
891
|
// Enqueues the root rollup proof if all inputs are available
|
|
957
892
|
private enqueueRootParityCircuit(provingState: BlockProvingState) {
|
|
958
893
|
if (!provingState.verifyState()) {
|
|
959
|
-
logger.debug('Not running root parity. State no longer valid.');
|
|
894
|
+
this.logger.debug('Not running root parity. State no longer valid.');
|
|
960
895
|
return;
|
|
961
896
|
}
|
|
962
897
|
|
|
963
898
|
if (!provingState.tryStartProvingRootParity()) {
|
|
964
|
-
logger.debug('Root parity already started.');
|
|
899
|
+
this.logger.debug('Root parity already started.');
|
|
965
900
|
return;
|
|
966
901
|
}
|
|
967
902
|
|
|
@@ -988,12 +923,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
988
923
|
// Enqueues the next level of merge if all inputs are available
|
|
989
924
|
private enqueueBlockMergeRollup(provingState: CheckpointProvingState, location: TreeNodeLocation) {
|
|
990
925
|
if (!provingState.verifyState()) {
|
|
991
|
-
logger.debug('Not running block merge rollup. State no longer valid.');
|
|
926
|
+
this.logger.debug('Not running block merge rollup. State no longer valid.');
|
|
992
927
|
return;
|
|
993
928
|
}
|
|
994
929
|
|
|
995
930
|
if (!provingState.tryStartProvingBlockMerge(location)) {
|
|
996
|
-
logger.debug('Block merge rollup already started.');
|
|
931
|
+
this.logger.debug('Block merge rollup already started.');
|
|
997
932
|
return;
|
|
998
933
|
}
|
|
999
934
|
|
|
@@ -1008,29 +943,34 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1008
943
|
},
|
|
1009
944
|
signal => this.prover.getBlockMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
1010
945
|
),
|
|
1011
|
-
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
|
+
});
|
|
1012
952
|
provingState.setBlockMergeRollupProof(location, result);
|
|
1013
|
-
this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
|
|
953
|
+
await this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
|
|
1014
954
|
},
|
|
1015
955
|
);
|
|
1016
956
|
}
|
|
1017
957
|
|
|
1018
|
-
private enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
958
|
+
private async enqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
1019
959
|
if (!provingState.verifyState()) {
|
|
1020
|
-
logger.debug('Not running checkpoint root rollup. State no longer valid.');
|
|
960
|
+
this.logger.debug('Not running checkpoint root rollup. State no longer valid.');
|
|
1021
961
|
return;
|
|
1022
962
|
}
|
|
1023
963
|
|
|
1024
964
|
if (!provingState.tryStartProvingCheckpointRoot()) {
|
|
1025
|
-
logger.debug('Checkpoint root rollup already started.');
|
|
965
|
+
this.logger.debug('Checkpoint root rollup already started.');
|
|
1026
966
|
return;
|
|
1027
967
|
}
|
|
1028
968
|
|
|
1029
969
|
const rollupType = provingState.getCheckpointRootRollupType();
|
|
1030
970
|
|
|
1031
|
-
logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
|
|
971
|
+
this.logger.debug(`Enqueuing ${rollupType} for checkpoint ${provingState.index}.`);
|
|
1032
972
|
|
|
1033
|
-
const inputs = provingState.getCheckpointRootRollupInputs();
|
|
973
|
+
const inputs = await provingState.getCheckpointRootRollupInputs();
|
|
1034
974
|
|
|
1035
975
|
this.deferredProving(
|
|
1036
976
|
provingState,
|
|
@@ -1052,7 +992,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1052
992
|
const computedEndBlobAccumulatorState = provingState.getEndBlobAccumulator()!.toBlobAccumulator();
|
|
1053
993
|
const circuitEndBlobAccumulatorState = result.inputs.endBlobAccumulator;
|
|
1054
994
|
if (!circuitEndBlobAccumulatorState.equals(computedEndBlobAccumulatorState)) {
|
|
1055
|
-
logger.error(
|
|
995
|
+
this.logger.error(
|
|
1056
996
|
`Blob accumulator state mismatch.\nCircuit: ${inspect(circuitEndBlobAccumulatorState)}\nComputed: ${inspect(
|
|
1057
997
|
computedEndBlobAccumulatorState,
|
|
1058
998
|
)}`,
|
|
@@ -1061,7 +1001,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1061
1001
|
return;
|
|
1062
1002
|
}
|
|
1063
1003
|
|
|
1064
|
-
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
|
+
});
|
|
1065
1008
|
|
|
1066
1009
|
const leafLocation = provingState.setCheckpointRootRollupProof(result);
|
|
1067
1010
|
const epochProvingState = provingState.parentEpoch;
|
|
@@ -1075,99 +1018,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1075
1018
|
);
|
|
1076
1019
|
}
|
|
1077
1020
|
|
|
1078
|
-
private enqueueCheckpointMergeRollup(provingState: EpochProvingState, location: TreeNodeLocation) {
|
|
1079
|
-
if (!provingState.verifyState()) {
|
|
1080
|
-
logger.debug('Not running checkpoint merge rollup. State no longer valid.');
|
|
1081
|
-
return;
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
if (!provingState.tryStartProvingCheckpointMerge(location)) {
|
|
1085
|
-
logger.debug('Checkpoint merge rollup already started.');
|
|
1086
|
-
return;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
const inputs = provingState.getCheckpointMergeRollupInputs(location);
|
|
1090
|
-
|
|
1091
|
-
this.deferredProving(
|
|
1092
|
-
provingState,
|
|
1093
|
-
wrapCallbackInSpan(
|
|
1094
|
-
this.tracer,
|
|
1095
|
-
'ProvingOrchestrator.prover.getCheckpointMergeRollupProof',
|
|
1096
|
-
{
|
|
1097
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-checkpoint-merge' satisfies CircuitName,
|
|
1098
|
-
},
|
|
1099
|
-
signal => this.prover.getCheckpointMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
1100
|
-
),
|
|
1101
|
-
result => {
|
|
1102
|
-
logger.debug('Completed proof for checkpoint merge rollup.');
|
|
1103
|
-
provingState.setCheckpointMergeRollupProof(location, result);
|
|
1104
|
-
this.checkAndEnqueueNextCheckpointMergeRollup(provingState, location);
|
|
1105
|
-
},
|
|
1106
|
-
);
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
private enqueueEpochPadding(provingState: EpochProvingState) {
|
|
1110
|
-
if (!provingState.verifyState()) {
|
|
1111
|
-
logger.debug('Not running epoch padding. State no longer valid.');
|
|
1112
|
-
return;
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
if (!provingState.tryStartProvingPaddingCheckpoint()) {
|
|
1116
|
-
logger.debug('Padding checkpoint already started.');
|
|
1117
|
-
return;
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
logger.debug('Padding epoch proof with a padding block root proof.');
|
|
1121
|
-
|
|
1122
|
-
const inputs = provingState.getPaddingCheckpointInputs();
|
|
1123
|
-
|
|
1124
|
-
this.deferredProving(
|
|
1125
|
-
provingState,
|
|
1126
|
-
wrapCallbackInSpan(
|
|
1127
|
-
this.tracer,
|
|
1128
|
-
'ProvingOrchestrator.prover.getCheckpointPaddingRollupProof',
|
|
1129
|
-
{
|
|
1130
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-checkpoint-padding' satisfies CircuitName,
|
|
1131
|
-
},
|
|
1132
|
-
signal => this.prover.getCheckpointPaddingRollupProof(inputs, signal, provingState.epochNumber),
|
|
1133
|
-
),
|
|
1134
|
-
result => {
|
|
1135
|
-
logger.debug('Completed proof for padding checkpoint.');
|
|
1136
|
-
provingState.setCheckpointPaddingProof(result);
|
|
1137
|
-
this.checkAndEnqueueRootRollup(provingState);
|
|
1138
|
-
},
|
|
1139
|
-
);
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
// Executes the root rollup circuit
|
|
1143
|
-
private enqueueRootRollup(provingState: EpochProvingState) {
|
|
1144
|
-
if (!provingState.verifyState()) {
|
|
1145
|
-
logger.debug('Not running root rollup, state no longer valid');
|
|
1146
|
-
return;
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
logger.debug(`Preparing root rollup`);
|
|
1150
|
-
|
|
1151
|
-
const inputs = provingState.getRootRollupInputs();
|
|
1152
|
-
|
|
1153
|
-
this.deferredProving(
|
|
1154
|
-
provingState,
|
|
1155
|
-
wrapCallbackInSpan(
|
|
1156
|
-
this.tracer,
|
|
1157
|
-
'ProvingOrchestrator.prover.getRootRollupProof',
|
|
1158
|
-
{
|
|
1159
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'rollup-root' satisfies CircuitName,
|
|
1160
|
-
},
|
|
1161
|
-
signal => this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
1162
|
-
),
|
|
1163
|
-
result => {
|
|
1164
|
-
logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1165
|
-
provingState.setRootRollupProof(result);
|
|
1166
|
-
provingState.resolve({ status: 'success' });
|
|
1167
|
-
},
|
|
1168
|
-
);
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
1021
|
private checkAndEnqueueNextMergeRollup(provingState: BlockProvingState, currentLocation: TreeNodeLocation) {
|
|
1172
1022
|
if (!provingState.isReadyForMergeRollup(currentLocation)) {
|
|
1173
1023
|
return;
|
|
@@ -1183,54 +1033,35 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1183
1033
|
|
|
1184
1034
|
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
1185
1035
|
if (!provingState.isReadyForBlockRootRollup()) {
|
|
1186
|
-
logger.debug('Not ready for block root rollup');
|
|
1036
|
+
this.logger.debug('Not ready for block root rollup');
|
|
1187
1037
|
return;
|
|
1188
1038
|
}
|
|
1189
1039
|
|
|
1190
1040
|
this.enqueueBlockRootRollup(provingState);
|
|
1191
1041
|
}
|
|
1192
1042
|
|
|
1193
|
-
private checkAndEnqueueNextBlockMergeRollup(
|
|
1043
|
+
private async checkAndEnqueueNextBlockMergeRollup(
|
|
1044
|
+
provingState: CheckpointProvingState,
|
|
1045
|
+
currentLocation: TreeNodeLocation,
|
|
1046
|
+
) {
|
|
1194
1047
|
if (!provingState.isReadyForBlockMerge(currentLocation)) {
|
|
1195
1048
|
return;
|
|
1196
1049
|
}
|
|
1197
1050
|
|
|
1198
1051
|
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
1199
1052
|
if (parentLocation.level === 0) {
|
|
1200
|
-
this.checkAndEnqueueCheckpointRootRollup(provingState);
|
|
1053
|
+
await this.checkAndEnqueueCheckpointRootRollup(provingState);
|
|
1201
1054
|
} else {
|
|
1202
1055
|
this.enqueueBlockMergeRollup(provingState, parentLocation);
|
|
1203
1056
|
}
|
|
1204
1057
|
}
|
|
1205
1058
|
|
|
1206
|
-
|
|
1059
|
+
protected async checkAndEnqueueCheckpointRootRollup(provingState: CheckpointProvingState) {
|
|
1207
1060
|
if (!provingState.isReadyForCheckpointRoot()) {
|
|
1208
1061
|
return;
|
|
1209
1062
|
}
|
|
1210
1063
|
|
|
1211
|
-
this.enqueueCheckpointRootRollup(provingState);
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
private checkAndEnqueueNextCheckpointMergeRollup(provingState: EpochProvingState, currentLocation: TreeNodeLocation) {
|
|
1215
|
-
if (!provingState.isReadyForCheckpointMerge(currentLocation)) {
|
|
1216
|
-
return;
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
1220
|
-
if (parentLocation.level === 0) {
|
|
1221
|
-
this.checkAndEnqueueRootRollup(provingState);
|
|
1222
|
-
} else {
|
|
1223
|
-
this.enqueueCheckpointMergeRollup(provingState, parentLocation);
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
|
|
1227
|
-
private checkAndEnqueueRootRollup(provingState: EpochProvingState) {
|
|
1228
|
-
if (!provingState.isReadyForRootRollup()) {
|
|
1229
|
-
logger.debug('Not ready for root rollup');
|
|
1230
|
-
return;
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
this.enqueueRootRollup(provingState);
|
|
1064
|
+
await this.enqueueCheckpointRootRollup(provingState);
|
|
1234
1065
|
}
|
|
1235
1066
|
|
|
1236
1067
|
/**
|
|
@@ -1241,7 +1072,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1241
1072
|
*/
|
|
1242
1073
|
private enqueueVM(provingState: BlockProvingState, txIndex: number) {
|
|
1243
1074
|
if (!provingState.verifyState()) {
|
|
1244
|
-
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`);
|
|
1245
1076
|
return;
|
|
1246
1077
|
}
|
|
1247
1078
|
|
|
@@ -1260,20 +1091,20 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1260
1091
|
);
|
|
1261
1092
|
|
|
1262
1093
|
this.deferredProving(provingState, doAvmProving, proof => {
|
|
1263
|
-
logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1094
|
+
this.logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1264
1095
|
txProvingState.setAvmProof(proof);
|
|
1265
1096
|
this.checkAndEnqueueBaseRollup(provingState, txIndex);
|
|
1266
1097
|
});
|
|
1267
1098
|
}
|
|
1268
1099
|
|
|
1269
|
-
|
|
1100
|
+
protected checkAndEnqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
|
|
1270
1101
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
1271
1102
|
if (!txProvingState.ready()) {
|
|
1272
1103
|
return;
|
|
1273
1104
|
}
|
|
1274
1105
|
|
|
1275
1106
|
// We must have completed all proving (chonk verifier proof and (if required) vm proof are generated), we now move to the base rollup.
|
|
1276
|
-
logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
1107
|
+
this.logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
1277
1108
|
|
|
1278
1109
|
this.enqueueBaseRollup(provingState, txIndex);
|
|
1279
1110
|
}
|