@aztec/simulator 0.62.0 → 0.63.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/acvm/acvm.d.ts +2 -16
- package/dest/acvm/acvm.d.ts.map +1 -1
- package/dest/acvm/acvm.js +2 -70
- package/dest/acvm/oracle/oracle.d.ts +4 -4
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +10 -11
- package/dest/acvm/oracle/typed_oracle.d.ts +5 -5
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +8 -8
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +2 -1
- package/dest/avm/avm_machine_state.d.ts +27 -8
- package/dest/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/avm/avm_machine_state.js +6 -10
- package/dest/avm/avm_memory_types.d.ts +8 -0
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +5 -1
- package/dest/avm/avm_simulator.d.ts +2 -19
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +12 -14
- package/dest/avm/avm_tree.d.ts +249 -0
- package/dest/avm/avm_tree.d.ts.map +1 -0
- package/dest/avm/avm_tree.js +637 -0
- package/dest/avm/errors.d.ts +4 -17
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +21 -50
- package/dest/avm/fixtures/index.d.ts +7 -2
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +12 -12
- package/dest/avm/index.d.ts +1 -0
- package/dest/avm/index.d.ts.map +1 -1
- package/dest/avm/index.js +2 -1
- package/dest/avm/journal/journal.d.ts +43 -24
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +172 -39
- package/dest/avm/journal/nullifiers.d.ts +5 -4
- package/dest/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/avm/journal/nullifiers.js +2 -3
- package/dest/avm/journal/public_storage.d.ts +6 -5
- package/dest/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/avm/journal/public_storage.js +1 -1
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +4 -10
- package/dest/avm/opcodes/arithmetic.d.ts +4 -1
- package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/avm/opcodes/arithmetic.js +18 -4
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +1 -3
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +1 -2
- package/dest/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/avm/opcodes/contract.js +2 -3
- package/dest/avm/opcodes/control_flow.d.ts +4 -0
- package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/avm/opcodes/control_flow.js +21 -6
- package/dest/avm/opcodes/conversion.d.ts.map +1 -1
- package/dest/avm/opcodes/conversion.js +1 -2
- package/dest/avm/opcodes/ec_add.d.ts.map +1 -1
- package/dest/avm/opcodes/ec_add.js +5 -11
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +1 -2
- package/dest/avm/opcodes/external_calls.d.ts +4 -2
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +38 -22
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +1 -4
- package/dest/avm/opcodes/instruction.d.ts +4 -0
- package/dest/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction.js +7 -1
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +1 -7
- package/dest/avm/opcodes/misc.js +3 -3
- package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -1
- package/dest/avm/opcodes/multi_scalar_mul.js +6 -5
- package/dest/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/avm/opcodes/storage.js +2 -4
- package/dest/avm/serialization/bytecode_serialization.d.ts +1 -6
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +24 -20
- package/dest/client/client_execution_context.d.ts +7 -11
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +18 -20
- package/dest/client/db_oracle.d.ts +17 -10
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/db_oracle.js +1 -1
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +5 -4
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +3 -2
- package/dest/client/view_data_oracle.d.ts +6 -12
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +10 -12
- package/dest/common/errors.d.ts +15 -2
- package/dest/common/errors.d.ts.map +1 -1
- package/dest/common/errors.js +85 -4
- package/dest/mocks/fixtures.d.ts +9 -28
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +12 -57
- package/dest/public/dual_side_effect_trace.d.ts +34 -26
- package/dest/public/dual_side_effect_trace.d.ts.map +1 -1
- package/dest/public/dual_side_effect_trace.js +48 -36
- package/dest/public/enqueued_call_side_effect_trace.d.ts +96 -33
- package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
- package/dest/public/enqueued_call_side_effect_trace.js +212 -138
- package/dest/public/execution.d.ts +50 -17
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -29
- package/dest/public/executor.d.ts +28 -11
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +33 -33
- package/dest/public/index.d.ts +4 -5
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +4 -5
- package/dest/public/public_db_sources.d.ts +1 -0
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +12 -5
- package/dest/public/public_processor.d.ts +7 -11
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +60 -42
- package/dest/public/public_processor_metrics.d.ts +3 -3
- package/dest/public/public_processor_metrics.d.ts.map +1 -1
- package/dest/public/public_processor_metrics.js +1 -1
- package/dest/public/public_tx_context.d.ts +130 -0
- package/dest/public/public_tx_context.d.ts.map +1 -0
- package/dest/public/public_tx_context.js +293 -0
- package/dest/public/public_tx_simulator.d.ts +36 -0
- package/dest/public/public_tx_simulator.d.ts.map +1 -0
- package/dest/public/public_tx_simulator.js +148 -0
- package/dest/public/side_effect_trace.d.ts +30 -15
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +70 -16
- package/dest/public/side_effect_trace_interface.d.ts +43 -12
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/public/transitional_adapters.d.ts +9 -0
- package/dest/public/transitional_adapters.d.ts.map +1 -0
- package/dest/public/transitional_adapters.js +127 -0
- package/dest/public/utils.d.ts +5 -0
- package/dest/public/utils.d.ts.map +1 -0
- package/dest/public/utils.js +30 -0
- package/package.json +12 -9
- package/src/acvm/acvm.ts +3 -94
- package/src/acvm/oracle/oracle.ts +9 -14
- package/src/acvm/oracle/typed_oracle.ts +8 -8
- package/src/avm/avm_gas.ts +1 -0
- package/src/avm/avm_machine_state.ts +28 -12
- package/src/avm/avm_memory_types.ts +5 -0
- package/src/avm/avm_simulator.ts +13 -16
- package/src/avm/avm_tree.ts +785 -0
- package/src/avm/errors.ts +25 -48
- package/src/avm/fixtures/index.ts +16 -12
- package/src/avm/index.ts +1 -0
- package/src/avm/journal/journal.ts +291 -52
- package/src/avm/journal/nullifiers.ts +7 -7
- package/src/avm/journal/public_storage.ts +5 -5
- package/src/avm/opcodes/accrued_substate.ts +3 -9
- package/src/avm/opcodes/arithmetic.ts +26 -4
- package/src/avm/opcodes/bitwise.ts +0 -2
- package/src/avm/opcodes/comparators.ts +0 -1
- package/src/avm/opcodes/contract.ts +1 -2
- package/src/avm/opcodes/control_flow.ts +24 -5
- package/src/avm/opcodes/conversion.ts +0 -1
- package/src/avm/opcodes/ec_add.ts +6 -9
- package/src/avm/opcodes/environment_getters.ts +0 -1
- package/src/avm/opcodes/external_calls.ts +39 -21
- package/src/avm/opcodes/hashing.ts +0 -3
- package/src/avm/opcodes/instruction.ts +7 -0
- package/src/avm/opcodes/memory.ts +0 -6
- package/src/avm/opcodes/misc.ts +2 -2
- package/src/avm/opcodes/multi_scalar_mul.ts +5 -4
- package/src/avm/opcodes/storage.ts +1 -3
- package/src/avm/serialization/bytecode_serialization.ts +31 -22
- package/src/client/client_execution_context.ts +22 -23
- package/src/client/db_oracle.ts +22 -11
- package/src/client/private_execution.ts +5 -4
- package/src/client/unconstrained_execution.ts +2 -1
- package/src/client/view_data_oracle.ts +14 -13
- package/src/common/errors.ts +119 -3
- package/src/mocks/fixtures.ts +15 -106
- package/src/public/dual_side_effect_trace.ts +138 -50
- package/src/public/enqueued_call_side_effect_trace.ts +352 -212
- package/src/public/execution.ts +58 -42
- package/src/public/executor.ts +52 -67
- package/src/public/index.ts +7 -5
- package/src/public/public_db_sources.ts +12 -4
- package/src/public/public_processor.ts +111 -73
- package/src/public/public_processor_metrics.ts +3 -3
- package/src/public/public_tx_context.ts +411 -0
- package/src/public/public_tx_simulator.ts +232 -0
- package/src/public/side_effect_trace.ts +154 -28
- package/src/public/side_effect_trace_interface.ts +92 -14
- package/src/public/transitional_adapters.ts +347 -0
- package/src/public/utils.ts +32 -0
- package/dest/public/enqueued_call_simulator.d.ts +0 -43
- package/dest/public/enqueued_call_simulator.d.ts.map +0 -1
- package/dest/public/enqueued_call_simulator.js +0 -156
- package/dest/public/enqueued_calls_processor.d.ts +0 -43
- package/dest/public/enqueued_calls_processor.d.ts.map +0 -1
- package/dest/public/enqueued_calls_processor.js +0 -209
- package/dest/public/hints_builder.d.ts +0 -29
- package/dest/public/hints_builder.d.ts.map +0 -1
- package/dest/public/hints_builder.js +0 -75
- package/dest/public/public_kernel.d.ts +0 -30
- package/dest/public/public_kernel.d.ts.map +0 -1
- package/dest/public/public_kernel.js +0 -67
- package/dest/public/public_kernel_circuit_simulator.d.ts +0 -25
- package/dest/public/public_kernel_circuit_simulator.d.ts.map +0 -1
- package/dest/public/public_kernel_circuit_simulator.js +0 -2
- package/dest/public/public_kernel_tail_simulator.d.ts +0 -15
- package/dest/public/public_kernel_tail_simulator.d.ts.map +0 -1
- package/dest/public/public_kernel_tail_simulator.js +0 -39
- package/src/public/enqueued_call_simulator.ts +0 -360
- package/src/public/enqueued_calls_processor.ts +0 -372
- package/src/public/hints_builder.ts +0 -168
- package/src/public/public_kernel.ts +0 -100
- package/src/public/public_kernel_circuit_simulator.ts +0 -32
- package/src/public/public_kernel_tail_simulator.ts +0 -97
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type Field,
|
|
4
|
+
type MemoryValue,
|
|
5
|
+
TaggedMemory,
|
|
6
|
+
type TaggedMemoryInterface,
|
|
7
|
+
TypeTag,
|
|
8
|
+
} from '../avm_memory_types.js';
|
|
9
|
+
import { ArithmeticError } from '../errors.js';
|
|
3
10
|
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
4
11
|
import { Addressing } from './addressing_mode.js';
|
|
5
12
|
import { ThreeOperandInstruction } from './instruction_impl.js';
|
|
@@ -12,7 +19,7 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst
|
|
|
12
19
|
const operands = [this.aOffset, this.bOffset, this.dstOffset];
|
|
13
20
|
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
14
21
|
const [aOffset, bOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
15
|
-
|
|
22
|
+
this.checkTags(memory, aOffset, bOffset);
|
|
16
23
|
|
|
17
24
|
const a = memory.get(aOffset);
|
|
18
25
|
const b = memory.get(bOffset);
|
|
@@ -21,10 +28,12 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst
|
|
|
21
28
|
memory.set(dstOffset, dest);
|
|
22
29
|
|
|
23
30
|
memory.assert({ reads: 2, writes: 1, addressing });
|
|
24
|
-
context.machineState.incrementPc();
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
protected abstract compute(a: MemoryValue, b: MemoryValue): MemoryValue;
|
|
34
|
+
protected checkTags(memory: TaggedMemoryInterface, aOffset: number, bOffset: number) {
|
|
35
|
+
memory.checkTagsAreSame(aOffset, bOffset);
|
|
36
|
+
}
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
export class Add extends ThreeOperandArithmeticInstruction {
|
|
@@ -59,11 +68,19 @@ export class Div extends ThreeOperandArithmeticInstruction {
|
|
|
59
68
|
static readonly opcode = Opcode.DIV_8; // FIXME: needed for gas.
|
|
60
69
|
|
|
61
70
|
protected compute(a: MemoryValue, b: MemoryValue): MemoryValue {
|
|
71
|
+
if (b.toBigInt() === 0n) {
|
|
72
|
+
throw new ArithmeticError('Division by zero');
|
|
73
|
+
}
|
|
74
|
+
|
|
62
75
|
return a.div(b);
|
|
63
76
|
}
|
|
77
|
+
|
|
78
|
+
protected override checkTags(memory: TaggedMemoryInterface, aOffset: number, bOffset: number) {
|
|
79
|
+
memory.checkTagsAreSame(aOffset, bOffset);
|
|
80
|
+
TaggedMemory.checkIsIntegralTag(memory.getTag(aOffset)); // Follows that bOffset tag is also of integral type
|
|
81
|
+
}
|
|
64
82
|
}
|
|
65
83
|
|
|
66
|
-
// TODO: This class now temporarily has a tag, until all tags are removed.
|
|
67
84
|
export class FieldDiv extends ThreeOperandArithmeticInstruction {
|
|
68
85
|
static type: string = 'FDIV';
|
|
69
86
|
static readonly opcode = Opcode.FDIV_8; // FIXME: needed for gas.
|
|
@@ -72,4 +89,9 @@ export class FieldDiv extends ThreeOperandArithmeticInstruction {
|
|
|
72
89
|
// return (a as Field).fdiv(b as Field);
|
|
73
90
|
return a.fdiv(b);
|
|
74
91
|
}
|
|
92
|
+
|
|
93
|
+
protected override checkTags(memory: TaggedMemoryInterface, aOffset: number, bOffset: number) {
|
|
94
|
+
memory.checkTagsAreSame(aOffset, bOffset);
|
|
95
|
+
memory.checkTag(TypeTag.FIELD, aOffset); // Follows that bOffset has also tag of type Field
|
|
96
|
+
}
|
|
75
97
|
}
|
|
@@ -22,7 +22,6 @@ abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
|
|
|
22
22
|
memory.set(dstOffset, res);
|
|
23
23
|
|
|
24
24
|
memory.assert({ reads: 2, writes: 1, addressing });
|
|
25
|
-
context.machineState.incrementPc();
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
protected abstract compute(a: IntegralValue, b: IntegralValue): IntegralValue;
|
|
@@ -110,6 +109,5 @@ export class Not extends Instruction {
|
|
|
110
109
|
memory.set(dstOffset, res);
|
|
111
110
|
|
|
112
111
|
memory.assert({ reads: 1, writes: 1, addressing });
|
|
113
|
-
context.machineState.incrementPc();
|
|
114
112
|
}
|
|
115
113
|
}
|
|
@@ -21,7 +21,6 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction {
|
|
|
21
21
|
memory.set(dstOffset, dest);
|
|
22
22
|
|
|
23
23
|
memory.assert({ reads: 2, writes: 1, addressing });
|
|
24
|
-
context.machineState.incrementPc();
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
protected abstract compare(a: MemoryValue, b: MemoryValue): boolean;
|
|
@@ -47,7 +47,7 @@ export class GetContractInstance extends Instruction {
|
|
|
47
47
|
const [addressOffset, dstOffset, existsOffset] = addressing.resolve(operands, memory);
|
|
48
48
|
memory.checkTag(TypeTag.FIELD, addressOffset);
|
|
49
49
|
|
|
50
|
-
const address = memory.get(addressOffset).
|
|
50
|
+
const address = memory.get(addressOffset).toAztecAddress();
|
|
51
51
|
const instance = await context.persistableState.getContractInstance(address);
|
|
52
52
|
const exists = instance !== undefined;
|
|
53
53
|
|
|
@@ -70,6 +70,5 @@ export class GetContractInstance extends Instruction {
|
|
|
70
70
|
memory.set(dstOffset, memberValue);
|
|
71
71
|
|
|
72
72
|
memory.assert({ reads: 1, writes: 2, addressing });
|
|
73
|
-
context.machineState.incrementPc();
|
|
74
73
|
}
|
|
75
74
|
}
|
|
@@ -22,6 +22,10 @@ export class Jump extends Instruction {
|
|
|
22
22
|
|
|
23
23
|
context.machineState.memory.assert({});
|
|
24
24
|
}
|
|
25
|
+
|
|
26
|
+
public override handlesPC(): boolean {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
export class JumpI extends Instruction {
|
|
@@ -50,13 +54,17 @@ export class JumpI extends Instruction {
|
|
|
50
54
|
const condition = memory.getAs<IntegralValue>(condOffset);
|
|
51
55
|
|
|
52
56
|
if (condition.toBigInt() == 0n) {
|
|
53
|
-
context.machineState.
|
|
57
|
+
context.machineState.pc = context.machineState.nextPc;
|
|
54
58
|
} else {
|
|
55
59
|
context.machineState.pc = this.loc;
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
memory.assert({ reads: 1, addressing });
|
|
59
63
|
}
|
|
64
|
+
|
|
65
|
+
public override handlesPC(): boolean {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
export class InternalCall extends Instruction {
|
|
@@ -72,11 +80,18 @@ export class InternalCall extends Instruction {
|
|
|
72
80
|
public async execute(context: AvmContext): Promise<void> {
|
|
73
81
|
context.machineState.consumeGas(this.gasCost());
|
|
74
82
|
|
|
75
|
-
context.machineState.internalCallStack.push(
|
|
83
|
+
context.machineState.internalCallStack.push({
|
|
84
|
+
callPc: context.machineState.pc,
|
|
85
|
+
returnPc: context.machineState.nextPc,
|
|
86
|
+
});
|
|
76
87
|
context.machineState.pc = this.loc;
|
|
77
88
|
|
|
78
89
|
context.machineState.memory.assert({});
|
|
79
90
|
}
|
|
91
|
+
|
|
92
|
+
public override handlesPC(): boolean {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
80
95
|
}
|
|
81
96
|
|
|
82
97
|
export class InternalReturn extends Instruction {
|
|
@@ -92,12 +107,16 @@ export class InternalReturn extends Instruction {
|
|
|
92
107
|
public async execute(context: AvmContext): Promise<void> {
|
|
93
108
|
context.machineState.consumeGas(this.gasCost());
|
|
94
109
|
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
110
|
+
const stackEntry = context.machineState.internalCallStack.pop();
|
|
111
|
+
if (stackEntry === undefined) {
|
|
97
112
|
throw new InstructionExecutionError('Internal call stack empty!');
|
|
98
113
|
}
|
|
99
|
-
context.machineState.pc =
|
|
114
|
+
context.machineState.pc = stackEntry.returnPc;
|
|
100
115
|
|
|
101
116
|
context.machineState.memory.assert({});
|
|
102
117
|
}
|
|
118
|
+
|
|
119
|
+
public override handlesPC(): boolean {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
103
122
|
}
|
|
@@ -2,7 +2,7 @@ import { Grumpkin } from '@aztec/circuits.js/barretenberg';
|
|
|
2
2
|
import { Point } from '@aztec/foundation/fields';
|
|
3
3
|
|
|
4
4
|
import { type AvmContext } from '../avm_context.js';
|
|
5
|
-
import { Field } from '../avm_memory_types.js';
|
|
5
|
+
import { Field, TypeTag, Uint1 } from '../avm_memory_types.js';
|
|
6
6
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
7
7
|
import { Addressing } from './addressing_mode.js';
|
|
8
8
|
import { Instruction } from './instruction.js';
|
|
@@ -54,6 +54,9 @@ export class EcAdd extends Instruction {
|
|
|
54
54
|
const [p1XOffset, p1YOffset, p1IsInfiniteOffset, p2XOffset, p2YOffset, p2IsInfiniteOffset, dstOffset] =
|
|
55
55
|
addressing.resolve(operands, memory);
|
|
56
56
|
|
|
57
|
+
memory.checkTags(TypeTag.FIELD, p1XOffset, p1YOffset, p2XOffset, p2YOffset);
|
|
58
|
+
memory.checkTags(TypeTag.UINT1, p1IsInfiniteOffset, p2IsInfiniteOffset);
|
|
59
|
+
|
|
57
60
|
const p1X = memory.get(p1XOffset);
|
|
58
61
|
const p1Y = memory.get(p1YOffset);
|
|
59
62
|
const p1IsInfinite = memory.get(p1IsInfiniteOffset).toNumber() === 1;
|
|
@@ -80,18 +83,12 @@ export class EcAdd extends Instruction {
|
|
|
80
83
|
} else {
|
|
81
84
|
dest = grumpkin.add(p1, p2);
|
|
82
85
|
}
|
|
83
|
-
|
|
84
|
-
if (p1IsInfinite) {
|
|
85
|
-
dest = p2;
|
|
86
|
-
} else if (p2IsInfinite) {
|
|
87
|
-
dest = p1;
|
|
88
|
-
}
|
|
86
|
+
|
|
89
87
|
memory.set(dstOffset, new Field(dest.x));
|
|
90
88
|
memory.set(dstOffset + 1, new Field(dest.y));
|
|
91
89
|
// Check representation of infinity for grumpkin
|
|
92
|
-
memory.set(dstOffset + 2, new
|
|
90
|
+
memory.set(dstOffset + 2, new Uint1(dest.equals(Point.ZERO) ? 1 : 0));
|
|
93
91
|
|
|
94
92
|
memory.assert({ reads: 6, writes: 3, addressing });
|
|
95
|
-
context.machineState.incrementPc();
|
|
96
93
|
}
|
|
97
94
|
}
|
|
@@ -5,7 +5,6 @@ import { type AvmContractCallResult } from '../avm_contract_call_result.js';
|
|
|
5
5
|
import { gasLeftToGas } from '../avm_gas.js';
|
|
6
6
|
import { type Field, TypeTag, Uint1 } from '../avm_memory_types.js';
|
|
7
7
|
import { AvmSimulator } from '../avm_simulator.js';
|
|
8
|
-
import { RethrownError } from '../errors.js';
|
|
9
8
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
10
9
|
import { Addressing } from './addressing_mode.js';
|
|
11
10
|
import { Instruction } from './instruction.js';
|
|
@@ -65,7 +64,7 @@ abstract class ExternalCall extends Instruction {
|
|
|
65
64
|
context.machineState.consumeGas(allocatedGas);
|
|
66
65
|
|
|
67
66
|
const nestedContext = context.createNestedContractCallContext(
|
|
68
|
-
callAddress.
|
|
67
|
+
callAddress.toAztecAddress(),
|
|
69
68
|
calldata,
|
|
70
69
|
allocatedGas,
|
|
71
70
|
callType,
|
|
@@ -76,28 +75,35 @@ abstract class ExternalCall extends Instruction {
|
|
|
76
75
|
const nestedCallResults: AvmContractCallResult = await simulator.execute();
|
|
77
76
|
const success = !nestedCallResults.reverted;
|
|
78
77
|
|
|
79
|
-
// TRANSITIONAL: We rethrow here so that the MESSAGE gets propagated.
|
|
80
|
-
// This means that for now, the caller cannot recover from errors.
|
|
81
|
-
if (!success) {
|
|
82
|
-
if (!nestedCallResults.revertReason) {
|
|
83
|
-
throw new Error('A reverted nested call should be assigned a revert reason in the AVM execution loop');
|
|
84
|
-
}
|
|
85
|
-
// The nested call's revertReason will be used to track the stack of error causes down to the root.
|
|
86
|
-
throw new RethrownError(nestedCallResults.revertReason.message, nestedCallResults.revertReason);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
78
|
// Save return/revert data for later.
|
|
90
79
|
const fullReturnData = nestedCallResults.output;
|
|
91
80
|
context.machineState.nestedReturndata = fullReturnData;
|
|
92
81
|
|
|
82
|
+
// If the nested call reverted, we try to save the reason and the revert data.
|
|
83
|
+
// This will be used by the caller to try to reconstruct the call stack.
|
|
84
|
+
// This is only a heuristic and may not always work. It is intended to work
|
|
85
|
+
// for the case where a nested call reverts and the caller always rethrows
|
|
86
|
+
// (in Noir code).
|
|
87
|
+
if (!success) {
|
|
88
|
+
context.machineState.collectedRevertInfo = {
|
|
89
|
+
revertDataRepresentative: fullReturnData,
|
|
90
|
+
recursiveRevertReason: nestedCallResults.revertReason!,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
93
94
|
// Write our success flag into memory.
|
|
94
95
|
memory.set(successOffset, new Uint1(success ? 1 : 0));
|
|
95
96
|
|
|
96
97
|
// Refund unused gas
|
|
97
98
|
context.machineState.refundGas(gasLeftToGas(nestedContext.machineState));
|
|
98
99
|
|
|
99
|
-
//
|
|
100
|
-
|
|
100
|
+
// Merge nested call's state and trace based on whether it succeeded.
|
|
101
|
+
if (success) {
|
|
102
|
+
context.persistableState.merge(nestedContext.persistableState);
|
|
103
|
+
} else {
|
|
104
|
+
context.persistableState.reject(nestedContext.persistableState);
|
|
105
|
+
}
|
|
106
|
+
await context.persistableState.traceNestedCall(
|
|
101
107
|
/*nestedState=*/ nestedContext.persistableState,
|
|
102
108
|
/*nestedEnvironment=*/ nestedContext.environment,
|
|
103
109
|
/*startGasLeft=*/ Gas.from(allocatedGas),
|
|
@@ -107,7 +113,6 @@ abstract class ExternalCall extends Instruction {
|
|
|
107
113
|
);
|
|
108
114
|
|
|
109
115
|
memory.assert({ reads: calldataSize + 4, writes: 1, addressing });
|
|
110
|
-
context.machineState.incrementPc();
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
public abstract override get type(): 'CALL' | 'STATICCALL';
|
|
@@ -142,22 +147,29 @@ export class Return extends Instruction {
|
|
|
142
147
|
OperandType.UINT16,
|
|
143
148
|
];
|
|
144
149
|
|
|
145
|
-
constructor(private indirect: number, private returnOffset: number, private
|
|
150
|
+
constructor(private indirect: number, private returnOffset: number, private returnSizeOffset: number) {
|
|
146
151
|
super();
|
|
147
152
|
}
|
|
148
153
|
|
|
149
154
|
public async execute(context: AvmContext): Promise<void> {
|
|
150
155
|
const memory = context.machineState.memory.track(this.type);
|
|
151
|
-
context.machineState.consumeGas(this.gasCost(this.copySize));
|
|
152
156
|
|
|
153
|
-
const operands = [this.returnOffset];
|
|
157
|
+
const operands = [this.returnOffset, this.returnSizeOffset];
|
|
154
158
|
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
155
|
-
const [returnOffset] = addressing.resolve(operands, memory);
|
|
159
|
+
const [returnOffset, returnSizeOffset] = addressing.resolve(operands, memory);
|
|
160
|
+
|
|
161
|
+
memory.checkTag(TypeTag.UINT32, returnSizeOffset);
|
|
162
|
+
const returnSize = memory.get(returnSizeOffset).toNumber();
|
|
163
|
+
context.machineState.consumeGas(this.gasCost(returnSize));
|
|
156
164
|
|
|
157
|
-
const output = memory.getSlice(returnOffset,
|
|
165
|
+
const output = memory.getSlice(returnOffset, returnSize).map(word => word.toFr());
|
|
158
166
|
|
|
159
167
|
context.machineState.return(output);
|
|
160
|
-
memory.assert({ reads:
|
|
168
|
+
memory.assert({ reads: returnSize + 1, addressing });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public override handlesPC(): boolean {
|
|
172
|
+
return true;
|
|
161
173
|
}
|
|
162
174
|
}
|
|
163
175
|
|
|
@@ -197,6 +209,12 @@ export class Revert extends Instruction {
|
|
|
197
209
|
context.machineState.revert(output);
|
|
198
210
|
memory.assert({ reads: retSize + 1, addressing });
|
|
199
211
|
}
|
|
212
|
+
|
|
213
|
+
// We don't want to increase the PC after reverting because it breaks messages.
|
|
214
|
+
// Maybe we can remove this once messages don't depend on PCs.
|
|
215
|
+
public override handlesPC(): boolean {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
200
218
|
}
|
|
201
219
|
|
|
202
220
|
/** Returns the smaller of two bigints. */
|
|
@@ -40,7 +40,6 @@ export class Poseidon2 extends Instruction {
|
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
memory.assert({ reads: Poseidon2.stateSize, writes: Poseidon2.stateSize, addressing });
|
|
43
|
-
context.machineState.incrementPc();
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
45
|
|
|
@@ -78,7 +77,6 @@ export class KeccakF1600 extends Instruction {
|
|
|
78
77
|
memory.setSlice(dstOffset, res);
|
|
79
78
|
|
|
80
79
|
memory.assert({ reads: inputSize, writes: inputSize, addressing });
|
|
81
|
-
context.machineState.incrementPc();
|
|
82
80
|
}
|
|
83
81
|
}
|
|
84
82
|
|
|
@@ -127,6 +125,5 @@ export class Sha256Compression extends Instruction {
|
|
|
127
125
|
memory.setSlice(outputOffset, res);
|
|
128
126
|
|
|
129
127
|
memory.assert({ reads: STATE_SIZE + INPUTS_SIZE, writes: STATE_SIZE, addressing });
|
|
130
|
-
context.machineState.incrementPc();
|
|
131
128
|
}
|
|
132
129
|
}
|
|
@@ -22,6 +22,13 @@ export abstract class Instruction {
|
|
|
22
22
|
*/
|
|
23
23
|
public abstract execute(context: AvmContext): Promise<void>;
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Whether the instruction will modify the PC itself.
|
|
27
|
+
*/
|
|
28
|
+
public handlesPC(): boolean {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
25
32
|
/**
|
|
26
33
|
* Generate a string representation of the instruction including
|
|
27
34
|
* the instruction sub-class name all of its flags and operands.
|
|
@@ -72,7 +72,6 @@ export class Set extends Instruction {
|
|
|
72
72
|
memory.set(dstOffset, res);
|
|
73
73
|
|
|
74
74
|
memory.assert({ writes: 1, addressing });
|
|
75
|
-
context.machineState.incrementPc();
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
77
|
|
|
@@ -113,7 +112,6 @@ export class Cast extends Instruction {
|
|
|
113
112
|
memory.set(dstOffset, casted);
|
|
114
113
|
|
|
115
114
|
memory.assert({ reads: 1, writes: 1, addressing });
|
|
116
|
-
context.machineState.incrementPc();
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
117
|
|
|
@@ -152,7 +150,6 @@ export class Mov extends Instruction {
|
|
|
152
150
|
memory.set(dstOffset, a);
|
|
153
151
|
|
|
154
152
|
memory.assert({ reads: 1, writes: 1, addressing });
|
|
155
|
-
context.machineState.incrementPc();
|
|
156
153
|
}
|
|
157
154
|
}
|
|
158
155
|
|
|
@@ -193,7 +190,6 @@ export class CalldataCopy extends Instruction {
|
|
|
193
190
|
memory.setSlice(dstOffset, transformedData);
|
|
194
191
|
|
|
195
192
|
memory.assert({ reads: 2, writes: copySize, addressing });
|
|
196
|
-
context.machineState.incrementPc();
|
|
197
193
|
}
|
|
198
194
|
}
|
|
199
195
|
|
|
@@ -217,7 +213,6 @@ export class ReturndataSize extends Instruction {
|
|
|
217
213
|
memory.set(dstOffset, new Uint32(context.machineState.nestedReturndata.length));
|
|
218
214
|
|
|
219
215
|
memory.assert({ writes: 1, addressing });
|
|
220
|
-
context.machineState.incrementPc();
|
|
221
216
|
}
|
|
222
217
|
}
|
|
223
218
|
|
|
@@ -260,6 +255,5 @@ export class ReturndataCopy extends Instruction {
|
|
|
260
255
|
memory.setSlice(dstOffset, transformedData);
|
|
261
256
|
|
|
262
257
|
memory.assert({ reads: 2, writes: copySize, addressing });
|
|
263
|
-
context.machineState.incrementPc();
|
|
264
258
|
}
|
|
265
259
|
}
|
package/src/avm/opcodes/misc.ts
CHANGED
|
@@ -37,11 +37,12 @@ export class DebugLog extends Instruction {
|
|
|
37
37
|
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
38
38
|
const [messageOffset, fieldsOffset, fieldsSizeOffset] = addressing.resolve(operands, memory);
|
|
39
39
|
|
|
40
|
+
memory.checkTag(TypeTag.UINT32, fieldsSizeOffset);
|
|
40
41
|
const fieldsSize = memory.get(fieldsSizeOffset).toNumber();
|
|
41
42
|
memory.checkTagsRange(TypeTag.UINT8, messageOffset, this.messageSize);
|
|
42
43
|
memory.checkTagsRange(TypeTag.FIELD, fieldsOffset, fieldsSize);
|
|
43
44
|
|
|
44
|
-
context.machineState.consumeGas(this.gasCost());
|
|
45
|
+
context.machineState.consumeGas(this.gasCost(this.messageSize + fieldsSize));
|
|
45
46
|
|
|
46
47
|
const rawMessage = memory.getSlice(messageOffset, this.messageSize);
|
|
47
48
|
const fields = memory.getSlice(fieldsOffset, fieldsSize);
|
|
@@ -56,6 +57,5 @@ export class DebugLog extends Instruction {
|
|
|
56
57
|
DebugLog.logger.verbose(formattedStr);
|
|
57
58
|
|
|
58
59
|
memory.assert({ reads: 1 + fieldsSize + this.messageSize, addressing });
|
|
59
|
-
context.machineState.incrementPc();
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -2,7 +2,7 @@ import { Fq, Point } from '@aztec/circuits.js';
|
|
|
2
2
|
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
|
|
3
3
|
|
|
4
4
|
import { type AvmContext } from '../avm_context.js';
|
|
5
|
-
import { Field, TypeTag } from '../avm_memory_types.js';
|
|
5
|
+
import { Field, TypeTag, Uint1 } from '../avm_memory_types.js';
|
|
6
6
|
import { InstructionExecutionError } from '../errors.js';
|
|
7
7
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
8
8
|
import { Addressing } from './addressing_mode.js';
|
|
@@ -105,15 +105,16 @@ export class MultiScalarMul extends Instruction {
|
|
|
105
105
|
return grumpkin.add(acc, grumpkin.mul(curr[0], curr[1]));
|
|
106
106
|
}
|
|
107
107
|
}, grumpkin.mul(firstBaseScalarPair[0], firstBaseScalarPair[1]));
|
|
108
|
-
const output = outputPoint.toFields().map(f => new Field(f));
|
|
109
108
|
|
|
110
|
-
memory.
|
|
109
|
+
memory.set(outputOffset, new Field(outputPoint.x));
|
|
110
|
+
memory.set(outputOffset + 1, new Field(outputPoint.y));
|
|
111
|
+
// Check representation of infinity for grumpkin
|
|
112
|
+
memory.set(outputOffset + 2, new Uint1(outputPoint.equals(Point.ZERO) ? 1 : 0));
|
|
111
113
|
|
|
112
114
|
memory.assert({
|
|
113
115
|
reads: 1 + pointsReadLength + scalarReadLength /* points and scalars */,
|
|
114
116
|
writes: 3 /* output triplet */,
|
|
115
117
|
addressing,
|
|
116
118
|
});
|
|
117
|
-
context.machineState.incrementPc();
|
|
118
119
|
}
|
|
119
120
|
}
|
|
@@ -43,10 +43,9 @@ export class SStore extends BaseStorageInstruction {
|
|
|
43
43
|
|
|
44
44
|
const slot = memory.get(slotOffset).toFr();
|
|
45
45
|
const value = memory.get(srcOffset).toFr();
|
|
46
|
-
context.persistableState.writeStorage(context.environment.address, slot, value);
|
|
46
|
+
await context.persistableState.writeStorage(context.environment.address, slot, value);
|
|
47
47
|
|
|
48
48
|
memory.assert({ reads: 2, addressing });
|
|
49
|
-
context.machineState.incrementPc();
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
|
|
@@ -71,7 +70,6 @@ export class SLoad extends BaseStorageInstruction {
|
|
|
71
70
|
const value = await context.persistableState.readStorage(context.environment.address, slot);
|
|
72
71
|
memory.set(dstOffset, new Field(value));
|
|
73
72
|
|
|
74
|
-
context.machineState.incrementPc();
|
|
75
73
|
memory.assert({ writes: 1, reads: 1, addressing });
|
|
76
74
|
}
|
|
77
75
|
}
|
|
@@ -143,12 +143,11 @@ const INSTRUCTION_SET = () =>
|
|
|
143
143
|
[EcAdd.opcode, Instruction.deserialize.bind(EcAdd)],
|
|
144
144
|
[Poseidon2.opcode, Instruction.deserialize.bind(Poseidon2)],
|
|
145
145
|
[Sha256Compression.opcode, Instruction.deserialize.bind(Sha256Compression)],
|
|
146
|
+
[KeccakF1600.opcode, Instruction.deserialize.bind(KeccakF1600)],
|
|
146
147
|
[MultiScalarMul.opcode, Instruction.deserialize.bind(MultiScalarMul)],
|
|
148
|
+
|
|
147
149
|
// Conversions
|
|
148
150
|
[ToRadixBE.opcode, Instruction.deserialize.bind(ToRadixBE)],
|
|
149
|
-
// Future Gadgets -- pending changes in noir
|
|
150
|
-
// SHA256COMPRESSION,
|
|
151
|
-
[KeccakF1600.opcode, Instruction.deserialize.bind(KeccakF1600)],
|
|
152
151
|
]);
|
|
153
152
|
|
|
154
153
|
/**
|
|
@@ -158,30 +157,40 @@ export function encodeToBytecode(instructions: Serializable[]): Buffer {
|
|
|
158
157
|
return Buffer.concat(instructions.map(i => i.serialize()));
|
|
159
158
|
}
|
|
160
159
|
|
|
161
|
-
|
|
162
|
-
* Convert a buffer of bytecode into an array of instructions.
|
|
163
|
-
* @param bytecode Buffer of bytecode.
|
|
164
|
-
* @param instructionSet Optional {@code InstructionSet} to be used for deserialization.
|
|
165
|
-
* @returns Bytecode decoded into an ordered array of Instructions
|
|
166
|
-
*/
|
|
160
|
+
// For testing only
|
|
167
161
|
export function decodeFromBytecode(
|
|
168
162
|
bytecode: Buffer,
|
|
169
163
|
instructionSet: InstructionSet = INSTRUCTION_SET(),
|
|
170
164
|
): Instruction[] {
|
|
171
165
|
const instructions: Instruction[] = [];
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (instructionDeserializerOrUndef === undefined) {
|
|
178
|
-
throw new Error(`Opcode ${Opcode[opcode]} (0x${opcode.toString(16)}) not implemented`);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const instructionDeserializer: InstructionDeserializer = instructionDeserializerOrUndef;
|
|
182
|
-
const i: Instruction = instructionDeserializer(cursor);
|
|
183
|
-
instructions.push(i);
|
|
166
|
+
let pc = 0;
|
|
167
|
+
while (pc < bytecode.length) {
|
|
168
|
+
const [instruction, bytesConsumed] = decodeInstructionFromBytecode(bytecode, pc, instructionSet);
|
|
169
|
+
instructions.push(instruction);
|
|
170
|
+
pc += bytesConsumed;
|
|
184
171
|
}
|
|
185
|
-
|
|
186
172
|
return instructions;
|
|
187
173
|
}
|
|
174
|
+
|
|
175
|
+
// Returns the instruction and the number of bytes consumed.
|
|
176
|
+
export function decodeInstructionFromBytecode(
|
|
177
|
+
bytecode: Buffer,
|
|
178
|
+
pc: number,
|
|
179
|
+
instructionSet: InstructionSet = INSTRUCTION_SET(),
|
|
180
|
+
): [Instruction, number] {
|
|
181
|
+
if (pc >= bytecode.length) {
|
|
182
|
+
throw new Error(`pc ${pc} is out of bounds for bytecode of length ${bytecode.length}`);
|
|
183
|
+
}
|
|
184
|
+
const cursor = new BufferCursor(bytecode, pc);
|
|
185
|
+
const startingPosition = cursor.position();
|
|
186
|
+
const opcode: Opcode = cursor.bufferAtPosition().readUint8(); // peek.
|
|
187
|
+
|
|
188
|
+
const instructionDeserializerOrUndef = instructionSet.get(opcode);
|
|
189
|
+
if (instructionDeserializerOrUndef === undefined) {
|
|
190
|
+
throw new Error(`Opcode ${Opcode[opcode]} (0x${opcode.toString(16)}) not implemented`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const instructionDeserializer: InstructionDeserializer = instructionDeserializerOrUndef;
|
|
194
|
+
const instruction = instructionDeserializer(cursor);
|
|
195
|
+
return [instruction, cursor.position() - startingPosition];
|
|
196
|
+
}
|