@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
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AvmContext } from '../avm_context.js';
|
|
2
|
+
import { Field, type MemoryValue } from '../avm_memory_types.js';
|
|
3
|
+
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
4
|
+
import { GetterInstruction } from './instruction_impl.js';
|
|
5
|
+
|
|
6
|
+
export class L2GasLeft extends GetterInstruction {
|
|
7
|
+
static type: string = 'L2GASLEFT';
|
|
8
|
+
static readonly opcode: Opcode = Opcode.L2GASLEFT;
|
|
9
|
+
|
|
10
|
+
// TODO(@spalladino) Yellow paper specifies that the value should be an Uint32, not a Field.
|
|
11
|
+
protected getValue(context: AvmContext): MemoryValue {
|
|
12
|
+
return new Field(context.machineState.l2GasLeft);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class L1GasLeft extends GetterInstruction {
|
|
17
|
+
static type: string = 'L1GASLEFT';
|
|
18
|
+
static readonly opcode: Opcode = Opcode.L1GASLEFT;
|
|
19
|
+
|
|
20
|
+
protected getValue(context: AvmContext): MemoryValue {
|
|
21
|
+
return new Field(context.machineState.l1GasLeft);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class DAGasLeft extends GetterInstruction {
|
|
26
|
+
static type: string = 'DAGASLEFT';
|
|
27
|
+
static readonly opcode: Opcode = Opcode.DAGASLEFT;
|
|
28
|
+
|
|
29
|
+
protected getValue(context: AvmContext): MemoryValue {
|
|
30
|
+
return new Field(context.machineState.daGasLeft);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { AztecAddress, Fr } from '@aztec/circuits.js';
|
|
2
|
+
|
|
3
|
+
import type { AvmContext } from '../avm_context.js';
|
|
4
|
+
import { Field } from '../avm_memory_types.js';
|
|
5
|
+
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
6
|
+
import { Addressing } from './addressing_mode.js';
|
|
7
|
+
import { Instruction } from './instruction.js';
|
|
8
|
+
|
|
9
|
+
export class GetContractInstance extends Instruction {
|
|
10
|
+
static readonly type: string = 'GETCONTRACTINSTANCE';
|
|
11
|
+
static readonly opcode: Opcode = Opcode.GETCONTRACTINSTANCE;
|
|
12
|
+
// Informs (de)serialization. See Instruction.deserialize.
|
|
13
|
+
static readonly wireFormat: OperandType[] = [
|
|
14
|
+
OperandType.UINT8,
|
|
15
|
+
OperandType.UINT8,
|
|
16
|
+
OperandType.UINT32,
|
|
17
|
+
OperandType.UINT32,
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
constructor(private indirect: number, private addressOffset: number, private dstOffset: number) {
|
|
21
|
+
super();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async execute(context: AvmContext): Promise<void> {
|
|
25
|
+
const [addressOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
26
|
+
[this.addressOffset, this.dstOffset],
|
|
27
|
+
context.machineState.memory,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const address = AztecAddress.fromField(context.machineState.memory.get(addressOffset).toFr());
|
|
31
|
+
const instance = await context.persistableState.hostStorage.contractsDb.getContractInstance(address);
|
|
32
|
+
|
|
33
|
+
const data =
|
|
34
|
+
instance === undefined
|
|
35
|
+
? [
|
|
36
|
+
new Field(0), // not found
|
|
37
|
+
new Field(0),
|
|
38
|
+
new Field(0),
|
|
39
|
+
new Field(0),
|
|
40
|
+
new Field(0),
|
|
41
|
+
new Field(0),
|
|
42
|
+
new Field(0),
|
|
43
|
+
]
|
|
44
|
+
: [
|
|
45
|
+
new Fr(1), // found
|
|
46
|
+
instance.salt,
|
|
47
|
+
instance.deployer.toField(),
|
|
48
|
+
instance.contractClassId,
|
|
49
|
+
instance.initializationHash,
|
|
50
|
+
instance.portalContractAddress.toField(),
|
|
51
|
+
instance.publicKeysHash,
|
|
52
|
+
].map(f => new Field(f));
|
|
53
|
+
|
|
54
|
+
context.machineState.memory.setSlice(dstOffset, data);
|
|
55
|
+
|
|
56
|
+
context.machineState.incrementPc();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -14,8 +14,12 @@ export class Jump extends Instruction {
|
|
|
14
14
|
super();
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
async execute(context: AvmContext): Promise<void> {
|
|
17
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
18
|
+
context.machineState.consumeGas(this.gasCost());
|
|
19
|
+
|
|
18
20
|
context.machineState.pc = this.jumpOffset;
|
|
21
|
+
|
|
22
|
+
context.machineState.memory.assert({});
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
25
|
|
|
@@ -35,8 +39,12 @@ export class JumpI extends Instruction {
|
|
|
35
39
|
super();
|
|
36
40
|
}
|
|
37
41
|
|
|
38
|
-
async execute(context: AvmContext): Promise<void> {
|
|
39
|
-
const
|
|
42
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
43
|
+
const memoryOperations = { reads: 1, indirect: this.indirect };
|
|
44
|
+
const memory = context.machineState.memory.track(this.type);
|
|
45
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
46
|
+
|
|
47
|
+
const condition = memory.getAs<IntegralValue>(this.condOffset);
|
|
40
48
|
|
|
41
49
|
// TODO: reconsider this casting
|
|
42
50
|
if (condition.toBigInt() == 0n) {
|
|
@@ -44,6 +52,8 @@ export class JumpI extends Instruction {
|
|
|
44
52
|
} else {
|
|
45
53
|
context.machineState.pc = this.loc;
|
|
46
54
|
}
|
|
55
|
+
|
|
56
|
+
memory.assert(memoryOperations);
|
|
47
57
|
}
|
|
48
58
|
}
|
|
49
59
|
|
|
@@ -57,9 +67,13 @@ export class InternalCall extends Instruction {
|
|
|
57
67
|
super();
|
|
58
68
|
}
|
|
59
69
|
|
|
60
|
-
async execute(context: AvmContext): Promise<void> {
|
|
70
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
71
|
+
context.machineState.consumeGas(this.gasCost());
|
|
72
|
+
|
|
61
73
|
context.machineState.internalCallStack.push(context.machineState.pc + 1);
|
|
62
74
|
context.machineState.pc = this.loc;
|
|
75
|
+
|
|
76
|
+
context.machineState.memory.assert({});
|
|
63
77
|
}
|
|
64
78
|
}
|
|
65
79
|
|
|
@@ -73,11 +87,15 @@ export class InternalReturn extends Instruction {
|
|
|
73
87
|
super();
|
|
74
88
|
}
|
|
75
89
|
|
|
76
|
-
async execute(context: AvmContext): Promise<void> {
|
|
90
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
91
|
+
context.machineState.consumeGas(this.gasCost());
|
|
92
|
+
|
|
77
93
|
const jumpOffset = context.machineState.internalCallStack.pop();
|
|
78
94
|
if (jumpOffset === undefined) {
|
|
79
95
|
throw new InstructionExecutionError('Internal call stack empty!');
|
|
80
96
|
}
|
|
81
97
|
context.machineState.pc = jumpOffset;
|
|
98
|
+
|
|
99
|
+
context.machineState.memory.assert({});
|
|
82
100
|
}
|
|
83
101
|
}
|
|
@@ -2,136 +2,127 @@ import { type Fr } from '@aztec/circuits.js';
|
|
|
2
2
|
|
|
3
3
|
import type { AvmContext } from '../avm_context.js';
|
|
4
4
|
import type { AvmExecutionEnvironment } from '../avm_execution_environment.js';
|
|
5
|
-
import { Field } from '../avm_memory_types.js';
|
|
6
|
-
import { Opcode
|
|
7
|
-
import {
|
|
5
|
+
import { Field, type MemoryValue } from '../avm_memory_types.js';
|
|
6
|
+
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
7
|
+
import { GetterInstruction } from './instruction_impl.js';
|
|
8
8
|
|
|
9
|
-
abstract class
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
constructor(protected indirect: number, protected dstOffset: number) {
|
|
14
|
-
super();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async execute(context: AvmContext): Promise<void> {
|
|
18
|
-
const res = new Field(this.getIt(context.environment));
|
|
19
|
-
context.machineState.memory.set(this.dstOffset, res);
|
|
20
|
-
context.machineState.incrementPc();
|
|
9
|
+
abstract class EnvironmentGetterInstruction extends GetterInstruction {
|
|
10
|
+
protected getValue(context: AvmContext): MemoryValue {
|
|
11
|
+
return new Field(this.getEnvironmentValue(context.environment));
|
|
21
12
|
}
|
|
22
13
|
|
|
23
|
-
protected abstract
|
|
14
|
+
protected abstract getEnvironmentValue(env: AvmExecutionEnvironment): Fr | number | bigint;
|
|
24
15
|
}
|
|
25
16
|
|
|
26
|
-
export class Address extends
|
|
17
|
+
export class Address extends EnvironmentGetterInstruction {
|
|
27
18
|
static type: string = 'ADDRESS';
|
|
28
19
|
static readonly opcode: Opcode = Opcode.ADDRESS;
|
|
29
20
|
|
|
30
|
-
protected
|
|
21
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
31
22
|
return env.address;
|
|
32
23
|
}
|
|
33
24
|
}
|
|
34
25
|
|
|
35
|
-
export class StorageAddress extends
|
|
26
|
+
export class StorageAddress extends EnvironmentGetterInstruction {
|
|
36
27
|
static type: string = 'STORAGEADDRESS';
|
|
37
28
|
static readonly opcode: Opcode = Opcode.STORAGEADDRESS;
|
|
38
29
|
|
|
39
|
-
protected
|
|
30
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
40
31
|
return env.storageAddress;
|
|
41
32
|
}
|
|
42
33
|
}
|
|
43
34
|
|
|
44
|
-
export class Sender extends
|
|
35
|
+
export class Sender extends EnvironmentGetterInstruction {
|
|
45
36
|
static type: string = 'SENDER';
|
|
46
37
|
static readonly opcode: Opcode = Opcode.SENDER;
|
|
47
38
|
|
|
48
|
-
protected
|
|
39
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
49
40
|
return env.sender;
|
|
50
41
|
}
|
|
51
42
|
}
|
|
52
43
|
|
|
53
|
-
export class Origin extends
|
|
44
|
+
export class Origin extends EnvironmentGetterInstruction {
|
|
54
45
|
static type: string = 'ORIGIN';
|
|
55
46
|
static readonly opcode: Opcode = Opcode.ORIGIN;
|
|
56
47
|
|
|
57
|
-
protected
|
|
48
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
58
49
|
return env.origin;
|
|
59
50
|
}
|
|
60
51
|
}
|
|
61
52
|
|
|
62
|
-
export class FeePerL1Gas extends
|
|
53
|
+
export class FeePerL1Gas extends EnvironmentGetterInstruction {
|
|
63
54
|
static type: string = 'FEEPERL1GAS';
|
|
64
55
|
static readonly opcode: Opcode = Opcode.FEEPERL1GAS;
|
|
65
56
|
|
|
66
|
-
protected
|
|
57
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
67
58
|
return env.feePerL1Gas;
|
|
68
59
|
}
|
|
69
60
|
}
|
|
70
61
|
|
|
71
|
-
export class FeePerL2Gas extends
|
|
62
|
+
export class FeePerL2Gas extends EnvironmentGetterInstruction {
|
|
72
63
|
static type: string = 'FEEPERL2GAS';
|
|
73
64
|
static readonly opcode: Opcode = Opcode.FEEPERL2GAS;
|
|
74
65
|
|
|
75
|
-
protected
|
|
66
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
76
67
|
return env.feePerL2Gas;
|
|
77
68
|
}
|
|
78
69
|
}
|
|
79
70
|
|
|
80
|
-
export class FeePerDAGas extends
|
|
71
|
+
export class FeePerDAGas extends EnvironmentGetterInstruction {
|
|
81
72
|
static type: string = 'FEEPERDAGAS';
|
|
82
73
|
static readonly opcode: Opcode = Opcode.FEEPERDAGAS;
|
|
83
74
|
|
|
84
|
-
protected
|
|
75
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
85
76
|
return env.feePerDaGas;
|
|
86
77
|
}
|
|
87
78
|
}
|
|
88
79
|
|
|
89
|
-
export class Portal extends
|
|
80
|
+
export class Portal extends EnvironmentGetterInstruction {
|
|
90
81
|
static type: string = 'PORTAL';
|
|
91
82
|
static readonly opcode: Opcode = Opcode.PORTAL;
|
|
92
83
|
|
|
93
|
-
protected
|
|
84
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
94
85
|
return env.portal.toField();
|
|
95
86
|
}
|
|
96
87
|
}
|
|
97
88
|
|
|
98
|
-
export class ChainId extends
|
|
89
|
+
export class ChainId extends EnvironmentGetterInstruction {
|
|
99
90
|
static type: string = 'CHAINID';
|
|
100
91
|
static readonly opcode: Opcode = Opcode.CHAINID;
|
|
101
92
|
|
|
102
|
-
protected
|
|
93
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
103
94
|
return env.globals.chainId;
|
|
104
95
|
}
|
|
105
96
|
}
|
|
106
97
|
|
|
107
|
-
export class Version extends
|
|
98
|
+
export class Version extends EnvironmentGetterInstruction {
|
|
108
99
|
static type: string = 'VERSION';
|
|
109
100
|
static readonly opcode: Opcode = Opcode.VERSION;
|
|
110
101
|
|
|
111
|
-
protected
|
|
102
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
112
103
|
return env.globals.version;
|
|
113
104
|
}
|
|
114
105
|
}
|
|
115
106
|
|
|
116
|
-
export class BlockNumber extends
|
|
107
|
+
export class BlockNumber extends EnvironmentGetterInstruction {
|
|
117
108
|
static type: string = 'BLOCKNUMBER';
|
|
118
109
|
static readonly opcode: Opcode = Opcode.BLOCKNUMBER;
|
|
119
110
|
|
|
120
|
-
protected
|
|
111
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
121
112
|
return env.globals.blockNumber;
|
|
122
113
|
}
|
|
123
114
|
}
|
|
124
115
|
|
|
125
|
-
export class Timestamp extends
|
|
116
|
+
export class Timestamp extends EnvironmentGetterInstruction {
|
|
126
117
|
static type: string = 'TIMESTAMP';
|
|
127
118
|
static readonly opcode: Opcode = Opcode.TIMESTAMP;
|
|
128
119
|
|
|
129
|
-
protected
|
|
120
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
130
121
|
return env.globals.timestamp;
|
|
131
122
|
}
|
|
132
123
|
}
|
|
133
124
|
|
|
134
|
-
// export class Coinbase extends
|
|
125
|
+
// export class Coinbase extends EnvironmentGetterInstruction {
|
|
135
126
|
// static type: string = 'COINBASE';
|
|
136
127
|
// static numberOfOperands = 1;
|
|
137
128
|
|
|
@@ -149,7 +140,7 @@ export class Timestamp extends GetterInstruction {
|
|
|
149
140
|
// }
|
|
150
141
|
|
|
151
142
|
// // TODO: are these even needed within the block? (both block gas limit variables - why does the execution env care?)
|
|
152
|
-
// export class BlockL1GasLimit extends
|
|
143
|
+
// export class BlockL1GasLimit extends EnvironmentGetterInstruction {
|
|
153
144
|
// static type: string = 'BLOCKL1GASLIMIT';
|
|
154
145
|
// static numberOfOperands = 1;
|
|
155
146
|
|
|
@@ -166,7 +157,7 @@ export class Timestamp extends GetterInstruction {
|
|
|
166
157
|
// }
|
|
167
158
|
// }
|
|
168
159
|
|
|
169
|
-
// export class BlockL2GasLimit extends
|
|
160
|
+
// export class BlockL2GasLimit extends EnvironmentGetterInstruction {
|
|
170
161
|
// static type: string = 'BLOCKL2GASLIMIT';
|
|
171
162
|
// static numberOfOperands = 1;
|
|
172
163
|
|
|
@@ -183,7 +174,7 @@ export class Timestamp extends GetterInstruction {
|
|
|
183
174
|
// }
|
|
184
175
|
// }
|
|
185
176
|
|
|
186
|
-
// export class BlockDAGasLimit extends
|
|
177
|
+
// export class BlockDAGasLimit extends EnvironmentGetterInstruction {
|
|
187
178
|
// static type: string = 'BLOCKDAGASLIMIT';
|
|
188
179
|
// static numberOfOperands = 1;
|
|
189
180
|
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { FunctionSelector } from '@aztec/circuits.js';
|
|
2
|
-
|
|
2
|
+
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
3
|
+
|
|
4
|
+
import { executePublicFunction } from '../../public/executor.js';
|
|
5
|
+
import {
|
|
6
|
+
convertPublicExecutionResult,
|
|
7
|
+
createPublicExecutionContext,
|
|
8
|
+
updateAvmContextFromPublicExecutionResult,
|
|
9
|
+
} from '../../public/transitional_adaptors.js';
|
|
3
10
|
import type { AvmContext } from '../avm_context.js';
|
|
11
|
+
import { gasLeftToGas, sumGas } from '../avm_gas.js';
|
|
4
12
|
import { Field, Uint8 } from '../avm_memory_types.js';
|
|
5
|
-
import {
|
|
13
|
+
import { type AvmContractCallResults } from '../avm_message_call_result.js';
|
|
6
14
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
7
15
|
import { Addressing } from './addressing_mode.js';
|
|
8
16
|
import { Instruction } from './instruction.js';
|
|
9
17
|
|
|
10
|
-
|
|
11
|
-
static type: string = 'CALL';
|
|
12
|
-
static readonly opcode: Opcode = Opcode.CALL;
|
|
18
|
+
abstract class ExternalCall extends Instruction {
|
|
13
19
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
14
20
|
static readonly wireFormat: OperandType[] = [
|
|
15
21
|
OperandType.UINT8,
|
|
@@ -27,7 +33,7 @@ export class Call extends Instruction {
|
|
|
27
33
|
|
|
28
34
|
constructor(
|
|
29
35
|
private indirect: number,
|
|
30
|
-
private
|
|
36
|
+
private gasOffset: number /* Unused due to no formal gas implementation at this moment */,
|
|
31
37
|
private addrOffset: number,
|
|
32
38
|
private argsOffset: number,
|
|
33
39
|
private argsSize: number,
|
|
@@ -42,110 +48,95 @@ export class Call extends Instruction {
|
|
|
42
48
|
super();
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const [
|
|
48
|
-
[this.
|
|
49
|
-
|
|
51
|
+
public async execute(context: AvmContext) {
|
|
52
|
+
const memory = context.machineState.memory.track(this.type);
|
|
53
|
+
const [gasOffset, addrOffset, argsOffset, retOffset, successOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
54
|
+
[this.gasOffset, this.addrOffset, this.argsOffset, this.retOffset, this.successOffset],
|
|
55
|
+
memory,
|
|
50
56
|
);
|
|
51
57
|
|
|
52
|
-
const callAddress =
|
|
53
|
-
const calldata =
|
|
54
|
-
const
|
|
58
|
+
const callAddress = memory.getAs<Field>(addrOffset);
|
|
59
|
+
const calldata = memory.getSlice(argsOffset, this.argsSize).map(f => f.toFr());
|
|
60
|
+
const l1Gas = memory.get(gasOffset).toNumber();
|
|
61
|
+
const l2Gas = memory.getAs<Field>(gasOffset + 1).toNumber();
|
|
62
|
+
const daGas = memory.getAs<Field>(gasOffset + 2).toNumber();
|
|
63
|
+
const functionSelector = memory.getAs<Field>(this.temporaryFunctionSelectorOffset).toFr();
|
|
55
64
|
|
|
65
|
+
const allocatedGas = { l1Gas, l2Gas, daGas };
|
|
66
|
+
const memoryOperations = { reads: this.argsSize + 5, writes: 1 + this.retSize, indirect: this.indirect };
|
|
67
|
+
const totalGas = sumGas(this.gasCost(memoryOperations), allocatedGas);
|
|
68
|
+
context.machineState.consumeGas(totalGas);
|
|
69
|
+
|
|
70
|
+
// TRANSITIONAL: This should be removed once the AVM is fully operational and the public executor is gone.
|
|
56
71
|
const nestedContext = context.createNestedContractCallContext(
|
|
57
72
|
callAddress.toFr(),
|
|
58
73
|
calldata,
|
|
74
|
+
allocatedGas,
|
|
75
|
+
this.type,
|
|
59
76
|
FunctionSelector.fromField(functionSelector),
|
|
60
77
|
);
|
|
78
|
+
const pxContext = createPublicExecutionContext(nestedContext, calldata);
|
|
79
|
+
const pxResults = await executePublicFunction(pxContext, /*nested=*/ true);
|
|
80
|
+
const nestedCallResults: AvmContractCallResults = convertPublicExecutionResult(pxResults);
|
|
81
|
+
updateAvmContextFromPublicExecutionResult(nestedContext, pxResults);
|
|
82
|
+
const nestedPersistableState = nestedContext.persistableState;
|
|
83
|
+
// const nestedContext = context.createNestedContractCallContext(
|
|
84
|
+
// callAddress.toFr(),
|
|
85
|
+
// calldata,
|
|
86
|
+
// allocatedGas,
|
|
87
|
+
// this.type,
|
|
88
|
+
// FunctionSelector.fromField(functionSelector),
|
|
89
|
+
// );
|
|
90
|
+
// const nestedCallResults: AvmContractCallResults = await new AvmSimulator(nestedContext).execute();
|
|
91
|
+
// const nestedPersistableState = nestedContext.persistableState;
|
|
61
92
|
|
|
62
|
-
const nestedCallResults = await new AvmSimulator(nestedContext).execute();
|
|
63
93
|
const success = !nestedCallResults.reverted;
|
|
64
94
|
|
|
65
|
-
// We only take as much data as was specified in the return size
|
|
95
|
+
// We only take as much data as was specified in the return size and pad with zeroes if the return data is smaller
|
|
96
|
+
// than the specified size in order to prevent that memory to be left with garbage
|
|
66
97
|
const returnData = nestedCallResults.output.slice(0, this.retSize);
|
|
67
|
-
const convertedReturnData =
|
|
98
|
+
const convertedReturnData = padArrayEnd(
|
|
99
|
+
returnData.map(f => new Field(f)),
|
|
100
|
+
new Field(0),
|
|
101
|
+
this.retSize,
|
|
102
|
+
);
|
|
68
103
|
|
|
69
104
|
// Write our return data into memory
|
|
70
|
-
|
|
71
|
-
|
|
105
|
+
memory.set(successOffset, new Uint8(success ? 1 : 0));
|
|
106
|
+
memory.setSlice(retOffset, convertedReturnData);
|
|
72
107
|
|
|
108
|
+
// Refund unused gas
|
|
109
|
+
context.machineState.refundGas(gasLeftToGas(nestedContext.machineState));
|
|
110
|
+
|
|
111
|
+
// TODO: Should we merge the changes from a nested call in the case of a STATIC call?
|
|
73
112
|
if (success) {
|
|
74
|
-
context.persistableState.acceptNestedCallState(
|
|
113
|
+
context.persistableState.acceptNestedCallState(nestedPersistableState);
|
|
75
114
|
} else {
|
|
76
|
-
context.persistableState.rejectNestedCallState(
|
|
115
|
+
context.persistableState.rejectNestedCallState(nestedPersistableState);
|
|
77
116
|
}
|
|
78
117
|
|
|
118
|
+
memory.assert(memoryOperations);
|
|
79
119
|
context.machineState.incrementPc();
|
|
80
120
|
}
|
|
121
|
+
|
|
122
|
+
public abstract get type(): 'CALL' | 'STATICCALL';
|
|
81
123
|
}
|
|
82
124
|
|
|
83
|
-
export class
|
|
84
|
-
static type
|
|
85
|
-
static readonly opcode: Opcode = Opcode.
|
|
86
|
-
// Informs (de)serialization. See Instruction.deserialize.
|
|
87
|
-
static readonly wireFormat: OperandType[] = [
|
|
88
|
-
OperandType.UINT8,
|
|
89
|
-
OperandType.UINT8,
|
|
90
|
-
OperandType.UINT32,
|
|
91
|
-
OperandType.UINT32,
|
|
92
|
-
OperandType.UINT32,
|
|
93
|
-
OperandType.UINT32,
|
|
94
|
-
OperandType.UINT32,
|
|
95
|
-
OperandType.UINT32,
|
|
96
|
-
OperandType.UINT32,
|
|
97
|
-
/* temporary function selector */
|
|
98
|
-
OperandType.UINT32,
|
|
99
|
-
];
|
|
125
|
+
export class Call extends ExternalCall {
|
|
126
|
+
static type = 'CALL' as const;
|
|
127
|
+
static readonly opcode: Opcode = Opcode.CALL;
|
|
100
128
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
private _gasOffset: number /* Unused due to no formal gas implementation at this moment */,
|
|
104
|
-
private addrOffset: number,
|
|
105
|
-
private argsOffset: number,
|
|
106
|
-
private argsSize: number,
|
|
107
|
-
private retOffset: number,
|
|
108
|
-
private retSize: number,
|
|
109
|
-
private successOffset: number,
|
|
110
|
-
private temporaryFunctionSelectorOffset: number,
|
|
111
|
-
) {
|
|
112
|
-
super();
|
|
129
|
+
public get type() {
|
|
130
|
+
return Call.type;
|
|
113
131
|
}
|
|
132
|
+
}
|
|
114
133
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
context.machineState.memory,
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
const callAddress = context.machineState.memory.get(addrOffset);
|
|
122
|
-
const calldata = context.machineState.memory.getSlice(argsOffset, this.argsSize).map(f => f.toFr());
|
|
123
|
-
const functionSelector = context.machineState.memory.getAs<Field>(this.temporaryFunctionSelectorOffset).toFr();
|
|
124
|
-
|
|
125
|
-
const nestedContext = context.createNestedContractStaticCallContext(
|
|
126
|
-
callAddress.toFr(),
|
|
127
|
-
calldata,
|
|
128
|
-
FunctionSelector.fromField(functionSelector),
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
const nestedCallResults = await new AvmSimulator(nestedContext).execute();
|
|
132
|
-
const success = !nestedCallResults.reverted;
|
|
133
|
-
|
|
134
|
-
// We only take as much data as was specified in the return size -> TODO: should we be reverting here
|
|
135
|
-
const returnData = nestedCallResults.output.slice(0, this.retSize);
|
|
136
|
-
const convertedReturnData = returnData.map(f => new Field(f));
|
|
137
|
-
|
|
138
|
-
// Write our return data into memory
|
|
139
|
-
context.machineState.memory.set(successOffset, new Uint8(success ? 1 : 0));
|
|
140
|
-
context.machineState.memory.setSlice(retOffset, convertedReturnData);
|
|
141
|
-
|
|
142
|
-
if (success) {
|
|
143
|
-
context.persistableState.acceptNestedCallState(nestedContext.persistableState);
|
|
144
|
-
} else {
|
|
145
|
-
context.persistableState.rejectNestedCallState(nestedContext.persistableState);
|
|
146
|
-
}
|
|
134
|
+
export class StaticCall extends ExternalCall {
|
|
135
|
+
static type = 'STATICCALL' as const;
|
|
136
|
+
static readonly opcode: Opcode = Opcode.STATICCALL;
|
|
147
137
|
|
|
148
|
-
|
|
138
|
+
public get type() {
|
|
139
|
+
return StaticCall.type;
|
|
149
140
|
}
|
|
150
141
|
}
|
|
151
142
|
|
|
@@ -164,12 +155,17 @@ export class Return extends Instruction {
|
|
|
164
155
|
super();
|
|
165
156
|
}
|
|
166
157
|
|
|
167
|
-
async execute(context: AvmContext): Promise<void> {
|
|
168
|
-
const
|
|
158
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
159
|
+
const memoryOperations = { reads: this.copySize, indirect: this.indirect };
|
|
160
|
+
const memory = context.machineState.memory.track(this.type);
|
|
161
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
162
|
+
|
|
163
|
+
const [returnOffset] = Addressing.fromWire(this.indirect).resolve([this.returnOffset], memory);
|
|
169
164
|
|
|
170
|
-
const output =
|
|
165
|
+
const output = memory.getSlice(returnOffset, this.copySize).map(word => word.toFr());
|
|
171
166
|
|
|
172
167
|
context.machineState.return(output);
|
|
168
|
+
memory.assert(memoryOperations);
|
|
173
169
|
}
|
|
174
170
|
}
|
|
175
171
|
|
|
@@ -188,11 +184,16 @@ export class Revert extends Instruction {
|
|
|
188
184
|
super();
|
|
189
185
|
}
|
|
190
186
|
|
|
191
|
-
async execute(context: AvmContext): Promise<void> {
|
|
192
|
-
const
|
|
187
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
188
|
+
const memoryOperations = { reads: this.retSize, indirect: this.indirect };
|
|
189
|
+
const memory = context.machineState.memory.track(this.type);
|
|
190
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
191
|
+
|
|
192
|
+
const [returnOffset] = Addressing.fromWire(this.indirect).resolve([this.returnOffset], memory);
|
|
193
193
|
|
|
194
|
-
const output =
|
|
194
|
+
const output = memory.getSlice(returnOffset, this.retSize).map(word => word.toFr());
|
|
195
195
|
|
|
196
196
|
context.machineState.revert(output);
|
|
197
|
+
memory.assert(memoryOperations);
|
|
197
198
|
}
|
|
198
199
|
}
|