@aztec/prover-client 0.47.0 → 0.48.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 +2 -0
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +28 -30
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +11 -7
- package/dest/mocks/test_context.d.ts +3 -3
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +6 -24
- package/dest/orchestrator/block-building-helpers.d.ts +3 -3
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +6 -5
- package/dest/orchestrator/orchestrator.d.ts +11 -6
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +115 -89
- package/dest/orchestrator/orchestrator_metrics.d.ts +8 -0
- package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -0
- package/dest/orchestrator/orchestrator_metrics.js +19 -0
- package/dest/orchestrator/proving-state.d.ts +3 -1
- package/dest/orchestrator/proving-state.d.ts.map +1 -1
- package/dest/orchestrator/proving-state.js +5 -1
- package/dest/orchestrator/tx-proving-state.d.ts +3 -2
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +26 -8
- package/dest/prover-agent/memory-proving-queue.d.ts +15 -13
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +37 -55
- package/dest/prover-agent/prover-agent.d.ts.map +1 -1
- package/dest/prover-agent/prover-agent.js +30 -8
- package/dest/prover-agent/queue_metrics.d.ts +10 -0
- package/dest/prover-agent/queue_metrics.d.ts.map +1 -0
- package/dest/prover-agent/queue_metrics.js +23 -0
- package/dest/prover-agent/rpc.d.ts.map +1 -1
- package/dest/prover-agent/rpc.js +4 -2
- package/dest/tx-prover/factory.d.ts +1 -3
- package/dest/tx-prover/factory.d.ts.map +1 -1
- package/dest/tx-prover/factory.js +3 -3
- package/dest/tx-prover/tx-prover.d.ts +8 -33
- package/dest/tx-prover/tx-prover.d.ts.map +1 -1
- package/dest/tx-prover/tx-prover.js +18 -46
- package/package.json +10 -10
- package/src/config.ts +28 -47
- package/src/mocks/fixtures.ts +14 -4
- package/src/mocks/test_context.ts +7 -27
- package/src/orchestrator/block-building-helpers.ts +6 -5
- package/src/orchestrator/orchestrator.ts +197 -103
- package/src/orchestrator/orchestrator_metrics.ts +32 -0
- package/src/orchestrator/proving-state.ts +5 -0
- package/src/orchestrator/tx-proving-state.ts +33 -7
- package/src/prover-agent/memory-proving-queue.ts +54 -70
- package/src/prover-agent/prover-agent.ts +42 -7
- package/src/prover-agent/queue_metrics.ts +29 -0
- package/src/prover-agent/rpc.ts +3 -0
- package/src/tx-prover/factory.ts +2 -9
- package/src/tx-prover/tx-prover.ts +21 -64
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { type BBProverConfig } from '@aztec/bb-prover';
|
|
2
2
|
import {
|
|
3
3
|
type BlockProver,
|
|
4
|
-
type BlockResult,
|
|
5
4
|
type ProcessedTx,
|
|
6
|
-
type
|
|
5
|
+
type PublicExecutionRequest,
|
|
7
6
|
type ServerCircuitProver,
|
|
8
7
|
type Tx,
|
|
9
8
|
type TxValidator,
|
|
@@ -14,7 +13,6 @@ import { type DebugLogger } from '@aztec/foundation/log';
|
|
|
14
13
|
import { openTmpStore } from '@aztec/kv-store/utils';
|
|
15
14
|
import {
|
|
16
15
|
type ContractsDataSourcePublicDB,
|
|
17
|
-
type PublicExecutionRequest,
|
|
18
16
|
type PublicExecutionResult,
|
|
19
17
|
PublicExecutionResultBuilder,
|
|
20
18
|
type PublicExecutor,
|
|
@@ -36,27 +34,7 @@ import { MemoryProvingQueue } from '../prover-agent/memory-proving-queue.js';
|
|
|
36
34
|
import { ProverAgent } from '../prover-agent/prover-agent.js';
|
|
37
35
|
import { getEnvironmentConfig, getSimulationProvider, makeGlobals } from './fixtures.js';
|
|
38
36
|
|
|
39
|
-
class DummyProverClient implements BlockProver {
|
|
40
|
-
constructor(private orchestrator: ProvingOrchestrator) {}
|
|
41
|
-
startNewBlock(numTxs: number, globalVariables: GlobalVariables, l1ToL2Messages: Fr[]): Promise<ProvingTicket> {
|
|
42
|
-
return this.orchestrator.startNewBlock(numTxs, globalVariables, l1ToL2Messages);
|
|
43
|
-
}
|
|
44
|
-
addNewTx(tx: ProcessedTx): Promise<void> {
|
|
45
|
-
return this.orchestrator.addNewTx(tx);
|
|
46
|
-
}
|
|
47
|
-
cancelBlock(): void {
|
|
48
|
-
return this.orchestrator.cancelBlock();
|
|
49
|
-
}
|
|
50
|
-
finaliseBlock(): Promise<BlockResult> {
|
|
51
|
-
return this.orchestrator.finaliseBlock();
|
|
52
|
-
}
|
|
53
|
-
setBlockCompleted(): Promise<void> {
|
|
54
|
-
return this.orchestrator.setBlockCompleted();
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
37
|
export class TestContext {
|
|
59
|
-
public blockProver: BlockProver;
|
|
60
38
|
constructor(
|
|
61
39
|
public publicExecutor: MockProxy<PublicExecutor>,
|
|
62
40
|
public publicContractsDB: MockProxy<ContractsDataSourcePublicDB>,
|
|
@@ -71,8 +49,10 @@ export class TestContext {
|
|
|
71
49
|
public blockNumber: number,
|
|
72
50
|
public directoriesToCleanup: string[],
|
|
73
51
|
public logger: DebugLogger,
|
|
74
|
-
) {
|
|
75
|
-
|
|
52
|
+
) {}
|
|
53
|
+
|
|
54
|
+
public get blockProver() {
|
|
55
|
+
return this.orchestrator;
|
|
76
56
|
}
|
|
77
57
|
|
|
78
58
|
static async new(
|
|
@@ -119,7 +99,7 @@ export class TestContext {
|
|
|
119
99
|
localProver = await createProver(bbConfig);
|
|
120
100
|
}
|
|
121
101
|
|
|
122
|
-
const queue = new MemoryProvingQueue();
|
|
102
|
+
const queue = new MemoryProvingQueue(telemetry);
|
|
123
103
|
const orchestrator = new ProvingOrchestrator(actualDb, queue, telemetry);
|
|
124
104
|
const agent = new ProverAgent(localProver, proverCount);
|
|
125
105
|
|
|
@@ -171,7 +151,7 @@ export class TestContext {
|
|
|
171
151
|
: [...tx.enqueuedPublicFunctionCalls, tx.publicTeardownFunctionCall];
|
|
172
152
|
for (const request of allCalls) {
|
|
173
153
|
if (execution.contractAddress.equals(request.contractAddress)) {
|
|
174
|
-
const result = PublicExecutionResultBuilder.
|
|
154
|
+
const result = PublicExecutionResultBuilder.fromPublicExecutionRequest({ request }).build({
|
|
175
155
|
startGasLeft: availableGas,
|
|
176
156
|
endGasLeft: availableGas,
|
|
177
157
|
transactionFee,
|
|
@@ -37,7 +37,6 @@ import {
|
|
|
37
37
|
type RootRollupPublicInputs,
|
|
38
38
|
StateDiffHints,
|
|
39
39
|
type StateReference,
|
|
40
|
-
type TUBE_PROOF_LENGTH,
|
|
41
40
|
VK_TREE_HEIGHT,
|
|
42
41
|
type VerificationKeyAsFields,
|
|
43
42
|
type VerificationKeyData,
|
|
@@ -61,7 +60,7 @@ export type TreeNames = BaseTreeNames | 'L1ToL2MessageTree' | 'Archive';
|
|
|
61
60
|
// Builds the base rollup inputs, updating the contract, nullifier, and data trees in the process
|
|
62
61
|
export async function buildBaseRollupInput(
|
|
63
62
|
tx: ProcessedTx,
|
|
64
|
-
proof: RecursiveProof<typeof
|
|
63
|
+
proof: RecursiveProof<typeof NESTED_RECURSIVE_PROOF_LENGTH>,
|
|
65
64
|
globalVariables: GlobalVariables,
|
|
66
65
|
db: MerkleTreeOperations,
|
|
67
66
|
kernelVk: VerificationKeyData,
|
|
@@ -84,13 +83,13 @@ export async function buildBaseRollupInput(
|
|
|
84
83
|
i < noteHashSubtreeSiblingPathArray.length ? noteHashSubtreeSiblingPathArray[i] : Fr.ZERO,
|
|
85
84
|
);
|
|
86
85
|
|
|
87
|
-
// Create data hint for reading fee payer initial balance in
|
|
86
|
+
// Create data hint for reading fee payer initial balance in Fee Juice
|
|
88
87
|
// If no fee payer is set, read hint should be empty
|
|
89
88
|
// If there is already a public data write for this slot, also skip the read hint
|
|
90
89
|
const hintsBuilder = new HintsBuilder(db);
|
|
91
90
|
const leafSlot = computeFeePayerBalanceLeafSlot(tx.data.feePayer);
|
|
92
91
|
const existingBalanceWrite = tx.data.end.publicDataUpdateRequests.find(write => write.leafSlot.equals(leafSlot));
|
|
93
|
-
const
|
|
92
|
+
const feePayerFeeJuiceBalanceReadHint =
|
|
94
93
|
leafSlot.isZero() || existingBalanceWrite
|
|
95
94
|
? PublicDataHint.empty()
|
|
96
95
|
: await hintsBuilder.getPublicDataHint(leafSlot.toBigInt());
|
|
@@ -163,7 +162,7 @@ export async function buildBaseRollupInput(
|
|
|
163
162
|
kernelData: getKernelDataFor(tx, kernelVk, proof),
|
|
164
163
|
start,
|
|
165
164
|
stateDiffHints,
|
|
166
|
-
|
|
165
|
+
feePayerFeeJuiceBalanceReadHint: feePayerFeeJuiceBalanceReadHint,
|
|
167
166
|
sortedPublicDataWrites: txPublicDataUpdateRequestInfo.sortedPublicDataWrites,
|
|
168
167
|
sortedPublicDataWritesIndexes: txPublicDataUpdateRequestInfo.sortedPublicDataWritesIndexes,
|
|
169
168
|
lowPublicDataWritesPreimages: txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages,
|
|
@@ -224,6 +223,7 @@ export async function getRootRollupInput(
|
|
|
224
223
|
messageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
225
224
|
messageTreeRootSiblingPath: Tuple<Fr, typeof L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>,
|
|
226
225
|
db: MerkleTreeOperations,
|
|
226
|
+
proverId: Fr,
|
|
227
227
|
) {
|
|
228
228
|
const previousRollupData: RootRollupInputs['previousRollupData'] = [
|
|
229
229
|
getPreviousRollupDataFromPublicInputs(rollupOutputLeft, rollupProofLeft, verificationKeyLeft),
|
|
@@ -254,6 +254,7 @@ export async function getRootRollupInput(
|
|
|
254
254
|
startL1ToL2MessageTreeSnapshot: messageTreeSnapshot,
|
|
255
255
|
startArchiveSnapshot,
|
|
256
256
|
newArchiveSiblingPath,
|
|
257
|
+
proverId,
|
|
257
258
|
});
|
|
258
259
|
}
|
|
259
260
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Body,
|
|
3
|
+
EncryptedNoteTxL2Logs,
|
|
4
|
+
EncryptedTxL2Logs,
|
|
3
5
|
L2Block,
|
|
4
6
|
MerkleTreeId,
|
|
5
7
|
type PaddingProcessedTx,
|
|
@@ -15,6 +17,7 @@ import {
|
|
|
15
17
|
} from '@aztec/circuit-types';
|
|
16
18
|
import {
|
|
17
19
|
BlockProofError,
|
|
20
|
+
type BlockProver,
|
|
18
21
|
type BlockResult,
|
|
19
22
|
PROVING_STATUS,
|
|
20
23
|
type ProvingResult,
|
|
@@ -34,19 +37,22 @@ import {
|
|
|
34
37
|
type KernelCircuitPublicInputs,
|
|
35
38
|
L1_TO_L2_MSG_SUBTREE_HEIGHT,
|
|
36
39
|
L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH,
|
|
37
|
-
|
|
40
|
+
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
38
41
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
39
42
|
NUM_BASE_PARITY_PER_ROOT_PARITY,
|
|
43
|
+
PrivateKernelEmptyInputData,
|
|
40
44
|
type Proof,
|
|
41
45
|
type PublicKernelCircuitPublicInputs,
|
|
42
46
|
type RECURSIVE_PROOF_LENGTH,
|
|
43
47
|
type RecursiveProof,
|
|
44
48
|
type RootParityInput,
|
|
45
49
|
RootParityInputs,
|
|
50
|
+
type TUBE_PROOF_LENGTH,
|
|
46
51
|
TubeInputs,
|
|
47
52
|
type VerificationKeyAsFields,
|
|
48
53
|
VerificationKeyData,
|
|
49
54
|
makeEmptyProof,
|
|
55
|
+
makeEmptyRecursiveProof,
|
|
50
56
|
} from '@aztec/circuits.js';
|
|
51
57
|
import { makeTuple } from '@aztec/foundation/array';
|
|
52
58
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
@@ -55,7 +61,8 @@ import { createDebugLogger } from '@aztec/foundation/log';
|
|
|
55
61
|
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
56
62
|
import { BufferReader, type Tuple } from '@aztec/foundation/serialize';
|
|
57
63
|
import { pushTestData } from '@aztec/foundation/testing';
|
|
58
|
-
import {
|
|
64
|
+
import { elapsed } from '@aztec/foundation/timer';
|
|
65
|
+
import { getVKIndex, getVKSiblingPath, getVKTreeRoot } from '@aztec/noir-protocol-circuits-types';
|
|
59
66
|
import { Attributes, type TelemetryClient, type Tracer, trackSpan, wrapCallbackInSpan } from '@aztec/telemetry-client';
|
|
60
67
|
import { type MerkleTreeOperations } from '@aztec/world-state';
|
|
61
68
|
|
|
@@ -71,8 +78,9 @@ import {
|
|
|
71
78
|
validateRootOutput,
|
|
72
79
|
validateTx,
|
|
73
80
|
} from './block-building-helpers.js';
|
|
81
|
+
import { ProvingOrchestratorMetrics } from './orchestrator_metrics.js';
|
|
74
82
|
import { type MergeRollupInputData, ProvingState, type TreeSnapshots } from './proving-state.js';
|
|
75
|
-
import { TX_PROVING_CODE, TxProvingState } from './tx-proving-state.js';
|
|
83
|
+
import { TX_PROVING_CODE, type TxProvingInstruction, TxProvingState } from './tx-proving-state.js';
|
|
76
84
|
|
|
77
85
|
const logger = createDebugLogger('aztec:prover:proving-orchestrator');
|
|
78
86
|
|
|
@@ -90,15 +98,28 @@ const logger = createDebugLogger('aztec:prover:proving-orchestrator');
|
|
|
90
98
|
/**
|
|
91
99
|
* The orchestrator, managing the flow of recursive proving operations required to build the rollup proof tree.
|
|
92
100
|
*/
|
|
93
|
-
export class ProvingOrchestrator {
|
|
101
|
+
export class ProvingOrchestrator implements BlockProver {
|
|
94
102
|
private provingState: ProvingState | undefined = undefined;
|
|
95
103
|
private pendingProvingJobs: AbortController[] = [];
|
|
96
104
|
private paddingTx: PaddingProcessedTx | undefined = undefined;
|
|
97
105
|
|
|
98
|
-
|
|
106
|
+
private metrics: ProvingOrchestratorMetrics;
|
|
99
107
|
|
|
100
|
-
constructor(
|
|
101
|
-
|
|
108
|
+
constructor(
|
|
109
|
+
private db: MerkleTreeOperations,
|
|
110
|
+
private prover: ServerCircuitProver,
|
|
111
|
+
telemetryClient: TelemetryClient,
|
|
112
|
+
private readonly proverId: Fr = Fr.ZERO,
|
|
113
|
+
) {
|
|
114
|
+
this.metrics = new ProvingOrchestratorMetrics(telemetryClient, 'ProvingOrchestrator');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
get tracer(): Tracer {
|
|
118
|
+
return this.metrics.tracer;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public getProverId(): Fr {
|
|
122
|
+
return this.proverId;
|
|
102
123
|
}
|
|
103
124
|
|
|
104
125
|
/**
|
|
@@ -128,9 +149,22 @@ export class ProvingOrchestrator {
|
|
|
128
149
|
if (!Number.isInteger(numTxs) || numTxs < 2) {
|
|
129
150
|
throw new Error(`Length of txs for the block should be at least two (got ${numTxs})`);
|
|
130
151
|
}
|
|
152
|
+
|
|
153
|
+
// TODO(palla/prover-node): Store block number in the db itself to make this check more reliable,
|
|
154
|
+
// and turn this warning into an exception that we throw.
|
|
155
|
+
const { blockNumber } = globalVariables;
|
|
156
|
+
const dbBlockNumber = (await this.db.getTreeInfo(MerkleTreeId.ARCHIVE)).size - 1n;
|
|
157
|
+
if (dbBlockNumber !== blockNumber.toBigInt() - 1n) {
|
|
158
|
+
logger.warn(
|
|
159
|
+
`Database is at wrong block number (starting block ${blockNumber.toBigInt()} with db at ${dbBlockNumber})`,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
131
163
|
// Cancel any currently proving block before starting a new one
|
|
132
164
|
this.cancelBlock();
|
|
133
|
-
logger.info(
|
|
165
|
+
logger.info(
|
|
166
|
+
`Starting block ${globalVariables.blockNumber} for slot ${globalVariables.slotNumber} with ${numTxs} transactions`,
|
|
167
|
+
);
|
|
134
168
|
// we start the block by enqueueing all of the base parity circuits
|
|
135
169
|
let baseParityInputs: BaseParityInputs[] = [];
|
|
136
170
|
let l1ToL2MessagesPadded: Tuple<Fr, typeof NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP>;
|
|
@@ -218,7 +252,7 @@ export class ProvingOrchestrator {
|
|
|
218
252
|
}
|
|
219
253
|
|
|
220
254
|
const [inputs, treeSnapshots] = await this.prepareTransaction(tx, this.provingState);
|
|
221
|
-
this.
|
|
255
|
+
this.enqueueFirstProofs(inputs, treeSnapshots, tx, this.provingState);
|
|
222
256
|
}
|
|
223
257
|
|
|
224
258
|
/**
|
|
@@ -301,16 +335,17 @@ export class ProvingOrchestrator {
|
|
|
301
335
|
},
|
|
302
336
|
signal =>
|
|
303
337
|
this.prover.getEmptyPrivateKernelProof(
|
|
304
|
-
|
|
338
|
+
new PrivateKernelEmptyInputData(
|
|
339
|
+
unprovenPaddingTx.data.constants.historicalHeader,
|
|
305
340
|
// Chain id and version should not change even if the proving state does, so it's safe to use them for the padding tx
|
|
306
341
|
// which gets cached across multiple runs of the orchestrator with different proving states. If they were to change,
|
|
307
342
|
// we'd have to clear out the paddingTx here and regenerate it when they do.
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
},
|
|
343
|
+
unprovenPaddingTx.data.constants.txContext.chainId,
|
|
344
|
+
unprovenPaddingTx.data.constants.txContext.version,
|
|
345
|
+
getVKTreeRoot(),
|
|
346
|
+
),
|
|
313
347
|
signal,
|
|
348
|
+
provingState.epochNumber,
|
|
314
349
|
),
|
|
315
350
|
),
|
|
316
351
|
result => {
|
|
@@ -333,14 +368,16 @@ export class ProvingOrchestrator {
|
|
|
333
368
|
provingState: ProvingState,
|
|
334
369
|
) {
|
|
335
370
|
// The padding tx contains the proof and vk, generated separately from the base inputs
|
|
336
|
-
// Copy these into the base rollup inputs
|
|
371
|
+
// Copy these into the base rollup inputs and enqueue the base rollup proof
|
|
337
372
|
for (let i = 0; i < txInputs.length; i++) {
|
|
338
373
|
txInputs[i].inputs.kernelData.vk = paddingTx.verificationKey;
|
|
339
374
|
txInputs[i].inputs.kernelData.proof = paddingTx.recursiveProof;
|
|
340
375
|
|
|
341
376
|
txInputs[i].inputs.kernelData.vkIndex = getVKIndex(paddingTx.verificationKey);
|
|
342
377
|
txInputs[i].inputs.kernelData.vkPath = getVKSiblingPath(txInputs[i].inputs.kernelData.vkIndex);
|
|
343
|
-
|
|
378
|
+
const txProvingState = new TxProvingState(paddingTx, txInputs[i].inputs, txInputs[i].snapshot);
|
|
379
|
+
const txIndex = provingState.addNewTx(txProvingState);
|
|
380
|
+
this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
|
|
344
381
|
}
|
|
345
382
|
}
|
|
346
383
|
|
|
@@ -443,32 +480,22 @@ export class ProvingOrchestrator {
|
|
|
443
480
|
const txInputs = await this.prepareBaseRollupInputs(provingState, tx);
|
|
444
481
|
if (!txInputs) {
|
|
445
482
|
// This should not be possible
|
|
446
|
-
throw new Error(`Unable to add
|
|
483
|
+
throw new Error(`Unable to add transaction, preparing base inputs failed`);
|
|
447
484
|
}
|
|
448
485
|
return txInputs;
|
|
449
486
|
}
|
|
450
487
|
|
|
451
|
-
private
|
|
488
|
+
private enqueueFirstProofs(
|
|
452
489
|
inputs: BaseRollupInputs,
|
|
453
490
|
treeSnapshots: TreeSnapshots,
|
|
454
491
|
tx: ProcessedTx,
|
|
455
492
|
provingState: ProvingState,
|
|
456
493
|
) {
|
|
457
|
-
const txProvingState = new TxProvingState(
|
|
458
|
-
tx,
|
|
459
|
-
inputs,
|
|
460
|
-
treeSnapshots,
|
|
461
|
-
ProtocolCircuitVks.PrivateKernelTailToPublicArtifact,
|
|
462
|
-
);
|
|
494
|
+
const txProvingState = new TxProvingState(tx, inputs, treeSnapshots);
|
|
463
495
|
const txIndex = provingState.addNewTx(txProvingState);
|
|
496
|
+
this.enqueueTube(provingState, txIndex);
|
|
464
497
|
const numPublicKernels = txProvingState.getNumPublicKernels();
|
|
465
|
-
|
|
466
|
-
// no public functions, go straight to the base rollup
|
|
467
|
-
logger.debug(`Enqueueing base rollup for tx ${txIndex}`);
|
|
468
|
-
this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
// Enqueue all of the VM/kernel proving requests
|
|
498
|
+
// Enqueue all of the VM proving requests
|
|
472
499
|
// Rather than handle the Kernel Tail as a special case here, we will just handle it inside enqueueVM
|
|
473
500
|
for (let i = 0; i < numPublicKernels; i++) {
|
|
474
501
|
logger.debug(`Enqueueing public VM ${i} for tx ${txIndex}`);
|
|
@@ -551,22 +578,22 @@ export class ProvingOrchestrator {
|
|
|
551
578
|
return;
|
|
552
579
|
}
|
|
553
580
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
581
|
+
// We build the base rollup inputs using a mock proof and verification key.
|
|
582
|
+
// These will be overwritten later once we have proven the tube circuit and any public kernels
|
|
583
|
+
const [ms, inputs] = await elapsed(
|
|
584
|
+
buildBaseRollupInput(
|
|
585
|
+
tx,
|
|
586
|
+
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
587
|
+
provingState.globalVariables,
|
|
588
|
+
this.db,
|
|
589
|
+
VerificationKeyData.makeFake(),
|
|
590
|
+
),
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
if (!tx.isEmpty) {
|
|
594
|
+
this.metrics.recordBaseRollupInputs(ms);
|
|
595
|
+
}
|
|
561
596
|
|
|
562
|
-
const proof = await this.prover.getEmptyTubeProof(inputs);
|
|
563
|
-
return await buildBaseRollupInput(tx, proof.proof, provingState.globalVariables, this.db, proof.verificationKey);
|
|
564
|
-
};
|
|
565
|
-
const getBaseInputsNonEmptyTx = async () => {
|
|
566
|
-
const proof = await this.prover.getTubeProof(new TubeInputs(tx.clientIvcProof));
|
|
567
|
-
return await buildBaseRollupInput(tx, proof.tubeProof, provingState.globalVariables, this.db, proof.tubeVK);
|
|
568
|
-
};
|
|
569
|
-
const inputs = tx.isEmpty ? await getBaseInputsEmptyTx() : await getBaseInputsNonEmptyTx();
|
|
570
597
|
const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(
|
|
571
598
|
async (id: MerkleTreeId) => {
|
|
572
599
|
return { key: id, value: await getTreeSnapshot(id, this.db) };
|
|
@@ -613,28 +640,30 @@ export class ProvingOrchestrator {
|
|
|
613
640
|
logger.debug('Not running base rollup, state invalid');
|
|
614
641
|
return;
|
|
615
642
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
.
|
|
619
|
-
.
|
|
620
|
-
)
|
|
643
|
+
const txNoteEncryptedLogs = EncryptedNoteTxL2Logs.hashNoteLogs(
|
|
644
|
+
tx.baseRollupInputs.kernelData.publicInputs.end.noteEncryptedLogsHashes
|
|
645
|
+
.filter(log => !log.isEmpty())
|
|
646
|
+
.map(log => log.value.toBuffer()),
|
|
647
|
+
);
|
|
648
|
+
if (!txNoteEncryptedLogs.equals(tx.processedTx.noteEncryptedLogs.hash())) {
|
|
621
649
|
provingState.reject(
|
|
622
|
-
`Note encrypted logs hash mismatch: ${
|
|
623
|
-
tx.
|
|
624
|
-
|
|
650
|
+
`Note encrypted logs hash mismatch: ${Fr.fromBuffer(txNoteEncryptedLogs)} === ${Fr.fromBuffer(
|
|
651
|
+
tx.processedTx.noteEncryptedLogs.hash(),
|
|
652
|
+
)}`,
|
|
625
653
|
);
|
|
626
654
|
return;
|
|
627
655
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
.
|
|
631
|
-
.
|
|
632
|
-
)
|
|
656
|
+
const txEncryptedLogs = EncryptedTxL2Logs.hashSiloedLogs(
|
|
657
|
+
tx.baseRollupInputs.kernelData.publicInputs.end.encryptedLogsHashes
|
|
658
|
+
.filter(log => !log.isEmpty())
|
|
659
|
+
.map(log => log.getSiloedHash()),
|
|
660
|
+
);
|
|
661
|
+
if (!txEncryptedLogs.equals(tx.processedTx.encryptedLogs.hash())) {
|
|
633
662
|
// @todo This rejection messages is never seen. Never making it out to the logs
|
|
634
663
|
provingState.reject(
|
|
635
|
-
`Encrypted logs hash mismatch: ${
|
|
636
|
-
tx.
|
|
637
|
-
|
|
664
|
+
`Encrypted logs hash mismatch: ${Fr.fromBuffer(txEncryptedLogs)} === ${Fr.fromBuffer(
|
|
665
|
+
tx.processedTx.encryptedLogs.hash(),
|
|
666
|
+
)}`,
|
|
638
667
|
);
|
|
639
668
|
return;
|
|
640
669
|
}
|
|
@@ -669,7 +698,7 @@ export class ProvingOrchestrator {
|
|
|
669
698
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
670
699
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'base-rollup' as CircuitName,
|
|
671
700
|
},
|
|
672
|
-
signal => this.prover.getBaseRollupProof(tx.baseRollupInputs, signal),
|
|
701
|
+
signal => this.prover.getBaseRollupProof(tx.baseRollupInputs, signal, provingState.epochNumber),
|
|
673
702
|
),
|
|
674
703
|
result => {
|
|
675
704
|
logger.debug(`Completed proof for base rollup for tx ${tx.processedTx.hash.toString()}`);
|
|
@@ -684,6 +713,49 @@ export class ProvingOrchestrator {
|
|
|
684
713
|
);
|
|
685
714
|
}
|
|
686
715
|
|
|
716
|
+
// Enqueues the tub circuit for a given transaction index
|
|
717
|
+
// Once completed, will enqueue the next circuit, either a public kernel or the base rollup
|
|
718
|
+
private enqueueTube(provingState: ProvingState, txIndex: number) {
|
|
719
|
+
if (!provingState?.verifyState()) {
|
|
720
|
+
logger.debug('Not running tube circuit, state invalid');
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
725
|
+
logger.debug(`Enqueuing tube circuit for tx index: ${txIndex}`);
|
|
726
|
+
|
|
727
|
+
this.deferredProving(
|
|
728
|
+
provingState,
|
|
729
|
+
wrapCallbackInSpan(
|
|
730
|
+
this.tracer,
|
|
731
|
+
'ProvingOrchestrator.prover.getTubeProof',
|
|
732
|
+
{
|
|
733
|
+
[Attributes.TX_HASH]: txProvingState.processedTx.hash.toString(),
|
|
734
|
+
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
735
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'tube-circuit' as CircuitName,
|
|
736
|
+
},
|
|
737
|
+
signal =>
|
|
738
|
+
this.prover.getTubeProof(
|
|
739
|
+
new TubeInputs(txProvingState.processedTx.clientIvcProof),
|
|
740
|
+
signal,
|
|
741
|
+
provingState.epochNumber,
|
|
742
|
+
),
|
|
743
|
+
),
|
|
744
|
+
result => {
|
|
745
|
+
logger.debug(`Completed tube proof for tx index: ${txIndex}`);
|
|
746
|
+
const nextKernelRequest = txProvingState.getNextPublicKernelFromTubeProof(result.tubeProof, result.tubeVK);
|
|
747
|
+
this.checkAndEnqueueNextTxCircuit(
|
|
748
|
+
provingState,
|
|
749
|
+
txIndex,
|
|
750
|
+
-1,
|
|
751
|
+
result.tubeProof,
|
|
752
|
+
result.tubeVK,
|
|
753
|
+
nextKernelRequest,
|
|
754
|
+
);
|
|
755
|
+
},
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
|
|
687
759
|
// Executes the merge rollup circuit and stored the output as intermediate state for the parent merge/root circuit
|
|
688
760
|
// Enqueues the next level of merge if all inputs are available
|
|
689
761
|
private enqueueMergeRollup(
|
|
@@ -706,7 +778,7 @@ export class ProvingOrchestrator {
|
|
|
706
778
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
707
779
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'merge-rollup' as CircuitName,
|
|
708
780
|
},
|
|
709
|
-
signal => this.prover.getMergeRollupProof(inputs, signal),
|
|
781
|
+
signal => this.prover.getMergeRollupProof(inputs, signal, provingState.epochNumber),
|
|
710
782
|
),
|
|
711
783
|
result => {
|
|
712
784
|
this.storeAndExecuteNextMergeLevel(provingState, level, index, [
|
|
@@ -739,6 +811,7 @@ export class ProvingOrchestrator {
|
|
|
739
811
|
provingState.messageTreeSnapshot,
|
|
740
812
|
provingState.messageTreeRootSiblingPath,
|
|
741
813
|
this.db,
|
|
814
|
+
this.proverId,
|
|
742
815
|
);
|
|
743
816
|
|
|
744
817
|
this.deferredProving(
|
|
@@ -750,7 +823,7 @@ export class ProvingOrchestrator {
|
|
|
750
823
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
751
824
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'root-rollup' as CircuitName,
|
|
752
825
|
},
|
|
753
|
-
signal => this.prover.getRootRollupProof(inputs, signal),
|
|
826
|
+
signal => this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber),
|
|
754
827
|
),
|
|
755
828
|
result => {
|
|
756
829
|
provingState.rootRollupPublicInputs = result.inputs;
|
|
@@ -780,7 +853,7 @@ export class ProvingOrchestrator {
|
|
|
780
853
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
781
854
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'base-parity' as CircuitName,
|
|
782
855
|
},
|
|
783
|
-
signal => this.prover.getBaseParityProof(inputs, signal),
|
|
856
|
+
signal => this.prover.getBaseParityProof(inputs, signal, provingState.epochNumber),
|
|
784
857
|
),
|
|
785
858
|
rootInput => {
|
|
786
859
|
provingState.setRootParityInputs(rootInput, index);
|
|
@@ -799,7 +872,7 @@ export class ProvingOrchestrator {
|
|
|
799
872
|
|
|
800
873
|
// Runs the root parity circuit ans stored the outputs
|
|
801
874
|
// Enqueues the root rollup proof if all inputs are available
|
|
802
|
-
private enqueueRootParityCircuit(provingState: ProvingState
|
|
875
|
+
private enqueueRootParityCircuit(provingState: ProvingState, inputs: RootParityInputs) {
|
|
803
876
|
this.deferredProving(
|
|
804
877
|
provingState,
|
|
805
878
|
wrapCallbackInSpan(
|
|
@@ -809,7 +882,7 @@ export class ProvingOrchestrator {
|
|
|
809
882
|
[Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
|
|
810
883
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'root-parity' as CircuitName,
|
|
811
884
|
},
|
|
812
|
-
signal => this.prover.getRootParityProof(inputs, signal),
|
|
885
|
+
signal => this.prover.getRootParityProof(inputs, signal, provingState.epochNumber),
|
|
813
886
|
),
|
|
814
887
|
async rootInput => {
|
|
815
888
|
provingState!.finalRootParityInput = rootInput;
|
|
@@ -895,7 +968,7 @@ export class ProvingOrchestrator {
|
|
|
895
968
|
publicFunction.vmRequest!.avmHints,
|
|
896
969
|
);
|
|
897
970
|
try {
|
|
898
|
-
return await this.prover.getAvmProof(inputs, signal);
|
|
971
|
+
return await this.prover.getAvmProof(inputs, signal, provingState.epochNumber);
|
|
899
972
|
} catch (err) {
|
|
900
973
|
if (process.env.AVM_PROVING_STRICT) {
|
|
901
974
|
throw err;
|
|
@@ -909,14 +982,14 @@ export class ProvingOrchestrator {
|
|
|
909
982
|
);
|
|
910
983
|
this.deferredProving(provingState, doAvmProving, proofAndVk => {
|
|
911
984
|
logger.debug(`Proven VM for function index ${functionIndex} of tx index ${txIndex}`);
|
|
912
|
-
this.
|
|
985
|
+
this.checkAndEnqueuePublicKernelFromVMProof(provingState, txIndex, functionIndex, proofAndVk.proof);
|
|
913
986
|
});
|
|
914
987
|
} else {
|
|
915
|
-
this.
|
|
988
|
+
this.checkAndEnqueuePublicKernelFromVMProof(provingState, txIndex, functionIndex, /*vmProof=*/ makeEmptyProof());
|
|
916
989
|
}
|
|
917
990
|
}
|
|
918
991
|
|
|
919
|
-
private
|
|
992
|
+
private checkAndEnqueuePublicKernelFromVMProof(
|
|
920
993
|
provingState: ProvingState,
|
|
921
994
|
txIndex: number,
|
|
922
995
|
functionIndex: number,
|
|
@@ -934,6 +1007,47 @@ export class ProvingOrchestrator {
|
|
|
934
1007
|
}
|
|
935
1008
|
}
|
|
936
1009
|
|
|
1010
|
+
// Takes a proof and verification key, passes it to the proving state before enqueueing the next proof
|
|
1011
|
+
// This could be either a public kernel or the base rollup
|
|
1012
|
+
// Alternatively, if we are still waiting on a public VM prof then it will continue waiting
|
|
1013
|
+
private checkAndEnqueueNextTxCircuit(
|
|
1014
|
+
provingState: ProvingState,
|
|
1015
|
+
txIndex: number,
|
|
1016
|
+
completedFunctionIndex: number,
|
|
1017
|
+
proof: RecursiveProof<typeof NESTED_RECURSIVE_PROOF_LENGTH> | RecursiveProof<typeof TUBE_PROOF_LENGTH>,
|
|
1018
|
+
verificationKey: VerificationKeyData,
|
|
1019
|
+
nextKernelRequest: TxProvingInstruction,
|
|
1020
|
+
) {
|
|
1021
|
+
const txProvingState = provingState.getTxProvingState(txIndex);
|
|
1022
|
+
// What's the status of the next kernel?
|
|
1023
|
+
if (nextKernelRequest.code === TX_PROVING_CODE.NOT_READY) {
|
|
1024
|
+
// Must be waiting on a VM proof
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
if (nextKernelRequest.code === TX_PROVING_CODE.COMPLETED) {
|
|
1029
|
+
// We must have completed all public function proving, we now move to the base rollup
|
|
1030
|
+
logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
1031
|
+
// Take the final proof and assign it to the base rollup inputs
|
|
1032
|
+
txProvingState.baseRollupInputs.kernelData.proof = proof;
|
|
1033
|
+
txProvingState.baseRollupInputs.kernelData.vk = verificationKey;
|
|
1034
|
+
txProvingState.baseRollupInputs.kernelData.vkIndex = getVKIndex(verificationKey);
|
|
1035
|
+
txProvingState.baseRollupInputs.kernelData.vkPath = getVKSiblingPath(
|
|
1036
|
+
txProvingState.baseRollupInputs.kernelData.vkIndex,
|
|
1037
|
+
);
|
|
1038
|
+
|
|
1039
|
+
this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
// There must be another kernel ready to be proven
|
|
1043
|
+
if (nextKernelRequest.function === undefined) {
|
|
1044
|
+
// Should not be possible
|
|
1045
|
+
throw new Error(`Error occurred, public function request undefined after kernel proof completed`);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
this.enqueuePublicKernel(provingState, txIndex, completedFunctionIndex + 1);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
937
1051
|
/**
|
|
938
1052
|
* Executes the kernel circuit for a public function, will enqueue the next kernel circuit if it's VM is already proven
|
|
939
1053
|
* or the base rollup circuit if there are no more kernels to be proven
|
|
@@ -965,46 +1079,26 @@ export class ProvingOrchestrator {
|
|
|
965
1079
|
signal,
|
|
966
1080
|
): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs | PublicKernelCircuitPublicInputs>> => {
|
|
967
1081
|
if (request.type === PublicKernelType.TAIL) {
|
|
968
|
-
return this.prover.getPublicTailProof(request, signal);
|
|
1082
|
+
return this.prover.getPublicTailProof(request, signal, provingState.epochNumber);
|
|
969
1083
|
} else {
|
|
970
|
-
return this.prover.getPublicKernelProof(request, signal);
|
|
1084
|
+
return this.prover.getPublicKernelProof(request, signal, provingState.epochNumber);
|
|
971
1085
|
}
|
|
972
1086
|
},
|
|
973
1087
|
),
|
|
974
1088
|
result => {
|
|
975
1089
|
const nextKernelRequest = txProvingState.getNextPublicKernelFromKernelProof(
|
|
976
1090
|
functionIndex,
|
|
977
|
-
// PUBLIC KERNEL: I want to pass a client ivc proof into here?
|
|
978
1091
|
result.proof,
|
|
979
1092
|
result.verificationKey,
|
|
980
1093
|
);
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
logger.debug(`Public functions completed for tx ${txIndex} enqueueing base rollup`);
|
|
990
|
-
// Take the final public tail proof and verification key and pass them to the base rollup
|
|
991
|
-
txProvingState.baseRollupInputs.kernelData.proof = result.proof;
|
|
992
|
-
txProvingState.baseRollupInputs.kernelData.vk = result.verificationKey;
|
|
993
|
-
txProvingState.baseRollupInputs.kernelData.vkIndex = getVKIndex(result.verificationKey);
|
|
994
|
-
txProvingState.baseRollupInputs.kernelData.vkPath = getVKSiblingPath(
|
|
995
|
-
txProvingState.baseRollupInputs.kernelData.vkIndex,
|
|
996
|
-
);
|
|
997
|
-
|
|
998
|
-
this.enqueueBaseRollup(provingState, BigInt(txIndex), txProvingState);
|
|
999
|
-
return;
|
|
1000
|
-
}
|
|
1001
|
-
// There must be another kernel ready to be proven
|
|
1002
|
-
if (nextKernelRequest.function === undefined) {
|
|
1003
|
-
// Should not be possible
|
|
1004
|
-
throw new Error(`Error occurred, public function request undefined after kernel proof completed`);
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
this.enqueuePublicKernel(provingState, txIndex, functionIndex + 1);
|
|
1094
|
+
this.checkAndEnqueueNextTxCircuit(
|
|
1095
|
+
provingState,
|
|
1096
|
+
txIndex,
|
|
1097
|
+
functionIndex,
|
|
1098
|
+
result.proof,
|
|
1099
|
+
result.verificationKey,
|
|
1100
|
+
nextKernelRequest,
|
|
1101
|
+
);
|
|
1008
1102
|
},
|
|
1009
1103
|
);
|
|
1010
1104
|
}
|