@aztec/prover-client 1.0.0-nightly.20250608 → 1.0.0-nightly.20250610
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/block-factory/light.d.ts.map +1 -1
- package/dest/block-factory/light.js +2 -1
- package/dest/mocks/test_context.d.ts +1 -0
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +3 -0
- package/dest/orchestrator/block-building-helpers.d.ts +7 -7
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +36 -24
- package/dest/orchestrator/block-proving-state.d.ts +10 -2
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +55 -18
- package/dest/orchestrator/epoch-proving-state.d.ts +9 -3
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +33 -8
- package/dest/orchestrator/orchestrator.d.ts +3 -1
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +30 -10
- package/dest/prover-client/prover-client.d.ts +1 -1
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +2 -0
- package/dest/prover-client/server-epoch-prover.d.ts +3 -1
- package/dest/prover-client/server-epoch-prover.d.ts.map +1 -1
- package/dest/prover-client/server-epoch-prover.js +2 -2
- package/package.json +15 -15
- package/src/block-factory/light.ts +2 -1
- package/src/mocks/test_context.ts +4 -0
- package/src/orchestrator/block-building-helpers.ts +42 -27
- package/src/orchestrator/block-proving-state.ts +69 -14
- package/src/orchestrator/epoch-proving-state.ts +34 -4
- package/src/orchestrator/orchestrator.ts +62 -11
- package/src/prover-client/prover-client.ts +11 -9
- package/src/prover-client/server-epoch-prover.ts +9 -3
|
@@ -19,19 +19,22 @@ var PROVING_STATE_LIFECYCLE = /*#__PURE__*/ function(PROVING_STATE_LIFECYCLE) {
|
|
|
19
19
|
epochNumber;
|
|
20
20
|
firstBlockNumber;
|
|
21
21
|
totalNumBlocks;
|
|
22
|
+
finalBlobBatchingChallenges;
|
|
22
23
|
completionCallback;
|
|
23
24
|
rejectionCallback;
|
|
24
25
|
blockRootOrMergeProvingOutputs;
|
|
25
26
|
paddingBlockRootProvingOutput;
|
|
26
27
|
rootRollupProvingOutput;
|
|
28
|
+
finalBatchedBlob;
|
|
27
29
|
provingStateLifecycle;
|
|
28
30
|
// Map from tx hash to tube proof promise. Used when kickstarting tube proofs before tx processing.
|
|
29
31
|
cachedTubeProofs;
|
|
30
32
|
blocks;
|
|
31
|
-
constructor(epochNumber, firstBlockNumber, totalNumBlocks, completionCallback, rejectionCallback){
|
|
33
|
+
constructor(epochNumber, firstBlockNumber, totalNumBlocks, finalBlobBatchingChallenges, completionCallback, rejectionCallback){
|
|
32
34
|
this.epochNumber = epochNumber;
|
|
33
35
|
this.firstBlockNumber = firstBlockNumber;
|
|
34
36
|
this.totalNumBlocks = totalNumBlocks;
|
|
37
|
+
this.finalBlobBatchingChallenges = finalBlobBatchingChallenges;
|
|
35
38
|
this.completionCallback = completionCallback;
|
|
36
39
|
this.rejectionCallback = rejectionCallback;
|
|
37
40
|
this.provingStateLifecycle = 0;
|
|
@@ -41,9 +44,9 @@ var PROVING_STATE_LIFECYCLE = /*#__PURE__*/ function(PROVING_STATE_LIFECYCLE) {
|
|
|
41
44
|
}
|
|
42
45
|
// Adds a block to the proving state, returns its index
|
|
43
46
|
// Will update the proving life cycle if this is the last block
|
|
44
|
-
startNewBlock(globalVariables, l1ToL2Messages, l1ToL2MessageSubtreeSiblingPath, l1ToL2MessageTreeSnapshotAfterInsertion, lastArchiveSnapshot, lastArchiveSiblingPath, newArchiveSiblingPath, previousBlockHeader) {
|
|
47
|
+
startNewBlock(globalVariables, l1ToL2Messages, l1ToL2MessageTreeSnapshot, l1ToL2MessageSubtreeSiblingPath, l1ToL2MessageTreeSnapshotAfterInsertion, lastArchiveSnapshot, lastArchiveSiblingPath, newArchiveSiblingPath, previousBlockHeader) {
|
|
45
48
|
const index = globalVariables.blockNumber.toNumber() - this.firstBlockNumber;
|
|
46
|
-
const block = new BlockProvingState(index, globalVariables, l1ToL2Messages, l1ToL2MessageSubtreeSiblingPath, l1ToL2MessageTreeSnapshotAfterInsertion, lastArchiveSnapshot, lastArchiveSiblingPath, newArchiveSiblingPath, previousBlockHeader, this);
|
|
49
|
+
const block = new BlockProvingState(index, globalVariables, l1ToL2Messages, l1ToL2MessageTreeSnapshot, l1ToL2MessageSubtreeSiblingPath, l1ToL2MessageTreeSnapshotAfterInsertion, lastArchiveSnapshot, lastArchiveSiblingPath, newArchiveSiblingPath, previousBlockHeader, this);
|
|
47
50
|
this.blocks[index] = block;
|
|
48
51
|
if (this.blocks.filter((b)=>!!b).length === this.totalNumBlocks) {
|
|
49
52
|
this.provingStateLifecycle = 1;
|
|
@@ -70,6 +73,28 @@ var PROVING_STATE_LIFECYCLE = /*#__PURE__*/ function(PROVING_STATE_LIFECYCLE) {
|
|
|
70
73
|
setPaddingBlockRootProof(proof) {
|
|
71
74
|
this.paddingBlockRootProvingOutput = proof;
|
|
72
75
|
}
|
|
76
|
+
setFinalBatchedBlob(batchedBlob) {
|
|
77
|
+
this.finalBatchedBlob = batchedBlob;
|
|
78
|
+
}
|
|
79
|
+
async setBlobAccumulators(toBlock) {
|
|
80
|
+
let previousAccumulator;
|
|
81
|
+
const end = toBlock ? toBlock - this.firstBlockNumber : this.blocks.length;
|
|
82
|
+
// Accumulate blobs as far as we can for this epoch.
|
|
83
|
+
for(let i = 0; i <= end; i++){
|
|
84
|
+
const block = this.blocks[i];
|
|
85
|
+
if (!block || !block.block) {
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
if (!block.startBlobAccumulator) {
|
|
89
|
+
// startBlobAccumulator always exists for firstBlockNumber, so the below should never assign an undefined:
|
|
90
|
+
block.setStartBlobAccumulator(previousAccumulator);
|
|
91
|
+
}
|
|
92
|
+
if (block.startBlobAccumulator && !block.endBlobAccumulator) {
|
|
93
|
+
await block.accumulateBlobs();
|
|
94
|
+
}
|
|
95
|
+
previousAccumulator = block.endBlobAccumulator;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
73
98
|
getParentLocation(location) {
|
|
74
99
|
return this.blockRootOrMergeProvingOutputs.getParentLocation(location);
|
|
75
100
|
}
|
|
@@ -83,7 +108,7 @@ var PROVING_STATE_LIFECYCLE = /*#__PURE__*/ function(PROVING_STATE_LIFECYCLE) {
|
|
|
83
108
|
this.#getPreviousRollupData(right)
|
|
84
109
|
]);
|
|
85
110
|
}
|
|
86
|
-
getRootRollupInputs(
|
|
111
|
+
getRootRollupInputs() {
|
|
87
112
|
const [left, right] = this.#getChildProofsForRoot();
|
|
88
113
|
if (!left || !right) {
|
|
89
114
|
throw new Error('At lease one child is not ready.');
|
|
@@ -92,8 +117,7 @@ var PROVING_STATE_LIFECYCLE = /*#__PURE__*/ function(PROVING_STATE_LIFECYCLE) {
|
|
|
92
117
|
previousRollupData: [
|
|
93
118
|
this.#getPreviousRollupData(left),
|
|
94
119
|
this.#getPreviousRollupData(right)
|
|
95
|
-
]
|
|
96
|
-
proverId
|
|
120
|
+
]
|
|
97
121
|
});
|
|
98
122
|
}
|
|
99
123
|
getPaddingBlockRootInputs(proverId) {
|
|
@@ -107,12 +131,13 @@ var PROVING_STATE_LIFECYCLE = /*#__PURE__*/ function(PROVING_STATE_LIFECYCLE) {
|
|
|
107
131
|
return this.blocks.find((block)=>block?.blockNumber === blockNumber);
|
|
108
132
|
}
|
|
109
133
|
getEpochProofResult() {
|
|
110
|
-
if (!this.rootRollupProvingOutput) {
|
|
134
|
+
if (!this.rootRollupProvingOutput || !this.finalBatchedBlob) {
|
|
111
135
|
throw new Error('Unable to get epoch proof result. Root rollup is not ready.');
|
|
112
136
|
}
|
|
113
137
|
return {
|
|
114
138
|
proof: this.rootRollupProvingOutput.proof.binaryProof,
|
|
115
|
-
publicInputs: this.rootRollupProvingOutput.inputs
|
|
139
|
+
publicInputs: this.rootRollupProvingOutput.inputs,
|
|
140
|
+
batchedBlobInputs: this.finalBatchedBlob
|
|
116
141
|
};
|
|
117
142
|
}
|
|
118
143
|
isReadyForBlockMerge(location) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FinalBlobBatchingChallenges } from '@aztec/blob-lib';
|
|
1
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
3
|
import { L2Block } from '@aztec/stdlib/block';
|
|
3
4
|
import type { EpochProver, ForkMerkleTreeOperations, ServerCircuitProver } from '@aztec/stdlib/interfaces/server';
|
|
@@ -30,7 +31,7 @@ export declare class ProvingOrchestrator implements EpochProver {
|
|
|
30
31
|
get tracer(): Tracer;
|
|
31
32
|
getProverId(): Fr;
|
|
32
33
|
stop(): Promise<void>;
|
|
33
|
-
startNewEpoch(epochNumber: number, firstBlockNumber: number, totalNumBlocks: number): void;
|
|
34
|
+
startNewEpoch(epochNumber: number, firstBlockNumber: number, totalNumBlocks: number, finalBlobBatchingChallenges: FinalBlobBatchingChallenges): void;
|
|
34
35
|
/**
|
|
35
36
|
* Starts off a new block
|
|
36
37
|
* @param globalVariables - The global variables for the block
|
|
@@ -67,6 +68,7 @@ export declare class ProvingOrchestrator implements EpochProver {
|
|
|
67
68
|
finaliseEpoch(): Promise<{
|
|
68
69
|
proof: import("@aztec/stdlib/proofs").Proof;
|
|
69
70
|
publicInputs: import("@aztec/stdlib/rollup").RootRollupPublicInputs;
|
|
71
|
+
batchedBlobInputs: import("@aztec/blob-lib").BatchedBlob;
|
|
70
72
|
}>;
|
|
71
73
|
/**
|
|
72
74
|
* Starts the proving process for the given transaction and adds it to our state
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/orchestrator/orchestrator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/orchestrator/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAU9D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAS9C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,KAAK,EACV,WAAW,EACX,wBAAwB,EAGxB,mBAAmB,EACpB,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EAAE,KAAK,sBAAsB,EAAgB,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,KAAK,EAAE,EAAmB,MAAM,kBAAkB,CAAC;AACtH,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,MAAM,EAIZ,MAAM,yBAAyB,CAAC;AAqBjC;;;;;;;;;GASG;AAEH;;GAEG;AACH,qBAAa,mBAAoB,YAAW,WAAW;IASnD,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAV3B,OAAO,CAAC,YAAY,CAA4C;IAChE,OAAO,CAAC,kBAAkB,CAAyB;IAEnD,OAAO,CAAC,cAAc,CAAiD;IACvE,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,GAAG,CAAqD;gBAGtD,UAAU,EAAE,wBAAwB,EACpC,MAAM,EAAE,mBAAmB,EAClB,QAAQ,EAAE,EAAE,EAC7B,eAAe,GAAE,eAAsC;IAKzD,IAAI,MAAM,IAAI,MAAM,CAEnB;IAEM,WAAW,IAAI,EAAE;IAIjB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrB,aAAa,CAClB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,2BAA2B,EAAE,2BAA2B;IAmB1D;;;;;OAKG;IAIU,aAAa,CAAC,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,EAAE,EAAE,EAAE,mBAAmB,EAAE,WAAW;IAgDnH;;;OAGG;IAIU,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDtD;;;OAGG;IAEU,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE;IAcxC;;;OAGG;IAIU,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BnG,oDAAoD;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;YAQzB,UAAU;cAqCR,kCAAkC,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,sBAAsB;IAWvG;;OAEG;IACI,MAAM;IAQb;;OAEG;IACU,aAAa;;;;;IA6B1B;;;;OAIG;YACW,kBAAkB;IAShC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;YAwDT,uBAAuB;YAkCvB,uBAAuB;IAyCrC,OAAO,CAAC,iBAAiB;IA8CzB,OAAO,CAAC,gBAAgB;IA0BxB,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,kBAAkB;YA0BZ,sBAAsB;IA8EpC,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,gCAAgC;IAUxC,OAAO,CAAC,wBAAwB;IA2BhC,OAAO,CAAC,uBAAuB;YAwBjB,mBAAmB;IA6BjC,OAAO,CAAC,iBAAiB;YA4BX,8BAA8B;YAa9B,8BAA8B;IA2B5C,OAAO,CAAC,mCAAmC;IAa3C,OAAO,CAAC,yBAAyB;IASjC;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAmDjB,OAAO,CAAC,4BAA4B;CAWrC"}
|
|
@@ -67,7 +67,7 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
67
67
|
this.cancel();
|
|
68
68
|
return Promise.resolve();
|
|
69
69
|
}
|
|
70
|
-
startNewEpoch(epochNumber, firstBlockNumber, totalNumBlocks) {
|
|
70
|
+
startNewEpoch(epochNumber, firstBlockNumber, totalNumBlocks, finalBlobBatchingChallenges) {
|
|
71
71
|
const { promise: _promise, resolve, reject } = promiseWithResolvers();
|
|
72
72
|
const promise = _promise.catch((reason)=>({
|
|
73
73
|
status: 'failure',
|
|
@@ -77,7 +77,7 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
77
77
|
throw new Error(`Invalid number of blocks for epoch (got ${totalNumBlocks})`);
|
|
78
78
|
}
|
|
79
79
|
logger.info(`Starting epoch ${epochNumber} with ${totalNumBlocks} blocks`);
|
|
80
|
-
this.provingState = new EpochProvingState(epochNumber, firstBlockNumber, totalNumBlocks, resolve, reject);
|
|
80
|
+
this.provingState = new EpochProvingState(epochNumber, firstBlockNumber, totalNumBlocks, finalBlobBatchingChallenges, resolve, reject);
|
|
81
81
|
this.provingPromise = promise;
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
@@ -97,12 +97,12 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
97
97
|
const db = await this.dbProvider.fork(globalVariables.blockNumber.toNumber() - 1);
|
|
98
98
|
this.dbs.set(globalVariables.blockNumber.toNumber(), db);
|
|
99
99
|
// we start the block by enqueueing all of the base parity circuits
|
|
100
|
-
const { l1ToL2MessageSubtreeSiblingPath, l1ToL2MessageTreeSnapshotAfterInsertion, baseParityInputs } = await this.prepareBaseParityInputs(l1ToL2Messages, db);
|
|
100
|
+
const { l1ToL2MessageTreeSnapshot, l1ToL2MessageSubtreeSiblingPath, l1ToL2MessageTreeSnapshotAfterInsertion, baseParityInputs } = await this.prepareBaseParityInputs(l1ToL2Messages, db);
|
|
101
101
|
// Get archive snapshot before this block lands
|
|
102
102
|
const lastArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
103
103
|
const lastArchiveSiblingPath = await getLastSiblingPath(MerkleTreeId.ARCHIVE, db);
|
|
104
104
|
const newArchiveSiblingPath = await getRootTreeSiblingPath(MerkleTreeId.ARCHIVE, db);
|
|
105
|
-
const blockProvingState = this.provingState.startNewBlock(globalVariables, l1ToL2Messages, l1ToL2MessageSubtreeSiblingPath, l1ToL2MessageTreeSnapshotAfterInsertion, lastArchive, lastArchiveSiblingPath, newArchiveSiblingPath, previousBlockHeader);
|
|
105
|
+
const blockProvingState = this.provingState.startNewBlock(globalVariables, l1ToL2Messages, l1ToL2MessageTreeSnapshot, l1ToL2MessageSubtreeSiblingPath, l1ToL2MessageTreeSnapshotAfterInsertion, lastArchive, lastArchiveSiblingPath, newArchiveSiblingPath, previousBlockHeader);
|
|
106
106
|
// Enqueue base parity circuits for the block
|
|
107
107
|
for(let i = 0; i < baseParityInputs.length; i++){
|
|
108
108
|
this.enqueueBaseParityCircuit(blockProvingState, baseParityInputs[i], i);
|
|
@@ -118,7 +118,7 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
118
118
|
logger.warn(`Provided no txs to orchestrator addTxs.`);
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
|
-
const blockNumber = txs[0].
|
|
121
|
+
const blockNumber = txs[0].globalVariables.blockNumber.toNumber();
|
|
122
122
|
const provingState = this.provingState?.getBlockProvingStateByBlockNumber(blockNumber);
|
|
123
123
|
if (!provingState) {
|
|
124
124
|
throw new Error(`Block proving state for ${blockNumber} not found`);
|
|
@@ -186,6 +186,8 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
186
186
|
// And build the block header
|
|
187
187
|
logger.verbose(`Block ${blockNumber} completed. Assembling header.`);
|
|
188
188
|
await this.buildBlock(provingState, expectedHeader);
|
|
189
|
+
logger.debug(`Accumulating blobs for ${blockNumber}`);
|
|
190
|
+
await this.provingState?.setBlobAccumulators(blockNumber);
|
|
189
191
|
// If the proofs were faster than the block building, then we need to try the block root rollup again here
|
|
190
192
|
await this.checkAndEnqueueBlockRootRollup(provingState);
|
|
191
193
|
return provingState.block;
|
|
@@ -216,7 +218,7 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
216
218
|
const l2Block = new L2Block(newArchive, header, body);
|
|
217
219
|
await this.verifyBuiltBlockAgainstSyncedState(l2Block, newArchive);
|
|
218
220
|
logger.verbose(`Orchestrator finalised block ${l2Block.number}`);
|
|
219
|
-
provingState.
|
|
221
|
+
provingState.setBlock(l2Block);
|
|
220
222
|
}
|
|
221
223
|
// Flagged as protected to disable in certain unit tests
|
|
222
224
|
async verifyBuiltBlockAgainstSyncedState(l2Block, newArchive) {
|
|
@@ -243,6 +245,14 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
243
245
|
if (result.status === 'failure') {
|
|
244
246
|
throw new Error(`Epoch proving failed: ${result.reason}`);
|
|
245
247
|
}
|
|
248
|
+
// TODO(MW): Move this? Requires async and don't want to force root methods to be async
|
|
249
|
+
// TODO(MW): EpochProvingState uses this.blocks.filter(b => !!b).length as total blocks, use this below:
|
|
250
|
+
const finalBlock = this.provingState.blocks[this.provingState.totalNumBlocks - 1];
|
|
251
|
+
if (!finalBlock || !finalBlock.endBlobAccumulator) {
|
|
252
|
+
throw new Error(`Epoch's final block not ready for finalise`);
|
|
253
|
+
}
|
|
254
|
+
const finalBatchedBlob = await finalBlock.endBlobAccumulator.finalize();
|
|
255
|
+
this.provingState.setFinalBatchedBlob(finalBatchedBlob);
|
|
246
256
|
const epochProofResult = this.provingState.getEpochProofResult();
|
|
247
257
|
pushTestData('epochProofResult', {
|
|
248
258
|
proof: epochProofResult.proof.toString(),
|
|
@@ -314,11 +324,13 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
314
324
|
async prepareBaseParityInputs(l1ToL2Messages, db) {
|
|
315
325
|
const l1ToL2MessagesPadded = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, 'Too many L1 to L2 messages');
|
|
316
326
|
const baseParityInputs = times(NUM_BASE_PARITY_PER_ROOT_PARITY, (i)=>BaseParityInputs.fromSlice(l1ToL2MessagesPadded, i, getVKTreeRoot()));
|
|
327
|
+
const l1ToL2MessageTreeSnapshot = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
317
328
|
const l1ToL2MessageSubtreeSiblingPath = assertLength(await getSubtreeSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, L1_TO_L2_MSG_SUBTREE_HEIGHT, db), L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH);
|
|
318
329
|
// Update the local trees to include the new l1 to l2 messages
|
|
319
330
|
await db.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2MessagesPadded);
|
|
320
331
|
const l1ToL2MessageTreeSnapshotAfterInsertion = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
321
332
|
return {
|
|
333
|
+
l1ToL2MessageTreeSnapshot,
|
|
322
334
|
l1ToL2MessageSubtreeSiblingPath,
|
|
323
335
|
l1ToL2MessageTreeSnapshotAfterInsertion,
|
|
324
336
|
baseParityInputs
|
|
@@ -333,7 +345,7 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
333
345
|
const db = this.dbs.get(provingState.blockNumber);
|
|
334
346
|
// We build the base rollup inputs using a mock proof and verification key.
|
|
335
347
|
// These will be overwritten later once we have proven the tube circuit and any public kernels
|
|
336
|
-
const [ms, hints] = await elapsed(insertSideEffectsAndBuildBaseRollupHints(tx, provingState.globalVariables, db, provingState.spongeBlobState));
|
|
348
|
+
const [ms, hints] = await elapsed(insertSideEffectsAndBuildBaseRollupHints(tx, provingState.globalVariables, provingState.l1ToL2MessageTreeSnapshot, db, provingState.spongeBlobState));
|
|
337
349
|
this.metrics.recordBaseRollupInputs(ms);
|
|
338
350
|
const promises = [
|
|
339
351
|
MerkleTreeId.NOTE_HASH_TREE,
|
|
@@ -473,6 +485,12 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
473
485
|
logger.error(`New archive root mismatch.\nCircuit: ${result.inputs.newArchive.root}\nComputed: ${dbArchiveRoot}`);
|
|
474
486
|
provingState.reject(`New archive root mismatch.`);
|
|
475
487
|
}
|
|
488
|
+
const endBlobAccumulator = provingState.endBlobAccumulator;
|
|
489
|
+
const circuitEndBlobAccumulatorState = result.inputs.blobPublicInputs.endBlobAccumulator;
|
|
490
|
+
if (!circuitEndBlobAccumulatorState.equals(endBlobAccumulator.toBlobAccumulatorPublicInputs())) {
|
|
491
|
+
logger.error(`Blob accumulator state mismatch.\nCircuit: ${inspect(circuitEndBlobAccumulatorState)}\nComputed: ${inspect(endBlobAccumulator.toBlobAccumulatorPublicInputs())}`);
|
|
492
|
+
provingState.reject(`Blob accumulator state mismatch.`);
|
|
493
|
+
}
|
|
476
494
|
logger.debug(`Completed ${rollupType} proof for block ${provingState.block.number}`);
|
|
477
495
|
// validatePartialState(result.inputs.end, tx.treeSnapshots); // TODO(palla/prover)
|
|
478
496
|
const epochProvingState = this.provingState;
|
|
@@ -556,7 +574,7 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
556
574
|
return;
|
|
557
575
|
}
|
|
558
576
|
logger.debug(`Preparing root rollup`);
|
|
559
|
-
const inputs = provingState.getRootRollupInputs(
|
|
577
|
+
const inputs = provingState.getRootRollupInputs();
|
|
560
578
|
this.deferredProving(provingState, wrapCallbackInSpan(this.tracer, 'ProvingOrchestrator.prover.getRootRollupProof', {
|
|
561
579
|
[Attributes.PROTOCOL_CIRCUIT_NAME]: 'root-rollup'
|
|
562
580
|
}, (signal)=>this.prover.getRootRollupProof(inputs, signal, provingState.epochNumber)), (result)=>{
|
|
@@ -579,15 +597,17 @@ const logger = createLogger('prover-client:orchestrator');
|
|
|
579
597
|
}
|
|
580
598
|
}
|
|
581
599
|
async checkAndEnqueueBlockRootRollup(provingState) {
|
|
600
|
+
const blockNumber = provingState.blockNumber;
|
|
601
|
+
// Accumulate as far as we can, in case blocks came in out of order and we are behind:
|
|
602
|
+
await this.provingState?.setBlobAccumulators(blockNumber);
|
|
582
603
|
if (!provingState.isReadyForBlockRootRollup()) {
|
|
583
|
-
logger.debug('Not ready for root rollup');
|
|
604
|
+
logger.debug('Not ready for block root rollup');
|
|
584
605
|
return;
|
|
585
606
|
}
|
|
586
607
|
if (provingState.blockRootRollupStarted) {
|
|
587
608
|
logger.debug('Block root rollup already started');
|
|
588
609
|
return;
|
|
589
610
|
}
|
|
590
|
-
const blockNumber = provingState.blockNumber;
|
|
591
611
|
// TODO(palla/prover): This closes the fork only on the happy path. If this epoch orchestrator
|
|
592
612
|
// is aborted and never reaches this point, it will leak the fork. We need to add a global cleanup,
|
|
593
613
|
// but have to make sure it only runs once all operations are completed, otherwise some function here
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ACVMConfig, type BBConfig } from '@aztec/bb-prover';
|
|
2
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
-
import type
|
|
3
|
+
import { type ActualProverConfig, type EpochProver, type EpochProverManager, type ForkMerkleTreeOperations, type ProvingJobBroker, type ProvingJobConsumer, type ServerCircuitProver } from '@aztec/stdlib/interfaces/server';
|
|
4
4
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
5
5
|
import type { ProverClientConfig } from '../config.js';
|
|
6
6
|
/** Manages proving of epochs by orchestrating the proving of individual blocks relying on a pool of prover agents. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prover-client.d.ts","sourceRoot":"","sources":["../../src/prover-client/prover-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAA2C,MAAM,kBAAkB,CAAC;AAE3G,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"prover-client.d.ts","sourceRoot":"","sources":["../../src/prover-client/prover-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAA2C,MAAM,kBAAkB,CAAC;AAE3G,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAG9C,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EAEvB,KAAK,mBAAmB,EAEzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAEnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAOvD,sHAAsH;AACtH,qBAAa,YAAa,YAAW,kBAAkB;IAQnD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,WAAW,CAAC;IACpB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,GAAG;IAZb,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAsB;IAEpC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,gBAAgB,CAAyB;IAEjD,OAAO;IAYA,iBAAiB,IAAI,WAAW;IAMhC,WAAW,IAAI,EAAE;IAIlB,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAc5E;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IASnC;;OAEG;IACU,IAAI;IASjB;;;;;OAKG;WACiB,GAAG,CACrB,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,wBAAwB,EACpC,MAAM,EAAE,gBAAgB,EACxB,SAAS,GAAE,eAAsC;IAO5C,mBAAmB,IAAI,kBAAkB;YAQlC,oBAAoB;YA2BpB,UAAU;CAGzB;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,kBAAkB,GAAG,UAAU,GAAG,QAAQ,EAClD,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAU9B"}
|
|
@@ -2,6 +2,7 @@ import { BBNativeRollupProver, TestCircuitProver } from '@aztec/bb-prover';
|
|
|
2
2
|
import { times } from '@aztec/foundation/collection';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { NativeACVMSimulator } from '@aztec/simulator/server';
|
|
5
|
+
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
5
6
|
import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
6
7
|
import { ProvingOrchestrator } from '../orchestrator/orchestrator.js';
|
|
7
8
|
import { BrokerCircuitProverFacade } from '../proving_broker/broker_prover_facade.js';
|
|
@@ -67,6 +68,7 @@ import { ServerEpochProver } from './server-epoch-prover.js';
|
|
|
67
68
|
}
|
|
68
69
|
this.running = false;
|
|
69
70
|
await this.stopAgents();
|
|
71
|
+
await tryStop(this.orchestratorClient);
|
|
70
72
|
}
|
|
71
73
|
/**
|
|
72
74
|
* Creates a new prover client and starts it
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BatchedBlob, FinalBlobBatchingChallenges } from '@aztec/blob-lib';
|
|
1
2
|
import type { Fr } from '@aztec/foundation/fields';
|
|
2
3
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
3
4
|
import type { EpochProver } from '@aztec/stdlib/interfaces/server';
|
|
@@ -11,12 +12,13 @@ export declare class ServerEpochProver implements EpochProver {
|
|
|
11
12
|
private facade;
|
|
12
13
|
private orchestrator;
|
|
13
14
|
constructor(facade: BrokerCircuitProverFacade, orchestrator: ProvingOrchestrator);
|
|
14
|
-
startNewEpoch(epochNumber: number, firstBlockNumber: number, totalNumBlocks: number): void;
|
|
15
|
+
startNewEpoch(epochNumber: number, firstBlockNumber: number, totalNumBlocks: number, finalBlobBatchingChallenges: FinalBlobBatchingChallenges): void;
|
|
15
16
|
startTubeCircuits(txs: Tx[]): Promise<void>;
|
|
16
17
|
setBlockCompleted(blockNumber: number, expectedBlockHeader?: BlockHeader): Promise<L2Block>;
|
|
17
18
|
finaliseEpoch(): Promise<{
|
|
18
19
|
publicInputs: RootRollupPublicInputs;
|
|
19
20
|
proof: Proof;
|
|
21
|
+
batchedBlobInputs: BatchedBlob;
|
|
20
22
|
}>;
|
|
21
23
|
cancel(): void;
|
|
22
24
|
getProverId(): Fr;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-epoch-prover.d.ts","sourceRoot":"","sources":["../../src/prover-client/server-epoch-prover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEtF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AAE3F,kEAAkE;AAClE,qBAAa,iBAAkB,YAAW,WAAW;IAEjD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;gBADZ,MAAM,EAAE,yBAAyB,EACjC,YAAY,EAAE,mBAAmB;IAG3C,aAAa,
|
|
1
|
+
{"version":3,"file":"server-epoch-prover.d.ts","sourceRoot":"","sources":["../../src/prover-client/server-epoch-prover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEtF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AAE3F,kEAAkE;AAClE,qBAAa,iBAAkB,YAAW,WAAW;IAEjD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;gBADZ,MAAM,EAAE,yBAAyB,EACjC,YAAY,EAAE,mBAAmB;IAG3C,aAAa,CACX,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,2BAA2B,EAAE,2BAA2B,GACvD,IAAI;IAIP,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAG3C,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAG3F,aAAa,IAAI,OAAO,CAAC;QAAE,YAAY,EAAE,sBAAsB,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC;QAAC,iBAAiB,EAAE,WAAW,CAAA;KAAE,CAAC;IAGhH,MAAM,IAAI,IAAI;IAGd,WAAW,IAAI,EAAE;IAGjB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAG1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,aAAa,CACX,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,EAAE,EAAE,EACpB,mBAAmB,EAAE,WAAW,GAC/B,OAAO,CAAC,IAAI,CAAC;IAGhB,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
this.facade = facade;
|
|
6
6
|
this.orchestrator = orchestrator;
|
|
7
7
|
}
|
|
8
|
-
startNewEpoch(epochNumber, firstBlockNumber, totalNumBlocks) {
|
|
9
|
-
this.orchestrator.startNewEpoch(epochNumber, firstBlockNumber, totalNumBlocks);
|
|
8
|
+
startNewEpoch(epochNumber, firstBlockNumber, totalNumBlocks, finalBlobBatchingChallenges) {
|
|
9
|
+
this.orchestrator.startNewEpoch(epochNumber, firstBlockNumber, totalNumBlocks, finalBlobBatchingChallenges);
|
|
10
10
|
this.facade.start();
|
|
11
11
|
}
|
|
12
12
|
startTubeCircuits(txs) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/prover-client",
|
|
3
|
-
"version": "1.0.0-nightly.
|
|
3
|
+
"version": "1.0.0-nightly.20250610",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -64,19 +64,19 @@
|
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/bb-prover": "1.0.0-nightly.
|
|
68
|
-
"@aztec/blob-lib": "1.0.0-nightly.
|
|
69
|
-
"@aztec/constants": "1.0.0-nightly.
|
|
70
|
-
"@aztec/ethereum": "1.0.0-nightly.
|
|
71
|
-
"@aztec/foundation": "1.0.0-nightly.
|
|
72
|
-
"@aztec/kv-store": "1.0.0-nightly.
|
|
73
|
-
"@aztec/noir-protocol-circuits-types": "1.0.0-nightly.
|
|
74
|
-
"@aztec/noir-types": "1.0.0-nightly.
|
|
75
|
-
"@aztec/protocol-contracts": "1.0.0-nightly.
|
|
76
|
-
"@aztec/simulator": "1.0.0-nightly.
|
|
77
|
-
"@aztec/stdlib": "1.0.0-nightly.
|
|
78
|
-
"@aztec/telemetry-client": "1.0.0-nightly.
|
|
79
|
-
"@aztec/world-state": "1.0.0-nightly.
|
|
67
|
+
"@aztec/bb-prover": "1.0.0-nightly.20250610",
|
|
68
|
+
"@aztec/blob-lib": "1.0.0-nightly.20250610",
|
|
69
|
+
"@aztec/constants": "1.0.0-nightly.20250610",
|
|
70
|
+
"@aztec/ethereum": "1.0.0-nightly.20250610",
|
|
71
|
+
"@aztec/foundation": "1.0.0-nightly.20250610",
|
|
72
|
+
"@aztec/kv-store": "1.0.0-nightly.20250610",
|
|
73
|
+
"@aztec/noir-protocol-circuits-types": "1.0.0-nightly.20250610",
|
|
74
|
+
"@aztec/noir-types": "1.0.0-nightly.20250610",
|
|
75
|
+
"@aztec/protocol-contracts": "1.0.0-nightly.20250610",
|
|
76
|
+
"@aztec/simulator": "1.0.0-nightly.20250610",
|
|
77
|
+
"@aztec/stdlib": "1.0.0-nightly.20250610",
|
|
78
|
+
"@aztec/telemetry-client": "1.0.0-nightly.20250610",
|
|
79
|
+
"@aztec/world-state": "1.0.0-nightly.20250610",
|
|
80
80
|
"@google-cloud/storage": "^7.15.0",
|
|
81
81
|
"@iarna/toml": "^2.2.5",
|
|
82
82
|
"commander": "^12.1.0",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"zod": "^3.23.8"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@aztec/noir-contracts.js": "1.0.0-nightly.
|
|
89
|
+
"@aztec/noir-contracts.js": "1.0.0-nightly.20250610",
|
|
90
90
|
"@jest/globals": "^29.5.0",
|
|
91
91
|
"@types/jest": "^29.5.0",
|
|
92
92
|
"@types/node": "^22.15.17",
|
|
@@ -99,8 +99,9 @@ export async function buildBlockWithCleanDB(
|
|
|
99
99
|
telemetry: TelemetryClient = getTelemetryClient(),
|
|
100
100
|
) {
|
|
101
101
|
const spongeBlobState = SpongeBlob.init(toNumBlobFields(txs));
|
|
102
|
+
const l1ToL2MessageTree = await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db);
|
|
102
103
|
for (const tx of txs) {
|
|
103
|
-
await insertSideEffectsAndBuildBaseRollupHints(tx, globalVariables, db, spongeBlobState);
|
|
104
|
+
await insertSideEffectsAndBuildBaseRollupHints(tx, globalVariables, l1ToL2MessageTree, db, spongeBlobState);
|
|
104
105
|
}
|
|
105
106
|
const builder = new LightweightBlockFactory(db, telemetry);
|
|
106
107
|
await builder.startNewBlock(globalVariables, l1ToL2Messages);
|
|
@@ -138,6 +138,10 @@ export class TestContext {
|
|
|
138
138
|
return blockNumber === 0 ? this.worldState.getCommitted().getInitialHeader() : this.headers.get(blockNumber);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
public setBlockHeader(header: BlockHeader, blockNumber: number) {
|
|
142
|
+
this.headers.set(blockNumber, header);
|
|
143
|
+
}
|
|
144
|
+
|
|
141
145
|
public getPreviousBlockHeader(currentBlockNumber = this.blockNumber): BlockHeader {
|
|
142
146
|
return this.getBlockHeader(currentBlockNumber - 1)!;
|
|
143
147
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Blob, type SpongeBlob } from '@aztec/blob-lib';
|
|
1
|
+
import { BatchedBlobAccumulator, Blob, type SpongeBlob } from '@aztec/blob-lib';
|
|
2
2
|
import {
|
|
3
3
|
ARCHIVE_HEIGHT,
|
|
4
4
|
MAX_CONTRACT_CLASS_LOGS_PER_TX,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import { makeTuple } from '@aztec/foundation/array';
|
|
16
16
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
17
17
|
import { sha256Trunc } from '@aztec/foundation/crypto';
|
|
18
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
18
|
+
import { BLS12Point, Fr } from '@aztec/foundation/fields';
|
|
19
19
|
import { type Tuple, assertLength, serializeToBuffer, toFriendlyJSON } from '@aztec/foundation/serialize';
|
|
20
20
|
import { MembershipWitness, MerkleTreeCalculator, computeUnbalancedMerkleRoot } from '@aztec/foundation/trees';
|
|
21
21
|
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
@@ -28,8 +28,8 @@ import { ContractClassLogFields } from '@aztec/stdlib/logs';
|
|
|
28
28
|
import type { ParityPublicInputs } from '@aztec/stdlib/parity';
|
|
29
29
|
import {
|
|
30
30
|
type BaseOrMergeRollupPublicInputs,
|
|
31
|
+
BlockConstantData,
|
|
31
32
|
type BlockRootOrBlockMergePublicInputs,
|
|
32
|
-
ConstantRollupData,
|
|
33
33
|
PrivateBaseRollupHints,
|
|
34
34
|
PrivateBaseStateDiffHints,
|
|
35
35
|
PublicBaseRollupHints,
|
|
@@ -71,12 +71,15 @@ export const insertSideEffectsAndBuildBaseRollupHints = runInSpan(
|
|
|
71
71
|
span: Span,
|
|
72
72
|
tx: ProcessedTx,
|
|
73
73
|
globalVariables: GlobalVariables,
|
|
74
|
+
// Passing in the snapshot instead of getting it from the db because it might've been updated in the orchestrator
|
|
75
|
+
// when base parity proof is being generated.
|
|
76
|
+
l1ToL2MessageTreeSnapshot: AppendOnlyTreeSnapshot,
|
|
74
77
|
db: MerkleTreeWriteOperations,
|
|
75
78
|
startSpongeBlob: SpongeBlob,
|
|
76
79
|
) => {
|
|
77
80
|
span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
|
|
78
81
|
// Get trees info before any changes hit
|
|
79
|
-
const
|
|
82
|
+
const lastArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
80
83
|
const start = new PartialStateReference(
|
|
81
84
|
await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
|
|
82
85
|
await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
|
|
@@ -144,7 +147,7 @@ export const insertSideEffectsAndBuildBaseRollupHints = runInSpan(
|
|
|
144
147
|
);
|
|
145
148
|
|
|
146
149
|
if (tx.avmProvingRequest) {
|
|
147
|
-
const blockHash = await tx.constants.historicalHeader.hash();
|
|
150
|
+
const blockHash = await tx.data.constants.historicalHeader.hash();
|
|
148
151
|
const archiveRootMembershipWitness = await getMembershipWitnessFor(
|
|
149
152
|
blockHash,
|
|
150
153
|
MerkleTreeId.ARCHIVE,
|
|
@@ -154,9 +157,9 @@ export const insertSideEffectsAndBuildBaseRollupHints = runInSpan(
|
|
|
154
157
|
|
|
155
158
|
return PublicBaseRollupHints.from({
|
|
156
159
|
startSpongeBlob: inputSpongeBlob,
|
|
160
|
+
lastArchive,
|
|
157
161
|
archiveRootMembershipWitness,
|
|
158
162
|
contractClassLogsFields,
|
|
159
|
-
constants,
|
|
160
163
|
});
|
|
161
164
|
} else {
|
|
162
165
|
if (
|
|
@@ -196,7 +199,7 @@ export const insertSideEffectsAndBuildBaseRollupHints = runInSpan(
|
|
|
196
199
|
feeWriteSiblingPath,
|
|
197
200
|
});
|
|
198
201
|
|
|
199
|
-
const blockHash = await tx.constants.historicalHeader.hash();
|
|
202
|
+
const blockHash = await tx.data.constants.historicalHeader.hash();
|
|
200
203
|
const archiveRootMembershipWitness = await getMembershipWitnessFor(
|
|
201
204
|
blockHash,
|
|
202
205
|
MerkleTreeId.ARCHIVE,
|
|
@@ -204,6 +207,14 @@ export const insertSideEffectsAndBuildBaseRollupHints = runInSpan(
|
|
|
204
207
|
db,
|
|
205
208
|
);
|
|
206
209
|
|
|
210
|
+
const constants = BlockConstantData.from({
|
|
211
|
+
lastArchive,
|
|
212
|
+
lastL1ToL2: l1ToL2MessageTreeSnapshot,
|
|
213
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
214
|
+
protocolContractTreeRoot,
|
|
215
|
+
globalVariables,
|
|
216
|
+
});
|
|
217
|
+
|
|
207
218
|
return PrivateBaseRollupHints.from({
|
|
208
219
|
start,
|
|
209
220
|
startSpongeBlob: inputSpongeBlob,
|
|
@@ -243,12 +254,28 @@ export const buildBlobHints = runInSpan(
|
|
|
243
254
|
async (_span: Span, txEffects: TxEffect[]) => {
|
|
244
255
|
const blobFields = txEffects.flatMap(tx => tx.toBlobFields());
|
|
245
256
|
const blobs = await Blob.getBlobs(blobFields);
|
|
246
|
-
|
|
257
|
+
// TODO(#13430): The blobsHash is confusingly similar to blobCommitmentsHash, calculated from below blobCommitments:
|
|
258
|
+
// - blobsHash := sha256([blobhash_0, ..., blobhash_m]) = a hash of all blob hashes in a block with m+1 blobs inserted into the header, exists so a user can cross check blobs.
|
|
259
|
+
// - blobCommitmentsHash := sha256( ...sha256(sha256(C_0), C_1) ... C_n) = iteratively calculated hash of all blob commitments in an epoch with n+1 blobs (see calculateBlobCommitmentsHash()),
|
|
260
|
+
// exists so we can validate injected commitments to the rollup circuits correspond to the correct real blobs.
|
|
261
|
+
// We may be able to combine these values e.g. blobCommitmentsHash := sha256( ...sha256(sha256(blobshash_0), blobshash_1) ... blobshash_l) for an epoch with l+1 blocks.
|
|
262
|
+
const blobCommitments = blobs.map(b => BLS12Point.decompress(b.commitment));
|
|
247
263
|
const blobsHash = new Fr(getBlobsHashFromBlobs(blobs));
|
|
248
264
|
return { blobFields, blobCommitments, blobs, blobsHash };
|
|
249
265
|
},
|
|
250
266
|
);
|
|
251
267
|
|
|
268
|
+
export const accumulateBlobs = runInSpan(
|
|
269
|
+
'BlockBuilderHelpers',
|
|
270
|
+
'accumulateBlobs',
|
|
271
|
+
async (_span: Span, txs: ProcessedTx[], startBlobAccumulator: BatchedBlobAccumulator) => {
|
|
272
|
+
const blobFields = txs.flatMap(tx => tx.txEffect.toBlobFields());
|
|
273
|
+
const blobs = await Blob.getBlobs(blobFields);
|
|
274
|
+
const endBlobAccumulator = startBlobAccumulator.accumulateBlobs(blobs);
|
|
275
|
+
return endBlobAccumulator;
|
|
276
|
+
},
|
|
277
|
+
);
|
|
278
|
+
|
|
252
279
|
export const buildHeaderFromCircuitOutputs = runInSpan(
|
|
253
280
|
'BlockBuilderHelpers',
|
|
254
281
|
'buildHeaderFromCircuitOutputs',
|
|
@@ -257,13 +284,13 @@ export const buildHeaderFromCircuitOutputs = runInSpan(
|
|
|
257
284
|
previousRollupData: BaseOrMergeRollupPublicInputs[],
|
|
258
285
|
parityPublicInputs: ParityPublicInputs,
|
|
259
286
|
rootRollupOutputs: BlockRootOrBlockMergePublicInputs,
|
|
287
|
+
blobsHash: Buffer,
|
|
260
288
|
endState: StateReference,
|
|
261
289
|
) => {
|
|
262
290
|
if (previousRollupData.length > 2) {
|
|
263
291
|
throw new Error(`There can't be more than 2 previous rollups. Received ${previousRollupData.length}.`);
|
|
264
292
|
}
|
|
265
293
|
|
|
266
|
-
const blobsHash = rootRollupOutputs.blobPublicInputs[0].getBlobsHash();
|
|
267
294
|
const numTxs = previousRollupData.reduce((sum, d) => sum + d.numTxs, 0);
|
|
268
295
|
const outHash =
|
|
269
296
|
previousRollupData.length === 0
|
|
@@ -359,6 +386,7 @@ export function getBlobsHashFromBlobs(inputs: Blob[]): Buffer {
|
|
|
359
386
|
}
|
|
360
387
|
|
|
361
388
|
// Validate that the roots of all local trees match the output of the root circuit simulation
|
|
389
|
+
// TODO: does this get called?
|
|
362
390
|
export async function validateBlockRootOutput(
|
|
363
391
|
blockRootOutput: BlockRootOrBlockMergePublicInputs,
|
|
364
392
|
blockHeader: BlockHeader,
|
|
@@ -403,19 +431,6 @@ export async function getRootTreeSiblingPath<TID extends MerkleTreeId>(treeId: T
|
|
|
403
431
|
return padArrayEnd(path.toFields(), Fr.ZERO, getTreeHeight(treeId));
|
|
404
432
|
}
|
|
405
433
|
|
|
406
|
-
export const getConstantRollupData = runInSpan(
|
|
407
|
-
'BlockBuilderHelpers',
|
|
408
|
-
'getConstantRollupData',
|
|
409
|
-
async (_span, globalVariables: GlobalVariables, db: MerkleTreeReadOperations): Promise<ConstantRollupData> => {
|
|
410
|
-
return ConstantRollupData.from({
|
|
411
|
-
vkTreeRoot: getVKTreeRoot(),
|
|
412
|
-
protocolContractTreeRoot,
|
|
413
|
-
lastArchive: await getTreeSnapshot(MerkleTreeId.ARCHIVE, db),
|
|
414
|
-
globalVariables,
|
|
415
|
-
});
|
|
416
|
-
},
|
|
417
|
-
);
|
|
418
|
-
|
|
419
434
|
export async function getTreeSnapshot(id: MerkleTreeId, db: MerkleTreeReadOperations): Promise<AppendOnlyTreeSnapshot> {
|
|
420
435
|
const treeInfo = await db.getTreeInfo(id);
|
|
421
436
|
return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size));
|
|
@@ -536,17 +551,17 @@ function validateSimulatedTree(
|
|
|
536
551
|
}
|
|
537
552
|
|
|
538
553
|
export function validateTx(tx: ProcessedTx) {
|
|
539
|
-
const txHeader = tx.constants.historicalHeader;
|
|
540
|
-
if (txHeader.state.l1ToL2MessageTree.
|
|
554
|
+
const txHeader = tx.data.constants.historicalHeader;
|
|
555
|
+
if (txHeader.state.l1ToL2MessageTree.isEmpty()) {
|
|
541
556
|
throw new Error(`Empty L1 to L2 messages tree in tx: ${toFriendlyJSON(tx)}`);
|
|
542
557
|
}
|
|
543
|
-
if (txHeader.state.partial.noteHashTree.
|
|
558
|
+
if (txHeader.state.partial.noteHashTree.isEmpty()) {
|
|
544
559
|
throw new Error(`Empty note hash tree in tx: ${toFriendlyJSON(tx)}`);
|
|
545
560
|
}
|
|
546
|
-
if (txHeader.state.partial.nullifierTree.
|
|
561
|
+
if (txHeader.state.partial.nullifierTree.isEmpty()) {
|
|
547
562
|
throw new Error(`Empty nullifier tree in tx: ${toFriendlyJSON(tx)}`);
|
|
548
563
|
}
|
|
549
|
-
if (txHeader.state.partial.publicDataTree.
|
|
564
|
+
if (txHeader.state.partial.publicDataTree.isEmpty()) {
|
|
550
565
|
throw new Error(`Empty public data tree in tx: ${toFriendlyJSON(tx)}`);
|
|
551
566
|
}
|
|
552
567
|
}
|