@aztec/pxe 0.0.1-commit.4eabbdb → 0.0.1-commit.5358163d3
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/contract_function_simulator/contract_function_simulator.d.ts +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.d.ts.map +1 -1
- package/dest/contract_function_simulator/contract_function_simulator.js +6 -6
- package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts +5 -5
- package/dest/contract_function_simulator/execution_tagging_index_cache.d.ts.map +1 -1
- package/dest/contract_function_simulator/execution_tagging_index_cache.js +3 -3
- package/dest/contract_function_simulator/noir-structs/event_validation_request.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/private_execution_oracle.d.ts +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/private_execution_oracle.js +10 -18
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +4 -7
- package/dest/contract_logging.d.ts +22 -0
- package/dest/contract_logging.d.ts.map +1 -0
- package/dest/contract_logging.js +23 -0
- package/dest/entrypoints/client/bundle/index.d.ts +2 -1
- package/dest/entrypoints/client/bundle/index.d.ts.map +1 -1
- package/dest/entrypoints/client/bundle/index.js +1 -0
- package/dest/entrypoints/client/lazy/index.d.ts +2 -1
- package/dest/entrypoints/client/lazy/index.d.ts.map +1 -1
- package/dest/entrypoints/client/lazy/index.js +1 -0
- package/dest/logs/log_service.d.ts +1 -1
- package/dest/logs/log_service.d.ts.map +1 -1
- package/dest/logs/log_service.js +4 -4
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts +4 -3
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.d.ts.map +1 -1
- package/dest/private_kernel/hints/private_kernel_reset_private_inputs_builder.js +125 -64
- package/dest/private_kernel/hints/test_utils.d.ts +122 -0
- package/dest/private_kernel/hints/test_utils.d.ts.map +1 -0
- package/dest/private_kernel/hints/test_utils.js +203 -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 -5
- package/dest/private_kernel/private_kernel_oracle.d.ts +6 -2
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_oracle.js +7 -3
- package/dest/pxe.d.ts +3 -2
- package/dest/pxe.d.ts.map +1 -1
- package/dest/pxe.js +24 -16
- package/dest/storage/contract_store/contract_store.d.ts +42 -15
- package/dest/storage/contract_store/contract_store.d.ts.map +1 -1
- package/dest/storage/contract_store/contract_store.js +140 -64
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts +6 -6
- package/dest/storage/tagging_store/recipient_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.d.ts +5 -5
- package/dest/storage/tagging_store/sender_tagging_store.d.ts.map +1 -1
- package/dest/storage/tagging_store/sender_tagging_store.js +4 -4
- package/dest/tagging/index.d.ts +2 -2
- package/dest/tagging/index.d.ts.map +1 -1
- package/dest/tagging/index.js +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts +4 -5
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.js +3 -3
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts +6 -7
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.d.ts.map +1 -1
- package/dest/tagging/recipient_sync/utils/load_logs_for_range.js +12 -11
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts +4 -8
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/sync_sender_tagging_indexes.js +3 -6
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts +4 -7
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.d.ts.map +1 -1
- package/dest/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.js +14 -15
- package/package.json +16 -16
- package/src/contract_function_simulator/contract_function_simulator.ts +12 -13
- package/src/contract_function_simulator/execution_tagging_index_cache.ts +5 -5
- package/src/contract_function_simulator/noir-structs/event_validation_request.ts +1 -1
- package/src/contract_function_simulator/noir-structs/note_validation_request.ts +1 -1
- package/src/contract_function_simulator/oracle/private_execution_oracle.ts +14 -20
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +8 -7
- package/src/contract_logging.ts +39 -0
- package/src/entrypoints/client/bundle/index.ts +1 -0
- package/src/entrypoints/client/lazy/index.ts +1 -0
- package/src/logs/log_service.ts +10 -5
- package/src/private_kernel/hints/private_kernel_reset_private_inputs_builder.ts +157 -110
- package/src/private_kernel/hints/test_utils.ts +325 -0
- package/src/private_kernel/private_kernel_execution_prover.ts +13 -6
- package/src/private_kernel/private_kernel_oracle.ts +7 -7
- package/src/pxe.ts +23 -16
- package/src/storage/contract_store/contract_store.ts +170 -71
- package/src/storage/tagging_store/recipient_tagging_store.ts +9 -5
- package/src/storage/tagging_store/sender_tagging_store.ts +8 -8
- package/src/tagging/index.ts +1 -1
- package/src/tagging/recipient_sync/load_private_logs_for_sender_recipient_pair.ts +3 -6
- package/src/tagging/recipient_sync/utils/load_logs_for_range.ts +10 -15
- package/src/tagging/sender_sync/sync_sender_tagging_indexes.ts +4 -9
- package/src/tagging/sender_sync/utils/load_and_store_new_tagging_indexes.ts +11 -20
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_KEY_VALIDATION_REQUESTS_PER_CALL,
|
|
3
|
+
MAX_KEY_VALIDATION_REQUESTS_PER_TX,
|
|
4
|
+
MAX_NOTE_HASHES_PER_CALL,
|
|
5
|
+
MAX_NOTE_HASHES_PER_TX,
|
|
6
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,
|
|
7
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
8
|
+
MAX_NULLIFIERS_PER_CALL,
|
|
9
|
+
MAX_NULLIFIERS_PER_TX,
|
|
10
|
+
MAX_NULLIFIER_READ_REQUESTS_PER_CALL,
|
|
11
|
+
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
12
|
+
MAX_PRIVATE_LOGS_PER_CALL,
|
|
13
|
+
MAX_PRIVATE_LOGS_PER_TX,
|
|
14
|
+
} from '@aztec/constants';
|
|
15
|
+
import { makeTuple } from '@aztec/foundation/array';
|
|
16
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
17
|
+
import { Point } from '@aztec/foundation/curves/grumpkin';
|
|
18
|
+
import type { Serializable } from '@aztec/foundation/serialize';
|
|
19
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
20
|
+
import {
|
|
21
|
+
ClaimedLengthArray,
|
|
22
|
+
KeyValidationRequest,
|
|
23
|
+
KeyValidationRequestAndSeparator,
|
|
24
|
+
NoteHash,
|
|
25
|
+
Nullifier,
|
|
26
|
+
PrivateCircuitPublicInputs,
|
|
27
|
+
PrivateKernelCircuitPublicInputs,
|
|
28
|
+
type PrivateKernelSimulateOutput,
|
|
29
|
+
ReadRequest,
|
|
30
|
+
ScopedKeyValidationRequestAndSeparator,
|
|
31
|
+
ScopedNoteHash,
|
|
32
|
+
ScopedNullifier,
|
|
33
|
+
ScopedReadRequest,
|
|
34
|
+
} from '@aztec/stdlib/kernel';
|
|
35
|
+
import { PrivateLogData, ScopedPrivateLogData } from '@aztec/stdlib/kernel';
|
|
36
|
+
import { PrivateLog } from '@aztec/stdlib/logs';
|
|
37
|
+
import { PrivateCallExecutionResult } from '@aztec/stdlib/tx';
|
|
38
|
+
import { VerificationKeyData } from '@aztec/stdlib/vks';
|
|
39
|
+
|
|
40
|
+
const DEFAULT_CONTRACT_ADDRESS = AztecAddress.fromBigInt(987654n);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Builds a ClaimedLengthArray from a list of items, padding to the required size.
|
|
44
|
+
*/
|
|
45
|
+
function makeClaimed<T extends Serializable, N extends number>(items: T[], emptyFactory: { empty(): T }, maxSize: N) {
|
|
46
|
+
const padded = makeTuple(maxSize, i => items[i] ?? emptyFactory.empty());
|
|
47
|
+
return new ClaimedLengthArray<T, typeof maxSize>(padded, items.length);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Builder for PrivateKernelCircuitPublicInputs with fluent API for adding side effects. */
|
|
51
|
+
export class PrivateKernelCircuitPublicInputsBuilder {
|
|
52
|
+
private noteHashes: ScopedNoteHash[] = [];
|
|
53
|
+
private nullifiers: ScopedNullifier[] = [];
|
|
54
|
+
private noteHashReadRequests: ScopedReadRequest[] = [];
|
|
55
|
+
private nullifierReadRequests: ScopedReadRequest[] = [];
|
|
56
|
+
private keyValidationRequests: ScopedKeyValidationRequestAndSeparator[] = [];
|
|
57
|
+
private privateLogs: ScopedPrivateLogData[] = [];
|
|
58
|
+
private nextCounter: number;
|
|
59
|
+
|
|
60
|
+
constructor(
|
|
61
|
+
private contractAddress: AztecAddress = DEFAULT_CONTRACT_ADDRESS,
|
|
62
|
+
startCounter = 1,
|
|
63
|
+
) {
|
|
64
|
+
this.nextCounter = startCounter;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private getCounter(sideEffectCounter?: number): number {
|
|
68
|
+
if (sideEffectCounter !== undefined) {
|
|
69
|
+
this.nextCounter = sideEffectCounter + 1;
|
|
70
|
+
return sideEffectCounter;
|
|
71
|
+
}
|
|
72
|
+
return this.nextCounter++;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Adds a note hash to the accumulated data. Defaults are generated randomly. */
|
|
76
|
+
addNoteHash(opts?: { value?: Fr; counter?: number; contractAddress?: AztecAddress }): this {
|
|
77
|
+
const value = opts?.value ?? Fr.random();
|
|
78
|
+
const counter = this.getCounter(opts?.counter);
|
|
79
|
+
const addr = opts?.contractAddress ?? this.contractAddress;
|
|
80
|
+
this.noteHashes.push(new NoteHash(value, counter).scope(addr));
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Adds a nullifier to the accumulated data. Defaults are generated randomly. */
|
|
85
|
+
addNullifier(opts?: { value?: Fr; noteHash?: Fr; counter?: number; contractAddress?: AztecAddress }): this {
|
|
86
|
+
const value = opts?.value ?? Fr.random();
|
|
87
|
+
const noteHash = opts?.noteHash ?? Fr.ZERO;
|
|
88
|
+
const counter = this.getCounter(opts?.counter);
|
|
89
|
+
const addr = opts?.contractAddress ?? this.contractAddress;
|
|
90
|
+
this.nullifiers.push(new Nullifier(value, noteHash, counter).scope(addr));
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Adds a pending note hash read request (non-empty contract address, can match a pending note hash). */
|
|
95
|
+
addPendingNoteHashReadRequest(opts?: { value?: Fr; counter?: number; contractAddress?: AztecAddress }): this {
|
|
96
|
+
const value = opts?.value ?? Fr.random();
|
|
97
|
+
const counter = this.getCounter(opts?.counter);
|
|
98
|
+
const addr = opts?.contractAddress ?? this.contractAddress;
|
|
99
|
+
this.noteHashReadRequests.push(new ScopedReadRequest(new ReadRequest(value, counter), addr));
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Adds a settled note hash read request (empty contract address, resolved against the note hash tree). */
|
|
104
|
+
addSettledNoteHashReadRequest(opts?: { value?: Fr; counter?: number }): this {
|
|
105
|
+
const value = opts?.value ?? Fr.random();
|
|
106
|
+
const counter = this.getCounter(opts?.counter);
|
|
107
|
+
this.noteHashReadRequests.push(new ScopedReadRequest(new ReadRequest(value, counter), AztecAddress.ZERO));
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Adds a pending nullifier read request (non-empty contract address, can match a pending nullifier). */
|
|
112
|
+
addPendingNullifierReadRequest(opts?: { value?: Fr; counter?: number; contractAddress?: AztecAddress }): this {
|
|
113
|
+
const value = opts?.value ?? Fr.random();
|
|
114
|
+
const counter = this.getCounter(opts?.counter);
|
|
115
|
+
const addr = opts?.contractAddress ?? this.contractAddress;
|
|
116
|
+
this.nullifierReadRequests.push(new ScopedReadRequest(new ReadRequest(value, counter), addr));
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Adds a settled nullifier read request (empty contract address, resolved against the nullifier tree). */
|
|
121
|
+
addSettledNullifierReadRequest(opts?: { value?: Fr; counter?: number }): this {
|
|
122
|
+
const value = opts?.value ?? Fr.random();
|
|
123
|
+
const counter = this.getCounter(opts?.counter);
|
|
124
|
+
this.nullifierReadRequests.push(new ScopedReadRequest(new ReadRequest(value, counter), AztecAddress.ZERO));
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Adds a key validation request to validation requests. */
|
|
129
|
+
addKeyValidationRequest(opts?: { contractAddress?: AztecAddress }): this {
|
|
130
|
+
const addr = opts?.contractAddress ?? this.contractAddress;
|
|
131
|
+
this.keyValidationRequests.push(
|
|
132
|
+
new ScopedKeyValidationRequestAndSeparator(
|
|
133
|
+
new KeyValidationRequestAndSeparator(
|
|
134
|
+
new KeyValidationRequest(new Point(Fr.random(), Fr.random(), false), Fr.random()),
|
|
135
|
+
Fr.random(),
|
|
136
|
+
),
|
|
137
|
+
addr,
|
|
138
|
+
),
|
|
139
|
+
);
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Adds a private log to the accumulated data. Defaults are generated randomly. */
|
|
144
|
+
addPrivateLog(opts?: { noteHashCounter?: number; counter?: number; contractAddress?: AztecAddress }): this {
|
|
145
|
+
const noteHashCounter = opts?.noteHashCounter ?? 0;
|
|
146
|
+
const counter = this.getCounter(opts?.counter);
|
|
147
|
+
const addr = opts?.contractAddress ?? this.contractAddress;
|
|
148
|
+
this.privateLogs.push(
|
|
149
|
+
new ScopedPrivateLogData(new PrivateLogData(PrivateLog.empty(), noteHashCounter, counter), addr),
|
|
150
|
+
);
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Builds the PrivateKernelCircuitPublicInputs with all added side effects. */
|
|
155
|
+
build(): PrivateKernelCircuitPublicInputs {
|
|
156
|
+
const publicInputs = PrivateKernelCircuitPublicInputs.empty();
|
|
157
|
+
publicInputs.end.noteHashes = makeClaimed(this.noteHashes, ScopedNoteHash, MAX_NOTE_HASHES_PER_TX);
|
|
158
|
+
publicInputs.end.nullifiers = makeClaimed(this.nullifiers, ScopedNullifier, MAX_NULLIFIERS_PER_TX);
|
|
159
|
+
publicInputs.end.privateLogs = makeClaimed(this.privateLogs, ScopedPrivateLogData, MAX_PRIVATE_LOGS_PER_TX);
|
|
160
|
+
publicInputs.validationRequests.noteHashReadRequests = makeClaimed(
|
|
161
|
+
this.noteHashReadRequests,
|
|
162
|
+
ScopedReadRequest,
|
|
163
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
|
|
164
|
+
);
|
|
165
|
+
publicInputs.validationRequests.nullifierReadRequests = makeClaimed(
|
|
166
|
+
this.nullifierReadRequests,
|
|
167
|
+
ScopedReadRequest,
|
|
168
|
+
MAX_NULLIFIER_READ_REQUESTS_PER_TX,
|
|
169
|
+
);
|
|
170
|
+
publicInputs.validationRequests.scopedKeyValidationRequestsAndSeparators = makeClaimed(
|
|
171
|
+
this.keyValidationRequests,
|
|
172
|
+
ScopedKeyValidationRequestAndSeparator,
|
|
173
|
+
MAX_KEY_VALIDATION_REQUESTS_PER_TX,
|
|
174
|
+
);
|
|
175
|
+
return publicInputs;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Builder for PrivateCircuitPublicInputs (call-level) with fluent API for adding side effects. */
|
|
180
|
+
export class PrivateCircuitPublicInputsBuilder {
|
|
181
|
+
private noteHashes: NoteHash[] = [];
|
|
182
|
+
private nullifiers: Nullifier[] = [];
|
|
183
|
+
private noteHashReadRequests: ScopedReadRequest[] = [];
|
|
184
|
+
private nullifierReadRequests: ScopedReadRequest[] = [];
|
|
185
|
+
private keyValidationRequests: KeyValidationRequestAndSeparator[] = [];
|
|
186
|
+
private privateLogs: PrivateLogData[] = [];
|
|
187
|
+
private nextCounter: number;
|
|
188
|
+
|
|
189
|
+
constructor(
|
|
190
|
+
private contractAddress: AztecAddress = DEFAULT_CONTRACT_ADDRESS,
|
|
191
|
+
startCounter = 1,
|
|
192
|
+
) {
|
|
193
|
+
this.nextCounter = startCounter;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private getCounter(sideEffectCounter?: number): number {
|
|
197
|
+
if (sideEffectCounter !== undefined) {
|
|
198
|
+
this.nextCounter = sideEffectCounter + 1;
|
|
199
|
+
return sideEffectCounter;
|
|
200
|
+
}
|
|
201
|
+
return this.nextCounter++;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** Adds a note hash. Defaults are generated randomly. */
|
|
205
|
+
addNoteHash(opts?: { value?: Fr; counter?: number }): this {
|
|
206
|
+
const value = opts?.value ?? Fr.random();
|
|
207
|
+
const counter = this.getCounter(opts?.counter);
|
|
208
|
+
this.noteHashes.push(new NoteHash(value, counter));
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** Adds a nullifier. Defaults are generated randomly. */
|
|
213
|
+
addNullifier(opts?: { value?: Fr; noteHash?: Fr; counter?: number }): this {
|
|
214
|
+
const value = opts?.value ?? Fr.random();
|
|
215
|
+
const noteHash = opts?.noteHash ?? Fr.ZERO;
|
|
216
|
+
const counter = this.getCounter(opts?.counter);
|
|
217
|
+
this.nullifiers.push(new Nullifier(value, noteHash, counter));
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Adds a pending note hash read request (non-empty contract address, can match a pending note hash). */
|
|
222
|
+
addPendingNoteHashReadRequest(opts?: { value?: Fr; counter?: number }): this {
|
|
223
|
+
const value = opts?.value ?? Fr.random();
|
|
224
|
+
const counter = this.getCounter(opts?.counter);
|
|
225
|
+
this.noteHashReadRequests.push(new ScopedReadRequest(new ReadRequest(value, counter), this.contractAddress));
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Adds a settled note hash read request (empty contract address, resolved against the note hash tree). */
|
|
230
|
+
addSettledNoteHashReadRequest(opts?: { value?: Fr; counter?: number }): this {
|
|
231
|
+
const value = opts?.value ?? Fr.random();
|
|
232
|
+
const counter = this.getCounter(opts?.counter);
|
|
233
|
+
this.noteHashReadRequests.push(new ScopedReadRequest(new ReadRequest(value, counter), AztecAddress.ZERO));
|
|
234
|
+
return this;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Adds a pending nullifier read request (non-empty contract address, can match a pending nullifier). */
|
|
238
|
+
addPendingNullifierReadRequest(opts?: { value?: Fr; counter?: number }): this {
|
|
239
|
+
const value = opts?.value ?? Fr.random();
|
|
240
|
+
const counter = this.getCounter(opts?.counter);
|
|
241
|
+
this.nullifierReadRequests.push(new ScopedReadRequest(new ReadRequest(value, counter), this.contractAddress));
|
|
242
|
+
return this;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Adds a settled nullifier read request (empty contract address, resolved against the nullifier tree). */
|
|
246
|
+
addSettledNullifierReadRequest(opts?: { value?: Fr; counter?: number }): this {
|
|
247
|
+
const value = opts?.value ?? Fr.random();
|
|
248
|
+
const counter = this.getCounter(opts?.counter);
|
|
249
|
+
this.nullifierReadRequests.push(new ScopedReadRequest(new ReadRequest(value, counter), AztecAddress.ZERO));
|
|
250
|
+
return this;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Adds a key validation request. */
|
|
254
|
+
addKeyValidationRequest(): this {
|
|
255
|
+
this.keyValidationRequests.push(
|
|
256
|
+
new KeyValidationRequestAndSeparator(
|
|
257
|
+
new KeyValidationRequest(new Point(Fr.random(), Fr.random(), false), Fr.random()),
|
|
258
|
+
Fr.random(),
|
|
259
|
+
),
|
|
260
|
+
);
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** Adds a private log. Defaults are generated randomly. */
|
|
265
|
+
addPrivateLog(opts?: { noteHashCounter?: number; counter?: number }): this {
|
|
266
|
+
const noteHashCounter = opts?.noteHashCounter ?? 0;
|
|
267
|
+
const counter = this.getCounter(opts?.counter);
|
|
268
|
+
this.privateLogs.push(new PrivateLogData(PrivateLog.empty(), noteHashCounter, counter));
|
|
269
|
+
return this;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Builds the PrivateCircuitPublicInputs with all added side effects. */
|
|
273
|
+
build(): PrivateCircuitPublicInputs {
|
|
274
|
+
const publicInputs = PrivateCircuitPublicInputs.empty();
|
|
275
|
+
publicInputs.callContext.contractAddress = this.contractAddress;
|
|
276
|
+
publicInputs.noteHashes = makeClaimed(this.noteHashes, NoteHash, MAX_NOTE_HASHES_PER_CALL);
|
|
277
|
+
publicInputs.nullifiers = makeClaimed(this.nullifiers, Nullifier, MAX_NULLIFIERS_PER_CALL);
|
|
278
|
+
publicInputs.privateLogs = makeClaimed(this.privateLogs, PrivateLogData, MAX_PRIVATE_LOGS_PER_CALL);
|
|
279
|
+
publicInputs.noteHashReadRequests = makeClaimed(
|
|
280
|
+
this.noteHashReadRequests,
|
|
281
|
+
ScopedReadRequest,
|
|
282
|
+
MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,
|
|
283
|
+
);
|
|
284
|
+
publicInputs.nullifierReadRequests = makeClaimed(
|
|
285
|
+
this.nullifierReadRequests,
|
|
286
|
+
ScopedReadRequest,
|
|
287
|
+
MAX_NULLIFIER_READ_REQUESTS_PER_CALL,
|
|
288
|
+
);
|
|
289
|
+
publicInputs.keyValidationRequestsAndSeparators = makeClaimed(
|
|
290
|
+
this.keyValidationRequests,
|
|
291
|
+
KeyValidationRequestAndSeparator,
|
|
292
|
+
MAX_KEY_VALIDATION_REQUESTS_PER_CALL,
|
|
293
|
+
);
|
|
294
|
+
return publicInputs;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** Wraps a PrivateKernelCircuitPublicInputs in a PrivateKernelSimulateOutput. */
|
|
299
|
+
export function makeKernelOutput(
|
|
300
|
+
publicInputs?: PrivateKernelCircuitPublicInputs,
|
|
301
|
+
): PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs> {
|
|
302
|
+
return {
|
|
303
|
+
publicInputs: publicInputs ?? PrivateKernelCircuitPublicInputs.empty(),
|
|
304
|
+
verificationKey: VerificationKeyData.empty(),
|
|
305
|
+
outputWitness: new Map(),
|
|
306
|
+
bytecode: Buffer.from([]),
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Wraps a PrivateCircuitPublicInputs in a PrivateCallExecutionResult. */
|
|
311
|
+
export function makeExecutionResult(publicInputs?: PrivateCircuitPublicInputs): PrivateCallExecutionResult {
|
|
312
|
+
return new PrivateCallExecutionResult(
|
|
313
|
+
Buffer.alloc(0),
|
|
314
|
+
Buffer.alloc(0),
|
|
315
|
+
new Map(),
|
|
316
|
+
publicInputs ?? PrivateCircuitPublicInputs.empty(),
|
|
317
|
+
[],
|
|
318
|
+
new Map(),
|
|
319
|
+
[],
|
|
320
|
+
[],
|
|
321
|
+
[],
|
|
322
|
+
[],
|
|
323
|
+
[],
|
|
324
|
+
);
|
|
325
|
+
}
|
|
@@ -116,6 +116,7 @@ export class PrivateKernelExecutionProver {
|
|
|
116
116
|
splitCounter,
|
|
117
117
|
);
|
|
118
118
|
while (resetBuilder.needsReset()) {
|
|
119
|
+
// Inner reset: without siloing.
|
|
119
120
|
const witgenTimer = new Timer();
|
|
120
121
|
const privateInputs = await resetBuilder.build(this.oracle);
|
|
121
122
|
output = generateWitnesses
|
|
@@ -216,16 +217,24 @@ export class PrivateKernelExecutionProver {
|
|
|
216
217
|
firstIteration = false;
|
|
217
218
|
}
|
|
218
219
|
|
|
219
|
-
//
|
|
220
|
-
|
|
220
|
+
// Final reset: include siloing of note hashes, nullifiers and private logs.
|
|
221
|
+
const finalResetBuilder = new PrivateKernelResetPrivateInputsBuilder(
|
|
221
222
|
output,
|
|
222
223
|
[],
|
|
223
224
|
noteHashNullifierCounterMap,
|
|
224
225
|
splitCounter,
|
|
225
226
|
);
|
|
226
|
-
|
|
227
|
+
if (!finalResetBuilder.needsReset()) {
|
|
228
|
+
// The final reset must be performed exactly once, because each tx has at least one nullifier that requires
|
|
229
|
+
// siloing, and siloing cannot be done multiple times.
|
|
230
|
+
// While, in theory, it might be possible to silo note hashes first and then run another reset to silo nullifiers
|
|
231
|
+
// and/or private logs, we currently don't have standalone dimensions for the arrays that require siloing. As a
|
|
232
|
+
// result, all necessary siloing must be done together in a single reset.
|
|
233
|
+
// Refer to the possible combinations of dimensions in private_kernel_reset_config.json.
|
|
234
|
+
throw new Error('Nothing to reset for the final reset.');
|
|
235
|
+
} else {
|
|
227
236
|
const witgenTimer = new Timer();
|
|
228
|
-
const privateInputs = await
|
|
237
|
+
const privateInputs = await finalResetBuilder.build(this.oracle);
|
|
229
238
|
output = generateWitnesses
|
|
230
239
|
? await this.proofCreator.generateResetOutput(privateInputs)
|
|
231
240
|
: await this.proofCreator.simulateReset(privateInputs);
|
|
@@ -239,8 +248,6 @@ export class PrivateKernelExecutionProver {
|
|
|
239
248
|
witgen: witgenTimer.ms(),
|
|
240
249
|
},
|
|
241
250
|
});
|
|
242
|
-
|
|
243
|
-
resetBuilder = new PrivateKernelResetPrivateInputsBuilder(output, [], noteHashNullifierCounterMap, splitCounter);
|
|
244
251
|
}
|
|
245
252
|
|
|
246
253
|
if (output.publicInputs.feePayer.isZero() && skipFeeEnforcement) {
|
|
@@ -8,11 +8,7 @@ import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
|
8
8
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
9
9
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
10
10
|
import { BlockHash } from '@aztec/stdlib/block';
|
|
11
|
-
import {
|
|
12
|
-
type ContractInstanceWithAddress,
|
|
13
|
-
computeContractClassIdPreimage,
|
|
14
|
-
computeSaltedInitializationHash,
|
|
15
|
-
} from '@aztec/stdlib/contract';
|
|
11
|
+
import { type ContractInstanceWithAddress, computeSaltedInitializationHash } from '@aztec/stdlib/contract';
|
|
16
12
|
import { DelayedPublicMutableValues, DelayedPublicMutableValuesWithHash } from '@aztec/stdlib/delayed-public-mutable';
|
|
17
13
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
18
14
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
@@ -49,11 +45,15 @@ export class PrivateKernelOracle {
|
|
|
49
45
|
|
|
50
46
|
/** Retrieves the preimage of a contract class id from the contract classes db. */
|
|
51
47
|
public async getContractClassIdPreimage(contractClassId: Fr) {
|
|
52
|
-
const contractClass = await this.contractStore.
|
|
48
|
+
const contractClass = await this.contractStore.getContractClassWithPreimage(contractClassId);
|
|
53
49
|
if (!contractClass) {
|
|
54
50
|
throw new Error(`Contract class not found when getting class id preimage. Class id: ${contractClassId}.`);
|
|
55
51
|
}
|
|
56
|
-
return
|
|
52
|
+
return {
|
|
53
|
+
artifactHash: contractClass.artifactHash,
|
|
54
|
+
privateFunctionsRoot: contractClass.privateFunctionsRoot,
|
|
55
|
+
publicBytecodeCommitment: contractClass.publicBytecodeCommitment,
|
|
56
|
+
};
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/** Returns a membership witness with the sibling path and leaf index in our private functions tree. */
|
package/src/pxe.ts
CHANGED
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
generateSimulatedProvingResult,
|
|
62
62
|
} from './contract_function_simulator/contract_function_simulator.js';
|
|
63
63
|
import { ProxiedContractStoreFactory } from './contract_function_simulator/proxied_contract_data_source.js';
|
|
64
|
+
import { displayDebugLogs } from './contract_logging.js';
|
|
64
65
|
import { ContractSyncService } from './contract_sync/contract_sync_service.js';
|
|
65
66
|
import { readCurrentClassId } from './contract_sync/helpers.js';
|
|
66
67
|
import { PXEDebugUtils } from './debug/pxe_debug_utils.js';
|
|
@@ -144,6 +145,7 @@ export type PXECreateArgs = {
|
|
|
144
145
|
export class PXE {
|
|
145
146
|
private constructor(
|
|
146
147
|
private node: AztecNode,
|
|
148
|
+
private db: AztecAsyncKVStore,
|
|
147
149
|
private blockStateSynchronizer: BlockSynchronizer,
|
|
148
150
|
private keyStore: KeyStore,
|
|
149
151
|
private contractStore: ContractStore,
|
|
@@ -239,6 +241,7 @@ export class PXE {
|
|
|
239
241
|
|
|
240
242
|
const pxe = new PXE(
|
|
241
243
|
node,
|
|
244
|
+
store,
|
|
242
245
|
synchronizer,
|
|
243
246
|
keyStore,
|
|
244
247
|
contractStore,
|
|
@@ -344,9 +347,8 @@ export class PXE {
|
|
|
344
347
|
async #registerProtocolContracts() {
|
|
345
348
|
const registered: Record<string, string> = {};
|
|
346
349
|
for (const name of protocolContractNames) {
|
|
347
|
-
const { address,
|
|
348
|
-
|
|
349
|
-
await this.contractStore.addContractArtifact(contractClass.id, artifact);
|
|
350
|
+
const { address, instance, artifact } = await this.protocolContractsProvider.getProtocolContractArtifact(name);
|
|
351
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
350
352
|
await this.contractStore.addContractInstance(instance);
|
|
351
353
|
registered[name] = address.toString();
|
|
352
354
|
}
|
|
@@ -601,8 +603,7 @@ export class PXE {
|
|
|
601
603
|
* @param artifact - The build artifact for the contract class.
|
|
602
604
|
*/
|
|
603
605
|
public async registerContractClass(artifact: ContractArtifact): Promise<void> {
|
|
604
|
-
const
|
|
605
|
-
await this.contractStore.addContractArtifact(contractClassId, artifact);
|
|
606
|
+
const contractClassId = await this.contractStore.addContractArtifact(artifact);
|
|
606
607
|
this.log.info(`Added contract class ${artifact.name} with id ${contractClassId}`);
|
|
607
608
|
}
|
|
608
609
|
|
|
@@ -621,17 +622,17 @@ export class PXE {
|
|
|
621
622
|
if (artifact) {
|
|
622
623
|
// If the user provides an artifact, validate it against the expected class id and register it
|
|
623
624
|
const contractClass = await getContractClassFromArtifact(artifact);
|
|
624
|
-
|
|
625
|
-
if (!contractClassId.equals(instance.currentContractClassId)) {
|
|
625
|
+
if (!contractClass.id.equals(instance.currentContractClassId)) {
|
|
626
626
|
throw new Error(
|
|
627
|
-
`Artifact does not match expected class id (computed ${
|
|
627
|
+
`Artifact does not match expected class id (computed ${contractClass.id} but instance refers to ${instance.currentContractClassId})`,
|
|
628
628
|
);
|
|
629
629
|
}
|
|
630
630
|
const computedAddress = await computeContractAddressFromInstance(instance);
|
|
631
631
|
if (!computedAddress.equals(instance.address)) {
|
|
632
632
|
throw new Error('Added a contract in which the address does not match the contract instance.');
|
|
633
633
|
}
|
|
634
|
-
|
|
634
|
+
|
|
635
|
+
await this.contractStore.addContractArtifact(artifact, contractClass);
|
|
635
636
|
|
|
636
637
|
const publicFunctionSignatures = artifact.functions
|
|
637
638
|
.filter(fn => fn.functionType === FunctionType.PUBLIC)
|
|
@@ -680,15 +681,16 @@ export class PXE {
|
|
|
680
681
|
throw new Error('Could not update contract to a class different from the current one.');
|
|
681
682
|
}
|
|
682
683
|
|
|
683
|
-
await this.contractStore.addContractArtifact(contractClass.id, artifact);
|
|
684
|
-
|
|
685
684
|
const publicFunctionSignatures = artifact.functions
|
|
686
685
|
.filter(fn => fn.functionType === FunctionType.PUBLIC)
|
|
687
686
|
.map(fn => decodeFunctionSignature(fn.name, fn.parameters));
|
|
688
687
|
await this.node.registerContractFunctionSignatures(publicFunctionSignatures);
|
|
689
688
|
|
|
690
689
|
currentInstance.currentContractClassId = contractClass.id;
|
|
691
|
-
await
|
|
690
|
+
await Promise.all([
|
|
691
|
+
this.contractStore.addContractArtifact(artifact, contractClass),
|
|
692
|
+
this.contractStore.addContractInstance(currentInstance),
|
|
693
|
+
]);
|
|
692
694
|
this.log.info(`Updated contract ${artifact.name} at ${contractAddress.toString()} to class ${contractClass.id}`);
|
|
693
695
|
});
|
|
694
696
|
}
|
|
@@ -947,6 +949,9 @@ export class PXE {
|
|
|
947
949
|
const publicSimulationTimer = new Timer();
|
|
948
950
|
publicOutput = await this.#simulatePublicCalls(simulatedTx, skipFeeEnforcement);
|
|
949
951
|
publicSimulationTime = publicSimulationTimer.ms();
|
|
952
|
+
if (publicOutput?.debugLogs?.length) {
|
|
953
|
+
await displayDebugLogs(publicOutput.debugLogs, addr => this.contractStore.getDebugContractName(addr));
|
|
954
|
+
}
|
|
950
955
|
}
|
|
951
956
|
|
|
952
957
|
let validationTime: number | undefined;
|
|
@@ -955,7 +960,8 @@ export class PXE {
|
|
|
955
960
|
const validationResult = await this.node.isValidTx(simulatedTx, { isSimulation: true, skipFeeEnforcement });
|
|
956
961
|
validationTime = validationTimer.ms();
|
|
957
962
|
if (validationResult.result === 'invalid') {
|
|
958
|
-
|
|
963
|
+
const reason = validationResult.reason.length > 0 ? ` Reason: ${validationResult.reason.join(', ')}` : '';
|
|
964
|
+
throw new Error(`The simulated transaction is unable to be added to state and is invalid.${reason}`);
|
|
959
965
|
}
|
|
960
966
|
}
|
|
961
967
|
|
|
@@ -1126,9 +1132,10 @@ export class PXE {
|
|
|
1126
1132
|
}
|
|
1127
1133
|
|
|
1128
1134
|
/**
|
|
1129
|
-
* Stops the PXE's job queue.
|
|
1135
|
+
* Stops the PXE's job queue and closes the backing store.
|
|
1130
1136
|
*/
|
|
1131
|
-
public stop(): Promise<void> {
|
|
1132
|
-
|
|
1137
|
+
public async stop(): Promise<void> {
|
|
1138
|
+
await this.jobQueue.end();
|
|
1139
|
+
await this.db.close();
|
|
1133
1140
|
}
|
|
1134
1141
|
}
|