@aztec/pxe 1.2.1 → 2.0.0-nightly.20250813
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/package_info.js +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts +5 -2
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +48 -29
- package/dest/contract_function_simulator/index.d.ts +1 -0
- package/dest/contract_function_simulator/index.d.ts.map +1 -1
- package/dest/contract_function_simulator/index.js +1 -0
- package/dest/contract_function_simulator/noir-structs/event_validation_request.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/event_validation_request.js +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_request.js +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/log_retrieval_response.js +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.d.ts +1 -1
- package/dest/contract_function_simulator/noir-structs/note_validation_request.js +1 -1
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts +22 -0
- package/dest/contract_function_simulator/oracle/note_packing_utils.d.ts.map +1 -0
- package/dest/contract_function_simulator/oracle/note_packing_utils.js +49 -0
- package/dest/contract_function_simulator/oracle/oracle.d.ts +44 -43
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +127 -106
- package/dest/contract_function_simulator/oracle/private_execution.d.ts +7 -2
- package/dest/contract_function_simulator/oracle/private_execution.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution.js +16 -11
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts +41 -17
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +51 -23
- package/dest/contract_function_simulator/oracle/typed_oracle.d.ts +48 -47
- package/dest/contract_function_simulator/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/typed_oracle.js +89 -87
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +31 -30
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +33 -30
- package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/contract_function_simulator/pxe_oracle_interface.js +6 -7
- package/dest/entrypoints/server/utils.d.ts +4 -2
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +4 -2
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts +4 -4
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.js +58 -59
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts +4 -0
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.d.ts.map +1 -0
- package/dest/private_kernel/hints/compute_tx_include_by_timestamp.js +41 -0
- package/dest/private_kernel/hints/index.d.ts +1 -0
- package/dest/private_kernel/hints/index.d.ts.map +1 -1
- package/dest/private_kernel/hints/index.js +1 -0
- package/dest/private_kernel/private_kernel_execution_prover.d.ts +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +13 -4
- package/dest/private_kernel/private_kernel_oracle.d.ts +1 -1
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle_impl.js +6 -6
- package/dest/pxe_service/error_enriching.d.ts.map +1 -1
- package/dest/pxe_service/error_enriching.js +1 -0
- package/dest/pxe_service/pxe_service.d.ts +3 -2
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +28 -19
- package/dest/storage/capsule_data_provider/capsule_data_provider.js +1 -1
- package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
- package/dest/storage/note_data_provider/note_data_provider.js +16 -4
- package/package.json +16 -16
- package/src/config/package_info.ts +1 -1
- package/src/contract_function_simulator/contract_function_simulator.ts +67 -37
- package/src/contract_function_simulator/index.ts +1 -0
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/log_retrieval_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/log_retrieval_response.ts +1 -1
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
- package/src/contract_function_simulator/oracle/note_packing_utils.ts +52 -0
- package/src/contract_function_simulator/oracle/oracle.ts +149 -111
- package/src/contract_function_simulator/oracle/private_execution.ts +17 -12
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +60 -24
- package/src/contract_function_simulator/oracle/typed_oracle.ts +108 -92
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +34 -30
- package/src/contract_function_simulator/pxe_oracle_interface.ts +6 -8
- package/src/entrypoints/server/utils.ts +17 -6
- package/src/private_kernel/hints/build_private_kernel_reset_private_inputs.ts +106 -104
- package/src/private_kernel/hints/compute_tx_include_by_timestamp.ts +58 -0
- package/src/private_kernel/hints/index.ts +1 -0
- package/src/private_kernel/private_kernel_execution_prover.ts +21 -4
- package/src/private_kernel/private_kernel_oracle.ts +1 -1
- package/src/private_kernel/private_kernel_oracle_impl.ts +12 -9
- package/src/pxe_service/error_enriching.ts +1 -0
- package/src/pxe_service/pxe_service.ts +30 -32
- package/src/storage/capsule_data_provider/capsule_data_provider.ts +1 -1
- package/src/storage/note_data_provider/note_data_provider.ts +27 -16
|
@@ -14,6 +14,7 @@ import { type Tuple, assertLength } from '@aztec/foundation/serialize';
|
|
|
14
14
|
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
15
15
|
import { privateKernelResetDimensionsConfig } from '@aztec/noir-protocol-circuits-types/client';
|
|
16
16
|
import {
|
|
17
|
+
ClaimedLengthArray,
|
|
17
18
|
KeyValidationHint,
|
|
18
19
|
PaddedSideEffects,
|
|
19
20
|
type PrivateCircuitPublicInputs,
|
|
@@ -24,21 +25,19 @@ import {
|
|
|
24
25
|
PrivateKernelResetHints,
|
|
25
26
|
type PrivateKernelSimulateOutput,
|
|
26
27
|
type ReadRequest,
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
ReadRequestActionEnum,
|
|
29
|
+
ReadRequestResetActions,
|
|
29
30
|
type ScopedKeyValidationRequestAndGenerator,
|
|
30
31
|
ScopedNoteHash,
|
|
31
32
|
ScopedNullifier,
|
|
32
33
|
ScopedReadRequest,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
TransientDataSquashingHint,
|
|
35
|
+
buildNoteHashReadRequestHintsFromResetActions,
|
|
36
|
+
buildNullifierReadRequestHintsFromResetActions,
|
|
36
37
|
buildTransientDataHints,
|
|
37
|
-
countAccumulatedItems,
|
|
38
38
|
findPrivateKernelResetDimensions,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
getNullifierReadRequestResetStates,
|
|
39
|
+
getNoteHashReadRequestResetActions,
|
|
40
|
+
getNullifierReadRequestResetActions,
|
|
42
41
|
privateKernelResetDimensionNames,
|
|
43
42
|
} from '@aztec/stdlib/kernel';
|
|
44
43
|
import { type PrivateCallExecutionResult, collectNested } from '@aztec/stdlib/tx';
|
|
@@ -46,15 +45,14 @@ import { VkData } from '@aztec/stdlib/vks';
|
|
|
46
45
|
|
|
47
46
|
import type { PrivateKernelOracle } from '../private_kernel_oracle.js';
|
|
48
47
|
|
|
49
|
-
function collectNestedReadRequests(
|
|
48
|
+
function collectNestedReadRequests<N extends number>(
|
|
50
49
|
executionStack: PrivateCallExecutionResult[],
|
|
51
|
-
extractReadRequests: (execution: PrivateCallExecutionResult) => ReadRequest
|
|
50
|
+
extractReadRequests: (execution: PrivateCallExecutionResult) => ClaimedLengthArray<ReadRequest, N>,
|
|
52
51
|
): ScopedReadRequest[] {
|
|
53
52
|
return collectNested(executionStack, executionResult => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
readRequest => new ScopedReadRequest(readRequest, executionResult.publicInputs.callContext.contractAddress)
|
|
57
|
-
);
|
|
53
|
+
return extractReadRequests(executionResult)
|
|
54
|
+
.getActiveItems()
|
|
55
|
+
.map(readRequest => new ScopedReadRequest(readRequest, executionResult.publicInputs.callContext.contractAddress));
|
|
58
56
|
});
|
|
59
57
|
}
|
|
60
58
|
|
|
@@ -74,13 +72,16 @@ function getNullifierMembershipWitnessResolver(oracle: PrivateKernelOracle) {
|
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
async function getMasterSecretKeysAndAppKeyGenerators(
|
|
77
|
-
keyValidationRequests:
|
|
75
|
+
keyValidationRequests: ClaimedLengthArray<
|
|
76
|
+
ScopedKeyValidationRequestAndGenerator,
|
|
77
|
+
typeof MAX_KEY_VALIDATION_REQUESTS_PER_TX
|
|
78
|
+
>,
|
|
78
79
|
numRequestsToVerify: number,
|
|
79
80
|
oracle: PrivateKernelOracle,
|
|
80
81
|
) {
|
|
81
|
-
const
|
|
82
|
+
const numRequestsToProcess = Math.min(keyValidationRequests.claimedLength, numRequestsToVerify);
|
|
82
83
|
const keysHints = await Promise.all(
|
|
83
|
-
keyValidationRequests.slice(0,
|
|
84
|
+
keyValidationRequests.array.slice(0, numRequestsToProcess).map(async ({ request }) => {
|
|
84
85
|
const secretKeys = await oracle.getMasterSecretKey(request.request.pkM);
|
|
85
86
|
return new KeyValidationHint(secretKeys);
|
|
86
87
|
}),
|
|
@@ -93,10 +94,10 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
93
94
|
// If there's no next iteration, it's the final reset.
|
|
94
95
|
private nextIteration?: PrivateCircuitPublicInputs;
|
|
95
96
|
|
|
96
|
-
private
|
|
97
|
-
private
|
|
97
|
+
private noteHashResetActions: ReadRequestResetActions<typeof MAX_NOTE_HASH_READ_REQUESTS_PER_TX>;
|
|
98
|
+
private nullifierResetActions: ReadRequestResetActions<typeof MAX_NULLIFIER_READ_REQUESTS_PER_TX>;
|
|
98
99
|
private numTransientData?: number;
|
|
99
|
-
private
|
|
100
|
+
private transientDataSquashingHints: Tuple<TransientDataSquashingHint, typeof MAX_NULLIFIERS_PER_TX>;
|
|
100
101
|
private requestedDimensions: PrivateKernelResetDimensions;
|
|
101
102
|
|
|
102
103
|
constructor(
|
|
@@ -107,11 +108,11 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
107
108
|
) {
|
|
108
109
|
this.previousKernel = previousKernelOutput.publicInputs;
|
|
109
110
|
this.requestedDimensions = PrivateKernelResetDimensions.empty();
|
|
110
|
-
this.
|
|
111
|
-
this.
|
|
112
|
-
this.
|
|
111
|
+
this.noteHashResetActions = ReadRequestResetActions.empty(MAX_NOTE_HASH_READ_REQUESTS_PER_TX);
|
|
112
|
+
this.nullifierResetActions = ReadRequestResetActions.empty(MAX_NULLIFIER_READ_REQUESTS_PER_TX);
|
|
113
|
+
this.transientDataSquashingHints = makeTuple(
|
|
113
114
|
MAX_NULLIFIERS_PER_TX,
|
|
114
|
-
() => new
|
|
115
|
+
() => new TransientDataSquashingHint(MAX_NULLIFIERS_PER_TX, MAX_NOTE_HASHES_PER_TX),
|
|
115
116
|
);
|
|
116
117
|
this.nextIteration = executionStack[this.executionStack.length - 1]?.publicInputs;
|
|
117
118
|
}
|
|
@@ -169,13 +170,13 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
169
170
|
);
|
|
170
171
|
const previousKernelData = new PrivateKernelData(this.previousKernelOutput.publicInputs, vkData);
|
|
171
172
|
|
|
172
|
-
this.
|
|
173
|
-
this.
|
|
173
|
+
this.reduceReadRequestActions(
|
|
174
|
+
this.noteHashResetActions,
|
|
174
175
|
dimensions.NOTE_HASH_PENDING_READ,
|
|
175
176
|
dimensions.NOTE_HASH_SETTLED_READ,
|
|
176
177
|
);
|
|
177
|
-
this.
|
|
178
|
-
this.
|
|
178
|
+
this.reduceReadRequestActions(
|
|
179
|
+
this.nullifierResetActions,
|
|
179
180
|
dimensions.NULLIFIER_PENDING_READ,
|
|
180
181
|
dimensions.NULLIFIER_SETTLED_READ,
|
|
181
182
|
);
|
|
@@ -187,101 +188,104 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
187
188
|
previousKernelData,
|
|
188
189
|
paddedSideEffects,
|
|
189
190
|
new PrivateKernelResetHints(
|
|
190
|
-
await
|
|
191
|
+
await buildNoteHashReadRequestHintsFromResetActions(
|
|
191
192
|
oracle,
|
|
192
193
|
this.previousKernel.validationRequests.noteHashReadRequests,
|
|
193
194
|
this.previousKernel.end.noteHashes,
|
|
194
|
-
this.
|
|
195
|
+
this.noteHashResetActions,
|
|
195
196
|
noteHashLeafIndexMap,
|
|
196
197
|
),
|
|
197
|
-
await
|
|
198
|
+
await buildNullifierReadRequestHintsFromResetActions(
|
|
198
199
|
{ getNullifierMembershipWitness: getNullifierMembershipWitnessResolver(oracle) },
|
|
199
200
|
this.previousKernel.validationRequests.nullifierReadRequests,
|
|
200
|
-
this.
|
|
201
|
+
this.nullifierResetActions,
|
|
201
202
|
),
|
|
202
203
|
await getMasterSecretKeysAndAppKeyGenerators(
|
|
203
204
|
this.previousKernel.validationRequests.scopedKeyValidationRequestsAndGenerators,
|
|
204
205
|
dimensions.KEY_VALIDATION,
|
|
205
206
|
oracle,
|
|
206
207
|
),
|
|
207
|
-
this.
|
|
208
|
+
this.transientDataSquashingHints,
|
|
208
209
|
this.validationRequestsSplitCounter,
|
|
209
210
|
),
|
|
210
211
|
dimensions,
|
|
211
212
|
);
|
|
212
213
|
}
|
|
213
214
|
|
|
214
|
-
private
|
|
215
|
-
|
|
215
|
+
private reduceReadRequestActions<NUM_READS extends number>(
|
|
216
|
+
resetActions: ReadRequestResetActions<NUM_READS>,
|
|
216
217
|
maxPending: number,
|
|
217
218
|
maxSettled: number,
|
|
218
219
|
) {
|
|
219
220
|
let numPending = 0;
|
|
220
221
|
let numSettled = 0;
|
|
221
|
-
for (let i = 0; i <
|
|
222
|
-
const
|
|
223
|
-
if (
|
|
222
|
+
for (let i = 0; i < resetActions.actions.length; i++) {
|
|
223
|
+
const action = resetActions.actions[i];
|
|
224
|
+
if (action === ReadRequestActionEnum.READ_AS_PENDING) {
|
|
224
225
|
if (numPending < maxPending) {
|
|
225
226
|
numPending++;
|
|
226
227
|
} else {
|
|
227
|
-
|
|
228
|
+
resetActions.actions[i] = ReadRequestActionEnum.SKIP;
|
|
228
229
|
}
|
|
229
|
-
} else if (
|
|
230
|
+
} else if (action === ReadRequestActionEnum.READ_AS_SETTLED) {
|
|
230
231
|
if (numSettled < maxSettled) {
|
|
231
232
|
numSettled++;
|
|
232
233
|
} else {
|
|
233
|
-
|
|
234
|
+
resetActions.actions[i] = ReadRequestActionEnum.SKIP;
|
|
234
235
|
}
|
|
235
236
|
}
|
|
236
237
|
}
|
|
237
238
|
|
|
238
|
-
|
|
239
|
+
resetActions.pendingReadHints = resetActions.pendingReadHints.slice(0, maxPending);
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
private needsResetNoteHashReadRequests(forceResetAll = false) {
|
|
242
|
-
const numCurr =
|
|
243
|
-
const numNext = this.nextIteration ?
|
|
243
|
+
const numCurr = this.previousKernel.validationRequests.noteHashReadRequests.claimedLength;
|
|
244
|
+
const numNext = this.nextIteration ? this.nextIteration.noteHashReadRequests.claimedLength : 0;
|
|
244
245
|
const maxAmountToKeep = !this.nextIteration || forceResetAll ? 0 : MAX_NOTE_HASH_READ_REQUESTS_PER_TX;
|
|
245
246
|
if (numCurr + numNext <= maxAmountToKeep) {
|
|
246
247
|
return false;
|
|
247
248
|
}
|
|
248
249
|
|
|
249
250
|
const futureNoteHashes = collectNested(this.executionStack, executionResult => {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
noteHash => new ScopedNoteHash(noteHash, executionResult.publicInputs.callContext.contractAddress)
|
|
253
|
-
);
|
|
251
|
+
return executionResult.publicInputs.noteHashes
|
|
252
|
+
.getActiveItems()
|
|
253
|
+
.map(noteHash => new ScopedNoteHash(noteHash, executionResult.publicInputs.callContext.contractAddress));
|
|
254
254
|
});
|
|
255
255
|
|
|
256
|
-
const
|
|
256
|
+
const resetActions = getNoteHashReadRequestResetActions(
|
|
257
257
|
this.previousKernel.validationRequests.noteHashReadRequests,
|
|
258
258
|
this.previousKernel.end.noteHashes,
|
|
259
259
|
futureNoteHashes,
|
|
260
260
|
);
|
|
261
261
|
|
|
262
|
-
const numPendingReads =
|
|
263
|
-
const numSettledReads =
|
|
264
|
-
(accum,
|
|
262
|
+
const numPendingReads = resetActions.pendingReadHints.length;
|
|
263
|
+
const numSettledReads = resetActions.actions.reduce(
|
|
264
|
+
(accum, action) => accum + (action === ReadRequestActionEnum.READ_AS_SETTLED ? 1 : 0),
|
|
265
265
|
0,
|
|
266
266
|
);
|
|
267
267
|
|
|
268
268
|
if (!this.nextIteration) {
|
|
269
|
-
this.
|
|
269
|
+
this.noteHashResetActions = resetActions;
|
|
270
270
|
this.requestedDimensions.NOTE_HASH_PENDING_READ = numPendingReads;
|
|
271
271
|
this.requestedDimensions.NOTE_HASH_SETTLED_READ = numSettledReads;
|
|
272
272
|
} else {
|
|
273
273
|
// Pick only one dimension to reset if next iteration is not empty.
|
|
274
274
|
if (numPendingReads > numSettledReads) {
|
|
275
275
|
this.requestedDimensions.NOTE_HASH_PENDING_READ = numPendingReads;
|
|
276
|
-
this.
|
|
277
|
-
|
|
276
|
+
this.noteHashResetActions.actions = assertLength(
|
|
277
|
+
resetActions.actions.map(action =>
|
|
278
|
+
action === ReadRequestActionEnum.READ_AS_PENDING ? action : ReadRequestActionEnum.SKIP,
|
|
279
|
+
),
|
|
278
280
|
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
279
281
|
);
|
|
280
|
-
this.
|
|
282
|
+
this.noteHashResetActions.pendingReadHints = resetActions.pendingReadHints;
|
|
281
283
|
} else {
|
|
282
284
|
this.requestedDimensions.NOTE_HASH_SETTLED_READ = numSettledReads;
|
|
283
|
-
this.
|
|
284
|
-
|
|
285
|
+
this.noteHashResetActions.actions = assertLength(
|
|
286
|
+
resetActions.actions.map(action =>
|
|
287
|
+
action === ReadRequestActionEnum.READ_AS_SETTLED ? action : ReadRequestActionEnum.SKIP,
|
|
288
|
+
),
|
|
285
289
|
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
286
290
|
);
|
|
287
291
|
}
|
|
@@ -291,49 +295,52 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
291
295
|
}
|
|
292
296
|
|
|
293
297
|
private needsResetNullifierReadRequests(forceResetAll = false) {
|
|
294
|
-
const numCurr =
|
|
295
|
-
const numNext = this.nextIteration ?
|
|
298
|
+
const numCurr = this.previousKernel.validationRequests.nullifierReadRequests.claimedLength;
|
|
299
|
+
const numNext = this.nextIteration ? this.nextIteration.nullifierReadRequests.claimedLength : 0;
|
|
296
300
|
const maxAmountToKeep = !this.nextIteration || forceResetAll ? 0 : MAX_NULLIFIER_READ_REQUESTS_PER_TX;
|
|
297
301
|
if (numCurr + numNext <= maxAmountToKeep) {
|
|
298
302
|
return false;
|
|
299
303
|
}
|
|
300
304
|
|
|
301
305
|
const futureNullifiers = collectNested(this.executionStack, executionResult => {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
nullifier => new ScopedNullifier(nullifier, executionResult.publicInputs.callContext.contractAddress)
|
|
305
|
-
);
|
|
306
|
+
return executionResult.publicInputs.nullifiers
|
|
307
|
+
.getActiveItems()
|
|
308
|
+
.map(nullifier => new ScopedNullifier(nullifier, executionResult.publicInputs.callContext.contractAddress));
|
|
306
309
|
});
|
|
307
310
|
|
|
308
|
-
const
|
|
311
|
+
const resetActions = getNullifierReadRequestResetActions(
|
|
309
312
|
this.previousKernel.validationRequests.nullifierReadRequests,
|
|
310
313
|
this.previousKernel.end.nullifiers,
|
|
311
314
|
futureNullifiers,
|
|
312
315
|
);
|
|
313
316
|
|
|
314
|
-
const numPendingReads =
|
|
315
|
-
const numSettledReads =
|
|
316
|
-
(accum,
|
|
317
|
+
const numPendingReads = resetActions.pendingReadHints.length;
|
|
318
|
+
const numSettledReads = resetActions.actions.reduce(
|
|
319
|
+
(accum, action) => accum + (action === ReadRequestActionEnum.READ_AS_SETTLED ? 1 : 0),
|
|
317
320
|
0,
|
|
318
321
|
);
|
|
319
322
|
|
|
320
323
|
if (!this.nextIteration) {
|
|
321
|
-
this.
|
|
324
|
+
this.nullifierResetActions = resetActions;
|
|
322
325
|
this.requestedDimensions.NULLIFIER_PENDING_READ = numPendingReads;
|
|
323
326
|
this.requestedDimensions.NULLIFIER_SETTLED_READ = numSettledReads;
|
|
324
327
|
} else {
|
|
325
328
|
// Pick only one dimension to reset if next iteration is not empty.
|
|
326
329
|
if (numPendingReads > numSettledReads) {
|
|
327
330
|
this.requestedDimensions.NULLIFIER_PENDING_READ = numPendingReads;
|
|
328
|
-
this.
|
|
329
|
-
|
|
331
|
+
this.nullifierResetActions.actions = assertLength(
|
|
332
|
+
resetActions.actions.map(action =>
|
|
333
|
+
action === ReadRequestActionEnum.READ_AS_PENDING ? action : ReadRequestActionEnum.SKIP,
|
|
334
|
+
),
|
|
330
335
|
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
331
336
|
);
|
|
332
|
-
this.
|
|
337
|
+
this.nullifierResetActions.pendingReadHints = resetActions.pendingReadHints;
|
|
333
338
|
} else {
|
|
334
339
|
this.requestedDimensions.NULLIFIER_SETTLED_READ = numSettledReads;
|
|
335
|
-
this.
|
|
336
|
-
|
|
340
|
+
this.nullifierResetActions.actions = assertLength(
|
|
341
|
+
resetActions.actions.map(action =>
|
|
342
|
+
action === ReadRequestActionEnum.READ_AS_SETTLED ? action : ReadRequestActionEnum.SKIP,
|
|
343
|
+
),
|
|
337
344
|
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
338
345
|
);
|
|
339
346
|
}
|
|
@@ -343,12 +350,8 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
343
350
|
}
|
|
344
351
|
|
|
345
352
|
private needsResetNullifierKeys() {
|
|
346
|
-
const numCurr =
|
|
347
|
-
|
|
348
|
-
);
|
|
349
|
-
const numNext = this.nextIteration
|
|
350
|
-
? countAccumulatedItems(this.nextIteration.keyValidationRequestsAndGenerators)
|
|
351
|
-
: 0;
|
|
353
|
+
const numCurr = this.previousKernel.validationRequests.scopedKeyValidationRequestsAndGenerators.claimedLength;
|
|
354
|
+
const numNext = this.nextIteration ? this.nextIteration.keyValidationRequestsAndGenerators.claimedLength : 0;
|
|
352
355
|
const maxAmountToKeep = !this.nextIteration ? 0 : MAX_KEY_VALIDATION_REQUESTS_PER_TX;
|
|
353
356
|
if (numCurr + numNext <= maxAmountToKeep) {
|
|
354
357
|
return false;
|
|
@@ -364,16 +367,13 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
364
367
|
this.numTransientData = 0;
|
|
365
368
|
|
|
366
369
|
const nextAccumNoteHashes =
|
|
367
|
-
|
|
368
|
-
countAccumulatedItems(this.nextIteration?.noteHashes ?? []);
|
|
370
|
+
this.previousKernel.end.noteHashes.claimedLength + (this.nextIteration?.noteHashes.claimedLength ?? 0);
|
|
369
371
|
const noteHashWillOverflow = nextAccumNoteHashes > MAX_NOTE_HASHES_PER_TX;
|
|
370
372
|
const nextAccumNullifiers =
|
|
371
|
-
|
|
372
|
-
countAccumulatedItems(this.nextIteration?.nullifiers ?? []);
|
|
373
|
+
this.previousKernel.end.nullifiers.claimedLength + (this.nextIteration?.nullifiers.claimedLength ?? 0);
|
|
373
374
|
const nullifierWillOverflow = nextAccumNullifiers > MAX_NULLIFIERS_PER_TX;
|
|
374
375
|
const nextAccumLogs =
|
|
375
|
-
|
|
376
|
-
countAccumulatedItems(this.nextIteration?.privateLogs ?? []);
|
|
376
|
+
this.previousKernel.end.privateLogs.claimedLength + (this.nextIteration?.privateLogs.claimedLength ?? 0);
|
|
377
377
|
const logsWillOverflow = nextAccumLogs > MAX_PRIVATE_LOGS_PER_TX;
|
|
378
378
|
|
|
379
379
|
if (this.nextIteration && !noteHashWillOverflow && !nullifierWillOverflow && !logsWillOverflow) {
|
|
@@ -388,26 +388,22 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
388
388
|
this.executionStack,
|
|
389
389
|
executionResult => executionResult.publicInputs.nullifierReadRequests,
|
|
390
390
|
);
|
|
391
|
+
// TODO(#15902): Collect future logs and only allow squashing a note hash when all its logs have been emitted
|
|
392
|
+
// (i.e. none of the future logs are linked to the to-be-squashed note hashes).
|
|
391
393
|
if (this.nextIteration) {
|
|
392
394
|
// If it's not the final reset, only one dimension will be reset at a time.
|
|
393
395
|
// The note hashes and nullifiers for the remaining read requests can't be squashed.
|
|
394
|
-
futureNoteHashReads.push(
|
|
395
|
-
|
|
396
|
-
);
|
|
397
|
-
futureNullifierReads.push(
|
|
398
|
-
...this.previousKernel.validationRequests.nullifierReadRequests.filter(r => !r.isEmpty()),
|
|
399
|
-
);
|
|
396
|
+
futureNoteHashReads.push(...this.previousKernel.validationRequests.noteHashReadRequests.getActiveItems());
|
|
397
|
+
futureNullifierReads.push(...this.previousKernel.validationRequests.nullifierReadRequests.getActiveItems());
|
|
400
398
|
}
|
|
401
399
|
|
|
402
|
-
const { numTransientData, hints:
|
|
400
|
+
const { numTransientData, hints: transientDataSquashingHints } = buildTransientDataHints(
|
|
403
401
|
this.previousKernel.end.noteHashes,
|
|
404
402
|
this.previousKernel.end.nullifiers,
|
|
405
403
|
futureNoteHashReads,
|
|
406
404
|
futureNullifierReads,
|
|
407
405
|
this.noteHashNullifierCounterMap,
|
|
408
406
|
this.validationRequestsSplitCounter,
|
|
409
|
-
MAX_NOTE_HASHES_PER_TX,
|
|
410
|
-
MAX_NULLIFIERS_PER_TX,
|
|
411
407
|
);
|
|
412
408
|
|
|
413
409
|
if (this.nextIteration && !numTransientData) {
|
|
@@ -430,7 +426,7 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
430
426
|
}
|
|
431
427
|
|
|
432
428
|
this.numTransientData = numTransientData;
|
|
433
|
-
this.
|
|
429
|
+
this.transientDataSquashingHints = transientDataSquashingHints;
|
|
434
430
|
this.requestedDimensions.TRANSIENT_DATA_SQUASHING = numTransientData;
|
|
435
431
|
|
|
436
432
|
return numTransientData > 0;
|
|
@@ -441,7 +437,9 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
441
437
|
throw new Error('`needsResetTransientData` must be run before `needsSiloNoteHashes`.');
|
|
442
438
|
}
|
|
443
439
|
|
|
444
|
-
const numNoteHashes = this.previousKernel.end.noteHashes
|
|
440
|
+
const numNoteHashes = this.previousKernel.end.noteHashes
|
|
441
|
+
.getActiveItems()
|
|
442
|
+
.filter(n => !n.contractAddress.isZero()).length;
|
|
445
443
|
const numToSilo = Math.max(0, numNoteHashes - this.numTransientData);
|
|
446
444
|
this.requestedDimensions.NOTE_HASH_SILOING = numToSilo;
|
|
447
445
|
|
|
@@ -453,7 +451,9 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
453
451
|
throw new Error('`needsResetTransientData` must be run before `needsSiloNullifiers`.');
|
|
454
452
|
}
|
|
455
453
|
|
|
456
|
-
const numNullifiers = this.previousKernel.end.nullifiers
|
|
454
|
+
const numNullifiers = this.previousKernel.end.nullifiers
|
|
455
|
+
.getActiveItems()
|
|
456
|
+
.filter(n => !n.contractAddress.isZero()).length;
|
|
457
457
|
const numToSilo = Math.max(0, numNullifiers - this.numTransientData);
|
|
458
458
|
// Include the first nullifier if there's something to silo.
|
|
459
459
|
// The reset circuit checks that capped_size must be greater than or equal to all non-empty nullifiers.
|
|
@@ -470,13 +470,15 @@ export class PrivateKernelResetPrivateInputsBuilder {
|
|
|
470
470
|
}
|
|
471
471
|
|
|
472
472
|
const privateLogs = this.previousKernel.end.privateLogs;
|
|
473
|
-
const numLogs = privateLogs.filter(l => !l.contractAddress.isZero()).length;
|
|
473
|
+
const numLogs = privateLogs.getActiveItems().filter(l => !l.contractAddress.isZero()).length;
|
|
474
474
|
|
|
475
475
|
const noteHashes = this.previousKernel.end.noteHashes;
|
|
476
|
-
const squashedNoteHashCounters = this.
|
|
477
|
-
.filter(h => h.noteHashIndex < noteHashes.
|
|
478
|
-
.map(h => noteHashes[h.noteHashIndex].counter);
|
|
479
|
-
const numSquashedLogs = privateLogs
|
|
476
|
+
const squashedNoteHashCounters = this.transientDataSquashingHints
|
|
477
|
+
.filter(h => h.noteHashIndex < noteHashes.claimedLength)
|
|
478
|
+
.map(h => noteHashes.array[h.noteHashIndex].counter);
|
|
479
|
+
const numSquashedLogs = privateLogs
|
|
480
|
+
.getActiveItems()
|
|
481
|
+
.filter(l => squashedNoteHashCounters.includes(l.inner.noteHashCounter)).length;
|
|
480
482
|
|
|
481
483
|
const numToSilo = numLogs - numSquashedLogs;
|
|
482
484
|
this.requestedDimensions.PRIVATE_LOG_SILOING = numToSilo;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { MAX_INCLUDE_BY_TIMESTAMP_DURATION } from '@aztec/constants';
|
|
2
|
+
import type { PrivateKernelCircuitPublicInputs } from '@aztec/stdlib/kernel';
|
|
3
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
4
|
+
|
|
5
|
+
const ROUNDED_DURATIONS = [
|
|
6
|
+
3600, // 1 hour
|
|
7
|
+
1800, // 30 mins
|
|
8
|
+
1, // 1 second
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
function roundTimestamp(blockTimestamp: bigint, includeByTimestamp: bigint): UInt64 {
|
|
12
|
+
return ROUNDED_DURATIONS.reduce((timestamp, duration) => {
|
|
13
|
+
if (timestamp <= blockTimestamp) {
|
|
14
|
+
// The timestamp must be greater than the block timestamp.
|
|
15
|
+
// If it is too small, round it down again using a smaller duration.
|
|
16
|
+
const totalDuration = includeByTimestamp - blockTimestamp;
|
|
17
|
+
const roundedDuration = totalDuration - (totalDuration % BigInt(duration));
|
|
18
|
+
return blockTimestamp + roundedDuration;
|
|
19
|
+
}
|
|
20
|
+
return timestamp;
|
|
21
|
+
}, 0n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function computeTxIncludeByTimestamp(
|
|
25
|
+
previousKernel: PrivateKernelCircuitPublicInputs,
|
|
26
|
+
maxDuration = MAX_INCLUDE_BY_TIMESTAMP_DURATION,
|
|
27
|
+
): UInt64 {
|
|
28
|
+
if (maxDuration > MAX_INCLUDE_BY_TIMESTAMP_DURATION) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Custom max duration cannot be greater than the max allowed. Max allowed: ${MAX_INCLUDE_BY_TIMESTAMP_DURATION}. Custom value: ${maxDuration}.`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const blockTimestamp = previousKernel.constants.historicalHeader.globalVariables.timestamp;
|
|
35
|
+
const maxTimestamp = blockTimestamp + BigInt(maxDuration);
|
|
36
|
+
const includeByTimestamp = previousKernel.includeByTimestamp;
|
|
37
|
+
|
|
38
|
+
// If the includeByTimestamp set during the tx execution is greater than or equal to the max allowed duration,
|
|
39
|
+
// use the maximum allowed timestamp.
|
|
40
|
+
// Note: It shouldn't be larger than the max allowed duration, but we check for it anyway.
|
|
41
|
+
if (includeByTimestamp >= maxTimestamp) {
|
|
42
|
+
return maxTimestamp;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Round it down to the nearest hour/min/second to reduce precision and avoid revealing the exact value.
|
|
46
|
+
// This makes it harder for others to infer what function calls may have been used to produce a specific timestamp.
|
|
47
|
+
const roundedTimestamp = roundTimestamp(blockTimestamp, includeByTimestamp);
|
|
48
|
+
|
|
49
|
+
// The tx can't be published if the timestamp is the same or less than the historical block's timestamp.
|
|
50
|
+
// Future blocks will have a greater timestamp, so the tx would never be included.
|
|
51
|
+
if (roundedTimestamp <= blockTimestamp) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`Include-by timestamp must be greater than the historical block timestamp. Block timestamp: ${blockTimestamp}. Include-by timestamp: ${includeByTimestamp}.`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return roundedTimestamp;
|
|
58
|
+
}
|
|
@@ -50,7 +50,7 @@ export interface PrivateKernelExecutionProverConfig {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
|
-
* The
|
|
53
|
+
* The PrivateKernelExecutionProver class is responsible for taking a transaction request and sequencing the
|
|
54
54
|
* the execution of the private functions within, sequenced with private kernel "glue" to check protocol rules.
|
|
55
55
|
* The result can be a client IVC proof of the private transaction portion, or just a simulation that can e.g.
|
|
56
56
|
* inform state tree updates.
|
|
@@ -91,6 +91,8 @@ export class PrivateKernelExecutionProver {
|
|
|
91
91
|
|
|
92
92
|
const isPrivateOnlyTx = executionResult.publicFunctionCalldata.length === 0;
|
|
93
93
|
|
|
94
|
+
// Initialise an executionStack, beginning with the PrivateCallExecutionResult
|
|
95
|
+
// of the entrypoint function of the tx.
|
|
94
96
|
const executionStack = [executionResult.entrypoint];
|
|
95
97
|
let firstIteration = true;
|
|
96
98
|
|
|
@@ -138,7 +140,7 @@ export class PrivateKernelExecutionProver {
|
|
|
138
140
|
|
|
139
141
|
const currentExecution = executionStack.pop()!;
|
|
140
142
|
|
|
141
|
-
executionStack.push(...[...currentExecution.
|
|
143
|
+
executionStack.push(...[...currentExecution.nestedExecutionResults].reverse());
|
|
142
144
|
|
|
143
145
|
const functionName = await this.oracle.getDebugFunctionName(
|
|
144
146
|
currentExecution.publicInputs.callContext.contractAddress,
|
|
@@ -270,9 +272,24 @@ export class PrivateKernelExecutionProver {
|
|
|
270
272
|
`Calling private kernel tail with hwm ${previousKernelData.publicInputs.minRevertibleSideEffectCounter}`,
|
|
271
273
|
);
|
|
272
274
|
|
|
273
|
-
// TODO: Enable padding
|
|
275
|
+
// TODO: Enable padding once we better understand the final amounts to pad to.
|
|
274
276
|
const paddedSideEffectAmounts = PaddedSideEffectAmounts.empty();
|
|
275
|
-
|
|
277
|
+
|
|
278
|
+
// Use the aggregated includeByTimestamp set throughout the tx execution.
|
|
279
|
+
// TODO: Call `computeTxIncludeByTimestamp` to round the value down and reduce precision, improving privacy.
|
|
280
|
+
const includeByTimestampUpperBound = previousKernelData.publicInputs.includeByTimestamp;
|
|
281
|
+
const blockTimestamp = previousKernelData.publicInputs.constants.historicalHeader.globalVariables.timestamp;
|
|
282
|
+
if (includeByTimestampUpperBound <= blockTimestamp) {
|
|
283
|
+
throw new Error(
|
|
284
|
+
`Include-by timestamp must be greater than the historical block timestamp. Block timestamp: ${blockTimestamp}. Include-by timestamp: ${includeByTimestampUpperBound}.`,
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const privateInputs = new PrivateKernelTailCircuitPrivateInputs(
|
|
289
|
+
previousKernelData,
|
|
290
|
+
paddedSideEffectAmounts,
|
|
291
|
+
includeByTimestampUpperBound,
|
|
292
|
+
);
|
|
276
293
|
|
|
277
294
|
pushTestData('private-kernel-inputs-ordering', privateInputs);
|
|
278
295
|
|
|
@@ -66,6 +66,6 @@ export interface PrivateKernelOracle {
|
|
|
66
66
|
getDebugFunctionName(contractAddress: AztecAddress, selector: FunctionSelector): Promise<string | undefined>;
|
|
67
67
|
|
|
68
68
|
/** Returns a membership witness and leaf index to our public data indexed merkle tree,
|
|
69
|
-
* along with an associated
|
|
69
|
+
* along with an associated DelayedPublicMutable containing the class ID to update. */
|
|
70
70
|
getUpdatedClassIdHints(contractAddress: AztecAddress): Promise<UpdatedClassIdHints>;
|
|
71
71
|
}
|
|
@@ -10,10 +10,10 @@ import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
|
10
10
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
11
11
|
import type { L2BlockNumber } from '@aztec/stdlib/block';
|
|
12
12
|
import { computeContractClassIdPreimage, computeSaltedInitializationHash } from '@aztec/stdlib/contract';
|
|
13
|
+
import { DelayedPublicMutableValues, DelayedPublicMutableValuesWithHash } from '@aztec/stdlib/delayed-public-mutable';
|
|
13
14
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
14
15
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
15
16
|
import { UpdatedClassIdHints } from '@aztec/stdlib/kernel';
|
|
16
|
-
import { SharedMutableValues, SharedMutableValuesWithHash } from '@aztec/stdlib/shared-mutable';
|
|
17
17
|
import type { NullifierMembershipWitness } from '@aztec/stdlib/trees';
|
|
18
18
|
import type { VerificationKeyAsFields } from '@aztec/stdlib/vks';
|
|
19
19
|
|
|
@@ -22,10 +22,10 @@ import type { PrivateKernelOracle } from './private_kernel_oracle.js';
|
|
|
22
22
|
|
|
23
23
|
// TODO: Block number should not be "latest".
|
|
24
24
|
// It should be fixed at the time the proof is being simulated. I.e., it should be the same as the value defined in the constant data.
|
|
25
|
+
|
|
25
26
|
/**
|
|
26
27
|
* A data oracle that provides information needed for simulating a transaction.
|
|
27
28
|
*/
|
|
28
|
-
|
|
29
29
|
export class PrivateKernelOracleImpl implements PrivateKernelOracle {
|
|
30
30
|
constructor(
|
|
31
31
|
private contractDataProvider: ContractDataProvider,
|
|
@@ -99,12 +99,12 @@ export class PrivateKernelOracleImpl implements PrivateKernelOracle {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
public async getUpdatedClassIdHints(contractAddress: AztecAddress): Promise<UpdatedClassIdHints> {
|
|
102
|
-
const {
|
|
103
|
-
await
|
|
102
|
+
const { delayedPublicMutableSlot, delayedPublicMutableHashSlot } =
|
|
103
|
+
await DelayedPublicMutableValuesWithHash.getContractUpdateSlots(contractAddress);
|
|
104
104
|
|
|
105
105
|
const hashLeafSlot = await computePublicDataTreeLeafSlot(
|
|
106
|
-
ProtocolContractAddress.
|
|
107
|
-
|
|
106
|
+
ProtocolContractAddress.ContractInstanceRegistry,
|
|
107
|
+
delayedPublicMutableHashSlot,
|
|
108
108
|
);
|
|
109
109
|
const updatedClassIdWitness = await this.node.getPublicDataWitness(this.blockNumber, hashLeafSlot);
|
|
110
110
|
|
|
@@ -113,8 +113,11 @@ export class PrivateKernelOracleImpl implements PrivateKernelOracle {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
const readStorage = (storageSlot: Fr) =>
|
|
116
|
-
this.node.getPublicStorageAt(this.blockNumber, ProtocolContractAddress.
|
|
117
|
-
const
|
|
116
|
+
this.node.getPublicStorageAt(this.blockNumber, ProtocolContractAddress.ContractInstanceRegistry, storageSlot);
|
|
117
|
+
const delayedPublicMutableValues = await DelayedPublicMutableValues.readFromTree(
|
|
118
|
+
delayedPublicMutableSlot,
|
|
119
|
+
readStorage,
|
|
120
|
+
);
|
|
118
121
|
|
|
119
122
|
return new UpdatedClassIdHints(
|
|
120
123
|
new MembershipWitness(
|
|
@@ -123,7 +126,7 @@ export class PrivateKernelOracleImpl implements PrivateKernelOracle {
|
|
|
123
126
|
updatedClassIdWitness.siblingPath.toTuple(),
|
|
124
127
|
),
|
|
125
128
|
updatedClassIdWitness.leafPreimage,
|
|
126
|
-
|
|
129
|
+
delayedPublicMutableValues,
|
|
127
130
|
);
|
|
128
131
|
}
|
|
129
132
|
}
|
|
@@ -19,6 +19,7 @@ export async function enrichSimulationError(
|
|
|
19
19
|
// Maps contract addresses to the set of function selectors that were in error.
|
|
20
20
|
// Map and Set do reference equality for their keys instead of value equality, so we store the string
|
|
21
21
|
// representation to get e.g. different contract address objects with the same address value to match.
|
|
22
|
+
// eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
|
|
22
23
|
const mentionedFunctions: Map<string, Set<FunctionSelector>> = new Map();
|
|
23
24
|
|
|
24
25
|
err.getCallStack().forEach(({ contractAddress, functionSelector }) => {
|