@aztec/pxe 0.87.7 → 1.0.0-nightly.20250604
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/execution_data_provider.d.ts +20 -16
- package/dest/contract_function_simulator/execution_data_provider.d.ts.map +1 -1
- package/dest/contract_function_simulator/note_validation_request.d.ts +21 -0
- package/dest/contract_function_simulator/note_validation_request.d.ts.map +1 -0
- package/dest/contract_function_simulator/note_validation_request.js +42 -0
- package/dest/contract_function_simulator/oracle/oracle.d.ts +3 -2
- package/dest/contract_function_simulator/oracle/oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/oracle.js +21 -12
- package/dest/contract_function_simulator/oracle/typed_oracle.d.ts +4 -3
- package/dest/contract_function_simulator/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/typed_oracle.js +7 -4
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts +4 -3
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.d.ts.map +1 -1
- package/dest/contract_function_simulator/oracle/utility_execution_oracle.js +8 -5
- package/dest/contract_function_simulator/pxe_oracle_interface.d.ts +6 -4
- package/dest/contract_function_simulator/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/contract_function_simulator/pxe_oracle_interface.js +57 -21
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -1
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.js +30 -30
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -1
- package/dest/private_kernel/private_kernel_execution_prover.js +9 -7
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +10 -3
- package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts +4 -2
- package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts.map +1 -1
- package/dest/storage/capsule_data_provider/capsule_data_provider.js +46 -7
- package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
- package/dest/storage/note_data_provider/note_data_provider.js +14 -14
- package/package.json +16 -16
- package/src/contract_function_simulator/execution_data_provider.ts +22 -26
- package/src/contract_function_simulator/note_validation_request.ts +52 -0
- package/src/contract_function_simulator/oracle/oracle.ts +24 -25
- package/src/contract_function_simulator/oracle/typed_oracle.ts +14 -14
- package/src/contract_function_simulator/oracle/utility_execution_oracle.ts +10 -24
- package/src/contract_function_simulator/pxe_oracle_interface.ts +98 -22
- package/src/private_kernel/hints/build_private_kernel_reset_private_inputs.ts +35 -34
- package/src/private_kernel/private_kernel_execution_prover.ts +11 -10
- package/src/pxe_service/pxe_service.ts +10 -3
- package/src/storage/capsule_data_provider/capsule_data_provider.ts +56 -7
- package/src/storage/note_data_provider/note_data_provider.ts +22 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-nightly.20250604",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./server": "./dest/entrypoints/server/index.js",
|
|
@@ -58,19 +58,19 @@
|
|
|
58
58
|
]
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@aztec/bb-prover": "0.
|
|
62
|
-
"@aztec/bb.js": "0.
|
|
63
|
-
"@aztec/builder": "0.
|
|
64
|
-
"@aztec/constants": "0.
|
|
65
|
-
"@aztec/ethereum": "0.
|
|
66
|
-
"@aztec/foundation": "0.
|
|
67
|
-
"@aztec/key-store": "0.
|
|
68
|
-
"@aztec/kv-store": "0.
|
|
69
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
70
|
-
"@aztec/noir-types": "0.
|
|
71
|
-
"@aztec/protocol-contracts": "0.
|
|
72
|
-
"@aztec/simulator": "0.
|
|
73
|
-
"@aztec/stdlib": "0.
|
|
61
|
+
"@aztec/bb-prover": "1.0.0-nightly.20250604",
|
|
62
|
+
"@aztec/bb.js": "1.0.0-nightly.20250604",
|
|
63
|
+
"@aztec/builder": "1.0.0-nightly.20250604",
|
|
64
|
+
"@aztec/constants": "1.0.0-nightly.20250604",
|
|
65
|
+
"@aztec/ethereum": "1.0.0-nightly.20250604",
|
|
66
|
+
"@aztec/foundation": "1.0.0-nightly.20250604",
|
|
67
|
+
"@aztec/key-store": "1.0.0-nightly.20250604",
|
|
68
|
+
"@aztec/kv-store": "1.0.0-nightly.20250604",
|
|
69
|
+
"@aztec/noir-protocol-circuits-types": "1.0.0-nightly.20250604",
|
|
70
|
+
"@aztec/noir-types": "1.0.0-nightly.20250604",
|
|
71
|
+
"@aztec/protocol-contracts": "1.0.0-nightly.20250604",
|
|
72
|
+
"@aztec/simulator": "1.0.0-nightly.20250604",
|
|
73
|
+
"@aztec/stdlib": "1.0.0-nightly.20250604",
|
|
74
74
|
"koa": "^2.16.1",
|
|
75
75
|
"koa-router": "^12.0.0",
|
|
76
76
|
"lodash.omit": "^4.5.0",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"viem": "2.23.7"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@aztec/merkle-tree": "0.
|
|
83
|
-
"@aztec/noir-test-contracts.js": "0.
|
|
82
|
+
"@aztec/merkle-tree": "1.0.0-nightly.20250604",
|
|
83
|
+
"@aztec/noir-test-contracts.js": "1.0.0-nightly.20250604",
|
|
84
84
|
"@jest/globals": "^29.5.0",
|
|
85
85
|
"@types/jest": "^29.5.0",
|
|
86
86
|
"@types/lodash.omit": "^4.5.7",
|
|
@@ -10,7 +10,7 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
10
10
|
import type { L2Block } from '@aztec/stdlib/block';
|
|
11
11
|
import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
12
12
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
13
|
-
import { IndexedTaggingSecret,
|
|
13
|
+
import { IndexedTaggingSecret, PrivateLogWithTxData, PublicLogWithTxData } from '@aztec/stdlib/logs';
|
|
14
14
|
import type { NoteStatus } from '@aztec/stdlib/note';
|
|
15
15
|
import { type MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
16
16
|
import type { BlockHeader, NodeStats, TxHash } from '@aztec/stdlib/tx';
|
|
@@ -265,8 +265,8 @@ export interface ExecutionDataProvider {
|
|
|
265
265
|
): Promise<void>;
|
|
266
266
|
|
|
267
267
|
/**
|
|
268
|
-
* Synchronizes the logs tagged with scoped addresses and all the senders in the address book. Stores the found
|
|
269
|
-
* in CapsuleArray ready for a later retrieval in Aztec.nr.
|
|
268
|
+
* Synchronizes the private logs tagged with scoped addresses and all the senders in the address book. Stores the found
|
|
269
|
+
* logs in CapsuleArray ready for a later retrieval in Aztec.nr.
|
|
270
270
|
* @param contractAddress - The address of the contract that the logs are tagged for.
|
|
271
271
|
* @param pendingTaggedLogArrayBaseSlot - The base slot of the pending tagged log capsule array in which found logs will be stored.
|
|
272
272
|
* @param scopes - The scoped addresses to sync logs for. If not provided, all accounts in the address book will be
|
|
@@ -279,36 +279,32 @@ export interface ExecutionDataProvider {
|
|
|
279
279
|
): Promise<void>;
|
|
280
280
|
|
|
281
281
|
/**
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
* @param
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
* @param content - The note's content: this is the primary item to return in `getNotes`
|
|
289
|
-
* @param noteHash - The non-unique non-siloed note hash
|
|
290
|
-
* @param nullifier - The inner (non-siloed) note nullifier
|
|
291
|
-
* @param txHash - The transaction in which the note was added to the note hash tree
|
|
292
|
-
* @param recipient - The account that discovered the note
|
|
293
|
-
*/
|
|
294
|
-
deliverNote(
|
|
295
|
-
contractAddress: AztecAddress,
|
|
296
|
-
storageSlot: Fr,
|
|
297
|
-
nonce: Fr,
|
|
298
|
-
content: Fr[],
|
|
299
|
-
noteHash: Fr,
|
|
300
|
-
nullifier: Fr,
|
|
301
|
-
txHash: TxHash,
|
|
302
|
-
recipient: AztecAddress,
|
|
303
|
-
): Promise<void>;
|
|
282
|
+
* Validates a capsule array of `NoteValidationRequests`, storing the notes in the database so that they can be later
|
|
283
|
+
* queried via `getNotes`.
|
|
284
|
+
* @param contractAddress - The contract that the notes belong to.
|
|
285
|
+
* @param noteValidationRequestArrayBaseSlot - The capsule array base slot.
|
|
286
|
+
*/
|
|
287
|
+
validateEnqueuedNotes(contractAddress: AztecAddress, noteValidationRequestArrayBaseSlot: Fr): Promise<void>;
|
|
304
288
|
|
|
305
289
|
/**
|
|
306
290
|
* Searches for a log with the corresponding `tag` and returns it along with contextual transaction information.
|
|
307
291
|
* Returns null if no such log exists, and throws if more than one exists.
|
|
308
292
|
*
|
|
309
293
|
* @param tag - The log tag to search for.
|
|
294
|
+
* @param contractAddress - The contract address to search for the log in.
|
|
295
|
+
* @returns The public log with transaction data if found, null otherwise.
|
|
296
|
+
* @throws If more than one log with that tag exists.
|
|
297
|
+
*/
|
|
298
|
+
getPublicLogByTag(tag: Fr, contractAddress: AztecAddress): Promise<PublicLogWithTxData | null>;
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Searches for a private log with the corresponding `siloedTag` and returns it along with contextual transaction
|
|
302
|
+
* information.
|
|
303
|
+
*
|
|
304
|
+
* @param siloedTag - The siloed log tag to search for.
|
|
305
|
+
* @returns The private log with transaction data if found, null otherwise.
|
|
310
306
|
*/
|
|
311
|
-
|
|
307
|
+
getPrivateLogByTag(siloedTag: Fr): Promise<PrivateLogWithTxData | null>;
|
|
312
308
|
|
|
313
309
|
/**
|
|
314
310
|
* Removes all of a contract's notes that have been nullified from the note database.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { FieldReader } from '@aztec/foundation/serialize';
|
|
3
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
+
import { TxHash } from '@aztec/stdlib/tx';
|
|
5
|
+
|
|
6
|
+
// TODO(#14617): should we compute this from constants? This value is aztec-nr specific.
|
|
7
|
+
const MAX_NOTE_PACKED_LEN = 12;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Intermediate struct used to perform batch note validation by PXE. The `validateEnqueuedNotes` oracle expects for
|
|
11
|
+
* values of this type to be stored in a `CapsuleArray`.
|
|
12
|
+
*/
|
|
13
|
+
export class NoteValidationRequest {
|
|
14
|
+
constructor(
|
|
15
|
+
public contractAddress: AztecAddress,
|
|
16
|
+
public storageSlot: Fr,
|
|
17
|
+
public nonce: Fr,
|
|
18
|
+
public content: Fr[],
|
|
19
|
+
public noteHash: Fr,
|
|
20
|
+
public nullifier: Fr,
|
|
21
|
+
public txHash: TxHash,
|
|
22
|
+
public recipient: AztecAddress,
|
|
23
|
+
) {}
|
|
24
|
+
|
|
25
|
+
static fromFields(fields: Fr[] | FieldReader): NoteValidationRequest {
|
|
26
|
+
const reader = FieldReader.asReader(fields);
|
|
27
|
+
|
|
28
|
+
const contractAddress = AztecAddress.fromField(reader.readField());
|
|
29
|
+
const storageSlot = reader.readField();
|
|
30
|
+
const nonce = reader.readField();
|
|
31
|
+
|
|
32
|
+
const contentStorage = reader.readFieldArray(MAX_NOTE_PACKED_LEN);
|
|
33
|
+
const contentLen = reader.readField().toNumber();
|
|
34
|
+
const content = contentStorage.slice(0, contentLen);
|
|
35
|
+
|
|
36
|
+
const noteHash = reader.readField();
|
|
37
|
+
const nullifier = reader.readField();
|
|
38
|
+
const txHash = TxHash.fromField(reader.readField());
|
|
39
|
+
const recipient = AztecAddress.fromField(reader.readField());
|
|
40
|
+
|
|
41
|
+
return new NoteValidationRequest(
|
|
42
|
+
contractAddress,
|
|
43
|
+
storageSlot,
|
|
44
|
+
nonce,
|
|
45
|
+
content,
|
|
46
|
+
noteHash,
|
|
47
|
+
nullifier,
|
|
48
|
+
txHash,
|
|
49
|
+
recipient,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -12,7 +12,12 @@ import {
|
|
|
12
12
|
} from '@aztec/simulator/client';
|
|
13
13
|
import { EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
14
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
ContractClassLog,
|
|
17
|
+
ContractClassLogFields,
|
|
18
|
+
PrivateLogWithTxData,
|
|
19
|
+
PublicLogWithTxData,
|
|
20
|
+
} from '@aztec/stdlib/logs';
|
|
16
21
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
17
22
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
18
23
|
|
|
@@ -402,39 +407,33 @@ export class Oracle {
|
|
|
402
407
|
return [];
|
|
403
408
|
}
|
|
404
409
|
|
|
405
|
-
async
|
|
410
|
+
async validateEnqueuedNotes(
|
|
406
411
|
[contractAddress]: ACVMField[],
|
|
407
|
-
[
|
|
408
|
-
[nonce]: ACVMField[],
|
|
409
|
-
content: ACVMField[],
|
|
410
|
-
[contentLength]: ACVMField[],
|
|
411
|
-
[noteHash]: ACVMField[],
|
|
412
|
-
[nullifier]: ACVMField[],
|
|
413
|
-
[txHash]: ACVMField[],
|
|
414
|
-
[recipient]: ACVMField[],
|
|
412
|
+
[noteValidationRequestsArrayBaseSlot]: ACVMField[],
|
|
415
413
|
): Promise<ACVMField[]> {
|
|
416
|
-
|
|
417
|
-
// to do if a note fails delivery (e.g. not increment the tagging index, or add it to some pending work list).
|
|
418
|
-
// Delivery might fail due to temporary issues, such as poor node connectivity.
|
|
419
|
-
await this.typedOracle.deliverNote(
|
|
414
|
+
await this.typedOracle.validateEnqueuedNotes(
|
|
420
415
|
AztecAddress.fromString(contractAddress),
|
|
421
|
-
Fr.fromString(
|
|
422
|
-
Fr.fromString(nonce),
|
|
423
|
-
fromBoundedVec(content, contentLength),
|
|
424
|
-
Fr.fromString(noteHash),
|
|
425
|
-
Fr.fromString(nullifier),
|
|
426
|
-
TxHash.fromString(txHash),
|
|
427
|
-
AztecAddress.fromString(recipient),
|
|
416
|
+
Fr.fromString(noteValidationRequestsArrayBaseSlot),
|
|
428
417
|
);
|
|
429
418
|
|
|
430
|
-
return [
|
|
419
|
+
return [];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
async getPublicLogByTag([tag]: ACVMField[], [contractAddress]: ACVMField[]): Promise<(ACVMField | ACVMField[])[]> {
|
|
423
|
+
const log = await this.typedOracle.getPublicLogByTag(Fr.fromString(tag), AztecAddress.fromString(contractAddress));
|
|
424
|
+
|
|
425
|
+
if (log == null) {
|
|
426
|
+
return [toACVMField(0), ...PublicLogWithTxData.noirSerializationOfEmpty().map(toACVMFieldSingleOrArray)];
|
|
427
|
+
} else {
|
|
428
|
+
return [toACVMField(1), ...log.toNoirSerialization().map(toACVMFieldSingleOrArray)];
|
|
429
|
+
}
|
|
431
430
|
}
|
|
432
431
|
|
|
433
|
-
async
|
|
434
|
-
const log = await this.typedOracle.
|
|
432
|
+
async getPrivateLogByTag([siloedTag]: ACVMField[]): Promise<(ACVMField | ACVMField[])[]> {
|
|
433
|
+
const log = await this.typedOracle.getPrivateLogByTag(Fr.fromString(siloedTag));
|
|
435
434
|
|
|
436
435
|
if (log == null) {
|
|
437
|
-
return [toACVMField(0), ...
|
|
436
|
+
return [toACVMField(0), ...PrivateLogWithTxData.noirSerializationOfEmpty().map(toACVMFieldSingleOrArray)];
|
|
438
437
|
} else {
|
|
439
438
|
return [toACVMField(1), ...log.toNoirSerialization().map(toACVMFieldSingleOrArray)];
|
|
440
439
|
}
|
|
@@ -4,7 +4,12 @@ import type { EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdli
|
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
5
|
import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
6
6
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
7
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
ContractClassLog,
|
|
9
|
+
IndexedTaggingSecret,
|
|
10
|
+
PrivateLogWithTxData,
|
|
11
|
+
PublicLogWithTxData,
|
|
12
|
+
} from '@aztec/stdlib/logs';
|
|
8
13
|
import type { Note, NoteStatus } from '@aztec/stdlib/note';
|
|
9
14
|
import { type MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
10
15
|
import type { BlockHeader, TxHash } from '@aztec/stdlib/tx';
|
|
@@ -218,21 +223,16 @@ export abstract class TypedOracle {
|
|
|
218
223
|
return Promise.reject(new OracleMethodNotAvailableError('fetchTaggedLogs'));
|
|
219
224
|
}
|
|
220
225
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
_nullifier: Fr,
|
|
228
|
-
_txHash: TxHash,
|
|
229
|
-
_recipient: AztecAddress,
|
|
230
|
-
): Promise<void> {
|
|
231
|
-
return Promise.reject(new OracleMethodNotAvailableError('deliverNote'));
|
|
226
|
+
validateEnqueuedNotes(_contractAddress: AztecAddress, _noteValidationRequestsArrayBaseSlot: Fr): Promise<void> {
|
|
227
|
+
return Promise.reject(new OracleMethodNotAvailableError('validateEnqueuedNotes'));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
getPublicLogByTag(_tag: Fr, _contractAddress: AztecAddress): Promise<PublicLogWithTxData | null> {
|
|
231
|
+
throw new OracleMethodNotAvailableError('getPublicLogByTag');
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
|
|
235
|
-
throw new OracleMethodNotAvailableError('
|
|
234
|
+
getPrivateLogByTag(_siloedTag: Fr): Promise<PrivateLogWithTxData | null> {
|
|
235
|
+
throw new OracleMethodNotAvailableError('getPrivateLogByTag');
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
storeCapsule(_contractAddress: AztecAddress, _key: Fr, _capsule: Fr[]): Promise<void> {
|
|
@@ -7,7 +7,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
7
7
|
import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
8
8
|
import { siloNullifier } from '@aztec/stdlib/hash';
|
|
9
9
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
10
|
-
import { IndexedTaggingSecret,
|
|
10
|
+
import { IndexedTaggingSecret, PrivateLogWithTxData, PublicLogWithTxData } from '@aztec/stdlib/logs';
|
|
11
11
|
import type { NoteStatus } from '@aztec/stdlib/note';
|
|
12
12
|
import { type MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
13
13
|
import type { BlockHeader, Capsule, TxHash } from '@aztec/stdlib/tx';
|
|
@@ -280,35 +280,21 @@ export class UtilityExecutionOracle extends TypedOracle {
|
|
|
280
280
|
await this.executionDataProvider.removeNullifiedNotes(this.contractAddress);
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
-
public override async
|
|
284
|
-
contractAddress: AztecAddress,
|
|
285
|
-
storageSlot: Fr,
|
|
286
|
-
nonce: Fr,
|
|
287
|
-
content: Fr[],
|
|
288
|
-
noteHash: Fr,
|
|
289
|
-
nullifier: Fr,
|
|
290
|
-
txHash: TxHash,
|
|
291
|
-
recipient: AztecAddress,
|
|
292
|
-
) {
|
|
283
|
+
public override async validateEnqueuedNotes(contractAddress: AztecAddress, noteValidationRequestsArrayBaseSlot: Fr) {
|
|
293
284
|
// TODO(#10727): allow other contracts to deliver notes
|
|
294
285
|
if (!this.contractAddress.equals(contractAddress)) {
|
|
295
|
-
throw new Error(`Got a note
|
|
286
|
+
throw new Error(`Got a note validation request from ${contractAddress}, expected ${this.contractAddress}`);
|
|
296
287
|
}
|
|
297
288
|
|
|
298
|
-
await this.executionDataProvider.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
noteHash,
|
|
304
|
-
nullifier,
|
|
305
|
-
txHash,
|
|
306
|
-
recipient,
|
|
307
|
-
);
|
|
289
|
+
await this.executionDataProvider.validateEnqueuedNotes(contractAddress, noteValidationRequestsArrayBaseSlot);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
public override getPublicLogByTag(tag: Fr, contractAddress: AztecAddress): Promise<PublicLogWithTxData | null> {
|
|
293
|
+
return this.executionDataProvider.getPublicLogByTag(tag, contractAddress);
|
|
308
294
|
}
|
|
309
295
|
|
|
310
|
-
public override
|
|
311
|
-
return this.executionDataProvider.
|
|
296
|
+
public override getPrivateLogByTag(siloedTag: Fr): Promise<PrivateLogWithTxData | null> {
|
|
297
|
+
return this.executionDataProvider.getPrivateLogByTag(siloedTag);
|
|
312
298
|
}
|
|
313
299
|
|
|
314
300
|
public override storeCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[]): Promise<void> {
|
|
@@ -18,9 +18,10 @@ import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
|
18
18
|
import { computeAddressSecret, computeAppTaggingSecret } from '@aztec/stdlib/keys';
|
|
19
19
|
import {
|
|
20
20
|
IndexedTaggingSecret,
|
|
21
|
-
LogWithTxData,
|
|
22
21
|
PendingTaggedLog,
|
|
22
|
+
PrivateLogWithTxData,
|
|
23
23
|
PublicLog,
|
|
24
|
+
PublicLogWithTxData,
|
|
24
25
|
TxScopedL2Log,
|
|
25
26
|
deriveEcdhSharedSecret,
|
|
26
27
|
} from '@aztec/stdlib/logs';
|
|
@@ -40,6 +41,7 @@ import type { NoteDataProvider } from '../storage/note_data_provider/note_data_p
|
|
|
40
41
|
import type { PrivateEventDataProvider } from '../storage/private_event_data_provider/private_event_data_provider.js';
|
|
41
42
|
import type { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
|
|
42
43
|
import type { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
|
|
44
|
+
import { NoteValidationRequest } from './note_validation_request.js';
|
|
43
45
|
import type { ProxiedNode } from './proxied_node.js';
|
|
44
46
|
import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js';
|
|
45
47
|
|
|
@@ -384,7 +386,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
384
386
|
});
|
|
385
387
|
|
|
386
388
|
// We fetch the logs for the tags
|
|
387
|
-
const possibleLogs = await this
|
|
389
|
+
const possibleLogs = await this.#getPrivateLogsByTags(currentTags);
|
|
388
390
|
|
|
389
391
|
// We find the index of the last log in the window that is not empty
|
|
390
392
|
const indexOfLastLog = possibleLogs.findLastIndex(possibleLog => possibleLog.length !== 0);
|
|
@@ -421,8 +423,8 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
421
423
|
}
|
|
422
424
|
|
|
423
425
|
/**
|
|
424
|
-
* Synchronizes the logs tagged with scoped addresses and all the senders in the address book. Stores the found
|
|
425
|
-
* in CapsuleArray ready for a later retrieval in Aztec.nr.
|
|
426
|
+
* Synchronizes the private logs tagged with scoped addresses and all the senders in the address book. Stores the found
|
|
427
|
+
* logs in CapsuleArray ready for a later retrieval in Aztec.nr.
|
|
426
428
|
* @param contractAddress - The address of the contract that the logs are tagged for.
|
|
427
429
|
* @param pendingTaggedLogArrayBaseSlot - The base slot of the pending tagged logs capsule array in which
|
|
428
430
|
* found logs will be stored.
|
|
@@ -482,20 +484,14 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
482
484
|
// a new set of secrets and windows to fetch logs for.
|
|
483
485
|
const newLargestIndexMapForIteration: { [k: string]: number } = {};
|
|
484
486
|
|
|
485
|
-
// Fetch the logs for the tags and iterate over them
|
|
486
|
-
const logsByTags = await this
|
|
487
|
+
// Fetch the private logs for the tags and iterate over them
|
|
488
|
+
const logsByTags = await this.#getPrivateLogsByTags(tagsForTheWholeWindow);
|
|
487
489
|
|
|
488
490
|
for (let logIndex = 0; logIndex < logsByTags.length; logIndex++) {
|
|
489
491
|
const logsByTag = logsByTags[logIndex];
|
|
490
492
|
if (logsByTag.length > 0) {
|
|
491
|
-
// Discard public logs
|
|
492
|
-
const filteredLogsByTag = logsByTag.filter(l => !l.isFromPublic);
|
|
493
|
-
if (filteredLogsByTag.length < logsByTag.length) {
|
|
494
|
-
this.log.warn(`Discarded ${logsByTag.filter(l => l.isFromPublic).length} public logs with matching tags`);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
493
|
// We filter out the logs that are newer than the historical block number of the tx currently being constructed
|
|
498
|
-
const filteredLogsByBlockNumber =
|
|
494
|
+
const filteredLogsByBlockNumber = logsByTag.filter(l => l.blockNumber <= maxBlockNumber);
|
|
499
495
|
|
|
500
496
|
// We store the logs in capsules (to later be obtained in Noir)
|
|
501
497
|
await this.#storePendingTaggedLogs(
|
|
@@ -510,7 +506,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
510
506
|
const secretCorrespondingToLog = secretsForTheWholeWindow[logIndex];
|
|
511
507
|
const initialIndex = initialIndexesMap[secretCorrespondingToLog.appTaggingSecret.toString()];
|
|
512
508
|
|
|
513
|
-
this.log.debug(`Found ${
|
|
509
|
+
this.log.debug(`Found ${logsByTags.length} logs as recipient ${recipient}`, {
|
|
514
510
|
recipient,
|
|
515
511
|
secret: secretCorrespondingToLog.appTaggingSecret,
|
|
516
512
|
contractName,
|
|
@@ -606,7 +602,36 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
606
602
|
return this.capsuleDataProvider.appendToCapsuleArray(contractAddress, capsuleArrayBaseSlot, pendingTaggedLogs);
|
|
607
603
|
}
|
|
608
604
|
|
|
609
|
-
public async
|
|
605
|
+
public async validateEnqueuedNotes(
|
|
606
|
+
contractAddress: AztecAddress,
|
|
607
|
+
noteValidationRequestsArrayBaseSlot: Fr,
|
|
608
|
+
): Promise<void> {
|
|
609
|
+
// We read all note validation requests and process them all concurrently. This makes the process much faster as we
|
|
610
|
+
// don't need to wait for the network round-trip.
|
|
611
|
+
const noteValidationRequests = (
|
|
612
|
+
await this.capsuleDataProvider.readCapsuleArray(contractAddress, noteValidationRequestsArrayBaseSlot)
|
|
613
|
+
).map(NoteValidationRequest.fromFields);
|
|
614
|
+
|
|
615
|
+
await Promise.all(
|
|
616
|
+
noteValidationRequests.map(request =>
|
|
617
|
+
this.deliverNote(
|
|
618
|
+
request.contractAddress,
|
|
619
|
+
request.storageSlot,
|
|
620
|
+
request.nonce,
|
|
621
|
+
request.content,
|
|
622
|
+
request.noteHash,
|
|
623
|
+
request.nullifier,
|
|
624
|
+
request.txHash,
|
|
625
|
+
request.recipient,
|
|
626
|
+
),
|
|
627
|
+
),
|
|
628
|
+
);
|
|
629
|
+
|
|
630
|
+
// Requests are cleared once we're done.
|
|
631
|
+
await this.capsuleDataProvider.resetCapsuleArray(contractAddress, noteValidationRequestsArrayBaseSlot, []);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
async deliverNote(
|
|
610
635
|
contractAddress: AztecAddress,
|
|
611
636
|
storageSlot: Fr,
|
|
612
637
|
nonce: Fr,
|
|
@@ -690,18 +715,18 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
690
715
|
}
|
|
691
716
|
}
|
|
692
717
|
|
|
693
|
-
public async
|
|
694
|
-
const logs = await this
|
|
718
|
+
public async getPublicLogByTag(tag: Fr, contractAddress: AztecAddress): Promise<PublicLogWithTxData | null> {
|
|
719
|
+
const logs = await this.#getPublicLogsByTagsFromContract([tag], contractAddress);
|
|
695
720
|
const logsForTag = logs[0];
|
|
696
721
|
|
|
697
|
-
this.log.debug(`Got ${logsForTag.length} logs for tag ${tag}`);
|
|
722
|
+
this.log.debug(`Got ${logsForTag.length} public logs for tag ${tag}`);
|
|
698
723
|
|
|
699
724
|
if (logsForTag.length == 0) {
|
|
700
725
|
return null;
|
|
701
726
|
} else if (logsForTag.length > 1) {
|
|
702
727
|
// TODO(#11627): handle this case
|
|
703
728
|
throw new Error(
|
|
704
|
-
`Got ${logsForTag.length} logs for tag ${tag}.
|
|
729
|
+
`Got ${logsForTag.length} logs for tag ${tag} and contract ${contractAddress.toString()}. getPublicLogByTag currently only supports a single log per tag`,
|
|
705
730
|
);
|
|
706
731
|
}
|
|
707
732
|
|
|
@@ -715,11 +740,45 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
715
740
|
throw new Error(`Unexpected: failed to retrieve tx effects for tx ${scopedLog.txHash} which is known to exist`);
|
|
716
741
|
}
|
|
717
742
|
|
|
718
|
-
|
|
719
|
-
scopedLog.log.
|
|
743
|
+
return new PublicLogWithTxData(
|
|
744
|
+
scopedLog.log.getEmittedFieldsWithoutTag(),
|
|
745
|
+
scopedLog.txHash,
|
|
746
|
+
txEffect.data.noteHashes,
|
|
747
|
+
txEffect.data.nullifiers[0],
|
|
720
748
|
);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
public async getPrivateLogByTag(siloedTag: Fr): Promise<PrivateLogWithTxData | null> {
|
|
752
|
+
const logs = await this.#getPrivateLogsByTags([siloedTag]);
|
|
753
|
+
const logsForTag = logs[0];
|
|
754
|
+
|
|
755
|
+
this.log.debug(`Got ${logsForTag.length} private logs for tag ${siloedTag}`);
|
|
756
|
+
|
|
757
|
+
if (logsForTag.length == 0) {
|
|
758
|
+
return null;
|
|
759
|
+
} else if (logsForTag.length > 1) {
|
|
760
|
+
// TODO(#11627): handle this case
|
|
761
|
+
throw new Error(
|
|
762
|
+
`Got ${logsForTag.length} logs for tag ${siloedTag}. getPrivateLogByTag currently only supports a single log per tag`,
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const scopedLog = logsForTag[0];
|
|
721
767
|
|
|
722
|
-
|
|
768
|
+
// getLogsByTag doesn't have all of the information that we need (notably note hashes and the first nullifier), so
|
|
769
|
+
// we need to make a second call to the node for `getTxEffect`.
|
|
770
|
+
// TODO(#9789): bundle this information in the `getLogsByTag` call.
|
|
771
|
+
const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
|
|
772
|
+
if (txEffect == undefined) {
|
|
773
|
+
throw new Error(`Unexpected: failed to retrieve tx effects for tx ${scopedLog.txHash} which is known to exist`);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
return new PrivateLogWithTxData(
|
|
777
|
+
scopedLog.log.getEmittedFieldsWithoutTag(),
|
|
778
|
+
scopedLog.txHash,
|
|
779
|
+
txEffect.data.noteHashes,
|
|
780
|
+
txEffect.data.nullifiers[0],
|
|
781
|
+
);
|
|
723
782
|
}
|
|
724
783
|
|
|
725
784
|
public async removeNullifiedNotes(contractAddress: AztecAddress) {
|
|
@@ -823,6 +882,23 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
823
882
|
);
|
|
824
883
|
}
|
|
825
884
|
|
|
885
|
+
// TODO(#12656): Make this a public function on the AztecNode interface and remove the original getLogsByTags. This
|
|
886
|
+
// was not done yet as we were unsure about the API and we didn't want to introduce a breaking change.
|
|
887
|
+
async #getPrivateLogsByTags(tags: Fr[]): Promise<TxScopedL2Log[][]> {
|
|
888
|
+
const allLogs = await this.aztecNode.getLogsByTags(tags);
|
|
889
|
+
return allLogs.map(logs => logs.filter(log => !log.isFromPublic));
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
// TODO(#12656): Make this a public function on the AztecNode interface and remove the original getLogsByTags. This
|
|
893
|
+
// was not done yet as we were unsure about the API and we didn't want to introduce a breaking change.
|
|
894
|
+
async #getPublicLogsByTagsFromContract(tags: Fr[], contractAddress: AztecAddress): Promise<TxScopedL2Log[][]> {
|
|
895
|
+
const allLogs = await this.aztecNode.getLogsByTags(tags);
|
|
896
|
+
const allPublicLogs = allLogs.map(logs => logs.filter(log => log.isFromPublic));
|
|
897
|
+
return allPublicLogs.map(logs =>
|
|
898
|
+
logs.filter(log => (log.log as PublicLog).contractAddress.equals(contractAddress)),
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
|
|
826
902
|
getStats(): ExecutionStats {
|
|
827
903
|
const nodeRPCCalls =
|
|
828
904
|
typeof (this.aztecNode as ProxiedNode).getStats === 'function' ? (this.aztecNode as ProxiedNode).getStats() : {};
|