@aztec/txe 0.47.1 → 0.49.2
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 +14 -13
- package/dest/oracle/txe_oracle.d.ts.map +1 -1
- package/dest/oracle/txe_oracle.js +70 -64
- package/dest/txe_service/txe_service.d.ts +10 -3
- package/dest/txe_service/txe_service.d.ts.map +1 -1
- package/dest/txe_service/txe_service.js +36 -15
- package/package.json +15 -14
- package/src/oracle/txe_oracle.ts +86 -83
- package/src/txe_service/txe_service.ts +40 -14
package/src/oracle/txe_oracle.ts
CHANGED
|
@@ -68,6 +68,7 @@ import {
|
|
|
68
68
|
toACVMWitness,
|
|
69
69
|
witnessMapToFields,
|
|
70
70
|
} from '@aztec/simulator';
|
|
71
|
+
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
71
72
|
import { type ContractInstance, type ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
72
73
|
import { MerkleTreeSnapshotOperationsFacade, type MerkleTrees } from '@aztec/world-state';
|
|
73
74
|
|
|
@@ -103,6 +104,14 @@ export class TXE implements TypedOracle {
|
|
|
103
104
|
|
|
104
105
|
// Utils
|
|
105
106
|
|
|
107
|
+
async #getTreesAt(blockNumber: number) {
|
|
108
|
+
const db =
|
|
109
|
+
blockNumber === (await this.getBlockNumber())
|
|
110
|
+
? this.trees.asLatest()
|
|
111
|
+
: new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);
|
|
112
|
+
return db;
|
|
113
|
+
}
|
|
114
|
+
|
|
106
115
|
getChainId() {
|
|
107
116
|
return Promise.resolve(this.chainId);
|
|
108
117
|
}
|
|
@@ -174,11 +183,16 @@ export class TXE implements TypedOracle {
|
|
|
174
183
|
isStaticCall = false,
|
|
175
184
|
isDelegateCall = false,
|
|
176
185
|
) {
|
|
177
|
-
const
|
|
178
|
-
const
|
|
186
|
+
const db = await this.#getTreesAt(blockNumber);
|
|
187
|
+
const previousBlockState = await this.#getTreesAt(blockNumber - 1);
|
|
188
|
+
|
|
189
|
+
const stateReference = await db.getStateReference();
|
|
179
190
|
const inputs = PrivateContextInputs.empty();
|
|
180
191
|
inputs.historicalHeader.globalVariables.blockNumber = new Fr(blockNumber);
|
|
181
192
|
inputs.historicalHeader.state = stateReference;
|
|
193
|
+
inputs.historicalHeader.lastArchive.root = Fr.fromBuffer(
|
|
194
|
+
(await previousBlockState.getTreeInfo(MerkleTreeId.ARCHIVE)).root,
|
|
195
|
+
);
|
|
182
196
|
inputs.callContext.msgSender = this.msgSender;
|
|
183
197
|
inputs.callContext.storageContractAddress = this.contractAddress;
|
|
184
198
|
inputs.callContext.isStaticCall = isStaticCall;
|
|
@@ -213,10 +227,10 @@ export class TXE implements TypedOracle {
|
|
|
213
227
|
return Promise.resolve();
|
|
214
228
|
}
|
|
215
229
|
|
|
216
|
-
async avmOpcodeEmitNoteHash(
|
|
230
|
+
async avmOpcodeEmitNoteHash(noteHash: Fr) {
|
|
217
231
|
const db = this.trees.asLatest();
|
|
218
|
-
const
|
|
219
|
-
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [
|
|
232
|
+
const siloedNoteHash = siloNoteHash(this.contractAddress, noteHash);
|
|
233
|
+
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [siloedNoteHash]);
|
|
220
234
|
return Promise.resolve();
|
|
221
235
|
}
|
|
222
236
|
|
|
@@ -240,9 +254,9 @@ export class TXE implements TypedOracle {
|
|
|
240
254
|
await db.batchInsert(MerkleTreeId.NULLIFIER_TREE, siloedNullifiers, NULLIFIER_SUBTREE_HEIGHT);
|
|
241
255
|
}
|
|
242
256
|
|
|
243
|
-
async addNoteHashes(contractAddress: AztecAddress,
|
|
257
|
+
async addNoteHashes(contractAddress: AztecAddress, noteHashes: Fr[]) {
|
|
244
258
|
const db = this.trees.asLatest();
|
|
245
|
-
const siloedNoteHashes =
|
|
259
|
+
const siloedNoteHashes = noteHashes.map(noteHash => siloNoteHash(contractAddress, noteHash));
|
|
246
260
|
await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, siloedNoteHashes);
|
|
247
261
|
}
|
|
248
262
|
|
|
@@ -284,8 +298,14 @@ export class TXE implements TypedOracle {
|
|
|
284
298
|
return contractInstance;
|
|
285
299
|
}
|
|
286
300
|
|
|
287
|
-
getMembershipWitness(
|
|
288
|
-
|
|
301
|
+
async getMembershipWitness(blockNumber: number, treeId: MerkleTreeId, leafValue: Fr): Promise<Fr[] | undefined> {
|
|
302
|
+
const db = await this.#getTreesAt(blockNumber);
|
|
303
|
+
const index = await db.findLeafIndex(treeId, leafValue.toBuffer());
|
|
304
|
+
if (!index) {
|
|
305
|
+
throw new Error(`Leaf value: ${leafValue} not found in ${MerkleTreeId[treeId]} at block ${blockNumber}`);
|
|
306
|
+
}
|
|
307
|
+
const siblingPath = await db.getSiblingPath(treeId, index);
|
|
308
|
+
return [new Fr(index), ...siblingPath.toFields()];
|
|
289
309
|
}
|
|
290
310
|
|
|
291
311
|
async getSiblingPath(blockNumber: number, treeId: MerkleTreeId, leafIndex: Fr) {
|
|
@@ -298,14 +318,14 @@ export class TXE implements TypedOracle {
|
|
|
298
318
|
blockNumber: number,
|
|
299
319
|
nullifier: Fr,
|
|
300
320
|
): Promise<NullifierMembershipWitness | undefined> {
|
|
301
|
-
const
|
|
302
|
-
const index = await
|
|
321
|
+
const db = await this.#getTreesAt(blockNumber);
|
|
322
|
+
const index = await db.findLeafIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBuffer());
|
|
303
323
|
if (!index) {
|
|
304
324
|
return undefined;
|
|
305
325
|
}
|
|
306
326
|
|
|
307
|
-
const leafPreimagePromise =
|
|
308
|
-
const siblingPathPromise =
|
|
327
|
+
const leafPreimagePromise = db.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, index);
|
|
328
|
+
const siblingPathPromise = db.getSiblingPath<typeof NULLIFIER_TREE_HEIGHT>(
|
|
309
329
|
MerkleTreeId.NULLIFIER_TREE,
|
|
310
330
|
BigInt(index),
|
|
311
331
|
);
|
|
@@ -344,8 +364,12 @@ export class TXE implements TypedOracle {
|
|
|
344
364
|
throw new Error('Method not implemented.');
|
|
345
365
|
}
|
|
346
366
|
|
|
347
|
-
getHeader(
|
|
348
|
-
|
|
367
|
+
async getHeader(blockNumber: number): Promise<Header | undefined> {
|
|
368
|
+
const header = Header.empty();
|
|
369
|
+
const db = await this.#getTreesAt(blockNumber);
|
|
370
|
+
header.state = await db.getStateReference();
|
|
371
|
+
header.globalVariables.blockNumber = new Fr(blockNumber);
|
|
372
|
+
return header;
|
|
349
373
|
}
|
|
350
374
|
|
|
351
375
|
getCompleteAddress(account: AztecAddress) {
|
|
@@ -402,7 +426,7 @@ export class TXE implements TypedOracle {
|
|
|
402
426
|
return Promise.resolve(notes);
|
|
403
427
|
}
|
|
404
428
|
|
|
405
|
-
notifyCreatedNote(storageSlot: Fr, noteTypeId: NoteSelector, noteItems: Fr[],
|
|
429
|
+
notifyCreatedNote(storageSlot: Fr, noteTypeId: NoteSelector, noteItems: Fr[], noteHash: Fr, counter: number) {
|
|
406
430
|
const note = new Note(noteItems);
|
|
407
431
|
this.noteCache.addNewNote(
|
|
408
432
|
{
|
|
@@ -411,15 +435,17 @@ export class TXE implements TypedOracle {
|
|
|
411
435
|
nonce: Fr.ZERO, // Nonce cannot be known during private execution.
|
|
412
436
|
note,
|
|
413
437
|
siloedNullifier: undefined, // Siloed nullifier cannot be known for newly created note.
|
|
414
|
-
|
|
438
|
+
noteHash,
|
|
415
439
|
},
|
|
416
440
|
counter,
|
|
417
441
|
);
|
|
442
|
+
this.sideEffectsCounter = counter + 1;
|
|
418
443
|
return Promise.resolve();
|
|
419
444
|
}
|
|
420
445
|
|
|
421
|
-
notifyNullifiedNote(innerNullifier: Fr,
|
|
422
|
-
this.noteCache.nullifyNote(this.contractAddress, innerNullifier,
|
|
446
|
+
notifyNullifiedNote(innerNullifier: Fr, noteHash: Fr, counter: number) {
|
|
447
|
+
this.noteCache.nullifyNote(this.contractAddress, innerNullifier, noteHash);
|
|
448
|
+
this.sideEffectsCounter = counter + 1;
|
|
423
449
|
return Promise.resolve();
|
|
424
450
|
}
|
|
425
451
|
|
|
@@ -468,11 +494,7 @@ export class TXE implements TypedOracle {
|
|
|
468
494
|
blockNumber: number,
|
|
469
495
|
numberOfElements: number,
|
|
470
496
|
): Promise<Fr[]> {
|
|
471
|
-
const db =
|
|
472
|
-
blockNumber === (await this.getBlockNumber())
|
|
473
|
-
? this.trees.asLatest()
|
|
474
|
-
: new MerkleTreeSnapshotOperationsFacade(this.trees, blockNumber);
|
|
475
|
-
|
|
497
|
+
const db = await this.#getTreesAt(blockNumber);
|
|
476
498
|
const values = [];
|
|
477
499
|
for (let i = 0n; i < numberOfElements; i++) {
|
|
478
500
|
const storageSlot = startStorageSlot.add(new Fr(i));
|
|
@@ -510,11 +532,13 @@ export class TXE implements TypedOracle {
|
|
|
510
532
|
return publicDataWrites.map(write => write.newValue);
|
|
511
533
|
}
|
|
512
534
|
|
|
513
|
-
emitEncryptedLog(_contractAddress: AztecAddress, _randomness: Fr, _encryptedNote: Buffer,
|
|
535
|
+
emitEncryptedLog(_contractAddress: AztecAddress, _randomness: Fr, _encryptedNote: Buffer, counter: number): void {
|
|
536
|
+
this.sideEffectsCounter = counter + 1;
|
|
514
537
|
return;
|
|
515
538
|
}
|
|
516
539
|
|
|
517
|
-
emitEncryptedNoteLog(_noteHashCounter: number, _encryptedNote: Buffer,
|
|
540
|
+
emitEncryptedNoteLog(_noteHashCounter: number, _encryptedNote: Buffer, counter: number): void {
|
|
541
|
+
this.sideEffectsCounter = counter + 1;
|
|
518
542
|
return;
|
|
519
543
|
}
|
|
520
544
|
|
|
@@ -536,7 +560,8 @@ export class TXE implements TypedOracle {
|
|
|
536
560
|
return taggedNote.encrypt(ephSk, recipient, ivpkM, ovKeys);
|
|
537
561
|
}
|
|
538
562
|
|
|
539
|
-
emitUnencryptedLog(_log: UnencryptedL2Log,
|
|
563
|
+
emitUnencryptedLog(_log: UnencryptedL2Log, counter: number): void {
|
|
564
|
+
this.sideEffectsCounter = counter + 1;
|
|
540
565
|
return;
|
|
541
566
|
}
|
|
542
567
|
|
|
@@ -609,7 +634,7 @@ export class TXE implements TypedOracle {
|
|
|
609
634
|
|
|
610
635
|
// Apply side effects
|
|
611
636
|
const endSideEffectCounter = publicInputs.endSideEffectCounter;
|
|
612
|
-
this.sideEffectsCounter = endSideEffectCounter.toNumber();
|
|
637
|
+
this.sideEffectsCounter = endSideEffectCounter.toNumber() + 1;
|
|
613
638
|
|
|
614
639
|
await this.addNullifiers(
|
|
615
640
|
targetContractAddress,
|
|
@@ -676,27 +701,21 @@ export class TXE implements TypedOracle {
|
|
|
676
701
|
return `${artifact.name}:${f.name}`;
|
|
677
702
|
}
|
|
678
703
|
|
|
679
|
-
async executePublicFunction(
|
|
704
|
+
async executePublicFunction(
|
|
705
|
+
targetContractAddress: AztecAddress,
|
|
706
|
+
args: Fr[],
|
|
707
|
+
callContext: CallContext,
|
|
708
|
+
counter: number,
|
|
709
|
+
) {
|
|
680
710
|
const header = Header.empty();
|
|
681
711
|
header.state = await this.trees.getStateReference(true);
|
|
682
712
|
header.globalVariables.blockNumber = new Fr(await this.getBlockNumber());
|
|
683
|
-
header.state.partial.nullifierTree.root = Fr.fromBuffer(
|
|
684
|
-
(await this.trees.getTreeInfo(MerkleTreeId.NULLIFIER_TREE, true)).root,
|
|
685
|
-
);
|
|
686
|
-
header.state.partial.noteHashTree.root = Fr.fromBuffer(
|
|
687
|
-
(await this.trees.getTreeInfo(MerkleTreeId.NOTE_HASH_TREE, true)).root,
|
|
688
|
-
);
|
|
689
|
-
header.state.partial.publicDataTree.root = Fr.fromBuffer(
|
|
690
|
-
(await this.trees.getTreeInfo(MerkleTreeId.PUBLIC_DATA_TREE, true)).root,
|
|
691
|
-
);
|
|
692
|
-
header.state.l1ToL2MessageTree.root = Fr.fromBuffer(
|
|
693
|
-
(await this.trees.getTreeInfo(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, true)).root,
|
|
694
|
-
);
|
|
695
713
|
const executor = new PublicExecutor(
|
|
696
714
|
new TXEPublicStateDB(this),
|
|
697
715
|
new ContractsDataSourcePublicDB(new TXEPublicContractDataSource(this)),
|
|
698
716
|
new WorldStateDB(this.trees.asLatest()),
|
|
699
717
|
header,
|
|
718
|
+
new NoopTelemetryClient(),
|
|
700
719
|
);
|
|
701
720
|
const execution = new PublicExecutionRequest(targetContractAddress, callContext, args);
|
|
702
721
|
|
|
@@ -707,6 +726,7 @@ export class TXE implements TypedOracle {
|
|
|
707
726
|
TxContext.empty(),
|
|
708
727
|
/* pendingNullifiers */ [],
|
|
709
728
|
/* transactionFee */ Fr.ONE,
|
|
729
|
+
counter,
|
|
710
730
|
);
|
|
711
731
|
}
|
|
712
732
|
|
|
@@ -732,11 +752,16 @@ export class TXE implements TypedOracle {
|
|
|
732
752
|
callContext.isStaticCall = isStaticCall;
|
|
733
753
|
callContext.isDelegateCall = isDelegateCall;
|
|
734
754
|
|
|
735
|
-
const executionResult = await this.executePublicFunction(
|
|
755
|
+
const executionResult = await this.executePublicFunction(
|
|
756
|
+
targetContractAddress,
|
|
757
|
+
args,
|
|
758
|
+
callContext,
|
|
759
|
+
this.sideEffectsCounter,
|
|
760
|
+
);
|
|
736
761
|
|
|
737
762
|
// Apply side effects
|
|
738
763
|
if (!executionResult.reverted) {
|
|
739
|
-
this.sideEffectsCounter
|
|
764
|
+
this.sideEffectsCounter = executionResult.endSideEffectCounter.toNumber() + 1;
|
|
740
765
|
}
|
|
741
766
|
this.setContractAddress(currentContractAddress);
|
|
742
767
|
this.setMsgSender(currentMessageSender);
|
|
@@ -745,47 +770,11 @@ export class TXE implements TypedOracle {
|
|
|
745
770
|
return executionResult;
|
|
746
771
|
}
|
|
747
772
|
|
|
748
|
-
async callPublicFunction(
|
|
749
|
-
targetContractAddress: AztecAddress,
|
|
750
|
-
functionSelector: FunctionSelector,
|
|
751
|
-
argsHash: Fr,
|
|
752
|
-
_sideEffectCounter: number,
|
|
753
|
-
isStaticCall: boolean,
|
|
754
|
-
isDelegateCall: boolean,
|
|
755
|
-
): Promise<Fr[]> {
|
|
756
|
-
// Store and modify env
|
|
757
|
-
const currentContractAddress = AztecAddress.fromField(this.contractAddress);
|
|
758
|
-
const currentMessageSender = AztecAddress.fromField(this.msgSender);
|
|
759
|
-
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
760
|
-
this.setMsgSender(this.contractAddress);
|
|
761
|
-
this.setContractAddress(targetContractAddress);
|
|
762
|
-
this.setFunctionSelector(functionSelector);
|
|
763
|
-
|
|
764
|
-
const callContext = CallContext.empty();
|
|
765
|
-
callContext.msgSender = this.msgSender;
|
|
766
|
-
callContext.functionSelector = this.functionSelector;
|
|
767
|
-
callContext.storageContractAddress = targetContractAddress;
|
|
768
|
-
callContext.isStaticCall = isStaticCall;
|
|
769
|
-
callContext.isDelegateCall = isDelegateCall;
|
|
770
|
-
|
|
771
|
-
const args = this.packedValuesCache.unpack(argsHash);
|
|
772
|
-
|
|
773
|
-
const executionResult = await this.executePublicFunction(targetContractAddress, args, callContext);
|
|
774
|
-
|
|
775
|
-
// Apply side effects
|
|
776
|
-
this.sideEffectsCounter = executionResult.endSideEffectCounter.toNumber();
|
|
777
|
-
this.setContractAddress(currentContractAddress);
|
|
778
|
-
this.setMsgSender(currentMessageSender);
|
|
779
|
-
this.setFunctionSelector(currentFunctionSelector);
|
|
780
|
-
|
|
781
|
-
return executionResult.returnValues;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
773
|
async enqueuePublicFunctionCall(
|
|
785
774
|
targetContractAddress: AztecAddress,
|
|
786
775
|
functionSelector: FunctionSelector,
|
|
787
776
|
argsHash: Fr,
|
|
788
|
-
|
|
777
|
+
sideEffectCounter: number,
|
|
789
778
|
isStaticCall: boolean,
|
|
790
779
|
isDelegateCall: boolean,
|
|
791
780
|
) {
|
|
@@ -806,10 +795,19 @@ export class TXE implements TypedOracle {
|
|
|
806
795
|
|
|
807
796
|
const args = this.packedValuesCache.unpack(argsHash);
|
|
808
797
|
|
|
809
|
-
const executionResult = await this.executePublicFunction(
|
|
798
|
+
const executionResult = await this.executePublicFunction(
|
|
799
|
+
targetContractAddress,
|
|
800
|
+
args,
|
|
801
|
+
callContext,
|
|
802
|
+
sideEffectCounter,
|
|
803
|
+
);
|
|
804
|
+
|
|
805
|
+
if (executionResult.reverted) {
|
|
806
|
+
throw new Error(`Execution reverted with reason: ${executionResult.revertReason}`);
|
|
807
|
+
}
|
|
810
808
|
|
|
811
809
|
// Apply side effects
|
|
812
|
-
this.sideEffectsCounter
|
|
810
|
+
this.sideEffectsCounter = executionResult.endSideEffectCounter.toNumber() + 1;
|
|
813
811
|
this.setContractAddress(currentContractAddress);
|
|
814
812
|
this.setMsgSender(currentMessageSender);
|
|
815
813
|
this.setFunctionSelector(currentFunctionSelector);
|
|
@@ -835,6 +833,10 @@ export class TXE implements TypedOracle {
|
|
|
835
833
|
);
|
|
836
834
|
}
|
|
837
835
|
|
|
836
|
+
notifySetMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter: number) {
|
|
837
|
+
this.noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
838
|
+
}
|
|
839
|
+
|
|
838
840
|
aes128Encrypt(input: Buffer, initializationVector: Buffer, key: Buffer): Buffer {
|
|
839
841
|
const aes128 = new Aes128();
|
|
840
842
|
return aes128.encryptBufferCBC(input, initializationVector, key);
|
|
@@ -848,8 +850,9 @@ export class TXE implements TypedOracle {
|
|
|
848
850
|
_contractAddress: AztecAddress,
|
|
849
851
|
_randomness: Fr,
|
|
850
852
|
_encryptedEvent: Buffer,
|
|
851
|
-
|
|
853
|
+
counter: number,
|
|
852
854
|
): void {
|
|
855
|
+
this.sideEffectsCounter = counter + 1;
|
|
853
856
|
return;
|
|
854
857
|
}
|
|
855
858
|
|
|
@@ -40,7 +40,8 @@ export class TXEService {
|
|
|
40
40
|
const store = openTmpStore(true);
|
|
41
41
|
const trees = await MerkleTrees.new(store, logger);
|
|
42
42
|
const packedValuesCache = new PackedValuesCache();
|
|
43
|
-
const
|
|
43
|
+
const txHash = new Fr(1); // The txHash is used for computing the revertible nullifiers for non-revertible note hashes. It can be any value for testing.
|
|
44
|
+
const noteCache = new ExecutionNoteCache(txHash);
|
|
44
45
|
const keyStore = new KeyStore(store);
|
|
45
46
|
const txeDatabase = new TXEDatabase(store);
|
|
46
47
|
logger.info(`TXE service initialized`);
|
|
@@ -66,16 +67,16 @@ export class TXEService {
|
|
|
66
67
|
const nBlocks = fromSingle(blocks).toNumber();
|
|
67
68
|
this.logger.debug(`time traveling ${nBlocks} blocks`);
|
|
68
69
|
const trees = (this.typedOracle as TXE).getTrees();
|
|
69
|
-
const header = Header.empty();
|
|
70
|
-
const l2Block = L2Block.empty();
|
|
71
|
-
header.state = await trees.getStateReference(true);
|
|
72
|
-
const blockNumber = await this.typedOracle.getBlockNumber();
|
|
73
|
-
header.globalVariables.blockNumber = new Fr(blockNumber);
|
|
74
|
-
l2Block.archive.root = Fr.fromBuffer((await trees.getTreeInfo(MerkleTreeId.ARCHIVE, true)).root);
|
|
75
|
-
l2Block.header = header;
|
|
76
70
|
for (let i = 0; i < nBlocks; i++) {
|
|
77
71
|
const blockNumber = await this.typedOracle.getBlockNumber();
|
|
72
|
+
const header = Header.empty();
|
|
73
|
+
const l2Block = L2Block.empty();
|
|
74
|
+
header.state = await trees.getStateReference(true);
|
|
78
75
|
header.globalVariables.blockNumber = new Fr(blockNumber);
|
|
76
|
+
await trees.appendLeaves(MerkleTreeId.ARCHIVE, [header.hash()]);
|
|
77
|
+
l2Block.archive.root = Fr.fromBuffer((await trees.getTreeInfo(MerkleTreeId.ARCHIVE, true)).root);
|
|
78
|
+
l2Block.header = header;
|
|
79
|
+
this.logger.debug(`Block ${blockNumber} created, header hash ${header.hash().toString()}`);
|
|
79
80
|
await trees.handleL2BlockAndMessages(l2Block, []);
|
|
80
81
|
(this.typedOracle as TXE).setBlockNumber(blockNumber + 1);
|
|
81
82
|
}
|
|
@@ -442,14 +443,14 @@ export class TXEService {
|
|
|
442
443
|
storageSlot: ForeignCallSingle,
|
|
443
444
|
noteTypeId: ForeignCallSingle,
|
|
444
445
|
note: ForeignCallArray,
|
|
445
|
-
|
|
446
|
+
noteHash: ForeignCallSingle,
|
|
446
447
|
counter: ForeignCallSingle,
|
|
447
448
|
) {
|
|
448
449
|
this.typedOracle.notifyCreatedNote(
|
|
449
450
|
fromSingle(storageSlot),
|
|
450
451
|
NoteSelector.fromField(fromSingle(noteTypeId)),
|
|
451
452
|
fromArray(note),
|
|
452
|
-
fromSingle(
|
|
453
|
+
fromSingle(noteHash),
|
|
453
454
|
fromSingle(counter).toNumber(),
|
|
454
455
|
);
|
|
455
456
|
return toForeignCallResult([toSingle(new Fr(0))]);
|
|
@@ -457,12 +458,12 @@ export class TXEService {
|
|
|
457
458
|
|
|
458
459
|
async notifyNullifiedNote(
|
|
459
460
|
innerNullifier: ForeignCallSingle,
|
|
460
|
-
|
|
461
|
+
noteHash: ForeignCallSingle,
|
|
461
462
|
counter: ForeignCallSingle,
|
|
462
463
|
) {
|
|
463
464
|
await this.typedOracle.notifyNullifiedNote(
|
|
464
465
|
fromSingle(innerNullifier),
|
|
465
|
-
fromSingle(
|
|
466
|
+
fromSingle(noteHash),
|
|
466
467
|
fromSingle(counter).toNumber(),
|
|
467
468
|
);
|
|
468
469
|
return toForeignCallResult([toSingle(new Fr(0))]);
|
|
@@ -511,8 +512,8 @@ export class TXEService {
|
|
|
511
512
|
return toForeignCallResult([]);
|
|
512
513
|
}
|
|
513
514
|
|
|
514
|
-
async avmOpcodeEmitNoteHash(
|
|
515
|
-
await (this.typedOracle as TXE).avmOpcodeEmitNoteHash(fromSingle(
|
|
515
|
+
async avmOpcodeEmitNoteHash(noteHash: ForeignCallSingle) {
|
|
516
|
+
await (this.typedOracle as TXE).avmOpcodeEmitNoteHash(fromSingle(noteHash));
|
|
516
517
|
return toForeignCallResult([]);
|
|
517
518
|
}
|
|
518
519
|
|
|
@@ -711,6 +712,10 @@ export class TXEService {
|
|
|
711
712
|
return toForeignCallResult([]);
|
|
712
713
|
}
|
|
713
714
|
|
|
715
|
+
public notifySetMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter: ForeignCallSingle) {
|
|
716
|
+
this.typedOracle.notifySetMinRevertibleSideEffectCounter(fromSingle(minRevertibleSideEffectCounter).toNumber());
|
|
717
|
+
}
|
|
718
|
+
|
|
714
719
|
async getChainId() {
|
|
715
720
|
return toForeignCallResult([toSingle(await this.typedOracle.getChainId())]);
|
|
716
721
|
}
|
|
@@ -728,4 +733,25 @@ export class TXEService {
|
|
|
728
733
|
await (this.typedOracle as TXE).addNoteHashes(fromSingle(contractAddress), fromArray(noteHashes));
|
|
729
734
|
return toForeignCallResult([]);
|
|
730
735
|
}
|
|
736
|
+
|
|
737
|
+
async getHeader(blockNumber: ForeignCallSingle) {
|
|
738
|
+
const header = await this.typedOracle.getHeader(fromSingle(blockNumber).toNumber());
|
|
739
|
+
if (!header) {
|
|
740
|
+
throw new Error(`Block header not found for block ${blockNumber}.`);
|
|
741
|
+
}
|
|
742
|
+
return toForeignCallResult([toArray(header.toFields())]);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
async getMembershipWitness(blockNumber: ForeignCallSingle, treeId: ForeignCallSingle, leafValue: ForeignCallSingle) {
|
|
746
|
+
const parsedBlockNumber = fromSingle(blockNumber).toNumber();
|
|
747
|
+
const parsedTreeId = fromSingle(treeId).toNumber();
|
|
748
|
+
const parsedLeafValue = fromSingle(leafValue);
|
|
749
|
+
const witness = await this.typedOracle.getMembershipWitness(parsedBlockNumber, parsedTreeId, parsedLeafValue);
|
|
750
|
+
if (!witness) {
|
|
751
|
+
throw new Error(
|
|
752
|
+
`Membership witness in tree ${MerkleTreeId[parsedTreeId]} not found for value ${parsedLeafValue} at block ${parsedBlockNumber}.`,
|
|
753
|
+
);
|
|
754
|
+
}
|
|
755
|
+
return toForeignCallResult([toArray(witness)]);
|
|
756
|
+
}
|
|
731
757
|
}
|