@aztec/simulator 0.80.0 → 0.82.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/common/db_interfaces.d.ts +30 -17
- package/dest/common/db_interfaces.d.ts.map +1 -1
- package/dest/common/db_interfaces.js +1 -1
- package/dest/common/debug_fn_name.d.ts +2 -2
- package/dest/common/debug_fn_name.d.ts.map +1 -1
- package/dest/common/message_load_oracle_inputs.d.ts +4 -0
- package/dest/common/message_load_oracle_inputs.d.ts.map +1 -1
- package/dest/common/message_load_oracle_inputs.js +9 -0
- package/dest/private/acvm/acvm.d.ts +6 -1
- package/dest/private/acvm/acvm.d.ts.map +1 -1
- package/dest/private/acvm/acvm.js +7 -13
- package/dest/private/acvm/deserialize.d.ts +19 -18
- package/dest/private/acvm/deserialize.d.ts.map +1 -1
- package/dest/private/acvm/deserialize.js +31 -23
- package/dest/private/acvm/oracle/oracle.d.ts +36 -34
- package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/oracle.js +134 -79
- package/dest/private/acvm/oracle/typed_oracle.d.ts +3 -2
- package/dest/private/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/typed_oracle.js +5 -2
- package/dest/private/acvm/serialize.d.ts +11 -0
- package/dest/private/acvm/serialize.d.ts.map +1 -1
- package/dest/private/acvm/serialize.js +27 -0
- package/dest/private/execution_data_provider.d.ts +15 -13
- package/dest/private/execution_data_provider.d.ts.map +1 -1
- package/dest/private/private_execution.d.ts +2 -2
- package/dest/private/private_execution.d.ts.map +1 -1
- package/dest/private/private_execution.js +4 -5
- package/dest/private/private_execution_oracle.d.ts.map +1 -1
- package/dest/private/private_execution_oracle.js +1 -1
- package/dest/private/providers/acvm_native.d.ts +6 -4
- package/dest/private/providers/acvm_native.d.ts.map +1 -1
- package/dest/private/providers/acvm_native.js +6 -3
- package/dest/private/providers/acvm_wasm.d.ts +6 -7
- package/dest/private/providers/acvm_wasm.d.ts.map +1 -1
- package/dest/private/providers/acvm_wasm.js +13 -15
- package/dest/private/providers/acvm_wasm_with_blobs.d.ts +5 -5
- package/dest/private/providers/acvm_wasm_with_blobs.d.ts.map +1 -1
- package/dest/private/providers/acvm_wasm_with_blobs.js +7 -9
- package/dest/private/providers/circuit_recording/circuit_recorder.d.ts +90 -0
- package/dest/private/providers/circuit_recording/circuit_recorder.d.ts.map +1 -0
- package/dest/private/providers/circuit_recording/circuit_recorder.js +246 -0
- package/dest/private/providers/circuit_recording/simulation_provider_recorder_wrapper.d.ts +18 -0
- package/dest/private/providers/circuit_recording/simulation_provider_recorder_wrapper.d.ts.map +1 -0
- package/dest/private/providers/circuit_recording/simulation_provider_recorder_wrapper.js +39 -0
- package/dest/private/providers/simulation_provider.d.ts +21 -7
- package/dest/private/providers/simulation_provider.d.ts.map +1 -1
- package/dest/private/simulator.d.ts +3 -2
- package/dest/private/simulator.d.ts.map +1 -1
- package/dest/private/simulator.js +2 -2
- package/dest/private/unconstrained_execution.d.ts +2 -2
- package/dest/private/unconstrained_execution.d.ts.map +1 -1
- package/dest/private/unconstrained_execution.js +1 -2
- package/dest/private/unconstrained_execution_oracle.d.ts +5 -3
- package/dest/private/unconstrained_execution_oracle.d.ts.map +1 -1
- package/dest/private/unconstrained_execution_oracle.js +9 -5
- package/dest/public/avm/avm_simulator.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.js +0 -2
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.js +5 -5
- package/dest/public/avm/fixtures/index.d.ts +4 -4
- package/dest/public/avm/fixtures/index.d.ts.map +1 -1
- package/dest/public/avm/fixtures/index.js +9 -6
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts +1 -2
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts.map +1 -1
- package/dest/public/avm/fixtures/simple_contract_data_source.js +0 -3
- package/dest/public/avm/journal/journal.d.ts +16 -70
- package/dest/public/avm/journal/journal.d.ts.map +1 -1
- package/dest/public/avm/journal/journal.js +88 -210
- package/dest/public/avm/journal/nullifiers.d.ts +2 -2
- package/dest/public/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/public/avm/journal/public_storage.d.ts +2 -2
- package/dest/public/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/public/avm/test_utils.d.ts +10 -13
- package/dest/public/avm/test_utils.d.ts.map +1 -1
- package/dest/public/avm/test_utils.js +8 -13
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +3 -3
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +10 -9
- package/dest/public/hinting_db_sources.d.ts +19 -0
- package/dest/public/hinting_db_sources.d.ts.map +1 -0
- package/dest/public/hinting_db_sources.js +36 -0
- package/dest/public/public_db_sources.d.ts +46 -22
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +82 -27
- package/dest/public/public_processor/public_processor.d.ts +5 -5
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +21 -20
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +9 -14
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +15 -19
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +9 -6
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +28 -14
- package/dest/public/side_effect_trace.d.ts +6 -22
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +11 -70
- package/dest/public/side_effect_trace_interface.d.ts +5 -19
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/testing.d.ts +2 -0
- package/dest/testing.d.ts.map +1 -0
- package/dest/testing.js +1 -0
- package/package.json +15 -14
- package/src/common/db_interfaces.ts +32 -18
- package/src/common/debug_fn_name.ts +2 -2
- package/src/common/message_load_oracle_inputs.ts +8 -0
- package/src/private/acvm/acvm.ts +8 -24
- package/src/private/acvm/deserialize.ts +35 -29
- package/src/private/acvm/oracle/oracle.ts +171 -129
- package/src/private/acvm/oracle/typed_oracle.ts +7 -3
- package/src/private/acvm/serialize.ts +28 -0
- package/src/private/execution_data_provider.ts +19 -14
- package/src/private/private_execution.ts +11 -7
- package/src/private/private_execution_oracle.ts +5 -1
- package/src/private/providers/acvm_native.ts +17 -6
- package/src/private/providers/acvm_wasm.ts +27 -20
- package/src/private/providers/acvm_wasm_with_blobs.ts +15 -12
- package/src/private/providers/circuit_recording/circuit_recorder.ts +283 -0
- package/src/private/providers/circuit_recording/simulation_provider_recorder_wrapper.ts +82 -0
- package/src/private/providers/simulation_provider.ts +30 -5
- package/src/private/simulator.ts +5 -3
- package/src/private/unconstrained_execution.ts +8 -4
- package/src/private/unconstrained_execution_oracle.ts +15 -9
- package/src/public/avm/avm_simulator.ts +0 -2
- package/src/public/avm/fixtures/avm_simulation_tester.ts +8 -5
- package/src/public/avm/fixtures/index.ts +16 -10
- package/src/public/avm/fixtures/simple_contract_data_source.ts +1 -10
- package/src/public/avm/journal/journal.ts +119 -353
- package/src/public/avm/journal/nullifiers.ts +2 -2
- package/src/public/avm/journal/public_storage.ts +2 -2
- package/src/public/avm/test_utils.ts +20 -29
- package/src/public/fixtures/public_tx_simulation_tester.ts +9 -12
- package/src/public/hinting_db_sources.ts +71 -0
- package/src/public/public_db_sources.ts +134 -32
- package/src/public/public_processor/public_processor.ts +22 -21
- package/src/public/public_tx_simulator/public_tx_context.ts +30 -38
- package/src/public/public_tx_simulator/public_tx_simulator.ts +47 -17
- package/src/public/side_effect_trace.ts +8 -172
- package/src/public/side_effect_trace_interface.ts +4 -55
- package/src/testing.ts +1 -0
- package/dest/public/avm/bytecode_utils.d.ts +0 -5
- package/dest/public/avm/bytecode_utils.d.ts.map +0 -1
- package/dest/public/avm/bytecode_utils.js +0 -17
- package/src/public/avm/bytecode_utils.ts +0 -17
|
@@ -4,14 +4,13 @@ import { Fr } from '@aztec/foundation/fields';
|
|
|
4
4
|
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
6
6
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
7
|
-
import {
|
|
7
|
+
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
8
8
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
9
|
import { SerializableContractInstance } from '@aztec/stdlib/contract';
|
|
10
10
|
import { computeNoteHashNonce, computePublicDataTreeLeafSlot, computeUniqueNoteHash, siloNoteHash, siloNullifier } from '@aztec/stdlib/hash';
|
|
11
11
|
import { SharedMutableValues, SharedMutableValuesWithHash } from '@aztec/stdlib/shared-mutable';
|
|
12
12
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
13
13
|
import { strict as assert } from 'assert';
|
|
14
|
-
import cloneDeep from 'lodash.clonedeep';
|
|
15
14
|
import { getPublicFunctionDebugName } from '../../../common/debug_fn_name.js';
|
|
16
15
|
import { NullifierCollisionError, NullifierManager } from './nullifiers.js';
|
|
17
16
|
import { PublicStorage } from './public_storage.js';
|
|
@@ -24,39 +23,43 @@ import { PublicStorage } from './public_storage.js';
|
|
|
24
23
|
*
|
|
25
24
|
* Manages merging of successful/reverted child state into current state.
|
|
26
25
|
*/ export class AvmPersistableStateManager {
|
|
27
|
-
|
|
26
|
+
treesDB;
|
|
27
|
+
contractsDB;
|
|
28
28
|
trace;
|
|
29
|
+
firstNullifier;
|
|
30
|
+
blockNumber;
|
|
31
|
+
doMerkleOperations;
|
|
29
32
|
publicStorage;
|
|
30
33
|
nullifiers;
|
|
31
|
-
doMerkleOperations;
|
|
32
|
-
db;
|
|
33
|
-
firstNullifier;
|
|
34
34
|
log;
|
|
35
35
|
/** Make sure a forked state is never merged twice. */ alreadyMergedIntoParent;
|
|
36
|
-
constructor(
|
|
37
|
-
|
|
38
|
-
this.
|
|
36
|
+
constructor(treesDB, contractsDB, trace, firstNullifier, blockNumber, doMerkleOperations = false, publicStorage = new PublicStorage(treesDB), nullifiers = new NullifierManager(treesDB)){
|
|
37
|
+
this.treesDB = treesDB;
|
|
38
|
+
this.contractsDB = contractsDB;
|
|
39
39
|
this.trace = trace;
|
|
40
|
+
this.firstNullifier = firstNullifier;
|
|
41
|
+
this.blockNumber = blockNumber;
|
|
42
|
+
this.doMerkleOperations = doMerkleOperations;
|
|
40
43
|
this.publicStorage = publicStorage;
|
|
41
44
|
this.nullifiers = nullifiers;
|
|
42
|
-
this.doMerkleOperations = doMerkleOperations;
|
|
43
|
-
this.db = db;
|
|
44
|
-
this.firstNullifier = firstNullifier;
|
|
45
45
|
this.log = createLogger('simulator:avm:state_manager');
|
|
46
46
|
this.alreadyMergedIntoParent = false;
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* Create a new state manager
|
|
50
|
-
*/ static create(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
*/ static create(treesDB, contractsDB, trace, doMerkleOperations = false, firstNullifier, blockNumber) {
|
|
51
|
+
return new AvmPersistableStateManager(treesDB, contractsDB, trace, firstNullifier, blockNumber, doMerkleOperations);
|
|
52
|
+
}
|
|
53
|
+
// DO NOT USE!
|
|
54
|
+
// FIXME(fcarreiro): refactor and remove this.
|
|
55
|
+
deprecatedGetTreesForPIGeneration() {
|
|
56
|
+
return this.treesDB;
|
|
54
57
|
}
|
|
55
58
|
/**
|
|
56
59
|
* Create a new state manager forked from this one
|
|
57
60
|
*/ async fork() {
|
|
58
|
-
await this.
|
|
59
|
-
return new AvmPersistableStateManager(this.
|
|
61
|
+
await this.treesDB.createCheckpoint();
|
|
62
|
+
return new AvmPersistableStateManager(this.treesDB, this.contractsDB, this.trace.fork(), this.firstNullifier, this.blockNumber, this.doMerkleOperations, this.publicStorage.fork(), this.nullifiers.fork());
|
|
60
63
|
}
|
|
61
64
|
/**
|
|
62
65
|
* Accept forked world state modifications & traced side effects / hints
|
|
@@ -76,13 +79,13 @@ import { PublicStorage } from './public_storage.js';
|
|
|
76
79
|
this.nullifiers.acceptAndMerge(forkedState.nullifiers);
|
|
77
80
|
this.trace.merge(forkedState.trace, reverted);
|
|
78
81
|
if (reverted) {
|
|
79
|
-
await this.
|
|
82
|
+
await this.treesDB.revertCheckpoint();
|
|
80
83
|
if (this.doMerkleOperations) {
|
|
81
|
-
this.log.trace(`Rolled back nullifier tree to root ${new Fr((await this.
|
|
84
|
+
this.log.trace(`Rolled back nullifier tree to root ${new Fr((await this.treesDB.getTreeInfo(MerkleTreeId.NULLIFIER_TREE)).root)}`);
|
|
82
85
|
}
|
|
83
86
|
} else {
|
|
84
87
|
this.log.trace('Merging forked state into parent...');
|
|
85
|
-
await this.
|
|
88
|
+
await this.treesDB.commitCheckpoint();
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
/**
|
|
@@ -97,89 +100,34 @@ import { PublicStorage } from './public_storage.js';
|
|
|
97
100
|
if (this.doMerkleOperations) {
|
|
98
101
|
// write to native merkle trees
|
|
99
102
|
const publicDataWrite = new PublicDataWrite(leafSlot, value);
|
|
100
|
-
const result = await this.
|
|
103
|
+
const result = await this.treesDB.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, [
|
|
101
104
|
publicDataWrite.toBuffer()
|
|
102
105
|
]);
|
|
103
106
|
assert(result !== undefined, 'Public data tree insertion error. You might want to disable doMerkleOperations.');
|
|
104
107
|
this.log.trace(`Inserted public data tree leaf at leafSlot ${leafSlot}, value: ${value}`);
|
|
105
|
-
// low leaf hint
|
|
106
|
-
const lowLeafPreimage = result.lowLeavesWitnessData[0].leafPreimage;
|
|
107
|
-
const lowLeafIndex = result.lowLeavesWitnessData[0].index;
|
|
108
|
-
const lowLeafPath = result.lowLeavesWitnessData[0].siblingPath.toFields();
|
|
109
|
-
// new leaf insertion
|
|
110
|
-
const newLeafPreimage = cloneDeep(lowLeafPreimage);
|
|
111
|
-
let insertionPath;
|
|
112
|
-
if (result.insertionWitnessData.length === 0) {
|
|
113
|
-
assert(newLeafPreimage.value.equals(value), `Value mismatch when performing public data write (got value: ${value}, value in tree: ${newLeafPreimage.value})`);
|
|
114
|
-
} else {
|
|
115
|
-
// The new leaf preimage should have the new value and slot
|
|
116
|
-
newLeafPreimage.slot = leafSlot;
|
|
117
|
-
newLeafPreimage.value = value;
|
|
118
|
-
// TODO: is this necessary?! Why doesn't sequentialInsert return the newLeafPreimage via
|
|
119
|
-
// result.insertionWitnessData[0].leafPreimage?
|
|
120
|
-
this.log.trace(`newLeafPreimage.slot: ${newLeafPreimage.slot}, newLeafPreimage.value: ${newLeafPreimage.value}, insertionIndex: ${result.insertionWitnessData[0].index}`);
|
|
121
|
-
insertionPath = result.insertionWitnessData[0].siblingPath.toFields();
|
|
122
|
-
}
|
|
123
|
-
await this.trace.tracePublicStorageWrite(contractAddress, slot, value, protocolWrite, lowLeafPreimage, new Fr(lowLeafIndex), lowLeafPath, newLeafPreimage, insertionPath);
|
|
124
108
|
} else {
|
|
125
109
|
// Cache storage writes for later reference/reads
|
|
126
110
|
this.publicStorage.write(contractAddress, slot, value);
|
|
127
|
-
await this.trace.tracePublicStorageWrite(contractAddress, slot, value, protocolWrite);
|
|
128
111
|
}
|
|
112
|
+
await this.trace.tracePublicStorageWrite(contractAddress, slot, value, protocolWrite);
|
|
129
113
|
}
|
|
130
114
|
/**
|
|
131
|
-
* Read from public storage
|
|
115
|
+
* Read from public storage.
|
|
132
116
|
*
|
|
133
117
|
* @param contractAddress - the address of the contract whose storage is being read from
|
|
134
118
|
* @param slot - the slot in the contract's storage being read from
|
|
135
119
|
* @returns the latest value written to slot, or 0 if never written to before
|
|
136
120
|
*/ async readStorage(contractAddress, slot) {
|
|
137
121
|
if (this.doMerkleOperations) {
|
|
138
|
-
const
|
|
139
|
-
this.trace.tracePublicStorageRead(contractAddress, slot, value, leafPreimage, leafIndex, leafPath);
|
|
122
|
+
const value = await this.treesDB.storageRead(contractAddress, slot);
|
|
140
123
|
return value;
|
|
141
124
|
} else {
|
|
125
|
+
// TODO(fcarreiro): I don't get this. PublicStorage CAN end up reading the tree. Why is it in the "dont do merkle operations" branch?
|
|
142
126
|
const read = await this.publicStorage.read(contractAddress, slot);
|
|
143
127
|
this.log.trace(`Storage read results (address=${contractAddress}, slot=${slot}): value=${read.value}, cached=${read.cached}`);
|
|
144
|
-
this.trace.tracePublicStorageRead(contractAddress, slot, read.value);
|
|
145
128
|
return read.value;
|
|
146
129
|
}
|
|
147
130
|
}
|
|
148
|
-
async getPublicDataMembership(contractAddress, slot) {
|
|
149
|
-
const leafSlot = await computePublicDataTreeLeafSlot(contractAddress, slot);
|
|
150
|
-
const treeId = MerkleTreeId.PUBLIC_DATA_TREE;
|
|
151
|
-
// Get leaf if present, low leaf if absent
|
|
152
|
-
// If leaf is present, hint/trace it. Otherwise, hint/trace the low leaf.
|
|
153
|
-
const { preimage, leafOrLowLeafIndex, alreadyPresent } = await this.getLeafOrLowLeafInfo(treeId, leafSlot.toBigInt());
|
|
154
|
-
// The index and preimage here is either the low leaf or the leaf itself (depending on the value of update flag)
|
|
155
|
-
// In either case, we just want the sibling path to this leaf - it's up to the avm to distinguish if it's a low leaf or not
|
|
156
|
-
const leafPath = await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, leafOrLowLeafIndex);
|
|
157
|
-
const leafPreimage = preimage;
|
|
158
|
-
const value = alreadyPresent ? leafPreimage.value : Fr.zero(); // default value of 0
|
|
159
|
-
if (!alreadyPresent) {
|
|
160
|
-
this.log.trace(`Slot has never been written before!`);
|
|
161
|
-
// Sanity check that the leaf slot is skipped by low leaf when it doesn't exist
|
|
162
|
-
assert(leafPreimage.slot.toBigInt() < leafSlot.toBigInt() && (leafPreimage.nextIndex === 0n || leafPreimage.nextSlot.toBigInt() > leafSlot.toBigInt()), 'Public data tree low leaf should skip the target leaf slot when the target leaf does not exist or is the max value.');
|
|
163
|
-
}
|
|
164
|
-
this.log.trace(`Storage read results (address=${contractAddress}, slot=${slot}, leafSlot=${leafSlot}): value=${value}, previouslyWritten=${alreadyPresent}`);
|
|
165
|
-
return {
|
|
166
|
-
value,
|
|
167
|
-
leafPreimage,
|
|
168
|
-
leafIndex: new Fr(leafOrLowLeafIndex),
|
|
169
|
-
leafPath: leafPath.toFields()
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Read from public storage, don't trace the read.
|
|
174
|
-
*
|
|
175
|
-
* @param contractAddress - the address of the contract whose storage is being read from
|
|
176
|
-
* @param slot - the slot in the contract's storage being read from
|
|
177
|
-
* @returns the latest value written to slot, or 0 if never written to before
|
|
178
|
-
*/ async peekStorage(contractAddress, slot) {
|
|
179
|
-
const { value, cached } = await this.publicStorage.read(contractAddress, slot);
|
|
180
|
-
this.log.trace(`Storage peek (address=${contractAddress}, slot=${slot}): value=${value}, cached=${cached}`);
|
|
181
|
-
return Promise.resolve(value);
|
|
182
|
-
}
|
|
183
131
|
// TODO(4886): We currently don't silo note hashes.
|
|
184
132
|
/**
|
|
185
133
|
* Check if a note hash exists at the given leaf index, trace the check.
|
|
@@ -189,15 +137,9 @@ import { PublicStorage } from './public_storage.js';
|
|
|
189
137
|
* @param leafIndex - the leaf index being checked
|
|
190
138
|
* @returns true if the note hash exists at the given leaf index, false otherwise
|
|
191
139
|
*/ async checkNoteHashExists(contractAddress, noteHash, leafIndex) {
|
|
192
|
-
const gotLeafValue = await this.
|
|
140
|
+
const gotLeafValue = await this.treesDB.getNoteHash(leafIndex.toBigInt()) ?? Fr.ZERO;
|
|
193
141
|
const exists = gotLeafValue.equals(noteHash);
|
|
194
142
|
this.log.trace(`noteHashes(${contractAddress})@${noteHash} ?? leafIndex: ${leafIndex} | gotLeafValue: ${gotLeafValue}, exists: ${exists}.`);
|
|
195
|
-
if (this.doMerkleOperations) {
|
|
196
|
-
const path = await this.db.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex.toBigInt());
|
|
197
|
-
this.trace.traceNoteHashCheck(contractAddress, gotLeafValue, leafIndex, exists, path.toFields());
|
|
198
|
-
} else {
|
|
199
|
-
this.trace.traceNoteHashCheck(contractAddress, gotLeafValue, leafIndex, exists);
|
|
200
|
-
}
|
|
201
143
|
return Promise.resolve(exists);
|
|
202
144
|
}
|
|
203
145
|
/**
|
|
@@ -222,17 +164,11 @@ import { PublicStorage } from './public_storage.js';
|
|
|
222
164
|
*/ async writeUniqueNoteHash(uniqueNoteHash) {
|
|
223
165
|
this.log.trace(`noteHashes += @${uniqueNoteHash}.`);
|
|
224
166
|
if (this.doMerkleOperations) {
|
|
225
|
-
|
|
226
|
-
const treeInfo = await this.db.getTreeInfo(MerkleTreeId.NOTE_HASH_TREE);
|
|
227
|
-
const leafIndex = new Fr(treeInfo.size);
|
|
228
|
-
await this.db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [
|
|
167
|
+
await this.treesDB.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, [
|
|
229
168
|
uniqueNoteHash
|
|
230
169
|
]);
|
|
231
|
-
const insertionPath = await this.db.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex.toBigInt());
|
|
232
|
-
this.trace.traceNewNoteHash(uniqueNoteHash, leafIndex, insertionPath.toFields());
|
|
233
|
-
} else {
|
|
234
|
-
this.trace.traceNewNoteHash(uniqueNoteHash);
|
|
235
170
|
}
|
|
171
|
+
this.trace.traceNewNoteHash(uniqueNoteHash);
|
|
236
172
|
}
|
|
237
173
|
/**
|
|
238
174
|
* Check if a nullifier exists, trace the check.
|
|
@@ -243,47 +179,17 @@ import { PublicStorage } from './public_storage.js';
|
|
|
243
179
|
this.log.trace(`Checking existence of nullifier (address=${contractAddress}, nullifier=${nullifier})`);
|
|
244
180
|
const siloedNullifier = await siloNullifier(contractAddress, nullifier);
|
|
245
181
|
if (this.doMerkleOperations) {
|
|
246
|
-
const
|
|
247
|
-
this.trace
|
|
182
|
+
const exists = await this.treesDB.getNullifierIndex(siloedNullifier) !== undefined;
|
|
183
|
+
this.log.trace(`Checked siloed nullifier ${siloedNullifier} (exists=${exists})`);
|
|
248
184
|
return Promise.resolve(exists);
|
|
249
185
|
} else {
|
|
186
|
+
// TODO: same here, this CAN hit the db.
|
|
250
187
|
const { exists, cacheHit } = await this.nullifiers.checkExists(siloedNullifier);
|
|
251
188
|
this.log.trace(`Checked siloed nullifier ${siloedNullifier} (exists=${exists}), cacheHit=${cacheHit}`);
|
|
252
|
-
this.trace.traceNullifierCheck(siloedNullifier, exists);
|
|
253
189
|
return Promise.resolve(exists);
|
|
254
190
|
}
|
|
255
191
|
}
|
|
256
192
|
/**
|
|
257
|
-
* Helper to get membership information for a siloed nullifier when checking its existence.
|
|
258
|
-
* Optionally trace the nullifier check.
|
|
259
|
-
*
|
|
260
|
-
* @param siloedNullifier - the siloed nullifier to get membership information for
|
|
261
|
-
* @returns
|
|
262
|
-
* - exists - whether the nullifier exists in the nullifier set
|
|
263
|
-
* - leafOrLowLeafPreimage - the preimage of the nullifier leaf or its low-leaf if it doesn't exist
|
|
264
|
-
* - leafOrLowLeafIndex - the leaf index of the nullifier leaf or its low-leaf if it doesn't exist
|
|
265
|
-
* - leafOrLowLeafPath - the sibling path of the nullifier leaf or its low-leaf if it doesn't exist
|
|
266
|
-
*/ async getNullifierMembership(siloedNullifier) {
|
|
267
|
-
// Get leaf if present, low leaf if absent
|
|
268
|
-
// If leaf is present, hint/trace it. Otherwise, hint/trace the low leaf.
|
|
269
|
-
const treeId = MerkleTreeId.NULLIFIER_TREE;
|
|
270
|
-
const { preimage: leafPreimage, leafOrLowLeafIndex, alreadyPresent } = await this.getLeafOrLowLeafInfo(treeId, siloedNullifier.toBigInt());
|
|
271
|
-
this.log.trace(`Checked siloed nullifier ${siloedNullifier} (exists=${alreadyPresent})`);
|
|
272
|
-
const leafPath = await this.db.getSiblingPath(treeId, leafOrLowLeafIndex);
|
|
273
|
-
if (alreadyPresent) {
|
|
274
|
-
this.log.trace(`Siloed nullifier ${siloedNullifier} exists at leafIndex=${leafOrLowLeafIndex}`);
|
|
275
|
-
} else {
|
|
276
|
-
// Sanity check that the leaf value is skipped by low leaf when it doesn't exist
|
|
277
|
-
assert(leafPreimage.nullifier.toBigInt() < siloedNullifier.toBigInt() && (leafPreimage.nextIndex === 0n || leafPreimage.nextNullifier.toBigInt() > siloedNullifier.toBigInt()), 'Nullifier tree low leaf should skip the target leaf nullifier when the target leaf does not exist.');
|
|
278
|
-
}
|
|
279
|
-
return {
|
|
280
|
-
exists: alreadyPresent,
|
|
281
|
-
leafOrLowLeafPreimage: leafPreimage,
|
|
282
|
-
leafOrLowLeafIndex,
|
|
283
|
-
leafOrLowLeafPath: leafPath.toFields()
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
193
|
* Write a nullifier to the nullifier set, trace the write.
|
|
288
194
|
* @param contractAddress - address of the contract that the nullifier is associated with
|
|
289
195
|
* @param nullifier - the unsiloed nullifier to write
|
|
@@ -298,32 +204,20 @@ import { PublicStorage } from './public_storage.js';
|
|
|
298
204
|
*/ async writeSiloedNullifier(siloedNullifier) {
|
|
299
205
|
this.log.trace(`Inserting siloed nullifier=${siloedNullifier}`);
|
|
300
206
|
if (this.doMerkleOperations) {
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
this.log.verbose(`Siloed nullifier ${siloedNullifier} already present in tree at index ${leafOrLowLeafIndex}!`);
|
|
305
|
-
// If the nullifier is already present, we should not insert it again
|
|
306
|
-
// instead we provide the direct membership path
|
|
307
|
-
const membershipPath = await this.db.getSiblingPath(treeId, leafOrLowLeafIndex);
|
|
308
|
-
// This just becomes a nullifier read hint
|
|
309
|
-
this.trace.traceNullifierCheck(siloedNullifier, /*exists=*/ alreadyPresent, leafPreimage, new Fr(leafOrLowLeafIndex), membershipPath.toFields());
|
|
207
|
+
const index = await this.treesDB.getNullifierIndex(siloedNullifier);
|
|
208
|
+
if (index !== undefined) {
|
|
209
|
+
this.log.verbose(`Siloed nullifier ${siloedNullifier} already present in tree at index ${index}!`);
|
|
310
210
|
throw new NullifierCollisionError(`Siloed nullifier ${siloedNullifier} already exists in parent cache or host.`);
|
|
311
211
|
} else {
|
|
312
|
-
|
|
212
|
+
await this.treesDB.sequentialInsert(MerkleTreeId.NULLIFIER_TREE, [
|
|
313
213
|
siloedNullifier.toBuffer()
|
|
314
214
|
]);
|
|
315
|
-
const lowLeafWitnessData = appendResult.lowLeavesWitnessData[0];
|
|
316
|
-
const lowLeafPreimage = lowLeafWitnessData.leafPreimage;
|
|
317
|
-
const lowLeafIndex = lowLeafWitnessData.index;
|
|
318
|
-
const lowLeafPath = lowLeafWitnessData.siblingPath.toFields();
|
|
319
|
-
const insertionPath = appendResult.insertionWitnessData[0].siblingPath.toFields();
|
|
320
|
-
this.trace.traceNewNullifier(siloedNullifier, lowLeafPreimage, new Fr(lowLeafIndex), lowLeafPath, insertionPath);
|
|
321
215
|
}
|
|
322
216
|
} else {
|
|
323
217
|
// Cache pending nullifiers for later access
|
|
324
218
|
await this.nullifiers.append(siloedNullifier);
|
|
325
|
-
this.trace.traceNewNullifier(siloedNullifier);
|
|
326
219
|
}
|
|
220
|
+
this.trace.traceNewNullifier(siloedNullifier);
|
|
327
221
|
}
|
|
328
222
|
async writeSiloedNullifiersFromPrivate(siloedNullifiers) {
|
|
329
223
|
for (const siloedNullifier of siloedNullifiers.filter((n)=>!n.isEmpty())){
|
|
@@ -336,15 +230,9 @@ import { PublicStorage } from './public_storage.js';
|
|
|
336
230
|
* @param msgLeafIndex - the message leaf index to use in the check
|
|
337
231
|
* @returns exists - whether the message exists in the L1 to L2 Messages tree
|
|
338
232
|
*/ async checkL1ToL2MessageExists(contractAddress, msgHash, msgLeafIndex) {
|
|
339
|
-
const valueAtIndex = await this.
|
|
233
|
+
const valueAtIndex = await this.treesDB.getL1ToL2LeafValue(msgLeafIndex.toBigInt()) ?? Fr.ZERO;
|
|
340
234
|
const exists = valueAtIndex.equals(msgHash);
|
|
341
235
|
this.log.trace(`l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`);
|
|
342
|
-
if (this.doMerkleOperations) {
|
|
343
|
-
const path = await this.db.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, msgLeafIndex.toBigInt());
|
|
344
|
-
this.trace.traceL1ToL2MessageCheck(contractAddress, valueAtIndex, msgLeafIndex, exists, path.toFields());
|
|
345
|
-
} else {
|
|
346
|
-
this.trace.traceL1ToL2MessageCheck(contractAddress, valueAtIndex, msgLeafIndex, exists);
|
|
347
|
-
}
|
|
348
236
|
return Promise.resolve(exists);
|
|
349
237
|
}
|
|
350
238
|
/**
|
|
@@ -370,31 +258,61 @@ import { PublicStorage } from './public_storage.js';
|
|
|
370
258
|
* @returns the contract instance or undefined if it does not exist.
|
|
371
259
|
*/ async getContractInstance(contractAddress) {
|
|
372
260
|
this.log.trace(`Getting contract instance for address ${contractAddress}`);
|
|
373
|
-
const instanceWithAddress = await this.
|
|
261
|
+
const instanceWithAddress = await this.contractsDB.getContractInstance(contractAddress, this.blockNumber);
|
|
374
262
|
const exists = instanceWithAddress !== undefined;
|
|
375
263
|
const instance = exists ? new SerializableContractInstance(instanceWithAddress) : undefined;
|
|
376
264
|
if (!exists) {
|
|
377
265
|
this.log.debug(`Contract instance NOT FOUND (address=${contractAddress})`);
|
|
378
|
-
this.trace.traceGetContractInstance(contractAddress, exists);
|
|
379
266
|
return undefined;
|
|
380
267
|
}
|
|
381
268
|
this.log.trace(`Got contract instance (address=${contractAddress}): instance=${jsonStringify(instance)}`);
|
|
382
|
-
// Canonical addresses do not trigger nullifier
|
|
269
|
+
// Canonical addresses do not trigger nullifier and update checks.
|
|
383
270
|
if (contractAddressIsCanonical(contractAddress)) {
|
|
384
|
-
this.trace.traceGetContractInstance(contractAddress, exists, instance);
|
|
385
271
|
return instance;
|
|
386
272
|
}
|
|
387
273
|
// This will decide internally whether to check the nullifier tree or not depending on doMerkleOperations.
|
|
388
274
|
const nullifierExistsInTree = await this.checkNullifierExists(AztecAddress.fromNumber(DEPLOYER_CONTRACT_ADDRESS), contractAddress.toField());
|
|
389
|
-
assert(exists == nullifierExistsInTree, '
|
|
275
|
+
assert(exists == nullifierExistsInTree, 'treesDB contains contract instance, but nullifier tree does not contain contract address (or vice versa).... This is a bug!');
|
|
276
|
+
// All that is left is tocheck that the contract updatability information is correct.
|
|
277
|
+
// That is, that the current and original contract class ids are correct.
|
|
278
|
+
await this.checkContractUpdateInformation(instanceWithAddress);
|
|
279
|
+
return instance;
|
|
280
|
+
}
|
|
281
|
+
async checkContractUpdateInformation(instance) {
|
|
282
|
+
// If "merkle operations" are not requested, we trust the DB.
|
|
283
|
+
// Otherwise we check that the contract updatability information is correct.
|
|
284
|
+
// That is, that the current and original contract class ids are correct.
|
|
285
|
+
// All failures are fatal and the simulation is not expected to be provable.
|
|
390
286
|
if (this.doMerkleOperations) {
|
|
391
|
-
//
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
287
|
+
// Conceptually, we want to do the following:
|
|
288
|
+
// * Read a SharedMutable at the contract update slot.
|
|
289
|
+
// * Obtain the expected current class id from the SharedMutable, at the current block.
|
|
290
|
+
// * if expectedId == 0 then currentClassId should be original contract class id
|
|
291
|
+
// * if expectedId != 0 then currentClassId should be expectedId
|
|
292
|
+
//
|
|
293
|
+
// However, we will also be checking the hash of the shared mutable values.
|
|
294
|
+
// This is a bit of a leak of information, since the circuit will use it to prove
|
|
295
|
+
// one public read insted of N of the shared mutable values.
|
|
296
|
+
const { sharedMutableSlot, sharedMutableHashSlot } = await SharedMutableValuesWithHash.getContractUpdateSlots(instance.address);
|
|
297
|
+
const readDeployerStorage = async (storageSlot)=>await this.readStorage(ProtocolContractAddress.ContractInstanceDeployer, storageSlot);
|
|
298
|
+
const hash = await readDeployerStorage(sharedMutableHashSlot);
|
|
299
|
+
const sharedMutableValues = await SharedMutableValues.readFromTree(sharedMutableSlot, readDeployerStorage);
|
|
300
|
+
const preImage = sharedMutableValues.toFields();
|
|
301
|
+
// 1) update never scheduled: hash == 0 and preimage should be empty (but poseidon2hash(preimage) will not be 0s)
|
|
302
|
+
if (hash.isZero()) {
|
|
303
|
+
assert(preImage.every((f)=>f.isZero()), `Found updatability hash 0 but preimage is not empty for contract instance ${instance.address}.`);
|
|
304
|
+
assert(instance.currentContractClassId.equals(instance.originalContractClassId), `Found updatability hash 0 for contract instance ${instance.address} but original class id ${instance.originalContractClassId} != current class id ${instance.currentContractClassId}.`);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
// 2) At this point we know that the hash is not zero and this means that an update has at some point been scheduled.
|
|
308
|
+
const computedHash = await poseidon2Hash(preImage);
|
|
309
|
+
assert(hash.equals(computedHash), `Shared mutable values hash mismatch for contract instance ${instance.address}. Expected: ${hash}, computed: ${computedHash}`);
|
|
310
|
+
// We now check that, depending on the current block, the current class id is correct.
|
|
311
|
+
const expectedClassIdRaw = sharedMutableValues.svc.getCurrentAt(this.blockNumber).at(0);
|
|
312
|
+
const expectedClassId = expectedClassIdRaw.isZero() ? instance.originalContractClassId : expectedClassIdRaw;
|
|
313
|
+
assert(instance.currentContractClassId.equals(expectedClassId), `Current class id mismatch
|
|
314
|
+
for contract instance ${instance.address}. Expected: ${expectedClassId}, current: ${instance.currentContractClassId}`);
|
|
396
315
|
}
|
|
397
|
-
return instance;
|
|
398
316
|
}
|
|
399
317
|
/**
|
|
400
318
|
* Get a contract class.
|
|
@@ -402,7 +320,7 @@ import { PublicStorage } from './public_storage.js';
|
|
|
402
320
|
* @returns the contract class or undefined if it does not exist.
|
|
403
321
|
*/ async getContractClass(classId) {
|
|
404
322
|
this.log.trace(`Getting contract class for id ${classId}`);
|
|
405
|
-
const klass = await this.
|
|
323
|
+
const klass = await this.contractsDB.getContractClass(classId);
|
|
406
324
|
const exists = klass !== undefined;
|
|
407
325
|
let extendedClass = undefined;
|
|
408
326
|
// Note: We currently do not generate info to check the nullifier tree, because
|
|
@@ -410,7 +328,7 @@ import { PublicStorage } from './public_storage.js';
|
|
|
410
328
|
if (exists) {
|
|
411
329
|
this.log.trace(`Got contract class (id=${classId})`);
|
|
412
330
|
// Extend class information with public bytecode commitment.
|
|
413
|
-
const bytecodeCommitment = await this.
|
|
331
|
+
const bytecodeCommitment = await this.contractsDB.getBytecodeCommitment(classId);
|
|
414
332
|
assert(bytecodeCommitment, `Bytecode commitment was not found in DB for contract class (${classId}). This should not happen!`);
|
|
415
333
|
extendedClass = {
|
|
416
334
|
...klass,
|
|
@@ -419,7 +337,7 @@ import { PublicStorage } from './public_storage.js';
|
|
|
419
337
|
} else {
|
|
420
338
|
this.log.debug(`Contract instance NOT FOUND (id=${classId})`);
|
|
421
339
|
}
|
|
422
|
-
this.trace.traceGetContractClass(classId, exists
|
|
340
|
+
this.trace.traceGetContractClass(classId, exists);
|
|
423
341
|
return extendedClass;
|
|
424
342
|
}
|
|
425
343
|
/**
|
|
@@ -432,53 +350,13 @@ import { PublicStorage } from './public_storage.js';
|
|
|
432
350
|
}
|
|
433
351
|
const contractClass = await this.getContractClass(contractInstance.currentContractClassId);
|
|
434
352
|
assert(contractClass, `Contract class not found in DB, but a contract instance was found with this class ID (${contractInstance.currentContractClassId}). This should not happen!`);
|
|
435
|
-
// NOTE: If the contract instance is not found, we assume it has not been deployed.
|
|
436
|
-
// It doesnt matter what the values of the contract instance are in this case, as long as we tag it with exists=false.
|
|
437
|
-
// This will hint to the avm circuit to just perform the non-membership check on the address and disregard the bytecode hash
|
|
438
353
|
return contractClass.packedBytecode;
|
|
439
354
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const { value: hash, leafPreimage, leafIndex, leafPath } = await this.getPublicDataMembership(ProtocolContractAddress.ContractInstanceDeployer, sharedMutableHashSlot);
|
|
443
|
-
const updateMembership = new AvmPublicDataReadTreeHint(leafPreimage, leafIndex, leafPath);
|
|
444
|
-
const readStorage = async (storageSlot)=>(await this.publicStorage.read(ProtocolContractAddress.ContractInstanceDeployer, storageSlot)).value;
|
|
445
|
-
const sharedMutableValues = await SharedMutableValues.readFromTree(sharedMutableSlot, readStorage);
|
|
446
|
-
const updatePreimage = sharedMutableValues.toFields();
|
|
447
|
-
if (!hash.isZero()) {
|
|
448
|
-
const hashed = await poseidon2Hash(updatePreimage);
|
|
449
|
-
if (!hashed.equals(hash)) {
|
|
450
|
-
throw new Error(`Update hint hash mismatch: ${hash} != ${hashed}`);
|
|
451
|
-
}
|
|
452
|
-
this.log.trace(`Non empty update hint found for contract ${contractAddress}`);
|
|
453
|
-
} else {
|
|
454
|
-
if (updatePreimage.some((f)=>!f.isZero())) {
|
|
455
|
-
throw new Error(`Update hint hash is zero, but update preimage is not: ${updatePreimage}`);
|
|
456
|
-
}
|
|
457
|
-
this.log.trace(`No update hint found for contract ${contractAddress}`);
|
|
458
|
-
}
|
|
459
|
-
return {
|
|
460
|
-
updateMembership,
|
|
461
|
-
updatePreimage
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
traceEnqueuedCall(publicCallRequest, calldata, reverted) {
|
|
465
|
-
this.trace.traceEnqueuedCall(publicCallRequest, calldata, reverted);
|
|
355
|
+
traceEnqueuedCall(publicCallRequest) {
|
|
356
|
+
this.trace.traceEnqueuedCall(publicCallRequest);
|
|
466
357
|
}
|
|
467
358
|
async getPublicFunctionDebugName(avmEnvironment) {
|
|
468
|
-
return await getPublicFunctionDebugName(this.
|
|
469
|
-
}
|
|
470
|
-
async getLeafOrLowLeafInfo(treeId, key) {
|
|
471
|
-
// "key" is siloed slot (leafSlot) or siloed nullifier
|
|
472
|
-
const leafOrLowLeafInfo = await this.db.getPreviousValueIndex(treeId, key);
|
|
473
|
-
assert(leafOrLowLeafInfo !== undefined, `${MerkleTreeId[treeId]} low leaf index should always be found (even if target leaf does not exist)`);
|
|
474
|
-
const { index: leafOrLowLeafIndex, alreadyPresent } = leafOrLowLeafInfo;
|
|
475
|
-
const leafPreimage = await this.db.getLeafPreimage(treeId, leafOrLowLeafIndex);
|
|
476
|
-
assert(leafPreimage !== undefined, `${MerkleTreeId[treeId]} low leaf preimage should never be undefined (even if target leaf does not exist)`);
|
|
477
|
-
return {
|
|
478
|
-
preimage: leafPreimage,
|
|
479
|
-
leafOrLowLeafIndex,
|
|
480
|
-
alreadyPresent
|
|
481
|
-
};
|
|
359
|
+
return await getPublicFunctionDebugName(this.contractsDB, avmEnvironment.address, avmEnvironment.calldata);
|
|
482
360
|
}
|
|
483
361
|
}
|
|
484
362
|
function contractAddressIsCanonical(contractAddress) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import type {
|
|
2
|
+
import type { PublicTreesDB } from '../../public_db_sources.js';
|
|
3
3
|
/**
|
|
4
4
|
* A class to manage new nullifier staging and existence checks during a contract call's AVM simulation.
|
|
5
5
|
* Maintains a siloed nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
@@ -14,7 +14,7 @@ export declare class NullifierManager {
|
|
|
14
14
|
private readonly parent?;
|
|
15
15
|
constructor(
|
|
16
16
|
/** Reference to node storage. Checked on parent cache-miss. */
|
|
17
|
-
hostNullifiers:
|
|
17
|
+
hostNullifiers: PublicTreesDB,
|
|
18
18
|
/** Cache of siloed nullifiers. */
|
|
19
19
|
cache?: Set<bigint>,
|
|
20
20
|
/** Parent nullifier manager to fall back on */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nullifiers.d.ts","sourceRoot":"","sources":["../../../../src/public/avm/journal/nullifiers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"nullifiers.d.ts","sourceRoot":"","sources":["../../../../src/public/avm/journal/nullifiers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;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;IACI,IAAI;IAIX;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAW/B;;;;;;;;;;OAUG;IACU,WAAW,CAAC,eAAe,EAAE,EAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAmB9F;;;;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,6 +1,6 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PublicStateDBInterface } from '../../../common/db_interfaces.js';
|
|
4
4
|
type PublicStorageReadResult = {
|
|
5
5
|
value: Fr;
|
|
6
6
|
cached: boolean;
|
|
@@ -19,7 +19,7 @@ export declare class PublicStorage {
|
|
|
19
19
|
private readonly cache;
|
|
20
20
|
constructor(
|
|
21
21
|
/** Reference to node storage. Checked on parent cache-miss. */
|
|
22
|
-
hostPublicStorage:
|
|
22
|
+
hostPublicStorage: PublicStateDBInterface,
|
|
23
23
|
/** Parent's storage. Checked on this' cache-miss. */
|
|
24
24
|
parent?: PublicStorage | undefined);
|
|
25
25
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public_storage.d.ts","sourceRoot":"","sources":["../../../../src/public/avm/journal/public_storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"public_storage.d.ts","sourceRoot":"","sources":["../../../../src/public/avm/journal/public_storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAE/E,KAAK,uBAAuB,GAAG;IAC7B,KAAK,EAAE,EAAE,CAAC;IACV,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,qBAAa,aAAa;IAKtB,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAP1B,6BAA6B;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;;IAGzC,+DAA+D;IAC9C,iBAAiB,EAAE,sBAAsB;IAC1D,qDAAqD;IACpC,MAAM,CAAC,2BAAe;IAKzC;;OAEG;IACI,IAAI;IAIX;;;;;;;OAOG;IACI,gBAAgB,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,SAAS;IAWhF;;;;;;;;;;OAUG;IACU,IAAI,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAmB5F;;;;;;OAMG;IACI,KAAK,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE;IAI/D;;;;OAIG;IACI,cAAc,CAAC,qBAAqB,EAAE,aAAa;CAG3D"}
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
3
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
4
|
-
import {
|
|
5
|
-
import type {
|
|
2
|
+
import type { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
3
|
+
import type { PublicContractsDB, PublicTreesDB } from '../../public/public_db_sources.js';
|
|
6
4
|
import type { PublicSideEffectTraceInterface } from '../side_effect_trace_interface.js';
|
|
7
|
-
export declare function mockGetBytecode(worldStateDB: WorldStateDB, bytecode: Buffer): Promise<void>;
|
|
8
5
|
export declare function mockTraceFork(trace: PublicSideEffectTraceInterface, nestedTrace?: PublicSideEffectTraceInterface): void;
|
|
9
|
-
export declare function mockStorageRead(worldStateDB:
|
|
6
|
+
export declare function mockStorageRead(worldStateDB: PublicTreesDB, value: Fr): void;
|
|
10
7
|
export declare function mockNoteHashCount(mockedTrace: PublicSideEffectTraceInterface, count: number): void;
|
|
11
|
-
export declare function mockStorageReadWithMap(worldStateDB:
|
|
12
|
-
export declare function
|
|
13
|
-
export declare function
|
|
14
|
-
export declare function
|
|
15
|
-
export declare function
|
|
16
|
-
export declare function
|
|
17
|
-
export declare function
|
|
8
|
+
export declare function mockStorageReadWithMap(worldStateDB: PublicTreesDB, mockedStorage: Map<bigint, Fr>): void;
|
|
9
|
+
export declare function mockNoteHashExists(worldStateDB: PublicTreesDB, _leafIndex: Fr, value?: Fr): void;
|
|
10
|
+
export declare function mockGetNullifierIndex(worldStateDB: PublicTreesDB, leafIndex: Fr, _ignoredValue?: Fr): void;
|
|
11
|
+
export declare function mockL1ToL2MessageExists(worldStateDB: PublicTreesDB, leafIndex: Fr, value: Fr, valueAtOtherIndices?: Fr): void;
|
|
12
|
+
export declare function mockGetContractInstance(contractsDB: PublicContractsDB, contractInstance: ContractInstanceWithAddress): void;
|
|
13
|
+
export declare function mockGetContractClass(contractsDB: PublicContractsDB, contractClass: ContractClassPublic): void;
|
|
14
|
+
export declare function mockGetBytecodeCommitment(contractsDB: PublicContractsDB, commitment: Fr): void;
|
|
18
15
|
//# sourceMappingURL=test_utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test_utils.d.ts","sourceRoot":"","sources":["../../../src/public/avm/test_utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test_utils.d.ts","sourceRoot":"","sources":["../../../src/public/avm/test_utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAK/F,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC1F,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAExF,wBAAgB,aAAa,CAAC,KAAK,EAAE,8BAA8B,EAAE,WAAW,CAAC,EAAE,8BAA8B,QAIhH;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,QAErE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,8BAA8B,EAAE,KAAK,EAAE,MAAM,QAE3F;AAED,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,QAIjG;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,QASzF;AAED,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,CAAC,EAAE,EAAE,QAEnG;AAED,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,aAAa,EAC3B,SAAS,EAAE,EAAE,EACb,KAAK,EAAE,EAAE,EACT,mBAAmB,CAAC,EAAE,EAAE,QAWzB;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,2BAA2B,QAEpH;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,mBAAmB,QAEtG;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,EAAE,QAEvF"}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import { computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
|
|
3
2
|
import { mock } from 'jest-mock-extended';
|
|
4
|
-
export async function mockGetBytecode(worldStateDB, bytecode) {
|
|
5
|
-
const commitment = await computePublicBytecodeCommitment(bytecode);
|
|
6
|
-
worldStateDB.getBytecodeCommitment.mockResolvedValue(commitment);
|
|
7
|
-
}
|
|
8
3
|
export function mockTraceFork(trace, nestedTrace) {
|
|
9
4
|
trace.fork.mockReturnValue(nestedTrace ?? mock());
|
|
10
5
|
}
|
|
@@ -17,11 +12,8 @@ export function mockNoteHashCount(mockedTrace, count) {
|
|
|
17
12
|
export function mockStorageReadWithMap(worldStateDB, mockedStorage) {
|
|
18
13
|
worldStateDB.storageRead.mockImplementation((_address, slot)=>Promise.resolve(mockedStorage.get(slot.toBigInt()) ?? Fr.ZERO));
|
|
19
14
|
}
|
|
20
|
-
export function mockGetBytecodeCommitment(worldStateDB, commitment) {
|
|
21
|
-
worldStateDB.getBytecodeCommitment.mockResolvedValue(commitment);
|
|
22
|
-
}
|
|
23
15
|
export function mockNoteHashExists(worldStateDB, _leafIndex, value) {
|
|
24
|
-
worldStateDB.
|
|
16
|
+
worldStateDB.getNoteHash.mockImplementation((index)=>{
|
|
25
17
|
if (index == _leafIndex.toBigInt()) {
|
|
26
18
|
return Promise.resolve(value);
|
|
27
19
|
} else {
|
|
@@ -44,9 +36,12 @@ export function mockL1ToL2MessageExists(worldStateDB, leafIndex, value, valueAtO
|
|
|
44
36
|
}
|
|
45
37
|
});
|
|
46
38
|
}
|
|
47
|
-
export function mockGetContractInstance(
|
|
48
|
-
|
|
39
|
+
export function mockGetContractInstance(contractsDB, contractInstance) {
|
|
40
|
+
contractsDB.getContractInstance.mockResolvedValue(contractInstance);
|
|
41
|
+
}
|
|
42
|
+
export function mockGetContractClass(contractsDB, contractClass) {
|
|
43
|
+
contractsDB.getContractClass.mockResolvedValue(contractClass);
|
|
49
44
|
}
|
|
50
|
-
export function
|
|
51
|
-
|
|
45
|
+
export function mockGetBytecodeCommitment(contractsDB, commitment) {
|
|
46
|
+
contractsDB.getBytecodeCommitment.mockResolvedValue(commitment);
|
|
52
47
|
}
|