@aztec/simulator 0.32.1 → 0.34.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/README.md +5 -3
- package/dest/acvm/acvm.js +2 -2
- package/dest/acvm/oracle/index.d.ts +0 -1
- package/dest/acvm/oracle/index.d.ts.map +1 -1
- package/dest/acvm/oracle/index.js +1 -2
- package/dest/acvm/oracle/oracle.d.ts +1 -1
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +4 -5
- package/dest/avm/avm_context.d.ts +4 -14
- package/dest/avm/avm_context.d.ts.map +1 -1
- package/dest/avm/avm_context.js +10 -22
- package/dest/avm/avm_execution_environment.d.ts +4 -3
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +8 -7
- package/dest/avm/avm_gas.d.ts +71 -0
- package/dest/avm/avm_gas.d.ts.map +1 -0
- package/dest/avm/avm_gas.js +161 -0
- package/dest/avm/avm_machine_state.d.ts +4 -2
- package/dest/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/avm/avm_machine_state.js +8 -2
- package/dest/avm/avm_memory_types.d.ts +53 -1
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +99 -6
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +15 -13
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +3 -3
- 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 +5 -5
- package/dest/avm/journal/trace.d.ts +8 -19
- package/dest/avm/journal/trace.d.ts.map +1 -1
- package/dest/avm/journal/trace.js +48 -116
- package/dest/avm/journal/trace_types.d.ts +23 -4
- package/dest/avm/journal/trace_types.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +45 -17
- package/dest/avm/opcodes/addressing_mode.d.ts +5 -3
- package/dest/avm/opcodes/addressing_mode.d.ts.map +1 -1
- package/dest/avm/opcodes/addressing_mode.js +5 -1
- package/dest/avm/opcodes/arithmetic.d.ts +7 -3
- package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/avm/opcodes/arithmetic.js +27 -16
- package/dest/avm/opcodes/bitwise.d.ts +21 -20
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +43 -65
- package/dest/avm/opcodes/comparators.d.ts +12 -9
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +22 -32
- package/dest/avm/opcodes/context_getters.d.ts +20 -0
- package/dest/avm/opcodes/context_getters.d.ts.map +1 -0
- package/dest/avm/opcodes/context_getters.js +26 -0
- package/dest/avm/opcodes/contract.d.ts +14 -0
- package/dest/avm/opcodes/contract.d.ts.map +1 -0
- package/dest/avm/opcodes/contract.js +49 -0
- package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/avm/opcodes/control_flow.js +12 -2
- package/dest/avm/opcodes/environment_getters.d.ts +30 -33
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +34 -43
- package/dest/avm/opcodes/external_calls.d.ts +13 -19
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +69 -72
- package/dest/avm/opcodes/hashing.d.ts +2 -1
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +37 -18
- package/dest/avm/opcodes/index.d.ts +1 -0
- package/dest/avm/opcodes/index.d.ts.map +1 -1
- package/dest/avm/opcodes/index.js +2 -1
- package/dest/avm/opcodes/instruction.d.ts +10 -15
- package/dest/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction.js +12 -22
- package/dest/avm/opcodes/instruction_impl.d.ts +14 -0
- package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction_impl.js +37 -16
- package/dest/avm/opcodes/memory.d.ts +4 -3
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +38 -19
- package/dest/avm/opcodes/storage.d.ts +5 -0
- package/dest/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/avm/opcodes/storage.js +21 -7
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +7 -5
- package/dest/avm/serialization/instruction_serialization.d.ts +12 -11
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +13 -12
- package/dest/client/client_execution_context.d.ts +2 -2
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +6 -6
- package/dest/client/private_execution.d.ts +1 -1
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +8 -4
- package/dest/client/unconstrained_execution.d.ts +1 -1
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +2 -2
- package/dest/client/view_data_oracle.d.ts +2 -2
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +2 -2
- package/dest/public/executor.d.ts +2 -8
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +101 -69
- package/dest/public/index.d.ts +1 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/public_execution_context.d.ts +6 -6
- package/dest/public/public_execution_context.d.ts.map +1 -1
- package/dest/public/public_execution_context.js +8 -12
- package/dest/public/transitional_adaptors.d.ts +32 -0
- package/dest/public/transitional_adaptors.d.ts.map +1 -0
- package/dest/public/transitional_adaptors.js +161 -0
- package/package.json +15 -9
- package/src/acvm/acvm.ts +1 -1
- package/src/acvm/oracle/index.ts +0 -1
- package/src/acvm/oracle/oracle.ts +3 -4
- package/src/avm/avm_context.ts +11 -33
- package/src/avm/avm_execution_environment.ts +9 -17
- package/src/avm/{avm_gas_cost.ts → avm_gas.ts} +75 -21
- package/src/avm/avm_machine_state.ts +9 -2
- package/src/avm/avm_memory_types.ts +134 -6
- package/src/avm/avm_simulator.ts +14 -12
- package/src/avm/fixtures/index.ts +2 -1
- package/src/avm/journal/journal.ts +24 -17
- package/src/avm/journal/trace.ts +59 -121
- package/src/avm/journal/trace_types.ts +39 -39
- package/src/avm/opcodes/accrued_substate.ts +58 -23
- package/src/avm/opcodes/addressing_mode.ts +8 -3
- package/src/avm/opcodes/arithmetic.ts +32 -22
- package/src/avm/opcodes/bitwise.ts +49 -83
- package/src/avm/opcodes/comparators.ts +28 -43
- package/src/avm/opcodes/context_getters.ts +32 -0
- package/src/avm/opcodes/contract.ts +58 -0
- package/src/avm/opcodes/control_flow.ts +23 -5
- package/src/avm/opcodes/environment_getters.ts +35 -44
- package/src/avm/opcodes/external_calls.ts +90 -89
- package/src/avm/opcodes/hashing.ts +45 -22
- package/src/avm/opcodes/index.ts +1 -0
- package/src/avm/opcodes/instruction.ts +14 -26
- package/src/avm/opcodes/instruction_impl.ts +45 -15
- package/src/avm/opcodes/memory.ts +48 -28
- package/src/avm/opcodes/storage.ts +26 -12
- package/src/avm/serialization/bytecode_serialization.ts +6 -3
- package/src/avm/serialization/instruction_serialization.ts +1 -0
- package/src/client/client_execution_context.ts +5 -5
- package/src/client/private_execution.ts +10 -4
- package/src/client/unconstrained_execution.ts +1 -1
- package/src/client/view_data_oracle.ts +1 -1
- package/src/public/executor.ts +123 -75
- package/src/public/index.ts +2 -2
- package/src/public/public_execution_context.ts +14 -19
- package/src/public/transitional_adaptors.ts +240 -0
- package/dest/acvm/oracle/debug.d.ts +0 -19
- package/dest/acvm/oracle/debug.d.ts.map +0 -1
- package/dest/acvm/oracle/debug.js +0 -95
- package/dest/avm/avm_gas_cost.d.ts +0 -322
- package/dest/avm/avm_gas_cost.d.ts.map +0 -1
- package/dest/avm/avm_gas_cost.js +0 -118
- package/dest/avm/temporary_executor_migration.d.ts +0 -25
- package/dest/avm/temporary_executor_migration.d.ts.map +0 -1
- package/dest/avm/temporary_executor_migration.js +0 -83
- package/src/acvm/oracle/debug.ts +0 -109
- package/src/avm/temporary_executor_migration.ts +0 -122
|
@@ -29,19 +29,24 @@ export class Poseidon2 extends Instruction {
|
|
|
29
29
|
super();
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
async execute(context: AvmContext): Promise<void> {
|
|
32
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
33
|
+
const memoryOperations = { reads: this.messageSize, writes: 1, indirect: this.indirect };
|
|
34
|
+
const memory = context.machineState.memory.track(this.type);
|
|
35
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
36
|
+
|
|
33
37
|
// We hash a set of field elements
|
|
34
38
|
const [dstOffset, messageOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
35
39
|
[this.dstOffset, this.messageOffset],
|
|
36
|
-
|
|
40
|
+
memory,
|
|
37
41
|
);
|
|
38
42
|
|
|
39
43
|
// Memory pointer will be indirect
|
|
40
|
-
const hashData =
|
|
44
|
+
const hashData = memory.getSlice(messageOffset, this.messageSize).map(word => word.toBuffer());
|
|
41
45
|
|
|
42
46
|
const hash = poseidonHash(hashData);
|
|
43
|
-
|
|
47
|
+
memory.set(dstOffset, new Field(hash));
|
|
44
48
|
|
|
49
|
+
memory.assert(memoryOperations);
|
|
45
50
|
context.machineState.incrementPc();
|
|
46
51
|
}
|
|
47
52
|
}
|
|
@@ -69,14 +74,18 @@ export class Keccak extends Instruction {
|
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
// Note hash output is 32 bytes, so takes up two fields
|
|
72
|
-
async execute(context: AvmContext): Promise<void> {
|
|
77
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
78
|
+
const memoryOperations = { reads: this.messageSize, writes: 2, indirect: this.indirect };
|
|
79
|
+
const memory = context.machineState.memory.track(this.type);
|
|
80
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
81
|
+
|
|
73
82
|
// We hash a set of field elements
|
|
74
83
|
const [dstOffset, messageOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
75
84
|
[this.dstOffset, this.messageOffset],
|
|
76
|
-
|
|
85
|
+
memory,
|
|
77
86
|
);
|
|
78
87
|
|
|
79
|
-
const hashData =
|
|
88
|
+
const hashData = memory.getSlice(messageOffset, this.messageSize).map(word => word.toBuffer());
|
|
80
89
|
|
|
81
90
|
const hash = keccak(Buffer.concat(hashData));
|
|
82
91
|
|
|
@@ -84,9 +93,10 @@ export class Keccak extends Instruction {
|
|
|
84
93
|
const high = new Field(toBigIntBE(hash.subarray(0, 16)));
|
|
85
94
|
const low = new Field(toBigIntBE(hash.subarray(16, 32)));
|
|
86
95
|
|
|
87
|
-
|
|
88
|
-
|
|
96
|
+
memory.set(dstOffset, high);
|
|
97
|
+
memory.set(dstOffset + 1, low);
|
|
89
98
|
|
|
99
|
+
memory.assert(memoryOperations);
|
|
90
100
|
context.machineState.incrementPc();
|
|
91
101
|
}
|
|
92
102
|
}
|
|
@@ -114,14 +124,18 @@ export class Sha256 extends Instruction {
|
|
|
114
124
|
}
|
|
115
125
|
|
|
116
126
|
// Note hash output is 32 bytes, so takes up two fields
|
|
117
|
-
async execute(context: AvmContext): Promise<void> {
|
|
127
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
128
|
+
const memoryOperations = { reads: this.messageSize, writes: 2, indirect: this.indirect };
|
|
129
|
+
const memory = context.machineState.memory.track(this.type);
|
|
130
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
131
|
+
|
|
118
132
|
const [dstOffset, messageOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
119
133
|
[this.dstOffset, this.messageOffset],
|
|
120
|
-
|
|
134
|
+
memory,
|
|
121
135
|
);
|
|
122
136
|
|
|
123
137
|
// We hash a set of field elements
|
|
124
|
-
const hashData =
|
|
138
|
+
const hashData = memory.getSlice(messageOffset, this.messageSize).map(word => word.toBuffer());
|
|
125
139
|
|
|
126
140
|
const hash = sha256(Buffer.concat(hashData));
|
|
127
141
|
|
|
@@ -129,9 +143,10 @@ export class Sha256 extends Instruction {
|
|
|
129
143
|
const high = new Field(toBigIntBE(hash.subarray(0, 16)));
|
|
130
144
|
const low = new Field(toBigIntBE(hash.subarray(16, 32)));
|
|
131
145
|
|
|
132
|
-
|
|
133
|
-
|
|
146
|
+
memory.set(dstOffset, high);
|
|
147
|
+
memory.set(dstOffset + 1, low);
|
|
134
148
|
|
|
149
|
+
memory.assert(memoryOperations);
|
|
135
150
|
context.machineState.incrementPc();
|
|
136
151
|
}
|
|
137
152
|
}
|
|
@@ -147,10 +162,12 @@ export class Pedersen extends Instruction {
|
|
|
147
162
|
OperandType.UINT32,
|
|
148
163
|
OperandType.UINT32,
|
|
149
164
|
OperandType.UINT32,
|
|
165
|
+
OperandType.UINT32,
|
|
150
166
|
];
|
|
151
167
|
|
|
152
168
|
constructor(
|
|
153
169
|
private indirect: number,
|
|
170
|
+
private genIndexOffset: number,
|
|
154
171
|
private dstOffset: number,
|
|
155
172
|
private messageOffset: number,
|
|
156
173
|
private messageSizeOffset: number,
|
|
@@ -158,20 +175,26 @@ export class Pedersen extends Instruction {
|
|
|
158
175
|
super();
|
|
159
176
|
}
|
|
160
177
|
|
|
161
|
-
async execute(context: AvmContext): Promise<void> {
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
178
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
179
|
+
const memory = context.machineState.memory.track(this.type);
|
|
180
|
+
const [genIndexOffset, dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
181
|
+
[this.genIndexOffset, this.dstOffset, this.messageOffset, this.messageSizeOffset],
|
|
182
|
+
memory,
|
|
165
183
|
);
|
|
166
184
|
|
|
167
185
|
// We hash a set of field elements
|
|
168
|
-
const
|
|
169
|
-
const
|
|
186
|
+
const genIndex = Number(memory.get(genIndexOffset).toBigInt());
|
|
187
|
+
const messageSize = Number(memory.get(messageSizeOffset).toBigInt());
|
|
188
|
+
const hashData = memory.getSlice(messageOffset, messageSize);
|
|
189
|
+
|
|
190
|
+
const memoryOperations = { reads: messageSize + 2, writes: 1, indirect: this.indirect };
|
|
191
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
170
192
|
|
|
171
193
|
// No domain sep for now
|
|
172
|
-
const hash = pedersenHash(hashData);
|
|
173
|
-
|
|
194
|
+
const hash = pedersenHash(hashData, genIndex);
|
|
195
|
+
memory.set(dstOffset, new Field(hash));
|
|
174
196
|
|
|
197
|
+
memory.assert(memoryOperations);
|
|
175
198
|
context.machineState.incrementPc();
|
|
176
199
|
}
|
|
177
200
|
}
|
package/src/avm/opcodes/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { strict as assert } from 'assert';
|
|
2
2
|
|
|
3
3
|
import type { AvmContext } from '../avm_context.js';
|
|
4
|
-
import {
|
|
4
|
+
import { getBaseGasCost, getMemoryGasCost, sumGas } from '../avm_gas.js';
|
|
5
|
+
import { type MemoryOperations } from '../avm_memory_types.js';
|
|
5
6
|
import { type BufferCursor } from '../serialization/buffer_cursor.js';
|
|
6
7
|
import { Opcode, type OperandType, deserialize, serialize } from '../serialization/instruction_serialization.js';
|
|
7
8
|
|
|
@@ -20,31 +21,7 @@ export abstract class Instruction {
|
|
|
20
21
|
* This is the main entry point for the instruction.
|
|
21
22
|
* @param context - The AvmContext in which the instruction executes.
|
|
22
23
|
*/
|
|
23
|
-
public
|
|
24
|
-
context.machineState.consumeGas(this.gasCost());
|
|
25
|
-
return this.execute(context);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Loads default gas cost for the instruction from the GasCosts table.
|
|
30
|
-
* Instruction sub-classes can override this if their gas cost is not fixed.
|
|
31
|
-
*/
|
|
32
|
-
protected gasCost(): GasCost {
|
|
33
|
-
const gasCost = GasCosts[this.opcode];
|
|
34
|
-
if (gasCost === DynamicGasCost) {
|
|
35
|
-
throw new Error(`Instruction ${this.type} must define its own gas cost`);
|
|
36
|
-
}
|
|
37
|
-
return gasCost;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Execute the instruction.
|
|
42
|
-
* Instruction sub-classes must implement this.
|
|
43
|
-
* As an AvmContext executes its contract code, it calls this function for
|
|
44
|
-
* each instruction until the machine state signals "halted".
|
|
45
|
-
* @param context - The AvmContext in which the instruction executes.
|
|
46
|
-
*/
|
|
47
|
-
protected abstract execute(context: AvmContext): Promise<void>;
|
|
24
|
+
public abstract execute(context: AvmContext): Promise<void>;
|
|
48
25
|
|
|
49
26
|
/**
|
|
50
27
|
* Generate a string representation of the instruction including
|
|
@@ -85,6 +62,17 @@ export abstract class Instruction {
|
|
|
85
62
|
return new this(...args);
|
|
86
63
|
}
|
|
87
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Computes gas cost for the instruction based on its base cost and memory operations.
|
|
67
|
+
* @param memoryOps Memory operations performed by the instruction.
|
|
68
|
+
* @returns Gas cost.
|
|
69
|
+
*/
|
|
70
|
+
protected gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }> = {}) {
|
|
71
|
+
const baseGasCost = getBaseGasCost(this.opcode);
|
|
72
|
+
const memoryGasCost = getMemoryGasCost(memoryOps);
|
|
73
|
+
return sumGas(baseGasCost, memoryGasCost);
|
|
74
|
+
}
|
|
75
|
+
|
|
88
76
|
/**
|
|
89
77
|
* Returns the stringified type of the instruction.
|
|
90
78
|
* Instruction sub-classes should have a static `type` property.
|
|
@@ -1,19 +1,34 @@
|
|
|
1
|
+
import { type AvmContext } from '../avm_context.js';
|
|
2
|
+
import { type MemoryValue } from '../avm_memory_types.js';
|
|
1
3
|
import { OperandType } from '../serialization/instruction_serialization.js';
|
|
2
4
|
import { Instruction } from './instruction.js';
|
|
3
5
|
|
|
6
|
+
/** Wire format that informs deserialization for instructions with two operands. */
|
|
7
|
+
export const TwoOperandWireFormat = [
|
|
8
|
+
OperandType.UINT8,
|
|
9
|
+
OperandType.UINT8,
|
|
10
|
+
OperandType.UINT8,
|
|
11
|
+
OperandType.UINT32,
|
|
12
|
+
OperandType.UINT32,
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
/** Wire format that informs deserialization for instructions with three operands. */
|
|
16
|
+
export const ThreeOperandWireFormat = [
|
|
17
|
+
OperandType.UINT8,
|
|
18
|
+
OperandType.UINT8,
|
|
19
|
+
OperandType.UINT8,
|
|
20
|
+
OperandType.UINT32,
|
|
21
|
+
OperandType.UINT32,
|
|
22
|
+
OperandType.UINT32,
|
|
23
|
+
];
|
|
24
|
+
|
|
4
25
|
/**
|
|
5
26
|
* Covers (de)serialization for an instruction with:
|
|
6
27
|
* indirect, inTag, and two UINT32s.
|
|
7
28
|
*/
|
|
8
29
|
export abstract class TwoOperandInstruction extends Instruction {
|
|
9
30
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
10
|
-
static readonly wireFormat: OperandType[] =
|
|
11
|
-
OperandType.UINT8,
|
|
12
|
-
OperandType.UINT8,
|
|
13
|
-
OperandType.UINT8,
|
|
14
|
-
OperandType.UINT32,
|
|
15
|
-
OperandType.UINT32,
|
|
16
|
-
];
|
|
31
|
+
static readonly wireFormat: OperandType[] = TwoOperandWireFormat;
|
|
17
32
|
|
|
18
33
|
constructor(
|
|
19
34
|
protected indirect: number,
|
|
@@ -31,14 +46,7 @@ export abstract class TwoOperandInstruction extends Instruction {
|
|
|
31
46
|
*/
|
|
32
47
|
export abstract class ThreeOperandInstruction extends Instruction {
|
|
33
48
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
34
|
-
static readonly wireFormat: OperandType[] =
|
|
35
|
-
OperandType.UINT8,
|
|
36
|
-
OperandType.UINT8,
|
|
37
|
-
OperandType.UINT8,
|
|
38
|
-
OperandType.UINT32,
|
|
39
|
-
OperandType.UINT32,
|
|
40
|
-
OperandType.UINT32,
|
|
41
|
-
];
|
|
49
|
+
static readonly wireFormat: OperandType[] = ThreeOperandWireFormat;
|
|
42
50
|
|
|
43
51
|
constructor(
|
|
44
52
|
protected indirect: number,
|
|
@@ -50,3 +58,25 @@ export abstract class ThreeOperandInstruction extends Instruction {
|
|
|
50
58
|
super();
|
|
51
59
|
}
|
|
52
60
|
}
|
|
61
|
+
|
|
62
|
+
export abstract class GetterInstruction extends Instruction {
|
|
63
|
+
// Informs (de)serialization. See Instruction.deserialize.
|
|
64
|
+
static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT32];
|
|
65
|
+
|
|
66
|
+
constructor(protected indirect: number, protected dstOffset: number) {
|
|
67
|
+
super();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
71
|
+
const memoryOperations = { writes: 1, indirect: this.indirect };
|
|
72
|
+
const memory = context.machineState.memory.track(this.type);
|
|
73
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
74
|
+
|
|
75
|
+
memory.set(this.dstOffset, this.getValue(context));
|
|
76
|
+
|
|
77
|
+
memory.assert(memoryOperations);
|
|
78
|
+
context.machineState.incrementPc();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
protected abstract getValue(env: AvmContext): MemoryValue;
|
|
82
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
|
-
import {
|
|
3
|
-
import { Field, TaggedMemory, TypeTag } from '../avm_memory_types.js';
|
|
2
|
+
import { getBaseGasCost, getMemoryGasCost, mulGas, sumGas } from '../avm_gas.js';
|
|
3
|
+
import { Field, type MemoryOperations, TaggedMemory, TypeTag } from '../avm_memory_types.js';
|
|
4
4
|
import { InstructionExecutionError } from '../errors.js';
|
|
5
5
|
import { BufferCursor } from '../serialization/buffer_cursor.js';
|
|
6
6
|
import { Opcode, OperandType, deserialize, serialize } from '../serialization/instruction_serialization.js';
|
|
@@ -69,21 +69,22 @@ export class Set extends Instruction {
|
|
|
69
69
|
return new this(...args);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
async execute(context: AvmContext): Promise<void> {
|
|
72
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
73
|
+
const memoryOperations = { writes: 1, indirect: this.indirect };
|
|
74
|
+
const memory = context.machineState.memory.track(this.type);
|
|
75
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
76
|
+
|
|
73
77
|
// Per the YP, the tag cannot be a field.
|
|
74
78
|
if ([TypeTag.FIELD, TypeTag.UNINITIALIZED, TypeTag.INVALID].includes(this.inTag)) {
|
|
75
79
|
throw new InstructionExecutionError(`Invalid tag ${TypeTag[this.inTag]} for SET.`);
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
const res = TaggedMemory.integralFromTag(this.value, this.inTag);
|
|
79
|
-
|
|
83
|
+
memory.set(this.dstOffset, res);
|
|
80
84
|
|
|
85
|
+
memory.assert(memoryOperations);
|
|
81
86
|
context.machineState.incrementPc();
|
|
82
87
|
}
|
|
83
|
-
|
|
84
|
-
protected gasCost(): GasCost {
|
|
85
|
-
return makeGasCost({ l2Gas: GasCostConstants.SET_COST_PER_BYTE * getGasCostMultiplierFromTypeTag(this.inTag) });
|
|
86
|
-
}
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
export class CMov extends Instruction {
|
|
@@ -109,14 +110,19 @@ export class CMov extends Instruction {
|
|
|
109
110
|
super();
|
|
110
111
|
}
|
|
111
112
|
|
|
112
|
-
async execute(context: AvmContext): Promise<void> {
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
113
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
114
|
+
const memoryOperations = { reads: 3, writes: 1, indirect: this.indirect };
|
|
115
|
+
const memory = context.machineState.memory.track(this.type);
|
|
116
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
117
|
+
|
|
118
|
+
const a = memory.get(this.aOffset);
|
|
119
|
+
const b = memory.get(this.bOffset);
|
|
120
|
+
const cond = memory.get(this.condOffset);
|
|
116
121
|
|
|
117
122
|
// TODO: reconsider toBigInt() here
|
|
118
|
-
|
|
123
|
+
memory.set(this.dstOffset, cond.toBigInt() > 0 ? a : b);
|
|
119
124
|
|
|
125
|
+
memory.assert(memoryOperations);
|
|
120
126
|
context.machineState.incrementPc();
|
|
121
127
|
}
|
|
122
128
|
}
|
|
@@ -129,15 +135,20 @@ export class Cast extends TwoOperandInstruction {
|
|
|
129
135
|
super(indirect, dstTag, aOffset, dstOffset);
|
|
130
136
|
}
|
|
131
137
|
|
|
132
|
-
async execute(context: AvmContext): Promise<void> {
|
|
133
|
-
const
|
|
138
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
139
|
+
const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
|
|
140
|
+
const memory = context.machineState.memory.track(this.type);
|
|
141
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
142
|
+
|
|
143
|
+
const a = memory.get(this.aOffset);
|
|
134
144
|
|
|
135
145
|
// TODO: consider not using toBigInt()
|
|
136
146
|
const casted =
|
|
137
147
|
this.inTag == TypeTag.FIELD ? new Field(a.toBigInt()) : TaggedMemory.integralFromTag(a.toBigInt(), this.inTag);
|
|
138
148
|
|
|
139
|
-
|
|
149
|
+
memory.set(this.dstOffset, casted);
|
|
140
150
|
|
|
151
|
+
memory.assert(memoryOperations);
|
|
141
152
|
context.machineState.incrementPc();
|
|
142
153
|
}
|
|
143
154
|
}
|
|
@@ -157,16 +168,18 @@ export class Mov extends Instruction {
|
|
|
157
168
|
super();
|
|
158
169
|
}
|
|
159
170
|
|
|
160
|
-
async execute(context: AvmContext): Promise<void> {
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
171
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
172
|
+
const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
|
|
173
|
+
const memory = context.machineState.memory.track(this.type);
|
|
174
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
175
|
+
|
|
176
|
+
const [srcOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.srcOffset, this.dstOffset], memory);
|
|
165
177
|
|
|
166
|
-
const a =
|
|
178
|
+
const a = memory.get(srcOffset);
|
|
167
179
|
|
|
168
|
-
|
|
180
|
+
memory.set(dstOffset, a);
|
|
169
181
|
|
|
182
|
+
memory.assert(memoryOperations);
|
|
170
183
|
context.machineState.incrementPc();
|
|
171
184
|
}
|
|
172
185
|
}
|
|
@@ -187,19 +200,26 @@ export class CalldataCopy extends Instruction {
|
|
|
187
200
|
super();
|
|
188
201
|
}
|
|
189
202
|
|
|
190
|
-
async execute(context: AvmContext): Promise<void> {
|
|
191
|
-
const
|
|
203
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
204
|
+
const memoryOperations = { writes: this.copySize, indirect: this.indirect };
|
|
205
|
+
const memory = context.machineState.memory.track(this.type);
|
|
206
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
207
|
+
|
|
208
|
+
const [dstOffset] = Addressing.fromWire(this.indirect).resolve([this.dstOffset], memory);
|
|
192
209
|
|
|
193
210
|
const transformedData = context.environment.calldata
|
|
194
211
|
.slice(this.cdOffset, this.cdOffset + this.copySize)
|
|
195
212
|
.map(f => new Field(f));
|
|
196
213
|
|
|
197
|
-
|
|
214
|
+
memory.setSlice(dstOffset, transformedData);
|
|
198
215
|
|
|
216
|
+
memory.assert(memoryOperations);
|
|
199
217
|
context.machineState.incrementPc();
|
|
200
218
|
}
|
|
201
219
|
|
|
202
|
-
protected gasCost(
|
|
203
|
-
|
|
220
|
+
protected gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }> = {}) {
|
|
221
|
+
const baseGasCost = mulGas(getBaseGasCost(this.opcode), this.copySize);
|
|
222
|
+
const memoryGasCost = getMemoryGasCost(memoryOps);
|
|
223
|
+
return sumGas(baseGasCost, memoryGasCost);
|
|
204
224
|
}
|
|
205
225
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
|
|
3
3
|
import type { AvmContext } from '../avm_context.js';
|
|
4
|
-
import {
|
|
4
|
+
import { type Gas, getBaseGasCost, getMemoryGasCost, mulGas, sumGas } from '../avm_gas.js';
|
|
5
|
+
import { Field, type MemoryOperations } from '../avm_memory_types.js';
|
|
5
6
|
import { InstructionExecutionError } from '../errors.js';
|
|
6
7
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
7
8
|
import { Addressing } from './addressing_mode.js';
|
|
@@ -25,6 +26,12 @@ abstract class BaseStorageInstruction extends Instruction {
|
|
|
25
26
|
) {
|
|
26
27
|
super();
|
|
27
28
|
}
|
|
29
|
+
|
|
30
|
+
protected gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }>): Gas {
|
|
31
|
+
const baseGasCost = mulGas(getBaseGasCost(this.opcode), this.size);
|
|
32
|
+
const memoryGasCost = getMemoryGasCost(memoryOps);
|
|
33
|
+
return sumGas(baseGasCost, memoryGasCost);
|
|
34
|
+
}
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
export class SStore extends BaseStorageInstruction {
|
|
@@ -35,24 +42,26 @@ export class SStore extends BaseStorageInstruction {
|
|
|
35
42
|
super(indirect, srcOffset, srcSize, slotOffset);
|
|
36
43
|
}
|
|
37
44
|
|
|
38
|
-
async execute(context: AvmContext): Promise<void> {
|
|
45
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
39
46
|
if (context.environment.isStaticCall) {
|
|
40
47
|
throw new StaticCallStorageAlterError();
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
);
|
|
50
|
+
const memoryOperations = { reads: this.size + 1, indirect: this.indirect };
|
|
51
|
+
const memory = context.machineState.memory.track(this.type);
|
|
52
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
47
53
|
|
|
48
|
-
const
|
|
49
|
-
|
|
54
|
+
const [srcOffset, slotOffset] = Addressing.fromWire(this.indirect).resolve([this.aOffset, this.bOffset], memory);
|
|
55
|
+
|
|
56
|
+
const slot = memory.get(slotOffset).toFr();
|
|
57
|
+
const data = memory.getSlice(srcOffset, this.size).map(field => field.toFr());
|
|
50
58
|
|
|
51
59
|
for (const [index, value] of Object.entries(data)) {
|
|
52
60
|
const adjustedSlot = slot.add(new Fr(BigInt(index)));
|
|
53
61
|
context.persistableState.writeStorage(context.environment.storageAddress, adjustedSlot, value);
|
|
54
62
|
}
|
|
55
63
|
|
|
64
|
+
memory.assert(memoryOperations);
|
|
56
65
|
context.machineState.incrementPc();
|
|
57
66
|
}
|
|
58
67
|
}
|
|
@@ -65,13 +74,17 @@ export class SLoad extends BaseStorageInstruction {
|
|
|
65
74
|
super(indirect, slotOffset, size, dstOffset);
|
|
66
75
|
}
|
|
67
76
|
|
|
68
|
-
async execute(context: AvmContext): Promise<void> {
|
|
77
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
78
|
+
const memoryOperations = { writes: this.size, reads: 1, indirect: this.indirect };
|
|
79
|
+
const memory = context.machineState.memory.track(this.type);
|
|
80
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
81
|
+
|
|
69
82
|
const [aOffset, size, bOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
70
83
|
[this.aOffset, this.size, this.bOffset],
|
|
71
|
-
|
|
84
|
+
memory,
|
|
72
85
|
);
|
|
73
86
|
|
|
74
|
-
const slot =
|
|
87
|
+
const slot = memory.get(aOffset);
|
|
75
88
|
|
|
76
89
|
// Write each read value from storage into memory
|
|
77
90
|
for (let i = 0; i < size; i++) {
|
|
@@ -80,10 +93,11 @@ export class SLoad extends BaseStorageInstruction {
|
|
|
80
93
|
new Fr(slot.toBigInt() + BigInt(i)),
|
|
81
94
|
);
|
|
82
95
|
|
|
83
|
-
|
|
96
|
+
memory.set(bOffset + i, new Field(data));
|
|
84
97
|
}
|
|
85
98
|
|
|
86
99
|
context.machineState.incrementPc();
|
|
100
|
+
memory.assert(memoryOperations);
|
|
87
101
|
}
|
|
88
102
|
}
|
|
89
103
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DAGasLeft, L1GasLeft, L2GasLeft } from '../opcodes/context_getters.js';
|
|
1
2
|
import { Keccak, Pedersen, Poseidon2, Sha256 } from '../opcodes/hashing.js';
|
|
2
3
|
import {
|
|
3
4
|
Add,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
FeePerL1Gas,
|
|
19
20
|
FeePerL2Gas,
|
|
20
21
|
FieldDiv,
|
|
22
|
+
GetContractInstance,
|
|
21
23
|
InternalCall,
|
|
22
24
|
InternalReturn,
|
|
23
25
|
Jump,
|
|
@@ -101,9 +103,9 @@ const INSTRUCTION_SET = () =>
|
|
|
101
103
|
|
|
102
104
|
// Machine State
|
|
103
105
|
// Machine State - Gas
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
[L1GasLeft.opcode, L1GasLeft],
|
|
107
|
+
[L2GasLeft.opcode, L2GasLeft],
|
|
108
|
+
[DAGasLeft.opcode, DAGasLeft],
|
|
107
109
|
// Machine State - Internal Control Flow
|
|
108
110
|
[Jump.opcode, Jump],
|
|
109
111
|
[JumpI.opcode, JumpI],
|
|
@@ -126,6 +128,7 @@ const INSTRUCTION_SET = () =>
|
|
|
126
128
|
// Accrued Substate
|
|
127
129
|
[EmitUnencryptedLog.opcode, EmitUnencryptedLog],
|
|
128
130
|
[SendL2ToL1Message.opcode, SendL2ToL1Message],
|
|
131
|
+
[GetContractInstance.opcode, GetContractInstance],
|
|
129
132
|
|
|
130
133
|
// Control Flow - Contract Calls
|
|
131
134
|
[Call.opcode, Call],
|
|
@@ -235,7 +235,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
235
235
|
offset,
|
|
236
236
|
});
|
|
237
237
|
|
|
238
|
-
this.log(
|
|
238
|
+
this.log.debug(
|
|
239
239
|
`Returning ${notes.length} notes for ${this.callContext.storageContractAddress} at ${storageSlot}: ${notes
|
|
240
240
|
.map(n => `${n.nonce.toString()}:[${n.note.items.map(i => i.toString()).join(',')}]`)
|
|
241
241
|
.join(', ')}`,
|
|
@@ -316,7 +316,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
316
316
|
public emitUnencryptedLog(log: UnencryptedL2Log) {
|
|
317
317
|
this.unencryptedLogs.push(log);
|
|
318
318
|
const text = log.toHumanReadable();
|
|
319
|
-
this.log(`Emitted unencrypted log: "${text.length > 100 ? text.slice(0, 100) + '...' : text}"`);
|
|
319
|
+
this.log.verbose(`Emitted unencrypted log: "${text.length > 100 ? text.slice(0, 100) + '...' : text}"`);
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
#checkValidStaticCall(childExecutionResult: ExecutionResult) {
|
|
@@ -349,7 +349,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
349
349
|
isStaticCall: boolean,
|
|
350
350
|
isDelegateCall: boolean,
|
|
351
351
|
) {
|
|
352
|
-
this.log(
|
|
352
|
+
this.log.debug(
|
|
353
353
|
`Calling private function ${this.contractAddress}:${functionSelector} from ${this.callContext.storageContractAddress}`,
|
|
354
354
|
);
|
|
355
355
|
|
|
@@ -441,7 +441,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
441
441
|
// side-effect counter, that will leak info about how many other private
|
|
442
442
|
// side-effects occurred in the TX. Ultimately the private kernel should
|
|
443
443
|
// just output everything in the proper order without any counters.
|
|
444
|
-
this.log(
|
|
444
|
+
this.log.verbose(
|
|
445
445
|
`Enqueued call to public function (with side-effect counter #${sideEffectCounter}) ${targetContractAddress}:${functionSelector}(${targetArtifact.name})`,
|
|
446
446
|
);
|
|
447
447
|
|
|
@@ -497,7 +497,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
497
497
|
throw new Error(`No witness for slot ${storageSlot.toString()}`);
|
|
498
498
|
}
|
|
499
499
|
const value = witness.leafPreimage.value;
|
|
500
|
-
this.log(`Oracle storage read: slot=${storageSlot.toString()} value=${value}`);
|
|
500
|
+
this.log.debug(`Oracle storage read: slot=${storageSlot.toString()} value=${value}`);
|
|
501
501
|
values.push(value);
|
|
502
502
|
}
|
|
503
503
|
return values;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FunctionData, PrivateCallStackItem, PrivateCircuitPublicInputs } from '@aztec/circuits.js';
|
|
2
|
-
import { type FunctionArtifactWithDebugMetadata, decodeReturnValues } from '@aztec/foundation/abi';
|
|
2
|
+
import { type AbiType, type FunctionArtifactWithDebugMetadata, decodeReturnValues } from '@aztec/foundation/abi';
|
|
3
3
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
@@ -22,7 +22,7 @@ export async function executePrivateFunction(
|
|
|
22
22
|
log = createDebugLogger('aztec:simulator:secret_execution'),
|
|
23
23
|
): Promise<ExecutionResult> {
|
|
24
24
|
const functionSelector = functionData.selector;
|
|
25
|
-
log(`Executing external function ${contractAddress}:${functionSelector}(${artifact.name})`);
|
|
25
|
+
log.verbose(`Executing external function ${contractAddress}:${functionSelector}(${artifact.name})`);
|
|
26
26
|
const acir = artifact.bytecode;
|
|
27
27
|
const initialWitness = context.getInitialWitness(artifact);
|
|
28
28
|
const acvmCallback = new Oracle(context);
|
|
@@ -52,7 +52,13 @@ export async function executePrivateFunction(
|
|
|
52
52
|
publicInputs.unencryptedLogPreimagesLength = new Fr(unencryptedLogs.getSerializedLength());
|
|
53
53
|
|
|
54
54
|
const callStackItem = new PrivateCallStackItem(contractAddress, functionData, publicInputs);
|
|
55
|
-
|
|
55
|
+
|
|
56
|
+
// Mocking the return type to be an array of 4 fields
|
|
57
|
+
// TODO: @LHerskind must be updated as we are progressing with the macros to get the information
|
|
58
|
+
const returnTypes: AbiType[] = [{ kind: 'array', length: 4, type: { kind: 'field' } }];
|
|
59
|
+
const mockArtifact = { ...artifact, returnTypes };
|
|
60
|
+
const returnValues = decodeReturnValues(mockArtifact, publicInputs.returnValues);
|
|
61
|
+
|
|
56
62
|
const noteHashReadRequestPartialWitnesses = context.getNoteHashReadRequestPartialWitnesses(
|
|
57
63
|
publicInputs.noteHashReadRequests,
|
|
58
64
|
);
|
|
@@ -60,7 +66,7 @@ export async function executePrivateFunction(
|
|
|
60
66
|
const nestedExecutions = context.getNestedExecutions();
|
|
61
67
|
const enqueuedPublicFunctionCalls = context.getEnqueuedPublicFunctionCalls();
|
|
62
68
|
|
|
63
|
-
log(`Returning from call to ${contractAddress.toString()}:${functionSelector}`);
|
|
69
|
+
log.debug(`Returning from call to ${contractAddress.toString()}:${functionSelector}`);
|
|
64
70
|
|
|
65
71
|
return {
|
|
66
72
|
acir,
|
|
@@ -23,7 +23,7 @@ export async function executeUnconstrainedFunction(
|
|
|
23
23
|
log = createDebugLogger('aztec:simulator:unconstrained_execution'),
|
|
24
24
|
): Promise<DecodedReturn> {
|
|
25
25
|
const functionSelector = functionData.selector;
|
|
26
|
-
log(`Executing unconstrained function ${contractAddress}:${functionSelector}`);
|
|
26
|
+
log.verbose(`Executing unconstrained function ${contractAddress}:${functionSelector}(${artifact.name})`);
|
|
27
27
|
|
|
28
28
|
const acir = artifact.bytecode;
|
|
29
29
|
const initialWitness = toACVMWitness(0, args);
|