diff --git a/evm/src/cpu/kernel/asm/mpt/hash.asm b/evm/src/cpu/kernel/asm/mpt/hash.asm index ef0158e0..511e9d18 100644 --- a/evm/src/cpu/kernel/asm/mpt/hash.asm +++ b/evm/src/cpu/kernel/asm/mpt/hash.asm @@ -137,6 +137,8 @@ encode_node_branch: // stack: rlp_pos', node_payload_ptr, encode_value, retdest SWAP1 %add_const(16) + // stack: value_ptr_ptr, rlp_pos', encode_value, retdest + %mload_trie_data // stack: value_len_ptr, rlp_pos', encode_value, retdest DUP1 %mload_trie_data // stack: value_len, value_len_ptr, rlp_pos', encode_value, retdest @@ -257,7 +259,10 @@ encode_node_leaf: encode_node_leaf_after_hex_prefix: // stack: rlp_pos, node_payload_ptr, encode_value, retdest SWAP1 - %add_const(3) // The value starts at index 3, after num_nibbles, packed_nibbles, and value_len. + %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. + // stack: value_ptr_ptr, rlp_pos, encode_value, retdest + %mload_trie_data + %increment // skip over length prefix // stack: value_ptr, rlp_pos, encode_value, retdest %stack (value_ptr, rlp_pos, encode_value, retdest) -> (encode_value, rlp_pos, value_ptr, encode_node_leaf_after_encode_value, retdest) diff --git a/evm/src/cpu/kernel/asm/mpt/load.asm b/evm/src/cpu/kernel/asm/mpt/load.asm index f37e94ba..62909f2d 100644 --- a/evm/src/cpu/kernel/asm/mpt/load.asm +++ b/evm/src/cpu/kernel/asm/mpt/load.asm @@ -76,9 +76,14 @@ load_mpt_branch: %get_trie_data_size // stack: ptr_children, retdest DUP1 %add_const(16) - // stack: ptr_leaf, ptr_children, retdest + // stack: ptr_value, ptr_children, retdest %set_trie_data_size // stack: ptr_children, retdest + // We need to append a pointer to where the value will live. + // %load_leaf_value will append the value just after this pointer; + // we add 1 to account for the pointer itself. + %get_trie_data_size %increment %append_to_trie_data + // stack: ptr_children, retdest %load_leaf_value // Load the 16 children. @@ -128,6 +133,11 @@ load_mpt_leaf: PROVER_INPUT(mpt) // read packed_nibbles %append_to_trie_data // stack: retdest + // We need to append a pointer to where the value will live. + // %load_leaf_value will append the value just after this pointer; + // we add 1 to account for the pointer itself. + %get_trie_data_size %increment %append_to_trie_data + // stack: retdest %load_leaf_value // stack: retdest JUMP diff --git a/evm/src/cpu/kernel/asm/mpt/read.asm b/evm/src/cpu/kernel/asm/mpt/read.asm index c6f36204..dae97336 100644 --- a/evm/src/cpu/kernel/asm/mpt/read.asm +++ b/evm/src/cpu/kernel/asm/mpt/read.asm @@ -1,6 +1,6 @@ -// Given an address, return a pointer to the associated account data, which -// consists of four words (nonce, balance, storage_root, code_hash), in the -// state trie. Returns 0 if the address is not found. +// Given an address, return a pointer to the associated (length-prefixed) +// account data, which consists of four words (nonce, balance, storage_root, +// code_hash), in the state trie. Returns 0 if the address is not found. global mpt_read_state_trie: // stack: addr, retdest // The key is the hash of the address. Since KECCAK_GENERAL takes input from @@ -24,7 +24,7 @@ mpt_read_state_trie_after_mstore: // - the key, as a U256 // - the number of nibbles in the key (should start at 64) // -// This function returns a pointer to the leaf, or 0 if the key is not found. +// This function returns a pointer to the length-prefixed leaf, or 0 if the key is not found. global mpt_read: // stack: node_ptr, num_nibbles, key, retdest DUP1 @@ -75,6 +75,8 @@ mpt_read_branch_end_of_key: %stack (node_payload_ptr, num_nibbles, key, retdest) -> (node_payload_ptr, retdest) // stack: node_payload_ptr, retdest %add_const(16) // skip over the 16 child nodes + // stack: value_ptr_ptr, retdest + %mload_trie_data // stack: value_len_ptr, retdest DUP1 %mload_trie_data // stack: value_len, value_len_ptr, retdest @@ -147,7 +149,9 @@ mpt_read_leaf: JUMP mpt_read_leaf_found: // stack: node_payload_ptr, retdest - %add_const(3) // The value is located after num_nibbles, the key, and the value length. + %add_const(2) // The value pointer is located after num_nibbles and the key. + // stack: value_ptr_ptr, retdest + %mload_trie_data // stack: value_ptr, retdest SWAP1 JUMP diff --git a/evm/src/cpu/kernel/tests/mpt/load.rs b/evm/src/cpu/kernel/tests/mpt/load.rs index 3af39e30..ca4f7071 100644 --- a/evm/src/cpu/kernel/tests/mpt/load.rs +++ b/evm/src/cpu/kernel/tests/mpt/load.rs @@ -48,6 +48,7 @@ fn load_all_mpts() -> Result<()> { type_leaf, 3.into(), // 3 nibbles 0xDEF.into(), // key part + 9.into(), // value pointer 4.into(), // value length account.nonce, account.balance, diff --git a/evm/src/cpu/kernel/tests/mpt/read.rs b/evm/src/cpu/kernel/tests/mpt/read.rs index c45a6b60..06d89ff6 100644 --- a/evm/src/cpu/kernel/tests/mpt/read.rs +++ b/evm/src/cpu/kernel/tests/mpt/read.rs @@ -44,11 +44,12 @@ fn mpt_read() -> Result<()> { assert_eq!(interpreter.stack().len(), 1); let result_ptr = interpreter.stack()[0].as_usize(); - let result = &interpreter.get_trie_data()[result_ptr..][..4]; - assert_eq!(result[0], account.nonce); - assert_eq!(result[1], account.balance); - assert_eq!(result[2], account.storage_root.into_uint()); - assert_eq!(result[3], account.code_hash.into_uint()); + let result = &interpreter.get_trie_data()[result_ptr..][..5]; + assert_eq!(result[0], 4.into()); + assert_eq!(result[1], account.nonce); + assert_eq!(result[2], account.balance); + assert_eq!(result[3], account.storage_root.into_uint()); + assert_eq!(result[4], account.code_hash.into_uint()); Ok(()) }