From dfcf276dab2470abebe915b102d735ccc34fbdb4 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Thu, 30 Nov 2023 13:27:15 +0100 Subject: [PATCH 1/7] Refactor encode_empty_node and encode_branch_node Clean code Not important Restore jumpdets_analysis.asm Refactor encode_empty_node and encode_branch_node --- .../cpu/kernel/asm/core/jumpdest_analysis.asm | 29 +- evm/src/cpu/kernel/asm/main.asm | 3 + evm/src/cpu/kernel/asm/mpt/hash/hash.asm | 111 ++- evm/src/cpu/kernel/asm/mpt/util.asm | 10 + evm/src/generation/mod.rs | 776 +++++++++++++++++- 5 files changed, 904 insertions(+), 25 deletions(-) diff --git a/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm b/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm index bda6f96e63..56d9e12621 100644 --- a/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm +++ b/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm @@ -4,8 +4,9 @@ global jumpdest_analysis: // stack: ctx, code_len, retdest PUSH 0 // i = 0 + %stack (i, ctx, code_len, retdest) -> (i, ctx, code_len, retdest, 0) // ctr -loop: +global loop: // stack: i, ctx, code_len, retdest // Ideally we would break if i >= code_len, but checking i > code_len is // cheaper. It doesn't hurt to over-read by 1, since we'll read 0 which is @@ -13,6 +14,20 @@ loop: DUP3 DUP2 GT // i > code_len %jumpi(return) + %stack (i, ctx) -> (ctx, @SEGMENT_CODE, i, 32, i, ctx) + %mload_packing + // stack: packed_opcodes + DUP1 + PUSH 0x8080808080808080808080808080808080808080808080808080808080808080 + AND +global debug_before_as_dad: + %jumpi(as_dad) +global debug_wuau: +as_dad: + POP +global debug_not_wuau: + + // stack: i, ctx, code_len, retdest %stack (i, ctx) -> (ctx, @SEGMENT_CODE, i, i, ctx) MLOAD_GENERAL @@ -28,8 +43,11 @@ loop: // stack: JUMPDEST, i, ctx, code_len, retdest %stack (JUMPDEST, i, ctx) -> (1, ctx, @SEGMENT_JUMPDEST_BITS, i, JUMPDEST, i, ctx) MSTORE_GENERAL + %stack (opcode, i, ctx, code_len, retdest, ctr) -> (ctr, opcode, i, ctx, code_len, retdest) + %increment + %stack (ctr, opcode, i, ctx, code_len, retdest) -> (opcode, i, ctx, code_len, retdest, ctr) -continue: +global continue: // stack: opcode, i, ctx, code_len, retdest %add_const(code_bytes_to_skip) %mload_kernel_code @@ -38,9 +56,12 @@ continue: // stack: i, ctx, code_len, retdest %jump(loop) -return: +global return: // stack: i, ctx, code_len, retdest %pop3 + SWAP1 +global debug_ctr: + POP JUMP // Determines how many bytes away is the next opcode, based on the opcode we read. @@ -48,7 +69,7 @@ return: // // Note that the range of PUSH opcodes is [0x60, 0x80). I.e. PUSH1 is 0x60 // and PUSH32 is 0x7f. -code_bytes_to_skip: +global code_bytes_to_skip: %rep 96 BYTES 1 // 0x00-0x5f %endrep diff --git a/evm/src/cpu/kernel/asm/main.asm b/evm/src/cpu/kernel/asm/main.asm index b495d49947..f6cd03bc8f 100644 --- a/evm/src/cpu/kernel/asm/main.asm +++ b/evm/src/cpu/kernel/asm/main.asm @@ -13,6 +13,9 @@ global main: // Initialise the shift table %shift_table_init + + // Encode constant nodes + %initialize_rlp_segment // Initialize the state, transaction and receipt trie root pointers. PROVER_INPUT(trie_ptr::state) diff --git a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm index df7e1d741d..3bbb84f38f 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -92,9 +92,9 @@ maybe_hash_node: KECCAK_GENERAL %stack (hash, cur_len, retdest) -> (retdest, hash, 32, cur_len) JUMP -pack_small_rlp: - // stack: result_ptr, result_len, cur_len, retdest - %stack (result_ptr, result_len, cur_len) +global pack_small_rlp: + // stack: result_ptr, result_len, retdest + %stack (result_ptr, result_len) -> (0, @SEGMENT_RLP_RAW, result_ptr, result_len, after_packed_small_rlp, result_len, cur_len) %jump(mload_packing) @@ -105,10 +105,10 @@ after_packed_small_rlp: // RLP encode the given trie node, and return an (pointer, length) pair // indicating where the data lives within @SEGMENT_RLP_RAW. // -// Pre stack: node_type, node_ptr, encode_value, cur_len, retdest -// Post stack: result_ptr, result_len, cur_len -encode_node: - // stack: node_type, node_ptr, encode_value, cur_len, retdest +// Pre stack: node_type, node_ptr, encode_value, retdest +// Post stack: result_ptr, result_len +global encode_node: + // stack: node_type, node_ptr, encode_value, retdest // Increment node_ptr, so it points to the node payload instead of its type. SWAP1 %increment SWAP1 // stack: node_type, node_payload_ptr, encode_value, cur_len, retdest @@ -123,20 +123,13 @@ encode_node: PANIC global encode_node_empty: - // stack: node_type, node_payload_ptr, encode_value, cur_len, retdest - // Then length of `TrieData` is unchanged here. + // stack: node_type, node_payload_ptr, encode_value, retdest %pop3 - // stack: cur_len, retdest - // An empty node is encoded as a single byte, 0x80, which is the RLP encoding of the empty string. - // TODO: Write this byte just once to RLP memory, then we can always return (0, 1). - %alloc_rlp_block - // stack: rlp_pos, cur_len, retdest - PUSH 0x80 - // stack: 0x80, rlp_pos, cur_len, retdest - DUP2 - // stack: rlp_pos, 0x80, rlp_pos, cur_len, retdest - %mstore_rlp - %stack (rlp_pos, cur_len, retdest) -> (retdest, rlp_pos, 1, cur_len) + PUSH 0x1000 + %mload_kernel(@SEGMENT_RLP_RAW) +global debug_it_should_be_128: + POP + %stack (retdest) -> (retdest, 0x1000, 1) JUMP global encode_node_branch: @@ -329,3 +322,81 @@ encode_node_leaf_after_encode_value: %stack (rlp_prefix_start_pos, rlp_len, cur_len, retdest) -> (retdest, rlp_prefix_start_pos, rlp_len, cur_len) JUMP + +global encode_node_branch_new: + // stack: node_type, node_payload_ptr, encode_value, retdest + POP + // stack: node_payload_ptr, encode_value, retdest + + //Allocate a block of RLP memory + %alloc_rlp_block DUP1 + // stack: rlp_pos, node_payload_ptr, encode_value, retdest + + // Call encode_or_hash_node on each child + %encode_child_new(0) %encode_child_new(1) %encode_child_new(2) %encode_child_new(3) + %encode_child_new(4) %encode_child_new(5) %encode_child_new(6) %encode_child_new(7) + %encode_child_new(8) %encode_child_new(9) %encode_child_new(10) %encode_child_new(11) + %encode_child_new(12) %encode_child_new(13) %encode_child_new(14) %encode_child_new(15) + + // stack: rlp_pos', rlp_start, node_payload_ptr, encode_value, retdest + + %stack (rlp_pos, rlp_start, node_payload_ptr) + -> (node_payload_ptr, rlp_pos, rlp_start) + %add_const(16) + // stack: value_ptr_ptr, rlp_pos', rlp_start, encode_value, retdest + %mload_trie_data + // stack: value_ptr, rlp_pos', rlp_start, encode_value, retdest + DUP1 %jumpi(encode_node_branch_with_value_new) + + // No value; append the empty string (0x80). + // stack: value_ptr, rlp_pos', rlp_start, encode_value, retdest + %stack (value_ptr, rlp_pos, rlp_start, encode_value) -> (rlp_pos, 0x80, rlp_pos, rlp_start) + %mstore_rlp + // stack: rlp_pos', rlp_start, retdest + %increment + // stack: rlp_pos'', rlp_start, retdest + %jump(encode_node_branch_prepend_prefix_new) +encode_node_branch_with_value_new: + // stack: value_ptr, rlp_pos', rlp_start, encode_value, retdest + %stack (value_ptr, rlp_pos, rlp_start, encode_value) + -> (encode_value, rlp_pos, value_ptr, encode_node_branch_prepend_prefix, rlp_start) + JUMP // call encode_value +encode_node_branch_prepend_prefix_new: + // stack: rlp_pos'', rlp_start, retdest + %prepend_rlp_list_prefix + // stack: rlp_prefix_start, rlp_len, retdest + %stack (rlp_prefix_start, rlp_len, retdest) + -> (retdest, rlp_prefix_start, rlp_len) + JUMP + + +// Part of the encode_node_branch function. Encodes the i'th child. +// Stores the result in SEGMENT_TRIE_ENCODED_CHILD[base + i], and its length in +// SEGMENT_TRIE_ENCODED_CHILD_LEN[base + i]. +%macro encode_child_new(i) + // stack: rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest + PUSH %%after_encode + DUP5 DUP5 + // stack: node_payload_ptr, encode_value, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest + %add_const($i) %mload_trie_data + // stack: child_i_ptr, encode_value, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest + %jump(encode_or_hash_node) +%%after_encode: + // stack: result, result_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest + // If result_len != 32, result is raw RLP, with an appropriate RLP prefix already. + SWAP1 DUP1 %sub_const(32) %jumpi(%%unpack) + // Otherwise, result is a hash, and we need to add the prefix 0x80 + 32 = 160. + // stack: result_len, result, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest + PUSH 160 + DUP4 // rlp_pos + %mstore_rlp + SWAP2 %increment SWAP2 // rlp_pos += 1 +%%unpack: + %stack (result_len, result, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest) + -> (rlp_pos, result, result_len, %%after_unpacking, + rlp_start, node_payload_ptr, encode_value, retdest) + %jump(mstore_unpacking_rlp) +%%after_unpacking: + // stack: rlp_pos', rlp_start, node_payload_ptr, encode_value, retdest +%endmacro + diff --git a/evm/src/cpu/kernel/asm/mpt/util.asm b/evm/src/cpu/kernel/asm/mpt/util.asm index 80e5c6f7c5..b492a0d055 100644 --- a/evm/src/cpu/kernel/asm/mpt/util.asm +++ b/evm/src/cpu/kernel/asm/mpt/util.asm @@ -10,6 +10,16 @@ // stack: (empty) %endmacro +%macro initialize_rlp_segment + // Write the encoding of the empty node to address 0 leaving 9 bytes for a prefix + // TODO: Do we need a prefix? + PUSH 0x80 + PUSH 0x1000 + %mstore_rlp + PUSH 0x1000 // TODO: use 10? + %mstore_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE) +%endmacro + %macro alloc_rlp_block // stack: (empty) %mload_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE) diff --git a/evm/src/generation/mod.rs b/evm/src/generation/mod.rs index d691d34e61..a3ba330244 100644 --- a/evm/src/generation/mod.rs +++ b/evm/src/generation/mod.rs @@ -296,14 +296,63 @@ pub fn generate_traces, const D: usize>( Ok((tables, public_values)) } -fn simulate_cpu, const D: usize>( +fn _simulate_cpu, const D: usize>( + state: &mut GenerationState, +) -> anyhow::Result<()> { + let halt_pc = KERNEL.global_labels["halt"]; + + loop { + // If we've reached the kernel's halt routine, and our trace length is a power of 2, stop. + let pc = state.registers.program_counter; + let halt = state.registers.is_kernel && pc == halt_pc; + if halt { + log::info!("CPU halted after {} cycles", state.traces.clock()); + + // Padding + let mut row = CpuColumnsView::::default(); + row.clock = F::from_canonical_usize(state.traces.clock()); + row.context = F::from_canonical_usize(state.registers.context); + row.program_counter = F::from_canonical_usize(pc); + row.is_kernel_mode = F::ONE; + row.gas = F::from_canonical_u64(state.registers.gas_used); + row.stack_len = F::from_canonical_usize(state.registers.stack_len); + + loop { + state.traces.push_cpu(row); + row.clock += F::ONE; + if state.traces.clock().is_power_of_two() { + break; + } + } + + log::info!("CPU trace padded to {} cycles", state.traces.clock()); + + return Ok(()); + } + + transition(state)?; + } +} + +fn __simulate_cpu, const D: usize>( state: &mut GenerationState, ) -> anyhow::Result<()> { + let mut profiling_map = HashMap::::new(); + let halt_pc = KERNEL.global_labels["halt"]; loop { // If we've reached the kernel's halt routine, and our trace length is a power of 2, stop. let pc = state.registers.program_counter; + if let Ok(idx) = KERNEL + .ordered_labels + .binary_search_by_key(&pc, |label| KERNEL.global_labels[label]) + { + profiling_map + .entry(KERNEL.ordered_labels[idx].clone()) + .and_modify(|counter| *counter += 1) + .or_insert(1); + } let halt = state.registers.is_kernel && pc == halt_pc; if halt { log::info!("CPU halted after {} cycles", state.traces.clock()); @@ -324,12 +373,737 @@ fn simulate_cpu, const D: usize>( break; } } + log::info!("CPU trace padded to {} cycles", state.traces.clock()); + + let mut sorted_labels: Vec<_> = profiling_map.iter().collect(); + sorted_labels.sort_unstable_by_key(|item| item.1); + sorted_labels.reverse(); + log::info!("Offsets: {:?}", sorted_labels); + return Ok(()); + } + + transition(state)?; + } +} + +fn simulate_cpu, const D: usize>( + state: &mut GenerationState, +) -> anyhow::Result<()> { + let mut profiling_map = HashMap::::new(); + + let halt_pc = KERNEL.global_labels["halt"]; + + loop { + // If we've reached the kernel's halt routine, and our trace length is a power of 2, stop. + let pc = state.registers.program_counter; + let idx = match KERNEL + .ordered_labels + .binary_search_by_key(&pc, |label| KERNEL.global_labels[label]) + { + Ok(idx) => Some(idx), + Err(0) => None, + Err(idx) => Some(idx - 1), + }; + if let Some(idx) = idx { + profiling_map + .entry(KERNEL.ordered_labels[idx].clone()) + .and_modify(|counter| *counter += 1) + .or_insert(1); + } + let halt = state.registers.is_kernel && pc == halt_pc; + if halt { + log::info!("CPU halted after {} cycles", state.traces.clock()); + + // Padding + let mut row = CpuColumnsView::::default(); + row.clock = F::from_canonical_usize(state.traces.clock()); + row.context = F::from_canonical_usize(state.registers.context); + row.program_counter = F::from_canonical_usize(pc); + row.is_kernel_mode = F::ONE; + row.gas = F::from_canonical_u64(state.registers.gas_used); + row.stack_len = F::from_canonical_usize(state.registers.stack_len); + + loop { + state.traces.push_cpu(row); + row.clock += F::ONE; + if state.traces.clock().is_power_of_two() { + break; + } + } log::info!("CPU trace padded to {} cycles", state.traces.clock()); + let mut sorted_labels: Vec<_> = profiling_map.iter().collect(); + sorted_labels.sort_unstable_by_key(|item| item.1); + sorted_labels.reverse(); + log::info!("Offsets: {:?}", sorted_labels); + return Ok(()); } transition(state)?; + { + let _ = [ + ("secp_add_valid_points_no_edge_case", 10980), + ("ecrecover", 9009), + ("num_bytes", 7306), + ("hex_prefix_rlp", 5820), + ("secp_double", 4076), + ("encode_node_branch", 3408), + ("mstore_unpacking", 2368), + ("main", 2320), + ("secp_add_valid_points", 2281), + ("insert_accessed_addresses", 2238), + ("decode_int_given_len", 1809), + ("read_rlp_to_memory", 1626), + ("load_mpt", 1355), + ("encode_or_hash_node", 1160), + ("mpt_read_branch", 1152), + ("mpt_read", 1065), + ("encode_node", 803), + ("memcpy_bytes", 731), + ("encode_account", 662), + ("prepend_rlp_list_prefix", 602), + ("pack_small_rlp", 590), + ("secp_precompute_table", 477), + ("encode_node_leaf", 459), + ("mstore_unpacking_rlp", 448), + ("maybe_hash_node", 438), + ("encode_node_empty", 413), + ("encode_rlp_fixed", 380), + ("insert_touched_addresses", 368), + ("mpt_read_extension_not_found", 340), + ("mpt_read_state_trie", 323), + ("sys_sstore", 313), + ("debug_it_should_be_128", 295), + ("process_receipt", 292), + ("process_type_0_txn", 283), + ("encode_rlp_scalar", 271), + ("check_bloom_loop", 269), + ("mpt_insert_hash_node", 252), + ("initialize_block_bloom", 247), + ("encode_rlp_list_prefix", 221), + ("encode_rlp_multi_byte_string_prefix", 216), + ("mpt_load_state_trie_value", 213), + ("mload_packing", 204), + ("mpt_hash", 198), + ("decode_rlp_string_len", 197), + ("jumpdest_analysis", 164), + ("load_code", 155), + ("process_normalized_txn", 154), + ("secp_glv_decompose", 148), + ("process_message_txn_code_loaded", 145), + ("insert_accessed_storage_keys", 135), + ("delete_all_touched_addresses", 128), + ("mpt_read_leaf_not_found", 119), + ("encode_receipt", 113), + ("increment_nonce", 108), + ("add_eth", 93), + ("process_message_txn", 82), + ("process_message_txn_after_call", 77), + ("doubly_encode_rlp_scalar", 74), + ("deduct_eth", 72), + ("intrinsic_gas", 64), + ("hash_final_tries", 58), + ("update_txn_trie", 58), + ("terminate_common", 53), + ("extcodehash", 45), + ("warm_precompiles", 45), + ("sys_stop", 42), + ("start_txn", 41), + ("mpt_insert", 39), + ("load_all_mpts", 38), + ("sload_current", 36), + ("encode_txn", 36), + ("scalar_to_rlp", 35), + ("encode_rlp_string", 34), + ("hash_initial_tries", 33), + ("encode_node_branch_prepend_prefix", 32), + ("decode_rlp_scalar", 28), + ("encode_rlp_string_small", 24), + ("route_txn", 24), + ("mpt_hash_storage_trie", 24), + ("encode_rlp_string_large", 23), + ("buy_gas", 20), + ("mpt_insert_receipt_trie", 17), + ("transfer_eth", 17), + ("decode_rlp_list_len", 17), + ("mpt_insert_txn_trie", 16), + ("balance", 15), + ("mpt_hash_txn_trie", 14), + ("mpt_hash_receipt_trie", 14), + ("mpt_hash_state_trie", 14), + ("logs_bloom", 13), + ("delete_all_selfdestructed_addresses", 13), + ("encode_rlp_string_large_after_writing_len", 13), + ("txn_after", 12), + ("encode_rlp_256", 12), + ("encode_storage_value", 12), + ("increment_bounded_rlp", 11), + ("withdrawals", 10), + ("warm_coinbase", 9), + ("nonce", 9), + ("increment_sender_nonce", 9), + ("process_based_on_type", 8), + ("after_storage_read", 7), + ("mpt_read_empty", 7), + ("ec_double_retself", 6), + ("warm_origin", 5), + ("add_bignum", 5), + ("check_bloom_loop_end", 4), + ("execute_withdrawals", 3), + ("encode_rlp_160", 3), + ("charge_gas_hook", 2), + ("halt", 1), + ("jumped_to_0", 1), + ]; + let _ = [ + ("secp_add_valid_points_no_edge_case", 10980), + ("ecrecover", 9009), + ("num_bytes", 7306), + ("hex_prefix_rlp", 5820), + ("secp_double", 4076), + ("encode_node_branch", 3408), + ("mstore_unpacking", 2368), + ("main", 2306), + ("secp_add_valid_points", 2281), + ("insert_accessed_addresses", 2238), + ("decode_int_given_len", 1809), + ("encode_node_empty", 1652), + ("read_rlp_to_memory", 1626), + ("load_mpt", 1355), + ("encode_or_hash_node", 1160), + ("mpt_read_branch", 1152), + ("mpt_read", 1065), + ("encode_node", 803), + ("memcpy_bytes", 731), + ("encode_account", 662), + ("prepend_rlp_list_prefix", 602), + ("pack_small_rlp", 590), + ("secp_precompute_table", 477), + ("encode_node_leaf", 459), + ("mstore_unpacking_rlp", 448), + ("maybe_hash_node", 438), + ("encode_rlp_fixed", 380), + ("insert_touched_addresses", 368), + ("mpt_read_extension_not_found", 340), + ("mpt_read_state_trie", 323), + ("sys_sstore", 313), + ("hash_final_tries", 305), + ("process_receipt", 292), + ("process_type_0_txn", 283), + ("encode_rlp_scalar", 271), + ("check_bloom_loop", 269), + ("mpt_insert_hash_node", 252), + ("encode_rlp_list_prefix", 221), + ("encode_rlp_multi_byte_string_prefix", 216), + ("mpt_load_state_trie_value", 213), + ("mload_packing", 204), + ("mpt_hash", 198), + ("decode_rlp_string_len", 197), + ("jumpdest_analysis", 164), + ("load_code", 155), + ("process_normalized_txn", 154), + ("secp_glv_decompose", 148), + ("process_message_txn_code_loaded", 145), + ("insert_accessed_storage_keys", 135), + ("delete_all_touched_addresses", 128), + ("mpt_read_leaf_not_found", 119), + ("encode_receipt", 113), + ("increment_nonce", 108), + ("add_eth", 93), + ("process_message_txn", 82), + ("process_message_txn_after_call", 77), + ("doubly_encode_rlp_scalar", 74), + ("deduct_eth", 72), + ("intrinsic_gas", 64), + ("update_txn_trie", 58), + ("terminate_common", 53), + ("warm_precompiles", 45), + ("extcodehash", 45), + ("sys_stop", 42), + ("start_txn", 41), + ("mpt_insert", 39), + ("load_all_mpts", 38), + ("sload_current", 36), + ("encode_txn", 36), + ("scalar_to_rlp", 35), + ("encode_rlp_string", 34), + ("hash_initial_tries", 33), + ("encode_node_branch_prepend_prefix", 32), + ("decode_rlp_scalar", 28), + ("route_txn", 24), + ("mpt_hash_storage_trie", 24), + ("encode_rlp_string_small", 24), + ("encode_rlp_string_large", 23), + ("buy_gas", 20), + ("decode_rlp_list_len", 17), + ("transfer_eth", 17), + ("mpt_insert_receipt_trie", 17), + ("mpt_insert_txn_trie", 16), + ("balance", 15), + ("mpt_hash_receipt_trie", 14), + ("mpt_hash_txn_trie", 14), + ("mpt_hash_state_trie", 14), + ("delete_all_selfdestructed_addresses", 13), + ("logs_bloom", 13), + ("encode_rlp_string_large_after_writing_len", 13), + ("encode_storage_value", 12), + ("encode_rlp_256", 12), + ("txn_after", 12), + ("increment_bounded_rlp", 11), + ("withdrawals", 10), + ("nonce", 9), + ("increment_sender_nonce", 9), + ("warm_coinbase", 9), + ("process_based_on_type", 8), + ("after_storage_read", 7), + ("mpt_read_empty", 7), + ("ec_double_retself", 6), + ("add_bignum", 5), + ("warm_origin", 5), + ("check_bloom_loop_end", 4), + ("encode_rlp_160", 3), + ("execute_withdrawals", 3), + ("charge_gas_hook", 2), + ("halt", 1), + ("jumped_to_0", 1), + ]; + + let _ = [ + ("mstore_unpacking", 148), + ("secp_add_valid_points", 139), + ("secp_add_valid_points_no_edge_case", 132), + ("secp_double", 129), + ("mstore_unpacking_rlp", 112), + ("encode_or_hash_node", 76), + ("encode_node", 72), + ("maybe_hash_node", 72), + ("mload_packing", 68), + ("pack_small_rlp", 59), + ("encode_node_empty", 59), + ("mpt_read", 50), + ("num_bytes", 48), + ("load_mpt", 38), + ("mpt_read_branch", 32), + ("memcpy_bytes", 27), + ("encode_rlp_fixed", 20), + ("encode_rlp_scalar", 19), + ("mpt_read_state_trie", 17), + ("prepend_rlp_list_prefix", 14), + ("encode_rlp_256", 12), + ("mpt_hash", 12), + ("insert_accessed_addresses", 12), + ("decode_rlp_string_len", 9), + ("hex_prefix_rlp", 9), + ("encode_node_leaf", 9), + ("decode_int_given_len", 9), + ("encode_rlp_multi_byte_string_prefix", 8), + ("encode_rlp_list_prefix", 8), + ("decode_rlp_scalar", 7), + ("mpt_hash_storage_trie", 6), + ("encode_account", 6), + ("insert_touched_addresses", 5), + ("encode_node_branch_prepend_prefix", 4), + ("encode_node_branch", 4), + ("mpt_load_state_trie_value", 3), + ("extcodehash", 3), + ("mpt_insert", 3), + ("add_eth", 3), + ("mpt_hash_state_trie", 2), + ("encode_rlp_string", 2), + ("deduct_eth", 2), + ("mpt_hash_txn_trie", 2), + ("ec_double_retself", 2), + ("mpt_hash_receipt_trie", 2), + ("secp_glv_decompose", 2), + ("charge_gas_hook", 2), + ("sys_sstore", 1), + ("increment_sender_nonce", 1), + ("buy_gas", 1), + ("main", 1), + ("process_type_0_txn", 1), + ("jumpdest_analysis", 1), + ("txn_after", 1), + ("encode_rlp_160", 1), + ("intrinsic_gas", 1), + ("delete_all_selfdestructed_addresses", 1), + ("encode_rlp_string_large_after_writing_len", 1), + ("jumped_to_0", 1), + ("decode_rlp_list_len", 1), + ("mpt_read_empty", 1), + ("hash_final_tries", 1), + ("sload_current", 1), + ("encode_txn", 1), + ("start_txn", 1), + ("encode_rlp_string_large", 1), + ("load_code", 1), + ("increment_bounded_rlp", 1), + ("encode_receipt", 1), + ("process_message_txn", 1), + ("ecrecover", 1), + ("warm_origin", 1), + ("encode_rlp_string_small", 1), + ("process_based_on_type", 1), + ("secp_precompute_table", 1), + ("halt", 1), + ("update_txn_trie", 1), + ("transfer_eth", 1), + ("logs_bloom", 1), + ("read_rlp_to_memory", 1), + ("encode_storage_value", 1), + ("process_receipt", 1), + ("process_message_txn_code_loaded", 1), + ("increment_nonce", 1), + ("delete_all_touched_addresses", 1), + ("terminate_common", 1), + ("balance", 1), + ("withdrawals", 1), + ("sys_stop", 1), + ("after_storage_read", 1), + ("mpt_insert_receipt_trie", 1), + ("hash_initial_tries", 1), + ("doubly_encode_rlp_scalar", 1), + ("route_txn", 1), + ("mpt_insert_txn_trie", 1), + ("warm_coinbase", 1), + ("load_all_mpts", 1), + ("warm_precompiles", 1), + ("add_bignum", 1), + ("insert_accessed_storage_keys", 1), + ("process_normalized_txn", 1), + ("scalar_to_rlp", 1), + ("nonce", 1), + ("process_message_txn_after_call", 1), + ("execute_withdrawals", 1), + ]; + let _ = [ + ("secp_add_valid_points_no_edge_case", 10980), + ("ecrecover", 9009), + ("num_bytes", 7306), + ("hex_prefix_rlp", 5820), + ("secp_double", 4076), + ("encode_node_branch", 3440), + ("encode_or_hash_node", 2991), + ("mstore_unpacking", 2368), + ("main", 2306), + ("secp_add_valid_points", 2281), + ("insert_accessed_addresses", 2238), + ("decode_int_given_len", 1809), + ("encode_node_empty", 1652), + ("read_rlp_to_memory", 1626), + ("load_mpt", 1355), + ("mpt_read_branch", 1152), + ("mpt_read", 1065), + ("memcpy_bytes", 731), + ("encode_account", 662), + ("prepend_rlp_list_prefix", 602), + ("hash_final_tries", 578), + ("secp_precompute_table", 477), + ("encode_node_leaf", 459), + ("mstore_unpacking_rlp", 448), + ("encode_rlp_fixed", 380), + ("insert_touched_addresses", 368), + ("mpt_read_extension_not_found", 340), + ("mpt_read_state_trie", 323), + ("sys_sstore", 313), + ("process_receipt", 292), + ("process_type_0_txn", 283), + ("encode_rlp_scalar", 271), + ("mpt_insert_hash_node", 252), + ("encode_rlp_list_prefix", 221), + ("encode_rlp_multi_byte_string_prefix", 216), + ("mpt_load_state_trie_value", 213), + ("mload_packing", 204), + ("mpt_hash", 198), + ("decode_rlp_string_len", 197), + ("jumpdest_analysis", 164), + ("load_code", 155), + ("process_normalized_txn", 154), + ("secp_glv_decompose", 148), + ("process_message_txn_code_loaded", 145), + ("insert_accessed_storage_keys", 135), + ("delete_all_touched_addresses", 128), + ("mpt_read_leaf_not_found", 119), + ("encode_receipt", 113), + ("increment_nonce", 108), + ("add_eth", 93), + ("process_message_txn", 82), + ("process_message_txn_after_call", 77), + ("doubly_encode_rlp_scalar", 74), + ("deduct_eth", 72), + ("intrinsic_gas", 64), + ("update_txn_trie", 58), + ("terminate_common", 53), + ("warm_precompiles", 45), + ("extcodehash", 45), + ("sys_stop", 42), + ("start_txn", 41), + ("mpt_insert", 39), + ("load_all_mpts", 38), + ("encode_txn", 36), + ("sload_current", 36), + ("scalar_to_rlp", 35), + ("encode_rlp_string", 34), + ("hash_initial_tries", 33), + ("decode_rlp_scalar", 28), + ("route_txn", 24), + ("mpt_hash_storage_trie", 24), + ("encode_rlp_string_small", 24), + ("encode_rlp_string_large", 23), + ("buy_gas", 20), + ("transfer_eth", 17), + ("mpt_insert_receipt_trie", 17), + ("decode_rlp_list_len", 17), + ("mpt_insert_txn_trie", 16), + ("balance", 15), + ("mpt_hash_txn_trie", 14), + ("mpt_hash_receipt_trie", 14), + ("mpt_hash_state_trie", 14), + ("delete_all_selfdestructed_addresses", 13), + ("logs_bloom", 13), + ("encode_rlp_string_large_after_writing_len", 13), + ("encode_storage_value", 12), + ("encode_rlp_256", 12), + ("txn_after", 12), + ("increment_bounded_rlp", 11), + ("withdrawals", 10), + ("increment_sender_nonce", 9), + ("warm_coinbase", 9), + ("nonce", 9), + ("process_based_on_type", 8), + ("after_storage_read", 7), + ("mpt_read_empty", 7), + ("ec_double_retself", 6), + ("add_bignum", 5), + ("warm_origin", 5), + ("encode_rlp_160", 3), + ("execute_withdrawals", 3), + ("charge_gas_hook", 2), + ("jumped_to_0", 1), + ("halt", 1), + ]; + + let _ = [ + ("secp_add_valid_points_no_edge_case", 10980), + ("ecrecover", 9009), + ("num_bytes", 7306), + ("hex_prefix_rlp", 5820), + ("secp_double", 4076), + ("encode_node_branch", 3440), + ("mstore_unpacking", 2368), + ("main", 2306), + ("secp_add_valid_points", 2281), + ("insert_accessed_addresses", 2238), + ("decode_int_given_len", 1809), + ("encode_node_empty", 1652), + ("read_rlp_to_memory", 1626), + ("load_mpt", 1355), + ("encode_or_hash_node", 1160), + ("mpt_read_branch", 1152), + ("mpt_read", 1065), + ("encode_node", 803), + ("memcpy_bytes", 731), + ("encode_account", 662), + ("prepend_rlp_list_prefix", 602), + ("pack_small_rlp", 590), + ("hash_final_tries", 578), + ("secp_precompute_table", 477), + ("encode_node_leaf", 459), + ("mstore_unpacking_rlp", 448), + ("maybe_hash_node", 438), + ("encode_rlp_fixed", 380), + ("insert_touched_addresses", 368), + ("mpt_read_extension_not_found", 340), + ("mpt_read_state_trie", 323), + ("sys_sstore", 313), + ("process_receipt", 292), + ("process_type_0_txn", 283), + ("encode_rlp_scalar", 271), + ("mpt_insert_hash_node", 252), + ("encode_rlp_list_prefix", 221), + ("encode_rlp_multi_byte_string_prefix", 216), + ("mpt_load_state_trie_value", 213), + ("mload_packing", 204), + ("mpt_hash", 198), + ("decode_rlp_string_len", 197), + ("jumpdest_analysis", 164), + ("load_code", 155), + ("process_normalized_txn", 154), + ("secp_glv_decompose", 148), + ("process_message_txn_code_loaded", 145), + ("insert_accessed_storage_keys", 135), + ("delete_all_touched_addresses", 128), + ("mpt_read_leaf_not_found", 119), + ("encode_receipt", 113), + ("increment_nonce", 108), + ("add_eth", 93), + ("process_message_txn", 82), + ("process_message_txn_after_call", 77), + ("doubly_encode_rlp_scalar", 74), + ("deduct_eth", 72), + ("intrinsic_gas", 64), + ("update_txn_trie", 58), + ("terminate_common", 53), + ("extcodehash", 45), + ("warm_precompiles", 45), + ("sys_stop", 42), + ("start_txn", 41), + ("mpt_insert", 39), + ("load_all_mpts", 38), + ("encode_txn", 36), + ("sload_current", 36), + ("scalar_to_rlp", 35), + ("encode_rlp_string", 34), + ("hash_initial_tries", 33), + ("decode_rlp_scalar", 28), + ("route_txn", 24), + ("mpt_hash_storage_trie", 24), + ("encode_rlp_string_small", 24), + ("encode_rlp_string_large", 23), + ("buy_gas", 20), + ("decode_rlp_list_len", 17), + ("transfer_eth", 17), + ("mpt_insert_receipt_trie", 17), + ("mpt_insert_txn_trie", 16), + ("balance", 15), + ("mpt_hash_txn_trie", 14), + ("mpt_hash_receipt_trie", 14), + ("mpt_hash_state_trie", 14), + ("encode_rlp_string_large_after_writing_len", 13), + ("logs_bloom", 13), + ("delete_all_selfdestructed_addresses", 13), + ("txn_after", 12), + ("encode_storage_value", 12), + ("encode_rlp_256", 12), + ("increment_bounded_rlp", 11), + ("withdrawals", 10), + ("nonce", 9), + ("increment_sender_nonce", 9), + ("warm_coinbase", 9), + ("process_based_on_type", 8), + ("mpt_read_empty", 7), + ("after_storage_read", 7), + ("ec_double_retself", 6), + ("add_bignum", 5), + ("warm_origin", 5), + ("encode_rlp_160", 3), + ("execute_withdrawals", 3), + ("charge_gas_hook", 2), + ("halt", 1), + ("jumped_to_0", 1), + ]; + + let _ = [ + ("secp_add_valid_points_no_edge_case", 10980), + ("ecrecover", 9009), + ("num_bytes", 7306), + ("hex_prefix_rlp", 5820), + ("secp_double", 4076), + ("encode_node_branch", 3408), + ("mstore_unpacking", 2368), + ("main", 2306), + ("secp_add_valid_points", 2281), + ("insert_accessed_addresses", 2238), + ("decode_int_given_len", 1809), + ("encode_node_empty", 1652), + ("read_rlp_to_memory", 1626), + ("load_mpt", 1355), + ("encode_or_hash_node", 1160), + ("mpt_read_branch", 1152), + ("mpt_read", 1065), + ("encode_node", 803), + ("memcpy_bytes", 731), + ("encode_account", 662), + ("prepend_rlp_list_prefix", 602), + ("pack_small_rlp", 590), + ("hash_final_tries", 578), + ("secp_precompute_table", 477), + ("encode_node_leaf", 459), + ("mstore_unpacking_rlp", 448), + ("maybe_hash_node", 438), + ("encode_rlp_fixed", 380), + ("insert_touched_addresses", 368), + ("mpt_read_extension_not_found", 340), + ("mpt_read_state_trie", 323), + ("sys_sstore", 313), + ("process_receipt", 292), + ("process_type_0_txn", 283), + ("encode_rlp_scalar", 271), + ("mpt_insert_hash_node", 252), + ("encode_rlp_list_prefix", 221), + ("encode_rlp_multi_byte_string_prefix", 216), + ("mpt_load_state_trie_value", 213), + ("mload_packing", 204), + ("mpt_hash", 198), + ("decode_rlp_string_len", 197), + ("jumpdest_analysis", 164), + ("load_code", 155), + ("process_normalized_txn", 154), + ("secp_glv_decompose", 148), + ("process_message_txn_code_loaded", 145), + ("insert_accessed_storage_keys", 135), + ("delete_all_touched_addresses", 128), + ("mpt_read_leaf_not_found", 119), + ("encode_receipt", 113), + ("increment_nonce", 108), + ("add_eth", 93), + ("process_message_txn", 82), + ("process_message_txn_after_call", 77), + ("doubly_encode_rlp_scalar", 74), + ("deduct_eth", 72), + ("intrinsic_gas", 64), + ("update_txn_trie", 58), + ("terminate_common", 53), + ("extcodehash", 45), + ("warm_precompiles", 45), + ("sys_stop", 42), + ("start_txn", 41), + ("mpt_insert", 39), + ("load_all_mpts", 38), + ("encode_txn", 36), + ("sload_current", 36), + ("scalar_to_rlp", 35), + ("encode_rlp_string", 34), + ("hash_initial_tries", 33), + ("encode_node_branch_prepend_prefix", 32), + ("decode_rlp_scalar", 28), + ("mpt_hash_storage_trie", 24), + ("route_txn", 24), + ("encode_rlp_string_small", 24), + ("encode_rlp_string_large", 23), + ("buy_gas", 20), + ("transfer_eth", 17), + ("mpt_insert_receipt_trie", 17), + ("decode_rlp_list_len", 17), + ("mpt_insert_txn_trie", 16), + ("balance", 15), + ("mpt_hash_txn_trie", 14), + ("mpt_hash_state_trie", 14), + ("mpt_hash_receipt_trie", 14), + ("delete_all_selfdestructed_addresses", 13), + ("logs_bloom", 13), + ("encode_rlp_string_large_after_writing_len", 13), + ("txn_after", 12), + ("encode_rlp_256", 12), + ("encode_storage_value", 12), + ("increment_bounded_rlp", 11), + ("withdrawals", 10), + ("warm_coinbase", 9), + ("increment_sender_nonce", 9), + ("nonce", 9), + ("process_based_on_type", 8), + ("mpt_read_empty", 7), + ("after_storage_read", 7), + ("ec_double_retself", 6), + ("add_bignum", 5), + ("warm_origin", 5), + ("encode_rlp_160", 3), + ("execute_withdrawals", 3), + ("charge_gas_hook", 2), + ("halt", 1), + ("jumped_to_0", 1), + ]; + } } } From a83404966e9f4c3bab21a0d7ef4bdfa7f56c25c7 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Thu, 30 Nov 2023 13:27:15 +0100 Subject: [PATCH 2/7] Rebase to main Refactor encode_empty_node and encode_branch_node Add constant and store encoded empty node in an other position Remove child segment Clean code Apply suggestions from code review Co-authored-by: Robin Salen <30937548+Nashtare@users.noreply.github.com> Remive global label Move encoded empty nodes --- .../cpu/kernel/asm/core/jumpdest_analysis.asm | 29 +- evm/src/cpu/kernel/asm/main.asm | 2 + evm/src/cpu/kernel/asm/mpt/hash/hash.asm | 179 +--- .../asm/mpt/hash/hash_trie_specific.asm | 7 + evm/src/cpu/kernel/asm/mpt/util.asm | 8 +- .../cpu/kernel/constants/global_metadata.rs | 76 +- evm/src/cpu/kernel/constants/mod.rs | 14 +- evm/src/cpu/kernel/interpreter.rs | 18 +- evm/src/cpu/kernel/tests/account_code.rs | 64 +- evm/src/cpu/kernel/tests/add11.rs | 11 +- evm/src/cpu/kernel/tests/mpt/insert.rs | 4 +- evm/src/generation/mod.rs | 778 +----------------- evm/src/memory/segments.rs | 67 +- evm/src/witness/memory.rs | 14 + 14 files changed, 226 insertions(+), 1045 deletions(-) diff --git a/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm b/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm index 56d9e12621..bda6f96e63 100644 --- a/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm +++ b/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm @@ -4,9 +4,8 @@ global jumpdest_analysis: // stack: ctx, code_len, retdest PUSH 0 // i = 0 - %stack (i, ctx, code_len, retdest) -> (i, ctx, code_len, retdest, 0) // ctr -global loop: +loop: // stack: i, ctx, code_len, retdest // Ideally we would break if i >= code_len, but checking i > code_len is // cheaper. It doesn't hurt to over-read by 1, since we'll read 0 which is @@ -14,20 +13,6 @@ global loop: DUP3 DUP2 GT // i > code_len %jumpi(return) - %stack (i, ctx) -> (ctx, @SEGMENT_CODE, i, 32, i, ctx) - %mload_packing - // stack: packed_opcodes - DUP1 - PUSH 0x8080808080808080808080808080808080808080808080808080808080808080 - AND -global debug_before_as_dad: - %jumpi(as_dad) -global debug_wuau: -as_dad: - POP -global debug_not_wuau: - - // stack: i, ctx, code_len, retdest %stack (i, ctx) -> (ctx, @SEGMENT_CODE, i, i, ctx) MLOAD_GENERAL @@ -43,11 +28,8 @@ global debug_not_wuau: // stack: JUMPDEST, i, ctx, code_len, retdest %stack (JUMPDEST, i, ctx) -> (1, ctx, @SEGMENT_JUMPDEST_BITS, i, JUMPDEST, i, ctx) MSTORE_GENERAL - %stack (opcode, i, ctx, code_len, retdest, ctr) -> (ctr, opcode, i, ctx, code_len, retdest) - %increment - %stack (ctr, opcode, i, ctx, code_len, retdest) -> (opcode, i, ctx, code_len, retdest, ctr) -global continue: +continue: // stack: opcode, i, ctx, code_len, retdest %add_const(code_bytes_to_skip) %mload_kernel_code @@ -56,12 +38,9 @@ global continue: // stack: i, ctx, code_len, retdest %jump(loop) -global return: +return: // stack: i, ctx, code_len, retdest %pop3 - SWAP1 -global debug_ctr: - POP JUMP // Determines how many bytes away is the next opcode, based on the opcode we read. @@ -69,7 +48,7 @@ global debug_ctr: // // Note that the range of PUSH opcodes is [0x60, 0x80). I.e. PUSH1 is 0x60 // and PUSH32 is 0x7f. -global code_bytes_to_skip: +code_bytes_to_skip: %rep 96 BYTES 1 // 0x00-0x5f %endrep diff --git a/evm/src/cpu/kernel/asm/main.asm b/evm/src/cpu/kernel/asm/main.asm index f6cd03bc8f..d1e06b6633 100644 --- a/evm/src/cpu/kernel/asm/main.asm +++ b/evm/src/cpu/kernel/asm/main.asm @@ -13,6 +13,8 @@ global main: // Initialise the shift table %shift_table_init + // Encode constant nodes + %initialize_rlp_segment // Encode constant nodes %initialize_rlp_segment diff --git a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm index 3bbb84f38f..cf0634fd22 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -49,10 +49,9 @@ mpt_hash_hash_rlp_after_unpacking: // The result is given as a (value, length) pair, where the length is given // in bytes. // -// Pre stack: node_ptr, encode_value, retdest -// Post stack: result, result_len +// Pre stack: node_ptr, encode_value, cur_len, retdest +// Post stack: result, result_len, cur_len global encode_or_hash_node: - // stack: node_ptr, encode_value, cur_len, retdest DUP1 %mload_trie_data // Check if we're dealing with a concrete node, i.e. not a hash node. @@ -92,11 +91,11 @@ maybe_hash_node: KECCAK_GENERAL %stack (hash, cur_len, retdest) -> (retdest, hash, 32, cur_len) JUMP -global pack_small_rlp: - // stack: result_ptr, result_len, retdest +pack_small_rlp: + // stack: result_ptr, result_len, cur_len, retdest %stack (result_ptr, result_len) -> (0, @SEGMENT_RLP_RAW, result_ptr, result_len, - after_packed_small_rlp, result_len, cur_len) + after_packed_small_rlp, result_len) %jump(mload_packing) after_packed_small_rlp: %stack (result, result_len, cur_len, retdest) -> (retdest, result, result_len, cur_len) @@ -105,10 +104,10 @@ after_packed_small_rlp: // RLP encode the given trie node, and return an (pointer, length) pair // indicating where the data lives within @SEGMENT_RLP_RAW. // -// Pre stack: node_type, node_ptr, encode_value, retdest +// Pre stack: node_type, node_ptr, encode_value, cur_len, retdest // Post stack: result_ptr, result_len -global encode_node: - // stack: node_type, node_ptr, encode_value, retdest +encode_node: + // stack: node_type, node_ptr, encode_value, cur_len, retdest // Increment node_ptr, so it points to the node payload instead of its type. SWAP1 %increment SWAP1 // stack: node_type, node_payload_ptr, encode_value, cur_len, retdest @@ -122,14 +121,16 @@ global encode_node: // been handled earlier in encode_or_hash_node, or something invalid. PANIC +global encode_node_empty: + // stack: node_type, node_payload_ptr, encode_value, cur_len, retdest + %pop3 + %stack (cur_len, retdest) -> (retdest, @ENCODED_EMPTY_NODE_POS, 1, cur_len) + JUMP + global encode_node_empty: // stack: node_type, node_payload_ptr, encode_value, retdest %pop3 - PUSH 0x1000 - %mload_kernel(@SEGMENT_RLP_RAW) -global debug_it_should_be_128: - POP - %stack (retdest) -> (retdest, 0x1000, 1) + %stack (retdest) -> (retdest, @ENCODED_EMPTY_NODE_POS, 1) JUMP global encode_node_branch: @@ -140,33 +141,19 @@ global encode_node_branch: SWAP2 %add_const(18) SWAP2 // stack: node_payload_ptr, encode_value, cur_len, retdest - // Get the next unused offset within the encoded child buffers. - // Then immediately increment the next unused offset by 16, so any - // recursive calls will use nonoverlapping offsets. - // TODO: Allocate a block of RLP memory instead? - %mload_global_metadata(@GLOBAL_METADATA_TRIE_ENCODED_CHILD_SIZE) - DUP1 %add_const(16) - %mstore_global_metadata(@GLOBAL_METADATA_TRIE_ENCODED_CHILD_SIZE) - // stack: base_offset, node_payload_ptr, encode_value, cur_len, retdest - // We will call encode_or_hash_node on each child. For the i'th child, we - // will store the result in SEGMENT_TRIE_ENCODED_CHILD[base + i], and its length in - // SEGMENT_TRIE_ENCODED_CHILD_LEN[base + i]. + // Allocate a block of RLP memory + %alloc_rlp_block DUP1 + // stack: rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len retdest + + // Call encode_or_hash_node on each child %encode_child(0) %encode_child(1) %encode_child(2) %encode_child(3) %encode_child(4) %encode_child(5) %encode_child(6) %encode_child(7) %encode_child(8) %encode_child(9) %encode_child(10) %encode_child(11) %encode_child(12) %encode_child(13) %encode_child(14) %encode_child(15) - // stack: base_offset, node_payload_ptr, encode_value, cur_len, retdest - // Now, append each child to our RLP tape. - %alloc_rlp_block DUP1 - // stack: rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest - %append_child(0) %append_child(1) %append_child(2) %append_child(3) - %append_child(4) %append_child(5) %append_child(6) %append_child(7) - %append_child(8) %append_child(9) %append_child(10) %append_child(11) - %append_child(12) %append_child(13) %append_child(14) %append_child(15) - // stack: rlp_pos', rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest + // stack: rlp_pos', rlp_start, node_payload_ptr, encode_value, cur_len, retdest - %stack (rlp_pos, rlp_start, base_offset, node_payload_ptr) + %stack (rlp_pos, rlp_start, node_payload_ptr) -> (node_payload_ptr, rlp_pos, rlp_start) %add_const(16) // stack: value_ptr_ptr, rlp_pos', rlp_start, encode_value, cur_len, retdest @@ -198,48 +185,36 @@ encode_node_branch_prepend_prefix: -> (retdest, rlp_prefix_start, rlp_len, cur_len) JUMP + // Part of the encode_node_branch function. Encodes the i'th child. -// Stores the result in SEGMENT_TRIE_ENCODED_CHILD[base + i], and its length in -// SEGMENT_TRIE_ENCODED_CHILD_LEN[base + i]. %macro encode_child(i) - // stack: base_offset, node_payload_ptr, encode_value, cur_len, retdest + // stack: rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest PUSH %%after_encode - DUP4 DUP4 - // stack: node_payload_ptr, encode_value, %%after_encode, base_offset, node_payload_ptr, encode_value, cur_len, retdest + DUP6 DUP6 DUP6 + // stack: node_payload_ptr, encode_value, cur_len, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest %add_const($i) %mload_trie_data - // stack: child_i_ptr, encode_value, %%after_encode, base_offset, node_payload_ptr, encode_value, cur_len, retdest - %stack(child_i_ptr, encode_value, after_encode, base_offset, node_payload_ptr, encode_value, cur_len) -> (child_i_ptr, encode_value, cur_len, after_encode, base_offset, node_payload_ptr, encode_value) + // stack: child_i_ptr, encode_value, cur_len, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest + %stack + (child_i_ptr, encode_value, cur_len, after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest) -> + (child_i_ptr, encode_value, cur_len, after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest) %jump(encode_or_hash_node) %%after_encode: - // stack: result, result_len, cur_len, base_offset, node_payload_ptr, encode_value, retdest - %stack(result, result_len, cur_len, base_offset, node_payload_ptr, encode_value) -> (result, result_len, base_offset, node_payload_ptr, encode_value, cur_len) - DUP3 %add_const($i) %mstore_kernel(@SEGMENT_TRIE_ENCODED_CHILD) - // stack: result_len, base_offset, node_payload_ptr, encode_value, cur_len, retdest - DUP2 %add_const($i) %mstore_kernel(@SEGMENT_TRIE_ENCODED_CHILD_LEN) - // stack: base_offset, node_payload_ptr, encode_value, cur_len, retdest -%endmacro - -// Part of the encode_node_branch function. Appends the i'th child's RLP. -%macro append_child(i) - // stack: rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest - DUP3 %add_const($i) %mload_kernel(@SEGMENT_TRIE_ENCODED_CHILD) // load result - DUP4 %add_const($i) %mload_kernel(@SEGMENT_TRIE_ENCODED_CHILD_LEN) // load result_len - // stack: result_len, result, rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest + // stack: result, result_len, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest // If result_len != 32, result is raw RLP, with an appropriate RLP prefix already. - DUP1 %sub_const(32) %jumpi(%%unpack) + SWAP1 DUP1 %sub_const(32) %jumpi(%%unpack) // Otherwise, result is a hash, and we need to add the prefix 0x80 + 32 = 160. - // stack: result_len, result, rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest + // stack: result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest PUSH 160 - DUP4 // rlp_pos + DUP5 // rlp_pos %mstore_rlp - SWAP2 %increment SWAP2 // rlp_pos += 1 + SWAP3 %increment SWAP3 // rlp_pos += 1 %%unpack: - %stack (result_len, result, rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest) + %stack (result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest) -> (rlp_pos, result, result_len, %%after_unpacking, - rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest) + rlp_start, node_payload_ptr, encode_value, cur_len, retdest) %jump(mstore_unpacking_rlp) %%after_unpacking: - // stack: rlp_pos', rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest + // stack: rlp_pos', rlp_start, node_payload_ptr, encode_value, cur_len, retdest %endmacro global encode_node_extension: @@ -322,81 +297,3 @@ encode_node_leaf_after_encode_value: %stack (rlp_prefix_start_pos, rlp_len, cur_len, retdest) -> (retdest, rlp_prefix_start_pos, rlp_len, cur_len) JUMP - -global encode_node_branch_new: - // stack: node_type, node_payload_ptr, encode_value, retdest - POP - // stack: node_payload_ptr, encode_value, retdest - - //Allocate a block of RLP memory - %alloc_rlp_block DUP1 - // stack: rlp_pos, node_payload_ptr, encode_value, retdest - - // Call encode_or_hash_node on each child - %encode_child_new(0) %encode_child_new(1) %encode_child_new(2) %encode_child_new(3) - %encode_child_new(4) %encode_child_new(5) %encode_child_new(6) %encode_child_new(7) - %encode_child_new(8) %encode_child_new(9) %encode_child_new(10) %encode_child_new(11) - %encode_child_new(12) %encode_child_new(13) %encode_child_new(14) %encode_child_new(15) - - // stack: rlp_pos', rlp_start, node_payload_ptr, encode_value, retdest - - %stack (rlp_pos, rlp_start, node_payload_ptr) - -> (node_payload_ptr, rlp_pos, rlp_start) - %add_const(16) - // stack: value_ptr_ptr, rlp_pos', rlp_start, encode_value, retdest - %mload_trie_data - // stack: value_ptr, rlp_pos', rlp_start, encode_value, retdest - DUP1 %jumpi(encode_node_branch_with_value_new) - - // No value; append the empty string (0x80). - // stack: value_ptr, rlp_pos', rlp_start, encode_value, retdest - %stack (value_ptr, rlp_pos, rlp_start, encode_value) -> (rlp_pos, 0x80, rlp_pos, rlp_start) - %mstore_rlp - // stack: rlp_pos', rlp_start, retdest - %increment - // stack: rlp_pos'', rlp_start, retdest - %jump(encode_node_branch_prepend_prefix_new) -encode_node_branch_with_value_new: - // stack: value_ptr, rlp_pos', rlp_start, encode_value, retdest - %stack (value_ptr, rlp_pos, rlp_start, encode_value) - -> (encode_value, rlp_pos, value_ptr, encode_node_branch_prepend_prefix, rlp_start) - JUMP // call encode_value -encode_node_branch_prepend_prefix_new: - // stack: rlp_pos'', rlp_start, retdest - %prepend_rlp_list_prefix - // stack: rlp_prefix_start, rlp_len, retdest - %stack (rlp_prefix_start, rlp_len, retdest) - -> (retdest, rlp_prefix_start, rlp_len) - JUMP - - -// Part of the encode_node_branch function. Encodes the i'th child. -// Stores the result in SEGMENT_TRIE_ENCODED_CHILD[base + i], and its length in -// SEGMENT_TRIE_ENCODED_CHILD_LEN[base + i]. -%macro encode_child_new(i) - // stack: rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest - PUSH %%after_encode - DUP5 DUP5 - // stack: node_payload_ptr, encode_value, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest - %add_const($i) %mload_trie_data - // stack: child_i_ptr, encode_value, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest - %jump(encode_or_hash_node) -%%after_encode: - // stack: result, result_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest - // If result_len != 32, result is raw RLP, with an appropriate RLP prefix already. - SWAP1 DUP1 %sub_const(32) %jumpi(%%unpack) - // Otherwise, result is a hash, and we need to add the prefix 0x80 + 32 = 160. - // stack: result_len, result, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest - PUSH 160 - DUP4 // rlp_pos - %mstore_rlp - SWAP2 %increment SWAP2 // rlp_pos += 1 -%%unpack: - %stack (result_len, result, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest) - -> (rlp_pos, result, result_len, %%after_unpacking, - rlp_start, node_payload_ptr, encode_value, retdest) - %jump(mstore_unpacking_rlp) -%%after_unpacking: - // stack: rlp_pos', rlp_start, node_payload_ptr, encode_value, retdest -%endmacro - diff --git a/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm b/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm index 2ffefb7d5a..f3ee000def 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm @@ -3,6 +3,9 @@ global mpt_hash_state_trie: // stack: cur_len, retdest PUSH encode_account + PUSH debug_before_encoding_child + PUSH mpt_delete + %pop2 %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) // stack: node_ptr, encode_account, cur_len, retdest %jump(mpt_hash) @@ -101,6 +104,10 @@ global encode_account: DUP3 %add_const(2) %mload_trie_data // storage_root_ptr = value[2] // stack: storage_root_ptr, cur_len, rlp_pos_5, value_ptr, cur_len, retdest + + PUSH debug_after_hash_storage_trie + POP + // Hash storage trie. %mpt_hash_storage_trie // stack: storage_root_digest, new_len, rlp_pos_5, value_ptr, cur_len, retdest diff --git a/evm/src/cpu/kernel/asm/mpt/util.asm b/evm/src/cpu/kernel/asm/mpt/util.asm index b492a0d055..27418b1704 100644 --- a/evm/src/cpu/kernel/asm/mpt/util.asm +++ b/evm/src/cpu/kernel/asm/mpt/util.asm @@ -11,13 +11,9 @@ %endmacro %macro initialize_rlp_segment - // Write the encoding of the empty node to address 0 leaving 9 bytes for a prefix - // TODO: Do we need a prefix? PUSH 0x80 - PUSH 0x1000 + PUSH @ENCODED_EMPTY_NODE_POS %mstore_rlp - PUSH 0x1000 // TODO: use 10? - %mstore_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE) %endmacro %macro alloc_rlp_block @@ -27,7 +23,7 @@ // In our model it's fine to use memory in a sparse way, as long as the gaps aren't larger than // 2^16 or so. So instead of the caller specifying the size of the block they need, we'll just // allocate 0x10000 = 2^16 bytes, much larger than any RLP blob the EVM could possibly create. - DUP1 %add_const(0x10000) + DUP1 %add_const(@MAX_RLP_BLOB_SIZE) // stack: block_end, block_start %mstore_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE) // stack: block_start diff --git a/evm/src/cpu/kernel/constants/global_metadata.rs b/evm/src/cpu/kernel/constants/global_metadata.rs index 8b85c0b552..b5e52e5c3c 100644 --- a/evm/src/cpu/kernel/constants/global_metadata.rs +++ b/evm/src/cpu/kernel/constants/global_metadata.rs @@ -30,68 +30,64 @@ pub(crate) enum GlobalMetadata { TransactionTrieRootDigestAfter = 11, ReceiptTrieRootDigestAfter = 12, - /// The sizes of the `TrieEncodedChild` and `TrieEncodedChildLen` buffers. In other words, the - /// next available offset in these buffers. - TrieEncodedChildSize = 13, - // Block metadata. - BlockBeneficiary = 14, - BlockTimestamp = 15, - BlockNumber = 16, - BlockDifficulty = 17, - BlockRandom = 18, - BlockGasLimit = 19, - BlockChainId = 20, - BlockBaseFee = 21, - BlockGasUsed = 22, + BlockBeneficiary = 13, + BlockTimestamp = 14, + BlockNumber = 15, + BlockDifficulty = 16, + BlockRandom = 17, + BlockGasLimit = 18, + BlockChainId = 19, + BlockBaseFee = 20, + BlockGasUsed = 21, /// Before current transactions block values. - BlockGasUsedBefore = 23, + BlockGasUsedBefore = 22, /// After current transactions block values. - BlockGasUsedAfter = 24, + BlockGasUsedAfter = 23, /// Current block header hash - BlockCurrentHash = 25, + BlockCurrentHash = 24, /// Gas to refund at the end of the transaction. - RefundCounter = 26, + RefundCounter = 25, /// Length of the addresses access list. - AccessedAddressesLen = 27, + AccessedAddressesLen = 26, /// Length of the storage keys access list. - AccessedStorageKeysLen = 28, + AccessedStorageKeysLen = 27, /// Length of the self-destruct list. - SelfDestructListLen = 29, + SelfDestructListLen = 28, /// Length of the bloom entry buffer. - BloomEntryLen = 30, + BloomEntryLen = 29, /// Length of the journal. - JournalLen = 31, + JournalLen = 30, /// Length of the `JournalData` segment. - JournalDataLen = 32, + JournalDataLen = 31, /// Current checkpoint. - CurrentCheckpoint = 33, - TouchedAddressesLen = 34, + CurrentCheckpoint = 32, + TouchedAddressesLen = 33, // Gas cost for the access list in type-1 txns. See EIP-2930. - AccessListDataCost = 35, + AccessListDataCost = 34, // Start of the access list in the RLP for type-1 txns. - AccessListRlpStart = 36, + AccessListRlpStart = 35, // Length of the access list in the RLP for type-1 txns. - AccessListRlpLen = 37, + AccessListRlpLen = 36, // Boolean flag indicating if the txn is a contract creation txn. - ContractCreation = 38, - IsPrecompileFromEoa = 39, - CallStackDepth = 40, + ContractCreation = 37, + IsPrecompileFromEoa = 38, + CallStackDepth = 39, /// Transaction logs list length - LogsLen = 41, - LogsDataLen = 42, - LogsPayloadLen = 43, - TxnNumberBefore = 44, - TxnNumberAfter = 45, + LogsLen = 40, + LogsDataLen = 41, + LogsPayloadLen = 42, + TxnNumberBefore = 43, + TxnNumberAfter = 44, - KernelHash = 46, - KernelLen = 47, + KernelHash = 45, + KernelLen = 46, } impl GlobalMetadata { - pub(crate) const COUNT: usize = 48; + pub(crate) const COUNT: usize = 47; pub(crate) const fn all() -> [Self; Self::COUNT] { [ @@ -108,7 +104,6 @@ impl GlobalMetadata { Self::StateTrieRootDigestAfter, Self::TransactionTrieRootDigestAfter, Self::ReceiptTrieRootDigestAfter, - Self::TrieEncodedChildSize, Self::BlockBeneficiary, Self::BlockTimestamp, Self::BlockNumber, @@ -162,7 +157,6 @@ impl GlobalMetadata { Self::StateTrieRootDigestAfter => "GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER", Self::TransactionTrieRootDigestAfter => "GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER", Self::ReceiptTrieRootDigestAfter => "GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_AFTER", - Self::TrieEncodedChildSize => "GLOBAL_METADATA_TRIE_ENCODED_CHILD_SIZE", Self::BlockBeneficiary => "GLOBAL_METADATA_BLOCK_BENEFICIARY", Self::BlockTimestamp => "GLOBAL_METADATA_BLOCK_TIMESTAMP", Self::BlockNumber => "GLOBAL_METADATA_BLOCK_NUMBER", diff --git a/evm/src/cpu/kernel/constants/mod.rs b/evm/src/cpu/kernel/constants/mod.rs index 6e2a0015d3..fa25fa8704 100644 --- a/evm/src/cpu/kernel/constants/mod.rs +++ b/evm/src/cpu/kernel/constants/mod.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use ethereum_types::U256; use hex_literal::hex; +use static_assertions::const_assert; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; @@ -86,12 +87,23 @@ pub(crate) fn evm_constants() -> HashMap { c } -const MISC_CONSTANTS: [(&str, [u8; 32]); 1] = [ +const MISC_CONSTANTS: [(&str, [u8; 32]); 3] = [ // Base for limbs used in bignum arithmetic. ( "BIGNUM_LIMB_BASE", hex!("0000000000000000000000000000000100000000000000000000000000000000"), ), + // Position in SEGMENT_RLP_RAW where the empty node encoding is stored. It is + // equal to usize::MAX so that all rlp pointers all much smalled than that + ( + "ENCODED_EMPTY_NODE_POS", + hex!("00000000000000000000000000000000000000000000000000000000FFFFFFFF"), + ), + // 0x10000 = 2^16 bytes, much larger than any RLP blob the EVM could possibly create. + ( + "MAX_RLP_BLOB_SIZE", + hex!("0000000000000000000000000000000000000000000000000000000000010000"), + ), ]; const HASH_CONSTANTS: [(&str, [u8; 32]); 2] = [ diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index c437672113..58de9e3485 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -140,12 +140,14 @@ enum InterpreterMemOpKind { impl<'a> Interpreter<'a> { pub(crate) fn new_with_kernel(initial_offset: usize, initial_stack: Vec) -> Self { - Self::new( + let mut result = Self::new( &KERNEL.code, initial_offset, initial_stack, &KERNEL.prover_inputs, - ) + ); + result.initialize_rlp_segment(); + result } pub(crate) fn new( @@ -1171,6 +1173,18 @@ impl<'a> Interpreter<'a> { } self.generation_state.registers.context = context; } + + /// Writes the encoding of 0 to position @ + pub(crate) fn initialize_rlp_segment(&mut self) { + self.generation_state.memory.set( + MemoryAddress { + context: 0, + segment: Segment::RlpRaw as usize, + virt: 0xFFFFFFFF, + }, + 128.into(), + ) + } } // Computes the two's complement of the given integer. diff --git a/evm/src/cpu/kernel/tests/account_code.rs b/evm/src/cpu/kernel/tests/account_code.rs index 20c98bf976..f985ebd445 100644 --- a/evm/src/cpu/kernel/tests/account_code.rs +++ b/evm/src/cpu/kernel/tests/account_code.rs @@ -201,21 +201,36 @@ fn test_extcodecopy() -> Result<()> { prepare_interpreter(&mut interpreter, address, &account)?; let context = interpreter.context(); - interpreter.generation_state.memory.contexts[context].segments - [Segment::ContextMetadata as usize] - .set(GasLimit as usize, U256::from(1000000000000u64)); + interpreter.generation_state.memory.set( + MemoryAddress { + context, + segment: Segment::ContextMetadata as usize, + virt: GasLimit as usize, + }, + U256::from(1000000000000u64), + ); let extcodecopy = KERNEL.global_labels["sys_extcodecopy"]; // Put random data in main memory and the `KernelAccountCode` segment for realism. let mut rng = thread_rng(); for i in 0..2000 { - interpreter.generation_state.memory.contexts[context].segments - [Segment::MainMemory as usize] - .set(i, U256::from(rng.gen::())); - interpreter.generation_state.memory.contexts[context].segments - [Segment::KernelAccountCode as usize] - .set(i, U256::from(rng.gen::())); + interpreter.generation_state.memory.set( + MemoryAddress { + context, + segment: Segment::MainMemory as usize, + virt: i, + }, + U256::from(rng.gen::()), + ); + interpreter.generation_state.memory.set( + MemoryAddress { + context, + segment: Segment::KernelAccountCode as usize, + virt: i, + }, + U256::from(rng.gen::()), + ); } // Random inputs @@ -250,9 +265,11 @@ fn test_extcodecopy() -> Result<()> { assert!(interpreter.stack().is_empty()); // Check that the code was correctly copied to memory. for i in 0..size { - let memory = interpreter.generation_state.memory.contexts[context].segments - [Segment::MainMemory as usize] - .get(dest_offset + i); + let memory = interpreter.generation_state.memory.get(MemoryAddress { + context, + segment: Segment::MainMemory as usize, + virt: dest_offset + i, + }); assert_eq!( memory, code.get(offset + i).copied().unwrap_or_default().into() @@ -277,13 +294,22 @@ fn prepare_interpreter_all_accounts( // Switch context and initialize memory with the data we need for the tests. interpreter.generation_state.registers.program_counter = 0; interpreter.set_code(1, code.to_vec()); - interpreter.generation_state.memory.contexts[1].segments[Segment::ContextMetadata as usize] - .set( - ContextMetadata::Address as usize, - U256::from_big_endian(&addr), - ); - interpreter.generation_state.memory.contexts[1].segments[Segment::ContextMetadata as usize] - .set(ContextMetadata::GasLimit as usize, 100_000.into()); + interpreter.generation_state.memory.set( + MemoryAddress { + context: 1, + segment: Segment::ContextMetadata as usize, + virt: ContextMetadata::Address as usize, + }, + U256::from_big_endian(&addr), + ); + interpreter.generation_state.memory.set( + MemoryAddress { + context: 1, + segment: Segment::ContextMetadata as usize, + virt: ContextMetadata::GasLimit as usize, + }, + 100_000.into(), + ); interpreter.set_context(1); interpreter.set_is_kernel(false); interpreter.generation_state.memory.set( diff --git a/evm/src/cpu/kernel/tests/add11.rs b/evm/src/cpu/kernel/tests/add11.rs index 9ba65db2c9..b85bfe66c0 100644 --- a/evm/src/cpu/kernel/tests/add11.rs +++ b/evm/src/cpu/kernel/tests/add11.rs @@ -19,6 +19,7 @@ use crate::generation::TrieInputs; use crate::memory::segments::Segment; use crate::proof::TrieRoots; use crate::util::h2u; +use crate::witness::memory::MemoryAddress; // Stolen from `tests/mpt/insert.rs` // Prepare the interpreter by loading the initial MPTs and @@ -199,8 +200,14 @@ fn test_add11_yml() { let route_txn_label = KERNEL.global_labels["hash_initial_tries"]; // Switch context and initialize memory with the data we need for the tests. interpreter.generation_state.registers.program_counter = route_txn_label; - interpreter.generation_state.memory.contexts[0].segments[Segment::ContextMetadata as usize] - .set(ContextMetadata::GasLimit as usize, 1_000_000.into()); + interpreter.generation_state.memory.set( + MemoryAddress { + context: 0, + segment: Segment::ContextMetadata as usize, + virt: ContextMetadata::GasLimit as usize, + }, + 1_000_000.into(), + ); interpreter.set_is_kernel(true); interpreter.run().expect("Proving add11 failed."); } diff --git a/evm/src/cpu/kernel/tests/mpt/insert.rs b/evm/src/cpu/kernel/tests/mpt/insert.rs index 9c2fd50b24..acd42e8f3a 100644 --- a/evm/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm/src/cpu/kernel/tests/mpt/insert.rs @@ -12,11 +12,12 @@ use crate::cpu::kernel::tests::mpt::{ }; use crate::generation::mpt::AccountRlp; use crate::generation::TrieInputs; +use crate::util::u256_to_usize; use crate::Node; #[test] fn mpt_insert_empty() -> Result<()> { - test_state_trie(Default::default(), nibbles_64(0xABC), test_account_2()) + test_state_trie(Default::default(), nibbles_64(0xDEF), test_account_2()) } #[test] @@ -233,6 +234,7 @@ fn test_state_trie( let hash = H256::from_uint(&interpreter.stack()[1]); state_trie.insert(k, rlp::encode(&account).to_vec()); + let expected_state_trie_hash = state_trie.hash(); assert_eq!(hash, expected_state_trie_hash); diff --git a/evm/src/generation/mod.rs b/evm/src/generation/mod.rs index a3ba330244..e5dbc3e7b4 100644 --- a/evm/src/generation/mod.rs +++ b/evm/src/generation/mod.rs @@ -35,7 +35,7 @@ pub mod mpt; pub(crate) mod prover_input; pub(crate) mod rlp; pub(crate) mod state; -mod trie_extractor; +pub(crate) mod trie_extractor; use self::mpt::{load_all_mpts, TrieRootPtrs}; use crate::witness::util::mem_write_log; @@ -296,121 +296,14 @@ pub fn generate_traces, const D: usize>( Ok((tables, public_values)) } -fn _simulate_cpu, const D: usize>( - state: &mut GenerationState, -) -> anyhow::Result<()> { - let halt_pc = KERNEL.global_labels["halt"]; - - loop { - // If we've reached the kernel's halt routine, and our trace length is a power of 2, stop. - let pc = state.registers.program_counter; - let halt = state.registers.is_kernel && pc == halt_pc; - if halt { - log::info!("CPU halted after {} cycles", state.traces.clock()); - - // Padding - let mut row = CpuColumnsView::::default(); - row.clock = F::from_canonical_usize(state.traces.clock()); - row.context = F::from_canonical_usize(state.registers.context); - row.program_counter = F::from_canonical_usize(pc); - row.is_kernel_mode = F::ONE; - row.gas = F::from_canonical_u64(state.registers.gas_used); - row.stack_len = F::from_canonical_usize(state.registers.stack_len); - - loop { - state.traces.push_cpu(row); - row.clock += F::ONE; - if state.traces.clock().is_power_of_two() { - break; - } - } - - log::info!("CPU trace padded to {} cycles", state.traces.clock()); - - return Ok(()); - } - - transition(state)?; - } -} - -fn __simulate_cpu, const D: usize>( - state: &mut GenerationState, -) -> anyhow::Result<()> { - let mut profiling_map = HashMap::::new(); - - let halt_pc = KERNEL.global_labels["halt"]; - - loop { - // If we've reached the kernel's halt routine, and our trace length is a power of 2, stop. - let pc = state.registers.program_counter; - if let Ok(idx) = KERNEL - .ordered_labels - .binary_search_by_key(&pc, |label| KERNEL.global_labels[label]) - { - profiling_map - .entry(KERNEL.ordered_labels[idx].clone()) - .and_modify(|counter| *counter += 1) - .or_insert(1); - } - let halt = state.registers.is_kernel && pc == halt_pc; - if halt { - log::info!("CPU halted after {} cycles", state.traces.clock()); - - // Padding - let mut row = CpuColumnsView::::default(); - row.clock = F::from_canonical_usize(state.traces.clock()); - row.context = F::from_canonical_usize(state.registers.context); - row.program_counter = F::from_canonical_usize(pc); - row.is_kernel_mode = F::ONE; - row.gas = F::from_canonical_u64(state.registers.gas_used); - row.stack_len = F::from_canonical_usize(state.registers.stack_len); - - loop { - state.traces.push_cpu(row); - row.clock += F::ONE; - if state.traces.clock().is_power_of_two() { - break; - } - } - log::info!("CPU trace padded to {} cycles", state.traces.clock()); - - let mut sorted_labels: Vec<_> = profiling_map.iter().collect(); - sorted_labels.sort_unstable_by_key(|item| item.1); - sorted_labels.reverse(); - log::info!("Offsets: {:?}", sorted_labels); - - return Ok(()); - } - - transition(state)?; - } -} - fn simulate_cpu, const D: usize>( state: &mut GenerationState, ) -> anyhow::Result<()> { - let mut profiling_map = HashMap::::new(); - let halt_pc = KERNEL.global_labels["halt"]; loop { // If we've reached the kernel's halt routine, and our trace length is a power of 2, stop. let pc = state.registers.program_counter; - let idx = match KERNEL - .ordered_labels - .binary_search_by_key(&pc, |label| KERNEL.global_labels[label]) - { - Ok(idx) => Some(idx), - Err(0) => None, - Err(idx) => Some(idx - 1), - }; - if let Some(idx) = idx { - profiling_map - .entry(KERNEL.ordered_labels[idx].clone()) - .and_modify(|counter| *counter += 1) - .or_insert(1); - } let halt = state.registers.is_kernel && pc == halt_pc; if halt { log::info!("CPU halted after {} cycles", state.traces.clock()); @@ -431,679 +324,12 @@ fn simulate_cpu, const D: usize>( break; } } - log::info!("CPU trace padded to {} cycles", state.traces.clock()); - let mut sorted_labels: Vec<_> = profiling_map.iter().collect(); - sorted_labels.sort_unstable_by_key(|item| item.1); - sorted_labels.reverse(); - log::info!("Offsets: {:?}", sorted_labels); + log::info!("CPU trace padded to {} cycles", state.traces.clock()); return Ok(()); } transition(state)?; - { - let _ = [ - ("secp_add_valid_points_no_edge_case", 10980), - ("ecrecover", 9009), - ("num_bytes", 7306), - ("hex_prefix_rlp", 5820), - ("secp_double", 4076), - ("encode_node_branch", 3408), - ("mstore_unpacking", 2368), - ("main", 2320), - ("secp_add_valid_points", 2281), - ("insert_accessed_addresses", 2238), - ("decode_int_given_len", 1809), - ("read_rlp_to_memory", 1626), - ("load_mpt", 1355), - ("encode_or_hash_node", 1160), - ("mpt_read_branch", 1152), - ("mpt_read", 1065), - ("encode_node", 803), - ("memcpy_bytes", 731), - ("encode_account", 662), - ("prepend_rlp_list_prefix", 602), - ("pack_small_rlp", 590), - ("secp_precompute_table", 477), - ("encode_node_leaf", 459), - ("mstore_unpacking_rlp", 448), - ("maybe_hash_node", 438), - ("encode_node_empty", 413), - ("encode_rlp_fixed", 380), - ("insert_touched_addresses", 368), - ("mpt_read_extension_not_found", 340), - ("mpt_read_state_trie", 323), - ("sys_sstore", 313), - ("debug_it_should_be_128", 295), - ("process_receipt", 292), - ("process_type_0_txn", 283), - ("encode_rlp_scalar", 271), - ("check_bloom_loop", 269), - ("mpt_insert_hash_node", 252), - ("initialize_block_bloom", 247), - ("encode_rlp_list_prefix", 221), - ("encode_rlp_multi_byte_string_prefix", 216), - ("mpt_load_state_trie_value", 213), - ("mload_packing", 204), - ("mpt_hash", 198), - ("decode_rlp_string_len", 197), - ("jumpdest_analysis", 164), - ("load_code", 155), - ("process_normalized_txn", 154), - ("secp_glv_decompose", 148), - ("process_message_txn_code_loaded", 145), - ("insert_accessed_storage_keys", 135), - ("delete_all_touched_addresses", 128), - ("mpt_read_leaf_not_found", 119), - ("encode_receipt", 113), - ("increment_nonce", 108), - ("add_eth", 93), - ("process_message_txn", 82), - ("process_message_txn_after_call", 77), - ("doubly_encode_rlp_scalar", 74), - ("deduct_eth", 72), - ("intrinsic_gas", 64), - ("hash_final_tries", 58), - ("update_txn_trie", 58), - ("terminate_common", 53), - ("extcodehash", 45), - ("warm_precompiles", 45), - ("sys_stop", 42), - ("start_txn", 41), - ("mpt_insert", 39), - ("load_all_mpts", 38), - ("sload_current", 36), - ("encode_txn", 36), - ("scalar_to_rlp", 35), - ("encode_rlp_string", 34), - ("hash_initial_tries", 33), - ("encode_node_branch_prepend_prefix", 32), - ("decode_rlp_scalar", 28), - ("encode_rlp_string_small", 24), - ("route_txn", 24), - ("mpt_hash_storage_trie", 24), - ("encode_rlp_string_large", 23), - ("buy_gas", 20), - ("mpt_insert_receipt_trie", 17), - ("transfer_eth", 17), - ("decode_rlp_list_len", 17), - ("mpt_insert_txn_trie", 16), - ("balance", 15), - ("mpt_hash_txn_trie", 14), - ("mpt_hash_receipt_trie", 14), - ("mpt_hash_state_trie", 14), - ("logs_bloom", 13), - ("delete_all_selfdestructed_addresses", 13), - ("encode_rlp_string_large_after_writing_len", 13), - ("txn_after", 12), - ("encode_rlp_256", 12), - ("encode_storage_value", 12), - ("increment_bounded_rlp", 11), - ("withdrawals", 10), - ("warm_coinbase", 9), - ("nonce", 9), - ("increment_sender_nonce", 9), - ("process_based_on_type", 8), - ("after_storage_read", 7), - ("mpt_read_empty", 7), - ("ec_double_retself", 6), - ("warm_origin", 5), - ("add_bignum", 5), - ("check_bloom_loop_end", 4), - ("execute_withdrawals", 3), - ("encode_rlp_160", 3), - ("charge_gas_hook", 2), - ("halt", 1), - ("jumped_to_0", 1), - ]; - let _ = [ - ("secp_add_valid_points_no_edge_case", 10980), - ("ecrecover", 9009), - ("num_bytes", 7306), - ("hex_prefix_rlp", 5820), - ("secp_double", 4076), - ("encode_node_branch", 3408), - ("mstore_unpacking", 2368), - ("main", 2306), - ("secp_add_valid_points", 2281), - ("insert_accessed_addresses", 2238), - ("decode_int_given_len", 1809), - ("encode_node_empty", 1652), - ("read_rlp_to_memory", 1626), - ("load_mpt", 1355), - ("encode_or_hash_node", 1160), - ("mpt_read_branch", 1152), - ("mpt_read", 1065), - ("encode_node", 803), - ("memcpy_bytes", 731), - ("encode_account", 662), - ("prepend_rlp_list_prefix", 602), - ("pack_small_rlp", 590), - ("secp_precompute_table", 477), - ("encode_node_leaf", 459), - ("mstore_unpacking_rlp", 448), - ("maybe_hash_node", 438), - ("encode_rlp_fixed", 380), - ("insert_touched_addresses", 368), - ("mpt_read_extension_not_found", 340), - ("mpt_read_state_trie", 323), - ("sys_sstore", 313), - ("hash_final_tries", 305), - ("process_receipt", 292), - ("process_type_0_txn", 283), - ("encode_rlp_scalar", 271), - ("check_bloom_loop", 269), - ("mpt_insert_hash_node", 252), - ("encode_rlp_list_prefix", 221), - ("encode_rlp_multi_byte_string_prefix", 216), - ("mpt_load_state_trie_value", 213), - ("mload_packing", 204), - ("mpt_hash", 198), - ("decode_rlp_string_len", 197), - ("jumpdest_analysis", 164), - ("load_code", 155), - ("process_normalized_txn", 154), - ("secp_glv_decompose", 148), - ("process_message_txn_code_loaded", 145), - ("insert_accessed_storage_keys", 135), - ("delete_all_touched_addresses", 128), - ("mpt_read_leaf_not_found", 119), - ("encode_receipt", 113), - ("increment_nonce", 108), - ("add_eth", 93), - ("process_message_txn", 82), - ("process_message_txn_after_call", 77), - ("doubly_encode_rlp_scalar", 74), - ("deduct_eth", 72), - ("intrinsic_gas", 64), - ("update_txn_trie", 58), - ("terminate_common", 53), - ("warm_precompiles", 45), - ("extcodehash", 45), - ("sys_stop", 42), - ("start_txn", 41), - ("mpt_insert", 39), - ("load_all_mpts", 38), - ("sload_current", 36), - ("encode_txn", 36), - ("scalar_to_rlp", 35), - ("encode_rlp_string", 34), - ("hash_initial_tries", 33), - ("encode_node_branch_prepend_prefix", 32), - ("decode_rlp_scalar", 28), - ("route_txn", 24), - ("mpt_hash_storage_trie", 24), - ("encode_rlp_string_small", 24), - ("encode_rlp_string_large", 23), - ("buy_gas", 20), - ("decode_rlp_list_len", 17), - ("transfer_eth", 17), - ("mpt_insert_receipt_trie", 17), - ("mpt_insert_txn_trie", 16), - ("balance", 15), - ("mpt_hash_receipt_trie", 14), - ("mpt_hash_txn_trie", 14), - ("mpt_hash_state_trie", 14), - ("delete_all_selfdestructed_addresses", 13), - ("logs_bloom", 13), - ("encode_rlp_string_large_after_writing_len", 13), - ("encode_storage_value", 12), - ("encode_rlp_256", 12), - ("txn_after", 12), - ("increment_bounded_rlp", 11), - ("withdrawals", 10), - ("nonce", 9), - ("increment_sender_nonce", 9), - ("warm_coinbase", 9), - ("process_based_on_type", 8), - ("after_storage_read", 7), - ("mpt_read_empty", 7), - ("ec_double_retself", 6), - ("add_bignum", 5), - ("warm_origin", 5), - ("check_bloom_loop_end", 4), - ("encode_rlp_160", 3), - ("execute_withdrawals", 3), - ("charge_gas_hook", 2), - ("halt", 1), - ("jumped_to_0", 1), - ]; - - let _ = [ - ("mstore_unpacking", 148), - ("secp_add_valid_points", 139), - ("secp_add_valid_points_no_edge_case", 132), - ("secp_double", 129), - ("mstore_unpacking_rlp", 112), - ("encode_or_hash_node", 76), - ("encode_node", 72), - ("maybe_hash_node", 72), - ("mload_packing", 68), - ("pack_small_rlp", 59), - ("encode_node_empty", 59), - ("mpt_read", 50), - ("num_bytes", 48), - ("load_mpt", 38), - ("mpt_read_branch", 32), - ("memcpy_bytes", 27), - ("encode_rlp_fixed", 20), - ("encode_rlp_scalar", 19), - ("mpt_read_state_trie", 17), - ("prepend_rlp_list_prefix", 14), - ("encode_rlp_256", 12), - ("mpt_hash", 12), - ("insert_accessed_addresses", 12), - ("decode_rlp_string_len", 9), - ("hex_prefix_rlp", 9), - ("encode_node_leaf", 9), - ("decode_int_given_len", 9), - ("encode_rlp_multi_byte_string_prefix", 8), - ("encode_rlp_list_prefix", 8), - ("decode_rlp_scalar", 7), - ("mpt_hash_storage_trie", 6), - ("encode_account", 6), - ("insert_touched_addresses", 5), - ("encode_node_branch_prepend_prefix", 4), - ("encode_node_branch", 4), - ("mpt_load_state_trie_value", 3), - ("extcodehash", 3), - ("mpt_insert", 3), - ("add_eth", 3), - ("mpt_hash_state_trie", 2), - ("encode_rlp_string", 2), - ("deduct_eth", 2), - ("mpt_hash_txn_trie", 2), - ("ec_double_retself", 2), - ("mpt_hash_receipt_trie", 2), - ("secp_glv_decompose", 2), - ("charge_gas_hook", 2), - ("sys_sstore", 1), - ("increment_sender_nonce", 1), - ("buy_gas", 1), - ("main", 1), - ("process_type_0_txn", 1), - ("jumpdest_analysis", 1), - ("txn_after", 1), - ("encode_rlp_160", 1), - ("intrinsic_gas", 1), - ("delete_all_selfdestructed_addresses", 1), - ("encode_rlp_string_large_after_writing_len", 1), - ("jumped_to_0", 1), - ("decode_rlp_list_len", 1), - ("mpt_read_empty", 1), - ("hash_final_tries", 1), - ("sload_current", 1), - ("encode_txn", 1), - ("start_txn", 1), - ("encode_rlp_string_large", 1), - ("load_code", 1), - ("increment_bounded_rlp", 1), - ("encode_receipt", 1), - ("process_message_txn", 1), - ("ecrecover", 1), - ("warm_origin", 1), - ("encode_rlp_string_small", 1), - ("process_based_on_type", 1), - ("secp_precompute_table", 1), - ("halt", 1), - ("update_txn_trie", 1), - ("transfer_eth", 1), - ("logs_bloom", 1), - ("read_rlp_to_memory", 1), - ("encode_storage_value", 1), - ("process_receipt", 1), - ("process_message_txn_code_loaded", 1), - ("increment_nonce", 1), - ("delete_all_touched_addresses", 1), - ("terminate_common", 1), - ("balance", 1), - ("withdrawals", 1), - ("sys_stop", 1), - ("after_storage_read", 1), - ("mpt_insert_receipt_trie", 1), - ("hash_initial_tries", 1), - ("doubly_encode_rlp_scalar", 1), - ("route_txn", 1), - ("mpt_insert_txn_trie", 1), - ("warm_coinbase", 1), - ("load_all_mpts", 1), - ("warm_precompiles", 1), - ("add_bignum", 1), - ("insert_accessed_storage_keys", 1), - ("process_normalized_txn", 1), - ("scalar_to_rlp", 1), - ("nonce", 1), - ("process_message_txn_after_call", 1), - ("execute_withdrawals", 1), - ]; - let _ = [ - ("secp_add_valid_points_no_edge_case", 10980), - ("ecrecover", 9009), - ("num_bytes", 7306), - ("hex_prefix_rlp", 5820), - ("secp_double", 4076), - ("encode_node_branch", 3440), - ("encode_or_hash_node", 2991), - ("mstore_unpacking", 2368), - ("main", 2306), - ("secp_add_valid_points", 2281), - ("insert_accessed_addresses", 2238), - ("decode_int_given_len", 1809), - ("encode_node_empty", 1652), - ("read_rlp_to_memory", 1626), - ("load_mpt", 1355), - ("mpt_read_branch", 1152), - ("mpt_read", 1065), - ("memcpy_bytes", 731), - ("encode_account", 662), - ("prepend_rlp_list_prefix", 602), - ("hash_final_tries", 578), - ("secp_precompute_table", 477), - ("encode_node_leaf", 459), - ("mstore_unpacking_rlp", 448), - ("encode_rlp_fixed", 380), - ("insert_touched_addresses", 368), - ("mpt_read_extension_not_found", 340), - ("mpt_read_state_trie", 323), - ("sys_sstore", 313), - ("process_receipt", 292), - ("process_type_0_txn", 283), - ("encode_rlp_scalar", 271), - ("mpt_insert_hash_node", 252), - ("encode_rlp_list_prefix", 221), - ("encode_rlp_multi_byte_string_prefix", 216), - ("mpt_load_state_trie_value", 213), - ("mload_packing", 204), - ("mpt_hash", 198), - ("decode_rlp_string_len", 197), - ("jumpdest_analysis", 164), - ("load_code", 155), - ("process_normalized_txn", 154), - ("secp_glv_decompose", 148), - ("process_message_txn_code_loaded", 145), - ("insert_accessed_storage_keys", 135), - ("delete_all_touched_addresses", 128), - ("mpt_read_leaf_not_found", 119), - ("encode_receipt", 113), - ("increment_nonce", 108), - ("add_eth", 93), - ("process_message_txn", 82), - ("process_message_txn_after_call", 77), - ("doubly_encode_rlp_scalar", 74), - ("deduct_eth", 72), - ("intrinsic_gas", 64), - ("update_txn_trie", 58), - ("terminate_common", 53), - ("warm_precompiles", 45), - ("extcodehash", 45), - ("sys_stop", 42), - ("start_txn", 41), - ("mpt_insert", 39), - ("load_all_mpts", 38), - ("encode_txn", 36), - ("sload_current", 36), - ("scalar_to_rlp", 35), - ("encode_rlp_string", 34), - ("hash_initial_tries", 33), - ("decode_rlp_scalar", 28), - ("route_txn", 24), - ("mpt_hash_storage_trie", 24), - ("encode_rlp_string_small", 24), - ("encode_rlp_string_large", 23), - ("buy_gas", 20), - ("transfer_eth", 17), - ("mpt_insert_receipt_trie", 17), - ("decode_rlp_list_len", 17), - ("mpt_insert_txn_trie", 16), - ("balance", 15), - ("mpt_hash_txn_trie", 14), - ("mpt_hash_receipt_trie", 14), - ("mpt_hash_state_trie", 14), - ("delete_all_selfdestructed_addresses", 13), - ("logs_bloom", 13), - ("encode_rlp_string_large_after_writing_len", 13), - ("encode_storage_value", 12), - ("encode_rlp_256", 12), - ("txn_after", 12), - ("increment_bounded_rlp", 11), - ("withdrawals", 10), - ("increment_sender_nonce", 9), - ("warm_coinbase", 9), - ("nonce", 9), - ("process_based_on_type", 8), - ("after_storage_read", 7), - ("mpt_read_empty", 7), - ("ec_double_retself", 6), - ("add_bignum", 5), - ("warm_origin", 5), - ("encode_rlp_160", 3), - ("execute_withdrawals", 3), - ("charge_gas_hook", 2), - ("jumped_to_0", 1), - ("halt", 1), - ]; - - let _ = [ - ("secp_add_valid_points_no_edge_case", 10980), - ("ecrecover", 9009), - ("num_bytes", 7306), - ("hex_prefix_rlp", 5820), - ("secp_double", 4076), - ("encode_node_branch", 3440), - ("mstore_unpacking", 2368), - ("main", 2306), - ("secp_add_valid_points", 2281), - ("insert_accessed_addresses", 2238), - ("decode_int_given_len", 1809), - ("encode_node_empty", 1652), - ("read_rlp_to_memory", 1626), - ("load_mpt", 1355), - ("encode_or_hash_node", 1160), - ("mpt_read_branch", 1152), - ("mpt_read", 1065), - ("encode_node", 803), - ("memcpy_bytes", 731), - ("encode_account", 662), - ("prepend_rlp_list_prefix", 602), - ("pack_small_rlp", 590), - ("hash_final_tries", 578), - ("secp_precompute_table", 477), - ("encode_node_leaf", 459), - ("mstore_unpacking_rlp", 448), - ("maybe_hash_node", 438), - ("encode_rlp_fixed", 380), - ("insert_touched_addresses", 368), - ("mpt_read_extension_not_found", 340), - ("mpt_read_state_trie", 323), - ("sys_sstore", 313), - ("process_receipt", 292), - ("process_type_0_txn", 283), - ("encode_rlp_scalar", 271), - ("mpt_insert_hash_node", 252), - ("encode_rlp_list_prefix", 221), - ("encode_rlp_multi_byte_string_prefix", 216), - ("mpt_load_state_trie_value", 213), - ("mload_packing", 204), - ("mpt_hash", 198), - ("decode_rlp_string_len", 197), - ("jumpdest_analysis", 164), - ("load_code", 155), - ("process_normalized_txn", 154), - ("secp_glv_decompose", 148), - ("process_message_txn_code_loaded", 145), - ("insert_accessed_storage_keys", 135), - ("delete_all_touched_addresses", 128), - ("mpt_read_leaf_not_found", 119), - ("encode_receipt", 113), - ("increment_nonce", 108), - ("add_eth", 93), - ("process_message_txn", 82), - ("process_message_txn_after_call", 77), - ("doubly_encode_rlp_scalar", 74), - ("deduct_eth", 72), - ("intrinsic_gas", 64), - ("update_txn_trie", 58), - ("terminate_common", 53), - ("extcodehash", 45), - ("warm_precompiles", 45), - ("sys_stop", 42), - ("start_txn", 41), - ("mpt_insert", 39), - ("load_all_mpts", 38), - ("encode_txn", 36), - ("sload_current", 36), - ("scalar_to_rlp", 35), - ("encode_rlp_string", 34), - ("hash_initial_tries", 33), - ("decode_rlp_scalar", 28), - ("route_txn", 24), - ("mpt_hash_storage_trie", 24), - ("encode_rlp_string_small", 24), - ("encode_rlp_string_large", 23), - ("buy_gas", 20), - ("decode_rlp_list_len", 17), - ("transfer_eth", 17), - ("mpt_insert_receipt_trie", 17), - ("mpt_insert_txn_trie", 16), - ("balance", 15), - ("mpt_hash_txn_trie", 14), - ("mpt_hash_receipt_trie", 14), - ("mpt_hash_state_trie", 14), - ("encode_rlp_string_large_after_writing_len", 13), - ("logs_bloom", 13), - ("delete_all_selfdestructed_addresses", 13), - ("txn_after", 12), - ("encode_storage_value", 12), - ("encode_rlp_256", 12), - ("increment_bounded_rlp", 11), - ("withdrawals", 10), - ("nonce", 9), - ("increment_sender_nonce", 9), - ("warm_coinbase", 9), - ("process_based_on_type", 8), - ("mpt_read_empty", 7), - ("after_storage_read", 7), - ("ec_double_retself", 6), - ("add_bignum", 5), - ("warm_origin", 5), - ("encode_rlp_160", 3), - ("execute_withdrawals", 3), - ("charge_gas_hook", 2), - ("halt", 1), - ("jumped_to_0", 1), - ]; - - let _ = [ - ("secp_add_valid_points_no_edge_case", 10980), - ("ecrecover", 9009), - ("num_bytes", 7306), - ("hex_prefix_rlp", 5820), - ("secp_double", 4076), - ("encode_node_branch", 3408), - ("mstore_unpacking", 2368), - ("main", 2306), - ("secp_add_valid_points", 2281), - ("insert_accessed_addresses", 2238), - ("decode_int_given_len", 1809), - ("encode_node_empty", 1652), - ("read_rlp_to_memory", 1626), - ("load_mpt", 1355), - ("encode_or_hash_node", 1160), - ("mpt_read_branch", 1152), - ("mpt_read", 1065), - ("encode_node", 803), - ("memcpy_bytes", 731), - ("encode_account", 662), - ("prepend_rlp_list_prefix", 602), - ("pack_small_rlp", 590), - ("hash_final_tries", 578), - ("secp_precompute_table", 477), - ("encode_node_leaf", 459), - ("mstore_unpacking_rlp", 448), - ("maybe_hash_node", 438), - ("encode_rlp_fixed", 380), - ("insert_touched_addresses", 368), - ("mpt_read_extension_not_found", 340), - ("mpt_read_state_trie", 323), - ("sys_sstore", 313), - ("process_receipt", 292), - ("process_type_0_txn", 283), - ("encode_rlp_scalar", 271), - ("mpt_insert_hash_node", 252), - ("encode_rlp_list_prefix", 221), - ("encode_rlp_multi_byte_string_prefix", 216), - ("mpt_load_state_trie_value", 213), - ("mload_packing", 204), - ("mpt_hash", 198), - ("decode_rlp_string_len", 197), - ("jumpdest_analysis", 164), - ("load_code", 155), - ("process_normalized_txn", 154), - ("secp_glv_decompose", 148), - ("process_message_txn_code_loaded", 145), - ("insert_accessed_storage_keys", 135), - ("delete_all_touched_addresses", 128), - ("mpt_read_leaf_not_found", 119), - ("encode_receipt", 113), - ("increment_nonce", 108), - ("add_eth", 93), - ("process_message_txn", 82), - ("process_message_txn_after_call", 77), - ("doubly_encode_rlp_scalar", 74), - ("deduct_eth", 72), - ("intrinsic_gas", 64), - ("update_txn_trie", 58), - ("terminate_common", 53), - ("extcodehash", 45), - ("warm_precompiles", 45), - ("sys_stop", 42), - ("start_txn", 41), - ("mpt_insert", 39), - ("load_all_mpts", 38), - ("encode_txn", 36), - ("sload_current", 36), - ("scalar_to_rlp", 35), - ("encode_rlp_string", 34), - ("hash_initial_tries", 33), - ("encode_node_branch_prepend_prefix", 32), - ("decode_rlp_scalar", 28), - ("mpt_hash_storage_trie", 24), - ("route_txn", 24), - ("encode_rlp_string_small", 24), - ("encode_rlp_string_large", 23), - ("buy_gas", 20), - ("transfer_eth", 17), - ("mpt_insert_receipt_trie", 17), - ("decode_rlp_list_len", 17), - ("mpt_insert_txn_trie", 16), - ("balance", 15), - ("mpt_hash_txn_trie", 14), - ("mpt_hash_state_trie", 14), - ("mpt_hash_receipt_trie", 14), - ("delete_all_selfdestructed_addresses", 13), - ("logs_bloom", 13), - ("encode_rlp_string_large_after_writing_len", 13), - ("txn_after", 12), - ("encode_rlp_256", 12), - ("encode_storage_value", 12), - ("increment_bounded_rlp", 11), - ("withdrawals", 10), - ("warm_coinbase", 9), - ("increment_sender_nonce", 9), - ("nonce", 9), - ("process_based_on_type", 8), - ("mpt_read_empty", 7), - ("after_storage_read", 7), - ("ec_double_retself", 6), - ("add_bignum", 5), - ("warm_origin", 5), - ("encode_rlp_160", 3), - ("execute_withdrawals", 3), - ("charge_gas_hook", 2), - ("halt", 1), - ("jumped_to_0", 1), - ]; - } } } diff --git a/evm/src/memory/segments.rs b/evm/src/memory/segments.rs index 6e67e61942..48a1722214 100644 --- a/evm/src/memory/segments.rs +++ b/evm/src/memory/segments.rs @@ -1,3 +1,5 @@ +use ethereum_types::U256; + #[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)] pub(crate) enum Segment { /// Contains EVM bytecode. @@ -29,46 +31,42 @@ pub(crate) enum Segment { RlpRaw = 12, /// Contains all trie data. It is owned by the kernel, so it only lives on context 0. TrieData = 13, - /// A buffer used to store the encodings of a branch node's children. - TrieEncodedChild = 14, - /// A buffer used to store the lengths of the encodings of a branch node's children. - TrieEncodedChildLen = 15, /// A table of values 2^i for i=0..255 for use with shift /// instructions; initialised by `kernel/asm/shift.asm::init_shift_table()`. - ShiftTable = 16, - JumpdestBits = 17, - EcdsaTable = 18, - BnWnafA = 19, - BnWnafB = 20, - BnTableQ = 21, - BnPairing = 22, + ShiftTable = 14, + JumpdestBits = 15, + EcdsaTable = 16, + BnWnafA = 17, + BnWnafB = 18, + BnTableQ = 19, + BnPairing = 20, /// List of addresses that have been accessed in the current transaction. - AccessedAddresses = 23, + AccessedAddresses = 21, /// List of storage keys that have been accessed in the current transaction. - AccessedStorageKeys = 24, + AccessedStorageKeys = 22, /// List of addresses that have called SELFDESTRUCT in the current transaction. - SelfDestructList = 25, + SelfDestructList = 23, /// Contains the bloom filter of a transaction. - TxnBloom = 26, + TxnBloom = 24, /// Contains the bloom filter present in the block header. - GlobalBlockBloom = 27, + GlobalBlockBloom = 25, /// List of log pointers pointing to the LogsData segment. - Logs = 28, - LogsData = 29, + Logs = 26, + LogsData = 27, /// Journal of state changes. List of pointers to `JournalData`. Length in `GlobalMetadata`. - Journal = 30, - JournalData = 31, - JournalCheckpoints = 32, + Journal = 28, + JournalData = 29, + JournalCheckpoints = 30, /// List of addresses that have been touched in the current transaction. - TouchedAddresses = 33, + TouchedAddresses = 31, /// List of checkpoints for the current context. Length in `ContextMetadata`. - ContextCheckpoints = 34, + ContextCheckpoints = 32, /// List of 256 previous block hashes. - BlockHashes = 35, + BlockHashes = 33, } impl Segment { - pub(crate) const COUNT: usize = 36; + pub(crate) const COUNT: usize = 34; pub(crate) const fn all() -> [Self; Self::COUNT] { [ @@ -86,8 +84,6 @@ impl Segment { Self::TxnData, Self::RlpRaw, Self::TrieData, - Self::TrieEncodedChild, - Self::TrieEncodedChildLen, Self::ShiftTable, Self::JumpdestBits, Self::EcdsaTable, @@ -128,8 +124,6 @@ impl Segment { Segment::TxnData => "SEGMENT_TXN_DATA", Segment::RlpRaw => "SEGMENT_RLP_RAW", Segment::TrieData => "SEGMENT_TRIE_DATA", - Segment::TrieEncodedChild => "SEGMENT_TRIE_ENCODED_CHILD", - Segment::TrieEncodedChildLen => "SEGMENT_TRIE_ENCODED_CHILD_LEN", Segment::ShiftTable => "SEGMENT_SHIFT_TABLE", Segment::JumpdestBits => "SEGMENT_JUMPDEST_BITS", Segment::EcdsaTable => "SEGMENT_KERNEL_ECDSA_TABLE", @@ -169,8 +163,6 @@ impl Segment { Segment::TxnData => 8, Segment::RlpRaw => 8, Segment::TrieData => 256, - Segment::TrieEncodedChild => 256, - Segment::TrieEncodedChildLen => 6, Segment::ShiftTable => 256, Segment::JumpdestBits => 1, Segment::EcdsaTable => 256, @@ -193,4 +185,17 @@ impl Segment { Segment::BlockHashes => 256, } } + + pub(crate) fn constant(&self, virt: usize) -> Option { + match self { + Segment::RlpRaw => { + if virt == 0xFFFFFFFF { + Some(U256::from(0x80)) + } else { + None + } + } + _ => None, + } + } } diff --git a/evm/src/witness/memory.rs b/evm/src/witness/memory.rs index 8cb7daf704..f39073c0ef 100644 --- a/evm/src/witness/memory.rs +++ b/evm/src/witness/memory.rs @@ -177,6 +177,11 @@ impl MemoryState { } let segment = Segment::all()[address.segment]; + + if let Some(constant) = Segment::constant(&segment, address.virt) { + return constant; + } + let val = self.contexts[address.context].segments[address.segment].get(address.virt); assert!( val.bits() <= segment.bit_range(), @@ -194,6 +199,15 @@ impl MemoryState { } let segment = Segment::all()[address.segment]; + + if let Some(constant) = Segment::constant(&segment, address.virt) { + assert!( + constant == val, + "Attempting to set constant {} to incorrect value", + address.virt + ); + return; + } assert!( val.bits() <= segment.bit_range(), "Value {} exceeds {:?} range of {} bits", From 48b9769e342614b978557a5d771657ca0cd7d05b Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Wed, 27 Dec 2023 12:24:12 +0100 Subject: [PATCH 3/7] Remove duplicated label --- evm/src/cpu/kernel/asm/mpt/hash/hash.asm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm index cf0634fd22..9feb4e1916 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -127,12 +127,6 @@ global encode_node_empty: %stack (cur_len, retdest) -> (retdest, @ENCODED_EMPTY_NODE_POS, 1, cur_len) JUMP -global encode_node_empty: - // stack: node_type, node_payload_ptr, encode_value, retdest - %pop3 - %stack (retdest) -> (retdest, @ENCODED_EMPTY_NODE_POS, 1) - JUMP - global encode_node_branch: // stack: node_type, node_payload_ptr, encode_value, cur_len, retdest POP From f4713c44d3d1dec43ae36b745263aa87078c9398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alonso=20Gonz=C3=A1lez?= Date: Fri, 5 Jan 2024 17:18:03 +0100 Subject: [PATCH 4/7] Apply suggestions from code review Co-authored-by: Linda Guiga <101227802+LindaGuiga@users.noreply.github.com> Co-authored-by: Robin Salen <30937548+Nashtare@users.noreply.github.com> --- evm/src/cpu/kernel/asm/mpt/hash/hash.asm | 2 +- evm/src/cpu/kernel/constants/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm index 9feb4e1916..6d0cf10ccc 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -197,7 +197,7 @@ encode_node_branch_prepend_prefix: // If result_len != 32, result is raw RLP, with an appropriate RLP prefix already. SWAP1 DUP1 %sub_const(32) %jumpi(%%unpack) // Otherwise, result is a hash, and we need to add the prefix 0x80 + 32 = 160. - // stack: result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest + // stack: result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest PUSH 160 DUP5 // rlp_pos %mstore_rlp diff --git a/evm/src/cpu/kernel/constants/mod.rs b/evm/src/cpu/kernel/constants/mod.rs index fa25fa8704..1cd99b384d 100644 --- a/evm/src/cpu/kernel/constants/mod.rs +++ b/evm/src/cpu/kernel/constants/mod.rs @@ -94,7 +94,7 @@ const MISC_CONSTANTS: [(&str, [u8; 32]); 3] = [ hex!("0000000000000000000000000000000100000000000000000000000000000000"), ), // Position in SEGMENT_RLP_RAW where the empty node encoding is stored. It is - // equal to usize::MAX so that all rlp pointers all much smalled than that + // equal to usize::MAX so that all rlp pointers all much smaller than that. ( "ENCODED_EMPTY_NODE_POS", hex!("00000000000000000000000000000000000000000000000000000000FFFFFFFF"), From 1c994737ef025117333f6f0d5745d44a35a1d824 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 5 Jan 2024 17:30:59 +0100 Subject: [PATCH 5/7] Address comments --- evm/src/cpu/kernel/asm/main.asm | 3 --- evm/src/cpu/kernel/asm/mpt/hash/hash.asm | 2 +- evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm | 3 --- evm/src/cpu/kernel/interpreter.rs | 2 +- evm/src/cpu/kernel/tests/mpt/insert.rs | 4 +--- evm/src/generation/mod.rs | 2 +- 6 files changed, 4 insertions(+), 12 deletions(-) diff --git a/evm/src/cpu/kernel/asm/main.asm b/evm/src/cpu/kernel/asm/main.asm index d1e06b6633..df6b09b3e7 100644 --- a/evm/src/cpu/kernel/asm/main.asm +++ b/evm/src/cpu/kernel/asm/main.asm @@ -15,9 +15,6 @@ global main: %shift_table_init // Encode constant nodes %initialize_rlp_segment - - // Encode constant nodes - %initialize_rlp_segment // Initialize the state, transaction and receipt trie root pointers. PROVER_INPUT(trie_ptr::state) diff --git a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm index 6d0cf10ccc..c45785fa28 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -105,7 +105,7 @@ after_packed_small_rlp: // indicating where the data lives within @SEGMENT_RLP_RAW. // // Pre stack: node_type, node_ptr, encode_value, cur_len, retdest -// Post stack: result_ptr, result_len +// Post stack: result_ptr, result_len, cur_len encode_node: // stack: node_type, node_ptr, encode_value, cur_len, retdest // Increment node_ptr, so it points to the node payload instead of its type. diff --git a/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm b/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm index f3ee000def..03a8d27589 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm @@ -3,9 +3,6 @@ global mpt_hash_state_trie: // stack: cur_len, retdest PUSH encode_account - PUSH debug_before_encoding_child - PUSH mpt_delete - %pop2 %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) // stack: node_ptr, encode_account, cur_len, retdest %jump(mpt_hash) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 58de9e3485..4641e8a188 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -1174,7 +1174,7 @@ impl<'a> Interpreter<'a> { self.generation_state.registers.context = context; } - /// Writes the encoding of 0 to position @ + /// Writes the encoding of 0 to position @ENCODED_EMPTY_NODE_POS pub(crate) fn initialize_rlp_segment(&mut self) { self.generation_state.memory.set( MemoryAddress { diff --git a/evm/src/cpu/kernel/tests/mpt/insert.rs b/evm/src/cpu/kernel/tests/mpt/insert.rs index acd42e8f3a..9c2fd50b24 100644 --- a/evm/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm/src/cpu/kernel/tests/mpt/insert.rs @@ -12,12 +12,11 @@ use crate::cpu::kernel::tests::mpt::{ }; use crate::generation::mpt::AccountRlp; use crate::generation::TrieInputs; -use crate::util::u256_to_usize; use crate::Node; #[test] fn mpt_insert_empty() -> Result<()> { - test_state_trie(Default::default(), nibbles_64(0xDEF), test_account_2()) + test_state_trie(Default::default(), nibbles_64(0xABC), test_account_2()) } #[test] @@ -234,7 +233,6 @@ fn test_state_trie( let hash = H256::from_uint(&interpreter.stack()[1]); state_trie.insert(k, rlp::encode(&account).to_vec()); - let expected_state_trie_hash = state_trie.hash(); assert_eq!(hash, expected_state_trie_hash); diff --git a/evm/src/generation/mod.rs b/evm/src/generation/mod.rs index e5dbc3e7b4..d691d34e61 100644 --- a/evm/src/generation/mod.rs +++ b/evm/src/generation/mod.rs @@ -35,7 +35,7 @@ pub mod mpt; pub(crate) mod prover_input; pub(crate) mod rlp; pub(crate) mod state; -pub(crate) mod trie_extractor; +mod trie_extractor; use self::mpt::{load_all_mpts, TrieRootPtrs}; use crate::witness::util::mem_write_log; From 77f510950800ef241fa5be7b45bde502087ec8c8 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Mon, 8 Jan 2024 14:34:26 +0100 Subject: [PATCH 6/7] Adress reviewer comments --- evm/src/cpu/kernel/constants/mod.rs | 2 +- evm/src/cpu/kernel/tests/account_code.rs | 64 +++++++----------------- evm/src/cpu/kernel/tests/add11.rs | 11 +--- 3 files changed, 22 insertions(+), 55 deletions(-) diff --git a/evm/src/cpu/kernel/constants/mod.rs b/evm/src/cpu/kernel/constants/mod.rs index fa25fa8704..de4dfd4bcc 100644 --- a/evm/src/cpu/kernel/constants/mod.rs +++ b/evm/src/cpu/kernel/constants/mod.rs @@ -94,7 +94,7 @@ const MISC_CONSTANTS: [(&str, [u8; 32]); 3] = [ hex!("0000000000000000000000000000000100000000000000000000000000000000"), ), // Position in SEGMENT_RLP_RAW where the empty node encoding is stored. It is - // equal to usize::MAX so that all rlp pointers all much smalled than that + // equal to u32::MAX so that all rlp pointers are much smaller than that ( "ENCODED_EMPTY_NODE_POS", hex!("00000000000000000000000000000000000000000000000000000000FFFFFFFF"), diff --git a/evm/src/cpu/kernel/tests/account_code.rs b/evm/src/cpu/kernel/tests/account_code.rs index f985ebd445..20c98bf976 100644 --- a/evm/src/cpu/kernel/tests/account_code.rs +++ b/evm/src/cpu/kernel/tests/account_code.rs @@ -201,36 +201,21 @@ fn test_extcodecopy() -> Result<()> { prepare_interpreter(&mut interpreter, address, &account)?; let context = interpreter.context(); - interpreter.generation_state.memory.set( - MemoryAddress { - context, - segment: Segment::ContextMetadata as usize, - virt: GasLimit as usize, - }, - U256::from(1000000000000u64), - ); + interpreter.generation_state.memory.contexts[context].segments + [Segment::ContextMetadata as usize] + .set(GasLimit as usize, U256::from(1000000000000u64)); let extcodecopy = KERNEL.global_labels["sys_extcodecopy"]; // Put random data in main memory and the `KernelAccountCode` segment for realism. let mut rng = thread_rng(); for i in 0..2000 { - interpreter.generation_state.memory.set( - MemoryAddress { - context, - segment: Segment::MainMemory as usize, - virt: i, - }, - U256::from(rng.gen::()), - ); - interpreter.generation_state.memory.set( - MemoryAddress { - context, - segment: Segment::KernelAccountCode as usize, - virt: i, - }, - U256::from(rng.gen::()), - ); + interpreter.generation_state.memory.contexts[context].segments + [Segment::MainMemory as usize] + .set(i, U256::from(rng.gen::())); + interpreter.generation_state.memory.contexts[context].segments + [Segment::KernelAccountCode as usize] + .set(i, U256::from(rng.gen::())); } // Random inputs @@ -265,11 +250,9 @@ fn test_extcodecopy() -> Result<()> { assert!(interpreter.stack().is_empty()); // Check that the code was correctly copied to memory. for i in 0..size { - let memory = interpreter.generation_state.memory.get(MemoryAddress { - context, - segment: Segment::MainMemory as usize, - virt: dest_offset + i, - }); + let memory = interpreter.generation_state.memory.contexts[context].segments + [Segment::MainMemory as usize] + .get(dest_offset + i); assert_eq!( memory, code.get(offset + i).copied().unwrap_or_default().into() @@ -294,22 +277,13 @@ fn prepare_interpreter_all_accounts( // Switch context and initialize memory with the data we need for the tests. interpreter.generation_state.registers.program_counter = 0; interpreter.set_code(1, code.to_vec()); - interpreter.generation_state.memory.set( - MemoryAddress { - context: 1, - segment: Segment::ContextMetadata as usize, - virt: ContextMetadata::Address as usize, - }, - U256::from_big_endian(&addr), - ); - interpreter.generation_state.memory.set( - MemoryAddress { - context: 1, - segment: Segment::ContextMetadata as usize, - virt: ContextMetadata::GasLimit as usize, - }, - 100_000.into(), - ); + interpreter.generation_state.memory.contexts[1].segments[Segment::ContextMetadata as usize] + .set( + ContextMetadata::Address as usize, + U256::from_big_endian(&addr), + ); + interpreter.generation_state.memory.contexts[1].segments[Segment::ContextMetadata as usize] + .set(ContextMetadata::GasLimit as usize, 100_000.into()); interpreter.set_context(1); interpreter.set_is_kernel(false); interpreter.generation_state.memory.set( diff --git a/evm/src/cpu/kernel/tests/add11.rs b/evm/src/cpu/kernel/tests/add11.rs index b85bfe66c0..9ba65db2c9 100644 --- a/evm/src/cpu/kernel/tests/add11.rs +++ b/evm/src/cpu/kernel/tests/add11.rs @@ -19,7 +19,6 @@ use crate::generation::TrieInputs; use crate::memory::segments::Segment; use crate::proof::TrieRoots; use crate::util::h2u; -use crate::witness::memory::MemoryAddress; // Stolen from `tests/mpt/insert.rs` // Prepare the interpreter by loading the initial MPTs and @@ -200,14 +199,8 @@ fn test_add11_yml() { let route_txn_label = KERNEL.global_labels["hash_initial_tries"]; // Switch context and initialize memory with the data we need for the tests. interpreter.generation_state.registers.program_counter = route_txn_label; - interpreter.generation_state.memory.set( - MemoryAddress { - context: 0, - segment: Segment::ContextMetadata as usize, - virt: ContextMetadata::GasLimit as usize, - }, - 1_000_000.into(), - ); + interpreter.generation_state.memory.contexts[0].segments[Segment::ContextMetadata as usize] + .set(ContextMetadata::GasLimit as usize, 1_000_000.into()); interpreter.set_is_kernel(true); interpreter.run().expect("Proving add11 failed."); } From 5b71eb4ee0f96d8b563222b4c9c3013fe7e647d3 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Tue, 9 Jan 2024 11:48:30 +0100 Subject: [PATCH 7/7] Address review comments --- evm/src/cpu/kernel/constants/mod.rs | 2 +- evm/src/cpu/kernel/interpreter.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/src/cpu/kernel/constants/mod.rs b/evm/src/cpu/kernel/constants/mod.rs index 3386865a67..f6f021db76 100644 --- a/evm/src/cpu/kernel/constants/mod.rs +++ b/evm/src/cpu/kernel/constants/mod.rs @@ -97,7 +97,7 @@ const MISC_CONSTANTS: [(&str, [u8; 32]); 3] = [ hex!("0000000000000000000000000000000100000000000000000000000000000000"), ), // Position in SEGMENT_RLP_RAW where the empty node encoding is stored. It is - // equal to u32::MAX + @SEGMENT_RLP_RAW so that all rlp pointers are much smaller than that + // equal to u32::MAX + @SEGMENT_RLP_RAW so that all rlp pointers are much smaller than that. ( "ENCODED_EMPTY_NODE_POS", hex!("0000000000000000000000000000000000000000000000000000000CFFFFFFFF"), diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index b85ac1761b..b99ccaebc5 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -1196,7 +1196,7 @@ impl<'a> Interpreter<'a> { self.generation_state.registers.context = context; } - /// Writes the encoding of 0 to position @ENCODED_EMPTY_NODE_POS + /// Writes the encoding of 0 to position @ENCODED_EMPTY_NODE_POS. pub(crate) fn initialize_rlp_segment(&mut self) { self.generation_state.memory.set( MemoryAddress::new(0, Segment::RlpRaw, 0xFFFFFFFF),