@aztec/prover-client 0.69.0-devnet → 0.69.1-devnet
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/block_builder/light.d.ts +0 -1
- package/dest/block_builder/light.d.ts.map +1 -1
- package/dest/block_builder/light.js +4 -14
- package/dest/config.d.ts +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +3 -2
- package/dest/mocks/test_context.d.ts +2 -2
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +6 -6
- package/dest/orchestrator/block-building-helpers.d.ts +10 -25
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +33 -44
- package/dest/orchestrator/block-proving-state.d.ts +40 -44
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +149 -85
- package/dest/orchestrator/epoch-proving-state.d.ts +23 -30
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +92 -65
- package/dest/orchestrator/orchestrator.d.ts +16 -47
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +204 -341
- package/dest/orchestrator/tx-proving-state.d.ts +10 -6
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +57 -46
- package/dest/prover-agent/memory-proving-queue.d.ts +3 -3
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +4 -4
- package/dest/prover-agent/prover-agent.js +4 -4
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +5 -2
- package/dest/prover-client/server-epoch-prover.d.ts +25 -0
- package/dest/prover-client/server-epoch-prover.d.ts.map +1 -0
- package/dest/prover-client/server-epoch-prover.js +40 -0
- package/dest/proving_broker/broker_prover_facade.d.ts +15 -4
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +247 -44
- package/dest/proving_broker/config.d.ts +61 -0
- package/dest/proving_broker/config.d.ts.map +1 -0
- package/dest/proving_broker/config.js +83 -0
- package/dest/proving_broker/factory.d.ts +1 -1
- package/dest/proving_broker/factory.d.ts.map +1 -1
- package/dest/proving_broker/factory.js +2 -5
- package/dest/proving_broker/fixtures.d.ts +5 -0
- package/dest/proving_broker/fixtures.d.ts.map +1 -0
- package/dest/proving_broker/fixtures.js +12 -0
- package/dest/proving_broker/index.d.ts +1 -0
- package/dest/proving_broker/index.d.ts.map +1 -1
- package/dest/proving_broker/index.js +2 -1
- package/dest/proving_broker/proving_broker.d.ts +16 -12
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +306 -273
- package/dest/proving_broker/proving_broker_database/memory.d.ts +4 -2
- package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/memory.js +17 -4
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +10 -6
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.js +105 -13
- package/dest/proving_broker/proving_broker_database.d.ts +7 -3
- package/dest/proving_broker/proving_broker_database.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +4 -4
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +4 -4
- package/dest/test/mock_prover.d.ts +6 -6
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +6 -6
- package/package.json +11 -11
- package/src/block_builder/light.ts +3 -21
- package/src/config.ts +4 -4
- package/src/mocks/test_context.ts +3 -6
- package/src/orchestrator/block-building-helpers.ts +44 -118
- package/src/orchestrator/block-proving-state.ts +251 -121
- package/src/orchestrator/epoch-proving-state.ts +159 -88
- package/src/orchestrator/orchestrator.ts +251 -527
- package/src/orchestrator/tx-proving-state.ts +35 -19
- package/src/prover-agent/memory-proving-queue.ts +11 -12
- package/src/prover-agent/prover-agent.ts +4 -4
- package/src/prover-client/prover-client.ts +4 -6
- package/src/prover-client/server-epoch-prover.ts +44 -0
- package/src/proving_broker/broker_prover_facade.ts +321 -61
- package/src/proving_broker/config.ts +93 -0
- package/src/proving_broker/factory.ts +2 -5
- package/src/proving_broker/fixtures.ts +14 -0
- package/src/proving_broker/index.ts +1 -0
- package/src/proving_broker/proving_broker.ts +114 -71
- package/src/proving_broker/proving_broker_database/memory.ts +24 -4
- package/src/proving_broker/proving_broker_database/persisted.ts +141 -19
- package/src/proving_broker/proving_broker_database.ts +8 -3
- package/src/proving_broker/proving_job_controller.ts +5 -5
- package/src/proving_broker/rpc.ts +2 -3
- package/src/test/mock_prover.ts +9 -11
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
MerkleTreeId,
|
|
4
4
|
type ProcessedTx,
|
|
5
5
|
type ServerCircuitProver,
|
|
6
|
-
|
|
6
|
+
type Tx,
|
|
7
7
|
toNumBlobFields,
|
|
8
8
|
} from '@aztec/circuit-types';
|
|
9
9
|
import {
|
|
@@ -17,46 +17,38 @@ import {
|
|
|
17
17
|
AVM_PROOF_LENGTH_IN_FIELDS,
|
|
18
18
|
AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS,
|
|
19
19
|
type AppendOnlyTreeSnapshot,
|
|
20
|
-
BLOBS_PER_BLOCK,
|
|
21
20
|
BaseParityInputs,
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
BlockHeader,
|
|
22
|
+
ContentCommitment,
|
|
24
23
|
Fr,
|
|
25
|
-
|
|
24
|
+
GlobalVariables,
|
|
26
25
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
27
26
|
L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
|
|
28
|
-
type NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
29
27
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
30
28
|
NUM_BASE_PARITY_PER_ROOT_PARITY,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
type
|
|
34
|
-
RootParityInput,
|
|
35
|
-
RootParityInputs,
|
|
36
|
-
type VerificationKeyAsFields,
|
|
29
|
+
PartialStateReference,
|
|
30
|
+
StateReference,
|
|
31
|
+
type TUBE_PROOF_LENGTH,
|
|
37
32
|
VerificationKeyData,
|
|
38
33
|
makeEmptyRecursiveProof,
|
|
39
34
|
} from '@aztec/circuits.js';
|
|
40
|
-
import { BlobPublicInputs } from '@aztec/circuits.js/blobs';
|
|
41
35
|
import {
|
|
42
|
-
type BaseOrMergeRollupPublicInputs,
|
|
43
36
|
type BaseRollupHints,
|
|
44
|
-
type BlockRootOrBlockMergePublicInputs,
|
|
45
|
-
BlockRootRollupInputs,
|
|
46
37
|
EmptyBlockRootRollupInputs,
|
|
38
|
+
PrivateBaseRollupInputs,
|
|
39
|
+
SingleTxBlockRootRollupInputs,
|
|
40
|
+
TubeInputs,
|
|
47
41
|
} from '@aztec/circuits.js/rollup';
|
|
48
42
|
import { makeTuple } from '@aztec/foundation/array';
|
|
49
|
-
import {
|
|
50
|
-
import { maxBy, padArrayEnd } from '@aztec/foundation/collection';
|
|
51
|
-
import { sha256ToField } from '@aztec/foundation/crypto';
|
|
43
|
+
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
52
44
|
import { AbortError } from '@aztec/foundation/error';
|
|
53
45
|
import { createLogger } from '@aztec/foundation/log';
|
|
54
46
|
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
55
47
|
import { type Tuple } from '@aztec/foundation/serialize';
|
|
56
48
|
import { pushTestData } from '@aztec/foundation/testing';
|
|
57
49
|
import { elapsed } from '@aztec/foundation/timer';
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
50
|
+
import { type TreeNodeLocation } from '@aztec/foundation/trees';
|
|
51
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks';
|
|
60
52
|
import { Attributes, type TelemetryClient, type Tracer, trackSpan, wrapCallbackInSpan } from '@aztec/telemetry-client';
|
|
61
53
|
|
|
62
54
|
import { inspect } from 'util';
|
|
@@ -64,24 +56,14 @@ import { inspect } from 'util';
|
|
|
64
56
|
import {
|
|
65
57
|
buildBaseRollupHints,
|
|
66
58
|
buildHeaderAndBodyFromTxs,
|
|
67
|
-
buildHeaderFromCircuitOutputs,
|
|
68
|
-
createBlockMergeRollupInputs,
|
|
69
|
-
createMergeRollupInputs,
|
|
70
|
-
getPreviousRollupDataFromPublicInputs,
|
|
71
|
-
getRootRollupInput,
|
|
72
59
|
getRootTreeSiblingPath,
|
|
73
60
|
getSubtreeSiblingPath,
|
|
74
61
|
getTreeSnapshot,
|
|
75
62
|
validatePartialState,
|
|
76
63
|
validateTx,
|
|
77
64
|
} from './block-building-helpers.js';
|
|
78
|
-
import { type BlockProvingState
|
|
79
|
-
import {
|
|
80
|
-
type BlockMergeRollupInputData,
|
|
81
|
-
EpochProvingState,
|
|
82
|
-
type ProvingResult,
|
|
83
|
-
type TreeSnapshots,
|
|
84
|
-
} from './epoch-proving-state.js';
|
|
65
|
+
import { type BlockProvingState } from './block-proving-state.js';
|
|
66
|
+
import { EpochProvingState, type ProvingResult, type TreeSnapshots } from './epoch-proving-state.js';
|
|
85
67
|
import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
|
|
86
68
|
import { TxProvingState } from './tx-proving-state.js';
|
|
87
69
|
|
|
@@ -104,7 +86,6 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
104
86
|
export class ProvingOrchestrator implements EpochProver {
|
|
105
87
|
private provingState: EpochProvingState | undefined = undefined;
|
|
106
88
|
private pendingProvingJobs: AbortController[] = [];
|
|
107
|
-
private paddingTxProof?: ProofAndVerificationKey<typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>;
|
|
108
89
|
|
|
109
90
|
private provingPromise: Promise<ProvingResult> | undefined = undefined;
|
|
110
91
|
private metrics: ProvingOrchestratorMetrics;
|
|
@@ -127,11 +108,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
127
108
|
return this.proverId;
|
|
128
109
|
}
|
|
129
110
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
public reset() {
|
|
134
|
-
this.paddingTxProof = undefined;
|
|
111
|
+
public stop(): Promise<void> {
|
|
112
|
+
this.cancel();
|
|
113
|
+
return Promise.resolve();
|
|
135
114
|
}
|
|
136
115
|
|
|
137
116
|
public startNewEpoch(epochNumber: number, firstBlockNumber: number, totalNumBlocks: number) {
|
|
@@ -210,6 +189,22 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
210
189
|
BigInt(startArchiveSnapshot.nextAvailableLeafIndex - 1),
|
|
211
190
|
);
|
|
212
191
|
|
|
192
|
+
const partial = new PartialStateReference(
|
|
193
|
+
await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
|
|
194
|
+
await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
|
|
195
|
+
await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
|
|
196
|
+
);
|
|
197
|
+
const state = new StateReference(messageTreeSnapshot, partial);
|
|
198
|
+
// TODO: Construct the full previousBlockHeader.
|
|
199
|
+
const previousBlockHeader = BlockHeader.from({
|
|
200
|
+
lastArchive: startArchiveSnapshot,
|
|
201
|
+
contentCommitment: ContentCommitment.empty(),
|
|
202
|
+
state,
|
|
203
|
+
globalVariables: GlobalVariables.empty(),
|
|
204
|
+
totalFees: Fr.ZERO,
|
|
205
|
+
totalManaUsed: Fr.ZERO,
|
|
206
|
+
});
|
|
207
|
+
|
|
213
208
|
const blockProvingState = this.provingState!.startNewBlock(
|
|
214
209
|
globalVariables,
|
|
215
210
|
l1ToL2MessagesPadded,
|
|
@@ -218,6 +213,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
218
213
|
messageTreeSnapshotAfterInsertion,
|
|
219
214
|
startArchiveSnapshot,
|
|
220
215
|
newArchiveSiblingPath,
|
|
216
|
+
previousBlockHeader,
|
|
221
217
|
previousBlockHash!,
|
|
222
218
|
);
|
|
223
219
|
|
|
@@ -228,7 +224,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
228
224
|
}
|
|
229
225
|
|
|
230
226
|
/**
|
|
231
|
-
* The interface to add simulated transactions to the scheduler
|
|
227
|
+
* The interface to add simulated transactions to the scheduler. This can only be called once per block.
|
|
232
228
|
* @param txs - The transactions to be proven
|
|
233
229
|
*/
|
|
234
230
|
@trackSpan('ProvingOrchestrator.addTxs', txs => ({
|
|
@@ -247,11 +243,15 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
247
243
|
throw new Error(`Block proving state for ${blockNumber} not found`);
|
|
248
244
|
}
|
|
249
245
|
|
|
246
|
+
if (provingState.totalNumTxs) {
|
|
247
|
+
throw new Error(`Block ${blockNumber} has been initialized with transactions.`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
250
|
const numBlobFields = toNumBlobFields(txs);
|
|
251
|
-
provingState.startNewBlock(
|
|
251
|
+
provingState.startNewBlock(txs.length, numBlobFields);
|
|
252
252
|
|
|
253
253
|
logger.info(
|
|
254
|
-
`Adding ${txs.length} transactions with ${numBlobFields} blob fields to block ${provingState
|
|
254
|
+
`Adding ${txs.length} transactions with ${numBlobFields} blob fields to block ${provingState.blockNumber}`,
|
|
255
255
|
);
|
|
256
256
|
for (const tx of txs) {
|
|
257
257
|
try {
|
|
@@ -269,20 +269,42 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
const [hints, treeSnapshots] = await this.prepareTransaction(tx, provingState);
|
|
272
|
-
|
|
272
|
+
const txProvingState = new TxProvingState(tx, hints, treeSnapshots);
|
|
273
|
+
const txIndex = provingState.addNewTx(txProvingState);
|
|
274
|
+
this.getOrEnqueueTube(provingState, txIndex);
|
|
275
|
+
if (txProvingState.requireAvmProof) {
|
|
276
|
+
logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
277
|
+
this.enqueueVM(provingState, txIndex);
|
|
278
|
+
}
|
|
273
279
|
} catch (err: any) {
|
|
274
280
|
throw new Error(`Error adding transaction ${tx.hash.toString()} to block ${blockNumber}: ${err.message}`, {
|
|
275
281
|
cause: err,
|
|
276
282
|
});
|
|
277
283
|
}
|
|
278
284
|
}
|
|
279
|
-
|
|
280
|
-
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Kickstarts tube circuits for the specified txs. These will be used during epoch proving.
|
|
289
|
+
* Note that if the tube circuits are not started this way, they will be started nontheless after processing.
|
|
290
|
+
*/
|
|
291
|
+
@trackSpan('ProvingOrchestrator.startTubeCircuits')
|
|
292
|
+
public startTubeCircuits(txs: Tx[]) {
|
|
293
|
+
if (!this.provingState?.verifyState()) {
|
|
294
|
+
throw new Error(`Invalid proving state, call startNewEpoch before starting tube circuits`);
|
|
295
|
+
}
|
|
296
|
+
for (const tx of txs) {
|
|
297
|
+
const txHash = tx.getTxHash().toString();
|
|
298
|
+
const tubeInputs = new TubeInputs(tx.clientIvcProof);
|
|
299
|
+
const tubeProof = promiseWithResolvers<ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>>();
|
|
300
|
+
logger.debug(`Starting tube circuit for tx ${txHash}`);
|
|
301
|
+
this.doEnqueueTube(txHash, tubeInputs, proof => tubeProof.resolve(proof));
|
|
302
|
+
this.provingState?.cachedTubeProofs.set(txHash, tubeProof.promise);
|
|
281
303
|
}
|
|
282
304
|
}
|
|
283
305
|
|
|
284
306
|
/**
|
|
285
|
-
* Marks the block as
|
|
307
|
+
* Marks the block as completed.
|
|
286
308
|
* Computes the block header and updates the archive tree.
|
|
287
309
|
*/
|
|
288
310
|
@trackSpan('ProvingOrchestrator.setBlockCompleted', (blockNumber: number) => ({
|
|
@@ -296,50 +318,14 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
296
318
|
|
|
297
319
|
if (!provingState.spongeBlobState) {
|
|
298
320
|
// If we are completing an empty block, initialise the provingState.
|
|
299
|
-
// We will have
|
|
300
|
-
provingState.startNewBlock(
|
|
321
|
+
// We will have 0 txs and no blob fields.
|
|
322
|
+
provingState.startNewBlock(0, 0);
|
|
301
323
|
}
|
|
302
324
|
|
|
303
325
|
if (!provingState.verifyState()) {
|
|
304
326
|
throw new Error(`Block proving failed: ${provingState.error}`);
|
|
305
327
|
}
|
|
306
328
|
|
|
307
|
-
// We may need to pad the rollup with empty transactions
|
|
308
|
-
const paddingTxCount = provingState.totalNumTxs - provingState.transactionsReceived;
|
|
309
|
-
if (paddingTxCount > 0 && provingState.totalNumTxs > 2) {
|
|
310
|
-
throw new Error(`Block not ready for completion: expecting ${paddingTxCount} more transactions.`);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (paddingTxCount > 0) {
|
|
314
|
-
logger.debug(`Padding rollup with ${paddingTxCount} empty transactions`);
|
|
315
|
-
// Make an empty padding transaction
|
|
316
|
-
// Required for:
|
|
317
|
-
// 0 (when we want an empty block, largely for testing), or
|
|
318
|
-
// 1 (we need to pad with one tx as all rollup circuits require a pair of inputs) txs
|
|
319
|
-
// Insert it into the tree the required number of times to get all of the
|
|
320
|
-
// base rollup inputs
|
|
321
|
-
// Then enqueue the proving of all the transactions
|
|
322
|
-
const unprovenPaddingTx = makeEmptyProcessedTx(
|
|
323
|
-
this.dbs.get(blockNumber)!.getInitialHeader(),
|
|
324
|
-
provingState.globalVariables.chainId,
|
|
325
|
-
provingState.globalVariables.version,
|
|
326
|
-
getVKTreeRoot(),
|
|
327
|
-
protocolContractTreeRoot,
|
|
328
|
-
);
|
|
329
|
-
const txInputs: Array<{ hints: BaseRollupHints; snapshot: TreeSnapshots }> = [];
|
|
330
|
-
for (let i = 0; i < paddingTxCount; i++) {
|
|
331
|
-
const [hints, snapshot] = await this.prepareTransaction(unprovenPaddingTx, provingState);
|
|
332
|
-
const txInput = {
|
|
333
|
-
hints,
|
|
334
|
-
snapshot,
|
|
335
|
-
};
|
|
336
|
-
txInputs.push(txInput);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Now enqueue the proving
|
|
340
|
-
this.enqueuePaddingTxs(provingState, txInputs, unprovenPaddingTx);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
329
|
// And build the block header
|
|
344
330
|
logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
345
331
|
await this.buildBlock(provingState, expectedHeader);
|
|
@@ -358,73 +344,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
358
344
|
return block;
|
|
359
345
|
}
|
|
360
346
|
|
|
361
|
-
@trackSpan('ProvingOrchestrator.padEpoch', function () {
|
|
362
|
-
if (!this.provingState) {
|
|
363
|
-
return {};
|
|
364
|
-
}
|
|
365
|
-
return {
|
|
366
|
-
[Attributes.EPOCH_NUMBER]: this.provingState.epochNumber,
|
|
367
|
-
[Attributes.EPOCH_SIZE]: this.provingState.totalNumBlocks,
|
|
368
|
-
};
|
|
369
|
-
})
|
|
370
|
-
private padEpoch(): Promise<void> {
|
|
371
|
-
const provingState = this.provingState!;
|
|
372
|
-
const lastBlock = maxBy(
|
|
373
|
-
provingState.blocks.filter(b => !!b),
|
|
374
|
-
b => b!.blockNumber,
|
|
375
|
-
)?.block;
|
|
376
|
-
if (!lastBlock) {
|
|
377
|
-
return Promise.reject(new Error(`Epoch needs at least one completed block in order to be padded`));
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
const paddingBlockCount = Math.max(2, provingState.totalNumBlocks) - provingState.blocks.length;
|
|
381
|
-
if (paddingBlockCount === 0) {
|
|
382
|
-
return Promise.resolve();
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
logger.debug(`Padding epoch proof with ${paddingBlockCount} empty block proofs`);
|
|
386
|
-
|
|
387
|
-
const inputs = EmptyBlockRootRollupInputs.from({
|
|
388
|
-
archive: lastBlock.archive,
|
|
389
|
-
blockHash: lastBlock.header.hash(),
|
|
390
|
-
globalVariables: lastBlock.header.globalVariables,
|
|
391
|
-
vkTreeRoot: getVKTreeRoot(),
|
|
392
|
-
protocolContractTreeRoot,
|
|
393
|
-
proverId: this.proverId,
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
logger.debug(`Enqueuing deferred proving for padding block to enqueue ${paddingBlockCount} paddings`);
|
|
397
|
-
this.deferredProving(
|
|
398
|
-
provingState,
|
|
399
|
-
wrapCallbackInSpan(
|
|
400
|
-
this.tracer,
|
|
401
|
-
'ProvingOrchestrator.prover.getEmptyBlockRootRollupProof',
|
|
402
|
-
{
|
|
403
|
-
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
404
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'empty-block-root-rollup' satisfies CircuitName,
|
|
405
|
-
},
|
|
406
|
-
signal => this.prover.getEmptyBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
407
|
-
),
|
|
408
|
-
result => {
|
|
409
|
-
logger.debug(`Completed proof for padding block`);
|
|
410
|
-
const currentLevel = provingState.numMergeLevels + 1n;
|
|
411
|
-
for (let i = 0; i < paddingBlockCount; i++) {
|
|
412
|
-
logger.debug(`Enqueuing padding block with index ${provingState.blocks.length + i}`);
|
|
413
|
-
const index = BigInt(provingState.blocks.length + i);
|
|
414
|
-
this.storeAndExecuteNextBlockMergeLevel(provingState, currentLevel, index, [
|
|
415
|
-
result.inputs,
|
|
416
|
-
result.proof,
|
|
417
|
-
result.verificationKey.keyAsFields,
|
|
418
|
-
]);
|
|
419
|
-
}
|
|
420
|
-
},
|
|
421
|
-
);
|
|
422
|
-
return Promise.resolve();
|
|
423
|
-
}
|
|
424
|
-
|
|
425
347
|
private async buildBlock(provingState: BlockProvingState, expectedHeader?: BlockHeader) {
|
|
426
348
|
// Collect all new nullifiers, commitments, and contracts from all txs in this block to build body
|
|
427
|
-
const txs = provingState
|
|
349
|
+
const txs = provingState.allTxs.map(a => a.processedTx);
|
|
428
350
|
|
|
429
351
|
// Get db for this block
|
|
430
352
|
const db = this.dbs.get(provingState.blockNumber)!;
|
|
@@ -468,77 +390,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
468
390
|
}
|
|
469
391
|
}
|
|
470
392
|
|
|
471
|
-
// Enqueues the proving of the required padding transactions
|
|
472
|
-
// If the fully proven padding transaction is not available, this will first be proven
|
|
473
|
-
private enqueuePaddingTxs(
|
|
474
|
-
provingState: BlockProvingState,
|
|
475
|
-
txInputs: Array<{ hints: BaseRollupHints; snapshot: TreeSnapshots }>,
|
|
476
|
-
paddingTx: ProcessedTx,
|
|
477
|
-
) {
|
|
478
|
-
if (this.paddingTxProof) {
|
|
479
|
-
// We already have the padding transaction
|
|
480
|
-
logger.debug(`Enqueuing ${txInputs.length} padding transactions using existing padding tx`);
|
|
481
|
-
this.provePaddingTransactions(txInputs, paddingTx, this.paddingTxProof, provingState);
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
logger.debug(`Enqueuing deferred proving for padding txs to enqueue ${txInputs.length} paddings`);
|
|
485
|
-
this.deferredProving(
|
|
486
|
-
provingState,
|
|
487
|
-
wrapCallbackInSpan(
|
|
488
|
-
this.tracer,
|
|
489
|
-
'ProvingOrchestrator.prover.getEmptyPrivateKernelProof',
|
|
490
|
-
{
|
|
491
|
-
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
492
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'private-kernel-empty' satisfies CircuitName,
|
|
493
|
-
},
|
|
494
|
-
signal =>
|
|
495
|
-
this.prover.getEmptyPrivateKernelProof(
|
|
496
|
-
new PrivateKernelEmptyInputData(
|
|
497
|
-
paddingTx.constants.historicalHeader,
|
|
498
|
-
// Chain id and version should not change even if the proving state does, so it's safe to use them for the padding tx
|
|
499
|
-
// which gets cached across multiple runs of the orchestrator with different proving states. If they were to change,
|
|
500
|
-
// we'd have to clear out the paddingTx here and regenerate it when they do.
|
|
501
|
-
paddingTx.constants.txContext.chainId,
|
|
502
|
-
paddingTx.constants.txContext.version,
|
|
503
|
-
paddingTx.constants.vkTreeRoot,
|
|
504
|
-
paddingTx.constants.protocolContractTreeRoot,
|
|
505
|
-
),
|
|
506
|
-
signal,
|
|
507
|
-
provingState.epochNumber,
|
|
508
|
-
),
|
|
509
|
-
),
|
|
510
|
-
result => {
|
|
511
|
-
logger.debug(`Completed proof for padding tx, now enqueuing ${txInputs.length} padding txs`);
|
|
512
|
-
this.paddingTxProof = { proof: result.proof, verificationKey: result.verificationKey };
|
|
513
|
-
this.provePaddingTransactions(txInputs, paddingTx, this.paddingTxProof, provingState);
|
|
514
|
-
},
|
|
515
|
-
);
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Prepares the cached sets of base rollup inputs for padding transactions and proves them
|
|
520
|
-
* @param txInputs - The base rollup inputs, start and end hash paths etc
|
|
521
|
-
* @param paddingTx - The padding tx, contains the header and public inputs used in the proof
|
|
522
|
-
* @param proofAndVk - The proof and vk of the paddingTx.
|
|
523
|
-
* @param provingState - The block proving state
|
|
524
|
-
*/
|
|
525
|
-
private provePaddingTransactions(
|
|
526
|
-
txInputs: Array<{ hints: BaseRollupHints; snapshot: TreeSnapshots }>,
|
|
527
|
-
paddingTx: ProcessedTx,
|
|
528
|
-
proofAndVk: ProofAndVerificationKey<typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>,
|
|
529
|
-
provingState: BlockProvingState,
|
|
530
|
-
) {
|
|
531
|
-
// The padding tx contains the proof and vk, generated separately from the base inputs
|
|
532
|
-
// Copy these into the base rollup inputs and enqueue the base rollup proof
|
|
533
|
-
for (let i = 0; i < txInputs.length; i++) {
|
|
534
|
-
const { hints, snapshot } = txInputs[i];
|
|
535
|
-
const txProvingState = new TxProvingState(paddingTx, hints, snapshot);
|
|
536
|
-
txProvingState.assignTubeProof(proofAndVk);
|
|
537
|
-
const txIndex = provingState.addNewTx(txProvingState);
|
|
538
|
-
this.enqueueBaseRollup(provingState, txIndex);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
393
|
/**
|
|
543
394
|
* Cancel any further proving
|
|
544
395
|
*/
|
|
@@ -550,45 +401,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
550
401
|
this.provingState?.cancel();
|
|
551
402
|
}
|
|
552
403
|
|
|
553
|
-
/**
|
|
554
|
-
* Extract the block header from public inputs.
|
|
555
|
-
* @returns The header of this proving state's block.
|
|
556
|
-
*/
|
|
557
|
-
private extractBlockHeaderFromPublicInputs(
|
|
558
|
-
provingState: BlockProvingState,
|
|
559
|
-
rootRollupOutputs: BlockRootOrBlockMergePublicInputs,
|
|
560
|
-
) {
|
|
561
|
-
const previousMergeData = provingState.getMergeInputs(0).inputs;
|
|
562
|
-
|
|
563
|
-
if (!previousMergeData[0] || !previousMergeData[1]) {
|
|
564
|
-
throw new Error(`Invalid proving state, final merge inputs before block root circuit missing.`);
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
return buildHeaderFromCircuitOutputs(
|
|
568
|
-
[previousMergeData[0], previousMergeData[1]],
|
|
569
|
-
provingState.finalRootParityInput!.publicInputs,
|
|
570
|
-
rootRollupOutputs,
|
|
571
|
-
provingState.messageTreeSnapshotAfterInsertion,
|
|
572
|
-
logger,
|
|
573
|
-
);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* Collect all new nullifiers, commitments, and contracts from all txs in a block
|
|
578
|
-
* @returns The array of non empty tx effects.
|
|
579
|
-
*/
|
|
580
|
-
private extractTxEffects(provingState: BlockProvingState) {
|
|
581
|
-
// Note: this check should ensure that we have all txs and their effects ready.
|
|
582
|
-
if (!provingState.finalRootParityInput?.publicInputs.shaRoot) {
|
|
583
|
-
throw new Error(`Invalid proving state, a block must be ready to be proven before its effects can be extracted.`);
|
|
584
|
-
}
|
|
585
|
-
const nonEmptyTxEffects = provingState.allTxs
|
|
586
|
-
.map(txProvingState => txProvingState.processedTx.txEffect)
|
|
587
|
-
.filter(txEffect => !txEffect.isEmpty());
|
|
588
|
-
|
|
589
|
-
return nonEmptyTxEffects;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
404
|
/**
|
|
593
405
|
* Returns the proof for the current epoch.
|
|
594
406
|
*/
|
|
@@ -597,23 +409,19 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
597
409
|
throw new Error(`Invalid proving state, an epoch must be proven before it can be finalised`);
|
|
598
410
|
}
|
|
599
411
|
|
|
600
|
-
await this.padEpoch();
|
|
601
|
-
|
|
602
412
|
const result = await this.provingPromise!;
|
|
603
413
|
if (result.status === 'failure') {
|
|
604
414
|
throw new Error(`Epoch proving failed: ${result.reason}`);
|
|
605
415
|
}
|
|
606
416
|
|
|
607
|
-
|
|
608
|
-
throw new Error(`Invalid proving state, missing root rollup public inputs or final proof`);
|
|
609
|
-
}
|
|
417
|
+
const epochProofResult = this.provingState.getEpochProofResult();
|
|
610
418
|
|
|
611
419
|
pushTestData('epochProofResult', {
|
|
612
|
-
proof:
|
|
613
|
-
publicInputs:
|
|
420
|
+
proof: epochProofResult.proof.toString(),
|
|
421
|
+
publicInputs: epochProofResult.publicInputs.toString(),
|
|
614
422
|
});
|
|
615
423
|
|
|
616
|
-
return
|
|
424
|
+
return epochProofResult;
|
|
617
425
|
}
|
|
618
426
|
|
|
619
427
|
/**
|
|
@@ -630,21 +438,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
630
438
|
return txInputs;
|
|
631
439
|
}
|
|
632
440
|
|
|
633
|
-
private enqueueFirstProofs(
|
|
634
|
-
hints: BaseRollupHints,
|
|
635
|
-
treeSnapshots: TreeSnapshots,
|
|
636
|
-
tx: ProcessedTx,
|
|
637
|
-
provingState: BlockProvingState,
|
|
638
|
-
) {
|
|
639
|
-
const txProvingState = new TxProvingState(tx, hints, treeSnapshots);
|
|
640
|
-
const txIndex = provingState.addNewTx(txProvingState);
|
|
641
|
-
this.enqueueTube(provingState, txIndex);
|
|
642
|
-
if (txProvingState.requireAvmProof) {
|
|
643
|
-
logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
644
|
-
this.enqueueVM(provingState, txIndex);
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
|
|
648
441
|
/**
|
|
649
442
|
* Enqueue a job to be scheduled
|
|
650
443
|
* @param provingState - The proving state object being operated on
|
|
@@ -712,10 +505,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
712
505
|
[Attributes.TX_HASH]: tx.hash.toString(),
|
|
713
506
|
}))
|
|
714
507
|
private async prepareBaseRollupInputs(
|
|
715
|
-
provingState: BlockProvingState
|
|
508
|
+
provingState: BlockProvingState,
|
|
716
509
|
tx: ProcessedTx,
|
|
717
510
|
): Promise<[BaseRollupHints, TreeSnapshots] | undefined> {
|
|
718
|
-
if (!provingState
|
|
511
|
+
if (!provingState.verifyState() || !provingState.spongeBlobState) {
|
|
719
512
|
logger.debug('Not preparing base rollup inputs, state invalid');
|
|
720
513
|
return;
|
|
721
514
|
}
|
|
@@ -739,7 +532,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
739
532
|
);
|
|
740
533
|
const treeSnapshots: TreeSnapshots = new Map((await Promise.all(promises)).map(obj => [obj.key, obj.value]));
|
|
741
534
|
|
|
742
|
-
if (!provingState
|
|
535
|
+
if (!provingState.verifyState()) {
|
|
743
536
|
logger.debug(`Discarding proving job, state no longer valid`);
|
|
744
537
|
return;
|
|
745
538
|
}
|
|
@@ -748,15 +541,15 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
748
541
|
|
|
749
542
|
// Executes the base rollup circuit and stored the output as intermediate state for the parent merge/root circuit
|
|
750
543
|
// Executes the next level of merge if all inputs are available
|
|
751
|
-
private enqueueBaseRollup(provingState: BlockProvingState
|
|
752
|
-
if (!provingState
|
|
544
|
+
private enqueueBaseRollup(provingState: BlockProvingState, txIndex: number) {
|
|
545
|
+
if (!provingState.verifyState()) {
|
|
753
546
|
logger.debug('Not running base rollup, state invalid');
|
|
754
547
|
return;
|
|
755
548
|
}
|
|
756
549
|
|
|
757
550
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
758
551
|
const { processedTx } = txProvingState;
|
|
759
|
-
const rollupType = txProvingState.
|
|
552
|
+
const { rollupType, inputs } = txProvingState.getBaseRollupTypeAndInputs();
|
|
760
553
|
|
|
761
554
|
logger.debug(
|
|
762
555
|
`Enqueuing deferred proving base rollup${
|
|
@@ -769,19 +562,17 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
769
562
|
wrapCallbackInSpan(
|
|
770
563
|
this.tracer,
|
|
771
564
|
`ProvingOrchestrator.prover.${
|
|
772
|
-
|
|
565
|
+
inputs instanceof PrivateBaseRollupInputs ? 'getPrivateBaseRollupProof' : 'getPublicBaseRollupProof'
|
|
773
566
|
}`,
|
|
774
567
|
{
|
|
775
568
|
[Attributes.TX_HASH]: processedTx.hash.toString(),
|
|
776
569
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
777
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType
|
|
570
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType,
|
|
778
571
|
},
|
|
779
572
|
signal => {
|
|
780
|
-
if (
|
|
781
|
-
const inputs = txProvingState.getPrivateBaseInputs();
|
|
573
|
+
if (inputs instanceof PrivateBaseRollupInputs) {
|
|
782
574
|
return this.prover.getPrivateBaseRollupProof(inputs, signal, provingState.epochNumber);
|
|
783
575
|
} else {
|
|
784
|
-
const inputs = txProvingState.getPublicBaseInputs();
|
|
785
576
|
return this.prover.getPublicBaseRollupProof(inputs, signal, provingState.epochNumber);
|
|
786
577
|
}
|
|
787
578
|
},
|
|
@@ -789,26 +580,54 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
789
580
|
result => {
|
|
790
581
|
logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
791
582
|
validatePartialState(result.inputs.end, txProvingState.treeSnapshots);
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
583
|
+
const leafLocation = provingState.setBaseRollupProof(txIndex, result);
|
|
584
|
+
if (provingState.totalNumTxs === 1) {
|
|
585
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
586
|
+
} else {
|
|
587
|
+
this.checkAndEnqueueNextMergeRollup(provingState, leafLocation);
|
|
588
|
+
}
|
|
798
589
|
},
|
|
799
590
|
);
|
|
800
591
|
}
|
|
801
592
|
|
|
802
|
-
// Enqueues the tube circuit for a given transaction index
|
|
593
|
+
// Enqueues the tube circuit for a given transaction index, or reuses the one already enqueued
|
|
803
594
|
// Once completed, will enqueue the next circuit, either a public kernel or the base rollup
|
|
804
|
-
private
|
|
805
|
-
if (!provingState
|
|
595
|
+
private getOrEnqueueTube(provingState: BlockProvingState, txIndex: number) {
|
|
596
|
+
if (!provingState.verifyState()) {
|
|
806
597
|
logger.debug('Not running tube circuit, state invalid');
|
|
807
598
|
return;
|
|
808
599
|
}
|
|
809
600
|
|
|
810
601
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
602
|
+
const txHash = txProvingState.processedTx.hash.toString();
|
|
603
|
+
|
|
604
|
+
const handleResult = (result: ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>) => {
|
|
605
|
+
logger.debug(`Got tube proof for tx index: ${txIndex}`, { txHash });
|
|
606
|
+
txProvingState.setTubeProof(result);
|
|
607
|
+
this.provingState?.cachedTubeProofs.delete(txHash);
|
|
608
|
+
this.checkAndEnqueueNextTxCircuit(provingState, txIndex);
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
if (this.provingState?.cachedTubeProofs.has(txHash)) {
|
|
612
|
+
logger.debug(`Tube proof already enqueued for tx index: ${txIndex}`, { txHash });
|
|
613
|
+
void this.provingState!.cachedTubeProofs.get(txHash)!.then(handleResult);
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
|
|
811
617
|
logger.debug(`Enqueuing tube circuit for tx index: ${txIndex}`);
|
|
618
|
+
this.doEnqueueTube(txHash, txProvingState.getTubeInputs(), handleResult);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
private doEnqueueTube(
|
|
622
|
+
txHash: string,
|
|
623
|
+
inputs: TubeInputs,
|
|
624
|
+
handler: (result: ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>) => void,
|
|
625
|
+
provingState: EpochProvingState | BlockProvingState = this.provingState!,
|
|
626
|
+
) {
|
|
627
|
+
if (!provingState?.verifyState()) {
|
|
628
|
+
logger.debug('Not running tube circuit, state invalid');
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
812
631
|
|
|
813
632
|
this.deferredProving(
|
|
814
633
|
provingState,
|
|
@@ -816,35 +635,25 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
816
635
|
this.tracer,
|
|
817
636
|
'ProvingOrchestrator.prover.getTubeProof',
|
|
818
637
|
{
|
|
819
|
-
[Attributes.TX_HASH]:
|
|
638
|
+
[Attributes.TX_HASH]: txHash,
|
|
820
639
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
821
640
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'tube-circuit' satisfies CircuitName,
|
|
822
641
|
},
|
|
823
|
-
signal =>
|
|
824
|
-
const inputs = txProvingState.getTubeInputs();
|
|
825
|
-
return this.prover.getTubeProof(inputs, signal, provingState.epochNumber);
|
|
826
|
-
},
|
|
642
|
+
signal => this.prover.getTubeProof(inputs, signal, this.provingState!.epochNumber),
|
|
827
643
|
),
|
|
828
|
-
|
|
829
|
-
logger.debug(`Completed tube proof for tx index: ${txIndex}`);
|
|
830
|
-
txProvingState.assignTubeProof(result);
|
|
831
|
-
this.checkAndEnqueueNextTxCircuit(provingState, txIndex);
|
|
832
|
-
},
|
|
644
|
+
handler,
|
|
833
645
|
);
|
|
834
646
|
}
|
|
835
647
|
|
|
836
648
|
// Executes the merge rollup circuit and stored the output as intermediate state for the parent merge/block root circuit
|
|
837
649
|
// Enqueues the next level of merge if all inputs are available
|
|
838
|
-
private enqueueMergeRollup(
|
|
839
|
-
provingState
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
const inputs =
|
|
845
|
-
[mergeInputData.inputs[0]!, mergeInputData.proofs[0]!, mergeInputData.verificationKeys[0]!],
|
|
846
|
-
[mergeInputData.inputs[1]!, mergeInputData.proofs[1]!, mergeInputData.verificationKeys[1]!],
|
|
847
|
-
);
|
|
650
|
+
private enqueueMergeRollup(provingState: BlockProvingState, location: TreeNodeLocation) {
|
|
651
|
+
if (!provingState.verifyState()) {
|
|
652
|
+
logger.debug('Not running merge rollup. State no longer valid.');
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
const inputs = provingState.getMergeRollupInputs(location);
|
|
848
657
|
|
|
849
658
|
this.deferredProving(
|
|
850
659
|
provingState,
|
|
@@ -858,66 +667,27 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
858
667
|
signal => this.prover.getMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
859
668
|
),
|
|
860
669
|
result => {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
result.proof,
|
|
864
|
-
result.verificationKey.keyAsFields,
|
|
865
|
-
]);
|
|
670
|
+
provingState.setMergeRollupProof(location, result);
|
|
671
|
+
this.checkAndEnqueueNextMergeRollup(provingState, location);
|
|
866
672
|
},
|
|
867
673
|
);
|
|
868
674
|
}
|
|
869
675
|
|
|
870
676
|
// Executes the block root rollup circuit
|
|
871
677
|
private enqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
872
|
-
if (!provingState.block) {
|
|
873
|
-
throw new Error(`Invalid proving state for block root rollup, block not available`);
|
|
874
|
-
}
|
|
875
|
-
|
|
876
678
|
if (!provingState.verifyState()) {
|
|
877
679
|
logger.debug('Not running block root rollup, state no longer valid');
|
|
878
680
|
return;
|
|
879
681
|
}
|
|
880
682
|
|
|
881
683
|
provingState.blockRootRollupStarted = true;
|
|
882
|
-
const mergeInputData = provingState.getMergeInputs(0);
|
|
883
|
-
const rootParityInput = provingState.finalRootParityInput!;
|
|
884
|
-
const blobFields = this.extractTxEffects(provingState)
|
|
885
|
-
.map(tx => tx.toBlobFields())
|
|
886
|
-
.flat();
|
|
887
|
-
const blobs = Blob.getBlobs(blobFields);
|
|
888
|
-
const blobsHash = sha256ToField(blobs.map(b => b.getEthVersionedBlobHash()));
|
|
889
684
|
|
|
890
|
-
|
|
891
|
-
`Enqueuing block root rollup for block ${provingState.blockNumber} with ${provingState.newL1ToL2Messages.length} l1 to l2 msgs and ${blobs.length} blobs.`,
|
|
892
|
-
);
|
|
685
|
+
const { rollupType, inputs } = provingState.getBlockRootRollupTypeAndInputs(this.proverId);
|
|
893
686
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
mergeInputData.inputs[i]!,
|
|
897
|
-
mergeInputData.proofs[i]!,
|
|
898
|
-
mergeInputData.verificationKeys[i]!,
|
|
899
|
-
),
|
|
687
|
+
logger.debug(
|
|
688
|
+
`Enqueuing ${rollupType} for block ${provingState.blockNumber} with ${provingState.newL1ToL2Messages.length} l1 to l2 msgs.`,
|
|
900
689
|
);
|
|
901
690
|
|
|
902
|
-
const inputs = BlockRootRollupInputs.from({
|
|
903
|
-
previousRollupData,
|
|
904
|
-
l1ToL2Roots: rootParityInput,
|
|
905
|
-
newL1ToL2Messages: provingState.newL1ToL2Messages,
|
|
906
|
-
newL1ToL2MessageTreeRootSiblingPath: provingState.messageTreeRootSiblingPath,
|
|
907
|
-
startL1ToL2MessageTreeSnapshot: provingState.messageTreeSnapshot,
|
|
908
|
-
startArchiveSnapshot: provingState.archiveTreeSnapshot,
|
|
909
|
-
newArchiveSiblingPath: provingState.archiveTreeRootSiblingPath,
|
|
910
|
-
previousBlockHash: provingState.previousBlockHash,
|
|
911
|
-
proverId: this.proverId,
|
|
912
|
-
blobFields: padArrayEnd(blobFields, Fr.ZERO, FIELDS_PER_BLOB * BLOBS_PER_BLOCK),
|
|
913
|
-
blobCommitments: padArrayEnd(
|
|
914
|
-
blobs.map(b => b.commitmentToFields()),
|
|
915
|
-
[Fr.ZERO, Fr.ZERO],
|
|
916
|
-
BLOBS_PER_BLOCK,
|
|
917
|
-
),
|
|
918
|
-
blobsHash: blobsHash,
|
|
919
|
-
});
|
|
920
|
-
|
|
921
691
|
this.deferredProving(
|
|
922
692
|
provingState,
|
|
923
693
|
wrapCallbackInSpan(
|
|
@@ -925,12 +695,21 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
925
695
|
'ProvingOrchestrator.prover.getBlockRootRollupProof',
|
|
926
696
|
{
|
|
927
697
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
928
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]:
|
|
698
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType,
|
|
699
|
+
},
|
|
700
|
+
signal => {
|
|
701
|
+
if (inputs instanceof EmptyBlockRootRollupInputs) {
|
|
702
|
+
return this.prover.getEmptyBlockRootRollupProof(inputs, signal, provingState.epochNumber);
|
|
703
|
+
} else if (inputs instanceof SingleTxBlockRootRollupInputs) {
|
|
704
|
+
return this.prover.getSingleTxBlockRootRollupProof(inputs, signal, provingState.epochNumber);
|
|
705
|
+
} else {
|
|
706
|
+
return this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber);
|
|
707
|
+
}
|
|
929
708
|
},
|
|
930
|
-
signal => this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
931
709
|
),
|
|
932
710
|
result => {
|
|
933
|
-
|
|
711
|
+
provingState.setBlockRootRollupProof(result);
|
|
712
|
+
const header = provingState.buildHeaderFromProvingOutputs(logger);
|
|
934
713
|
if (!header.hash().equals(provingState.block!.header.hash())) {
|
|
935
714
|
logger.error(
|
|
936
715
|
`Block header mismatch\nCircuit:${inspect(header)}\nComputed:${inspect(provingState.block!.header)}`,
|
|
@@ -938,29 +717,16 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
938
717
|
provingState.reject(`Block header hash mismatch`);
|
|
939
718
|
}
|
|
940
719
|
|
|
941
|
-
|
|
942
|
-
provingState.finalProof = result.proof.binaryProof;
|
|
943
|
-
const blobOutputs = result.inputs.blobPublicInputs[0];
|
|
944
|
-
blobOutputs.inner.forEach((blobOutput, i) => {
|
|
945
|
-
if (!blobOutput.isEmpty() && !blobOutput.equals(BlobPublicInputs.fromBlob(blobs[i]))) {
|
|
946
|
-
throw new Error(
|
|
947
|
-
`Rollup circuits produced mismatched blob evaluation:
|
|
948
|
-
z: ${blobOutput.z} == ${blobs[i].challengeZ},
|
|
949
|
-
y: ${blobOutput.y.toString(16)} == ${blobs[i].evaluationY.toString('hex')},
|
|
950
|
-
C: ${blobOutput.kzgCommitment} == ${blobs[i].commitmentToFields()}`,
|
|
951
|
-
);
|
|
952
|
-
}
|
|
953
|
-
});
|
|
954
|
-
|
|
955
|
-
logger.debug(`Completed proof for block root rollup for ${provingState.block?.number}`);
|
|
720
|
+
logger.debug(`Completed ${rollupType} proof for block ${provingState.block!.number}`);
|
|
956
721
|
// validatePartialState(result.inputs.end, tx.treeSnapshots); // TODO(palla/prover)
|
|
957
722
|
|
|
958
|
-
const
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
723
|
+
const epochProvingState = this.provingState!;
|
|
724
|
+
const leafLocation = epochProvingState.setBlockRootRollupProof(provingState.index, result);
|
|
725
|
+
if (epochProvingState.totalNumBlocks === 1) {
|
|
726
|
+
this.enqueueEpochPadding(epochProvingState);
|
|
727
|
+
} else {
|
|
728
|
+
this.checkAndEnqueueNextBlockMergeRollup(epochProvingState, leafLocation);
|
|
729
|
+
}
|
|
964
730
|
},
|
|
965
731
|
);
|
|
966
732
|
}
|
|
@@ -968,6 +734,11 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
968
734
|
// Executes the base parity circuit and stores the intermediate state for the root parity circuit
|
|
969
735
|
// Enqueues the root parity circuit if all inputs are available
|
|
970
736
|
private enqueueBaseParityCircuit(provingState: BlockProvingState, inputs: BaseParityInputs, index: number) {
|
|
737
|
+
if (!provingState.verifyState()) {
|
|
738
|
+
logger.debug('Not running base parity. State no longer valid.');
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
|
|
971
742
|
this.deferredProving(
|
|
972
743
|
provingState,
|
|
973
744
|
wrapCallbackInSpan(
|
|
@@ -980,29 +751,30 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
980
751
|
signal => this.prover.getBaseParityProof(inputs, signal, provingState.epochNumber),
|
|
981
752
|
),
|
|
982
753
|
provingOutput => {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
provingOutput.verificationKey.keyAsFields,
|
|
986
|
-
getVKSiblingPath(getVKIndex(provingOutput.verificationKey)),
|
|
987
|
-
provingOutput.inputs,
|
|
988
|
-
);
|
|
989
|
-
provingState.setRootParityInputs(rootParityInput, index);
|
|
990
|
-
if (provingState.areRootParityInputsReady()) {
|
|
991
|
-
const rootParityInputs = new RootParityInputs(
|
|
992
|
-
provingState.rootParityInput as Tuple<
|
|
993
|
-
RootParityInput<typeof RECURSIVE_PROOF_LENGTH>,
|
|
994
|
-
typeof NUM_BASE_PARITY_PER_ROOT_PARITY
|
|
995
|
-
>,
|
|
996
|
-
);
|
|
997
|
-
this.enqueueRootParityCircuit(provingState, rootParityInputs);
|
|
998
|
-
}
|
|
754
|
+
provingState.setBaseParityProof(index, provingOutput);
|
|
755
|
+
this.checkAndEnqueueRootParityCircuit(provingState);
|
|
999
756
|
},
|
|
1000
757
|
);
|
|
1001
758
|
}
|
|
1002
759
|
|
|
760
|
+
private checkAndEnqueueRootParityCircuit(provingState: BlockProvingState) {
|
|
761
|
+
if (!provingState.isReadyForRootParity()) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
this.enqueueRootParityCircuit(provingState);
|
|
766
|
+
}
|
|
767
|
+
|
|
1003
768
|
// Runs the root parity circuit ans stored the outputs
|
|
1004
769
|
// Enqueues the root rollup proof if all inputs are available
|
|
1005
|
-
private enqueueRootParityCircuit(provingState: BlockProvingState
|
|
770
|
+
private enqueueRootParityCircuit(provingState: BlockProvingState) {
|
|
771
|
+
if (!provingState.verifyState()) {
|
|
772
|
+
logger.debug('Not running root parity. State no longer valid.');
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
const inputs = provingState.getRootParityInputs();
|
|
777
|
+
|
|
1006
778
|
this.deferredProving(
|
|
1007
779
|
provingState,
|
|
1008
780
|
wrapCallbackInSpan(
|
|
@@ -1014,14 +786,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1014
786
|
},
|
|
1015
787
|
signal => this.prover.getRootParityProof(inputs, signal, provingState.epochNumber),
|
|
1016
788
|
),
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
provingOutput.proof,
|
|
1020
|
-
provingOutput.verificationKey.keyAsFields,
|
|
1021
|
-
getVKSiblingPath(getVKIndex(provingOutput.verificationKey)),
|
|
1022
|
-
provingOutput.inputs,
|
|
1023
|
-
);
|
|
1024
|
-
provingState!.finalRootParityInput = rootParityInput;
|
|
789
|
+
result => {
|
|
790
|
+
provingState.setRootParityProof(result);
|
|
1025
791
|
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
1026
792
|
},
|
|
1027
793
|
);
|
|
@@ -1029,16 +795,13 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1029
795
|
|
|
1030
796
|
// Executes the block merge rollup circuit and stored the output as intermediate state for the parent merge/block root circuit
|
|
1031
797
|
// Enqueues the next level of merge if all inputs are available
|
|
1032
|
-
private enqueueBlockMergeRollup(
|
|
1033
|
-
provingState
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
const inputs =
|
|
1039
|
-
[mergeInputData.inputs[0]!, mergeInputData.proofs[0]!, mergeInputData.verificationKeys[0]!],
|
|
1040
|
-
[mergeInputData.inputs[1]!, mergeInputData.proofs[1]!, mergeInputData.verificationKeys[1]!],
|
|
1041
|
-
);
|
|
798
|
+
private enqueueBlockMergeRollup(provingState: EpochProvingState, location: TreeNodeLocation) {
|
|
799
|
+
if (!provingState.verifyState()) {
|
|
800
|
+
logger.debug('Not running block merge rollup. State no longer valid.');
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
const inputs = provingState.getBlockMergeRollupInputs(location);
|
|
1042
805
|
|
|
1043
806
|
this.deferredProving(
|
|
1044
807
|
provingState,
|
|
@@ -1052,34 +815,51 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1052
815
|
signal => this.prover.getBlockMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
1053
816
|
),
|
|
1054
817
|
result => {
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
818
|
+
provingState.setBlockMergeRollupProof(location, result);
|
|
819
|
+
this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
|
|
820
|
+
},
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
private enqueueEpochPadding(provingState: EpochProvingState) {
|
|
825
|
+
if (!provingState.verifyState()) {
|
|
826
|
+
logger.debug('Not running epoch padding. State no longer valid.');
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
logger.debug('Padding epoch proof with an empty block root proof.');
|
|
831
|
+
|
|
832
|
+
const inputs = provingState.getPaddingBlockRootInputs(this.proverId);
|
|
833
|
+
|
|
834
|
+
this.deferredProving(
|
|
835
|
+
provingState,
|
|
836
|
+
wrapCallbackInSpan(
|
|
837
|
+
this.tracer,
|
|
838
|
+
'ProvingOrchestrator.prover.getEmptyBlockRootRollupProof',
|
|
839
|
+
{
|
|
840
|
+
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
841
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'empty-block-root-rollup' satisfies CircuitName,
|
|
842
|
+
},
|
|
843
|
+
signal => this.prover.getEmptyBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
844
|
+
),
|
|
845
|
+
result => {
|
|
846
|
+
logger.debug('Completed proof for padding block root.');
|
|
847
|
+
provingState.setPaddingBlockRootProof(result);
|
|
848
|
+
this.checkAndEnqueueRootRollup(provingState);
|
|
1060
849
|
},
|
|
1061
850
|
);
|
|
1062
851
|
}
|
|
1063
852
|
|
|
1064
853
|
// Executes the root rollup circuit
|
|
1065
|
-
private enqueueRootRollup(provingState: EpochProvingState
|
|
1066
|
-
if (!provingState
|
|
854
|
+
private enqueueRootRollup(provingState: EpochProvingState) {
|
|
855
|
+
if (!provingState.verifyState()) {
|
|
1067
856
|
logger.debug('Not running root rollup, state no longer valid');
|
|
1068
857
|
return;
|
|
1069
858
|
}
|
|
1070
859
|
|
|
1071
860
|
logger.debug(`Preparing root rollup`);
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
const inputs = getRootRollupInput(
|
|
1075
|
-
mergeInputData.inputs[0]!,
|
|
1076
|
-
mergeInputData.proofs[0]!,
|
|
1077
|
-
mergeInputData.verificationKeys[0]!,
|
|
1078
|
-
mergeInputData.inputs[1]!,
|
|
1079
|
-
mergeInputData.proofs[1]!,
|
|
1080
|
-
mergeInputData.verificationKeys[1]!,
|
|
1081
|
-
this.proverId,
|
|
1082
|
-
);
|
|
861
|
+
|
|
862
|
+
const inputs = provingState.getRootRollupInputs(this.proverId);
|
|
1083
863
|
|
|
1084
864
|
this.deferredProving(
|
|
1085
865
|
provingState,
|
|
@@ -1094,15 +874,27 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1094
874
|
),
|
|
1095
875
|
result => {
|
|
1096
876
|
logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1097
|
-
provingState.
|
|
1098
|
-
provingState.finalProof = result.proof.binaryProof;
|
|
877
|
+
provingState.setRootRollupProof(result);
|
|
1099
878
|
provingState.resolve({ status: 'success' });
|
|
1100
879
|
},
|
|
1101
880
|
);
|
|
1102
881
|
}
|
|
1103
882
|
|
|
883
|
+
private checkAndEnqueueNextMergeRollup(provingState: BlockProvingState, currentLocation: TreeNodeLocation) {
|
|
884
|
+
if (!provingState.isReadyForMergeRollup(currentLocation)) {
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
889
|
+
if (parentLocation.level === 0) {
|
|
890
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
891
|
+
} else {
|
|
892
|
+
this.enqueueMergeRollup(provingState, parentLocation);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
|
|
1104
896
|
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
1105
|
-
if (!provingState
|
|
897
|
+
if (!provingState.isReadyForBlockRootRollup()) {
|
|
1106
898
|
logger.debug('Not ready for root rollup');
|
|
1107
899
|
return;
|
|
1108
900
|
}
|
|
@@ -1126,94 +918,26 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1126
918
|
this.enqueueBlockRootRollup(provingState);
|
|
1127
919
|
}
|
|
1128
920
|
|
|
1129
|
-
private
|
|
1130
|
-
if (!provingState
|
|
1131
|
-
logger.debug('Not ready for root rollup');
|
|
921
|
+
private checkAndEnqueueNextBlockMergeRollup(provingState: EpochProvingState, currentLocation: TreeNodeLocation) {
|
|
922
|
+
if (!provingState.isReadyForBlockMerge(currentLocation)) {
|
|
1132
923
|
return;
|
|
1133
924
|
}
|
|
1134
|
-
this.enqueueRootRollup(provingState);
|
|
1135
|
-
}
|
|
1136
925
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
* @param currentLevel - The level of the merge/root circuit
|
|
1141
|
-
* @param currentIndex - The index of the merge/root circuit
|
|
1142
|
-
* @param mergeInputData - The inputs to be stored
|
|
1143
|
-
*/
|
|
1144
|
-
private storeAndExecuteNextMergeLevel(
|
|
1145
|
-
provingState: BlockProvingState,
|
|
1146
|
-
currentLevel: bigint,
|
|
1147
|
-
currentIndex: bigint,
|
|
1148
|
-
mergeInputData: [
|
|
1149
|
-
BaseOrMergeRollupPublicInputs,
|
|
1150
|
-
RecursiveProof<typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>,
|
|
1151
|
-
VerificationKeyAsFields,
|
|
1152
|
-
],
|
|
1153
|
-
) {
|
|
1154
|
-
const [mergeLevel, indexWithinMergeLevel, indexWithinMerge] = provingState.findMergeLevel(
|
|
1155
|
-
currentLevel,
|
|
1156
|
-
currentIndex,
|
|
1157
|
-
);
|
|
1158
|
-
const mergeIndex = 2n ** mergeLevel - 1n + indexWithinMergeLevel;
|
|
1159
|
-
const ready = provingState.storeMergeInputs(mergeInputData, Number(indexWithinMerge), Number(mergeIndex));
|
|
1160
|
-
const nextMergeInputData = provingState.getMergeInputs(Number(mergeIndex));
|
|
1161
|
-
|
|
1162
|
-
// Are we ready to execute the next circuit?
|
|
1163
|
-
if (!ready) {
|
|
1164
|
-
return;
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
if (mergeLevel === 0n) {
|
|
1168
|
-
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
926
|
+
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
927
|
+
if (parentLocation.level === 0) {
|
|
928
|
+
this.checkAndEnqueueRootRollup(provingState);
|
|
1169
929
|
} else {
|
|
1170
|
-
|
|
1171
|
-
this.enqueueMergeRollup(provingState, mergeLevel, indexWithinMergeLevel, nextMergeInputData);
|
|
930
|
+
this.enqueueBlockMergeRollup(provingState, parentLocation);
|
|
1172
931
|
}
|
|
1173
932
|
}
|
|
1174
933
|
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
* @param currentLevel - The level of the merge/root circuit
|
|
1179
|
-
* @param currentIndex - The index of the merge/root circuit
|
|
1180
|
-
* @param mergeInputData - The inputs to be stored
|
|
1181
|
-
*/
|
|
1182
|
-
private storeAndExecuteNextBlockMergeLevel(
|
|
1183
|
-
provingState: EpochProvingState,
|
|
1184
|
-
currentLevel: bigint,
|
|
1185
|
-
currentIndex: bigint,
|
|
1186
|
-
mergeInputData: [
|
|
1187
|
-
BlockRootOrBlockMergePublicInputs,
|
|
1188
|
-
RecursiveProof<typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>,
|
|
1189
|
-
VerificationKeyAsFields,
|
|
1190
|
-
],
|
|
1191
|
-
) {
|
|
1192
|
-
const [mergeLevel, indexWithinMergeLevel, indexWithinMerge] = provingState.findMergeLevel(
|
|
1193
|
-
currentLevel,
|
|
1194
|
-
currentIndex,
|
|
1195
|
-
);
|
|
1196
|
-
logger.debug(`Computed merge for ${currentLevel}.${currentIndex} as ${mergeLevel}.${indexWithinMergeLevel}`);
|
|
1197
|
-
if (mergeLevel < 0n) {
|
|
1198
|
-
throw new Error(`Invalid merge level ${mergeLevel}`);
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
const mergeIndex = 2n ** mergeLevel - 1n + indexWithinMergeLevel;
|
|
1202
|
-
const ready = provingState.storeMergeInputs(mergeInputData, Number(indexWithinMerge), Number(mergeIndex));
|
|
1203
|
-
const nextMergeInputData = provingState.getMergeInputs(Number(mergeIndex));
|
|
1204
|
-
|
|
1205
|
-
// Are we ready to execute the next circuit?
|
|
1206
|
-
if (!ready) {
|
|
1207
|
-
logger.debug(`Not ready to execute next block merge for level ${mergeLevel} index ${indexWithinMergeLevel}`);
|
|
934
|
+
private checkAndEnqueueRootRollup(provingState: EpochProvingState) {
|
|
935
|
+
if (!provingState.isReadyForRootRollup()) {
|
|
936
|
+
logger.debug('Not ready for root rollup');
|
|
1208
937
|
return;
|
|
1209
938
|
}
|
|
1210
939
|
|
|
1211
|
-
|
|
1212
|
-
this.checkAndEnqueueRootRollup(provingState);
|
|
1213
|
-
} else {
|
|
1214
|
-
// onto the next merge level
|
|
1215
|
-
this.enqueueBlockMergeRollup(provingState, mergeLevel, indexWithinMergeLevel, nextMergeInputData);
|
|
1216
|
-
}
|
|
940
|
+
this.enqueueRootRollup(provingState);
|
|
1217
941
|
}
|
|
1218
942
|
|
|
1219
943
|
/**
|
|
@@ -1222,8 +946,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1222
946
|
* @param provingState - The proving state being operated on
|
|
1223
947
|
* @param txIndex - The index of the transaction being proven
|
|
1224
948
|
*/
|
|
1225
|
-
private enqueueVM(provingState: BlockProvingState
|
|
1226
|
-
if (!provingState
|
|
949
|
+
private enqueueVM(provingState: BlockProvingState, txIndex: number) {
|
|
950
|
+
if (!provingState.verifyState()) {
|
|
1227
951
|
logger.debug(`Not running VM circuit as state is no longer valid`);
|
|
1228
952
|
return;
|
|
1229
953
|
}
|
|
@@ -1263,7 +987,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1263
987
|
|
|
1264
988
|
this.deferredProving(provingState, doAvmProving, proofAndVk => {
|
|
1265
989
|
logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1266
|
-
txProvingState.
|
|
990
|
+
txProvingState.setAvmProof(proofAndVk);
|
|
1267
991
|
this.checkAndEnqueueNextTxCircuit(provingState, txIndex);
|
|
1268
992
|
});
|
|
1269
993
|
}
|