From ff57bb18e143b2d9197c30738a65b97109cc40d9 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 25 Jun 2020 11:50:19 +0100 Subject: [PATCH 01/10] add gas argument --- core/src/env/engine/on_chain/ext.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/env/engine/on_chain/ext.rs b/core/src/env/engine/on_chain/ext.rs index 72f308bc869..53797bc6947 100644 --- a/core/src/env/engine/on_chain/ext.rs +++ b/core/src/env/engine/on_chain/ext.rs @@ -89,7 +89,7 @@ mod sys { pub fn ext_block_number(); pub fn ext_address(); pub fn ext_balance(); - pub fn ext_gas_price(); + pub fn ext_gas_price(gas: u64); pub fn ext_gas_left(); pub fn ext_value_transferred(); pub fn ext_now(); From 3f829b15a1b005f034f954562f780132911f2cd4 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 25 Jun 2020 14:56:13 +0100 Subject: [PATCH 02/10] Add gas parameter to ext_gas_price --- core/src/env/api.rs | 6 +++--- core/src/env/backend.rs | 4 ++-- core/src/env/engine/on_chain/ext.rs | 5 ++++- core/src/env/engine/on_chain/impls.rs | 9 +++++---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/core/src/env/api.rs b/core/src/env/api.rs index 3e1c46f035b..3ea53596ed0 100644 --- a/core/src/env/api.rs +++ b/core/src/env/api.rs @@ -60,17 +60,17 @@ where }) } -/// Returns the current price for gas. +/// Returns the price for the specified amount of weight. /// /// # Errors /// /// If the returned value cannot be properly decoded. -pub fn gas_price() -> Result +pub fn gas_price(gas: u64) -> Result where T: EnvTypes, { ::on_instance(|instance| { - TypedEnv::gas_price::(instance) + TypedEnv::gas_price::(instance, gas) }) } diff --git a/core/src/env/backend.rs b/core/src/env/backend.rs index a9b11f290ea..1722b66729e 100644 --- a/core/src/env/backend.rs +++ b/core/src/env/backend.rs @@ -126,12 +126,12 @@ pub trait TypedEnv: Env { /// For more details visit: [`ink_core::env::transferred_balance`] fn transferred_balance(&mut self) -> Result; - /// Returns the current price for gas. + /// Returns the price for the specified amount of weight. /// /// # Note /// /// For more details visit: [`ink_core::env::gas_price`] - fn gas_price(&mut self) -> Result; + fn gas_price(&mut self, gas: u64) -> Result; /// Returns the amount of gas left for the contract execution. /// diff --git a/core/src/env/engine/on_chain/ext.rs b/core/src/env/engine/on_chain/ext.rs index 53797bc6947..98a27d84f6c 100644 --- a/core/src/env/engine/on_chain/ext.rs +++ b/core/src/env/engine/on_chain/ext.rs @@ -285,7 +285,6 @@ impl_ext_wrapper_for! { (block_number => ext_block_number), (address => ext_address), (balance => ext_balance), - (gas_price => ext_gas_price), (gas_left => ext_gas_left), (value_transferred => ext_value_transferred), (now => ext_now), @@ -294,6 +293,10 @@ impl_ext_wrapper_for! { (tombstone_deposit => ext_tombstone_deposit), } +pub fn gas_price(gas: u64) { + unsafe { sys::ext_gas_price(gas) } +} + pub fn set_rent_allowance(value: &[u8]) { unsafe { sys::ext_set_rent_allowance(value.as_ptr() as u32, value.len() as u32) } } diff --git a/core/src/env/engine/on_chain/impls.rs b/core/src/env/engine/on_chain/impls.rs index 40c8768385c..ea09bec3275 100644 --- a/core/src/env/engine/on_chain/impls.rs +++ b/core/src/env/engine/on_chain/impls.rs @@ -208,10 +208,6 @@ impl TypedEnv for EnvInstance { self.get_property::(ext::value_transferred) } - fn gas_price(&mut self) -> Result { - self.get_property::(ext::gas_price) - } - fn gas_left(&mut self) -> Result { self.get_property::(ext::gas_left) } @@ -380,6 +376,11 @@ impl TypedEnv for EnvInstance { ext::transfer(destination, value) } + fn gas_price(&mut self, gas: u64) -> Result { + ext::gas_price(gas); + self.decode_scratch_buffer().map_err(Into::into) + } + fn random(&mut self, subject: &[u8]) -> Result where T: EnvTypes, From f9d56d1236b6cb5e8b250854d9b1095cdaa54f7e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 26 Jun 2020 12:27:42 +0100 Subject: [PATCH 03/10] Fix up gas_price offchain api --- core/src/env/engine/off_chain/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/env/engine/off_chain/impls.rs b/core/src/env/engine/off_chain/impls.rs index 23af67d2bf4..7be7c833162 100644 --- a/core/src/env/engine/off_chain/impls.rs +++ b/core/src/env/engine/off_chain/impls.rs @@ -153,7 +153,7 @@ impl TypedEnv for EnvInstance { .map_err(Into::into) } - fn gas_price(&mut self) -> Result { + fn gas_price(&mut self, _gas: u64) -> Result { self.chain_spec .gas_price::() .map_err(|_| scale::Error::from("could not decode gas price")) From 9b5c99cc857468c87aa2574d8b96d8742feacb5c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 26 Jun 2020 12:38:06 +0100 Subject: [PATCH 04/10] Fix up env_access api --- core/src/env/api.rs | 2 +- core/src/env/backend.rs | 2 +- lang/src/env_access.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/env/api.rs b/core/src/env/api.rs index 3ea53596ed0..5e0f73c8b21 100644 --- a/core/src/env/api.rs +++ b/core/src/env/api.rs @@ -60,7 +60,7 @@ where }) } -/// Returns the price for the specified amount of weight. +/// Returns the price for the specified amount of gas. /// /// # Errors /// diff --git a/core/src/env/backend.rs b/core/src/env/backend.rs index 1722b66729e..54599365528 100644 --- a/core/src/env/backend.rs +++ b/core/src/env/backend.rs @@ -126,7 +126,7 @@ pub trait TypedEnv: Env { /// For more details visit: [`ink_core::env::transferred_balance`] fn transferred_balance(&mut self) -> Result; - /// Returns the price for the specified amount of weight. + /// Returns the price for the specified amount of gas. /// /// # Note /// diff --git a/lang/src/env_access.rs b/lang/src/env_access.rs index 68600fc3c41..2e9793d46c0 100644 --- a/lang/src/env_access.rs +++ b/lang/src/env_access.rs @@ -104,13 +104,13 @@ where env::transferred_balance::().expect("couldn't decode transferred balance") } - /// Returns the current price for gas. + /// Returns the price for the specified amount of gas. /// /// # Note /// /// For more details visit: [`ink_core::env::gas_price`] - pub fn gas_price(self) -> T::Balance { - env::gas_price::().expect("couldn't decode gas price") + pub fn gas_price(self, gas: u64) -> T::Balance { + env::gas_price::(gas).expect("couldn't decode gas price") } /// Returns the amount of gas left for the contract execution. From 6a883531d6835be05031e742e00ef138af21853b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 30 Jun 2020 07:54:03 +0100 Subject: [PATCH 05/10] Emulate gas price calculation --- core/src/env/engine/off_chain/impls.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/core/src/env/engine/off_chain/impls.rs b/core/src/env/engine/off_chain/impls.rs index 7be7c833162..fe56922c646 100644 --- a/core/src/env/engine/off_chain/impls.rs +++ b/core/src/env/engine/off_chain/impls.rs @@ -31,6 +31,7 @@ use crate::env::{ TypedEnv, }; use ink_primitives::Key; +use core::convert::TryFrom; impl EnvInstance { /// Returns the callee account. @@ -153,11 +154,18 @@ impl TypedEnv for EnvInstance { .map_err(Into::into) } - fn gas_price(&mut self, _gas: u64) -> Result { - self.chain_spec + /// Emulates gas price calculation, scaling price linearly up to `u32::max_value()`. + /// + /// # Panics + /// + /// If the resulting gas price overflows `u32::max_value()` + fn gas_price(&mut self, gas: u64) -> Result { + let gas_price = self.chain_spec .gas_price::() - .map_err(|_| scale::Error::from("could not decode gas price")) - .map_err(Into::into) + .map_err(|_| scale::Error::from("could not decode gas price"))?; + + let gas = u32::try_from(gas).unwrap_or(u32::max_value().into()); + Ok(T::Balance::from(gas) * gas_price) } fn gas_left(&mut self) -> Result { From c1c22b465a6f577c8fc8be1bea8b423eb0c13e14 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 30 Jun 2020 08:12:39 +0100 Subject: [PATCH 06/10] Make clippy happy --- core/src/env/engine/off_chain/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/env/engine/off_chain/impls.rs b/core/src/env/engine/off_chain/impls.rs index fe56922c646..36e58b6348f 100644 --- a/core/src/env/engine/off_chain/impls.rs +++ b/core/src/env/engine/off_chain/impls.rs @@ -164,7 +164,7 @@ impl TypedEnv for EnvInstance { .gas_price::() .map_err(|_| scale::Error::from("could not decode gas price"))?; - let gas = u32::try_from(gas).unwrap_or(u32::max_value().into()); + let gas = u32::try_from(gas).unwrap_or_else(|_| { u32::max_value() }); Ok(T::Balance::from(gas) * gas_price) } From 787aa151fcd559aef135c6df859f6fcab12d73a1 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 30 Jun 2020 13:59:21 +0100 Subject: [PATCH 07/10] Use Saturating impl for emulating gas price calculation offchain --- core/src/env/arithmetic.rs | 40 +++++++++++++++++--------- core/src/env/engine/off_chain/impls.rs | 14 ++++----- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/core/src/env/arithmetic.rs b/core/src/env/arithmetic.rs index 14c43b10826..5f949717d8a 100644 --- a/core/src/env/arithmetic.rs +++ b/core/src/env/arithmetic.rs @@ -24,6 +24,10 @@ use core::ops::{ Sub, SubAssign, }; +use core::convert::{ + TryFrom, + TryInto, +}; use num_traits::{ checked_pow, Bounded, @@ -40,7 +44,7 @@ use num_traits::{ /// if needed. pub trait BaseArithmetic: Sized - + From + + From + Bounded + Ord + PartialOrd @@ -57,21 +61,19 @@ pub trait BaseArithmetic: + DivAssign + CheckedMul + Saturating + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryInto + + TryInto + + TryInto + + TryInto + + TryInto // Further trait bounds from the original BaseArithmetic trait // that we could use to extend ink!'s BaseArithmetic trait. // -// From + -// From + -// From + -// TryFrom + -// TryFrom + -// TryFrom + -// TryInto + -// TryInto + -// TryInto + -// TryInto + -// TryInto + -// TryInto + // UniqueSaturatedInto + // UniqueSaturatedInto + // UniqueSaturatedInto + @@ -92,7 +94,7 @@ pub trait BaseArithmetic: impl BaseArithmetic for T where T: Sized - + From + + From + Bounded + Ord + PartialOrd @@ -108,6 +110,16 @@ impl BaseArithmetic for T where + DivAssign + CheckedMul + Saturating + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryInto + + TryInto + + TryInto + + TryInto + + TryInto { } diff --git a/core/src/env/engine/off_chain/impls.rs b/core/src/env/engine/off_chain/impls.rs index 36e58b6348f..df41adea4fa 100644 --- a/core/src/env/engine/off_chain/impls.rs +++ b/core/src/env/engine/off_chain/impls.rs @@ -31,7 +31,8 @@ use crate::env::{ TypedEnv, }; use ink_primitives::Key; -use core::convert::TryFrom; +use core::convert::TryInto; +use num_traits::Bounded; impl EnvInstance { /// Returns the callee account. @@ -154,18 +155,15 @@ impl TypedEnv for EnvInstance { .map_err(Into::into) } - /// Emulates gas price calculation, scaling price linearly up to `u32::max_value()`. - /// - /// # Panics - /// - /// If the resulting gas price overflows `u32::max_value()` + /// Emulates gas price calculation fn gas_price(&mut self, gas: u64) -> Result { + use crate::env::arithmetic::Saturating as _; + let gas_price = self.chain_spec .gas_price::() .map_err(|_| scale::Error::from("could not decode gas price"))?; - let gas = u32::try_from(gas).unwrap_or_else(|_| { u32::max_value() }); - Ok(T::Balance::from(gas) * gas_price) + Ok(gas_price.saturating_mul(gas.try_into().unwrap_or_else(|_| Bounded::max_value()))) } fn gas_left(&mut self) -> Result { From d216d11b79b1768a5495a3ef2152812bb563a0af Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 30 Jun 2020 14:01:45 +0100 Subject: [PATCH 08/10] Fmt --- core/src/env/arithmetic.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/core/src/env/arithmetic.rs b/core/src/env/arithmetic.rs index 5f949717d8a..75629af84b6 100644 --- a/core/src/env/arithmetic.rs +++ b/core/src/env/arithmetic.rs @@ -14,19 +14,21 @@ //! Primitive traits for runtime arithmetic, copied from substrate -use core::ops::{ - Add, - AddAssign, - Div, - DivAssign, - Mul, - MulAssign, - Sub, - SubAssign, -}; -use core::convert::{ - TryFrom, - TryInto, +use core::{ + convert::{ + TryFrom, + TryInto, + }, + ops::{ + Add, + AddAssign, + Div, + DivAssign, + Mul, + MulAssign, + Sub, + SubAssign, + }, }; use num_traits::{ checked_pow, From a6668b7b5528a885801f5a86b4a6291b051f345f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 2 Jul 2020 12:44:15 +0100 Subject: [PATCH 09/10] Add offchain gas_price test --- core/src/env/engine/off_chain/db/chain_spec.rs | 8 ++++++++ core/src/env/engine/off_chain/mod.rs | 4 ++++ core/src/env/engine/off_chain/test_api.rs | 11 +++++++++++ core/src/env/engine/off_chain/tests.rs | 16 ++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/core/src/env/engine/off_chain/db/chain_spec.rs b/core/src/env/engine/off_chain/db/chain_spec.rs index aa5315d74c0..731f2f18ea0 100644 --- a/core/src/env/engine/off_chain/db/chain_spec.rs +++ b/core/src/env/engine/off_chain/db/chain_spec.rs @@ -75,6 +75,14 @@ impl ChainSpec { self.gas_price.decode().map_err(Into::into) } + /// Set the gas price for the chain. + pub fn set_gas_price(&mut self, gas_price: T::Balance) + where + T: EnvTypes + { + self.gas_price = OffBalance::new(&gas_price) + } + /// Returns the minimum balance for an account on the chain. pub fn minimum_balance(&self) -> Result where diff --git a/core/src/env/engine/off_chain/mod.rs b/core/src/env/engine/off_chain/mod.rs index 7f586220b87..21013eee161 100644 --- a/core/src/env/engine/off_chain/mod.rs +++ b/core/src/env/engine/off_chain/mod.rs @@ -254,6 +254,10 @@ impl EnvInstance { .last_mut() .ok_or_else(|| OffChainError::UninitializedBlocks) } + + fn chain_spec_mut(&mut self) -> &mut ChainSpec { + &mut self.chain_spec + } } impl OnInstance for EnvInstance { diff --git a/core/src/env/engine/off_chain/test_api.rs b/core/src/env/engine/off_chain/test_api.rs index a8427251e48..fe69084ca33 100644 --- a/core/src/env/engine/off_chain/test_api.rs +++ b/core/src/env/engine/off_chain/test_api.rs @@ -25,6 +25,7 @@ use super::{ use crate::env::{ EnvTypes, Result, + engine::off_chain::db::ChainSpec, }; use ink_prelude::string::String; @@ -210,6 +211,16 @@ where .map_err(Into::into) } +/// Update the [ChainSpec](`crate::env::engine::off_chain::db::ChainSpec`) for the test environment +pub fn update_chain_spec(f: F) -> Result<()> +where + F: FnOnce(&mut ChainSpec) -> () +{ + Ok(::on_instance(|instance| { + f(instance.chain_spec_mut()) + })) +} + /// Returns the contents of the past performed environmental `println` in order. pub fn recorded_printlns() -> impl Iterator { ::on_instance(|instance| { diff --git a/core/src/env/engine/off_chain/tests.rs b/core/src/env/engine/off_chain/tests.rs index 48b2c39d508..f3979b24592 100644 --- a/core/src/env/engine/off_chain/tests.rs +++ b/core/src/env/engine/off_chain/tests.rs @@ -68,3 +68,19 @@ fn key_add_sub() -> Result<()> { Ok(()) }) } + +#[test] +fn gas_price() -> env::Result<()> { + env::test::run_test::(|_| { + let gas_price= 2u32; + env::test::update_chain_spec(|chain_spec| { + chain_spec.set_gas_price::(gas_price.into()) + })?; + + assert_eq!(2u128, env::gas_price::(1).unwrap()); + assert_eq!(20u128, env::gas_price::(10).unwrap()); + assert_eq!(6u128, env::gas_price::(3).unwrap()); + + Ok(()) + }) +} From d8a7e98e05c6933bf4e21b20005497227aadd8ba Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 2 Jul 2020 13:28:41 +0100 Subject: [PATCH 10/10] Make clippy happy --- core/src/env/engine/off_chain/test_api.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/env/engine/off_chain/test_api.rs b/core/src/env/engine/off_chain/test_api.rs index fe69084ca33..73bd3da1687 100644 --- a/core/src/env/engine/off_chain/test_api.rs +++ b/core/src/env/engine/off_chain/test_api.rs @@ -214,11 +214,12 @@ where /// Update the [ChainSpec](`crate::env::engine::off_chain::db::ChainSpec`) for the test environment pub fn update_chain_spec(f: F) -> Result<()> where - F: FnOnce(&mut ChainSpec) -> () + F: FnOnce(&mut ChainSpec) { - Ok(::on_instance(|instance| { + ::on_instance(|instance| { f(instance.chain_spec_mut()) - })) + }); + Ok(()) } /// Returns the contents of the past performed environmental `println` in order.