@aztec/simulator 0.58.0 → 0.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/acvm/acvm.d.ts +1 -0
- package/dest/acvm/acvm.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.d.ts +3 -3
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +7 -7
- package/dest/acvm/oracle/typed_oracle.d.ts +4 -3
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +4 -4
- package/dest/acvm/serialize.d.ts +1 -0
- package/dest/acvm/serialize.d.ts.map +1 -1
- package/dest/avm/avm_context.d.ts +1 -1
- package/dest/avm/avm_context.js +1 -1
- package/dest/avm/avm_execution_environment.d.ts +2 -5
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +7 -15
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +1 -8
- package/dest/avm/avm_memory_types.d.ts +1 -0
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_simulator.d.ts +1 -0
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/bytecode_utils.d.ts +1 -0
- package/dest/avm/bytecode_utils.d.ts.map +1 -1
- package/dest/avm/fixtures/index.d.ts +3 -0
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +8 -2
- package/dest/avm/journal/journal.d.ts +14 -13
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +33 -33
- package/dest/avm/journal/nullifiers.d.ts +9 -9
- package/dest/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/avm/journal/nullifiers.js +24 -24
- package/dest/avm/journal/public_storage.d.ts +10 -10
- package/dest/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/avm/journal/public_storage.js +21 -21
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +5 -5
- package/dest/avm/opcodes/environment_getters.d.ts +12 -13
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +13 -16
- package/dest/avm/opcodes/hashing.d.ts +2 -26
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +11 -95
- package/dest/avm/opcodes/index.d.ts +0 -1
- package/dest/avm/opcodes/index.d.ts.map +1 -1
- package/dest/avm/opcodes/index.js +1 -2
- package/dest/avm/opcodes/instruction.d.ts +1 -0
- package/dest/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/avm/opcodes/storage.js +3 -3
- package/dest/avm/serialization/buffer_cursor.d.ts +1 -0
- package/dest/avm/serialization/buffer_cursor.d.ts.map +1 -1
- 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 +2 -6
- package/dest/avm/serialization/instruction_serialization.d.ts +11 -14
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +11 -15
- package/dest/avm/test_utils.d.ts +1 -0
- package/dest/avm/test_utils.d.ts.map +1 -1
- package/dest/client/client_execution_context.d.ts +9 -10
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +30 -33
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +3 -4
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +3 -3
- package/dest/mocks/fixtures.js +2 -2
- package/dest/providers/acvm_native.d.ts +1 -0
- package/dest/providers/acvm_native.d.ts.map +1 -1
- package/dest/public/db_interfaces.d.ts +1 -0
- package/dest/public/db_interfaces.d.ts.map +1 -1
- package/dest/public/dual_side_effect_trace.d.ts +7 -6
- package/dest/public/dual_side_effect_trace.d.ts.map +1 -1
- package/dest/public/dual_side_effect_trace.js +19 -19
- package/dest/public/enqueued_call_side_effect_trace.d.ts +7 -6
- package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
- package/dest/public/enqueued_call_side_effect_trace.js +15 -17
- package/dest/public/enqueued_call_simulator.d.ts +1 -1
- package/dest/public/enqueued_call_simulator.d.ts.map +1 -1
- package/dest/public/enqueued_call_simulator.js +11 -12
- package/dest/public/enqueued_calls_processor.d.ts.map +1 -1
- package/dest/public/enqueued_calls_processor.js +2 -2
- package/dest/public/execution.d.ts +1 -0
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +2 -2
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +6 -5
- package/dest/public/public_db_sources.d.ts +1 -0
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/side_effect_trace.d.ts +7 -6
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +14 -15
- package/dest/public/side_effect_trace_interface.d.ts +7 -6
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/acvm/oracle/oracle.ts +0 -6
- package/src/acvm/oracle/typed_oracle.ts +0 -3
- package/src/avm/avm_context.ts +1 -1
- package/src/avm/avm_execution_environment.ts +0 -15
- package/src/avm/avm_gas.ts +0 -7
- package/src/avm/fixtures/index.ts +7 -2
- package/src/avm/journal/journal.ts +32 -32
- package/src/avm/journal/nullifiers.ts +23 -23
- package/src/avm/journal/public_storage.ts +20 -20
- package/src/avm/opcodes/accrued_substate.ts +4 -8
- package/src/avm/opcodes/environment_getters.ts +0 -3
- package/src/avm/opcodes/hashing.ts +9 -122
- package/src/avm/opcodes/index.ts +0 -1
- package/src/avm/opcodes/storage.ts +2 -2
- package/src/avm/serialization/bytecode_serialization.ts +0 -7
- package/src/avm/serialization/instruction_serialization.ts +0 -4
- package/src/client/client_execution_context.ts +21 -44
- package/src/client/private_execution.ts +1 -9
- package/src/client/simulator.ts +0 -2
- package/src/mocks/fixtures.ts +1 -1
- package/src/public/dual_side_effect_trace.ts +18 -18
- package/src/public/enqueued_call_side_effect_trace.ts +14 -20
- package/src/public/enqueued_call_simulator.ts +10 -23
- package/src/public/enqueued_calls_processor.ts +1 -3
- package/src/public/execution.ts +1 -1
- package/src/public/executor.ts +11 -5
- package/src/public/side_effect_trace.ts +19 -14
- package/src/public/side_effect_trace_interface.ts +6 -6
- package/dest/avm/opcodes/commitment.d.ts +0 -16
- package/dest/avm/opcodes/commitment.d.ts.map +0 -1
- package/dest/avm/opcodes/commitment.js +0 -51
- package/src/avm/opcodes/commitment.ts +0 -65
|
@@ -37,17 +37,17 @@ export class NullifierManager {
|
|
|
37
37
|
/**
|
|
38
38
|
* Get a nullifier's existence in this' cache or parent's (recursively).
|
|
39
39
|
* DOES NOT CHECK HOST STORAGE!
|
|
40
|
-
* @param
|
|
40
|
+
* @param contractAddress - the address of the contract whose storage is being read from
|
|
41
41
|
* @param nullifier - the nullifier to check for
|
|
42
42
|
* @returns exists: whether the nullifier exists in cache here or in parent's
|
|
43
43
|
*/
|
|
44
|
-
private checkExistsHereOrParent(
|
|
44
|
+
private checkExistsHereOrParent(contractAddress: Fr, nullifier: Fr): boolean {
|
|
45
45
|
// First check this cache
|
|
46
|
-
let existsAsPending = this.cache.exists(
|
|
46
|
+
let existsAsPending = this.cache.exists(contractAddress, nullifier);
|
|
47
47
|
// Then try parent's nullifier cache
|
|
48
48
|
if (!existsAsPending && this.parent) {
|
|
49
49
|
// Note: this will recurse to grandparent/etc until a cache-hit is encountered.
|
|
50
|
-
existsAsPending = this.parent.checkExistsHereOrParent(
|
|
50
|
+
existsAsPending = this.parent.checkExistsHereOrParent(contractAddress, nullifier);
|
|
51
51
|
}
|
|
52
52
|
return existsAsPending;
|
|
53
53
|
}
|
|
@@ -59,24 +59,24 @@ export class NullifierManager {
|
|
|
59
59
|
* 3. Fall back to the host state.
|
|
60
60
|
* 4. Not found! Nullifier does not exist.
|
|
61
61
|
*
|
|
62
|
-
* @param
|
|
62
|
+
* @param contractAddress - the address of the contract whose storage is being read from
|
|
63
63
|
* @param nullifier - the nullifier to check for
|
|
64
64
|
* @returns exists: whether the nullifier exists at all,
|
|
65
65
|
* isPending: whether the nullifier was found in a cache,
|
|
66
66
|
* leafIndex: the nullifier's leaf index if it exists and is not pending (comes from host state).
|
|
67
67
|
*/
|
|
68
68
|
public async checkExists(
|
|
69
|
-
|
|
69
|
+
contractAddress: Fr,
|
|
70
70
|
nullifier: Fr,
|
|
71
71
|
): Promise<[/*exists=*/ boolean, /*isPending=*/ boolean, /*leafIndex=*/ Fr]> {
|
|
72
72
|
// Check this cache and parent's (recursively)
|
|
73
|
-
const existsAsPending = this.checkExistsHereOrParent(
|
|
73
|
+
const existsAsPending = this.checkExistsHereOrParent(contractAddress, nullifier);
|
|
74
74
|
// Finally try the host's Aztec state (a trip to the database)
|
|
75
75
|
// If the value is found in the database, it will be associated with a leaf index!
|
|
76
76
|
let leafIndex: bigint | undefined = undefined;
|
|
77
77
|
if (!existsAsPending) {
|
|
78
78
|
// silo the nullifier before checking for its existence in the host
|
|
79
|
-
leafIndex = await this.hostNullifiers.getNullifierIndex(siloNullifier(
|
|
79
|
+
leafIndex = await this.hostNullifiers.getNullifierIndex(siloNullifier(contractAddress, nullifier));
|
|
80
80
|
}
|
|
81
81
|
const exists = existsAsPending || leafIndex !== undefined;
|
|
82
82
|
leafIndex = leafIndex === undefined ? BigInt(0) : leafIndex;
|
|
@@ -86,17 +86,17 @@ export class NullifierManager {
|
|
|
86
86
|
/**
|
|
87
87
|
* Stage a new nullifier (append it to the cache).
|
|
88
88
|
*
|
|
89
|
-
* @param
|
|
89
|
+
* @param contractAddress - the address of the contract that the nullifier is associated with
|
|
90
90
|
* @param nullifier - the nullifier to stage
|
|
91
91
|
*/
|
|
92
|
-
public async append(
|
|
93
|
-
const [exists, ,] = await this.checkExists(
|
|
92
|
+
public async append(contractAddress: Fr, nullifier: Fr) {
|
|
93
|
+
const [exists, ,] = await this.checkExists(contractAddress, nullifier);
|
|
94
94
|
if (exists) {
|
|
95
95
|
throw new NullifierCollisionError(
|
|
96
|
-
`Nullifier ${nullifier} at contract ${
|
|
96
|
+
`Nullifier ${nullifier} at contract ${contractAddress} already exists in parent cache or host.`,
|
|
97
97
|
);
|
|
98
98
|
}
|
|
99
|
-
this.cache.append(
|
|
99
|
+
this.cache.append(contractAddress, nullifier);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
@@ -135,35 +135,35 @@ export class NullifierCache {
|
|
|
135
135
|
/**
|
|
136
136
|
* Check whether a nullifier exists in the cache.
|
|
137
137
|
*
|
|
138
|
-
* @param
|
|
138
|
+
* @param contractAddress - the address of the contract that the nullifier is associated with
|
|
139
139
|
* @param nullifier - the nullifier to check existence of
|
|
140
140
|
* @returns whether the nullifier is found in the cache
|
|
141
141
|
*/
|
|
142
|
-
public exists(
|
|
142
|
+
public exists(contractAddress: Fr, nullifier: Fr): boolean {
|
|
143
143
|
const exists =
|
|
144
|
-
this.cachePerContract.get(
|
|
145
|
-
this.siloedNullifiers.has(siloNullifier(AztecAddress.fromField(
|
|
144
|
+
this.cachePerContract.get(contractAddress.toBigInt())?.has(nullifier.toBigInt()) ||
|
|
145
|
+
this.siloedNullifiers.has(siloNullifier(AztecAddress.fromField(contractAddress), nullifier).toBigInt());
|
|
146
146
|
return !!exists;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
150
|
* Stage a new nullifier (append it to the cache).
|
|
151
151
|
*
|
|
152
|
-
* @param
|
|
152
|
+
* @param contractAddress - the address of the contract that the nullifier is associated with
|
|
153
153
|
* @param nullifier - the nullifier to stage
|
|
154
154
|
*/
|
|
155
|
-
public append(
|
|
156
|
-
if (this.exists(
|
|
155
|
+
public append(contractAddress: Fr, nullifier: Fr) {
|
|
156
|
+
if (this.exists(contractAddress, nullifier)) {
|
|
157
157
|
throw new NullifierCollisionError(
|
|
158
|
-
`Nullifier ${nullifier} at contract ${
|
|
158
|
+
`Nullifier ${nullifier} at contract ${contractAddress} already exists in cache.`,
|
|
159
159
|
);
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
let nullifiersForContract = this.cachePerContract.get(
|
|
162
|
+
let nullifiersForContract = this.cachePerContract.get(contractAddress.toBigInt());
|
|
163
163
|
// If this contract's nullifier set has no cached nullifiers, create a new Set to store them
|
|
164
164
|
if (!nullifiersForContract) {
|
|
165
165
|
nullifiersForContract = new Set();
|
|
166
|
-
this.cachePerContract.set(
|
|
166
|
+
this.cachePerContract.set(contractAddress.toBigInt(), nullifiersForContract);
|
|
167
167
|
}
|
|
168
168
|
nullifiersForContract.add(nullifier.toBigInt());
|
|
169
169
|
}
|
|
@@ -45,17 +45,17 @@ export class PublicStorage {
|
|
|
45
45
|
* Read a storage value from this' cache or parent's (recursively).
|
|
46
46
|
* DOES NOT CHECK HOST STORAGE!
|
|
47
47
|
*
|
|
48
|
-
* @param
|
|
48
|
+
* @param contractAddress - the address of the contract whose storage is being read from
|
|
49
49
|
* @param slot - the slot in the contract's storage being read from
|
|
50
50
|
* @returns value: the latest value written according to this cache or the parent's. undefined on cache miss.
|
|
51
51
|
*/
|
|
52
|
-
public readHereOrParent(
|
|
52
|
+
public readHereOrParent(contractAddress: Fr, slot: Fr): Fr | undefined {
|
|
53
53
|
// First try check this storage cache
|
|
54
|
-
let value = this.cache.read(
|
|
54
|
+
let value = this.cache.read(contractAddress, slot);
|
|
55
55
|
// Then try parent's storage cache
|
|
56
56
|
if (!value && this.parent) {
|
|
57
57
|
// Note: this will recurse to grandparent/etc until a cache-hit is encountered.
|
|
58
|
-
value = this.parent.readHereOrParent(
|
|
58
|
+
value = this.parent.readHereOrParent(contractAddress, slot);
|
|
59
59
|
}
|
|
60
60
|
return value;
|
|
61
61
|
}
|
|
@@ -67,17 +67,17 @@ export class PublicStorage {
|
|
|
67
67
|
* 3. Fall back to the host state.
|
|
68
68
|
* 4. Not found! Value has never been written to before. Flag it as non-existent and return value zero.
|
|
69
69
|
*
|
|
70
|
-
* @param
|
|
70
|
+
* @param contractAddress - the address of the contract whose storage is being read from
|
|
71
71
|
* @param slot - the slot in the contract's storage being read from
|
|
72
72
|
* @returns exists: whether the slot has EVER been written to before, value: the latest value written to slot, or 0 if never written to before
|
|
73
73
|
*/
|
|
74
|
-
public async read(
|
|
74
|
+
public async read(contractAddress: Fr, slot: Fr): Promise<PublicStorageReadResult> {
|
|
75
75
|
let cached = false;
|
|
76
76
|
// Check this cache and parent's (recursively)
|
|
77
|
-
let value = this.readHereOrParent(
|
|
77
|
+
let value = this.readHereOrParent(contractAddress, slot);
|
|
78
78
|
// Finally try the host's Aztec state (a trip to the database)
|
|
79
79
|
if (!value) {
|
|
80
|
-
value = await this.hostPublicStorage.storageRead(
|
|
80
|
+
value = await this.hostPublicStorage.storageRead(contractAddress, slot);
|
|
81
81
|
// TODO(dbanks12): if value retrieved from host storage, we can cache it here
|
|
82
82
|
// any future reads to the same slot can read from cache instead of more expensive
|
|
83
83
|
// DB access
|
|
@@ -93,12 +93,12 @@ export class PublicStorage {
|
|
|
93
93
|
/**
|
|
94
94
|
* Stage a storage write.
|
|
95
95
|
*
|
|
96
|
-
* @param
|
|
96
|
+
* @param contractAddress - the address of the contract whose storage is being written to
|
|
97
97
|
* @param slot - the slot in the contract's storage being written to
|
|
98
98
|
* @param value - the value being written to the slot
|
|
99
99
|
*/
|
|
100
|
-
public write(
|
|
101
|
-
this.cache.write(
|
|
100
|
+
public write(contractAddress: Fr, slot: Fr, value: Fr) {
|
|
101
|
+
this.cache.write(contractAddress, slot, value);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
@@ -114,9 +114,9 @@ export class PublicStorage {
|
|
|
114
114
|
* Commits ALL staged writes to the host's state.
|
|
115
115
|
*/
|
|
116
116
|
public async commitToDB() {
|
|
117
|
-
for (const [
|
|
117
|
+
for (const [contractAddress, cacheAtContract] of this.cache.cachePerContract) {
|
|
118
118
|
for (const [slot, value] of cacheAtContract) {
|
|
119
|
-
await this.hostPublicStorage.storageWrite(AztecAddress.fromBigInt(
|
|
119
|
+
await this.hostPublicStorage.storageWrite(AztecAddress.fromBigInt(contractAddress), new Fr(slot), value);
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -139,27 +139,27 @@ class PublicStorageCache {
|
|
|
139
139
|
/**
|
|
140
140
|
* Read a staged value from storage, if it has been previously written to.
|
|
141
141
|
*
|
|
142
|
-
* @param
|
|
142
|
+
* @param contractAddress - the address of the contract whose storage is being read from
|
|
143
143
|
* @param slot - the slot in the contract's storage being read from
|
|
144
144
|
* @returns the latest value written to slot, or undefined if no value has been written
|
|
145
145
|
*/
|
|
146
|
-
public read(
|
|
147
|
-
return this.cachePerContract.get(
|
|
146
|
+
public read(contractAddress: Fr, slot: Fr): Fr | undefined {
|
|
147
|
+
return this.cachePerContract.get(contractAddress.toBigInt())?.get(slot.toBigInt());
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
151
151
|
* Stage a storage write.
|
|
152
152
|
*
|
|
153
|
-
* @param
|
|
153
|
+
* @param contractAddress - the address of the contract whose storage is being written to
|
|
154
154
|
* @param slot - the slot in the contract's storage being written to
|
|
155
155
|
* @param value - the value being written to the slot
|
|
156
156
|
*/
|
|
157
|
-
public write(
|
|
158
|
-
let cacheAtContract = this.cachePerContract.get(
|
|
157
|
+
public write(contractAddress: Fr, slot: Fr, value: Fr) {
|
|
158
|
+
let cacheAtContract = this.cachePerContract.get(contractAddress.toBigInt());
|
|
159
159
|
if (!cacheAtContract) {
|
|
160
160
|
// If this contract's storage has no staged modifications, create a new inner map to store them
|
|
161
161
|
cacheAtContract = new Map();
|
|
162
|
-
this.cachePerContract.set(
|
|
162
|
+
this.cachePerContract.set(contractAddress.toBigInt(), cacheAtContract);
|
|
163
163
|
}
|
|
164
164
|
cacheAtContract.set(slot.toBigInt(), value);
|
|
165
165
|
}
|
|
@@ -39,11 +39,7 @@ export class NoteHashExists extends Instruction {
|
|
|
39
39
|
const noteHash = memory.get(noteHashOffset).toFr();
|
|
40
40
|
const leafIndex = memory.get(leafIndexOffset).toFr();
|
|
41
41
|
|
|
42
|
-
const exists = await context.persistableState.checkNoteHashExists(
|
|
43
|
-
context.environment.storageAddress,
|
|
44
|
-
noteHash,
|
|
45
|
-
leafIndex,
|
|
46
|
-
);
|
|
42
|
+
const exists = await context.persistableState.checkNoteHashExists(context.environment.address, noteHash, leafIndex);
|
|
47
43
|
memory.set(existsOffset, exists ? new Uint1(1) : new Uint1(0));
|
|
48
44
|
|
|
49
45
|
memory.assert({ reads: 2, writes: 1, addressing });
|
|
@@ -75,7 +71,7 @@ export class EmitNoteHash extends Instruction {
|
|
|
75
71
|
}
|
|
76
72
|
|
|
77
73
|
const noteHash = memory.get(noteHashOffset).toFr();
|
|
78
|
-
context.persistableState.writeNoteHash(context.environment.
|
|
74
|
+
context.persistableState.writeNoteHash(context.environment.address, noteHash);
|
|
79
75
|
|
|
80
76
|
memory.assert({ reads: 1, addressing });
|
|
81
77
|
context.machineState.incrementPc();
|
|
@@ -148,12 +144,12 @@ export class EmitNullifier extends Instruction {
|
|
|
148
144
|
|
|
149
145
|
const nullifier = memory.get(nullifierOffset).toFr();
|
|
150
146
|
try {
|
|
151
|
-
await context.persistableState.writeNullifier(context.environment.
|
|
147
|
+
await context.persistableState.writeNullifier(context.environment.address, nullifier);
|
|
152
148
|
} catch (e) {
|
|
153
149
|
if (e instanceof NullifierCollisionError) {
|
|
154
150
|
// Error is known/expected, raise as InstructionExecutionError that the will lead the simulator to revert this call
|
|
155
151
|
throw new InstructionExecutionError(
|
|
156
|
-
`Attempted to emit duplicate nullifier ${nullifier} (
|
|
152
|
+
`Attempted to emit duplicate nullifier ${nullifier} (contract address: ${context.environment.address}).`,
|
|
157
153
|
);
|
|
158
154
|
} else {
|
|
159
155
|
throw e;
|
|
@@ -6,7 +6,6 @@ import { Instruction } from './instruction.js';
|
|
|
6
6
|
|
|
7
7
|
export enum EnvironmentVariable {
|
|
8
8
|
ADDRESS,
|
|
9
|
-
STORAGEADDRESS,
|
|
10
9
|
SENDER,
|
|
11
10
|
FUNCTIONSELECTOR,
|
|
12
11
|
TRANSACTIONFEE,
|
|
@@ -25,8 +24,6 @@ function getValue(e: EnvironmentVariable, ctx: AvmContext) {
|
|
|
25
24
|
switch (e) {
|
|
26
25
|
case EnvironmentVariable.ADDRESS:
|
|
27
26
|
return new Field(ctx.environment.address.toField());
|
|
28
|
-
case EnvironmentVariable.STORAGEADDRESS:
|
|
29
|
-
return new Field(ctx.environment.storageAddress.toField());
|
|
30
27
|
case EnvironmentVariable.SENDER:
|
|
31
28
|
return new Field(ctx.environment.sender.toField());
|
|
32
29
|
case EnvironmentVariable.FUNCTIONSELECTOR:
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
keccak256,
|
|
3
|
-
keccakf1600,
|
|
4
|
-
pedersenHash,
|
|
5
|
-
poseidon2Permutation,
|
|
6
|
-
sha256Compression,
|
|
7
|
-
} from '@aztec/foundation/crypto';
|
|
8
|
-
|
|
9
|
-
import { strict as assert } from 'assert';
|
|
1
|
+
import { keccakf1600, poseidon2Permutation, sha256Compression } from '@aztec/foundation/crypto';
|
|
10
2
|
|
|
11
3
|
import { type AvmContext } from '../avm_context.js';
|
|
12
|
-
import { Field, TypeTag,
|
|
4
|
+
import { Field, TypeTag, Uint32, Uint64 } from '../avm_memory_types.js';
|
|
13
5
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
14
6
|
import { Addressing } from './addressing_mode.js';
|
|
15
7
|
import { Instruction } from './instruction.js';
|
|
@@ -52,52 +44,6 @@ export class Poseidon2 extends Instruction {
|
|
|
52
44
|
}
|
|
53
45
|
}
|
|
54
46
|
|
|
55
|
-
export class Keccak extends Instruction {
|
|
56
|
-
static type: string = 'KECCAK';
|
|
57
|
-
static readonly opcode: Opcode = Opcode.KECCAK;
|
|
58
|
-
|
|
59
|
-
// Informs (de)serialization. See Instruction.deserialize.
|
|
60
|
-
static readonly wireFormat: OperandType[] = [
|
|
61
|
-
OperandType.UINT8,
|
|
62
|
-
OperandType.UINT8,
|
|
63
|
-
OperandType.UINT32,
|
|
64
|
-
OperandType.UINT32,
|
|
65
|
-
OperandType.UINT32,
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
constructor(
|
|
69
|
-
private indirect: number,
|
|
70
|
-
private dstOffset: number,
|
|
71
|
-
private messageOffset: number,
|
|
72
|
-
private messageSizeOffset: number,
|
|
73
|
-
) {
|
|
74
|
-
super();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// pub fn keccak256(input: [u8], message_size: u32) -> [u8; 32]
|
|
78
|
-
public async execute(context: AvmContext): Promise<void> {
|
|
79
|
-
const memory = context.machineState.memory.track(this.type);
|
|
80
|
-
const operands = [this.dstOffset, this.messageOffset, this.messageSizeOffset];
|
|
81
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
82
|
-
const [dstOffset, messageOffset, messageSizeOffset] = addressing.resolve(operands, memory);
|
|
83
|
-
memory.checkTag(TypeTag.UINT32, messageSizeOffset);
|
|
84
|
-
const messageSize = memory.get(messageSizeOffset).toNumber();
|
|
85
|
-
context.machineState.consumeGas(this.gasCost(messageSize));
|
|
86
|
-
|
|
87
|
-
memory.checkTagsRange(TypeTag.UINT8, messageOffset, messageSize);
|
|
88
|
-
|
|
89
|
-
const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()));
|
|
90
|
-
const hashBuffer = keccak256(messageData);
|
|
91
|
-
|
|
92
|
-
// We need to convert the hashBuffer because map doesn't work as expected on an Uint8Array (Buffer).
|
|
93
|
-
const res = [...hashBuffer].map(byte => new Uint8(byte));
|
|
94
|
-
memory.setSlice(dstOffset, res);
|
|
95
|
-
|
|
96
|
-
memory.assert({ reads: messageSize + 1, writes: 32, addressing });
|
|
97
|
-
context.machineState.incrementPc();
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
47
|
export class KeccakF1600 extends Instruction {
|
|
102
48
|
static type: string = 'KECCAKF1600';
|
|
103
49
|
static readonly opcode: Opcode = Opcode.KECCAKF1600;
|
|
@@ -108,39 +54,30 @@ export class KeccakF1600 extends Instruction {
|
|
|
108
54
|
OperandType.UINT8,
|
|
109
55
|
OperandType.UINT16,
|
|
110
56
|
OperandType.UINT16,
|
|
111
|
-
OperandType.UINT16,
|
|
112
57
|
];
|
|
113
58
|
|
|
114
|
-
constructor(
|
|
115
|
-
private indirect: number,
|
|
116
|
-
private dstOffset: number,
|
|
117
|
-
private stateOffset: number,
|
|
118
|
-
// This is here for compatibility with the CPP side. Should be removed in both.
|
|
119
|
-
private stateSizeOffset: number,
|
|
120
|
-
) {
|
|
59
|
+
constructor(private indirect: number, private dstOffset: number, private inputOffset: number) {
|
|
121
60
|
super();
|
|
122
61
|
}
|
|
123
62
|
|
|
124
63
|
// pub fn keccakf1600(input: [u64; 25]) -> [u64; 25]
|
|
125
64
|
public async execute(context: AvmContext): Promise<void> {
|
|
65
|
+
const inputSize = 25;
|
|
126
66
|
const memory = context.machineState.memory.track(this.type);
|
|
127
|
-
const operands = [this.dstOffset, this.
|
|
67
|
+
const operands = [this.dstOffset, this.inputOffset];
|
|
128
68
|
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
129
|
-
const [dstOffset,
|
|
130
|
-
memory.checkTag(TypeTag.UINT32, stateSizeOffset);
|
|
131
|
-
const stateSize = memory.get(stateSizeOffset).toNumber();
|
|
132
|
-
assert(stateSize === 25, 'Invalid state size for keccakf1600');
|
|
69
|
+
const [dstOffset, inputOffset] = addressing.resolve(operands, memory);
|
|
133
70
|
context.machineState.consumeGas(this.gasCost());
|
|
134
71
|
|
|
135
|
-
memory.checkTagsRange(TypeTag.UINT64,
|
|
72
|
+
memory.checkTagsRange(TypeTag.UINT64, inputOffset, inputSize);
|
|
136
73
|
|
|
137
|
-
const stateData = memory.getSlice(
|
|
74
|
+
const stateData = memory.getSlice(inputOffset, inputSize).map(word => word.toBigInt());
|
|
138
75
|
const updatedState = keccakf1600(stateData);
|
|
139
76
|
|
|
140
77
|
const res = updatedState.map(word => new Uint64(word));
|
|
141
78
|
memory.setSlice(dstOffset, res);
|
|
142
79
|
|
|
143
|
-
memory.assert({ reads:
|
|
80
|
+
memory.assert({ reads: inputSize, writes: inputSize, addressing });
|
|
144
81
|
context.machineState.incrementPc();
|
|
145
82
|
}
|
|
146
83
|
}
|
|
@@ -193,53 +130,3 @@ export class Sha256Compression extends Instruction {
|
|
|
193
130
|
context.machineState.incrementPc();
|
|
194
131
|
}
|
|
195
132
|
}
|
|
196
|
-
|
|
197
|
-
export class Pedersen extends Instruction {
|
|
198
|
-
static type: string = 'PEDERSEN';
|
|
199
|
-
static readonly opcode: Opcode = Opcode.PEDERSEN;
|
|
200
|
-
|
|
201
|
-
// Informs (de)serialization. See Instruction.deserialize.
|
|
202
|
-
static readonly wireFormat: OperandType[] = [
|
|
203
|
-
OperandType.UINT8,
|
|
204
|
-
OperandType.UINT8,
|
|
205
|
-
OperandType.UINT32,
|
|
206
|
-
OperandType.UINT32,
|
|
207
|
-
OperandType.UINT32,
|
|
208
|
-
OperandType.UINT32,
|
|
209
|
-
];
|
|
210
|
-
|
|
211
|
-
constructor(
|
|
212
|
-
private indirect: number,
|
|
213
|
-
private genIndexOffset: number,
|
|
214
|
-
private dstOffset: number,
|
|
215
|
-
private messageOffset: number,
|
|
216
|
-
private messageSizeOffset: number,
|
|
217
|
-
) {
|
|
218
|
-
super();
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
public async execute(context: AvmContext): Promise<void> {
|
|
222
|
-
const memory = context.machineState.memory.track(this.type);
|
|
223
|
-
const operands = [this.genIndexOffset, this.dstOffset, this.messageOffset, this.messageSizeOffset];
|
|
224
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
225
|
-
const [genIndexOffset, dstOffset, messageOffset, messageSizeOffset] = addressing.resolve(operands, memory);
|
|
226
|
-
|
|
227
|
-
// We hash a set of field elements
|
|
228
|
-
const genIndex = Number(memory.get(genIndexOffset).toBigInt());
|
|
229
|
-
memory.checkTag(TypeTag.UINT32, genIndexOffset);
|
|
230
|
-
const messageSize = Number(memory.get(messageSizeOffset).toBigInt());
|
|
231
|
-
memory.checkTag(TypeTag.UINT32, messageSizeOffset);
|
|
232
|
-
const hashData = memory.getSlice(messageOffset, messageSize);
|
|
233
|
-
|
|
234
|
-
context.machineState.consumeGas(this.gasCost(messageSize));
|
|
235
|
-
|
|
236
|
-
memory.checkTagsRange(TypeTag.FIELD, messageOffset, messageSize);
|
|
237
|
-
|
|
238
|
-
// No domain sep for now
|
|
239
|
-
const hash = pedersenHash(hashData, genIndex);
|
|
240
|
-
memory.set(dstOffset, new Field(hash));
|
|
241
|
-
|
|
242
|
-
memory.assert({ reads: messageSize + 2, writes: 1, addressing });
|
|
243
|
-
context.machineState.incrementPc();
|
|
244
|
-
}
|
|
245
|
-
}
|
package/src/avm/opcodes/index.ts
CHANGED
|
@@ -43,7 +43,7 @@ export class SStore extends BaseStorageInstruction {
|
|
|
43
43
|
|
|
44
44
|
const slot = memory.get(slotOffset).toFr();
|
|
45
45
|
const value = memory.get(srcOffset).toFr();
|
|
46
|
-
context.persistableState.writeStorage(context.environment.
|
|
46
|
+
context.persistableState.writeStorage(context.environment.address, slot, value);
|
|
47
47
|
|
|
48
48
|
memory.assert({ reads: 2, addressing });
|
|
49
49
|
context.machineState.incrementPc();
|
|
@@ -68,7 +68,7 @@ export class SLoad extends BaseStorageInstruction {
|
|
|
68
68
|
memory.checkTag(TypeTag.FIELD, slotOffset);
|
|
69
69
|
|
|
70
70
|
const slot = memory.get(slotOffset).toFr();
|
|
71
|
-
const value = await context.persistableState.readStorage(context.environment.
|
|
71
|
+
const value = await context.persistableState.readStorage(context.environment.address, slot);
|
|
72
72
|
memory.set(dstOffset, new Field(value));
|
|
73
73
|
|
|
74
74
|
context.machineState.incrementPc();
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
InternalReturn,
|
|
20
20
|
Jump,
|
|
21
21
|
JumpI,
|
|
22
|
-
Keccak,
|
|
23
22
|
KeccakF1600,
|
|
24
23
|
L1ToL2MessageExists,
|
|
25
24
|
Lt,
|
|
@@ -30,8 +29,6 @@ import {
|
|
|
30
29
|
NoteHashExists,
|
|
31
30
|
NullifierExists,
|
|
32
31
|
Or,
|
|
33
|
-
Pedersen,
|
|
34
|
-
PedersenCommitment,
|
|
35
32
|
Poseidon2,
|
|
36
33
|
Return,
|
|
37
34
|
Revert,
|
|
@@ -131,7 +128,6 @@ const INSTRUCTION_SET = () =>
|
|
|
131
128
|
// Control Flow - Contract Calls
|
|
132
129
|
[Call.opcode, Instruction.deserialize.bind(Call)],
|
|
133
130
|
[StaticCall.opcode, Instruction.deserialize.bind(StaticCall)],
|
|
134
|
-
//[DelegateCall.opcode, Instruction.deserialize.bind(DelegateCall)],
|
|
135
131
|
[Return.opcode, Instruction.deserialize.bind(Return)],
|
|
136
132
|
[Opcode.REVERT_8, Revert.as(Revert.wireFormat8).deserialize],
|
|
137
133
|
[Opcode.REVERT_16, Revert.as(Revert.wireFormat16).deserialize],
|
|
@@ -141,12 +137,9 @@ const INSTRUCTION_SET = () =>
|
|
|
141
137
|
|
|
142
138
|
// Gadgets
|
|
143
139
|
[EcAdd.opcode, Instruction.deserialize.bind(EcAdd)],
|
|
144
|
-
[Keccak.opcode, Instruction.deserialize.bind(Keccak)],
|
|
145
140
|
[Poseidon2.opcode, Instruction.deserialize.bind(Poseidon2)],
|
|
146
141
|
[Sha256Compression.opcode, Instruction.deserialize.bind(Sha256Compression)],
|
|
147
|
-
[Pedersen.opcode, Instruction.deserialize.bind(Pedersen)],
|
|
148
142
|
[MultiScalarMul.opcode, Instruction.deserialize.bind(MultiScalarMul)],
|
|
149
|
-
[PedersenCommitment.opcode, Instruction.deserialize.bind(PedersenCommitment)],
|
|
150
143
|
// Conversions
|
|
151
144
|
[ToRadixLE.opcode, Instruction.deserialize.bind(ToRadixLE)],
|
|
152
145
|
// Future Gadgets -- pending changes in noir
|
|
@@ -69,21 +69,17 @@ export enum Opcode {
|
|
|
69
69
|
// External calls
|
|
70
70
|
CALL,
|
|
71
71
|
STATICCALL,
|
|
72
|
-
DELEGATECALL,
|
|
73
72
|
RETURN,
|
|
74
73
|
REVERT_8,
|
|
75
74
|
REVERT_16,
|
|
76
75
|
// Misc
|
|
77
76
|
DEBUGLOG,
|
|
78
77
|
// Gadgets
|
|
79
|
-
KECCAK,
|
|
80
78
|
POSEIDON2,
|
|
81
79
|
SHA256COMPRESSION,
|
|
82
80
|
KECCAKF1600,
|
|
83
|
-
PEDERSEN, // temp - may be removed, but alot of contracts rely on it
|
|
84
81
|
ECADD,
|
|
85
82
|
MSM,
|
|
86
|
-
PEDERSENCOMMITMENT,
|
|
87
83
|
// Conversion
|
|
88
84
|
TORADIXLE,
|
|
89
85
|
}
|