@aztec/simulator 0.34.0 → 0.35.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 +4 -1
- package/dest/acvm/acvm.d.ts.map +1 -1
- package/dest/acvm/acvm.js +5 -5
- package/dest/acvm/deserialize.d.ts +3 -5
- package/dest/acvm/deserialize.d.ts.map +1 -1
- package/dest/acvm/deserialize.js +6 -9
- package/dest/acvm/oracle/oracle.d.ts +2 -0
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +12 -4
- package/dest/acvm/oracle/typed_oracle.d.ts +2 -0
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +7 -1
- package/dest/avm/avm_execution_environment.d.ts +4 -2
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +7 -5
- package/dest/avm/avm_gas.js +2 -2
- package/dest/avm/avm_machine_state.d.ts +2 -0
- package/dest/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/avm/avm_machine_state.js +24 -6
- package/dest/avm/avm_memory_types.js +2 -2
- package/dest/avm/avm_simulator.js +2 -2
- package/dest/avm/fixtures/index.d.ts +3 -0
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +11 -4
- package/dest/avm/journal/journal.d.ts +1 -0
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +12 -1
- package/dest/avm/opcodes/accrued_substate.d.ts +2 -1
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +13 -5
- package/dest/avm/opcodes/context_getters.js +2 -2
- package/dest/avm/opcodes/external_calls.d.ts +2 -2
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +7 -6
- package/dest/avm/opcodes/hashing.d.ts +8 -8
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +35 -43
- package/dest/avm/serialization/instruction_serialization.d.ts +1 -1
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +2 -2
- package/dest/client/client_execution_context.d.ts +13 -3
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +23 -8
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +8 -6
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +6 -5
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +5 -4
- package/dest/common/index.d.ts +1 -1
- package/dest/common/index.d.ts.map +1 -1
- package/dest/common/index.js +2 -2
- package/dest/common/packed_values_cache.d.ts +28 -0
- package/dest/common/packed_values_cache.d.ts.map +1 -0
- package/dest/common/packed_values_cache.js +50 -0
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/mocks/fixtures.d.ts +42 -0
- package/dest/mocks/fixtures.d.ts.map +1 -0
- package/dest/mocks/fixtures.js +84 -0
- package/dest/mocks/index.d.ts +2 -0
- package/dest/mocks/index.d.ts.map +1 -0
- package/dest/mocks/index.js +2 -0
- package/dest/public/abstract_phase_manager.d.ts +82 -0
- package/dest/public/abstract_phase_manager.d.ts.map +1 -0
- package/dest/public/abstract_phase_manager.js +320 -0
- package/dest/public/app_logic_phase_manager.d.ts +29 -0
- package/dest/public/app_logic_phase_manager.d.ts.map +1 -0
- package/dest/public/app_logic_phase_manager.js +50 -0
- package/dest/public/execution.d.ts +3 -0
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -1
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +17 -13
- package/dest/public/hints_builder.d.ts +23 -0
- package/dest/public/hints_builder.d.ts.map +1 -0
- package/dest/public/hints_builder.js +62 -0
- package/dest/public/index.d.ts +5 -0
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +6 -1
- package/dest/public/phase_manager_factory.d.ts +18 -0
- package/dest/public/phase_manager_factory.d.ts.map +1 -0
- package/dest/public/phase_manager_factory.js +56 -0
- package/dest/public/public_execution_context.d.ts +15 -5
- package/dest/public/public_execution_context.d.ts.map +1 -1
- package/dest/public/public_execution_context.js +28 -12
- package/dest/public/public_executor.d.ts +79 -0
- package/dest/public/public_executor.d.ts.map +1 -0
- package/dest/public/public_executor.js +198 -0
- package/dest/public/public_kernel.d.ts +37 -0
- package/dest/public/public_kernel.d.ts.map +1 -0
- package/dest/public/public_kernel.js +97 -0
- package/dest/public/public_kernel_circuit_simulator.d.ts +31 -0
- package/dest/public/public_kernel_circuit_simulator.d.ts.map +1 -0
- package/dest/public/public_kernel_circuit_simulator.js +2 -0
- package/dest/public/public_processor.d.ts +53 -0
- package/dest/public/public_processor.d.ts.map +1 -0
- package/dest/public/public_processor.js +144 -0
- package/dest/public/setup_phase_manager.d.ts +30 -0
- package/dest/public/setup_phase_manager.d.ts.map +1 -0
- package/dest/public/setup_phase_manager.js +46 -0
- package/dest/public/tail_phase_manager.d.ts +30 -0
- package/dest/public/tail_phase_manager.d.ts.map +1 -0
- package/dest/public/tail_phase_manager.js +60 -0
- package/dest/public/teardown_phase_manager.d.ts +30 -0
- package/dest/public/teardown_phase_manager.d.ts.map +1 -0
- package/dest/public/teardown_phase_manager.js +46 -0
- package/dest/public/transitional_adaptors.d.ts +2 -1
- package/dest/public/transitional_adaptors.d.ts.map +1 -1
- package/dest/public/transitional_adaptors.js +11 -10
- package/dest/public/utils.d.ts +8 -0
- package/dest/public/utils.d.ts.map +1 -0
- package/dest/public/utils.js +29 -0
- package/dest/simulator/acvm_native.d.ts +19 -3
- package/dest/simulator/acvm_native.d.ts.map +1 -1
- package/dest/simulator/acvm_native.js +75 -48
- package/dest/simulator/acvm_wasm.d.ts.map +1 -1
- package/dest/simulator/acvm_wasm.js +3 -4
- package/package.json +8 -5
- package/src/acvm/acvm.ts +8 -5
- package/src/acvm/deserialize.ts +5 -9
- package/src/acvm/oracle/oracle.ts +13 -3
- package/src/acvm/oracle/typed_oracle.ts +8 -0
- package/src/avm/avm_execution_environment.ts +9 -1
- package/src/avm/avm_gas.ts +1 -1
- package/src/avm/avm_machine_state.ts +26 -5
- package/src/avm/avm_memory_types.ts +1 -1
- package/src/avm/avm_simulator.ts +1 -1
- package/src/avm/fixtures/index.ts +13 -1
- package/src/avm/journal/journal.ts +13 -0
- package/src/avm/opcodes/accrued_substate.ts +16 -4
- package/src/avm/opcodes/context_getters.ts +1 -1
- package/src/avm/opcodes/external_calls.ts +8 -5
- package/src/avm/opcodes/hashing.ts +38 -54
- package/src/avm/serialization/instruction_serialization.ts +1 -1
- package/src/client/client_execution_context.ts +25 -6
- package/src/client/private_execution.ts +7 -6
- package/src/client/simulator.ts +7 -3
- package/src/client/unconstrained_execution.ts +4 -3
- package/src/common/index.ts +1 -1
- package/src/common/packed_values_cache.ts +55 -0
- package/src/index.ts +1 -0
- package/src/mocks/fixtures.ts +169 -0
- package/src/mocks/index.ts +1 -0
- package/src/public/abstract_phase_manager.ts +571 -0
- package/src/public/app_logic_phase_manager.ts +76 -0
- package/src/public/execution.ts +4 -0
- package/src/public/executor.ts +18 -13
- package/src/public/hints_builder.ts +119 -0
- package/src/public/index.ts +5 -0
- package/src/public/phase_manager_factory.ts +126 -0
- package/src/public/public_execution_context.ts +29 -18
- package/src/public/public_executor.ts +267 -0
- package/src/public/public_kernel.ts +139 -0
- package/src/public/public_kernel_circuit_simulator.ts +36 -0
- package/src/public/public_processor.ts +212 -0
- package/src/public/setup_phase_manager.ts +66 -0
- package/src/public/tail_phase_manager.ts +120 -0
- package/src/public/teardown_phase_manager.ts +66 -0
- package/src/public/transitional_adaptors.ts +14 -5
- package/src/public/utils.ts +31 -0
- package/src/simulator/acvm_native.ts +94 -47
- package/src/simulator/acvm_wasm.ts +7 -3
- package/dest/common/packed_args_cache.d.ts +0 -28
- package/dest/common/packed_args_cache.d.ts.map +0 -1
- package/dest/common/packed_args_cache.js +0 -50
- package/src/common/packed_args_cache.ts +0 -55
|
@@ -80,19 +80,31 @@ export class NullifierExists extends Instruction {
|
|
|
80
80
|
static type: string = 'NULLIFIEREXISTS';
|
|
81
81
|
static readonly opcode: Opcode = Opcode.NULLIFIEREXISTS;
|
|
82
82
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
83
|
-
static readonly wireFormat = [
|
|
83
|
+
static readonly wireFormat = [
|
|
84
|
+
OperandType.UINT8,
|
|
85
|
+
OperandType.UINT8,
|
|
86
|
+
OperandType.UINT32,
|
|
87
|
+
OperandType.UINT32,
|
|
88
|
+
OperandType.UINT32,
|
|
89
|
+
];
|
|
84
90
|
|
|
85
|
-
constructor(
|
|
91
|
+
constructor(
|
|
92
|
+
private indirect: number,
|
|
93
|
+
private nullifierOffset: number,
|
|
94
|
+
private addressOffset: number,
|
|
95
|
+
private existsOffset: number,
|
|
96
|
+
) {
|
|
86
97
|
super();
|
|
87
98
|
}
|
|
88
99
|
|
|
89
100
|
public async execute(context: AvmContext): Promise<void> {
|
|
90
|
-
const memoryOperations = { reads:
|
|
101
|
+
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
91
102
|
const memory = context.machineState.memory.track(this.type);
|
|
92
103
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
93
104
|
|
|
94
105
|
const nullifier = memory.get(this.nullifierOffset).toFr();
|
|
95
|
-
const
|
|
106
|
+
const address = memory.get(this.addressOffset).toFr();
|
|
107
|
+
const exists = await context.persistableState.checkNullifierExists(address, nullifier);
|
|
96
108
|
|
|
97
109
|
memory.set(this.existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
98
110
|
|
|
@@ -7,7 +7,7 @@ export class L2GasLeft extends GetterInstruction {
|
|
|
7
7
|
static type: string = 'L2GASLEFT';
|
|
8
8
|
static readonly opcode: Opcode = Opcode.L2GASLEFT;
|
|
9
9
|
|
|
10
|
-
// TODO(@spalladino)
|
|
10
|
+
// TODO(@spalladino) Protocol specs specifies that the value should be an Uint32, not a Field.
|
|
11
11
|
protected getValue(context: AvmContext): MemoryValue {
|
|
12
12
|
return new Field(context.machineState.l2GasLeft);
|
|
13
13
|
}
|
|
@@ -36,7 +36,7 @@ abstract class ExternalCall extends Instruction {
|
|
|
36
36
|
private gasOffset: number /* Unused due to no formal gas implementation at this moment */,
|
|
37
37
|
private addrOffset: number,
|
|
38
38
|
private argsOffset: number,
|
|
39
|
-
private
|
|
39
|
+
private argsSizeOffset: number,
|
|
40
40
|
private retOffset: number,
|
|
41
41
|
private retSize: number,
|
|
42
42
|
private successOffset: number,
|
|
@@ -50,20 +50,23 @@ abstract class ExternalCall extends Instruction {
|
|
|
50
50
|
|
|
51
51
|
public async execute(context: AvmContext) {
|
|
52
52
|
const memory = context.machineState.memory.track(this.type);
|
|
53
|
-
const [gasOffset, addrOffset, argsOffset, retOffset, successOffset] = Addressing.fromWire(
|
|
54
|
-
|
|
53
|
+
const [gasOffset, addrOffset, argsOffset, argsSizeOffset, retOffset, successOffset] = Addressing.fromWire(
|
|
54
|
+
this.indirect,
|
|
55
|
+
).resolve(
|
|
56
|
+
[this.gasOffset, this.addrOffset, this.argsOffset, this.argsSizeOffset, this.retOffset, this.successOffset],
|
|
55
57
|
memory,
|
|
56
58
|
);
|
|
57
59
|
|
|
58
60
|
const callAddress = memory.getAs<Field>(addrOffset);
|
|
59
|
-
const
|
|
61
|
+
const calldataSize = memory.get(argsSizeOffset).toNumber();
|
|
62
|
+
const calldata = memory.getSlice(argsOffset, calldataSize).map(f => f.toFr());
|
|
60
63
|
const l1Gas = memory.get(gasOffset).toNumber();
|
|
61
64
|
const l2Gas = memory.getAs<Field>(gasOffset + 1).toNumber();
|
|
62
65
|
const daGas = memory.getAs<Field>(gasOffset + 2).toNumber();
|
|
63
66
|
const functionSelector = memory.getAs<Field>(this.temporaryFunctionSelectorOffset).toFr();
|
|
64
67
|
|
|
65
68
|
const allocatedGas = { l1Gas, l2Gas, daGas };
|
|
66
|
-
const memoryOperations = { reads:
|
|
69
|
+
const memoryOperations = { reads: calldataSize + 6, writes: 1 + this.retSize, indirect: this.indirect };
|
|
67
70
|
const totalGas = sumGas(this.gasCost(memoryOperations), allocatedGas);
|
|
68
71
|
context.machineState.consumeGas(totalGas);
|
|
69
72
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { keccak, pedersenHash, poseidonHash, sha256 } from '@aztec/foundation/crypto';
|
|
1
|
+
import { keccak256, pedersenHash, poseidon2Permutation, sha256 } from '@aztec/foundation/crypto';
|
|
3
2
|
|
|
4
3
|
import { type AvmContext } from '../avm_context.js';
|
|
5
|
-
import { Field } from '../avm_memory_types.js';
|
|
4
|
+
import { Field, Uint8 } from '../avm_memory_types.js';
|
|
6
5
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
7
6
|
import { Addressing } from './addressing_mode.js';
|
|
8
7
|
import { Instruction } from './instruction.js';
|
|
9
8
|
|
|
10
9
|
export class Poseidon2 extends Instruction {
|
|
11
10
|
static type: string = 'POSEIDON2';
|
|
12
|
-
static readonly opcode: Opcode = Opcode.
|
|
11
|
+
static readonly opcode: Opcode = Opcode.POSEIDON2;
|
|
12
|
+
static readonly stateSize = 4;
|
|
13
13
|
|
|
14
14
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
15
15
|
static readonly wireFormat: OperandType[] = [
|
|
@@ -17,34 +17,28 @@ export class Poseidon2 extends Instruction {
|
|
|
17
17
|
OperandType.UINT8,
|
|
18
18
|
OperandType.UINT32,
|
|
19
19
|
OperandType.UINT32,
|
|
20
|
-
OperandType.UINT32,
|
|
21
20
|
];
|
|
22
21
|
|
|
23
|
-
constructor(
|
|
24
|
-
private indirect: number,
|
|
25
|
-
private dstOffset: number,
|
|
26
|
-
private messageOffset: number,
|
|
27
|
-
private messageSize: number,
|
|
28
|
-
) {
|
|
22
|
+
constructor(private indirect: number, private inputStateOffset: number, private outputStateOffset: number) {
|
|
29
23
|
super();
|
|
30
24
|
}
|
|
31
25
|
|
|
32
26
|
public async execute(context: AvmContext): Promise<void> {
|
|
33
|
-
const memoryOperations = { reads:
|
|
27
|
+
const memoryOperations = { reads: Poseidon2.stateSize, writes: Poseidon2.stateSize, indirect: this.indirect };
|
|
34
28
|
const memory = context.machineState.memory.track(this.type);
|
|
35
29
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
[this.dstOffset, this.messageOffset],
|
|
31
|
+
const [inputOffset, outputOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
32
|
+
[this.inputStateOffset, this.outputStateOffset],
|
|
40
33
|
memory,
|
|
41
34
|
);
|
|
42
35
|
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
const inputState = memory.getSlice(inputOffset, Poseidon2.stateSize);
|
|
37
|
+
const outputState = poseidon2Permutation(inputState);
|
|
38
|
+
memory.setSlice(
|
|
39
|
+
outputOffset,
|
|
40
|
+
outputState.map(word => new Field(word)),
|
|
41
|
+
);
|
|
48
42
|
|
|
49
43
|
memory.assert(memoryOperations);
|
|
50
44
|
context.machineState.incrementPc();
|
|
@@ -68,33 +62,28 @@ export class Keccak extends Instruction {
|
|
|
68
62
|
private indirect: number,
|
|
69
63
|
private dstOffset: number,
|
|
70
64
|
private messageOffset: number,
|
|
71
|
-
private
|
|
65
|
+
private messageSizeOffset: number,
|
|
72
66
|
) {
|
|
73
67
|
super();
|
|
74
68
|
}
|
|
75
69
|
|
|
76
|
-
//
|
|
70
|
+
// pub fn keccak256(input: [u8], message_size: u32) -> [u8; 32]
|
|
77
71
|
public async execute(context: AvmContext): Promise<void> {
|
|
78
|
-
const memoryOperations = { reads: this.messageSize, writes: 2, indirect: this.indirect };
|
|
79
72
|
const memory = context.machineState.memory.track(this.type);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// We hash a set of field elements
|
|
83
|
-
const [dstOffset, messageOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
84
|
-
[this.dstOffset, this.messageOffset],
|
|
73
|
+
const [dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
74
|
+
[this.dstOffset, this.messageOffset, this.messageSizeOffset],
|
|
85
75
|
memory,
|
|
86
76
|
);
|
|
77
|
+
const messageSize = memory.get(messageSizeOffset).toNumber();
|
|
78
|
+
const memoryOperations = { reads: messageSize + 1, writes: 32, indirect: this.indirect };
|
|
79
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
87
80
|
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
const hash = keccak(Buffer.concat(hashData));
|
|
91
|
-
|
|
92
|
-
// Split output into two fields
|
|
93
|
-
const high = new Field(toBigIntBE(hash.subarray(0, 16)));
|
|
94
|
-
const low = new Field(toBigIntBE(hash.subarray(16, 32)));
|
|
81
|
+
const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()));
|
|
82
|
+
const hashBuffer = keccak256(messageData);
|
|
95
83
|
|
|
96
|
-
|
|
97
|
-
|
|
84
|
+
// We need to convert the hashBuffer because map doesn't work as expected on an Uint8Array (Buffer).
|
|
85
|
+
const res = [...hashBuffer].map(byte => new Uint8(byte));
|
|
86
|
+
memory.setSlice(dstOffset, res);
|
|
98
87
|
|
|
99
88
|
memory.assert(memoryOperations);
|
|
100
89
|
context.machineState.incrementPc();
|
|
@@ -118,33 +107,28 @@ export class Sha256 extends Instruction {
|
|
|
118
107
|
private indirect: number,
|
|
119
108
|
private dstOffset: number,
|
|
120
109
|
private messageOffset: number,
|
|
121
|
-
private
|
|
110
|
+
private messageSizeOffset: number,
|
|
122
111
|
) {
|
|
123
112
|
super();
|
|
124
113
|
}
|
|
125
114
|
|
|
126
|
-
//
|
|
115
|
+
// pub fn sha256_slice(input: [u8]) -> [u8; 32]
|
|
127
116
|
public async execute(context: AvmContext): Promise<void> {
|
|
128
|
-
const memoryOperations = { reads: this.messageSize, writes: 2, indirect: this.indirect };
|
|
129
117
|
const memory = context.machineState.memory.track(this.type);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const [dstOffset, messageOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
133
|
-
[this.dstOffset, this.messageOffset],
|
|
118
|
+
const [dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
119
|
+
[this.dstOffset, this.messageOffset, this.messageSizeOffset],
|
|
134
120
|
memory,
|
|
135
121
|
);
|
|
122
|
+
const messageSize = memory.get(messageSizeOffset).toNumber();
|
|
123
|
+
const memoryOperations = { reads: messageSize + 1, writes: 32, indirect: this.indirect };
|
|
124
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
136
125
|
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
const hash = sha256(Buffer.concat(hashData));
|
|
141
|
-
|
|
142
|
-
// Split output into two fields
|
|
143
|
-
const high = new Field(toBigIntBE(hash.subarray(0, 16)));
|
|
144
|
-
const low = new Field(toBigIntBE(hash.subarray(16, 32)));
|
|
126
|
+
const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()));
|
|
127
|
+
const hashBuffer = sha256(messageData);
|
|
145
128
|
|
|
146
|
-
|
|
147
|
-
|
|
129
|
+
// We need to convert the hashBuffer because map doesn't work as expected on an Uint8Array (Buffer).
|
|
130
|
+
const res = [...hashBuffer].map(byte => new Uint8(byte));
|
|
131
|
+
memory.setSlice(dstOffset, res);
|
|
148
132
|
|
|
149
133
|
memory.assert(memoryOperations);
|
|
150
134
|
context.machineState.incrementPc();
|
|
@@ -28,7 +28,7 @@ import { Fr, type Point } from '@aztec/foundation/fields';
|
|
|
28
28
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
29
29
|
|
|
30
30
|
import { type NoteData, toACVMWitness } from '../acvm/index.js';
|
|
31
|
-
import { type
|
|
31
|
+
import { type PackedValuesCache } from '../common/packed_values_cache.js';
|
|
32
32
|
import { type DBOracle } from './db_oracle.js';
|
|
33
33
|
import { type ExecutionNoteCache } from './execution_note_cache.js';
|
|
34
34
|
import { type ExecutionResult, type NoteAndSlot } from './execution_result.js';
|
|
@@ -72,7 +72,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
72
72
|
protected readonly historicalHeader: Header,
|
|
73
73
|
/** List of transient auth witnesses to be used during this simulation */
|
|
74
74
|
protected readonly authWitnesses: AuthWitness[],
|
|
75
|
-
private readonly
|
|
75
|
+
private readonly packedValuesCache: PackedValuesCache,
|
|
76
76
|
private readonly noteCache: ExecutionNoteCache,
|
|
77
77
|
protected readonly db: DBOracle,
|
|
78
78
|
private readonly curve: Grumpkin,
|
|
@@ -93,7 +93,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
93
93
|
public getInitialWitness(abi: FunctionAbi) {
|
|
94
94
|
const argumentsSize = countArgumentsSize(abi);
|
|
95
95
|
|
|
96
|
-
const args = this.
|
|
96
|
+
const args = this.packedValuesCache.unpack(this.argsHash);
|
|
97
97
|
|
|
98
98
|
if (args.length !== argumentsSize) {
|
|
99
99
|
throw new Error('Invalid arguments size');
|
|
@@ -175,7 +175,23 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
175
175
|
* @param args - Arguments to pack
|
|
176
176
|
*/
|
|
177
177
|
public packArguments(args: Fr[]): Promise<Fr> {
|
|
178
|
-
return Promise.resolve(this.
|
|
178
|
+
return Promise.resolve(this.packedValuesCache.pack(args));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Pack the given returns.
|
|
183
|
+
* @param returns - Returns to pack
|
|
184
|
+
*/
|
|
185
|
+
public packReturns(returns: Fr[]): Promise<Fr> {
|
|
186
|
+
return Promise.resolve(this.packedValuesCache.pack(returns));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Unpack the given returns.
|
|
191
|
+
* @param returnsHash - Returns hash to unpack
|
|
192
|
+
*/
|
|
193
|
+
public unpackReturns(returnsHash: Fr): Promise<Fr[]> {
|
|
194
|
+
return Promise.resolve(this.packedValuesCache.unpack(returnsHash));
|
|
179
195
|
}
|
|
180
196
|
|
|
181
197
|
/**
|
|
@@ -375,7 +391,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
375
391
|
derivedCallContext,
|
|
376
392
|
this.historicalHeader,
|
|
377
393
|
this.authWitnesses,
|
|
378
|
-
this.
|
|
394
|
+
this.packedValuesCache,
|
|
379
395
|
this.noteCache,
|
|
380
396
|
this.db,
|
|
381
397
|
this.curve,
|
|
@@ -428,7 +444,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
428
444
|
isDelegateCall,
|
|
429
445
|
isStaticCall,
|
|
430
446
|
);
|
|
431
|
-
const args = this.
|
|
447
|
+
const args = this.packedValuesCache.unpack(argsHash);
|
|
432
448
|
const enqueuedRequest = PublicCallRequest.from({
|
|
433
449
|
args,
|
|
434
450
|
callContext: derivedCallContext,
|
|
@@ -472,9 +488,12 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
472
488
|
isDelegateCall ? this.contractAddress : targetContractAddress,
|
|
473
489
|
portalContractAddress,
|
|
474
490
|
FunctionSelector.fromNameAndParameters(targetArtifact.name, targetArtifact.parameters),
|
|
491
|
+
this.callContext.gasLeft, // TODO(palla/gas): We should deduct DA and L1 gas used for the derived context
|
|
475
492
|
isDelegateCall,
|
|
476
493
|
isStaticCall,
|
|
477
494
|
startSideEffectCounter,
|
|
495
|
+
this.callContext.gasSettings,
|
|
496
|
+
this.callContext.transactionFee,
|
|
478
497
|
);
|
|
479
498
|
}
|
|
480
499
|
|
|
@@ -4,7 +4,7 @@ import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { witnessMapToFields } from '../acvm/deserialize.js';
|
|
8
8
|
import { Oracle, acvm, extractCallStack } from '../acvm/index.js';
|
|
9
9
|
import { ExecutionError } from '../common/errors.js';
|
|
10
10
|
import { type ClientExecutionContext } from './client_execution_context.js';
|
|
@@ -26,7 +26,7 @@ export async function executePrivateFunction(
|
|
|
26
26
|
const acir = artifact.bytecode;
|
|
27
27
|
const initialWitness = context.getInitialWitness(artifact);
|
|
28
28
|
const acvmCallback = new Oracle(context);
|
|
29
|
-
const
|
|
29
|
+
const acirExecutionResult = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, acvmCallback).catch(
|
|
30
30
|
(err: Error) => {
|
|
31
31
|
throw new ExecutionError(
|
|
32
32
|
err.message,
|
|
@@ -39,8 +39,8 @@ export async function executePrivateFunction(
|
|
|
39
39
|
);
|
|
40
40
|
},
|
|
41
41
|
);
|
|
42
|
-
|
|
43
|
-
const returnWitness =
|
|
42
|
+
const partialWitness = acirExecutionResult.partialWitness;
|
|
43
|
+
const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness);
|
|
44
44
|
const publicInputs = PrivateCircuitPublicInputs.fromFields(returnWitness);
|
|
45
45
|
|
|
46
46
|
const encryptedLogs = context.getEncryptedLogs();
|
|
@@ -55,9 +55,10 @@ export async function executePrivateFunction(
|
|
|
55
55
|
|
|
56
56
|
// Mocking the return type to be an array of 4 fields
|
|
57
57
|
// TODO: @LHerskind must be updated as we are progressing with the macros to get the information
|
|
58
|
-
const
|
|
58
|
+
const rawReturnValues = await context.unpackReturns(publicInputs.returnsHash);
|
|
59
|
+
const returnTypes: AbiType[] = [{ kind: 'array', length: rawReturnValues.length, type: { kind: 'field' } }];
|
|
59
60
|
const mockArtifact = { ...artifact, returnTypes };
|
|
60
|
-
const returnValues = decodeReturnValues(mockArtifact,
|
|
61
|
+
const returnValues = decodeReturnValues(mockArtifact, rawReturnValues);
|
|
61
62
|
|
|
62
63
|
const noteHashReadRequestPartialWitnesses = context.getNoteHashReadRequestPartialWitnesses(
|
|
63
64
|
publicInputs.noteHashReadRequests,
|
package/src/client/simulator.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
|
16
16
|
import { type WasmBlackBoxFunctionSolver, createBlackBoxSolver } from '@noir-lang/acvm_js';
|
|
17
17
|
|
|
18
18
|
import { createSimulationError } from '../common/errors.js';
|
|
19
|
-
import {
|
|
19
|
+
import { PackedValuesCache } from '../common/packed_values_cache.js';
|
|
20
20
|
import { ClientExecutionContext } from './client_execution_context.js';
|
|
21
21
|
import { type DBOracle } from './db_oracle.js';
|
|
22
22
|
import { ExecutionNoteCache } from './execution_note_cache.js';
|
|
@@ -89,14 +89,18 @@ export class AcirSimulator {
|
|
|
89
89
|
// reserve the first side effect for the tx hash (inserted by the private kernel)
|
|
90
90
|
const startSideEffectCounter = 1;
|
|
91
91
|
|
|
92
|
+
const transactionFee = Fr.ZERO;
|
|
92
93
|
const callContext = new CallContext(
|
|
93
94
|
msgSender,
|
|
94
95
|
contractAddress,
|
|
95
96
|
portalContractAddress,
|
|
96
97
|
FunctionSelector.fromNameAndParameters(entryPointArtifact.name, entryPointArtifact.parameters),
|
|
98
|
+
request.gasSettings.getInitialAvailable(),
|
|
97
99
|
false,
|
|
98
100
|
false,
|
|
99
101
|
startSideEffectCounter,
|
|
102
|
+
request.gasSettings,
|
|
103
|
+
transactionFee,
|
|
100
104
|
);
|
|
101
105
|
const context = new ClientExecutionContext(
|
|
102
106
|
contractAddress,
|
|
@@ -105,7 +109,7 @@ export class AcirSimulator {
|
|
|
105
109
|
callContext,
|
|
106
110
|
header,
|
|
107
111
|
request.authWitnesses,
|
|
108
|
-
|
|
112
|
+
PackedValuesCache.create(request.packedArguments),
|
|
109
113
|
new ExecutionNoteCache(),
|
|
110
114
|
this.db,
|
|
111
115
|
curve,
|
|
@@ -194,7 +198,7 @@ export class AcirSimulator {
|
|
|
194
198
|
const maxNoteFields = (artifact.parameters[artifact.parameters.length - 1].type as ArrayType).length;
|
|
195
199
|
if (maxNoteFields < note.items.length) {
|
|
196
200
|
throw new Error(
|
|
197
|
-
`The note being processed has ${note.items.length} fields, while "compute_note_hash_and_nullifier" can only handle a maximum of ${maxNoteFields} fields. Please
|
|
201
|
+
`The note being processed has ${note.items.length} fields, while "compute_note_hash_and_nullifier" can only handle a maximum of ${maxNoteFields} fields. Please reduce the number of fields in your note.`,
|
|
198
202
|
);
|
|
199
203
|
}
|
|
200
204
|
|
|
@@ -4,7 +4,7 @@ import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
|
4
4
|
import { type Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { witnessMapToFields } from '../acvm/deserialize.js';
|
|
8
8
|
import { Oracle, acvm, extractCallStack, toACVMWitness } from '../acvm/index.js';
|
|
9
9
|
import { ExecutionError } from '../common/errors.js';
|
|
10
10
|
import { AcirSimulator } from './simulator.js';
|
|
@@ -27,7 +27,7 @@ export async function executeUnconstrainedFunction(
|
|
|
27
27
|
|
|
28
28
|
const acir = artifact.bytecode;
|
|
29
29
|
const initialWitness = toACVMWitness(0, args);
|
|
30
|
-
const
|
|
30
|
+
const acirExecutionResult = await acvm(
|
|
31
31
|
await AcirSimulator.getSolver(),
|
|
32
32
|
acir,
|
|
33
33
|
initialWitness,
|
|
@@ -44,6 +44,7 @@ export async function executeUnconstrainedFunction(
|
|
|
44
44
|
);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
const returnWitness = witnessMapToFields(acirExecutionResult.returnWitness);
|
|
48
|
+
return decodeReturnValues(artifact, returnWitness);
|
|
48
49
|
}
|
|
49
50
|
// docs:end:execute_unconstrained_function
|
package/src/common/index.ts
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { PackedValues } from '@aztec/circuit-types';
|
|
2
|
+
import { Fr } from '@aztec/circuits.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A cache for packed values (arguments, returns) during transaction execution.
|
|
6
|
+
*/
|
|
7
|
+
export class PackedValuesCache {
|
|
8
|
+
private cache: Map<bigint, Fr[]>;
|
|
9
|
+
|
|
10
|
+
constructor(initialArguments: PackedValues[] = []) {
|
|
11
|
+
this.cache = new Map();
|
|
12
|
+
for (const initialArg of initialArguments) {
|
|
13
|
+
this.cache.set(initialArg.hash.toBigInt(), initialArg.values);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new packed values cache.
|
|
19
|
+
* @param initialArguments - The initial arguments to add to the cache.
|
|
20
|
+
* @returns The new packed values cache.
|
|
21
|
+
*/
|
|
22
|
+
public static create(initialArguments: PackedValues[] = []) {
|
|
23
|
+
return new PackedValuesCache(initialArguments);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Unpacks packed values.
|
|
28
|
+
* @param hash - The hash of the packed values.
|
|
29
|
+
* @returns The unpacked values.
|
|
30
|
+
*/
|
|
31
|
+
public unpack(hash: Fr): Fr[] {
|
|
32
|
+
if (hash.equals(Fr.ZERO)) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
const packedValues = this.cache.get(hash.value);
|
|
36
|
+
if (!packedValues) {
|
|
37
|
+
throw new Error(`Packed values for hash ${hash.toString()} not found in cache`);
|
|
38
|
+
}
|
|
39
|
+
return packedValues;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Packs values.
|
|
44
|
+
* @param values - The values to pack.
|
|
45
|
+
* @returns The hash of the packed values.
|
|
46
|
+
*/
|
|
47
|
+
public pack(values: Fr[]) {
|
|
48
|
+
if (values.length === 0) {
|
|
49
|
+
return Fr.ZERO;
|
|
50
|
+
}
|
|
51
|
+
const packedValues = PackedValues.fromValues(values);
|
|
52
|
+
this.cache.set(packedValues.hash.value, packedValues.values);
|
|
53
|
+
return packedValues.hash;
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/index.ts
CHANGED