@aztec/prover-client 0.56.0 → 0.58.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/config.d.ts +4 -5
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +11 -2
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/mocks/fixtures.d.ts +6 -6
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +8 -4
- package/dest/mocks/test_context.d.ts +7 -7
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +15 -18
- package/dest/orchestrator/block-building-helpers.d.ts +12 -12
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +4 -2
- package/dest/orchestrator/block-proving-state.d.ts +7 -7
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +11 -33
- package/dest/orchestrator/epoch-proving-state.d.ts +8 -2
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +8 -16
- package/dest/orchestrator/orchestrator.d.ts +15 -19
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +161 -106
- package/dest/prover-agent/memory-proving-queue.d.ts +5 -8
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +3 -3
- package/dest/prover-agent/prover-agent.js +4 -4
- package/dest/prover-agent/rpc.js +4 -4
- package/dest/test/mock_prover.d.ts +10 -16
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +18 -24
- package/dest/tx-prover/tx-prover.d.ts +3 -4
- package/dest/tx-prover/tx-prover.d.ts.map +1 -1
- package/dest/tx-prover/tx-prover.js +2 -2
- package/package.json +14 -10
- package/src/config.ts +20 -11
- package/src/index.ts +1 -1
- package/src/mocks/fixtures.ts +21 -7
- package/src/mocks/test_context.ts +26 -22
- package/src/orchestrator/block-building-helpers.ts +21 -12
- package/src/orchestrator/block-proving-state.ts +11 -35
- package/src/orchestrator/epoch-proving-state.ts +9 -20
- package/src/orchestrator/orchestrator.ts +205 -140
- package/src/prover-agent/memory-proving-queue.ts +8 -7
- package/src/prover-agent/prover-agent.ts +4 -4
- package/src/prover-agent/rpc.ts +3 -3
- package/src/test/mock_prover.ts +26 -28
- package/src/tx-prover/tx-prover.ts +5 -5
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
BlockProofError,
|
|
3
2
|
Body,
|
|
4
3
|
EncryptedNoteTxL2Logs,
|
|
5
4
|
EncryptedTxL2Logs,
|
|
6
5
|
L2Block,
|
|
7
6
|
MerkleTreeId,
|
|
8
|
-
PROVING_STATUS,
|
|
9
7
|
type PaddingProcessedTx,
|
|
10
8
|
type ProcessedTx,
|
|
11
|
-
type ProvingBlockResult,
|
|
12
9
|
ProvingRequestType,
|
|
13
|
-
type ProvingResult,
|
|
14
|
-
type ProvingTicket,
|
|
15
10
|
type PublicInputsAndRecursiveProof,
|
|
16
11
|
type ServerCircuitProver,
|
|
17
|
-
Tx,
|
|
18
12
|
type TxEffect,
|
|
19
13
|
UnencryptedTxL2Logs,
|
|
20
14
|
makeEmptyProcessedTx,
|
|
@@ -22,7 +16,7 @@ import {
|
|
|
22
16
|
mapProvingRequestTypeToCircuitName,
|
|
23
17
|
toTxEffect,
|
|
24
18
|
} from '@aztec/circuit-types';
|
|
25
|
-
import { type EpochProver } from '@aztec/circuit-types/interfaces';
|
|
19
|
+
import { type EpochProver, type MerkleTreeWriteOperations } from '@aztec/circuit-types/interfaces';
|
|
26
20
|
import { type CircuitName } from '@aztec/circuit-types/stats';
|
|
27
21
|
import {
|
|
28
22
|
AvmCircuitInputs,
|
|
@@ -31,8 +25,10 @@ import {
|
|
|
31
25
|
type BaseRollupInputs,
|
|
32
26
|
type BlockRootOrBlockMergePublicInputs,
|
|
33
27
|
BlockRootRollupInputs,
|
|
28
|
+
EmptyBlockRootRollupInputs,
|
|
34
29
|
Fr,
|
|
35
30
|
type GlobalVariables,
|
|
31
|
+
type Header,
|
|
36
32
|
type KernelCircuitPublicInputs,
|
|
37
33
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
38
34
|
L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
|
|
@@ -46,6 +42,7 @@ import {
|
|
|
46
42
|
type RecursiveProof,
|
|
47
43
|
type RootParityInput,
|
|
48
44
|
RootParityInputs,
|
|
45
|
+
TUBE_INDEX,
|
|
49
46
|
type TUBE_PROOF_LENGTH,
|
|
50
47
|
TubeInputs,
|
|
51
48
|
type VMCircuitPublicInputs,
|
|
@@ -62,9 +59,9 @@ import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
|
62
59
|
import { type Tuple } from '@aztec/foundation/serialize';
|
|
63
60
|
import { pushTestData } from '@aztec/foundation/testing';
|
|
64
61
|
import { elapsed } from '@aztec/foundation/timer';
|
|
65
|
-
import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types';
|
|
62
|
+
import { TubeVk, getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types';
|
|
63
|
+
import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
|
|
66
64
|
import { Attributes, type TelemetryClient, type Tracer, trackSpan, wrapCallbackInSpan } from '@aztec/telemetry-client';
|
|
67
|
-
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
68
65
|
|
|
69
66
|
import { inspect } from 'util';
|
|
70
67
|
|
|
@@ -83,7 +80,12 @@ import {
|
|
|
83
80
|
validateTx,
|
|
84
81
|
} from './block-building-helpers.js';
|
|
85
82
|
import { type BlockProvingState, type MergeRollupInputData } from './block-proving-state.js';
|
|
86
|
-
import {
|
|
83
|
+
import {
|
|
84
|
+
type BlockMergeRollupInputData,
|
|
85
|
+
EpochProvingState,
|
|
86
|
+
type ProvingResult,
|
|
87
|
+
type TreeSnapshots,
|
|
88
|
+
} from './epoch-proving-state.js';
|
|
87
89
|
import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
|
|
88
90
|
import { TX_PROVING_CODE, type TxProvingInstruction, TxProvingState } from './tx-proving-state.js';
|
|
89
91
|
|
|
@@ -108,10 +110,11 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
108
110
|
private pendingProvingJobs: AbortController[] = [];
|
|
109
111
|
private paddingTx: PaddingProcessedTx | undefined = undefined;
|
|
110
112
|
|
|
113
|
+
private provingPromise: Promise<ProvingResult> | undefined = undefined;
|
|
111
114
|
private metrics: ProvingOrchestratorMetrics;
|
|
112
115
|
|
|
113
116
|
constructor(
|
|
114
|
-
private db:
|
|
117
|
+
private db: MerkleTreeWriteOperations,
|
|
115
118
|
private prover: ServerCircuitProver,
|
|
116
119
|
telemetryClient: TelemetryClient,
|
|
117
120
|
private readonly proverId: Fr = Fr.ZERO,
|
|
@@ -134,26 +137,20 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
134
137
|
this.paddingTx = undefined;
|
|
135
138
|
}
|
|
136
139
|
|
|
137
|
-
|
|
138
|
-
[Attributes.EPOCH_SIZE]: totalNumBlocks,
|
|
139
|
-
[Attributes.EPOCH_NUMBER]: epochNumber,
|
|
140
|
-
}))
|
|
141
|
-
public startNewEpoch(epochNumber: number, totalNumBlocks: number): ProvingTicket {
|
|
140
|
+
public startNewEpoch(epochNumber: number, totalNumBlocks: number) {
|
|
142
141
|
const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
|
|
143
|
-
const promise = _promise.catch(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
);
|
|
149
|
-
|
|
142
|
+
const promise = _promise.catch((reason): ProvingResult => ({ status: 'failure', reason }));
|
|
143
|
+
if (totalNumBlocks <= 0 || !Number.isInteger(totalNumBlocks)) {
|
|
144
|
+
throw new Error(`Invalid number of blocks for epoch (got ${totalNumBlocks})`);
|
|
145
|
+
}
|
|
146
|
+
logger.info(`Starting epoch ${epochNumber} with ${totalNumBlocks} blocks`);
|
|
150
147
|
this.provingState = new EpochProvingState(epochNumber, totalNumBlocks, resolve, reject);
|
|
151
|
-
|
|
148
|
+
this.provingPromise = promise;
|
|
152
149
|
}
|
|
153
150
|
|
|
154
151
|
/**
|
|
155
152
|
* Starts off a new block
|
|
156
|
-
* @param numTxs - The total number of transactions in the block.
|
|
153
|
+
* @param numTxs - The total number of transactions in the block.
|
|
157
154
|
* @param globalVariables - The global variables for the block
|
|
158
155
|
* @param l1ToL2Messages - The l1 to l2 messages for the block
|
|
159
156
|
* @param verificationKeys - The private kernel verification keys
|
|
@@ -163,14 +160,9 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
163
160
|
[Attributes.BLOCK_SIZE]: numTxs,
|
|
164
161
|
[Attributes.BLOCK_NUMBER]: globalVariables.blockNumber.toNumber(),
|
|
165
162
|
}))
|
|
166
|
-
public async startNewBlock(
|
|
167
|
-
numTxs: number,
|
|
168
|
-
globalVariables: GlobalVariables,
|
|
169
|
-
l1ToL2Messages: Fr[],
|
|
170
|
-
): Promise<ProvingTicket> {
|
|
171
|
-
// If no proving state, assume we only care about proving this block and initialize a 1-block epoch
|
|
163
|
+
public async startNewBlock(numTxs: number, globalVariables: GlobalVariables, l1ToL2Messages: Fr[]) {
|
|
172
164
|
if (!this.provingState) {
|
|
173
|
-
|
|
165
|
+
throw new Error(`Invalid proving state, call startNewEpoch before starting a block`);
|
|
174
166
|
}
|
|
175
167
|
|
|
176
168
|
if (!this.provingState?.isAcceptingBlocks()) {
|
|
@@ -178,10 +170,14 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
178
170
|
}
|
|
179
171
|
|
|
180
172
|
if (!Number.isInteger(numTxs) || numTxs < 2) {
|
|
181
|
-
throw new Error(`
|
|
173
|
+
throw new Error(`Invalid number of txs for block (got ${numTxs})`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (this.provingState.currentBlock && !this.provingState.currentBlock.block) {
|
|
177
|
+
throw new Error(`Must end previous block before starting a new one`);
|
|
182
178
|
}
|
|
183
179
|
|
|
184
|
-
// TODO(palla/prover
|
|
180
|
+
// TODO(palla/prover): Store block number in the db itself to make this check more reliable,
|
|
185
181
|
// and turn this warning into an exception that we throw.
|
|
186
182
|
const { blockNumber } = globalVariables;
|
|
187
183
|
const dbBlockNumber = (await this.db.getTreeInfo(MerkleTreeId.ARCHIVE)).size - 1n;
|
|
@@ -234,9 +230,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
234
230
|
BigInt(startArchiveSnapshot.nextAvailableLeafIndex - 1),
|
|
235
231
|
);
|
|
236
232
|
|
|
237
|
-
const { promise: _promise, resolve, reject } = promiseWithResolvers<ProvingResult>();
|
|
238
|
-
const promise = _promise.catch((reason): ProvingResult => ({ status: PROVING_STATUS.FAILURE, reason }));
|
|
239
|
-
|
|
240
233
|
this.provingState!.startNewBlock(
|
|
241
234
|
numTxs,
|
|
242
235
|
globalVariables,
|
|
@@ -247,16 +240,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
247
240
|
startArchiveSnapshot,
|
|
248
241
|
newArchiveSiblingPath,
|
|
249
242
|
previousBlockHash!,
|
|
250
|
-
resolve,
|
|
251
|
-
reject,
|
|
252
243
|
);
|
|
253
244
|
|
|
254
245
|
// Enqueue base parity circuits for the block
|
|
255
246
|
for (let i = 0; i < baseParityInputs.length; i++) {
|
|
256
247
|
this.enqueueBaseParityCircuit(this.provingState!.currentBlock!, baseParityInputs[i], i);
|
|
257
248
|
}
|
|
258
|
-
|
|
259
|
-
return { provingPromise: promise };
|
|
260
249
|
}
|
|
261
250
|
|
|
262
251
|
/**
|
|
@@ -276,6 +265,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
276
265
|
throw new Error(`Rollup not accepting further transactions`);
|
|
277
266
|
}
|
|
278
267
|
|
|
268
|
+
if (!provingState.verifyState()) {
|
|
269
|
+
throw new Error(`Invalid proving state when adding a tx`);
|
|
270
|
+
}
|
|
271
|
+
|
|
279
272
|
validateTx(tx);
|
|
280
273
|
|
|
281
274
|
logger.info(`Received transaction: ${tx.hash}`);
|
|
@@ -289,10 +282,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
289
282
|
this.enqueueFirstProofs(inputs, treeSnapshots, tx, provingState);
|
|
290
283
|
|
|
291
284
|
if (provingState.transactionsReceived === provingState.totalNumTxs) {
|
|
292
|
-
logger.verbose(
|
|
293
|
-
`All transactions received for block ${provingState.globalVariables.blockNumber}. Assembling header.`,
|
|
294
|
-
);
|
|
295
|
-
await this.buildBlockHeader(provingState);
|
|
285
|
+
logger.verbose(`All transactions received for block ${provingState.globalVariables.blockNumber}.`);
|
|
296
286
|
}
|
|
297
287
|
}
|
|
298
288
|
|
|
@@ -311,53 +301,132 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
311
301
|
[Attributes.BLOCK_TXS_COUNT]: block.transactionsReceived,
|
|
312
302
|
};
|
|
313
303
|
})
|
|
314
|
-
public async setBlockCompleted() {
|
|
304
|
+
public async setBlockCompleted(expectedHeader?: Header): Promise<L2Block> {
|
|
315
305
|
const provingState = this.provingState?.currentBlock;
|
|
316
306
|
if (!provingState) {
|
|
317
307
|
throw new Error(`Invalid proving state, call startNewBlock before adding transactions or completing the block`);
|
|
318
308
|
}
|
|
319
309
|
|
|
320
|
-
|
|
310
|
+
if (!provingState.verifyState()) {
|
|
311
|
+
throw new Error(`Block proving failed: ${provingState.error}`);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// We may need to pad the rollup with empty transactions
|
|
321
315
|
const paddingTxCount = provingState.totalNumTxs - provingState.transactionsReceived;
|
|
322
|
-
if (paddingTxCount
|
|
323
|
-
return;
|
|
324
|
-
} else if (provingState.totalNumTxs > 2) {
|
|
316
|
+
if (paddingTxCount > 0 && provingState.totalNumTxs > 2) {
|
|
325
317
|
throw new Error(`Block not ready for completion: expecting ${paddingTxCount} more transactions.`);
|
|
326
318
|
}
|
|
327
319
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
inputs,
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
320
|
+
if (paddingTxCount > 0) {
|
|
321
|
+
logger.debug(`Padding rollup with ${paddingTxCount} empty transactions`);
|
|
322
|
+
// Make an empty padding transaction
|
|
323
|
+
// Required for:
|
|
324
|
+
// 0 (when we want an empty block, largely for testing), or
|
|
325
|
+
// 1 (we need to pad with one tx as all rollup circuits require a pair of inputs) txs
|
|
326
|
+
// Insert it into the tree the required number of times to get all of the
|
|
327
|
+
// base rollup inputs
|
|
328
|
+
// Then enqueue the proving of all the transactions
|
|
329
|
+
const unprovenPaddingTx = makeEmptyProcessedTx(
|
|
330
|
+
this.db.getInitialHeader(),
|
|
331
|
+
provingState.globalVariables.chainId,
|
|
332
|
+
provingState.globalVariables.version,
|
|
333
|
+
getVKTreeRoot(),
|
|
334
|
+
protocolContractTreeRoot,
|
|
335
|
+
);
|
|
336
|
+
const txInputs: Array<{ inputs: BaseRollupInputs; snapshot: TreeSnapshots }> = [];
|
|
337
|
+
for (let i = 0; i < paddingTxCount; i++) {
|
|
338
|
+
const [inputs, snapshot] = await this.prepareTransaction(unprovenPaddingTx, provingState);
|
|
339
|
+
const txInput = {
|
|
340
|
+
inputs,
|
|
341
|
+
snapshot,
|
|
342
|
+
};
|
|
343
|
+
txInputs.push(txInput);
|
|
344
|
+
}
|
|
351
345
|
|
|
352
|
-
|
|
353
|
-
|
|
346
|
+
// Now enqueue the proving
|
|
347
|
+
this.enqueuePaddingTxs(provingState, txInputs, unprovenPaddingTx);
|
|
348
|
+
}
|
|
354
349
|
|
|
355
350
|
// And build the block header
|
|
356
|
-
logger.verbose(`Block ${provingState.globalVariables.blockNumber}
|
|
357
|
-
await this.
|
|
351
|
+
logger.verbose(`Block ${provingState.globalVariables.blockNumber} completed. Assembling header.`);
|
|
352
|
+
await this.buildBlock(provingState, expectedHeader);
|
|
353
|
+
|
|
354
|
+
// If the proofs were faster than the block building, then we need to try the block root rollup again here
|
|
355
|
+
this.checkAndEnqueueBlockRootRollup(provingState);
|
|
356
|
+
return provingState.block!;
|
|
358
357
|
}
|
|
359
358
|
|
|
360
|
-
|
|
359
|
+
/** Returns the block as built for a given index. */
|
|
360
|
+
public getBlock(index: number): L2Block {
|
|
361
|
+
const block = this.provingState?.blocks[index].block;
|
|
362
|
+
if (!block) {
|
|
363
|
+
throw new Error(`Block at index ${index} not available`);
|
|
364
|
+
}
|
|
365
|
+
return block;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
@trackSpan('ProvingOrchestrator.padEpoch', function () {
|
|
369
|
+
if (!this.provingState) {
|
|
370
|
+
return {};
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
[Attributes.EPOCH_NUMBER]: this.provingState.epochNumber,
|
|
374
|
+
[Attributes.EPOCH_SIZE]: this.provingState.totalNumBlocks,
|
|
375
|
+
};
|
|
376
|
+
})
|
|
377
|
+
private padEpoch(): Promise<void> {
|
|
378
|
+
const provingState = this.provingState!;
|
|
379
|
+
const lastBlock = provingState.currentBlock?.block;
|
|
380
|
+
if (!lastBlock) {
|
|
381
|
+
return Promise.reject(new Error(`Epoch needs at least one completed block in order to be padded`));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const paddingBlockCount = Math.max(2, provingState.totalNumBlocks) - provingState.blocks.length;
|
|
385
|
+
if (paddingBlockCount === 0) {
|
|
386
|
+
return Promise.resolve();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
logger.debug(`Padding epoch proof with ${paddingBlockCount} empty block proofs`);
|
|
390
|
+
|
|
391
|
+
const inputs = EmptyBlockRootRollupInputs.from({
|
|
392
|
+
archive: lastBlock.archive,
|
|
393
|
+
blockHash: lastBlock.header.hash(),
|
|
394
|
+
globalVariables: lastBlock.header.globalVariables,
|
|
395
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
396
|
+
protocolContractTreeRoot,
|
|
397
|
+
proverId: this.proverId,
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
logger.debug(`Enqueuing deferred proving for padding block to enqueue ${paddingBlockCount} paddings`);
|
|
401
|
+
this.deferredProving(
|
|
402
|
+
provingState,
|
|
403
|
+
wrapCallbackInSpan(
|
|
404
|
+
this.tracer,
|
|
405
|
+
'ProvingOrchestrator.prover.getEmptyBlockRootRollupProof',
|
|
406
|
+
{
|
|
407
|
+
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
408
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'empty-block-root-rollup' satisfies CircuitName,
|
|
409
|
+
},
|
|
410
|
+
signal => this.prover.getEmptyBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
411
|
+
),
|
|
412
|
+
result => {
|
|
413
|
+
logger.debug(`Completed proof for padding block`);
|
|
414
|
+
const currentLevel = provingState.numMergeLevels + 1n;
|
|
415
|
+
for (let i = 0; i < paddingBlockCount; i++) {
|
|
416
|
+
logger.debug(`Enqueuing padding block with index ${provingState.blocks.length + i}`);
|
|
417
|
+
const index = BigInt(provingState.blocks.length + i);
|
|
418
|
+
this.storeAndExecuteNextBlockMergeLevel(provingState, currentLevel, index, [
|
|
419
|
+
result.inputs,
|
|
420
|
+
result.proof,
|
|
421
|
+
result.verificationKey.keyAsFields,
|
|
422
|
+
]);
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
);
|
|
426
|
+
return Promise.resolve();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private async buildBlock(provingState: BlockProvingState, expectedHeader?: Header) {
|
|
361
430
|
// Collect all new nullifiers, commitments, and contracts from all txs in this block to build body
|
|
362
431
|
const gasFees = provingState.globalVariables.gasFees;
|
|
363
432
|
const nonEmptyTxEffects: TxEffect[] = provingState!.allTxs
|
|
@@ -374,12 +443,17 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
374
443
|
this.db,
|
|
375
444
|
);
|
|
376
445
|
|
|
446
|
+
if (expectedHeader && !header.equals(expectedHeader)) {
|
|
447
|
+
logger.error(`Block header mismatch: header=${header} expectedHeader=${expectedHeader}`);
|
|
448
|
+
throw new Error('Block header mismatch');
|
|
449
|
+
}
|
|
450
|
+
|
|
377
451
|
logger.verbose(`Updating archive tree with block ${provingState.blockNumber} header ${header.hash().toString()}`);
|
|
378
452
|
await this.db.updateArchive(header);
|
|
379
453
|
|
|
380
454
|
// Assemble the L2 block
|
|
381
455
|
const newArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, this.db);
|
|
382
|
-
const l2Block = L2Block
|
|
456
|
+
const l2Block = new L2Block(newArchive, header, body);
|
|
383
457
|
|
|
384
458
|
if (!l2Block.body.getTxsEffectsHash().equals(header.contentCommitment.txsEffectsHash)) {
|
|
385
459
|
throw new Error(
|
|
@@ -426,6 +500,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
426
500
|
unprovenPaddingTx.data.constants.txContext.chainId,
|
|
427
501
|
unprovenPaddingTx.data.constants.txContext.version,
|
|
428
502
|
getVKTreeRoot(),
|
|
503
|
+
protocolContractTreeRoot,
|
|
429
504
|
),
|
|
430
505
|
signal,
|
|
431
506
|
provingState.epochNumber,
|
|
@@ -499,52 +574,29 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
499
574
|
}
|
|
500
575
|
|
|
501
576
|
/**
|
|
502
|
-
* Returns the
|
|
503
|
-
* @param index - The index of the block to finalise. Defaults to the last block.
|
|
504
|
-
* @returns The fully proven block and proof.
|
|
577
|
+
* Returns the proof for the current epoch.
|
|
505
578
|
*/
|
|
506
|
-
public
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (!block || !block.blockRootRollupPublicInputs || !block.finalProof || !block.block) {
|
|
511
|
-
throw new Error(`Invalid proving state, a block must be proven before it can be finalised`);
|
|
512
|
-
}
|
|
579
|
+
public async finaliseEpoch() {
|
|
580
|
+
if (!this.provingState || !this.provingPromise) {
|
|
581
|
+
throw new Error(`Invalid proving state, an epoch must be proven before it can be finalised`);
|
|
582
|
+
}
|
|
513
583
|
|
|
514
|
-
|
|
515
|
-
proof: block.finalProof,
|
|
516
|
-
aggregationObject: block.finalProof.extractAggregationObject(),
|
|
517
|
-
block: block.block!,
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
pushTestData('blockResults', {
|
|
521
|
-
proverId: this.proverId.toString(),
|
|
522
|
-
vkTreeRoot: getVKTreeRoot().toString(),
|
|
523
|
-
block: blockResult.block.toString(),
|
|
524
|
-
proof: blockResult.proof.toString(),
|
|
525
|
-
aggregationObject: blockResult.aggregationObject.map(x => x.toString()),
|
|
526
|
-
});
|
|
584
|
+
await this.padEpoch();
|
|
527
585
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
throw new
|
|
531
|
-
err && typeof err === 'object' && 'message' in err ? String(err.message) : String(err),
|
|
532
|
-
this.provingState?.blocks[index ?? this.provingState?.blocks.length - 1]?.allTxs.map(x =>
|
|
533
|
-
Tx.getHash(x.processedTx),
|
|
534
|
-
) ?? [],
|
|
535
|
-
);
|
|
586
|
+
const result = await this.provingPromise!;
|
|
587
|
+
if (result.status === 'failure') {
|
|
588
|
+
throw new Error(`Epoch proving failed: ${result.reason}`);
|
|
536
589
|
}
|
|
537
|
-
}
|
|
538
590
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
* Requires proving to have been completed.
|
|
542
|
-
*/
|
|
543
|
-
public finaliseEpoch() {
|
|
544
|
-
if (!this.provingState || !this.provingState.rootRollupPublicInputs || !this.provingState.finalProof) {
|
|
545
|
-
throw new Error(`Invalid proving state, an epoch must be proven before it can be finalised`);
|
|
591
|
+
if (!this.provingState.rootRollupPublicInputs || !this.provingState.finalProof) {
|
|
592
|
+
throw new Error(`Invalid proving state, missing root rollup public inputs or final proof`);
|
|
546
593
|
}
|
|
547
594
|
|
|
595
|
+
pushTestData('epochProofResult', {
|
|
596
|
+
proof: this.provingState.finalProof.toString(),
|
|
597
|
+
publicInputs: this.provingState.rootRollupPublicInputs.toString(),
|
|
598
|
+
});
|
|
599
|
+
|
|
548
600
|
return { proof: this.provingState.finalProof, publicInputs: this.provingState.rootRollupPublicInputs };
|
|
549
601
|
}
|
|
550
602
|
|
|
@@ -663,7 +715,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
663
715
|
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
664
716
|
provingState.globalVariables,
|
|
665
717
|
this.db,
|
|
666
|
-
|
|
718
|
+
TubeVk,
|
|
667
719
|
),
|
|
668
720
|
);
|
|
669
721
|
|
|
@@ -795,8 +847,14 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
795
847
|
),
|
|
796
848
|
result => {
|
|
797
849
|
logger.debug(`Completed tube proof for tx index: ${txIndex}`);
|
|
798
|
-
const nextKernelRequest = txProvingState.getNextPublicKernelFromTubeProof(result.
|
|
799
|
-
this.checkAndEnqueueNextTxCircuit(
|
|
850
|
+
const nextKernelRequest = txProvingState.getNextPublicKernelFromTubeProof(result.proof, result.verificationKey);
|
|
851
|
+
this.checkAndEnqueueNextTxCircuit(
|
|
852
|
+
provingState,
|
|
853
|
+
txIndex,
|
|
854
|
+
result.proof,
|
|
855
|
+
result.verificationKey,
|
|
856
|
+
nextKernelRequest,
|
|
857
|
+
);
|
|
800
858
|
},
|
|
801
859
|
);
|
|
802
860
|
}
|
|
@@ -836,11 +894,17 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
836
894
|
}
|
|
837
895
|
|
|
838
896
|
// Executes the block root rollup circuit
|
|
839
|
-
private enqueueBlockRootRollup(provingState: BlockProvingState
|
|
840
|
-
if (!provingState
|
|
897
|
+
private enqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
898
|
+
if (!provingState.block) {
|
|
899
|
+
throw new Error(`Invalid proving state for block root rollup, block not available`);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
if (!provingState.verifyState()) {
|
|
841
903
|
logger.debug('Not running block root rollup, state no longer valid');
|
|
842
904
|
return;
|
|
843
905
|
}
|
|
906
|
+
|
|
907
|
+
provingState.blockRootRollupStarted = true;
|
|
844
908
|
const mergeInputData = provingState.getMergeInputs(0);
|
|
845
909
|
const rootParityInput = provingState.finalRootParityInput!;
|
|
846
910
|
|
|
@@ -868,8 +932,6 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
868
932
|
proverId: this.proverId,
|
|
869
933
|
});
|
|
870
934
|
|
|
871
|
-
const shouldProveEpoch = this.provingState!.totalNumBlocks > 1;
|
|
872
|
-
|
|
873
935
|
this.deferredProving(
|
|
874
936
|
provingState,
|
|
875
937
|
wrapCallbackInSpan(
|
|
@@ -879,10 +941,7 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
879
941
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
880
942
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'block-root-rollup' satisfies CircuitName,
|
|
881
943
|
},
|
|
882
|
-
signal =>
|
|
883
|
-
shouldProveEpoch
|
|
884
|
-
? this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber)
|
|
885
|
-
: this.prover.getBlockRootRollupFinalProof(inputs, signal, provingState.epochNumber),
|
|
944
|
+
signal => this.prover.getBlockRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
886
945
|
),
|
|
887
946
|
result => {
|
|
888
947
|
const header = this.extractBlockHeaderFromPublicInputs(provingState, result.inputs);
|
|
@@ -895,17 +954,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
895
954
|
|
|
896
955
|
provingState.blockRootRollupPublicInputs = result.inputs;
|
|
897
956
|
provingState.finalProof = result.proof.binaryProof;
|
|
898
|
-
provingState.resolve({ status: PROVING_STATUS.SUCCESS });
|
|
899
957
|
|
|
900
958
|
logger.debug(`Completed proof for block root rollup for ${provingState.block?.number}`);
|
|
901
959
|
// validatePartialState(result.inputs.end, tx.treeSnapshots); // TODO(palla/prover)
|
|
902
960
|
|
|
903
|
-
// TODO(palla/prover): Remove this once we've dropped the flow for proving single blocks
|
|
904
|
-
if (!shouldProveEpoch) {
|
|
905
|
-
logger.verbose(`Skipping epoch rollup, only one block in epoch`);
|
|
906
|
-
return;
|
|
907
|
-
}
|
|
908
|
-
|
|
909
961
|
const currentLevel = this.provingState!.numMergeLevels + 1n;
|
|
910
962
|
this.storeAndExecuteNextBlockMergeLevel(this.provingState!, currentLevel, BigInt(provingState.index), [
|
|
911
963
|
result.inputs,
|
|
@@ -1032,18 +1084,23 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1032
1084
|
signal => this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
1033
1085
|
),
|
|
1034
1086
|
result => {
|
|
1087
|
+
logger.verbose(`Orchestrator completed root rollup for epoch ${provingState.epochNumber}`);
|
|
1035
1088
|
provingState.rootRollupPublicInputs = result.inputs;
|
|
1036
1089
|
provingState.finalProof = result.proof.binaryProof;
|
|
1037
|
-
provingState.resolve({ status:
|
|
1090
|
+
provingState.resolve({ status: 'success' });
|
|
1038
1091
|
},
|
|
1039
1092
|
);
|
|
1040
1093
|
}
|
|
1041
1094
|
|
|
1042
|
-
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState
|
|
1095
|
+
private checkAndEnqueueBlockRootRollup(provingState: BlockProvingState) {
|
|
1043
1096
|
if (!provingState?.isReadyForBlockRootRollup()) {
|
|
1044
1097
|
logger.debug('Not ready for root rollup');
|
|
1045
1098
|
return;
|
|
1046
1099
|
}
|
|
1100
|
+
if (provingState.blockRootRollupStarted) {
|
|
1101
|
+
logger.debug('Block root rollup already started');
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1047
1104
|
this.enqueueBlockRootRollup(provingState);
|
|
1048
1105
|
}
|
|
1049
1106
|
|
|
@@ -1181,7 +1238,10 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1181
1238
|
logger.warn(
|
|
1182
1239
|
`Error thrown when proving AVM circuit, but AVM_PROVING_STRICT is off, so faking AVM proof and carrying on. Error: ${err}.`,
|
|
1183
1240
|
);
|
|
1184
|
-
return {
|
|
1241
|
+
return {
|
|
1242
|
+
proof: makeEmptyProof(),
|
|
1243
|
+
verificationKey: VerificationKeyData.makeFakeHonk(),
|
|
1244
|
+
};
|
|
1185
1245
|
}
|
|
1186
1246
|
}
|
|
1187
1247
|
},
|
|
@@ -1234,7 +1294,12 @@ export class ProvingOrchestrator implements EpochProver {
|
|
|
1234
1294
|
// Take the final proof and assign it to the base rollup inputs
|
|
1235
1295
|
txProvingState.baseRollupInputs.kernelData.proof = proof;
|
|
1236
1296
|
txProvingState.baseRollupInputs.kernelData.vk = verificationKey;
|
|
1237
|
-
|
|
1297
|
+
try {
|
|
1298
|
+
txProvingState.baseRollupInputs.kernelData.vkIndex = getVKIndex(verificationKey);
|
|
1299
|
+
} catch (_ignored) {
|
|
1300
|
+
// TODO(#7410) The VK for the tube won't be in the tree for now, so we manually set it to the tube vk index
|
|
1301
|
+
txProvingState.baseRollupInputs.kernelData.vkIndex = TUBE_INDEX;
|
|
1302
|
+
}
|
|
1238
1303
|
txProvingState.baseRollupInputs.kernelData.vkPath = getVKSiblingPath(
|
|
1239
1304
|
txProvingState.baseRollupInputs.kernelData.vkIndex,
|
|
1240
1305
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type
|
|
2
|
+
type ProofAndVerificationKey,
|
|
3
3
|
type ProvingJob,
|
|
4
4
|
type ProvingJobSource,
|
|
5
5
|
type ProvingRequest,
|
|
@@ -16,10 +16,12 @@ import type {
|
|
|
16
16
|
BlockMergeRollupInputs,
|
|
17
17
|
BlockRootOrBlockMergePublicInputs,
|
|
18
18
|
BlockRootRollupInputs,
|
|
19
|
+
EmptyBlockRootRollupInputs,
|
|
19
20
|
KernelCircuitPublicInputs,
|
|
20
21
|
MergeRollupInputs,
|
|
21
22
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
22
23
|
PrivateKernelEmptyInputData,
|
|
24
|
+
Proof,
|
|
23
25
|
PublicKernelCircuitPrivateInputs,
|
|
24
26
|
PublicKernelCircuitPublicInputs,
|
|
25
27
|
PublicKernelInnerCircuitPrivateInputs,
|
|
@@ -32,7 +34,6 @@ import type {
|
|
|
32
34
|
RootRollupPublicInputs,
|
|
33
35
|
TubeInputs,
|
|
34
36
|
VMCircuitPublicInputs,
|
|
35
|
-
VerificationKeyData,
|
|
36
37
|
} from '@aztec/circuits.js';
|
|
37
38
|
import { randomBytes } from '@aztec/foundation/crypto';
|
|
38
39
|
import { AbortError, TimeoutError } from '@aztec/foundation/error';
|
|
@@ -279,7 +280,7 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
|
|
|
279
280
|
inputs: TubeInputs,
|
|
280
281
|
signal?: AbortSignal,
|
|
281
282
|
epochNumber?: number,
|
|
282
|
-
): Promise<
|
|
283
|
+
): Promise<ProofAndVerificationKey<RecursiveProof<typeof RECURSIVE_PROOF_LENGTH>>> {
|
|
283
284
|
return this.enqueue({ type: ProvingRequestType.TUBE_PROOF, inputs }, signal, epochNumber);
|
|
284
285
|
}
|
|
285
286
|
|
|
@@ -351,12 +352,12 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
|
|
|
351
352
|
return this.enqueue({ type: ProvingRequestType.BLOCK_ROOT_ROLLUP, inputs: input }, signal, epochNumber);
|
|
352
353
|
}
|
|
353
354
|
|
|
354
|
-
|
|
355
|
-
input:
|
|
355
|
+
getEmptyBlockRootRollupProof(
|
|
356
|
+
input: EmptyBlockRootRollupInputs,
|
|
356
357
|
signal?: AbortSignal,
|
|
357
358
|
epochNumber?: number,
|
|
358
359
|
): Promise<PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs>> {
|
|
359
|
-
return this.enqueue({ type: ProvingRequestType.
|
|
360
|
+
return this.enqueue({ type: ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP, inputs: input }, signal, epochNumber);
|
|
360
361
|
}
|
|
361
362
|
|
|
362
363
|
/**
|
|
@@ -426,7 +427,7 @@ export class MemoryProvingQueue implements ServerCircuitProver, ProvingJobSource
|
|
|
426
427
|
inputs: AvmCircuitInputs,
|
|
427
428
|
signal?: AbortSignal,
|
|
428
429
|
epochNumber?: number,
|
|
429
|
-
): Promise<
|
|
430
|
+
): Promise<ProofAndVerificationKey<Proof>> {
|
|
430
431
|
return this.enqueue({ type: ProvingRequestType.PUBLIC_VM, inputs }, signal, epochNumber);
|
|
431
432
|
}
|
|
432
433
|
|
|
@@ -181,12 +181,12 @@ export class ProverAgent {
|
|
|
181
181
|
return this.circuitProver.getMergeRollupProof(inputs);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
case ProvingRequestType.
|
|
185
|
-
return this.circuitProver.
|
|
184
|
+
case ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP: {
|
|
185
|
+
return this.circuitProver.getEmptyBlockRootRollupProof(inputs);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
case ProvingRequestType.
|
|
189
|
-
return this.circuitProver.
|
|
188
|
+
case ProvingRequestType.BLOCK_ROOT_ROLLUP: {
|
|
189
|
+
return this.circuitProver.getBlockRootRollupProof(inputs);
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
case ProvingRequestType.BLOCK_MERGE_ROLLUP: {
|