@aztec/pxe 0.47.0 → 0.48.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.
Files changed (66) hide show
  1. package/dest/config/index.d.ts +17 -0
  2. package/dest/config/index.d.ts.map +1 -1
  3. package/dest/config/index.js +67 -8
  4. package/dest/database/incoming_note_dao.d.ts +4 -4
  5. package/dest/database/incoming_note_dao.d.ts.map +1 -1
  6. package/dest/database/incoming_note_dao.js +7 -7
  7. package/dest/database/kv_pxe_database.d.ts +3 -3
  8. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  9. package/dest/database/kv_pxe_database.js +64 -31
  10. package/dest/database/outgoing_note_dao.d.ts +6 -6
  11. package/dest/database/outgoing_note_dao.d.ts.map +1 -1
  12. package/dest/database/outgoing_note_dao.js +8 -8
  13. package/dest/database/pxe_database.d.ts +6 -2
  14. package/dest/database/pxe_database.d.ts.map +1 -1
  15. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  16. package/dest/database/pxe_database_test_suite.js +43 -4
  17. package/dest/kernel_prover/{private_inputs_builders → hints}/build_private_kernel_reset_hints.d.ts +1 -1
  18. package/dest/kernel_prover/hints/build_private_kernel_reset_hints.d.ts.map +1 -0
  19. package/dest/kernel_prover/hints/build_private_kernel_reset_hints.js +77 -0
  20. package/dest/kernel_prover/hints/index.d.ts +3 -0
  21. package/dest/kernel_prover/hints/index.d.ts.map +1 -0
  22. package/dest/kernel_prover/hints/index.js +3 -0
  23. package/dest/kernel_prover/hints/needs_reset.d.ts +5 -0
  24. package/dest/kernel_prover/hints/needs_reset.d.ts.map +1 -0
  25. package/dest/kernel_prover/hints/needs_reset.js +35 -0
  26. package/dest/kernel_prover/kernel_prover.d.ts +0 -2
  27. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  28. package/dest/kernel_prover/kernel_prover.js +16 -48
  29. package/dest/note_processor/note_processor.js +2 -2
  30. package/dest/note_processor/produce_note_dao.js +15 -15
  31. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
  32. package/dest/pxe_http/pxe_http_server.js +3 -1
  33. package/dest/pxe_service/create_pxe_service.js +2 -2
  34. package/dest/pxe_service/pxe_service.d.ts +5 -4
  35. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  36. package/dest/pxe_service/pxe_service.js +28 -31
  37. package/dest/simulator_oracle/index.d.ts +2 -2
  38. package/dest/simulator_oracle/index.d.ts.map +1 -1
  39. package/dest/simulator_oracle/index.js +6 -5
  40. package/dest/synchronizer/synchronizer.d.ts +1 -1
  41. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  42. package/dest/synchronizer/synchronizer.js +8 -10
  43. package/package.json +14 -14
  44. package/src/config/index.ts +84 -14
  45. package/src/database/incoming_note_dao.ts +5 -5
  46. package/src/database/kv_pxe_database.ts +86 -31
  47. package/src/database/outgoing_note_dao.ts +6 -6
  48. package/src/database/pxe_database.ts +6 -2
  49. package/src/database/pxe_database_test_suite.ts +70 -3
  50. package/src/kernel_prover/{private_inputs_builders → hints}/build_private_kernel_reset_hints.ts +2 -0
  51. package/src/kernel_prover/hints/index.ts +2 -0
  52. package/src/kernel_prover/hints/needs_reset.ts +51 -0
  53. package/src/kernel_prover/kernel_prover.ts +22 -72
  54. package/src/note_processor/note_processor.ts +1 -1
  55. package/src/note_processor/produce_note_dao.ts +14 -14
  56. package/src/pxe_http/pxe_http_server.ts +2 -0
  57. package/src/pxe_service/create_pxe_service.ts +2 -2
  58. package/src/pxe_service/pxe_service.ts +47 -52
  59. package/src/simulator_oracle/index.ts +5 -4
  60. package/src/synchronizer/synchronizer.ts +19 -19
  61. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.d.ts.map +0 -1
  62. package/dest/kernel_prover/private_inputs_builders/build_private_kernel_reset_hints.js +0 -77
  63. package/dest/kernel_prover/private_inputs_builders/index.d.ts +0 -2
  64. package/dest/kernel_prover/private_inputs_builders/index.d.ts.map +0 -1
  65. package/dest/kernel_prover/private_inputs_builders/index.js +0 -2
  66. package/src/kernel_prover/private_inputs_builders/index.ts +0 -1
@@ -1,14 +1,6 @@
1
1
  import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types';
2
2
  import {
3
- CallRequest,
4
3
  Fr,
5
- MAX_KEY_VALIDATION_REQUESTS_PER_TX,
6
- MAX_NOTE_ENCRYPTED_LOGS_PER_TX,
7
- MAX_NOTE_HASHES_PER_TX,
8
- MAX_NOTE_HASH_READ_REQUESTS_PER_TX,
9
- MAX_NULLIFIERS_PER_TX,
10
- MAX_NULLIFIER_READ_REQUESTS_PER_TX,
11
- MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
12
4
  PrivateCallData,
13
5
  PrivateKernelCircuitPublicInputs,
14
6
  PrivateKernelData,
@@ -19,9 +11,7 @@ import {
19
11
  type TxRequest,
20
12
  VK_TREE_HEIGHT,
21
13
  VerificationKeyAsFields,
22
- getNonEmptyItems,
23
14
  } from '@aztec/circuits.js';
24
- import { padArrayEnd } from '@aztec/foundation/collection';
25
15
  import { createDebugLogger } from '@aztec/foundation/log';
26
16
  import { assertLength } from '@aztec/foundation/serialize';
27
17
  import { pushTestData } from '@aztec/foundation/testing';
@@ -30,11 +20,18 @@ import {
30
20
  PrivateResetTagToArtifactName,
31
21
  getVKTreeRoot,
32
22
  } from '@aztec/noir-protocol-circuits-types';
33
- import { type ExecutionResult, collectNoteHashLeafIndexMap, collectNullifiedNoteHashCounters } from '@aztec/simulator';
23
+ import {
24
+ type ExecutionResult,
25
+ collectEnqueuedPublicFunctionCalls,
26
+ collectNoteHashLeafIndexMap,
27
+ collectNoteHashNullifierCounterMap,
28
+ collectPublicTeardownFunctionCall,
29
+ getFinalMinRevertibleSideEffectCounter,
30
+ } from '@aztec/simulator';
34
31
 
35
32
  import { type WitnessMap } from '@noir-lang/types';
36
33
 
37
- import { buildPrivateKernelResetInputs } from './private_inputs_builders/index.js';
34
+ import { buildPrivateKernelResetInputs, needsReset, somethingToReset } from './hints/index.js';
38
35
  import { type ProvingDataOracle } from './proving_data_oracle.js';
39
36
 
40
37
  const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs> = {
@@ -74,18 +71,23 @@ export class KernelProver {
74
71
  let output = NULL_PROVE_OUTPUT;
75
72
 
76
73
  const noteHashLeafIndexMap = collectNoteHashLeafIndexMap(executionResult);
77
- const noteHashNullifierCounterMap = collectNullifiedNoteHashCounters(executionResult);
74
+ const noteHashNullifierCounterMap = collectNoteHashNullifierCounterMap(executionResult);
75
+ const enqueuedPublicFunctions = collectEnqueuedPublicFunctionCalls(executionResult);
76
+ const hasPublicCalls =
77
+ enqueuedPublicFunctions.length > 0 || !collectPublicTeardownFunctionCall(executionResult).isEmpty();
78
+ const validationRequestsSplitCounter = hasPublicCalls ? getFinalMinRevertibleSideEffectCounter(executionResult) : 0;
78
79
  // vector of gzipped bincode acirs
79
80
  const acirs: Buffer[] = [];
80
81
  const witnessStack: WitnessMap[] = [];
81
82
 
82
83
  while (executionStack.length) {
83
- if (!firstIteration && this.needsReset(executionStack, output)) {
84
+ if (!firstIteration && needsReset(output.publicInputs, executionStack)) {
84
85
  const resetInputs = await this.getPrivateKernelResetInputs(
85
86
  executionStack,
86
87
  output,
87
88
  noteHashLeafIndexMap,
88
89
  noteHashNullifierCounterMap,
90
+ validationRequestsSplitCounter,
89
91
  );
90
92
  output = await this.proofCreator.simulateProofReset(resetInputs);
91
93
  // TODO(#7368) consider refactoring this redundant bytecode pushing
@@ -97,11 +99,6 @@ export class KernelProver {
97
99
  const currentExecution = executionStack.pop()!;
98
100
  executionStack.push(...[...currentExecution.nestedExecutions].reverse());
99
101
 
100
- const publicCallRequests = currentExecution.enqueuedPublicFunctionCalls.map(result => result.toCallRequest());
101
- const publicTeardownCallRequest = currentExecution.publicTeardownFunctionCall.isEmpty()
102
- ? CallRequest.empty()
103
- : currentExecution.publicTeardownFunctionCall.toCallRequest();
104
-
105
102
  const functionName = await this.oracle.getDebugFunctionName(
106
103
  currentExecution.callStackItem.contractAddress,
107
104
  currentExecution.callStackItem.functionData.selector,
@@ -113,12 +110,7 @@ export class KernelProver {
113
110
  acirs.push(currentExecution.acir);
114
111
  witnessStack.push(currentExecution.partialWitness);
115
112
 
116
- const privateCallData = await this.createPrivateCallData(
117
- currentExecution,
118
- publicCallRequests,
119
- publicTeardownCallRequest,
120
- appVk.verificationKey,
121
- );
113
+ const privateCallData = await this.createPrivateCallData(currentExecution, appVk.verificationKey);
122
114
 
123
115
  if (firstIteration) {
124
116
  const proofInput = new PrivateKernelInitCircuitPrivateInputs(txRequest, getVKTreeRoot(), privateCallData);
@@ -143,12 +135,13 @@ export class KernelProver {
143
135
  firstIteration = false;
144
136
  }
145
137
 
146
- if (this.somethingToReset(output)) {
138
+ if (somethingToReset(output.publicInputs)) {
147
139
  const resetInputs = await this.getPrivateKernelResetInputs(
148
140
  executionStack,
149
141
  output,
150
142
  noteHashLeafIndexMap,
151
143
  noteHashNullifierCounterMap,
144
+ validationRequestsSplitCounter,
152
145
  );
153
146
  output = await this.proofCreator.simulateProofReset(resetInputs);
154
147
  // TODO(#7368) consider refactoring this redundant bytecode pushing
@@ -189,47 +182,12 @@ export class KernelProver {
189
182
  return tailOutput;
190
183
  }
191
184
 
192
- private needsReset(
193
- executionStack: ExecutionResult[],
194
- output: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>,
195
- ) {
196
- const nextIteration = executionStack[executionStack.length - 1];
197
- return (
198
- getNonEmptyItems(nextIteration.callStackItem.publicInputs.noteHashes).length +
199
- getNonEmptyItems(output.publicInputs.end.noteHashes).length >
200
- MAX_NOTE_HASHES_PER_TX ||
201
- getNonEmptyItems(nextIteration.callStackItem.publicInputs.nullifiers).length +
202
- getNonEmptyItems(output.publicInputs.end.nullifiers).length >
203
- MAX_NULLIFIERS_PER_TX ||
204
- getNonEmptyItems(nextIteration.callStackItem.publicInputs.noteEncryptedLogsHashes).length +
205
- getNonEmptyItems(output.publicInputs.end.noteEncryptedLogsHashes).length >
206
- MAX_NOTE_ENCRYPTED_LOGS_PER_TX ||
207
- getNonEmptyItems(nextIteration.callStackItem.publicInputs.noteHashReadRequests).length +
208
- getNonEmptyItems(output.publicInputs.validationRequests.noteHashReadRequests).length >
209
- MAX_NOTE_HASH_READ_REQUESTS_PER_TX ||
210
- getNonEmptyItems(nextIteration.callStackItem.publicInputs.nullifierReadRequests).length +
211
- getNonEmptyItems(output.publicInputs.validationRequests.nullifierReadRequests).length >
212
- MAX_NULLIFIER_READ_REQUESTS_PER_TX ||
213
- getNonEmptyItems(nextIteration.callStackItem.publicInputs.keyValidationRequestsAndGenerators).length +
214
- getNonEmptyItems(output.publicInputs.validationRequests.scopedKeyValidationRequestsAndGenerators).length >
215
- MAX_KEY_VALIDATION_REQUESTS_PER_TX
216
- );
217
- }
218
-
219
- private somethingToReset(output: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>) {
220
- return (
221
- getNonEmptyItems(output.publicInputs.validationRequests.noteHashReadRequests).length > 0 ||
222
- getNonEmptyItems(output.publicInputs.validationRequests.nullifierReadRequests).length > 0 ||
223
- getNonEmptyItems(output.publicInputs.validationRequests.scopedKeyValidationRequestsAndGenerators).length > 0 ||
224
- output.publicInputs.end.nullifiers.find(nullifier => !nullifier.nullifiedNoteHash.equals(Fr.zero()))
225
- );
226
- }
227
-
228
185
  private async getPrivateKernelResetInputs(
229
186
  executionStack: ExecutionResult[],
230
187
  output: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>,
231
188
  noteHashLeafIndexMap: Map<bigint, bigint>,
232
189
  noteHashNullifierCounterMap: Map<number, number>,
190
+ validationRequestsSplitCounter: number,
233
191
  ) {
234
192
  const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(output.verificationKey);
235
193
  const previousKernelData = new PrivateKernelData(
@@ -244,20 +202,14 @@ export class KernelProver {
244
202
  previousKernelData,
245
203
  noteHashLeafIndexMap,
246
204
  noteHashNullifierCounterMap,
205
+ validationRequestsSplitCounter,
247
206
  this.oracle,
248
207
  );
249
208
  }
250
209
 
251
- private async createPrivateCallData(
252
- { callStackItem }: ExecutionResult,
253
- publicCallRequests: CallRequest[],
254
- publicTeardownCallRequest: CallRequest,
255
- vk: VerificationKeyAsFields,
256
- ) {
210
+ private async createPrivateCallData({ callStackItem }: ExecutionResult, vk: VerificationKeyAsFields) {
257
211
  const { contractAddress, functionData } = callStackItem;
258
212
 
259
- const publicCallStack = padArrayEnd(publicCallRequests, CallRequest.empty(), MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL);
260
-
261
213
  const functionLeafMembershipWitness = await this.oracle.getFunctionMembershipWitness(
262
214
  contractAddress,
263
215
  functionData.selector,
@@ -274,8 +226,6 @@ export class KernelProver {
274
226
 
275
227
  return PrivateCallData.from({
276
228
  callStackItem,
277
- publicCallStack,
278
- publicTeardownCallRequest,
279
229
  vk,
280
230
  publicKeysHash,
281
231
  contractClassArtifactHash,
@@ -227,7 +227,7 @@ export class NoteProcessor {
227
227
  const incomingNotes = blocksAndNotes.flatMap(b => b.incomingNotes);
228
228
  const outgoingNotes = blocksAndNotes.flatMap(b => b.outgoingNotes);
229
229
  if (incomingNotes.length || outgoingNotes.length) {
230
- await this.db.addNotes(incomingNotes, outgoingNotes);
230
+ await this.db.addNotes(incomingNotes, outgoingNotes, this.account);
231
231
  incomingNotes.forEach(noteDao => {
232
232
  this.log.verbose(
233
233
  `Added incoming note for contract ${noteDao.contractAddress} at slot ${
@@ -51,7 +51,7 @@ export async function produceNoteDaos(
51
51
 
52
52
  try {
53
53
  if (ivpkM) {
54
- const { noteHashIndex, nonce, innerNoteHash, siloedNullifier } = await findNoteIndexAndNullifier(
54
+ const { noteHashIndex, nonce, noteHash, siloedNullifier } = await findNoteIndexAndNullifier(
55
55
  simulator,
56
56
  noteHashes,
57
57
  txHash,
@@ -69,7 +69,7 @@ export async function produceNoteDaos(
69
69
  payload.noteTypeId,
70
70
  txHash,
71
71
  nonce,
72
- innerNoteHash,
72
+ noteHash,
73
73
  siloedNullifier,
74
74
  index,
75
75
  ivpkM,
@@ -108,12 +108,12 @@ export async function produceNoteDaos(
108
108
  payload.noteTypeId,
109
109
  txHash,
110
110
  incomingNote.nonce,
111
- incomingNote.innerNoteHash,
111
+ incomingNote.noteHash,
112
112
  incomingNote.index,
113
113
  ovpkM,
114
114
  );
115
115
  } else {
116
- const { noteHashIndex, nonce, innerNoteHash } = await findNoteIndexAndNullifier(
116
+ const { noteHashIndex, nonce, noteHash } = await findNoteIndexAndNullifier(
117
117
  simulator,
118
118
  noteHashes,
119
119
  txHash,
@@ -130,7 +130,7 @@ export async function produceNoteDaos(
130
130
  payload.noteTypeId,
131
131
  txHash,
132
132
  nonce,
133
- innerNoteHash,
133
+ noteHash,
134
134
  index,
135
135
  ovpkM,
136
136
  );
@@ -170,7 +170,7 @@ export async function produceNoteDaos(
170
170
  * @dev Finds the index in the note hash tree by computing the note hash with different nonce and see which hash for
171
171
  * the current tx matches this value.
172
172
  * @remarks This method assists in identifying spent notes in the note hash tree.
173
- * @param noteHashes - Note hashes in the tx. One of them should correspond to the note we are looking for
173
+ * @param siloedNoteHashes - Note hashes in the tx. One of them should correspond to the note we are looking for
174
174
  * @param txHash - Hash of a tx the note was emitted in.
175
175
  * @param l1NotePayload - The note payload.
176
176
  * @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same
@@ -181,7 +181,7 @@ export async function produceNoteDaos(
181
181
  */
182
182
  async function findNoteIndexAndNullifier(
183
183
  simulator: AcirSimulator,
184
- noteHashes: Fr[],
184
+ siloedNoteHashes: Fr[],
185
185
  txHash: TxHash,
186
186
  { contractAddress, storageSlot, noteTypeId, note }: L1NotePayload,
187
187
  excludedIndices: Set<number>,
@@ -189,23 +189,23 @@ async function findNoteIndexAndNullifier(
189
189
  ) {
190
190
  let noteHashIndex = 0;
191
191
  let nonce: Fr | undefined;
192
- let innerNoteHash: Fr | undefined;
192
+ let noteHash: Fr | undefined;
193
193
  let siloedNoteHash: Fr | undefined;
194
194
  let innerNullifier: Fr | undefined;
195
195
  const firstNullifier = Fr.fromBuffer(txHash.toBuffer());
196
196
 
197
- for (; noteHashIndex < noteHashes.length; ++noteHashIndex) {
197
+ for (; noteHashIndex < siloedNoteHashes.length; ++noteHashIndex) {
198
198
  if (excludedIndices.has(noteHashIndex)) {
199
199
  continue;
200
200
  }
201
201
 
202
- const noteHash = noteHashes[noteHashIndex];
203
- if (noteHash.equals(Fr.ZERO)) {
202
+ const siloedNoteHashFromTxEffect = siloedNoteHashes[noteHashIndex];
203
+ if (siloedNoteHashFromTxEffect.equals(Fr.ZERO)) {
204
204
  break;
205
205
  }
206
206
 
207
207
  const expectedNonce = computeNoteHashNonce(firstNullifier, noteHashIndex);
208
- ({ innerNoteHash, siloedNoteHash, innerNullifier } = await simulator.computeNoteHashAndOptionallyANullifier(
208
+ ({ noteHash, siloedNoteHash, innerNullifier } = await simulator.computeNoteHashAndOptionallyANullifier(
209
209
  contractAddress,
210
210
  expectedNonce,
211
211
  storageSlot,
@@ -214,7 +214,7 @@ async function findNoteIndexAndNullifier(
214
214
  note,
215
215
  ));
216
216
 
217
- if (noteHash.equals(siloedNoteHash)) {
217
+ if (siloedNoteHashFromTxEffect.equals(siloedNoteHash)) {
218
218
  nonce = expectedNonce;
219
219
  break;
220
220
  }
@@ -229,7 +229,7 @@ async function findNoteIndexAndNullifier(
229
229
  return {
230
230
  noteHashIndex,
231
231
  nonce,
232
- innerNoteHash: innerNoteHash!,
232
+ noteHash: noteHash!,
233
233
  siloedNullifier: siloNullifier(contractAddress, innerNullifier!),
234
234
  };
235
235
  }
@@ -22,6 +22,7 @@ import { NoteSelector } from '@aztec/foundation/abi';
22
22
  import { AztecAddress } from '@aztec/foundation/aztec-address';
23
23
  import { EthAddress } from '@aztec/foundation/eth-address';
24
24
  import { Fr, GrumpkinScalar, Point } from '@aztec/foundation/fields';
25
+ import { BaseHashType } from '@aztec/foundation/hash';
25
26
  import { JsonRpcServer, createNamespacedJsonRpcServer } from '@aztec/foundation/json-rpc/server';
26
27
 
27
28
  import http from 'http';
@@ -40,6 +41,7 @@ export function createPXERpcServer(pxeService: PXE): JsonRpcServer {
40
41
  ExtendedUnencryptedL2Log,
41
42
  FunctionSelector,
42
43
  TxHash,
44
+ BaseHashType,
43
45
  EthAddress,
44
46
  Point,
45
47
  Fr,
@@ -7,7 +7,7 @@ import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
7
7
  import { initStoreForRollup } from '@aztec/kv-store/utils';
8
8
  import { getCanonicalAuthRegistry } from '@aztec/protocol-contracts/auth-registry';
9
9
  import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer';
10
- import { getCanonicalGasToken } from '@aztec/protocol-contracts/gas-token';
10
+ import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
11
11
  import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer';
12
12
  import { getCanonicalKeyRegistry } from '@aztec/protocol-contracts/key-registry';
13
13
  import { getCanonicalMultiCallEntrypointContract } from '@aztec/protocol-contracts/multi-call-entrypoint';
@@ -66,7 +66,7 @@ export async function createPXEService(
66
66
  getCanonicalClassRegisterer(),
67
67
  getCanonicalInstanceDeployer(),
68
68
  getCanonicalMultiCallEntrypointContract(),
69
- getCanonicalGasToken(),
69
+ getCanonicalFeeJuice(),
70
70
  getCanonicalKeyRegistry(),
71
71
  getCanonicalAuthRegistry(),
72
72
  ]) {
@@ -44,11 +44,11 @@ import {
44
44
  encodeArguments,
45
45
  } from '@aztec/foundation/abi';
46
46
  import { type Fq, Fr, type Point } from '@aztec/foundation/fields';
47
- import { SerialQueue } from '@aztec/foundation/fifo';
48
47
  import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
48
+ import { SerialQueue } from '@aztec/foundation/queue';
49
49
  import { type KeyStore } from '@aztec/key-store';
50
50
  import { ClassRegistererAddress } from '@aztec/protocol-contracts/class-registerer';
51
- import { getCanonicalGasToken } from '@aztec/protocol-contracts/gas-token';
51
+ import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
52
52
  import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer';
53
53
  import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry';
54
54
  import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint';
@@ -338,7 +338,7 @@ export class PXEService implements PXE {
338
338
  return Promise.all(extendedNotes);
339
339
  }
340
340
 
341
- public async addNote(note: ExtendedNote) {
341
+ public async addNote(note: ExtendedNote, scope?: AztecAddress) {
342
342
  const owner = await this.db.getCompleteAddress(note.owner);
343
343
  if (!owner) {
344
344
  throw new Error(`Unknown account: ${note.owner.toString()}`);
@@ -350,15 +350,14 @@ export class PXEService implements PXE {
350
350
  }
351
351
 
352
352
  for (const nonce of nonces) {
353
- const { innerNoteHash, siloedNoteHash, innerNullifier } =
354
- await this.simulator.computeNoteHashAndOptionallyANullifier(
355
- note.contractAddress,
356
- nonce,
357
- note.storageSlot,
358
- note.noteTypeId,
359
- true,
360
- note.note,
361
- );
353
+ const { noteHash, siloedNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
354
+ note.contractAddress,
355
+ nonce,
356
+ note.storageSlot,
357
+ note.noteTypeId,
358
+ true,
359
+ note.note,
360
+ );
362
361
 
363
362
  const index = await this.node.findLeafIndex('latest', MerkleTreeId.NOTE_HASH_TREE, siloedNoteHash);
364
363
  if (index === undefined) {
@@ -379,11 +378,12 @@ export class PXEService implements PXE {
379
378
  note.noteTypeId,
380
379
  note.txHash,
381
380
  nonce,
382
- innerNoteHash,
381
+ noteHash,
383
382
  siloedNullifier,
384
383
  index,
385
384
  owner.publicKeys.masterIncomingViewingPublicKey,
386
385
  ),
386
+ scope,
387
387
  );
388
388
  }
389
389
  }
@@ -400,15 +400,14 @@ export class PXEService implements PXE {
400
400
  }
401
401
 
402
402
  for (const nonce of nonces) {
403
- const { innerNoteHash, siloedNoteHash, innerNullifier } =
404
- await this.simulator.computeNoteHashAndOptionallyANullifier(
405
- note.contractAddress,
406
- nonce,
407
- note.storageSlot,
408
- note.noteTypeId,
409
- false,
410
- note.note,
411
- );
403
+ const { noteHash, siloedNoteHash, innerNullifier } = await this.simulator.computeNoteHashAndOptionallyANullifier(
404
+ note.contractAddress,
405
+ nonce,
406
+ note.storageSlot,
407
+ note.noteTypeId,
408
+ false,
409
+ note.note,
410
+ );
412
411
 
413
412
  if (!innerNullifier.equals(Fr.ZERO)) {
414
413
  throw new Error('Unexpectedly received non-zero nullifier.');
@@ -427,7 +426,7 @@ export class PXEService implements PXE {
427
426
  note.noteTypeId,
428
427
  note.txHash,
429
428
  nonce,
430
- innerNoteHash,
429
+ noteHash,
431
430
  Fr.ZERO, // We are not able to derive
432
431
  index,
433
432
  owner.publicKeys.masterIncomingViewingPublicKey,
@@ -450,24 +449,6 @@ export class PXEService implements PXE {
450
449
  }
451
450
 
452
451
  const nonces: Fr[] = [];
453
-
454
- // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)
455
- // Remove this once notes added from public also include nonces.
456
- {
457
- const publicNoteNonce = Fr.ZERO;
458
- const { siloedNoteHash } = await this.simulator.computeNoteHashAndOptionallyANullifier(
459
- note.contractAddress,
460
- publicNoteNonce,
461
- note.storageSlot,
462
- note.noteTypeId,
463
- false,
464
- note.note,
465
- );
466
- if (tx.noteHashes.some(hash => hash.equals(siloedNoteHash))) {
467
- nonces.push(publicNoteNonce);
468
- }
469
- }
470
-
471
452
  const firstNullifier = tx.nullifiers[0];
472
453
  const hashes = tx.noteHashes;
473
454
  for (let i = 0; i < hashes.length; ++i) {
@@ -501,9 +482,9 @@ export class PXEService implements PXE {
501
482
  return await this.node.getBlock(blockNumber);
502
483
  }
503
484
 
504
- public proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise<Tx> {
485
+ public proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean, scopes?: AztecAddress[]): Promise<Tx> {
505
486
  return this.jobQueue.put(async () => {
506
- const simulatedTx = await this.#simulateAndProve(txRequest, this.proofCreator, undefined);
487
+ const simulatedTx = await this.#simulateAndProve(txRequest, this.proofCreator, undefined, scopes);
507
488
  if (simulatePublic) {
508
489
  simulatedTx.publicOutput = await this.#simulatePublicCalls(simulatedTx.tx);
509
490
  }
@@ -516,9 +497,10 @@ export class PXEService implements PXE {
516
497
  txRequest: TxExecutionRequest,
517
498
  simulatePublic: boolean,
518
499
  msgSender: AztecAddress | undefined = undefined,
500
+ scopes?: AztecAddress[],
519
501
  ): Promise<SimulatedTx> {
520
502
  return await this.jobQueue.put(async () => {
521
- const simulatedTx = await this.#simulateAndProve(txRequest, this.fakeProofCreator, msgSender);
503
+ const simulatedTx = await this.#simulateAndProve(txRequest, this.fakeProofCreator, msgSender, scopes);
522
504
  if (simulatePublic) {
523
505
  simulatedTx.publicOutput = await this.#simulatePublicCalls(simulatedTx.tx);
524
506
  }
@@ -549,12 +531,13 @@ export class PXEService implements PXE {
549
531
  args: any[],
550
532
  to: AztecAddress,
551
533
  _from?: AztecAddress,
534
+ scopes?: AztecAddress[],
552
535
  ): Promise<DecodedReturn> {
553
536
  // all simulations must be serialized w.r.t. the synchronizer
554
537
  return await this.jobQueue.put(async () => {
555
538
  // TODO - Should check if `from` has the permission to call the view function.
556
539
  const functionCall = await this.#getFunctionCall(functionName, args, to);
557
- const executionResult = await this.#simulateUnconstrained(functionCall);
540
+ const executionResult = await this.#simulateUnconstrained(functionCall, scopes);
558
541
 
559
542
  // TODO - Return typed result based on the function artifact.
560
543
  return executionResult;
@@ -590,7 +573,7 @@ export class PXEService implements PXE {
590
573
  const contract = await this.db.getContract(to);
591
574
  if (!contract) {
592
575
  throw new Error(
593
- `Unknown contract ${to}: add it to PXE Service by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
576
+ `Unknown contract ${to}: add it to PXE Service by calling server.addContracts(...).\nSee docs for context: https://docs.aztec.network/reference/common_errors/aztecnr-errors#unknown-contract-0x0-add-it-to-pxe-by-calling-serveraddcontracts`,
594
577
  );
595
578
  }
596
579
 
@@ -635,7 +618,7 @@ export class PXEService implements PXE {
635
618
  pxeVersion: this.packageVersion,
636
619
  protocolContractAddresses: {
637
620
  classRegisterer: ClassRegistererAddress,
638
- gasToken: getCanonicalGasToken().address,
621
+ feeJuice: getCanonicalFeeJuice().address,
639
622
  instanceDeployer: getCanonicalInstanceDeployer().address,
640
623
  keyRegistry: getCanonicalKeyRegistryAddress(),
641
624
  multiCallEntrypoint: getCanonicalMultiCallEntrypointAddress(),
@@ -666,14 +649,18 @@ export class PXEService implements PXE {
666
649
  };
667
650
  }
668
651
 
669
- async #simulate(txRequest: TxExecutionRequest, msgSender?: AztecAddress): Promise<ExecutionResult> {
652
+ async #simulate(
653
+ txRequest: TxExecutionRequest,
654
+ msgSender?: AztecAddress,
655
+ scopes?: AztecAddress[],
656
+ ): Promise<ExecutionResult> {
670
657
  // TODO - Pause syncing while simulating.
671
658
 
672
659
  const { contractAddress, functionArtifact } = await this.#getSimulationParameters(txRequest);
673
660
 
674
661
  this.log.debug('Executing simulator...');
675
662
  try {
676
- const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, msgSender);
663
+ const result = await this.simulator.run(txRequest, functionArtifact, contractAddress, msgSender, scopes);
677
664
  this.log.verbose(`Simulation completed for ${contractAddress.toString()}:${functionArtifact.name}`);
678
665
  return result;
679
666
  } catch (err) {
@@ -690,14 +677,15 @@ export class PXEService implements PXE {
690
677
  * Returns the simulation result containing the outputs of the unconstrained function.
691
678
  *
692
679
  * @param execRequest - The transaction request object containing the target contract and function data.
680
+ * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
693
681
  * @returns The simulation result containing the outputs of the unconstrained function.
694
682
  */
695
- async #simulateUnconstrained(execRequest: FunctionCall) {
683
+ async #simulateUnconstrained(execRequest: FunctionCall, scopes?: AztecAddress[]) {
696
684
  const { contractAddress, functionArtifact } = await this.#getSimulationParameters(execRequest);
697
685
 
698
686
  this.log.debug('Executing unconstrained simulator...');
699
687
  try {
700
- const result = await this.simulator.runUnconstrained(execRequest, functionArtifact, contractAddress);
688
+ const result = await this.simulator.runUnconstrained(execRequest, functionArtifact, contractAddress, scopes);
701
689
  this.log.verbose(`Unconstrained simulation for ${contractAddress}.${functionArtifact.name} completed`);
702
690
 
703
691
  return result;
@@ -755,6 +743,7 @@ export class PXEService implements PXE {
755
743
  * @param txExecutionRequest - The transaction request to be simulated and proved.
756
744
  * @param proofCreator - The proof creator to use for proving the execution.
757
745
  * @param msgSender - (Optional) The message sender to use for the simulation.
746
+ * @param scopes - The accounts whose notes we can access in this call. Currently optional and will default to all.
758
747
  * @returns An object that contains:
759
748
  * A private transaction object containing the proof, public inputs, and encrypted logs.
760
749
  * The return values of the private execution
@@ -763,9 +752,10 @@ export class PXEService implements PXE {
763
752
  txExecutionRequest: TxExecutionRequest,
764
753
  proofCreator: PrivateKernelProver,
765
754
  msgSender?: AztecAddress,
755
+ scopes?: AztecAddress[],
766
756
  ): Promise<SimulatedTx> {
767
757
  // Get values that allow us to reconstruct the block hash
768
- const executionResult = await this.#simulate(txExecutionRequest, msgSender);
758
+ const executionResult = await this.#simulate(txExecutionRequest, msgSender, scopes);
769
759
 
770
760
  const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node);
771
761
  const kernelProver = new KernelProver(kernelOracle, proofCreator);
@@ -855,6 +845,11 @@ export class PXEService implements PXE {
855
845
  return !!(await this.node.getContract(address));
856
846
  }
857
847
 
848
+ public async isContractInitialized(address: AztecAddress): Promise<boolean> {
849
+ const initNullifier = siloNullifier(address, address);
850
+ return !!(await this.node.getNullifierMembershipWitness('latest', initNullifier));
851
+ }
852
+
858
853
  public getEvents<T>(
859
854
  type: EventType.Encrypted,
860
855
  eventMetadata: EventMetadata<T>,
@@ -47,7 +47,7 @@ export class SimulatorOracle implements DBOracle {
47
47
  if (!completeAddress) {
48
48
  throw new Error(
49
49
  `No public key registered for address ${account}.
50
- Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/developers/debugging/aztecnr-errors#simulation-error-No-public-key-registered-for-address-0x0-Register-it-by-calling-pxeregisterRecipient-or-pxeregisterAccount`,
50
+ Register it by calling pxe.registerRecipient(...) or pxe.registerAccount(...).\nSee docs for context: https://docs.aztec.network/reference/common_errors/aztecnr-errors#simulation-error-no-public-key-registered-for-address-0x0-register-it-by-calling-pxeregisterrecipient-or-pxeregisteraccount`,
51
51
  );
52
52
  }
53
53
  return completeAddress;
@@ -77,18 +77,19 @@ export class SimulatorOracle implements DBOracle {
77
77
  return capsule;
78
78
  }
79
79
 
80
- async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus) {
80
+ async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus, scopes?: AztecAddress[]) {
81
81
  const noteDaos = await this.db.getIncomingNotes({
82
82
  contractAddress,
83
83
  storageSlot,
84
84
  status,
85
+ scopes,
85
86
  });
86
- return noteDaos.map(({ contractAddress, storageSlot, nonce, note, innerNoteHash, siloedNullifier, index }) => ({
87
+ return noteDaos.map(({ contractAddress, storageSlot, nonce, note, noteHash, siloedNullifier, index }) => ({
87
88
  contractAddress,
88
89
  storageSlot,
89
90
  nonce,
90
91
  note,
91
- innerNoteHash,
92
+ noteHash,
92
93
  siloedNullifier,
93
94
  // PXE can use this index to get full MembershipWitness
94
95
  index,