@aztec/pxe 0.56.0 → 0.58.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 (111) hide show
  1. package/dest/bin/index.js +0 -0
  2. package/dest/contract_data_oracle/index.d.ts +1 -2
  3. package/dest/contract_data_oracle/index.d.ts.map +1 -1
  4. package/dest/contract_data_oracle/index.js +1 -1
  5. package/dest/contract_data_oracle/private_functions_tree.d.ts +1 -2
  6. package/dest/contract_data_oracle/private_functions_tree.d.ts.map +1 -1
  7. package/dest/contract_data_oracle/private_functions_tree.js +1 -1
  8. package/dest/database/contracts/contract_instance_db.d.ts +1 -2
  9. package/dest/database/contracts/contract_instance_db.d.ts.map +1 -1
  10. package/dest/database/deferred_note_dao.d.ts +6 -2
  11. package/dest/database/deferred_note_dao.d.ts.map +1 -1
  12. package/dest/database/deferred_note_dao.js +8 -5
  13. package/dest/database/incoming_note_dao.d.ts +3 -1
  14. package/dest/database/incoming_note_dao.d.ts.map +1 -1
  15. package/dest/database/incoming_note_dao.js +5 -1
  16. package/dest/database/kv_pxe_database.d.ts +1 -2
  17. package/dest/database/kv_pxe_database.d.ts.map +1 -1
  18. package/dest/database/kv_pxe_database.js +4 -4
  19. package/dest/database/outgoing_note_dao.d.ts +3 -1
  20. package/dest/database/outgoing_note_dao.d.ts.map +1 -1
  21. package/dest/database/outgoing_note_dao.js +5 -1
  22. package/dest/database/pxe_database.d.ts +1 -2
  23. package/dest/database/pxe_database.d.ts.map +1 -1
  24. package/dest/database/pxe_database_test_suite.d.ts.map +1 -1
  25. package/dest/database/pxe_database_test_suite.js +2 -3
  26. package/dest/kernel_oracle/index.d.ts +8 -4
  27. package/dest/kernel_oracle/index.d.ts.map +1 -1
  28. package/dest/kernel_oracle/index.js +6 -5
  29. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts +28 -0
  30. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -0
  31. package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.js +260 -0
  32. package/dest/kernel_prover/hints/index.d.ts +1 -2
  33. package/dest/kernel_prover/hints/index.d.ts.map +1 -1
  34. package/dest/kernel_prover/hints/index.js +2 -3
  35. package/dest/kernel_prover/kernel_prover.d.ts +2 -4
  36. package/dest/kernel_prover/kernel_prover.d.ts.map +1 -1
  37. package/dest/kernel_prover/kernel_prover.js +37 -30
  38. package/dest/kernel_prover/proving_data_oracle.d.ts +2 -2
  39. package/dest/kernel_prover/proving_data_oracle.d.ts.map +1 -1
  40. package/dest/kernel_prover/test/test_circuit_prover.d.ts +2 -3
  41. package/dest/kernel_prover/test/test_circuit_prover.d.ts.map +1 -1
  42. package/dest/kernel_prover/test/test_circuit_prover.js +10 -13
  43. package/dest/note_processor/note_processor.d.ts +3 -3
  44. package/dest/note_processor/note_processor.d.ts.map +1 -1
  45. package/dest/note_processor/note_processor.js +16 -18
  46. package/dest/note_processor/utils/add_nullable_field_to_payload.d.ts +12 -0
  47. package/dest/note_processor/utils/add_nullable_field_to_payload.d.ts.map +1 -0
  48. package/dest/note_processor/utils/add_nullable_field_to_payload.js +46 -0
  49. package/dest/note_processor/utils/brute_force_note_info.d.ts +26 -0
  50. package/dest/note_processor/utils/brute_force_note_info.d.ts.map +1 -0
  51. package/dest/note_processor/utils/brute_force_note_info.js +52 -0
  52. package/dest/note_processor/utils/index.d.ts +3 -0
  53. package/dest/note_processor/utils/index.d.ts.map +1 -0
  54. package/dest/note_processor/utils/index.js +2 -0
  55. package/dest/note_processor/{produce_note_dao.d.ts → utils/produce_note_daos.d.ts} +12 -8
  56. package/dest/note_processor/utils/produce_note_daos.d.ts.map +1 -0
  57. package/dest/note_processor/utils/produce_note_daos.js +53 -0
  58. package/dest/note_processor/utils/produce_note_daos_for_key.d.ts +9 -0
  59. package/dest/note_processor/utils/produce_note_daos_for_key.d.ts.map +1 -0
  60. package/dest/note_processor/utils/produce_note_daos_for_key.js +80 -0
  61. package/dest/pxe_http/pxe_http_server.d.ts.map +1 -1
  62. package/dest/pxe_http/pxe_http_server.js +13 -4
  63. package/dest/pxe_service/create_pxe_service.d.ts.map +1 -1
  64. package/dest/pxe_service/create_pxe_service.js +2 -18
  65. package/dest/pxe_service/pxe_service.d.ts +4 -6
  66. package/dest/pxe_service/pxe_service.d.ts.map +1 -1
  67. package/dest/pxe_service/pxe_service.js +55 -49
  68. package/dest/simulator_oracle/index.d.ts +1 -2
  69. package/dest/simulator_oracle/index.d.ts.map +1 -1
  70. package/dest/simulator_oracle/index.js +1 -1
  71. package/dest/synchronizer/synchronizer.d.ts +2 -2
  72. package/dest/synchronizer/synchronizer.d.ts.map +1 -1
  73. package/dest/synchronizer/synchronizer.js +6 -10
  74. package/package.json +17 -14
  75. package/src/contract_data_oracle/index.ts +1 -2
  76. package/src/contract_data_oracle/private_functions_tree.ts +1 -1
  77. package/src/database/contracts/contract_instance_db.ts +1 -2
  78. package/src/database/deferred_note_dao.ts +5 -1
  79. package/src/database/incoming_note_dao.ts +24 -1
  80. package/src/database/kv_pxe_database.ts +10 -3
  81. package/src/database/outgoing_note_dao.ts +23 -1
  82. package/src/database/pxe_database.ts +6 -2
  83. package/src/database/pxe_database_test_suite.ts +7 -2
  84. package/src/kernel_oracle/index.ts +5 -4
  85. package/src/kernel_prover/hints/build_private_kernel_reset_private_inputs.ts +467 -0
  86. package/src/kernel_prover/hints/index.ts +1 -2
  87. package/src/kernel_prover/kernel_prover.ts +74 -79
  88. package/src/kernel_prover/proving_data_oracle.ts +2 -1
  89. package/src/kernel_prover/test/test_circuit_prover.ts +13 -16
  90. package/src/note_processor/note_processor.ts +36 -27
  91. package/src/note_processor/utils/add_nullable_field_to_payload.ts +67 -0
  92. package/src/note_processor/utils/brute_force_note_info.ts +82 -0
  93. package/src/note_processor/utils/index.ts +2 -0
  94. package/src/note_processor/utils/produce_note_daos.ts +114 -0
  95. package/src/note_processor/utils/produce_note_daos_for_key.ts +157 -0
  96. package/src/pxe_http/pxe_http_server.ts +19 -3
  97. package/src/pxe_service/create_pxe_service.ts +1 -18
  98. package/src/pxe_service/pxe_service.ts +81 -83
  99. package/src/simulator_oracle/index.ts +1 -1
  100. package/src/synchronizer/synchronizer.ts +12 -10
  101. package/dest/kernel_prover/hints/build_private_kernel_reset_hints.d.ts +0 -5
  102. package/dest/kernel_prover/hints/build_private_kernel_reset_hints.d.ts.map +0 -1
  103. package/dest/kernel_prover/hints/build_private_kernel_reset_hints.js +0 -90
  104. package/dest/kernel_prover/hints/needs_reset.d.ts +0 -5
  105. package/dest/kernel_prover/hints/needs_reset.d.ts.map +0 -1
  106. package/dest/kernel_prover/hints/needs_reset.js +0 -38
  107. package/dest/note_processor/produce_note_dao.d.ts.map +0 -1
  108. package/dest/note_processor/produce_note_dao.js +0 -131
  109. package/src/kernel_prover/hints/build_private_kernel_reset_hints.ts +0 -249
  110. package/src/kernel_prover/hints/needs_reset.ts +0 -54
  111. package/src/note_processor/produce_note_dao.ts +0 -235
@@ -1,6 +1,17 @@
1
- import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types';
2
1
  import {
2
+ type PrivateExecutionResult,
3
+ type PrivateKernelProver,
4
+ type PrivateKernelSimulateOutput,
5
+ collectEnqueuedPublicFunctionCalls,
6
+ collectNoteHashLeafIndexMap,
7
+ collectNoteHashNullifierCounterMap,
8
+ collectPublicTeardownFunctionCall,
9
+ getFinalMinRevertibleSideEffectCounter,
10
+ } from '@aztec/circuit-types';
11
+ import {
12
+ CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS,
3
13
  Fr,
14
+ PROTOCOL_CONTRACT_TREE_HEIGHT,
4
15
  PrivateCallData,
5
16
  PrivateKernelCircuitPublicInputs,
6
17
  PrivateKernelData,
@@ -12,32 +23,27 @@ import {
12
23
  VK_TREE_HEIGHT,
13
24
  VerificationKeyAsFields,
14
25
  } from '@aztec/circuits.js';
26
+ import { makeTuple } from '@aztec/foundation/array';
15
27
  import { createDebugLogger } from '@aztec/foundation/log';
16
28
  import { assertLength } from '@aztec/foundation/serialize';
17
29
  import { pushTestData } from '@aztec/foundation/testing';
30
+ import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types';
18
31
  import {
19
- ClientCircuitArtifacts,
20
- PrivateResetTagToArtifactName,
21
- getVKTreeRoot,
22
- } from '@aztec/noir-protocol-circuits-types';
23
- import {
24
- type ExecutionResult,
25
- collectEnqueuedPublicFunctionCalls,
26
- collectNoteHashLeafIndexMap,
27
- collectNoteHashNullifierCounterMap,
28
- collectPublicTeardownFunctionCall,
29
- getFinalMinRevertibleSideEffectCounter,
30
- } from '@aztec/simulator';
32
+ getProtocolContractSiblingPath,
33
+ isProtocolContract,
34
+ protocolContractTreeRoot,
35
+ } from '@aztec/protocol-contracts';
31
36
 
32
37
  import { type WitnessMap } from '@noir-lang/types';
33
38
 
34
- import { buildPrivateKernelResetInputs, needsFinalReset, needsReset } from './hints/index.js';
39
+ import { PrivateKernelResetPrivateInputsBuilder } from './hints/build_private_kernel_reset_private_inputs.js';
35
40
  import { type ProvingDataOracle } from './proving_data_oracle.js';
36
41
 
37
42
  const NULL_PROVE_OUTPUT: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs> = {
38
43
  publicInputs: PrivateKernelCircuitPublicInputs.empty(),
39
- verificationKey: VerificationKeyAsFields.makeEmpty(),
44
+ verificationKey: VerificationKeyAsFields.makeEmpty(CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS),
40
45
  outputWitness: new Map(),
46
+ bytecode: Buffer.from([]),
41
47
  };
42
48
  /**
43
49
  * The KernelProver class is responsible for generating kernel proofs.
@@ -63,7 +69,7 @@ export class KernelProver {
63
69
  */
64
70
  async prove(
65
71
  txRequest: TxRequest,
66
- executionResult: ExecutionResult,
72
+ executionResult: PrivateExecutionResult,
67
73
  ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
68
74
  const executionStack = [executionResult];
69
75
  let firstIteration = true;
@@ -81,22 +87,29 @@ export class KernelProver {
81
87
  const witnessStack: WitnessMap[] = [];
82
88
 
83
89
  while (executionStack.length) {
84
- if (!firstIteration && needsReset(output.publicInputs, executionStack)) {
85
- const resetInputs = await this.getPrivateKernelResetInputs(
86
- executionStack,
90
+ if (!firstIteration) {
91
+ let resetBuilder = new PrivateKernelResetPrivateInputsBuilder(
87
92
  output,
88
- noteHashLeafIndexMap,
93
+ executionStack,
89
94
  noteHashNullifierCounterMap,
90
95
  validationRequestsSplitCounter,
91
- false,
92
96
  );
93
- output = await this.proofCreator.simulateProofReset(resetInputs);
94
- // TODO(#7368) consider refactoring this redundant bytecode pushing
95
- acirs.push(
96
- Buffer.from(ClientCircuitArtifacts[PrivateResetTagToArtifactName[resetInputs.sizeTag]].bytecode, 'base64'),
97
- );
98
- witnessStack.push(output.outputWitness);
97
+ while (resetBuilder.needsReset()) {
98
+ const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap);
99
+ output = await this.proofCreator.simulateProofReset(privateInputs);
100
+ // TODO(#7368) consider refactoring this redundant bytecode pushing
101
+ acirs.push(output.bytecode);
102
+ witnessStack.push(output.outputWitness);
103
+
104
+ resetBuilder = new PrivateKernelResetPrivateInputsBuilder(
105
+ output,
106
+ executionStack,
107
+ noteHashNullifierCounterMap,
108
+ validationRequestsSplitCounter,
109
+ );
110
+ }
99
111
  }
112
+
100
113
  const currentExecution = executionStack.pop()!;
101
114
  executionStack.push(...[...currentExecution.nestedExecutions].reverse());
102
115
 
@@ -114,10 +127,15 @@ export class KernelProver {
114
127
  const privateCallData = await this.createPrivateCallData(currentExecution, appVk.verificationKey);
115
128
 
116
129
  if (firstIteration) {
117
- const proofInput = new PrivateKernelInitCircuitPrivateInputs(txRequest, getVKTreeRoot(), privateCallData);
130
+ const proofInput = new PrivateKernelInitCircuitPrivateInputs(
131
+ txRequest,
132
+ getVKTreeRoot(),
133
+ protocolContractTreeRoot,
134
+ privateCallData,
135
+ );
118
136
  pushTestData('private-kernel-inputs-init', proofInput);
119
137
  output = await this.proofCreator.simulateProofInit(proofInput);
120
- acirs.push(Buffer.from(ClientCircuitArtifacts.PrivateKernelInitArtifact.bytecode, 'base64'));
138
+ acirs.push(output.bytecode);
121
139
  witnessStack.push(output.outputWitness);
122
140
  } else {
123
141
  const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(output.verificationKey);
@@ -130,28 +148,34 @@ export class KernelProver {
130
148
  const proofInput = new PrivateKernelInnerCircuitPrivateInputs(previousKernelData, privateCallData);
131
149
  pushTestData('private-kernel-inputs-inner', proofInput);
132
150
  output = await this.proofCreator.simulateProofInner(proofInput);
133
- acirs.push(Buffer.from(ClientCircuitArtifacts.PrivateKernelInnerArtifact.bytecode, 'base64'));
151
+ acirs.push(output.bytecode);
134
152
  witnessStack.push(output.outputWitness);
135
153
  }
136
154
  firstIteration = false;
137
155
  }
138
156
 
139
- if (needsFinalReset(output.publicInputs)) {
140
- const resetInputs = await this.getPrivateKernelResetInputs(
141
- executionStack,
157
+ // Reset.
158
+ let resetBuilder = new PrivateKernelResetPrivateInputsBuilder(
159
+ output,
160
+ [],
161
+ noteHashNullifierCounterMap,
162
+ validationRequestsSplitCounter,
163
+ );
164
+ while (resetBuilder.needsReset()) {
165
+ const privateInputs = await resetBuilder.build(this.oracle, noteHashLeafIndexMap);
166
+ output = await this.proofCreator.simulateProofReset(privateInputs);
167
+ acirs.push(output.bytecode);
168
+ witnessStack.push(output.outputWitness);
169
+
170
+ resetBuilder = new PrivateKernelResetPrivateInputsBuilder(
142
171
  output,
143
- noteHashLeafIndexMap,
172
+ [],
144
173
  noteHashNullifierCounterMap,
145
174
  validationRequestsSplitCounter,
146
- true,
147
- );
148
- output = await this.proofCreator.simulateProofReset(resetInputs);
149
- // TODO(#7368) consider refactoring this redundant bytecode pushing
150
- acirs.push(
151
- Buffer.from(ClientCircuitArtifacts[PrivateResetTagToArtifactName[resetInputs.sizeTag]].bytecode, 'base64'),
152
175
  );
153
- witnessStack.push(output.outputWitness);
154
176
  }
177
+
178
+ // Private tail.
155
179
  const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(output.verificationKey);
156
180
  const previousKernelData = new PrivateKernelData(
157
181
  output.publicInputs,
@@ -168,14 +192,7 @@ export class KernelProver {
168
192
 
169
193
  pushTestData('private-kernel-inputs-ordering', privateInputs);
170
194
  const tailOutput = await this.proofCreator.simulateProofTail(privateInputs);
171
- acirs.push(
172
- Buffer.from(
173
- privateInputs.isForPublic()
174
- ? ClientCircuitArtifacts.PrivateKernelTailToPublicArtifact.bytecode
175
- : ClientCircuitArtifacts.PrivateKernelTailArtifact.bytecode,
176
- 'base64',
177
- ),
178
- );
195
+ acirs.push(tailOutput.bytecode);
179
196
  witnessStack.push(tailOutput.outputWitness);
180
197
 
181
198
  // TODO(#7368) how do we 'bincode' encode these inputs?
@@ -184,41 +201,14 @@ export class KernelProver {
184
201
  return tailOutput;
185
202
  }
186
203
 
187
- private async getPrivateKernelResetInputs(
188
- executionStack: ExecutionResult[],
189
- output: PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>,
190
- noteHashLeafIndexMap: Map<bigint, bigint>,
191
- noteHashNullifierCounterMap: Map<number, number>,
192
- validationRequestsSplitCounter: number,
193
- shouldSilo: boolean,
194
- ) {
195
- const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(output.verificationKey);
196
- const previousKernelData = new PrivateKernelData(
197
- output.publicInputs,
198
- output.verificationKey,
199
- Number(previousVkMembershipWitness.leafIndex),
200
- assertLength<Fr, typeof VK_TREE_HEIGHT>(previousVkMembershipWitness.siblingPath, VK_TREE_HEIGHT),
201
- );
202
-
203
- return await buildPrivateKernelResetInputs(
204
- executionStack,
205
- previousKernelData,
206
- noteHashLeafIndexMap,
207
- noteHashNullifierCounterMap,
208
- validationRequestsSplitCounter,
209
- shouldSilo,
210
- this.oracle,
211
- );
212
- }
213
-
214
- private async createPrivateCallData({ callStackItem }: ExecutionResult, vk: VerificationKeyAsFields) {
204
+ private async createPrivateCallData({ callStackItem }: PrivateExecutionResult, vk: VerificationKeyAsFields) {
215
205
  const { contractAddress, functionData } = callStackItem;
216
206
 
217
207
  const functionLeafMembershipWitness = await this.oracle.getFunctionMembershipWitness(
218
208
  contractAddress,
219
209
  functionData.selector,
220
210
  );
221
- const { contractClassId, publicKeysHash, saltedInitializationHash } = await this.oracle.getContractAddressPreimage(
211
+ const { contractClassId, publicKeys, saltedInitializationHash } = await this.oracle.getContractAddressPreimage(
222
212
  contractAddress,
223
213
  );
224
214
  const { artifactHash: contractClassArtifactHash, publicBytecodeCommitment: contractClassPublicBytecodeCommitment } =
@@ -228,14 +218,19 @@ export class KernelProver {
228
218
  // const acirHash = keccak256(Buffer.from(bytecode, 'hex'));
229
219
  const acirHash = Fr.fromBuffer(Buffer.alloc(32, 0));
230
220
 
221
+ const protocolContractSiblingPath = isProtocolContract(contractAddress)
222
+ ? getProtocolContractSiblingPath(contractAddress)
223
+ : makeTuple(PROTOCOL_CONTRACT_TREE_HEIGHT, Fr.zero);
224
+
231
225
  return PrivateCallData.from({
232
226
  callStackItem,
233
227
  vk,
234
- publicKeysHash,
228
+ publicKeys,
235
229
  contractClassArtifactHash,
236
230
  contractClassPublicBytecodeCommitment,
237
231
  saltedInitializationHash,
238
232
  functionLeafMembershipWitness,
233
+ protocolContractSiblingPath,
239
234
  acirHash,
240
235
  });
241
236
  }
@@ -7,6 +7,7 @@ import {
7
7
  type MembershipWitness,
8
8
  type NOTE_HASH_TREE_HEIGHT,
9
9
  type Point,
10
+ type PublicKeys,
10
11
  type VK_TREE_HEIGHT,
11
12
  type VerificationKeyAsFields,
12
13
  } from '@aztec/circuits.js';
@@ -20,7 +21,7 @@ export interface ProvingDataOracle {
20
21
  /** Retrieves the preimage of a contract address from the registered contract instances db. */
21
22
  getContractAddressPreimage(
22
23
  address: AztecAddress,
23
- ): Promise<{ saltedInitializationHash: Fr; publicKeysHash: Fr; contractClassId: Fr }>;
24
+ ): Promise<{ saltedInitializationHash: Fr; publicKeys: PublicKeys; contractClassId: Fr }>;
24
25
 
25
26
  /** Retrieves the preimage of a contract class id from the contract classes db. */
26
27
  getContractClassIdPreimage(
@@ -3,19 +3,18 @@ import {
3
3
  type PrivateKernelProver,
4
4
  type PrivateKernelSimulateOutput,
5
5
  } from '@aztec/circuit-types';
6
- import type { CircuitName, CircuitSimulationStats } from '@aztec/circuit-types/stats';
6
+ import type { CircuitSimulationStats } from '@aztec/circuit-types/stats';
7
7
  import {
8
+ CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS,
8
9
  ClientIvcProof,
9
- type PrivateCircuitPublicInputs,
10
10
  type PrivateKernelCircuitPublicInputs,
11
11
  type PrivateKernelInitCircuitPrivateInputs,
12
12
  type PrivateKernelInnerCircuitPrivateInputs,
13
- type PrivateKernelResetCircuitPrivateInputsVariants,
13
+ type PrivateKernelResetCircuitPrivateInputs,
14
14
  type PrivateKernelTailCircuitPrivateInputs,
15
15
  type PrivateKernelTailCircuitPublicInputs,
16
16
  VerificationKeyAsFields,
17
17
  } from '@aztec/circuits.js';
18
- import { siloNoteHash } from '@aztec/circuits.js/hash';
19
18
  import { createDebugLogger } from '@aztec/foundation/log';
20
19
  import { elapsed } from '@aztec/foundation/timer';
21
20
  import {
@@ -26,6 +25,8 @@ import {
26
25
  executeReset,
27
26
  executeTail,
28
27
  executeTailForPublic,
28
+ getPrivateKernelResetArtifactName,
29
+ maxPrivateKernelResetDimensions,
29
30
  } from '@aztec/noir-protocol-circuits-types';
30
31
 
31
32
  import { type WitnessMap } from '@noir-lang/types';
@@ -40,12 +41,6 @@ export class TestPrivateKernelProver implements PrivateKernelProver {
40
41
  return Promise.resolve(ClientIvcProof.empty());
41
42
  }
42
43
 
43
- public getSiloedCommitments(publicInputs: PrivateCircuitPublicInputs) {
44
- const contractAddress = publicInputs.callContext.storageContractAddress;
45
-
46
- return Promise.resolve(publicInputs.noteHashes.map(commitment => siloNoteHash(contractAddress, commitment.value)));
47
- }
48
-
49
44
  public async simulateProofInit(
50
45
  privateInputs: PrivateKernelInitCircuitPrivateInputs,
51
46
  ): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
@@ -75,19 +70,20 @@ export class TestPrivateKernelProver implements PrivateKernelProver {
75
70
  }
76
71
 
77
72
  public async simulateProofReset(
78
- privateInputs: PrivateKernelResetCircuitPrivateInputsVariants,
73
+ privateInputs: PrivateKernelResetCircuitPrivateInputs,
79
74
  ): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
80
- const [duration, result] = await elapsed(() => executeReset(privateInputs));
75
+ const variantPrivateInputs = privateInputs.trimToSizes();
76
+ const [duration, result] = await elapsed(() => executeReset(variantPrivateInputs, privateInputs.dimensions));
81
77
  this.log.debug(`Simulated private kernel reset`, {
82
78
  eventName: 'circuit-simulation',
83
- circuitName: ('private-kernel-reset-' + privateInputs.sizeTag) as CircuitName,
79
+ circuitName: 'private-kernel-reset',
84
80
  duration,
85
- inputSize: privateInputs.toBuffer().length,
81
+ inputSize: variantPrivateInputs.toBuffer().length,
86
82
  outputSize: result.toBuffer().length,
87
83
  } satisfies CircuitSimulationStats);
88
84
  return this.makeEmptyKernelSimulateOutput<PrivateKernelCircuitPublicInputs>(
89
85
  result,
90
- 'PrivateKernelResetFullArtifact',
86
+ getPrivateKernelResetArtifactName(maxPrivateKernelResetDimensions),
91
87
  );
92
88
  }
93
89
 
@@ -116,7 +112,7 @@ export class TestPrivateKernelProver implements PrivateKernelProver {
116
112
  _appCircuitName?: string | undefined,
117
113
  ): Promise<AppCircuitSimulateOutput> {
118
114
  const appCircuitProofOutput: AppCircuitSimulateOutput = {
119
- verificationKey: VerificationKeyAsFields.makeEmpty(),
115
+ verificationKey: VerificationKeyAsFields.makeEmpty(CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS),
120
116
  };
121
117
  return Promise.resolve(appCircuitProofOutput);
122
118
  }
@@ -129,6 +125,7 @@ export class TestPrivateKernelProver implements PrivateKernelProver {
129
125
  publicInputs,
130
126
  verificationKey: ProtocolCircuitVks[circuitType].keyAsFields,
131
127
  outputWitness: new Map(),
128
+ bytecode: Buffer.from([]),
132
129
  };
133
130
  return kernelProofOutput;
134
131
  }
@@ -1,6 +1,6 @@
1
- import { type AztecNode, L1NotePayload, type L2Block, TaggedLog } from '@aztec/circuit-types';
1
+ import { type AztecNode, L1NotePayload, type L2Block } from '@aztec/circuit-types';
2
2
  import { type NoteProcessorStats } from '@aztec/circuit-types/stats';
3
- import { type AztecAddress, INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX, type PublicKey } from '@aztec/circuits.js';
3
+ import { type CompleteAddress, INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX, type PublicKey } from '@aztec/circuits.js';
4
4
  import { type Fr } from '@aztec/foundation/fields';
5
5
  import { type Logger, createDebugLogger } from '@aztec/foundation/log';
6
6
  import { Timer } from '@aztec/foundation/timer';
@@ -12,7 +12,7 @@ import { type IncomingNoteDao } from '../database/incoming_note_dao.js';
12
12
  import { type PxeDatabase } from '../database/index.js';
13
13
  import { type OutgoingNoteDao } from '../database/outgoing_note_dao.js';
14
14
  import { getAcirSimulator } from '../simulator/index.js';
15
- import { produceNoteDaos } from './produce_note_dao.js';
15
+ import { produceNoteDaos } from './utils/produce_note_daos.js';
16
16
 
17
17
  /**
18
18
  * Contains all the decrypted data in this array so that we can later batch insert it all into the database.
@@ -47,7 +47,7 @@ export class NoteProcessor {
47
47
  };
48
48
 
49
49
  private constructor(
50
- public readonly account: AztecAddress,
50
+ public readonly account: CompleteAddress,
51
51
  /** The public counterpart to the secret key to be used in the decryption of incoming note logs. */
52
52
  private readonly ivpkM: PublicKey,
53
53
  /** The public counterpart to the secret key to be used in the decryption of outgoing note logs. */
@@ -61,7 +61,7 @@ export class NoteProcessor {
61
61
  ) {}
62
62
 
63
63
  public static async create(
64
- account: AztecAddress,
64
+ account: CompleteAddress,
65
65
  keyStore: KeyStore,
66
66
  db: PxeDatabase,
67
67
  node: AztecNode,
@@ -69,8 +69,8 @@ export class NoteProcessor {
69
69
  simulator = getAcirSimulator(db, node, keyStore),
70
70
  log = createDebugLogger('aztec:note_processor'),
71
71
  ) {
72
- const ivpkM = await keyStore.getMasterIncomingViewingPublicKey(account);
73
- const ovpkM = await keyStore.getMasterOutgoingViewingPublicKey(account);
72
+ const ivpkM = await keyStore.getMasterIncomingViewingPublicKey(account.address);
73
+ const ovpkM = await keyStore.getMasterOutgoingViewingPublicKey(account.address);
74
74
 
75
75
  return new NoteProcessor(account, ivpkM, ovpkM, keyStore, db, node, startingBlock, simulator, log);
76
76
  }
@@ -142,35 +142,33 @@ export class NoteProcessor {
142
142
  for (const functionLogs of txFunctionLogs) {
143
143
  for (const log of functionLogs.logs) {
144
144
  this.stats.seen++;
145
- const incomingTaggedNote = TaggedLog.decryptAsIncoming(log.data, ivskM)!;
146
- const outgoingTaggedNote = TaggedLog.decryptAsOutgoing(log.data, ovskM)!;
147
-
148
- if (incomingTaggedNote || outgoingTaggedNote) {
149
- if (
150
- incomingTaggedNote &&
151
- outgoingTaggedNote &&
152
- !incomingTaggedNote.payload.equals(outgoingTaggedNote.payload)
153
- ) {
145
+ const incomingNotePayload = L1NotePayload.decryptAsIncoming(log, ivskM);
146
+ const outgoingNotePayload = L1NotePayload.decryptAsOutgoing(log, ovskM);
147
+
148
+ if (incomingNotePayload || outgoingNotePayload) {
149
+ if (incomingNotePayload && outgoingNotePayload && !incomingNotePayload.equals(outgoingNotePayload)) {
154
150
  throw new Error(
155
151
  `Incoming and outgoing note payloads do not match. Incoming: ${JSON.stringify(
156
- incomingTaggedNote.payload,
157
- )}, Outgoing: ${JSON.stringify(outgoingTaggedNote.payload)}`,
152
+ incomingNotePayload,
153
+ )}, Outgoing: ${JSON.stringify(outgoingNotePayload)}`,
158
154
  );
159
155
  }
160
156
 
161
- const payload = incomingTaggedNote?.payload || outgoingTaggedNote?.payload;
157
+ const payload = incomingNotePayload || outgoingNotePayload;
162
158
 
163
- const txHash = block.body.txEffects[indexOfTxInABlock].txHash;
159
+ const txEffect = block.body.txEffects[indexOfTxInABlock];
164
160
  const { incomingNote, outgoingNote, incomingDeferredNote, outgoingDeferredNote } = await produceNoteDaos(
165
161
  this.simulator,
166
- incomingTaggedNote ? this.ivpkM : undefined,
167
- outgoingTaggedNote ? this.ovpkM : undefined,
168
- payload,
169
- txHash,
162
+ this.db,
163
+ incomingNotePayload ? this.ivpkM : undefined,
164
+ outgoingNotePayload ? this.ovpkM : undefined,
165
+ payload!,
166
+ txEffect.txHash,
170
167
  noteHashes,
171
168
  dataStartIndexForTx,
172
169
  excludedIndices,
173
170
  this.log,
171
+ txEffect.unencryptedLogs,
174
172
  );
175
173
 
176
174
  if (incomingNote) {
@@ -227,7 +225,7 @@ export class NoteProcessor {
227
225
  const incomingNotes = blocksAndNotes.flatMap(b => b.incomingNotes);
228
226
  const outgoingNotes = blocksAndNotes.flatMap(b => b.outgoingNotes);
229
227
  if (incomingNotes.length || outgoingNotes.length) {
230
- await this.db.addNotes(incomingNotes, outgoingNotes, this.account);
228
+ await this.db.addNotes(incomingNotes, outgoingNotes, this.account.address);
231
229
  incomingNotes.forEach(noteDao => {
232
230
  this.log.verbose(
233
231
  `Added incoming note for contract ${noteDao.contractAddress} at slot ${
@@ -300,8 +298,17 @@ export class NoteProcessor {
300
298
  const outgoingNotes: OutgoingNoteDao[] = [];
301
299
 
302
300
  for (const deferredNote of deferredNoteDaos) {
303
- const { publicKey, note, contractAddress, storageSlot, noteTypeId, txHash, noteHashes, dataStartIndexForTx } =
304
- deferredNote;
301
+ const {
302
+ publicKey,
303
+ note,
304
+ contractAddress,
305
+ storageSlot,
306
+ noteTypeId,
307
+ txHash,
308
+ noteHashes,
309
+ dataStartIndexForTx,
310
+ unencryptedLogs,
311
+ } = deferredNote;
305
312
  const payload = new L1NotePayload(note, contractAddress, storageSlot, noteTypeId);
306
313
 
307
314
  const isIncoming = publicKey.equals(this.ivpkM);
@@ -314,6 +321,7 @@ export class NoteProcessor {
314
321
 
315
322
  const { incomingNote, outgoingNote } = await produceNoteDaos(
316
323
  this.simulator,
324
+ this.db,
317
325
  isIncoming ? this.ivpkM : undefined,
318
326
  isOutgoing ? this.ovpkM : undefined,
319
327
  payload,
@@ -322,6 +330,7 @@ export class NoteProcessor {
322
330
  dataStartIndexForTx,
323
331
  excludedIndices,
324
332
  this.log,
333
+ unencryptedLogs,
325
334
  );
326
335
 
327
336
  if (isIncoming) {
@@ -0,0 +1,67 @@
1
+ import { L1NotePayload, Note } from '@aztec/circuit-types';
2
+ import { type Fr } from '@aztec/foundation/fields';
3
+ import { ContractNotFoundError } from '@aztec/simulator';
4
+
5
+ import { type PxeDatabase } from '../../database/pxe_database.js';
6
+
7
+ /**
8
+ * Inserts publicly delivered nullable fields into the note payload.
9
+ * @param db - PXE database used to fetch contract instance and artifact.
10
+ * @param payload - Note payload to which nullable fields should be added.
11
+ * @param nullableFields - List of nullable fields to be added to the note payload.
12
+ * @returns Note payload with nullable fields added.
13
+ */
14
+ export async function addNullableFieldsToPayload(
15
+ db: PxeDatabase,
16
+ payload: L1NotePayload,
17
+ nullableFields: Fr[],
18
+ ): Promise<L1NotePayload> {
19
+ const instance = await db.getContractInstance(payload.contractAddress);
20
+ if (!instance) {
21
+ throw new ContractNotFoundError(
22
+ `Could not find instance for ${payload.contractAddress.toString()}. This should never happen here as the partial notes flow should be triggered only for non-deferred notes.`,
23
+ );
24
+ }
25
+
26
+ const artifact = await db.getContractArtifact(instance.contractClassId);
27
+ if (!artifact) {
28
+ throw new Error(
29
+ `Could not find artifact for contract class ${instance.contractClassId.toString()}. This should never happen here as the partial notes flow should be triggered only for non-deferred notes.`,
30
+ );
31
+ }
32
+
33
+ const noteFields = Object.values(artifact.notes).find(note => note.id.equals(payload.noteTypeId))?.fields;
34
+
35
+ if (!noteFields) {
36
+ throw new Error(`Could not find note fields for note type ${payload.noteTypeId.toString()}.`);
37
+ }
38
+
39
+ // We sort note fields by index so that we can iterate over them in order.
40
+ noteFields.sort((a, b) => a.index - b.index);
41
+
42
+ // Now we insert the nullable fields into the note based on its indices defined in the ABI.
43
+ const modifiedNoteItems = [...payload.note.items];
44
+ let indexInNullable = 0;
45
+ for (let i = 0; i < noteFields.length; i++) {
46
+ const noteField = noteFields[i];
47
+ if (noteField.nullable) {
48
+ if (i == noteFields.length - 1) {
49
+ // We are processing the last field so we simply insert the rest of the nullable fields at the end
50
+ modifiedNoteItems.push(...nullableFields.slice(indexInNullable));
51
+ } else {
52
+ const noteFieldLength = noteFields[i + 1].index - noteField.index;
53
+ const nullableFieldsToInsert = nullableFields.slice(indexInNullable, indexInNullable + noteFieldLength);
54
+ indexInNullable += noteFieldLength;
55
+ // Now we insert the nullable fields at the note field index
56
+ modifiedNoteItems.splice(noteField.index, 0, ...nullableFieldsToInsert);
57
+ }
58
+ }
59
+ }
60
+
61
+ return new L1NotePayload(
62
+ new Note(modifiedNoteItems),
63
+ payload.contractAddress,
64
+ payload.storageSlot,
65
+ payload.noteTypeId,
66
+ );
67
+ }
@@ -0,0 +1,82 @@
1
+ import { type L1NotePayload, type TxHash } from '@aztec/circuit-types';
2
+ import { computeNoteHashNonce, siloNullifier } from '@aztec/circuits.js/hash';
3
+ import { Fr } from '@aztec/foundation/fields';
4
+ import { type AcirSimulator } from '@aztec/simulator';
5
+
6
+ export interface NoteInfo {
7
+ noteHashIndex: number;
8
+ nonce: Fr;
9
+ noteHash: Fr;
10
+ siloedNullifier: Fr;
11
+ txHash: TxHash;
12
+ }
13
+
14
+ /**
15
+ * Finds nonce, index, inner hash and siloed nullifier for a given note.
16
+ * @dev Finds the index in the note hash tree by computing the note hash with different nonce and see which hash for
17
+ * the current tx matches this value.
18
+ * @remarks This method assists in identifying spent notes in the note hash tree.
19
+ * @param siloedNoteHashes - Note hashes in the tx. One of them should correspond to the note we are looking for
20
+ * @param txHash - Hash of a tx the note was emitted in.
21
+ * @param l1NotePayload - The note payload.
22
+ * @param excludedIndices - Indices that have been assigned a note in the same tx. Notes in a tx can have the same
23
+ * l1NotePayload. We need to find a different index for each replicate.
24
+ * @param computeNullifier - A flag indicating whether to compute the nullifier or just return 0.
25
+ * @returns Nonce, index, inner hash and siloed nullifier for a given note.
26
+ * @throws If cannot find the nonce for the note.
27
+ */
28
+ export async function bruteForceNoteInfo(
29
+ simulator: AcirSimulator,
30
+ siloedNoteHashes: Fr[],
31
+ txHash: TxHash,
32
+ { contractAddress, storageSlot, noteTypeId, note }: L1NotePayload,
33
+ excludedIndices: Set<number>,
34
+ computeNullifier: boolean,
35
+ ): Promise<NoteInfo> {
36
+ let noteHashIndex = 0;
37
+ let nonce: Fr | undefined;
38
+ let noteHash: Fr | undefined;
39
+ let siloedNoteHash: Fr | undefined;
40
+ let innerNullifier: Fr | undefined;
41
+ const firstNullifier = Fr.fromBuffer(txHash.toBuffer());
42
+
43
+ for (; noteHashIndex < siloedNoteHashes.length; ++noteHashIndex) {
44
+ if (excludedIndices.has(noteHashIndex)) {
45
+ continue;
46
+ }
47
+
48
+ const siloedNoteHashFromTxEffect = siloedNoteHashes[noteHashIndex];
49
+ if (siloedNoteHashFromTxEffect.equals(Fr.ZERO)) {
50
+ break;
51
+ }
52
+
53
+ const expectedNonce = computeNoteHashNonce(firstNullifier, noteHashIndex);
54
+ ({ noteHash, siloedNoteHash, innerNullifier } = await simulator.computeNoteHashAndOptionallyANullifier(
55
+ contractAddress,
56
+ expectedNonce,
57
+ storageSlot,
58
+ noteTypeId,
59
+ computeNullifier,
60
+ note,
61
+ ));
62
+
63
+ if (siloedNoteHashFromTxEffect.equals(siloedNoteHash)) {
64
+ nonce = expectedNonce;
65
+ break;
66
+ }
67
+ }
68
+
69
+ if (!nonce) {
70
+ // NB: this used to warn the user that a decrypted log didn't match any notes.
71
+ // This was previously fine as we didn't chop transient note logs, but now we do (#1641 complete).
72
+ throw new Error('Cannot find a matching note hash for the note.');
73
+ }
74
+
75
+ return {
76
+ noteHashIndex,
77
+ nonce,
78
+ noteHash: noteHash!,
79
+ siloedNullifier: siloNullifier(contractAddress, innerNullifier!),
80
+ txHash,
81
+ };
82
+ }
@@ -0,0 +1,2 @@
1
+ export { produceNoteDaos } from './produce_note_daos.js';
2
+ export { NoteInfo } from './brute_force_note_info.js';