@aztec/prover-client 0.69.1 → 0.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bin/get-proof-inputs.d.ts +2 -0
- package/dest/bin/get-proof-inputs.d.ts.map +1 -0
- package/dest/bin/get-proof-inputs.js +50 -0
- package/dest/block_builder/light.d.ts +3 -5
- package/dest/block_builder/light.d.ts.map +1 -1
- package/dest/block_builder/light.js +9 -22
- package/dest/config.d.ts +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +3 -2
- package/dest/mocks/fixtures.d.ts +1 -1
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +2 -2
- package/dest/mocks/test_context.d.ts +1 -1
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +11 -12
- package/dest/orchestrator/block-building-helpers.d.ts +15 -29
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +51 -58
- 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 +17 -48
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +208 -351
- 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 +4 -4
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +5 -5
- package/dest/prover-agent/prover-agent.d.ts +0 -2
- package/dest/prover-agent/prover-agent.d.ts.map +1 -1
- package/dest/prover-agent/prover-agent.js +7 -9
- package/dest/prover-client/factory.d.ts.map +1 -1
- package/dest/prover-client/factory.js +3 -3
- package/dest/prover-client/prover-client.d.ts +4 -2
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +16 -15
- 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 +19 -7
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +271 -49
- 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 +4 -7
- 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 +2 -1
- package/dest/proving_broker/index.d.ts.map +1 -1
- package/dest/proving_broker/index.js +3 -2
- package/dest/proving_broker/proof_store/factory.d.ts +6 -0
- package/dest/proving_broker/proof_store/factory.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/factory.js +39 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +13 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.js +46 -0
- package/dest/proving_broker/proof_store/index.d.ts +4 -0
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/index.js +4 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts +14 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/inline_proof_store.js +37 -0
- package/dest/proving_broker/{proof_store.d.ts → proof_store/proof_store.d.ts} +1 -12
- package/dest/proving_broker/proof_store/proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/proof_store.js +2 -0
- package/dest/proving_broker/proving_agent.d.ts +4 -4
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +5 -5
- 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 +307 -274
- 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 +106 -14
- 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 +8 -8
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +9 -10
- package/package.json +14 -12
- package/src/bin/get-proof-inputs.ts +60 -0
- package/src/block_builder/light.ts +7 -31
- package/src/config.ts +4 -4
- package/src/mocks/fixtures.ts +1 -1
- package/src/mocks/test_context.ts +9 -11
- package/src/orchestrator/block-building-helpers.ts +360 -402
- package/src/orchestrator/block-proving-state.ts +251 -121
- package/src/orchestrator/epoch-proving-state.ts +159 -88
- package/src/orchestrator/orchestrator.ts +262 -542
- package/src/orchestrator/tx-proving-state.ts +30 -18
- package/src/prover-agent/memory-proving-queue.ts +12 -16
- package/src/prover-agent/prover-agent.ts +14 -8
- package/src/prover-client/factory.ts +2 -3
- package/src/prover-client/prover-client.ts +17 -20
- package/src/prover-client/server-epoch-prover.ts +44 -0
- package/src/proving_broker/broker_prover_facade.ts +347 -67
- package/src/proving_broker/config.ts +93 -0
- package/src/proving_broker/factory.ts +11 -10
- package/src/proving_broker/fixtures.ts +14 -0
- package/src/proving_broker/index.ts +2 -1
- package/src/proving_broker/proof_store/factory.ts +42 -0
- package/src/proving_broker/proof_store/gcs_proof_store.ts +72 -0
- package/src/proving_broker/proof_store/index.ts +3 -0
- package/src/proving_broker/{proof_store.ts → proof_store/inline_proof_store.ts} +1 -44
- package/src/proving_broker/proof_store/proof_store.ts +54 -0
- package/src/proving_broker/proving_agent.ts +11 -5
- package/src/proving_broker/proving_broker.ts +122 -73
- package/src/proving_broker/proving_broker_database/memory.ts +24 -4
- package/src/proving_broker/proving_broker_database/persisted.ts +142 -20
- 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 +12 -18
- package/dest/proving_broker/proof_store.d.ts.map +0 -1
- package/dest/proving_broker/proof_store.js +0 -37
|
@@ -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,71 +17,60 @@ 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 {
|
|
60
|
-
import {
|
|
50
|
+
import { type TreeNodeLocation } from '@aztec/foundation/trees';
|
|
51
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks';
|
|
52
|
+
import {
|
|
53
|
+
Attributes,
|
|
54
|
+
type TelemetryClient,
|
|
55
|
+
type Tracer,
|
|
56
|
+
getTelemetryClient,
|
|
57
|
+
trackSpan,
|
|
58
|
+
wrapCallbackInSpan,
|
|
59
|
+
} from '@aztec/telemetry-client';
|
|
61
60
|
|
|
62
61
|
import { inspect } from 'util';
|
|
63
62
|
|
|
64
63
|
import {
|
|
65
64
|
buildBaseRollupHints,
|
|
66
65
|
buildHeaderAndBodyFromTxs,
|
|
67
|
-
buildHeaderFromCircuitOutputs,
|
|
68
|
-
createBlockMergeRollupInputs,
|
|
69
|
-
createMergeRollupInputs,
|
|
70
|
-
getPreviousRollupDataFromPublicInputs,
|
|
71
|
-
getRootRollupInput,
|
|
72
66
|
getRootTreeSiblingPath,
|
|
73
67
|
getSubtreeSiblingPath,
|
|
74
68
|
getTreeSnapshot,
|
|
75
69
|
validatePartialState,
|
|
76
70
|
validateTx,
|
|
77
71
|
} 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';
|
|
72
|
+
import { type BlockProvingState } from './block-proving-state.js';
|
|
73
|
+
import { EpochProvingState, type ProvingResult, type TreeSnapshots } from './epoch-proving-state.js';
|
|
85
74
|
import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
|
|
86
75
|
import { TxProvingState } from './tx-proving-state.js';
|
|
87
76
|
|
|
@@ -104,7 +93,6 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
104
93
|
export class ProvingOrchestrator implements EpochProver {
|
|
105
94
|
private provingState: EpochProvingState | undefined = undefined;
|
|
106
95
|
private pendingProvingJobs: AbortController[] = [];
|
|
107
|
-
private paddingTxProof?: ProofAndVerificationKey<typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>;
|
|
108
96
|
|
|
109
97
|
private provingPromise: Promise<ProvingResult> | undefined = undefined;
|
|
110
98
|
private metrics: ProvingOrchestratorMetrics;
|
|
@@ -113,8 +101,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
113
101
|
constructor(
|
|
114
102
|
private dbProvider: ForkMerkleTreeOperations,
|
|
115
103
|
private prover: ServerCircuitProver,
|
|
116
|
-
telemetryClient: TelemetryClient,
|
|
117
104
|
private readonly proverId: Fr = Fr.ZERO,
|
|
105
|
+
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
118
106
|
) {
|
|
119
107
|
this.metrics = new ProvingOrchestratorMetrics(telemetryClient, 'ProvingOrchestrator');
|
|
120
108
|
}
|
|
@@ -127,11 +115,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
127
115
|
return this.proverId;
|
|
128
116
|
}
|
|
129
117
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
public reset() {
|
|
134
|
-
this.paddingTxProof = undefined;
|
|
118
|
+
public stop(): Promise<void> {
|
|
119
|
+
this.cancel();
|
|
120
|
+
return Promise.resolve();
|
|
135
121
|
}
|
|
136
122
|
|
|
137
123
|
public startNewEpoch(epochNumber: number, firstBlockNumber: number, totalNumBlocks: number) {
|
|
@@ -210,6 +196,22 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
210
196
|
BigInt(startArchiveSnapshot.nextAvailableLeafIndex - 1),
|
|
211
197
|
);
|
|
212
198
|
|
|
199
|
+
const partial = new PartialStateReference(
|
|
200
|
+
await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
|
|
201
|
+
await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
|
|
202
|
+
await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
|
|
203
|
+
);
|
|
204
|
+
const state = new StateReference(messageTreeSnapshot, partial);
|
|
205
|
+
// TODO: Construct the full previousBlockHeader.
|
|
206
|
+
const previousBlockHeader = BlockHeader.from({
|
|
207
|
+
lastArchive: startArchiveSnapshot,
|
|
208
|
+
contentCommitment: ContentCommitment.empty(),
|
|
209
|
+
state,
|
|
210
|
+
globalVariables: GlobalVariables.empty(),
|
|
211
|
+
totalFees: Fr.ZERO,
|
|
212
|
+
totalManaUsed: Fr.ZERO,
|
|
213
|
+
});
|
|
214
|
+
|
|
213
215
|
const blockProvingState = this.provingState!.startNewBlock(
|
|
214
216
|
globalVariables,
|
|
215
217
|
l1ToL2MessagesPadded,
|
|
@@ -218,6 +220,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
218
220
|
messageTreeSnapshotAfterInsertion,
|
|
219
221
|
startArchiveSnapshot,
|
|
220
222
|
newArchiveSiblingPath,
|
|
223
|
+
previousBlockHeader,
|
|
221
224
|
previousBlockHash!,
|
|
222
225
|
);
|
|
223
226
|
|
|
@@ -228,7 +231,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
228
231
|
}
|
|
229
232
|
|
|
230
233
|
/**
|
|
231
|
-
* The interface to add simulated transactions to the scheduler
|
|
234
|
+
* The interface to add simulated transactions to the scheduler. This can only be called once per block.
|
|
232
235
|
* @param txs - The transactions to be proven
|
|
233
236
|
*/
|
|
234
237
|
@trackSpan('ProvingOrchestrator.addTxs', txs => ({
|
|
@@ -247,11 +250,15 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
247
250
|
throw new Error(`Block proving state for ${blockNumber} not found`);
|
|
248
251
|
}
|
|
249
252
|
|
|
253
|
+
if (provingState.totalNumTxs) {
|
|
254
|
+
throw new Error(`Block ${blockNumber} has been initialized with transactions.`);
|
|
255
|
+
}
|
|
256
|
+
|
|
250
257
|
const numBlobFields = toNumBlobFields(txs);
|
|
251
|
-
provingState.startNewBlock(
|
|
258
|
+
provingState.startNewBlock(txs.length, numBlobFields);
|
|
252
259
|
|
|
253
260
|
logger.info(
|
|
254
|
-
`Adding ${txs.length} transactions with ${numBlobFields} blob fields to block ${provingState
|
|
261
|
+
`Adding ${txs.length} transactions with ${numBlobFields} blob fields to block ${provingState.blockNumber}`,
|
|
255
262
|
);
|
|
256
263
|
for (const tx of txs) {
|
|
257
264
|
try {
|
|
@@ -263,26 +270,43 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
263
270
|
|
|
264
271
|
logger.info(`Received transaction: ${tx.hash}`);
|
|
265
272
|
|
|
266
|
-
if (tx.isEmpty) {
|
|
267
|
-
logger.warn(`Ignoring empty transaction ${tx.hash} - it will not be added to this block`);
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
273
|
const [hints, treeSnapshots] = await this.prepareTransaction(tx, provingState);
|
|
272
|
-
|
|
274
|
+
const txProvingState = new TxProvingState(tx, hints, treeSnapshots);
|
|
275
|
+
const txIndex = provingState.addNewTx(txProvingState);
|
|
276
|
+
this.getOrEnqueueTube(provingState, txIndex);
|
|
277
|
+
if (txProvingState.requireAvmProof) {
|
|
278
|
+
logger.debug(`Enqueueing public VM for tx ${txIndex}`);
|
|
279
|
+
this.enqueueVM(provingState, txIndex);
|
|
280
|
+
}
|
|
273
281
|
} catch (err: any) {
|
|
274
282
|
throw new Error(`Error adding transaction ${tx.hash.toString()} to block ${blockNumber}: ${err.message}`, {
|
|
275
283
|
cause: err,
|
|
276
284
|
});
|
|
277
285
|
}
|
|
278
286
|
}
|
|
279
|
-
|
|
280
|
-
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Kickstarts tube circuits for the specified txs. These will be used during epoch proving.
|
|
291
|
+
* Note that if the tube circuits are not started this way, they will be started nontheless after processing.
|
|
292
|
+
*/
|
|
293
|
+
@trackSpan('ProvingOrchestrator.startTubeCircuits')
|
|
294
|
+
public startTubeCircuits(txs: Tx[]) {
|
|
295
|
+
if (!this.provingState?.verifyState()) {
|
|
296
|
+
throw new Error(`Invalid proving state, call startNewEpoch before starting tube circuits`);
|
|
297
|
+
}
|
|
298
|
+
for (const tx of txs) {
|
|
299
|
+
const txHash = tx.getTxHash().toString();
|
|
300
|
+
const tubeInputs = new TubeInputs(tx.clientIvcProof);
|
|
301
|
+
const tubeProof = promiseWithResolvers<ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>>();
|
|
302
|
+
logger.debug(`Starting tube circuit for tx ${txHash}`);
|
|
303
|
+
this.doEnqueueTube(txHash, tubeInputs, proof => tubeProof.resolve(proof));
|
|
304
|
+
this.provingState?.cachedTubeProofs.set(txHash, tubeProof.promise);
|
|
281
305
|
}
|
|
282
306
|
}
|
|
283
307
|
|
|
284
308
|
/**
|
|
285
|
-
* Marks the block as
|
|
309
|
+
* Marks the block as completed.
|
|
286
310
|
* Computes the block header and updates the archive tree.
|
|
287
311
|
*/
|
|
288
312
|
@trackSpan('ProvingOrchestrator.setBlockCompleted', (blockNumber: number) => ({
|
|
@@ -296,50 +320,14 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
296
320
|
|
|
297
321
|
if (!provingState.spongeBlobState) {
|
|
298
322
|
// If we are completing an empty block, initialise the provingState.
|
|
299
|
-
// We will have
|
|
300
|
-
provingState.startNewBlock(
|
|
323
|
+
// We will have 0 txs and no blob fields.
|
|
324
|
+
provingState.startNewBlock(0, 0);
|
|
301
325
|
}
|
|
302
326
|
|
|
303
327
|
if (!provingState.verifyState()) {
|
|
304
328
|
throw new Error(`Block proving failed: ${provingState.error}`);
|
|
305
329
|
}
|
|
306
330
|
|
|
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
331
|
// And build the block header
|
|
344
332
|
logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
345
333
|
await this.buildBlock(provingState, expectedHeader);
|
|
@@ -358,73 +346,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
358
346
|
return block;
|
|
359
347
|
}
|
|
360
348
|
|
|
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
349
|
private async buildBlock(provingState: BlockProvingState, expectedHeader?: BlockHeader) {
|
|
426
350
|
// Collect all new nullifiers, commitments, and contracts from all txs in this block to build body
|
|
427
|
-
const txs = provingState
|
|
351
|
+
const txs = provingState.allTxs.map(a => a.processedTx);
|
|
428
352
|
|
|
429
353
|
// Get db for this block
|
|
430
354
|
const db = this.dbs.get(provingState.blockNumber)!;
|
|
@@ -468,77 +392,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
468
392
|
}
|
|
469
393
|
}
|
|
470
394
|
|
|
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
395
|
/**
|
|
543
396
|
* Cancel any further proving
|
|
544
397
|
*/
|
|
@@ -550,45 +403,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
550
403
|
this.provingState?.cancel();
|
|
551
404
|
}
|
|
552
405
|
|
|
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
406
|
/**
|
|
593
407
|
* Returns the proof for the current epoch.
|
|
594
408
|
*/
|
|
@@ -597,23 +411,19 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
597
411
|
throw new Error(`Invalid proving state, an epoch must be proven before it can be finalised`);
|
|
598
412
|
}
|
|
599
413
|
|
|
600
|
-
await this.padEpoch();
|
|
601
|
-
|
|
602
414
|
const result = await this.provingPromise!;
|
|
603
415
|
if (result.status === 'failure') {
|
|
604
416
|
throw new Error(`Epoch proving failed: ${result.reason}`);
|
|
605
417
|
}
|
|
606
418
|
|
|
607
|
-
|
|
608
|
-
throw new Error(`Invalid proving state, missing root rollup public inputs or final proof`);
|
|
609
|
-
}
|
|
419
|
+
const epochProofResult = this.provingState.getEpochProofResult();
|
|
610
420
|
|
|
611
421
|
pushTestData('epochProofResult', {
|
|
612
|
-
proof:
|
|
613
|
-
publicInputs:
|
|
422
|
+
proof: epochProofResult.proof.toString(),
|
|
423
|
+
publicInputs: epochProofResult.publicInputs.toString(),
|
|
614
424
|
});
|
|
615
425
|
|
|
616
|
-
return
|
|
426
|
+
return epochProofResult;
|
|
617
427
|
}
|
|
618
428
|
|
|
619
429
|
/**
|
|
@@ -630,21 +440,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
630
440
|
return txInputs;
|
|
631
441
|
}
|
|
632
442
|
|
|
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
443
|
/**
|
|
649
444
|
* Enqueue a job to be scheduled
|
|
650
445
|
* @param provingState - The proving state object being operated on
|
|
@@ -712,10 +507,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
712
507
|
[Attributes.TX_HASH]: tx.hash.toString(),
|
|
713
508
|
}))
|
|
714
509
|
private async prepareBaseRollupInputs(
|
|
715
|
-
provingState: BlockProvingState
|
|
510
|
+
provingState: BlockProvingState,
|
|
716
511
|
tx: ProcessedTx,
|
|
717
512
|
): Promise<[BaseRollupHints, TreeSnapshots] | undefined> {
|
|
718
|
-
if (!provingState
|
|
513
|
+
if (!provingState.verifyState() || !provingState.spongeBlobState) {
|
|
719
514
|
logger.debug('Not preparing base rollup inputs, state invalid');
|
|
720
515
|
return;
|
|
721
516
|
}
|
|
@@ -728,9 +523,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
728
523
|
buildBaseRollupHints(tx, provingState.globalVariables, db, provingState.spongeBlobState),
|
|
729
524
|
);
|
|
730
525
|
|
|
731
|
-
|
|
732
|
-
this.metrics.recordBaseRollupInputs(ms);
|
|
733
|
-
}
|
|
526
|
+
this.metrics.recordBaseRollupInputs(ms);
|
|
734
527
|
|
|
735
528
|
const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(
|
|
736
529
|
async (id: MerkleTreeId) => {
|
|
@@ -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,40 +541,34 @@ 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
|
-
logger.debug(
|
|
762
|
-
`Enqueuing deferred proving base rollup${
|
|
763
|
-
processedTx.isEmpty ? ' with padding tx' : ''
|
|
764
|
-
} for ${processedTx.hash.toString()}`,
|
|
765
|
-
);
|
|
554
|
+
logger.debug(`Enqueuing deferred proving base rollup for ${processedTx.hash.toString()}`);
|
|
766
555
|
|
|
767
556
|
this.deferredProving(
|
|
768
557
|
provingState,
|
|
769
558
|
wrapCallbackInSpan(
|
|
770
559
|
this.tracer,
|
|
771
560
|
`ProvingOrchestrator.prover.${
|
|
772
|
-
|
|
561
|
+
inputs instanceof PrivateBaseRollupInputs ? 'getPrivateBaseRollupProof' : 'getPublicBaseRollupProof'
|
|
773
562
|
}`,
|
|
774
563
|
{
|
|
775
564
|
[Attributes.TX_HASH]: processedTx.hash.toString(),
|
|
776
565
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
777
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType
|
|
566
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType,
|
|
778
567
|
},
|
|
779
568
|
signal => {
|
|
780
|
-
if (
|
|
781
|
-
const inputs = txProvingState.getPrivateBaseInputs();
|
|
569
|
+
if (inputs instanceof PrivateBaseRollupInputs) {
|
|
782
570
|
return this.prover.getPrivateBaseRollupProof(inputs, signal, provingState.epochNumber);
|
|
783
571
|
} else {
|
|
784
|
-
const inputs = txProvingState.getPublicBaseInputs();
|
|
785
572
|
return this.prover.getPublicBaseRollupProof(inputs, signal, provingState.epochNumber);
|
|
786
573
|
}
|
|
787
574
|
},
|
|
@@ -789,26 +576,54 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
789
576
|
result => {
|
|
790
577
|
logger.debug(`Completed proof for ${rollupType} for tx ${processedTx.hash.toString()}`);
|
|
791
578
|
validatePartialState(result.inputs.end, txProvingState.treeSnapshots);
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
579
|
+
const leafLocation = provingState.setBaseRollupProof(txIndex, result);
|
|
580
|
+
if (provingState.totalNumTxs === 1) {
|
|
581
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
582
|
+
} else {
|
|
583
|
+
this.checkAndEnqueueNextMergeRollup(provingState, leafLocation);
|
|
584
|
+
}
|
|
798
585
|
},
|
|
799
586
|
);
|
|
800
587
|
}
|
|
801
588
|
|
|
802
|
-
// Enqueues the tube circuit for a given transaction index
|
|
589
|
+
// Enqueues the tube circuit for a given transaction index, or reuses the one already enqueued
|
|
803
590
|
// Once completed, will enqueue the next circuit, either a public kernel or the base rollup
|
|
804
|
-
private
|
|
805
|
-
if (!provingState
|
|
591
|
+
private getOrEnqueueTube(provingState: BlockProvingState, txIndex: number) {
|
|
592
|
+
if (!provingState.verifyState()) {
|
|
806
593
|
logger.debug('Not running tube circuit, state invalid');
|
|
807
594
|
return;
|
|
808
595
|
}
|
|
809
596
|
|
|
810
597
|
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
598
|
+
const txHash = txProvingState.processedTx.hash.toString();
|
|
599
|
+
|
|
600
|
+
const handleResult = (result: ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>) => {
|
|
601
|
+
logger.debug(`Got tube proof for tx index: ${txIndex}`, { txHash });
|
|
602
|
+
txProvingState.setTubeProof(result);
|
|
603
|
+
this.provingState?.cachedTubeProofs.delete(txHash);
|
|
604
|
+
this.checkAndEnqueueNextTxCircuit(provingState, txIndex);
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
if (this.provingState?.cachedTubeProofs.has(txHash)) {
|
|
608
|
+
logger.debug(`Tube proof already enqueued for tx index: ${txIndex}`, { txHash });
|
|
609
|
+
void this.provingState!.cachedTubeProofs.get(txHash)!.then(handleResult);
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
|
|
811
613
|
logger.debug(`Enqueuing tube circuit for tx index: ${txIndex}`);
|
|
614
|
+
this.doEnqueueTube(txHash, txProvingState.getTubeInputs(), handleResult);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
private doEnqueueTube(
|
|
618
|
+
txHash: string,
|
|
619
|
+
inputs: TubeInputs,
|
|
620
|
+
handler: (result: ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>) => void,
|
|
621
|
+
provingState: EpochProvingState | BlockProvingState = this.provingState!,
|
|
622
|
+
) {
|
|
623
|
+
if (!provingState?.verifyState()) {
|
|
624
|
+
logger.debug('Not running tube circuit, state invalid');
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
812
627
|
|
|
813
628
|
this.deferredProving(
|
|
814
629
|
provingState,
|
|
@@ -816,35 +631,25 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
816
631
|
this.tracer,
|
|
817
632
|
'ProvingOrchestrator.prover.getTubeProof',
|
|
818
633
|
{
|
|
819
|
-
[Attributes.TX_HASH]:
|
|
634
|
+
[Attributes.TX_HASH]: txHash,
|
|
820
635
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
821
636
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'tube-circuit' satisfies CircuitName,
|
|
822
637
|
},
|
|
823
|
-
signal =>
|
|
824
|
-
const inputs = txProvingState.getTubeInputs();
|
|
825
|
-
return this.prover.getTubeProof(inputs, signal, provingState.epochNumber);
|
|
826
|
-
},
|
|
638
|
+
signal => this.prover.getTubeProof(inputs, signal, this.provingState!.epochNumber),
|
|
827
639
|
),
|
|
828
|
-
|
|
829
|
-
logger.debug(`Completed tube proof for tx index: ${txIndex}`);
|
|
830
|
-
txProvingState.assignTubeProof(result);
|
|
831
|
-
this.checkAndEnqueueNextTxCircuit(provingState, txIndex);
|
|
832
|
-
},
|
|
640
|
+
handler,
|
|
833
641
|
);
|
|
834
642
|
}
|
|
835
643
|
|
|
836
644
|
// Executes the merge rollup circuit and stored the output as intermediate state for the parent merge/block root circuit
|
|
837
645
|
// 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
|
-
);
|
|
646
|
+
private enqueueMergeRollup(provingState: BlockProvingState, location: TreeNodeLocation) {
|
|
647
|
+
if (!provingState.verifyState()) {
|
|
648
|
+
logger.debug('Not running merge rollup. State no longer valid.');
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const inputs = provingState.getMergeRollupInputs(location);
|
|
848
653
|
|
|
849
654
|
this.deferredProving(
|
|
850
655
|
provingState,
|
|
@@ -858,66 +663,27 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
858
663
|
signal => this.prover.getMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
859
664
|
),
|
|
860
665
|
result => {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
result.proof,
|
|
864
|
-
result.verificationKey.keyAsFields,
|
|
865
|
-
]);
|
|
666
|
+
provingState.setMergeRollupProof(location, result);
|
|
667
|
+
this.checkAndEnqueueNextMergeRollup(provingState, location);
|
|
866
668
|
},
|
|
867
669
|
);
|
|
868
670
|
}
|
|
869
671
|
|
|
870
672
|
// Executes the block root rollup circuit
|
|
871
673
|
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
674
|
if (!provingState.verifyState()) {
|
|
877
675
|
logger.debug('Not running block root rollup, state no longer valid');
|
|
878
676
|
return;
|
|
879
677
|
}
|
|
880
678
|
|
|
881
679
|
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
680
|
|
|
890
|
-
|
|
891
|
-
`Enqueuing block root rollup for block ${provingState.blockNumber} with ${provingState.newL1ToL2Messages.length} l1 to l2 msgs and ${blobs.length} blobs.`,
|
|
892
|
-
);
|
|
681
|
+
const { rollupType, inputs } = provingState.getBlockRootRollupTypeAndInputs(this.proverId);
|
|
893
682
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
mergeInputData.inputs[i]!,
|
|
897
|
-
mergeInputData.proofs[i]!,
|
|
898
|
-
mergeInputData.verificationKeys[i]!,
|
|
899
|
-
),
|
|
683
|
+
logger.debug(
|
|
684
|
+
`Enqueuing ${rollupType} for block ${provingState.blockNumber} with ${provingState.newL1ToL2Messages.length} l1 to l2 msgs.`,
|
|
900
685
|
);
|
|
901
686
|
|
|
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
687
|
this.deferredProving(
|
|
922
688
|
provingState,
|
|
923
689
|
wrapCallbackInSpan(
|
|
@@ -925,12 +691,21 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
925
691
|
'ProvingOrchestrator.prover.getBlockRootRollupProof',
|
|
926
692
|
{
|
|
927
693
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
928
|
-
[Attributes.PROTOCOL_CIRCUIT_NAME]:
|
|
694
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: rollupType,
|
|
695
|
+
},
|
|
696
|
+
signal => {
|
|
697
|
+
if (inputs instanceof EmptyBlockRootRollupInputs) {
|
|
698
|
+
return this.prover.getEmptyBlockRootRollupProof(inputs, signal, provingState.epochNumber);
|
|
699
|
+
} else if (inputs instanceof SingleTxBlockRootRollupInputs) {
|
|
700
|
+
return this.prover.getSingleTxBlockRootRollupProof(inputs, signal, provingState.epochNumber);
|
|
701
|
+
} else {
|
|
702
|
+
return this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber);
|
|
703
|
+
}
|
|
929
704
|
},
|
|
930
|
-
signal => this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
931
705
|
),
|
|
932
706
|
result => {
|
|
933
|
-
|
|
707
|
+
provingState.setBlockRootRollupProof(result);
|
|
708
|
+
const header = provingState.buildHeaderFromProvingOutputs(logger);
|
|
934
709
|
if (!header.hash().equals(provingState.block!.header.hash())) {
|
|
935
710
|
logger.error(
|
|
936
711
|
`Block header mismatch\nCircuit:${inspect(header)}\nComputed:${inspect(provingState.block!.header)}`,
|
|
@@ -938,29 +713,16 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
938
713
|
provingState.reject(`Block header hash mismatch`);
|
|
939
714
|
}
|
|
940
715
|
|
|
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}`);
|
|
716
|
+
logger.debug(`Completed ${rollupType} proof for block ${provingState.block!.number}`);
|
|
956
717
|
// validatePartialState(result.inputs.end, tx.treeSnapshots); // TODO(palla/prover)
|
|
957
718
|
|
|
958
|
-
const
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
719
|
+
const epochProvingState = this.provingState!;
|
|
720
|
+
const leafLocation = epochProvingState.setBlockRootRollupProof(provingState.index, result);
|
|
721
|
+
if (epochProvingState.totalNumBlocks === 1) {
|
|
722
|
+
this.enqueueEpochPadding(epochProvingState);
|
|
723
|
+
} else {
|
|
724
|
+
this.checkAndEnqueueNextBlockMergeRollup(epochProvingState, leafLocation);
|
|
725
|
+
}
|
|
964
726
|
},
|
|
965
727
|
);
|
|
966
728
|
}
|
|
@@ -968,6 +730,11 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
968
730
|
// Executes the base parity circuit and stores the intermediate state for the root parity circuit
|
|
969
731
|
// Enqueues the root parity circuit if all inputs are available
|
|
970
732
|
private enqueueBaseParityCircuit(provingState: BlockProvingState, inputs: BaseParityInputs, index: number) {
|
|
733
|
+
if (!provingState.verifyState()) {
|
|
734
|
+
logger.debug('Not running base parity. State no longer valid.');
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
|
|
971
738
|
this.deferredProving(
|
|
972
739
|
provingState,
|
|
973
740
|
wrapCallbackInSpan(
|
|
@@ -980,29 +747,30 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
980
747
|
signal => this.prover.getBaseParityProof(inputs, signal, provingState.epochNumber),
|
|
981
748
|
),
|
|
982
749
|
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
|
-
}
|
|
750
|
+
provingState.setBaseParityProof(index, provingOutput);
|
|
751
|
+
this.checkAndEnqueueRootParityCircuit(provingState);
|
|
999
752
|
},
|
|
1000
753
|
);
|
|
1001
754
|
}
|
|
1002
755
|
|
|
756
|
+
private checkAndEnqueueRootParityCircuit(provingState: BlockProvingState) {
|
|
757
|
+
if (!provingState.isReadyForRootParity()) {
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
this.enqueueRootParityCircuit(provingState);
|
|
762
|
+
}
|
|
763
|
+
|
|
1003
764
|
// Runs the root parity circuit ans stored the outputs
|
|
1004
765
|
// Enqueues the root rollup proof if all inputs are available
|
|
1005
|
-
private enqueueRootParityCircuit(provingState: BlockProvingState
|
|
766
|
+
private enqueueRootParityCircuit(provingState: BlockProvingState) {
|
|
767
|
+
if (!provingState.verifyState()) {
|
|
768
|
+
logger.debug('Not running root parity. State no longer valid.');
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
const inputs = provingState.getRootParityInputs();
|
|
773
|
+
|
|
1006
774
|
this.deferredProving(
|
|
1007
775
|
provingState,
|
|
1008
776
|
wrapCallbackInSpan(
|
|
@@ -1014,14 +782,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1014
782
|
},
|
|
1015
783
|
signal => this.prover.getRootParityProof(inputs, signal, provingState.epochNumber),
|
|
1016
784
|
),
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
provingOutput.proof,
|
|
1020
|
-
provingOutput.verificationKey.keyAsFields,
|
|
1021
|
-
getVKSiblingPath(getVKIndex(provingOutput.verificationKey)),
|
|
1022
|
-
provingOutput.inputs,
|
|
1023
|
-
);
|
|
1024
|
-
provingState!.finalRootParityInput = rootParityInput;
|
|
785
|
+
result => {
|
|
786
|
+
provingState.setRootParityProof(result);
|
|
1025
787
|
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
1026
788
|
},
|
|
1027
789
|
);
|
|
@@ -1029,16 +791,13 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1029
791
|
|
|
1030
792
|
// Executes the block merge rollup circuit and stored the output as intermediate state for the parent merge/block root circuit
|
|
1031
793
|
// 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
|
-
);
|
|
794
|
+
private enqueueBlockMergeRollup(provingState: EpochProvingState, location: TreeNodeLocation) {
|
|
795
|
+
if (!provingState.verifyState()) {
|
|
796
|
+
logger.debug('Not running block merge rollup. State no longer valid.');
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
const inputs = provingState.getBlockMergeRollupInputs(location);
|
|
1042
801
|
|
|
1043
802
|
this.deferredProving(
|
|
1044
803
|
provingState,
|
|
@@ -1052,34 +811,51 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1052
811
|
signal => this.prover.getBlockMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
1053
812
|
),
|
|
1054
813
|
result => {
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
814
|
+
provingState.setBlockMergeRollupProof(location, result);
|
|
815
|
+
this.checkAndEnqueueNextBlockMergeRollup(provingState, location);
|
|
816
|
+
},
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
private enqueueEpochPadding(provingState: EpochProvingState) {
|
|
821
|
+
if (!provingState.verifyState()) {
|
|
822
|
+
logger.debug('Not running epoch padding. State no longer valid.');
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
logger.debug('Padding epoch proof with an empty block root proof.');
|
|
827
|
+
|
|
828
|
+
const inputs = provingState.getPaddingBlockRootInputs(this.proverId);
|
|
829
|
+
|
|
830
|
+
this.deferredProving(
|
|
831
|
+
provingState,
|
|
832
|
+
wrapCallbackInSpan(
|
|
833
|
+
this.tracer,
|
|
834
|
+
'ProvingOrchestrator.prover.getEmptyBlockRootRollupProof',
|
|
835
|
+
{
|
|
836
|
+
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
837
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'empty-block-root-rollup' satisfies CircuitName,
|
|
838
|
+
},
|
|
839
|
+
signal => this.prover.getEmptyBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
840
|
+
),
|
|
841
|
+
result => {
|
|
842
|
+
logger.debug('Completed proof for padding block root.');
|
|
843
|
+
provingState.setPaddingBlockRootProof(result);
|
|
844
|
+
this.checkAndEnqueueRootRollup(provingState);
|
|
1060
845
|
},
|
|
1061
846
|
);
|
|
1062
847
|
}
|
|
1063
848
|
|
|
1064
849
|
// Executes the root rollup circuit
|
|
1065
|
-
private enqueueRootRollup(provingState: EpochProvingState
|
|
1066
|
-
if (!provingState
|
|
850
|
+
private enqueueRootRollup(provingState: EpochProvingState) {
|
|
851
|
+
if (!provingState.verifyState()) {
|
|
1067
852
|
logger.debug('Not running root rollup, state no longer valid');
|
|
1068
853
|
return;
|
|
1069
854
|
}
|
|
1070
855
|
|
|
1071
856
|
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
|
-
);
|
|
857
|
+
|
|
858
|
+
const inputs = provingState.getRootRollupInputs(this.proverId);
|
|
1083
859
|
|
|
1084
860
|
this.deferredProving(
|
|
1085
861
|
provingState,
|
|
@@ -1094,15 +870,27 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1094
870
|
),
|
|
1095
871
|
result => {
|
|
1096
872
|
logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1097
|
-
provingState.
|
|
1098
|
-
provingState.finalProof = result.proof.binaryProof;
|
|
873
|
+
provingState.setRootRollupProof(result);
|
|
1099
874
|
provingState.resolve({ status: 'success' });
|
|
1100
875
|
},
|
|
1101
876
|
);
|
|
1102
877
|
}
|
|
1103
878
|
|
|
879
|
+
private checkAndEnqueueNextMergeRollup(provingState: BlockProvingState, currentLocation: TreeNodeLocation) {
|
|
880
|
+
if (!provingState.isReadyForMergeRollup(currentLocation)) {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
885
|
+
if (parentLocation.level === 0) {
|
|
886
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
887
|
+
} else {
|
|
888
|
+
this.enqueueMergeRollup(provingState, parentLocation);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
1104
892
|
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
1105
|
-
if (!provingState
|
|
893
|
+
if (!provingState.isReadyForBlockRootRollup()) {
|
|
1106
894
|
logger.debug('Not ready for root rollup');
|
|
1107
895
|
return;
|
|
1108
896
|
}
|
|
@@ -1126,94 +914,26 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1126
914
|
this.enqueueBlockRootRollup(provingState);
|
|
1127
915
|
}
|
|
1128
916
|
|
|
1129
|
-
private
|
|
1130
|
-
if (!provingState
|
|
1131
|
-
logger.debug('Not ready for root rollup');
|
|
917
|
+
private checkAndEnqueueNextBlockMergeRollup(provingState: EpochProvingState, currentLocation: TreeNodeLocation) {
|
|
918
|
+
if (!provingState.isReadyForBlockMerge(currentLocation)) {
|
|
1132
919
|
return;
|
|
1133
920
|
}
|
|
1134
|
-
this.enqueueRootRollup(provingState);
|
|
1135
|
-
}
|
|
1136
921
|
|
|
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);
|
|
922
|
+
const parentLocation = provingState.getParentLocation(currentLocation);
|
|
923
|
+
if (parentLocation.level === 0) {
|
|
924
|
+
this.checkAndEnqueueRootRollup(provingState);
|
|
1169
925
|
} else {
|
|
1170
|
-
|
|
1171
|
-
this.enqueueMergeRollup(provingState, mergeLevel, indexWithinMergeLevel, nextMergeInputData);
|
|
926
|
+
this.enqueueBlockMergeRollup(provingState, parentLocation);
|
|
1172
927
|
}
|
|
1173
928
|
}
|
|
1174
929
|
|
|
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}`);
|
|
930
|
+
private checkAndEnqueueRootRollup(provingState: EpochProvingState) {
|
|
931
|
+
if (!provingState.isReadyForRootRollup()) {
|
|
932
|
+
logger.debug('Not ready for root rollup');
|
|
1208
933
|
return;
|
|
1209
934
|
}
|
|
1210
935
|
|
|
1211
|
-
|
|
1212
|
-
this.checkAndEnqueueRootRollup(provingState);
|
|
1213
|
-
} else {
|
|
1214
|
-
// onto the next merge level
|
|
1215
|
-
this.enqueueBlockMergeRollup(provingState, mergeLevel, indexWithinMergeLevel, nextMergeInputData);
|
|
1216
|
-
}
|
|
936
|
+
this.enqueueRootRollup(provingState);
|
|
1217
937
|
}
|
|
1218
938
|
|
|
1219
939
|
/**
|
|
@@ -1222,8 +942,8 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1222
942
|
* @param provingState - The proving state being operated on
|
|
1223
943
|
* @param txIndex - The index of the transaction being proven
|
|
1224
944
|
*/
|
|
1225
|
-
private enqueueVM(provingState: BlockProvingState
|
|
1226
|
-
if (!provingState
|
|
945
|
+
private enqueueVM(provingState: BlockProvingState, txIndex: number) {
|
|
946
|
+
if (!provingState.verifyState()) {
|
|
1227
947
|
logger.debug(`Not running VM circuit as state is no longer valid`);
|
|
1228
948
|
return;
|
|
1229
949
|
}
|
|
@@ -1263,7 +983,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1263
983
|
|
|
1264
984
|
this.deferredProving(provingState, doAvmProving, proofAndVk => {
|
|
1265
985
|
logger.debug(`Proven VM for tx index: ${txIndex}`);
|
|
1266
|
-
txProvingState.
|
|
986
|
+
txProvingState.setAvmProof(proofAndVk);
|
|
1267
987
|
this.checkAndEnqueueNextTxCircuit(provingState, txIndex);
|
|
1268
988
|
});
|
|
1269
989
|
}
|