@aztec/simulator 0.44.0 → 0.45.1
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 -3
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +8 -8
- package/dest/acvm/oracle/typed_oracle.d.ts +1 -1
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +2 -2
- package/dest/avm/avm_context.d.ts +1 -1
- package/dest/avm/avm_context.d.ts.map +1 -1
- package/dest/avm/avm_context.js +3 -3
- package/dest/avm/{avm_message_call_result.d.ts → avm_contract_call_result.d.ts} +2 -2
- package/dest/avm/avm_contract_call_result.d.ts.map +1 -0
- package/dest/avm/avm_contract_call_result.js +18 -0
- package/dest/avm/avm_execution_environment.d.ts +7 -11
- package/dest/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/avm/avm_execution_environment.js +11 -20
- package/dest/avm/avm_gas.js +2 -2
- package/dest/avm/avm_simulator.d.ts +4 -4
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +7 -7
- package/dest/avm/bytecode_utils.d.ts +5 -0
- package/dest/avm/bytecode_utils.d.ts.map +1 -0
- package/dest/avm/bytecode_utils.js +29 -0
- package/dest/avm/errors.js +2 -2
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +3 -3
- package/dest/avm/journal/journal.d.ts +5 -5
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +9 -7
- package/dest/avm/journal/public_storage.d.ts +1 -1
- package/dest/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/avm/journal/public_storage.js +2 -2
- package/dest/avm/opcodes/accrued_substate.d.ts +1 -2
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +6 -15
- package/dest/avm/opcodes/environment_getters.d.ts +13 -8
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +20 -13
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +1 -2
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +5 -5
- package/dest/avm/serialization/instruction_serialization.d.ts +9 -9
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +10 -10
- package/dest/client/client_execution_context.d.ts +3 -1
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +9 -7
- package/dest/client/view_data_oracle.d.ts +3 -1
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +6 -4
- package/dest/mocks/fixtures.d.ts +3 -3
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +7 -7
- package/dest/public/abstract_phase_manager.js +21 -21
- package/dest/public/execution.d.ts +10 -9
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +6 -6
- package/dest/public/executor.d.ts +4 -4
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +19 -14
- 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 +1 -1
- package/dest/public/index.d.ts +1 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +1 -1
- package/dest/public/public_kernel.d.ts +1 -1
- package/dest/public/public_kernel.d.ts.map +1 -1
- package/dest/public/public_kernel.js +2 -2
- package/dest/public/side_effect_trace.d.ts +7 -6
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +32 -18
- 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/public/tail_phase_manager.js +3 -3
- package/dest/rollup/rollup.d.ts +1 -1
- package/dest/rollup/rollup.d.ts.map +1 -1
- package/dest/rollup/rollup.js +2 -2
- package/package.json +9 -9
- package/src/acvm/oracle/oracle.ts +16 -20
- package/src/acvm/oracle/typed_oracle.ts +6 -1
- package/src/avm/avm_context.ts +2 -2
- package/src/avm/{avm_message_call_result.ts → avm_contract_call_result.ts} +1 -1
- package/src/avm/avm_execution_environment.ts +10 -27
- package/src/avm/avm_gas.ts +1 -1
- package/src/avm/avm_simulator.ts +9 -11
- package/src/avm/bytecode_utils.ts +32 -0
- package/src/avm/errors.ts +1 -1
- package/src/avm/fixtures/index.ts +3 -6
- package/src/avm/journal/journal.ts +14 -11
- package/src/avm/journal/public_storage.ts +2 -2
- package/src/avm/opcodes/accrued_substate.ts +6 -19
- package/src/avm/opcodes/environment_getters.ts +23 -14
- package/src/avm/opcodes/external_calls.ts +2 -3
- package/src/avm/serialization/bytecode_serialization.ts +4 -3
- package/src/avm/serialization/instruction_serialization.ts +3 -3
- package/src/client/client_execution_context.ts +15 -6
- package/src/client/view_data_oracle.ts +12 -3
- package/src/mocks/fixtures.ts +8 -8
- package/src/public/abstract_phase_manager.ts +26 -26
- package/src/public/execution.ts +19 -15
- package/src/public/executor.ts +35 -20
- package/src/public/hints_builder.ts +3 -3
- package/src/public/index.ts +1 -1
- package/src/public/public_kernel.ts +2 -1
- package/src/public/side_effect_trace.ts +40 -22
- package/src/public/side_effect_trace_interface.ts +3 -3
- package/src/public/tail_phase_manager.ts +4 -4
- package/src/rollup/rollup.ts +3 -1
- package/dest/avm/avm_message_call_result.d.ts.map +0 -1
- package/dest/avm/avm_message_call_result.js +0 -18
- package/dest/public/transitional_adaptors.d.ts +0 -17
- package/dest/public/transitional_adaptors.d.ts.map +0 -1
- package/dest/public/transitional_adaptors.js +0 -42
- package/src/public/transitional_adaptors.ts +0 -70
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionSelector, type
|
|
1
|
+
import { FunctionSelector, type GlobalVariables, type Header } from '@aztec/circuits.js';
|
|
2
2
|
import { computeVarArgsHash } from '@aztec/circuits.js/hash';
|
|
3
3
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
4
4
|
import { Fr } from '@aztec/foundation/fields';
|
|
5
5
|
|
|
6
6
|
export class AvmContextInputs {
|
|
7
|
-
static readonly SIZE =
|
|
7
|
+
static readonly SIZE = 2;
|
|
8
8
|
|
|
9
|
-
constructor(private
|
|
9
|
+
constructor(private argsHash: Fr, private isStaticCall: boolean) {}
|
|
10
10
|
|
|
11
11
|
public toFields(): Fr[] {
|
|
12
|
-
return [this.
|
|
12
|
+
return [this.argsHash, new Fr(this.isStaticCall)];
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -17,38 +17,24 @@ export class AvmContextInputs {
|
|
|
17
17
|
* Contains variables that remain constant during AVM execution
|
|
18
18
|
* These variables are provided by the public kernel circuit
|
|
19
19
|
*/
|
|
20
|
-
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/3992): gas not implemented
|
|
21
20
|
export class AvmExecutionEnvironment {
|
|
22
|
-
private readonly calldataPrefixLength;
|
|
23
21
|
constructor(
|
|
24
22
|
public readonly address: AztecAddress,
|
|
25
23
|
public readonly storageAddress: AztecAddress,
|
|
26
24
|
public readonly sender: AztecAddress,
|
|
27
|
-
public readonly
|
|
28
|
-
public readonly feePerDaGas: Fr,
|
|
25
|
+
public readonly functionSelector: FunctionSelector, // may be temporary (#7224)
|
|
29
26
|
public readonly contractCallDepth: Fr,
|
|
27
|
+
public readonly transactionFee: Fr,
|
|
30
28
|
public readonly header: Header,
|
|
31
29
|
public readonly globals: GlobalVariables,
|
|
32
30
|
public readonly isStaticCall: boolean,
|
|
33
31
|
public readonly isDelegateCall: boolean,
|
|
34
32
|
public readonly calldata: Fr[],
|
|
35
|
-
public readonly gasSettings: GasSettings,
|
|
36
|
-
public readonly transactionFee: Fr,
|
|
37
|
-
|
|
38
|
-
// Function selector is temporary since eventually public contract bytecode will be one blob
|
|
39
|
-
// 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
|
-
public readonly temporaryFunctionSelector: FunctionSelector,
|
|
42
33
|
) {
|
|
43
34
|
// We encode some extra inputs (AvmContextInputs) in calldata.
|
|
44
35
|
// This will have to go once we move away from one proof per call.
|
|
45
|
-
const inputs = new AvmContextInputs(
|
|
46
|
-
temporaryFunctionSelector.toField(),
|
|
47
|
-
computeVarArgsHash(calldata),
|
|
48
|
-
isStaticCall,
|
|
49
|
-
).toFields();
|
|
36
|
+
const inputs = new AvmContextInputs(computeVarArgsHash(calldata), isStaticCall).toFields();
|
|
50
37
|
this.calldata = [...inputs, ...calldata];
|
|
51
|
-
this.calldataPrefixLength = inputs.length;
|
|
52
38
|
}
|
|
53
39
|
|
|
54
40
|
private deriveEnvironmentForNestedCallInternal(
|
|
@@ -62,17 +48,14 @@ export class AvmExecutionEnvironment {
|
|
|
62
48
|
/*address=*/ targetAddress,
|
|
63
49
|
/*storageAddress=*/ targetAddress,
|
|
64
50
|
/*sender=*/ this.address,
|
|
65
|
-
|
|
66
|
-
this.feePerDaGas,
|
|
51
|
+
functionSelector,
|
|
67
52
|
this.contractCallDepth.add(Fr.ONE),
|
|
53
|
+
this.transactionFee,
|
|
68
54
|
this.header,
|
|
69
55
|
this.globals,
|
|
70
56
|
isStaticCall,
|
|
71
57
|
isDelegateCall,
|
|
72
58
|
calldata,
|
|
73
|
-
this.gasSettings,
|
|
74
|
-
this.transactionFee,
|
|
75
|
-
functionSelector,
|
|
76
59
|
);
|
|
77
60
|
}
|
|
78
61
|
|
|
@@ -114,6 +97,6 @@ export class AvmExecutionEnvironment {
|
|
|
114
97
|
|
|
115
98
|
public getCalldataWithoutPrefix(): Fr[] {
|
|
116
99
|
// clip off the first few entries
|
|
117
|
-
return this.calldata.slice(
|
|
100
|
+
return this.calldata.slice(AvmContextInputs.SIZE);
|
|
118
101
|
}
|
|
119
102
|
}
|
package/src/avm/avm_gas.ts
CHANGED
|
@@ -76,7 +76,7 @@ const BaseGasCosts: Record<Opcode, Gas> = {
|
|
|
76
76
|
[Opcode.FEEPERL2GAS]: DefaultBaseGasCost,
|
|
77
77
|
[Opcode.FEEPERDAGAS]: DefaultBaseGasCost,
|
|
78
78
|
[Opcode.TRANSACTIONFEE]: DefaultBaseGasCost,
|
|
79
|
-
[Opcode.
|
|
79
|
+
[Opcode.FUNCTIONSELECTOR]: DefaultBaseGasCost,
|
|
80
80
|
[Opcode.CHAINID]: DefaultBaseGasCost,
|
|
81
81
|
[Opcode.VERSION]: DefaultBaseGasCost,
|
|
82
82
|
[Opcode.BLOCKNUMBER]: DefaultBaseGasCost,
|
package/src/avm/avm_simulator.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
|
2
2
|
|
|
3
3
|
import { strict as assert } from 'assert';
|
|
4
4
|
|
|
5
|
-
import { decompressBytecodeIfCompressed, isAvmBytecode } from '../public/transitional_adaptors.js';
|
|
6
5
|
import type { AvmContext } from './avm_context.js';
|
|
7
|
-
import {
|
|
6
|
+
import { AvmContractCallResult } from './avm_contract_call_result.js';
|
|
7
|
+
import { decompressBytecodeIfCompressed, isAvmBytecode } from './bytecode_utils.js';
|
|
8
8
|
import {
|
|
9
9
|
AvmExecutionError,
|
|
10
10
|
InvalidProgramCounterError,
|
|
@@ -20,18 +20,16 @@ export class AvmSimulator {
|
|
|
20
20
|
private bytecode: Buffer | undefined;
|
|
21
21
|
|
|
22
22
|
constructor(private context: AvmContext) {
|
|
23
|
-
this.log = createDebugLogger(
|
|
24
|
-
`aztec:avm_simulator:core(f:${context.environment.temporaryFunctionSelector.toString()})`,
|
|
25
|
-
);
|
|
23
|
+
this.log = createDebugLogger(`aztec:avm_simulator:core(f:${context.environment.functionSelector.toString()})`);
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
/**
|
|
29
27
|
* Fetch the bytecode and execute it in the current context.
|
|
30
28
|
*/
|
|
31
|
-
public async execute(): Promise<
|
|
29
|
+
public async execute(): Promise<AvmContractCallResult> {
|
|
32
30
|
const bytecode = await this.context.persistableState.getBytecode(
|
|
33
31
|
this.context.environment.address,
|
|
34
|
-
this.context.environment.
|
|
32
|
+
this.context.environment.functionSelector,
|
|
35
33
|
);
|
|
36
34
|
|
|
37
35
|
// This assumes that we will not be able to send messages to accounts without code
|
|
@@ -54,7 +52,7 @@ export class AvmSimulator {
|
|
|
54
52
|
* Executes the provided bytecode in the current context.
|
|
55
53
|
* This method is useful for testing and debugging.
|
|
56
54
|
*/
|
|
57
|
-
public async executeBytecode(bytecode: Buffer): Promise<
|
|
55
|
+
public async executeBytecode(bytecode: Buffer): Promise<AvmContractCallResult> {
|
|
58
56
|
const decompressedBytecode = await decompressBytecodeIfCompressed(bytecode);
|
|
59
57
|
assert(isAvmBytecode(decompressedBytecode), "AVM simulator can't execute non-AVM bytecode");
|
|
60
58
|
|
|
@@ -66,7 +64,7 @@ export class AvmSimulator {
|
|
|
66
64
|
* Executes the provided instructions in the current context.
|
|
67
65
|
* This method is useful for testing and debugging.
|
|
68
66
|
*/
|
|
69
|
-
public async executeInstructions(instructions: Instruction[]): Promise<
|
|
67
|
+
public async executeInstructions(instructions: Instruction[]): Promise<AvmContractCallResult> {
|
|
70
68
|
assert(instructions.length > 0);
|
|
71
69
|
const { machineState } = this.context;
|
|
72
70
|
try {
|
|
@@ -95,7 +93,7 @@ export class AvmSimulator {
|
|
|
95
93
|
const output = machineState.getOutput();
|
|
96
94
|
const reverted = machineState.getReverted();
|
|
97
95
|
const revertReason = reverted ? revertReasonFromExplicitRevert(output, this.context) : undefined;
|
|
98
|
-
const results = new
|
|
96
|
+
const results = new AvmContractCallResult(reverted, output, revertReason);
|
|
99
97
|
this.log.debug(`Context execution results: ${results.toString()}`);
|
|
100
98
|
// Return results for processing by calling context
|
|
101
99
|
return results;
|
|
@@ -108,7 +106,7 @@ export class AvmSimulator {
|
|
|
108
106
|
|
|
109
107
|
const revertReason = revertReasonFromExceptionalHalt(err, this.context);
|
|
110
108
|
// Note: "exceptional halts" cannot return data, hence []
|
|
111
|
-
const results = new
|
|
109
|
+
const results = new AvmContractCallResult(/*reverted=*/ true, /*output=*/ [], revertReason);
|
|
112
110
|
this.log.debug(`Context execution results: ${results.toString()}`);
|
|
113
111
|
// Return results for processing by calling context
|
|
114
112
|
return results;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { promisify } from 'util';
|
|
2
|
+
import { gunzip } from 'zlib';
|
|
3
|
+
|
|
4
|
+
import { Mov } from '../avm/opcodes/memory.js';
|
|
5
|
+
|
|
6
|
+
const AVM_MAGIC_SUFFIX = Buffer.from([
|
|
7
|
+
Mov.opcode, // opcode
|
|
8
|
+
0x00, // indirect
|
|
9
|
+
...Buffer.from('000018ca', 'hex'), // srcOffset
|
|
10
|
+
...Buffer.from('000018ca', 'hex'), // dstOffset
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
export function markBytecodeAsAvm(bytecode: Buffer): Buffer {
|
|
14
|
+
return Buffer.concat([bytecode, AVM_MAGIC_SUFFIX]);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// This is just a helper function for the AVM simulator
|
|
18
|
+
export async function decompressBytecodeIfCompressed(bytecode: Buffer): Promise<Buffer> {
|
|
19
|
+
try {
|
|
20
|
+
return await promisify(gunzip)(bytecode);
|
|
21
|
+
} catch {
|
|
22
|
+
// If the bytecode is not compressed, the gunzip call will throw an error
|
|
23
|
+
// In this case, we assume the bytecode is not compressed and continue.
|
|
24
|
+
return Promise.resolve(bytecode);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function isAvmBytecode(bytecode: Buffer): Promise<boolean> {
|
|
29
|
+
const decompressedBytecode = await decompressBytecodeIfCompressed(bytecode);
|
|
30
|
+
const magicSize = AVM_MAGIC_SUFFIX.length;
|
|
31
|
+
return decompressedBytecode.subarray(-magicSize).equals(AVM_MAGIC_SUFFIX);
|
|
32
|
+
}
|
package/src/avm/errors.ts
CHANGED
|
@@ -113,7 +113,7 @@ function createRevertReason(message: string, context: AvmContext, nestedError?:
|
|
|
113
113
|
message,
|
|
114
114
|
/*failingFunction=*/ {
|
|
115
115
|
contractAddress: context.environment.address,
|
|
116
|
-
functionSelector: context.environment.
|
|
116
|
+
functionSelector: context.environment.functionSelector,
|
|
117
117
|
},
|
|
118
118
|
/*noirCallStack=*/ [...context.machineState.internalCallStack, context.machineState.pc].map(pc => `0.${pc}`),
|
|
119
119
|
/*options=*/ { cause: nestedError },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GasFees,
|
|
1
|
+
import { GasFees, GlobalVariables, Header } from '@aztec/circuits.js';
|
|
2
2
|
import { FunctionSelector } from '@aztec/foundation/abi';
|
|
3
3
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -72,17 +72,14 @@ export function initExecutionEnvironment(overrides?: Partial<AvmExecutionEnviron
|
|
|
72
72
|
overrides?.address ?? AztecAddress.zero(),
|
|
73
73
|
overrides?.storageAddress ?? AztecAddress.zero(),
|
|
74
74
|
overrides?.sender ?? AztecAddress.zero(),
|
|
75
|
-
overrides?.
|
|
76
|
-
overrides?.feePerDaGas ?? Fr.zero(),
|
|
75
|
+
overrides?.functionSelector ?? FunctionSelector.empty(),
|
|
77
76
|
overrides?.contractCallDepth ?? Fr.zero(),
|
|
77
|
+
overrides?.transactionFee ?? Fr.zero(),
|
|
78
78
|
overrides?.header ?? Header.empty(),
|
|
79
79
|
overrides?.globals ?? GlobalVariables.empty(),
|
|
80
80
|
overrides?.isStaticCall ?? false,
|
|
81
81
|
overrides?.isDelegateCall ?? false,
|
|
82
82
|
overrides?.calldata ?? [],
|
|
83
|
-
overrides?.gasSettings ?? GasSettings.empty(),
|
|
84
|
-
overrides?.transactionFee ?? Fr.ZERO,
|
|
85
|
-
overrides?.temporaryFunctionSelector ?? FunctionSelector.empty(),
|
|
86
83
|
);
|
|
87
84
|
}
|
|
88
85
|
|
|
@@ -5,8 +5,8 @@ import { SerializableContractInstance } from '@aztec/types/contracts';
|
|
|
5
5
|
|
|
6
6
|
import { type TracedContractInstance } from '../../public/side_effect_trace.js';
|
|
7
7
|
import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js';
|
|
8
|
+
import { type AvmContractCallResult } from '../avm_contract_call_result.js';
|
|
8
9
|
import { type AvmExecutionEnvironment } from '../avm_execution_environment.js';
|
|
9
|
-
import { type AvmContractCallResults } from '../avm_message_call_result.js';
|
|
10
10
|
import { type HostStorage } from './host_storage.js';
|
|
11
11
|
import { NullifierManager } from './nullifiers.js';
|
|
12
12
|
import { PublicStorage } from './public_storage.js';
|
|
@@ -25,10 +25,11 @@ export class AvmPersistableStateManager {
|
|
|
25
25
|
|
|
26
26
|
constructor(
|
|
27
27
|
/** Reference to node storage */
|
|
28
|
-
private hostStorage: HostStorage,
|
|
28
|
+
private readonly hostStorage: HostStorage,
|
|
29
29
|
/** Side effect trace */
|
|
30
|
-
private trace: PublicSideEffectTraceInterface,
|
|
30
|
+
private readonly trace: PublicSideEffectTraceInterface,
|
|
31
31
|
/** Public storage, including cached writes */
|
|
32
|
+
// TODO(5818): make private once no longer accessed in executor
|
|
32
33
|
public readonly publicStorage: PublicStorage,
|
|
33
34
|
/** Nullifier set, including cached/recently-emitted nullifiers */
|
|
34
35
|
private readonly nullifiers: NullifierManager,
|
|
@@ -197,9 +198,9 @@ export class AvmPersistableStateManager {
|
|
|
197
198
|
* @param event - log event selector
|
|
198
199
|
* @param log - log contents
|
|
199
200
|
*/
|
|
200
|
-
public writeUnencryptedLog(contractAddress: Fr,
|
|
201
|
-
this.log.debug(`UnencryptedL2Log(${contractAddress}) += event
|
|
202
|
-
this.trace.traceUnencryptedLog(contractAddress,
|
|
201
|
+
public writeUnencryptedLog(contractAddress: Fr, log: Fr[]) {
|
|
202
|
+
this.log.debug(`UnencryptedL2Log(${contractAddress}) += event with ${log.length} fields.`);
|
|
203
|
+
this.trace.traceUnencryptedLog(contractAddress, log);
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
/**
|
|
@@ -243,21 +244,23 @@ export class AvmPersistableStateManager {
|
|
|
243
244
|
*/
|
|
244
245
|
public async processNestedCall(
|
|
245
246
|
nestedState: AvmPersistableStateManager,
|
|
246
|
-
success: boolean,
|
|
247
247
|
nestedEnvironment: AvmExecutionEnvironment,
|
|
248
248
|
startGasLeft: Gas,
|
|
249
249
|
endGasLeft: Gas,
|
|
250
250
|
bytecode: Buffer,
|
|
251
|
-
avmCallResults:
|
|
251
|
+
avmCallResults: AvmContractCallResult,
|
|
252
252
|
) {
|
|
253
|
-
if (
|
|
253
|
+
if (!avmCallResults.reverted) {
|
|
254
254
|
this.acceptNestedCallState(nestedState);
|
|
255
255
|
}
|
|
256
256
|
const functionName =
|
|
257
257
|
(await nestedState.hostStorage.contractsDb.getDebugFunctionName(
|
|
258
258
|
nestedEnvironment.address,
|
|
259
|
-
nestedEnvironment.
|
|
260
|
-
)) ?? `${nestedEnvironment.address}:${nestedEnvironment.
|
|
259
|
+
nestedEnvironment.functionSelector,
|
|
260
|
+
)) ?? `${nestedEnvironment.address}:${nestedEnvironment.functionSelector}`;
|
|
261
|
+
|
|
262
|
+
this.log.verbose(`[AVM] Calling nested function ${functionName}`);
|
|
263
|
+
|
|
261
264
|
this.trace.traceNestedCall(
|
|
262
265
|
nestedState.trace,
|
|
263
266
|
nestedEnvironment,
|
|
@@ -16,7 +16,7 @@ type PublicStorageReadResult = {
|
|
|
16
16
|
*/
|
|
17
17
|
export class PublicStorage {
|
|
18
18
|
/** Cached storage writes. */
|
|
19
|
-
private cache: PublicStorageCache;
|
|
19
|
+
private readonly cache: PublicStorageCache;
|
|
20
20
|
|
|
21
21
|
constructor(
|
|
22
22
|
/** Reference to node storage. Checked on parent cache-miss. */
|
|
@@ -134,7 +134,7 @@ class PublicStorageCache {
|
|
|
134
134
|
* mapping storage slot to latest staged write value.
|
|
135
135
|
*/
|
|
136
136
|
public cachePerContract: Map<bigint, Map<bigint, Fr>> = new Map();
|
|
137
|
-
// FIXME: storage ^ should be private, but its value is used in
|
|
137
|
+
// FIXME: storage ^ should be private, but its value is used in commitToDB
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
140
|
* Read a staged value from storage, if it has been previously written to.
|
|
@@ -217,20 +217,9 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
217
217
|
static type: string = 'EMITUNENCRYPTEDLOG';
|
|
218
218
|
static readonly opcode: Opcode = Opcode.EMITUNENCRYPTEDLOG;
|
|
219
219
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
220
|
-
static readonly wireFormat = [
|
|
221
|
-
OperandType.UINT8,
|
|
222
|
-
OperandType.UINT8,
|
|
223
|
-
OperandType.UINT32,
|
|
224
|
-
OperandType.UINT32,
|
|
225
|
-
OperandType.UINT32,
|
|
226
|
-
];
|
|
220
|
+
static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32];
|
|
227
221
|
|
|
228
|
-
constructor(
|
|
229
|
-
private indirect: number,
|
|
230
|
-
private eventSelectorOffset: number,
|
|
231
|
-
private logOffset: number,
|
|
232
|
-
private logSizeOffset: number,
|
|
233
|
-
) {
|
|
222
|
+
constructor(private indirect: number, private logOffset: number, private logSizeOffset: number) {
|
|
234
223
|
super();
|
|
235
224
|
}
|
|
236
225
|
|
|
@@ -241,22 +230,20 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
241
230
|
|
|
242
231
|
const memory = context.machineState.memory.track(this.type);
|
|
243
232
|
|
|
244
|
-
const [
|
|
245
|
-
[this.
|
|
233
|
+
const [logOffset, logSizeOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
234
|
+
[this.logOffset, this.logSizeOffset],
|
|
246
235
|
memory,
|
|
247
236
|
);
|
|
248
|
-
memory.checkTag(TypeTag.FIELD, eventSelectorOffset);
|
|
249
237
|
memory.checkTag(TypeTag.UINT32, logSizeOffset);
|
|
250
238
|
const logSize = memory.get(logSizeOffset).toNumber();
|
|
251
239
|
memory.checkTagsRange(TypeTag.FIELD, logOffset, logSize);
|
|
252
240
|
|
|
253
241
|
const contractAddress = context.environment.address;
|
|
254
|
-
const event = memory.get(eventSelectorOffset).toFr();
|
|
255
242
|
|
|
256
|
-
const memoryOperations = { reads:
|
|
243
|
+
const memoryOperations = { reads: 1 + logSize, indirect: this.indirect };
|
|
257
244
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
258
245
|
const log = memory.getSlice(logOffset, logSize).map(f => f.toFr());
|
|
259
|
-
context.persistableState.writeUnencryptedLog(contractAddress,
|
|
246
|
+
context.persistableState.writeUnencryptedLog(contractAddress, log);
|
|
260
247
|
|
|
261
248
|
memory.assert(memoryOperations);
|
|
262
249
|
context.machineState.incrementPc();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
2
|
import type { AvmExecutionEnvironment } from '../avm_execution_environment.js';
|
|
3
|
-
import { Field, type MemoryValue, Uint64 } from '../avm_memory_types.js';
|
|
3
|
+
import { Field, type MemoryValue, Uint32, Uint64 } from '../avm_memory_types.js';
|
|
4
4
|
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
5
5
|
import { GetterInstruction } from './instruction_impl.js';
|
|
6
6
|
|
|
@@ -39,21 +39,12 @@ export class Sender extends EnvironmentGetterInstruction {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export class
|
|
43
|
-
static type: string = '
|
|
44
|
-
static readonly opcode: Opcode = Opcode.
|
|
45
|
-
|
|
46
|
-
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
47
|
-
return new Field(env.feePerL2Gas);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class FeePerDAGas extends EnvironmentGetterInstruction {
|
|
52
|
-
static type: string = 'FEEPERDAGAS';
|
|
53
|
-
static readonly opcode: Opcode = Opcode.FEEPERDAGAS;
|
|
42
|
+
export class FunctionSelector extends EnvironmentGetterInstruction {
|
|
43
|
+
static type: string = 'FUNCTIONSELECTOR';
|
|
44
|
+
static readonly opcode: Opcode = Opcode.FUNCTIONSELECTOR;
|
|
54
45
|
|
|
55
46
|
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
56
|
-
return new
|
|
47
|
+
return new Uint32(env.functionSelector.value);
|
|
57
48
|
}
|
|
58
49
|
}
|
|
59
50
|
|
|
@@ -101,3 +92,21 @@ export class Timestamp extends EnvironmentGetterInstruction {
|
|
|
101
92
|
return new Uint64(env.globals.timestamp.toBigInt());
|
|
102
93
|
}
|
|
103
94
|
}
|
|
95
|
+
|
|
96
|
+
export class FeePerL2Gas extends EnvironmentGetterInstruction {
|
|
97
|
+
static type: string = 'FEEPERL2GAS';
|
|
98
|
+
static readonly opcode: Opcode = Opcode.FEEPERL2GAS;
|
|
99
|
+
|
|
100
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
101
|
+
return new Field(env.globals.gasFees.feePerL2Gas);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export class FeePerDAGas extends EnvironmentGetterInstruction {
|
|
106
|
+
static type: string = 'FEEPERDAGAS';
|
|
107
|
+
static readonly opcode: Opcode = Opcode.FEEPERDAGAS;
|
|
108
|
+
|
|
109
|
+
protected getEnvironmentValue(env: AvmExecutionEnvironment) {
|
|
110
|
+
return new Field(env.globals.gasFees.feePerDaGas);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -2,9 +2,9 @@ import { FunctionSelector, Gas } from '@aztec/circuits.js';
|
|
|
2
2
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
3
3
|
|
|
4
4
|
import type { AvmContext } from '../avm_context.js';
|
|
5
|
+
import { type AvmContractCallResult } from '../avm_contract_call_result.js';
|
|
5
6
|
import { gasLeftToGas } from '../avm_gas.js';
|
|
6
7
|
import { Field, TypeTag, Uint8 } from '../avm_memory_types.js';
|
|
7
|
-
import { type AvmContractCallResults } from '../avm_message_call_result.js';
|
|
8
8
|
import { AvmSimulator } from '../avm_simulator.js';
|
|
9
9
|
import { RethrownError } from '../errors.js';
|
|
10
10
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
@@ -88,7 +88,7 @@ abstract class ExternalCall extends Instruction {
|
|
|
88
88
|
);
|
|
89
89
|
|
|
90
90
|
const simulator = new AvmSimulator(nestedContext);
|
|
91
|
-
const nestedCallResults:
|
|
91
|
+
const nestedCallResults: AvmContractCallResult = await simulator.execute();
|
|
92
92
|
const success = !nestedCallResults.reverted;
|
|
93
93
|
|
|
94
94
|
// TRANSITIONAL: We rethrow here so that the MESSAGE gets propagated.
|
|
@@ -120,7 +120,6 @@ abstract class ExternalCall extends Instruction {
|
|
|
120
120
|
// Accept the nested call's state and trace the nested call
|
|
121
121
|
await context.persistableState.processNestedCall(
|
|
122
122
|
/*nestedState=*/ nestedContext.persistableState,
|
|
123
|
-
/*success=*/ success,
|
|
124
123
|
/*nestedEnvironment=*/ nestedContext.environment,
|
|
125
124
|
/*startGasLeft=*/ Gas.from(allocatedGas),
|
|
126
125
|
/*endGasLeft=*/ Gas.from(nestedContext.machineState.gasLeft),
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
FeePerDAGas,
|
|
22
22
|
FeePerL2Gas,
|
|
23
23
|
FieldDiv,
|
|
24
|
+
FunctionSelector,
|
|
24
25
|
GetContractInstance,
|
|
25
26
|
InternalCall,
|
|
26
27
|
InternalReturn,
|
|
@@ -85,16 +86,16 @@ const INSTRUCTION_SET = () =>
|
|
|
85
86
|
[Address.opcode, Address],
|
|
86
87
|
[StorageAddress.opcode, StorageAddress],
|
|
87
88
|
[Sender.opcode, Sender],
|
|
88
|
-
[
|
|
89
|
-
[FeePerDAGas.opcode, FeePerDAGas],
|
|
89
|
+
[FunctionSelector.opcode, FunctionSelector],
|
|
90
90
|
[TransactionFee.opcode, TransactionFee],
|
|
91
|
-
//[Contractcalldepth.opcode, Contractcalldepth],
|
|
92
91
|
// Execution Environment - Globals
|
|
93
92
|
[ChainId.opcode, ChainId],
|
|
94
93
|
[Version.opcode, Version],
|
|
95
94
|
[BlockNumber.opcode, BlockNumber],
|
|
96
95
|
[Timestamp.opcode, Timestamp],
|
|
97
96
|
//[Coinbase.opcode, Coinbase],
|
|
97
|
+
[FeePerL2Gas.opcode, FeePerL2Gas],
|
|
98
|
+
[FeePerDAGas.opcode, FeePerDAGas],
|
|
98
99
|
//[Blockl2gaslimit.opcode, Blockl2gaslimit],
|
|
99
100
|
//[Blockdagaslimit.opcode, Blockdagaslimit],
|
|
100
101
|
// Execution Environment - Calldata
|
|
@@ -27,15 +27,15 @@ export enum Opcode {
|
|
|
27
27
|
ADDRESS,
|
|
28
28
|
STORAGEADDRESS,
|
|
29
29
|
SENDER,
|
|
30
|
-
|
|
31
|
-
FEEPERDAGAS,
|
|
30
|
+
FUNCTIONSELECTOR,
|
|
32
31
|
TRANSACTIONFEE,
|
|
33
|
-
CONTRACTCALLDEPTH,
|
|
34
32
|
CHAINID,
|
|
35
33
|
VERSION,
|
|
36
34
|
BLOCKNUMBER,
|
|
37
35
|
TIMESTAMP,
|
|
38
36
|
COINBASE,
|
|
37
|
+
FEEPERL2GAS,
|
|
38
|
+
FEEPERDAGAS,
|
|
39
39
|
BLOCKL2GASLIMIT,
|
|
40
40
|
BLOCKDAGASLIMIT,
|
|
41
41
|
CALLDATACOPY,
|
|
@@ -459,9 +459,9 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
459
459
|
|
|
460
460
|
#checkValidStaticCall(childExecutionResult: ExecutionResult) {
|
|
461
461
|
if (
|
|
462
|
-
childExecutionResult.callStackItem.publicInputs.
|
|
463
|
-
childExecutionResult.callStackItem.publicInputs.
|
|
464
|
-
childExecutionResult.callStackItem.publicInputs.
|
|
462
|
+
childExecutionResult.callStackItem.publicInputs.noteHashes.some(item => !item.isEmpty()) ||
|
|
463
|
+
childExecutionResult.callStackItem.publicInputs.nullifiers.some(item => !item.isEmpty()) ||
|
|
464
|
+
childExecutionResult.callStackItem.publicInputs.l2ToL1Msgs.some(item => !item.isEmpty()) ||
|
|
465
465
|
childExecutionResult.callStackItem.publicInputs.encryptedLogsHashes.some(item => !item.isEmpty()) ||
|
|
466
466
|
childExecutionResult.callStackItem.publicInputs.unencryptedLogsHashes.some(item => !item.isEmpty())
|
|
467
467
|
) {
|
|
@@ -678,16 +678,25 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
678
678
|
|
|
679
679
|
/**
|
|
680
680
|
* Read the public storage data.
|
|
681
|
+
* @param contractAddress - The address to read storage from.
|
|
681
682
|
* @param startStorageSlot - The starting storage slot.
|
|
683
|
+
* @param blockNumber - The block number to read storage at.
|
|
682
684
|
* @param numberOfElements - Number of elements to read from the starting storage slot.
|
|
683
685
|
*/
|
|
684
|
-
public override async storageRead(
|
|
686
|
+
public override async storageRead(
|
|
687
|
+
contractAddress: Fr,
|
|
688
|
+
startStorageSlot: Fr,
|
|
689
|
+
blockNumber: number,
|
|
690
|
+
numberOfElements: number,
|
|
691
|
+
): Promise<Fr[]> {
|
|
685
692
|
const values = [];
|
|
686
693
|
for (let i = 0n; i < numberOfElements; i++) {
|
|
687
694
|
const storageSlot = new Fr(startStorageSlot.value + i);
|
|
688
695
|
|
|
689
|
-
const value = await this.aztecNode.getPublicStorageAt(
|
|
690
|
-
this.log.debug(
|
|
696
|
+
const value = await this.aztecNode.getPublicStorageAt(contractAddress, storageSlot, blockNumber);
|
|
697
|
+
this.log.debug(
|
|
698
|
+
`Oracle storage read: slot=${storageSlot.toString()} address-${contractAddress.toString()} value=${value}`,
|
|
699
|
+
);
|
|
691
700
|
|
|
692
701
|
values.push(value);
|
|
693
702
|
}
|
|
@@ -260,16 +260,25 @@ export class ViewDataOracle extends TypedOracle {
|
|
|
260
260
|
|
|
261
261
|
/**
|
|
262
262
|
* Read the public storage data.
|
|
263
|
+
* @param contractAddress - The address to read storage from.
|
|
263
264
|
* @param startStorageSlot - The starting storage slot.
|
|
265
|
+
* @param blockNumber - The block number to read storage at.
|
|
264
266
|
* @param numberOfElements - Number of elements to read from the starting storage slot.
|
|
265
267
|
*/
|
|
266
|
-
public override async storageRead(
|
|
268
|
+
public override async storageRead(
|
|
269
|
+
contractAddress: Fr,
|
|
270
|
+
startStorageSlot: Fr,
|
|
271
|
+
blockNumber: number,
|
|
272
|
+
numberOfElements: number,
|
|
273
|
+
) {
|
|
267
274
|
const values = [];
|
|
268
275
|
for (let i = 0n; i < numberOfElements; i++) {
|
|
269
276
|
const storageSlot = new Fr(startStorageSlot.value + i);
|
|
270
|
-
const value = await this.aztecNode.getPublicStorageAt(
|
|
277
|
+
const value = await this.aztecNode.getPublicStorageAt(contractAddress, storageSlot, blockNumber);
|
|
271
278
|
|
|
272
|
-
this.log.debug(
|
|
279
|
+
this.log.debug(
|
|
280
|
+
`Oracle storage read: slot=${storageSlot.toString()} address-${contractAddress.toString()} value=${value}`,
|
|
281
|
+
);
|
|
273
282
|
values.push(value);
|
|
274
283
|
}
|
|
275
284
|
return values;
|
package/src/mocks/fixtures.ts
CHANGED
|
@@ -14,10 +14,10 @@ import { makeAztecAddress, makeSelector } from '@aztec/circuits.js/testing';
|
|
|
14
14
|
import { FunctionType } from '@aztec/foundation/abi';
|
|
15
15
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
16
16
|
|
|
17
|
-
import { type
|
|
17
|
+
import { type PublicExecutionRequest, type PublicExecutionResult } from '../public/execution.js';
|
|
18
18
|
|
|
19
19
|
export class PublicExecutionResultBuilder {
|
|
20
|
-
private
|
|
20
|
+
private _executionRequest: PublicExecutionRequest;
|
|
21
21
|
private _nestedExecutions: PublicExecutionResult[] = [];
|
|
22
22
|
private _contractStorageUpdateRequests: ContractStorageUpdateRequest[] = [];
|
|
23
23
|
private _contractStorageReads: ContractStorageRead[] = [];
|
|
@@ -25,8 +25,8 @@ export class PublicExecutionResultBuilder {
|
|
|
25
25
|
private _reverted = false;
|
|
26
26
|
private _revertReason: SimulationError | undefined = undefined;
|
|
27
27
|
|
|
28
|
-
constructor(
|
|
29
|
-
this.
|
|
28
|
+
constructor(executionRequest: PublicExecutionRequest) {
|
|
29
|
+
this._executionRequest = executionRequest;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
static fromPublicCallRequest({
|
|
@@ -120,7 +120,7 @@ export class PublicExecutionResultBuilder {
|
|
|
120
120
|
|
|
121
121
|
build(overrides: Partial<PublicExecutionResult> = {}): PublicExecutionResult {
|
|
122
122
|
return {
|
|
123
|
-
|
|
123
|
+
executionRequest: this._executionRequest,
|
|
124
124
|
nestedExecutions: this._nestedExecutions,
|
|
125
125
|
noteHashReadRequests: [],
|
|
126
126
|
nullifierReadRequests: [],
|
|
@@ -128,9 +128,9 @@ export class PublicExecutionResultBuilder {
|
|
|
128
128
|
l1ToL2MsgReadRequests: [],
|
|
129
129
|
contractStorageUpdateRequests: this._contractStorageUpdateRequests,
|
|
130
130
|
returnValues: padArrayEnd(this._returnValues, Fr.ZERO, 4), // TODO(#5450) Need to use the proper return values here
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
noteHashes: [],
|
|
132
|
+
nullifiers: [],
|
|
133
|
+
l2ToL1Messages: [],
|
|
134
134
|
contractStorageReads: [],
|
|
135
135
|
unencryptedLogsHashes: [],
|
|
136
136
|
unencryptedLogs: UnencryptedFunctionL2Logs.empty(),
|