@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
|
@@ -6,64 +6,64 @@ import { type Fr } from '@aztec/foundation/fields';
|
|
|
6
6
|
// storageAddress: Fr;
|
|
7
7
|
// endLifetime: Fr;
|
|
8
8
|
//};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// callPointer: Fr;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// endLifetime: Fr;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// callPointer: Fr;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// endLifetime: Fr;
|
|
27
|
-
|
|
28
|
-
|
|
9
|
+
|
|
10
|
+
export type TracedPublicStorageRead = {
|
|
11
|
+
// callPointer: Fr;
|
|
12
|
+
storageAddress: Fr;
|
|
13
|
+
exists: boolean;
|
|
14
|
+
slot: Fr;
|
|
15
|
+
value: Fr;
|
|
16
|
+
counter: Fr;
|
|
17
|
+
// endLifetime: Fr;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type TracedPublicStorageWrite = {
|
|
21
|
+
// callPointer: Fr;
|
|
22
|
+
storageAddress: Fr;
|
|
23
|
+
slot: Fr;
|
|
24
|
+
value: Fr;
|
|
25
|
+
counter: Fr;
|
|
26
|
+
// endLifetime: Fr;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
29
|
export type TracedNoteHashCheck = {
|
|
30
|
-
callPointer: Fr;
|
|
30
|
+
// callPointer: Fr;
|
|
31
31
|
storageAddress: Fr;
|
|
32
32
|
leafIndex: Fr;
|
|
33
33
|
noteHash: Fr;
|
|
34
34
|
exists: boolean;
|
|
35
35
|
counter: Fr;
|
|
36
|
-
endLifetime: Fr;
|
|
36
|
+
// endLifetime: Fr;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type TracedNoteHash = {
|
|
40
|
+
// callPointer: Fr;
|
|
41
|
+
storageAddress: Fr;
|
|
42
|
+
noteHash: Fr;
|
|
43
|
+
counter: Fr;
|
|
44
|
+
// endLifetime: Fr;
|
|
37
45
|
};
|
|
38
|
-
//
|
|
39
|
-
//export type TracedNoteHash = {
|
|
40
|
-
// callPointer: Fr;
|
|
41
|
-
// storageAddress: Fr;
|
|
42
|
-
// noteHash: Fr;
|
|
43
|
-
// counter: Fr;
|
|
44
|
-
// endLifetime: Fr;
|
|
45
|
-
//};
|
|
46
46
|
|
|
47
47
|
export type TracedNullifierCheck = {
|
|
48
|
-
callPointer: Fr;
|
|
48
|
+
// callPointer: Fr;
|
|
49
49
|
storageAddress: Fr;
|
|
50
50
|
nullifier: Fr;
|
|
51
51
|
exists: boolean;
|
|
52
52
|
counter: Fr;
|
|
53
|
-
endLifetime: Fr;
|
|
53
|
+
// endLifetime: Fr;
|
|
54
54
|
// the fields below are relevant only to the public kernel
|
|
55
55
|
// and are therefore omitted from VM inputs
|
|
56
56
|
isPending: boolean;
|
|
57
57
|
leafIndex: Fr;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
|
|
60
|
+
export type TracedNullifier = {
|
|
61
|
+
// callPointer: Fr;
|
|
62
|
+
storageAddress: Fr;
|
|
63
|
+
nullifier: Fr;
|
|
64
|
+
counter: Fr;
|
|
65
|
+
// endLifetime: Fr;
|
|
66
|
+
};
|
|
67
67
|
|
|
68
68
|
export type TracedL1toL2MessageCheck = {
|
|
69
69
|
//callPointer: Fr;
|
|
@@ -28,18 +28,23 @@ export class NoteHashExists extends Instruction {
|
|
|
28
28
|
super();
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
async execute(context: AvmContext): Promise<void> {
|
|
31
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
32
|
+
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
33
|
+
const memory = context.machineState.memory.track(this.type);
|
|
34
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
35
|
+
|
|
32
36
|
// Note that this instruction accepts any type in memory, and converts to Field.
|
|
33
|
-
const noteHash =
|
|
34
|
-
const leafIndex =
|
|
37
|
+
const noteHash = memory.get(this.noteHashOffset).toFr();
|
|
38
|
+
const leafIndex = memory.get(this.leafIndexOffset).toFr();
|
|
35
39
|
|
|
36
40
|
const exists = await context.persistableState.checkNoteHashExists(
|
|
37
41
|
context.environment.storageAddress,
|
|
38
42
|
noteHash,
|
|
39
43
|
leafIndex,
|
|
40
44
|
);
|
|
41
|
-
|
|
45
|
+
memory.set(this.existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
42
46
|
|
|
47
|
+
memory.assert(memoryOperations);
|
|
43
48
|
context.machineState.incrementPc();
|
|
44
49
|
}
|
|
45
50
|
}
|
|
@@ -54,14 +59,19 @@ export class EmitNoteHash extends Instruction {
|
|
|
54
59
|
super();
|
|
55
60
|
}
|
|
56
61
|
|
|
57
|
-
async execute(context: AvmContext): Promise<void> {
|
|
62
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
63
|
+
const memoryOperations = { reads: 1, indirect: this.indirect };
|
|
64
|
+
const memory = context.machineState.memory.track(this.type);
|
|
65
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
66
|
+
|
|
58
67
|
if (context.environment.isStaticCall) {
|
|
59
68
|
throw new StaticCallStorageAlterError();
|
|
60
69
|
}
|
|
61
70
|
|
|
62
|
-
const noteHash =
|
|
63
|
-
context.persistableState.writeNoteHash(noteHash);
|
|
71
|
+
const noteHash = memory.get(this.noteHashOffset).toFr();
|
|
72
|
+
context.persistableState.writeNoteHash(context.environment.storageAddress, noteHash);
|
|
64
73
|
|
|
74
|
+
memory.assert(memoryOperations);
|
|
65
75
|
context.machineState.incrementPc();
|
|
66
76
|
}
|
|
67
77
|
}
|
|
@@ -76,12 +86,17 @@ export class NullifierExists extends Instruction {
|
|
|
76
86
|
super();
|
|
77
87
|
}
|
|
78
88
|
|
|
79
|
-
async execute(context: AvmContext): Promise<void> {
|
|
80
|
-
const
|
|
89
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
90
|
+
const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
|
|
91
|
+
const memory = context.machineState.memory.track(this.type);
|
|
92
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
93
|
+
|
|
94
|
+
const nullifier = memory.get(this.nullifierOffset).toFr();
|
|
81
95
|
const exists = await context.persistableState.checkNullifierExists(context.environment.storageAddress, nullifier);
|
|
82
96
|
|
|
83
|
-
|
|
97
|
+
memory.set(this.existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
84
98
|
|
|
99
|
+
memory.assert(memoryOperations);
|
|
85
100
|
context.machineState.incrementPc();
|
|
86
101
|
}
|
|
87
102
|
}
|
|
@@ -96,12 +111,16 @@ export class EmitNullifier extends Instruction {
|
|
|
96
111
|
super();
|
|
97
112
|
}
|
|
98
113
|
|
|
99
|
-
async execute(context: AvmContext): Promise<void> {
|
|
114
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
100
115
|
if (context.environment.isStaticCall) {
|
|
101
116
|
throw new StaticCallStorageAlterError();
|
|
102
117
|
}
|
|
103
118
|
|
|
104
|
-
const
|
|
119
|
+
const memoryOperations = { reads: 1, indirect: this.indirect };
|
|
120
|
+
const memory = context.machineState.memory.track(this.type);
|
|
121
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
122
|
+
|
|
123
|
+
const nullifier = memory.get(this.nullifierOffset).toFr();
|
|
105
124
|
try {
|
|
106
125
|
await context.persistableState.writeNullifier(context.environment.storageAddress, nullifier);
|
|
107
126
|
} catch (e) {
|
|
@@ -115,6 +134,7 @@ export class EmitNullifier extends Instruction {
|
|
|
115
134
|
}
|
|
116
135
|
}
|
|
117
136
|
|
|
137
|
+
memory.assert(memoryOperations);
|
|
118
138
|
context.machineState.incrementPc();
|
|
119
139
|
}
|
|
120
140
|
}
|
|
@@ -140,12 +160,17 @@ export class L1ToL2MessageExists extends Instruction {
|
|
|
140
160
|
super();
|
|
141
161
|
}
|
|
142
162
|
|
|
143
|
-
async execute(context: AvmContext): Promise<void> {
|
|
144
|
-
const
|
|
145
|
-
const
|
|
163
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
164
|
+
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
165
|
+
const memory = context.machineState.memory.track(this.type);
|
|
166
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
167
|
+
|
|
168
|
+
const msgHash = memory.get(this.msgHashOffset).toFr();
|
|
169
|
+
const msgLeafIndex = memory.get(this.msgLeafIndexOffset).toFr();
|
|
146
170
|
const exists = await context.persistableState.checkL1ToL2MessageExists(msgHash, msgLeafIndex);
|
|
147
|
-
|
|
171
|
+
memory.set(this.existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
148
172
|
|
|
173
|
+
memory.assert(memoryOperations);
|
|
149
174
|
context.machineState.incrementPc();
|
|
150
175
|
}
|
|
151
176
|
}
|
|
@@ -171,21 +196,26 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
171
196
|
super();
|
|
172
197
|
}
|
|
173
198
|
|
|
174
|
-
async execute(context: AvmContext): Promise<void> {
|
|
199
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
175
200
|
if (context.environment.isStaticCall) {
|
|
176
201
|
throw new StaticCallStorageAlterError();
|
|
177
202
|
}
|
|
178
203
|
|
|
204
|
+
const memoryOperations = { reads: 1 + this.logSize, indirect: this.indirect };
|
|
205
|
+
const memory = context.machineState.memory.track(this.type);
|
|
206
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
207
|
+
|
|
179
208
|
const [eventSelectorOffset, logOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
180
209
|
[this.eventSelectorOffset, this.logOffset],
|
|
181
|
-
|
|
210
|
+
memory,
|
|
182
211
|
);
|
|
183
212
|
|
|
184
213
|
const contractAddress = context.environment.address;
|
|
185
|
-
const event =
|
|
186
|
-
const log =
|
|
214
|
+
const event = memory.get(eventSelectorOffset).toFr();
|
|
215
|
+
const log = memory.getSlice(logOffset, this.logSize).map(f => f.toFr());
|
|
187
216
|
context.persistableState.writeLog(contractAddress, event, log);
|
|
188
217
|
|
|
218
|
+
memory.assert(memoryOperations);
|
|
189
219
|
context.machineState.incrementPc();
|
|
190
220
|
}
|
|
191
221
|
}
|
|
@@ -200,15 +230,20 @@ export class SendL2ToL1Message extends Instruction {
|
|
|
200
230
|
super();
|
|
201
231
|
}
|
|
202
232
|
|
|
203
|
-
async execute(context: AvmContext): Promise<void> {
|
|
233
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
204
234
|
if (context.environment.isStaticCall) {
|
|
205
235
|
throw new StaticCallStorageAlterError();
|
|
206
236
|
}
|
|
207
237
|
|
|
208
|
-
const
|
|
209
|
-
const
|
|
238
|
+
const memoryOperations = { reads: 2, indirect: this.indirect };
|
|
239
|
+
const memory = context.machineState.memory.track(this.type);
|
|
240
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
241
|
+
|
|
242
|
+
const recipient = memory.get(this.recipientOffset).toFr();
|
|
243
|
+
const content = memory.get(this.contentOffset).toFr();
|
|
210
244
|
context.persistableState.writeL1Message(recipient, content);
|
|
211
245
|
|
|
246
|
+
memory.assert(memoryOperations);
|
|
212
247
|
context.machineState.incrementPc();
|
|
213
248
|
}
|
|
214
249
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { strict as assert } from 'assert';
|
|
2
2
|
|
|
3
|
-
import { type
|
|
3
|
+
import { type TaggedMemoryInterface } from '../avm_memory_types.js';
|
|
4
4
|
|
|
5
5
|
export enum AddressingMode {
|
|
6
6
|
DIRECT,
|
|
@@ -12,7 +12,7 @@ export enum AddressingMode {
|
|
|
12
12
|
export class Addressing {
|
|
13
13
|
public constructor(
|
|
14
14
|
/** The addressing mode for each operand. The length of this array is the number of operands of the instruction. */
|
|
15
|
-
|
|
15
|
+
private readonly modePerOperand: AddressingMode[],
|
|
16
16
|
) {
|
|
17
17
|
assert(modePerOperand.length <= 8, 'At most 8 operands are supported');
|
|
18
18
|
}
|
|
@@ -39,13 +39,18 @@ export class Addressing {
|
|
|
39
39
|
return wire;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/** Returns how many operands use the given addressing mode. */
|
|
43
|
+
public count(mode: AddressingMode): number {
|
|
44
|
+
return this.modePerOperand.filter(m => m === mode).length;
|
|
45
|
+
}
|
|
46
|
+
|
|
42
47
|
/**
|
|
43
48
|
* Resolves the offsets using the addressing mode.
|
|
44
49
|
* @param offsets The offsets to resolve.
|
|
45
50
|
* @param mem The memory to use for resolution.
|
|
46
51
|
* @returns The resolved offsets. The length of the returned array is the same as the length of the input array.
|
|
47
52
|
*/
|
|
48
|
-
public resolve(offsets: number[], mem:
|
|
53
|
+
public resolve(offsets: number[], mem: TaggedMemoryInterface): number[] {
|
|
49
54
|
assert(offsets.length <= this.modePerOperand.length);
|
|
50
55
|
const resolved = new Array(offsets.length);
|
|
51
56
|
for (const [i, offset] of offsets.entries()) {
|
|
@@ -1,33 +1,32 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
|
-
import {
|
|
3
|
-
import { type Field, type MemoryValue, TypeTag } from '../avm_memory_types.js';
|
|
2
|
+
import { getBaseGasCost, getGasCostForTypeTag, getMemoryGasCost, sumGas } from '../avm_gas.js';
|
|
3
|
+
import { type Field, type MemoryOperations, type MemoryValue, TypeTag } from '../avm_memory_types.js';
|
|
4
4
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
5
|
-
import { Addressing, AddressingMode } from './addressing_mode.js';
|
|
6
5
|
import { Instruction } from './instruction.js';
|
|
7
6
|
import { ThreeOperandInstruction } from './instruction_impl.js';
|
|
8
7
|
|
|
9
8
|
export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInstruction {
|
|
10
|
-
async execute(context: AvmContext): Promise<void> {
|
|
11
|
-
|
|
9
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
10
|
+
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
11
|
+
const memory = context.machineState.memory.track(this.type);
|
|
12
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
memory.checkTags(this.inTag, this.aOffset, this.bOffset);
|
|
15
|
+
|
|
16
|
+
const a = memory.get(this.aOffset);
|
|
17
|
+
const b = memory.get(this.bOffset);
|
|
15
18
|
|
|
16
19
|
const dest = this.compute(a, b);
|
|
17
|
-
|
|
20
|
+
memory.set(this.dstOffset, dest);
|
|
18
21
|
|
|
22
|
+
memory.assert(memoryOperations);
|
|
19
23
|
context.machineState.incrementPc();
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
protected gasCost(
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
const l2Gas =
|
|
28
|
-
indirectCount * GasCostConstants.ARITHMETIC_COST_PER_INDIRECT_ACCESS +
|
|
29
|
-
getGasCostMultiplierFromTypeTag(this.inTag) * GasCostConstants.ARITHMETIC_COST_PER_BYTE;
|
|
30
|
-
return makeGasCost({ l2Gas });
|
|
26
|
+
protected gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }>) {
|
|
27
|
+
const baseGasCost = getGasCostForTypeTag(this.inTag, getBaseGasCost(this.opcode));
|
|
28
|
+
const memoryGasCost = getMemoryGasCost(memoryOps);
|
|
29
|
+
return sumGas(baseGasCost, memoryGasCost);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
protected abstract compute(a: MemoryValue, b: MemoryValue): MemoryValue;
|
|
@@ -86,15 +85,26 @@ export class FieldDiv extends Instruction {
|
|
|
86
85
|
super();
|
|
87
86
|
}
|
|
88
87
|
|
|
89
|
-
async execute(context: AvmContext): Promise<void> {
|
|
90
|
-
|
|
88
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
89
|
+
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
90
|
+
const memory = context.machineState.memory.track(this.type);
|
|
91
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
92
|
+
|
|
93
|
+
memory.checkTags(TypeTag.FIELD, this.aOffset, this.bOffset);
|
|
91
94
|
|
|
92
|
-
const a =
|
|
93
|
-
const b =
|
|
95
|
+
const a = memory.getAs<Field>(this.aOffset);
|
|
96
|
+
const b = memory.getAs<Field>(this.bOffset);
|
|
94
97
|
|
|
95
98
|
const dest = a.fdiv(b);
|
|
96
|
-
|
|
99
|
+
memory.set(this.dstOffset, dest);
|
|
97
100
|
|
|
101
|
+
memory.assert(memoryOperations);
|
|
98
102
|
context.machineState.incrementPc();
|
|
99
103
|
}
|
|
104
|
+
|
|
105
|
+
protected gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }>) {
|
|
106
|
+
const baseGasCost = getGasCostForTypeTag(TypeTag.FIELD, getBaseGasCost(this.opcode));
|
|
107
|
+
const memoryGasCost = getMemoryGasCost(memoryOps);
|
|
108
|
+
return sumGas(baseGasCost, memoryGasCost);
|
|
109
|
+
}
|
|
100
110
|
}
|
|
@@ -3,66 +3,69 @@ import { type IntegralValue } from '../avm_memory_types.js';
|
|
|
3
3
|
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
4
4
|
import { ThreeOperandInstruction, TwoOperandInstruction } from './instruction_impl.js';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
super(indirect, inTag, aOffset, bOffset, dstOffset);
|
|
12
|
-
}
|
|
6
|
+
abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
|
|
7
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
8
|
+
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
9
|
+
const memory = context.machineState.memory.track(this.type);
|
|
10
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
context.machineState.memory.checkTags(this.inTag, this.aOffset, this.bOffset);
|
|
12
|
+
memory.checkTags(this.inTag, this.aOffset, this.bOffset);
|
|
16
13
|
|
|
17
|
-
const a =
|
|
18
|
-
const b =
|
|
14
|
+
const a = memory.getAs<IntegralValue>(this.aOffset);
|
|
15
|
+
const b = memory.getAs<IntegralValue>(this.bOffset);
|
|
19
16
|
|
|
20
|
-
const res =
|
|
21
|
-
|
|
17
|
+
const res = this.compute(a, b);
|
|
18
|
+
memory.set(this.dstOffset, res);
|
|
22
19
|
|
|
20
|
+
memory.assert(memoryOperations);
|
|
23
21
|
context.machineState.incrementPc();
|
|
24
22
|
}
|
|
23
|
+
|
|
24
|
+
protected abstract compute(a: IntegralValue, b: IntegralValue): IntegralValue;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export class
|
|
28
|
-
static readonly type: string = '
|
|
29
|
-
static readonly opcode = Opcode.
|
|
27
|
+
export class And extends ThreeOperandBitwiseInstruction {
|
|
28
|
+
static readonly type: string = 'AND';
|
|
29
|
+
static readonly opcode = Opcode.AND;
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
protected compute(a: IntegralValue, b: IntegralValue): IntegralValue {
|
|
32
|
+
return a.and(b);
|
|
33
33
|
}
|
|
34
|
+
}
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const a = context.machineState.memory.getAs<IntegralValue>(this.aOffset);
|
|
39
|
-
const b = context.machineState.memory.getAs<IntegralValue>(this.bOffset);
|
|
40
|
-
|
|
41
|
-
const res = a.or(b);
|
|
42
|
-
context.machineState.memory.set(this.dstOffset, res);
|
|
36
|
+
export class Or extends ThreeOperandBitwiseInstruction {
|
|
37
|
+
static readonly type: string = 'OR';
|
|
38
|
+
static readonly opcode = Opcode.OR;
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
protected compute(a: IntegralValue, b: IntegralValue): IntegralValue {
|
|
41
|
+
return a.or(b);
|
|
45
42
|
}
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
export class Xor extends
|
|
45
|
+
export class Xor extends ThreeOperandBitwiseInstruction {
|
|
49
46
|
static readonly type: string = 'XOR';
|
|
50
47
|
static readonly opcode = Opcode.XOR;
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
protected compute(a: IntegralValue, b: IntegralValue): IntegralValue {
|
|
50
|
+
return a.xor(b);
|
|
54
51
|
}
|
|
52
|
+
}
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
export class Shl extends ThreeOperandBitwiseInstruction {
|
|
55
|
+
static readonly type: string = 'SHL';
|
|
56
|
+
static readonly opcode = Opcode.SHL;
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
protected compute(a: IntegralValue, b: IntegralValue): IntegralValue {
|
|
59
|
+
return a.shl(b);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
export class Shr extends ThreeOperandBitwiseInstruction {
|
|
64
|
+
static readonly type: string = 'SHR';
|
|
65
|
+
static readonly opcode = Opcode.SHR;
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
protected compute(a: IntegralValue, b: IntegralValue): IntegralValue {
|
|
68
|
+
return a.shr(b);
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
71
|
|
|
@@ -74,56 +77,19 @@ export class Not extends TwoOperandInstruction {
|
|
|
74
77
|
super(indirect, inTag, aOffset, dstOffset);
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
async execute(context: AvmContext): Promise<void> {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const res = a.not();
|
|
83
|
-
context.machineState.memory.set(this.dstOffset, res);
|
|
84
|
-
|
|
85
|
-
context.machineState.incrementPc();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export class Shl extends ThreeOperandInstruction {
|
|
90
|
-
static readonly type: string = 'SHL';
|
|
91
|
-
static readonly opcode = Opcode.SHL;
|
|
92
|
-
|
|
93
|
-
constructor(indirect: number, inTag: number, aOffset: number, bOffset: number, dstOffset: number) {
|
|
94
|
-
super(indirect, inTag, aOffset, bOffset, dstOffset);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async execute(context: AvmContext): Promise<void> {
|
|
98
|
-
context.machineState.memory.checkTags(this.inTag, this.aOffset, this.bOffset);
|
|
80
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
81
|
+
const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
|
|
82
|
+
const memory = context.machineState.memory.track(this.type);
|
|
83
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
99
84
|
|
|
100
|
-
|
|
101
|
-
const b = context.machineState.memory.getAs<IntegralValue>(this.bOffset);
|
|
85
|
+
memory.checkTags(this.inTag, this.aOffset);
|
|
102
86
|
|
|
103
|
-
const
|
|
104
|
-
context.machineState.memory.set(this.dstOffset, res);
|
|
87
|
+
const a = memory.getAs<IntegralValue>(this.aOffset);
|
|
105
88
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export class Shr extends ThreeOperandInstruction {
|
|
111
|
-
static readonly type: string = 'SHR';
|
|
112
|
-
static readonly opcode = Opcode.SHR;
|
|
113
|
-
|
|
114
|
-
constructor(indirect: number, inTag: number, aOffset: number, bOffset: number, dstOffset: number) {
|
|
115
|
-
super(indirect, inTag, aOffset, bOffset, dstOffset);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async execute(context: AvmContext): Promise<void> {
|
|
119
|
-
context.machineState.memory.checkTags(this.inTag, this.aOffset, this.bOffset);
|
|
120
|
-
|
|
121
|
-
const a = context.machineState.memory.getAs<IntegralValue>(this.aOffset);
|
|
122
|
-
const b = context.machineState.memory.getAs<IntegralValue>(this.bOffset);
|
|
123
|
-
|
|
124
|
-
const res = a.shr(b);
|
|
125
|
-
context.machineState.memory.set(this.dstOffset, res);
|
|
89
|
+
const res = a.not();
|
|
90
|
+
memory.set(this.dstOffset, res);
|
|
126
91
|
|
|
92
|
+
memory.assert(memoryOperations);
|
|
127
93
|
context.machineState.incrementPc();
|
|
128
94
|
}
|
|
129
95
|
}
|
|
@@ -1,67 +1,52 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
|
-
import { Uint8 } from '../avm_memory_types.js';
|
|
2
|
+
import { type MemoryValue, Uint8 } from '../avm_memory_types.js';
|
|
3
3
|
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
4
4
|
import { ThreeOperandInstruction } from './instruction_impl.js';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
super(indirect, inTag, aOffset, bOffset, dstOffset);
|
|
12
|
-
}
|
|
6
|
+
abstract class ComparatorInstruction extends ThreeOperandInstruction {
|
|
7
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
8
|
+
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
9
|
+
const memory = context.machineState.memory.track(this.type);
|
|
10
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
context.machineState.memory.checkTags(this.inTag, this.aOffset, this.bOffset);
|
|
12
|
+
memory.checkTags(this.inTag, this.aOffset, this.bOffset);
|
|
16
13
|
|
|
17
|
-
const a =
|
|
18
|
-
const b =
|
|
14
|
+
const a = memory.get(this.aOffset);
|
|
15
|
+
const b = memory.get(this.bOffset);
|
|
19
16
|
|
|
20
|
-
const dest = new Uint8(
|
|
21
|
-
|
|
17
|
+
const dest = new Uint8(this.compare(a, b) ? 1 : 0);
|
|
18
|
+
memory.set(this.dstOffset, dest);
|
|
22
19
|
|
|
20
|
+
memory.assert(memoryOperations);
|
|
23
21
|
context.machineState.incrementPc();
|
|
24
22
|
}
|
|
23
|
+
|
|
24
|
+
protected abstract compare(a: MemoryValue, b: MemoryValue): boolean;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export class
|
|
28
|
-
static readonly type: string = '
|
|
29
|
-
static readonly opcode = Opcode.
|
|
27
|
+
export class Eq extends ComparatorInstruction {
|
|
28
|
+
static readonly type: string = 'EQ';
|
|
29
|
+
static readonly opcode = Opcode.EQ;
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
protected compare(a: MemoryValue, b: MemoryValue): boolean {
|
|
32
|
+
return a.equals(b);
|
|
33
33
|
}
|
|
34
|
+
}
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const a = context.machineState.memory.get(this.aOffset);
|
|
39
|
-
const b = context.machineState.memory.get(this.bOffset);
|
|
40
|
-
|
|
41
|
-
const dest = new Uint8(a.lt(b) ? 1 : 0);
|
|
42
|
-
context.machineState.memory.set(this.dstOffset, dest);
|
|
36
|
+
export class Lt extends ComparatorInstruction {
|
|
37
|
+
static readonly type: string = 'LT';
|
|
38
|
+
static readonly opcode = Opcode.LT;
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
protected compare(a: MemoryValue, b: MemoryValue): boolean {
|
|
41
|
+
return a.lt(b);
|
|
45
42
|
}
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
export class Lte extends
|
|
45
|
+
export class Lte extends ComparatorInstruction {
|
|
49
46
|
static readonly type: string = 'LTE';
|
|
50
47
|
static readonly opcode = Opcode.LTE;
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async execute(context: AvmContext): Promise<void> {
|
|
57
|
-
context.machineState.memory.checkTags(this.inTag, this.aOffset, this.bOffset);
|
|
58
|
-
|
|
59
|
-
const a = context.machineState.memory.get(this.aOffset);
|
|
60
|
-
const b = context.machineState.memory.get(this.bOffset);
|
|
61
|
-
|
|
62
|
-
const dest = new Uint8(a.lt(b) || a.equals(b) ? 1 : 0);
|
|
63
|
-
context.machineState.memory.set(this.dstOffset, dest);
|
|
64
|
-
|
|
65
|
-
context.machineState.incrementPc();
|
|
49
|
+
protected compare(a: MemoryValue, b: MemoryValue): boolean {
|
|
50
|
+
return a.lt(b) || a.equals(b);
|
|
66
51
|
}
|
|
67
52
|
}
|