@aztec/txe 0.61.0 → 0.63.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/bin/index.js +13 -13
- package/dest/index.d.ts +1 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +19 -5
- package/dest/oracle/txe_oracle.d.ts +15 -10
- package/dest/oracle/txe_oracle.d.ts.map +1 -1
- package/dest/oracle/txe_oracle.js +114 -99
- package/dest/txe_service/txe_service.d.ts +2 -2
- package/dest/txe_service/txe_service.d.ts.map +1 -1
- package/dest/txe_service/txe_service.js +32 -32
- package/dest/util/encoding.d.ts +16 -1
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +13 -1
- package/package.json +17 -16
- package/src/bin/index.ts +12 -14
- package/src/index.ts +30 -5
- package/src/oracle/txe_oracle.ts +157 -125
- package/src/txe_service/txe_service.ts +31 -32
- package/src/util/encoding.ts +23 -1
package/src/oracle/txe_oracle.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AuthWitness,
|
|
3
|
+
type EncryptedL2NoteLog,
|
|
3
4
|
MerkleTreeId,
|
|
4
5
|
Note,
|
|
5
6
|
type NoteStatus,
|
|
6
7
|
NullifierMembershipWitness,
|
|
7
8
|
PublicDataWitness,
|
|
8
|
-
PublicDataWrite,
|
|
9
9
|
PublicExecutionRequest,
|
|
10
10
|
SimulationError,
|
|
11
11
|
type UnencryptedL2Log,
|
|
@@ -16,20 +16,24 @@ import {
|
|
|
16
16
|
CombinedConstantData,
|
|
17
17
|
type ContractInstance,
|
|
18
18
|
type ContractInstanceWithAddress,
|
|
19
|
+
DEFAULT_GAS_LIMIT,
|
|
19
20
|
Gas,
|
|
20
21
|
Header,
|
|
21
22
|
IndexedTaggingSecret,
|
|
22
23
|
type KeyValidationRequest,
|
|
24
|
+
type L1_TO_L2_MSG_TREE_HEIGHT,
|
|
25
|
+
MAX_L2_GAS_PER_ENQUEUED_CALL,
|
|
23
26
|
NULLIFIER_SUBTREE_HEIGHT,
|
|
24
27
|
type NULLIFIER_TREE_HEIGHT,
|
|
25
28
|
type NullifierLeafPreimage,
|
|
29
|
+
PRIVATE_CONTEXT_INPUTS_LENGTH,
|
|
26
30
|
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
27
31
|
type PUBLIC_DATA_TREE_HEIGHT,
|
|
28
32
|
PUBLIC_DISPATCH_SELECTOR,
|
|
29
33
|
PrivateContextInputs,
|
|
30
34
|
PublicDataTreeLeaf,
|
|
31
35
|
type PublicDataTreeLeafPreimage,
|
|
32
|
-
|
|
36
|
+
type PublicDataUpdateRequest,
|
|
33
37
|
computeContractClassId,
|
|
34
38
|
computeTaggingSecret,
|
|
35
39
|
deriveKeys,
|
|
@@ -65,19 +69,21 @@ import {
|
|
|
65
69
|
extractCallStack,
|
|
66
70
|
extractPrivateCircuitPublicInputs,
|
|
67
71
|
pickNotes,
|
|
72
|
+
resolveAssertionMessageFromError,
|
|
68
73
|
toACVMWitness,
|
|
69
74
|
witnessMapToFields,
|
|
70
75
|
} from '@aztec/simulator';
|
|
71
76
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
72
77
|
import { MerkleTreeSnapshotOperationsFacade, type MerkleTrees } from '@aztec/world-state';
|
|
73
78
|
|
|
79
|
+
import { type EnqueuedPublicCallExecutionResultWithSideEffects } from '../../../simulator/src/public/execution.js';
|
|
74
80
|
import { type TXEDatabase } from '../util/txe_database.js';
|
|
75
81
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
76
82
|
import { TXEWorldStateDB } from '../util/txe_world_state_db.js';
|
|
77
83
|
|
|
78
84
|
export class TXE implements TypedOracle {
|
|
79
85
|
private blockNumber = 0;
|
|
80
|
-
private
|
|
86
|
+
private sideEffectCounter = 0;
|
|
81
87
|
private contractAddress: AztecAddress;
|
|
82
88
|
private msgSender: AztecAddress;
|
|
83
89
|
private functionSelector = FunctionSelector.fromField(new Fr(0));
|
|
@@ -90,6 +96,8 @@ export class TXE implements TypedOracle {
|
|
|
90
96
|
private version: Fr = Fr.ONE;
|
|
91
97
|
private chainId: Fr = Fr.ONE;
|
|
92
98
|
|
|
99
|
+
private logsByTags = new Map<string, EncryptedL2NoteLog[]>();
|
|
100
|
+
|
|
93
101
|
constructor(
|
|
94
102
|
private logger: Logger,
|
|
95
103
|
private trees: MerkleTrees,
|
|
@@ -130,7 +138,7 @@ export class TXE implements TypedOracle {
|
|
|
130
138
|
return this.functionSelector;
|
|
131
139
|
}
|
|
132
140
|
|
|
133
|
-
setMsgSender(msgSender:
|
|
141
|
+
setMsgSender(msgSender: AztecAddress) {
|
|
134
142
|
this.msgSender = msgSender;
|
|
135
143
|
}
|
|
136
144
|
|
|
@@ -139,11 +147,11 @@ export class TXE implements TypedOracle {
|
|
|
139
147
|
}
|
|
140
148
|
|
|
141
149
|
getSideEffectsCounter() {
|
|
142
|
-
return this.
|
|
150
|
+
return this.sideEffectCounter;
|
|
143
151
|
}
|
|
144
152
|
|
|
145
153
|
setSideEffectsCounter(sideEffectsCounter: number) {
|
|
146
|
-
this.
|
|
154
|
+
this.sideEffectCounter = sideEffectsCounter;
|
|
147
155
|
}
|
|
148
156
|
|
|
149
157
|
setContractAddress(contractAddress: AztecAddress) {
|
|
@@ -181,7 +189,7 @@ export class TXE implements TypedOracle {
|
|
|
181
189
|
|
|
182
190
|
async getPrivateContextInputs(
|
|
183
191
|
blockNumber: number,
|
|
184
|
-
sideEffectsCounter = this.
|
|
192
|
+
sideEffectsCounter = this.sideEffectCounter,
|
|
185
193
|
isStaticCall = false,
|
|
186
194
|
) {
|
|
187
195
|
const db = await this.#getTreesAt(blockNumber);
|
|
@@ -214,11 +222,36 @@ export class TXE implements TypedOracle {
|
|
|
214
222
|
return this.txeDatabase.addAuthWitness(authWitness.requestHash, authWitness.witness);
|
|
215
223
|
}
|
|
216
224
|
|
|
217
|
-
async
|
|
225
|
+
async addPublicDataWrites(writes: PublicDataUpdateRequest[]) {
|
|
226
|
+
const db = await this.trees.getLatest();
|
|
227
|
+
|
|
228
|
+
// only insert the last write to a given slot
|
|
229
|
+
const uniqueWritesSet = new Map<bigint, PublicDataUpdateRequest>();
|
|
230
|
+
for (const write of writes) {
|
|
231
|
+
uniqueWritesSet.set(write.leafSlot.toBigInt(), write);
|
|
232
|
+
}
|
|
233
|
+
const uniqueWrites = Array.from(uniqueWritesSet.values());
|
|
234
|
+
|
|
235
|
+
await db.batchInsert(
|
|
236
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
237
|
+
uniqueWrites.map(w => new PublicDataTreeLeaf(w.leafSlot, w.newValue).toBuffer()),
|
|
238
|
+
0,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async addSiloedNullifiers(siloedNullifiers: Fr[]) {
|
|
218
243
|
const db = await this.trees.getLatest();
|
|
219
|
-
const siloedNullifiers = nullifiers.map(nullifier => siloNullifier(contractAddress, nullifier).toBuffer());
|
|
220
244
|
|
|
221
|
-
await db.batchInsert(
|
|
245
|
+
await db.batchInsert(
|
|
246
|
+
MerkleTreeId.NULLIFIER_TREE,
|
|
247
|
+
siloedNullifiers.map(n => n.toBuffer()),
|
|
248
|
+
NULLIFIER_SUBTREE_HEIGHT,
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async addNullifiers(contractAddress: AztecAddress, nullifiers: Fr[]) {
|
|
253
|
+
const siloedNullifiers = nullifiers.map(nullifier => siloNullifier(contractAddress, nullifier));
|
|
254
|
+
await this.addSiloedNullifiers(siloedNullifiers);
|
|
222
255
|
}
|
|
223
256
|
|
|
224
257
|
async addNoteHashes(contractAddress: AztecAddress, noteHashes: Fr[]) {
|
|
@@ -315,16 +348,16 @@ export class TXE implements TypedOracle {
|
|
|
315
348
|
}
|
|
316
349
|
|
|
317
350
|
async getPublicDataTreeWitness(blockNumber: number, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
318
|
-
const
|
|
319
|
-
const lowLeafResult = await
|
|
351
|
+
const db = await this.#getTreesAt(blockNumber);
|
|
352
|
+
const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
320
353
|
if (!lowLeafResult) {
|
|
321
354
|
return undefined;
|
|
322
355
|
} else {
|
|
323
|
-
const preimage = (await
|
|
356
|
+
const preimage = (await db.getLeafPreimage(
|
|
324
357
|
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
325
358
|
lowLeafResult.index,
|
|
326
359
|
)) as PublicDataTreeLeafPreimage;
|
|
327
|
-
const path = await
|
|
360
|
+
const path = await db.getSiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>(
|
|
328
361
|
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
329
362
|
lowLeafResult.index,
|
|
330
363
|
);
|
|
@@ -414,13 +447,13 @@ export class TXE implements TypedOracle {
|
|
|
414
447
|
},
|
|
415
448
|
counter,
|
|
416
449
|
);
|
|
417
|
-
this.
|
|
450
|
+
this.sideEffectCounter = counter + 1;
|
|
418
451
|
return Promise.resolve();
|
|
419
452
|
}
|
|
420
453
|
|
|
421
454
|
notifyNullifiedNote(innerNullifier: Fr, noteHash: Fr, counter: number) {
|
|
422
455
|
this.noteCache.nullifyNote(this.contractAddress, innerNullifier, noteHash);
|
|
423
|
-
this.
|
|
456
|
+
this.sideEffectCounter = counter + 1;
|
|
424
457
|
return Promise.resolve();
|
|
425
458
|
}
|
|
426
459
|
|
|
@@ -435,12 +468,12 @@ export class TXE implements TypedOracle {
|
|
|
435
468
|
_contractAddress: AztecAddress,
|
|
436
469
|
_messageHash: Fr,
|
|
437
470
|
_secret: Fr,
|
|
438
|
-
): Promise<MessageLoadOracleInputs<
|
|
471
|
+
): Promise<MessageLoadOracleInputs<typeof L1_TO_L2_MSG_TREE_HEIGHT>> {
|
|
439
472
|
throw new Error('Method not implemented.');
|
|
440
473
|
}
|
|
441
474
|
|
|
442
475
|
async storageRead(
|
|
443
|
-
contractAddress:
|
|
476
|
+
contractAddress: AztecAddress,
|
|
444
477
|
startStorageSlot: Fr,
|
|
445
478
|
blockNumber: number,
|
|
446
479
|
numberOfElements: number,
|
|
@@ -473,32 +506,32 @@ export class TXE implements TypedOracle {
|
|
|
473
506
|
const publicDataWrites = values.map((value, i) => {
|
|
474
507
|
const storageSlot = startStorageSlot.add(new Fr(i));
|
|
475
508
|
this.logger.debug(`Oracle storage write: slot=${storageSlot.toString()} value=${value}`);
|
|
476
|
-
return new
|
|
509
|
+
return new PublicDataTreeLeaf(computePublicDataTreeLeafSlot(this.contractAddress, storageSlot), value);
|
|
477
510
|
});
|
|
478
511
|
await db.batchInsert(
|
|
479
512
|
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
480
|
-
publicDataWrites.map(write =>
|
|
513
|
+
publicDataWrites.map(write => write.toBuffer()),
|
|
481
514
|
PUBLIC_DATA_SUBTREE_HEIGHT,
|
|
482
515
|
);
|
|
483
|
-
return publicDataWrites.map(write => write.
|
|
516
|
+
return publicDataWrites.map(write => write.value);
|
|
484
517
|
}
|
|
485
518
|
|
|
486
519
|
emitEncryptedLog(_contractAddress: AztecAddress, _randomness: Fr, _encryptedNote: Buffer, counter: number): void {
|
|
487
|
-
this.
|
|
520
|
+
this.sideEffectCounter = counter + 1;
|
|
488
521
|
return;
|
|
489
522
|
}
|
|
490
523
|
|
|
491
524
|
emitEncryptedNoteLog(_noteHashCounter: number, _encryptedNote: Buffer, counter: number): void {
|
|
492
|
-
this.
|
|
525
|
+
this.sideEffectCounter = counter + 1;
|
|
493
526
|
return;
|
|
494
527
|
}
|
|
495
528
|
|
|
496
529
|
emitUnencryptedLog(_log: UnencryptedL2Log, counter: number): void {
|
|
497
|
-
this.
|
|
530
|
+
this.sideEffectCounter = counter + 1;
|
|
498
531
|
return;
|
|
499
532
|
}
|
|
500
533
|
|
|
501
|
-
|
|
534
|
+
emitContractClassLog(_log: UnencryptedL2Log, _counter: number): Fr {
|
|
502
535
|
throw new Error('Method not implemented.');
|
|
503
536
|
}
|
|
504
537
|
|
|
@@ -517,8 +550,8 @@ export class TXE implements TypedOracle {
|
|
|
517
550
|
);
|
|
518
551
|
|
|
519
552
|
// Store and modify env
|
|
520
|
-
const currentContractAddress =
|
|
521
|
-
const currentMessageSender =
|
|
553
|
+
const currentContractAddress = this.contractAddress;
|
|
554
|
+
const currentMessageSender = this.msgSender;
|
|
522
555
|
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
523
556
|
this.setMsgSender(this.contractAddress);
|
|
524
557
|
this.setContractAddress(targetContractAddress);
|
|
@@ -530,53 +563,53 @@ export class TXE implements TypedOracle {
|
|
|
530
563
|
const initialWitness = await this.getInitialWitness(artifact, argsHash, sideEffectCounter, isStaticCall);
|
|
531
564
|
const acvmCallback = new Oracle(this);
|
|
532
565
|
const timer = new Timer();
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
this.logger.debug(`Error executing private function ${targetContractAddress}:${functionSelector}`);
|
|
545
|
-
throw createSimulationError(execError);
|
|
546
|
-
});
|
|
547
|
-
const duration = timer.ms();
|
|
548
|
-
const publicInputs = extractPrivateCircuitPublicInputs(artifact, acirExecutionResult.partialWitness);
|
|
549
|
-
|
|
550
|
-
const initialWitnessSize = witnessMapToFields(initialWitness).length * Fr.SIZE_IN_BYTES;
|
|
551
|
-
this.logger.debug(`Ran external function ${targetContractAddress.toString()}:${functionSelector}`, {
|
|
552
|
-
circuitName: 'app-circuit',
|
|
553
|
-
duration,
|
|
554
|
-
eventName: 'circuit-witness-generation',
|
|
555
|
-
inputSize: initialWitnessSize,
|
|
556
|
-
outputSize: publicInputs.toBuffer().length,
|
|
557
|
-
appCircuitName: 'noname',
|
|
558
|
-
} satisfies CircuitWitnessGenerationStats);
|
|
559
|
-
|
|
560
|
-
// Apply side effects
|
|
561
|
-
const endSideEffectCounter = publicInputs.endSideEffectCounter;
|
|
562
|
-
this.sideEffectsCounter = endSideEffectCounter.toNumber() + 1;
|
|
563
|
-
|
|
564
|
-
await this.addNullifiers(
|
|
565
|
-
targetContractAddress,
|
|
566
|
-
publicInputs.nullifiers.filter(nullifier => !nullifier.isEmpty()).map(nullifier => nullifier.value),
|
|
566
|
+
const acirExecutionResult = await acvm(acir, initialWitness, acvmCallback).catch((err: Error) => {
|
|
567
|
+
err.message = resolveAssertionMessageFromError(err, artifact);
|
|
568
|
+
|
|
569
|
+
const execError = new ExecutionError(
|
|
570
|
+
err.message,
|
|
571
|
+
{
|
|
572
|
+
contractAddress: targetContractAddress,
|
|
573
|
+
functionSelector,
|
|
574
|
+
},
|
|
575
|
+
extractCallStack(err, artifact.debug),
|
|
576
|
+
{ cause: err },
|
|
567
577
|
);
|
|
578
|
+
this.logger.debug(`Error executing private function ${targetContractAddress}:${functionSelector}`);
|
|
579
|
+
throw createSimulationError(execError);
|
|
580
|
+
});
|
|
581
|
+
const duration = timer.ms();
|
|
582
|
+
const publicInputs = extractPrivateCircuitPublicInputs(artifact, acirExecutionResult.partialWitness);
|
|
583
|
+
|
|
584
|
+
const initialWitnessSize = witnessMapToFields(initialWitness).length * Fr.SIZE_IN_BYTES;
|
|
585
|
+
this.logger.debug(`Ran external function ${targetContractAddress.toString()}:${functionSelector}`, {
|
|
586
|
+
circuitName: 'app-circuit',
|
|
587
|
+
duration,
|
|
588
|
+
eventName: 'circuit-witness-generation',
|
|
589
|
+
inputSize: initialWitnessSize,
|
|
590
|
+
outputSize: publicInputs.toBuffer().length,
|
|
591
|
+
appCircuitName: 'noname',
|
|
592
|
+
} satisfies CircuitWitnessGenerationStats);
|
|
568
593
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
);
|
|
594
|
+
// Apply side effects
|
|
595
|
+
const endSideEffectCounter = publicInputs.endSideEffectCounter;
|
|
596
|
+
this.sideEffectCounter = endSideEffectCounter.toNumber() + 1;
|
|
573
597
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
598
|
+
await this.addNullifiers(
|
|
599
|
+
targetContractAddress,
|
|
600
|
+
publicInputs.nullifiers.filter(nullifier => !nullifier.isEmpty()).map(nullifier => nullifier.value),
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
await this.addNoteHashes(
|
|
604
|
+
targetContractAddress,
|
|
605
|
+
publicInputs.noteHashes.filter(noteHash => !noteHash.isEmpty()).map(noteHash => noteHash.value),
|
|
606
|
+
);
|
|
607
|
+
|
|
608
|
+
this.setContractAddress(currentContractAddress);
|
|
609
|
+
this.setMsgSender(currentMessageSender);
|
|
610
|
+
this.setFunctionSelector(currentFunctionSelector);
|
|
611
|
+
|
|
612
|
+
return { endSideEffectCounter, returnsHash: publicInputs.returnsHash };
|
|
580
613
|
}
|
|
581
614
|
|
|
582
615
|
async getInitialWitness(abi: FunctionAbi, argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean) {
|
|
@@ -593,9 +626,12 @@ export class TXE implements TypedOracle {
|
|
|
593
626
|
sideEffectCounter,
|
|
594
627
|
isStaticCall,
|
|
595
628
|
);
|
|
629
|
+
const privateContextInputsAsFields = privateContextInputs.toFields();
|
|
630
|
+
if (privateContextInputsAsFields.length !== PRIVATE_CONTEXT_INPUTS_LENGTH) {
|
|
631
|
+
throw new Error('Invalid private context inputs size');
|
|
632
|
+
}
|
|
596
633
|
|
|
597
|
-
const fields = [...
|
|
598
|
-
|
|
634
|
+
const fields = [...privateContextInputsAsFields, ...args];
|
|
599
635
|
return toACVMWitness(0, fields);
|
|
600
636
|
}
|
|
601
637
|
|
|
@@ -619,11 +655,7 @@ export class TXE implements TypedOracle {
|
|
|
619
655
|
return `${artifact.name}:${f.name}`;
|
|
620
656
|
}
|
|
621
657
|
|
|
622
|
-
private async executePublicFunction(args: Fr[], callContext: CallContext
|
|
623
|
-
const executor = new PublicExecutor(
|
|
624
|
-
new TXEWorldStateDB(await this.trees.getLatest(), new TXEPublicContractDataSource(this)),
|
|
625
|
-
new NoopTelemetryClient(),
|
|
626
|
-
);
|
|
658
|
+
private async executePublicFunction(args: Fr[], callContext: CallContext) {
|
|
627
659
|
const execution = new PublicExecutionRequest(callContext, args);
|
|
628
660
|
|
|
629
661
|
const db = await this.trees.getLatest();
|
|
@@ -644,14 +676,16 @@ export class TXE implements TypedOracle {
|
|
|
644
676
|
combinedConstantData.txContext.chainId = this.chainId;
|
|
645
677
|
combinedConstantData.txContext.version = this.version;
|
|
646
678
|
|
|
647
|
-
const
|
|
679
|
+
const simulator = new PublicExecutor(
|
|
680
|
+
new TXEWorldStateDB(db, new TXEPublicContractDataSource(this)),
|
|
681
|
+
new NoopTelemetryClient(),
|
|
682
|
+
);
|
|
683
|
+
const executionResult = await simulator.simulateIsolatedEnqueuedCall(
|
|
648
684
|
execution,
|
|
649
|
-
combinedConstantData,
|
|
650
|
-
Gas
|
|
651
|
-
|
|
652
|
-
/*
|
|
653
|
-
/* transactionFee */ Fr.ONE,
|
|
654
|
-
counter,
|
|
685
|
+
combinedConstantData.globalVariables,
|
|
686
|
+
/*allocatedGas*/ new Gas(DEFAULT_GAS_LIMIT, MAX_L2_GAS_PER_ENQUEUED_CALL),
|
|
687
|
+
/*transactionFee=*/ Fr.ONE,
|
|
688
|
+
/*startSideEffectCounter=*/ this.sideEffectCounter,
|
|
655
689
|
);
|
|
656
690
|
return Promise.resolve(executionResult);
|
|
657
691
|
}
|
|
@@ -660,12 +694,12 @@ export class TXE implements TypedOracle {
|
|
|
660
694
|
targetContractAddress: AztecAddress,
|
|
661
695
|
functionSelector: FunctionSelector,
|
|
662
696
|
argsHash: Fr,
|
|
663
|
-
|
|
697
|
+
_sideEffectCounter: number,
|
|
664
698
|
isStaticCall: boolean,
|
|
665
699
|
): Promise<Fr> {
|
|
666
700
|
// Store and modify env
|
|
667
|
-
const currentContractAddress =
|
|
668
|
-
const currentMessageSender =
|
|
701
|
+
const currentContractAddress = this.contractAddress;
|
|
702
|
+
const currentMessageSender = this.msgSender;
|
|
669
703
|
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
670
704
|
this.setMsgSender(this.contractAddress);
|
|
671
705
|
this.setContractAddress(targetContractAddress);
|
|
@@ -681,7 +715,7 @@ export class TXE implements TypedOracle {
|
|
|
681
715
|
const args = [this.functionSelector.toField(), ...this.packedValuesCache.unpack(argsHash)];
|
|
682
716
|
const newArgsHash = this.packedValuesCache.pack(args);
|
|
683
717
|
|
|
684
|
-
const executionResult = await this.executePublicFunction(args, callContext
|
|
718
|
+
const executionResult = await this.executePublicFunction(args, callContext);
|
|
685
719
|
|
|
686
720
|
// Poor man's revert handling
|
|
687
721
|
if (executionResult.reverted) {
|
|
@@ -699,15 +733,13 @@ export class TXE implements TypedOracle {
|
|
|
699
733
|
}
|
|
700
734
|
|
|
701
735
|
// Apply side effects
|
|
702
|
-
this.
|
|
736
|
+
this.sideEffectCounter = executionResult.endSideEffectCounter.toNumber();
|
|
737
|
+
await this.addPublicDataWrites(executionResult.sideEffects.publicDataWrites);
|
|
703
738
|
await this.addNoteHashes(
|
|
704
739
|
targetContractAddress,
|
|
705
|
-
executionResult.noteHashes.map(noteHash => noteHash.value),
|
|
706
|
-
);
|
|
707
|
-
await this.addNullifiers(
|
|
708
|
-
targetContractAddress,
|
|
709
|
-
executionResult.nullifiers.map(nullifier => nullifier.value),
|
|
740
|
+
executionResult.sideEffects.noteHashes.map(noteHash => noteHash.value),
|
|
710
741
|
);
|
|
742
|
+
await this.addSiloedNullifiers(executionResult.sideEffects.nullifiers.map(nullifier => nullifier.value));
|
|
711
743
|
|
|
712
744
|
this.setContractAddress(currentContractAddress);
|
|
713
745
|
this.setMsgSender(currentMessageSender);
|
|
@@ -748,43 +780,45 @@ export class TXE implements TypedOracle {
|
|
|
748
780
|
_encryptedEvent: Buffer,
|
|
749
781
|
counter: number,
|
|
750
782
|
): void {
|
|
751
|
-
this.
|
|
783
|
+
this.sideEffectCounter = counter + 1;
|
|
752
784
|
return;
|
|
753
785
|
}
|
|
754
786
|
|
|
755
|
-
async
|
|
787
|
+
async incrementAppTaggingSecretIndexAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<void> {
|
|
788
|
+
const directionalSecret = await this.#calculateTaggingSecret(this.contractAddress, sender, recipient);
|
|
789
|
+
await this.txeDatabase.incrementTaggingSecretsIndexesAsSender([directionalSecret]);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
async getAppTaggingSecretAsSender(sender: AztecAddress, recipient: AztecAddress): Promise<IndexedTaggingSecret> {
|
|
793
|
+
const secret = await this.#calculateTaggingSecret(this.contractAddress, sender, recipient);
|
|
794
|
+
const [index] = await this.txeDatabase.getTaggingSecretsIndexesAsSender([secret]);
|
|
795
|
+
return new IndexedTaggingSecret(secret, index);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
async #calculateTaggingSecret(contractAddress: AztecAddress, sender: AztecAddress, recipient: AztecAddress) {
|
|
756
799
|
const senderCompleteAddress = await this.getCompleteAddress(sender);
|
|
757
800
|
const senderIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(sender);
|
|
758
801
|
const sharedSecret = computeTaggingSecret(senderCompleteAddress, senderIvsk, recipient);
|
|
759
802
|
// Silo the secret to the app so it can't be used to track other app's notes
|
|
760
|
-
const
|
|
761
|
-
|
|
762
|
-
return new IndexedTaggingSecret(secret, index);
|
|
803
|
+
const siloedSecret = poseidon2Hash([sharedSecret.x, sharedSecret.y, contractAddress]);
|
|
804
|
+
return siloedSecret;
|
|
763
805
|
}
|
|
764
806
|
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
// Filter out the addresses corresponding to accounts
|
|
769
|
-
const accounts = await this.keyStore.getAccounts();
|
|
770
|
-
const senders = completeAddresses.filter(
|
|
771
|
-
completeAddress => !accounts.find(account => account.equals(completeAddress.address)),
|
|
772
|
-
);
|
|
773
|
-
const recipientIvsk = await this.keyStore.getMasterIncomingViewingSecretKey(recipient);
|
|
774
|
-
const secrets = senders.map(({ address: sender }) => {
|
|
775
|
-
const sharedSecret = computeTaggingSecret(recipientCompleteAddress, recipientIvsk, sender);
|
|
776
|
-
return poseidon2Hash([sharedSecret.x, sharedSecret.y, this.contractAddress]);
|
|
777
|
-
});
|
|
778
|
-
const indexes = await this.txeDatabase.getTaggingSecretsIndexes(secrets);
|
|
779
|
-
return secrets.map((secret, i) => new IndexedTaggingSecret(secret, indexes[i]));
|
|
807
|
+
syncNotes() {
|
|
808
|
+
// TODO: Implement
|
|
809
|
+
return Promise.resolve();
|
|
780
810
|
}
|
|
781
811
|
|
|
782
812
|
// AVM oracles
|
|
783
813
|
|
|
784
|
-
async avmOpcodeCall(
|
|
814
|
+
async avmOpcodeCall(
|
|
815
|
+
targetContractAddress: AztecAddress,
|
|
816
|
+
args: Fr[],
|
|
817
|
+
isStaticCall: boolean,
|
|
818
|
+
): Promise<EnqueuedPublicCallExecutionResultWithSideEffects> {
|
|
785
819
|
// Store and modify env
|
|
786
|
-
const currentContractAddress =
|
|
787
|
-
const currentMessageSender =
|
|
820
|
+
const currentContractAddress = this.contractAddress;
|
|
821
|
+
const currentMessageSender = this.msgSender;
|
|
788
822
|
this.setMsgSender(this.contractAddress);
|
|
789
823
|
this.setContractAddress(targetContractAddress);
|
|
790
824
|
|
|
@@ -795,21 +829,19 @@ export class TXE implements TypedOracle {
|
|
|
795
829
|
isStaticCall,
|
|
796
830
|
);
|
|
797
831
|
|
|
798
|
-
const executionResult = await this.executePublicFunction(args, callContext
|
|
832
|
+
const executionResult = await this.executePublicFunction(args, callContext);
|
|
799
833
|
// Save return/revert data for later.
|
|
800
834
|
this.nestedCallReturndata = executionResult.returnValues;
|
|
801
835
|
|
|
802
836
|
// Apply side effects
|
|
803
837
|
if (!executionResult.reverted) {
|
|
804
|
-
this.
|
|
838
|
+
this.sideEffectCounter = executionResult.endSideEffectCounter.toNumber();
|
|
839
|
+
await this.addPublicDataWrites(executionResult.sideEffects.publicDataWrites);
|
|
805
840
|
await this.addNoteHashes(
|
|
806
841
|
targetContractAddress,
|
|
807
|
-
executionResult.noteHashes.map(noteHash => noteHash.value),
|
|
808
|
-
);
|
|
809
|
-
await this.addNullifiers(
|
|
810
|
-
targetContractAddress,
|
|
811
|
-
executionResult.nullifiers.map(nullifier => nullifier.value),
|
|
842
|
+
executionResult.sideEffects.noteHashes.map(noteHash => noteHash.value),
|
|
812
843
|
);
|
|
844
|
+
await this.addSiloedNullifiers(executionResult.sideEffects.nullifiers.map(nullifier => nullifier.value));
|
|
813
845
|
}
|
|
814
846
|
|
|
815
847
|
this.setContractAddress(currentContractAddress);
|