@aztec/pxe 0.48.0 → 0.50.1
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 +1 -0
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +6 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_hints.d.ts +1 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_hints.d.ts.map +1 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_hints.js +20 -7
- package/dest/kernel_prover/hints/needs_reset.d.ts +1 -1
- package/dest/kernel_prover/hints/needs_reset.d.ts.map +1 -1
- package/dest/kernel_prover/hints/needs_reset.js +21 -18
- package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
- package/dest/kernel_prover/kernel_prover.js +7 -7
- package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
- package/dest/pxe_http/pxe_http_server.js +6 -4
- package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/create_pxe_service.js +17 -15
- package/dest/pxe_service/pxe_service.d.ts +7 -13
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +48 -38
- package/dest/simulator_oracle/index.d.ts.map +1 -1
- package/dest/simulator_oracle/index.js +3 -19
- package/package.json +14 -14
- package/src/config/index.ts +6 -0
- package/src/kernel_prover/hints/build_private_kernel_reset_hints.ts +29 -7
- package/src/kernel_prover/hints/needs_reset.ts +20 -17
- package/src/kernel_prover/kernel_prover.ts +6 -2
- package/src/pxe_http/pxe_http_server.ts +6 -2
- package/src/pxe_service/create_pxe_service.ts +18 -19
- package/src/pxe_service/pxe_service.ts +46 -10
- package/src/simulator_oracle/index.ts +7 -21
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
|
|
32
32
|
import { type WitnessMap } from '@noir-lang/types';
|
|
33
33
|
|
|
34
|
-
import { buildPrivateKernelResetInputs,
|
|
34
|
+
import { buildPrivateKernelResetInputs, needsFinalReset, needsReset } from './hints/index.js';
|
|
35
35
|
import { type ProvingDataOracle } from './proving_data_oracle.js';
|
|
36
36
|
|
|
37
37
|
const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs> = {
|
|
@@ -88,6 +88,7 @@ export class KernelProver {
|
|
|
88
88
|
noteHashLeafIndexMap,
|
|
89
89
|
noteHashNullifierCounterMap,
|
|
90
90
|
validationRequestsSplitCounter,
|
|
91
|
+
false,
|
|
91
92
|
);
|
|
92
93
|
output = await this.proofCreator.simulateProofReset(resetInputs);
|
|
93
94
|
// TODO(#7368) consider refactoring this redundant bytecode pushing
|
|
@@ -135,13 +136,14 @@ export class KernelProver {
|
|
|
135
136
|
firstIteration = false;
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
if (
|
|
139
|
+
if (needsFinalReset(output.publicInputs)) {
|
|
139
140
|
const resetInputs = await this.getPrivateKernelResetInputs(
|
|
140
141
|
executionStack,
|
|
141
142
|
output,
|
|
142
143
|
noteHashLeafIndexMap,
|
|
143
144
|
noteHashNullifierCounterMap,
|
|
144
145
|
validationRequestsSplitCounter,
|
|
146
|
+
true,
|
|
145
147
|
);
|
|
146
148
|
output = await this.proofCreator.simulateProofReset(resetInputs);
|
|
147
149
|
// TODO(#7368) consider refactoring this redundant bytecode pushing
|
|
@@ -188,6 +190,7 @@ export class KernelProver {
|
|
|
188
190
|
noteHashLeafIndexMap: Map<bigint, bigint>,
|
|
189
191
|
noteHashNullifierCounterMap: Map<number, number>,
|
|
190
192
|
validationRequestsSplitCounter: number,
|
|
193
|
+
shouldSilo: boolean,
|
|
191
194
|
) {
|
|
192
195
|
const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(output.verificationKey);
|
|
193
196
|
const previousKernelData = new PrivateKernelData(
|
|
@@ -203,6 +206,7 @@ export class KernelProver {
|
|
|
203
206
|
noteHashLeafIndexMap,
|
|
204
207
|
noteHashNullifierCounterMap,
|
|
205
208
|
validationRequestsSplitCounter,
|
|
209
|
+
shouldSilo,
|
|
206
210
|
this.oracle,
|
|
207
211
|
);
|
|
208
212
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
Note,
|
|
10
10
|
NullifierMembershipWitness,
|
|
11
11
|
type PXE,
|
|
12
|
+
SiblingPath,
|
|
12
13
|
SimulatedTx,
|
|
13
14
|
Tx,
|
|
14
15
|
TxEffect,
|
|
@@ -16,13 +17,14 @@ import {
|
|
|
16
17
|
TxHash,
|
|
17
18
|
TxReceipt,
|
|
18
19
|
UnencryptedL2BlockL2Logs,
|
|
20
|
+
UniqueNote,
|
|
19
21
|
} from '@aztec/circuit-types';
|
|
20
22
|
import { FunctionSelector } from '@aztec/circuits.js';
|
|
21
23
|
import { NoteSelector } from '@aztec/foundation/abi';
|
|
22
24
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
25
|
+
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
23
26
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
24
27
|
import { Fr, GrumpkinScalar, Point } from '@aztec/foundation/fields';
|
|
25
|
-
import { BaseHashType } from '@aztec/foundation/hash';
|
|
26
28
|
import { JsonRpcServer, createNamespacedJsonRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
27
29
|
|
|
28
30
|
import http from 'http';
|
|
@@ -41,13 +43,15 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer {
|
|
|
41
43
|
ExtendedUnencryptedL2Log,
|
|
42
44
|
FunctionSelector,
|
|
43
45
|
TxHash,
|
|
44
|
-
|
|
46
|
+
Buffer32,
|
|
45
47
|
EthAddress,
|
|
46
48
|
Point,
|
|
47
49
|
Fr,
|
|
48
50
|
GrumpkinScalar,
|
|
49
51
|
Note,
|
|
50
52
|
ExtendedNote,
|
|
53
|
+
UniqueNote,
|
|
54
|
+
SiblingPath,
|
|
51
55
|
AuthWitness,
|
|
52
56
|
L2Block,
|
|
53
57
|
TxEffect,
|
|
@@ -3,8 +3,7 @@ import { type AztecNode, type PrivateKernelProver } from '@aztec/circuit-types';
|
|
|
3
3
|
import { randomBytes } from '@aztec/foundation/crypto';
|
|
4
4
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
5
5
|
import { KeyStore } from '@aztec/key-store';
|
|
6
|
-
import {
|
|
7
|
-
import { initStoreForRollup } from '@aztec/kv-store/utils';
|
|
6
|
+
import { createStore } from '@aztec/kv-store/utils';
|
|
8
7
|
import { getCanonicalAuthRegistry } from '@aztec/protocol-contracts/auth-registry';
|
|
9
8
|
import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer';
|
|
10
9
|
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
|
|
@@ -43,24 +42,10 @@ export async function createPXEService(
|
|
|
43
42
|
const keyStorePath = config.dataDirectory ? join(config.dataDirectory, 'pxe_key_store') : undefined;
|
|
44
43
|
const l1Contracts = await aztecNode.getL1ContractAddresses();
|
|
45
44
|
|
|
46
|
-
const keyStore = new KeyStore(await
|
|
47
|
-
const db = new KVPxeDatabase(await
|
|
48
|
-
|
|
49
|
-
// (@PhilWindle) Temporary validation until WASM is implemented
|
|
50
|
-
let prover: PrivateKernelProver | undefined = proofCreator;
|
|
51
|
-
if (!prover) {
|
|
52
|
-
if (config.proverEnabled && (!config.bbBinaryPath || !config.bbWorkingDirectory)) {
|
|
53
|
-
throw new Error(`Prover must be configured with binary path and working directory`);
|
|
54
|
-
}
|
|
55
|
-
prover = !config.proverEnabled
|
|
56
|
-
? new TestPrivateKernelProver()
|
|
57
|
-
: new BBNativePrivateKernelProver(
|
|
58
|
-
config.bbBinaryPath!,
|
|
59
|
-
config.bbWorkingDirectory!,
|
|
60
|
-
createDebugLogger('aztec:pxe:bb-native-prover' + (logSuffix ? `:${logSuffix}` : '')),
|
|
61
|
-
);
|
|
62
|
-
}
|
|
45
|
+
const keyStore = new KeyStore(await createStore(keyStorePath, l1Contracts.rollupAddress));
|
|
46
|
+
const db = new KVPxeDatabase(await createStore(pxeDbPath, l1Contracts.rollupAddress));
|
|
63
47
|
|
|
48
|
+
const prover = proofCreator ?? (await createProver(config, logSuffix));
|
|
64
49
|
const server = new PXEService(keyStore, aztecNode, db, prover, config, logSuffix);
|
|
65
50
|
for (const contract of [
|
|
66
51
|
getCanonicalClassRegisterer(),
|
|
@@ -76,3 +61,17 @@ export async function createPXEService(
|
|
|
76
61
|
await server.start();
|
|
77
62
|
return server;
|
|
78
63
|
}
|
|
64
|
+
|
|
65
|
+
function createProver(config: PXEServiceConfig, logSuffix?: string) {
|
|
66
|
+
if (!config.proverEnabled) {
|
|
67
|
+
return new TestPrivateKernelProver();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// (@PhilWindle) Temporary validation until WASM is implemented
|
|
71
|
+
if (!config.bbBinaryPath || !config.bbWorkingDirectory) {
|
|
72
|
+
throw new Error(`Prover must be configured with binary path and working directory`);
|
|
73
|
+
}
|
|
74
|
+
const bbConfig = config as Required<Pick<PXEServiceConfig, 'bbBinaryPath' | 'bbWorkingDirectory'>> & PXEServiceConfig;
|
|
75
|
+
const log = createDebugLogger('aztec:pxe:bb-native-prover' + (logSuffix ? `:${logSuffix}` : ''));
|
|
76
|
+
return BBNativePrivateKernelProver.new(bbConfig, log);
|
|
77
|
+
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
EncryptedTxL2Logs,
|
|
6
6
|
type EventMetadata,
|
|
7
7
|
EventType,
|
|
8
|
-
ExtendedNote,
|
|
8
|
+
type ExtendedNote,
|
|
9
9
|
type FunctionCall,
|
|
10
10
|
type GetUnencryptedLogsResponse,
|
|
11
11
|
type IncomingNotesFilter,
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type PXE,
|
|
18
18
|
type PXEInfo,
|
|
19
19
|
type PrivateKernelProver,
|
|
20
|
+
type SiblingPath,
|
|
20
21
|
SimulatedTx,
|
|
21
22
|
SimulationError,
|
|
22
23
|
TaggedLog,
|
|
@@ -26,11 +27,14 @@ import {
|
|
|
26
27
|
type TxHash,
|
|
27
28
|
type TxReceipt,
|
|
28
29
|
UnencryptedTxL2Logs,
|
|
30
|
+
UniqueNote,
|
|
31
|
+
getNonNullifiedL1ToL2MessageWitness,
|
|
29
32
|
isNoirCallStackUnresolved,
|
|
30
33
|
} from '@aztec/circuit-types';
|
|
31
34
|
import {
|
|
32
35
|
AztecAddress,
|
|
33
36
|
type CompleteAddress,
|
|
37
|
+
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
34
38
|
type PartialAddress,
|
|
35
39
|
computeContractClassId,
|
|
36
40
|
getContractClassFromArtifact,
|
|
@@ -296,7 +300,7 @@ export class PXEService implements PXE {
|
|
|
296
300
|
return await this.node.getPublicStorageAt(contract, slot, 'latest');
|
|
297
301
|
}
|
|
298
302
|
|
|
299
|
-
public async getIncomingNotes(filter: IncomingNotesFilter): Promise<
|
|
303
|
+
public async getIncomingNotes(filter: IncomingNotesFilter): Promise<UniqueNote[]> {
|
|
300
304
|
const noteDaos = await this.db.getIncomingNotes(filter);
|
|
301
305
|
|
|
302
306
|
// TODO(#6531): Refactor --> This type conversion is ugly but I decided to keep it this way for now because
|
|
@@ -312,12 +316,20 @@ export class PXEService implements PXE {
|
|
|
312
316
|
}
|
|
313
317
|
owner = completeAddresses.address;
|
|
314
318
|
}
|
|
315
|
-
return new
|
|
319
|
+
return new UniqueNote(
|
|
320
|
+
dao.note,
|
|
321
|
+
owner,
|
|
322
|
+
dao.contractAddress,
|
|
323
|
+
dao.storageSlot,
|
|
324
|
+
dao.noteTypeId,
|
|
325
|
+
dao.txHash,
|
|
326
|
+
dao.nonce,
|
|
327
|
+
);
|
|
316
328
|
});
|
|
317
329
|
return Promise.all(extendedNotes);
|
|
318
330
|
}
|
|
319
331
|
|
|
320
|
-
public async getOutgoingNotes(filter: OutgoingNotesFilter): Promise<
|
|
332
|
+
public async getOutgoingNotes(filter: OutgoingNotesFilter): Promise<UniqueNote[]> {
|
|
321
333
|
const noteDaos = await this.db.getOutgoingNotes(filter);
|
|
322
334
|
|
|
323
335
|
// TODO(#6532): Refactor --> This type conversion is ugly but I decided to keep it this way for now because
|
|
@@ -333,18 +345,34 @@ export class PXEService implements PXE {
|
|
|
333
345
|
}
|
|
334
346
|
owner = completeAddresses.address;
|
|
335
347
|
}
|
|
336
|
-
return new
|
|
348
|
+
return new UniqueNote(
|
|
349
|
+
dao.note,
|
|
350
|
+
owner,
|
|
351
|
+
dao.contractAddress,
|
|
352
|
+
dao.storageSlot,
|
|
353
|
+
dao.noteTypeId,
|
|
354
|
+
dao.txHash,
|
|
355
|
+
dao.nonce,
|
|
356
|
+
);
|
|
337
357
|
});
|
|
338
358
|
return Promise.all(extendedNotes);
|
|
339
359
|
}
|
|
340
360
|
|
|
361
|
+
public async getL1ToL2MembershipWitness(
|
|
362
|
+
contractAddress: AztecAddress,
|
|
363
|
+
messageHash: Fr,
|
|
364
|
+
secret: Fr,
|
|
365
|
+
): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>]> {
|
|
366
|
+
return await getNonNullifiedL1ToL2MessageWitness(this.node, contractAddress, messageHash, secret);
|
|
367
|
+
}
|
|
368
|
+
|
|
341
369
|
public async addNote(note: ExtendedNote, scope?: AztecAddress) {
|
|
342
370
|
const owner = await this.db.getCompleteAddress(note.owner);
|
|
343
371
|
if (!owner) {
|
|
344
372
|
throw new Error(`Unknown account: ${note.owner.toString()}`);
|
|
345
373
|
}
|
|
346
374
|
|
|
347
|
-
const nonces = await this
|
|
375
|
+
const nonces = await this.#getNoteNonces(note);
|
|
348
376
|
if (nonces.length === 0) {
|
|
349
377
|
throw new Error(`Cannot find the note in tx: ${note.txHash}.`);
|
|
350
378
|
}
|
|
@@ -394,7 +422,7 @@ export class PXEService implements PXE {
|
|
|
394
422
|
throw new Error(`Unknown account: ${note.owner.toString()}`);
|
|
395
423
|
}
|
|
396
424
|
|
|
397
|
-
const nonces = await this
|
|
425
|
+
const nonces = await this.#getNoteNonces(note);
|
|
398
426
|
if (nonces.length === 0) {
|
|
399
427
|
throw new Error(`Cannot find the note in tx: ${note.txHash}.`);
|
|
400
428
|
}
|
|
@@ -440,9 +468,8 @@ export class PXEService implements PXE {
|
|
|
440
468
|
* @param note - The note to find the nonces for.
|
|
441
469
|
* @returns The nonces of the note.
|
|
442
470
|
* @remarks More than a single nonce may be returned since there might be more than one nonce for a given note.
|
|
443
|
-
* TODO(#4956): Un-expose this
|
|
444
471
|
*/
|
|
445
|
-
|
|
472
|
+
async #getNoteNonces(note: ExtendedNote): Promise<Fr[]> {
|
|
446
473
|
const tx = await this.node.getTxEffect(note.txHash);
|
|
447
474
|
if (!tx) {
|
|
448
475
|
throw new Error(`Unknown tx: ${note.txHash}`);
|
|
@@ -497,6 +524,7 @@ export class PXEService implements PXE {
|
|
|
497
524
|
txRequest: TxExecutionRequest,
|
|
498
525
|
simulatePublic: boolean,
|
|
499
526
|
msgSender: AztecAddress | undefined = undefined,
|
|
527
|
+
skipTxValidation: boolean = true, // TODO(#7956): make the default be false
|
|
500
528
|
scopes?: AztecAddress[],
|
|
501
529
|
): Promise<SimulatedTx> {
|
|
502
530
|
return await this.jobQueue.put(async () => {
|
|
@@ -505,6 +533,12 @@ export class PXEService implements PXE {
|
|
|
505
533
|
simulatedTx.publicOutput = await this.#simulatePublicCalls(simulatedTx.tx);
|
|
506
534
|
}
|
|
507
535
|
|
|
536
|
+
if (!skipTxValidation) {
|
|
537
|
+
if (!(await this.node.isValidTx(simulatedTx.tx))) {
|
|
538
|
+
throw new Error('The simulated transaction is unable to be added to state and is invalid.');
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
508
542
|
// We log only if the msgSender is undefined, as simulating with a different msgSender
|
|
509
543
|
// is unlikely to be a real transaction, and likely to be only used to read data.
|
|
510
544
|
// Meaning that it will not necessarily have produced a nullifier (and thus have no TxHash)
|
|
@@ -718,7 +752,9 @@ export class PXEService implements PXE {
|
|
|
718
752
|
const noirCallStack = err.getNoirCallStack();
|
|
719
753
|
if (debugInfo && isNoirCallStackUnresolved(noirCallStack)) {
|
|
720
754
|
try {
|
|
721
|
-
|
|
755
|
+
// Public functions are simulated as a single Brillig entry point.
|
|
756
|
+
// Thus, we can safely assume here that the Brillig function id is `0`.
|
|
757
|
+
const parsedCallStack = resolveOpcodeLocations(noirCallStack, debugInfo, 0);
|
|
722
758
|
err.setNoirCallStack(parsedCallStack);
|
|
723
759
|
} catch (err) {
|
|
724
760
|
this.log.warn(
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type NoteStatus,
|
|
6
6
|
type NullifierMembershipWitness,
|
|
7
7
|
type PublicDataWitness,
|
|
8
|
-
|
|
8
|
+
getNonNullifiedL1ToL2MessageWitness,
|
|
9
9
|
} from '@aztec/circuit-types';
|
|
10
10
|
import {
|
|
11
11
|
type AztecAddress,
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
type KeyValidationRequest,
|
|
17
17
|
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
18
18
|
} from '@aztec/circuits.js';
|
|
19
|
-
import { computeL1ToL2MessageNullifier } from '@aztec/circuits.js/hash';
|
|
20
19
|
import { type FunctionArtifact, getFunctionArtifact } from '@aztec/foundation/abi';
|
|
21
20
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
22
21
|
import { type KeyStore } from '@aztec/key-store';
|
|
@@ -127,25 +126,12 @@ export class SimulatorOracle implements DBOracle {
|
|
|
127
126
|
messageHash: Fr,
|
|
128
127
|
secret: Fr,
|
|
129
128
|
): Promise<MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>> {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// for nullifiers because messages can have duplicates.
|
|
137
|
-
do {
|
|
138
|
-
const response = await this.aztecNode.getL1ToL2MessageMembershipWitness('latest', messageHash, startIndex);
|
|
139
|
-
if (!response) {
|
|
140
|
-
throw new Error(`No non-nullified L1 to L2 message found for message hash ${messageHash.toString()}`);
|
|
141
|
-
}
|
|
142
|
-
[messageIndex, siblingPath] = response;
|
|
143
|
-
|
|
144
|
-
const messageNullifier = computeL1ToL2MessageNullifier(contractAddress, messageHash, secret, messageIndex);
|
|
145
|
-
nullifierIndex = await this.getNullifierIndex(messageNullifier);
|
|
146
|
-
|
|
147
|
-
startIndex = messageIndex + 1n;
|
|
148
|
-
} while (nullifierIndex !== undefined);
|
|
129
|
+
const [messageIndex, siblingPath] = await getNonNullifiedL1ToL2MessageWitness(
|
|
130
|
+
this.aztecNode,
|
|
131
|
+
contractAddress,
|
|
132
|
+
messageHash,
|
|
133
|
+
secret,
|
|
134
|
+
);
|
|
149
135
|
|
|
150
136
|
// Assuming messageIndex is what you intended to use for the index in MessageLoadOracleInputs
|
|
151
137
|
return new MessageLoadOracleInputs(messageIndex, siblingPath);
|