diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 522da72a25..bd06bb6194 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -114,6 +114,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/smt/hash.asm"), include_str!("asm/smt/insert.asm"), include_str!("asm/smt/read.asm"), + include_str!("asm/smt/delete.asm"), include_str!("asm/smt/utils.asm"), include_str!("asm/smt/accounts.asm"), include_str!("asm/mpt/delete/delete.asm"), diff --git a/evm/src/cpu/kernel/asm/core/create.asm b/evm/src/cpu/kernel/asm/core/create.asm index 4756b40702..c0d768f9aa 100644 --- a/evm/src/cpu/kernel/asm/core/create.asm +++ b/evm/src/cpu/kernel/asm/core/create.asm @@ -242,7 +242,7 @@ create_too_deep: global set_codehash: // stack: addr, codehash, retdest DUP1 %insert_touched_addresses - DUP1 %mpt_read_state_trie + DUP1 %smt_read_state // stack: account_ptr, addr, codehash, retdest %add_const(3) // stack: codehash_ptr, addr, codehash, retdest diff --git a/evm/src/cpu/kernel/asm/core/create_contract_account.asm b/evm/src/cpu/kernel/asm/core/create_contract_account.asm index b45d45ca5c..ca74dcfe67 100644 --- a/evm/src/cpu/kernel/asm/core/create_contract_account.asm +++ b/evm/src/cpu/kernel/asm/core/create_contract_account.asm @@ -4,7 +4,7 @@ %macro create_contract_account // stack: address DUP1 %insert_touched_addresses - DUP1 %mpt_read_state_trie + DUP1 %smt_read_state // stack: existing_account_ptr, address // If the account doesn't exist, there's no need to check its balance or nonce, // so we can skip ahead, setting existing_balance = existing_account_ptr = 0. @@ -46,7 +46,7 @@ // stack: address, account_ptr %addr_to_state_key // stack: state_key, account_ptr - %mpt_insert_state_trie + %smt_insert_state // stack: (empty) PUSH 0 // success %jump(%%end) diff --git a/evm/src/cpu/kernel/asm/core/terminate.asm b/evm/src/cpu/kernel/asm/core/terminate.asm index bdbd3e5886..a91d664752 100644 --- a/evm/src/cpu/kernel/asm/core/terminate.asm +++ b/evm/src/cpu/kernel/asm/core/terminate.asm @@ -89,7 +89,7 @@ global sys_selfdestruct: // stack: balance, address, recipient, kexit_info PUSH 0 // stack: 0, balance, address, recipient, kexit_info - DUP3 %mpt_read_state_trie + DUP3 %smt_read_state // stack: account_ptr, 0, balance, address, recipient, kexit_info %add_const(1) // stack: balance_ptr, 0, balance, address, recipient, kexit_info diff --git a/evm/src/cpu/kernel/asm/core/util.asm b/evm/src/cpu/kernel/asm/core/util.asm index a186520cd7..33d60ab709 100644 --- a/evm/src/cpu/kernel/asm/core/util.asm +++ b/evm/src/cpu/kernel/asm/core/util.asm @@ -34,7 +34,7 @@ // Returns 1 if the account is non-existent, 0 otherwise. %macro is_non_existent // stack: addr - %mpt_read_state_trie ISZERO + %smt_read_state ISZERO %endmacro // Returns 1 if the account is empty, 0 otherwise. diff --git a/evm/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm/src/cpu/kernel/asm/journal/account_destroyed.asm index 3806a891dc..152e87bc70 100644 --- a/evm/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -16,7 +16,7 @@ revert_account_destroyed_contd: SWAP1 // Remove `prev_balance` from `target`'s balance. // stack: target, address, prev_balance, retdest - %mpt_read_state_trie + %smt_read_state %add_const(1) // stack: target_balance_ptr, address, prev_balance, retdest DUP3 @@ -25,7 +25,7 @@ revert_account_destroyed_contd: SUB SWAP1 %mstore_trie_data // Set `address`'s balance to `prev_balance`. // stack: address, prev_balance, retdest - %mpt_read_state_trie + %smt_read_state %add_const(1) %mstore_trie_data JUMP diff --git a/evm/src/cpu/kernel/asm/journal/code_change.asm b/evm/src/cpu/kernel/asm/journal/code_change.asm index 5bb637c726..df211135a8 100644 --- a/evm/src/cpu/kernel/asm/journal/code_change.asm +++ b/evm/src/cpu/kernel/asm/journal/code_change.asm @@ -9,7 +9,7 @@ global revert_code_change: POP %journal_load_2 // stack: address, prev_codehash, retdest - %mpt_read_state_trie + %smt_read_state // stack: account_ptr, prev_codehash, retdest %add_const(3) // stack: codehash_ptr, prev_codehash, retdest diff --git a/evm/src/cpu/kernel/asm/journal/nonce_change.asm b/evm/src/cpu/kernel/asm/journal/nonce_change.asm index 3ab8f13677..3c2ab17060 100644 --- a/evm/src/cpu/kernel/asm/journal/nonce_change.asm +++ b/evm/src/cpu/kernel/asm/journal/nonce_change.asm @@ -9,7 +9,7 @@ global revert_nonce_change: POP %journal_load_2 // stack: address, prev_nonce, retdest - %mpt_read_state_trie + %smt_read_state // stack: nonce_ptr, prev_nonce retdest %mstore_trie_data // stack: retdest diff --git a/evm/src/cpu/kernel/asm/journal/storage_change.asm b/evm/src/cpu/kernel/asm/journal/storage_change.asm index 752674d1e1..1a5d7e44c1 100644 --- a/evm/src/cpu/kernel/asm/journal/storage_change.asm +++ b/evm/src/cpu/kernel/asm/journal/storage_change.asm @@ -15,7 +15,7 @@ global revert_storage_change: // stack: storage_key, address, prev_value, retdest PUSH 64 // storage_key has 64 nibbles // stack: 64, storage_key, address, prev_value, retdest - DUP3 %mpt_read_state_trie + DUP3 %smt_read_state DUP1 ISZERO %jumpi(panic) // stack: account_ptr, 64, storage_key, address, prev_value, retdest %add_const(2) @@ -33,20 +33,18 @@ delete: %stack (slot, address, retdest) -> (slot, new_storage_root, address, retdest) %slot_to_storage_key // stack: storage_key, new_storage_root, address, retdest - PUSH 64 // storage_key has 64 nibbles - // stack: 64, storage_key, new_storage_root, address, retdest - DUP4 %mpt_read_state_trie + DUP3 %smt_read_state DUP1 ISZERO %jumpi(panic) - // stack: account_ptr, 64, storage_key, new_storage_root, address, retdest + // stack: account_ptr, storage_key, new_storage_root, address, retdest %add_const(2) - // stack: storage_root_ptr_ptr, 64, storage_key, new_storage_root, address, retdest + // stack: storage_root_ptr_ptr, storage_key, new_storage_root, address, retdest %mload_trie_data - // stack: storage_root_ptr, 64, storage_key, new_storage_root, address, retdest - %jump(mpt_delete) + // stack: storage_root_ptr, storage_key, new_storage_root, address, retdest + %jump(smt_delete) new_storage_root: // stack: new_storage_root_ptr, address, retdest - DUP2 %mpt_read_state_trie + DUP2 %smt_read_state // stack: account_ptr, new_storage_root_ptr, address, retdest // Update account with our new storage root pointer. diff --git a/evm/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm/src/cpu/kernel/asm/mpt/delete/delete.asm index 913ba1fcfb..5df1e283b1 100644 --- a/evm/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -22,24 +22,3 @@ mpt_delete_leaf: %pop4 PUSH 0 // empty node ptr SWAP1 JUMP - -global delete_account: - %stack (address, retdest) -> (address, delete_account_save, retdest) - %addr_to_state_key - // stack: key, delete_account_save, retdest - PUSH 64 - // stack: 64, key, delete_account_save, retdest - %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) - // stack: state_root_prt, 64, key, delete_account_save, retdest - %jump(mpt_delete) -delete_account_save: - // stack: updated_state_root_ptr, retdest - %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) - JUMP - -%macro delete_account - %stack (address) -> (address, %%after) - %jump(delete_account) -%%after: - // stack: (empty) -%endmacro \ No newline at end of file diff --git a/evm/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm/src/cpu/kernel/asm/mpt/storage/storage_write.asm index 5caafb3b5f..f5b9610cc5 100644 --- a/evm/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -133,14 +133,12 @@ sstore_noop: // Delete the slot from the storage SMT. sstore_delete: - PANIC // TODO: Not implemented for SMT. // stack: slot, value, kexit_info SWAP1 POP PUSH after_storage_insert SWAP1 // stack: slot, after_storage_insert, kexit_info %slot_to_storage_key // stack: storage_key, after_storage_insert, kexit_info - PUSH 64 // storage_key has 64 nibbles %current_storage_smt - // stack: storage_root_ptr, 64, storage_key, after_storage_insert, kexit_info - %jump(mpt_delete) + // stack: storage_root_ptr, storage_key, after_storage_insert, kexit_info + %jump(smt_delete) diff --git a/evm/src/cpu/kernel/asm/smt/delete.asm b/evm/src/cpu/kernel/asm/smt/delete.asm new file mode 100644 index 0000000000..ec6268ef47 --- /dev/null +++ b/evm/src/cpu/kernel/asm/smt/delete.asm @@ -0,0 +1,154 @@ +// Return a copy of the given node with the given key deleted. +// Assumes that the key is in the SMT. +// +// Pre stack: node_ptr, key, retdest +// Post stack: updated_node_ptr +global smt_delete: + // stack: node_ptr, key, retdest + DUP1 %mload_trie_data + // stack: node_type, node_ptr, key, retdest + // Increment node_ptr, so it points to the node payload instead of its type. + SWAP1 %increment SWAP1 + // stack: node_type, node_payload_ptr, key, retdest + + DUP1 %eq_const(@SMT_NODE_INTERNAL) %jumpi(smt_delete_internal) + DUP1 %eq_const(@SMT_NODE_LEAF) %jumpi(smt_delete_leaf) + PANIC // Should never happen. + +smt_delete_leaf: + // stack: node_type, node_payload_ptr, key, retdest + %pop3 + PUSH 0 // empty node ptr + SWAP1 JUMP + +smt_delete_internal: + // stack: node_type, node_payload_ptr, key, retdest + POP + // stack: node_payload_ptr, key, retdest + SWAP1 %pop_bit + %stack (bit, key, node_payload_ptr, retdest) -> (bit, node_payload_ptr, key, internal_update, node_payload_ptr, bit, retdest) + ADD + // stack: child_ptr_ptr, key, internal_update, node_payload_ptr, bit, retdest + %mload_trie_data + // stack: child_ptr, key, internal_update, node_payload_ptr, bit, retdest + %jump(smt_delete) + +// Update the internal node, possibly deleting it, or returning a leaf node. +// TODO: Could replace a lot of `is_empty` check with just ISZERO. +internal_update: + // Update the child first. + // stack: deleted_child_ptr, node_payload_ptr, bit, retdest + DUP3 PUSH 1 SUB + // stack: 1-bit, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP3 ADD + // stack: sibling_ptr_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + %mload_trie_data DUP1 %mload_trie_data + // stack: sibling_node_type, sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP1 %eq_const(@SMT_NODE_HASH) %jumpi(sibling_is_hash) + %eq_const(@SMT_NODE_LEAF) %jumpi(sibling_is_leaf) +sibling_is_internal: + // stack: sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + POP +insert_child: + // stack: deleted_child_ptr, node_payload_ptr, bit, retdest + %stack (deleted_child_ptr, node_payload_ptr, bit) -> (node_payload_ptr, bit, deleted_child_ptr, node_payload_ptr) + ADD %mstore_trie_data + // stack: node_payload_ptr, retdest + %decrement SWAP1 + // stack: retdest, node_ptr + JUMP + +sibling_is_hash: + // stack: sibling_node_type, sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + POP + // stack: sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + %increment %mload_trie_data + // stack: hash, deleted_child_ptr, node_payload_ptr, bit, retdest + %jumpi(insert_child) +sibling_is_empty: + // stack: deleted_child_ptr, node_payload_ptr, bit, retdest + DUP1 %mload_trie_data + // stack: deleted_child_node_type, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP1 %eq_const(@SMT_NODE_HASH) %jumpi(sibling_is_empty_child_is_hash) + DUP1 %eq_const(@SMT_NODE_LEAF) %jumpi(sibling_is_empty_child_is_leaf) +sibling_is_empty_child_is_internal: + // stack: deleted_child_node_type, deleted_child_ptr, node_payload_ptr, bit, retdest + POP + // stack: deleted_child_ptr, node_payload_ptr, bit, retdest + %jump(insert_child) + +sibling_is_empty_child_is_hash: + // stack: deleted_child_node_type, deleted_child_ptr, node_payload_ptr, bit, retdest + POP + // stack: deleted_child_ptr, node_payload_ptr, bit, retdest + DUP1 %increment %mload_trie_data + // stack: hash, deleted_child_ptr, node_payload_ptr, bit, retdest + %jumpi(insert_child) +sibling_is_empty_child_is_empty: + // We can just delete this node. + // stack: deleted_child_ptr, node_payload_ptr, bit, retdest + %pop3 + SWAP1 PUSH 0 + // stack: retdest, 0 + JUMP + +sibling_is_empty_child_is_leaf: + // stack: deleted_child_node_type, deleted_child_ptr, node_payload_ptr, bit, retdest + POP + // stack: deleted_child_ptr, node_payload_ptr, bit, retdest + DUP1 %increment %mload_trie_data + // stack: child_key_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP1 %mload_trie_data + // stack: key, child_key_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + %shl_const(1) + // stack: key<<1, child_key_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP5 ADD + // stack: new_key, child_key_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + SWAP1 %mstore_trie_data + %stack (deleted_child_ptr, node_payload_ptr, bit, retdest) -> (retdest, deleted_child_ptr) + JUMP + +sibling_is_leaf: + // stack: sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP2 %is_non_empty_node + // stack: child_is_non_empty, sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + %jumpi(sibling_is_leaf_child_is_non_empty) +sibling_is_leaf_child_is_empty: + // stack: sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP1 %increment %mload_trie_data + // stack: sibling_key_ptr, sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP1 %mload_trie_data + // stack: sibling_key, sibling_key_ptr, sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + %shl_const(1) + // stack: sibling_key<<1, sibling_key_ptr, sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + DUP6 PUSH 1 SUB + // stack: 1-bit, sibling_key<<1, sibling_key_ptr, sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + ADD SWAP1 %mstore_trie_data + // stack: sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + %stack (sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest) -> (retdest, sibling_ptr) + JUMP + +sibling_is_leaf_child_is_non_empty: + // stack: sibling_ptr, deleted_child_ptr, node_payload_ptr, bit, retdest + POP + // stack: deleted_child_ptr, node_payload_ptr, bit, retdest + %jump(insert_child) + +global delete_account: + %stack (address, retdest) -> (address, delete_account_save, retdest) + %addr_to_state_key + // stack: key, delete_account_save, retdest + %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + // stack: state_root_prt, key, delete_account_save, retdest + %jump(smt_delete) +delete_account_save: + // stack: updated_state_root_ptr, retdest + %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + JUMP + +%macro delete_account + %stack (address) -> (address, %%after) + %jump(delete_account) +%%after: + // stack: (empty) +%endmacro diff --git a/evm/src/cpu/kernel/asm/smt/insert.asm b/evm/src/cpu/kernel/asm/smt/insert.asm index 32b248c66a..cc8f58405b 100644 --- a/evm/src/cpu/kernel/asm/smt/insert.asm +++ b/evm/src/cpu/kernel/asm/smt/insert.asm @@ -12,6 +12,12 @@ smt_insert_state_set_root: // stack: retdest JUMP +%macro smt_insert_state + %stack (key, value_ptr) -> (key, value_ptr, %%after) + %jump(smt_insert_state) +%%after: +%endmacro + // Insert a key-value pair in the SMT at `trie_data[node_ptr]`. // `value_ptr` should point to a an empty slot reserved for `rem_key`, followed by the actual value. // Pseudocode: diff --git a/evm/src/cpu/kernel/asm/smt/utils.asm b/evm/src/cpu/kernel/asm/smt/utils.asm index 145f61310a..bc5dd57ee7 100644 --- a/evm/src/cpu/kernel/asm/smt/utils.asm +++ b/evm/src/cpu/kernel/asm/smt/utils.asm @@ -5,3 +5,15 @@ SWAP1 %and_const(1) // stack: key&1, key>>1 %endmacro + +// Returns a non-zero value if the node is non-empty. +%macro is_non_empty_node + // stack: node_ptr + DUP1 %mload_trie_data %jumpi(%%end) // If the node is not a hash node, node_ptr is non-zero. + // The node is a hash node + // stack: node_ptr + %increment %mload_trie_data + // stack: hash + %jump(%%end) +%%end: +%endmacro diff --git a/evm/src/cpu/kernel/asm/transactions/common_decoding.asm b/evm/src/cpu/kernel/asm/transactions/common_decoding.asm index d4df7a6e57..96279b0822 100644 --- a/evm/src/cpu/kernel/asm/transactions/common_decoding.asm +++ b/evm/src/cpu/kernel/asm/transactions/common_decoding.asm @@ -235,17 +235,16 @@ sload_with_addr: %stack (slot, addr) -> (slot, addr, after_storage_read) %slot_to_storage_key // stack: storage_key, addr, after_storage_read - PUSH 64 // storage_key has 64 nibbles - %stack (n64, storage_key, addr, after_storage_read) -> (addr, n64, storage_key, after_storage_read) - %mpt_read_state_trie - // stack: account_ptr, 64, storage_key, after_storage_read + %stack (storage_key, addr, after_storage_read) -> (addr, storage_key, after_storage_read) + %smt_read_state + // stack: account_ptr, storage_key, after_storage_read DUP1 ISZERO %jumpi(ret_zero) // TODO: Fix this. This should never happen. - // stack: account_ptr, 64, storage_key, after_storage_read + // stack: account_ptr, storage_key, after_storage_read %add_const(2) // stack: storage_root_ptr_ptr %mload_trie_data // stack: storage_root_ptr, 64, storage_key, after_storage_read - %jump(mpt_read) + %jump(smt_read) ret_zero: // stack: account_ptr, 64, storage_key, after_storage_read, retdest diff --git a/evm/src/cpu/kernel/tests/smt/delete.rs b/evm/src/cpu/kernel/tests/smt/delete.rs new file mode 100644 index 0000000000..494f1dc8ed --- /dev/null +++ b/evm/src/cpu/kernel/tests/smt/delete.rs @@ -0,0 +1,87 @@ +use anyhow::{anyhow, Result}; +use ethereum_types::{BigEndianHash, H256, U256}; +use rand::{thread_rng, Rng}; +use smt_utils::account::Account; +use smt_utils::smt::Smt; + +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; +use crate::cpu::kernel::interpreter::Interpreter; +use crate::generation::mpt::{all_mpt_prover_inputs_reversed, state_smt_prover_inputs_reversed}; +use crate::generation::TrieInputs; + +#[test] +fn smt_delete() -> Result<()> { + let mut rng = thread_rng(); + let n = rng.gen_range(0..100); + let rand_node = |_| (U256(rng.gen()).into(), Account::rand(10).into()); + let smt = Smt::new((0..n).map(rand_node)).unwrap(); + + let new_account = Account::rand(0); + test_state_smt(smt, U256(rng.gen()), new_account) +} + +fn test_state_smt(smt: Smt, k: U256, account: Account) -> Result<()> { + let trie_inputs = TrieInputs { + state_smt: smt.serialize(), + transactions_trie: Default::default(), + receipts_trie: Default::default(), + storage_tries: vec![], + }; + let load_all_mpts = KERNEL.global_labels["load_all_mpts"]; + let smt_insert_state = KERNEL.global_labels["smt_insert_state"]; + let smt_delete = KERNEL.global_labels["smt_delete"]; + let smt_hash_state = KERNEL.global_labels["smt_hash_state"]; + + let initial_stack = vec![0xDEADBEEFu32.into()]; + let mut interpreter = Interpreter::new_with_kernel(load_all_mpts, initial_stack); + interpreter.generation_state.state_smt_prover_inputs = + state_smt_prover_inputs_reversed(&trie_inputs); + interpreter.generation_state.mpt_prover_inputs = + all_mpt_prover_inputs_reversed(&trie_inputs).map_err(|_| anyhow!("Invalid MPT data"))?; + interpreter.run()?; + assert_eq!(interpreter.stack(), vec![]); + + // Next, execute smt_insert_state. + interpreter.generation_state.registers.program_counter = smt_insert_state; + let trie_data = interpreter.get_trie_data_mut(); + let value_ptr = trie_data.len(); + trie_data.push(U256::zero()); // For the key. + trie_data.push(account.nonce.into()); + trie_data.push(account.balance); + trie_data.push(U256::zero()); // Empty storage root. + trie_data.push(account.code_hash.into_uint()); + let trie_data_len = trie_data.len().into(); + interpreter.set_global_metadata_field(GlobalMetadata::TrieDataSize, trie_data_len); + interpreter.push(0xDEADBEEFu32.into()); + interpreter.push(value_ptr.into()); // value_ptr + interpreter.push(k); // key + interpreter.run()?; + assert_eq!( + interpreter.stack().len(), + 0, + "Expected empty stack after insert, found {:?}", + interpreter.stack() + ); + + // Next, execute smt_delete, deleting the account we just inserted. + let state_trie_ptr = interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot); + interpreter.generation_state.registers.program_counter = smt_delete; + interpreter.push(0xDEADBEEFu32.into()); + interpreter.push(k); + interpreter.push(state_trie_ptr); + interpreter.run()?; + let state_trie_ptr = interpreter.pop(); + interpreter.set_global_metadata_field(GlobalMetadata::StateTrieRoot, state_trie_ptr); + + // Now, execute smt_hash_state. + interpreter.generation_state.registers.program_counter = smt_hash_state; + interpreter.push(0xDEADBEEFu32.into()); + interpreter.run()?; + + let state_smt_hash = H256::from_uint(&interpreter.pop()); + let expected_state_smt_hash = smt.root; + assert_eq!(state_smt_hash, expected_state_smt_hash); + + Ok(()) +} diff --git a/evm/src/cpu/kernel/tests/smt/mod.rs b/evm/src/cpu/kernel/tests/smt/mod.rs index 2d7504cdc5..6a9fd304b2 100644 --- a/evm/src/cpu/kernel/tests/smt/mod.rs +++ b/evm/src/cpu/kernel/tests/smt/mod.rs @@ -1,2 +1,3 @@ +mod delete; mod hash; mod insert; diff --git a/evm/src/generation/mod.rs b/evm/src/generation/mod.rs index c4d19dca01..d3b1b0c7b2 100644 --- a/evm/src/generation/mod.rs +++ b/evm/src/generation/mod.rs @@ -21,7 +21,7 @@ use crate::cpu::bootstrap_kernel::generate_bootstrap_kernel; use crate::cpu::columns::CpuColumnsView; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; -use crate::generation::outputs::{get_outputs, GenerationOutputs}; +use crate::generation::outputs::GenerationOutputs; use crate::generation::state::GenerationState; use crate::memory::segments::Segment; use crate::proof::{BlockHashes, BlockMetadata, ExtraBlockData, PublicValues, TrieRoots}; @@ -255,8 +255,10 @@ pub fn generate_traces, const D: usize>( state.traces.get_lengths() ); - let outputs = get_outputs(&mut state) - .map_err(|err| anyhow!("Failed to generate post-state info: {:?}", err))?; + // TODO: fix this + // let outputs = get_outputs(&mut state) + // .map_err(|err| anyhow!("Failed to generate post-state info: {:?}", err))?; + let outputs = Default::default(); let read_metadata = |field| state.memory.read_global_metadata(field); let trie_roots_before = TrieRoots { diff --git a/evm/src/generation/outputs.rs b/evm/src/generation/outputs.rs index 0ce8708297..ccea75bbf5 100644 --- a/evm/src/generation/outputs.rs +++ b/evm/src/generation/outputs.rs @@ -12,7 +12,7 @@ use crate::util::u256_to_usize; use crate::witness::errors::ProgramError; /// The post-state after trace generation; intended for debugging. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct GenerationOutputs { pub accounts: HashMap, } @@ -31,6 +31,7 @@ pub struct AccountOutput { pub storage: HashMap, } +#[allow(unused)] pub(crate) fn get_outputs( state: &mut GenerationState, ) -> Result { @@ -64,6 +65,7 @@ pub(crate) fn get_outputs( Ok(GenerationOutputs { accounts }) } +#[allow(unused)] fn account_trie_record_to_output( state: &GenerationState, account: AccountTrieRecord, @@ -88,6 +90,7 @@ fn account_trie_record_to_output( }) } +#[allow(unused)] /// Get an account's storage trie, given a pointer to its root. fn get_storage( state: &GenerationState, diff --git a/evm/src/generation/trie_extractor.rs b/evm/src/generation/trie_extractor.rs index 42c50c6d75..dfc9c26f24 100644 --- a/evm/src/generation/trie_extractor.rs +++ b/evm/src/generation/trie_extractor.rs @@ -12,6 +12,7 @@ use crate::witness::errors::ProgramError; use crate::witness::memory::{MemoryAddress, MemoryState}; /// Account data as it's stored in the state trie, with a pointer to the storage trie. +#[allow(unused)] #[derive(Debug)] pub(crate) struct AccountTrieRecord { pub(crate) nonce: u64, @@ -20,6 +21,7 @@ pub(crate) struct AccountTrieRecord { pub(crate) code_hash: H256, } +#[allow(unused)] pub(crate) fn read_state_trie_value(slice: &[U256]) -> Result { Ok(AccountTrieRecord { nonce: slice[0].low_u64(), @@ -29,6 +31,7 @@ pub(crate) fn read_state_trie_value(slice: &[U256]) -> Result U256 { slice[0] }