@aztec/simulator 0.38.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/acvm/oracle/oracle.d.ts +3 -5
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +13 -32
- package/dest/acvm/oracle/typed_oracle.d.ts +3 -3
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +7 -7
- 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 +17 -11
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +5 -1
- package/dest/avm/avm_machine_state.d.ts +5 -8
- package/dest/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/avm/avm_machine_state.js +10 -22
- package/dest/avm/avm_message_call_result.d.ts +5 -8
- package/dest/avm/avm_message_call_result.d.ts.map +1 -1
- package/dest/avm/avm_message_call_result.js +1 -4
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +17 -13
- package/dest/avm/errors.d.ts +43 -2
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +86 -4
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +4 -3
- package/dest/avm/opcodes/conversion.d.ts +16 -0
- package/dest/avm/opcodes/conversion.d.ts.map +1 -0
- package/dest/avm/opcodes/conversion.js +48 -0
- package/dest/avm/opcodes/environment_getters.d.ts +12 -13
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +13 -49
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +11 -1
- package/dest/avm/opcodes/index.d.ts +2 -0
- package/dest/avm/opcodes/index.d.ts.map +1 -1
- package/dest/avm/opcodes/index.js +3 -1
- package/dest/avm/opcodes/misc.d.ts +17 -0
- package/dest/avm/opcodes/misc.d.ts.map +1 -0
- package/dest/avm/opcodes/misc.js +45 -0
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +6 -2
- package/dest/avm/serialization/instruction_serialization.d.ts +6 -4
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +9 -5
- package/dest/client/client_execution_context.d.ts +29 -1
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +54 -16
- package/dest/client/db_oracle.d.ts +1 -8
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/execution_result.d.ts +4 -1
- package/dest/client/execution_result.d.ts.map +1 -1
- package/dest/client/execution_result.js +16 -3
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +3 -1
- package/dest/client/simulator.d.ts +1 -31
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +3 -42
- package/dest/client/view_data_oracle.d.ts +0 -7
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +1 -10
- package/dest/common/errors.d.ts +5 -0
- package/dest/common/errors.d.ts.map +1 -1
- package/dest/common/errors.js +6 -1
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/public/abstract_phase_manager.d.ts +8 -4
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +38 -14
- package/dest/public/app_logic_phase_manager.d.ts +1 -0
- package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
- package/dest/public/app_logic_phase_manager.js +3 -3
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +1 -4
- package/dest/public/hints_builder.d.ts +3 -3
- package/dest/public/hints_builder.d.ts.map +1 -1
- package/dest/public/hints_builder.js +3 -3
- package/dest/public/public_execution_context.d.ts +1 -0
- package/dest/public/public_execution_context.d.ts.map +1 -1
- package/dest/public/public_execution_context.js +6 -2
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +5 -3
- package/dest/public/setup_phase_manager.d.ts +1 -0
- package/dest/public/setup_phase_manager.d.ts.map +1 -1
- package/dest/public/setup_phase_manager.js +3 -2
- package/dest/public/tail_phase_manager.d.ts +1 -0
- package/dest/public/tail_phase_manager.d.ts.map +1 -1
- package/dest/public/tail_phase_manager.js +2 -1
- package/dest/public/teardown_phase_manager.d.ts +1 -0
- package/dest/public/teardown_phase_manager.d.ts.map +1 -1
- package/dest/public/teardown_phase_manager.js +3 -2
- package/dest/public/transitional_adaptors.d.ts.map +1 -1
- package/dest/public/transitional_adaptors.js +1 -1
- package/dest/rollup/index.d.ts +2 -0
- package/dest/rollup/index.d.ts.map +1 -0
- package/dest/rollup/index.js +2 -0
- package/dest/rollup/rollup.d.ts +77 -0
- package/dest/rollup/rollup.d.ts.map +1 -0
- package/dest/rollup/rollup.js +78 -0
- package/dest/stats/index.d.ts +2 -0
- package/dest/stats/index.d.ts.map +1 -0
- package/dest/stats/index.js +2 -0
- package/dest/stats/stats.d.ts +4 -0
- package/dest/stats/stats.d.ts.map +1 -0
- package/dest/stats/stats.js +11 -0
- package/package.json +8 -8
- package/src/acvm/oracle/oracle.ts +27 -35
- package/src/acvm/oracle/typed_oracle.ts +16 -9
- package/src/avm/avm_execution_environment.ts +34 -42
- package/src/avm/avm_gas.ts +4 -0
- package/src/avm/avm_machine_state.ts +14 -25
- package/src/avm/avm_message_call_result.ts +3 -14
- package/src/avm/avm_simulator.ts +22 -12
- package/src/avm/errors.ts +94 -4
- package/src/avm/journal/journal.ts +3 -2
- package/src/avm/opcodes/conversion.ts +59 -0
- package/src/avm/opcodes/environment_getters.ts +13 -66
- package/src/avm/opcodes/external_calls.ts +11 -0
- package/src/avm/opcodes/index.ts +2 -0
- package/src/avm/opcodes/misc.ts +63 -0
- package/src/avm/serialization/bytecode_serialization.ts +7 -0
- package/src/avm/serialization/instruction_serialization.ts +4 -0
- package/src/client/client_execution_context.ts +92 -16
- package/src/client/db_oracle.ts +1 -9
- package/src/client/execution_result.ts +21 -2
- package/src/client/private_execution.ts +2 -0
- package/src/client/simulator.ts +2 -80
- package/src/client/view_data_oracle.ts +0 -10
- package/src/common/errors.ts +5 -0
- package/src/index.ts +1 -0
- package/src/public/abstract_phase_manager.ts +46 -18
- package/src/public/app_logic_phase_manager.ts +2 -1
- package/src/public/executor.ts +0 -4
- package/src/public/hints_builder.ts +5 -5
- package/src/public/public_execution_context.ts +6 -1
- package/src/public/public_processor.ts +8 -2
- package/src/public/setup_phase_manager.ts +16 -8
- package/src/public/tail_phase_manager.ts +6 -1
- package/src/public/teardown_phase_manager.ts +16 -8
- package/src/public/transitional_adaptors.ts +1 -0
- package/src/rollup/index.ts +1 -0
- package/src/rollup/rollup.ts +160 -0
- package/src/stats/index.ts +1 -0
- package/src/stats/stats.ts +20 -0
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { type Fr } from '@aztec/circuits.js';
|
|
2
|
-
|
|
3
1
|
import type { AvmContext } from '../avm_context.js';
|
|
4
2
|
import type { AvmExecutionEnvironment } from '../avm_execution_environment.js';
|
|
5
|
-
import { Field, type MemoryValue } from '../avm_memory_types.js';
|
|
3
|
+
import { Field, type MemoryValue, Uint64 } from '../avm_memory_types.js';
|
|
6
4
|
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
7
5
|
import { GetterInstruction } from './instruction_impl.js';
|
|
8
6
|
|
|
9
7
|
abstract class EnvironmentGetterInstruction extends GetterInstruction {
|
|
10
8
|
protected getValue(context: AvmContext): MemoryValue {
|
|
11
|
-
return
|
|
9
|
+
return this.getEnvironmentValue(context.environment);
|
|
12
10
|
}
|
|
13
11
|
|
|
14
|
-
protected abstract getEnvironmentValue(env: AvmExecutionEnvironment):
|
|
12
|
+
protected abstract getEnvironmentValue(env: AvmExecutionEnvironment): MemoryValue;
|
|
15
13
|
}
|
|
16
14
|
|
|
17
15
|
export class Address extends EnvironmentGetterInstruction {
|
|
@@ -19,7 +17,7 @@ export class Address extends EnvironmentGetterInstruction {
|
|
|
19
17
|
static readonly opcode: Opcode = Opcode.ADDRESS;
|
|
20
18
|
|
|
21
19
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
22
|
-
return env.address;
|
|
20
|
+
return new Field(env.address.toField());
|
|
23
21
|
}
|
|
24
22
|
}
|
|
25
23
|
|
|
@@ -28,7 +26,7 @@ export class StorageAddress extends EnvironmentGetterInstruction {
|
|
|
28
26
|
static readonly opcode: Opcode = Opcode.STORAGEADDRESS;
|
|
29
27
|
|
|
30
28
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
31
|
-
return env.storageAddress;
|
|
29
|
+
return new Field(env.storageAddress.toField());
|
|
32
30
|
}
|
|
33
31
|
}
|
|
34
32
|
|
|
@@ -37,7 +35,7 @@ export class Sender extends EnvironmentGetterInstruction {
|
|
|
37
35
|
static readonly opcode: Opcode = Opcode.SENDER;
|
|
38
36
|
|
|
39
37
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
40
|
-
return env.sender;
|
|
38
|
+
return new Field(env.sender.toField());
|
|
41
39
|
}
|
|
42
40
|
}
|
|
43
41
|
|
|
@@ -46,7 +44,7 @@ export class FeePerL2Gas extends EnvironmentGetterInstruction {
|
|
|
46
44
|
static readonly opcode: Opcode = Opcode.FEEPERL2GAS;
|
|
47
45
|
|
|
48
46
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
49
|
-
return env.feePerL2Gas;
|
|
47
|
+
return new Field(env.feePerL2Gas);
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
|
|
@@ -55,7 +53,7 @@ export class FeePerDAGas extends EnvironmentGetterInstruction {
|
|
|
55
53
|
static readonly opcode: Opcode = Opcode.FEEPERDAGAS;
|
|
56
54
|
|
|
57
55
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
58
|
-
return env.feePerDaGas;
|
|
56
|
+
return new Field(env.feePerDaGas);
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
59
|
|
|
@@ -64,7 +62,7 @@ export class TransactionFee extends EnvironmentGetterInstruction {
|
|
|
64
62
|
static readonly opcode: Opcode = Opcode.TRANSACTIONFEE;
|
|
65
63
|
|
|
66
64
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
67
|
-
return env.transactionFee;
|
|
65
|
+
return new Field(env.transactionFee);
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
|
|
@@ -73,7 +71,7 @@ export class ChainId extends EnvironmentGetterInstruction {
|
|
|
73
71
|
static readonly opcode: Opcode = Opcode.CHAINID;
|
|
74
72
|
|
|
75
73
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
76
|
-
return env.globals.chainId;
|
|
74
|
+
return new Field(env.globals.chainId);
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
77
|
|
|
@@ -82,7 +80,7 @@ export class Version extends EnvironmentGetterInstruction {
|
|
|
82
80
|
static readonly opcode: Opcode = Opcode.VERSION;
|
|
83
81
|
|
|
84
82
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
85
|
-
return env.globals.version;
|
|
83
|
+
return new Field(env.globals.version);
|
|
86
84
|
}
|
|
87
85
|
}
|
|
88
86
|
|
|
@@ -91,7 +89,7 @@ export class BlockNumber extends EnvironmentGetterInstruction {
|
|
|
91
89
|
static readonly opcode: Opcode = Opcode.BLOCKNUMBER;
|
|
92
90
|
|
|
93
91
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
94
|
-
return env.globals.blockNumber;
|
|
92
|
+
return new Field(env.globals.blockNumber);
|
|
95
93
|
}
|
|
96
94
|
}
|
|
97
95
|
|
|
@@ -100,57 +98,6 @@ export class Timestamp extends EnvironmentGetterInstruction {
|
|
|
100
98
|
static readonly opcode: Opcode = Opcode.TIMESTAMP;
|
|
101
99
|
|
|
102
100
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
103
|
-
return env.globals.timestamp;
|
|
101
|
+
return new Uint64(env.globals.timestamp.toBigInt());
|
|
104
102
|
}
|
|
105
103
|
}
|
|
106
|
-
|
|
107
|
-
// export class Coinbase extends EnvironmentGetterInstruction {
|
|
108
|
-
// static type: string = 'COINBASE';
|
|
109
|
-
// static numberOfOperands = 1;
|
|
110
|
-
|
|
111
|
-
// constructor(private destOffset: number) {
|
|
112
|
-
// super();
|
|
113
|
-
// }
|
|
114
|
-
|
|
115
|
-
// async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise<void> {
|
|
116
|
-
// const {coinbase} = machineState.executionEnvironment.globals;
|
|
117
|
-
|
|
118
|
-
// machineState.memory.set(this.destOffset, coinbase);
|
|
119
|
-
|
|
120
|
-
// this.incrementPc(machineState);
|
|
121
|
-
// }
|
|
122
|
-
// }
|
|
123
|
-
|
|
124
|
-
// export class BlockL2GasLimit extends EnvironmentGetterInstruction {
|
|
125
|
-
// static type: string = 'BLOCKL2GASLIMIT';
|
|
126
|
-
// static numberOfOperands = 1;
|
|
127
|
-
|
|
128
|
-
// constructor(private destOffset: number) {
|
|
129
|
-
// super();
|
|
130
|
-
// }
|
|
131
|
-
|
|
132
|
-
// async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise<void> {
|
|
133
|
-
// const {blockL2GasLimit} = machineState.executionEnvironment.globals;
|
|
134
|
-
|
|
135
|
-
// machineState.memory.set(this.destOffset, blockL2GasLimit);
|
|
136
|
-
|
|
137
|
-
// this.incrementPc(machineState);
|
|
138
|
-
// }
|
|
139
|
-
// }
|
|
140
|
-
|
|
141
|
-
// export class BlockDAGasLimit extends EnvironmentGetterInstruction {
|
|
142
|
-
// static type: string = 'BLOCKDAGASLIMIT';
|
|
143
|
-
// static numberOfOperands = 1;
|
|
144
|
-
|
|
145
|
-
// constructor(private destOffset: number) {
|
|
146
|
-
// super();
|
|
147
|
-
// }
|
|
148
|
-
|
|
149
|
-
// async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise<void> {
|
|
150
|
-
// const {blockDAGasLimit} = machineState.executionEnvironment.globals;
|
|
151
|
-
|
|
152
|
-
// machineState.memory.set(this.destOffset, blockDAGasLimit);
|
|
153
|
-
|
|
154
|
-
// this.incrementPc(machineState);
|
|
155
|
-
// }
|
|
156
|
-
// }
|
|
@@ -7,6 +7,7 @@ import { gasLeftToGas, sumGas } from '../avm_gas.js';
|
|
|
7
7
|
import { Field, Uint8 } from '../avm_memory_types.js';
|
|
8
8
|
import { type AvmContractCallResults } from '../avm_message_call_result.js';
|
|
9
9
|
import { AvmSimulator } from '../avm_simulator.js';
|
|
10
|
+
import { RethrownError } from '../errors.js';
|
|
10
11
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
11
12
|
import { Addressing } from './addressing_mode.js';
|
|
12
13
|
import { Instruction } from './instruction.js';
|
|
@@ -99,6 +100,16 @@ abstract class ExternalCall extends Instruction {
|
|
|
99
100
|
|
|
100
101
|
const success = !nestedCallResults.reverted;
|
|
101
102
|
|
|
103
|
+
// TRANSITIONAL: We rethrow here so that the MESSAGE gets propagated.
|
|
104
|
+
// This means that for now, the caller cannot recover from errors.
|
|
105
|
+
if (!success) {
|
|
106
|
+
if (!nestedCallResults.revertReason) {
|
|
107
|
+
throw new Error('A reverted nested call should be assigned a revert reason in the AVM execution loop');
|
|
108
|
+
}
|
|
109
|
+
// The nested call's revertReason will be used to track the stack of error causes down to the root.
|
|
110
|
+
throw new RethrownError(nestedCallResults.revertReason.message, nestedCallResults.revertReason);
|
|
111
|
+
}
|
|
112
|
+
|
|
102
113
|
// We only take as much data as was specified in the return size and pad with zeroes if the return data is smaller
|
|
103
114
|
// than the specified size in order to prevent that memory to be left with garbage
|
|
104
115
|
const returnData = nestedCallResults.output.slice(0, this.retSize);
|
package/src/avm/opcodes/index.ts
CHANGED
|
@@ -2,9 +2,11 @@ export * from './arithmetic.js';
|
|
|
2
2
|
export * from './bitwise.js';
|
|
3
3
|
export * from './control_flow.js';
|
|
4
4
|
export * from './contract.js';
|
|
5
|
+
export * from './conversion.js';
|
|
5
6
|
export * from './instruction.js';
|
|
6
7
|
export * from './comparators.js';
|
|
7
8
|
export * from './memory.js';
|
|
9
|
+
export * from './misc.js';
|
|
8
10
|
export * from './storage.js';
|
|
9
11
|
export * from './external_calls.js';
|
|
10
12
|
export * from './environment_getters.js';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { applyStringFormatting, createDebugLogger } from '@aztec/foundation/log';
|
|
2
|
+
|
|
3
|
+
import { type AvmContext } from '../avm_context.js';
|
|
4
|
+
import { TypeTag } 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 DebugLog extends Instruction {
|
|
10
|
+
static type: string = 'DEBUGLOG';
|
|
11
|
+
static readonly opcode: Opcode = Opcode.DEBUGLOG;
|
|
12
|
+
static readonly logger = createDebugLogger('aztec:avm_simulator:debug_log');
|
|
13
|
+
|
|
14
|
+
// Informs (de)serialization. See Instruction.deserialize.
|
|
15
|
+
static readonly wireFormat: OperandType[] = [
|
|
16
|
+
OperandType.UINT8, // Opcode
|
|
17
|
+
OperandType.UINT8, // Indirect
|
|
18
|
+
OperandType.UINT32, // message memory address
|
|
19
|
+
OperandType.UINT32, // message size
|
|
20
|
+
OperandType.UINT32, // fields memory address
|
|
21
|
+
OperandType.UINT32, // fields size address
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
private indirect: number,
|
|
26
|
+
private messageOffset: number,
|
|
27
|
+
private messageSize: number,
|
|
28
|
+
private fieldsOffset: number,
|
|
29
|
+
private fieldsSizeOffset: number,
|
|
30
|
+
) {
|
|
31
|
+
super();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
35
|
+
const memory = context.machineState.memory.track(this.type);
|
|
36
|
+
const [messageOffset, fieldsOffset, fieldsSizeOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
37
|
+
[this.messageOffset, this.fieldsOffset, this.fieldsSizeOffset],
|
|
38
|
+
memory,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const fieldsSize = memory.get(fieldsSizeOffset).toNumber();
|
|
42
|
+
memory.checkTagsRange(TypeTag.UINT8, messageOffset, this.messageSize);
|
|
43
|
+
memory.checkTagsRange(TypeTag.FIELD, fieldsOffset, fieldsSize);
|
|
44
|
+
|
|
45
|
+
const memoryOperations = { reads: 1 + fieldsSize + this.messageSize, writes: 0, indirect: this.indirect };
|
|
46
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
47
|
+
|
|
48
|
+
const rawMessage = memory.getSlice(messageOffset, this.messageSize);
|
|
49
|
+
const fields = memory.getSlice(fieldsOffset, fieldsSize);
|
|
50
|
+
|
|
51
|
+
// Interpret str<N> = [u8; N] to string.
|
|
52
|
+
const messageAsStr = rawMessage.map(field => String.fromCharCode(field.toNumber())).join('');
|
|
53
|
+
const formattedStr = applyStringFormatting(
|
|
54
|
+
messageAsStr,
|
|
55
|
+
fields.map(field => field.toFr()),
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
DebugLog.logger.verbose(formattedStr);
|
|
59
|
+
|
|
60
|
+
memory.assert(memoryOperations);
|
|
61
|
+
context.machineState.incrementPc();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
CalldataCopy,
|
|
12
12
|
Cast,
|
|
13
13
|
ChainId,
|
|
14
|
+
DebugLog,
|
|
14
15
|
Div,
|
|
15
16
|
EmitNoteHash,
|
|
16
17
|
EmitNullifier,
|
|
@@ -46,6 +47,7 @@ import {
|
|
|
46
47
|
StorageAddress,
|
|
47
48
|
Sub,
|
|
48
49
|
Timestamp,
|
|
50
|
+
ToRadixLE,
|
|
49
51
|
TransactionFee,
|
|
50
52
|
Version,
|
|
51
53
|
Xor,
|
|
@@ -131,11 +133,16 @@ const INSTRUCTION_SET = () =>
|
|
|
131
133
|
[Return.opcode, Return],
|
|
132
134
|
[Revert.opcode, Revert],
|
|
133
135
|
|
|
136
|
+
// Misc
|
|
137
|
+
[DebugLog.opcode, DebugLog],
|
|
138
|
+
|
|
134
139
|
// //// Gadgets
|
|
135
140
|
[Keccak.opcode, Keccak],
|
|
136
141
|
[Poseidon2.opcode, Poseidon2],
|
|
137
142
|
[Sha256.opcode, Sha256],
|
|
138
143
|
[Pedersen.opcode, Pedersen],
|
|
144
|
+
// Conversions
|
|
145
|
+
[ToRadixLE.opcode, ToRadixLE],
|
|
139
146
|
]);
|
|
140
147
|
|
|
141
148
|
interface Serializable {
|
|
@@ -69,11 +69,15 @@ export enum Opcode {
|
|
|
69
69
|
DELEGATECALL,
|
|
70
70
|
RETURN,
|
|
71
71
|
REVERT,
|
|
72
|
+
// Misc
|
|
73
|
+
DEBUGLOG,
|
|
72
74
|
// Gadgets
|
|
73
75
|
KECCAK,
|
|
74
76
|
POSEIDON2,
|
|
75
77
|
SHA256, // temp - may be removed, but alot of contracts rely on it
|
|
76
78
|
PEDERSEN, // temp - may be removed, but alot of contracts rely on it
|
|
79
|
+
// Conversion
|
|
80
|
+
TORADIXLE,
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
// Possible types for an instruction's operand in its wire format. (Keep in sync with CPP code.
|
|
@@ -24,7 +24,7 @@ import { computePublicDataTreeLeafSlot, computeUniqueNoteHash, siloNoteHash } fr
|
|
|
24
24
|
import { type FunctionAbi, type FunctionArtifact, countArgumentsSize } from '@aztec/foundation/abi';
|
|
25
25
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
26
26
|
import { Fr, type Point } from '@aztec/foundation/fields';
|
|
27
|
-
import { createDebugLogger } from '@aztec/foundation/log';
|
|
27
|
+
import { applyStringFormatting, createDebugLogger } from '@aztec/foundation/log';
|
|
28
28
|
|
|
29
29
|
import { type NoteData, toACVMWitness } from '../acvm/index.js';
|
|
30
30
|
import { type PackedValuesCache } from '../common/packed_values_cache.js';
|
|
@@ -63,6 +63,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
63
63
|
private unencryptedLogs: CountedLog<UnencryptedL2Log>[] = [];
|
|
64
64
|
private nestedExecutions: ExecutionResult[] = [];
|
|
65
65
|
private enqueuedPublicFunctionCalls: PublicCallRequest[] = [];
|
|
66
|
+
private publicTeardownFunctionCall: PublicCallRequest = PublicCallRequest.empty();
|
|
66
67
|
|
|
67
68
|
constructor(
|
|
68
69
|
contractAddress: AztecAddress,
|
|
@@ -173,6 +174,13 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
173
174
|
return this.enqueuedPublicFunctionCalls;
|
|
174
175
|
}
|
|
175
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Return the public teardown function call set during this execution.
|
|
179
|
+
*/
|
|
180
|
+
public getPublicTeardownFunctionCall() {
|
|
181
|
+
return this.publicTeardownFunctionCall;
|
|
182
|
+
}
|
|
183
|
+
|
|
176
184
|
/**
|
|
177
185
|
* Pack the given array of arguments.
|
|
178
186
|
* @param args - Arguments to pack
|
|
@@ -262,11 +270,11 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
262
270
|
|
|
263
271
|
notes.forEach(n => {
|
|
264
272
|
if (n.index !== undefined) {
|
|
265
|
-
const siloedNoteHash = siloNoteHash(n.contractAddress, n.innerNoteHash);
|
|
266
|
-
const uniqueSiloedNoteHash = computeUniqueNoteHash(n.nonce, siloedNoteHash);
|
|
267
273
|
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)
|
|
268
|
-
// Should always
|
|
269
|
-
const
|
|
274
|
+
// Should always call computeUniqueNoteHash when publicly created notes include nonces.
|
|
275
|
+
const uniqueNoteHash = n.nonce.isZero() ? n.innerNoteHash : computeUniqueNoteHash(n.nonce, n.innerNoteHash);
|
|
276
|
+
const siloedNoteHash = siloNoteHash(n.contractAddress, uniqueNoteHash);
|
|
277
|
+
const noteHashForReadRequest = siloedNoteHash;
|
|
270
278
|
this.noteHashLeafIndexMap.set(noteHashForReadRequest.toBigInt(), n.index);
|
|
271
279
|
}
|
|
272
280
|
});
|
|
@@ -465,9 +473,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
465
473
|
}
|
|
466
474
|
|
|
467
475
|
/**
|
|
468
|
-
* Creates a PublicCallStackItem object representing the request to call a public function.
|
|
469
|
-
* is actually called, since that must happen on the sequencer side. All the fields related to the result
|
|
470
|
-
* of the execution are empty.
|
|
476
|
+
* Creates a PublicCallStackItem object representing the request to call a public function.
|
|
471
477
|
* @param targetContractAddress - The address of the contract to call.
|
|
472
478
|
* @param functionSelector - The function selector of the function to call.
|
|
473
479
|
* @param argsHash - The packed arguments to pass to the function.
|
|
@@ -475,7 +481,8 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
475
481
|
* @param isStaticCall - Whether the call is a static call.
|
|
476
482
|
* @returns The public call stack item with the request information.
|
|
477
483
|
*/
|
|
478
|
-
|
|
484
|
+
protected async createPublicCallRequest(
|
|
485
|
+
callType: 'enqueued' | 'teardown',
|
|
479
486
|
targetContractAddress: AztecAddress,
|
|
480
487
|
functionSelector: FunctionSelector,
|
|
481
488
|
argsHash: Fr,
|
|
@@ -494,20 +501,51 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
494
501
|
isStaticCall,
|
|
495
502
|
);
|
|
496
503
|
const args = this.packedValuesCache.unpack(argsHash);
|
|
497
|
-
|
|
504
|
+
|
|
505
|
+
// TODO($846): if enqueued public calls are associated with global
|
|
506
|
+
// side-effect counter, that will leak info about how many other private
|
|
507
|
+
// side-effects occurred in the TX. Ultimately the private kernel should
|
|
508
|
+
// just output everything in the proper order without any counters.
|
|
509
|
+
this.log.verbose(
|
|
510
|
+
`Created PublicCallRequest of type [${callType}], side-effect counter [${sideEffectCounter}] to ${targetContractAddress}:${functionSelector}(${targetArtifact.name})`,
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
return PublicCallRequest.from({
|
|
498
514
|
args,
|
|
499
515
|
callContext: derivedCallContext,
|
|
500
516
|
parentCallContext: this.callContext,
|
|
501
517
|
functionData: FunctionData.fromAbi(targetArtifact),
|
|
502
518
|
contractAddress: targetContractAddress,
|
|
503
519
|
});
|
|
520
|
+
}
|
|
504
521
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
522
|
+
/**
|
|
523
|
+
* Creates and enqueues a PublicCallStackItem object representing the request to call a public function. No function
|
|
524
|
+
* is actually called, since that must happen on the sequencer side. All the fields related to the result
|
|
525
|
+
* of the execution are empty.
|
|
526
|
+
* @param targetContractAddress - The address of the contract to call.
|
|
527
|
+
* @param functionSelector - The function selector of the function to call.
|
|
528
|
+
* @param argsHash - The packed arguments to pass to the function.
|
|
529
|
+
* @param sideEffectCounter - The side effect counter at the start of the call.
|
|
530
|
+
* @param isStaticCall - Whether the call is a static call.
|
|
531
|
+
* @returns The public call stack item with the request information.
|
|
532
|
+
*/
|
|
533
|
+
public override async enqueuePublicFunctionCall(
|
|
534
|
+
targetContractAddress: AztecAddress,
|
|
535
|
+
functionSelector: FunctionSelector,
|
|
536
|
+
argsHash: Fr,
|
|
537
|
+
sideEffectCounter: number,
|
|
538
|
+
isStaticCall: boolean,
|
|
539
|
+
isDelegateCall: boolean,
|
|
540
|
+
): Promise<PublicCallRequest> {
|
|
541
|
+
const enqueuedRequest = await this.createPublicCallRequest(
|
|
542
|
+
'enqueued',
|
|
543
|
+
targetContractAddress,
|
|
544
|
+
functionSelector,
|
|
545
|
+
argsHash,
|
|
546
|
+
sideEffectCounter,
|
|
547
|
+
isStaticCall,
|
|
548
|
+
isDelegateCall,
|
|
511
549
|
);
|
|
512
550
|
|
|
513
551
|
this.enqueuedPublicFunctionCalls.push(enqueuedRequest);
|
|
@@ -515,6 +553,40 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
515
553
|
return enqueuedRequest;
|
|
516
554
|
}
|
|
517
555
|
|
|
556
|
+
/**
|
|
557
|
+
* Creates a PublicCallStackItem and sets it as the public teardown function. No function
|
|
558
|
+
* is actually called, since that must happen on the sequencer side. All the fields related to the result
|
|
559
|
+
* of the execution are empty.
|
|
560
|
+
* @param targetContractAddress - The address of the contract to call.
|
|
561
|
+
* @param functionSelector - The function selector of the function to call.
|
|
562
|
+
* @param argsHash - The packed arguments to pass to the function.
|
|
563
|
+
* @param sideEffectCounter - The side effect counter at the start of the call.
|
|
564
|
+
* @param isStaticCall - Whether the call is a static call.
|
|
565
|
+
* @returns The public call stack item with the request information.
|
|
566
|
+
*/
|
|
567
|
+
public override async setPublicTeardownFunctionCall(
|
|
568
|
+
targetContractAddress: AztecAddress,
|
|
569
|
+
functionSelector: FunctionSelector,
|
|
570
|
+
argsHash: Fr,
|
|
571
|
+
sideEffectCounter: number,
|
|
572
|
+
isStaticCall: boolean,
|
|
573
|
+
isDelegateCall: boolean,
|
|
574
|
+
): Promise<PublicCallRequest> {
|
|
575
|
+
const publicTeardownFunctionCall = await this.createPublicCallRequest(
|
|
576
|
+
'teardown',
|
|
577
|
+
targetContractAddress,
|
|
578
|
+
functionSelector,
|
|
579
|
+
argsHash,
|
|
580
|
+
sideEffectCounter,
|
|
581
|
+
isStaticCall,
|
|
582
|
+
isDelegateCall,
|
|
583
|
+
);
|
|
584
|
+
|
|
585
|
+
this.publicTeardownFunctionCall = publicTeardownFunctionCall;
|
|
586
|
+
|
|
587
|
+
return publicTeardownFunctionCall;
|
|
588
|
+
}
|
|
589
|
+
|
|
518
590
|
/**
|
|
519
591
|
* Derives the call context for a nested execution.
|
|
520
592
|
* @param targetContractAddress - The address of the contract being called.
|
|
@@ -570,4 +642,8 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
570
642
|
const aes128 = new Aes128();
|
|
571
643
|
return aes128.encryptBufferCBC(input, initializationVector, key);
|
|
572
644
|
}
|
|
645
|
+
|
|
646
|
+
public override debugLog(message: string, fields: Fr[]) {
|
|
647
|
+
this.log.verbose(`debug_log ${applyStringFormatting(message, fields)}`);
|
|
648
|
+
}
|
|
573
649
|
}
|
package/src/client/db_oracle.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { type CompleteAddress, type Header } from '@aztec/circuits.js';
|
|
9
9
|
import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi';
|
|
10
10
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
11
|
-
import { type Fr
|
|
11
|
+
import { type Fr } from '@aztec/foundation/fields';
|
|
12
12
|
import { type ContractInstance } from '@aztec/types/contracts';
|
|
13
13
|
|
|
14
14
|
import { type NoteData, type NullifierKeys } from '../acvm/index.js';
|
|
@@ -64,14 +64,6 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
64
64
|
*/
|
|
65
65
|
popCapsule(): Promise<Fr[]>;
|
|
66
66
|
|
|
67
|
-
/**
|
|
68
|
-
* Gets public keys for an address.
|
|
69
|
-
* @param The address to look up
|
|
70
|
-
* @returns The public keys for a specific address
|
|
71
|
-
* TODO(#5834): Replace with `getCompleteAddress`.
|
|
72
|
-
*/
|
|
73
|
-
getPublicKeysForAddress(address: AztecAddress): Promise<Point[]>;
|
|
74
|
-
|
|
75
67
|
/**
|
|
76
68
|
* Retrieve nullifier keys associated with a specific account and app/contract address.
|
|
77
69
|
*
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
UnencryptedFunctionL2Logs,
|
|
6
6
|
type UnencryptedL2Log,
|
|
7
7
|
} from '@aztec/circuit-types';
|
|
8
|
-
import { type IsEmpty, type PrivateCallStackItem,
|
|
8
|
+
import { type IsEmpty, type PrivateCallStackItem, PublicCallRequest, sortByCounter } from '@aztec/circuits.js';
|
|
9
9
|
import { type Fr } from '@aztec/foundation/fields';
|
|
10
10
|
|
|
11
11
|
import { type ACVMField } from '../acvm/index.js';
|
|
@@ -56,6 +56,8 @@ export interface ExecutionResult {
|
|
|
56
56
|
nestedExecutions: this[];
|
|
57
57
|
/** Enqueued public function execution requests to be picked up by the sequencer. */
|
|
58
58
|
enqueuedPublicFunctionCalls: PublicCallRequest[];
|
|
59
|
+
/** Public function execution requested for teardown */
|
|
60
|
+
publicTeardownFunctionCall: PublicCallRequest;
|
|
59
61
|
/**
|
|
60
62
|
* Encrypted logs emitted during execution of this function call.
|
|
61
63
|
* Note: These are preimages to `encryptedLogsHashes`.
|
|
@@ -130,6 +132,23 @@ export function collectEnqueuedPublicFunctionCalls(execResult: ExecutionResult):
|
|
|
130
132
|
// as the kernel processes it like a stack, popping items off and pushing them to output
|
|
131
133
|
return [
|
|
132
134
|
...execResult.enqueuedPublicFunctionCalls,
|
|
133
|
-
...
|
|
135
|
+
...execResult.nestedExecutions.flatMap(collectEnqueuedPublicFunctionCalls),
|
|
134
136
|
].sort((a, b) => b.callContext.sideEffectCounter - a.callContext.sideEffectCounter);
|
|
135
137
|
}
|
|
138
|
+
|
|
139
|
+
export function collectPublicTeardownFunctionCall(execResult: ExecutionResult): PublicCallRequest {
|
|
140
|
+
const teardownCalls = [
|
|
141
|
+
execResult.publicTeardownFunctionCall,
|
|
142
|
+
...execResult.nestedExecutions.flatMap(collectPublicTeardownFunctionCall),
|
|
143
|
+
].filter(call => !call.isEmpty());
|
|
144
|
+
|
|
145
|
+
if (teardownCalls.length === 1) {
|
|
146
|
+
return teardownCalls[0];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (teardownCalls.length > 1) {
|
|
150
|
+
throw new Error('Multiple public teardown calls detected');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return PublicCallRequest.empty();
|
|
154
|
+
}
|
|
@@ -54,6 +54,7 @@ export async function executePrivateFunction(
|
|
|
54
54
|
const nullifiedNoteHashCounters = context.getNullifiedNoteHashCounters();
|
|
55
55
|
const nestedExecutions = context.getNestedExecutions();
|
|
56
56
|
const enqueuedPublicFunctionCalls = context.getEnqueuedPublicFunctionCalls();
|
|
57
|
+
const publicTeardownFunctionCall = context.getPublicTeardownFunctionCall();
|
|
57
58
|
|
|
58
59
|
log.debug(`Returning from call to ${contractAddress.toString()}:${functionSelector}`);
|
|
59
60
|
|
|
@@ -68,6 +69,7 @@ export async function executePrivateFunction(
|
|
|
68
69
|
vk: Buffer.from(artifact.verificationKey!, 'hex'),
|
|
69
70
|
nestedExecutions,
|
|
70
71
|
enqueuedPublicFunctionCalls,
|
|
72
|
+
publicTeardownFunctionCall,
|
|
71
73
|
encryptedLogs,
|
|
72
74
|
unencryptedLogs,
|
|
73
75
|
};
|
package/src/client/simulator.ts
CHANGED
|
@@ -200,7 +200,7 @@ export class AcirSimulator {
|
|
|
200
200
|
args: encodeArguments(artifact, [contractAddress, nonce, storageSlot, noteTypeId, extendedNoteItems]),
|
|
201
201
|
};
|
|
202
202
|
|
|
203
|
-
const [innerNoteHash,
|
|
203
|
+
const [innerNoteHash, uniqueNoteHash, siloedNoteHash, innerNullifier] = (await this.runUnconstrained(
|
|
204
204
|
execRequest,
|
|
205
205
|
artifact,
|
|
206
206
|
contractAddress,
|
|
@@ -208,8 +208,8 @@ export class AcirSimulator {
|
|
|
208
208
|
|
|
209
209
|
return {
|
|
210
210
|
innerNoteHash: new Fr(innerNoteHash),
|
|
211
|
+
uniqueNoteHash: new Fr(uniqueNoteHash),
|
|
211
212
|
siloedNoteHash: new Fr(siloedNoteHash),
|
|
212
|
-
uniqueSiloedNoteHash: new Fr(uniqueSiloedNoteHash),
|
|
213
213
|
innerNullifier: new Fr(innerNullifier),
|
|
214
214
|
};
|
|
215
215
|
}
|
|
@@ -232,82 +232,4 @@ export class AcirSimulator {
|
|
|
232
232
|
);
|
|
233
233
|
return innerNoteHash;
|
|
234
234
|
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Computes the unique note hash of a note.
|
|
238
|
-
* @param contractAddress - The address of the contract.
|
|
239
|
-
* @param nonce - The nonce of the note hash.
|
|
240
|
-
* @param storageSlot - The storage slot.
|
|
241
|
-
* @param noteTypeId - The note type identifier.
|
|
242
|
-
* @param note - The note.
|
|
243
|
-
* @returns The note hash.
|
|
244
|
-
*/
|
|
245
|
-
public async computeUniqueSiloedNoteHash(
|
|
246
|
-
contractAddress: AztecAddress,
|
|
247
|
-
nonce: Fr,
|
|
248
|
-
storageSlot: Fr,
|
|
249
|
-
noteTypeId: Fr,
|
|
250
|
-
note: Note,
|
|
251
|
-
) {
|
|
252
|
-
const { uniqueSiloedNoteHash } = await this.computeNoteHashAndNullifier(
|
|
253
|
-
contractAddress,
|
|
254
|
-
nonce,
|
|
255
|
-
storageSlot,
|
|
256
|
-
noteTypeId,
|
|
257
|
-
note,
|
|
258
|
-
);
|
|
259
|
-
return uniqueSiloedNoteHash;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Computes the siloed note hash of a note.
|
|
264
|
-
* @param contractAddress - The address of the contract.
|
|
265
|
-
* @param nonce - The nonce of the note hash.
|
|
266
|
-
* @param storageSlot - The storage slot.
|
|
267
|
-
* @param noteTypeId - The note type identifier.
|
|
268
|
-
* @param note - The note.
|
|
269
|
-
* @returns The note hash.
|
|
270
|
-
*/
|
|
271
|
-
public async computeSiloedNoteHash(
|
|
272
|
-
contractAddress: AztecAddress,
|
|
273
|
-
nonce: Fr,
|
|
274
|
-
storageSlot: Fr,
|
|
275
|
-
noteTypeId: Fr,
|
|
276
|
-
note: Note,
|
|
277
|
-
) {
|
|
278
|
-
const { siloedNoteHash } = await this.computeNoteHashAndNullifier(
|
|
279
|
-
contractAddress,
|
|
280
|
-
nonce,
|
|
281
|
-
storageSlot,
|
|
282
|
-
noteTypeId,
|
|
283
|
-
note,
|
|
284
|
-
);
|
|
285
|
-
return siloedNoteHash;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Computes the inner note hash of a note, which contains storage slot and the custom note hash.
|
|
290
|
-
* @param contractAddress - The address of the contract.
|
|
291
|
-
* @param nonce - The nonce of the unique note hash.
|
|
292
|
-
* @param storageSlot - The storage slot.
|
|
293
|
-
* @param noteTypeId - The note type identifier.
|
|
294
|
-
* @param note - The note.
|
|
295
|
-
* @returns The note hash.
|
|
296
|
-
*/
|
|
297
|
-
public async computeInnerNullifier(
|
|
298
|
-
contractAddress: AztecAddress,
|
|
299
|
-
nonce: Fr,
|
|
300
|
-
storageSlot: Fr,
|
|
301
|
-
noteTypeId: Fr,
|
|
302
|
-
note: Note,
|
|
303
|
-
) {
|
|
304
|
-
const { innerNullifier } = await this.computeNoteHashAndNullifier(
|
|
305
|
-
contractAddress,
|
|
306
|
-
nonce,
|
|
307
|
-
storageSlot,
|
|
308
|
-
noteTypeId,
|
|
309
|
-
note,
|
|
310
|
-
);
|
|
311
|
-
return innerNullifier;
|
|
312
|
-
}
|
|
313
235
|
}
|