@aztec/txe 0.58.0 → 0.60.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/oracle/txe_oracle.d.ts +13 -15
- package/dest/oracle/txe_oracle.d.ts.map +1 -1
- package/dest/oracle/txe_oracle.js +95 -90
- package/dest/txe_service/txe_service.d.ts +50 -70
- package/dest/txe_service/txe_service.d.ts.map +1 -1
- package/dest/txe_service/txe_service.js +106 -118
- package/package.json +15 -15
- package/src/oracle/txe_oracle.ts +141 -139
- package/src/txe_service/txe_service.ts +148 -172
package/src/oracle/txe_oracle.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
PublicDataWitness,
|
|
8
8
|
PublicDataWrite,
|
|
9
9
|
PublicExecutionRequest,
|
|
10
|
+
SimulationError,
|
|
10
11
|
type UnencryptedL2Log,
|
|
11
12
|
} from '@aztec/circuit-types';
|
|
12
13
|
import { type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
|
|
@@ -46,7 +47,7 @@ import { Fr } from '@aztec/foundation/fields';
|
|
|
46
47
|
import { type Logger, applyStringFormatting } from '@aztec/foundation/log';
|
|
47
48
|
import { Timer } from '@aztec/foundation/timer';
|
|
48
49
|
import { type KeyStore } from '@aztec/key-store';
|
|
49
|
-
import { ContractDataOracle } from '@aztec/pxe';
|
|
50
|
+
import { ContractDataOracle, enrichPublicSimulationError } from '@aztec/pxe';
|
|
50
51
|
import {
|
|
51
52
|
ExecutionError,
|
|
52
53
|
type ExecutionNoteCache,
|
|
@@ -78,9 +79,6 @@ export class TXE implements TypedOracle {
|
|
|
78
79
|
private msgSender: AztecAddress;
|
|
79
80
|
private functionSelector = FunctionSelector.fromField(new Fr(0));
|
|
80
81
|
private isStaticCall = false;
|
|
81
|
-
// This will hold the _real_ calldata. That is, the one without the PublicContextInputs.
|
|
82
|
-
// TODO: Remove this comment once PublicContextInputs are removed.
|
|
83
|
-
private calldata: Fr[] = [];
|
|
84
82
|
|
|
85
83
|
private contractDataOracle: ContractDataOracle;
|
|
86
84
|
|
|
@@ -127,18 +125,10 @@ export class TXE implements TypedOracle {
|
|
|
127
125
|
return this.functionSelector;
|
|
128
126
|
}
|
|
129
127
|
|
|
130
|
-
getCalldata() {
|
|
131
|
-
return this.calldata;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
128
|
setMsgSender(msgSender: Fr) {
|
|
135
129
|
this.msgSender = msgSender;
|
|
136
130
|
}
|
|
137
131
|
|
|
138
|
-
setCalldata(calldata: Fr[]) {
|
|
139
|
-
this.calldata = calldata;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
132
|
setFunctionSelector(functionSelector: FunctionSelector) {
|
|
143
133
|
this.functionSelector = functionSelector;
|
|
144
134
|
}
|
|
@@ -188,48 +178,24 @@ export class TXE implements TypedOracle {
|
|
|
188
178
|
blockNumber: number,
|
|
189
179
|
sideEffectsCounter = this.sideEffectsCounter,
|
|
190
180
|
isStaticCall = false,
|
|
191
|
-
isDelegateCall = false,
|
|
192
181
|
) {
|
|
193
182
|
const db = await this.#getTreesAt(blockNumber);
|
|
194
183
|
const previousBlockState = await this.#getTreesAt(blockNumber - 1);
|
|
195
184
|
|
|
196
185
|
const stateReference = await db.getStateReference();
|
|
197
186
|
const inputs = PrivateContextInputs.empty();
|
|
187
|
+
inputs.txContext.chainId = this.chainId;
|
|
188
|
+
inputs.txContext.version = this.version;
|
|
198
189
|
inputs.historicalHeader.globalVariables.blockNumber = new Fr(blockNumber);
|
|
199
190
|
inputs.historicalHeader.state = stateReference;
|
|
200
191
|
inputs.historicalHeader.lastArchive.root = Fr.fromBuffer(
|
|
201
192
|
(await previousBlockState.getTreeInfo(MerkleTreeId.ARCHIVE)).root,
|
|
202
193
|
);
|
|
203
|
-
inputs.callContext.msgSender
|
|
204
|
-
inputs.callContext.storageContractAddress = this.contractAddress;
|
|
205
|
-
inputs.callContext.isStaticCall = isStaticCall;
|
|
206
|
-
inputs.callContext.isDelegateCall = isDelegateCall;
|
|
194
|
+
inputs.callContext = new CallContext(this.msgSender, this.contractAddress, this.functionSelector, isStaticCall);
|
|
207
195
|
inputs.startSideEffectCounter = sideEffectsCounter;
|
|
208
|
-
inputs.callContext.functionSelector = this.functionSelector;
|
|
209
196
|
return inputs;
|
|
210
197
|
}
|
|
211
198
|
|
|
212
|
-
async avmOpcodeNullifierExists(innerNullifier: Fr, targetAddress: AztecAddress): Promise<boolean> {
|
|
213
|
-
const nullifier = siloNullifier(targetAddress, innerNullifier!);
|
|
214
|
-
const db = await this.trees.getLatest();
|
|
215
|
-
const index = await db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
216
|
-
return index !== undefined;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
async avmOpcodeEmitNullifier(nullifier: Fr) {
|
|
220
|
-
const db = await this.trees.getLatest();
|
|
221
|
-
const siloedNullifier = siloNullifier(this.contractAddress, nullifier);
|
|
222
|
-
await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()], NULLIFIER_SUBTREE_HEIGHT);
|
|
223
|
-
return Promise.resolve();
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
async avmOpcodeEmitNoteHash(noteHash: Fr) {
|
|
227
|
-
const db = await this.trees.getLatest();
|
|
228
|
-
const siloedNoteHash = siloNoteHash(this.contractAddress, noteHash);
|
|
229
|
-
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [siloedNoteHash]);
|
|
230
|
-
return Promise.resolve();
|
|
231
|
-
}
|
|
232
|
-
|
|
233
199
|
deriveKeys(secret: Fr) {
|
|
234
200
|
return deriveKeys(secret);
|
|
235
201
|
}
|
|
@@ -468,24 +434,6 @@ export class TXE implements TypedOracle {
|
|
|
468
434
|
throw new Error('Method not implemented.');
|
|
469
435
|
}
|
|
470
436
|
|
|
471
|
-
async avmOpcodeStorageRead(slot: Fr) {
|
|
472
|
-
const db = await this.trees.getLatest();
|
|
473
|
-
|
|
474
|
-
const leafSlot = computePublicDataTreeLeafSlot(this.contractAddress, slot);
|
|
475
|
-
|
|
476
|
-
const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
477
|
-
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
|
|
478
|
-
return Fr.ZERO;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
const preimage = (await db.getLeafPreimage(
|
|
482
|
-
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
483
|
-
lowLeafResult.index,
|
|
484
|
-
)) as PublicDataTreeLeafPreimage;
|
|
485
|
-
|
|
486
|
-
return preimage.value;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
437
|
async storageRead(
|
|
490
438
|
contractAddress: Fr,
|
|
491
439
|
startStorageSlot: Fr,
|
|
@@ -555,13 +503,12 @@ export class TXE implements TypedOracle {
|
|
|
555
503
|
argsHash: Fr,
|
|
556
504
|
sideEffectCounter: number,
|
|
557
505
|
isStaticCall: boolean,
|
|
558
|
-
isDelegateCall: boolean,
|
|
559
506
|
) {
|
|
560
507
|
this.logger.verbose(
|
|
561
508
|
`Executing external function ${await this.getDebugFunctionName(
|
|
562
509
|
targetContractAddress,
|
|
563
510
|
functionSelector,
|
|
564
|
-
)}@${targetContractAddress} isStaticCall=${isStaticCall}
|
|
511
|
+
)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
565
512
|
);
|
|
566
513
|
|
|
567
514
|
// Store and modify env
|
|
@@ -575,13 +522,7 @@ export class TXE implements TypedOracle {
|
|
|
575
522
|
const artifact = await this.contractDataOracle.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
576
523
|
|
|
577
524
|
const acir = artifact.bytecode;
|
|
578
|
-
const initialWitness = await this.getInitialWitness(
|
|
579
|
-
artifact,
|
|
580
|
-
argsHash,
|
|
581
|
-
sideEffectCounter,
|
|
582
|
-
isStaticCall,
|
|
583
|
-
isDelegateCall,
|
|
584
|
-
);
|
|
525
|
+
const initialWitness = await this.getInitialWitness(artifact, argsHash, sideEffectCounter, isStaticCall);
|
|
585
526
|
const acvmCallback = new Oracle(this);
|
|
586
527
|
const timer = new Timer();
|
|
587
528
|
try {
|
|
@@ -633,13 +574,7 @@ export class TXE implements TypedOracle {
|
|
|
633
574
|
}
|
|
634
575
|
}
|
|
635
576
|
|
|
636
|
-
async getInitialWitness(
|
|
637
|
-
abi: FunctionAbi,
|
|
638
|
-
argsHash: Fr,
|
|
639
|
-
sideEffectCounter: number,
|
|
640
|
-
isStaticCall: boolean,
|
|
641
|
-
isDelegateCall: boolean,
|
|
642
|
-
) {
|
|
577
|
+
async getInitialWitness(abi: FunctionAbi, argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean) {
|
|
643
578
|
const argumentsSize = countArgumentsSize(abi);
|
|
644
579
|
|
|
645
580
|
const args = this.packedValuesCache.unpack(argsHash);
|
|
@@ -652,7 +587,6 @@ export class TXE implements TypedOracle {
|
|
|
652
587
|
this.blockNumber - 1,
|
|
653
588
|
sideEffectCounter,
|
|
654
589
|
isStaticCall,
|
|
655
|
-
isDelegateCall,
|
|
656
590
|
);
|
|
657
591
|
|
|
658
592
|
const fields = [...privateContextInputs.toFields(), ...args];
|
|
@@ -680,21 +614,34 @@ export class TXE implements TypedOracle {
|
|
|
680
614
|
return `${artifact.name}:${f.name}`;
|
|
681
615
|
}
|
|
682
616
|
|
|
683
|
-
async executePublicFunction(
|
|
684
|
-
targetContractAddress: AztecAddress,
|
|
685
|
-
args: Fr[],
|
|
686
|
-
callContext: CallContext,
|
|
687
|
-
counter: number,
|
|
688
|
-
) {
|
|
617
|
+
private async executePublicFunction(args: Fr[], callContext: CallContext, counter: number) {
|
|
689
618
|
const executor = new PublicExecutor(
|
|
690
619
|
new TXEWorldStateDB(await this.trees.getLatest(), new TXEPublicContractDataSource(this)),
|
|
691
620
|
new NoopTelemetryClient(),
|
|
692
621
|
);
|
|
693
|
-
const execution = new PublicExecutionRequest(
|
|
622
|
+
const execution = new PublicExecutionRequest(callContext, args);
|
|
623
|
+
|
|
624
|
+
const db = await this.trees.getLatest();
|
|
625
|
+
const previousBlockState = await this.#getTreesAt(this.blockNumber - 1);
|
|
626
|
+
|
|
627
|
+
const combinedConstantData = CombinedConstantData.empty();
|
|
628
|
+
combinedConstantData.globalVariables.chainId = this.chainId;
|
|
629
|
+
combinedConstantData.globalVariables.version = this.version;
|
|
630
|
+
combinedConstantData.globalVariables.blockNumber = new Fr(this.blockNumber);
|
|
631
|
+
combinedConstantData.historicalHeader.globalVariables.chainId = this.chainId;
|
|
632
|
+
combinedConstantData.historicalHeader.globalVariables.version = this.version;
|
|
633
|
+
combinedConstantData.historicalHeader.globalVariables.blockNumber = new Fr(this.blockNumber - 1);
|
|
634
|
+
combinedConstantData.historicalHeader.state = await db.getStateReference();
|
|
635
|
+
combinedConstantData.historicalHeader.lastArchive.root = Fr.fromBuffer(
|
|
636
|
+
(await previousBlockState.getTreeInfo(MerkleTreeId.ARCHIVE)).root,
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
combinedConstantData.txContext.chainId = this.chainId;
|
|
640
|
+
combinedConstantData.txContext.version = this.version;
|
|
694
641
|
|
|
695
642
|
const executionResult = executor.simulate(
|
|
696
643
|
execution,
|
|
697
|
-
|
|
644
|
+
combinedConstantData,
|
|
698
645
|
Gas.test(),
|
|
699
646
|
TxContext.empty(),
|
|
700
647
|
/* pendingNullifiers */ [],
|
|
@@ -704,54 +651,12 @@ export class TXE implements TypedOracle {
|
|
|
704
651
|
return Promise.resolve(executionResult);
|
|
705
652
|
}
|
|
706
653
|
|
|
707
|
-
async avmOpcodeCall(
|
|
708
|
-
targetContractAddress: AztecAddress,
|
|
709
|
-
functionSelector: FunctionSelector,
|
|
710
|
-
args: Fr[],
|
|
711
|
-
isStaticCall: boolean,
|
|
712
|
-
isDelegateCall: boolean,
|
|
713
|
-
) {
|
|
714
|
-
// Store and modify env
|
|
715
|
-
const currentContractAddress = AztecAddress.fromField(this.contractAddress);
|
|
716
|
-
const currentMessageSender = AztecAddress.fromField(this.msgSender);
|
|
717
|
-
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
718
|
-
this.setMsgSender(this.contractAddress);
|
|
719
|
-
this.setContractAddress(targetContractAddress);
|
|
720
|
-
this.setFunctionSelector(functionSelector);
|
|
721
|
-
this.setCalldata(args);
|
|
722
|
-
|
|
723
|
-
const callContext = CallContext.empty();
|
|
724
|
-
callContext.msgSender = this.msgSender;
|
|
725
|
-
callContext.functionSelector = this.functionSelector;
|
|
726
|
-
callContext.storageContractAddress = targetContractAddress;
|
|
727
|
-
callContext.isStaticCall = isStaticCall;
|
|
728
|
-
callContext.isDelegateCall = isDelegateCall;
|
|
729
|
-
|
|
730
|
-
const executionResult = await this.executePublicFunction(
|
|
731
|
-
targetContractAddress,
|
|
732
|
-
args,
|
|
733
|
-
callContext,
|
|
734
|
-
this.sideEffectsCounter,
|
|
735
|
-
);
|
|
736
|
-
|
|
737
|
-
// Apply side effects
|
|
738
|
-
if (!executionResult.reverted) {
|
|
739
|
-
this.sideEffectsCounter = executionResult.endSideEffectCounter.toNumber() + 1;
|
|
740
|
-
}
|
|
741
|
-
this.setContractAddress(currentContractAddress);
|
|
742
|
-
this.setMsgSender(currentMessageSender);
|
|
743
|
-
this.setFunctionSelector(currentFunctionSelector);
|
|
744
|
-
|
|
745
|
-
return executionResult;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
654
|
async enqueuePublicFunctionCall(
|
|
749
655
|
targetContractAddress: AztecAddress,
|
|
750
656
|
functionSelector: FunctionSelector,
|
|
751
657
|
argsHash: Fr,
|
|
752
658
|
sideEffectCounter: number,
|
|
753
659
|
isStaticCall: boolean,
|
|
754
|
-
isDelegateCall: boolean,
|
|
755
660
|
): Promise<Fr> {
|
|
756
661
|
// Store and modify env
|
|
757
662
|
const currentContractAddress = AztecAddress.fromField(this.contractAddress);
|
|
@@ -761,29 +666,44 @@ export class TXE implements TypedOracle {
|
|
|
761
666
|
this.setContractAddress(targetContractAddress);
|
|
762
667
|
this.setFunctionSelector(functionSelector);
|
|
763
668
|
|
|
764
|
-
const callContext = CallContext
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
669
|
+
const callContext = new CallContext(
|
|
670
|
+
/* msgSender */ currentContractAddress,
|
|
671
|
+
targetContractAddress,
|
|
672
|
+
FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)),
|
|
673
|
+
isStaticCall,
|
|
674
|
+
);
|
|
770
675
|
|
|
771
676
|
const args = [this.functionSelector.toField(), ...this.packedValuesCache.unpack(argsHash)];
|
|
772
677
|
const newArgsHash = this.packedValuesCache.pack(args);
|
|
773
678
|
|
|
774
|
-
const executionResult = await this.executePublicFunction(
|
|
775
|
-
targetContractAddress,
|
|
776
|
-
args,
|
|
777
|
-
callContext,
|
|
778
|
-
sideEffectCounter,
|
|
779
|
-
);
|
|
679
|
+
const executionResult = await this.executePublicFunction(args, callContext, sideEffectCounter);
|
|
780
680
|
|
|
681
|
+
// Poor man's revert handling
|
|
781
682
|
if (executionResult.reverted) {
|
|
782
|
-
|
|
683
|
+
if (executionResult.revertReason && executionResult.revertReason instanceof SimulationError) {
|
|
684
|
+
await enrichPublicSimulationError(
|
|
685
|
+
executionResult.revertReason,
|
|
686
|
+
this.contractDataOracle,
|
|
687
|
+
this.txeDatabase,
|
|
688
|
+
this.logger,
|
|
689
|
+
);
|
|
690
|
+
throw new Error(executionResult.revertReason.message);
|
|
691
|
+
} else {
|
|
692
|
+
throw new Error(`Enqueued public function call reverted: ${executionResult.revertReason}`);
|
|
693
|
+
}
|
|
783
694
|
}
|
|
784
695
|
|
|
785
696
|
// Apply side effects
|
|
786
697
|
this.sideEffectsCounter = executionResult.endSideEffectCounter.toNumber() + 1;
|
|
698
|
+
await this.addNoteHashes(
|
|
699
|
+
targetContractAddress,
|
|
700
|
+
executionResult.noteHashes.map(noteHash => noteHash.value),
|
|
701
|
+
);
|
|
702
|
+
await this.addNullifiers(
|
|
703
|
+
targetContractAddress,
|
|
704
|
+
executionResult.nullifiers.map(nullifier => nullifier.value),
|
|
705
|
+
);
|
|
706
|
+
|
|
787
707
|
this.setContractAddress(currentContractAddress);
|
|
788
708
|
this.setMsgSender(currentMessageSender);
|
|
789
709
|
this.setFunctionSelector(currentFunctionSelector);
|
|
@@ -797,7 +717,6 @@ export class TXE implements TypedOracle {
|
|
|
797
717
|
argsHash: Fr,
|
|
798
718
|
sideEffectCounter: number,
|
|
799
719
|
isStaticCall: boolean,
|
|
800
|
-
isDelegateCall: boolean,
|
|
801
720
|
): Promise<Fr> {
|
|
802
721
|
// Definitely not right, in that the teardown should always be last.
|
|
803
722
|
// But useful for executing flows.
|
|
@@ -807,7 +726,6 @@ export class TXE implements TypedOracle {
|
|
|
807
726
|
argsHash,
|
|
808
727
|
sideEffectCounter,
|
|
809
728
|
isStaticCall,
|
|
810
|
-
isDelegateCall,
|
|
811
729
|
);
|
|
812
730
|
}
|
|
813
731
|
|
|
@@ -828,4 +746,88 @@ export class TXE implements TypedOracle {
|
|
|
828
746
|
this.sideEffectsCounter = counter + 1;
|
|
829
747
|
return;
|
|
830
748
|
}
|
|
749
|
+
|
|
750
|
+
// AVM oracles
|
|
751
|
+
|
|
752
|
+
async avmOpcodeCall(
|
|
753
|
+
targetContractAddress: AztecAddress,
|
|
754
|
+
functionSelector: FunctionSelector,
|
|
755
|
+
args: Fr[],
|
|
756
|
+
isStaticCall: boolean,
|
|
757
|
+
) {
|
|
758
|
+
// Store and modify env
|
|
759
|
+
const currentContractAddress = AztecAddress.fromField(this.contractAddress);
|
|
760
|
+
const currentMessageSender = AztecAddress.fromField(this.msgSender);
|
|
761
|
+
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
762
|
+
this.setMsgSender(this.contractAddress);
|
|
763
|
+
this.setContractAddress(targetContractAddress);
|
|
764
|
+
this.setFunctionSelector(functionSelector);
|
|
765
|
+
|
|
766
|
+
const callContext = new CallContext(
|
|
767
|
+
/* msgSender */ currentContractAddress,
|
|
768
|
+
targetContractAddress,
|
|
769
|
+
functionSelector,
|
|
770
|
+
isStaticCall,
|
|
771
|
+
);
|
|
772
|
+
|
|
773
|
+
const executionResult = await this.executePublicFunction(args, callContext, this.sideEffectsCounter);
|
|
774
|
+
|
|
775
|
+
// Apply side effects
|
|
776
|
+
if (!executionResult.reverted) {
|
|
777
|
+
this.sideEffectsCounter = executionResult.endSideEffectCounter.toNumber() + 1;
|
|
778
|
+
await this.addNoteHashes(
|
|
779
|
+
targetContractAddress,
|
|
780
|
+
executionResult.noteHashes.map(noteHash => noteHash.value),
|
|
781
|
+
);
|
|
782
|
+
await this.addNullifiers(
|
|
783
|
+
targetContractAddress,
|
|
784
|
+
executionResult.nullifiers.map(nullifier => nullifier.value),
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
this.setContractAddress(currentContractAddress);
|
|
789
|
+
this.setMsgSender(currentMessageSender);
|
|
790
|
+
this.setFunctionSelector(currentFunctionSelector);
|
|
791
|
+
|
|
792
|
+
return executionResult;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
async avmOpcodeNullifierExists(innerNullifier: Fr, targetAddress: AztecAddress): Promise<boolean> {
|
|
796
|
+
const nullifier = siloNullifier(targetAddress, innerNullifier!);
|
|
797
|
+
const db = await this.trees.getLatest();
|
|
798
|
+
const index = await db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
799
|
+
return index !== undefined;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
async avmOpcodeEmitNullifier(nullifier: Fr) {
|
|
803
|
+
const db = await this.trees.getLatest();
|
|
804
|
+
const siloedNullifier = siloNullifier(this.contractAddress, nullifier);
|
|
805
|
+
await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()], NULLIFIER_SUBTREE_HEIGHT);
|
|
806
|
+
return Promise.resolve();
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
async avmOpcodeEmitNoteHash(noteHash: Fr) {
|
|
810
|
+
const db = await this.trees.getLatest();
|
|
811
|
+
const siloedNoteHash = siloNoteHash(this.contractAddress, noteHash);
|
|
812
|
+
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [siloedNoteHash]);
|
|
813
|
+
return Promise.resolve();
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
async avmOpcodeStorageRead(slot: Fr) {
|
|
817
|
+
const db = await this.trees.getLatest();
|
|
818
|
+
|
|
819
|
+
const leafSlot = computePublicDataTreeLeafSlot(this.contractAddress, slot);
|
|
820
|
+
|
|
821
|
+
const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
822
|
+
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
|
|
823
|
+
return Fr.ZERO;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
const preimage = (await db.getLeafPreimage(
|
|
827
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
828
|
+
lowLeafResult.index,
|
|
829
|
+
)) as PublicDataTreeLeafPreimage;
|
|
830
|
+
|
|
831
|
+
return preimage.value;
|
|
832
|
+
}
|
|
831
833
|
}
|