@aztec/pxe 0.40.1 → 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.
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +5 -2
- package/dest/contract_data_oracle/index.d.ts +1 -0
- package/dest/contract_data_oracle/index.d.ts.map +1 -1
- package/dest/contract_data_oracle/index.js +7 -1
- package/dest/contract_data_oracle/private_functions_tree.d.ts.map +1 -1
- package/dest/contract_data_oracle/private_functions_tree.js +2 -2
- package/dest/database/kv_pxe_database.d.ts +1 -1
- package/dest/database/kv_pxe_database.js +2 -2
- package/dest/database/pxe_database.d.ts +5 -5
- package/dest/kernel_oracle/index.d.ts +7 -4
- package/dest/kernel_oracle/index.d.ts.map +1 -1
- package/dest/kernel_oracle/index.js +9 -4
- package/dest/kernel_prover/kernel_prover.d.ts +3 -0
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +51 -15
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.d.ts +3 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.d.ts.map +1 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.js +11 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.d.ts +5 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.d.ts.map +1 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.js +79 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.d.ts +4 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.d.ts.map +1 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.js +14 -0
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.d.ts +1 -2
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.d.ts.map +1 -1
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.js +11 -53
- package/dest/kernel_prover/private_inputs_builders/index.d.ts +3 -1
- package/dest/kernel_prover/private_inputs_builders/index.d.ts.map +1 -1
- package/dest/kernel_prover/private_inputs_builders/index.js +4 -2
- package/dest/kernel_prover/proving_data_oracle.d.ts +7 -5
- package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -1
- package/dest/kernel_prover/test/test_circuit_prover.d.ts +2 -1
- package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/kernel_prover/test/test_circuit_prover.js +14 -3
- package/dest/note_processor/note_processor.d.ts +3 -2
- package/dest/note_processor/note_processor.d.ts.map +1 -1
- package/dest/note_processor/note_processor.js +3 -2
- package/dest/note_processor/produce_note_dao.js +4 -20
- package/dest/pxe_http/pxe_http_server.js +3 -3
- package/dest/pxe_service/create_pxe_service.d.ts +1 -1
- package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/create_pxe_service.js +7 -6
- package/dest/pxe_service/pxe_service.d.ts +10 -6
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +45 -73
- package/dest/pxe_service/test/pxe_test_suite.d.ts.map +1 -1
- package/dest/pxe_service/test/pxe_test_suite.js +4 -17
- package/dest/simulator/index.d.ts +2 -1
- package/dest/simulator/index.d.ts.map +1 -1
- package/dest/simulator/index.js +1 -1
- package/dest/simulator_oracle/index.d.ts +7 -5
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +10 -8
- package/dest/synchronizer/synchronizer.d.ts +9 -1
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +16 -8
- package/package.json +14 -14
- package/src/config/index.ts +11 -1
- package/src/contract_data_oracle/index.ts +7 -0
- package/src/contract_data_oracle/private_functions_tree.ts +3 -1
- package/src/database/kv_pxe_database.ts +2 -2
- package/src/database/pxe_database.ts +5 -5
- package/src/kernel_oracle/index.ts +16 -4
- package/src/kernel_prover/kernel_prover.ts +93 -24
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_init_hints.ts +28 -0
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.ts +250 -0
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_reset_outputs.ts +45 -0
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_tail_hints.ts +29 -126
- package/src/kernel_prover/private_inputs_builders/index.ts +3 -1
- package/src/kernel_prover/proving_data_oracle.ts +8 -5
- package/src/kernel_prover/test/test_circuit_prover.ts +24 -3
- package/src/note_processor/note_processor.ts +5 -4
- package/src/note_processor/produce_note_dao.ts +3 -19
- package/src/pxe_http/pxe_http_server.ts +2 -2
- package/src/pxe_service/create_pxe_service.ts +10 -7
- package/src/pxe_service/pxe_service.ts +55 -120
- package/src/pxe_service/test/pxe_test_suite.ts +1 -21
- package/src/simulator/index.ts +2 -1
- package/src/simulator_oracle/index.ts +13 -9
- package/src/synchronizer/synchronizer.ts +17 -14
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.d.ts +0 -4
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.d.ts.map +0 -1
- package/dest/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.js +0 -10
- package/src/kernel_prover/private_inputs_builders/build_private_kernel_tail_outputs.ts +0 -30
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Fr,
|
|
3
|
+
KeyValidationHint,
|
|
4
|
+
MAX_KEY_VALIDATION_REQUESTS_PER_TX,
|
|
5
|
+
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
6
|
+
MAX_NEW_NULLIFIERS_PER_TX,
|
|
7
|
+
MAX_NOTE_ENCRYPTED_LOGS_PER_TX,
|
|
8
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
9
|
+
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
10
|
+
MembershipWitness,
|
|
11
|
+
NULLIFIER_TREE_HEIGHT,
|
|
12
|
+
PRIVATE_RESET_VARIANTS,
|
|
13
|
+
type PrivateKernelData,
|
|
14
|
+
PrivateKernelResetCircuitPrivateInputs,
|
|
15
|
+
type PrivateKernelResetCircuitPrivateInputsVariants,
|
|
16
|
+
PrivateKernelResetHints,
|
|
17
|
+
type ReadRequest,
|
|
18
|
+
type ScopedKeyValidationRequestAndGenerator,
|
|
19
|
+
ScopedNoteHash,
|
|
20
|
+
ScopedNullifier,
|
|
21
|
+
ScopedReadRequest,
|
|
22
|
+
buildNoteHashReadRequestHints,
|
|
23
|
+
buildNullifierReadRequestHints,
|
|
24
|
+
buildTransientDataHints,
|
|
25
|
+
getNonEmptyItems,
|
|
26
|
+
} from '@aztec/circuits.js';
|
|
27
|
+
import { makeTuple } from '@aztec/foundation/array';
|
|
28
|
+
import { type Tuple } from '@aztec/foundation/serialize';
|
|
29
|
+
import type { ExecutionResult } from '@aztec/simulator';
|
|
30
|
+
|
|
31
|
+
import { type ProvingDataOracle } from '../proving_data_oracle.js';
|
|
32
|
+
import { buildPrivateKernelResetOutputs } from './build_private_kernel_reset_outputs.js';
|
|
33
|
+
|
|
34
|
+
function getNullifierReadRequestHints<PENDING extends number, SETTLED extends number>(
|
|
35
|
+
nullifierReadRequests: Tuple<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
|
|
36
|
+
nullifiers: Tuple<ScopedNullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
37
|
+
oracle: ProvingDataOracle,
|
|
38
|
+
sizePending: PENDING,
|
|
39
|
+
sizeSettled: SETTLED,
|
|
40
|
+
futureNullifiers: ScopedNullifier[],
|
|
41
|
+
) {
|
|
42
|
+
const getNullifierMembershipWitness = async (nullifier: Fr) => {
|
|
43
|
+
const res = await oracle.getNullifierMembershipWitness(nullifier);
|
|
44
|
+
if (!res) {
|
|
45
|
+
throw new Error(`Cannot find the leaf for nullifier ${nullifier.toBigInt()}.`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { index, siblingPath, leafPreimage } = res;
|
|
49
|
+
return {
|
|
50
|
+
membershipWitness: new MembershipWitness(
|
|
51
|
+
NULLIFIER_TREE_HEIGHT,
|
|
52
|
+
index,
|
|
53
|
+
siblingPath.toTuple<typeof NULLIFIER_TREE_HEIGHT>(),
|
|
54
|
+
),
|
|
55
|
+
leafPreimage,
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return buildNullifierReadRequestHints(
|
|
60
|
+
{ getNullifierMembershipWitness },
|
|
61
|
+
nullifierReadRequests,
|
|
62
|
+
nullifiers,
|
|
63
|
+
sizePending,
|
|
64
|
+
sizeSettled,
|
|
65
|
+
futureNullifiers,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function getMasterSecretKeysAndAppKeyGenerators(
|
|
70
|
+
keyValidationRequests: Tuple<ScopedKeyValidationRequestAndGenerator, typeof MAX_KEY_VALIDATION_REQUESTS_PER_TX>,
|
|
71
|
+
oracle: ProvingDataOracle,
|
|
72
|
+
) {
|
|
73
|
+
const keysHints = makeTuple(MAX_KEY_VALIDATION_REQUESTS_PER_TX, KeyValidationHint.empty);
|
|
74
|
+
|
|
75
|
+
let keyIndex = 0;
|
|
76
|
+
for (let i = 0; i < keyValidationRequests.length; ++i) {
|
|
77
|
+
const request = keyValidationRequests[i].request;
|
|
78
|
+
if (request.isEmpty()) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
const secretKeys = await oracle.getMasterSecretKey(request.request.pkM);
|
|
82
|
+
keysHints[keyIndex] = new KeyValidationHint(secretKeys, i);
|
|
83
|
+
keyIndex++;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
keysCount: keyIndex,
|
|
87
|
+
keysHints,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function buildPrivateKernelResetInputs(
|
|
92
|
+
executionStack: ExecutionResult[],
|
|
93
|
+
previousKernelData: PrivateKernelData,
|
|
94
|
+
noteHashLeafIndexMap: Map<bigint, bigint>,
|
|
95
|
+
noteHashNullifierCounterMap: Map<number, number>,
|
|
96
|
+
oracle: ProvingDataOracle,
|
|
97
|
+
) {
|
|
98
|
+
const publicInputs = previousKernelData.publicInputs;
|
|
99
|
+
// Use max sizes, they will be trimmed down later.
|
|
100
|
+
|
|
101
|
+
const futureNoteHashes = collectNested(executionStack, executionResult => {
|
|
102
|
+
const nonEmptyNoteHashes = getNonEmptyItems(executionResult.callStackItem.publicInputs.newNoteHashes);
|
|
103
|
+
return nonEmptyNoteHashes.map(
|
|
104
|
+
noteHash =>
|
|
105
|
+
new ScopedNoteHash(
|
|
106
|
+
noteHash,
|
|
107
|
+
noteHashNullifierCounterMap.get(noteHash.counter) ?? 0,
|
|
108
|
+
executionResult.callStackItem.publicInputs.callContext.storageContractAddress,
|
|
109
|
+
),
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const {
|
|
114
|
+
numPendingReadHints: noteHashPendingReadHints,
|
|
115
|
+
numSettledReadHints: noteHashSettledReadHints,
|
|
116
|
+
hints: noteHashReadRequestHints,
|
|
117
|
+
} = await buildNoteHashReadRequestHints(
|
|
118
|
+
oracle,
|
|
119
|
+
publicInputs.validationRequests.noteHashReadRequests,
|
|
120
|
+
publicInputs.end.newNoteHashes,
|
|
121
|
+
noteHashLeafIndexMap,
|
|
122
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
123
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
124
|
+
futureNoteHashes,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
const futureNullifiers = collectNested(executionStack, executionResult => {
|
|
128
|
+
const nonEmptyNullifiers = getNonEmptyItems(executionResult.callStackItem.publicInputs.newNullifiers);
|
|
129
|
+
return nonEmptyNullifiers.map(
|
|
130
|
+
nullifier =>
|
|
131
|
+
new ScopedNullifier(nullifier, executionResult.callStackItem.publicInputs.callContext.storageContractAddress),
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const {
|
|
136
|
+
numPendingReadHints: nullifierPendingReadHints,
|
|
137
|
+
numSettledReadHints: nullifierSettledReadHints,
|
|
138
|
+
hints: nullifierReadRequestHints,
|
|
139
|
+
} = await getNullifierReadRequestHints(
|
|
140
|
+
publicInputs.validationRequests.nullifierReadRequests,
|
|
141
|
+
publicInputs.end.newNullifiers,
|
|
142
|
+
oracle,
|
|
143
|
+
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
144
|
+
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
145
|
+
futureNullifiers,
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
const { keysCount, keysHints } = await getMasterSecretKeysAndAppKeyGenerators(
|
|
149
|
+
publicInputs.validationRequests.scopedKeyValidationRequestsAndGenerators,
|
|
150
|
+
oracle,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const futureNoteHashReads = collectNestedReadRequests(
|
|
154
|
+
executionStack,
|
|
155
|
+
executionResult => executionResult.callStackItem.publicInputs.noteHashReadRequests,
|
|
156
|
+
);
|
|
157
|
+
const futureNullifierReads = collectNestedReadRequests(
|
|
158
|
+
executionStack,
|
|
159
|
+
executionResult => executionResult.callStackItem.publicInputs.nullifierReadRequests,
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
const [
|
|
163
|
+
transientNullifierIndexesForNoteHashes,
|
|
164
|
+
transientNoteHashIndexesForNullifiers,
|
|
165
|
+
transientNoteHashIndexesForLogs,
|
|
166
|
+
] = buildTransientDataHints(
|
|
167
|
+
publicInputs.end.newNoteHashes,
|
|
168
|
+
publicInputs.end.newNullifiers,
|
|
169
|
+
publicInputs.end.noteEncryptedLogsHashes,
|
|
170
|
+
futureNoteHashReads,
|
|
171
|
+
futureNullifierReads,
|
|
172
|
+
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
173
|
+
MAX_NEW_NULLIFIERS_PER_TX,
|
|
174
|
+
MAX_NOTE_ENCRYPTED_LOGS_PER_TX,
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const expectedOutputs = buildPrivateKernelResetOutputs(
|
|
178
|
+
previousKernelData.publicInputs.end.newNoteHashes,
|
|
179
|
+
previousKernelData.publicInputs.end.newNullifiers,
|
|
180
|
+
previousKernelData.publicInputs.end.noteEncryptedLogsHashes,
|
|
181
|
+
transientNullifierIndexesForNoteHashes,
|
|
182
|
+
transientNoteHashIndexesForNullifiers,
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
let privateInputs;
|
|
186
|
+
|
|
187
|
+
for (const [sizeTag, hintSizes] of Object.entries(PRIVATE_RESET_VARIANTS)) {
|
|
188
|
+
if (
|
|
189
|
+
hintSizes.NOTE_HASH_PENDING_AMOUNT >= noteHashPendingReadHints &&
|
|
190
|
+
hintSizes.NOTE_HASH_SETTLED_AMOUNT >= noteHashSettledReadHints &&
|
|
191
|
+
hintSizes.NULLIFIER_PENDING_AMOUNT >= nullifierPendingReadHints &&
|
|
192
|
+
hintSizes.NULLIFIER_SETTLED_AMOUNT >= nullifierSettledReadHints &&
|
|
193
|
+
hintSizes.NULLIFIER_KEYS >= keysCount
|
|
194
|
+
) {
|
|
195
|
+
privateInputs = new PrivateKernelResetCircuitPrivateInputs(
|
|
196
|
+
previousKernelData,
|
|
197
|
+
expectedOutputs,
|
|
198
|
+
new PrivateKernelResetHints(
|
|
199
|
+
transientNullifierIndexesForNoteHashes,
|
|
200
|
+
transientNoteHashIndexesForNullifiers,
|
|
201
|
+
transientNoteHashIndexesForLogs,
|
|
202
|
+
noteHashReadRequestHints,
|
|
203
|
+
nullifierReadRequestHints,
|
|
204
|
+
keysHints,
|
|
205
|
+
).trimToSizes(
|
|
206
|
+
hintSizes.NOTE_HASH_PENDING_AMOUNT,
|
|
207
|
+
hintSizes.NOTE_HASH_SETTLED_AMOUNT,
|
|
208
|
+
hintSizes.NULLIFIER_PENDING_AMOUNT,
|
|
209
|
+
hintSizes.NULLIFIER_SETTLED_AMOUNT,
|
|
210
|
+
hintSizes.NULLIFIER_KEYS,
|
|
211
|
+
),
|
|
212
|
+
sizeTag,
|
|
213
|
+
);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (!privateInputs) {
|
|
219
|
+
throw new Error('No private inputs found for the given hint sizes.');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return privateInputs as PrivateKernelResetCircuitPrivateInputsVariants;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function collectNested<T>(
|
|
226
|
+
executionStack: ExecutionResult[],
|
|
227
|
+
extractExecutionItems: (execution: ExecutionResult) => T[],
|
|
228
|
+
): T[] {
|
|
229
|
+
const thisExecutionReads = executionStack.flatMap(extractExecutionItems);
|
|
230
|
+
|
|
231
|
+
return thisExecutionReads.concat(
|
|
232
|
+
executionStack.flatMap(({ nestedExecutions }) => collectNested(nestedExecutions, extractExecutionItems)),
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function collectNestedReadRequests(
|
|
237
|
+
executionStack: ExecutionResult[],
|
|
238
|
+
extractReadRequests: (execution: ExecutionResult) => ReadRequest[],
|
|
239
|
+
): ScopedReadRequest[] {
|
|
240
|
+
return collectNested(executionStack, executionResult => {
|
|
241
|
+
const nonEmptyReadRequests = getNonEmptyItems(extractReadRequests(executionResult));
|
|
242
|
+
return nonEmptyReadRequests.map(
|
|
243
|
+
readRequest =>
|
|
244
|
+
new ScopedReadRequest(
|
|
245
|
+
readRequest,
|
|
246
|
+
executionResult.callStackItem.publicInputs.callContext.storageContractAddress,
|
|
247
|
+
),
|
|
248
|
+
);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
3
|
+
MAX_NEW_NULLIFIERS_PER_TX,
|
|
4
|
+
MAX_NOTE_ENCRYPTED_LOGS_PER_TX,
|
|
5
|
+
NoteLogHash,
|
|
6
|
+
PrivateKernelResetOutputs,
|
|
7
|
+
ScopedNoteHash,
|
|
8
|
+
ScopedNullifier,
|
|
9
|
+
} from '@aztec/circuits.js';
|
|
10
|
+
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
11
|
+
import { type Tuple } from '@aztec/foundation/serialize';
|
|
12
|
+
|
|
13
|
+
export function buildPrivateKernelResetOutputs(
|
|
14
|
+
prevNoteHashes: Tuple<ScopedNoteHash, typeof MAX_NEW_NOTE_HASHES_PER_TX>,
|
|
15
|
+
prevNullifiers: Tuple<ScopedNullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
16
|
+
prevLogs: Tuple<NoteLogHash, typeof MAX_NOTE_ENCRYPTED_LOGS_PER_TX>,
|
|
17
|
+
transientNullifierIndexesForNoteHashes: Tuple<number, typeof MAX_NEW_NOTE_HASHES_PER_TX>,
|
|
18
|
+
transientNoteHashIndexesForNullifiers: Tuple<number, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
19
|
+
) {
|
|
20
|
+
// Propagate note hashes that are not going to be squashed in the transient arrays.
|
|
21
|
+
// A value isn't going to be squashed if the symmetrical index in the corresponding array is the length of the array.
|
|
22
|
+
const noteHashes = padArrayEnd(
|
|
23
|
+
prevNoteHashes.filter((_, index) => transientNullifierIndexesForNoteHashes[index] === MAX_NEW_NULLIFIERS_PER_TX),
|
|
24
|
+
ScopedNoteHash.empty(),
|
|
25
|
+
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const nullifiers = padArrayEnd(
|
|
29
|
+
prevNullifiers.filter((_, index) => transientNoteHashIndexesForNullifiers[index] === MAX_NEW_NOTE_HASHES_PER_TX),
|
|
30
|
+
ScopedNullifier.empty(),
|
|
31
|
+
MAX_NEW_NULLIFIERS_PER_TX,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const nullifiedNotes = prevNoteHashes
|
|
35
|
+
.filter((_, index) => transientNullifierIndexesForNoteHashes[index] < MAX_NEW_NULLIFIERS_PER_TX)
|
|
36
|
+
.map(n => n.counter);
|
|
37
|
+
|
|
38
|
+
const logs = padArrayEnd(
|
|
39
|
+
prevLogs.filter(l => !l.isEmpty() && !nullifiedNotes.includes(l.noteHashCounter)),
|
|
40
|
+
NoteLogHash.empty(),
|
|
41
|
+
MAX_NOTE_ENCRYPTED_LOGS_PER_TX,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
return new PrivateKernelResetOutputs(noteHashes, nullifiers, logs);
|
|
45
|
+
}
|
|
@@ -1,119 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
GrumpkinScalar,
|
|
4
|
-
type MAX_ENCRYPTED_LOGS_PER_TX,
|
|
2
|
+
MAX_ENCRYPTED_LOGS_PER_TX,
|
|
5
3
|
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
6
4
|
MAX_NEW_NULLIFIERS_PER_TX,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
MembershipWitness,
|
|
11
|
-
NULLIFIER_TREE_HEIGHT,
|
|
5
|
+
MAX_NOTE_ENCRYPTED_LOGS_PER_TX,
|
|
6
|
+
MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
7
|
+
MAX_UNENCRYPTED_LOGS_PER_TX,
|
|
12
8
|
type PrivateKernelCircuitPublicInputs,
|
|
13
9
|
PrivateKernelTailHints,
|
|
14
|
-
type ScopedNullifier,
|
|
15
|
-
type ScopedNullifierKeyValidationRequest,
|
|
16
|
-
type ScopedReadRequest,
|
|
17
|
-
type SideEffect,
|
|
18
|
-
type SideEffectType,
|
|
19
|
-
buildNoteHashReadRequestHints,
|
|
20
|
-
buildNullifierReadRequestHints,
|
|
21
|
-
buildTransientDataHints,
|
|
22
10
|
sortByCounterGetSortedHints,
|
|
23
11
|
} from '@aztec/circuits.js';
|
|
24
|
-
import { makeTuple } from '@aztec/foundation/array';
|
|
25
|
-
import { type Tuple } from '@aztec/foundation/serialize';
|
|
26
|
-
|
|
27
|
-
import { type ProvingDataOracle } from '../proving_data_oracle.js';
|
|
28
|
-
|
|
29
|
-
/** @deprecated Use sortByCounterGetSortedHints instead */
|
|
30
|
-
function sortSideEffects<T extends SideEffectType, K extends number>(
|
|
31
|
-
sideEffects: Tuple<T, K>,
|
|
32
|
-
): [Tuple<T, K>, Tuple<number, K>] {
|
|
33
|
-
const sorted = sideEffects
|
|
34
|
-
.map((sideEffect, index) => ({ sideEffect, index }))
|
|
35
|
-
.sort((a, b) => {
|
|
36
|
-
// Empty ones go to the right
|
|
37
|
-
if (a.sideEffect.isEmpty()) {
|
|
38
|
-
return 1;
|
|
39
|
-
}
|
|
40
|
-
return Number(a.sideEffect.counter.toBigInt() - b.sideEffect.counter.toBigInt());
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const originalToSorted = sorted.map(() => 0);
|
|
44
|
-
sorted.forEach(({ index }, i) => {
|
|
45
|
-
originalToSorted[index] = i;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
return [sorted.map(({ sideEffect }) => sideEffect) as Tuple<T, K>, originalToSorted as Tuple<number, K>];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function getNullifierReadRequestHints(
|
|
52
|
-
nullifierReadRequests: Tuple<ScopedReadRequest, typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>,
|
|
53
|
-
nullifiers: Tuple<ScopedNullifier, typeof MAX_NEW_NULLIFIERS_PER_TX>,
|
|
54
|
-
oracle: ProvingDataOracle,
|
|
55
|
-
) {
|
|
56
|
-
const getNullifierMembershipWitness = async (nullifier: Fr) => {
|
|
57
|
-
const res = await oracle.getNullifierMembershipWitness(nullifier);
|
|
58
|
-
if (!res) {
|
|
59
|
-
throw new Error(`Cannot find the leaf for nullifier ${nullifier.toBigInt()}.`);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const { index, siblingPath, leafPreimage } = res;
|
|
63
|
-
return {
|
|
64
|
-
membershipWitness: new MembershipWitness(
|
|
65
|
-
NULLIFIER_TREE_HEIGHT,
|
|
66
|
-
index,
|
|
67
|
-
siblingPath.toTuple<typeof NULLIFIER_TREE_HEIGHT>(),
|
|
68
|
-
),
|
|
69
|
-
leafPreimage,
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
return buildNullifierReadRequestHints({ getNullifierMembershipWitness }, nullifierReadRequests, nullifiers);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function getMasterNullifierSecretKeys(
|
|
77
|
-
nullifierKeyValidationRequests: Tuple<
|
|
78
|
-
ScopedNullifierKeyValidationRequest,
|
|
79
|
-
typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX
|
|
80
|
-
>,
|
|
81
|
-
oracle: ProvingDataOracle,
|
|
82
|
-
) {
|
|
83
|
-
const keys = makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, GrumpkinScalar.zero);
|
|
84
|
-
for (let i = 0; i < nullifierKeyValidationRequests.length; ++i) {
|
|
85
|
-
const request = nullifierKeyValidationRequests[i].request;
|
|
86
|
-
if (request.isEmpty()) {
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
keys[i] = await oracle.getMasterNullifierSecretKey(request.masterNullifierPublicKey);
|
|
90
|
-
}
|
|
91
|
-
return keys;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export async function buildPrivateKernelTailHints(
|
|
95
|
-
publicInputs: PrivateKernelCircuitPublicInputs,
|
|
96
|
-
noteHashLeafIndexMap: Map<bigint, bigint>,
|
|
97
|
-
oracle: ProvingDataOracle,
|
|
98
|
-
) {
|
|
99
|
-
const noteHashReadRequestHints = await buildNoteHashReadRequestHints(
|
|
100
|
-
oracle,
|
|
101
|
-
publicInputs.validationRequests.noteHashReadRequests,
|
|
102
|
-
publicInputs.end.newNoteHashes,
|
|
103
|
-
noteHashLeafIndexMap,
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
const nullifierReadRequestHints = await getNullifierReadRequestHints(
|
|
107
|
-
publicInputs.validationRequests.nullifierReadRequests,
|
|
108
|
-
publicInputs.end.newNullifiers,
|
|
109
|
-
oracle,
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
const masterNullifierSecretKeys = await getMasterNullifierSecretKeys(
|
|
113
|
-
publicInputs.validationRequests.nullifierKeyValidationRequests,
|
|
114
|
-
oracle,
|
|
115
|
-
);
|
|
116
12
|
|
|
13
|
+
export function buildPrivateKernelTailHints(publicInputs: PrivateKernelCircuitPublicInputs): PrivateKernelTailHints {
|
|
117
14
|
const [sortedNoteHashes, sortedNoteHashesIndexes] = sortByCounterGetSortedHints(
|
|
118
15
|
publicInputs.end.newNoteHashes,
|
|
119
16
|
MAX_NEW_NOTE_HASHES_PER_TX,
|
|
@@ -124,36 +21,42 @@ export async function buildPrivateKernelTailHints(
|
|
|
124
21
|
MAX_NEW_NULLIFIERS_PER_TX,
|
|
125
22
|
);
|
|
126
23
|
|
|
127
|
-
const [
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
24
|
+
const [sortedNoteEncryptedLogHashes, sortedNoteEncryptedLogHashesIndexes] = sortByCounterGetSortedHints(
|
|
25
|
+
publicInputs.end.noteEncryptedLogsHashes,
|
|
26
|
+
MAX_NOTE_ENCRYPTED_LOGS_PER_TX,
|
|
27
|
+
);
|
|
131
28
|
|
|
132
|
-
const [
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
29
|
+
const [sortedEncryptedLogHashes, sortedEncryptedLogHashesIndexes] = sortByCounterGetSortedHints(
|
|
30
|
+
publicInputs.end.encryptedLogsHashes,
|
|
31
|
+
MAX_ENCRYPTED_LOGS_PER_TX,
|
|
32
|
+
);
|
|
136
33
|
|
|
137
|
-
const [
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
34
|
+
const [sortedUnencryptedLogHashes, sortedUnencryptedLogHashesIndexes] = sortByCounterGetSortedHints(
|
|
35
|
+
publicInputs.end.unencryptedLogsHashes,
|
|
36
|
+
MAX_UNENCRYPTED_LOGS_PER_TX,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const [sortedCallRequests, sortedCallRequestsIndexes] = sortByCounterGetSortedHints(
|
|
40
|
+
publicInputs.end.publicCallStack,
|
|
41
|
+
MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX,
|
|
42
|
+
{
|
|
43
|
+
ascending: false,
|
|
44
|
+
hintIndexesBy: 'sorted',
|
|
45
|
+
},
|
|
142
46
|
);
|
|
143
47
|
|
|
144
48
|
return new PrivateKernelTailHints(
|
|
145
|
-
transientNullifierIndexesForNoteHashes,
|
|
146
|
-
transientNoteHashIndexesForNullifiers,
|
|
147
|
-
noteHashReadRequestHints,
|
|
148
|
-
nullifierReadRequestHints,
|
|
149
|
-
masterNullifierSecretKeys,
|
|
150
49
|
sortedNoteHashes,
|
|
151
50
|
sortedNoteHashesIndexes,
|
|
152
51
|
sortedNullifiers,
|
|
153
52
|
sortedNullifiersIndexes,
|
|
53
|
+
sortedNoteEncryptedLogHashes,
|
|
54
|
+
sortedNoteEncryptedLogHashesIndexes,
|
|
154
55
|
sortedEncryptedLogHashes,
|
|
155
56
|
sortedEncryptedLogHashesIndexes,
|
|
156
57
|
sortedUnencryptedLogHashes,
|
|
157
58
|
sortedUnencryptedLogHashesIndexes,
|
|
59
|
+
sortedCallRequests,
|
|
60
|
+
sortedCallRequestsIndexes,
|
|
158
61
|
);
|
|
159
62
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { buildPrivateKernelInitHints } from './build_private_kernel_init_hints.js';
|
|
1
2
|
export { buildPrivateKernelInnerHints } from './build_private_kernel_inner_hints.js';
|
|
2
3
|
export { buildPrivateKernelTailHints } from './build_private_kernel_tail_hints.js';
|
|
3
|
-
export {
|
|
4
|
+
export { buildPrivateKernelResetInputs } from './build_private_kernel_reset_hints.js';
|
|
5
|
+
export { buildPrivateKernelResetOutputs } from './build_private_kernel_reset_outputs.js';
|
|
@@ -70,10 +70,13 @@ export interface ProvingDataOracle {
|
|
|
70
70
|
getNoteHashTreeRoot(): Promise<Fr>;
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* @param
|
|
76
|
-
* @returns
|
|
73
|
+
* Retrieves the sk_m corresponding to the pk_m.
|
|
74
|
+
* @throws If the provided public key is not associated with any of the registered accounts.
|
|
75
|
+
* @param pkM - The master public key to get secret key for.
|
|
76
|
+
* @returns A Promise that resolves to sk_m.
|
|
77
|
+
* @dev Used when feeding the sk_m to the kernel circuit for keys verification.
|
|
77
78
|
*/
|
|
78
|
-
|
|
79
|
+
getMasterSecretKey(masterPublicKey: Point): Promise<GrumpkinPrivateKey>;
|
|
80
|
+
|
|
81
|
+
getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;
|
|
79
82
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type AppCircuitProofOutput, type KernelProofOutput, type ProofCreator } from '@aztec/circuit-types';
|
|
2
|
-
import {
|
|
2
|
+
import type { CircuitName, CircuitSimulationStats } from '@aztec/circuit-types/stats';
|
|
3
3
|
import {
|
|
4
4
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
5
5
|
type PrivateCircuitPublicInputs,
|
|
6
6
|
type PrivateKernelCircuitPublicInputs,
|
|
7
7
|
type PrivateKernelInitCircuitPrivateInputs,
|
|
8
8
|
type PrivateKernelInnerCircuitPrivateInputs,
|
|
9
|
+
type PrivateKernelResetCircuitPrivateInputsVariants,
|
|
9
10
|
type PrivateKernelTailCircuitPrivateInputs,
|
|
10
11
|
type PrivateKernelTailCircuitPublicInputs,
|
|
11
12
|
RECURSIVE_PROOF_LENGTH,
|
|
@@ -15,7 +16,13 @@ import {
|
|
|
15
16
|
import { siloNoteHash } from '@aztec/circuits.js/hash';
|
|
16
17
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
17
18
|
import { elapsed } from '@aztec/foundation/timer';
|
|
18
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
executeInit,
|
|
21
|
+
executeInner,
|
|
22
|
+
executeReset,
|
|
23
|
+
executeTail,
|
|
24
|
+
executeTailForPublic,
|
|
25
|
+
} from '@aztec/noir-protocol-circuits-types';
|
|
19
26
|
|
|
20
27
|
/**
|
|
21
28
|
* Test Proof Creator executes circuit simulations and provides fake proofs.
|
|
@@ -59,6 +66,20 @@ export class TestProofCreator implements ProofCreator {
|
|
|
59
66
|
return this.makeEmptyKernelProofOutput<PrivateKernelCircuitPublicInputs>(result);
|
|
60
67
|
}
|
|
61
68
|
|
|
69
|
+
public async createProofReset(
|
|
70
|
+
privateInputs: PrivateKernelResetCircuitPrivateInputsVariants,
|
|
71
|
+
): Promise<KernelProofOutput<PrivateKernelCircuitPublicInputs>> {
|
|
72
|
+
const [duration, result] = await elapsed(() => executeReset(privateInputs));
|
|
73
|
+
this.log.debug(`Simulated private kernel reset`, {
|
|
74
|
+
eventName: 'circuit-simulation',
|
|
75
|
+
circuitName: ('private-kernel-reset-' + privateInputs.sizeTag) as CircuitName,
|
|
76
|
+
duration,
|
|
77
|
+
inputSize: privateInputs.toBuffer().length,
|
|
78
|
+
outputSize: result.toBuffer().length,
|
|
79
|
+
} satisfies CircuitSimulationStats);
|
|
80
|
+
return this.makeEmptyKernelProofOutput<PrivateKernelCircuitPublicInputs>(result);
|
|
81
|
+
}
|
|
82
|
+
|
|
62
83
|
public async createProofTail(
|
|
63
84
|
privateInputs: PrivateKernelTailCircuitPrivateInputs,
|
|
64
85
|
): Promise<KernelProofOutput<PrivateKernelTailCircuitPublicInputs>> {
|
|
@@ -68,7 +89,7 @@ export class TestProofCreator implements ProofCreator {
|
|
|
68
89
|
);
|
|
69
90
|
this.log.debug(`Simulated private kernel ordering`, {
|
|
70
91
|
eventName: 'circuit-simulation',
|
|
71
|
-
circuitName: 'private-kernel-
|
|
92
|
+
circuitName: 'private-kernel-tail',
|
|
72
93
|
duration,
|
|
73
94
|
inputSize: privateInputs.toBuffer().length,
|
|
74
95
|
outputSize: result.toBuffer().length,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type AztecNode,
|
|
3
|
-
type
|
|
4
|
-
type KeyStore,
|
|
3
|
+
type EncryptedNoteL2BlockL2Logs,
|
|
5
4
|
L1NotePayload,
|
|
6
5
|
type L2Block,
|
|
7
6
|
TaggedNote,
|
|
@@ -11,6 +10,7 @@ import { INITIAL_L2_BLOCK_NUM, MAX_NEW_NOTE_HASHES_PER_TX, type PublicKey } from
|
|
|
11
10
|
import { type Fr } from '@aztec/foundation/fields';
|
|
12
11
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
13
12
|
import { Timer } from '@aztec/foundation/timer';
|
|
13
|
+
import { type KeyStore } from '@aztec/key-store';
|
|
14
14
|
import { ContractNotFoundError } from '@aztec/simulator';
|
|
15
15
|
|
|
16
16
|
import { DeferredNoteDao } from '../database/deferred_note_dao.js';
|
|
@@ -88,7 +88,7 @@ export class NoteProcessor {
|
|
|
88
88
|
* @param encryptedL2BlockLogs - Encrypted logs associated with the L2 blocks.
|
|
89
89
|
* @returns A promise that resolves once the processing is completed.
|
|
90
90
|
*/
|
|
91
|
-
public async process(l2Blocks: L2Block[], encryptedL2BlockLogs:
|
|
91
|
+
public async process(l2Blocks: L2Block[], encryptedL2BlockLogs: EncryptedNoteL2BlockL2Logs[]): Promise<void> {
|
|
92
92
|
if (l2Blocks.length !== encryptedL2BlockLogs.length) {
|
|
93
93
|
throw new Error(
|
|
94
94
|
`Number of blocks and EncryptedLogs is not equal. Received ${l2Blocks.length} blocks, ${encryptedL2BlockLogs.length} encrypted logs.`,
|
|
@@ -130,7 +130,8 @@ export class NoteProcessor {
|
|
|
130
130
|
for (const functionLogs of txFunctionLogs) {
|
|
131
131
|
for (const log of functionLogs.logs) {
|
|
132
132
|
this.stats.seen++;
|
|
133
|
-
|
|
133
|
+
// @todo Issue(#6410) We should also try decrypting as outgoing if this fails.
|
|
134
|
+
const taggedNote = TaggedNote.decryptAsIncoming(log.data, secretKey);
|
|
134
135
|
if (taggedNote?.notePayload) {
|
|
135
136
|
const { notePayload: payload } = taggedNote;
|
|
136
137
|
// We have successfully decrypted the data.
|
|
@@ -107,25 +107,9 @@ async function findNoteIndexAndNullifier(
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
if (!nonce) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
} else {
|
|
114
|
-
errorString = `We decrypted a log, but couldn't find a corresponding note in the tree.
|
|
115
|
-
This might be because the note was nullified in the same tx which created it.
|
|
116
|
-
In that case, everything is fine. To check whether this is the case, look back through
|
|
117
|
-
the logs for a notification
|
|
118
|
-
'important: chopped commitment for siloed inner hash note
|
|
119
|
-
${siloedNoteHash.toString()}'.
|
|
120
|
-
If you can see that notification. Everything's fine.
|
|
121
|
-
If that's not the case, and you can't find such a notification, something has gone wrong.
|
|
122
|
-
There could be a problem with the way you've defined a custom note, or with the way you're
|
|
123
|
-
serializing / deserializing / hashing / encrypting / decrypting that note.
|
|
124
|
-
Please see the following github issue to track an improvement that we're working on:
|
|
125
|
-
https://github.com/AztecProtocol/aztec-packages/issues/1641`;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
throw new Error(errorString);
|
|
110
|
+
// NB: this used to warn the user that a decrypted log didn't match any notes.
|
|
111
|
+
// This was previously fine as we didn't chop transient note logs, but now we do (#1641 complete).
|
|
112
|
+
throw new Error('Cannot find a matching commitment for the note.');
|
|
129
113
|
}
|
|
130
114
|
|
|
131
115
|
return {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AuthWitness,
|
|
3
3
|
CompleteAddress,
|
|
4
|
-
|
|
4
|
+
EncryptedNoteL2BlockL2Logs,
|
|
5
5
|
ExtendedNote,
|
|
6
6
|
ExtendedUnencryptedL2Log,
|
|
7
7
|
L2Block,
|
|
@@ -50,7 +50,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer {
|
|
|
50
50
|
TxEffect,
|
|
51
51
|
LogId,
|
|
52
52
|
},
|
|
53
|
-
{ SimulatedTx, Tx, TxReceipt,
|
|
53
|
+
{ SimulatedTx, Tx, TxReceipt, EncryptedNoteL2BlockL2Logs, UnencryptedL2BlockL2Logs, NullifierMembershipWitness },
|
|
54
54
|
['start', 'stop'],
|
|
55
55
|
);
|
|
56
56
|
}
|