@aztec/prover-client 0.43.0 → 0.45.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.
@@ -1,4 +1,5 @@
1
- import { Body, L2Block, MerkleTreeId, PublicKernelType, Tx, makeEmptyProcessedTx, makePaddingProcessedTx, toTxEffect, } from '@aztec/circuit-types';
1
+ import { __esDecorate, __runInitializers } from "tslib";
2
+ import { Body, L2Block, MerkleTreeId, PublicKernelType, Tx, makeEmptyProcessedTx, makePaddingProcessedTx, mapPublicKernelToCircuitName, toTxEffect, } from '@aztec/circuit-types';
2
3
  import { BlockProofError, PROVING_STATUS, } from '@aztec/circuit-types/interfaces';
3
4
  import { AGGREGATION_OBJECT_LENGTH, AvmCircuitInputs, BaseParityInputs, Fr, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, NUM_BASE_PARITY_PER_ROOT_PARITY, RootParityInputs, VerificationKeyData, makeEmptyProof, } from '@aztec/circuits.js';
4
5
  import { makeTuple } from '@aztec/foundation/array';
@@ -8,6 +9,7 @@ import { createDebugLogger } from '@aztec/foundation/log';
8
9
  import { promiseWithResolvers } from '@aztec/foundation/promise';
9
10
  import { BufferReader } from '@aztec/foundation/serialize';
10
11
  import { pushTestData } from '@aztec/foundation/testing';
12
+ import { Attributes, trackSpan, wrapCallbackInSpan } from '@aztec/telemetry-client';
11
13
  import { inspect } from 'util';
12
14
  import { buildBaseRollupInput, createMergeRollupInputs, getRootRollupInput, getSubtreeSiblingPath, getTreeSnapshot, validatePartialState, validateRootOutput, validateTx, } from './block-building-helpers.js';
13
15
  import { ProvingState } from './proving-state.js';
@@ -26,549 +28,638 @@ const logger = createDebugLogger('aztec:prover:proving-orchestrator');
26
28
  /**
27
29
  * The orchestrator, managing the flow of recursive proving operations required to build the rollup proof tree.
28
30
  */
29
- export class ProvingOrchestrator {
30
- constructor(db, prover, initialHeader) {
31
- this.db = db;
32
- this.prover = prover;
33
- this.initialHeader = initialHeader;
34
- this.provingState = undefined;
35
- this.pendingProvingJobs = [];
36
- this.paddingTx = undefined;
37
- }
38
- /**
39
- * Resets the orchestrator's cached padding tx.
40
- */
41
- reset() {
42
- this.paddingTx = undefined;
43
- }
44
- /**
45
- * Starts off a new block
46
- * @param numTxs - The total number of transactions in the block. Must be a power of 2
47
- * @param globalVariables - The global variables for the block
48
- * @param l1ToL2Messages - The l1 to l2 messages for the block
49
- * @param verificationKeys - The private kernel verification keys
50
- * @returns A proving ticket, containing a promise notifying of proving completion
51
- */
52
- async startNewBlock(numTxs, globalVariables, l1ToL2Messages, verificationKeys) {
53
- // Create initial header if not done so yet
54
- if (!this.initialHeader) {
55
- this.initialHeader = await this.db.buildInitialHeader();
56
- }
57
- // Check that the length of the array of txs is a power of two
58
- // See https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
59
- if (!Number.isInteger(numTxs) || numTxs < 2 || (numTxs & (numTxs - 1)) !== 0) {
60
- throw new Error(`Length of txs for the block should be a power of two and at least two (got ${numTxs})`);
61
- }
62
- // Cancel any currently proving block before starting a new one
63
- this.cancelBlock();
64
- logger.info(`Starting new block with ${numTxs} transactions`);
65
- // we start the block by enqueueing all of the base parity circuits
66
- let baseParityInputs = [];
67
- let l1ToL2MessagesPadded;
68
- try {
69
- l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
70
- }
71
- catch (err) {
72
- throw new Error('Too many L1 to L2 messages');
73
- }
74
- baseParityInputs = Array.from({ length: NUM_BASE_PARITY_PER_ROOT_PARITY }, (_, i) => BaseParityInputs.fromSlice(l1ToL2MessagesPadded, i));
75
- const messageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, this.db);
76
- const newL1ToL2MessageTreeRootSiblingPathArray = await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, this.db);
77
- const newL1ToL2MessageTreeRootSiblingPath = makeTuple(L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, i => i < newL1ToL2MessageTreeRootSiblingPathArray.length ? newL1ToL2MessageTreeRootSiblingPathArray[i] : Fr.ZERO, 0);
78
- // Update the local trees to include the new l1 to l2 messages
79
- await this.db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
80
- const { promise: _promise, resolve, reject } = promiseWithResolvers();
81
- const promise = _promise.catch((reason) => ({
82
- status: PROVING_STATUS.FAILURE,
83
- reason,
84
- }));
85
- const provingState = new ProvingState(numTxs, resolve, reject, globalVariables, l1ToL2MessagesPadded, baseParityInputs.length, messageTreeSnapshot, newL1ToL2MessageTreeRootSiblingPath, verificationKeys);
86
- for (let i = 0; i < baseParityInputs.length; i++) {
87
- this.enqueueBaseParityCircuit(provingState, baseParityInputs[i], i);
88
- }
89
- this.provingState = provingState;
90
- const ticket = {
91
- provingPromise: promise,
92
- };
93
- return ticket;
94
- }
95
- /**
96
- * The interface to add a simulated transaction to the scheduler
97
- * @param tx - The transaction to be proven
98
- */
99
- async addNewTx(tx) {
100
- if (!this.provingState) {
101
- throw new Error(`Invalid proving state, call startNewBlock before adding transactions`);
102
- }
103
- if (!this.provingState.isAcceptingTransactions()) {
104
- throw new Error(`Rollup not accepting further transactions`);
105
- }
106
- validateTx(tx);
107
- logger.info(`Received transaction: ${tx.hash}`);
108
- const [inputs, treeSnapshots] = await this.prepareTransaction(tx, this.provingState);
109
- this.enqueueFirstProof(inputs, treeSnapshots, tx, this.provingState);
110
- }
111
- /**
112
- * Marks the block as full and pads it to the full power of 2 block size, no more transactions will be accepted.
113
- */
114
- async setBlockCompleted() {
115
- if (!this.provingState) {
116
- throw new Error(`Invalid proving state, call startNewBlock before adding transactions or completing the block`);
117
- }
118
- // we may need to pad the rollup with empty transactions
119
- const paddingTxCount = this.provingState.totalNumTxs - this.provingState.transactionsReceived;
120
- if (paddingTxCount === 0) {
121
- return;
122
- }
123
- logger.debug(`Padding rollup with ${paddingTxCount} empty transactions`);
124
- // Make an empty padding transaction
125
- // Insert it into the tree the required number of times to get all of the
126
- // base rollup inputs
127
- // Then enqueue the proving of all the transactions
128
- const unprovenPaddingTx = makeEmptyProcessedTx(this.initialHeader ?? (await this.db.buildInitialHeader()), this.provingState.globalVariables.chainId, this.provingState.globalVariables.version);
129
- const txInputs = [];
130
- for (let i = 0; i < paddingTxCount; i++) {
131
- const [inputs, snapshot] = await this.prepareTransaction(unprovenPaddingTx, this.provingState);
132
- const txInput = {
133
- inputs,
134
- snapshot,
135
- };
136
- txInputs.push(txInput);
137
- }
138
- // Now enqueue the proving
139
- this.enqueuePaddingTxs(this.provingState, txInputs, unprovenPaddingTx);
140
- }
141
- // Enqueues the proving of the required padding transactions
142
- // If the fully proven padding transaction is not available, this will first be proven
143
- enqueuePaddingTxs(provingState, txInputs, unprovenPaddingTx) {
144
- if (this.paddingTx) {
145
- // We already have the padding transaction
146
- logger.debug(`Enqueuing ${txInputs.length} padding transactions using existing padding tx`);
147
- this.provePaddingTransactions(txInputs, this.paddingTx, provingState);
148
- return;
149
- }
150
- logger.debug(`Enqueuing deferred proving for padding txs to enqueue ${txInputs.length} paddings`);
151
- this.deferredProving(provingState, signal => this.prover.getEmptyPrivateKernelProof({
152
- // Chain id and version should not change even if the proving state does, so it's safe to use them for the padding tx
153
- // which gets cached across multiple runs of the orchestrator with different proving states. If they were to change,
154
- // we'd have to clear out the paddingTx here and regenerate it when they do.
155
- chainId: unprovenPaddingTx.data.constants.txContext.chainId,
156
- version: unprovenPaddingTx.data.constants.txContext.version,
157
- header: unprovenPaddingTx.data.constants.historicalHeader,
158
- }, signal), result => {
159
- logger.debug(`Completed proof for padding tx, now enqueuing ${txInputs.length} padding txs`);
160
- this.paddingTx = makePaddingProcessedTx(result);
161
- this.provePaddingTransactions(txInputs, this.paddingTx, provingState);
162
- });
163
- }
164
- /**
165
- * Prepares the cached sets of base rollup inputs for padding transactions and proves them
166
- * @param txInputs - The base rollup inputs, start and end hash paths etc
167
- * @param paddingTx - The padding tx, contains the header, proof, vk, public inputs used in the proof
168
- * @param provingState - The block proving state
169
- */
170
- provePaddingTransactions(txInputs, paddingTx, provingState) {
171
- // The padding tx contains the proof and vk, generated separately from the base inputs
172
- // Copy these into the base rollup inputs
173
- for (let i = 0; i < txInputs.length; i++) {
174
- txInputs[i].inputs.kernelData.vk = paddingTx.verificationKey;
175
- txInputs[i].inputs.kernelData.proof = paddingTx.recursiveProof;
176
- this.enqueueFirstProof(txInputs[i].inputs, txInputs[i].snapshot, paddingTx, provingState);
177
- }
178
- }
179
- /**
180
- * Cancel any further proving of the block
181
- */
182
- cancelBlock() {
183
- for (const controller of this.pendingProvingJobs) {
184
- controller.abort();
185
- }
186
- this.provingState?.cancel();
187
- }
188
- /**
189
- * Performs the final tree update for the block and returns the fully proven block.
190
- * @returns The fully proven block and proof.
191
- */
192
- async finaliseBlock() {
193
- try {
194
- if (!this.provingState ||
195
- !this.provingState.rootRollupPublicInputs ||
196
- !this.provingState.finalProof ||
197
- !this.provingState.finalAggregationObject) {
198
- throw new Error(`Invalid proving state, a block must be proven before it can be finalised`);
31
+ let ProvingOrchestrator = (() => {
32
+ var _a;
33
+ let _instanceExtraInitializers = [];
34
+ let _startNewBlock_decorators;
35
+ let _addNewTx_decorators;
36
+ let _setBlockCompleted_decorators;
37
+ let _finaliseBlock_decorators;
38
+ let _prepareBaseRollupInputs_decorators;
39
+ return _a = class ProvingOrchestrator {
40
+ constructor(db, prover, telemetryClient, initialHeader) {
41
+ this.db = (__runInitializers(this, _instanceExtraInitializers), db);
42
+ this.prover = prover;
43
+ this.initialHeader = initialHeader;
44
+ this.provingState = undefined;
45
+ this.pendingProvingJobs = [];
46
+ this.paddingTx = undefined;
47
+ this.tracer = telemetryClient.getTracer('ProvingOrchestrator');
199
48
  }
200
- if (this.provingState.block) {
201
- throw new Error('Block already finalised');
49
+ /**
50
+ * Resets the orchestrator's cached padding tx.
51
+ */
52
+ reset() {
53
+ this.paddingTx = undefined;
202
54
  }
203
- const rootRollupOutputs = this.provingState.rootRollupPublicInputs;
204
- logger?.debug(`Updating and validating root trees`);
205
- await this.db.updateArchive(rootRollupOutputs.header);
206
- await validateRootOutput(rootRollupOutputs, this.db);
207
- // Collect all new nullifiers, commitments, and contracts from all txs in this block
208
- const gasFees = this.provingState.globalVariables.gasFees;
209
- const nonEmptyTxEffects = this.provingState.allTxs.map(txProvingState => toTxEffect(txProvingState.processedTx, gasFees)).filter(txEffect => !txEffect.isEmpty());
210
- const blockBody = new Body(nonEmptyTxEffects);
211
- const l2Block = L2Block.fromFields({
212
- archive: rootRollupOutputs.archive,
213
- header: rootRollupOutputs.header,
214
- body: blockBody,
215
- });
216
- if (!l2Block.body.getTxsEffectsHash().equals(rootRollupOutputs.header.contentCommitment.txsEffectsHash)) {
217
- logger.debug(inspect(blockBody));
218
- throw new Error(`Txs effects hash mismatch, ${l2Block.body
219
- .getTxsEffectsHash()
220
- .toString('hex')} == ${rootRollupOutputs.header.contentCommitment.txsEffectsHash.toString('hex')} `);
55
+ /**
56
+ * Starts off a new block
57
+ * @param numTxs - The total number of transactions in the block. Must be a power of 2
58
+ * @param globalVariables - The global variables for the block
59
+ * @param l1ToL2Messages - The l1 to l2 messages for the block
60
+ * @param verificationKeys - The private kernel verification keys
61
+ * @returns A proving ticket, containing a promise notifying of proving completion
62
+ */
63
+ async startNewBlock(numTxs, globalVariables, l1ToL2Messages, verificationKeys) {
64
+ // Create initial header if not done so yet
65
+ if (!this.initialHeader) {
66
+ this.initialHeader = await this.db.buildInitialHeader();
67
+ }
68
+ if (!Number.isInteger(numTxs) || numTxs < 2) {
69
+ throw new Error(`Length of txs for the block should be at least two (got ${numTxs})`);
70
+ }
71
+ // Cancel any currently proving block before starting a new one
72
+ this.cancelBlock();
73
+ logger.info(`Starting new block with ${numTxs} transactions`);
74
+ // we start the block by enqueueing all of the base parity circuits
75
+ let baseParityInputs = [];
76
+ let l1ToL2MessagesPadded;
77
+ try {
78
+ l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
79
+ }
80
+ catch (err) {
81
+ throw new Error('Too many L1 to L2 messages');
82
+ }
83
+ baseParityInputs = Array.from({ length: NUM_BASE_PARITY_PER_ROOT_PARITY }, (_, i) => BaseParityInputs.fromSlice(l1ToL2MessagesPadded, i));
84
+ const messageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, this.db);
85
+ const newL1ToL2MessageTreeRootSiblingPathArray = await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, this.db);
86
+ const newL1ToL2MessageTreeRootSiblingPath = makeTuple(L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, i => i < newL1ToL2MessageTreeRootSiblingPathArray.length ? newL1ToL2MessageTreeRootSiblingPathArray[i] : Fr.ZERO, 0);
87
+ // Update the local trees to include the new l1 to l2 messages
88
+ await this.db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
89
+ const { promise: _promise, resolve, reject } = promiseWithResolvers();
90
+ const promise = _promise.catch((reason) => ({
91
+ status: PROVING_STATUS.FAILURE,
92
+ reason,
93
+ }));
94
+ const provingState = new ProvingState(numTxs, resolve, reject, globalVariables, l1ToL2MessagesPadded, baseParityInputs.length, messageTreeSnapshot, newL1ToL2MessageTreeRootSiblingPath, verificationKeys);
95
+ for (let i = 0; i < baseParityInputs.length; i++) {
96
+ this.enqueueBaseParityCircuit(provingState, baseParityInputs[i], i);
97
+ }
98
+ this.provingState = provingState;
99
+ const ticket = {
100
+ provingPromise: promise,
101
+ };
102
+ return ticket;
221
103
  }
222
- logger.info(`Successfully proven block ${l2Block.number}!`);
223
- this.provingState.block = l2Block;
224
- const blockResult = {
225
- proof: this.provingState.finalProof,
226
- aggregationObject: this.provingState.finalAggregationObject,
227
- block: l2Block,
228
- };
229
- pushTestData('blockResults', {
230
- block: l2Block.toString(),
231
- proof: this.provingState.finalProof.toString(),
232
- aggregationObject: blockResult.aggregationObject.map(x => x.toString()),
233
- });
234
- return blockResult;
235
- }
236
- catch (err) {
237
- throw new BlockProofError(err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err), this.provingState?.allTxs.map(x => Tx.getHash(x.processedTx)) ?? []);
238
- }
239
- }
240
- /**
241
- * Starts the proving process for the given transaction and adds it to our state
242
- * @param tx - The transaction whose proving we wish to commence
243
- * @param provingState - The proving state being worked on
244
- */
245
- async prepareTransaction(tx, provingState) {
246
- // Pass the private kernel tail vk here as the previous one.
247
- // If there are public functions then this key will be overwritten once the public tail has been proven
248
- const previousKernelVerificationKey = provingState.privateKernelVerificationKeys.privateKernelCircuit;
249
- const txInputs = await this.prepareBaseRollupInputs(provingState, tx, previousKernelVerificationKey);
250
- if (!txInputs) {
251
- // This should not be possible
252
- throw new Error(`Unable to add padding transaction, preparing base inputs failed`);
253
- }
254
- return txInputs;
255
- }
256
- enqueueFirstProof(inputs, treeSnapshots, tx, provingState) {
257
- const txProvingState = new TxProvingState(tx, inputs, treeSnapshots, provingState.privateKernelVerificationKeys.privateKernelToPublicCircuit);
258
- const txIndex = provingState.addNewTx(txProvingState);
259
- const numPublicKernels = txProvingState.getNumPublicKernels();
260
- if (!numPublicKernels) {
261
- // no public functions, go straight to the base rollup
262
- logger.debug(`Enqueueing base rollup for tx ${txIndex}`);
263
- this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
264
- return;
265
- }
266
- // Enqueue all of the VM/kernel proving requests
267
- // Rather than handle the Kernel Tail as a special case here, we will just handle it inside enqueueVM
268
- for (let i = 0; i < numPublicKernels; i++) {
269
- logger.debug(`Enqueueing public VM ${i} for tx ${txIndex}`);
270
- this.enqueueVM(provingState, txIndex, i);
271
- }
272
- }
273
- /**
274
- * Enqueue a job to be scheduled
275
- * @param provingState - The proving state object being operated on
276
- * @param jobType - The type of job to be queued
277
- * @param job - The actual job, returns a promise notifying of the job's completion
278
- */
279
- deferredProving(provingState, request, callback) {
280
- if (!provingState?.verifyState()) {
281
- logger.debug(`Not enqueuing job, state no longer valid`);
282
- return;
283
- }
284
- const controller = new AbortController();
285
- this.pendingProvingJobs.push(controller);
286
- // We use a 'safeJob'. We don't want promise rejections in the proving pool, we want to capture the error here
287
- // and reject the proving job whilst keeping the event loop free of rejections
288
- const safeJob = async () => {
289
- try {
290
- // there's a delay between enqueueing this job and it actually running
291
- if (controller.signal.aborted) {
292
- return;
104
+ /**
105
+ * The interface to add a simulated transaction to the scheduler
106
+ * @param tx - The transaction to be proven
107
+ */
108
+ async addNewTx(tx) {
109
+ if (!this.provingState) {
110
+ throw new Error(`Invalid proving state, call startNewBlock before adding transactions`);
293
111
  }
294
- const result = await request(controller.signal);
295
- if (!provingState?.verifyState()) {
296
- logger.debug(`State no longer valid, discarding result`);
112
+ if (!this.provingState.isAcceptingTransactions()) {
113
+ throw new Error(`Rollup not accepting further transactions`);
114
+ }
115
+ validateTx(tx);
116
+ logger.info(`Received transaction: ${tx.hash}`);
117
+ if (tx.isEmpty) {
118
+ logger.warn(`Ignoring empty transaction ${tx.hash} - it will not be added to this block`);
297
119
  return;
298
120
  }
299
- // we could have been cancelled whilst waiting for the result
300
- // and the prover ignored the signal. Drop the result in that case
301
- if (controller.signal.aborted) {
121
+ const [inputs, treeSnapshots] = await this.prepareTransaction(tx, this.provingState);
122
+ this.enqueueFirstProof(inputs, treeSnapshots, tx, this.provingState);
123
+ }
124
+ /**
125
+ * Marks the block as full and pads it if required, no more transactions will be accepted.
126
+ */
127
+ async setBlockCompleted() {
128
+ if (!this.provingState) {
129
+ throw new Error(`Invalid proving state, call startNewBlock before adding transactions or completing the block`);
130
+ }
131
+ // we may need to pad the rollup with empty transactions
132
+ const paddingTxCount = this.provingState.totalNumTxs - this.provingState.transactionsReceived;
133
+ if (paddingTxCount === 0) {
302
134
  return;
303
135
  }
304
- await callback(result);
136
+ else if (this.provingState.totalNumTxs > 2) {
137
+ throw new Error(`Block not ready for completion: expecting ${paddingTxCount} more transactions.`);
138
+ }
139
+ logger.debug(`Padding rollup with ${paddingTxCount} empty transactions`);
140
+ // Make an empty padding transaction
141
+ // Required for:
142
+ // 0 (when we want an empty block, largely for testing), or
143
+ // 1 (we need to pad with one tx as all rollup circuits require a pair of inputs) txs
144
+ // Insert it into the tree the required number of times to get all of the
145
+ // base rollup inputs
146
+ // Then enqueue the proving of all the transactions
147
+ const unprovenPaddingTx = makeEmptyProcessedTx(this.initialHeader ?? (await this.db.buildInitialHeader()), this.provingState.globalVariables.chainId, this.provingState.globalVariables.version);
148
+ const txInputs = [];
149
+ for (let i = 0; i < paddingTxCount; i++) {
150
+ const [inputs, snapshot] = await this.prepareTransaction(unprovenPaddingTx, this.provingState);
151
+ const txInput = {
152
+ inputs,
153
+ snapshot,
154
+ };
155
+ txInputs.push(txInput);
156
+ }
157
+ // Now enqueue the proving
158
+ this.enqueuePaddingTxs(this.provingState, txInputs, unprovenPaddingTx);
305
159
  }
306
- catch (err) {
307
- if (err instanceof AbortError) {
308
- // operation was cancelled, probably because the block was cancelled
309
- // drop this result
160
+ // Enqueues the proving of the required padding transactions
161
+ // If the fully proven padding transaction is not available, this will first be proven
162
+ enqueuePaddingTxs(provingState, txInputs, unprovenPaddingTx) {
163
+ if (this.paddingTx) {
164
+ // We already have the padding transaction
165
+ logger.debug(`Enqueuing ${txInputs.length} padding transactions using existing padding tx`);
166
+ this.provePaddingTransactions(txInputs, this.paddingTx, provingState);
310
167
  return;
311
168
  }
312
- logger.error(`Error thrown when proving job`);
313
- provingState.reject(`${err}`);
169
+ logger.debug(`Enqueuing deferred proving for padding txs to enqueue ${txInputs.length} paddings`);
170
+ this.deferredProving(provingState, wrapCallbackInSpan(this.tracer, 'ProvingOrchestrator.prover.getEmptyPrivateKernelProof', {
171
+ [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
172
+ [Attributes.PROTOCOL_CIRCUIT_NAME]: 'private-kernel-empty',
173
+ }, signal => this.prover.getEmptyPrivateKernelProof({
174
+ // Chain id and version should not change even if the proving state does, so it's safe to use them for the padding tx
175
+ // which gets cached across multiple runs of the orchestrator with different proving states. If they were to change,
176
+ // we'd have to clear out the paddingTx here and regenerate it when they do.
177
+ chainId: unprovenPaddingTx.data.constants.txContext.chainId,
178
+ version: unprovenPaddingTx.data.constants.txContext.version,
179
+ header: unprovenPaddingTx.data.constants.historicalHeader,
180
+ }, signal)), result => {
181
+ logger.debug(`Completed proof for padding tx, now enqueuing ${txInputs.length} padding txs`);
182
+ this.paddingTx = makePaddingProcessedTx(result);
183
+ this.provePaddingTransactions(txInputs, this.paddingTx, provingState);
184
+ });
314
185
  }
315
- finally {
316
- const index = this.pendingProvingJobs.indexOf(controller);
317
- if (index > -1) {
318
- this.pendingProvingJobs.splice(index, 1);
186
+ /**
187
+ * Prepares the cached sets of base rollup inputs for padding transactions and proves them
188
+ * @param txInputs - The base rollup inputs, start and end hash paths etc
189
+ * @param paddingTx - The padding tx, contains the header, proof, vk, public inputs used in the proof
190
+ * @param provingState - The block proving state
191
+ */
192
+ provePaddingTransactions(txInputs, paddingTx, provingState) {
193
+ // The padding tx contains the proof and vk, generated separately from the base inputs
194
+ // Copy these into the base rollup inputs
195
+ for (let i = 0; i < txInputs.length; i++) {
196
+ txInputs[i].inputs.kernelData.vk = paddingTx.verificationKey;
197
+ txInputs[i].inputs.kernelData.proof = paddingTx.recursiveProof;
198
+ this.enqueueFirstProof(txInputs[i].inputs, txInputs[i].snapshot, paddingTx, provingState);
319
199
  }
320
200
  }
321
- };
322
- // let the callstack unwind before adding the job to the queue
323
- setImmediate(safeJob);
324
- }
325
- // Updates the merkle trees for a transaction. The first enqueued job for a transaction
326
- async prepareBaseRollupInputs(provingState, tx, kernelVk) {
327
- if (!provingState?.verifyState()) {
328
- logger.debug('Not preparing base rollup inputs, state invalid');
329
- return;
330
- }
331
- const inputs = await buildBaseRollupInput(tx, provingState.globalVariables, this.db, kernelVk);
332
- const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(async (id) => {
333
- return { key: id, value: await getTreeSnapshot(id, this.db) };
334
- });
335
- const treeSnapshots = new Map((await Promise.all(promises)).map(obj => [obj.key, obj.value]));
336
- if (!provingState?.verifyState()) {
337
- logger.debug(`Discarding proving job, state no longer valid`);
338
- return;
339
- }
340
- return [inputs, treeSnapshots];
341
- }
342
- // Stores the intermediate inputs prepared for a merge proof
343
- storeMergeInputs(provingState, currentLevel, currentIndex, mergeInputs) {
344
- const mergeLevel = currentLevel - 1n;
345
- const indexWithinMergeLevel = currentIndex >> 1n;
346
- const mergeIndex = 2n ** mergeLevel - 1n + indexWithinMergeLevel;
347
- const subscript = Number(mergeIndex);
348
- const indexWithinMerge = Number(currentIndex & 1n);
349
- const ready = provingState.storeMergeInputs(mergeInputs, indexWithinMerge, subscript);
350
- return { ready, indexWithinMergeLevel, mergeLevel, mergeInputData: provingState.getMergeInputs(subscript) };
351
- }
352
- // Executes the base rollup circuit and stored the output as intermediate state for the parent merge/root circuit
353
- // Executes the next level of merge if all inputs are available
354
- enqueueBaseRollup(provingState, index, tx) {
355
- if (!provingState?.verifyState()) {
356
- logger.debug('Not running base rollup, state invalid');
357
- return;
358
- }
359
- if (!tx.baseRollupInputs.kernelData.publicInputs.end.noteEncryptedLogsHash
360
- .toBuffer()
361
- .equals(tx.processedTx.noteEncryptedLogs.hash())) {
362
- provingState.reject(`Note encrypted logs hash mismatch: ${tx.baseRollupInputs.kernelData.publicInputs.end.noteEncryptedLogsHash} === ${Fr.fromBuffer(tx.processedTx.noteEncryptedLogs.hash())}`);
363
- return;
364
- }
365
- if (!tx.baseRollupInputs.kernelData.publicInputs.end.encryptedLogsHash
366
- .toBuffer()
367
- .equals(tx.processedTx.encryptedLogs.hash())) {
368
- // @todo This rejection messages is never seen. Never making it out to the logs
369
- provingState.reject(`Encrypted logs hash mismatch: ${tx.baseRollupInputs.kernelData.publicInputs.end.encryptedLogsHash} === ${Fr.fromBuffer(tx.processedTx.encryptedLogs.hash())}`);
370
- return;
371
- }
372
- if (!tx.baseRollupInputs.kernelData.publicInputs.end.unencryptedLogsHash
373
- .toBuffer()
374
- .equals(tx.processedTx.unencryptedLogs.hash())) {
375
- provingState.reject(`Unencrypted logs hash mismatch: ${tx.baseRollupInputs.kernelData.publicInputs.end.unencryptedLogsHash} === ${Fr.fromBuffer(tx.processedTx.unencryptedLogs.hash())}`);
376
- return;
377
- }
378
- logger.debug(`Enqueuing deferred proving base rollup${tx.processedTx.isEmpty ? ' with padding tx' : ''} for ${tx.processedTx.hash.toString()}`);
379
- this.deferredProving(provingState, signal => this.prover.getBaseRollupProof(tx.baseRollupInputs, signal), result => {
380
- logger.debug(`Completed proof for base rollup for tx ${tx.processedTx.hash.toString()}`);
381
- validatePartialState(result.inputs.end, tx.treeSnapshots);
382
- const currentLevel = provingState.numMergeLevels + 1n;
383
- this.storeAndExecuteNextMergeLevel(provingState, currentLevel, index, [
384
- result.inputs,
385
- result.proof,
386
- result.verificationKey.keyAsFields,
387
- ]);
388
- });
389
- }
390
- // Executes the merge rollup circuit and stored the output as intermediate state for the parent merge/root circuit
391
- // Enqueues the next level of merge if all inputs are available
392
- enqueueMergeRollup(provingState, level, index, mergeInputData) {
393
- const inputs = createMergeRollupInputs([mergeInputData.inputs[0], mergeInputData.proofs[0], mergeInputData.verificationKeys[0]], [mergeInputData.inputs[1], mergeInputData.proofs[1], mergeInputData.verificationKeys[1]]);
394
- this.deferredProving(provingState, signal => this.prover.getMergeRollupProof(inputs, signal), result => {
395
- this.storeAndExecuteNextMergeLevel(provingState, level, index, [
396
- result.inputs,
397
- result.proof,
398
- result.verificationKey.keyAsFields,
399
- ]);
400
- });
401
- }
402
- // Executes the root rollup circuit
403
- async enqueueRootRollup(provingState) {
404
- if (!provingState?.verifyState()) {
405
- logger.debug('Not running root rollup, state no longer valid');
406
- return;
407
- }
408
- const mergeInputData = provingState.getMergeInputs(0);
409
- const rootParityInput = provingState.finalRootParityInput;
410
- const inputs = await getRootRollupInput(mergeInputData.inputs[0], mergeInputData.proofs[0], mergeInputData.verificationKeys[0], mergeInputData.inputs[1], mergeInputData.proofs[1], mergeInputData.verificationKeys[1], rootParityInput, provingState.newL1ToL2Messages, provingState.messageTreeSnapshot, provingState.messageTreeRootSiblingPath, this.db);
411
- this.deferredProving(provingState, signal => this.prover.getRootRollupProof(inputs, signal), result => {
412
- provingState.rootRollupPublicInputs = result.inputs;
413
- provingState.finalAggregationObject = extractAggregationObject(result.proof.binaryProof, result.verificationKey.numPublicInputs);
414
- provingState.finalProof = result.proof.binaryProof;
415
- const provingResult = {
416
- status: PROVING_STATUS.SUCCESS,
417
- };
418
- provingState.resolve(provingResult);
419
- });
420
- }
421
- // Executes the base parity circuit and stores the intermediate state for the root parity circuit
422
- // Enqueues the root parity circuit if all inputs are available
423
- enqueueBaseParityCircuit(provingState, inputs, index) {
424
- this.deferredProving(provingState, signal => this.prover.getBaseParityProof(inputs, signal), rootInput => {
425
- provingState.setRootParityInputs(rootInput, index);
426
- if (provingState.areRootParityInputsReady()) {
427
- const rootParityInputs = new RootParityInputs(provingState.rootParityInput);
428
- this.enqueueRootParityCircuit(provingState, rootParityInputs);
201
+ /**
202
+ * Cancel any further proving of the block
203
+ */
204
+ cancelBlock() {
205
+ for (const controller of this.pendingProvingJobs) {
206
+ controller.abort();
207
+ }
208
+ this.provingState?.cancel();
429
209
  }
430
- });
431
- }
432
- // Runs the root parity circuit ans stored the outputs
433
- // Enqueues the root rollup proof if all inputs are available
434
- enqueueRootParityCircuit(provingState, inputs) {
435
- this.deferredProving(provingState, signal => this.prover.getRootParityProof(inputs, signal), async (rootInput) => {
436
- provingState.finalRootParityInput = rootInput;
437
- await this.checkAndEnqueueRootRollup(provingState);
438
- });
439
- }
440
- async checkAndEnqueueRootRollup(provingState) {
441
- if (!provingState?.isReadyForRootRollup()) {
442
- logger.debug('Not ready for root rollup');
443
- return;
444
- }
445
- await this.enqueueRootRollup(provingState);
446
- }
447
- /**
448
- * Stores the inputs to a merge/root circuit and enqueues the circuit if ready
449
- * @param provingState - The proving state being operated on
450
- * @param currentLevel - The level of the merge/root circuit
451
- * @param currentIndex - The index of the merge/root circuit
452
- * @param mergeInputData - The inputs to be stored
453
- */
454
- storeAndExecuteNextMergeLevel(provingState, currentLevel, currentIndex, mergeInputData) {
455
- const result = this.storeMergeInputs(provingState, currentLevel, currentIndex, mergeInputData);
456
- // Are we ready to execute the next circuit?
457
- if (!result.ready) {
458
- return;
459
- }
460
- if (result.mergeLevel === 0n) {
461
- // TODO (alexg) remove this `void`
462
- void this.checkAndEnqueueRootRollup(provingState);
463
- }
464
- else {
465
- // onto the next merge level
466
- this.enqueueMergeRollup(provingState, result.mergeLevel, result.indexWithinMergeLevel, result.mergeInputData);
467
- }
468
- }
469
- /**
470
- * Executes the VM circuit for a public function, will enqueue the corresponding kernel if the
471
- * previous kernel is ready
472
- * @param provingState - The proving state being operated on
473
- * @param txIndex - The index of the transaction being proven
474
- * @param functionIndex - The index of the function/kernel being proven
475
- */
476
- enqueueVM(provingState, txIndex, functionIndex) {
477
- if (!provingState?.verifyState()) {
478
- logger.debug(`Not running VM circuit as state is no longer valid`);
479
- return;
480
- }
481
- const txProvingState = provingState.getTxProvingState(txIndex);
482
- const publicFunction = txProvingState.getPublicFunctionState(functionIndex);
483
- // If there is a VM request, we need to prove it. Otherwise, continue with the kernel.
484
- if (publicFunction.vmRequest) {
485
- // This function tries to do AVM proving. If there is a failure, it fakes the proof unless AVM_PROVING_STRICT is defined.
486
- // Nothing downstream depends on the AVM proof yet. So having this mode lets us incrementally build the AVM circuit.
487
- const doAvmProving = async (signal) => {
488
- const inputs = new AvmCircuitInputs(publicFunction.vmRequest.bytecode, publicFunction.vmRequest.calldata, publicFunction.vmRequest.kernelRequest.inputs.publicCall.callStackItem.publicInputs, publicFunction.vmRequest.avmHints);
210
+ /**
211
+ * Performs the final tree update for the block and returns the fully proven block.
212
+ * @returns The fully proven block and proof.
213
+ */
214
+ async finaliseBlock() {
489
215
  try {
490
- return await this.prover.getAvmProof(inputs, signal);
216
+ if (!this.provingState ||
217
+ !this.provingState.rootRollupPublicInputs ||
218
+ !this.provingState.finalProof ||
219
+ !this.provingState.finalAggregationObject) {
220
+ throw new Error(`Invalid proving state, a block must be proven before it can be finalised`);
221
+ }
222
+ if (this.provingState.block) {
223
+ throw new Error('Block already finalised');
224
+ }
225
+ const rootRollupOutputs = this.provingState.rootRollupPublicInputs;
226
+ logger?.debug(`Updating and validating root trees`);
227
+ await this.db.updateArchive(rootRollupOutputs.header);
228
+ await validateRootOutput(rootRollupOutputs, this.db);
229
+ // Collect all new nullifiers, commitments, and contracts from all txs in this block
230
+ const gasFees = this.provingState.globalVariables.gasFees;
231
+ const nonEmptyTxEffects = this.provingState.allTxs.map(txProvingState => toTxEffect(txProvingState.processedTx, gasFees)).filter(txEffect => !txEffect.isEmpty());
232
+ const blockBody = new Body(nonEmptyTxEffects);
233
+ const l2Block = L2Block.fromFields({
234
+ archive: rootRollupOutputs.archive,
235
+ header: rootRollupOutputs.header,
236
+ body: blockBody,
237
+ });
238
+ if (!l2Block.body.getTxsEffectsHash().equals(rootRollupOutputs.header.contentCommitment.txsEffectsHash)) {
239
+ logger.debug(inspect(blockBody));
240
+ throw new Error(`Txs effects hash mismatch, ${l2Block.body
241
+ .getTxsEffectsHash()
242
+ .toString('hex')} == ${rootRollupOutputs.header.contentCommitment.txsEffectsHash.toString('hex')} `);
243
+ }
244
+ logger.info(`Successfully proven block ${l2Block.number}!`);
245
+ this.provingState.block = l2Block;
246
+ const blockResult = {
247
+ proof: this.provingState.finalProof,
248
+ aggregationObject: this.provingState.finalAggregationObject,
249
+ block: l2Block,
250
+ };
251
+ pushTestData('blockResults', {
252
+ block: l2Block.toString(),
253
+ proof: this.provingState.finalProof.toString(),
254
+ aggregationObject: blockResult.aggregationObject.map(x => x.toString()),
255
+ });
256
+ return blockResult;
491
257
  }
492
258
  catch (err) {
493
- if (process.env.AVM_PROVING_STRICT) {
494
- throw err;
259
+ throw new BlockProofError(err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err), this.provingState?.allTxs.map(x => Tx.getHash(x.processedTx)) ?? []);
260
+ }
261
+ }
262
+ /**
263
+ * Starts the proving process for the given transaction and adds it to our state
264
+ * @param tx - The transaction whose proving we wish to commence
265
+ * @param provingState - The proving state being worked on
266
+ */
267
+ async prepareTransaction(tx, provingState) {
268
+ // Pass the private kernel tail vk here as the previous one.
269
+ // If there are public functions then this key will be overwritten once the public tail has been proven
270
+ const previousKernelVerificationKey = provingState.privateKernelVerificationKeys.privateKernelCircuit;
271
+ const txInputs = await this.prepareBaseRollupInputs(provingState, tx, previousKernelVerificationKey);
272
+ if (!txInputs) {
273
+ // This should not be possible
274
+ throw new Error(`Unable to add padding transaction, preparing base inputs failed`);
275
+ }
276
+ return txInputs;
277
+ }
278
+ enqueueFirstProof(inputs, treeSnapshots, tx, provingState) {
279
+ const txProvingState = new TxProvingState(tx, inputs, treeSnapshots, provingState.privateKernelVerificationKeys.privateKernelToPublicCircuit);
280
+ const txIndex = provingState.addNewTx(txProvingState);
281
+ const numPublicKernels = txProvingState.getNumPublicKernels();
282
+ if (!numPublicKernels) {
283
+ // no public functions, go straight to the base rollup
284
+ logger.debug(`Enqueueing base rollup for tx ${txIndex}`);
285
+ this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
286
+ return;
287
+ }
288
+ // Enqueue all of the VM/kernel proving requests
289
+ // Rather than handle the Kernel Tail as a special case here, we will just handle it inside enqueueVM
290
+ for (let i = 0; i < numPublicKernels; i++) {
291
+ logger.debug(`Enqueueing public VM ${i} for tx ${txIndex}`);
292
+ this.enqueueVM(provingState, txIndex, i);
293
+ }
294
+ }
295
+ /**
296
+ * Enqueue a job to be scheduled
297
+ * @param provingState - The proving state object being operated on
298
+ * @param jobType - The type of job to be queued
299
+ * @param job - The actual job, returns a promise notifying of the job's completion
300
+ */
301
+ deferredProving(provingState, request, callback) {
302
+ if (!provingState?.verifyState()) {
303
+ logger.debug(`Not enqueuing job, state no longer valid`);
304
+ return;
305
+ }
306
+ const controller = new AbortController();
307
+ this.pendingProvingJobs.push(controller);
308
+ // We use a 'safeJob'. We don't want promise rejections in the proving pool, we want to capture the error here
309
+ // and reject the proving job whilst keeping the event loop free of rejections
310
+ const safeJob = async () => {
311
+ try {
312
+ // there's a delay between enqueueing this job and it actually running
313
+ if (controller.signal.aborted) {
314
+ return;
315
+ }
316
+ const result = await request(controller.signal);
317
+ if (!provingState?.verifyState()) {
318
+ logger.debug(`State no longer valid, discarding result`);
319
+ return;
320
+ }
321
+ // we could have been cancelled whilst waiting for the result
322
+ // and the prover ignored the signal. Drop the result in that case
323
+ if (controller.signal.aborted) {
324
+ return;
325
+ }
326
+ await callback(result);
495
327
  }
496
- else {
497
- logger.warn(`Error thrown when proving AVM circuit: ${err}`);
498
- logger.warn(`AVM_PROVING_STRICT is off, faking AVM proof and carrying on...`);
499
- return { proof: makeEmptyProof(), verificationKey: VerificationKeyData.makeFake() };
328
+ catch (err) {
329
+ if (err instanceof AbortError) {
330
+ // operation was cancelled, probably because the block was cancelled
331
+ // drop this result
332
+ return;
333
+ }
334
+ logger.error(`Error thrown when proving job`);
335
+ provingState.reject(`${err}`);
336
+ }
337
+ finally {
338
+ const index = this.pendingProvingJobs.indexOf(controller);
339
+ if (index > -1) {
340
+ this.pendingProvingJobs.splice(index, 1);
341
+ }
500
342
  }
343
+ };
344
+ // let the callstack unwind before adding the job to the queue
345
+ setImmediate(safeJob);
346
+ }
347
+ // Updates the merkle trees for a transaction. The first enqueued job for a transaction
348
+ async prepareBaseRollupInputs(provingState, tx, kernelVk) {
349
+ if (!provingState?.verifyState()) {
350
+ logger.debug('Not preparing base rollup inputs, state invalid');
351
+ return;
501
352
  }
502
- };
503
- this.deferredProving(provingState, doAvmProving, proofAndVk => {
504
- logger.debug(`Proven VM for function index ${functionIndex} of tx index ${txIndex}`);
505
- this.checkAndEnqueuePublicKernel(provingState, txIndex, functionIndex, proofAndVk.proof);
506
- });
507
- }
508
- else {
509
- this.checkAndEnqueuePublicKernel(provingState, txIndex, functionIndex, /*vmProof=*/ makeEmptyProof());
510
- }
511
- }
512
- checkAndEnqueuePublicKernel(provingState, txIndex, functionIndex, vmProof) {
513
- const txProvingState = provingState.getTxProvingState(txIndex);
514
- const kernelRequest = txProvingState.getNextPublicKernelFromVMProof(functionIndex, vmProof);
515
- if (kernelRequest.code === TX_PROVING_CODE.READY) {
516
- if (kernelRequest.function === undefined) {
517
- // Should not be possible
518
- throw new Error(`Error occurred, public function request undefined after VM proof completed`);
353
+ const inputs = await buildBaseRollupInput(tx, provingState.globalVariables, this.db, kernelVk);
354
+ const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(async (id) => {
355
+ return { key: id, value: await getTreeSnapshot(id, this.db) };
356
+ });
357
+ const treeSnapshots = new Map((await Promise.all(promises)).map(obj => [obj.key, obj.value]));
358
+ if (!provingState?.verifyState()) {
359
+ logger.debug(`Discarding proving job, state no longer valid`);
360
+ return;
361
+ }
362
+ return [inputs, treeSnapshots];
519
363
  }
520
- logger.debug(`Enqueuing kernel from VM for tx ${txIndex}, function ${functionIndex}`);
521
- this.enqueuePublicKernel(provingState, txIndex, functionIndex);
522
- }
523
- }
524
- /**
525
- * Executes the kernel circuit for a public function, will enqueue the next kernel circuit if it's VM is already proven
526
- * or the base rollup circuit if there are no more kernels to be proven
527
- * @param provingState - The proving state being operated on
528
- * @param txIndex - The index of the transaction being proven
529
- * @param functionIndex - The index of the function/kernel being proven
530
- */
531
- enqueuePublicKernel(provingState, txIndex, functionIndex) {
532
- if (!provingState?.verifyState()) {
533
- logger.debug(`Not running public kernel circuit as state is no longer valid`);
534
- return;
535
- }
536
- const txProvingState = provingState.getTxProvingState(txIndex);
537
- const request = txProvingState.getPublicFunctionState(functionIndex).publicKernelRequest;
538
- this.deferredProving(provingState, (signal) => {
539
- if (request.type === PublicKernelType.TAIL) {
540
- return this.prover.getPublicTailProof(request, signal);
364
+ // Stores the intermediate inputs prepared for a merge proof
365
+ storeMergeInputs(provingState, currentLevel, currentIndex, mergeInputs) {
366
+ const [mergeLevel, indexWithinMergeLevel, indexWithinMerge] = provingState.findMergeLevel(currentLevel, currentIndex);
367
+ const mergeIndex = 2n ** mergeLevel - 1n + indexWithinMergeLevel;
368
+ const ready = provingState.storeMergeInputs(mergeInputs, Number(indexWithinMerge), Number(mergeIndex));
369
+ return {
370
+ ready,
371
+ indexWithinMergeLevel,
372
+ mergeLevel,
373
+ mergeInputData: provingState.getMergeInputs(Number(mergeIndex)),
374
+ };
375
+ }
376
+ // Executes the base rollup circuit and stored the output as intermediate state for the parent merge/root circuit
377
+ // Executes the next level of merge if all inputs are available
378
+ enqueueBaseRollup(provingState, index, tx) {
379
+ if (!provingState?.verifyState()) {
380
+ logger.debug('Not running base rollup, state invalid');
381
+ return;
382
+ }
383
+ if (!tx.baseRollupInputs.kernelData.publicInputs.end.noteEncryptedLogsHash
384
+ .toBuffer()
385
+ .equals(tx.processedTx.noteEncryptedLogs.hash())) {
386
+ provingState.reject(`Note encrypted logs hash mismatch: ${tx.baseRollupInputs.kernelData.publicInputs.end.noteEncryptedLogsHash} === ${Fr.fromBuffer(tx.processedTx.noteEncryptedLogs.hash())}`);
387
+ return;
388
+ }
389
+ if (!tx.baseRollupInputs.kernelData.publicInputs.end.encryptedLogsHash
390
+ .toBuffer()
391
+ .equals(tx.processedTx.encryptedLogs.hash())) {
392
+ // @todo This rejection messages is never seen. Never making it out to the logs
393
+ provingState.reject(`Encrypted logs hash mismatch: ${tx.baseRollupInputs.kernelData.publicInputs.end.encryptedLogsHash} === ${Fr.fromBuffer(tx.processedTx.encryptedLogs.hash())}`);
394
+ return;
395
+ }
396
+ if (!tx.baseRollupInputs.kernelData.publicInputs.end.unencryptedLogsHash
397
+ .toBuffer()
398
+ .equals(tx.processedTx.unencryptedLogs.hash())) {
399
+ provingState.reject(`Unencrypted logs hash mismatch: ${tx.baseRollupInputs.kernelData.publicInputs.end.unencryptedLogsHash} === ${Fr.fromBuffer(tx.processedTx.unencryptedLogs.hash())}`);
400
+ return;
401
+ }
402
+ logger.debug(`Enqueuing deferred proving base rollup${tx.processedTx.isEmpty ? ' with padding tx' : ''} for ${tx.processedTx.hash.toString()}`);
403
+ this.deferredProving(provingState, wrapCallbackInSpan(this.tracer, 'ProvingOrchestrator.prover.getBaseRollupProof', {
404
+ [Attributes.TX_HASH]: tx.processedTx.hash.toString(),
405
+ [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
406
+ [Attributes.PROTOCOL_CIRCUIT_NAME]: 'base-rollup',
407
+ }, signal => this.prover.getBaseRollupProof(tx.baseRollupInputs, signal)), result => {
408
+ logger.debug(`Completed proof for base rollup for tx ${tx.processedTx.hash.toString()}`);
409
+ validatePartialState(result.inputs.end, tx.treeSnapshots);
410
+ const currentLevel = provingState.numMergeLevels + 1n;
411
+ this.storeAndExecuteNextMergeLevel(provingState, currentLevel, index, [
412
+ result.inputs,
413
+ result.proof,
414
+ result.verificationKey.keyAsFields,
415
+ ]);
416
+ });
541
417
  }
542
- else {
543
- return this.prover.getPublicKernelProof(request, signal);
418
+ // Executes the merge rollup circuit and stored the output as intermediate state for the parent merge/root circuit
419
+ // Enqueues the next level of merge if all inputs are available
420
+ enqueueMergeRollup(provingState, level, index, mergeInputData) {
421
+ const inputs = createMergeRollupInputs([mergeInputData.inputs[0], mergeInputData.proofs[0], mergeInputData.verificationKeys[0]], [mergeInputData.inputs[1], mergeInputData.proofs[1], mergeInputData.verificationKeys[1]]);
422
+ this.deferredProving(provingState, wrapCallbackInSpan(this.tracer, 'ProvingOrchestrator.prover.getMergeRollupProof', {
423
+ [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
424
+ [Attributes.PROTOCOL_CIRCUIT_NAME]: 'merge-rollup',
425
+ }, signal => this.prover.getMergeRollupProof(inputs, signal)), result => {
426
+ this.storeAndExecuteNextMergeLevel(provingState, level, index, [
427
+ result.inputs,
428
+ result.proof,
429
+ result.verificationKey.keyAsFields,
430
+ ]);
431
+ });
544
432
  }
545
- }, result => {
546
- const nextKernelRequest = txProvingState.getNextPublicKernelFromKernelProof(functionIndex, result.proof, result.verificationKey);
547
- // What's the status of the next kernel?
548
- if (nextKernelRequest.code === TX_PROVING_CODE.NOT_READY) {
549
- // Must be waiting on a VM proof
550
- return;
433
+ // Executes the root rollup circuit
434
+ async enqueueRootRollup(provingState) {
435
+ if (!provingState?.verifyState()) {
436
+ logger.debug('Not running root rollup, state no longer valid');
437
+ return;
438
+ }
439
+ const mergeInputData = provingState.getMergeInputs(0);
440
+ const rootParityInput = provingState.finalRootParityInput;
441
+ const inputs = await getRootRollupInput(mergeInputData.inputs[0], mergeInputData.proofs[0], mergeInputData.verificationKeys[0], mergeInputData.inputs[1], mergeInputData.proofs[1], mergeInputData.verificationKeys[1], rootParityInput, provingState.newL1ToL2Messages, provingState.messageTreeSnapshot, provingState.messageTreeRootSiblingPath, this.db);
442
+ this.deferredProving(provingState, wrapCallbackInSpan(this.tracer, 'ProvingOrchestrator.prover.getRootRollupProof', {
443
+ [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
444
+ [Attributes.PROTOCOL_CIRCUIT_NAME]: 'root-rollup',
445
+ }, signal => this.prover.getRootRollupProof(inputs, signal)), result => {
446
+ provingState.rootRollupPublicInputs = result.inputs;
447
+ provingState.finalAggregationObject = extractAggregationObject(result.proof.binaryProof, result.verificationKey.numPublicInputs);
448
+ provingState.finalProof = result.proof.binaryProof;
449
+ const provingResult = {
450
+ status: PROVING_STATUS.SUCCESS,
451
+ };
452
+ provingState.resolve(provingResult);
453
+ });
551
454
  }
552
- if (nextKernelRequest.code === TX_PROVING_CODE.COMPLETED) {
553
- // We must have completed all public function proving, we now move to the base rollup
554
- logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
555
- // Take the final public tail proof and verification key and pass them to the base rollup
556
- txProvingState.baseRollupInputs.kernelData.proof = result.proof;
557
- txProvingState.baseRollupInputs.kernelData.vk = result.verificationKey;
558
- this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
559
- return;
455
+ // Executes the base parity circuit and stores the intermediate state for the root parity circuit
456
+ // Enqueues the root parity circuit if all inputs are available
457
+ enqueueBaseParityCircuit(provingState, inputs, index) {
458
+ this.deferredProving(provingState, wrapCallbackInSpan(this.tracer, 'ProvingOrchestrator.prover.getBaseParityProof', {
459
+ [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
460
+ [Attributes.PROTOCOL_CIRCUIT_NAME]: 'base-parity',
461
+ }, signal => this.prover.getBaseParityProof(inputs, signal)), rootInput => {
462
+ provingState.setRootParityInputs(rootInput, index);
463
+ if (provingState.areRootParityInputsReady()) {
464
+ const rootParityInputs = new RootParityInputs(provingState.rootParityInput);
465
+ this.enqueueRootParityCircuit(provingState, rootParityInputs);
466
+ }
467
+ });
560
468
  }
561
- // There must be another kernel ready to be proven
562
- if (nextKernelRequest.function === undefined) {
563
- // Should not be possible
564
- throw new Error(`Error occurred, public function request undefined after kernel proof completed`);
469
+ // Runs the root parity circuit ans stored the outputs
470
+ // Enqueues the root rollup proof if all inputs are available
471
+ enqueueRootParityCircuit(provingState, inputs) {
472
+ this.deferredProving(provingState, wrapCallbackInSpan(this.tracer, 'ProvingOrchestrator.prover.getRootParityProof', {
473
+ [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
474
+ [Attributes.PROTOCOL_CIRCUIT_NAME]: 'root-parity',
475
+ }, signal => this.prover.getRootParityProof(inputs, signal)), async (rootInput) => {
476
+ provingState.finalRootParityInput = rootInput;
477
+ await this.checkAndEnqueueRootRollup(provingState);
478
+ });
565
479
  }
566
- this.enqueuePublicKernel(provingState, txIndex, functionIndex + 1);
567
- });
568
- }
569
- }
480
+ async checkAndEnqueueRootRollup(provingState) {
481
+ if (!provingState?.isReadyForRootRollup()) {
482
+ logger.debug('Not ready for root rollup');
483
+ return;
484
+ }
485
+ await this.enqueueRootRollup(provingState);
486
+ }
487
+ /**
488
+ * Stores the inputs to a merge/root circuit and enqueues the circuit if ready
489
+ * @param provingState - The proving state being operated on
490
+ * @param currentLevel - The level of the merge/root circuit
491
+ * @param currentIndex - The index of the merge/root circuit
492
+ * @param mergeInputData - The inputs to be stored
493
+ */
494
+ storeAndExecuteNextMergeLevel(provingState, currentLevel, currentIndex, mergeInputData) {
495
+ const result = this.storeMergeInputs(provingState, currentLevel, currentIndex, mergeInputData);
496
+ // Are we ready to execute the next circuit?
497
+ if (!result.ready) {
498
+ return;
499
+ }
500
+ if (result.mergeLevel === 0n) {
501
+ // TODO (alexg) remove this `void`
502
+ void this.checkAndEnqueueRootRollup(provingState);
503
+ }
504
+ else {
505
+ // onto the next merge level
506
+ this.enqueueMergeRollup(provingState, result.mergeLevel, result.indexWithinMergeLevel, result.mergeInputData);
507
+ }
508
+ }
509
+ /**
510
+ * Executes the VM circuit for a public function, will enqueue the corresponding kernel if the
511
+ * previous kernel is ready
512
+ * @param provingState - The proving state being operated on
513
+ * @param txIndex - The index of the transaction being proven
514
+ * @param functionIndex - The index of the function/kernel being proven
515
+ */
516
+ enqueueVM(provingState, txIndex, functionIndex) {
517
+ if (!provingState?.verifyState()) {
518
+ logger.debug(`Not running VM circuit as state is no longer valid`);
519
+ return;
520
+ }
521
+ const txProvingState = provingState.getTxProvingState(txIndex);
522
+ const publicFunction = txProvingState.getPublicFunctionState(functionIndex);
523
+ // If there is a VM request, we need to prove it. Otherwise, continue with the kernel.
524
+ if (publicFunction.vmRequest) {
525
+ // This function tries to do AVM proving. If there is a failure, it fakes the proof unless AVM_PROVING_STRICT is defined.
526
+ // Nothing downstream depends on the AVM proof yet. So having this mode lets us incrementally build the AVM circuit.
527
+ const doAvmProving = wrapCallbackInSpan(this.tracer, 'ProvingOrchestrator.prover.getAvmProof', {
528
+ [Attributes.TX_HASH]: txProvingState.processedTx.hash.toString(),
529
+ [Attributes.APP_CIRCUIT_NAME]: publicFunction.vmRequest.functionName,
530
+ }, async (signal) => {
531
+ const inputs = new AvmCircuitInputs(publicFunction.vmRequest.functionName, publicFunction.vmRequest.bytecode, publicFunction.vmRequest.calldata, publicFunction.vmRequest.kernelRequest.inputs.publicCall.callStackItem.publicInputs, publicFunction.vmRequest.avmHints);
532
+ try {
533
+ return await this.prover.getAvmProof(inputs, signal);
534
+ }
535
+ catch (err) {
536
+ if (process.env.AVM_PROVING_STRICT) {
537
+ throw err;
538
+ }
539
+ else {
540
+ logger.warn(`Error thrown when proving AVM circuit: ${err}`);
541
+ logger.warn(`AVM_PROVING_STRICT is off, faking AVM proof and carrying on...`);
542
+ return { proof: makeEmptyProof(), verificationKey: VerificationKeyData.makeFake() };
543
+ }
544
+ }
545
+ });
546
+ this.deferredProving(provingState, doAvmProving, proofAndVk => {
547
+ logger.debug(`Proven VM for function index ${functionIndex} of tx index ${txIndex}`);
548
+ this.checkAndEnqueuePublicKernel(provingState, txIndex, functionIndex, proofAndVk.proof);
549
+ });
550
+ }
551
+ else {
552
+ this.checkAndEnqueuePublicKernel(provingState, txIndex, functionIndex, /*vmProof=*/ makeEmptyProof());
553
+ }
554
+ }
555
+ checkAndEnqueuePublicKernel(provingState, txIndex, functionIndex, vmProof) {
556
+ const txProvingState = provingState.getTxProvingState(txIndex);
557
+ const kernelRequest = txProvingState.getNextPublicKernelFromVMProof(functionIndex, vmProof);
558
+ if (kernelRequest.code === TX_PROVING_CODE.READY) {
559
+ if (kernelRequest.function === undefined) {
560
+ // Should not be possible
561
+ throw new Error(`Error occurred, public function request undefined after VM proof completed`);
562
+ }
563
+ logger.debug(`Enqueuing kernel from VM for tx ${txIndex}, function ${functionIndex}`);
564
+ this.enqueuePublicKernel(provingState, txIndex, functionIndex);
565
+ }
566
+ }
567
+ /**
568
+ * Executes the kernel circuit for a public function, will enqueue the next kernel circuit if it's VM is already proven
569
+ * or the base rollup circuit if there are no more kernels to be proven
570
+ * @param provingState - The proving state being operated on
571
+ * @param txIndex - The index of the transaction being proven
572
+ * @param functionIndex - The index of the function/kernel being proven
573
+ */
574
+ enqueuePublicKernel(provingState, txIndex, functionIndex) {
575
+ if (!provingState?.verifyState()) {
576
+ logger.debug(`Not running public kernel circuit as state is no longer valid`);
577
+ return;
578
+ }
579
+ const txProvingState = provingState.getTxProvingState(txIndex);
580
+ const request = txProvingState.getPublicFunctionState(functionIndex).publicKernelRequest;
581
+ this.deferredProving(provingState, wrapCallbackInSpan(this.tracer, request.type === PublicKernelType.TAIL
582
+ ? 'ProvingOrchestrator.prover.getPublicTailProof'
583
+ : 'ProvingOrchestrator.prover.getPublicKernelProof', {
584
+ [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
585
+ [Attributes.PROTOCOL_CIRCUIT_NAME]: mapPublicKernelToCircuitName(request.type),
586
+ }, (signal) => {
587
+ if (request.type === PublicKernelType.TAIL) {
588
+ return this.prover.getPublicTailProof(request, signal);
589
+ }
590
+ else {
591
+ return this.prover.getPublicKernelProof(request, signal);
592
+ }
593
+ }), result => {
594
+ const nextKernelRequest = txProvingState.getNextPublicKernelFromKernelProof(functionIndex, result.proof, result.verificationKey);
595
+ // What's the status of the next kernel?
596
+ if (nextKernelRequest.code === TX_PROVING_CODE.NOT_READY) {
597
+ // Must be waiting on a VM proof
598
+ return;
599
+ }
600
+ if (nextKernelRequest.code === TX_PROVING_CODE.COMPLETED) {
601
+ // We must have completed all public function proving, we now move to the base rollup
602
+ logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
603
+ // Take the final public tail proof and verification key and pass them to the base rollup
604
+ txProvingState.baseRollupInputs.kernelData.proof = result.proof;
605
+ txProvingState.baseRollupInputs.kernelData.vk = result.verificationKey;
606
+ this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
607
+ return;
608
+ }
609
+ // There must be another kernel ready to be proven
610
+ if (nextKernelRequest.function === undefined) {
611
+ // Should not be possible
612
+ throw new Error(`Error occurred, public function request undefined after kernel proof completed`);
613
+ }
614
+ this.enqueuePublicKernel(provingState, txIndex, functionIndex + 1);
615
+ });
616
+ }
617
+ },
618
+ (() => {
619
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
620
+ _startNewBlock_decorators = [trackSpan('ProvingOrchestrator.startNewBlock', (numTxs, globalVariables) => ({
621
+ [Attributes.BLOCK_SIZE]: numTxs,
622
+ [Attributes.BLOCK_NUMBER]: globalVariables.blockNumber.toNumber(),
623
+ }))];
624
+ _addNewTx_decorators = [trackSpan('ProvingOrchestrator.addNewTx', tx => ({
625
+ [Attributes.TX_HASH]: tx.hash.toString(),
626
+ }))];
627
+ _setBlockCompleted_decorators = [trackSpan('ProvingOrchestrator.setBlockCompleted', function () {
628
+ if (!this.provingState) {
629
+ return {};
630
+ }
631
+ return {
632
+ [Attributes.BLOCK_NUMBER]: this.provingState.globalVariables.blockNumber.toNumber(),
633
+ [Attributes.BLOCK_SIZE]: this.provingState.totalNumTxs,
634
+ [Attributes.BLOCK_TXS_COUNT]: this.provingState.transactionsReceived,
635
+ };
636
+ })];
637
+ _finaliseBlock_decorators = [trackSpan('ProvingOrchestrator.finaliseBlock', function () {
638
+ return {
639
+ [Attributes.BLOCK_NUMBER]: this.provingState.globalVariables.blockNumber.toNumber(),
640
+ [Attributes.BLOCK_TXS_COUNT]: this.provingState.transactionsReceived,
641
+ [Attributes.BLOCK_SIZE]: this.provingState.totalNumTxs,
642
+ };
643
+ })];
644
+ _prepareBaseRollupInputs_decorators = [trackSpan('ProvingOrchestrator.prepareBaseRollupInputs', (_, tx) => ({
645
+ [Attributes.TX_HASH]: tx.hash.toString(),
646
+ }))];
647
+ __esDecorate(_a, null, _startNewBlock_decorators, { kind: "method", name: "startNewBlock", static: false, private: false, access: { has: obj => "startNewBlock" in obj, get: obj => obj.startNewBlock }, metadata: _metadata }, null, _instanceExtraInitializers);
648
+ __esDecorate(_a, null, _addNewTx_decorators, { kind: "method", name: "addNewTx", static: false, private: false, access: { has: obj => "addNewTx" in obj, get: obj => obj.addNewTx }, metadata: _metadata }, null, _instanceExtraInitializers);
649
+ __esDecorate(_a, null, _setBlockCompleted_decorators, { kind: "method", name: "setBlockCompleted", static: false, private: false, access: { has: obj => "setBlockCompleted" in obj, get: obj => obj.setBlockCompleted }, metadata: _metadata }, null, _instanceExtraInitializers);
650
+ __esDecorate(_a, null, _finaliseBlock_decorators, { kind: "method", name: "finaliseBlock", static: false, private: false, access: { has: obj => "finaliseBlock" in obj, get: obj => obj.finaliseBlock }, metadata: _metadata }, null, _instanceExtraInitializers);
651
+ __esDecorate(_a, null, _prepareBaseRollupInputs_decorators, { kind: "method", name: "prepareBaseRollupInputs", static: false, private: false, access: { has: obj => "prepareBaseRollupInputs" in obj, get: obj => obj.prepareBaseRollupInputs }, metadata: _metadata }, null, _instanceExtraInitializers);
652
+ if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
653
+ })(),
654
+ _a;
655
+ })();
656
+ export { ProvingOrchestrator };
570
657
  function extractAggregationObject(proof, numPublicInputs) {
571
658
  const buffer = proof.buffer.subarray(Fr.SIZE_IN_BYTES * (numPublicInputs - AGGREGATION_OBJECT_LENGTH), Fr.SIZE_IN_BYTES * numPublicInputs);
659
+ // TODO(#7159): Remove the following workaround
660
+ if (buffer.length === 0) {
661
+ return Array.from({ length: AGGREGATION_OBJECT_LENGTH }, () => Fr.ZERO);
662
+ }
572
663
  return BufferReader.asReader(buffer).readArray(AGGREGATION_OBJECT_LENGTH, Fr);
573
664
  }
574
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JjaGVzdHJhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29yY2hlc3RyYXRvci9vcmNoZXN0cmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLElBQUksRUFDSixPQUFPLEVBQ1AsWUFBWSxFQUdaLGdCQUFnQixFQUNoQixFQUFFLEVBRUYsb0JBQW9CLEVBQ3BCLHNCQUFzQixFQUN0QixVQUFVLEdBQ1gsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQ0wsZUFBZSxFQUVmLGNBQWMsR0FLZixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFDTCx5QkFBeUIsRUFDekIsZ0JBQWdCLEVBRWhCLGdCQUFnQixFQUVoQixFQUFFLEVBSUYsMkJBQTJCLEVBQzNCLHdDQUF3QyxFQUV4QyxtQ0FBbUMsRUFDbkMsK0JBQStCLEVBTS9CLGdCQUFnQixFQUVoQixtQkFBbUIsRUFFbkIsY0FBYyxHQUNmLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDakUsT0FBTyxFQUFFLFlBQVksRUFBYyxNQUFNLDZCQUE2QixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUd6RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRS9CLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsdUJBQXVCLEVBQ3ZCLGtCQUFrQixFQUNsQixxQkFBcUIsRUFDckIsZUFBZSxFQUNmLG9C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
665
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JjaGVzdHJhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29yY2hlc3RyYXRvci9vcmNoZXN0cmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFDTCxJQUFJLEVBQ0osT0FBTyxFQUNQLFlBQVksRUFHWixnQkFBZ0IsRUFDaEIsRUFBRSxFQUVGLG9CQUFvQixFQUNwQixzQkFBc0IsRUFDdEIsNEJBQTRCLEVBQzVCLFVBQVUsR0FDWCxNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFDTCxlQUFlLEVBRWYsY0FBYyxHQUtmLE1BQU0saUNBQWlDLENBQUM7QUFFekMsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixnQkFBZ0IsRUFFaEIsZ0JBQWdCLEVBRWhCLEVBQUUsRUFJRiwyQkFBMkIsRUFDM0Isd0NBQXdDLEVBRXhDLG1DQUFtQyxFQUNuQywrQkFBK0IsRUFNL0IsZ0JBQWdCLEVBRWhCLG1CQUFtQixFQUVuQixjQUFjLEdBQ2YsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzNELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsWUFBWSxFQUFjLE1BQU0sNkJBQTZCLENBQUM7QUFDdkUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxVQUFVLEVBQXFDLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBR3ZILE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7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