diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 02fc48af..402048d4 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -144,6 +144,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/journal/storage_change.asm"), include_str!("asm/journal/storage_loaded.asm"), include_str!("asm/journal/code_change.asm"), + include_str!("asm/journal/refund.asm"), include_str!("asm/journal/revert.asm"), include_str!("asm/transactions/common_decoding.asm"), include_str!("asm/transactions/router.asm"), diff --git a/evm/src/cpu/kernel/asm/core/call.asm b/evm/src/cpu/kernel/asm/core/call.asm index 1acb715b..6176674a 100644 --- a/evm/src/cpu/kernel/asm/core/call.asm +++ b/evm/src/cpu/kernel/asm/core/call.asm @@ -11,8 +11,6 @@ global sys_call: MUL // Cheaper than AND %jumpi(fault_exception) - %checkpoint // Checkpoint - %stack (kexit_info, gas, address, value, args_offset, args_size, ret_offset, ret_size) -> (args_size, args_offset, kexit_info, gas, address, value, args_offset, args_size, ret_offset, ret_size) %checked_mem_expansion @@ -23,8 +21,9 @@ global sys_call: SWAP2 // stack: address, gas, kexit_info, value, args_offset, args_size, ret_offset, ret_size %u256_to_addr // Truncate to 160 bits - DUP1 %insert_touched_addresses DUP1 %insert_accessed_addresses + %checkpoint // Checkpoint + DUP1 %insert_touched_addresses %call_charge_gas(1, 1) @@ -59,7 +58,6 @@ global sys_call: // Creates a new sub context as if calling itself, but with the code of the // given account. In particular the storage remains the same. global sys_callcode: - %checkpoint // Checkpoint // stack: kexit_info, gas, address, value, args_offset, args_size, ret_offset, ret_size %stack (kexit_info, gas, address, value, args_offset, args_size, ret_offset, ret_size) -> @@ -73,6 +71,7 @@ global sys_callcode: // stack: address, gas, kexit_info, value, args_offset, args_size, ret_offset, ret_size %u256_to_addr // Truncate to 160 bits DUP1 %insert_accessed_addresses + %checkpoint // Checkpoint %call_charge_gas(1, 0) @@ -111,8 +110,6 @@ global sys_callcode: // are CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT and // CALL if the value sent is not 0. global sys_staticcall: - %checkpoint // Checkpoint - // stack: kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size %stack (kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size) -> (args_size, args_offset, kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size) @@ -124,8 +121,9 @@ global sys_staticcall: SWAP2 // stack: address, gas, kexit_info, args_offset, args_size, ret_offset, ret_size %u256_to_addr // Truncate to 160 bits - DUP1 %insert_touched_addresses DUP1 %insert_accessed_addresses + %checkpoint // Checkpoint + DUP1 %insert_touched_addresses // Add a value of 0 to the stack. Slightly inefficient but that way we can reuse %call_charge_gas. %stack (cold_access, address, gas, kexit_info) -> (cold_access, address, gas, kexit_info, 0) @@ -162,7 +160,6 @@ global sys_staticcall: // given account. In particular the storage, the current sender and the current // value remain the same. global sys_delegatecall: - %checkpoint // Checkpoint // stack: kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size %stack (kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size) -> @@ -176,6 +173,7 @@ global sys_delegatecall: // stack: address, gas, kexit_info, args_offset, args_size, ret_offset, ret_size %u256_to_addr // Truncate to 160 bits DUP1 %insert_accessed_addresses + %checkpoint // Checkpoint // Add a value of 0 to the stack. Slightly inefficient but that way we can reuse %call_charge_gas. %stack (cold_access, address, gas, kexit_info) -> (cold_access, address, gas, kexit_info, 0) diff --git a/evm/src/cpu/kernel/asm/core/gas.asm b/evm/src/cpu/kernel/asm/core/gas.asm index 436ccb3e..d5e4e9bb 100644 --- a/evm/src/cpu/kernel/asm/core/gas.asm +++ b/evm/src/cpu/kernel/asm/core/gas.asm @@ -28,6 +28,7 @@ global refund_gas_hook: %macro refund_gas_original // stack: amount + DUP1 %journal_refund %mload_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER) ADD %mstore_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER) diff --git a/evm/src/cpu/kernel/asm/core/process_txn.asm b/evm/src/cpu/kernel/asm/core/process_txn.asm index 8431e502..a935a783 100644 --- a/evm/src/cpu/kernel/asm/core/process_txn.asm +++ b/evm/src/cpu/kernel/asm/core/process_txn.asm @@ -173,7 +173,6 @@ global process_contract_creation_txn_after_constructor: // stack: leftover_gas, new_ctx, address, retdest %pay_coinbase_and_refund_sender - // TODO: Delete accounts in self-destruct list and empty touched addresses. %delete_all_touched_addresses %delete_all_selfdestructed_addresses // stack: new_ctx, address, retdest @@ -264,16 +263,26 @@ process_message_txn_code_loaded_finish: global process_message_txn_after_call: // stack: success, leftover_gas, new_ctx, retdest - POP // TODO: Success will go into the receipt when we support that. + DUP1 POP // TODO: Success will go into the receipt when we support that. + ISZERO %jumpi(process_message_txn_fail) +process_message_txn_after_call_contd: // stack: leftover_gas, new_ctx, retdest %pay_coinbase_and_refund_sender - // TODO: Delete accounts in self-destruct list and empty touched addresses. %delete_all_touched_addresses %delete_all_selfdestructed_addresses // stack: new_ctx, retdest POP JUMP +process_message_txn_fail: + // stack: leftover_gas, new_ctx, retdest + // Transfer value back to the caller. + %mload_txn_field(@TXN_FIELD_VALUE) + %mload_txn_field(@TXN_FIELD_ORIGIN) + %mload_txn_field(@TXN_FIELD_TO) + %transfer_eth %jumpi(panic) + %jump(process_message_txn_after_call_contd) + %macro pay_coinbase_and_refund_sender // stack: leftover_gas DUP1 diff --git a/evm/src/cpu/kernel/asm/journal/code_change.asm b/evm/src/cpu/kernel/asm/journal/code_change.asm index 725a2ab8..5bb637c7 100644 --- a/evm/src/cpu/kernel/asm/journal/code_change.asm +++ b/evm/src/cpu/kernel/asm/journal/code_change.asm @@ -5,7 +5,8 @@ %endmacro global revert_code_change: - // stack: ptr, retdest + // stack: entry_ptr, ptr, retdest + POP %journal_load_2 // stack: address, prev_codehash, retdest %mpt_read_state_trie diff --git a/evm/src/cpu/kernel/asm/journal/refund.asm b/evm/src/cpu/kernel/asm/journal/refund.asm new file mode 100644 index 00000000..b0e34cc6 --- /dev/null +++ b/evm/src/cpu/kernel/asm/journal/refund.asm @@ -0,0 +1,15 @@ +// struct Refund { amount } + +%macro journal_refund + %journal_add_1(@JOURNAL_ENTRY_REFUND) +%endmacro + +global revert_refund: + // stack: entry_type, ptr, retdest + POP + %journal_load_1 + // stack: amount, retdest + %mload_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER) + SUB + %mstore_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER) + JUMP diff --git a/evm/src/cpu/kernel/asm/journal/revert.asm b/evm/src/cpu/kernel/asm/journal/revert.asm index 143f51ba..cc7bcc7c 100644 --- a/evm/src/cpu/kernel/asm/journal/revert.asm +++ b/evm/src/cpu/kernel/asm/journal/revert.asm @@ -13,7 +13,8 @@ DUP1 %eq_const(@JOURNAL_ENTRY_NONCE_CHANGE) %jumpi(revert_nonce_change) DUP1 %eq_const(@JOURNAL_ENTRY_STORAGE_CHANGE) %jumpi(revert_storage_change) DUP1 %eq_const(@JOURNAL_ENTRY_STORAGE_LOADED) %jumpi(revert_storage_loaded) - %eq_const(@JOURNAL_ENTRY_CODE_CHANGE) %jumpi(revert_code_change) + DUP1 %eq_const(@JOURNAL_ENTRY_CODE_CHANGE) %jumpi(revert_code_change) + DUP1 %eq_const(@JOURNAL_ENTRY_REFUND) %jumpi(revert_refund) PANIC // This should never happen. %%after: // stack: journal_size-1 diff --git a/evm/src/cpu/kernel/asm/journal/storage_change.asm b/evm/src/cpu/kernel/asm/journal/storage_change.asm index 6f34e7f3..99b59472 100644 --- a/evm/src/cpu/kernel/asm/journal/storage_change.asm +++ b/evm/src/cpu/kernel/asm/journal/storage_change.asm @@ -21,8 +21,10 @@ global revert_storage_change: %add_const(2) // stack: storage_root_ptr_ptr, 64, storage_key, address, prev_value, retdest %mload_trie_data - %stack (storage_root_ptr, num_nibbles, storage_key, address, prev_value, retdest) -> - (storage_root_ptr, num_nibbles, storage_key, prev_value, new_storage_root, address, retdest) + %get_trie_data_size + DUP6 %append_to_trie_data + %stack (prev_value_ptr, storage_root_ptr, num_nibbles, storage_key, address, prev_value, retdest) -> + (storage_root_ptr, num_nibbles, storage_key, prev_value_ptr, new_storage_root, address, retdest) %jump(mpt_insert) delete: diff --git a/evm/src/cpu/kernel/constants/journal_entry.rs b/evm/src/cpu/kernel/constants/journal_entry.rs index 39d06fe9..3b6190ae 100644 --- a/evm/src/cpu/kernel/constants/journal_entry.rs +++ b/evm/src/cpu/kernel/constants/journal_entry.rs @@ -9,10 +9,11 @@ pub(crate) enum JournalEntry { StorageChange = 5, StorageLoaded = 6, CodeChange = 7, + Refund = 8, } impl JournalEntry { - pub(crate) const COUNT: usize = 8; + pub(crate) const COUNT: usize = 9; pub(crate) fn all() -> [Self; Self::COUNT] { [ @@ -24,6 +25,7 @@ impl JournalEntry { Self::StorageChange, Self::StorageLoaded, Self::CodeChange, + Self::Refund, ] } @@ -38,6 +40,7 @@ impl JournalEntry { Self::StorageChange => "JOURNAL_ENTRY_STORAGE_CHANGE", Self::StorageLoaded => "JOURNAL_ENTRY_STORAGE_LOADED", Self::CodeChange => "JOURNAL_ENTRY_CODE_CHANGE", + Self::Refund => "JOURNAL_ENTRY_REFUND", } } }