@aztec/simulator 0.52.0 → 0.54.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/acvm.d.ts +7 -0
- package/dest/acvm/acvm.d.ts.map +1 -1
- package/dest/acvm/acvm.js +17 -1
- package/dest/avm/avm_execution_environment.d.ts +2 -2
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +5 -6
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +73 -43
- package/dest/avm/avm_memory_types.d.ts +1 -1
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +5 -3
- package/dest/avm/bytecode_utils.js +5 -5
- package/dest/avm/errors.js +2 -2
- package/dest/avm/fixtures/index.d.ts +2 -0
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +18 -2
- package/dest/avm/journal/journal.d.ts +1 -1
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +13 -8
- package/dest/avm/opcodes/arithmetic.d.ts +9 -16
- package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/avm/opcodes/arithmetic.js +12 -37
- package/dest/avm/opcodes/bitwise.d.ts +5 -5
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +6 -6
- package/dest/avm/opcodes/comparators.d.ts +3 -3
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +4 -4
- package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/avm/opcodes/control_flow.js +6 -6
- package/dest/avm/opcodes/instruction.d.ts +18 -12
- package/dest/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction.js +36 -19
- package/dest/avm/opcodes/instruction_impl.d.ts +4 -2
- package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction_impl.js +15 -7
- package/dest/avm/opcodes/memory.d.ts +11 -12
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +68 -68
- package/dest/avm/serialization/bytecode_serialization.d.ts +7 -8
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +83 -67
- package/dest/avm/serialization/instruction_serialization.d.ts +84 -68
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +102 -71
- package/dest/avm/test_utils.d.ts +1 -1
- package/dest/avm/test_utils.d.ts.map +1 -1
- package/dest/avm/test_utils.js +11 -3
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +4 -4
- package/dest/public/db_interfaces.d.ts +6 -0
- package/dest/public/db_interfaces.d.ts.map +1 -1
- package/dest/public/execution.d.ts +3 -3
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -1
- package/dest/public/hints_builder.d.ts +6 -4
- package/dest/public/hints_builder.d.ts.map +1 -1
- package/dest/public/hints_builder.js +20 -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 +11 -1
- 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 +10 -12
- package/dest/public/tail_phase_manager.d.ts.map +1 -1
- package/dest/public/tail_phase_manager.js +4 -3
- package/package.json +9 -9
- package/src/acvm/acvm.ts +22 -0
- package/src/avm/avm_execution_environment.ts +3 -4
- package/src/avm/avm_gas.ts +72 -42
- package/src/avm/avm_memory_types.ts +4 -2
- package/src/avm/bytecode_utils.ts +4 -4
- package/src/avm/errors.ts +1 -1
- package/src/avm/fixtures/index.ts +32 -2
- package/src/avm/journal/journal.ts +14 -8
- package/src/avm/opcodes/arithmetic.ts +12 -41
- package/src/avm/opcodes/bitwise.ts +5 -5
- package/src/avm/opcodes/comparators.ts +3 -3
- package/src/avm/opcodes/control_flow.ts +5 -5
- package/src/avm/opcodes/instruction.ts +41 -19
- package/src/avm/opcodes/instruction_impl.ts +14 -6
- package/src/avm/opcodes/memory.ts +76 -74
- package/src/avm/serialization/bytecode_serialization.ts +93 -77
- package/src/avm/serialization/instruction_serialization.ts +58 -25
- package/src/avm/test_utils.ts +9 -2
- package/src/public/abstract_phase_manager.ts +3 -2
- package/src/public/db_interfaces.ts +7 -0
- package/src/public/execution.ts +3 -2
- package/src/public/hints_builder.ts +48 -13
- package/src/public/public_db_sources.ts +11 -0
- package/src/public/side_effect_trace.ts +11 -12
- package/src/public/tail_phase_manager.ts +10 -7
|
@@ -1,39 +1,57 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
|
-
import { Field, TaggedMemory
|
|
3
|
-
import {
|
|
4
|
-
import { BufferCursor } from '../serialization/buffer_cursor.js';
|
|
5
|
-
import { Opcode, OperandType, deserialize, serialize } from '../serialization/instruction_serialization.js';
|
|
2
|
+
import { Field, TaggedMemory } from '../avm_memory_types.js';
|
|
3
|
+
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
6
4
|
import { Addressing } from './addressing_mode.js';
|
|
7
5
|
import { Instruction } from './instruction.js';
|
|
8
6
|
import { TwoOperandInstruction } from './instruction_impl.js';
|
|
9
7
|
|
|
10
|
-
const TAG_TO_OPERAND_TYPE = new Map<TypeTag, OperandType>([
|
|
11
|
-
[TypeTag.UINT8, OperandType.UINT8],
|
|
12
|
-
[TypeTag.UINT16, OperandType.UINT16],
|
|
13
|
-
[TypeTag.UINT32, OperandType.UINT32],
|
|
14
|
-
[TypeTag.UINT64, OperandType.UINT64],
|
|
15
|
-
[TypeTag.UINT128, OperandType.UINT128],
|
|
16
|
-
]);
|
|
17
|
-
|
|
18
|
-
function getOperandTypeFromInTag(inTag: number | bigint): OperandType {
|
|
19
|
-
inTag = inTag as number;
|
|
20
|
-
const tagOperandType = TAG_TO_OPERAND_TYPE.get(inTag);
|
|
21
|
-
if (tagOperandType === undefined) {
|
|
22
|
-
throw new Error(`Invalid tag ${inTag} for SET.`);
|
|
23
|
-
}
|
|
24
|
-
return tagOperandType;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
8
|
export class Set extends Instruction {
|
|
28
9
|
static readonly type: string = 'SET';
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
OperandType.UINT8,
|
|
34
|
-
OperandType.UINT8,
|
|
10
|
+
// Required for gas.
|
|
11
|
+
static readonly opcode: Opcode = Opcode.SET_8;
|
|
12
|
+
|
|
13
|
+
public static readonly wireFormat8: OperandType[] = [
|
|
14
|
+
OperandType.UINT8, // opcode
|
|
15
|
+
OperandType.UINT8, // indirect
|
|
16
|
+
OperandType.UINT8, // tag
|
|
17
|
+
OperandType.UINT8, // const (value)
|
|
18
|
+
OperandType.UINT8, // dstOffset
|
|
19
|
+
];
|
|
20
|
+
public static readonly wireFormat16: OperandType[] = [
|
|
21
|
+
OperandType.UINT8, // opcode
|
|
22
|
+
OperandType.UINT8, // indirect
|
|
23
|
+
OperandType.UINT8, // tag
|
|
24
|
+
OperandType.UINT16, // const (value)
|
|
25
|
+
OperandType.UINT16, // dstOffset
|
|
26
|
+
];
|
|
27
|
+
public static readonly wireFormat32: OperandType[] = [
|
|
28
|
+
OperandType.UINT8, // opcode
|
|
29
|
+
OperandType.UINT8, // indirect
|
|
30
|
+
OperandType.UINT8, // tag
|
|
31
|
+
OperandType.UINT32, // const (value)
|
|
32
|
+
OperandType.UINT16, // dstOffset
|
|
33
|
+
];
|
|
34
|
+
public static readonly wireFormat64: OperandType[] = [
|
|
35
|
+
OperandType.UINT8, // opcode
|
|
36
|
+
OperandType.UINT8, // indirect
|
|
37
|
+
OperandType.UINT8, // tag
|
|
38
|
+
OperandType.UINT64, // const (value)
|
|
39
|
+
OperandType.UINT16, // dstOffset
|
|
40
|
+
];
|
|
41
|
+
public static readonly wireFormat128: OperandType[] = [
|
|
42
|
+
OperandType.UINT8, // opcode
|
|
43
|
+
OperandType.UINT8, // indirect
|
|
44
|
+
OperandType.UINT8, // tag
|
|
45
|
+
OperandType.UINT128, // const (value)
|
|
46
|
+
OperandType.UINT16, // dstOffset
|
|
47
|
+
];
|
|
48
|
+
public static readonly wireFormatFF: OperandType[] = [
|
|
49
|
+
OperandType.UINT8, // opcode
|
|
50
|
+
OperandType.UINT8, // indirect
|
|
51
|
+
OperandType.UINT8, // tag
|
|
52
|
+
OperandType.FF, // const (value)
|
|
53
|
+
OperandType.UINT16, // dstOffset
|
|
35
54
|
];
|
|
36
|
-
private static readonly wireFormatAfterConst: OperandType[] = [OperandType.UINT32];
|
|
37
55
|
|
|
38
56
|
constructor(
|
|
39
57
|
private indirect: number,
|
|
@@ -44,42 +62,13 @@ export class Set extends Instruction {
|
|
|
44
62
|
super();
|
|
45
63
|
}
|
|
46
64
|
|
|
47
|
-
/** We need to use a custom serialize function because of the variable length of the value. */
|
|
48
|
-
public override serialize(): Buffer {
|
|
49
|
-
const format: OperandType[] = [
|
|
50
|
-
...Set.wireFormatBeforeConst,
|
|
51
|
-
getOperandTypeFromInTag(this.inTag),
|
|
52
|
-
...Set.wireFormatAfterConst,
|
|
53
|
-
];
|
|
54
|
-
return serialize(format, this);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** We need to use a custom deserialize function because of the variable length of the value. */
|
|
58
|
-
public static override deserialize(this: typeof Set, buf: BufferCursor | Buffer): Set {
|
|
59
|
-
if (buf instanceof Buffer) {
|
|
60
|
-
buf = new BufferCursor(buf);
|
|
61
|
-
}
|
|
62
|
-
const beforeConst = deserialize(buf, Set.wireFormatBeforeConst);
|
|
63
|
-
const tag = beforeConst[beforeConst.length - 1];
|
|
64
|
-
const val = deserialize(buf, [getOperandTypeFromInTag(tag)]);
|
|
65
|
-
const afterConst = deserialize(buf, Set.wireFormatAfterConst);
|
|
66
|
-
const res = [...beforeConst, ...val, ...afterConst];
|
|
67
|
-
const args = res.slice(1) as ConstructorParameters<typeof Set>; // Remove opcode.
|
|
68
|
-
return new this(...args);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
65
|
public async execute(context: AvmContext): Promise<void> {
|
|
72
66
|
const memoryOperations = { writes: 1, indirect: this.indirect };
|
|
73
67
|
const memory = context.machineState.memory.track(this.type);
|
|
74
68
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
75
69
|
|
|
76
|
-
// Per the YP, the tag cannot be a field.
|
|
77
|
-
if ([TypeTag.FIELD, TypeTag.UNINITIALIZED, TypeTag.INVALID].includes(this.inTag)) {
|
|
78
|
-
throw new InstructionExecutionError(`Invalid tag ${TypeTag[this.inTag]} for SET.`);
|
|
79
|
-
}
|
|
80
70
|
const [dstOffset] = Addressing.fromWire(this.indirect).resolve([this.dstOffset], memory);
|
|
81
|
-
|
|
82
|
-
const res = TaggedMemory.integralFromTag(this.value, this.inTag);
|
|
71
|
+
const res = TaggedMemory.buildFromTagTruncating(this.value, this.inTag);
|
|
83
72
|
memory.set(dstOffset, res);
|
|
84
73
|
|
|
85
74
|
memory.assert(memoryOperations);
|
|
@@ -148,9 +137,7 @@ export class Cast extends TwoOperandInstruction {
|
|
|
148
137
|
const [srcOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.aOffset, this.dstOffset], memory);
|
|
149
138
|
|
|
150
139
|
const a = memory.get(srcOffset);
|
|
151
|
-
|
|
152
|
-
const casted =
|
|
153
|
-
this.inTag == TypeTag.FIELD ? new Field(a.toBigInt()) : TaggedMemory.integralFromTag(a.toBigInt(), this.inTag);
|
|
140
|
+
const casted = TaggedMemory.buildFromTagTruncating(a.toBigInt(), this.inTag);
|
|
154
141
|
|
|
155
142
|
memory.set(dstOffset, casted);
|
|
156
143
|
|
|
@@ -161,13 +148,20 @@ export class Cast extends TwoOperandInstruction {
|
|
|
161
148
|
|
|
162
149
|
export class Mov extends Instruction {
|
|
163
150
|
static readonly type: string = 'MOV';
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
151
|
+
// FIXME: This is needed for gas.
|
|
152
|
+
static readonly opcode: Opcode = Opcode.MOV_8;
|
|
153
|
+
|
|
154
|
+
static readonly wireFormat8: OperandType[] = [
|
|
167
155
|
OperandType.UINT8,
|
|
168
156
|
OperandType.UINT8,
|
|
169
|
-
OperandType.
|
|
170
|
-
OperandType.
|
|
157
|
+
OperandType.UINT8,
|
|
158
|
+
OperandType.UINT8,
|
|
159
|
+
];
|
|
160
|
+
static readonly wireFormat16: OperandType[] = [
|
|
161
|
+
OperandType.UINT8,
|
|
162
|
+
OperandType.UINT8,
|
|
163
|
+
OperandType.UINT16,
|
|
164
|
+
OperandType.UINT16,
|
|
171
165
|
];
|
|
172
166
|
|
|
173
167
|
constructor(private indirect: number, private srcOffset: number, private dstOffset: number) {
|
|
@@ -202,21 +196,29 @@ export class CalldataCopy extends Instruction {
|
|
|
202
196
|
OperandType.UINT32,
|
|
203
197
|
];
|
|
204
198
|
|
|
205
|
-
constructor(
|
|
199
|
+
constructor(
|
|
200
|
+
private indirect: number,
|
|
201
|
+
private cdStartOffset: number,
|
|
202
|
+
private copySizeOffset: number,
|
|
203
|
+
private dstOffset: number,
|
|
204
|
+
) {
|
|
206
205
|
super();
|
|
207
206
|
}
|
|
208
207
|
|
|
209
208
|
public async execute(context: AvmContext): Promise<void> {
|
|
210
|
-
const memoryOperations = { writes: this.copySize, indirect: this.indirect };
|
|
211
209
|
const memory = context.machineState.memory.track(this.type);
|
|
212
|
-
context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.copySize }));
|
|
213
|
-
|
|
214
210
|
// We don't need to check tags here because: (1) the calldata is NOT in memory, and (2) we are the ones writing to destination.
|
|
215
|
-
const [
|
|
211
|
+
const [cdStartOffset, copySizeOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
212
|
+
[this.cdStartOffset, this.copySizeOffset, this.dstOffset],
|
|
213
|
+
memory,
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
const cdStart = memory.get(cdStartOffset).toNumber();
|
|
217
|
+
const copySize = memory.get(copySizeOffset).toNumber();
|
|
218
|
+
const memoryOperations = { reads: 2, writes: copySize, indirect: this.indirect };
|
|
219
|
+
context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: copySize }));
|
|
216
220
|
|
|
217
|
-
const transformedData = context.environment.calldata
|
|
218
|
-
.slice(cdOffset, cdOffset + this.copySize)
|
|
219
|
-
.map(f => new Field(f));
|
|
221
|
+
const transformedData = context.environment.calldata.slice(cdStart, cdStart + copySize).map(f => new Field(f));
|
|
220
222
|
|
|
221
223
|
memory.setSlice(dstOffset, transformedData);
|
|
222
224
|
|
|
@@ -2,7 +2,7 @@ import { PedersenCommitment } from '../opcodes/commitment.js';
|
|
|
2
2
|
import { DAGasLeft, L2GasLeft } from '../opcodes/context_getters.js';
|
|
3
3
|
import { EcAdd } from '../opcodes/ec_add.js';
|
|
4
4
|
import { Keccak, KeccakF1600, Pedersen, Poseidon2, Sha256 } from '../opcodes/hashing.js';
|
|
5
|
-
import
|
|
5
|
+
import { Instruction } from '../opcodes/index.js';
|
|
6
6
|
import {
|
|
7
7
|
Add,
|
|
8
8
|
Address,
|
|
@@ -59,106 +59,122 @@ import { MultiScalarMul } from '../opcodes/multi_scalar_mul.js';
|
|
|
59
59
|
import { BufferCursor } from './buffer_cursor.js';
|
|
60
60
|
import { Opcode } from './instruction_serialization.js';
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
export type InstructionDeserializer = (buf: BufferCursor | Buffer) => Instruction;
|
|
63
|
+
|
|
64
|
+
export interface Serializable {
|
|
65
|
+
serialize(): Buffer;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface Deserializable {
|
|
69
|
+
deserialize: InstructionDeserializer;
|
|
65
70
|
}
|
|
66
71
|
|
|
67
|
-
export type InstructionSet = Map<Opcode,
|
|
72
|
+
export type InstructionSet = Map<Opcode, InstructionDeserializer>;
|
|
68
73
|
// TODO(4359): This is a function so that Call and StaticCall can be lazily resolved.
|
|
69
74
|
// This is a temporary solution until we solve the dependency cycle.
|
|
70
75
|
const INSTRUCTION_SET = () =>
|
|
71
|
-
new Map<Opcode,
|
|
72
|
-
[
|
|
73
|
-
[
|
|
74
|
-
[
|
|
75
|
-
[
|
|
76
|
-
[
|
|
77
|
-
[
|
|
78
|
-
[
|
|
79
|
-
[
|
|
80
|
-
[
|
|
81
|
-
[
|
|
82
|
-
[
|
|
83
|
-
[
|
|
84
|
-
[
|
|
85
|
-
[
|
|
86
|
-
[
|
|
87
|
-
[
|
|
88
|
-
[
|
|
89
|
-
[
|
|
90
|
-
[
|
|
91
|
-
[
|
|
76
|
+
new Map<Opcode, InstructionDeserializer>([
|
|
77
|
+
[Opcode.ADD_8, Add.as(Add.wireFormat8).deserialize],
|
|
78
|
+
[Opcode.ADD_16, Add.as(Add.wireFormat16).deserialize],
|
|
79
|
+
[Opcode.SUB_8, Sub.as(Sub.wireFormat8).deserialize],
|
|
80
|
+
[Opcode.SUB_16, Sub.as(Sub.wireFormat16).deserialize],
|
|
81
|
+
[Opcode.MUL_8, Mul.as(Mul.wireFormat8).deserialize],
|
|
82
|
+
[Opcode.MUL_16, Mul.as(Mul.wireFormat16).deserialize],
|
|
83
|
+
[Opcode.DIV_8, Div.as(Div.wireFormat8).deserialize],
|
|
84
|
+
[Opcode.DIV_16, Div.as(Div.wireFormat16).deserialize],
|
|
85
|
+
[Opcode.FDIV_8, FieldDiv.as(FieldDiv.wireFormat8).deserialize],
|
|
86
|
+
[Opcode.FDIV_16, FieldDiv.as(FieldDiv.wireFormat16).deserialize],
|
|
87
|
+
[Opcode.EQ_8, Eq.as(Eq.wireFormat8).deserialize],
|
|
88
|
+
[Opcode.EQ_16, Eq.as(Eq.wireFormat16).deserialize],
|
|
89
|
+
[Opcode.LT_8, Lt.as(Lt.wireFormat8).deserialize],
|
|
90
|
+
[Opcode.LT_16, Lt.as(Lt.wireFormat16).deserialize],
|
|
91
|
+
[Opcode.LTE_8, Lte.as(Lte.wireFormat8).deserialize],
|
|
92
|
+
[Opcode.LTE_16, Lte.as(Lte.wireFormat16).deserialize],
|
|
93
|
+
[Opcode.AND_8, And.as(And.wireFormat8).deserialize],
|
|
94
|
+
[Opcode.AND_16, And.as(And.wireFormat16).deserialize],
|
|
95
|
+
[Opcode.OR_8, Or.as(Or.wireFormat8).deserialize],
|
|
96
|
+
[Opcode.OR_16, Or.as(Or.wireFormat16).deserialize],
|
|
97
|
+
[Opcode.XOR_8, Xor.as(Xor.wireFormat8).deserialize],
|
|
98
|
+
[Opcode.XOR_16, Xor.as(Xor.wireFormat16).deserialize],
|
|
99
|
+
[Not.opcode, Instruction.deserialize.bind(Not)],
|
|
100
|
+
[Opcode.SHL_8, Shl.as(Shl.wireFormat8).deserialize],
|
|
101
|
+
[Opcode.SHL_16, Shl.as(Shl.wireFormat16).deserialize],
|
|
102
|
+
[Opcode.SHR_8, Shr.as(Shr.wireFormat8).deserialize],
|
|
103
|
+
[Opcode.SHR_16, Shr.as(Shr.wireFormat16).deserialize],
|
|
104
|
+
[Cast.opcode, Instruction.deserialize.bind(Cast)],
|
|
105
|
+
[Address.opcode, Instruction.deserialize.bind(Address)],
|
|
106
|
+
[StorageAddress.opcode, Instruction.deserialize.bind(StorageAddress)],
|
|
107
|
+
[Sender.opcode, Instruction.deserialize.bind(Sender)],
|
|
108
|
+
[FunctionSelector.opcode, Instruction.deserialize.bind(FunctionSelector)],
|
|
109
|
+
[TransactionFee.opcode, Instruction.deserialize.bind(TransactionFee)],
|
|
92
110
|
// Execution Environment - Globals
|
|
93
|
-
[ChainId.opcode, ChainId],
|
|
94
|
-
[Version.opcode, Version],
|
|
95
|
-
[BlockNumber.opcode, BlockNumber],
|
|
96
|
-
[Timestamp.opcode, Timestamp],
|
|
97
|
-
|
|
98
|
-
[
|
|
99
|
-
[FeePerDAGas.opcode, FeePerDAGas],
|
|
100
|
-
//[Blockl2gaslimit.opcode, Blockl2gaslimit],
|
|
101
|
-
//[Blockdagaslimit.opcode, Blockdagaslimit],
|
|
111
|
+
[ChainId.opcode, Instruction.deserialize.bind(ChainId)],
|
|
112
|
+
[Version.opcode, Instruction.deserialize.bind(Version)],
|
|
113
|
+
[BlockNumber.opcode, Instruction.deserialize.bind(BlockNumber)],
|
|
114
|
+
[Timestamp.opcode, Instruction.deserialize.bind(Timestamp)],
|
|
115
|
+
[FeePerL2Gas.opcode, Instruction.deserialize.bind(FeePerL2Gas)],
|
|
116
|
+
[FeePerDAGas.opcode, Instruction.deserialize.bind(FeePerDAGas)],
|
|
102
117
|
// Execution Environment - Calldata
|
|
103
|
-
[CalldataCopy.opcode, CalldataCopy],
|
|
118
|
+
[CalldataCopy.opcode, Instruction.deserialize.bind(CalldataCopy)],
|
|
104
119
|
|
|
105
120
|
// Machine State
|
|
106
121
|
// Machine State - Gas
|
|
107
|
-
[L2GasLeft.opcode, L2GasLeft],
|
|
108
|
-
[DAGasLeft.opcode, DAGasLeft],
|
|
122
|
+
[L2GasLeft.opcode, Instruction.deserialize.bind(L2GasLeft)],
|
|
123
|
+
[DAGasLeft.opcode, Instruction.deserialize.bind(DAGasLeft)],
|
|
109
124
|
// Machine State - Internal Control Flow
|
|
110
|
-
[Jump.opcode, Jump],
|
|
111
|
-
[JumpI.opcode, JumpI],
|
|
112
|
-
[InternalCall.opcode, InternalCall],
|
|
113
|
-
[InternalReturn.opcode, InternalReturn],
|
|
114
|
-
[
|
|
115
|
-
[
|
|
116
|
-
[
|
|
125
|
+
[Jump.opcode, Instruction.deserialize.bind(Jump)],
|
|
126
|
+
[JumpI.opcode, Instruction.deserialize.bind(JumpI)],
|
|
127
|
+
[InternalCall.opcode, Instruction.deserialize.bind(InternalCall)],
|
|
128
|
+
[InternalReturn.opcode, Instruction.deserialize.bind(InternalReturn)],
|
|
129
|
+
[Opcode.SET_8, Set.as(Set.wireFormat8).deserialize],
|
|
130
|
+
[Opcode.SET_16, Set.as(Set.wireFormat16).deserialize],
|
|
131
|
+
[Opcode.SET_32, Set.as(Set.wireFormat32).deserialize],
|
|
132
|
+
[Opcode.SET_64, Set.as(Set.wireFormat64).deserialize],
|
|
133
|
+
[Opcode.SET_128, Set.as(Set.wireFormat128).deserialize],
|
|
134
|
+
[Opcode.SET_FF, Set.as(Set.wireFormatFF).deserialize],
|
|
135
|
+
[Opcode.MOV_8, Mov.as(Mov.wireFormat8).deserialize],
|
|
136
|
+
[Opcode.MOV_16, Mov.as(Mov.wireFormat16).deserialize],
|
|
137
|
+
[CMov.opcode, Instruction.deserialize.bind(CMov)],
|
|
117
138
|
|
|
118
139
|
// World State
|
|
119
|
-
[SLoad.opcode, SLoad], // Public Storage
|
|
120
|
-
[SStore.opcode, SStore], // Public Storage
|
|
121
|
-
[NoteHashExists.opcode, NoteHashExists], // Notes & Nullifiers
|
|
122
|
-
[EmitNoteHash.opcode, EmitNoteHash], // Notes & Nullifiers
|
|
123
|
-
[NullifierExists.opcode, NullifierExists], // Notes & Nullifiers
|
|
124
|
-
[EmitNullifier.opcode, EmitNullifier], // Notes & Nullifiers
|
|
125
|
-
[L1ToL2MessageExists.opcode, L1ToL2MessageExists], // Messages
|
|
126
|
-
//[HeaderMember.opcode, HeaderMember], // Header
|
|
140
|
+
[SLoad.opcode, Instruction.deserialize.bind(SLoad)], // Public Storage
|
|
141
|
+
[SStore.opcode, Instruction.deserialize.bind(SStore)], // Public Storage
|
|
142
|
+
[NoteHashExists.opcode, Instruction.deserialize.bind(NoteHashExists)], // Notes & Nullifiers
|
|
143
|
+
[EmitNoteHash.opcode, Instruction.deserialize.bind(EmitNoteHash)], // Notes & Nullifiers
|
|
144
|
+
[NullifierExists.opcode, Instruction.deserialize.bind(NullifierExists)], // Notes & Nullifiers
|
|
145
|
+
[EmitNullifier.opcode, Instruction.deserialize.bind(EmitNullifier)], // Notes & Nullifiers
|
|
146
|
+
[L1ToL2MessageExists.opcode, Instruction.deserialize.bind(L1ToL2MessageExists)], // Messages
|
|
127
147
|
|
|
128
148
|
// Accrued Substate
|
|
129
|
-
[EmitUnencryptedLog.opcode, EmitUnencryptedLog],
|
|
130
|
-
[SendL2ToL1Message.opcode, SendL2ToL1Message],
|
|
131
|
-
[GetContractInstance.opcode, GetContractInstance],
|
|
149
|
+
[EmitUnencryptedLog.opcode, Instruction.deserialize.bind(EmitUnencryptedLog)],
|
|
150
|
+
[SendL2ToL1Message.opcode, Instruction.deserialize.bind(SendL2ToL1Message)],
|
|
151
|
+
[GetContractInstance.opcode, Instruction.deserialize.bind(GetContractInstance)],
|
|
132
152
|
|
|
133
153
|
// Control Flow - Contract Calls
|
|
134
|
-
[Call.opcode, Call],
|
|
135
|
-
[StaticCall.opcode, StaticCall],
|
|
136
|
-
//[DelegateCall.opcode, DelegateCall],
|
|
137
|
-
[Return.opcode, Return],
|
|
138
|
-
[Revert.opcode, Revert],
|
|
154
|
+
[Call.opcode, Instruction.deserialize.bind(Call)],
|
|
155
|
+
[StaticCall.opcode, Instruction.deserialize.bind(StaticCall)],
|
|
156
|
+
//[DelegateCall.opcode, Instruction.deserialize.bind(DelegateCall)],
|
|
157
|
+
[Return.opcode, Instruction.deserialize.bind(Return)],
|
|
158
|
+
[Revert.opcode, Instruction.deserialize.bind(Revert)],
|
|
139
159
|
|
|
140
160
|
// Misc
|
|
141
|
-
[DebugLog.opcode, DebugLog],
|
|
161
|
+
[DebugLog.opcode, Instruction.deserialize.bind(DebugLog)],
|
|
142
162
|
|
|
143
163
|
// Gadgets
|
|
144
|
-
[EcAdd.opcode, EcAdd],
|
|
145
|
-
[Keccak.opcode, Keccak],
|
|
146
|
-
[Poseidon2.opcode, Poseidon2],
|
|
147
|
-
[Sha256.opcode, Sha256],
|
|
148
|
-
[Pedersen.opcode, Pedersen],
|
|
149
|
-
[MultiScalarMul.opcode, MultiScalarMul],
|
|
150
|
-
[PedersenCommitment.opcode, PedersenCommitment],
|
|
164
|
+
[EcAdd.opcode, Instruction.deserialize.bind(EcAdd)],
|
|
165
|
+
[Keccak.opcode, Instruction.deserialize.bind(Keccak)],
|
|
166
|
+
[Poseidon2.opcode, Instruction.deserialize.bind(Poseidon2)],
|
|
167
|
+
[Sha256.opcode, Instruction.deserialize.bind(Sha256)],
|
|
168
|
+
[Pedersen.opcode, Instruction.deserialize.bind(Pedersen)],
|
|
169
|
+
[MultiScalarMul.opcode, Instruction.deserialize.bind(MultiScalarMul)],
|
|
170
|
+
[PedersenCommitment.opcode, Instruction.deserialize.bind(PedersenCommitment)],
|
|
151
171
|
// Conversions
|
|
152
|
-
[ToRadixLE.opcode, ToRadixLE],
|
|
172
|
+
[ToRadixLE.opcode, Instruction.deserialize.bind(ToRadixLE)],
|
|
153
173
|
// Future Gadgets -- pending changes in noir
|
|
154
174
|
// SHA256COMPRESSION,
|
|
155
|
-
[KeccakF1600.opcode, KeccakF1600],
|
|
175
|
+
[KeccakF1600.opcode, Instruction.deserialize.bind(KeccakF1600)],
|
|
156
176
|
]);
|
|
157
177
|
|
|
158
|
-
interface Serializable {
|
|
159
|
-
serialize(): Buffer;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
178
|
/**
|
|
163
179
|
* Serializes an array of instructions to bytecode.
|
|
164
180
|
*/
|
|
@@ -186,8 +202,8 @@ export function decodeFromBytecode(
|
|
|
186
202
|
throw new Error(`Opcode ${Opcode[opcode]} (0x${opcode.toString(16)}) not implemented`);
|
|
187
203
|
}
|
|
188
204
|
|
|
189
|
-
const instructionDeserializer:
|
|
190
|
-
const i: Instruction = instructionDeserializer
|
|
205
|
+
const instructionDeserializer: InstructionDeserializer = instructionDeserializerOrUndef;
|
|
206
|
+
const i: Instruction = instructionDeserializer(cursor);
|
|
191
207
|
instructions.push(i);
|
|
192
208
|
}
|
|
193
209
|
|
|
@@ -8,20 +8,33 @@ import { BufferCursor } from './buffer_cursor.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export enum Opcode {
|
|
10
10
|
// Compute
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
ADD_8,
|
|
12
|
+
ADD_16,
|
|
13
|
+
SUB_8,
|
|
14
|
+
SUB_16,
|
|
15
|
+
MUL_8,
|
|
16
|
+
MUL_16,
|
|
17
|
+
DIV_8,
|
|
18
|
+
DIV_16,
|
|
19
|
+
FDIV_8,
|
|
20
|
+
FDIV_16,
|
|
21
|
+
EQ_8,
|
|
22
|
+
EQ_16,
|
|
23
|
+
LT_8,
|
|
24
|
+
LT_16,
|
|
25
|
+
LTE_8,
|
|
26
|
+
LTE_16,
|
|
27
|
+
AND_8,
|
|
28
|
+
AND_16,
|
|
29
|
+
OR_8,
|
|
30
|
+
OR_16,
|
|
31
|
+
XOR_8,
|
|
32
|
+
XOR_16,
|
|
22
33
|
NOT,
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
SHL_8,
|
|
35
|
+
SHL_16,
|
|
36
|
+
SHR_8,
|
|
37
|
+
SHR_16,
|
|
25
38
|
CAST,
|
|
26
39
|
// Execution environment
|
|
27
40
|
ADDRESS,
|
|
@@ -33,23 +46,26 @@ export enum Opcode {
|
|
|
33
46
|
VERSION,
|
|
34
47
|
BLOCKNUMBER,
|
|
35
48
|
TIMESTAMP,
|
|
36
|
-
COINBASE,
|
|
37
49
|
FEEPERL2GAS,
|
|
38
50
|
FEEPERDAGAS,
|
|
39
|
-
BLOCKL2GASLIMIT,
|
|
40
|
-
BLOCKDAGASLIMIT,
|
|
41
51
|
CALLDATACOPY,
|
|
42
52
|
// Gas
|
|
43
53
|
L2GASLEFT,
|
|
44
54
|
DAGASLEFT,
|
|
45
55
|
// Control flow
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
JUMP_16,
|
|
57
|
+
JUMPI_16,
|
|
48
58
|
INTERNALCALL,
|
|
49
59
|
INTERNALRETURN,
|
|
50
60
|
// Memory
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
SET_8,
|
|
62
|
+
SET_16,
|
|
63
|
+
SET_32,
|
|
64
|
+
SET_64,
|
|
65
|
+
SET_128,
|
|
66
|
+
SET_FF,
|
|
67
|
+
MOV_8,
|
|
68
|
+
MOV_16,
|
|
53
69
|
CMOV,
|
|
54
70
|
// World state
|
|
55
71
|
SLOAD,
|
|
@@ -59,7 +75,6 @@ export enum Opcode {
|
|
|
59
75
|
NULLIFIEREXISTS,
|
|
60
76
|
EMITNULLIFIER,
|
|
61
77
|
L1TOL2MSGEXISTS,
|
|
62
|
-
HEADERMEMBER,
|
|
63
78
|
GETCONTRACTINSTANCE,
|
|
64
79
|
EMITUNENCRYPTEDLOG,
|
|
65
80
|
SENDL2TOL1MSG,
|
|
@@ -96,6 +111,7 @@ export enum OperandType {
|
|
|
96
111
|
UINT32,
|
|
97
112
|
UINT64,
|
|
98
113
|
UINT128,
|
|
114
|
+
FF,
|
|
99
115
|
}
|
|
100
116
|
|
|
101
117
|
type OperandNativeType = number | bigint;
|
|
@@ -108,8 +124,27 @@ const OPERAND_SPEC = new Map<OperandType, [number, () => OperandNativeType, Oper
|
|
|
108
124
|
[OperandType.UINT32, [4, Buffer.prototype.readUint32BE, Buffer.prototype.writeUint32BE]],
|
|
109
125
|
[OperandType.UINT64, [8, Buffer.prototype.readBigInt64BE, Buffer.prototype.writeBigInt64BE]],
|
|
110
126
|
[OperandType.UINT128, [16, readBigInt128BE, writeBigInt128BE]],
|
|
127
|
+
[OperandType.FF, [32, readBigInt254BE, writeBigInt254BE]],
|
|
111
128
|
]);
|
|
112
129
|
|
|
130
|
+
function readBigInt254BE(this: Buffer): bigint {
|
|
131
|
+
const totalBytes = 32;
|
|
132
|
+
let ret: bigint = 0n;
|
|
133
|
+
for (let i = 0; i < totalBytes; ++i) {
|
|
134
|
+
ret <<= 8n;
|
|
135
|
+
ret |= BigInt(this.readUint8(i));
|
|
136
|
+
}
|
|
137
|
+
return ret;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function writeBigInt254BE(this: Buffer, value: bigint): void {
|
|
141
|
+
const totalBytes = 32;
|
|
142
|
+
for (let offset = totalBytes - 1; offset >= 0; --offset) {
|
|
143
|
+
this.writeUint8(Number(value & 0xffn), offset);
|
|
144
|
+
value >>= 8n;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
113
148
|
function readBigInt128BE(this: Buffer): bigint {
|
|
114
149
|
const totalBytes = 16;
|
|
115
150
|
let ret: bigint = 0n;
|
|
@@ -160,12 +195,10 @@ export function deserialize(cursor: BufferCursor | Buffer, operands: OperandType
|
|
|
160
195
|
* @param cls The class to be serialized.
|
|
161
196
|
* @returns
|
|
162
197
|
*/
|
|
163
|
-
export function
|
|
198
|
+
export function serializeAs(operands: OperandType[], opcode: Opcode, cls: any): Buffer {
|
|
164
199
|
const chunks: Buffer[] = [];
|
|
165
200
|
|
|
166
|
-
|
|
167
|
-
assert(cls.constructor.opcode !== undefined && cls.constructor.opcode !== null);
|
|
168
|
-
const rawClassValues: any[] = [cls.constructor.opcode, ...Object.values(cls)];
|
|
201
|
+
const rawClassValues: any[] = [opcode, ...Object.values(cls)];
|
|
169
202
|
assert(
|
|
170
203
|
rawClassValues.length === operands.length,
|
|
171
204
|
`Got ${rawClassValues.length} values but only ${operands.length} serialization operands are specified!`,
|
package/src/avm/test_utils.ts
CHANGED
|
@@ -28,8 +28,15 @@ export function mockStorageReadWithMap(hs: HostStorage, mockedStorage: Map<bigin
|
|
|
28
28
|
);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export function mockNoteHashExists(hs: HostStorage,
|
|
32
|
-
(hs.commitmentsDb as jest.Mocked<CommitmentsDB>).
|
|
31
|
+
export function mockNoteHashExists(hs: HostStorage, _leafIndex: Fr, value?: Fr) {
|
|
32
|
+
(hs.commitmentsDb as jest.Mocked<CommitmentsDB>).getCommitmentValue.mockImplementation((index: bigint) => {
|
|
33
|
+
if (index == _leafIndex.toBigInt()) {
|
|
34
|
+
return Promise.resolve(value);
|
|
35
|
+
} else {
|
|
36
|
+
// This is ok for now since the traceing functions handle it
|
|
37
|
+
return Promise.resolve(undefined);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
33
40
|
}
|
|
34
41
|
|
|
35
42
|
export function mockNullifierExists(hs: HostStorage, leafIndex: Fr, _value?: Fr) {
|
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
PublicKernelData,
|
|
48
48
|
ReadRequest,
|
|
49
49
|
RevertCode,
|
|
50
|
+
TreeLeafReadRequest,
|
|
50
51
|
makeEmptyProof,
|
|
51
52
|
makeEmptyRecursiveProof,
|
|
52
53
|
} from '@aztec/circuits.js';
|
|
@@ -412,7 +413,7 @@ export abstract class AbstractPhaseManager {
|
|
|
412
413
|
returnsHash: computeVarArgsHash(result.returnValues),
|
|
413
414
|
noteHashReadRequests: padArrayEnd(
|
|
414
415
|
result.noteHashReadRequests,
|
|
415
|
-
|
|
416
|
+
TreeLeafReadRequest.empty(),
|
|
416
417
|
MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,
|
|
417
418
|
),
|
|
418
419
|
nullifierReadRequests: padArrayEnd(
|
|
@@ -427,7 +428,7 @@ export abstract class AbstractPhaseManager {
|
|
|
427
428
|
),
|
|
428
429
|
l1ToL2MsgReadRequests: padArrayEnd(
|
|
429
430
|
result.l1ToL2MsgReadRequests,
|
|
430
|
-
|
|
431
|
+
TreeLeafReadRequest.empty(),
|
|
431
432
|
MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL,
|
|
432
433
|
),
|
|
433
434
|
contractStorageReads: padArrayEnd(
|
|
@@ -100,6 +100,13 @@ export interface CommitmentsDB {
|
|
|
100
100
|
*/
|
|
101
101
|
getCommitmentIndex(commitment: Fr): Promise<bigint | undefined>;
|
|
102
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Gets commitment in the note hash tree given a leaf index.
|
|
105
|
+
* @param leafIndex - the leaf to look up.
|
|
106
|
+
* @returns - The commitment at that index. Undefined if leaf index is not found.
|
|
107
|
+
*/
|
|
108
|
+
getCommitmentValue(leafIndex: bigint): Promise<Fr | undefined>;
|
|
109
|
+
|
|
103
110
|
/**
|
|
104
111
|
* Gets the index of a nullifier in the nullifier tree.
|
|
105
112
|
* @param nullifier - The nullifier.
|
package/src/public/execution.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
PublicCallStackItemCompressed,
|
|
18
18
|
type ReadRequest,
|
|
19
19
|
RevertCode,
|
|
20
|
+
type TreeLeafReadRequest,
|
|
20
21
|
} from '@aztec/circuits.js';
|
|
21
22
|
import { computeVarArgsHash } from '@aztec/circuits.js/hash';
|
|
22
23
|
|
|
@@ -62,13 +63,13 @@ export interface PublicExecutionResult {
|
|
|
62
63
|
/** The new nullifiers to be inserted into the nullifier tree. */
|
|
63
64
|
nullifiers: Nullifier[];
|
|
64
65
|
/** The note hash read requests emitted in this call. */
|
|
65
|
-
noteHashReadRequests:
|
|
66
|
+
noteHashReadRequests: TreeLeafReadRequest[];
|
|
66
67
|
/** The nullifier read requests emitted in this call. */
|
|
67
68
|
nullifierReadRequests: ReadRequest[];
|
|
68
69
|
/** The nullifier non existent read requests emitted in this call. */
|
|
69
70
|
nullifierNonExistentReadRequests: ReadRequest[];
|
|
70
71
|
/** L1 to L2 message read requests emitted in this call. */
|
|
71
|
-
l1ToL2MsgReadRequests:
|
|
72
|
+
l1ToL2MsgReadRequests: TreeLeafReadRequest[];
|
|
72
73
|
/**
|
|
73
74
|
* The hashed logs with side effect counter.
|
|
74
75
|
* Note: required as we don't track the counter anywhere else.
|