@aztec/pxe 0.82.3 → 0.83.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/pxe_oracle_interface/pxe_oracle_interface.d.ts +15 -20
- package/dest/pxe_oracle_interface/pxe_oracle_interface.d.ts.map +1 -1
- package/dest/pxe_oracle_interface/pxe_oracle_interface.js +56 -103
- package/dest/pxe_service/pxe_service.d.ts +3 -2
- package/dest/pxe_service/pxe_service.d.ts.map +1 -1
- package/dest/pxe_service/pxe_service.js +26 -56
- package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts +9 -0
- package/dest/storage/capsule_data_provider/capsule_data_provider.d.ts.map +1 -1
- package/dest/storage/capsule_data_provider/capsule_data_provider.js +24 -0
- package/dest/storage/index.d.ts +1 -0
- package/dest/storage/index.d.ts.map +1 -1
- package/dest/storage/index.js +1 -0
- package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts +37 -0
- package/dest/storage/private_event_data_provider/private_event_data_provider.d.ts.map +1 -0
- package/dest/storage/private_event_data_provider/private_event_data_provider.js +106 -0
- package/dest/storage/sync_data_provider/sync_data_provider.d.ts +1 -1
- package/dest/storage/sync_data_provider/sync_data_provider.d.ts.map +1 -1
- package/dest/storage/sync_data_provider/sync_data_provider.js +1 -1
- package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts +4 -4
- package/dest/storage/tagging_data_provider/tagging_data_provider.d.ts.map +1 -1
- package/dest/storage/tagging_data_provider/tagging_data_provider.js +29 -12
- package/dest/synchronizer/synchronizer.d.ts +4 -6
- package/dest/synchronizer/synchronizer.d.ts.map +1 -1
- package/dest/synchronizer/synchronizer.js +11 -15
- package/dest/test/pxe_test_suite.js +1 -1
- package/package.json +15 -15
- package/src/config/package_info.ts +1 -1
- package/src/pxe_oracle_interface/pxe_oracle_interface.ts +113 -143
- package/src/pxe_service/pxe_service.ts +35 -76
- package/src/storage/capsule_data_provider/capsule_data_provider.ts +26 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/private_event_data_provider/private_event_data_provider.ts +137 -0
- package/src/storage/sync_data_provider/sync_data_provider.ts +2 -2
- package/src/storage/tagging_data_provider/tagging_data_provider.ts +44 -13
- package/src/synchronizer/synchronizer.ts +11 -14
- package/src/test/pxe_test_suite.ts +1 -1
|
@@ -89,7 +89,7 @@ export const pxeTestSuite = (testName, pxeSetup)=>{
|
|
|
89
89
|
});
|
|
90
90
|
it('successfully gets node info', async ()=>{
|
|
91
91
|
const nodeInfo = await pxe.getNodeInfo();
|
|
92
|
-
expect(typeof nodeInfo.
|
|
92
|
+
expect(typeof nodeInfo.rollupVersion).toEqual('number');
|
|
93
93
|
expect(typeof nodeInfo.l1ChainId).toEqual('number');
|
|
94
94
|
expect(nodeInfo.l1ContractAddresses.rollupAddress.toString()).toMatch(/0x[a-fA-F0-9]+/);
|
|
95
95
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/pxe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.83.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./server": "./dest/entrypoints/server/index.js",
|
|
@@ -59,19 +59,19 @@
|
|
|
59
59
|
]
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@aztec/bb-prover": "0.
|
|
63
|
-
"@aztec/bb.js": "0.
|
|
64
|
-
"@aztec/builder": "0.
|
|
65
|
-
"@aztec/constants": "0.
|
|
66
|
-
"@aztec/ethereum": "0.
|
|
67
|
-
"@aztec/foundation": "0.
|
|
68
|
-
"@aztec/key-store": "0.
|
|
69
|
-
"@aztec/kv-store": "0.
|
|
70
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
71
|
-
"@aztec/noir-types": "0.
|
|
72
|
-
"@aztec/protocol-contracts": "0.
|
|
73
|
-
"@aztec/simulator": "0.
|
|
74
|
-
"@aztec/stdlib": "0.
|
|
62
|
+
"@aztec/bb-prover": "0.83.0",
|
|
63
|
+
"@aztec/bb.js": "0.83.0",
|
|
64
|
+
"@aztec/builder": "0.83.0",
|
|
65
|
+
"@aztec/constants": "0.83.0",
|
|
66
|
+
"@aztec/ethereum": "0.83.0",
|
|
67
|
+
"@aztec/foundation": "0.83.0",
|
|
68
|
+
"@aztec/key-store": "0.83.0",
|
|
69
|
+
"@aztec/kv-store": "0.83.0",
|
|
70
|
+
"@aztec/noir-protocol-circuits-types": "0.83.0",
|
|
71
|
+
"@aztec/noir-types": "0.83.0",
|
|
72
|
+
"@aztec/protocol-contracts": "0.83.0",
|
|
73
|
+
"@aztec/simulator": "0.83.0",
|
|
74
|
+
"@aztec/stdlib": "0.83.0",
|
|
75
75
|
"@msgpack/msgpack": "^3.0.0-beta2",
|
|
76
76
|
"koa": "^2.14.2",
|
|
77
77
|
"koa-router": "^12.0.0",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"viem": "2.23.7"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
|
-
"@aztec/noir-contracts.js": "0.
|
|
84
|
+
"@aztec/noir-contracts.js": "0.83.0",
|
|
85
85
|
"@jest/globals": "^29.5.0",
|
|
86
86
|
"@types/jest": "^29.5.0",
|
|
87
87
|
"@types/lodash.omit": "^4.5.7",
|
|
@@ -1,22 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
|
|
2
2
|
import { timesParallel } from '@aztec/foundation/collection';
|
|
3
|
-
import { poseidon2Hash } from '@aztec/foundation/crypto';
|
|
4
3
|
import { Fr, Point } from '@aztec/foundation/fields';
|
|
5
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
5
|
import type { KeyStore } from '@aztec/key-store';
|
|
6
|
+
import { type ExecutionDataProvider, MessageLoadOracleInputs } from '@aztec/simulator/client';
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
type ExecutionDataProvider,
|
|
10
|
-
MessageLoadOracleInputs,
|
|
11
|
-
type SimulationProvider,
|
|
12
|
-
} from '@aztec/simulator/client';
|
|
13
|
-
import {
|
|
14
|
-
type FunctionArtifact,
|
|
8
|
+
EventSelector,
|
|
15
9
|
type FunctionArtifactWithContractName,
|
|
16
|
-
FunctionCall,
|
|
17
10
|
FunctionSelector,
|
|
18
|
-
FunctionType,
|
|
19
|
-
encodeArguments,
|
|
20
11
|
getFunctionArtifact,
|
|
21
12
|
} from '@aztec/stdlib/abi';
|
|
22
13
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -25,8 +16,14 @@ import type { CompleteAddress, ContractInstance } from '@aztec/stdlib/contract';
|
|
|
25
16
|
import { computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
|
|
26
17
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
27
18
|
import type { KeyValidationRequest } from '@aztec/stdlib/kernel';
|
|
28
|
-
import { computeAddressSecret,
|
|
29
|
-
import {
|
|
19
|
+
import { computeAddressSecret, computeAppTaggingSecret } from '@aztec/stdlib/keys';
|
|
20
|
+
import {
|
|
21
|
+
IndexedTaggingSecret,
|
|
22
|
+
LogWithTxData,
|
|
23
|
+
PendingTaggedLog,
|
|
24
|
+
TxScopedL2Log,
|
|
25
|
+
deriveEcdhSharedSecret,
|
|
26
|
+
} from '@aztec/stdlib/logs';
|
|
30
27
|
import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
|
|
31
28
|
import { Note, type NoteStatus } from '@aztec/stdlib/note';
|
|
32
29
|
import { MerkleTreeId, type NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
@@ -38,6 +35,7 @@ import type { CapsuleDataProvider } from '../storage/capsule_data_provider/capsu
|
|
|
38
35
|
import type { ContractDataProvider } from '../storage/contract_data_provider/contract_data_provider.js';
|
|
39
36
|
import { NoteDao } from '../storage/note_data_provider/note_dao.js';
|
|
40
37
|
import type { NoteDataProvider } from '../storage/note_data_provider/note_data_provider.js';
|
|
38
|
+
import type { PrivateEventDataProvider } from '../storage/private_event_data_provider/private_event_data_provider.js';
|
|
41
39
|
import type { SyncDataProvider } from '../storage/sync_data_provider/sync_data_provider.js';
|
|
42
40
|
import type { TaggingDataProvider } from '../storage/tagging_data_provider/tagging_data_provider.js';
|
|
43
41
|
import { WINDOW_HALF_SIZE, getIndexedTaggingSecretsForTheWindow, getInitialIndexesMap } from './tagging_utils.js';
|
|
@@ -49,13 +47,13 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
49
47
|
constructor(
|
|
50
48
|
private aztecNode: AztecNode,
|
|
51
49
|
private keyStore: KeyStore,
|
|
52
|
-
private simulationProvider: SimulationProvider,
|
|
53
50
|
private contractDataProvider: ContractDataProvider,
|
|
54
51
|
private noteDataProvider: NoteDataProvider,
|
|
55
52
|
private capsuleDataProvider: CapsuleDataProvider,
|
|
56
53
|
private syncDataProvider: SyncDataProvider,
|
|
57
54
|
private taggingDataProvider: TaggingDataProvider,
|
|
58
55
|
private addressDataProvider: AddressDataProvider,
|
|
56
|
+
private privateEventDataProvider: PrivateEventDataProvider,
|
|
59
57
|
private log = createLogger('pxe:pxe_oracle_interface'),
|
|
60
58
|
) {}
|
|
61
59
|
|
|
@@ -291,7 +289,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
291
289
|
await this.syncTaggedLogsAsSender(contractAddress, sender, recipient);
|
|
292
290
|
|
|
293
291
|
const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
|
|
294
|
-
const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret]);
|
|
292
|
+
const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret], sender);
|
|
295
293
|
|
|
296
294
|
return new IndexedTaggingSecret(appTaggingSecret, index);
|
|
297
295
|
}
|
|
@@ -317,17 +315,17 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
317
315
|
contractAddress,
|
|
318
316
|
});
|
|
319
317
|
|
|
320
|
-
const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([secret]);
|
|
321
|
-
await this.taggingDataProvider.setTaggingSecretsIndexesAsSender(
|
|
318
|
+
const [index] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([secret], sender);
|
|
319
|
+
await this.taggingDataProvider.setTaggingSecretsIndexesAsSender(
|
|
320
|
+
[new IndexedTaggingSecret(secret, index + 1)],
|
|
321
|
+
sender,
|
|
322
|
+
);
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
async #calculateAppTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
|
|
325
326
|
const senderCompleteAddress = await this.getCompleteAddress(sender);
|
|
326
327
|
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
327
|
-
|
|
328
|
-
// Silo the secret so it can't be used to track other app's notes
|
|
329
|
-
const appSecret = poseidon2Hash([secretPoint.x, secretPoint.y, contractAddress]);
|
|
330
|
-
return appSecret;
|
|
328
|
+
return computeAppTaggingSecret(senderCompleteAddress, senderIvsk, recipient, contractAddress);
|
|
331
329
|
}
|
|
332
330
|
|
|
333
331
|
/**
|
|
@@ -353,12 +351,11 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
353
351
|
...(await this.keyStore.getAccounts()),
|
|
354
352
|
].filter((address, index, self) => index === self.findIndex(otherAddress => otherAddress.equals(address)));
|
|
355
353
|
const appTaggingSecrets = await Promise.all(
|
|
356
|
-
senders.map(
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}),
|
|
354
|
+
senders.map(contact =>
|
|
355
|
+
computeAppTaggingSecret(recipientCompleteAddress, recipientIvsk, contact, contractAddress),
|
|
356
|
+
),
|
|
360
357
|
);
|
|
361
|
-
const indexes = await this.taggingDataProvider.getTaggingSecretsIndexesAsRecipient(appTaggingSecrets);
|
|
358
|
+
const indexes = await this.taggingDataProvider.getTaggingSecretsIndexesAsRecipient(appTaggingSecrets, recipient);
|
|
362
359
|
return appTaggingSecrets.map((secret, i) => new IndexedTaggingSecret(secret, indexes[i]));
|
|
363
360
|
}
|
|
364
361
|
|
|
@@ -375,7 +372,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
375
372
|
recipient: AztecAddress,
|
|
376
373
|
): Promise<void> {
|
|
377
374
|
const appTaggingSecret = await this.#calculateAppTaggingSecret(contractAddress, sender, recipient);
|
|
378
|
-
const [oldIndex] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret]);
|
|
375
|
+
const [oldIndex] = await this.taggingDataProvider.getTaggingSecretsIndexesAsSender([appTaggingSecret], sender);
|
|
379
376
|
|
|
380
377
|
// This algorithm works such that:
|
|
381
378
|
// 1. If we find minimum consecutive empty logs in a window of logs we set the index to the index of the last log
|
|
@@ -413,9 +410,10 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
413
410
|
|
|
414
411
|
const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
|
|
415
412
|
if (currentIndex !== oldIndex) {
|
|
416
|
-
await this.taggingDataProvider.setTaggingSecretsIndexesAsSender(
|
|
417
|
-
new IndexedTaggingSecret(appTaggingSecret, currentIndex),
|
|
418
|
-
|
|
413
|
+
await this.taggingDataProvider.setTaggingSecretsIndexesAsSender(
|
|
414
|
+
[new IndexedTaggingSecret(appTaggingSecret, currentIndex)],
|
|
415
|
+
sender,
|
|
416
|
+
);
|
|
419
417
|
|
|
420
418
|
this.log.debug(`Syncing logs for sender ${sender} at contract ${contractName}(${contractAddress})`, {
|
|
421
419
|
sender,
|
|
@@ -430,20 +428,23 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
430
428
|
}
|
|
431
429
|
|
|
432
430
|
/**
|
|
433
|
-
* Synchronizes the logs tagged with scoped addresses and all the senders in the address book.
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
* @param
|
|
437
|
-
*
|
|
438
|
-
* @
|
|
431
|
+
* Synchronizes the logs tagged with scoped addresses and all the senders in the address book. Stores the found logs
|
|
432
|
+
* in CapsuleArray ready for a later retrieval in Aztec.nr.
|
|
433
|
+
* @param contractAddress - The address of the contract that the logs are tagged for.
|
|
434
|
+
* @param pendingTaggedLogArrayBaseSlot - The base slot of the pending tagged logs capsule array in which
|
|
435
|
+
* found logs will be stored.
|
|
436
|
+
* @param scopes - The scoped addresses to sync logs for. If not provided, all accounts in the address book will be
|
|
437
|
+
* synced.
|
|
439
438
|
*/
|
|
440
439
|
public async syncTaggedLogs(
|
|
441
440
|
contractAddress: AztecAddress,
|
|
442
|
-
|
|
441
|
+
pendingTaggedLogArrayBaseSlot: Fr,
|
|
443
442
|
scopes?: AztecAddress[],
|
|
444
|
-
)
|
|
443
|
+
) {
|
|
445
444
|
this.log.verbose('Searching for tagged logs', { contract: contractAddress });
|
|
446
445
|
|
|
446
|
+
const maxBlockNumber = await this.syncDataProvider.getBlockNumber();
|
|
447
|
+
|
|
447
448
|
// Ideally this algorithm would be implemented in noir, exposing its building blocks as oracles.
|
|
448
449
|
// However it is impossible at the moment due to the language not supporting nested slices.
|
|
449
450
|
// This nesting is necessary because for a given set of tags we don't
|
|
@@ -451,14 +452,8 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
451
452
|
// length, since we don't really know the note they correspond to until we decrypt them.
|
|
452
453
|
|
|
453
454
|
const recipients = scopes ? scopes : await this.keyStore.getAccounts();
|
|
454
|
-
// A map of logs going from recipient address to logs. Note that the logs might have been processed before
|
|
455
|
-
// due to us having a sliding window that "looks back" for logs as well. (We look back as there is no guarantee
|
|
456
|
-
// that a logs will be received ordered by a given tag index and that the tags won't be reused).
|
|
457
|
-
const logsMap = new Map<string, TxScopedL2Log[]>();
|
|
458
455
|
const contractName = await this.contractDataProvider.getDebugContractName(contractAddress);
|
|
459
456
|
for (const recipient of recipients) {
|
|
460
|
-
const logsForRecipient: TxScopedL2Log[] = [];
|
|
461
|
-
|
|
462
457
|
// Get all the secrets for the recipient and sender pairs (#9365)
|
|
463
458
|
const secrets = await this.#getIndexedTaggingSecretsForSenders(contractAddress, recipient);
|
|
464
459
|
|
|
@@ -497,7 +492,8 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
497
492
|
// Fetch the logs for the tags and iterate over them
|
|
498
493
|
const logsByTags = await this.aztecNode.getLogsByTags(tagsForTheWholeWindow);
|
|
499
494
|
|
|
500
|
-
logsByTags.
|
|
495
|
+
for (let logIndex = 0; logIndex < logsByTags.length; logIndex++) {
|
|
496
|
+
const logsByTag = logsByTags[logIndex];
|
|
501
497
|
if (logsByTag.length > 0) {
|
|
502
498
|
// Discard public logs
|
|
503
499
|
const filteredLogsByTag = logsByTag.filter(l => !l.isFromPublic);
|
|
@@ -505,8 +501,16 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
505
501
|
this.log.warn(`Discarded ${logsByTag.filter(l => l.isFromPublic).length} public logs with matching tags`);
|
|
506
502
|
}
|
|
507
503
|
|
|
508
|
-
//
|
|
509
|
-
|
|
504
|
+
// We filter out the logs that are newer than the historical block number of the tx currently being constructed
|
|
505
|
+
const filteredLogsByBlockNumber = filteredLogsByTag.filter(l => l.blockNumber <= maxBlockNumber);
|
|
506
|
+
|
|
507
|
+
// We store the logs in capsules (to later be obtained in Noir)
|
|
508
|
+
await this.#storePendingTaggedLogs(
|
|
509
|
+
contractAddress,
|
|
510
|
+
pendingTaggedLogArrayBaseSlot,
|
|
511
|
+
recipient,
|
|
512
|
+
filteredLogsByBlockNumber,
|
|
513
|
+
);
|
|
510
514
|
|
|
511
515
|
// We retrieve the indexed tagging secret corresponding to the log as I need that to evaluate whether
|
|
512
516
|
// a new largest index have been found.
|
|
@@ -538,7 +542,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
538
542
|
);
|
|
539
543
|
}
|
|
540
544
|
}
|
|
541
|
-
}
|
|
545
|
+
}
|
|
542
546
|
|
|
543
547
|
// Now based on the new largest indexes we found, we will construct a new secrets and windows set to fetch logs
|
|
544
548
|
// for. Note that it's very unlikely that a new log from the current window would appear between the iterations
|
|
@@ -567,59 +571,45 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
567
571
|
secretsAndWindows = newSecretsAndWindows;
|
|
568
572
|
}
|
|
569
573
|
|
|
570
|
-
// We filter the logs by block number and store them in the map.
|
|
571
|
-
logsMap.set(
|
|
572
|
-
recipient.toString(),
|
|
573
|
-
logsForRecipient.filter(log => log.blockNumber <= maxBlockNumber),
|
|
574
|
-
);
|
|
575
|
-
|
|
576
574
|
// At this point we have processed all the logs for the recipient so we store the new largest indexes in the db.
|
|
577
575
|
await this.taggingDataProvider.setTaggingSecretsIndexesAsRecipient(
|
|
578
576
|
Object.entries(newLargestIndexMapToStore).map(
|
|
579
577
|
([appTaggingSecret, index]) => new IndexedTaggingSecret(Fr.fromHexString(appTaggingSecret), index),
|
|
580
578
|
),
|
|
579
|
+
recipient,
|
|
581
580
|
);
|
|
582
581
|
}
|
|
583
|
-
return logsMap;
|
|
584
582
|
}
|
|
585
583
|
|
|
586
|
-
|
|
587
|
-
* Processes the tagged logs returned by syncTaggedLogs by decrypting them and storing them in the database.
|
|
588
|
-
* @param contractAddress - The address of the contract that the logs are tagged for.
|
|
589
|
-
* @param logs - The logs to process.
|
|
590
|
-
* @param recipient - The recipient of the logs.
|
|
591
|
-
*/
|
|
592
|
-
public async processTaggedLogs(
|
|
584
|
+
async #storePendingTaggedLogs(
|
|
593
585
|
contractAddress: AztecAddress,
|
|
594
|
-
|
|
586
|
+
capsuleArrayBaseSlot: Fr,
|
|
595
587
|
recipient: AztecAddress,
|
|
596
|
-
|
|
597
|
-
)
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
588
|
+
logs: TxScopedL2Log[],
|
|
589
|
+
) {
|
|
590
|
+
// Build all pending tagged logs upfront with their tx effects
|
|
591
|
+
const pendingTaggedLogs = await Promise.all(
|
|
592
|
+
logs.map(async scopedLog => {
|
|
593
|
+
// TODO(#9789): get these effects along with the log
|
|
594
|
+
const txEffect = await this.aztecNode.getTxEffect(scopedLog.txHash);
|
|
595
|
+
if (!txEffect) {
|
|
596
|
+
throw new Error(`Could not find tx effect for tx hash ${scopedLog.txHash}`);
|
|
597
|
+
}
|
|
602
598
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
599
|
+
const pendingTaggedLog = new PendingTaggedLog(
|
|
600
|
+
scopedLog.log.toFields(),
|
|
601
|
+
scopedLog.txHash.hash,
|
|
602
|
+
txEffect.data.noteHashes,
|
|
603
|
+
txEffect.data.nullifiers[0],
|
|
604
|
+
recipient,
|
|
605
|
+
scopedLog.logIndexInTx,
|
|
606
|
+
);
|
|
610
607
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
txEffect.data.noteHashes,
|
|
617
|
-
txEffect.data.nullifiers[0],
|
|
618
|
-
recipient,
|
|
619
|
-
simulator,
|
|
620
|
-
);
|
|
621
|
-
}
|
|
622
|
-
return;
|
|
608
|
+
return pendingTaggedLog.toFields();
|
|
609
|
+
}),
|
|
610
|
+
);
|
|
611
|
+
|
|
612
|
+
return this.capsuleDataProvider.appendToCapsuleArray(contractAddress, capsuleArrayBaseSlot, pendingTaggedLogs);
|
|
623
613
|
}
|
|
624
614
|
|
|
625
615
|
public async deliverNote(
|
|
@@ -649,10 +639,7 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
649
639
|
// in time of the locally synced state.
|
|
650
640
|
// Note that while this technically results in historical queries, we perform it at the latest locally synced block
|
|
651
641
|
// number which *should* be recent enough to be available, even for non-archive nodes.
|
|
652
|
-
const syncedBlockNumber =
|
|
653
|
-
if (syncedBlockNumber === undefined) {
|
|
654
|
-
throw new Error(`Attempted to deliver a note with an unsynchronized PXE - this should never happen`);
|
|
655
|
-
}
|
|
642
|
+
const syncedBlockNumber = await this.syncDataProvider.getBlockNumber();
|
|
656
643
|
|
|
657
644
|
// By computing siloed and unique note hashes ourselves we prevent contracts from interfering with the note storage
|
|
658
645
|
// of other contracts, which would constitute a security breach.
|
|
@@ -688,9 +675,10 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
688
675
|
|
|
689
676
|
await this.noteDataProvider.addNotes([noteDao], recipient);
|
|
690
677
|
this.log.verbose('Added note', {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
678
|
+
index: noteDao.index,
|
|
679
|
+
contract: noteDao.contractAddress.toString(),
|
|
680
|
+
slot: noteDao.storageSlot.toString(),
|
|
681
|
+
noteHash: noteDao.noteHash.toString(),
|
|
694
682
|
nullifier: noteDao.siloedNullifier.toString(),
|
|
695
683
|
});
|
|
696
684
|
|
|
@@ -778,50 +766,6 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
778
766
|
}
|
|
779
767
|
}
|
|
780
768
|
|
|
781
|
-
async callProcessLog(
|
|
782
|
-
contractAddress: AztecAddress,
|
|
783
|
-
logCiphertext: Fr[],
|
|
784
|
-
txHash: TxHash,
|
|
785
|
-
noteHashes: Fr[],
|
|
786
|
-
firstNullifier: Fr,
|
|
787
|
-
recipient: AztecAddress,
|
|
788
|
-
simulator?: AcirSimulator,
|
|
789
|
-
) {
|
|
790
|
-
const artifact: FunctionArtifact | undefined = await this.contractDataProvider.getFunctionArtifactByName(
|
|
791
|
-
contractAddress,
|
|
792
|
-
'process_log',
|
|
793
|
-
);
|
|
794
|
-
if (!artifact) {
|
|
795
|
-
throw new Error(
|
|
796
|
-
`Mandatory implementation of "process_log" missing in noir contract ${contractAddress.toString()}.`,
|
|
797
|
-
);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
const selector = await FunctionSelector.fromNameAndParameters(artifact);
|
|
801
|
-
const execRequest: FunctionCall = {
|
|
802
|
-
name: artifact.name,
|
|
803
|
-
to: contractAddress,
|
|
804
|
-
selector,
|
|
805
|
-
type: FunctionType.UNCONSTRAINED,
|
|
806
|
-
isStatic: artifact.isStatic,
|
|
807
|
-
args: encodeArguments(artifact, [
|
|
808
|
-
toBoundedVec(logCiphertext, PRIVATE_LOG_SIZE_IN_FIELDS),
|
|
809
|
-
txHash.toString(),
|
|
810
|
-
toBoundedVec(noteHashes, MAX_NOTE_HASHES_PER_TX),
|
|
811
|
-
firstNullifier,
|
|
812
|
-
recipient,
|
|
813
|
-
]),
|
|
814
|
-
returnTypes: artifact.returnTypes,
|
|
815
|
-
};
|
|
816
|
-
|
|
817
|
-
await (simulator ?? new AcirSimulator(this, this.simulationProvider)).runUnconstrained(
|
|
818
|
-
execRequest,
|
|
819
|
-
contractAddress,
|
|
820
|
-
selector,
|
|
821
|
-
[], // empty scope as this call should not require access to private information
|
|
822
|
-
);
|
|
823
|
-
}
|
|
824
|
-
|
|
825
769
|
storeCapsule(contractAddress: AztecAddress, slot: Fr, capsule: Fr[]): Promise<void> {
|
|
826
770
|
return this.capsuleDataProvider.storeCapsule(contractAddress, slot, capsule);
|
|
827
771
|
}
|
|
@@ -847,8 +791,34 @@ export class PXEOracleInterface implements ExecutionDataProvider {
|
|
|
847
791
|
const addressSecret = await computeAddressSecret(await recipientCompleteAddress.getPreaddress(), ivskM);
|
|
848
792
|
return deriveEcdhSharedSecret(addressSecret, ephPk);
|
|
849
793
|
}
|
|
850
|
-
}
|
|
851
794
|
|
|
852
|
-
|
|
853
|
-
|
|
795
|
+
async storePrivateEventLog(
|
|
796
|
+
contractAddress: AztecAddress,
|
|
797
|
+
recipient: AztecAddress,
|
|
798
|
+
eventSelector: EventSelector,
|
|
799
|
+
logContent: Fr[],
|
|
800
|
+
txHash: TxHash,
|
|
801
|
+
logIndexInTx: number,
|
|
802
|
+
): Promise<void> {
|
|
803
|
+
const txReceipt = await this.aztecNode.getTxReceipt(txHash);
|
|
804
|
+
const blockNumber = txReceipt.blockNumber;
|
|
805
|
+
if (blockNumber === undefined) {
|
|
806
|
+
throw new Error(`Block number is undefined for tx ${txHash} in storePrivateEventLog`);
|
|
807
|
+
}
|
|
808
|
+
const historicalBlockNumber = await this.syncDataProvider.getBlockNumber();
|
|
809
|
+
if (blockNumber > historicalBlockNumber) {
|
|
810
|
+
throw new Error(
|
|
811
|
+
`Attempting to store private event log from a block newer than the historical block of the simulation. Log block number: ${blockNumber}, historical block number: ${historicalBlockNumber}`,
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
return this.privateEventDataProvider.storePrivateEventLog(
|
|
815
|
+
contractAddress,
|
|
816
|
+
recipient,
|
|
817
|
+
eventSelector,
|
|
818
|
+
logContent,
|
|
819
|
+
txHash,
|
|
820
|
+
logIndexInTx,
|
|
821
|
+
blockNumber,
|
|
822
|
+
);
|
|
823
|
+
}
|
|
854
824
|
}
|