@aztec/simulator 0.0.1-commit.f295ac2 → 0.0.1-commit.f2ce05ee
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/private/acvm/acvm.d.ts +4 -2
- package/dest/private/acvm/acvm.d.ts.map +1 -1
- package/dest/private/acvm/acvm.js +4 -3
- package/dest/private/acvm_native.d.ts +5 -3
- package/dest/private/acvm_native.d.ts.map +1 -1
- package/dest/private/acvm_native.js +8 -6
- package/dest/private/acvm_wasm.d.ts +4 -3
- package/dest/private/acvm_wasm.d.ts.map +1 -1
- package/dest/private/acvm_wasm.js +4 -4
- package/dest/private/circuit_recording/circuit_recorder.d.ts +4 -3
- package/dest/private/circuit_recording/circuit_recorder.d.ts.map +1 -1
- package/dest/private/circuit_recording/circuit_recorder.js +5 -3
- package/dest/private/circuit_recording/file_circuit_recorder.d.ts +3 -2
- package/dest/private/circuit_recording/file_circuit_recorder.d.ts.map +1 -1
- package/dest/private/circuit_recording/file_circuit_recorder.js +2 -2
- package/dest/private/circuit_recording/memory_circuit_recorder.d.ts +7 -2
- package/dest/private/circuit_recording/memory_circuit_recorder.d.ts.map +1 -1
- package/dest/private/circuit_recording/memory_circuit_recorder.js +4 -4
- package/dest/private/factory.d.ts +3 -3
- package/dest/private/factory.d.ts.map +1 -1
- package/dest/private/factory.js +7 -4
- package/dest/public/avm/avm_context.d.ts +3 -3
- package/dest/public/avm/avm_context.d.ts.map +1 -1
- package/dest/public/avm/avm_contract_call_result.d.ts +6 -6
- package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -1
- package/dest/public/avm/avm_contract_call_result.js +3 -3
- package/dest/public/avm/avm_execution_environment.d.ts +6 -5
- package/dest/public/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/public/avm/avm_machine_state.d.ts +6 -5
- package/dest/public/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/public/avm/avm_machine_state.js +3 -2
- package/dest/public/avm/avm_memory_types.d.ts +1 -1
- package/dest/public/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/public/avm/avm_memory_types.js +3 -0
- package/dest/public/avm/avm_simulator.d.ts +3 -2
- package/dest/public/avm/avm_simulator.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.js +5 -4
- package/dest/public/avm/calldata.d.ts +51 -0
- package/dest/public/avm/calldata.d.ts.map +1 -0
- package/dest/public/avm/calldata.js +63 -0
- package/dest/public/avm/fixtures/account_proof_fetcher.d.ts +2 -0
- package/dest/public/avm/fixtures/account_proof_fetcher.d.ts.map +1 -0
- package/dest/public/avm/fixtures/account_proof_fetcher.js +152 -0
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.js +3 -2
- package/dest/public/avm/fixtures/initializers.d.ts +1 -1
- package/dest/public/avm/fixtures/initializers.d.ts.map +1 -1
- package/dest/public/avm/fixtures/initializers.js +2 -1
- package/dest/public/avm/opcodes/accrued_substate.d.ts +3 -4
- package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/public/avm/opcodes/accrued_substate.js +12 -12
- package/dest/public/avm/opcodes/contract.d.ts +1 -1
- package/dest/public/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/public/avm/opcodes/contract.js +4 -4
- package/dest/public/avm/opcodes/external_calls.d.ts +1 -1
- package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/public/avm/opcodes/external_calls.js +7 -7
- package/dest/public/avm/opcodes/memory.js +1 -1
- package/dest/public/avm/opcodes/storage.d.ts +13 -12
- package/dest/public/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/public/avm/opcodes/storage.js +30 -20
- package/dest/public/debug_fn_name.d.ts +4 -4
- package/dest/public/debug_fn_name.d.ts.map +1 -1
- package/dest/public/debug_fn_name.js +7 -5
- package/dest/public/executor_metrics.d.ts +1 -1
- package/dest/public/executor_metrics.d.ts.map +1 -1
- package/dest/public/executor_metrics.js +7 -2
- package/dest/public/fixtures/opcode_spammer.d.ts +3 -4
- package/dest/public/fixtures/opcode_spammer.d.ts.map +1 -1
- package/dest/public/fixtures/opcode_spammer.js +30 -58
- package/dest/public/fuzzing/avm_simulator_bin.js +7 -4
- package/dest/public/public_db_sources.d.ts +4 -3
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +4 -4
- package/dest/public/public_processor/public_processor.d.ts +5 -3
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +8 -5
- package/dest/public/public_processor/public_processor_metrics.d.ts +2 -2
- package/dest/public/public_processor/public_processor_metrics.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor_metrics.js +20 -4
- package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts +3 -2
- package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +2 -2
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts +5 -5
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.js +8 -8
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.d.ts +4 -4
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.js +5 -5
- package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts +4 -4
- package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.js +6 -6
- package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts +3 -2
- package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.js +2 -2
- package/dest/public/public_tx_simulator/factories.d.ts +3 -2
- package/dest/public/public_tx_simulator/factories.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/factories.js +3 -3
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +4 -3
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +8 -8
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +4 -3
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +9 -6
- package/dest/public/side_effect_trace.d.ts +4 -4
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +3 -3
- package/dest/public/state_manager/state_manager.d.ts +10 -4
- package/dest/public/state_manager/state_manager.d.ts.map +1 -1
- package/dest/public/state_manager/state_manager.js +12 -5
- package/dest/public/test_executor_metrics.d.ts +3 -2
- package/dest/public/test_executor_metrics.d.ts.map +1 -1
- package/dest/public/test_executor_metrics.js +2 -2
- package/package.json +16 -16
- package/src/private/acvm/acvm.ts +4 -3
- package/src/private/acvm_native.ts +11 -5
- package/src/private/acvm_wasm.ts +7 -3
- package/src/private/circuit_recording/circuit_recorder.ts +5 -3
- package/src/private/circuit_recording/file_circuit_recorder.ts +7 -2
- package/src/private/circuit_recording/memory_circuit_recorder.ts +6 -4
- package/src/private/factory.ts +7 -4
- package/src/public/avm/avm_context.ts +2 -2
- package/src/public/avm/avm_contract_call_result.ts +8 -6
- package/src/public/avm/avm_execution_environment.ts +9 -4
- package/src/public/avm/avm_machine_state.ts +6 -5
- package/src/public/avm/avm_memory_types.ts +4 -0
- package/src/public/avm/avm_simulator.ts +8 -5
- package/src/public/avm/calldata.ts +100 -0
- package/src/public/avm/fixtures/account_proof.json +553 -0
- package/src/public/avm/fixtures/account_proof_fetcher.ts +166 -0
- package/src/public/avm/fixtures/avm_simulation_tester.ts +8 -2
- package/src/public/avm/fixtures/initializers.ts +2 -1
- package/src/public/avm/opcodes/accrued_substate.ts +13 -15
- package/src/public/avm/opcodes/contract.ts +1 -4
- package/src/public/avm/opcodes/external_calls.ts +8 -7
- package/src/public/avm/opcodes/memory.ts +1 -1
- package/src/public/avm/opcodes/storage.ts +28 -20
- package/src/public/debug_fn_name.ts +10 -8
- package/src/public/executor_metrics.ts +4 -1
- package/src/public/fixtures/opcode_spammer.ts +49 -53
- package/src/public/fuzzing/avm_simulator_bin.ts +11 -1
- package/src/public/public_db_sources.ts +15 -5
- package/src/public/public_processor/public_processor.ts +18 -5
- package/src/public/public_processor/public_processor_metrics.ts +10 -4
- package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +6 -3
- package/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +9 -6
- package/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts +6 -4
- package/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts +7 -5
- package/src/public/public_tx_simulator/dumping_cpp_public_tx_simulator.ts +3 -1
- package/src/public/public_tx_simulator/factories.ts +4 -2
- package/src/public/public_tx_simulator/public_tx_context.ts +13 -6
- package/src/public/public_tx_simulator/public_tx_simulator.ts +14 -5
- package/src/public/side_effect_trace.ts +5 -2
- package/src/public/state_manager/state_manager.ts +27 -4
- package/src/public/test_executor_metrics.ts +3 -3
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetches an account proof from the Ethereum mainnet and saves it as account_proof.json.
|
|
3
|
+
* This script is not using any Aztec library code, so it's easily portable.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import { createPublicClient, fromRlp, hexToBytes, http } from 'viem';
|
|
9
|
+
import { mainnet } from 'viem/chains';
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
|
|
13
|
+
const RPC_URL = process.env.RPC_URL;
|
|
14
|
+
const ADDRESS = (process.env.ADDRESS || '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045') as `0x${string}`;
|
|
15
|
+
const BLOCK_TAG = process.env.BLOCK_NUMBER ? BigInt(process.env.BLOCK_NUMBER) : 'latest';
|
|
16
|
+
const MAX_ACCOUNT_PATH = 15;
|
|
17
|
+
|
|
18
|
+
function padTo(arr: number[], len: number) {
|
|
19
|
+
return [...arr, ...Array(len - arr.length).fill(0)].slice(0, len);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function toBytes(hex: `0x${string}`) {
|
|
23
|
+
return Array.from(hexToBytes(hex));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function bytesToU64s(bytes: number[]) {
|
|
27
|
+
const paddedBytes = padTo(bytes, 32);
|
|
28
|
+
return Array.from({ length: 4 }, (_, i) => {
|
|
29
|
+
let val = 0n;
|
|
30
|
+
for (let j = 0; j < 8; j++) {
|
|
31
|
+
val += BigInt(paddedBytes[i * 8 + j]) << BigInt(j * 8);
|
|
32
|
+
}
|
|
33
|
+
return val.toString();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function toBytesAndLen(val: bigint | number) {
|
|
38
|
+
if (val === 0n || val === 0) {
|
|
39
|
+
return { bytes: [0], length: 0 };
|
|
40
|
+
}
|
|
41
|
+
let hex = val.toString(16);
|
|
42
|
+
if (hex.length % 2) {
|
|
43
|
+
hex = '0' + hex;
|
|
44
|
+
}
|
|
45
|
+
const bytes = toBytes(`0x${hex}`);
|
|
46
|
+
return { bytes, length: bytes.length };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function parseNode(rlp: `0x${string}`) {
|
|
50
|
+
// Should be safe when working with branches and extensions without embedded children.
|
|
51
|
+
const decoded = fromRlp(rlp) as `0x${string}`[];
|
|
52
|
+
const node = {
|
|
53
|
+
rows: Array(16)
|
|
54
|
+
.fill(0)
|
|
55
|
+
.map(() => Array(32).fill(0)),
|
|
56
|
+
row_exist: Array(16).fill(false),
|
|
57
|
+
node_type: 0,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
if (decoded.length === 17) {
|
|
61
|
+
for (let i = 0; i < 16; i++) {
|
|
62
|
+
if (decoded[i] !== '0x') {
|
|
63
|
+
node.row_exist[i] = true;
|
|
64
|
+
node.rows[i] = padTo(toBytes(decoded[i]), 32);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} else if (decoded.length === 2) {
|
|
68
|
+
const keyBytes = toBytes(decoded[0]);
|
|
69
|
+
const prefix = keyBytes[0];
|
|
70
|
+
if (prefix >> 4 >= 2) {
|
|
71
|
+
throw new Error('Unsupported: leaf node in proof path');
|
|
72
|
+
}
|
|
73
|
+
node.node_type = 1;
|
|
74
|
+
// Extension header format expected by the noir code: check out storage_proof types.nr.
|
|
75
|
+
node.rows[0][0] = prefix >> 4;
|
|
76
|
+
node.rows[0][8] = prefix & 0x0f;
|
|
77
|
+
node.rows[0][16] = keyBytes.length - 1;
|
|
78
|
+
|
|
79
|
+
for (let i = 1; i < keyBytes.length && i < 32; i++) {
|
|
80
|
+
node.rows[1][i - 1] = keyBytes[i];
|
|
81
|
+
}
|
|
82
|
+
node.rows[2] = padTo(toBytes(decoded[1]), 32);
|
|
83
|
+
node.row_exist[0] = node.row_exist[1] = node.row_exist[2] = true;
|
|
84
|
+
}
|
|
85
|
+
return node;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function parseProof(proof: `0x${string}`[], maxLen: number) {
|
|
89
|
+
const nodes = proof.slice(0, -1).slice(0, maxLen).map(parseNode);
|
|
90
|
+
while (nodes.length < maxLen) {
|
|
91
|
+
nodes.push({
|
|
92
|
+
rows: Array(16)
|
|
93
|
+
.fill(0)
|
|
94
|
+
.map(() => Array(32).fill(0)),
|
|
95
|
+
row_exist: Array(16).fill(false),
|
|
96
|
+
node_type: 0,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return nodes;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function nodeToLibFormat(node: { rows: number[][]; row_exist: boolean[]; node_type: number }) {
|
|
103
|
+
return {
|
|
104
|
+
rows: node.rows.map(bytesToU64s),
|
|
105
|
+
row_exist: node.row_exist,
|
|
106
|
+
node_type: String(node.node_type),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function main() {
|
|
111
|
+
if (!RPC_URL) {
|
|
112
|
+
throw new Error('RPC_URL is not set');
|
|
113
|
+
}
|
|
114
|
+
console.log(`Fetching account proof for ${ADDRESS}`);
|
|
115
|
+
|
|
116
|
+
const client = createPublicClient({
|
|
117
|
+
chain: mainnet,
|
|
118
|
+
transport: http(RPC_URL),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const [blockNumber, proof, block] = await Promise.all([
|
|
122
|
+
client.getBlockNumber(),
|
|
123
|
+
client.getProof({
|
|
124
|
+
address: ADDRESS,
|
|
125
|
+
storageKeys: [],
|
|
126
|
+
blockNumber: BLOCK_TAG === 'latest' ? undefined : BLOCK_TAG,
|
|
127
|
+
}),
|
|
128
|
+
client.getBlock({
|
|
129
|
+
blockNumber: BLOCK_TAG === 'latest' ? undefined : BLOCK_TAG,
|
|
130
|
+
}),
|
|
131
|
+
]);
|
|
132
|
+
|
|
133
|
+
console.log(`Block: ${blockNumber}, Account nodes: ${proof.accountProof.length}`);
|
|
134
|
+
|
|
135
|
+
// The -1 is because the last node in the proof is the leaf, which is excluded from path verification.
|
|
136
|
+
const accountPathLen = proof.accountProof.length - 1;
|
|
137
|
+
if (accountPathLen > MAX_ACCOUNT_PATH) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Account proof path length ${accountPathLen} exceeds MAX_ACCOUNT_PATH ${MAX_ACCOUNT_PATH}. Increase the limit.`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const nonce = toBytesAndLen(proof.nonce);
|
|
144
|
+
const balance = toBytesAndLen(proof.balance);
|
|
145
|
+
|
|
146
|
+
const data = {
|
|
147
|
+
block_number: String(blockNumber),
|
|
148
|
+
node_length: String(accountPathLen),
|
|
149
|
+
root: bytesToU64s(toBytes(block.stateRoot)),
|
|
150
|
+
nodes: parseProof(proof.accountProof, MAX_ACCOUNT_PATH).map(nodeToLibFormat),
|
|
151
|
+
account: {
|
|
152
|
+
address: toBytes(ADDRESS).map(String),
|
|
153
|
+
balance: padTo(balance.bytes, 32).map(String),
|
|
154
|
+
balance_length: String(balance.length),
|
|
155
|
+
code_hash: bytesToU64s(toBytes(proof.codeHash)),
|
|
156
|
+
nonce: padTo(nonce.bytes, 8).map(String),
|
|
157
|
+
nonce_length: String(nonce.length),
|
|
158
|
+
storage_hash: bytesToU64s(toBytes(proof.storageHash)),
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
fs.writeFileSync(join(__dirname, 'account_proof.json'), JSON.stringify(data, null, 2));
|
|
163
|
+
console.log('account_proof.json generated');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
main().catch(console.error);
|
|
@@ -13,6 +13,7 @@ import { SimpleContractDataSource } from '../../fixtures/simple_contract_data_so
|
|
|
13
13
|
import { PublicContractsDB, PublicTreesDB } from '../../public_db_sources.js';
|
|
14
14
|
import { PublicPersistableStateManager } from '../../state_manager/state_manager.js';
|
|
15
15
|
import { AvmSimulator } from '../avm_simulator.js';
|
|
16
|
+
import { CallDataArray } from '../calldata.js';
|
|
16
17
|
import { BaseAvmSimulationTester } from './base_avm_simulation_tester.js';
|
|
17
18
|
import { initContext, initExecutionEnvironment } from './initializers.js';
|
|
18
19
|
import {
|
|
@@ -89,7 +90,7 @@ export class AvmSimulationTester extends BaseAvmSimulationTester {
|
|
|
89
90
|
collectCallMetadata: true,
|
|
90
91
|
});
|
|
91
92
|
const environment = initExecutionEnvironment({
|
|
92
|
-
calldata,
|
|
93
|
+
calldata: new CallDataArray(calldata),
|
|
93
94
|
globals,
|
|
94
95
|
address,
|
|
95
96
|
sender,
|
|
@@ -105,7 +106,12 @@ export class AvmSimulationTester extends BaseAvmSimulationTester {
|
|
|
105
106
|
if (result.reverted) {
|
|
106
107
|
this.logger.error(`Error in ${fnName}:`);
|
|
107
108
|
this.logger.error(
|
|
108
|
-
resolveContractAssertionMessage(
|
|
109
|
+
resolveContractAssertionMessage(
|
|
110
|
+
fnName,
|
|
111
|
+
result.revertReason!,
|
|
112
|
+
result.output.bestEffortReadAll(),
|
|
113
|
+
contractArtifact,
|
|
114
|
+
)!,
|
|
109
115
|
);
|
|
110
116
|
} else {
|
|
111
117
|
this.logger.info(`Simulation of function ${fnName} succeeded!`);
|
|
@@ -19,6 +19,7 @@ import { AvmContext } from '../avm_context.js';
|
|
|
19
19
|
import { AvmExecutionEnvironment } from '../avm_execution_environment.js';
|
|
20
20
|
import { AvmMachineState } from '../avm_machine_state.js';
|
|
21
21
|
import { AvmSimulator } from '../avm_simulator.js';
|
|
22
|
+
import { CallDataArray } from '../calldata.js';
|
|
22
23
|
import { DEFAULT_TIMESTAMP } from './utils.js';
|
|
23
24
|
|
|
24
25
|
/**
|
|
@@ -70,7 +71,7 @@ export function initExecutionEnvironment(overrides?: Partial<AvmExecutionEnviron
|
|
|
70
71
|
overrides?.transactionFee ?? Fr.zero(),
|
|
71
72
|
overrides?.globals ?? GlobalVariables.empty(),
|
|
72
73
|
overrides?.isStaticCall ?? false,
|
|
73
|
-
overrides?.calldata ?? [],
|
|
74
|
+
overrides?.calldata ?? new CallDataArray([]),
|
|
74
75
|
overrides?.config ?? PublicSimulatorConfig.empty(),
|
|
75
76
|
);
|
|
76
77
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { MAX_ETH_ADDRESS_VALUE } from '@aztec/constants';
|
|
2
|
+
|
|
1
3
|
import { NullifierCollisionError } from '../../side_effect_errors.js';
|
|
2
4
|
import type { AvmContext } from '../avm_context.js';
|
|
3
5
|
import { TypeTag, Uint1 } from '../avm_memory_types.js';
|
|
@@ -86,18 +88,11 @@ export class NullifierExists extends Instruction {
|
|
|
86
88
|
static type: string = 'NULLIFIEREXISTS';
|
|
87
89
|
static readonly opcode: Opcode = Opcode.NULLIFIEREXISTS;
|
|
88
90
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
89
|
-
static readonly wireFormat = [
|
|
90
|
-
OperandType.UINT8,
|
|
91
|
-
OperandType.UINT8,
|
|
92
|
-
OperandType.UINT16,
|
|
93
|
-
OperandType.UINT16,
|
|
94
|
-
OperandType.UINT16,
|
|
95
|
-
];
|
|
91
|
+
static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16, OperandType.UINT16];
|
|
96
92
|
|
|
97
93
|
constructor(
|
|
98
94
|
private addressingMode: number,
|
|
99
|
-
private
|
|
100
|
-
private addressOffset: number,
|
|
95
|
+
private siloedNullifierOffset: number,
|
|
101
96
|
private existsOffset: number,
|
|
102
97
|
) {
|
|
103
98
|
super();
|
|
@@ -111,13 +106,12 @@ export class NullifierExists extends Instruction {
|
|
|
111
106
|
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
112
107
|
);
|
|
113
108
|
|
|
114
|
-
const operands = [this.
|
|
115
|
-
const [
|
|
116
|
-
memory.
|
|
109
|
+
const operands = [this.siloedNullifierOffset, this.existsOffset];
|
|
110
|
+
const [siloedNullifierOffset, existsOffset] = addressing.resolve(operands, memory);
|
|
111
|
+
memory.checkTag(TypeTag.FIELD, siloedNullifierOffset);
|
|
117
112
|
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
const exists = await context.persistableState.checkNullifierExists(address, nullifier);
|
|
113
|
+
const siloedNullifier = memory.get(siloedNullifierOffset).toFr();
|
|
114
|
+
const exists = await context.persistableState.checkSiloedNullifierExists(siloedNullifier);
|
|
121
115
|
|
|
122
116
|
memory.set(existsOffset, exists ? new Uint1(1) : new Uint1(0));
|
|
123
117
|
}
|
|
@@ -282,6 +276,10 @@ export class SendL2ToL1Message extends Instruction {
|
|
|
282
276
|
memory.checkTags(TypeTag.FIELD, recipientOffset, contentOffset);
|
|
283
277
|
|
|
284
278
|
const recipient = memory.get(recipientOffset).toFr();
|
|
279
|
+
|
|
280
|
+
if (recipient.toBigInt() > MAX_ETH_ADDRESS_VALUE) {
|
|
281
|
+
throw new InstructionExecutionError(`SENDL2TOL1MSG: Recipient address is too large`);
|
|
282
|
+
}
|
|
285
283
|
const content = memory.get(contentOffset).toFr();
|
|
286
284
|
context.persistableState.writeL2ToL1Message(context.environment.address, recipient, content);
|
|
287
285
|
}
|
|
@@ -67,9 +67,6 @@ export class GetContractInstance extends Instruction {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
const memberValueOffset = dstOffset + 1;
|
|
72
|
-
memory.set(existsOffset, new Uint1(exists ? 1 : 0));
|
|
73
|
-
memory.set(memberValueOffset, memberValue);
|
|
70
|
+
memory.setSlice(dstOffset, [new Uint1(exists ? 1 : 0), memberValue]);
|
|
74
71
|
}
|
|
75
72
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
2
|
import type { AvmContractCallResult } from '../avm_contract_call_result.js';
|
|
3
3
|
import { type Field, TypeTag, Uint1 } from '../avm_memory_types.js';
|
|
4
|
+
import { CallDataMemory, ReturnDataMemory } from '../calldata.js';
|
|
4
5
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
5
6
|
import { Addressing } from './addressing_mode.js';
|
|
6
7
|
import { Instruction } from './instruction.js';
|
|
@@ -45,8 +46,8 @@ abstract class ExternalCall extends Instruction {
|
|
|
45
46
|
memory.checkTag(TypeTag.UINT32, argsSizeOffset);
|
|
46
47
|
|
|
47
48
|
const calldataSize = memory.get(argsSizeOffset).toNumber();
|
|
48
|
-
|
|
49
|
-
const calldata = memory
|
|
49
|
+
|
|
50
|
+
const calldata = new CallDataMemory(memory, argsOffset, calldataSize);
|
|
50
51
|
|
|
51
52
|
const callAddress = memory.getAs<Field>(addrOffset);
|
|
52
53
|
// If we are already in a static call, we propagate the environment.
|
|
@@ -73,8 +74,8 @@ abstract class ExternalCall extends Instruction {
|
|
|
73
74
|
const success = !nestedCallResults.reverted;
|
|
74
75
|
|
|
75
76
|
// Save return/revert data for later.
|
|
76
|
-
const
|
|
77
|
-
context.machineState.nestedReturndata =
|
|
77
|
+
const returnData = nestedCallResults.output;
|
|
78
|
+
context.machineState.nestedReturndata = returnData;
|
|
78
79
|
|
|
79
80
|
// Track the success status directly
|
|
80
81
|
context.machineState.nestedCallSuccess = success;
|
|
@@ -89,7 +90,7 @@ abstract class ExternalCall extends Instruction {
|
|
|
89
90
|
// (in Noir code).
|
|
90
91
|
if (!success) {
|
|
91
92
|
context.machineState.collectedRevertInfo = {
|
|
92
|
-
revertDataRepresentative:
|
|
93
|
+
revertDataRepresentative: returnData.bestEffortReadAll(),
|
|
93
94
|
recursiveRevertReason: nestedCallResults.revertReason!,
|
|
94
95
|
};
|
|
95
96
|
}
|
|
@@ -195,7 +196,7 @@ export class Return extends Instruction {
|
|
|
195
196
|
memory.checkTag(TypeTag.UINT32, returnSizeOffset);
|
|
196
197
|
const returnSize = memory.get(returnSizeOffset).toNumber();
|
|
197
198
|
|
|
198
|
-
const output = memory
|
|
199
|
+
const output = new ReturnDataMemory(memory, returnOffset, returnSize);
|
|
199
200
|
|
|
200
201
|
context.machineState.return(output);
|
|
201
202
|
}
|
|
@@ -243,7 +244,7 @@ export class Revert extends Instruction {
|
|
|
243
244
|
|
|
244
245
|
memory.checkTag(TypeTag.UINT32, retSizeOffset);
|
|
245
246
|
const retSize = memory.get(retSizeOffset).toNumber();
|
|
246
|
-
const output = memory
|
|
247
|
+
const output = new ReturnDataMemory(memory, returnOffset, retSize);
|
|
247
248
|
|
|
248
249
|
context.machineState.revert(output);
|
|
249
250
|
}
|
|
@@ -242,7 +242,7 @@ export class ReturndataSize extends Instruction {
|
|
|
242
242
|
const operands = [this.dstOffset];
|
|
243
243
|
const [dstOffset] = addressing.resolve(operands, memory);
|
|
244
244
|
|
|
245
|
-
memory.set(dstOffset, new Uint32(context.machineState.nestedReturndata.length));
|
|
245
|
+
memory.set(dstOffset, new Uint32(context.machineState.nestedReturndata.length()));
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
|
|
@@ -5,7 +5,9 @@ import { Opcode, OperandType } from '../serialization/instruction_serialization.
|
|
|
5
5
|
import { Addressing } from './addressing_mode.js';
|
|
6
6
|
import { Instruction } from './instruction.js';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
export class SStore extends Instruction {
|
|
9
|
+
static readonly type: string = 'SSTORE';
|
|
10
|
+
static readonly opcode = Opcode.SSTORE;
|
|
9
11
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
10
12
|
public static readonly wireFormat: OperandType[] = [
|
|
11
13
|
OperandType.UINT8,
|
|
@@ -15,21 +17,12 @@ abstract class BaseStorageInstruction extends Instruction {
|
|
|
15
17
|
];
|
|
16
18
|
|
|
17
19
|
constructor(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
private addressingMode: number,
|
|
21
|
+
private srcOffset: number,
|
|
22
|
+
private slotOffset: number,
|
|
21
23
|
) {
|
|
22
24
|
super();
|
|
23
25
|
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class SStore extends BaseStorageInstruction {
|
|
27
|
-
static readonly type: string = 'SSTORE';
|
|
28
|
-
static readonly opcode = Opcode.SSTORE;
|
|
29
|
-
|
|
30
|
-
constructor(addressingMode: number, srcOffset: number, slotOffset: number) {
|
|
31
|
-
super(addressingMode, srcOffset, slotOffset);
|
|
32
|
-
}
|
|
33
26
|
|
|
34
27
|
public async execute(context: AvmContext): Promise<void> {
|
|
35
28
|
if (context.environment.isStaticCall) {
|
|
@@ -43,7 +36,7 @@ export class SStore extends BaseStorageInstruction {
|
|
|
43
36
|
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
44
37
|
);
|
|
45
38
|
|
|
46
|
-
const operands = [this.
|
|
39
|
+
const operands = [this.srcOffset, this.slotOffset];
|
|
47
40
|
const [srcOffset, slotOffset] = addressing.resolve(operands, memory);
|
|
48
41
|
// We read before tag checking since it's needed for gas cost calculation
|
|
49
42
|
const slot = memory.get(slotOffset).toFr();
|
|
@@ -60,12 +53,25 @@ export class SStore extends BaseStorageInstruction {
|
|
|
60
53
|
}
|
|
61
54
|
}
|
|
62
55
|
|
|
63
|
-
export class SLoad extends
|
|
56
|
+
export class SLoad extends Instruction {
|
|
64
57
|
static readonly type: string = 'SLOAD';
|
|
65
58
|
static readonly opcode = Opcode.SLOAD;
|
|
59
|
+
// Informs (de)serialization. See Instruction.deserialize.
|
|
60
|
+
public static readonly wireFormat: OperandType[] = [
|
|
61
|
+
OperandType.UINT8,
|
|
62
|
+
OperandType.UINT8,
|
|
63
|
+
OperandType.UINT16,
|
|
64
|
+
OperandType.UINT16,
|
|
65
|
+
OperandType.UINT16,
|
|
66
|
+
];
|
|
66
67
|
|
|
67
|
-
constructor(
|
|
68
|
-
|
|
68
|
+
constructor(
|
|
69
|
+
private addressingMode: number,
|
|
70
|
+
private slotOffset: number,
|
|
71
|
+
private contractAddressOffset: number,
|
|
72
|
+
private dstOffset: number,
|
|
73
|
+
) {
|
|
74
|
+
super();
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
public async execute(context: AvmContext): Promise<void> {
|
|
@@ -76,12 +82,14 @@ export class SLoad extends BaseStorageInstruction {
|
|
|
76
82
|
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
77
83
|
);
|
|
78
84
|
|
|
79
|
-
const operands = [this.
|
|
80
|
-
const [slotOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
85
|
+
const operands = [this.slotOffset, this.contractAddressOffset, this.dstOffset];
|
|
86
|
+
const [slotOffset, contractAddressOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
81
87
|
memory.checkTag(TypeTag.FIELD, slotOffset);
|
|
88
|
+
memory.checkTag(TypeTag.FIELD, contractAddressOffset);
|
|
82
89
|
|
|
83
90
|
const slot = memory.get(slotOffset).toFr();
|
|
84
|
-
const
|
|
91
|
+
const contractAddress = memory.get(contractAddressOffset).toAztecAddress();
|
|
92
|
+
const value = await context.persistableState.readStorage(contractAddress, slot);
|
|
85
93
|
memory.set(dstOffset, new Field(value));
|
|
86
94
|
}
|
|
87
95
|
}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
1
|
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
2
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
3
|
|
|
4
|
+
import type { CallData } from './avm/calldata.js';
|
|
5
5
|
import type { PublicContractsDBInterface } from './db_interfaces.js';
|
|
6
6
|
|
|
7
7
|
export async function getPublicFunctionDebugName(
|
|
8
8
|
db: PublicContractsDBInterface,
|
|
9
9
|
contractAddress: AztecAddress,
|
|
10
|
-
calldata:
|
|
10
|
+
calldata: CallData,
|
|
11
11
|
): Promise<string> {
|
|
12
12
|
// Public function is dispatched and therefore the target function is passed in the first argument.
|
|
13
|
-
|
|
13
|
+
const selectorField = calldata.read(0);
|
|
14
|
+
if (!selectorField) {
|
|
14
15
|
return `<calldata[0] undefined> (Contract Address: ${contractAddress})`;
|
|
15
16
|
}
|
|
16
|
-
const fallbackName = `<calldata[0]:${
|
|
17
|
-
const selector = FunctionSelector.fromFieldOrUndefined(
|
|
17
|
+
const fallbackName = `<calldata[0]:${selectorField.toString()}> (Contract Address: ${contractAddress})`;
|
|
18
|
+
const selector = FunctionSelector.fromFieldOrUndefined(selectorField);
|
|
18
19
|
if (!selector) {
|
|
19
20
|
return fallbackName;
|
|
20
21
|
}
|
|
@@ -32,13 +33,14 @@ export async function getPublicFunctionDebugName(
|
|
|
32
33
|
export async function getPublicFunctionSelectorAndName(
|
|
33
34
|
db: PublicContractsDBInterface,
|
|
34
35
|
contractAddress: AztecAddress,
|
|
35
|
-
calldata:
|
|
36
|
+
calldata: CallData,
|
|
36
37
|
): Promise<{ functionSelector?: FunctionSelector; functionName?: string }> {
|
|
37
38
|
// Public function is dispatched and therefore the target function is passed in the first argument.
|
|
38
|
-
|
|
39
|
+
const selectorField = calldata.read(0);
|
|
40
|
+
if (!selectorField) {
|
|
39
41
|
return {};
|
|
40
42
|
}
|
|
41
|
-
const selector = FunctionSelector.fromFieldOrUndefined(
|
|
43
|
+
const selector = FunctionSelector.fromFieldOrUndefined(selectorField);
|
|
42
44
|
if (!selector) {
|
|
43
45
|
return {};
|
|
44
46
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type TelemetryClient,
|
|
8
8
|
type Tracer,
|
|
9
9
|
type UpDownCounter,
|
|
10
|
+
createUpDownCounterWithDefault,
|
|
10
11
|
} from '@aztec/telemetry-client';
|
|
11
12
|
|
|
12
13
|
import type { ExecutorMetricsInterface } from './executor_metrics_interface.js';
|
|
@@ -25,7 +26,9 @@ export class ExecutorMetrics implements ExecutorMetricsInterface {
|
|
|
25
26
|
this.tracer = client.getTracer(name);
|
|
26
27
|
const meter = client.getMeter(name);
|
|
27
28
|
|
|
28
|
-
this.fnCount = meter
|
|
29
|
+
this.fnCount = createUpDownCounterWithDefault(meter, Metrics.PUBLIC_EXECUTOR_SIMULATION_COUNT, {
|
|
30
|
+
[Attributes.OK]: [true, false],
|
|
31
|
+
});
|
|
29
32
|
|
|
30
33
|
this.fnDuration = meter.createHistogram(Metrics.PUBLIC_EXECUTOR_SIMULATION_DURATION);
|
|
31
34
|
|