@aztec/prover-client 0.42.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.
Files changed (58) hide show
  1. package/README.md +1 -0
  2. package/dest/config.d.ts +21 -0
  3. package/dest/config.d.ts.map +1 -0
  4. package/dest/config.js +31 -0
  5. package/dest/index.d.ts +4 -0
  6. package/dest/index.d.ts.map +1 -0
  7. package/dest/index.js +3 -0
  8. package/dest/mocks/fixtures.d.ts +22 -0
  9. package/dest/mocks/fixtures.d.ts.map +1 -0
  10. package/dest/mocks/fixtures.js +95 -0
  11. package/dest/mocks/test_context.d.ts +32 -0
  12. package/dest/mocks/test_context.d.ts.map +1 -0
  13. package/dest/mocks/test_context.js +116 -0
  14. package/dest/orchestrator/block-building-helpers.d.ts +36 -0
  15. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -0
  16. package/dest/orchestrator/block-building-helpers.js +236 -0
  17. package/dest/orchestrator/orchestrator.d.ts +113 -0
  18. package/dest/orchestrator/orchestrator.d.ts.map +1 -0
  19. package/dest/orchestrator/orchestrator.js +574 -0
  20. package/dest/orchestrator/proving-state.d.ts +68 -0
  21. package/dest/orchestrator/proving-state.d.ts.map +1 -0
  22. package/dest/orchestrator/proving-state.js +142 -0
  23. package/dest/orchestrator/tx-proving-state.d.ts +35 -0
  24. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -0
  25. package/dest/orchestrator/tx-proving-state.js +92 -0
  26. package/dest/prover-agent/index.d.ts +4 -0
  27. package/dest/prover-agent/index.d.ts.map +1 -0
  28. package/dest/prover-agent/index.js +4 -0
  29. package/dest/prover-agent/memory-proving-queue.d.ts +64 -0
  30. package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -0
  31. package/dest/prover-agent/memory-proving-queue.js +187 -0
  32. package/dest/prover-agent/prover-agent.d.ts +30 -0
  33. package/dest/prover-agent/prover-agent.d.ts.map +1 -0
  34. package/dest/prover-agent/prover-agent.js +115 -0
  35. package/dest/prover-agent/proving-error.d.ts +5 -0
  36. package/dest/prover-agent/proving-error.d.ts.map +1 -0
  37. package/dest/prover-agent/proving-error.js +9 -0
  38. package/dest/prover-agent/rpc.d.ts +5 -0
  39. package/dest/prover-agent/rpc.d.ts.map +1 -0
  40. package/dest/prover-agent/rpc.js +53 -0
  41. package/dest/tx-prover/tx-prover.d.ts +65 -0
  42. package/dest/tx-prover/tx-prover.d.ts.map +1 -0
  43. package/dest/tx-prover/tx-prover.js +122 -0
  44. package/package.json +87 -0
  45. package/src/config.ts +59 -0
  46. package/src/index.ts +4 -0
  47. package/src/mocks/fixtures.ts +182 -0
  48. package/src/mocks/test_context.ts +217 -0
  49. package/src/orchestrator/block-building-helpers.ts +470 -0
  50. package/src/orchestrator/orchestrator.ts +883 -0
  51. package/src/orchestrator/proving-state.ts +210 -0
  52. package/src/orchestrator/tx-proving-state.ts +139 -0
  53. package/src/prover-agent/index.ts +3 -0
  54. package/src/prover-agent/memory-proving-queue.ts +303 -0
  55. package/src/prover-agent/prover-agent.ts +144 -0
  56. package/src/prover-agent/proving-error.ts +9 -0
  57. package/src/prover-agent/rpc.ts +91 -0
  58. package/src/tx-prover/tx-prover.ts +171 -0
@@ -0,0 +1,236 @@
1
+ import { MerkleTreeId } from '@aztec/circuit-types';
2
+ import { ARCHIVE_HEIGHT, AppendOnlyTreeSnapshot, BaseRollupInputs, ConstantRollupData, Fr, KernelData, MAX_NEW_NULLIFIERS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, MergeRollupInputs, NESTED_RECURSIVE_PROOF_LENGTH, NOTE_HASH_SUBTREE_HEIGHT, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, NullifierLeafPreimage, PUBLIC_DATA_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_TREE_HEIGHT, PartialStateReference, PreviousRollupData, PublicDataHint, PublicDataTreeLeaf, PublicDataUpdateRequest, ROLLUP_VK_TREE_HEIGHT, RootRollupInputs, StateDiffHints, VK_TREE_HEIGHT, makeRecursiveProofFromBinary, } from '@aztec/circuits.js';
3
+ import { assertPermutation, makeTuple } from '@aztec/foundation/array';
4
+ import { padArrayEnd } from '@aztec/foundation/collection';
5
+ import { assertLength, toFriendlyJSON } from '@aztec/foundation/serialize';
6
+ import { HintsBuilder, computeFeePayerBalanceLeafSlot } from '@aztec/simulator';
7
+ // Denotes fields that are not used now, but will be in the future
8
+ const FUTURE_FR = new Fr(0n);
9
+ const FUTURE_NUM = 0;
10
+ // Denotes fields that should be deleted
11
+ const DELETE_FR = new Fr(0n);
12
+ // Builds the base rollup inputs, updating the contract, nullifier, and data trees in the process
13
+ export async function buildBaseRollupInput(tx, globalVariables, db, kernelVk) {
14
+ // Get trees info before any changes hit
15
+ const constants = await getConstantRollupData(globalVariables, db);
16
+ const start = new PartialStateReference(await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db), await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db), await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db));
17
+ // Get the subtree sibling paths for the circuit
18
+ const noteHashSubtreeSiblingPathArray = await getSubtreeSiblingPath(MerkleTreeId.NOTE_HASH_TREE, NOTE_HASH_SUBTREE_HEIGHT, db);
19
+ const noteHashSubtreeSiblingPath = makeTuple(NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, i => i < noteHashSubtreeSiblingPathArray.length ? noteHashSubtreeSiblingPathArray[i] : Fr.ZERO);
20
+ // Create data hint for reading fee payer initial balance in gas tokens
21
+ // If no fee payer is set, read hint should be empty
22
+ // If there is already a public data write for this slot, also skip the read hint
23
+ const hintsBuilder = new HintsBuilder(db);
24
+ const leafSlot = computeFeePayerBalanceLeafSlot(tx.data.feePayer);
25
+ const existingBalanceWrite = tx.data.end.publicDataUpdateRequests.find(write => write.leafSlot.equals(leafSlot));
26
+ const feePayerGasTokenBalanceReadHint = leafSlot.isZero() || existingBalanceWrite
27
+ ? PublicDataHint.empty()
28
+ : await hintsBuilder.getPublicDataHint(leafSlot.toBigInt());
29
+ // Update the note hash trees with the new items being inserted to get the new roots
30
+ // that will be used by the next iteration of the base rollup circuit, skipping the empty ones
31
+ const newNoteHashes = tx.data.end.newNoteHashes;
32
+ await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, newNoteHashes);
33
+ // The read witnesses for a given TX should be generated before the writes of the same TX are applied.
34
+ // All reads that refer to writes in the same tx are transient and can be simplified out.
35
+ const txPublicDataUpdateRequestInfo = await processPublicDataUpdateRequests(tx, db);
36
+ // Update the nullifier tree, capturing the low nullifier info for each individual operation
37
+ const { lowLeavesWitnessData: nullifierWitnessLeaves, newSubtreeSiblingPath: newNullifiersSubtreeSiblingPath, sortedNewLeaves: sortedNewNullifiers, sortedNewLeavesIndexes, } = await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, tx.data.end.newNullifiers.map(n => n.toBuffer()), NULLIFIER_SUBTREE_HEIGHT);
38
+ if (nullifierWitnessLeaves === undefined) {
39
+ throw new Error(`Could not craft nullifier batch insertion proofs`);
40
+ }
41
+ // Extract witness objects from returned data
42
+ const nullifierPredecessorMembershipWitnessesWithoutPadding = nullifierWitnessLeaves.map(l => MembershipWitness.fromBufferArray(l.index, assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT)));
43
+ const nullifierSubtreeSiblingPathArray = newNullifiersSubtreeSiblingPath.toFields();
44
+ const nullifierSubtreeSiblingPath = makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, i => i < nullifierSubtreeSiblingPathArray.length ? nullifierSubtreeSiblingPathArray[i] : Fr.ZERO);
45
+ const publicDataSiblingPath = txPublicDataUpdateRequestInfo.newPublicDataSubtreeSiblingPath;
46
+ const stateDiffHints = StateDiffHints.from({
47
+ nullifierPredecessorPreimages: makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => i < nullifierWitnessLeaves.length
48
+ ? nullifierWitnessLeaves[i].leafPreimage
49
+ : NullifierLeafPreimage.empty()),
50
+ nullifierPredecessorMembershipWitnesses: makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => i < nullifierPredecessorMembershipWitnessesWithoutPadding.length
51
+ ? nullifierPredecessorMembershipWitnessesWithoutPadding[i]
52
+ : makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT)),
53
+ sortedNullifiers: makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortedNewNullifiers[i])),
54
+ sortedNullifierIndexes: makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => sortedNewLeavesIndexes[i]),
55
+ noteHashSubtreeSiblingPath,
56
+ nullifierSubtreeSiblingPath,
57
+ publicDataSiblingPath,
58
+ });
59
+ const blockHash = tx.data.constants.historicalHeader.hash();
60
+ const archiveRootMembershipWitness = await getMembershipWitnessFor(blockHash, MerkleTreeId.ARCHIVE, ARCHIVE_HEIGHT, db);
61
+ return BaseRollupInputs.from({
62
+ kernelData: getKernelDataFor(tx, kernelVk),
63
+ start,
64
+ stateDiffHints,
65
+ feePayerGasTokenBalanceReadHint,
66
+ sortedPublicDataWrites: txPublicDataUpdateRequestInfo.sortedPublicDataWrites,
67
+ sortedPublicDataWritesIndexes: txPublicDataUpdateRequestInfo.sortedPublicDataWritesIndexes,
68
+ lowPublicDataWritesPreimages: txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages,
69
+ lowPublicDataWritesMembershipWitnesses: txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses,
70
+ archiveRootMembershipWitness,
71
+ constants,
72
+ });
73
+ }
74
+ export function createMergeRollupInputs(left, right) {
75
+ const mergeInputs = new MergeRollupInputs([
76
+ getPreviousRollupDataFromPublicInputs(left[0], left[1], left[2]),
77
+ getPreviousRollupDataFromPublicInputs(right[0], right[1], right[2]),
78
+ ]);
79
+ return mergeInputs;
80
+ }
81
+ // Validate that the roots of all local trees match the output of the root circuit simulation
82
+ export async function validateRootOutput(rootOutput, db) {
83
+ await Promise.all([
84
+ validateState(rootOutput.header.state, db),
85
+ validateSimulatedTree(await getTreeSnapshot(MerkleTreeId.ARCHIVE, db), rootOutput.archive, 'Archive'),
86
+ ]);
87
+ }
88
+ export async function validateState(state, db) {
89
+ const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(async (id) => {
90
+ return { key: id, value: await getTreeSnapshot(id, db) };
91
+ });
92
+ const snapshots = new Map((await Promise.all(promises)).map(obj => [obj.key, obj.value]));
93
+ validatePartialState(state.partial, snapshots);
94
+ validateSimulatedTree(await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db), state.l1ToL2MessageTree, 'L1ToL2MessageTree');
95
+ }
96
+ // Builds the inputs for the root rollup circuit, without making any changes to trees
97
+ export async function getRootRollupInput(rollupOutputLeft, rollupProofLeft, verificationKeyLeft, rollupOutputRight, rollupProofRight, verificationKeyRight, l1ToL2Roots, newL1ToL2Messages, messageTreeSnapshot, messageTreeRootSiblingPath, db) {
98
+ const previousRollupData = [
99
+ getPreviousRollupDataFromPublicInputs(rollupOutputLeft, rollupProofLeft, verificationKeyLeft),
100
+ getPreviousRollupDataFromPublicInputs(rollupOutputRight, rollupProofRight, verificationKeyRight),
101
+ ];
102
+ const getRootTreeSiblingPath = async (treeId) => {
103
+ const { size } = await db.getTreeInfo(treeId);
104
+ const path = await db.getSiblingPath(treeId, size);
105
+ return path.toFields();
106
+ };
107
+ // Get blocks tree
108
+ const startArchiveSnapshot = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
109
+ const newArchiveSiblingPathArray = await getRootTreeSiblingPath(MerkleTreeId.ARCHIVE);
110
+ const newArchiveSiblingPath = makeTuple(ARCHIVE_HEIGHT, i => (i < newArchiveSiblingPathArray.length ? newArchiveSiblingPathArray[i] : Fr.ZERO), 0);
111
+ return RootRollupInputs.from({
112
+ previousRollupData,
113
+ l1ToL2Roots,
114
+ newL1ToL2Messages,
115
+ newL1ToL2MessageTreeRootSiblingPath: messageTreeRootSiblingPath,
116
+ startL1ToL2MessageTreeSnapshot: messageTreeSnapshot,
117
+ startArchiveSnapshot,
118
+ newArchiveSiblingPath,
119
+ });
120
+ }
121
+ export function getPreviousRollupDataFromPublicInputs(rollupOutput, rollupProof, vk) {
122
+ return new PreviousRollupData(rollupOutput, rollupProof, vk,
123
+ // MembershipWitness for a VK tree to be implemented in the future
124
+ FUTURE_NUM, new MembershipWitness(ROLLUP_VK_TREE_HEIGHT, BigInt(FUTURE_NUM), makeTuple(ROLLUP_VK_TREE_HEIGHT, () => FUTURE_FR)));
125
+ }
126
+ export async function getConstantRollupData(globalVariables, db) {
127
+ return ConstantRollupData.from({
128
+ baseRollupVkHash: DELETE_FR,
129
+ mergeRollupVkHash: DELETE_FR,
130
+ privateKernelVkTreeRoot: FUTURE_FR,
131
+ publicKernelVkTreeRoot: FUTURE_FR,
132
+ lastArchive: await getTreeSnapshot(MerkleTreeId.ARCHIVE, db),
133
+ globalVariables,
134
+ });
135
+ }
136
+ export async function getTreeSnapshot(id, db) {
137
+ const treeInfo = await db.getTreeInfo(id);
138
+ return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size));
139
+ }
140
+ export function getKernelDataFor(tx, vk) {
141
+ const recursiveProof = makeRecursiveProofFromBinary(tx.proof, NESTED_RECURSIVE_PROOF_LENGTH);
142
+ return new KernelData(tx.data, recursiveProof,
143
+ // VK for the kernel circuit
144
+ vk,
145
+ // MembershipWitness for a VK tree to be implemented in the future
146
+ FUTURE_NUM, assertLength(Array(VK_TREE_HEIGHT).fill(FUTURE_FR), VK_TREE_HEIGHT));
147
+ }
148
+ export function makeEmptyMembershipWitness(height) {
149
+ return new MembershipWitness(height, 0n, makeTuple(height, () => Fr.ZERO));
150
+ }
151
+ export async function processPublicDataUpdateRequests(tx, db) {
152
+ const allPublicDataUpdateRequests = padArrayEnd(tx.finalPublicDataUpdateRequests, PublicDataUpdateRequest.empty(), MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX);
153
+ const allPublicDataWrites = allPublicDataUpdateRequests.map(({ leafSlot, newValue }) => new PublicDataTreeLeaf(leafSlot, newValue));
154
+ const { lowLeavesWitnessData, newSubtreeSiblingPath, sortedNewLeaves, sortedNewLeavesIndexes } = await db.batchInsert(MerkleTreeId.PUBLIC_DATA_TREE, allPublicDataWrites.map(x => x.toBuffer()),
155
+ // TODO(#3675) remove oldValue from update requests
156
+ PUBLIC_DATA_SUBTREE_HEIGHT);
157
+ if (lowLeavesWitnessData === undefined) {
158
+ throw new Error(`Could not craft public data batch insertion proofs`);
159
+ }
160
+ const sortedPublicDataWrites = makeTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => {
161
+ return PublicDataTreeLeaf.fromBuffer(sortedNewLeaves[i]);
162
+ });
163
+ const sortedPublicDataWritesIndexes = makeTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => {
164
+ return sortedNewLeavesIndexes[i];
165
+ });
166
+ const subtreeSiblingPathAsFields = newSubtreeSiblingPath.toFields();
167
+ const newPublicDataSubtreeSiblingPath = makeTuple(PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, i => {
168
+ return subtreeSiblingPathAsFields[i];
169
+ });
170
+ const lowPublicDataWritesMembershipWitnesses = makeTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => {
171
+ const witness = lowLeavesWitnessData[i];
172
+ return MembershipWitness.fromBufferArray(witness.index, assertLength(witness.siblingPath.toBufferArray(), PUBLIC_DATA_TREE_HEIGHT));
173
+ });
174
+ const lowPublicDataWritesPreimages = makeTuple(MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => {
175
+ return lowLeavesWitnessData[i].leafPreimage;
176
+ });
177
+ // validate that the sortedPublicDataWrites and sortedPublicDataWritesIndexes are in the correct order
178
+ // otherwise it will just fail in the circuit
179
+ assertPermutation(allPublicDataWrites, sortedPublicDataWrites, sortedPublicDataWritesIndexes, (a, b) => a.equals(b));
180
+ return {
181
+ lowPublicDataWritesPreimages,
182
+ lowPublicDataWritesMembershipWitnesses,
183
+ newPublicDataSubtreeSiblingPath,
184
+ sortedPublicDataWrites,
185
+ sortedPublicDataWritesIndexes,
186
+ };
187
+ }
188
+ export async function getSubtreeSiblingPath(treeId, subtreeHeight, db) {
189
+ const nextAvailableLeafIndex = await db.getTreeInfo(treeId).then(t => t.size);
190
+ const fullSiblingPath = await db.getSiblingPath(treeId, nextAvailableLeafIndex);
191
+ // Drop the first subtreeHeight items since we only care about the path to the subtree root
192
+ return fullSiblingPath.getSubtreeSiblingPath(subtreeHeight).toFields();
193
+ }
194
+ // Scan a tree searching for a specific value and return a membership witness proof for it
195
+ export async function getMembershipWitnessFor(value, treeId, height, db) {
196
+ // If this is an empty tx, then just return zeroes
197
+ if (value.isZero()) {
198
+ return makeEmptyMembershipWitness(height);
199
+ }
200
+ const index = await db.findLeafIndex(treeId, value.toBuffer());
201
+ if (index === undefined) {
202
+ throw new Error(`Leaf with value ${value} not found in tree ${MerkleTreeId[treeId]}`);
203
+ }
204
+ const path = await db.getSiblingPath(treeId, index);
205
+ return new MembershipWitness(height, index, assertLength(path.toFields(), height));
206
+ }
207
+ export function validatePartialState(partialState, treeSnapshots) {
208
+ validateSimulatedTree(treeSnapshots.get(MerkleTreeId.NOTE_HASH_TREE), partialState.noteHashTree, 'NoteHashTree');
209
+ validateSimulatedTree(treeSnapshots.get(MerkleTreeId.NULLIFIER_TREE), partialState.nullifierTree, 'NullifierTree');
210
+ validateSimulatedTree(treeSnapshots.get(MerkleTreeId.PUBLIC_DATA_TREE), partialState.publicDataTree, 'PublicDataTree');
211
+ }
212
+ // Helper for comparing two trees snapshots
213
+ export function validateSimulatedTree(localTree, simulatedTree, name, label) {
214
+ if (!simulatedTree.root.toBuffer().equals(localTree.root.toBuffer())) {
215
+ throw new Error(`${label ?? name} tree root mismatch (local ${localTree.root}, simulated ${simulatedTree.root})`);
216
+ }
217
+ if (simulatedTree.nextAvailableLeafIndex !== localTree.nextAvailableLeafIndex) {
218
+ throw new Error(`${label ?? name} tree next available leaf index mismatch (local ${localTree.nextAvailableLeafIndex}, simulated ${simulatedTree.nextAvailableLeafIndex})`);
219
+ }
220
+ }
221
+ export function validateTx(tx) {
222
+ const txHeader = tx.data.constants.historicalHeader;
223
+ if (txHeader.state.l1ToL2MessageTree.isZero()) {
224
+ throw new Error(`Empty L1 to L2 messages tree in tx: ${toFriendlyJSON(tx)}`);
225
+ }
226
+ if (txHeader.state.partial.noteHashTree.isZero()) {
227
+ throw new Error(`Empty note hash tree in tx: ${toFriendlyJSON(tx)}`);
228
+ }
229
+ if (txHeader.state.partial.nullifierTree.isZero()) {
230
+ throw new Error(`Empty nullifier tree in tx: ${toFriendlyJSON(tx)}`);
231
+ }
232
+ if (txHeader.state.partial.publicDataTree.isZero()) {
233
+ throw new Error(`Empty public data tree in tx: ${toFriendlyJSON(tx)}`);
234
+ }
235
+ }
236
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2stYnVpbGRpbmctaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcmNoZXN0cmF0b3IvYmxvY2stYnVpbGRpbmctaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFvQixNQUFNLHNCQUFzQixDQUFDO0FBQ3RFLE9BQU8sRUFDTCxjQUFjLEVBQ2Qsc0JBQXNCLEVBRXRCLGdCQUFnQixFQUNoQixrQkFBa0IsRUFDbEIsRUFBRSxFQUVGLFVBQVUsRUFFVix5QkFBeUIsRUFDekIsNENBQTRDLEVBQzVDLGlCQUFpQixFQUNqQixpQkFBaUIsRUFDakIsNkJBQTZCLEVBQzdCLHdCQUF3QixFQUN4QixxQ0FBcUMsRUFDckMsd0JBQXdCLEVBQ3hCLHFDQUFxQyxFQUNyQyxxQkFBcUIsRUFFckIscUJBQXFCLEVBQ3JCLDBCQUEwQixFQUMxQix1Q0FBdUMsRUFDdkMsdUJBQXVCLEVBQ3ZCLHFCQUFxQixFQUNyQixrQkFBa0IsRUFDbEIsY0FBYyxFQUNkLGtCQUFrQixFQUVsQix1QkFBdUIsRUFDdkIscUJBQXFCLEVBR3JCLGdCQUFnQixFQUVoQixjQUFjLEVBRWQsY0FBYyxFQUdkLDRCQUE0QixHQUM3QixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDM0QsT0FBTyxFQUFjLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN2RixPQUFPLEVBQUUsWUFBWSxFQUFFLDhCQUE4QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFHaEYsa0VBQWtFO0FBQ2xFLE1BQU0sU0FBUyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzdCLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQztB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
@@ -0,0 +1,113 @@
1
+ import { type ProcessedTx } from '@aztec/circuit-types';
2
+ import { type BlockResult, type ProvingTicket, type ServerCircuitProver } from '@aztec/circuit-types/interfaces';
3
+ import { Fr, type GlobalVariables, type Header, type VerificationKeys } from '@aztec/circuits.js';
4
+ import { type MerkleTreeOperations } from '@aztec/world-state';
5
+ /**
6
+ * Implements an event driven proving scheduler to build the recursive proof tree. The idea being:
7
+ * 1. Transactions are provided to the scheduler post simulation.
8
+ * 2. Tree insertions are performed as required to generate transaction specific proofs
9
+ * 3. Those transaction specific proofs are generated in the necessary order accounting for dependencies
10
+ * 4. Once a transaction is proven, it will be incorporated into a merge proof
11
+ * 5. Merge proofs are produced at each level of the tree until the root proof is produced
12
+ *
13
+ * The proving implementation is determined by the provided prover. This could be for example a local prover or a remote prover pool.
14
+ */
15
+ /**
16
+ * The orchestrator, managing the flow of recursive proving operations required to build the rollup proof tree.
17
+ */
18
+ export declare class ProvingOrchestrator {
19
+ private db;
20
+ private prover;
21
+ private initialHeader?;
22
+ private provingState;
23
+ private pendingProvingJobs;
24
+ private paddingTx;
25
+ constructor(db: MerkleTreeOperations, prover: ServerCircuitProver, initialHeader?: Header | undefined);
26
+ /**
27
+ * Resets the orchestrator's cached padding tx.
28
+ */
29
+ reset(): void;
30
+ /**
31
+ * Starts off a new block
32
+ * @param numTxs - The total number of transactions in the block. Must be a power of 2
33
+ * @param globalVariables - The global variables for the block
34
+ * @param l1ToL2Messages - The l1 to l2 messages for the block
35
+ * @param verificationKeys - The private kernel verification keys
36
+ * @returns A proving ticket, containing a promise notifying of proving completion
37
+ */
38
+ startNewBlock(numTxs: number, globalVariables: GlobalVariables, l1ToL2Messages: Fr[], verificationKeys: VerificationKeys): Promise<ProvingTicket>;
39
+ /**
40
+ * The interface to add a simulated transaction to the scheduler
41
+ * @param tx - The transaction to be proven
42
+ */
43
+ addNewTx(tx: ProcessedTx): Promise<void>;
44
+ /**
45
+ * Marks the block as full and pads it to the full power of 2 block size, no more transactions will be accepted.
46
+ */
47
+ setBlockCompleted(): Promise<void>;
48
+ private enqueuePaddingTxs;
49
+ /**
50
+ * Prepares the cached sets of base rollup inputs for padding transactions and proves them
51
+ * @param txInputs - The base rollup inputs, start and end hash paths etc
52
+ * @param paddingTx - The padding tx, contains the header, proof, vk, public inputs used in the proof
53
+ * @param provingState - The block proving state
54
+ */
55
+ private provePaddingTransactions;
56
+ /**
57
+ * Cancel any further proving of the block
58
+ */
59
+ cancelBlock(): void;
60
+ /**
61
+ * Performs the final tree update for the block and returns the fully proven block.
62
+ * @returns The fully proven block and proof.
63
+ */
64
+ finaliseBlock(): Promise<BlockResult>;
65
+ /**
66
+ * Starts the proving process for the given transaction and adds it to our state
67
+ * @param tx - The transaction whose proving we wish to commence
68
+ * @param provingState - The proving state being worked on
69
+ */
70
+ private prepareTransaction;
71
+ private enqueueFirstProof;
72
+ /**
73
+ * Enqueue a job to be scheduled
74
+ * @param provingState - The proving state object being operated on
75
+ * @param jobType - The type of job to be queued
76
+ * @param job - The actual job, returns a promise notifying of the job's completion
77
+ */
78
+ private deferredProving;
79
+ private prepareBaseRollupInputs;
80
+ private storeMergeInputs;
81
+ private enqueueBaseRollup;
82
+ private enqueueMergeRollup;
83
+ private enqueueRootRollup;
84
+ private enqueueBaseParityCircuit;
85
+ private enqueueRootParityCircuit;
86
+ private checkAndEnqueueRootRollup;
87
+ /**
88
+ * Stores the inputs to a merge/root circuit and enqueues the circuit if ready
89
+ * @param provingState - The proving state being operated on
90
+ * @param currentLevel - The level of the merge/root circuit
91
+ * @param currentIndex - The index of the merge/root circuit
92
+ * @param mergeInputData - The inputs to be stored
93
+ */
94
+ private storeAndExecuteNextMergeLevel;
95
+ /**
96
+ * Executes the VM circuit for a public function, will enqueue the corresponding kernel if the
97
+ * previous kernel is ready
98
+ * @param provingState - The proving state being operated on
99
+ * @param txIndex - The index of the transaction being proven
100
+ * @param functionIndex - The index of the function/kernel being proven
101
+ */
102
+ private enqueueVM;
103
+ private checkAndEnqueuePublicKernel;
104
+ /**
105
+ * Executes the kernel circuit for a public function, will enqueue the next kernel circuit if it's VM is already proven
106
+ * or the base rollup circuit if there are no more kernels to be proven
107
+ * @param provingState - The proving state being operated on
108
+ * @param txIndex - The index of the transaction being proven
109
+ * @param functionIndex - The index of the function/kernel being proven
110
+ */
111
+ private enqueuePublicKernel;
112
+ }
113
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/orchestrator/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,WAAW,EAOjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,WAAW,EAGhB,KAAK,aAAa,EAElB,KAAK,mBAAmB,EACzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAML,EAAE,EACF,KAAK,eAAe,EACpB,KAAK,MAAM,EAeX,KAAK,gBAAgB,EAEtB,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAmB/D;;;;;;;;;GASG;AAEH;;GAEG;AACH,qBAAa,mBAAmB;IAKlB,OAAO,CAAC,EAAE;IAAwB,OAAO,CAAC,MAAM;IAAuB,OAAO,CAAC,aAAa,CAAC;IAJzG,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,kBAAkB,CAAyB;IACnD,OAAO,CAAC,SAAS,CAA6C;gBAE1C,EAAE,EAAE,oBAAoB,EAAU,MAAM,EAAE,mBAAmB,EAAU,aAAa,CAAC,oBAAQ;IAEjH;;OAEG;IACI,KAAK;IAIZ;;;;;;;OAOG;IACU,aAAa,CACxB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,EAAE,EAAE,EACpB,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,aAAa,CAAC;IA4EzB;;;OAGG;IACU,QAAQ,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBrD;;OAEG;IACU,iBAAiB;IAqC9B,OAAO,CAAC,iBAAiB;IAkCzB;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAchC;;OAEG;IACI,WAAW;IAQlB;;;OAGG;IACU,aAAa;IAoE1B;;;;OAIG;YACW,kBAAkB;IAahC,OAAO,CAAC,iBAAiB;IA4BzB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;YAyDT,uBAAuB;IAyBrC,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,iBAAiB;IAmEzB,OAAO,CAAC,kBAAkB;YAyBZ,iBAAiB;IA2C/B,OAAO,CAAC,wBAAwB;IAqBhC,OAAO,CAAC,wBAAwB;YAWlB,yBAAyB;IAQvC;;;;;;OAMG;IACH,OAAO,CAAC,6BAA6B;IA0BrC;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IAyCjB,OAAO,CAAC,2BAA2B;IAkBnC;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;CAiD5B"}