@aztec/simulator 0.56.0 → 0.57.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/oracle/oracle.d.ts +2 -5
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +6 -37
- package/dest/acvm/oracle/typed_oracle.d.ts +3 -6
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +1 -10
- package/dest/avm/avm_execution_environment.d.ts +2 -3
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +3 -4
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +1 -2
- package/dest/avm/avm_memory_types.d.ts +3 -2
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +3 -3
- package/dest/avm/errors.d.ts +1 -1
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +12 -3
- 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 +2 -1
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +7 -6
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +37 -30
- package/dest/avm/opcodes/addressing_mode.d.ts +3 -2
- package/dest/avm/opcodes/addressing_mode.d.ts.map +1 -1
- package/dest/avm/opcodes/addressing_mode.js +25 -21
- package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/avm/opcodes/arithmetic.js +6 -5
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +11 -9
- package/dest/avm/opcodes/commitment.d.ts.map +1 -1
- package/dest/avm/opcodes/commitment.js +6 -5
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +6 -5
- package/dest/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/avm/opcodes/contract.js +6 -5
- package/dest/avm/opcodes/control_flow.js +6 -6
- package/dest/avm/opcodes/conversion.d.ts.map +1 -1
- package/dest/avm/opcodes/conversion.js +7 -6
- package/dest/avm/opcodes/ec_add.d.ts.map +1 -1
- package/dest/avm/opcodes/ec_add.js +8 -7
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +6 -5
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +27 -16
- package/dest/avm/opcodes/hashing.d.ts +1 -3
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +31 -40
- package/dest/avm/opcodes/instruction.d.ts +2 -6
- package/dest/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction.js +3 -9
- package/dest/avm/opcodes/memory.d.ts +0 -12
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +21 -51
- package/dest/avm/opcodes/misc.d.ts.map +1 -1
- package/dest/avm/opcodes/misc.js +6 -5
- package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -1
- package/dest/avm/opcodes/multi_scalar_mul.js +12 -12
- package/dest/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/avm/opcodes/storage.js +11 -9
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +2 -3
- package/dest/avm/serialization/instruction_serialization.d.ts +32 -34
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +33 -36
- package/dest/client/client_execution_context.d.ts +6 -30
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +31 -53
- package/dest/client/index.d.ts +0 -1
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +1 -2
- package/dest/client/private_execution.d.ts +2 -2
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +5 -19
- package/dest/client/simulator.d.ts +2 -3
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +1 -1
- package/dest/common/debug_fn_name.d.ts +4 -0
- package/dest/common/debug_fn_name.d.ts.map +1 -0
- package/dest/common/debug_fn_name.js +15 -0
- package/dest/common/index.d.ts +0 -1
- package/dest/common/index.d.ts.map +1 -1
- package/dest/common/index.js +1 -2
- package/dest/public/enqueued_call_simulator.d.ts.map +1 -1
- package/dest/public/enqueued_call_simulator.js +3 -4
- package/dest/public/execution.d.ts +8 -1
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +13 -1
- package/dest/public/executor.d.ts +2 -3
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +8 -8
- package/dest/public/hints_builder.d.ts.map +1 -1
- package/dest/public/hints_builder.js +2 -2
- package/dest/public/public_processor.d.ts +1 -0
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +5 -2
- package/dest/public/side_effect_errors.d.ts +4 -0
- package/dest/public/side_effect_errors.d.ts.map +1 -0
- package/dest/public/side_effect_errors.js +7 -0
- package/dest/public/side_effect_trace.d.ts +2 -2
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +53 -28
- package/dest/public/side_effect_trace_interface.d.ts +1 -1
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/package.json +12 -9
- package/src/acvm/oracle/oracle.ts +7 -85
- package/src/acvm/oracle/typed_oracle.ts +2 -31
- package/src/avm/avm_execution_environment.ts +1 -3
- package/src/avm/avm_gas.ts +0 -1
- package/src/avm/avm_memory_types.ts +10 -5
- package/src/avm/errors.ts +11 -3
- package/src/avm/fixtures/index.ts +1 -2
- package/src/avm/journal/journal.ts +11 -6
- package/src/avm/opcodes/accrued_substate.ts +36 -44
- package/src/avm/opcodes/addressing_mode.ts +27 -24
- package/src/avm/opcodes/arithmetic.ts +5 -7
- package/src/avm/opcodes/bitwise.ts +10 -11
- package/src/avm/opcodes/commitment.ts +6 -7
- package/src/avm/opcodes/comparators.ts +5 -7
- package/src/avm/opcodes/contract.ts +5 -7
- package/src/avm/opcodes/control_flow.ts +5 -5
- package/src/avm/opcodes/conversion.ts +6 -8
- package/src/avm/opcodes/ec_add.ts +14 -16
- package/src/avm/opcodes/environment_getters.ts +5 -4
- package/src/avm/opcodes/external_calls.ts +27 -20
- package/src/avm/opcodes/hashing.ts +30 -55
- package/src/avm/opcodes/instruction.ts +3 -10
- package/src/avm/opcodes/memory.ts +20 -64
- package/src/avm/opcodes/misc.ts +5 -7
- package/src/avm/opcodes/multi_scalar_mul.ts +11 -14
- package/src/avm/opcodes/storage.ts +10 -8
- package/src/avm/serialization/bytecode_serialization.ts +0 -2
- package/src/avm/serialization/instruction_serialization.ts +0 -3
- package/src/client/client_execution_context.ts +40 -96
- package/src/client/index.ts +0 -1
- package/src/client/private_execution.ts +9 -9
- package/src/client/simulator.ts +2 -3
- package/src/common/debug_fn_name.ts +22 -0
- package/src/common/index.ts +0 -1
- package/src/public/enqueued_call_simulator.ts +2 -3
- package/src/public/execution.ts +13 -2
- package/src/public/executor.ts +6 -12
- package/src/public/hints_builder.ts +7 -9
- package/src/public/public_processor.ts +5 -1
- package/src/public/side_effect_errors.ts +6 -0
- package/src/public/side_effect_trace.ts +72 -27
- package/src/public/side_effect_trace_interface.ts +2 -2
- package/dest/client/execution_result.d.ts +0 -104
- package/dest/client/execution_result.d.ts.map +0 -1
- package/dest/client/execution_result.js +0 -136
- package/dest/common/return_values.d.ts +0 -11
- package/dest/common/return_values.d.ts.map +0 -1
- package/dest/common/return_values.js +0 -13
- package/src/client/execution_result.ts +0 -228
- package/src/common/return_values.ts +0 -18
|
@@ -3,6 +3,7 @@ import { Fr } from '@aztec/foundation/fields';
|
|
|
3
3
|
import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { SerializableContractInstance } from '@aztec/types/contracts';
|
|
5
5
|
|
|
6
|
+
import { getPublicFunctionDebugName } from '../../common/debug_fn_name.js';
|
|
6
7
|
import { type WorldStateDB } from '../../public/public_db_sources.js';
|
|
7
8
|
import { type TracedContractInstance } from '../../public/side_effect_trace.js';
|
|
8
9
|
import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js';
|
|
@@ -187,12 +188,13 @@ export class AvmPersistableStateManager {
|
|
|
187
188
|
|
|
188
189
|
/**
|
|
189
190
|
* Write an L2 to L1 message.
|
|
191
|
+
* @param contractAddress - L2 contract address that created this message
|
|
190
192
|
* @param recipient - L1 contract address to send the message to.
|
|
191
193
|
* @param content - Message content.
|
|
192
194
|
*/
|
|
193
|
-
public writeL2ToL1Message(recipient: Fr, content: Fr) {
|
|
194
|
-
this.log.debug(`
|
|
195
|
-
this.trace.traceNewL2ToL1Message(recipient, content);
|
|
195
|
+
public writeL2ToL1Message(contractAddress: Fr, recipient: Fr, content: Fr) {
|
|
196
|
+
this.log.debug(`L2ToL1Messages(${contractAddress}) += (recipient: ${recipient}, content: ${content}).`);
|
|
197
|
+
this.trace.traceNewL2ToL1Message(contractAddress, recipient, content);
|
|
196
198
|
}
|
|
197
199
|
|
|
198
200
|
/**
|
|
@@ -256,9 +258,12 @@ export class AvmPersistableStateManager {
|
|
|
256
258
|
if (!avmCallResults.reverted) {
|
|
257
259
|
this.acceptNestedCallState(nestedState);
|
|
258
260
|
}
|
|
259
|
-
const functionName =
|
|
260
|
-
|
|
261
|
-
|
|
261
|
+
const functionName = await getPublicFunctionDebugName(
|
|
262
|
+
this.worldStateDB,
|
|
263
|
+
nestedEnvironment.address,
|
|
264
|
+
nestedEnvironment.functionSelector,
|
|
265
|
+
nestedEnvironment.calldata,
|
|
266
|
+
);
|
|
262
267
|
|
|
263
268
|
this.log.verbose(`[AVM] Calling nested function ${functionName}`);
|
|
264
269
|
|
|
@@ -28,13 +28,11 @@ export class NoteHashExists extends Instruction {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
public async execute(context: AvmContext): Promise<void> {
|
|
31
|
-
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
32
31
|
const memory = context.machineState.memory.track(this.type);
|
|
33
|
-
context.machineState.consumeGas(this.gasCost(
|
|
34
|
-
const [noteHashOffset, leafIndexOffset, existsOffset]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
);
|
|
32
|
+
context.machineState.consumeGas(this.gasCost());
|
|
33
|
+
const operands = [this.noteHashOffset, this.leafIndexOffset, this.existsOffset];
|
|
34
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
35
|
+
const [noteHashOffset, leafIndexOffset, existsOffset] = addressing.resolve(operands, memory);
|
|
38
36
|
memory.checkTags(TypeTag.FIELD, noteHashOffset, leafIndexOffset);
|
|
39
37
|
|
|
40
38
|
// Note that this instruction accepts any type in memory, and converts to Field.
|
|
@@ -48,7 +46,7 @@ export class NoteHashExists extends Instruction {
|
|
|
48
46
|
);
|
|
49
47
|
memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
50
48
|
|
|
51
|
-
memory.assert(
|
|
49
|
+
memory.assert({ reads: 2, writes: 1, addressing });
|
|
52
50
|
context.machineState.incrementPc();
|
|
53
51
|
}
|
|
54
52
|
}
|
|
@@ -64,11 +62,12 @@ export class EmitNoteHash extends Instruction {
|
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
public async execute(context: AvmContext): Promise<void> {
|
|
67
|
-
const memoryOperations = { reads: 1, indirect: this.indirect };
|
|
68
65
|
const memory = context.machineState.memory.track(this.type);
|
|
69
|
-
context.machineState.consumeGas(this.gasCost(
|
|
66
|
+
context.machineState.consumeGas(this.gasCost());
|
|
70
67
|
|
|
71
|
-
const
|
|
68
|
+
const operands = [this.noteHashOffset];
|
|
69
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
70
|
+
const [noteHashOffset] = addressing.resolve(operands, memory);
|
|
72
71
|
memory.checkTag(TypeTag.FIELD, noteHashOffset);
|
|
73
72
|
|
|
74
73
|
if (context.environment.isStaticCall) {
|
|
@@ -78,7 +77,7 @@ export class EmitNoteHash extends Instruction {
|
|
|
78
77
|
const noteHash = memory.get(noteHashOffset).toFr();
|
|
79
78
|
context.persistableState.writeNoteHash(context.environment.storageAddress, noteHash);
|
|
80
79
|
|
|
81
|
-
memory.assert(
|
|
80
|
+
memory.assert({ reads: 1, addressing });
|
|
82
81
|
context.machineState.incrementPc();
|
|
83
82
|
}
|
|
84
83
|
}
|
|
@@ -105,14 +104,12 @@ export class NullifierExists extends Instruction {
|
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
public async execute(context: AvmContext): Promise<void> {
|
|
108
|
-
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
109
107
|
const memory = context.machineState.memory.track(this.type);
|
|
110
|
-
context.machineState.consumeGas(this.gasCost(
|
|
108
|
+
context.machineState.consumeGas(this.gasCost());
|
|
111
109
|
|
|
112
|
-
const [nullifierOffset, addressOffset, existsOffset]
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
);
|
|
110
|
+
const operands = [this.nullifierOffset, this.addressOffset, this.existsOffset];
|
|
111
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
112
|
+
const [nullifierOffset, addressOffset, existsOffset] = addressing.resolve(operands, memory);
|
|
116
113
|
memory.checkTags(TypeTag.FIELD, nullifierOffset, addressOffset);
|
|
117
114
|
|
|
118
115
|
const nullifier = memory.get(nullifierOffset).toFr();
|
|
@@ -121,7 +118,7 @@ export class NullifierExists extends Instruction {
|
|
|
121
118
|
|
|
122
119
|
memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
123
120
|
|
|
124
|
-
memory.assert(
|
|
121
|
+
memory.assert({ reads: 2, writes: 1, addressing });
|
|
125
122
|
context.machineState.incrementPc();
|
|
126
123
|
}
|
|
127
124
|
}
|
|
@@ -141,11 +138,12 @@ export class EmitNullifier extends Instruction {
|
|
|
141
138
|
throw new StaticCallAlterationError();
|
|
142
139
|
}
|
|
143
140
|
|
|
144
|
-
const memoryOperations = { reads: 1, indirect: this.indirect };
|
|
145
141
|
const memory = context.machineState.memory.track(this.type);
|
|
146
|
-
context.machineState.consumeGas(this.gasCost(
|
|
142
|
+
context.machineState.consumeGas(this.gasCost());
|
|
147
143
|
|
|
148
|
-
const
|
|
144
|
+
const operands = [this.nullifierOffset];
|
|
145
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
146
|
+
const [nullifierOffset] = addressing.resolve(operands, memory);
|
|
149
147
|
memory.checkTag(TypeTag.FIELD, nullifierOffset);
|
|
150
148
|
|
|
151
149
|
const nullifier = memory.get(nullifierOffset).toFr();
|
|
@@ -162,7 +160,7 @@ export class EmitNullifier extends Instruction {
|
|
|
162
160
|
}
|
|
163
161
|
}
|
|
164
162
|
|
|
165
|
-
memory.assert(
|
|
163
|
+
memory.assert({ reads: 1, addressing });
|
|
166
164
|
context.machineState.incrementPc();
|
|
167
165
|
}
|
|
168
166
|
}
|
|
@@ -189,14 +187,12 @@ export class L1ToL2MessageExists extends Instruction {
|
|
|
189
187
|
}
|
|
190
188
|
|
|
191
189
|
public async execute(context: AvmContext): Promise<void> {
|
|
192
|
-
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
193
190
|
const memory = context.machineState.memory.track(this.type);
|
|
194
|
-
context.machineState.consumeGas(this.gasCost(
|
|
191
|
+
context.machineState.consumeGas(this.gasCost());
|
|
195
192
|
|
|
196
|
-
const [msgHashOffset, msgLeafIndexOffset, existsOffset]
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
);
|
|
193
|
+
const operands = [this.msgHashOffset, this.msgLeafIndexOffset, this.existsOffset];
|
|
194
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
195
|
+
const [msgHashOffset, msgLeafIndexOffset, existsOffset] = addressing.resolve(operands, memory);
|
|
200
196
|
memory.checkTags(TypeTag.FIELD, msgHashOffset, msgLeafIndexOffset);
|
|
201
197
|
|
|
202
198
|
const msgHash = memory.get(msgHashOffset).toFr();
|
|
@@ -208,7 +204,7 @@ export class L1ToL2MessageExists extends Instruction {
|
|
|
208
204
|
);
|
|
209
205
|
memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
210
206
|
|
|
211
|
-
memory.assert(
|
|
207
|
+
memory.assert({ reads: 2, writes: 1, addressing });
|
|
212
208
|
context.machineState.incrementPc();
|
|
213
209
|
}
|
|
214
210
|
}
|
|
@@ -230,22 +226,20 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
230
226
|
|
|
231
227
|
const memory = context.machineState.memory.track(this.type);
|
|
232
228
|
|
|
233
|
-
const [logOffset, logSizeOffset]
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
);
|
|
229
|
+
const operands = [this.logOffset, this.logSizeOffset];
|
|
230
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
231
|
+
const [logOffset, logSizeOffset] = addressing.resolve(operands, memory);
|
|
237
232
|
memory.checkTag(TypeTag.UINT32, logSizeOffset);
|
|
238
233
|
const logSize = memory.get(logSizeOffset).toNumber();
|
|
239
234
|
memory.checkTagsRange(TypeTag.FIELD, logOffset, logSize);
|
|
240
235
|
|
|
241
236
|
const contractAddress = context.environment.address;
|
|
242
237
|
|
|
243
|
-
|
|
244
|
-
context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: logSize }));
|
|
238
|
+
context.machineState.consumeGas(this.gasCost(logSize));
|
|
245
239
|
const log = memory.getSlice(logOffset, logSize).map(f => f.toFr());
|
|
246
240
|
context.persistableState.writeUnencryptedLog(contractAddress, log);
|
|
247
241
|
|
|
248
|
-
memory.assert(
|
|
242
|
+
memory.assert({ reads: 1 + logSize, addressing });
|
|
249
243
|
context.machineState.incrementPc();
|
|
250
244
|
}
|
|
251
245
|
}
|
|
@@ -265,20 +259,18 @@ export class SendL2ToL1Message extends Instruction {
|
|
|
265
259
|
throw new StaticCallAlterationError();
|
|
266
260
|
}
|
|
267
261
|
|
|
268
|
-
const memoryOperations = { reads: 2, indirect: this.indirect };
|
|
269
262
|
const memory = context.machineState.memory.track(this.type);
|
|
270
|
-
context.machineState.consumeGas(this.gasCost(
|
|
263
|
+
context.machineState.consumeGas(this.gasCost());
|
|
271
264
|
|
|
272
|
-
const [recipientOffset, contentOffset]
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
);
|
|
265
|
+
const operands = [this.recipientOffset, this.contentOffset];
|
|
266
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
267
|
+
const [recipientOffset, contentOffset] = addressing.resolve(operands, memory);
|
|
276
268
|
|
|
277
269
|
const recipient = memory.get(recipientOffset).toFr();
|
|
278
270
|
const content = memory.get(contentOffset).toFr();
|
|
279
|
-
context.persistableState.writeL2ToL1Message(recipient, content);
|
|
271
|
+
context.persistableState.writeL2ToL1Message(context.environment.address, recipient, content);
|
|
280
272
|
|
|
281
|
-
memory.assert(
|
|
273
|
+
memory.assert({ reads: 2, addressing });
|
|
282
274
|
context.machineState.incrementPc();
|
|
283
275
|
}
|
|
284
276
|
}
|
|
@@ -3,9 +3,10 @@ import { strict as assert } from 'assert';
|
|
|
3
3
|
import { type TaggedMemoryInterface } from '../avm_memory_types.js';
|
|
4
4
|
|
|
5
5
|
export enum AddressingMode {
|
|
6
|
-
DIRECT,
|
|
7
|
-
INDIRECT,
|
|
8
|
-
|
|
6
|
+
DIRECT = 0,
|
|
7
|
+
INDIRECT = 1,
|
|
8
|
+
RELATIVE = 2,
|
|
9
|
+
INDIRECT_RELATIVE = 3,
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
/** A class to represent the addressing mode of an instruction. */
|
|
@@ -13,16 +14,17 @@ export class Addressing {
|
|
|
13
14
|
public constructor(
|
|
14
15
|
/** The addressing mode for each operand. The length of this array is the number of operands of the instruction. */
|
|
15
16
|
private readonly modePerOperand: AddressingMode[],
|
|
16
|
-
) {
|
|
17
|
-
assert(modePerOperand.length <= 8, 'At most 8 operands are supported');
|
|
18
|
-
}
|
|
17
|
+
) {}
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
// TODO(facundo): 8 for backwards compatibility.
|
|
20
|
+
public static fromWire(wireModes: number, numOperands: number = 8): Addressing {
|
|
21
21
|
// The modes are stored in the wire format as a byte, with each bit representing the mode for an operand.
|
|
22
22
|
// The least significant bit represents the zeroth operand, and the most significant bit represents the last operand.
|
|
23
|
-
const modes = new Array<AddressingMode>(
|
|
24
|
-
for (let i = 0; i <
|
|
25
|
-
modes[i] =
|
|
23
|
+
const modes = new Array<AddressingMode>(numOperands);
|
|
24
|
+
for (let i = 0; i < numOperands; i++) {
|
|
25
|
+
modes[i] =
|
|
26
|
+
(((wireModes >> i) & 1) * AddressingMode.INDIRECT) |
|
|
27
|
+
(((wireModes >> (i + numOperands)) & 1) * AddressingMode.RELATIVE);
|
|
26
28
|
}
|
|
27
29
|
return new Addressing(modes);
|
|
28
30
|
}
|
|
@@ -31,17 +33,20 @@ export class Addressing {
|
|
|
31
33
|
// The modes are stored in the wire format as a byte, with each bit representing the mode for an operand.
|
|
32
34
|
// The least significant bit represents the zeroth operand, and the least significant bit represents the last operand.
|
|
33
35
|
let wire: number = 0;
|
|
34
|
-
for (let i = 0; i <
|
|
35
|
-
if (this.modePerOperand[i]
|
|
36
|
+
for (let i = 0; i < this.modePerOperand.length; i++) {
|
|
37
|
+
if (this.modePerOperand[i] & AddressingMode.INDIRECT) {
|
|
36
38
|
wire |= 1 << i;
|
|
37
39
|
}
|
|
40
|
+
if (this.modePerOperand[i] & AddressingMode.RELATIVE) {
|
|
41
|
+
wire |= 1 << (this.modePerOperand.length + i);
|
|
42
|
+
}
|
|
38
43
|
}
|
|
39
44
|
return wire;
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
/** Returns how many operands use the given addressing mode. */
|
|
43
48
|
public count(mode: AddressingMode): number {
|
|
44
|
-
return this.modePerOperand.filter(m => m
|
|
49
|
+
return this.modePerOperand.filter(m => (m & mode) !== 0).length;
|
|
45
50
|
}
|
|
46
51
|
|
|
47
52
|
/**
|
|
@@ -54,17 +59,15 @@ export class Addressing {
|
|
|
54
59
|
assert(offsets.length <= this.modePerOperand.length);
|
|
55
60
|
const resolved = new Array(offsets.length);
|
|
56
61
|
for (const [i, offset] of offsets.entries()) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
default:
|
|
67
|
-
throw new Error(`Unimplemented addressing mode: ${AddressingMode[this.modePerOperand[i]]}`);
|
|
62
|
+
const mode = this.modePerOperand[i];
|
|
63
|
+
resolved[i] = offset;
|
|
64
|
+
if (mode & AddressingMode.RELATIVE) {
|
|
65
|
+
mem.checkIsValidMemoryOffsetTag(0);
|
|
66
|
+
resolved[i] += Number(mem.get(0).toBigInt());
|
|
67
|
+
}
|
|
68
|
+
if (mode & AddressingMode.INDIRECT) {
|
|
69
|
+
mem.checkIsValidMemoryOffsetTag(resolved[i]);
|
|
70
|
+
resolved[i] = Number(mem.get(resolved[i]).toBigInt());
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
return resolved;
|
|
@@ -6,14 +6,12 @@ import { ThreeOperandInstruction } from './instruction_impl.js';
|
|
|
6
6
|
|
|
7
7
|
export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInstruction {
|
|
8
8
|
public async execute(context: AvmContext): Promise<void> {
|
|
9
|
-
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
10
9
|
const memory = context.machineState.memory.track(this.type);
|
|
11
|
-
context.machineState.consumeGas(this.gasCost(
|
|
10
|
+
context.machineState.consumeGas(this.gasCost());
|
|
12
11
|
|
|
13
|
-
const [aOffset, bOffset, dstOffset]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
);
|
|
12
|
+
const operands = [this.aOffset, this.bOffset, this.dstOffset];
|
|
13
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
14
|
+
const [aOffset, bOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
17
15
|
memory.checkTags(this.inTag, aOffset, bOffset);
|
|
18
16
|
|
|
19
17
|
const a = memory.get(aOffset);
|
|
@@ -22,7 +20,7 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst
|
|
|
22
20
|
const dest = this.compute(a, b);
|
|
23
21
|
memory.set(dstOffset, dest);
|
|
24
22
|
|
|
25
|
-
memory.assert(
|
|
23
|
+
memory.assert({ reads: 2, writes: 1, addressing });
|
|
26
24
|
context.machineState.incrementPc();
|
|
27
25
|
}
|
|
28
26
|
|
|
@@ -7,14 +7,12 @@ import { ThreeOperandInstruction } from './instruction_impl.js';
|
|
|
7
7
|
|
|
8
8
|
abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
|
|
9
9
|
public async execute(context: AvmContext): Promise<void> {
|
|
10
|
-
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
11
10
|
const memory = context.machineState.memory.track(this.type);
|
|
12
|
-
context.machineState.consumeGas(this.gasCost(
|
|
11
|
+
context.machineState.consumeGas(this.gasCost());
|
|
13
12
|
|
|
14
|
-
const [aOffset, bOffset, dstOffset]
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
);
|
|
13
|
+
const operands = [this.aOffset, this.bOffset, this.dstOffset];
|
|
14
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
15
|
+
const [aOffset, bOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
18
16
|
this.checkTags(memory, this.inTag, aOffset, bOffset);
|
|
19
17
|
|
|
20
18
|
const a = memory.getAs<IntegralValue>(aOffset);
|
|
@@ -23,7 +21,7 @@ abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
|
|
|
23
21
|
const res = this.compute(a, b);
|
|
24
22
|
memory.set(dstOffset, res);
|
|
25
23
|
|
|
26
|
-
memory.assert(
|
|
24
|
+
memory.assert({ reads: 2, writes: 1, addressing });
|
|
27
25
|
context.machineState.incrementPc();
|
|
28
26
|
}
|
|
29
27
|
|
|
@@ -98,18 +96,19 @@ export class Not extends Instruction {
|
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
public async execute(context: AvmContext): Promise<void> {
|
|
101
|
-
const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
|
|
102
99
|
const memory = context.machineState.memory.track(this.type);
|
|
103
|
-
context.machineState.consumeGas(this.gasCost(
|
|
100
|
+
context.machineState.consumeGas(this.gasCost());
|
|
104
101
|
|
|
105
|
-
const
|
|
102
|
+
const operands = [this.srcOffset, this.dstOffset];
|
|
103
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
104
|
+
const [srcOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
106
105
|
TaggedMemory.checkIsIntegralTag(memory.getTag(srcOffset));
|
|
107
106
|
const value = memory.getAs<IntegralValue>(srcOffset);
|
|
108
107
|
|
|
109
108
|
const res = value.not();
|
|
110
109
|
memory.set(dstOffset, res);
|
|
111
110
|
|
|
112
|
-
memory.assert(
|
|
111
|
+
memory.assert({ reads: 1, writes: 1, addressing });
|
|
113
112
|
context.machineState.incrementPc();
|
|
114
113
|
}
|
|
115
114
|
}
|
|
@@ -32,10 +32,10 @@ export class PedersenCommitment extends Instruction {
|
|
|
32
32
|
|
|
33
33
|
public async execute(context: AvmContext): Promise<void> {
|
|
34
34
|
const memory = context.machineState.memory.track(this.type);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
);
|
|
35
|
+
|
|
36
|
+
const operands = [this.inputOffset, this.outputOffset, this.inputSizeOffset, this.genIndexOffset];
|
|
37
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
38
|
+
const [inputOffset, outputOffset, inputSizeOffset, genIndexOffset] = addressing.resolve(operands, memory);
|
|
39
39
|
|
|
40
40
|
const inputSize = memory.get(inputSizeOffset).toNumber();
|
|
41
41
|
memory.checkTag(TypeTag.UINT32, inputSizeOffset);
|
|
@@ -46,8 +46,7 @@ export class PedersenCommitment extends Instruction {
|
|
|
46
46
|
const generatorIndex = memory.get(genIndexOffset).toNumber();
|
|
47
47
|
memory.checkTag(TypeTag.UINT32, genIndexOffset);
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: inputSize }));
|
|
49
|
+
context.machineState.consumeGas(this.gasCost(inputSize));
|
|
51
50
|
|
|
52
51
|
const inputBuffer: Buffer[] = inputs.map(input => input.toBuffer());
|
|
53
52
|
// TODO: Add the generate index to the pedersenCommit function
|
|
@@ -60,7 +59,7 @@ export class PedersenCommitment extends Instruction {
|
|
|
60
59
|
memory.set(outputOffset + 1, commitment[1]); // Field typed
|
|
61
60
|
memory.set(outputOffset + 2, new Uint8(isInfinity ? 1 : 0)); // U8 typed
|
|
62
61
|
|
|
63
|
-
memory.assert(
|
|
62
|
+
memory.assert({ reads: inputSize + 2, writes: 3, addressing });
|
|
64
63
|
context.machineState.incrementPc();
|
|
65
64
|
}
|
|
66
65
|
}
|
|
@@ -6,14 +6,12 @@ import { ThreeOperandInstruction } from './instruction_impl.js';
|
|
|
6
6
|
|
|
7
7
|
abstract class ComparatorInstruction extends ThreeOperandInstruction {
|
|
8
8
|
public async execute(context: AvmContext): Promise<void> {
|
|
9
|
-
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
10
9
|
const memory = context.machineState.memory.track(this.type);
|
|
11
|
-
context.machineState.consumeGas(this.gasCost(
|
|
10
|
+
context.machineState.consumeGas(this.gasCost());
|
|
12
11
|
|
|
13
|
-
const [aOffset, bOffset, dstOffset]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
);
|
|
12
|
+
const operands = [this.aOffset, this.bOffset, this.dstOffset];
|
|
13
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
14
|
+
const [aOffset, bOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
17
15
|
memory.checkTags(this.inTag, aOffset, bOffset);
|
|
18
16
|
|
|
19
17
|
const a = memory.get(aOffset);
|
|
@@ -22,7 +20,7 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction {
|
|
|
22
20
|
const dest = new Uint1(this.compare(a, b) ? 1 : 0);
|
|
23
21
|
memory.set(dstOffset, dest);
|
|
24
22
|
|
|
25
|
-
memory.assert(
|
|
23
|
+
memory.assert({ reads: 2, writes: 1, addressing });
|
|
26
24
|
context.machineState.incrementPc();
|
|
27
25
|
}
|
|
28
26
|
|
|
@@ -22,14 +22,12 @@ export class GetContractInstance extends Instruction {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
async execute(context: AvmContext): Promise<void> {
|
|
25
|
-
const memoryOperations = { reads: 1, writes: 6, indirect: this.indirect };
|
|
26
25
|
const memory = context.machineState.memory.track(this.type);
|
|
27
|
-
context.machineState.consumeGas(this.gasCost(
|
|
26
|
+
context.machineState.consumeGas(this.gasCost());
|
|
28
27
|
|
|
29
|
-
const [addressOffset, dstOffset]
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
);
|
|
28
|
+
const operands = [this.addressOffset, this.dstOffset];
|
|
29
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
30
|
+
const [addressOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
33
31
|
memory.checkTag(TypeTag.FIELD, addressOffset);
|
|
34
32
|
|
|
35
33
|
const address = memory.get(addressOffset).toFr();
|
|
@@ -46,7 +44,7 @@ export class GetContractInstance extends Instruction {
|
|
|
46
44
|
|
|
47
45
|
memory.setSlice(dstOffset, data);
|
|
48
46
|
|
|
49
|
-
memory.assert(
|
|
47
|
+
memory.assert({ reads: 1, writes: 6, addressing });
|
|
50
48
|
context.machineState.incrementPc();
|
|
51
49
|
}
|
|
52
50
|
}
|
|
@@ -41,21 +41,21 @@ export class JumpI extends Instruction {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
public async execute(context: AvmContext): Promise<void> {
|
|
44
|
-
const memoryOperations = { reads: 1, indirect: this.indirect };
|
|
45
44
|
const memory = context.machineState.memory.track(this.type);
|
|
46
|
-
context.machineState.consumeGas(this.gasCost(
|
|
45
|
+
context.machineState.consumeGas(this.gasCost());
|
|
47
46
|
|
|
48
|
-
const
|
|
47
|
+
const operands = [this.condOffset];
|
|
48
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
49
|
+
const [condOffset] = addressing.resolve(operands, memory);
|
|
49
50
|
const condition = memory.getAs<IntegralValue>(condOffset);
|
|
50
51
|
|
|
51
|
-
// TODO: reconsider this casting
|
|
52
52
|
if (condition.toBigInt() == 0n) {
|
|
53
53
|
context.machineState.incrementPc();
|
|
54
54
|
} else {
|
|
55
55
|
context.machineState.pc = this.loc;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
memory.assert(
|
|
58
|
+
memory.assert({ reads: 1, addressing });
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -17,7 +17,7 @@ export class ToRadixLE extends Instruction {
|
|
|
17
17
|
OperandType.UINT32, // dst memory address
|
|
18
18
|
OperandType.UINT32, // radix memory address
|
|
19
19
|
OperandType.UINT32, // number of limbs (Immediate)
|
|
20
|
-
OperandType.
|
|
20
|
+
OperandType.UINT8, // output is in "bits" mode (Immediate - Uint1 still takes up a whole byte)
|
|
21
21
|
];
|
|
22
22
|
|
|
23
23
|
constructor(
|
|
@@ -33,12 +33,10 @@ export class ToRadixLE extends Instruction {
|
|
|
33
33
|
|
|
34
34
|
public async execute(context: AvmContext): Promise<void> {
|
|
35
35
|
const memory = context.machineState.memory.track(this.type);
|
|
36
|
-
const [srcOffset, dstOffset, radixOffset]
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
);
|
|
40
|
-
const memoryOperations = { reads: 2, writes: this.numLimbs, indirect: this.indirect };
|
|
41
|
-
context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.numLimbs }));
|
|
36
|
+
const operands = [this.srcOffset, this.dstOffset, this.radixOffset];
|
|
37
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
38
|
+
const [srcOffset, dstOffset, radixOffset] = addressing.resolve(operands, memory);
|
|
39
|
+
context.machineState.consumeGas(this.gasCost(this.numLimbs));
|
|
42
40
|
|
|
43
41
|
// The radix gadget only takes in a Field
|
|
44
42
|
memory.checkTag(TypeTag.FIELD, srcOffset);
|
|
@@ -62,7 +60,7 @@ export class ToRadixLE extends Instruction {
|
|
|
62
60
|
const res = limbArray.map(byte => new outputType(byte));
|
|
63
61
|
memory.setSlice(dstOffset, res);
|
|
64
62
|
|
|
65
|
-
memory.assert(
|
|
63
|
+
memory.assert({ reads: 2, writes: this.numLimbs, addressing });
|
|
66
64
|
context.machineState.incrementPc();
|
|
67
65
|
}
|
|
68
66
|
}
|
|
@@ -14,7 +14,7 @@ export class EcAdd extends Instruction {
|
|
|
14
14
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
15
15
|
static readonly wireFormat: OperandType[] = [
|
|
16
16
|
OperandType.UINT8, // reserved
|
|
17
|
-
OperandType.
|
|
17
|
+
OperandType.UINT16, // indirect
|
|
18
18
|
OperandType.UINT32, // p1X
|
|
19
19
|
OperandType.UINT32, // p1Y
|
|
20
20
|
OperandType.UINT32, // p1IsInfinite
|
|
@@ -38,23 +38,21 @@ export class EcAdd extends Instruction {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
public async execute(context: AvmContext): Promise<void> {
|
|
41
|
-
const memoryOperations = { reads: 6, writes: 3, indirect: this.indirect };
|
|
42
41
|
const memory = context.machineState.memory.track(this.type);
|
|
43
|
-
context.machineState.consumeGas(this.gasCost(
|
|
42
|
+
context.machineState.consumeGas(this.gasCost());
|
|
44
43
|
|
|
44
|
+
const operands = [
|
|
45
|
+
this.p1XOffset,
|
|
46
|
+
this.p1YOffset,
|
|
47
|
+
this.p1IsInfiniteOffset,
|
|
48
|
+
this.p2XOffset,
|
|
49
|
+
this.p2YOffset,
|
|
50
|
+
this.p2IsInfiniteOffset,
|
|
51
|
+
this.dstOffset,
|
|
52
|
+
];
|
|
53
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
45
54
|
const [p1XOffset, p1YOffset, p1IsInfiniteOffset, p2XOffset, p2YOffset, p2IsInfiniteOffset, dstOffset] =
|
|
46
|
-
|
|
47
|
-
[
|
|
48
|
-
this.p1XOffset,
|
|
49
|
-
this.p1YOffset,
|
|
50
|
-
this.p1IsInfiniteOffset,
|
|
51
|
-
this.p2XOffset,
|
|
52
|
-
this.p2YOffset,
|
|
53
|
-
this.p2IsInfiniteOffset,
|
|
54
|
-
this.dstOffset,
|
|
55
|
-
],
|
|
56
|
-
memory,
|
|
57
|
-
);
|
|
55
|
+
addressing.resolve(operands, memory);
|
|
58
56
|
|
|
59
57
|
const p1X = memory.get(p1XOffset);
|
|
60
58
|
const p1Y = memory.get(p1YOffset);
|
|
@@ -86,7 +84,7 @@ export class EcAdd extends Instruction {
|
|
|
86
84
|
// Check representation of infinity for grumpkin
|
|
87
85
|
memory.set(dstOffset + 2, new Field(dest.equals(Point.ZERO) ? 1 : 0));
|
|
88
86
|
|
|
89
|
-
memory.assert(
|
|
87
|
+
memory.assert({ reads: 6, writes: 3, addressing });
|
|
90
88
|
context.machineState.incrementPc();
|
|
91
89
|
}
|
|
92
90
|
}
|
|
@@ -71,15 +71,16 @@ export class GetEnvVar extends Instruction {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
public async execute(context: AvmContext): Promise<void> {
|
|
74
|
-
const memoryOperations = { writes: 1, indirect: this.indirect };
|
|
75
74
|
const memory = context.machineState.memory.track(this.type);
|
|
76
|
-
context.machineState.consumeGas(this.gasCost(
|
|
75
|
+
context.machineState.consumeGas(this.gasCost());
|
|
77
76
|
|
|
78
|
-
const
|
|
77
|
+
const operands = [this.dstOffset];
|
|
78
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
79
|
+
const [dstOffset] = addressing.resolve(operands, memory);
|
|
79
80
|
|
|
80
81
|
memory.set(dstOffset, getValue(this.varEnum, context));
|
|
81
82
|
|
|
82
|
-
memory.assert(
|
|
83
|
+
memory.assert({ writes: 1, addressing });
|
|
83
84
|
context.machineState.incrementPc();
|
|
84
85
|
}
|
|
85
86
|
}
|