@aztec/simulator 0.64.0 → 0.65.1
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/avm/avm_memory_types.d.ts +3 -1
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +22 -24
- package/dest/avm/avm_simulator.d.ts +5 -1
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +16 -9
- package/dest/avm/avm_tree.d.ts +56 -7
- package/dest/avm/avm_tree.d.ts.map +1 -1
- package/dest/avm/avm_tree.js +155 -82
- package/dest/avm/errors.d.ts +19 -0
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +29 -1
- package/dest/avm/journal/journal.d.ts +8 -7
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +47 -29
- package/dest/avm/journal/nullifiers.d.ts +11 -58
- package/dest/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/avm/journal/nullifiers.js +27 -107
- package/dest/avm/opcodes/contract.d.ts +2 -2
- package/dest/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/avm/opcodes/contract.js +4 -4
- package/dest/avm/opcodes/control_flow.d.ts +2 -2
- package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/avm/opcodes/control_flow.js +4 -4
- package/dest/avm/opcodes/environment_getters.d.ts +2 -2
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +4 -4
- package/dest/avm/opcodes/instruction.d.ts +1 -1
- package/dest/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction.js +1 -1
- package/dest/avm/opcodes/memory.d.ts +4 -4
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +17 -13
- package/dest/avm/opcodes/misc.d.ts +2 -2
- package/dest/avm/opcodes/misc.d.ts.map +1 -1
- package/dest/avm/opcodes/misc.js +4 -4
- package/dest/avm/serialization/buffer_cursor.d.ts +2 -0
- package/dest/avm/serialization/buffer_cursor.d.ts.map +1 -1
- package/dest/avm/serialization/buffer_cursor.js +8 -3
- package/dest/avm/serialization/bytecode_serialization.d.ts +1 -0
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +27 -13
- package/dest/avm/serialization/instruction_serialization.d.ts +1 -0
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +9 -6
- package/dest/avm/test_utils.d.ts.map +1 -1
- package/dest/avm/test_utils.js +3 -2
- package/dest/common/errors.d.ts.map +1 -1
- package/dest/common/errors.js +3 -2
- package/dest/public/dual_side_effect_trace.d.ts +2 -2
- package/dest/public/dual_side_effect_trace.d.ts.map +1 -1
- package/dest/public/dual_side_effect_trace.js +7 -7
- package/dest/public/enqueued_call_side_effect_trace.d.ts +8 -23
- package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
- package/dest/public/enqueued_call_side_effect_trace.js +31 -92
- package/dest/public/executor_metrics.d.ts +4 -2
- package/dest/public/executor_metrics.d.ts.map +1 -1
- package/dest/public/executor_metrics.js +20 -3
- package/dest/public/fixtures/index.d.ts.map +1 -1
- package/dest/public/fixtures/index.js +66 -35
- package/dest/public/public_db_sources.d.ts +3 -1
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +26 -11
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +12 -5
- package/dest/public/public_tx_context.d.ts +5 -6
- package/dest/public/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_context.js +19 -17
- package/dest/public/public_tx_simulator.d.ts +13 -2
- package/dest/public/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator.js +263 -217
- package/dest/public/side_effect_trace.d.ts +2 -2
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +8 -6
- package/dest/public/side_effect_trace_interface.d.ts +2 -2
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/public/transitional_adapters.d.ts.map +1 -1
- package/dest/public/transitional_adapters.js +2 -6
- package/package.json +9 -9
- package/src/avm/avm_memory_types.ts +26 -24
- package/src/avm/avm_simulator.ts +20 -13
- package/src/avm/avm_tree.ts +196 -93
- package/src/avm/errors.ts +31 -0
- package/src/avm/journal/journal.ts +61 -47
- package/src/avm/journal/nullifiers.ts +29 -121
- package/src/avm/opcodes/contract.ts +2 -2
- package/src/avm/opcodes/control_flow.ts +2 -2
- package/src/avm/opcodes/environment_getters.ts +2 -2
- package/src/avm/opcodes/instruction.ts +1 -1
- package/src/avm/opcodes/memory.ts +15 -10
- package/src/avm/opcodes/misc.ts +2 -2
- package/src/avm/serialization/buffer_cursor.ts +9 -3
- package/src/avm/serialization/bytecode_serialization.ts +29 -13
- package/src/avm/serialization/instruction_serialization.ts +12 -6
- package/src/avm/test_utils.ts +9 -1
- package/src/common/errors.ts +2 -1
- package/src/public/dual_side_effect_trace.ts +6 -30
- package/src/public/enqueued_call_side_effect_trace.ts +35 -154
- package/src/public/executor_metrics.ts +23 -1
- package/src/public/fixtures/index.ts +97 -43
- package/src/public/public_db_sources.ts +29 -15
- package/src/public/public_processor.ts +11 -4
- package/src/public/public_tx_context.ts +21 -23
- package/src/public/public_tx_simulator.ts +45 -8
- package/src/public/side_effect_trace.ts +7 -9
- package/src/public/side_effect_trace_interface.ts +2 -4
- package/src/public/transitional_adapters.ts +0 -11
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { MerkleTreeId } from '@aztec/circuit-types';
|
|
2
|
-
import { SerializableContractInstance,
|
|
2
|
+
import { SerializableContractInstance, } from '@aztec/circuits.js';
|
|
3
3
|
import { computePublicDataTreeLeafSlot, siloNoteHash, siloNullifier } from '@aztec/circuits.js/hash';
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
|
+
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
5
6
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
|
-
import assert from 'assert';
|
|
7
|
+
import { strict as assert } from 'assert';
|
|
7
8
|
import { getPublicFunctionDebugName } from '../../common/debug_fn_name.js';
|
|
8
9
|
import { AvmEphemeralForest } from '../avm_tree.js';
|
|
9
10
|
import { NullifierCollisionError, NullifierManager } from './nullifiers.js';
|
|
@@ -53,12 +54,12 @@ export class AvmPersistableStateManager {
|
|
|
53
54
|
/**
|
|
54
55
|
* Create a new state manager
|
|
55
56
|
*/
|
|
56
|
-
static async create(worldStateDB, trace) {
|
|
57
|
+
static async create(worldStateDB, trace, doMerkleOperations = false) {
|
|
57
58
|
const ephemeralForest = await AvmEphemeralForest.create(worldStateDB.getMerkleInterface());
|
|
58
59
|
return new AvmPersistableStateManager(worldStateDB, trace,
|
|
59
60
|
/*publicStorage=*/ new PublicStorage(worldStateDB),
|
|
60
61
|
/*nullifiers=*/ new NullifierManager(worldStateDB),
|
|
61
|
-
/*doMerkleOperations=*/
|
|
62
|
+
/*doMerkleOperations=*/ doMerkleOperations, ephemeralForest);
|
|
62
63
|
}
|
|
63
64
|
/**
|
|
64
65
|
* Create a new state manager forked from this one
|
|
@@ -78,13 +79,6 @@ export class AvmPersistableStateManager {
|
|
|
78
79
|
reject(forkedState) {
|
|
79
80
|
this._merge(forkedState, /*reverted=*/ true);
|
|
80
81
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Commit cached storage writes to the DB.
|
|
83
|
-
* Keeps public storage up to date from tx to tx within a block.
|
|
84
|
-
*/
|
|
85
|
-
async commitStorageWritesToDB() {
|
|
86
|
-
await this.publicStorage.commitToDB();
|
|
87
|
-
}
|
|
88
82
|
_merge(forkedState, reverted) {
|
|
89
83
|
// sanity check to avoid merging the same forked trace twice
|
|
90
84
|
assert(!forkedState.alreadyMergedIntoParent, 'Cannot merge forked state that has already been merged into its parent!');
|
|
@@ -92,6 +86,12 @@ export class AvmPersistableStateManager {
|
|
|
92
86
|
this.publicStorage.acceptAndMerge(forkedState.publicStorage);
|
|
93
87
|
this.nullifiers.acceptAndMerge(forkedState.nullifiers);
|
|
94
88
|
this.trace.merge(forkedState.trace, reverted);
|
|
89
|
+
if (!reverted) {
|
|
90
|
+
this.merkleTrees = forkedState.merkleTrees;
|
|
91
|
+
if (this.doMerkleOperations) {
|
|
92
|
+
this.log.debug(`Rolled back nullifier tree to root ${this.merkleTrees.treeMap.get(MerkleTreeId.NULLIFIER_TREE).getRoot()}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
95
|
}
|
|
96
96
|
/**
|
|
97
97
|
* Write to public storage, journal/trace the write.
|
|
@@ -217,8 +217,10 @@ export class AvmPersistableStateManager {
|
|
|
217
217
|
* @returns exists - whether the nullifier exists in the nullifier set
|
|
218
218
|
*/
|
|
219
219
|
async checkNullifierExists(contractAddress, nullifier) {
|
|
220
|
-
|
|
220
|
+
this.log.debug(`Checking existence of nullifier (address=${contractAddress}, nullifier=${nullifier})`);
|
|
221
221
|
const siloedNullifier = siloNullifier(contractAddress, nullifier);
|
|
222
|
+
const [exists, isPending, _] = await this.nullifiers.checkExists(siloedNullifier);
|
|
223
|
+
this.log.debug(`Checked siloed nullifier ${siloedNullifier} (exists=${exists}, pending=${isPending})`);
|
|
222
224
|
if (this.doMerkleOperations) {
|
|
223
225
|
// Get leaf if present, low leaf if absent
|
|
224
226
|
// If leaf is present, hint/trace it. Otherwise, hint/trace the low leaf.
|
|
@@ -226,18 +228,18 @@ export class AvmPersistableStateManager {
|
|
|
226
228
|
const leafPreimage = preimage;
|
|
227
229
|
const leafPath = await this.merkleTrees.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, leafIndex);
|
|
228
230
|
assert(update == exists, 'WorldStateDB contains nullifier leaf, but merkle tree does not.... This is a bug!');
|
|
229
|
-
|
|
230
|
-
|
|
231
|
+
if (exists) {
|
|
232
|
+
this.log.debug(`Siloed nullifier ${siloedNullifier} exists at leafIndex=${leafIndex}`);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
231
235
|
// Sanity check that the leaf value is skipped by low leaf when it doesn't exist
|
|
232
236
|
assert(siloedNullifier.toBigInt() > leafPreimage.nullifier.toBigInt() &&
|
|
233
237
|
siloedNullifier.toBigInt() < leafPreimage.nextNullifier.toBigInt(), 'Nullifier tree low leaf should skip the target leaf nullifier when the target leaf does not exist.');
|
|
234
238
|
}
|
|
235
|
-
this.trace.traceNullifierCheck(
|
|
236
|
-
exists, leafPreimage, new Fr(leafIndex), leafPath);
|
|
239
|
+
this.trace.traceNullifierCheck(siloedNullifier, exists, leafPreimage, new Fr(leafIndex), leafPath);
|
|
237
240
|
}
|
|
238
241
|
else {
|
|
239
|
-
this.trace.traceNullifierCheck(
|
|
240
|
-
exists);
|
|
242
|
+
this.trace.traceNullifierCheck(siloedNullifier, exists);
|
|
241
243
|
}
|
|
242
244
|
return Promise.resolve(exists);
|
|
243
245
|
}
|
|
@@ -247,39 +249,53 @@ export class AvmPersistableStateManager {
|
|
|
247
249
|
* @param nullifier - the unsiloed nullifier to write
|
|
248
250
|
*/
|
|
249
251
|
async writeNullifier(contractAddress, nullifier) {
|
|
250
|
-
this.log.debug(`
|
|
252
|
+
this.log.debug(`Inserting new nullifier (address=${nullifier}, nullifier=${contractAddress})`);
|
|
251
253
|
const siloedNullifier = siloNullifier(contractAddress, nullifier);
|
|
254
|
+
await this.writeSiloedNullifier(siloedNullifier);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Write a nullifier to the nullifier set, trace the write.
|
|
258
|
+
* @param siloedNullifier - the siloed nullifier to write
|
|
259
|
+
*/
|
|
260
|
+
async writeSiloedNullifier(siloedNullifier) {
|
|
261
|
+
this.log.debug(`Inserting siloed nullifier=${siloedNullifier}`);
|
|
252
262
|
if (this.doMerkleOperations) {
|
|
253
263
|
// Maybe overkill, but we should check if the nullifier is already present in the tree before attempting to insert
|
|
254
264
|
// It might be better to catch the error from the insert operation
|
|
255
265
|
// Trace all nullifier creations, even duplicate insertions that fail
|
|
256
266
|
const { preimage, index, update } = await this.merkleTrees.getLeafOrLowLeafInfo(MerkleTreeId.NULLIFIER_TREE, siloedNullifier);
|
|
257
267
|
if (update) {
|
|
258
|
-
this.log.verbose(`
|
|
268
|
+
this.log.verbose(`Siloed nullifier ${siloedNullifier} already present in tree at index ${index}!`);
|
|
259
269
|
// If the nullifier is already present, we should not insert it again
|
|
260
270
|
// instead we provide the direct membership path
|
|
261
271
|
const path = await this.merkleTrees.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, index);
|
|
262
272
|
// This just becomes a nullifier read hint
|
|
263
|
-
this.trace.traceNullifierCheck(
|
|
273
|
+
this.trace.traceNullifierCheck(siloedNullifier,
|
|
264
274
|
/*exists=*/ update, preimage, new Fr(index), path);
|
|
265
|
-
throw new NullifierCollisionError(`
|
|
275
|
+
throw new NullifierCollisionError(`Siloed nullifier ${siloedNullifier} already exists in parent cache or host.`);
|
|
266
276
|
}
|
|
267
277
|
else {
|
|
268
278
|
// Cache pending nullifiers for later access
|
|
269
|
-
await this.nullifiers.append(
|
|
279
|
+
await this.nullifiers.append(siloedNullifier);
|
|
270
280
|
// We append the new nullifier
|
|
271
281
|
const appendResult = await this.merkleTrees.appendNullifier(siloedNullifier);
|
|
282
|
+
this.log.debug(`Nullifier tree root after insertion ${this.merkleTrees.treeMap.get(MerkleTreeId.NULLIFIER_TREE).getRoot()}`);
|
|
272
283
|
const lowLeafPreimage = appendResult.lowWitness.preimage;
|
|
273
284
|
const lowLeafIndex = appendResult.lowWitness.index;
|
|
274
285
|
const lowLeafPath = appendResult.lowWitness.siblingPath;
|
|
275
286
|
const insertionPath = appendResult.insertionPath;
|
|
276
|
-
this.trace.traceNewNullifier(
|
|
287
|
+
this.trace.traceNewNullifier(siloedNullifier, lowLeafPreimage, new Fr(lowLeafIndex), lowLeafPath, insertionPath);
|
|
277
288
|
}
|
|
278
289
|
}
|
|
279
290
|
else {
|
|
280
291
|
// Cache pending nullifiers for later access
|
|
281
|
-
await this.nullifiers.append(
|
|
282
|
-
this.trace.traceNewNullifier(
|
|
292
|
+
await this.nullifiers.append(siloedNullifier);
|
|
293
|
+
this.trace.traceNewNullifier(siloedNullifier);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async writeSiloedNullifiersFromPrivate(siloedNullifiers) {
|
|
297
|
+
for (const siloedNullifier of siloedNullifiers.filter(n => !n.isEmpty())) {
|
|
298
|
+
await this.writeSiloedNullifier(siloedNullifier);
|
|
283
299
|
}
|
|
284
300
|
}
|
|
285
301
|
/**
|
|
@@ -336,7 +352,7 @@ export class AvmPersistableStateManager {
|
|
|
336
352
|
// TODO: nullifier check!
|
|
337
353
|
if (exists) {
|
|
338
354
|
const instance = new SerializableContractInstance(instanceWithAddress);
|
|
339
|
-
this.log.debug(`Got contract instance (address=${contractAddress}): exists=${exists}, instance=${
|
|
355
|
+
this.log.debug(`Got contract instance (address=${contractAddress}): exists=${exists}, instance=${jsonStringify(instance)}`);
|
|
340
356
|
this.trace.traceGetContractInstance(contractAddress, exists, instance);
|
|
341
357
|
return Promise.resolve(instance);
|
|
342
358
|
}
|
|
@@ -356,11 +372,13 @@ export class AvmPersistableStateManager {
|
|
|
356
372
|
if (exists) {
|
|
357
373
|
const instance = new SerializableContractInstance(instanceWithAddress);
|
|
358
374
|
const contractClass = await this.worldStateDB.getContractClass(instance.contractClassId);
|
|
375
|
+
const bytecodeCommitment = await this.worldStateDB.getBytecodeCommitment(instance.contractClassId);
|
|
359
376
|
assert(contractClass, `Contract class not found in DB, but a contract instance was found with this class ID (${instance.contractClassId}). This should not happen!`);
|
|
377
|
+
assert(bytecodeCommitment, `Bytecode commitment was not found in DB for contract class (${instance.contractClassId}). This should not happen!`);
|
|
360
378
|
const contractClassPreimage = {
|
|
361
379
|
artifactHash: contractClass.artifactHash,
|
|
362
380
|
privateFunctionsRoot: contractClass.privateFunctionsRoot,
|
|
363
|
-
publicBytecodeCommitment:
|
|
381
|
+
publicBytecodeCommitment: bytecodeCommitment,
|
|
364
382
|
};
|
|
365
383
|
this.trace.traceGetBytecode(contractAddress, exists, contractClass.packedBytecode, instance, contractClassPreimage);
|
|
366
384
|
return contractClass.packedBytecode;
|
|
@@ -382,4 +400,4 @@ export class AvmPersistableStateManager {
|
|
|
382
400
|
this.trace.traceEnqueuedCall(publicCallRequest, calldata, reverted);
|
|
383
401
|
}
|
|
384
402
|
}
|
|
385
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam91cm5hbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdm0vam91cm5hbC9qb3VybmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNwRCxPQUFPLEVBTUwsNEJBQTRCLEVBQzVCLCtCQUErQixHQUNoQyxNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckcsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTFELE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUU1QixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUszRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFcEQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLE9BQU8sMEJBQTBCO0lBTXJDO0lBQ0UsZ0NBQWdDO0lBQ2YsWUFBMEI7SUFDM0Msd0JBQXdCO0lBQ3hCLCtEQUErRDtJQUMvQyxLQUFxQztJQUNyRCw4Q0FBOEM7SUFDN0IsZ0JBQStCLElBQUksYUFBYSxDQUFDLFlBQVksQ0FBQztJQUMvRSxrRUFBa0U7SUFDakQsYUFBK0IsSUFBSSxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsRUFDakUscUJBQThCLEtBQUs7SUFDcEQsaURBQWlEO0lBQ2pDLFdBQStCO1FBVjlCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBRzNCLFVBQUssR0FBTCxLQUFLLENB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
|
|
403
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam91cm5hbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdm0vam91cm5hbC9qb3VybmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNwRCxPQUFPLEVBTUwsNEJBQTRCLEdBQzdCLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLDZCQUE2QixFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTFELE9BQU8sRUFBRSxNQUFNLElBQUksTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRTFDLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBSzNFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sT0FBTywwQkFBMEI7SUFNckM7SUFDRSxnQ0FBZ0M7SUFDZixZQUEwQjtJQUMzQyx3QkFBd0I7SUFDeEIsK0RBQStEO0lBQy9DLEtBQXFDO0lBQ3JELDhDQUE4QztJQUM3QixnQkFBK0IsSUFBSSxhQUFhLENBQUMsWUFBWSxDQUFDO0lBQy9FLGtFQUFrRTtJQUNqRCxhQUErQixJQUFJLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxFQUNqRSxxQkFBOEIsS0FBSztJQUNwRCxpREFBaUQ7SUFDMUMsV0FBK0I7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
|
|
@@ -1,29 +1,28 @@
|
|
|
1
|
-
import { type AztecAddress } from '@aztec/circuits.js';
|
|
2
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
2
|
import type { CommitmentsDB } from '../../index.js';
|
|
4
3
|
/**
|
|
5
4
|
* A class to manage new nullifier staging and existence checks during a contract call's AVM simulation.
|
|
6
|
-
* Maintains a nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
5
|
+
* Maintains a siloed nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
7
6
|
* When a contract call completes, its cached nullifier set can be merged into its parent's.
|
|
8
7
|
*/
|
|
9
8
|
export declare class NullifierManager {
|
|
10
9
|
/** Reference to node storage. Checked on parent cache-miss. */
|
|
11
10
|
private readonly hostNullifiers;
|
|
12
|
-
/**
|
|
13
|
-
private
|
|
11
|
+
/** Cache of siloed nullifiers. */
|
|
12
|
+
private cache;
|
|
14
13
|
/** Parent nullifier manager to fall back on */
|
|
15
14
|
private readonly parent?;
|
|
16
15
|
constructor(
|
|
17
16
|
/** Reference to node storage. Checked on parent cache-miss. */
|
|
18
17
|
hostNullifiers: CommitmentsDB,
|
|
19
|
-
/**
|
|
20
|
-
cache?:
|
|
18
|
+
/** Cache of siloed nullifiers. */
|
|
19
|
+
cache?: Set<bigint>,
|
|
21
20
|
/** Parent nullifier manager to fall back on */
|
|
22
21
|
parent?: NullifierManager | undefined);
|
|
23
22
|
/**
|
|
24
23
|
* Create a new nullifiers manager with some preloaded pending siloed nullifiers
|
|
25
24
|
*/
|
|
26
|
-
static newWithPendingSiloedNullifiers(hostNullifiers: CommitmentsDB, pendingSiloedNullifiers
|
|
25
|
+
static newWithPendingSiloedNullifiers(hostNullifiers: CommitmentsDB, pendingSiloedNullifiers?: Fr[]): NullifierManager;
|
|
27
26
|
/**
|
|
28
27
|
* Create a new nullifiers manager forked from this one
|
|
29
28
|
*/
|
|
@@ -31,8 +30,7 @@ export declare class NullifierManager {
|
|
|
31
30
|
/**
|
|
32
31
|
* Get a nullifier's existence in this' cache or parent's (recursively).
|
|
33
32
|
* DOES NOT CHECK HOST STORAGE!
|
|
34
|
-
* @param
|
|
35
|
-
* @param nullifier - the nullifier to check for
|
|
33
|
+
* @param siloedNullifier - the nullifier to check for
|
|
36
34
|
* @returns exists: whether the nullifier exists in cache here or in parent's
|
|
37
35
|
*/
|
|
38
36
|
private checkExistsHereOrParent;
|
|
@@ -43,20 +41,18 @@ export declare class NullifierManager {
|
|
|
43
41
|
* 3. Fall back to the host state.
|
|
44
42
|
* 4. Not found! Nullifier does not exist.
|
|
45
43
|
*
|
|
46
|
-
* @param
|
|
47
|
-
* @param nullifier - the nullifier to check for
|
|
44
|
+
* @param siloedNullifier - the nullifier to check for
|
|
48
45
|
* @returns exists: whether the nullifier exists at all,
|
|
49
46
|
* isPending: whether the nullifier was found in a cache,
|
|
50
47
|
* leafIndex: the nullifier's leaf index if it exists and is not pending (comes from host state).
|
|
51
48
|
*/
|
|
52
|
-
checkExists(
|
|
49
|
+
checkExists(siloedNullifier: Fr): Promise<[/*exists=*/ boolean, /*isPending=*/ boolean, /*leafIndex=*/ Fr]>;
|
|
53
50
|
/**
|
|
54
51
|
* Stage a new nullifier (append it to the cache).
|
|
55
52
|
*
|
|
56
|
-
* @param
|
|
57
|
-
* @param nullifier - the nullifier to stage
|
|
53
|
+
* @param siloedNullifier - the nullifier to stage
|
|
58
54
|
*/
|
|
59
|
-
append(
|
|
55
|
+
append(siloedNullifier: Fr): Promise<void>;
|
|
60
56
|
/**
|
|
61
57
|
* Merges another nullifier cache into this one.
|
|
62
58
|
*
|
|
@@ -64,49 +60,6 @@ export declare class NullifierManager {
|
|
|
64
60
|
*/
|
|
65
61
|
acceptAndMerge(incomingNullifiers: NullifierManager): void;
|
|
66
62
|
}
|
|
67
|
-
/**
|
|
68
|
-
* A class to cache nullifiers created during a contract call's AVM simulation.
|
|
69
|
-
* "append" updates a map, "exists" checks that map.
|
|
70
|
-
* An instance of this class can merge another instance's cached nullifiers into its own.
|
|
71
|
-
*/
|
|
72
|
-
export declare class NullifierCache {
|
|
73
|
-
/**
|
|
74
|
-
* Map for staging nullifiers.
|
|
75
|
-
* One inner-set per contract storage address,
|
|
76
|
-
* each entry being a nullifier.
|
|
77
|
-
*/
|
|
78
|
-
private cachePerContract;
|
|
79
|
-
private siloedNullifiers;
|
|
80
|
-
/**
|
|
81
|
-
* @parem siloedNullifierFrs: optional list of pending siloed nullifiers to initialize this cache with
|
|
82
|
-
*/
|
|
83
|
-
constructor(siloedNullifierFrs?: Fr[]);
|
|
84
|
-
/**
|
|
85
|
-
* Check whether a nullifier exists in the cache.
|
|
86
|
-
*
|
|
87
|
-
* @param contractAddress - the address of the contract that the nullifier is associated with
|
|
88
|
-
* @param nullifier - the nullifier to check existence of
|
|
89
|
-
* @returns whether the nullifier is found in the cache
|
|
90
|
-
*/
|
|
91
|
-
exists(contractAddress: AztecAddress, nullifier: Fr): boolean;
|
|
92
|
-
/**
|
|
93
|
-
* Stage a new nullifier (append it to the cache).
|
|
94
|
-
*
|
|
95
|
-
* @param contractAddress - the address of the contract that the nullifier is associated with
|
|
96
|
-
* @param nullifier - the nullifier to stage
|
|
97
|
-
*/
|
|
98
|
-
append(contractAddress: AztecAddress, nullifier: Fr): void;
|
|
99
|
-
/**
|
|
100
|
-
* Merge another cache's nullifiers into this instance's.
|
|
101
|
-
*
|
|
102
|
-
* Cached nullifiers in "incoming" must not collide with any present in "this".
|
|
103
|
-
*
|
|
104
|
-
* In practice, "this" is a parent call's pending nullifiers, and "incoming" is a nested call's.
|
|
105
|
-
*
|
|
106
|
-
* @param incomingNullifiers - the incoming cached nullifiers to merge into this instance's
|
|
107
|
-
*/
|
|
108
|
-
acceptAndMerge(incomingNullifiers: NullifierCache): void;
|
|
109
|
-
}
|
|
110
63
|
export declare class NullifierCollisionError extends Error {
|
|
111
64
|
constructor(message: string, ...rest: any[]);
|
|
112
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nullifiers.d.ts","sourceRoot":"","sources":["../../../src/avm/journal/nullifiers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"nullifiers.d.ts","sourceRoot":"","sources":["../../../src/avm/journal/nullifiers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;;GAIG;AACH,qBAAa,gBAAgB;IAEzB,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,kCAAkC;IAClC,OAAO,CAAC,KAAK;IACb,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;;IALxB,+DAA+D;IAC9C,cAAc,EAAE,aAAa;IAC9C,kCAAkC;IAC1B,KAAK,GAAE,GAAG,CAAC,MAAM,CAAa;IACtC,+CAA+C;IAC9B,MAAM,CAAC,8BAAkB;IAG5C;;OAEG;WACW,8BAA8B,CAAC,cAAc,EAAE,aAAa,EAAE,uBAAuB,CAAC,EAAE,EAAE,EAAE;IAQ1G;;OAEG;IACI,IAAI;IAIX;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAW/B;;;;;;;;;;;OAWG;IACU,WAAW,CACtB,eAAe,EAAE,EAAE,GAClB,OAAO,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IAe5E;;;;OAIG;IACU,MAAM,CAAC,eAAe,EAAE,EAAE;IAQvC;;;;OAIG;IACI,cAAc,CAAC,kBAAkB,EAAE,gBAAgB;CAU3D;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;CAI5C"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { siloNullifier } from '@aztec/circuits.js/hash';
|
|
2
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
2
|
/**
|
|
4
3
|
* A class to manage new nullifier staging and existence checks during a contract call's AVM simulation.
|
|
5
|
-
* Maintains a nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
4
|
+
* Maintains a siloed nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
6
5
|
* When a contract call completes, its cached nullifier set can be merged into its parent's.
|
|
7
6
|
*/
|
|
8
7
|
export class NullifierManager {
|
|
9
8
|
constructor(
|
|
10
9
|
/** Reference to node storage. Checked on parent cache-miss. */
|
|
11
10
|
hostNullifiers,
|
|
12
|
-
/**
|
|
13
|
-
cache = new
|
|
11
|
+
/** Cache of siloed nullifiers. */
|
|
12
|
+
cache = new Set(),
|
|
14
13
|
/** Parent nullifier manager to fall back on */
|
|
15
14
|
parent) {
|
|
16
15
|
this.hostNullifiers = hostNullifiers;
|
|
@@ -21,29 +20,31 @@ export class NullifierManager {
|
|
|
21
20
|
* Create a new nullifiers manager with some preloaded pending siloed nullifiers
|
|
22
21
|
*/
|
|
23
22
|
static newWithPendingSiloedNullifiers(hostNullifiers, pendingSiloedNullifiers) {
|
|
24
|
-
const
|
|
25
|
-
|
|
23
|
+
const cachedSiloedNullifiers = new Set();
|
|
24
|
+
if (pendingSiloedNullifiers !== undefined) {
|
|
25
|
+
pendingSiloedNullifiers.forEach(nullifier => cachedSiloedNullifiers.add(nullifier.toBigInt()));
|
|
26
|
+
}
|
|
27
|
+
return new NullifierManager(hostNullifiers, cachedSiloedNullifiers);
|
|
26
28
|
}
|
|
27
29
|
/**
|
|
28
30
|
* Create a new nullifiers manager forked from this one
|
|
29
31
|
*/
|
|
30
32
|
fork() {
|
|
31
|
-
return new NullifierManager(this.hostNullifiers, new
|
|
33
|
+
return new NullifierManager(this.hostNullifiers, new Set(), this);
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
34
36
|
* Get a nullifier's existence in this' cache or parent's (recursively).
|
|
35
37
|
* DOES NOT CHECK HOST STORAGE!
|
|
36
|
-
* @param
|
|
37
|
-
* @param nullifier - the nullifier to check for
|
|
38
|
+
* @param siloedNullifier - the nullifier to check for
|
|
38
39
|
* @returns exists: whether the nullifier exists in cache here or in parent's
|
|
39
40
|
*/
|
|
40
|
-
checkExistsHereOrParent(
|
|
41
|
+
checkExistsHereOrParent(siloedNullifier) {
|
|
41
42
|
// First check this cache
|
|
42
|
-
let existsAsPending = this.cache.
|
|
43
|
+
let existsAsPending = this.cache.has(siloedNullifier.toBigInt());
|
|
43
44
|
// Then try parent's nullifier cache
|
|
44
45
|
if (!existsAsPending && this.parent) {
|
|
45
46
|
// Note: this will recurse to grandparent/etc until a cache-hit is encountered.
|
|
46
|
-
existsAsPending = this.parent.checkExistsHereOrParent(
|
|
47
|
+
existsAsPending = this.parent.checkExistsHereOrParent(siloedNullifier);
|
|
47
48
|
}
|
|
48
49
|
return existsAsPending;
|
|
49
50
|
}
|
|
@@ -54,21 +55,20 @@ export class NullifierManager {
|
|
|
54
55
|
* 3. Fall back to the host state.
|
|
55
56
|
* 4. Not found! Nullifier does not exist.
|
|
56
57
|
*
|
|
57
|
-
* @param
|
|
58
|
-
* @param nullifier - the nullifier to check for
|
|
58
|
+
* @param siloedNullifier - the nullifier to check for
|
|
59
59
|
* @returns exists: whether the nullifier exists at all,
|
|
60
60
|
* isPending: whether the nullifier was found in a cache,
|
|
61
61
|
* leafIndex: the nullifier's leaf index if it exists and is not pending (comes from host state).
|
|
62
62
|
*/
|
|
63
|
-
async checkExists(
|
|
63
|
+
async checkExists(siloedNullifier) {
|
|
64
64
|
// Check this cache and parent's (recursively)
|
|
65
|
-
const existsAsPending = this.checkExistsHereOrParent(
|
|
65
|
+
const existsAsPending = this.checkExistsHereOrParent(siloedNullifier);
|
|
66
66
|
// Finally try the host's Aztec state (a trip to the database)
|
|
67
67
|
// If the value is found in the database, it will be associated with a leaf index!
|
|
68
68
|
let leafIndex = undefined;
|
|
69
69
|
if (!existsAsPending) {
|
|
70
70
|
// silo the nullifier before checking for its existence in the host
|
|
71
|
-
leafIndex = await this.hostNullifiers.getNullifierIndex(
|
|
71
|
+
leafIndex = await this.hostNullifiers.getNullifierIndex(siloedNullifier);
|
|
72
72
|
}
|
|
73
73
|
const exists = existsAsPending || leafIndex !== undefined;
|
|
74
74
|
leafIndex = leafIndex === undefined ? BigInt(0) : leafIndex;
|
|
@@ -77,15 +77,14 @@ export class NullifierManager {
|
|
|
77
77
|
/**
|
|
78
78
|
* Stage a new nullifier (append it to the cache).
|
|
79
79
|
*
|
|
80
|
-
* @param
|
|
81
|
-
* @param nullifier - the nullifier to stage
|
|
80
|
+
* @param siloedNullifier - the nullifier to stage
|
|
82
81
|
*/
|
|
83
|
-
async append(
|
|
84
|
-
const [exists, ,] = await this.checkExists(
|
|
82
|
+
async append(siloedNullifier) {
|
|
83
|
+
const [exists, ,] = await this.checkExists(siloedNullifier);
|
|
85
84
|
if (exists) {
|
|
86
|
-
throw new NullifierCollisionError(`
|
|
85
|
+
throw new NullifierCollisionError(`Siloed nullifier ${siloedNullifier} already exists in parent cache or host.`);
|
|
87
86
|
}
|
|
88
|
-
this.cache.
|
|
87
|
+
this.cache.add(siloedNullifier.toBigInt());
|
|
89
88
|
}
|
|
90
89
|
/**
|
|
91
90
|
* Merges another nullifier cache into this one.
|
|
@@ -93,91 +92,12 @@ export class NullifierManager {
|
|
|
93
92
|
* @param incomingNullifiers - the incoming cached nullifiers to merge into this instance's
|
|
94
93
|
*/
|
|
95
94
|
acceptAndMerge(incomingNullifiers) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* A class to cache nullifiers created during a contract call's AVM simulation.
|
|
101
|
-
* "append" updates a map, "exists" checks that map.
|
|
102
|
-
* An instance of this class can merge another instance's cached nullifiers into its own.
|
|
103
|
-
*/
|
|
104
|
-
export class NullifierCache {
|
|
105
|
-
/**
|
|
106
|
-
* @parem siloedNullifierFrs: optional list of pending siloed nullifiers to initialize this cache with
|
|
107
|
-
*/
|
|
108
|
-
constructor(siloedNullifierFrs) {
|
|
109
|
-
/**
|
|
110
|
-
* Map for staging nullifiers.
|
|
111
|
-
* One inner-set per contract storage address,
|
|
112
|
-
* each entry being a nullifier.
|
|
113
|
-
*/
|
|
114
|
-
this.cachePerContract = new Map();
|
|
115
|
-
this.siloedNullifiers = new Set();
|
|
116
|
-
if (siloedNullifierFrs !== undefined) {
|
|
117
|
-
siloedNullifierFrs.forEach(nullifier => this.siloedNullifiers.add(nullifier.toBigInt()));
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Check whether a nullifier exists in the cache.
|
|
122
|
-
*
|
|
123
|
-
* @param contractAddress - the address of the contract that the nullifier is associated with
|
|
124
|
-
* @param nullifier - the nullifier to check existence of
|
|
125
|
-
* @returns whether the nullifier is found in the cache
|
|
126
|
-
*/
|
|
127
|
-
exists(contractAddress, nullifier) {
|
|
128
|
-
const exists = this.cachePerContract.get(contractAddress.toBigInt())?.has(nullifier.toBigInt()) ||
|
|
129
|
-
this.siloedNullifiers.has(siloNullifier(contractAddress, nullifier).toBigInt());
|
|
130
|
-
return !!exists;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Stage a new nullifier (append it to the cache).
|
|
134
|
-
*
|
|
135
|
-
* @param contractAddress - the address of the contract that the nullifier is associated with
|
|
136
|
-
* @param nullifier - the nullifier to stage
|
|
137
|
-
*/
|
|
138
|
-
append(contractAddress, nullifier) {
|
|
139
|
-
if (this.exists(contractAddress, nullifier)) {
|
|
140
|
-
throw new NullifierCollisionError(`Nullifier ${nullifier} at contract ${contractAddress} already exists in cache.`);
|
|
141
|
-
}
|
|
142
|
-
let nullifiersForContract = this.cachePerContract.get(contractAddress.toBigInt());
|
|
143
|
-
// If this contract's nullifier set has no cached nullifiers, create a new Set to store them
|
|
144
|
-
if (!nullifiersForContract) {
|
|
145
|
-
nullifiersForContract = new Set();
|
|
146
|
-
this.cachePerContract.set(contractAddress.toBigInt(), nullifiersForContract);
|
|
147
|
-
}
|
|
148
|
-
nullifiersForContract.add(nullifier.toBigInt());
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Merge another cache's nullifiers into this instance's.
|
|
152
|
-
*
|
|
153
|
-
* Cached nullifiers in "incoming" must not collide with any present in "this".
|
|
154
|
-
*
|
|
155
|
-
* In practice, "this" is a parent call's pending nullifiers, and "incoming" is a nested call's.
|
|
156
|
-
*
|
|
157
|
-
* @param incomingNullifiers - the incoming cached nullifiers to merge into this instance's
|
|
158
|
-
*/
|
|
159
|
-
acceptAndMerge(incomingNullifiers) {
|
|
160
|
-
// Merge siloed nullifiers.
|
|
161
|
-
this.siloedNullifiers = new Set([...this.siloedNullifiers, ...incomingNullifiers.siloedNullifiers]);
|
|
162
|
-
// Iterate over all contracts with staged writes in the child.
|
|
163
|
-
for (const [incomingAddress, incomingCacheAtContract] of incomingNullifiers.cachePerContract) {
|
|
164
|
-
const thisCacheAtContract = this.cachePerContract.get(incomingAddress);
|
|
165
|
-
if (!thisCacheAtContract) {
|
|
166
|
-
// This contract has no nullifiers cached here
|
|
167
|
-
// so just accept incoming cache as-is for this contract.
|
|
168
|
-
this.cachePerContract.set(incomingAddress, incomingCacheAtContract);
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
// "Incoming" and "this" both have cached nullifiers for this contract.
|
|
172
|
-
// Merge in incoming nullifiers, erroring if there are any duplicates.
|
|
173
|
-
for (const nullifier of incomingCacheAtContract) {
|
|
174
|
-
if (thisCacheAtContract.has(nullifier)) {
|
|
175
|
-
throw new NullifierCollisionError(`Failed to accept child call's nullifiers. Nullifier ${nullifier} already exists at contract ${incomingAddress}.`);
|
|
176
|
-
}
|
|
177
|
-
thisCacheAtContract.add(nullifier);
|
|
178
|
-
}
|
|
95
|
+
for (const incomingNullifier of incomingNullifiers.cache) {
|
|
96
|
+
if (this.cache.has(incomingNullifier)) {
|
|
97
|
+
throw new NullifierCollisionError(`Failed to merge in fork's cached nullifiers. Siloed nullifier ${incomingNullifier} already exists in parent cache.`);
|
|
179
98
|
}
|
|
180
99
|
}
|
|
100
|
+
this.cache = new Set([...this.cache, ...incomingNullifiers.cache]);
|
|
181
101
|
}
|
|
182
102
|
}
|
|
183
103
|
export class NullifierCollisionError extends Error {
|
|
@@ -186,4 +106,4 @@ export class NullifierCollisionError extends Error {
|
|
|
186
106
|
this.name = 'NullifierCollisionError';
|
|
187
107
|
}
|
|
188
108
|
}
|
|
189
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
109
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVsbGlmaWVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdm0vam91cm5hbC9udWxsaWZpZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUk5Qzs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLGdCQUFnQjtJQUMzQjtJQUNFLCtEQUErRDtJQUM5QyxjQUE2QjtJQUM5QyxrQ0FBa0M7SUFDMUIsUUFBcUIsSUFBSSxHQUFHLEVBQUU7SUFDdEMsK0NBQStDO0lBQzlCLE1BQXlCO1FBSnpCLG1CQUFjLEdBQWQsY0FBYyxDQUFlO1FBRXRDLFVBQUssR0FBTCxLQUFLLENBQXlCO1FBRXJCLFdBQU0sR0FBTixNQUFNLENBQW1CO0lBQ3pDLENBQUM7SUFFSjs7T0FFRztJQUNJLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxjQUE2QixFQUFFLHVCQUE4QjtRQUN4RyxNQUFNLHNCQUFzQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDakQsSUFBSSx1QkFBdUIsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMxQyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqRyxDQUFDO1FBQ0QsT0FBTyxJQUFJLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7T0FFRztJQUNJLElBQUk7UUFDVCxPQUFPLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLHVCQUF1QixDQUFDLGVBQW1CO1FBQ2pELHlCQUF5QjtRQUN6QixJQUFJLGVBQWUsR0FBRyxJQUFJ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
|
|
@@ -8,14 +8,14 @@ export declare enum ContractInstanceMember {
|
|
|
8
8
|
}
|
|
9
9
|
export declare class GetContractInstance extends Instruction {
|
|
10
10
|
private indirect;
|
|
11
|
-
private memberEnum;
|
|
12
11
|
private addressOffset;
|
|
13
12
|
private dstOffset;
|
|
14
13
|
private existsOffset;
|
|
14
|
+
private memberEnum;
|
|
15
15
|
static readonly type: string;
|
|
16
16
|
static readonly opcode: Opcode;
|
|
17
17
|
static readonly wireFormat: OperandType[];
|
|
18
|
-
constructor(indirect: number,
|
|
18
|
+
constructor(indirect: number, addressOffset: number, dstOffset: number, existsOffset: number, memberEnum: number);
|
|
19
19
|
execute(context: AvmContext): Promise<void>;
|
|
20
20
|
}
|
|
21
21
|
//# sourceMappingURL=contract.d.ts.map
|