@aztec/pxe 0.80.0 → 0.82.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.
- package/dest/config/package_info.js +1 -1
- package/dest/entrypoints/server/utils.d.ts +15 -7
- package/dest/entrypoints/server/utils.d.ts.map +1 -1
- package/dest/entrypoints/server/utils.js +17 -9
- package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.d.ts +2 -2
- package/dest/private_kernel/hints/build_private_kernel_reset_private_inputs.d.ts.map +1 -0
- package/dest/private_kernel/hints/index.d.ts.map +1 -0
- package/dest/private_kernel/index.d.ts +3 -0
- package/dest/private_kernel/index.d.ts.map +1 -0
- package/dest/private_kernel/index.js +2 -0
- package/dest/{kernel_prover/kernel_prover.d.ts → private_kernel/private_kernel_execution_prover.d.ts} +13 -14
- package/dest/private_kernel/private_kernel_execution_prover.d.ts.map +1 -0
- package/dest/{kernel_prover/kernel_prover.js → private_kernel/private_kernel_execution_prover.js} +64 -64
- package/dest/{kernel_prover/proving_data_oracle.d.ts → private_kernel/private_kernel_oracle.d.ts} +17 -28
- package/dest/private_kernel/private_kernel_oracle.d.ts.map +1 -0
- package/dest/private_kernel/private_kernel_oracle.js +4 -0
- package/dest/{kernel_oracle/index.d.ts → private_kernel/private_kernel_oracle_impl.d.ts} +5 -5
- package/dest/private_kernel/private_kernel_oracle_impl.d.ts.map +1 -0
- package/dest/{kernel_oracle/index.js → private_kernel/private_kernel_oracle_impl.js} +2 -2
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts +14 -22
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.js +51 -107
- package/dest/pxe_service/pxe_service.d.ts +13 -27
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +213 -241
- package/dest/storage/contract_data_provider/contract_data_provider.d.ts +2 -2
- package/dest/storage/contract_data_provider/contract_data_provider.d.ts.map +1 -1
- package/dest/storage/contract_data_provider/contract_data_provider.js +6 -1
- package/dest/storage/contract_data_provider/private_functions_tree.d.ts +2 -2
- package/dest/storage/contract_data_provider/private_functions_tree.d.ts.map +1 -1
- package/dest/storage/index.d.ts +1 -2
- package/dest/storage/index.d.ts.map +1 -1
- package/dest/storage/index.js +1 -2
- package/dest/storage/metadata.d.ts +2 -0
- package/dest/storage/metadata.d.ts.map +1 -0
- package/dest/storage/metadata.js +1 -0
- package/dest/storage/note_data_provider/note_dao.d.ts +9 -13
- package/dest/storage/note_data_provider/note_dao.d.ts.map +1 -1
- package/dest/storage/note_data_provider/note_dao.js +11 -15
- package/dest/storage/note_data_provider/note_data_provider.d.ts +2 -2
- package/dest/storage/note_data_provider/note_data_provider.d.ts.map +1 -1
- package/dest/storage/note_data_provider/note_data_provider.js +18 -19
- package/dest/synchronizer/synchronizer.js +1 -1
- package/package.json +15 -15
- package/src/config/package_info.ts +1 -1
- package/src/entrypoints/server/utils.ts +25 -11
- package/src/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.ts +4 -4
- package/src/private_kernel/index.ts +2 -0
- package/src/{kernel_prover/kernel_prover.ts → private_kernel/private_kernel_execution_prover.ts} +76 -71
- package/src/{kernel_prover/proving_data_oracle.ts → private_kernel/private_kernel_oracle.ts} +17 -29
- package/src/{kernel_oracle/index.ts → private_kernel/private_kernel_oracle_impl.ts} +6 -5
- package/src/pxe_oracle_interface/pxe_oracle_interface.ts +77 -153
- package/src/pxe_service/pxe_service.ts +289 -310
- package/src/storage/contract_data_provider/contract_data_provider.ts +11 -2
- package/src/storage/contract_data_provider/private_functions_tree.ts +2 -2
- package/src/storage/index.ts +1 -3
- package/src/storage/metadata.ts +1 -0
- package/src/storage/note_data_provider/note_dao.ts +9 -18
- package/src/storage/note_data_provider/note_data_provider.ts +22 -28
- package/src/synchronizer/synchronizer.ts +1 -1
- package/dest/kernel_oracle/index.d.ts.map +0 -1
- package/dest/kernel_prover/hints/build_private_kernel_reset_private_inputs.d.ts.map +0 -1
- package/dest/kernel_prover/hints/index.d.ts.map +0 -1
- package/dest/kernel_prover/index.d.ts +0 -3
- package/dest/kernel_prover/index.d.ts.map +0 -1
- package/dest/kernel_prover/index.js +0 -2
- package/dest/kernel_prover/kernel_prover.d.ts.map +0 -1
- package/dest/kernel_prover/proving_data_oracle.d.ts.map +0 -1
- package/dest/kernel_prover/proving_data_oracle.js +0 -4
- package/dest/note_decryption_utils/add_public_values_to_payload.d.ts +0 -11
- package/dest/note_decryption_utils/add_public_values_to_payload.d.ts.map +0 -1
- package/dest/note_decryption_utils/add_public_values_to_payload.js +0 -47
- package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts +0 -11
- package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.d.ts.map +0 -1
- package/dest/storage/auth_witness_data_provider/auth_witness_data_provider.js +0 -20
- package/dest/storage/auth_witness_data_provider/index.d.ts +0 -2
- package/dest/storage/auth_witness_data_provider/index.d.ts.map +0 -1
- package/dest/storage/auth_witness_data_provider/index.js +0 -1
- package/src/kernel_prover/index.ts +0 -2
- package/src/note_decryption_utils/add_public_values_to_payload.ts +0 -64
- package/src/storage/auth_witness_data_provider/auth_witness_data_provider.ts +0 -34
- package/src/storage/auth_witness_data_provider/index.ts +0 -1
- /package/dest/{kernel_prover → private_kernel}/hints/build_private_kernel_reset_private_inputs.js +0 -0
- /package/dest/{kernel_prover → private_kernel}/hints/index.d.ts +0 -0
- /package/dest/{kernel_prover → private_kernel}/hints/index.js +0 -0
- /package/src/{kernel_prover → private_kernel}/hints/index.ts +0 -0
|
@@ -1,50 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
3
|
-
MAX_NOTE_HASHES_PER_TX,
|
|
4
|
-
PRIVATE_LOG_SIZE_IN_FIELDS,
|
|
5
|
-
PUBLIC_LOG_DATA_SIZE_IN_FIELDS,
|
|
6
|
-
} from '@aztec/constants';
|
|
1
|
+
import { type L1_TO_L2_MSG_TREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, PRIVATE_LOG_SIZE_IN_FIELDS } from '@aztec/constants';
|
|
7
2
|
import { timesParallel } from '@aztec/foundation/collection';
|
|
8
3
|
import { poseidon2Hash } from '@aztec/foundation/crypto';
|
|
9
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
4
|
+
import { Fr, Point } from '@aztec/foundation/fields';
|
|
10
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
11
|
-
import { BufferReader } from '@aztec/foundation/serialize';
|
|
12
6
|
import type { KeyStore } from '@aztec/key-store';
|
|
13
|
-
import {
|
|
14
|
-
|
|
7
|
+
import {
|
|
8
|
+
AcirSimulator,
|
|
9
|
+
type ExecutionDataProvider,
|
|
10
|
+
MessageLoadOracleInputs,
|
|
11
|
+
type SimulationProvider,
|
|
12
|
+
} from '@aztec/simulator/client';
|
|
15
13
|
import {
|
|
16
14
|
type FunctionArtifact,
|
|
15
|
+
type FunctionArtifactWithContractName,
|
|
17
16
|
FunctionCall,
|
|
18
17
|
FunctionSelector,
|
|
19
18
|
FunctionType,
|
|
20
|
-
NoteSelector,
|
|
21
19
|
encodeArguments,
|
|
22
20
|
getFunctionArtifact,
|
|
23
21
|
} from '@aztec/stdlib/abi';
|
|
24
|
-
import
|
|
22
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
25
23
|
import type { InBlock, L2Block, L2BlockNumber } from '@aztec/stdlib/block';
|
|
26
24
|
import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
27
25
|
import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
|
|
28
26
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
29
27
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
30
28
|
import { computeAddressSecret, computeTaggingSecretPoint } from '@aztec/stdlib/keys';
|
|
31
|
-
import {
|
|
32
|
-
IndexedTaggingSecret,
|
|
33
|
-
L1NotePayload,
|
|
34
|
-
LogWithTxData,
|
|
35
|
-
PrivateLog,
|
|
36
|
-
PublicLog,
|
|
37
|
-
TxScopedL2Log,
|
|
38
|
-
} from '@aztec/stdlib/logs';
|
|
29
|
+
import { IndexedTaggingSecret, LogWithTxData, TxScopedL2Log, deriveEcdhSharedSecret } from '@aztec/stdlib/logs';
|
|
39
30
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
40
31
|
import { Note, type NoteStatus } from '@aztec/stdlib/note';
|
|
41
32
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
42
33
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
43
34
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
44
35
|
|
|
45
|
-
import { getOrderedNoteItems } from '../note_decryption_utils/add_public_values_to_payload.js';
|
|
46
36
|
import type { AddressDataProvider } from '../storage/address_data_provider/address_data_provider.js';
|
|
47
|
-
import type { AuthWitnessDataProvider } from '../storage/auth_witness_data_provider/auth_witness_data_provider.js';
|
|
48
37
|
import type { CapsuleDataProvider } from '../storage/capsule_data_provider/capsule_data_provider.js';
|
|
49
38
|
import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
|
|
50
39
|
import { NoteDao } from '../storage/note_data_provider/note_dao.js';
|
|
@@ -67,8 +56,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
67
56
|
private syncDataProvider: SyncDataProvider,
|
|
68
57
|
private taggingDataProvider: TaggingDataProvider,
|
|
69
58
|
private addressDataProvider: AddressDataProvider,
|
|
70
|
-
private
|
|
71
|
-
private log = createLogger('pxe:pxe_data_manager'),
|
|
59
|
+
private log = createLogger('pxe:pxe_oracle_interface'),
|
|
72
60
|
) {}
|
|
73
61
|
|
|
74
62
|
getKeyValidationRequest(pkMHash: Fr, contractAddress: AztecAddress): Promise<KeyValidationRequest> {
|
|
@@ -94,11 +82,6 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
94
82
|
return instance;
|
|
95
83
|
}
|
|
96
84
|
|
|
97
|
-
async getAuthWitness(messageHash: Fr): Promise<Fr[] | undefined> {
|
|
98
|
-
const witness = await this.authWitnessDataProvider.getAuthWitness(messageHash);
|
|
99
|
-
return witness;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
85
|
async getNotes(contractAddress: AztecAddress, storageSlot: Fr, status: NoteStatus, scopes?: AztecAddress[]) {
|
|
103
86
|
const noteDaos = await this.noteDataProvider.getNotes({
|
|
104
87
|
contractAddress,
|
|
@@ -118,7 +101,10 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
118
101
|
}));
|
|
119
102
|
}
|
|
120
103
|
|
|
121
|
-
async getFunctionArtifact(
|
|
104
|
+
async getFunctionArtifact(
|
|
105
|
+
contractAddress: AztecAddress,
|
|
106
|
+
selector: FunctionSelector,
|
|
107
|
+
): Promise<FunctionArtifactWithContractName> {
|
|
122
108
|
const artifact = await this.contractDataProvider.getFunctionArtifact(contractAddress, selector);
|
|
123
109
|
const debug = await this.contractDataProvider.getFunctionDebugMetadata(contractAddress, selector);
|
|
124
110
|
return {
|
|
@@ -130,7 +116,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
130
116
|
async getFunctionArtifactByName(
|
|
131
117
|
contractAddress: AztecAddress,
|
|
132
118
|
functionName: string,
|
|
133
|
-
): Promise<
|
|
119
|
+
): Promise<FunctionArtifactWithContractName | undefined> {
|
|
134
120
|
const instance = await this.contractDataProvider.getContractInstance(contractAddress);
|
|
135
121
|
const artifact = await this.contractDataProvider.getContractArtifact(instance.currentContractClassId);
|
|
136
122
|
return artifact && getFunctionArtifact(artifact, functionName);
|
|
@@ -161,21 +147,12 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
161
147
|
}
|
|
162
148
|
|
|
163
149
|
// Only used in public.
|
|
164
|
-
public
|
|
150
|
+
public getL1ToL2MessageHash(_leafIndex: bigint): Promise<Fr | undefined> {
|
|
165
151
|
throw new Error('Unimplemented in private!');
|
|
166
152
|
}
|
|
167
153
|
|
|
168
|
-
/**
|
|
169
|
-
* Gets the index of a commitment in the note hash tree.
|
|
170
|
-
* @param commitment - The commitment.
|
|
171
|
-
* @returns - The index of the commitment. Undefined if it does not exist in the tree.
|
|
172
|
-
*/
|
|
173
|
-
async getCommitmentIndex(commitment: Fr) {
|
|
174
|
-
return await this.#findLeafIndex('latest', MerkleTreeId.NOTE_HASH_TREE, commitment);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
154
|
// We need this in public as part of the EXISTS calls - but isn't used in private
|
|
178
|
-
public
|
|
155
|
+
public getNoteHash(_leafIndex: bigint): Promise<Fr | undefined> {
|
|
179
156
|
throw new Error('Unimplemented in private!');
|
|
180
157
|
}
|
|
181
158
|
|
|
@@ -185,7 +162,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
185
162
|
|
|
186
163
|
async #findLeafIndex(blockNumber: L2BlockNumber, treeId: MerkleTreeId, leafValue: Fr): Promise<bigint | undefined> {
|
|
187
164
|
const [leafIndex] = await this.aztecNode.findLeavesIndexes(blockNumber, treeId, [leafValue]);
|
|
188
|
-
return leafIndex;
|
|
165
|
+
return leafIndex?.data;
|
|
189
166
|
}
|
|
190
167
|
|
|
191
168
|
public async getMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[]> {
|
|
@@ -236,8 +213,8 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
236
213
|
return await this.aztecNode.getBlock(blockNumber);
|
|
237
214
|
}
|
|
238
215
|
|
|
239
|
-
public async
|
|
240
|
-
return await this.aztecNode.
|
|
216
|
+
public async getPublicDataWitness(blockNumber: number, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
217
|
+
return await this.aztecNode.getPublicDataWitness(blockNumber, leafSlot);
|
|
241
218
|
}
|
|
242
219
|
|
|
243
220
|
public async getPublicStorageAt(blockNumber: number, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
@@ -470,7 +447,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
470
447
|
const recipients = scopes ? scopes : await this.keyStore.getAccounts();
|
|
471
448
|
// A map of logs going from recipient address to logs. Note that the logs might have been processed before
|
|
472
449
|
// due to us having a sliding window that "looks back" for logs as well. (We look back as there is no guarantee
|
|
473
|
-
// that a logs will be received ordered by a given
|
|
450
|
+
// that a logs will be received ordered by a given tag index and that the tags won't be reused).
|
|
474
451
|
const logsMap = new Map<string, TxScopedL2Log[]>();
|
|
475
452
|
const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
|
|
476
453
|
for (const recipient of recipients) {
|
|
@@ -516,31 +493,21 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
516
493
|
|
|
517
494
|
logsByTags.forEach((logsByTag, logIndex) => {
|
|
518
495
|
if (logsByTag.length > 0) {
|
|
519
|
-
//
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
if (checkedLogsbyTag.length < logsByTag.length) {
|
|
524
|
-
const discarded = logsByTag.filter(
|
|
525
|
-
log => checkedLogsbyTag.find(filteredLog => filteredLog.equals(log)) === undefined,
|
|
526
|
-
);
|
|
527
|
-
this.log.warn(
|
|
528
|
-
`Discarded ${
|
|
529
|
-
logsByTag.length - checkedLogsbyTag.length
|
|
530
|
-
} public logs with mismatched contract address ${contractAddress}:`,
|
|
531
|
-
discarded.map(l => PublicLog.fromBuffer(l.logData)),
|
|
532
|
-
);
|
|
496
|
+
// Discard public logs
|
|
497
|
+
const filteredLogsByTag = logsByTag.filter(l => !l.isFromPublic);
|
|
498
|
+
if (filteredLogsByTag.length < logsByTag.length) {
|
|
499
|
+
this.log.warn(`Discarded ${logsByTag.filter(l => l.isFromPublic).length} public logs with matching tags`);
|
|
533
500
|
}
|
|
534
501
|
|
|
535
502
|
// The logs for the given tag exist so we store them for later processing
|
|
536
|
-
logsForRecipient.push(...
|
|
503
|
+
logsForRecipient.push(...filteredLogsByTag);
|
|
537
504
|
|
|
538
505
|
// We retrieve the indexed tagging secret corresponding to the log as I need that to evaluate whether
|
|
539
506
|
// a new largest index have been found.
|
|
540
507
|
const secretCorrespondingToLog = secretsForTheWholeWindow[logIndex];
|
|
541
508
|
const initialIndex = initialIndexesMap[secretCorrespondingToLog.appTaggingSecret.toString()];
|
|
542
509
|
|
|
543
|
-
this.log.debug(`Found ${
|
|
510
|
+
this.log.debug(`Found ${filteredLogsByTag.length} logs as recipient ${recipient}`, {
|
|
544
511
|
recipient,
|
|
545
512
|
secret: secretCorrespondingToLog.appTaggingSecret,
|
|
546
513
|
contractName,
|
|
@@ -610,77 +577,36 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
610
577
|
return logsMap;
|
|
611
578
|
}
|
|
612
579
|
|
|
613
|
-
/**
|
|
614
|
-
* Decrypts logs tagged for a recipient and returns them.
|
|
615
|
-
* @param scopedLogs - The logs to decrypt.
|
|
616
|
-
* @param recipient - The recipient of the logs.
|
|
617
|
-
* @returns The decrypted notes.
|
|
618
|
-
*/
|
|
619
|
-
async #decryptTaggedLogs(scopedLogs: TxScopedL2Log[], recipient: AztecAddress) {
|
|
620
|
-
const recipientCompleteAddress = await this.getCompleteAddress(recipient);
|
|
621
|
-
const ivskM = await this.keyStore.getMasterSecretKey(
|
|
622
|
-
recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
|
|
623
|
-
);
|
|
624
|
-
const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
|
|
625
|
-
|
|
626
|
-
// Since we could have notes with the same index for different txs, we need
|
|
627
|
-
// to keep track of them scoping by txHash
|
|
628
|
-
const excludedIndices: Map<string, Set<number>> = new Map();
|
|
629
|
-
const decrypted = [];
|
|
630
|
-
|
|
631
|
-
for (const scopedLog of scopedLogs) {
|
|
632
|
-
const payload = scopedLog.isFromPublic
|
|
633
|
-
? await L1NotePayload.decryptAsIncomingFromPublic(PublicLog.fromBuffer(scopedLog.logData), addressSecret)
|
|
634
|
-
: await L1NotePayload.decryptAsIncoming(PrivateLog.fromBuffer(scopedLog.logData), addressSecret);
|
|
635
|
-
|
|
636
|
-
if (!payload) {
|
|
637
|
-
this.log.verbose('Unable to decrypt log');
|
|
638
|
-
continue;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
if (!excludedIndices.has(scopedLog.txHash.toString())) {
|
|
642
|
-
excludedIndices.set(scopedLog.txHash.toString(), new Set());
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
const note = await getOrderedNoteItems(this.contractDataProvider, payload);
|
|
646
|
-
const plaintext = [payload.storageSlot, payload.noteTypeId.toField(), ...note.items];
|
|
647
|
-
|
|
648
|
-
decrypted.push({ plaintext, txHash: scopedLog.txHash, contractAddress: payload.contractAddress });
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
return decrypted;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
580
|
/**
|
|
655
581
|
* Processes the tagged logs returned by syncTaggedLogs by decrypting them and storing them in the database.
|
|
582
|
+
* @param contractAddress - The address of the contract that the logs are tagged for.
|
|
656
583
|
* @param logs - The logs to process.
|
|
657
584
|
* @param recipient - The recipient of the logs.
|
|
658
585
|
*/
|
|
659
586
|
public async processTaggedLogs(
|
|
587
|
+
contractAddress: AztecAddress,
|
|
660
588
|
logs: TxScopedL2Log[],
|
|
661
589
|
recipient: AztecAddress,
|
|
662
590
|
simulator?: AcirSimulator,
|
|
663
591
|
): Promise<void> {
|
|
664
|
-
const
|
|
592
|
+
for (const scopedLog of logs) {
|
|
593
|
+
if (scopedLog.isFromPublic) {
|
|
594
|
+
throw new Error('Attempted to decrypt public log');
|
|
595
|
+
}
|
|
665
596
|
|
|
666
|
-
// We've produced the full NoteDao, which we'd be able to simply insert into the database. However, this is
|
|
667
|
-
// only a temporary measure as we migrate from the PXE-driven discovery into the new contract-driven approach. We
|
|
668
|
-
// discard most of the work done up to this point and reconstruct the note plaintext to then hand over to the
|
|
669
|
-
// contract for further processing.
|
|
670
|
-
for (const decryptedLog of decryptedLogs) {
|
|
671
597
|
// Log processing requires the note hashes in the tx in which the note was created. We are now assuming that the
|
|
672
598
|
// note was included in the same block in which the log was delivered - note that partial notes will not work this
|
|
673
599
|
// way.
|
|
674
|
-
const txEffect = await this.aztecNode.getTxEffect(
|
|
600
|
+
const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
|
|
675
601
|
if (!txEffect) {
|
|
676
|
-
throw new Error(`Could not find tx effect for tx hash ${
|
|
602
|
+
throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
|
|
677
603
|
}
|
|
678
604
|
|
|
679
605
|
// This will trigger calls to the deliverNote oracle
|
|
680
606
|
await this.callProcessLog(
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
607
|
+
contractAddress,
|
|
608
|
+
scopedLog.log.toFields(),
|
|
609
|
+
scopedLog.txHash,
|
|
684
610
|
txEffect.data.noteHashes,
|
|
685
611
|
txEffect.data.nullifiers[0],
|
|
686
612
|
recipient,
|
|
@@ -729,28 +655,17 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
729
655
|
|
|
730
656
|
// We store notes by their index in the global note hash tree, which has the convenient side effect of validating
|
|
731
657
|
// note existence in said tree.
|
|
732
|
-
const [
|
|
658
|
+
const [uniqueNoteHashTreeIndexInBlock] = await this.aztecNode.findLeavesIndexes(
|
|
733
659
|
syncedBlockNumber,
|
|
734
660
|
MerkleTreeId.NOTE_HASH_TREE,
|
|
735
661
|
[uniqueNoteHash],
|
|
736
662
|
);
|
|
737
|
-
if (
|
|
663
|
+
if (uniqueNoteHashTreeIndexInBlock === undefined) {
|
|
738
664
|
throw new Error(
|
|
739
665
|
`Note hash ${noteHash} (uniqued as ${uniqueNoteHash}) is not present on the tree at block ${syncedBlockNumber} (from tx ${txHash})`,
|
|
740
666
|
);
|
|
741
667
|
}
|
|
742
668
|
|
|
743
|
-
// TODO (#12550): findLeavesIndexes should probably return an InBlock, same as findNullifiersIndexesWithBlock. This
|
|
744
|
-
// would save us from having to then query the tx receipt in order to get the block hash and number. Note regardless
|
|
745
|
-
// that we're not validating that the note was indeed created in this tx (which would require inspecting the tx
|
|
746
|
-
// effects), so maybe what we really want is an InTx.
|
|
747
|
-
const txReceipt = await this.aztecNode.getTxReceipt(new TxHash(txHash));
|
|
748
|
-
if (txReceipt === undefined) {
|
|
749
|
-
throw new Error(`Failed to fetch tx receipt for tx hash ${txHash} when searching for note hashes`);
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
// TODO(#12549): does it make sense to store the recipient's address point instead of just its address?
|
|
753
|
-
const recipientAddressPoint = await recipient.toAddressPoint();
|
|
754
669
|
const noteDao = new NoteDao(
|
|
755
670
|
new Note(content),
|
|
756
671
|
contractAddress,
|
|
@@ -759,11 +674,10 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
759
674
|
noteHash,
|
|
760
675
|
siloedNullifier,
|
|
761
676
|
new TxHash(txHash),
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
NoteSelector.empty(), // TODO(#12013): remove
|
|
677
|
+
uniqueNoteHashTreeIndexInBlock?.l2BlockNumber,
|
|
678
|
+
uniqueNoteHashTreeIndexInBlock?.l2BlockHash,
|
|
679
|
+
uniqueNoteHashTreeIndexInBlock?.data,
|
|
680
|
+
recipient,
|
|
767
681
|
);
|
|
768
682
|
|
|
769
683
|
await this.noteDataProvider.addNotes([noteDao], recipient);
|
|
@@ -774,13 +688,12 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
774
688
|
nullifier: noteDao.siloedNullifier.toString(),
|
|
775
689
|
});
|
|
776
690
|
|
|
777
|
-
const [nullifierIndex] = await this.aztecNode.
|
|
691
|
+
const [nullifierIndex] = await this.aztecNode.findLeavesIndexes(syncedBlockNumber, MerkleTreeId.NULLIFIER_TREE, [
|
|
692
|
+
siloedNullifier,
|
|
693
|
+
]);
|
|
778
694
|
if (nullifierIndex !== undefined) {
|
|
779
695
|
const { data: _, ...blockHashAndNum } = nullifierIndex;
|
|
780
|
-
await this.noteDataProvider.removeNullifiedNotes(
|
|
781
|
-
[{ data: siloedNullifier, ...blockHashAndNum }],
|
|
782
|
-
recipientAddressPoint,
|
|
783
|
-
);
|
|
696
|
+
await this.noteDataProvider.removeNullifiedNotes([{ data: siloedNullifier, ...blockHashAndNum }], recipient);
|
|
784
697
|
|
|
785
698
|
this.log.verbose(`Removed just-added note`, {
|
|
786
699
|
contract: contractAddress,
|
|
@@ -806,35 +719,39 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
806
719
|
);
|
|
807
720
|
}
|
|
808
721
|
|
|
809
|
-
const
|
|
722
|
+
const scopedLog = logsForTag[0];
|
|
810
723
|
|
|
811
724
|
// getLogsByTag doesn't have all of the information that we need (notably note hashes and the first nullifier), so
|
|
812
725
|
// we need to make a second call to the node for `getTxEffect`.
|
|
813
726
|
// TODO(#9789): bundle this information in the `getLogsByTag` call.
|
|
814
|
-
const txEffect = await this.aztecNode.getTxEffect(
|
|
727
|
+
const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
|
|
815
728
|
if (txEffect == undefined) {
|
|
816
|
-
throw new Error(`Unexpected: failed to retrieve tx effects for tx ${
|
|
729
|
+
throw new Error(`Unexpected: failed to retrieve tx effects for tx ${scopedLog.txHash} which is known to exist`);
|
|
817
730
|
}
|
|
818
731
|
|
|
819
|
-
const reader = BufferReader.asReader(log.logData);
|
|
820
|
-
const logArray = reader.readArray(PUBLIC_LOG_DATA_SIZE_IN_FIELDS, Fr);
|
|
821
|
-
|
|
822
732
|
// Public logs always take up all available fields by padding with zeroes, and the length of the originally emitted
|
|
823
733
|
// log is lost. Until this is improved, we simply remove all of the zero elements (which are expected to be at the
|
|
824
734
|
// end).
|
|
825
735
|
// TODO(#11636): use the actual log length.
|
|
826
|
-
const trimmedLog =
|
|
736
|
+
const trimmedLog = scopedLog.log.toFields().filter(x => !x.isZero());
|
|
827
737
|
|
|
828
|
-
return new LogWithTxData(trimmedLog,
|
|
738
|
+
return new LogWithTxData(trimmedLog, scopedLog.txHash.hash, txEffect.data.noteHashes, txEffect.data.nullifiers[0]);
|
|
829
739
|
}
|
|
830
740
|
|
|
741
|
+
// TODO(#12553): nuke this as part of tackling that issue. This function is no longer unit tested as I had to remove
|
|
742
|
+
// it from pxe_oracle_interface.test.ts when moving decryption to Noir (at that point we could not get a hold of
|
|
743
|
+
// the decrypted note in the test as TS decryption no longer existed).
|
|
831
744
|
public async removeNullifiedNotes(contractAddress: AztecAddress) {
|
|
832
745
|
this.log.verbose('Searching for nullifiers of known notes', { contract: contractAddress });
|
|
833
746
|
|
|
834
747
|
for (const recipient of await this.keyStore.getAccounts()) {
|
|
835
|
-
const currentNotesForRecipient = await this.noteDataProvider.getNotes({ contractAddress,
|
|
748
|
+
const currentNotesForRecipient = await this.noteDataProvider.getNotes({ contractAddress, recipient });
|
|
836
749
|
const nullifiersToCheck = currentNotesForRecipient.map(note => note.siloedNullifier);
|
|
837
|
-
const nullifierIndexes = await this.aztecNode.
|
|
750
|
+
const nullifierIndexes = await this.aztecNode.findLeavesIndexes(
|
|
751
|
+
'latest',
|
|
752
|
+
MerkleTreeId.NULLIFIER_TREE,
|
|
753
|
+
nullifiersToCheck,
|
|
754
|
+
);
|
|
838
755
|
|
|
839
756
|
const foundNullifiers = nullifiersToCheck
|
|
840
757
|
.map((nullifier, i) => {
|
|
@@ -844,10 +761,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
844
761
|
})
|
|
845
762
|
.filter(nullifier => nullifier !== undefined) as InBlock<Fr>[];
|
|
846
763
|
|
|
847
|
-
const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(
|
|
848
|
-
foundNullifiers,
|
|
849
|
-
await recipient.toAddressPoint(),
|
|
850
|
-
);
|
|
764
|
+
const nullifiedNotes = await this.noteDataProvider.removeNullifiedNotes(foundNullifiers, recipient);
|
|
851
765
|
nullifiedNotes.forEach(noteDao => {
|
|
852
766
|
this.log.verbose(`Removed note for contract ${noteDao.contractAddress} at slot ${noteDao.storageSlot}`, {
|
|
853
767
|
contract: noteDao.contractAddress,
|
|
@@ -860,7 +774,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
860
774
|
|
|
861
775
|
async callProcessLog(
|
|
862
776
|
contractAddress: AztecAddress,
|
|
863
|
-
|
|
777
|
+
logCiphertext: Fr[],
|
|
864
778
|
txHash: TxHash,
|
|
865
779
|
noteHashes: Fr[],
|
|
866
780
|
firstNullifier: Fr,
|
|
@@ -885,7 +799,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
885
799
|
type: FunctionType.UNCONSTRAINED,
|
|
886
800
|
isStatic: artifact.isStatic,
|
|
887
801
|
args: encodeArguments(artifact, [
|
|
888
|
-
toBoundedVec(
|
|
802
|
+
toBoundedVec(logCiphertext, PRIVATE_LOG_SIZE_IN_FIELDS),
|
|
889
803
|
txHash.toString(),
|
|
890
804
|
toBoundedVec(noteHashes, MAX_NOTE_HASHES_PER_TX),
|
|
891
805
|
firstNullifier,
|
|
@@ -917,6 +831,16 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
917
831
|
copyCapsule(contractAddress: AztecAddress, srcSlot: Fr, dstSlot: Fr, numEntries: number): Promise<void> {
|
|
918
832
|
return this.capsuleDataProvider.copyCapsule(contractAddress, srcSlot, dstSlot, numEntries);
|
|
919
833
|
}
|
|
834
|
+
|
|
835
|
+
async getSharedSecret(address: AztecAddress, ephPk: Point): Promise<Point> {
|
|
836
|
+
// TODO(#12656): return an app-siloed secret
|
|
837
|
+
const recipientCompleteAddress = await this.getCompleteAddress(address);
|
|
838
|
+
const ivskM = await this.keyStore.getMasterSecretKey(
|
|
839
|
+
recipientCompleteAddress.publicKeys.masterIncomingViewingPublicKey,
|
|
840
|
+
);
|
|
841
|
+
const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
|
|
842
|
+
return deriveEcdhSharedSecret(addressSecret, ephPk);
|
|
843
|
+
}
|
|
920
844
|
}
|
|
921
845
|
|
|
922
846
|
function toBoundedVec(array: Fr[], maxLength: number) {
|