diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 980f033024d6a32b567ec22ea226244626c65fbc..730a983a43818dfd89a9b698ac6209bb0c93e0cc 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -81,8 +81,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 225, - impl_version: 1, + spec_version: 226, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/substrate/frame/contracts/src/gas.rs b/substrate/frame/contracts/src/gas.rs index c8572daaa43d487efd84725b26a6492beaa63794..362f15f3aae795ef44b346285de79cd557291a23 100644 --- a/substrate/frame/contracts/src/gas.rs +++ b/substrate/frame/contracts/src/gas.rs @@ -250,7 +250,11 @@ pub fn refund_unused_gas<T: Trait>( pub fn approx_gas_for_balance<Balance>(gas_price: Balance, balance: Balance) -> Gas where Balance: AtLeast32Bit { - (balance / gas_price).saturated_into::<Gas>() + if gas_price.is_zero() { + Zero::zero() + } else { + (balance / gas_price).saturated_into::<Gas>() + } } /// A simple utility macro that helps to match against a @@ -294,7 +298,7 @@ macro_rules! match_tokens { #[cfg(test)] mod tests { use super::{GasMeter, Token}; - use crate::tests::Test; + use crate::{tests::Test, gas::approx_gas_for_balance}; /// A trivial token that charges the specified number of gas units. #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -382,4 +386,22 @@ mod tests { let mut gas_meter = GasMeter::<Test>::with_limit(25, 10); assert!(!gas_meter.charge(&(), SimpleToken(25)).is_out_of_gas()); } + + // A unit test for `fn approx_gas_for_balance()`, and makes + // sure setting gas_price 0 does not cause `div by zero` error. + #[test] + fn approx_gas_for_balance_works() { + let tests = vec![ + (approx_gas_for_balance(0_u64, 123), 0), + (approx_gas_for_balance(0_u64, 456), 0), + (approx_gas_for_balance(1_u64, 123), 123), + (approx_gas_for_balance(1_u64, 456), 456), + (approx_gas_for_balance(100_u64, 900), 9), + (approx_gas_for_balance(123_u64, 900), 7), + ]; + + for (lhs, rhs) in tests { + assert_eq!(lhs, rhs); + } + } } diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index e775998a3a55331443d37fad3cad78275e7f0527..51da3e8d1ff97ee0048290d073ac53e6e10f291f 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -2079,6 +2079,22 @@ fn deploy_and_call_other_contract() { }); } +#[test] +fn deploy_works_without_gas_price() { + let (wasm, code_hash) = compile_module::<Test>(CODE_GET_RUNTIME_STORAGE).unwrap(); + ExtBuilder::default().existential_deposit(50).gas_price(0).build().execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 100, + 100_000, + code_hash.into(), + vec![], + )); + }); +} + const CODE_SELF_DESTRUCT: &str = r#" (module (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32)))