diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs
index a65386d396..ba0471c233 100644
--- a/frame/contracts/src/gas.rs
+++ b/frame/contracts/src/gas.rs
@@ -14,14 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
-use crate::{GasSpent, Module, Trait, BalanceOf};
+use crate::{Module, Trait, BalanceOf};
use sp_std::convert::TryFrom;
use sp_runtime::traits::{
CheckedMul, Zero, SaturatedConversion, AtLeast32Bit, UniqueSaturatedInto,
};
use frame_support::{
- traits::{Currency, ExistenceRequirement, OnUnbalanced, WithdrawReason}, StorageValue,
- dispatch::DispatchError,
+ traits::{Currency, ExistenceRequirement, OnUnbalanced, WithdrawReason}, dispatch::DispatchError,
};
#[cfg(test)]
@@ -257,14 +256,8 @@ pub fn refund_unused_gas(
transactor: &T::AccountId,
gas_meter: GasMeter,
) {
- let gas_spent = gas_meter.spent();
let gas_left = gas_meter.gas_left();
- // Increase total spent gas.
- // This cannot overflow, since `gas_spent` is never greater than `block_gas_limit`, which
- // also has Gas type.
- GasSpent::mutate(|block_gas_spent| *block_gas_spent += gas_spent);
-
// Refund gas left by the price it was bought at.
let refund = gas_meter.gas_price * gas_left.unique_saturated_into();
let _imbalance = T::Currency::deposit_creating(transactor, refund);
diff --git a/frame/contracts/src/gas_tests.rs b/frame/contracts/src/gas_tests.rs
index dc6d0fa8bb..32c5e1e8e2 100644
--- a/frame/contracts/src/gas_tests.rs
+++ b/frame/contracts/src/gas_tests.rs
@@ -262,6 +262,24 @@ impl GasHandler for TestGasHandler {
}
}
+pub struct NoChargeGasHandler;
+impl GasHandler for NoChargeGasHandler {
+ fn fill_gas(
+ _transactor: &::AccountId,
+ gas_limit: Gas,
+ ) -> Result, DispatchError> {
+ // fills the gas meter without charging the user
+ Ok(GasMeter::with_limit(gas_limit, 1))
+ }
+
+ fn empty_unused_gas(
+ transactor: &::AccountId,
+ gas_meter: GasMeter,
+ ) {
+ // Do not charge the transactor. Give gas for free.
+ }
+}
+
#[test]
// Tests that the user is not charged when filling up gas meters
fn customized_fill_gas_does_not_charge_the_user() {
@@ -273,9 +291,11 @@ fn customized_fill_gas_does_not_charge_the_user() {
// Create test account
Balances::deposit_creating(&ALICE, 1000);
- // fill gas
- let gas_meter_result = TestGasHandler::fill_gas(&ALICE, 500);
- assert!(gas_meter_result.is_ok());
+ let gas_limit = 500;
+ let mut gas_meter = NoChargeGasHandler::fill_gas(&ALICE, gas_limit).unwrap();
+ // Charge as if the whole gas_limit is used
+ gas_meter.charge(&(), SimpleToken(gas_limit));
+ NoChargeGasHandler::empty_unused_gas(&ALICE, gas_meter);
// Check the user is not charged
assert_eq!(Balances::free_balance(&ALICE), 1000);
diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs
index a6587d8b36..b897fe1b85 100644
--- a/frame/contracts/src/lib.rs
+++ b/frame/contracts/src/lib.rs
@@ -588,6 +588,11 @@ decl_module! {
if let Ok(code_hash) = result {
Self::deposit_event(RawEvent::CodeStored(code_hash));
}
+ // Increase total spent gas.
+ // This cannot overflow, since `gas_spent` is never greater than `block_gas_limit`, which
+ // also has Gas type.
+ GasSpent::mutate(|block_gas_spent| *block_gas_spent += gas_meter.spent());
+
T::GasHandler::empty_unused_gas(&origin, gas_meter);
result.map(|_| ()).map_err(Into::into)
@@ -752,6 +757,11 @@ impl Module {
DirectAccountDb.commit(ctx.overlay.into_change_set());
}
+ // Increase total spent gas.
+ // This cannot overflow, since `gas_spent` is never greater than `block_gas_limit`, which
+ // also has Gas type.
+ GasSpent::mutate(|block_gas_spent| *block_gas_spent += gas_meter.spent());
+
// Handle unused gas of the gas meter. Default behaviour is to refund cost of the unused gas.
//
// NOTE: This should go after the commit to the storage, since the storage changes