@aztec/txe 0.69.1-devnet → 0.70.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/index.js +2 -2
- package/dest/oracle/txe_oracle.d.ts +12 -9
- package/dest/oracle/txe_oracle.d.ts.map +1 -1
- package/dest/oracle/txe_oracle.js +45 -57
- package/dest/txe_service/txe_service.d.ts +7 -7
- package/dest/txe_service/txe_service.d.ts.map +1 -1
- package/dest/txe_service/txe_service.js +17 -19
- package/dest/util/txe_world_state_db.d.ts +1 -1
- package/dest/util/txe_world_state_db.d.ts.map +1 -1
- package/dest/util/txe_world_state_db.js +2 -2
- package/package.json +14 -14
- package/src/index.ts +1 -1
- package/src/oracle/txe_oracle.ts +79 -77
- package/src/txe_service/txe_service.ts +18 -19
- package/src/util/txe_world_state_db.ts +1 -1
package/src/oracle/txe_oracle.ts
CHANGED
|
@@ -63,25 +63,27 @@ import { Timer } from '@aztec/foundation/timer';
|
|
|
63
63
|
import { type KeyStore } from '@aztec/key-store';
|
|
64
64
|
import { ContractDataOracle, SimulatorOracle, enrichPublicSimulationError } from '@aztec/pxe';
|
|
65
65
|
import {
|
|
66
|
-
ExecutionError,
|
|
67
66
|
ExecutionNoteCache,
|
|
68
67
|
type MessageLoadOracleInputs,
|
|
69
68
|
type NoteData,
|
|
70
69
|
Oracle,
|
|
71
|
-
type PackedValuesCache,
|
|
72
|
-
type PublicTxResult,
|
|
73
|
-
PublicTxSimulator,
|
|
74
70
|
type TypedOracle,
|
|
75
|
-
|
|
76
|
-
createSimulationError,
|
|
71
|
+
WASMSimulator,
|
|
77
72
|
extractCallStack,
|
|
78
73
|
extractPrivateCircuitPublicInputs,
|
|
79
74
|
pickNotes,
|
|
80
|
-
resolveAssertionMessageFromError,
|
|
81
75
|
toACVMWitness,
|
|
82
76
|
witnessMapToFields,
|
|
83
|
-
} from '@aztec/simulator';
|
|
84
|
-
import {
|
|
77
|
+
} from '@aztec/simulator/client';
|
|
78
|
+
import { createTxForPublicCalls } from '@aztec/simulator/public/fixtures';
|
|
79
|
+
import {
|
|
80
|
+
ExecutionError,
|
|
81
|
+
type HashedValuesCache,
|
|
82
|
+
type PublicTxResult,
|
|
83
|
+
PublicTxSimulator,
|
|
84
|
+
createSimulationError,
|
|
85
|
+
resolveAssertionMessageFromError,
|
|
86
|
+
} from '@aztec/simulator/server';
|
|
85
87
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
86
88
|
import { MerkleTreeSnapshotOperationsFacade, type MerkleTrees } from '@aztec/world-state';
|
|
87
89
|
|
|
@@ -108,7 +110,6 @@ export class TXE implements TypedOracle {
|
|
|
108
110
|
|
|
109
111
|
private uniqueNoteHashesFromPublic: Fr[] = [];
|
|
110
112
|
private siloedNullifiersFromPublic: Fr[] = [];
|
|
111
|
-
private siloedNullifiersFromPrivate: Set<string> = new Set();
|
|
112
113
|
private privateLogs: PrivateLog[] = [];
|
|
113
114
|
private publicLogs: UnencryptedL2Log[] = [];
|
|
114
115
|
|
|
@@ -116,21 +117,31 @@ export class TXE implements TypedOracle {
|
|
|
116
117
|
|
|
117
118
|
private node = new TXENode(this.blockNumber);
|
|
118
119
|
|
|
120
|
+
private simulationProvider = new WASMSimulator();
|
|
121
|
+
|
|
122
|
+
private noteCache: ExecutionNoteCache;
|
|
123
|
+
|
|
119
124
|
debug: LogFn;
|
|
120
125
|
|
|
121
126
|
constructor(
|
|
122
127
|
private logger: Logger,
|
|
123
128
|
private trees: MerkleTrees,
|
|
124
|
-
private
|
|
125
|
-
private noteCache: ExecutionNoteCache,
|
|
129
|
+
private executionCache: HashedValuesCache,
|
|
126
130
|
private keyStore: KeyStore,
|
|
127
131
|
private txeDatabase: TXEDatabase,
|
|
128
132
|
) {
|
|
133
|
+
this.noteCache = new ExecutionNoteCache(this.getTxRequestHash());
|
|
129
134
|
this.contractDataOracle = new ContractDataOracle(txeDatabase);
|
|
130
135
|
this.contractAddress = AztecAddress.random();
|
|
131
136
|
// Default msg_sender (for entrypoints) is now Fr.max_value rather than 0 addr (see #7190 & #7404)
|
|
132
137
|
this.msgSender = AztecAddress.fromField(Fr.MAX_FIELD_VALUE);
|
|
133
|
-
this.simulatorOracle = new SimulatorOracle(
|
|
138
|
+
this.simulatorOracle = new SimulatorOracle(
|
|
139
|
+
this.contractDataOracle,
|
|
140
|
+
txeDatabase,
|
|
141
|
+
keyStore,
|
|
142
|
+
this.node,
|
|
143
|
+
this.simulationProvider,
|
|
144
|
+
);
|
|
134
145
|
|
|
135
146
|
this.debug = createDebugOnlyLogger('aztec:kv-pxe-database');
|
|
136
147
|
}
|
|
@@ -264,18 +275,14 @@ export class TXE implements TypedOracle {
|
|
|
264
275
|
);
|
|
265
276
|
}
|
|
266
277
|
|
|
267
|
-
async
|
|
278
|
+
async checkNullifiersNotInTree(contractAddress: AztecAddress, nullifiers: Fr[]) {
|
|
268
279
|
const siloedNullifiers = nullifiers.map(nullifier => siloNullifier(contractAddress, nullifier));
|
|
269
280
|
const db = await this.trees.getLatest();
|
|
270
281
|
const nullifierIndexesInTree = await db.findLeafIndices(
|
|
271
282
|
MerkleTreeId.NULLIFIER_TREE,
|
|
272
283
|
siloedNullifiers.map(n => n.toBuffer()),
|
|
273
284
|
);
|
|
274
|
-
|
|
275
|
-
const notInCache = siloedNullifiers.every(n => !this.siloedNullifiersFromPrivate.has(n.toString()));
|
|
276
|
-
if (notInTree && notInCache) {
|
|
277
|
-
siloedNullifiers.forEach(n => this.siloedNullifiersFromPrivate.add(n.toString()));
|
|
278
|
-
} else {
|
|
285
|
+
if (nullifierIndexesInTree.some(index => index !== undefined)) {
|
|
279
286
|
throw new Error(`Rejecting tx for emitting duplicate nullifiers`);
|
|
280
287
|
}
|
|
281
288
|
}
|
|
@@ -364,16 +371,16 @@ export class TXE implements TypedOracle {
|
|
|
364
371
|
return Fr.random();
|
|
365
372
|
}
|
|
366
373
|
|
|
367
|
-
|
|
368
|
-
return Promise.resolve(this.
|
|
374
|
+
storeArrayInExecutionCache(values: Fr[]) {
|
|
375
|
+
return Promise.resolve(this.executionCache.store(values));
|
|
369
376
|
}
|
|
370
377
|
|
|
371
|
-
|
|
372
|
-
return Promise.resolve(this.
|
|
378
|
+
storeInExecutionCache(values: Fr[]) {
|
|
379
|
+
return Promise.resolve(this.executionCache.store(values));
|
|
373
380
|
}
|
|
374
381
|
|
|
375
|
-
|
|
376
|
-
return Promise.resolve(this.
|
|
382
|
+
loadFromExecutionCache(returnsHash: Fr) {
|
|
383
|
+
return Promise.resolve(this.executionCache.getPreimage(returnsHash));
|
|
377
384
|
}
|
|
378
385
|
|
|
379
386
|
getKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
@@ -554,12 +561,18 @@ export class TXE implements TypedOracle {
|
|
|
554
561
|
}
|
|
555
562
|
|
|
556
563
|
async notifyNullifiedNote(innerNullifier: Fr, noteHash: Fr, counter: number) {
|
|
557
|
-
await this.
|
|
564
|
+
await this.checkNullifiersNotInTree(this.contractAddress, [innerNullifier]);
|
|
558
565
|
this.noteCache.nullifyNote(this.contractAddress, innerNullifier, noteHash);
|
|
559
566
|
this.sideEffectCounter = counter + 1;
|
|
560
567
|
return Promise.resolve();
|
|
561
568
|
}
|
|
562
569
|
|
|
570
|
+
async notifyCreatedNullifier(innerNullifier: Fr): Promise<void> {
|
|
571
|
+
await this.checkNullifiersNotInTree(this.contractAddress, [innerNullifier]);
|
|
572
|
+
this.noteCache.nullifierCreated(this.contractAddress, innerNullifier);
|
|
573
|
+
return Promise.resolve();
|
|
574
|
+
}
|
|
575
|
+
|
|
563
576
|
async checkNullifierExists(innerNullifier: Fr): Promise<boolean> {
|
|
564
577
|
const nullifier = siloNullifier(this.contractAddress, innerNullifier!);
|
|
565
578
|
const db = await this.trees.getLatest();
|
|
@@ -621,6 +634,7 @@ export class TXE implements TypedOracle {
|
|
|
621
634
|
|
|
622
635
|
async commitState() {
|
|
623
636
|
const blockNumber = await this.getBlockNumber();
|
|
637
|
+
const { usedTxRequestHashForNonces } = this.noteCache.finish();
|
|
624
638
|
if (this.committedBlocks.has(blockNumber)) {
|
|
625
639
|
throw new Error('Already committed state');
|
|
626
640
|
} else {
|
|
@@ -629,30 +643,25 @@ export class TXE implements TypedOracle {
|
|
|
629
643
|
|
|
630
644
|
const txEffect = TxEffect.empty();
|
|
631
645
|
|
|
646
|
+
const nonceGenerator = usedTxRequestHashForNonces ? this.getTxRequestHash() : this.noteCache.getAllNullifiers()[0];
|
|
647
|
+
|
|
632
648
|
let i = 0;
|
|
633
649
|
txEffect.noteHashes = [
|
|
634
650
|
...this.noteCache
|
|
635
651
|
.getAllNotes()
|
|
636
652
|
.map(pendingNote =>
|
|
637
653
|
computeUniqueNoteHash(
|
|
638
|
-
computeNoteHashNonce(
|
|
654
|
+
computeNoteHashNonce(nonceGenerator, i++),
|
|
639
655
|
siloNoteHash(pendingNote.note.contractAddress, pendingNote.noteHashForConsumption),
|
|
640
656
|
),
|
|
641
657
|
),
|
|
642
658
|
...this.uniqueNoteHashesFromPublic,
|
|
643
659
|
];
|
|
644
|
-
txEffect.nullifiers = [
|
|
645
|
-
new Fr(blockNumber + 6969),
|
|
646
|
-
...Array.from(this.siloedNullifiersFromPrivate).map(n => Fr.fromString(n)),
|
|
647
|
-
];
|
|
648
|
-
|
|
649
|
-
// Using block number itself, (without adding 6969) gets killed at 1 as it says the slot is already used,
|
|
650
|
-
// it seems like we commit a 1 there to the trees before ? To see what I mean, uncomment these lines below
|
|
651
|
-
// let index = await (await this.trees.getLatest()).findLeafIndex(MerkleTreeId.NULLIFIER_TREE, Fr.ONE.toBuffer());
|
|
652
|
-
// console.log('INDEX OF ONE', index);
|
|
653
|
-
// index = await (await this.trees.getLatest()).findLeafIndex(MerkleTreeId.NULLIFIER_TREE, Fr.random().toBuffer());
|
|
654
|
-
// console.log('INDEX OF RANDOM', index);
|
|
655
660
|
|
|
661
|
+
txEffect.nullifiers = this.noteCache.getAllNullifiers();
|
|
662
|
+
if (usedTxRequestHashForNonces) {
|
|
663
|
+
txEffect.nullifiers.unshift(this.getTxRequestHash());
|
|
664
|
+
}
|
|
656
665
|
this.node.setTxEffect(blockNumber, new TxHash(new Fr(blockNumber)), txEffect);
|
|
657
666
|
this.node.setNullifiersIndexesWithBlock(blockNumber, txEffect.nullifiers);
|
|
658
667
|
this.node.addNoteLogsByTags(this.blockNumber, this.privateLogs);
|
|
@@ -663,10 +672,14 @@ export class TXE implements TypedOracle {
|
|
|
663
672
|
|
|
664
673
|
this.privateLogs = [];
|
|
665
674
|
this.publicLogs = [];
|
|
666
|
-
this.siloedNullifiersFromPrivate = new Set();
|
|
667
675
|
this.uniqueNoteHashesFromPublic = [];
|
|
668
676
|
this.siloedNullifiersFromPublic = [];
|
|
669
|
-
this.noteCache = new ExecutionNoteCache(
|
|
677
|
+
this.noteCache = new ExecutionNoteCache(this.getTxRequestHash());
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
getTxRequestHash() {
|
|
681
|
+
// Using block number itself is invalid since indexed trees come prefilled with the first slots.
|
|
682
|
+
return new Fr(this.blockNumber + 6969);
|
|
670
683
|
}
|
|
671
684
|
|
|
672
685
|
emitContractClassLog(_log: UnencryptedL2Log, _counter: number): Fr {
|
|
@@ -701,21 +714,23 @@ export class TXE implements TypedOracle {
|
|
|
701
714
|
const initialWitness = await this.getInitialWitness(artifact, argsHash, sideEffectCounter, isStaticCall);
|
|
702
715
|
const acvmCallback = new Oracle(this);
|
|
703
716
|
const timer = new Timer();
|
|
704
|
-
const acirExecutionResult = await
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
717
|
+
const acirExecutionResult = await this.simulationProvider
|
|
718
|
+
.executeUserCircuit(acir, initialWitness, acvmCallback)
|
|
719
|
+
.catch((err: Error) => {
|
|
720
|
+
err.message = resolveAssertionMessageFromError(err, artifact);
|
|
721
|
+
|
|
722
|
+
const execError = new ExecutionError(
|
|
723
|
+
err.message,
|
|
724
|
+
{
|
|
725
|
+
contractAddress: targetContractAddress,
|
|
726
|
+
functionSelector,
|
|
727
|
+
},
|
|
728
|
+
extractCallStack(err, artifact.debug),
|
|
729
|
+
{ cause: err },
|
|
730
|
+
);
|
|
731
|
+
this.logger.debug(`Error executing private function ${targetContractAddress}:${functionSelector}`);
|
|
732
|
+
throw createSimulationError(execError);
|
|
733
|
+
});
|
|
719
734
|
const duration = timer.ms();
|
|
720
735
|
const publicInputs = extractPrivateCircuitPublicInputs(artifact, acirExecutionResult.partialWitness);
|
|
721
736
|
|
|
@@ -738,24 +753,6 @@ export class TXE implements TypedOracle {
|
|
|
738
753
|
publicInputs.privateLogs.filter(privateLog => !privateLog.isEmpty()).map(privateLog => privateLog.log),
|
|
739
754
|
);
|
|
740
755
|
|
|
741
|
-
const executionNullifiers = publicInputs.nullifiers
|
|
742
|
-
.filter(nullifier => !nullifier.isEmpty())
|
|
743
|
-
.map(nullifier => nullifier.value);
|
|
744
|
-
// We inject nullifiers into siloedNullifiersFromPrivate from notifyNullifiedNote,
|
|
745
|
-
// so top level calls to destroyNote work as expected. As such, we are certain
|
|
746
|
-
// that we would insert duplicates if we just took the nullifiers from the public inputs and
|
|
747
|
-
// blindly inserted them into siloedNullifiersFromPrivate. To avoid this, we extract the first
|
|
748
|
-
// (and only the first!) duplicated nullifier from the public inputs, so we can just push
|
|
749
|
-
// the ones that were not created by deleting a note
|
|
750
|
-
const firstDuplicateIndexes = executionNullifiers
|
|
751
|
-
.map((nullifier, index) => {
|
|
752
|
-
const siloedNullifier = siloNullifier(targetContractAddress, nullifier);
|
|
753
|
-
return this.siloedNullifiersFromPrivate.has(siloedNullifier.toString()) ? index : -1;
|
|
754
|
-
})
|
|
755
|
-
.filter(index => index !== -1);
|
|
756
|
-
const nonNoteNullifiers = executionNullifiers.filter((_, index) => !firstDuplicateIndexes.includes(index));
|
|
757
|
-
await this.addNullifiersFromPrivate(targetContractAddress, nonNoteNullifiers);
|
|
758
|
-
|
|
759
756
|
this.setContractAddress(currentContractAddress);
|
|
760
757
|
this.setMsgSender(currentMessageSender);
|
|
761
758
|
this.setFunctionSelector(currentFunctionSelector);
|
|
@@ -766,7 +763,7 @@ export class TXE implements TypedOracle {
|
|
|
766
763
|
async getInitialWitness(abi: FunctionAbi, argsHash: Fr, sideEffectCounter: number, isStaticCall: boolean) {
|
|
767
764
|
const argumentsSize = countArgumentsSize(abi);
|
|
768
765
|
|
|
769
|
-
const args = this.
|
|
766
|
+
const args = this.executionCache.getPreimage(argsHash);
|
|
770
767
|
|
|
771
768
|
if (args.length !== argumentsSize) {
|
|
772
769
|
throw new Error('Invalid arguments size');
|
|
@@ -840,7 +837,12 @@ export class TXE implements TypedOracle {
|
|
|
840
837
|
// When setting up a teardown call, we tell it that
|
|
841
838
|
// private execution used Gas(1, 1) so it can compute a tx fee.
|
|
842
839
|
const gasUsedByPrivate = isTeardown ? new Gas(1, 1) : Gas.empty();
|
|
843
|
-
const tx =
|
|
840
|
+
const tx = createTxForPublicCalls(
|
|
841
|
+
/*setupExecutionRequests=*/ [],
|
|
842
|
+
/*appExecutionRequests=*/ isTeardown ? [] : [executionRequest],
|
|
843
|
+
/*teardownExecutionRequests=*/ isTeardown ? executionRequest : undefined,
|
|
844
|
+
gasUsedByPrivate,
|
|
845
|
+
);
|
|
844
846
|
|
|
845
847
|
const result = await simulator.simulate(tx);
|
|
846
848
|
|
|
@@ -872,8 +874,8 @@ export class TXE implements TypedOracle {
|
|
|
872
874
|
isStaticCall,
|
|
873
875
|
);
|
|
874
876
|
|
|
875
|
-
const args = [this.functionSelector.toField(), ...this.
|
|
876
|
-
const newArgsHash = this.
|
|
877
|
+
const args = [this.functionSelector.toField(), ...this.executionCache.getPreimage(argsHash)];
|
|
878
|
+
const newArgsHash = this.executionCache.store(args);
|
|
877
879
|
|
|
878
880
|
const executionResult = await this.executePublicFunction(args, callContext, isTeardown);
|
|
879
881
|
|
|
@@ -18,7 +18,8 @@ import { openTmpStore } from '@aztec/kv-store/lmdb';
|
|
|
18
18
|
import { protocolContractNames } from '@aztec/protocol-contracts';
|
|
19
19
|
import { getCanonicalProtocolContract } from '@aztec/protocol-contracts/bundle';
|
|
20
20
|
import { enrichPublicSimulationError } from '@aztec/pxe';
|
|
21
|
-
import {
|
|
21
|
+
import { type TypedOracle } from '@aztec/simulator/client';
|
|
22
|
+
import { HashedValuesCache } from '@aztec/simulator/server';
|
|
22
23
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
23
24
|
import { MerkleTrees } from '@aztec/world-state';
|
|
24
25
|
|
|
@@ -42,9 +43,7 @@ export class TXEService {
|
|
|
42
43
|
static async init(logger: Logger) {
|
|
43
44
|
const store = openTmpStore(true);
|
|
44
45
|
const trees = await MerkleTrees.new(store, new NoopTelemetryClient(), logger);
|
|
45
|
-
const
|
|
46
|
-
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.
|
|
47
|
-
const noteCache = new ExecutionNoteCache(txHash);
|
|
46
|
+
const executionCache = new HashedValuesCache();
|
|
48
47
|
const keyStore = new KeyStore(store);
|
|
49
48
|
const txeDatabase = new TXEDatabase(store);
|
|
50
49
|
// Register protocol contracts.
|
|
@@ -54,7 +53,7 @@ export class TXEService {
|
|
|
54
53
|
await txeDatabase.addContractInstance(instance);
|
|
55
54
|
}
|
|
56
55
|
logger.debug(`TXE service initialized`);
|
|
57
|
-
const txe = new TXE(logger, trees,
|
|
56
|
+
const txe = new TXE(logger, trees, executionCache, keyStore, txeDatabase);
|
|
58
57
|
const service = new TXEService(logger, txe);
|
|
59
58
|
await service.advanceBlocksBy(toSingle(new Fr(1n)));
|
|
60
59
|
return service;
|
|
@@ -272,25 +271,20 @@ export class TXEService {
|
|
|
272
271
|
return toForeignCallResult([toSingle(new Fr(blockNumber))]);
|
|
273
272
|
}
|
|
274
273
|
|
|
275
|
-
async
|
|
276
|
-
const
|
|
277
|
-
return toForeignCallResult([toSingle(
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
async packArguments(_length: ForeignCallSingle, values: ForeignCallArray) {
|
|
281
|
-
const packed = await this.typedOracle.packArgumentsArray(fromArray(values));
|
|
282
|
-
return toForeignCallResult([toSingle(packed)]);
|
|
274
|
+
async storeArrayInExecutionCache(args: ForeignCallArray) {
|
|
275
|
+
const hash = await this.typedOracle.storeArrayInExecutionCache(fromArray(args));
|
|
276
|
+
return toForeignCallResult([toSingle(hash)]);
|
|
283
277
|
}
|
|
284
278
|
|
|
285
279
|
// Since the argument is a slice, noir automatically adds a length field to oracle call.
|
|
286
|
-
async
|
|
287
|
-
const
|
|
288
|
-
return toForeignCallResult([toSingle(
|
|
280
|
+
async storeInExecutionCache(_length: ForeignCallSingle, values: ForeignCallArray) {
|
|
281
|
+
const returnsHash = await this.typedOracle.storeInExecutionCache(fromArray(values));
|
|
282
|
+
return toForeignCallResult([toSingle(returnsHash)]);
|
|
289
283
|
}
|
|
290
284
|
|
|
291
|
-
async
|
|
292
|
-
const
|
|
293
|
-
return toForeignCallResult([toArray(
|
|
285
|
+
async loadFromExecutionCache(hash: ForeignCallSingle) {
|
|
286
|
+
const returns = await this.typedOracle.loadFromExecutionCache(fromSingle(hash));
|
|
287
|
+
return toForeignCallResult([toArray(returns)]);
|
|
294
288
|
}
|
|
295
289
|
|
|
296
290
|
// Since the argument is a slice, noir automatically adds a length field to oracle call.
|
|
@@ -425,6 +419,11 @@ export class TXEService {
|
|
|
425
419
|
return toForeignCallResult([toSingle(new Fr(0))]);
|
|
426
420
|
}
|
|
427
421
|
|
|
422
|
+
async notifyCreatedNullifier(innerNullifier: ForeignCallSingle) {
|
|
423
|
+
await this.typedOracle.notifyCreatedNullifier(fromSingle(innerNullifier));
|
|
424
|
+
return toForeignCallResult([toSingle(new Fr(0))]);
|
|
425
|
+
}
|
|
426
|
+
|
|
428
427
|
async checkNullifierExists(innerNullifier: ForeignCallSingle) {
|
|
429
428
|
const exists = await this.typedOracle.checkNullifierExists(fromSingle(innerNullifier));
|
|
430
429
|
return toForeignCallResult([toSingle(new Fr(exists))]);
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type PublicDataTreeLeafPreimage,
|
|
8
8
|
} from '@aztec/circuits.js';
|
|
9
9
|
import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash';
|
|
10
|
-
import { WorldStateDB } from '@aztec/simulator';
|
|
10
|
+
import { WorldStateDB } from '@aztec/simulator/server';
|
|
11
11
|
|
|
12
12
|
export class TXEWorldStateDB extends WorldStateDB {
|
|
13
13
|
constructor(private merkleDb: MerkleTreeWriteOperations, dataSource: ContractDataSource) {
|