@aztec/prover-client 0.70.0 → 0.71.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/bin/get-proof-inputs.d.ts +2 -0
- package/dest/bin/get-proof-inputs.d.ts.map +1 -0
- package/dest/bin/get-proof-inputs.js +50 -0
- package/dest/block_builder/light.d.ts +3 -4
- package/dest/block_builder/light.d.ts.map +1 -1
- package/dest/block_builder/light.js +8 -11
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +9 -10
- package/dest/orchestrator/block-building-helpers.d.ts +8 -7
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +20 -16
- package/dest/orchestrator/orchestrator.d.ts +1 -1
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +5 -11
- package/dest/prover-agent/memory-proving-queue.d.ts +1 -1
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +2 -2
- package/dest/prover-agent/prover-agent.d.ts +0 -2
- package/dest/prover-agent/prover-agent.d.ts.map +1 -1
- package/dest/prover-agent/prover-agent.js +4 -6
- package/dest/prover-client/factory.d.ts.map +1 -1
- package/dest/prover-client/factory.js +3 -3
- package/dest/prover-client/prover-client.d.ts +4 -2
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +13 -15
- package/dest/proving_broker/broker_prover_facade.d.ts +4 -3
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -1
- package/dest/proving_broker/broker_prover_facade.js +25 -6
- package/dest/proving_broker/factory.d.ts.map +1 -1
- package/dest/proving_broker/factory.js +3 -3
- package/dest/proving_broker/index.d.ts +1 -1
- package/dest/proving_broker/index.d.ts.map +1 -1
- package/dest/proving_broker/index.js +2 -2
- package/dest/proving_broker/proof_store/factory.d.ts +6 -0
- package/dest/proving_broker/proof_store/factory.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/factory.js +39 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +13 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/gcs_proof_store.js +46 -0
- package/dest/proving_broker/proof_store/index.d.ts +4 -0
- package/dest/proving_broker/proof_store/index.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/index.js +4 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts +14 -0
- package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/inline_proof_store.js +37 -0
- package/dest/proving_broker/{proof_store.d.ts → proof_store/proof_store.d.ts} +1 -12
- package/dest/proving_broker/proof_store/proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store/proof_store.js +2 -0
- package/dest/proving_broker/proving_agent.d.ts +4 -4
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +5 -5
- package/dest/proving_broker/proving_broker.d.ts +1 -1
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +3 -3
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker_database/persisted.js +4 -4
- package/dest/test/mock_prover.d.ts +1 -1
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +4 -5
- package/package.json +14 -12
- package/src/bin/get-proof-inputs.ts +60 -0
- package/src/block_builder/light.ts +6 -11
- package/src/mocks/test_context.ts +7 -9
- package/src/orchestrator/block-building-helpers.ts +358 -326
- package/src/orchestrator/orchestrator.ts +11 -15
- package/src/prover-agent/memory-proving-queue.ts +1 -1
- package/src/prover-agent/prover-agent.ts +10 -4
- package/src/prover-client/factory.ts +2 -3
- package/src/prover-client/prover-client.ts +14 -15
- package/src/proving_broker/broker_prover_facade.ts +28 -5
- package/src/proving_broker/factory.ts +9 -5
- package/src/proving_broker/index.ts +1 -1
- package/src/proving_broker/proof_store/factory.ts +42 -0
- package/src/proving_broker/proof_store/gcs_proof_store.ts +72 -0
- package/src/proving_broker/proof_store/index.ts +3 -0
- package/src/proving_broker/{proof_store.ts → proof_store/inline_proof_store.ts} +1 -44
- package/src/proving_broker/proof_store/proof_store.ts +54 -0
- package/src/proving_broker/proving_agent.ts +11 -5
- package/src/proving_broker/proving_broker.ts +8 -2
- package/src/proving_broker/proving_broker_database/persisted.ts +3 -3
- package/src/test/mock_prover.ts +3 -4
- package/dest/proving_broker/proof_store.d.ts.map +0 -1
- package/dest/proving_broker/proof_store.js +0 -37
|
@@ -53,6 +53,7 @@ import { computeUnbalancedMerkleRoot } from '@aztec/foundation/trees';
|
|
|
53
53
|
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vks';
|
|
54
54
|
import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
|
|
55
55
|
import { computeFeePayerBalanceLeafSlot } from '@aztec/simulator/server';
|
|
56
|
+
import { Attributes, type Span, runInSpan } from '@aztec/telemetry-client';
|
|
56
57
|
import { type MerkleTreeReadOperations } from '@aztec/world-state';
|
|
57
58
|
|
|
58
59
|
import { inspect } from 'util';
|
|
@@ -67,185 +68,191 @@ type BaseTreeNames = 'NoteHashTree' | 'ContractTree' | 'NullifierTree' | 'Public
|
|
|
67
68
|
export type TreeNames = BaseTreeNames | 'L1ToL2MessageTree' | 'Archive';
|
|
68
69
|
|
|
69
70
|
// Builds the hints for base rollup. Updating the contract, nullifier, and data trees in the process.
|
|
70
|
-
export
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// Update the note hash trees with the new items being inserted to get the new roots
|
|
95
|
-
// that will be used by the next iteration of the base rollup circuit, skipping the empty ones
|
|
96
|
-
const noteHashes = padArrayEnd(tx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX);
|
|
97
|
-
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashes);
|
|
98
|
-
|
|
99
|
-
// The read witnesses for a given TX should be generated before the writes of the same TX are applied.
|
|
100
|
-
// All reads that refer to writes in the same tx are transient and can be simplified out.
|
|
101
|
-
const txPublicDataUpdateRequestInfo = await processPublicDataUpdateRequests(tx, db);
|
|
102
|
-
|
|
103
|
-
// Update the nullifier tree, capturing the low nullifier info for each individual operation
|
|
104
|
-
const {
|
|
105
|
-
lowLeavesWitnessData: nullifierWitnessLeaves,
|
|
106
|
-
newSubtreeSiblingPath: nullifiersSubtreeSiblingPath,
|
|
107
|
-
sortedNewLeaves: sortednullifiers,
|
|
108
|
-
sortedNewLeavesIndexes,
|
|
109
|
-
} = await db.batchInsert(
|
|
110
|
-
MerkleTreeId.NULLIFIER_TREE,
|
|
111
|
-
padArrayEnd(tx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()),
|
|
112
|
-
NULLIFIER_SUBTREE_HEIGHT,
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
if (nullifierWitnessLeaves === undefined) {
|
|
116
|
-
throw new Error(`Could not craft nullifier batch insertion proofs`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Extract witness objects from returned data
|
|
120
|
-
const nullifierPredecessorMembershipWitnessesWithoutPadding: MembershipWitness<typeof NULLIFIER_TREE_HEIGHT>[] =
|
|
121
|
-
nullifierWitnessLeaves.map(l =>
|
|
122
|
-
MembershipWitness.fromBufferArray(l.index, assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT)),
|
|
71
|
+
export const buildBaseRollupHints = runInSpan(
|
|
72
|
+
'BlockBuilderHelpers',
|
|
73
|
+
'buildBaseRollupHints',
|
|
74
|
+
async (
|
|
75
|
+
span: Span,
|
|
76
|
+
tx: ProcessedTx,
|
|
77
|
+
globalVariables: GlobalVariables,
|
|
78
|
+
db: MerkleTreeWriteOperations,
|
|
79
|
+
startSpongeBlob: SpongeBlob,
|
|
80
|
+
) => {
|
|
81
|
+
span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
|
|
82
|
+
// Get trees info before any changes hit
|
|
83
|
+
const constants = await getConstantRollupData(globalVariables, db);
|
|
84
|
+
const start = new PartialStateReference(
|
|
85
|
+
await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
|
|
86
|
+
await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
|
|
87
|
+
await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
|
|
88
|
+
);
|
|
89
|
+
// Get the subtree sibling paths for the circuit
|
|
90
|
+
const noteHashSubtreeSiblingPathArray = await getSubtreeSiblingPath(
|
|
91
|
+
MerkleTreeId.NOTE_HASH_TREE,
|
|
92
|
+
NOTE_HASH_SUBTREE_HEIGHT,
|
|
93
|
+
db,
|
|
123
94
|
);
|
|
124
95
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
i < nullifierSubtreeSiblingPathArray.length ? nullifierSubtreeSiblingPathArray[i] : Fr.ZERO,
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
// Append new data to startSpongeBlob
|
|
132
|
-
const inputSpongeBlob = startSpongeBlob.clone();
|
|
133
|
-
startSpongeBlob.absorb(tx.txEffect.toBlobFields());
|
|
134
|
-
|
|
135
|
-
if (tx.avmProvingRequest) {
|
|
136
|
-
// Build public base rollup hints
|
|
137
|
-
const stateDiffHints = PublicBaseStateDiffHints.from({
|
|
138
|
-
nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
|
|
139
|
-
i < nullifierWitnessLeaves.length
|
|
140
|
-
? (nullifierWitnessLeaves[i].leafPreimage as NullifierLeafPreimage)
|
|
141
|
-
: NullifierLeafPreimage.empty(),
|
|
142
|
-
),
|
|
143
|
-
nullifierPredecessorMembershipWitnesses: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
|
|
144
|
-
i < nullifierPredecessorMembershipWitnessesWithoutPadding.length
|
|
145
|
-
? nullifierPredecessorMembershipWitnessesWithoutPadding[i]
|
|
146
|
-
: makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
|
|
147
|
-
),
|
|
148
|
-
sortedNullifiers: makeTuple(MAX_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortednullifiers[i])),
|
|
149
|
-
sortedNullifierIndexes: makeTuple(MAX_NULLIFIERS_PER_TX, i => sortedNewLeavesIndexes[i]),
|
|
150
|
-
noteHashSubtreeSiblingPath,
|
|
151
|
-
nullifierSubtreeSiblingPath,
|
|
152
|
-
lowPublicDataWritesPreimages: padArrayEnd(
|
|
153
|
-
txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages,
|
|
154
|
-
PublicDataTreeLeafPreimage.empty(),
|
|
155
|
-
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
156
|
-
),
|
|
157
|
-
lowPublicDataWritesMembershipWitnesses: padArrayEnd(
|
|
158
|
-
txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses,
|
|
159
|
-
MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT),
|
|
160
|
-
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
161
|
-
),
|
|
162
|
-
publicDataTreeSiblingPaths: padArrayEnd(
|
|
163
|
-
txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths,
|
|
164
|
-
makeTuple(PUBLIC_DATA_TREE_HEIGHT, () => Fr.ZERO),
|
|
165
|
-
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
166
|
-
),
|
|
167
|
-
});
|
|
96
|
+
const noteHashSubtreeSiblingPath = makeTuple(NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, i =>
|
|
97
|
+
i < noteHashSubtreeSiblingPathArray.length ? noteHashSubtreeSiblingPathArray[i] : Fr.ZERO,
|
|
98
|
+
);
|
|
168
99
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
100
|
+
// Update the note hash trees with the new items being inserted to get the new roots
|
|
101
|
+
// that will be used by the next iteration of the base rollup circuit, skipping the empty ones
|
|
102
|
+
const noteHashes = padArrayEnd(tx.txEffect.noteHashes, Fr.ZERO, MAX_NOTE_HASHES_PER_TX);
|
|
103
|
+
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, noteHashes);
|
|
104
|
+
|
|
105
|
+
// The read witnesses for a given TX should be generated before the writes of the same TX are applied.
|
|
106
|
+
// All reads that refer to writes in the same tx are transient and can be simplified out.
|
|
107
|
+
const txPublicDataUpdateRequestInfo = await processPublicDataUpdateRequests(tx, db);
|
|
108
|
+
|
|
109
|
+
// Update the nullifier tree, capturing the low nullifier info for each individual operation
|
|
110
|
+
const {
|
|
111
|
+
lowLeavesWitnessData: nullifierWitnessLeaves,
|
|
112
|
+
newSubtreeSiblingPath: nullifiersSubtreeSiblingPath,
|
|
113
|
+
sortedNewLeaves: sortednullifiers,
|
|
114
|
+
sortedNewLeavesIndexes,
|
|
115
|
+
} = await db.batchInsert(
|
|
116
|
+
MerkleTreeId.NULLIFIER_TREE,
|
|
117
|
+
padArrayEnd(tx.txEffect.nullifiers, Fr.ZERO, MAX_NULLIFIERS_PER_TX).map(n => n.toBuffer()),
|
|
118
|
+
NULLIFIER_SUBTREE_HEIGHT,
|
|
175
119
|
);
|
|
176
120
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
startSpongeBlob: inputSpongeBlob,
|
|
180
|
-
stateDiffHints,
|
|
181
|
-
archiveRootMembershipWitness,
|
|
182
|
-
constants,
|
|
183
|
-
});
|
|
184
|
-
} else {
|
|
185
|
-
if (
|
|
186
|
-
txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses.length > 1 ||
|
|
187
|
-
txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages.length > 1 ||
|
|
188
|
-
txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths.length > 1
|
|
189
|
-
) {
|
|
190
|
-
throw new Error(`More than one public data write in a private only tx`);
|
|
121
|
+
if (nullifierWitnessLeaves === undefined) {
|
|
122
|
+
throw new Error(`Could not craft nullifier batch insertion proofs`);
|
|
191
123
|
}
|
|
192
124
|
|
|
193
|
-
//
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
: await getPublicDataHint(db, leafSlot.toBigInt());
|
|
199
|
-
|
|
200
|
-
const feeWriteLowLeafPreimage =
|
|
201
|
-
txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages[0] || PublicDataTreeLeafPreimage.empty();
|
|
202
|
-
const feeWriteLowLeafMembershipWitness =
|
|
203
|
-
txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses[0] ||
|
|
204
|
-
MembershipWitness.empty<typeof PUBLIC_DATA_TREE_HEIGHT>(PUBLIC_DATA_TREE_HEIGHT);
|
|
205
|
-
const feeWriteSiblingPath =
|
|
206
|
-
txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths[0] ||
|
|
207
|
-
makeTuple(PUBLIC_DATA_TREE_HEIGHT, () => Fr.ZERO);
|
|
208
|
-
|
|
209
|
-
const stateDiffHints = PrivateBaseStateDiffHints.from({
|
|
210
|
-
nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
|
|
211
|
-
i < nullifierWitnessLeaves.length
|
|
212
|
-
? (nullifierWitnessLeaves[i].leafPreimage as NullifierLeafPreimage)
|
|
213
|
-
: NullifierLeafPreimage.empty(),
|
|
214
|
-
),
|
|
215
|
-
nullifierPredecessorMembershipWitnesses: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
|
|
216
|
-
i < nullifierPredecessorMembershipWitnessesWithoutPadding.length
|
|
217
|
-
? nullifierPredecessorMembershipWitnessesWithoutPadding[i]
|
|
218
|
-
: makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
|
|
219
|
-
),
|
|
220
|
-
sortedNullifiers: makeTuple(MAX_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortednullifiers[i])),
|
|
221
|
-
sortedNullifierIndexes: makeTuple(MAX_NULLIFIERS_PER_TX, i => sortedNewLeavesIndexes[i]),
|
|
222
|
-
noteHashSubtreeSiblingPath,
|
|
223
|
-
nullifierSubtreeSiblingPath,
|
|
224
|
-
feeWriteLowLeafPreimage,
|
|
225
|
-
feeWriteLowLeafMembershipWitness,
|
|
226
|
-
feeWriteSiblingPath,
|
|
227
|
-
});
|
|
125
|
+
// Extract witness objects from returned data
|
|
126
|
+
const nullifierPredecessorMembershipWitnessesWithoutPadding: MembershipWitness<typeof NULLIFIER_TREE_HEIGHT>[] =
|
|
127
|
+
nullifierWitnessLeaves.map(l =>
|
|
128
|
+
MembershipWitness.fromBufferArray(l.index, assertLength(l.siblingPath.toBufferArray(), NULLIFIER_TREE_HEIGHT)),
|
|
129
|
+
);
|
|
228
130
|
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
ARCHIVE_HEIGHT,
|
|
234
|
-
db,
|
|
131
|
+
const nullifierSubtreeSiblingPathArray = nullifiersSubtreeSiblingPath.toFields();
|
|
132
|
+
|
|
133
|
+
const nullifierSubtreeSiblingPath = makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, i =>
|
|
134
|
+
i < nullifierSubtreeSiblingPathArray.length ? nullifierSubtreeSiblingPathArray[i] : Fr.ZERO,
|
|
235
135
|
);
|
|
236
136
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
137
|
+
// Append new data to startSpongeBlob
|
|
138
|
+
const inputSpongeBlob = startSpongeBlob.clone();
|
|
139
|
+
startSpongeBlob.absorb(tx.txEffect.toBlobFields());
|
|
140
|
+
|
|
141
|
+
if (tx.avmProvingRequest) {
|
|
142
|
+
// Build public base rollup hints
|
|
143
|
+
const stateDiffHints = PublicBaseStateDiffHints.from({
|
|
144
|
+
nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
|
|
145
|
+
i < nullifierWitnessLeaves.length
|
|
146
|
+
? (nullifierWitnessLeaves[i].leafPreimage as NullifierLeafPreimage)
|
|
147
|
+
: NullifierLeafPreimage.empty(),
|
|
148
|
+
),
|
|
149
|
+
nullifierPredecessorMembershipWitnesses: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
|
|
150
|
+
i < nullifierPredecessorMembershipWitnessesWithoutPadding.length
|
|
151
|
+
? nullifierPredecessorMembershipWitnessesWithoutPadding[i]
|
|
152
|
+
: makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
|
|
153
|
+
),
|
|
154
|
+
sortedNullifiers: makeTuple(MAX_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortednullifiers[i])),
|
|
155
|
+
sortedNullifierIndexes: makeTuple(MAX_NULLIFIERS_PER_TX, i => sortedNewLeavesIndexes[i]),
|
|
156
|
+
noteHashSubtreeSiblingPath,
|
|
157
|
+
nullifierSubtreeSiblingPath,
|
|
158
|
+
lowPublicDataWritesPreimages: padArrayEnd(
|
|
159
|
+
txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages,
|
|
160
|
+
PublicDataTreeLeafPreimage.empty(),
|
|
161
|
+
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
162
|
+
),
|
|
163
|
+
lowPublicDataWritesMembershipWitnesses: padArrayEnd(
|
|
164
|
+
txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses,
|
|
165
|
+
MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT),
|
|
166
|
+
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
167
|
+
),
|
|
168
|
+
publicDataTreeSiblingPaths: padArrayEnd(
|
|
169
|
+
txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths,
|
|
170
|
+
makeTuple(PUBLIC_DATA_TREE_HEIGHT, () => Fr.ZERO),
|
|
171
|
+
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
172
|
+
),
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const blockHash = tx.constants.historicalHeader.hash();
|
|
176
|
+
const archiveRootMembershipWitness = await getMembershipWitnessFor(
|
|
177
|
+
blockHash,
|
|
178
|
+
MerkleTreeId.ARCHIVE,
|
|
179
|
+
ARCHIVE_HEIGHT,
|
|
180
|
+
db,
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
return PublicBaseRollupHints.from({
|
|
184
|
+
start,
|
|
185
|
+
startSpongeBlob: inputSpongeBlob,
|
|
186
|
+
stateDiffHints,
|
|
187
|
+
archiveRootMembershipWitness,
|
|
188
|
+
constants,
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
if (
|
|
192
|
+
txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses.length > 1 ||
|
|
193
|
+
txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages.length > 1 ||
|
|
194
|
+
txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths.length > 1
|
|
195
|
+
) {
|
|
196
|
+
throw new Error(`More than one public data write in a private only tx`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Create data hint for reading fee payer initial balance in Fee Juice
|
|
200
|
+
// If no fee payer is set, read hint should be empty
|
|
201
|
+
const leafSlot = computeFeePayerBalanceLeafSlot(tx.data.feePayer);
|
|
202
|
+
const feePayerFeeJuiceBalanceReadHint = tx.data.feePayer.isZero()
|
|
203
|
+
? PublicDataHint.empty()
|
|
204
|
+
: await getPublicDataHint(db, leafSlot.toBigInt());
|
|
205
|
+
|
|
206
|
+
const feeWriteLowLeafPreimage =
|
|
207
|
+
txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages[0] || PublicDataTreeLeafPreimage.empty();
|
|
208
|
+
const feeWriteLowLeafMembershipWitness =
|
|
209
|
+
txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses[0] ||
|
|
210
|
+
MembershipWitness.empty<typeof PUBLIC_DATA_TREE_HEIGHT>(PUBLIC_DATA_TREE_HEIGHT);
|
|
211
|
+
const feeWriteSiblingPath =
|
|
212
|
+
txPublicDataUpdateRequestInfo.publicDataWritesSiblingPaths[0] ||
|
|
213
|
+
makeTuple(PUBLIC_DATA_TREE_HEIGHT, () => Fr.ZERO);
|
|
214
|
+
|
|
215
|
+
const stateDiffHints = PrivateBaseStateDiffHints.from({
|
|
216
|
+
nullifierPredecessorPreimages: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
|
|
217
|
+
i < nullifierWitnessLeaves.length
|
|
218
|
+
? (nullifierWitnessLeaves[i].leafPreimage as NullifierLeafPreimage)
|
|
219
|
+
: NullifierLeafPreimage.empty(),
|
|
220
|
+
),
|
|
221
|
+
nullifierPredecessorMembershipWitnesses: makeTuple(MAX_NULLIFIERS_PER_TX, i =>
|
|
222
|
+
i < nullifierPredecessorMembershipWitnessesWithoutPadding.length
|
|
223
|
+
? nullifierPredecessorMembershipWitnessesWithoutPadding[i]
|
|
224
|
+
: makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT),
|
|
225
|
+
),
|
|
226
|
+
sortedNullifiers: makeTuple(MAX_NULLIFIERS_PER_TX, i => Fr.fromBuffer(sortednullifiers[i])),
|
|
227
|
+
sortedNullifierIndexes: makeTuple(MAX_NULLIFIERS_PER_TX, i => sortedNewLeavesIndexes[i]),
|
|
228
|
+
noteHashSubtreeSiblingPath,
|
|
229
|
+
nullifierSubtreeSiblingPath,
|
|
230
|
+
feeWriteLowLeafPreimage,
|
|
231
|
+
feeWriteLowLeafMembershipWitness,
|
|
232
|
+
feeWriteSiblingPath,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const blockHash = tx.constants.historicalHeader.hash();
|
|
236
|
+
const archiveRootMembershipWitness = await getMembershipWitnessFor(
|
|
237
|
+
blockHash,
|
|
238
|
+
MerkleTreeId.ARCHIVE,
|
|
239
|
+
ARCHIVE_HEIGHT,
|
|
240
|
+
db,
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
return PrivateBaseRollupHints.from({
|
|
244
|
+
start,
|
|
245
|
+
startSpongeBlob: inputSpongeBlob,
|
|
246
|
+
stateDiffHints,
|
|
247
|
+
feePayerFeeJuiceBalanceReadHint: feePayerFeeJuiceBalanceReadHint,
|
|
248
|
+
archiveRootMembershipWitness,
|
|
249
|
+
constants,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
);
|
|
247
254
|
|
|
248
|
-
async function getPublicDataHint(db: MerkleTreeWriteOperations, leafSlot: bigint) {
|
|
255
|
+
export async function getPublicDataHint(db: MerkleTreeWriteOperations, leafSlot: bigint) {
|
|
249
256
|
const { index } = (await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot)) ?? {};
|
|
250
257
|
if (index === undefined) {
|
|
251
258
|
throw new Error(`Cannot find the previous value index for public data ${leafSlot}.`);
|
|
@@ -265,111 +272,126 @@ async function getPublicDataHint(db: MerkleTreeWriteOperations, leafSlot: bigint
|
|
|
265
272
|
return new PublicDataHint(new Fr(leafSlot), value, membershipWitness, leafPreimage);
|
|
266
273
|
}
|
|
267
274
|
|
|
268
|
-
export
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
: sha256Trunc(
|
|
295
|
-
Buffer.concat([previousRollupData[0].outHash.toBuffer(), previousRollupData[1].outHash.toBuffer()]),
|
|
296
|
-
);
|
|
297
|
-
const contentCommitment = new ContentCommitment(
|
|
298
|
-
new Fr(numTxs),
|
|
299
|
-
blobsHash,
|
|
300
|
-
parityPublicInputs.shaRoot.toBuffer(),
|
|
301
|
-
outHash,
|
|
302
|
-
);
|
|
275
|
+
export const buildBlobHints = runInSpan(
|
|
276
|
+
'BlockBuilderHelpers',
|
|
277
|
+
'buildBlobHints',
|
|
278
|
+
(_span: Span, txEffects: TxEffect[]) => {
|
|
279
|
+
const blobFields = txEffects.flatMap(tx => tx.toBlobFields());
|
|
280
|
+
const blobs = Blob.getBlobs(blobFields);
|
|
281
|
+
const blobCommitments = blobs.map(b => b.commitmentToFields());
|
|
282
|
+
const blobsHash = new Fr(getBlobsHashFromBlobs(blobs));
|
|
283
|
+
return { blobFields, blobCommitments, blobs, blobsHash };
|
|
284
|
+
},
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
export const buildHeaderFromCircuitOutputs = runInSpan(
|
|
288
|
+
'BlockBuilderHelpers',
|
|
289
|
+
'buildHeaderFromCircuitOutputs',
|
|
290
|
+
(
|
|
291
|
+
_span,
|
|
292
|
+
previousRollupData: BaseOrMergeRollupPublicInputs[],
|
|
293
|
+
parityPublicInputs: ParityPublicInputs,
|
|
294
|
+
rootRollupOutputs: BlockRootOrBlockMergePublicInputs,
|
|
295
|
+
endState: StateReference,
|
|
296
|
+
logger?: Logger,
|
|
297
|
+
) => {
|
|
298
|
+
if (previousRollupData.length > 2) {
|
|
299
|
+
throw new Error(`There can't be more than 2 previous rollups. Received ${previousRollupData.length}.`);
|
|
300
|
+
}
|
|
303
301
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
302
|
+
const blobsHash = rootRollupOutputs.blobPublicInputs[0].getBlobsHash();
|
|
303
|
+
const numTxs = previousRollupData.reduce((sum, d) => sum + d.numTxs, 0);
|
|
304
|
+
const outHash =
|
|
305
|
+
previousRollupData.length === 0
|
|
306
|
+
? Fr.ZERO.toBuffer()
|
|
307
|
+
: previousRollupData.length === 1
|
|
308
|
+
? previousRollupData[0].outHash.toBuffer()
|
|
309
|
+
: sha256Trunc(
|
|
310
|
+
Buffer.concat([previousRollupData[0].outHash.toBuffer(), previousRollupData[1].outHash.toBuffer()]),
|
|
311
|
+
);
|
|
312
|
+
const contentCommitment = new ContentCommitment(
|
|
313
|
+
new Fr(numTxs),
|
|
314
|
+
blobsHash,
|
|
315
|
+
parityPublicInputs.shaRoot.toBuffer(),
|
|
316
|
+
outHash,
|
|
319
317
|
);
|
|
320
|
-
throw new Error(`Block header mismatch when building from circuit outputs`);
|
|
321
|
-
}
|
|
322
|
-
return header;
|
|
323
|
-
}
|
|
324
318
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
319
|
+
const accumulatedFees = previousRollupData.reduce((sum, d) => sum.add(d.accumulatedFees), Fr.ZERO);
|
|
320
|
+
const accumulatedManaUsed = previousRollupData.reduce((sum, d) => sum.add(d.accumulatedManaUsed), Fr.ZERO);
|
|
321
|
+
const header = new BlockHeader(
|
|
322
|
+
rootRollupOutputs.previousArchive,
|
|
323
|
+
contentCommitment,
|
|
324
|
+
endState,
|
|
325
|
+
rootRollupOutputs.endGlobalVariables,
|
|
326
|
+
accumulatedFees,
|
|
327
|
+
accumulatedManaUsed,
|
|
328
|
+
);
|
|
329
|
+
if (!header.hash().equals(rootRollupOutputs.endBlockHash)) {
|
|
330
|
+
logger?.error(
|
|
331
|
+
`Block header mismatch when building header from circuit outputs.` +
|
|
332
|
+
`\n\nHeader: ${inspect(header)}` +
|
|
333
|
+
`\n\nCircuit: ${toFriendlyJSON(rootRollupOutputs)}`,
|
|
334
|
+
);
|
|
335
|
+
throw new Error(`Block header mismatch when building from circuit outputs`);
|
|
336
|
+
}
|
|
337
|
+
return header;
|
|
338
|
+
},
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
export const buildHeaderAndBodyFromTxs = runInSpan(
|
|
342
|
+
'BlockBuilderHelpers',
|
|
343
|
+
'buildHeaderAndBodyFromTxs',
|
|
344
|
+
async (
|
|
345
|
+
span,
|
|
346
|
+
txs: ProcessedTx[],
|
|
347
|
+
globalVariables: GlobalVariables,
|
|
348
|
+
l1ToL2Messages: Fr[],
|
|
349
|
+
db: MerkleTreeReadOperations,
|
|
350
|
+
) => {
|
|
351
|
+
span.setAttribute(Attributes.BLOCK_NUMBER, globalVariables.blockNumber.toNumber());
|
|
352
|
+
const stateReference = new StateReference(
|
|
353
|
+
await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db),
|
|
354
|
+
new PartialStateReference(
|
|
355
|
+
await getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE, db),
|
|
356
|
+
await getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE, db),
|
|
357
|
+
await getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE, db),
|
|
358
|
+
),
|
|
359
|
+
);
|
|
339
360
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
361
|
+
const previousArchive = await getTreeSnapshot(MerkleTreeId.ARCHIVE, db);
|
|
362
|
+
|
|
363
|
+
const txEffects = txs.map(tx => tx.txEffect);
|
|
364
|
+
const body = new Body(txEffects);
|
|
365
|
+
|
|
366
|
+
const numTxs = body.txEffects.length;
|
|
367
|
+
const outHash =
|
|
368
|
+
numTxs === 0
|
|
369
|
+
? Fr.ZERO.toBuffer()
|
|
370
|
+
: numTxs === 1
|
|
371
|
+
? body.txEffects[0].txOutHash()
|
|
372
|
+
: computeUnbalancedMerkleRoot(
|
|
373
|
+
body.txEffects.map(tx => tx.txOutHash()),
|
|
374
|
+
TxEffect.empty().txOutHash(),
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
l1ToL2Messages = padArrayEnd(l1ToL2Messages, Fr.ZERO, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP);
|
|
378
|
+
const hasher = (left: Buffer, right: Buffer) => sha256Trunc(Buffer.concat([left, right]));
|
|
379
|
+
const parityHeight = Math.ceil(Math.log2(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP));
|
|
380
|
+
const parityShaRoot = new MerkleTreeCalculator(parityHeight, Fr.ZERO.toBuffer(), hasher).computeTreeRoot(
|
|
381
|
+
l1ToL2Messages.map(msg => msg.toBuffer()),
|
|
382
|
+
);
|
|
383
|
+
const blobsHash = getBlobsHashFromBlobs(Blob.getBlobs(body.toBlobFields()));
|
|
363
384
|
|
|
364
|
-
|
|
385
|
+
const contentCommitment = new ContentCommitment(new Fr(numTxs), blobsHash, parityShaRoot, outHash);
|
|
365
386
|
|
|
366
|
-
|
|
367
|
-
|
|
387
|
+
const fees = body.txEffects.reduce((acc, tx) => acc.add(tx.transactionFee), Fr.ZERO);
|
|
388
|
+
const manaUsed = txs.reduce((acc, tx) => acc.add(new Fr(tx.gasUsed.totalGas.l2Gas)), Fr.ZERO);
|
|
368
389
|
|
|
369
|
-
|
|
390
|
+
const header = new BlockHeader(previousArchive, contentCommitment, stateReference, globalVariables, fees, manaUsed);
|
|
370
391
|
|
|
371
|
-
|
|
372
|
-
}
|
|
392
|
+
return { header, body };
|
|
393
|
+
},
|
|
394
|
+
);
|
|
373
395
|
|
|
374
396
|
export function getBlobsHashFromBlobs(inputs: Blob[]): Buffer {
|
|
375
397
|
const blobHashes = serializeToBuffer(inputs.map(b => b.getEthVersionedBlobHash()));
|
|
@@ -388,22 +410,26 @@ export async function validateBlockRootOutput(
|
|
|
388
410
|
]);
|
|
389
411
|
}
|
|
390
412
|
|
|
391
|
-
export
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
state.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
413
|
+
export const validateState = runInSpan(
|
|
414
|
+
'BlockBuilderHelpers',
|
|
415
|
+
'validateState',
|
|
416
|
+
async (_span, state: StateReference, db: MerkleTreeReadOperations) => {
|
|
417
|
+
const promises = [MerkleTreeId.NOTE_HASH_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.PUBLIC_DATA_TREE].map(
|
|
418
|
+
async (id: MerkleTreeId) => {
|
|
419
|
+
return { key: id, value: await getTreeSnapshot(id, db) };
|
|
420
|
+
},
|
|
421
|
+
);
|
|
422
|
+
const snapshots: Map<MerkleTreeId, AppendOnlyTreeSnapshot> = new Map(
|
|
423
|
+
(await Promise.all(promises)).map(obj => [obj.key, obj.value]),
|
|
424
|
+
);
|
|
425
|
+
validatePartialState(state.partial, snapshots);
|
|
426
|
+
validateSimulatedTree(
|
|
427
|
+
await getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, db),
|
|
428
|
+
state.l1ToL2MessageTree,
|
|
429
|
+
'L1ToL2MessageTree',
|
|
430
|
+
);
|
|
431
|
+
},
|
|
432
|
+
);
|
|
407
433
|
|
|
408
434
|
export async function getRootTreeSiblingPath<TID extends MerkleTreeId>(treeId: TID, db: MerkleTreeReadOperations) {
|
|
409
435
|
const { size } = await db.getTreeInfo(treeId);
|
|
@@ -411,17 +437,18 @@ export async function getRootTreeSiblingPath<TID extends MerkleTreeId>(treeId: T
|
|
|
411
437
|
return padArrayEnd(path.toFields(), Fr.ZERO, getTreeHeight(treeId));
|
|
412
438
|
}
|
|
413
439
|
|
|
414
|
-
export
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
): Promise<ConstantRollupData> {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
440
|
+
export const getConstantRollupData = runInSpan(
|
|
441
|
+
'BlockBuilderHelpers',
|
|
442
|
+
'getConstantRollupData',
|
|
443
|
+
async (_span, globalVariables: GlobalVariables, db: MerkleTreeReadOperations): Promise<ConstantRollupData> => {
|
|
444
|
+
return ConstantRollupData.from({
|
|
445
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
446
|
+
protocolContractTreeRoot,
|
|
447
|
+
lastArchive: await getTreeSnapshot(MerkleTreeId.ARCHIVE, db),
|
|
448
|
+
globalVariables,
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
);
|
|
425
452
|
|
|
426
453
|
export async function getTreeSnapshot(id: MerkleTreeId, db: MerkleTreeReadOperations): Promise<AppendOnlyTreeSnapshot> {
|
|
427
454
|
const treeInfo = await db.getTreeInfo(id);
|
|
@@ -436,42 +463,47 @@ export function makeEmptyMembershipWitness<N extends number>(height: N) {
|
|
|
436
463
|
);
|
|
437
464
|
}
|
|
438
465
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
)
|
|
466
|
+
const processPublicDataUpdateRequests = runInSpan(
|
|
467
|
+
'BlockBuilderHelpers',
|
|
468
|
+
'processPublicDataUpdateRequests',
|
|
469
|
+
async (span, tx: ProcessedTx, db: MerkleTreeWriteOperations) => {
|
|
470
|
+
span.setAttribute(Attributes.TX_HASH, tx.hash.toString());
|
|
471
|
+
const allPublicDataWrites = tx.txEffect.publicDataWrites.map(
|
|
472
|
+
({ leafSlot, value }) => new PublicDataTreeLeaf(leafSlot, value),
|
|
473
|
+
);
|
|
443
474
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
475
|
+
const { lowLeavesWitnessData, insertionWitnessData } = await db.sequentialInsert(
|
|
476
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
477
|
+
allPublicDataWrites.map(write => {
|
|
478
|
+
if (write.isEmpty()) {
|
|
479
|
+
throw new Error(`Empty public data write in tx: ${toFriendlyJSON(tx)}`);
|
|
480
|
+
}
|
|
481
|
+
return write.toBuffer();
|
|
482
|
+
}),
|
|
483
|
+
);
|
|
453
484
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
485
|
+
const lowPublicDataWritesPreimages = lowLeavesWitnessData.map(
|
|
486
|
+
lowLeafWitness => lowLeafWitness.leafPreimage as PublicDataTreeLeafPreimage,
|
|
487
|
+
);
|
|
488
|
+
const lowPublicDataWritesMembershipWitnesses = lowLeavesWitnessData.map(lowLeafWitness =>
|
|
489
|
+
MembershipWitness.fromBufferArray<typeof PUBLIC_DATA_TREE_HEIGHT>(
|
|
490
|
+
lowLeafWitness.index,
|
|
491
|
+
assertLength(lowLeafWitness.siblingPath.toBufferArray(), PUBLIC_DATA_TREE_HEIGHT),
|
|
492
|
+
),
|
|
493
|
+
);
|
|
494
|
+
const publicDataWritesSiblingPaths = insertionWitnessData.map(w => {
|
|
495
|
+
const insertionSiblingPath = w.siblingPath.toFields();
|
|
496
|
+
assertLength(insertionSiblingPath, PUBLIC_DATA_TREE_HEIGHT);
|
|
497
|
+
return insertionSiblingPath as Tuple<Fr, typeof PUBLIC_DATA_TREE_HEIGHT>;
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
return {
|
|
501
|
+
lowPublicDataWritesPreimages,
|
|
502
|
+
lowPublicDataWritesMembershipWitnesses,
|
|
503
|
+
publicDataWritesSiblingPaths,
|
|
504
|
+
};
|
|
505
|
+
},
|
|
506
|
+
);
|
|
475
507
|
|
|
476
508
|
export async function getSubtreeSiblingPath(
|
|
477
509
|
treeId: MerkleTreeId,
|