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