@aztec/pxe 0.24.0 → 0.26.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/config/index.js +2 -2
- package/dest/database/deferred_note_dao.d.ts +4 -4
- package/dest/database/deferred_note_dao.d.ts.map +1 -1
- package/dest/database/deferred_note_dao.js +5 -5
- package/dest/database/pxe_database_test_suite.js +4 -4
- package/dest/kernel_oracle/index.d.ts +1 -0
- package/dest/kernel_oracle/index.d.ts.map +1 -1
- package/dest/kernel_oracle/index.js +4 -1
- package/dest/kernel_prover/hints_builder.d.ts +36 -0
- package/dest/kernel_prover/hints_builder.d.ts.map +1 -0
- package/dest/kernel_prover/hints_builder.js +115 -0
- package/dest/kernel_prover/kernel_prover.d.ts +2 -24
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +26 -97
- package/dest/kernel_prover/proof_creator.d.ts +1 -1
- package/dest/kernel_prover/proof_creator.js +3 -3
- package/dest/kernel_prover/proving_data_oracle.d.ts +2 -0
- package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -1
- package/dest/note_processor/note_processor.d.ts.map +1 -1
- package/dest/note_processor/note_processor.js +14 -13
- package/dest/note_processor/produce_note_dao.d.ts +2 -2
- package/dest/note_processor/produce_note_dao.d.ts.map +1 -1
- package/dest/note_processor/produce_note_dao.js +5 -5
- package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
- package/dest/pxe_http/pxe_http_server.js +7 -6
- package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/create_pxe_service.js +3 -2
- package/dest/pxe_service/pxe_service.d.ts +5 -3
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +47 -40
- package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
- package/dest/pxe_service/test/pxe_test_suite.js +3 -3
- package/dest/simulator_oracle/index.d.ts +7 -4
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +17 -8
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +14 -42
- package/package.json +13 -13
- package/src/config/index.ts +1 -1
- package/src/database/deferred_note_dao.ts +3 -3
- package/src/database/pxe_database_test_suite.ts +3 -3
- package/src/kernel_oracle/index.ts +4 -0
- package/src/kernel_prover/hints_builder.ts +170 -0
- package/src/kernel_prover/kernel_prover.ts +56 -135
- package/src/kernel_prover/proof_creator.ts +3 -3
- package/src/kernel_prover/proving_data_oracle.ts +3 -0
- package/src/note_processor/note_processor.ts +15 -22
- package/src/note_processor/produce_note_dao.ts +4 -4
- package/src/pxe_http/pxe_http_server.ts +7 -5
- package/src/pxe_service/create_pxe_service.ts +2 -1
- package/src/pxe_service/pxe_service.ts +70 -57
- package/src/pxe_service/test/pxe_test_suite.ts +8 -6
- package/src/simulator_oracle/index.ts +19 -7
- package/src/synchronizer/synchronizer.ts +14 -56
|
@@ -2,25 +2,20 @@ import {
|
|
|
2
2
|
AztecAddress,
|
|
3
3
|
CallRequest,
|
|
4
4
|
Fr,
|
|
5
|
-
|
|
6
|
-
MAX_NEW_COMMITMENTS_PER_TX,
|
|
5
|
+
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
7
6
|
MAX_NEW_NULLIFIERS_PER_TX,
|
|
8
|
-
|
|
7
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,
|
|
9
8
|
MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,
|
|
10
9
|
MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
|
|
11
|
-
|
|
12
|
-
MAX_READ_REQUESTS_PER_TX,
|
|
13
|
-
NullifierKeyValidationRequestContext,
|
|
10
|
+
NoteHashReadRequestMembershipWitness,
|
|
14
11
|
PrivateCallData,
|
|
15
12
|
PrivateKernelInitCircuitPrivateInputs,
|
|
16
13
|
PrivateKernelInnerCircuitPrivateInputs,
|
|
17
14
|
PrivateKernelInnerCircuitPublicInputs,
|
|
18
15
|
PrivateKernelInnerData,
|
|
19
16
|
PrivateKernelTailCircuitPrivateInputs,
|
|
20
|
-
ReadRequestMembershipWitness,
|
|
21
17
|
SideEffect,
|
|
22
18
|
SideEffectLinkedToNoteHash,
|
|
23
|
-
SideEffectType,
|
|
24
19
|
TxRequest,
|
|
25
20
|
VK_TREE_HEIGHT,
|
|
26
21
|
VerificationKey,
|
|
@@ -28,10 +23,12 @@ import {
|
|
|
28
23
|
} from '@aztec/circuits.js';
|
|
29
24
|
import { makeTuple } from '@aztec/foundation/array';
|
|
30
25
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
31
|
-
import {
|
|
26
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
27
|
+
import { assertLength, mapTuple } from '@aztec/foundation/serialize';
|
|
32
28
|
import { pushTestData } from '@aztec/foundation/testing';
|
|
33
29
|
import { ExecutionResult, NoteAndSlot } from '@aztec/simulator';
|
|
34
30
|
|
|
31
|
+
import { HintsBuilder } from './hints_builder.js';
|
|
35
32
|
import { KernelProofCreator, ProofCreator, ProofOutput, ProofOutputFinal } from './proof_creator.js';
|
|
36
33
|
import { ProvingDataOracle } from './proving_data_oracle.js';
|
|
37
34
|
|
|
@@ -73,7 +70,12 @@ export interface KernelProverOutput extends ProofOutputFinal {
|
|
|
73
70
|
* constructs private call data based on the execution results.
|
|
74
71
|
*/
|
|
75
72
|
export class KernelProver {
|
|
76
|
-
|
|
73
|
+
private log = createDebugLogger('aztec:kernel-prover');
|
|
74
|
+
private hintsBuilder: HintsBuilder;
|
|
75
|
+
|
|
76
|
+
constructor(private oracle: ProvingDataOracle, private proofCreator: ProofCreator = new KernelProofCreator()) {
|
|
77
|
+
this.hintsBuilder = new HintsBuilder(oracle);
|
|
78
|
+
}
|
|
77
79
|
|
|
78
80
|
/**
|
|
79
81
|
* Generate a proof for a given transaction request and execution result.
|
|
@@ -100,13 +102,15 @@ export class KernelProver {
|
|
|
100
102
|
const currentExecution = executionStack.pop()!;
|
|
101
103
|
executionStack.push(...currentExecution.nestedExecutions);
|
|
102
104
|
|
|
103
|
-
const privateCallRequests = currentExecution.nestedExecutions.map(result =>
|
|
105
|
+
const privateCallRequests = currentExecution.nestedExecutions.map(result =>
|
|
106
|
+
result.callStackItem.toCallRequest(currentExecution.callStackItem.publicInputs.callContext),
|
|
107
|
+
);
|
|
104
108
|
const publicCallRequests = currentExecution.enqueuedPublicFunctionCalls.map(result => result.toCallRequest());
|
|
105
109
|
|
|
106
110
|
// Start with the partially filled in read request witnesses from the simulator
|
|
107
111
|
// and fill the non-transient ones in with sibling paths via oracle.
|
|
108
|
-
const
|
|
109
|
-
for (let rr = 0; rr <
|
|
112
|
+
const noteHashReadRequestMembershipWitnesses = currentExecution.noteHashReadRequestPartialWitnesses;
|
|
113
|
+
for (let rr = 0; rr < noteHashReadRequestMembershipWitnesses.length; rr++) {
|
|
110
114
|
// Pretty sure this check was forever broken. I made some changes to Fr and this started triggering.
|
|
111
115
|
// The conditional makes no sense to me anyway.
|
|
112
116
|
// if (currentExecution.callStackItem.publicInputs.readRequests[rr] == Fr.ZERO) {
|
|
@@ -114,7 +118,7 @@ export class KernelProver {
|
|
|
114
118
|
// 'Number of read requests output from Noir circuit does not match number of read request commitment indices output from simulator.',
|
|
115
119
|
// );
|
|
116
120
|
// }
|
|
117
|
-
const rrWitness =
|
|
121
|
+
const rrWitness = noteHashReadRequestMembershipWitnesses[rr];
|
|
118
122
|
if (!rrWitness.isTransient) {
|
|
119
123
|
// Non-transient reads must contain full membership witness with sibling path from commitment to root.
|
|
120
124
|
// Get regular membership witness to fill in sibling path in the read request witness.
|
|
@@ -124,17 +128,17 @@ export class KernelProver {
|
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
// fill in witnesses for remaining/empty read requests
|
|
127
|
-
|
|
128
|
-
...Array(
|
|
131
|
+
noteHashReadRequestMembershipWitnesses.push(
|
|
132
|
+
...Array(MAX_NOTE_HASH_READ_REQUESTS_PER_CALL - noteHashReadRequestMembershipWitnesses.length)
|
|
129
133
|
.fill(0)
|
|
130
|
-
.map(() =>
|
|
134
|
+
.map(() => NoteHashReadRequestMembershipWitness.empty(BigInt(0))),
|
|
131
135
|
);
|
|
132
136
|
|
|
133
137
|
const privateCallData = await this.createPrivateCallData(
|
|
134
138
|
currentExecution,
|
|
135
139
|
privateCallRequests,
|
|
136
140
|
publicCallRequests,
|
|
137
|
-
|
|
141
|
+
noteHashReadRequestMembershipWitnesses,
|
|
138
142
|
);
|
|
139
143
|
|
|
140
144
|
if (firstIteration) {
|
|
@@ -170,73 +174,65 @@ export class KernelProver {
|
|
|
170
174
|
assertLength<Fr, typeof VK_TREE_HEIGHT>(previousVkMembershipWitness.siblingPath, VK_TREE_HEIGHT),
|
|
171
175
|
);
|
|
172
176
|
|
|
173
|
-
const [
|
|
177
|
+
const [sortedNoteHashes, sortedNoteHashesIndexes] = this.hintsBuilder.sortSideEffects<
|
|
174
178
|
SideEffect,
|
|
175
|
-
typeof
|
|
176
|
-
>(output.publicInputs.end.
|
|
179
|
+
typeof MAX_NEW_NOTE_HASHES_PER_TX
|
|
180
|
+
>(output.publicInputs.end.newNoteHashes);
|
|
177
181
|
|
|
178
|
-
const [sortedNullifiers, sortedNullifiersIndexes] = this.sortSideEffects<
|
|
182
|
+
const [sortedNullifiers, sortedNullifiersIndexes] = this.hintsBuilder.sortSideEffects<
|
|
179
183
|
SideEffectLinkedToNoteHash,
|
|
180
184
|
typeof MAX_NEW_NULLIFIERS_PER_TX
|
|
181
185
|
>(output.publicInputs.end.newNullifiers);
|
|
182
186
|
|
|
183
|
-
const
|
|
187
|
+
const readNoteHashHints = this.hintsBuilder.getNoteHashReadRequestHints(
|
|
188
|
+
output.publicInputs.end.noteHashReadRequests,
|
|
189
|
+
sortedNoteHashes,
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const nullifierReadRequestResetHints = await this.hintsBuilder.getNullifierReadRequestResetHints(
|
|
193
|
+
output.publicInputs.end.nullifierReadRequests,
|
|
194
|
+
output.publicInputs.end.newNullifiers,
|
|
195
|
+
);
|
|
184
196
|
|
|
185
|
-
const
|
|
197
|
+
const nullifierNoteHashHints = this.hintsBuilder.getNullifierHints(
|
|
186
198
|
mapTuple(sortedNullifiers, n => n.noteHash),
|
|
187
|
-
|
|
199
|
+
sortedNoteHashes,
|
|
188
200
|
);
|
|
189
201
|
|
|
190
|
-
const masterNullifierSecretKeys = await this.getMasterNullifierSecretKeys(
|
|
202
|
+
const masterNullifierSecretKeys = await this.hintsBuilder.getMasterNullifierSecretKeys(
|
|
191
203
|
output.publicInputs.end.nullifierKeyValidationRequests,
|
|
192
204
|
);
|
|
193
205
|
|
|
206
|
+
this.log.debug(
|
|
207
|
+
`Calling private kernel tail with hwm ${previousKernelData.publicInputs.minRevertibleSideEffectCounter}`,
|
|
208
|
+
);
|
|
209
|
+
|
|
194
210
|
const privateInputs = new PrivateKernelTailCircuitPrivateInputs(
|
|
195
211
|
previousKernelData,
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
212
|
+
sortedNoteHashes,
|
|
213
|
+
sortedNoteHashesIndexes,
|
|
214
|
+
readNoteHashHints,
|
|
199
215
|
sortedNullifiers,
|
|
200
216
|
sortedNullifiersIndexes,
|
|
201
|
-
|
|
217
|
+
nullifierReadRequestResetHints,
|
|
218
|
+
nullifierNoteHashHints,
|
|
202
219
|
masterNullifierSecretKeys,
|
|
203
220
|
);
|
|
204
221
|
pushTestData('private-kernel-inputs-ordering', privateInputs);
|
|
205
222
|
const outputFinal = await this.proofCreator.createProofTail(privateInputs);
|
|
206
223
|
|
|
207
224
|
// Only return the notes whose commitment is in the commitments of the final proof.
|
|
208
|
-
const finalNewCommitments = outputFinal.publicInputs.end.
|
|
225
|
+
const finalNewCommitments = outputFinal.publicInputs.end.newNoteHashes;
|
|
209
226
|
const outputNotes = finalNewCommitments.map(c => newNotes[c.value.toString()]).filter(c => !!c);
|
|
210
227
|
|
|
211
228
|
return { ...outputFinal, outputNotes };
|
|
212
229
|
}
|
|
213
230
|
|
|
214
|
-
private sortSideEffects<T extends SideEffectType, K extends number>(
|
|
215
|
-
sideEffects: Tuple<T, K>,
|
|
216
|
-
): [Tuple<T, K>, Tuple<number, K>] {
|
|
217
|
-
const sorted = sideEffects
|
|
218
|
-
.map((sideEffect, index) => ({ sideEffect, index }))
|
|
219
|
-
.sort((a, b) => {
|
|
220
|
-
// Empty ones go to the right
|
|
221
|
-
if (a.sideEffect.isEmpty()) {
|
|
222
|
-
return 1;
|
|
223
|
-
}
|
|
224
|
-
return Number(a.sideEffect.counter.toBigInt() - b.sideEffect.counter.toBigInt());
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
const originalToSorted = sorted.map(() => 0);
|
|
228
|
-
sorted.forEach(({ index }, i) => {
|
|
229
|
-
originalToSorted[index] = i;
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
return [sorted.map(({ sideEffect }) => sideEffect) as Tuple<T, K>, originalToSorted as Tuple<number, K>];
|
|
233
|
-
}
|
|
234
|
-
|
|
235
231
|
private async createPrivateCallData(
|
|
236
232
|
{ callStackItem, vk }: ExecutionResult,
|
|
237
233
|
privateCallRequests: CallRequest[],
|
|
238
234
|
publicCallRequests: CallRequest[],
|
|
239
|
-
|
|
235
|
+
noteHashReadRequestMembershipWitnesses: NoteHashReadRequestMembershipWitness[],
|
|
240
236
|
) {
|
|
241
237
|
const { contractAddress, functionData, publicInputs } = callStackItem;
|
|
242
238
|
const { portalContractAddress } = publicInputs.callContext;
|
|
@@ -277,7 +273,11 @@ export class KernelProver {
|
|
|
277
273
|
contractClassPublicBytecodeCommitment,
|
|
278
274
|
saltedInitializationHash,
|
|
279
275
|
functionLeafMembershipWitness,
|
|
280
|
-
|
|
276
|
+
noteHashReadRequestMembershipWitnesses: makeTuple(
|
|
277
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,
|
|
278
|
+
i => noteHashReadRequestMembershipWitnesses[i],
|
|
279
|
+
0,
|
|
280
|
+
),
|
|
281
281
|
portalContractAddress: portalContractAddress.toField(),
|
|
282
282
|
acirHash,
|
|
283
283
|
});
|
|
@@ -299,90 +299,11 @@ export class KernelProver {
|
|
|
299
299
|
} = executionResult;
|
|
300
300
|
const contractAddress = publicInputs.callContext.storageContractAddress;
|
|
301
301
|
// Assuming that for each new commitment there's an output note added to the execution result.
|
|
302
|
-
const
|
|
302
|
+
const newNoteHashes = await this.proofCreator.getSiloedCommitments(publicInputs);
|
|
303
303
|
return newNotes.map((data, i) => ({
|
|
304
304
|
contractAddress,
|
|
305
305
|
data,
|
|
306
|
-
commitment:
|
|
306
|
+
commitment: newNoteHashes[i],
|
|
307
307
|
}));
|
|
308
308
|
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Performs the matching between an array of read request and an array of commitments. This produces
|
|
312
|
-
* hints for the private kernel ordering circuit to efficiently match a read request with the corresponding
|
|
313
|
-
* commitment.
|
|
314
|
-
*
|
|
315
|
-
* @param readRequests - The array of read requests.
|
|
316
|
-
* @param commitments - The array of commitments.
|
|
317
|
-
* @returns An array of hints where each element is the index of the commitment in commitments array
|
|
318
|
-
* corresponding to the read request. In other words we have readRequests[i] == commitments[hints[i]].
|
|
319
|
-
*/
|
|
320
|
-
private getReadRequestHints(
|
|
321
|
-
readRequests: Tuple<SideEffect, typeof MAX_READ_REQUESTS_PER_TX>,
|
|
322
|
-
commitments: Tuple<SideEffect, typeof MAX_NEW_COMMITMENTS_PER_TX>,
|
|
323
|
-
): Tuple<Fr, typeof MAX_READ_REQUESTS_PER_TX> {
|
|
324
|
-
const hints = makeTuple(MAX_READ_REQUESTS_PER_TX, Fr.zero);
|
|
325
|
-
for (let i = 0; i < MAX_READ_REQUESTS_PER_TX && !readRequests[i].isEmpty(); i++) {
|
|
326
|
-
const equalToRR = (cmt: SideEffect) => cmt.value.equals(readRequests[i].value);
|
|
327
|
-
const result = commitments.findIndex(equalToRR);
|
|
328
|
-
if (result == -1) {
|
|
329
|
-
throw new Error(
|
|
330
|
-
`The read request at index ${i} with value ${readRequests[i].toString()} does not match to any commitment.`,
|
|
331
|
-
);
|
|
332
|
-
} else {
|
|
333
|
-
hints[i] = new Fr(result);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
return hints;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Performs the matching between an array of nullified commitments and an array of commitments. This produces
|
|
341
|
-
* hints for the private kernel ordering circuit to efficiently match a nullifier with the corresponding
|
|
342
|
-
* commitment.
|
|
343
|
-
*
|
|
344
|
-
* @param nullifiedCommitments - The array of nullified commitments.
|
|
345
|
-
* @param commitments - The array of commitments.
|
|
346
|
-
* @returns An array of hints where each element is the index of the commitment in commitments array
|
|
347
|
-
* corresponding to the nullified commitments. In other words we have nullifiedCommitments[i] == commitments[hints[i]].
|
|
348
|
-
*/
|
|
349
|
-
private getNullifierHints(
|
|
350
|
-
nullifiedCommitments: Tuple<Fr, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
351
|
-
commitments: Tuple<SideEffect, typeof MAX_NEW_COMMITMENTS_PER_TX>,
|
|
352
|
-
): Tuple<Fr, typeof MAX_NEW_NULLIFIERS_PER_TX> {
|
|
353
|
-
const hints = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, Fr.zero);
|
|
354
|
-
for (let i = 0; i < MAX_NEW_NULLIFIERS_PER_TX; i++) {
|
|
355
|
-
if (!nullifiedCommitments[i].isZero()) {
|
|
356
|
-
const equalToCommitment = (cmt: SideEffect) => cmt.value.equals(nullifiedCommitments[i]);
|
|
357
|
-
const result = commitments.findIndex(equalToCommitment);
|
|
358
|
-
if (result == -1) {
|
|
359
|
-
throw new Error(
|
|
360
|
-
`The nullified commitment at index ${i} with value ${nullifiedCommitments[
|
|
361
|
-
i
|
|
362
|
-
].toString()} does not match to any commitment.`,
|
|
363
|
-
);
|
|
364
|
-
} else {
|
|
365
|
-
hints[i] = new Fr(result);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
return hints;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
private async getMasterNullifierSecretKeys(
|
|
373
|
-
nullifierKeyValidationRequests: Tuple<
|
|
374
|
-
NullifierKeyValidationRequestContext,
|
|
375
|
-
typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX
|
|
376
|
-
>,
|
|
377
|
-
) {
|
|
378
|
-
const keys = makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, GrumpkinScalar.zero);
|
|
379
|
-
for (let i = 0; i < nullifierKeyValidationRequests.length; ++i) {
|
|
380
|
-
const request = nullifierKeyValidationRequests[i];
|
|
381
|
-
if (request.isEmpty()) {
|
|
382
|
-
break;
|
|
383
|
-
}
|
|
384
|
-
keys[i] = await this.oracle.getMasterNullifierSecretKey(request.publicKey);
|
|
385
|
-
}
|
|
386
|
-
return keys;
|
|
387
|
-
}
|
|
388
309
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
Proof,
|
|
10
10
|
makeEmptyProof,
|
|
11
11
|
} from '@aztec/circuits.js';
|
|
12
|
-
import {
|
|
12
|
+
import { siloNoteHash } from '@aztec/circuits.js/hash';
|
|
13
13
|
import { Fr } from '@aztec/foundation/fields';
|
|
14
14
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
15
15
|
import { elapsed } from '@aztec/foundation/timer';
|
|
@@ -53,7 +53,7 @@ export interface ProofCreator {
|
|
|
53
53
|
/**
|
|
54
54
|
* Computes the siloed commitments for a given set of public inputs.
|
|
55
55
|
*
|
|
56
|
-
* @param publicInputs - The public inputs containing the contract address and new
|
|
56
|
+
* @param publicInputs - The public inputs containing the contract address and new note hashes to be used in generating siloed note hashes.
|
|
57
57
|
* @returns An array of Fr (finite field) elements representing the siloed commitments.
|
|
58
58
|
*/
|
|
59
59
|
getSiloedCommitments(publicInputs: PrivateCircuitPublicInputs): Promise<Fr[]>;
|
|
@@ -97,7 +97,7 @@ export class KernelProofCreator implements ProofCreator {
|
|
|
97
97
|
const contractAddress = publicInputs.callContext.storageContractAddress;
|
|
98
98
|
|
|
99
99
|
return Promise.resolve(
|
|
100
|
-
publicInputs.
|
|
100
|
+
publicInputs.newNoteHashes.map(commitment => siloNoteHash(contractAddress, commitment.value)),
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NullifierMembershipWitness } from '@aztec/circuit-types';
|
|
1
2
|
import {
|
|
2
3
|
FUNCTION_TREE_HEIGHT,
|
|
3
4
|
Fr,
|
|
@@ -59,6 +60,8 @@ export interface ProvingDataOracle {
|
|
|
59
60
|
*/
|
|
60
61
|
getNoteMembershipWitness(leafIndex: bigint): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT>>;
|
|
61
62
|
|
|
63
|
+
getNullifierMembershipWitness(blockNumber: number, nullifier: Fr): Promise<NullifierMembershipWitness | undefined>;
|
|
64
|
+
|
|
62
65
|
/**
|
|
63
66
|
* Get the root of the note hash tree.
|
|
64
67
|
*
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AztecNode,
|
|
3
|
-
INITIAL_L2_BLOCK_NUM,
|
|
4
|
-
KeyStore,
|
|
5
|
-
L1NotePayload,
|
|
6
|
-
L2BlockContext,
|
|
7
|
-
L2BlockL2Logs,
|
|
8
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { AztecNode, KeyStore, L1NotePayload, L2BlockContext, L2BlockL2Logs, TaggedNote } from '@aztec/circuit-types';
|
|
9
2
|
import { NoteProcessorStats } from '@aztec/circuit-types/stats';
|
|
10
|
-
import {
|
|
3
|
+
import { INITIAL_L2_BLOCK_NUM, MAX_NEW_NOTE_HASHES_PER_TX, PublicKey } from '@aztec/circuits.js';
|
|
11
4
|
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
|
|
12
5
|
import { Fr } from '@aztec/foundation/fields';
|
|
13
6
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
@@ -123,20 +116,18 @@ export class NoteProcessor {
|
|
|
123
116
|
for (let indexOfTxInABlock = 0; indexOfTxInABlock < txLogs.length; ++indexOfTxInABlock) {
|
|
124
117
|
this.stats.txs++;
|
|
125
118
|
const dataStartIndexForTx =
|
|
126
|
-
dataEndIndexForBlock - (txLogs.length - indexOfTxInABlock) *
|
|
127
|
-
const
|
|
128
|
-
indexOfTxInABlock * MAX_NEW_COMMITMENTS_PER_TX,
|
|
129
|
-
(indexOfTxInABlock + 1) * MAX_NEW_COMMITMENTS_PER_TX,
|
|
130
|
-
);
|
|
119
|
+
dataEndIndexForBlock - (txLogs.length - indexOfTxInABlock) * MAX_NEW_NOTE_HASHES_PER_TX;
|
|
120
|
+
const newNoteHashes = block.body.txEffects[indexOfTxInABlock].noteHashes;
|
|
131
121
|
// Note: Each tx generates a `TxL2Logs` object and for this reason we can rely on its index corresponding
|
|
132
122
|
// to the index of a tx in a block.
|
|
133
123
|
const txFunctionLogs = txLogs[indexOfTxInABlock].functionLogs;
|
|
134
124
|
const excludedIndices: Set<number> = new Set();
|
|
135
125
|
for (const functionLogs of txFunctionLogs) {
|
|
136
|
-
for (const
|
|
126
|
+
for (const log of functionLogs.logs) {
|
|
137
127
|
this.stats.seen++;
|
|
138
|
-
const
|
|
139
|
-
if (
|
|
128
|
+
const taggedNote = TaggedNote.fromEncryptedBuffer(log, privateKey, curve);
|
|
129
|
+
if (taggedNote?.notePayload) {
|
|
130
|
+
const { notePayload: payload } = taggedNote;
|
|
140
131
|
// We have successfully decrypted the data.
|
|
141
132
|
const txHash = blockContext.getTxHash(indexOfTxInABlock);
|
|
142
133
|
try {
|
|
@@ -145,7 +136,7 @@ export class NoteProcessor {
|
|
|
145
136
|
this.publicKey,
|
|
146
137
|
payload,
|
|
147
138
|
txHash,
|
|
148
|
-
|
|
139
|
+
newNoteHashes,
|
|
149
140
|
dataStartIndexForTx,
|
|
150
141
|
excludedIndices,
|
|
151
142
|
);
|
|
@@ -162,7 +153,7 @@ export class NoteProcessor {
|
|
|
162
153
|
payload.storageSlot,
|
|
163
154
|
payload.noteTypeId,
|
|
164
155
|
txHash,
|
|
165
|
-
|
|
156
|
+
newNoteHashes,
|
|
166
157
|
dataStartIndexForTx,
|
|
167
158
|
);
|
|
168
159
|
deferredNoteDaos.push(deferredNoteDao);
|
|
@@ -213,7 +204,9 @@ export class NoteProcessor {
|
|
|
213
204
|
});
|
|
214
205
|
}
|
|
215
206
|
|
|
216
|
-
const newNullifiers: Fr[] = blocksAndNotes.flatMap(b =>
|
|
207
|
+
const newNullifiers: Fr[] = blocksAndNotes.flatMap(b =>
|
|
208
|
+
b.blockContext.block.body.txEffects.flatMap(txEffect => txEffect.nullifiers),
|
|
209
|
+
);
|
|
217
210
|
const removedNotes = await this.db.removeNullifiedNotes(newNullifiers, this.publicKey);
|
|
218
211
|
removedNotes.forEach(noteDao => {
|
|
219
212
|
this.log(
|
|
@@ -255,7 +248,7 @@ export class NoteProcessor {
|
|
|
255
248
|
const excludedIndices: Set<number> = new Set();
|
|
256
249
|
const noteDaos: NoteDao[] = [];
|
|
257
250
|
for (const deferredNote of deferredNoteDaos) {
|
|
258
|
-
const { note, contractAddress, storageSlot, noteTypeId, txHash,
|
|
251
|
+
const { note, contractAddress, storageSlot, noteTypeId, txHash, newNoteHashes, dataStartIndexForTx } =
|
|
259
252
|
deferredNote;
|
|
260
253
|
const payload = new L1NotePayload(note, contractAddress, storageSlot, noteTypeId);
|
|
261
254
|
|
|
@@ -265,7 +258,7 @@ export class NoteProcessor {
|
|
|
265
258
|
this.publicKey,
|
|
266
259
|
payload,
|
|
267
260
|
txHash,
|
|
268
|
-
|
|
261
|
+
newNoteHashes,
|
|
269
262
|
dataStartIndexForTx,
|
|
270
263
|
excludedIndices,
|
|
271
264
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { L1NotePayload, TxHash } from '@aztec/circuit-types';
|
|
2
2
|
import { Fr, PublicKey } from '@aztec/circuits.js';
|
|
3
|
-
import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/
|
|
3
|
+
import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash';
|
|
4
4
|
import { AcirSimulator } from '@aztec/simulator';
|
|
5
5
|
|
|
6
6
|
import { NoteDao } from '../database/note_dao.js';
|
|
@@ -14,7 +14,7 @@ import { NoteDao } from '../database/note_dao.js';
|
|
|
14
14
|
* @param publicKey - The public counterpart to the private key to be used in note decryption.
|
|
15
15
|
* @param payload - An instance of l1NotePayload.
|
|
16
16
|
* @param txHash - The hash of the transaction that created the note. Equivalent to the first nullifier of the transaction.
|
|
17
|
-
* @param
|
|
17
|
+
* @param newNoteHashes - New note hashes in this transaction, one of which belongs to this note.
|
|
18
18
|
* @param dataStartIndexForTx - The next available leaf index for the note hash tree for this transaction.
|
|
19
19
|
* @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same l1NotePayload, we need to find a different index for each replicate.
|
|
20
20
|
* @param simulator - An instance of AcirSimulator.
|
|
@@ -25,13 +25,13 @@ export async function produceNoteDao(
|
|
|
25
25
|
publicKey: PublicKey,
|
|
26
26
|
payload: L1NotePayload,
|
|
27
27
|
txHash: TxHash,
|
|
28
|
-
|
|
28
|
+
newNoteHashes: Fr[],
|
|
29
29
|
dataStartIndexForTx: number,
|
|
30
30
|
excludedIndices: Set<number>,
|
|
31
31
|
): Promise<NoteDao> {
|
|
32
32
|
const { commitmentIndex, nonce, innerNoteHash, siloedNullifier } = await findNoteIndexAndNullifier(
|
|
33
33
|
simulator,
|
|
34
|
-
|
|
34
|
+
newNoteHashes,
|
|
35
35
|
txHash,
|
|
36
36
|
payload,
|
|
37
37
|
excludedIndices,
|
|
@@ -7,11 +7,12 @@ import {
|
|
|
7
7
|
ExtendedUnencryptedL2Log,
|
|
8
8
|
L2Block,
|
|
9
9
|
L2BlockL2Logs,
|
|
10
|
-
L2Tx,
|
|
11
10
|
LogId,
|
|
12
11
|
Note,
|
|
12
|
+
NullifierMembershipWitness,
|
|
13
13
|
PXE,
|
|
14
14
|
Tx,
|
|
15
|
+
TxEffect,
|
|
15
16
|
TxExecutionRequest,
|
|
16
17
|
TxHash,
|
|
17
18
|
TxReceipt,
|
|
@@ -20,7 +21,7 @@ import { FunctionSelector } from '@aztec/circuits.js';
|
|
|
20
21
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
21
22
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
22
23
|
import { Fr, GrumpkinScalar, Point } from '@aztec/foundation/fields';
|
|
23
|
-
import { JsonRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
24
|
+
import { JsonRpcServer, createNamespacedJsonRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
24
25
|
|
|
25
26
|
import http from 'http';
|
|
26
27
|
|
|
@@ -48,10 +49,10 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer {
|
|
|
48
49
|
ExtendedNote,
|
|
49
50
|
AuthWitness,
|
|
50
51
|
L2Block,
|
|
51
|
-
|
|
52
|
+
TxEffect,
|
|
52
53
|
LogId,
|
|
53
54
|
},
|
|
54
|
-
{ Tx, TxReceipt, L2BlockL2Logs },
|
|
55
|
+
{ Tx, TxReceipt, L2BlockL2Logs, NullifierMembershipWitness },
|
|
55
56
|
['start', 'stop'],
|
|
56
57
|
);
|
|
57
58
|
}
|
|
@@ -63,7 +64,8 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer {
|
|
|
63
64
|
* @returns A running http server.
|
|
64
65
|
*/
|
|
65
66
|
export function startPXEHttpServer(pxeService: PXE, port: string | number): http.Server {
|
|
66
|
-
const
|
|
67
|
+
const pxeServer = createPXERpcServer(pxeService);
|
|
68
|
+
const rpcServer = createNamespacedJsonRpcServer([{ pxe: pxeServer }]);
|
|
67
69
|
|
|
68
70
|
const app = rpcServer.getApp();
|
|
69
71
|
const httpServer = http.createServer(app.callback());
|
|
@@ -4,6 +4,7 @@ import { TestKeyStore } from '@aztec/key-store';
|
|
|
4
4
|
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
|
|
5
5
|
import { initStoreForRollup } from '@aztec/kv-store/utils';
|
|
6
6
|
import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer';
|
|
7
|
+
import { getCanonicalGasToken } from '@aztec/protocol-contracts/gas-token';
|
|
7
8
|
import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer';
|
|
8
9
|
|
|
9
10
|
import { join } from 'path';
|
|
@@ -45,7 +46,7 @@ export async function createPXEService(
|
|
|
45
46
|
const db = new KVPxeDatabase(await initStoreForRollup(AztecLmdbStore.open(pxeDbPath), l1Contracts.rollupAddress));
|
|
46
47
|
|
|
47
48
|
const server = new PXEService(keyStore, aztecNode, db, config, logSuffix);
|
|
48
|
-
await server.addContracts([getCanonicalClassRegisterer(), getCanonicalInstanceDeployer()]);
|
|
49
|
+
await server.addContracts([getCanonicalClassRegisterer(), getCanonicalInstanceDeployer(), getCanonicalGasToken()]);
|
|
49
50
|
|
|
50
51
|
await server.start();
|
|
51
52
|
return server;
|