@aztec/simulator 0.60.0 → 0.62.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 -0
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +12 -1
- package/dest/acvm/oracle/typed_oracle.d.ts +4 -1
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +10 -1
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +8 -5
- 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 +3 -1
- package/dest/avm/avm_simulator.d.ts +15 -0
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +45 -4
- package/dest/avm/fixtures/index.d.ts +1 -1
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +7 -7
- package/dest/avm/journal/journal.d.ts +5 -6
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +42 -17
- package/dest/avm/opcodes/contract.d.ts +8 -1
- package/dest/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/avm/opcodes/contract.js +41 -21
- package/dest/avm/opcodes/control_flow.js +5 -5
- package/dest/avm/opcodes/conversion.d.ts +1 -1
- package/dest/avm/opcodes/conversion.d.ts.map +1 -1
- package/dest/avm/opcodes/conversion.js +12 -9
- package/dest/avm/opcodes/environment_getters.d.ts +1 -1
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +5 -1
- package/dest/avm/opcodes/external_calls.d.ts +3 -6
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +23 -43
- package/dest/avm/opcodes/memory.d.ts +20 -0
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +59 -3
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +5 -3
- package/dest/avm/serialization/instruction_serialization.d.ts +36 -34
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +37 -35
- package/dest/avm/test_utils.d.ts +2 -1
- package/dest/avm/test_utils.d.ts.map +1 -1
- package/dest/avm/test_utils.js +4 -1
- package/dest/client/client_execution_context.d.ts +1 -8
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +4 -18
- package/dest/client/db_oracle.d.ts +24 -1
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/db_oracle.js +1 -1
- package/dest/client/view_data_oracle.d.ts +17 -1
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +21 -1
- package/dest/common/index.d.ts +0 -1
- package/dest/common/index.d.ts.map +1 -1
- package/dest/common/index.js +1 -2
- package/dest/public/dual_side_effect_trace.d.ts +3 -5
- package/dest/public/dual_side_effect_trace.d.ts.map +1 -1
- package/dest/public/dual_side_effect_trace.js +8 -4
- package/dest/public/enqueued_call_side_effect_trace.d.ts +4 -6
- package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
- package/dest/public/enqueued_call_side_effect_trace.js +19 -7
- package/dest/public/enqueued_call_simulator.d.ts +2 -2
- package/dest/public/enqueued_call_simulator.d.ts.map +1 -1
- package/dest/public/enqueued_call_simulator.js +21 -29
- package/dest/public/enqueued_calls_processor.d.ts +2 -3
- package/dest/public/enqueued_calls_processor.d.ts.map +1 -1
- package/dest/public/enqueued_calls_processor.js +18 -25
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +10 -15
- package/dest/public/public_kernel.d.ts +0 -1
- package/dest/public/public_kernel.d.ts.map +1 -1
- package/dest/public/public_kernel.js +5 -8
- package/dest/public/public_kernel_tail_simulator.d.ts +1 -5
- package/dest/public/public_kernel_tail_simulator.d.ts.map +1 -1
- package/dest/public/public_kernel_tail_simulator.js +6 -12
- package/dest/public/public_processor.js +4 -4
- package/dest/public/side_effect_trace.d.ts +4 -3
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +27 -16
- package/dest/public/side_effect_trace_interface.d.ts +3 -3
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/test/utils.d.ts +2 -2
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +4 -4
- package/package.json +9 -9
- package/src/acvm/oracle/oracle.ts +20 -0
- package/src/acvm/oracle/typed_oracle.ts +13 -0
- package/src/avm/avm_gas.ts +7 -4
- package/src/avm/avm_machine_state.ts +2 -0
- package/src/avm/avm_simulator.ts +69 -6
- package/src/avm/fixtures/index.ts +7 -7
- package/src/avm/journal/journal.ts +62 -19
- package/src/avm/opcodes/contract.ts +45 -21
- package/src/avm/opcodes/control_flow.ts +5 -5
- package/src/avm/opcodes/conversion.ts +9 -6
- package/src/avm/opcodes/environment_getters.ts +7 -2
- package/src/avm/opcodes/external_calls.ts +21 -45
- package/src/avm/opcodes/memory.ts +69 -2
- package/src/avm/serialization/bytecode_serialization.ts +6 -2
- package/src/avm/serialization/instruction_serialization.ts +5 -3
- package/src/avm/test_utils.ts +5 -1
- package/src/client/client_execution_context.ts +4 -27
- package/src/client/db_oracle.ts +38 -0
- package/src/client/view_data_oracle.ts +31 -1
- package/src/common/index.ts +0 -1
- package/src/public/dual_side_effect_trace.ts +20 -6
- package/src/public/enqueued_call_side_effect_trace.ts +46 -8
- package/src/public/enqueued_call_simulator.ts +42 -26
- package/src/public/enqueued_calls_processor.ts +26 -38
- package/src/public/public_db_sources.ts +10 -15
- package/src/public/public_kernel.ts +9 -12
- package/src/public/public_kernel_tail_simulator.ts +6 -15
- package/src/public/public_processor.ts +3 -3
- package/src/public/side_effect_trace.ts +54 -15
- package/src/public/side_effect_trace_interface.ts +9 -4
- package/src/test/utils.ts +9 -2
- package/dest/client/test_utils.d.ts +0 -9
- package/dest/client/test_utils.d.ts.map +0 -1
- package/dest/client/test_utils.js +0 -27
- package/dest/common/side_effect_counter.d.ts +0 -10
- package/dest/common/side_effect_counter.d.ts.map +0 -1
- package/dest/common/side_effect_counter.js +0 -18
- package/dest/rollup/index.d.ts +0 -2
- package/dest/rollup/index.d.ts.map +0 -1
- package/dest/rollup/index.js +0 -2
- package/dest/rollup/rollup.d.ts +0 -101
- package/dest/rollup/rollup.d.ts.map +0 -1
- package/dest/rollup/rollup.js +0 -100
- package/src/client/test_utils.ts +0 -57
- package/src/common/side_effect_counter.ts +0 -17
- package/src/rollup/index.ts +0 -1
- package/src/rollup/rollup.ts +0 -228
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { FunctionSelector, Gas } from '@aztec/circuits.js';
|
|
2
|
-
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
1
|
+
import { Fr, FunctionSelector, Gas, PUBLIC_DISPATCH_SELECTOR } from '@aztec/circuits.js';
|
|
3
2
|
|
|
4
3
|
import type { AvmContext } from '../avm_context.js';
|
|
5
4
|
import { type AvmContractCallResult } from '../avm_contract_call_result.js';
|
|
6
5
|
import { gasLeftToGas } from '../avm_gas.js';
|
|
7
|
-
import { Field, TypeTag,
|
|
6
|
+
import { type Field, TypeTag, Uint1 } from '../avm_memory_types.js';
|
|
8
7
|
import { AvmSimulator } from '../avm_simulator.js';
|
|
9
8
|
import { RethrownError } from '../errors.js';
|
|
10
9
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
@@ -21,58 +20,39 @@ abstract class ExternalCall extends Instruction {
|
|
|
21
20
|
OperandType.UINT16,
|
|
22
21
|
OperandType.UINT16,
|
|
23
22
|
OperandType.UINT16,
|
|
24
|
-
OperandType.UINT16,
|
|
25
|
-
OperandType.UINT16,
|
|
26
|
-
OperandType.UINT16,
|
|
27
23
|
];
|
|
28
24
|
|
|
29
25
|
constructor(
|
|
30
26
|
private indirect: number,
|
|
31
|
-
private gasOffset: number
|
|
27
|
+
private gasOffset: number,
|
|
32
28
|
private addrOffset: number,
|
|
33
29
|
private argsOffset: number,
|
|
34
30
|
private argsSizeOffset: number,
|
|
35
|
-
private retOffset: number,
|
|
36
|
-
private retSize: number,
|
|
37
31
|
private successOffset: number,
|
|
38
|
-
// NOTE: Function selector is likely temporary since eventually public contract bytecode will be one
|
|
39
|
-
// blob containing all functions, and function selector will become an application-level mechanism
|
|
40
|
-
// (e.g. first few bytes of calldata + compiler-generated jump table)
|
|
41
|
-
private functionSelectorOffset: number,
|
|
42
32
|
) {
|
|
43
33
|
super();
|
|
44
34
|
}
|
|
45
35
|
|
|
46
36
|
public async execute(context: AvmContext) {
|
|
47
37
|
const memory = context.machineState.memory.track(this.type);
|
|
48
|
-
const operands = [
|
|
49
|
-
this.gasOffset,
|
|
50
|
-
this.addrOffset,
|
|
51
|
-
this.argsOffset,
|
|
52
|
-
this.argsSizeOffset,
|
|
53
|
-
this.retOffset,
|
|
54
|
-
this.successOffset,
|
|
55
|
-
this.functionSelectorOffset,
|
|
56
|
-
];
|
|
38
|
+
const operands = [this.gasOffset, this.addrOffset, this.argsOffset, this.argsSizeOffset, this.successOffset];
|
|
57
39
|
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
58
|
-
const [gasOffset, addrOffset, argsOffset, argsSizeOffset,
|
|
59
|
-
addressing.resolve(operands, memory);
|
|
40
|
+
const [gasOffset, addrOffset, argsOffset, argsSizeOffset, successOffset] = addressing.resolve(operands, memory);
|
|
60
41
|
memory.checkTags(TypeTag.FIELD, gasOffset, gasOffset + 1);
|
|
61
42
|
memory.checkTag(TypeTag.FIELD, addrOffset);
|
|
62
43
|
memory.checkTag(TypeTag.UINT32, argsSizeOffset);
|
|
63
|
-
memory.checkTag(TypeTag.FIELD, functionSelectorOffset);
|
|
64
44
|
|
|
65
45
|
const calldataSize = memory.get(argsSizeOffset).toNumber();
|
|
66
46
|
memory.checkTagsRange(TypeTag.FIELD, argsOffset, calldataSize);
|
|
67
47
|
|
|
68
48
|
const callAddress = memory.getAs<Field>(addrOffset);
|
|
69
49
|
const calldata = memory.getSlice(argsOffset, calldataSize).map(f => f.toFr());
|
|
70
|
-
const functionSelector =
|
|
50
|
+
const functionSelector = new Fr(PUBLIC_DISPATCH_SELECTOR);
|
|
71
51
|
// If we are already in a static call, we propagate the environment.
|
|
72
52
|
const callType = context.environment.isStaticCall ? 'STATICCALL' : this.type;
|
|
73
53
|
|
|
74
54
|
// First we consume the gas for this operation.
|
|
75
|
-
context.machineState.consumeGas(this.gasCost(calldataSize
|
|
55
|
+
context.machineState.consumeGas(this.gasCost(calldataSize));
|
|
76
56
|
// Then we consume the gas allocated for the nested call. The excess will be refunded later.
|
|
77
57
|
// Gas allocation is capped by the amount of gas left in the current context.
|
|
78
58
|
// We have to do some dancing here because the gas allocation is a field,
|
|
@@ -106,18 +86,12 @@ abstract class ExternalCall extends Instruction {
|
|
|
106
86
|
throw new RethrownError(nestedCallResults.revertReason.message, nestedCallResults.revertReason);
|
|
107
87
|
}
|
|
108
88
|
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const convertedReturnData = padArrayEnd(
|
|
113
|
-
returnData.map(f => new Field(f)),
|
|
114
|
-
new Field(0),
|
|
115
|
-
this.retSize,
|
|
116
|
-
);
|
|
89
|
+
// Save return/revert data for later.
|
|
90
|
+
const fullReturnData = nestedCallResults.output;
|
|
91
|
+
context.machineState.nestedReturndata = fullReturnData;
|
|
117
92
|
|
|
118
|
-
// Write our
|
|
119
|
-
memory.set(successOffset, new
|
|
120
|
-
memory.setSlice(retOffset, convertedReturnData);
|
|
93
|
+
// Write our success flag into memory.
|
|
94
|
+
memory.set(successOffset, new Uint1(success ? 1 : 0));
|
|
121
95
|
|
|
122
96
|
// Refund unused gas
|
|
123
97
|
context.machineState.refundGas(gasLeftToGas(nestedContext.machineState));
|
|
@@ -132,7 +106,7 @@ abstract class ExternalCall extends Instruction {
|
|
|
132
106
|
/*avmCallResults=*/ nestedCallResults,
|
|
133
107
|
);
|
|
134
108
|
|
|
135
|
-
memory.assert({ reads: calldataSize +
|
|
109
|
+
memory.assert({ reads: calldataSize + 4, writes: 1, addressing });
|
|
136
110
|
context.machineState.incrementPc();
|
|
137
111
|
}
|
|
138
112
|
|
|
@@ -204,22 +178,24 @@ export class Revert extends Instruction {
|
|
|
204
178
|
OperandType.UINT16,
|
|
205
179
|
];
|
|
206
180
|
|
|
207
|
-
constructor(private indirect: number, private returnOffset: number, private
|
|
181
|
+
constructor(private indirect: number, private returnOffset: number, private retSizeOffset: number) {
|
|
208
182
|
super();
|
|
209
183
|
}
|
|
210
184
|
|
|
211
185
|
public async execute(context: AvmContext): Promise<void> {
|
|
212
186
|
const memory = context.machineState.memory.track(this.type);
|
|
213
|
-
context.machineState.consumeGas(this.gasCost(this.retSize));
|
|
214
187
|
|
|
215
|
-
const operands = [this.returnOffset];
|
|
188
|
+
const operands = [this.returnOffset, this.retSizeOffset];
|
|
216
189
|
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
217
|
-
const [returnOffset] = addressing.resolve(operands, memory);
|
|
190
|
+
const [returnOffset, retSizeOffset] = addressing.resolve(operands, memory);
|
|
218
191
|
|
|
219
|
-
|
|
192
|
+
memory.checkTag(TypeTag.UINT32, retSizeOffset);
|
|
193
|
+
const retSize = memory.get(retSizeOffset).toNumber();
|
|
194
|
+
context.machineState.consumeGas(this.gasCost(retSize));
|
|
195
|
+
const output = memory.getSlice(returnOffset, retSize).map(word => word.toFr());
|
|
220
196
|
|
|
221
197
|
context.machineState.revert(output);
|
|
222
|
-
memory.assert({ reads:
|
|
198
|
+
memory.assert({ reads: retSize + 1, addressing });
|
|
223
199
|
}
|
|
224
200
|
}
|
|
225
201
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
|
-
import { Field, TaggedMemory } from '../avm_memory_types.js';
|
|
2
|
+
import { Field, TaggedMemory, TypeTag, Uint32 } from '../avm_memory_types.js';
|
|
3
3
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
4
4
|
import { Addressing } from './addressing_mode.js';
|
|
5
5
|
import { Instruction } from './instruction.js';
|
|
@@ -179,11 +179,11 @@ export class CalldataCopy extends Instruction {
|
|
|
179
179
|
|
|
180
180
|
public async execute(context: AvmContext): Promise<void> {
|
|
181
181
|
const memory = context.machineState.memory.track(this.type);
|
|
182
|
-
// 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.
|
|
183
182
|
const operands = [this.cdStartOffset, this.copySizeOffset, this.dstOffset];
|
|
184
183
|
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
185
184
|
const [cdStartOffset, copySizeOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
186
185
|
|
|
186
|
+
memory.checkTags(TypeTag.UINT32, cdStartOffset, copySizeOffset);
|
|
187
187
|
const cdStart = memory.get(cdStartOffset).toNumber();
|
|
188
188
|
const copySize = memory.get(copySizeOffset).toNumber();
|
|
189
189
|
context.machineState.consumeGas(this.gasCost(copySize));
|
|
@@ -196,3 +196,70 @@ export class CalldataCopy extends Instruction {
|
|
|
196
196
|
context.machineState.incrementPc();
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
+
|
|
200
|
+
export class ReturndataSize extends Instruction {
|
|
201
|
+
static readonly type: string = 'RETURNDATASIZE';
|
|
202
|
+
static readonly opcode: Opcode = Opcode.RETURNDATASIZE;
|
|
203
|
+
// Informs (de)serialization. See Instruction.deserialize.
|
|
204
|
+
static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16];
|
|
205
|
+
|
|
206
|
+
constructor(private indirect: number, private dstOffset: number) {
|
|
207
|
+
super();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
211
|
+
const memory = context.machineState.memory.track(this.type);
|
|
212
|
+
const operands = [this.dstOffset];
|
|
213
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
214
|
+
const [dstOffset] = addressing.resolve(operands, memory);
|
|
215
|
+
context.machineState.consumeGas(this.gasCost());
|
|
216
|
+
|
|
217
|
+
memory.set(dstOffset, new Uint32(context.machineState.nestedReturndata.length));
|
|
218
|
+
|
|
219
|
+
memory.assert({ writes: 1, addressing });
|
|
220
|
+
context.machineState.incrementPc();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export class ReturndataCopy extends Instruction {
|
|
225
|
+
static readonly type: string = 'RETURNDATACOPY';
|
|
226
|
+
static readonly opcode: Opcode = Opcode.RETURNDATACOPY;
|
|
227
|
+
// Informs (de)serialization. See Instruction.deserialize.
|
|
228
|
+
static readonly wireFormat: OperandType[] = [
|
|
229
|
+
OperandType.UINT8,
|
|
230
|
+
OperandType.UINT8,
|
|
231
|
+
OperandType.UINT16,
|
|
232
|
+
OperandType.UINT16,
|
|
233
|
+
OperandType.UINT16,
|
|
234
|
+
];
|
|
235
|
+
|
|
236
|
+
constructor(
|
|
237
|
+
private indirect: number,
|
|
238
|
+
private rdStartOffset: number,
|
|
239
|
+
private copySizeOffset: number,
|
|
240
|
+
private dstOffset: number,
|
|
241
|
+
) {
|
|
242
|
+
super();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
public async execute(context: AvmContext): Promise<void> {
|
|
246
|
+
const memory = context.machineState.memory.track(this.type);
|
|
247
|
+
const operands = [this.rdStartOffset, this.copySizeOffset, this.dstOffset];
|
|
248
|
+
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
249
|
+
const [rdStartOffset, copySizeOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
250
|
+
|
|
251
|
+
memory.checkTags(TypeTag.UINT32, rdStartOffset, copySizeOffset);
|
|
252
|
+
const rdStart = memory.get(rdStartOffset).toNumber();
|
|
253
|
+
const copySize = memory.get(copySizeOffset).toNumber();
|
|
254
|
+
context.machineState.consumeGas(this.gasCost(copySize));
|
|
255
|
+
|
|
256
|
+
const transformedData = context.machineState.nestedReturndata
|
|
257
|
+
.slice(rdStart, rdStart + copySize)
|
|
258
|
+
.map(f => new Field(f));
|
|
259
|
+
|
|
260
|
+
memory.setSlice(dstOffset, transformedData);
|
|
261
|
+
|
|
262
|
+
memory.assert({ reads: 2, writes: copySize, addressing });
|
|
263
|
+
context.machineState.incrementPc();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
@@ -31,6 +31,8 @@ import {
|
|
|
31
31
|
Or,
|
|
32
32
|
Poseidon2,
|
|
33
33
|
Return,
|
|
34
|
+
ReturndataCopy,
|
|
35
|
+
ReturndataSize,
|
|
34
36
|
Revert,
|
|
35
37
|
SLoad,
|
|
36
38
|
SStore,
|
|
@@ -41,7 +43,7 @@ import {
|
|
|
41
43
|
Shr,
|
|
42
44
|
StaticCall,
|
|
43
45
|
Sub,
|
|
44
|
-
|
|
46
|
+
ToRadixBE,
|
|
45
47
|
Xor,
|
|
46
48
|
} from '../opcodes/index.js';
|
|
47
49
|
import { MultiScalarMul } from '../opcodes/multi_scalar_mul.js';
|
|
@@ -96,6 +98,8 @@ const INSTRUCTION_SET = () =>
|
|
|
96
98
|
// Execution Environment
|
|
97
99
|
[Opcode.GETENVVAR_16, GetEnvVar.as(GetEnvVar.wireFormat16).deserialize],
|
|
98
100
|
[CalldataCopy.opcode, Instruction.deserialize.bind(CalldataCopy)],
|
|
101
|
+
[Opcode.RETURNDATASIZE, Instruction.deserialize.bind(ReturndataSize)],
|
|
102
|
+
[Opcode.RETURNDATACOPY, Instruction.deserialize.bind(ReturndataCopy)],
|
|
99
103
|
|
|
100
104
|
// Machine State - Internal Control Flow
|
|
101
105
|
[Jump.opcode, Instruction.deserialize.bind(Jump)],
|
|
@@ -141,7 +145,7 @@ const INSTRUCTION_SET = () =>
|
|
|
141
145
|
[Sha256Compression.opcode, Instruction.deserialize.bind(Sha256Compression)],
|
|
142
146
|
[MultiScalarMul.opcode, Instruction.deserialize.bind(MultiScalarMul)],
|
|
143
147
|
// Conversions
|
|
144
|
-
[
|
|
148
|
+
[ToRadixBE.opcode, Instruction.deserialize.bind(ToRadixBE)],
|
|
145
149
|
// Future Gadgets -- pending changes in noir
|
|
146
150
|
// SHA256COMPRESSION,
|
|
147
151
|
[KeccakF1600.opcode, Instruction.deserialize.bind(KeccakF1600)],
|
|
@@ -41,9 +41,11 @@ export enum Opcode {
|
|
|
41
41
|
// Execution environment
|
|
42
42
|
GETENVVAR_16,
|
|
43
43
|
CALLDATACOPY,
|
|
44
|
+
RETURNDATASIZE,
|
|
45
|
+
RETURNDATACOPY,
|
|
44
46
|
// Control flow
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
JUMP_32,
|
|
48
|
+
JUMPI_32,
|
|
47
49
|
INTERNALCALL,
|
|
48
50
|
INTERNALRETURN,
|
|
49
51
|
// Memory
|
|
@@ -81,7 +83,7 @@ export enum Opcode {
|
|
|
81
83
|
ECADD,
|
|
82
84
|
MSM,
|
|
83
85
|
// Conversion
|
|
84
|
-
|
|
86
|
+
TORADIXBE,
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
// Possible types for an instruction's operand in its wire format. (Keep in sync with CPP code.
|
package/src/avm/test_utils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ContractInstanceWithAddress, Fr } from '@aztec/circuits.js';
|
|
1
|
+
import { type ContractClassPublic, type ContractInstanceWithAddress, Fr } from '@aztec/circuits.js';
|
|
2
2
|
|
|
3
3
|
import { type jest } from '@jest/globals';
|
|
4
4
|
import { mock } from 'jest-mock-extended';
|
|
@@ -61,3 +61,7 @@ export function mockL1ToL2MessageExists(
|
|
|
61
61
|
export function mockGetContractInstance(worldStateDB: WorldStateDB, contractInstance: ContractInstanceWithAddress) {
|
|
62
62
|
(worldStateDB as jest.Mocked<WorldStateDB>).getContractInstance.mockResolvedValue(contractInstance);
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
export function mockGetContractClass(worldStateDB: WorldStateDB, contractClass: ContractClassPublic) {
|
|
66
|
+
(worldStateDB as jest.Mocked<WorldStateDB>).getContractClass.mockResolvedValue(contractClass);
|
|
67
|
+
}
|
|
@@ -602,33 +602,6 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
602
602
|
);
|
|
603
603
|
}
|
|
604
604
|
|
|
605
|
-
/**
|
|
606
|
-
* Read the public storage data.
|
|
607
|
-
* @param contractAddress - The address to read storage from.
|
|
608
|
-
* @param startStorageSlot - The starting storage slot.
|
|
609
|
-
* @param blockNumber - The block number to read storage at.
|
|
610
|
-
* @param numberOfElements - Number of elements to read from the starting storage slot.
|
|
611
|
-
*/
|
|
612
|
-
public override async storageRead(
|
|
613
|
-
contractAddress: Fr,
|
|
614
|
-
startStorageSlot: Fr,
|
|
615
|
-
blockNumber: number,
|
|
616
|
-
numberOfElements: number,
|
|
617
|
-
): Promise<Fr[]> {
|
|
618
|
-
const values = [];
|
|
619
|
-
for (let i = 0n; i < numberOfElements; i++) {
|
|
620
|
-
const storageSlot = new Fr(startStorageSlot.value + i);
|
|
621
|
-
|
|
622
|
-
const value = await this.aztecNode.getPublicStorageAt(contractAddress, storageSlot, blockNumber);
|
|
623
|
-
this.log.debug(
|
|
624
|
-
`Oracle storage read: slot=${storageSlot.toString()} address-${contractAddress.toString()} value=${value}`,
|
|
625
|
-
);
|
|
626
|
-
|
|
627
|
-
values.push(value);
|
|
628
|
-
}
|
|
629
|
-
return values;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
605
|
public override debugLog(message: string, fields: Fr[]) {
|
|
633
606
|
this.log.verbose(`debug_log ${applyStringFormatting(message, fields)}`);
|
|
634
607
|
}
|
|
@@ -636,4 +609,8 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
636
609
|
public getDebugFunctionName() {
|
|
637
610
|
return this.db.getDebugFunctionName(this.contractAddress, this.callContext.functionSelector);
|
|
638
611
|
}
|
|
612
|
+
|
|
613
|
+
public override async incrementAppTaggingSecret(sender: AztecAddress, recipient: AztecAddress) {
|
|
614
|
+
await this.db.incrementAppTaggingSecret(this.contractAddress, sender, recipient);
|
|
615
|
+
}
|
|
639
616
|
}
|
package/src/client/db_oracle.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type CompleteAddress,
|
|
10
10
|
type ContractInstance,
|
|
11
11
|
type Header,
|
|
12
|
+
type IndexedTaggingSecret,
|
|
12
13
|
type KeyValidationRequest,
|
|
13
14
|
} from '@aztec/circuits.js';
|
|
14
15
|
import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi';
|
|
@@ -193,4 +194,41 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
193
194
|
* @returns The block number.
|
|
194
195
|
*/
|
|
195
196
|
getBlockNumber(): Promise<number>;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Returns the tagging secret for a given sender and recipient pair. For this to work, the ivpsk_m of the sender must be known.
|
|
200
|
+
* Includes the last known index used for tagging with this secret.
|
|
201
|
+
* @param contractAddress - The contract address to silo the secret for
|
|
202
|
+
* @param sender - The address sending the note
|
|
203
|
+
* @param recipient - The address receiving the note
|
|
204
|
+
* @returns A tagging secret that can be used to tag notes.
|
|
205
|
+
*/
|
|
206
|
+
getAppTaggingSecret(
|
|
207
|
+
contractAddress: AztecAddress,
|
|
208
|
+
sender: AztecAddress,
|
|
209
|
+
recipient: AztecAddress,
|
|
210
|
+
): Promise<IndexedTaggingSecret>;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Increments the tagging secret for a given sender and recipient pair. For this to work, the ivpsk_m of the sender must be known.
|
|
214
|
+
* @param contractAddress - The contract address to silo the secret for
|
|
215
|
+
* @param sender - The address sending the note
|
|
216
|
+
* @param recipient - The address receiving the note
|
|
217
|
+
*/
|
|
218
|
+
incrementAppTaggingSecret(
|
|
219
|
+
contractAddress: AztecAddress,
|
|
220
|
+
sender: AztecAddress,
|
|
221
|
+
recipient: AztecAddress,
|
|
222
|
+
): Promise<void>;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Returns the siloed tagging secrets for a given recipient and all the senders in the address book
|
|
226
|
+
* @param contractAddress - The contract address to silo the secret for
|
|
227
|
+
* @param recipient - The address receiving the notes
|
|
228
|
+
* @returns A list of siloed tagging secrets
|
|
229
|
+
*/
|
|
230
|
+
getAppTaggingSecretsForSenders(
|
|
231
|
+
contractAddress: AztecAddress,
|
|
232
|
+
recipient: AztecAddress,
|
|
233
|
+
): Promise<IndexedTaggingSecret[]>;
|
|
196
234
|
}
|
|
@@ -7,7 +7,12 @@ import {
|
|
|
7
7
|
type NullifierMembershipWitness,
|
|
8
8
|
type PublicDataWitness,
|
|
9
9
|
} from '@aztec/circuit-types';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type ContractInstance,
|
|
12
|
+
type Header,
|
|
13
|
+
type IndexedTaggingSecret,
|
|
14
|
+
type KeyValidationRequest,
|
|
15
|
+
} from '@aztec/circuits.js';
|
|
11
16
|
import { siloNullifier } from '@aztec/circuits.js/hash';
|
|
12
17
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
13
18
|
import { Fr } from '@aztec/foundation/fields';
|
|
@@ -288,4 +293,29 @@ export class ViewDataOracle extends TypedOracle {
|
|
|
288
293
|
const formattedStr = applyStringFormatting(message, fields);
|
|
289
294
|
this.log.verbose(`debug_log ${formattedStr}`);
|
|
290
295
|
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Returns the tagging secret for a given sender and recipient pair, siloed to the current contract address.
|
|
299
|
+
* Includes the last known index used for tagging with this secret.
|
|
300
|
+
* For this to work, the ivpsk_m of the sender must be known.
|
|
301
|
+
* @param sender - The address sending the note
|
|
302
|
+
* @param recipient - The address receiving the note
|
|
303
|
+
* @returns A tagging secret that can be used to tag notes.
|
|
304
|
+
*/
|
|
305
|
+
public override async getAppTaggingSecret(
|
|
306
|
+
sender: AztecAddress,
|
|
307
|
+
recipient: AztecAddress,
|
|
308
|
+
): Promise<IndexedTaggingSecret> {
|
|
309
|
+
return await this.db.getAppTaggingSecret(this.contractAddress, sender, recipient);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Returns the siloed tagging secrets for a given recipient and all the senders in the address book
|
|
314
|
+
* @param contractAddress - The contract address to silo the secret for
|
|
315
|
+
* @param recipient - The address receiving the notes
|
|
316
|
+
* @returns A list of siloed tagging secrets
|
|
317
|
+
*/
|
|
318
|
+
public override async getAppTaggingSecretsForSenders(recipient: AztecAddress): Promise<IndexedTaggingSecret[]> {
|
|
319
|
+
return await this.db.getAppTaggingSecretsForSenders(this.contractAddress, recipient);
|
|
320
|
+
}
|
|
291
321
|
}
|
package/src/common/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type CombinedConstantData,
|
|
3
|
-
type
|
|
3
|
+
type ContractClassIdPreimage,
|
|
4
4
|
type Gas,
|
|
5
|
+
type SerializableContractInstance,
|
|
5
6
|
type VMCircuitPublicInputs,
|
|
6
7
|
} from '@aztec/circuits.js';
|
|
7
8
|
import { type Fr } from '@aztec/foundation/fields';
|
|
@@ -15,8 +16,6 @@ import { type PublicExecutionResult } from './execution.js';
|
|
|
15
16
|
import { type PublicSideEffectTrace } from './side_effect_trace.js';
|
|
16
17
|
import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js';
|
|
17
18
|
|
|
18
|
-
export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress;
|
|
19
|
-
|
|
20
19
|
export class DualSideEffectTrace implements PublicSideEffectTraceInterface {
|
|
21
20
|
constructor(
|
|
22
21
|
public readonly innerCallTrace: PublicSideEffectTrace,
|
|
@@ -78,9 +77,24 @@ export class DualSideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
78
77
|
this.enqueuedCallTrace.traceUnencryptedLog(contractAddress, log);
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
public traceGetContractInstance(
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
public traceGetContractInstance(
|
|
81
|
+
contractAddress: Fr,
|
|
82
|
+
exists: boolean,
|
|
83
|
+
instance: SerializableContractInstance | undefined,
|
|
84
|
+
) {
|
|
85
|
+
this.innerCallTrace.traceGetContractInstance(contractAddress, exists, instance);
|
|
86
|
+
this.enqueuedCallTrace.traceGetContractInstance(contractAddress, exists, instance);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public traceGetBytecode(
|
|
90
|
+
contractAddress: Fr,
|
|
91
|
+
exists: boolean,
|
|
92
|
+
bytecode: Buffer,
|
|
93
|
+
contractInstance: SerializableContractInstance | undefined,
|
|
94
|
+
contractClass: ContractClassIdPreimage | undefined,
|
|
95
|
+
) {
|
|
96
|
+
this.innerCallTrace.traceGetBytecode(contractAddress, exists, bytecode, contractInstance, contractClass);
|
|
97
|
+
this.enqueuedCallTrace.traceGetBytecode(contractAddress, exists, bytecode, contractInstance, contractClass);
|
|
84
98
|
}
|
|
85
99
|
|
|
86
100
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { UnencryptedL2Log } from '@aztec/circuit-types';
|
|
2
2
|
import {
|
|
3
|
+
AvmContractBytecodeHints,
|
|
3
4
|
AvmContractInstanceHint,
|
|
4
5
|
AvmExecutionHints,
|
|
5
6
|
AvmExternalCallHint,
|
|
@@ -7,7 +8,7 @@ import {
|
|
|
7
8
|
AztecAddress,
|
|
8
9
|
CallContext,
|
|
9
10
|
type CombinedConstantData,
|
|
10
|
-
type
|
|
11
|
+
type ContractClassIdPreimage,
|
|
11
12
|
ContractStorageRead,
|
|
12
13
|
ContractStorageUpdateRequest,
|
|
13
14
|
EthAddress,
|
|
@@ -44,6 +45,7 @@ import {
|
|
|
44
45
|
ScopedNoteHash,
|
|
45
46
|
type ScopedNullifier,
|
|
46
47
|
ScopedReadRequest,
|
|
48
|
+
SerializableContractInstance,
|
|
47
49
|
TreeLeafReadRequest,
|
|
48
50
|
VMCircuitPublicInputs,
|
|
49
51
|
} from '@aztec/circuits.js';
|
|
@@ -58,8 +60,6 @@ import { type AvmExecutionEnvironment } from '../avm/avm_execution_environment.j
|
|
|
58
60
|
import { SideEffectLimitReachedError } from './side_effect_errors.js';
|
|
59
61
|
import { type PublicSideEffectTraceInterface } from './side_effect_trace_interface.js';
|
|
60
62
|
|
|
61
|
-
export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress;
|
|
62
|
-
|
|
63
63
|
/**
|
|
64
64
|
* A struct containing just the side effects as regular arrays
|
|
65
65
|
* as opposed to "Tuple" arrays used by circuit public inputs.
|
|
@@ -307,14 +307,17 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
307
307
|
this.incrementSideEffectCounter();
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
-
public traceGetContractInstance(
|
|
310
|
+
public traceGetContractInstance(
|
|
311
|
+
contractAddress: Fr,
|
|
312
|
+
exists: boolean,
|
|
313
|
+
instance: SerializableContractInstance = SerializableContractInstance.default(),
|
|
314
|
+
) {
|
|
311
315
|
this.enforceLimitOnNullifierChecks('(contract address nullifier from GETCONTRACTINSTANCE)');
|
|
312
|
-
// TODO(dbanks12): should emit a nullifier read request
|
|
313
316
|
|
|
314
317
|
this.avmCircuitHints.contractInstances.items.push(
|
|
315
318
|
new AvmContractInstanceHint(
|
|
316
|
-
|
|
317
|
-
|
|
319
|
+
contractAddress,
|
|
320
|
+
exists,
|
|
318
321
|
instance.salt,
|
|
319
322
|
instance.deployer,
|
|
320
323
|
instance.contractClassId,
|
|
@@ -326,6 +329,40 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
326
329
|
this.incrementSideEffectCounter();
|
|
327
330
|
}
|
|
328
331
|
|
|
332
|
+
// This tracing function gets called everytime we start simulation/execution.
|
|
333
|
+
// This happens both when starting a new top-level trace and the start of every nested trace
|
|
334
|
+
// We use this to collect the AvmContractBytecodeHints
|
|
335
|
+
public traceGetBytecode(
|
|
336
|
+
contractAddress: Fr,
|
|
337
|
+
exists: boolean,
|
|
338
|
+
bytecode: Buffer = Buffer.alloc(0),
|
|
339
|
+
contractInstance: SerializableContractInstance = SerializableContractInstance.default(),
|
|
340
|
+
contractClass: ContractClassIdPreimage = {
|
|
341
|
+
artifactHash: Fr.zero(),
|
|
342
|
+
privateFunctionsRoot: Fr.zero(),
|
|
343
|
+
publicBytecodeCommitment: Fr.zero(),
|
|
344
|
+
},
|
|
345
|
+
) {
|
|
346
|
+
const instance = new AvmContractInstanceHint(
|
|
347
|
+
contractAddress,
|
|
348
|
+
exists,
|
|
349
|
+
contractInstance.salt,
|
|
350
|
+
contractInstance.deployer,
|
|
351
|
+
contractInstance.contractClassId,
|
|
352
|
+
contractInstance.initializationHash,
|
|
353
|
+
contractInstance.publicKeys,
|
|
354
|
+
);
|
|
355
|
+
// We need to deduplicate the contract instances based on addresses
|
|
356
|
+
this.avmCircuitHints.contractBytecodeHints.items.push(
|
|
357
|
+
new AvmContractBytecodeHints(bytecode, instance, contractClass),
|
|
358
|
+
);
|
|
359
|
+
this.log.debug(
|
|
360
|
+
`Bytecode retrieval for contract execution traced: exists=${exists}, instance=${JSON.stringify(
|
|
361
|
+
contractInstance,
|
|
362
|
+
)}`,
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
329
366
|
/**
|
|
330
367
|
* Trace a nested call.
|
|
331
368
|
* Accept some results from a finished nested call's trace into this one.
|
|
@@ -334,7 +371,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
334
371
|
/** The trace of the nested call. */
|
|
335
372
|
nestedCallTrace: this,
|
|
336
373
|
/** The execution environment of the nested call. */
|
|
337
|
-
|
|
374
|
+
nestedEnvironment: AvmExecutionEnvironment,
|
|
338
375
|
/** How much gas was available for this public execution. */
|
|
339
376
|
startGasLeft: Gas,
|
|
340
377
|
/** How much gas was left after this public execution. */
|
|
@@ -368,6 +405,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
368
405
|
avmCallResults.output,
|
|
369
406
|
gasUsed,
|
|
370
407
|
endSideEffectCounter,
|
|
408
|
+
nestedEnvironment.address,
|
|
371
409
|
),
|
|
372
410
|
);
|
|
373
411
|
}
|