From c76e7eb471241cc17b2d6e61b182755bdad22434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20P=C3=A9cseli?= Date: Fri, 25 Aug 2023 16:10:36 +0100 Subject: [PATCH] EVM on WASM: Refund unused gas --- src/kernel_evm/CHANGES.md | 1 + src/kernel_evm/evm_execution/src/handler.rs | 25 +++++++++++++++++++++ src/kernel_evm/evm_execution/src/lib.rs | 11 ++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/kernel_evm/CHANGES.md b/src/kernel_evm/CHANGES.md index 50dcb3d1e3a0..f677afcf9b6c 100644 --- a/src/kernel_evm/CHANGES.md +++ b/src/kernel_evm/CHANGES.md @@ -14,6 +14,7 @@ - Adds a new type of message in simulation mode, to verify that a transaction is valid by checking if the nonce is neither too low nor too high. (!9679) - Simulate if a transaction has a correct chain id. (!9752) - Fees are now paid by the sender. (!9480) +- Unused gas is refunded after succesful transactions. (!9915) ### EVM Node diff --git a/src/kernel_evm/evm_execution/src/handler.rs b/src/kernel_evm/evm_execution/src/handler.rs index f5d7993c9213..2264a5cc5bf1 100644 --- a/src/kernel_evm/evm_execution/src/handler.rs +++ b/src/kernel_evm/evm_execution/src/handler.rs @@ -273,6 +273,31 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { } } + /// Repay unused gas + pub fn repay_gas( + &mut self, + caller: H160, + unused_gas: Option, + ) -> Result<(), EthereumError> { + match unused_gas { + Some(unused_gas) => { + let amount = U256::from(unused_gas) * self.block.gas_price; + + debug_msg!( + self.host, + "{:?} refunded {:?} for transaction", + caller, + amount + ); + + self.get_or_create_account(caller)? + .balance_add(self.host, amount) + .map_err(EthereumError::from) + } + None => Ok(()), + } + } + /// Execute a SputnikVM runtime with this handler fn execute( &mut self, diff --git a/src/kernel_evm/evm_execution/src/lib.rs b/src/kernel_evm/evm_execution/src/lib.rs index 5cc54c9bc002..62463cb8bf1c 100644 --- a/src/kernel_evm/evm_execution/src/lib.rs +++ b/src/kernel_evm/evm_execution/src/lib.rs @@ -162,6 +162,11 @@ where handler.increment_nonce(caller)?; + if result.is_success { + let unused_gas = gas_limit.map(|gl| gl - result.gas_used); + handler.repay_gas(caller, unused_gas)?; + } + Ok(Some(result)) } else { // caller was unable to pay for the gas limit @@ -1624,9 +1629,13 @@ mod test { .unwrap(), None ); + + let funds_total = + 1_000_000 + all_the_gas - expected_result.unwrap().unwrap().gas_used; + assert_eq!( get_balance(&mut mock_runtime, &mut evm_account_storage, &caller), - 1_000_000.into() + funds_total.into() ); } -- GitLab