Unverified Commit 2456fdd2 authored by Andrew Jones's avatar Andrew Jones Committed by GitHub
Browse files

[core] add gas arg to ext_gas_price (#461)

* add gas argument

* Add gas parameter to ext_gas_price

* Fix up gas_price offchain api

* Fix up env_access api

* Emulate gas price calculation

* Make clippy happy

* Use Saturating impl for emulating gas price calculation offchain

* Fmt

* Add offchain gas_price test

* Make clippy happy
parent 30fe10df
Pipeline #99119 failed with stages
in 9 minutes and 29 seconds
......@@ -60,17 +60,17 @@ where
})
}
/// Returns the current price for gas.
/// Returns the price for the specified amount of gas.
///
/// # Errors
///
/// If the returned value cannot be properly decoded.
pub fn gas_price<T>() -> Result<T::Balance>
pub fn gas_price<T>(gas: u64) -> Result<T::Balance>
where
T: EnvTypes,
{
<EnvInstance as OnInstance>::on_instance(|instance| {
TypedEnv::gas_price::<T>(instance)
TypedEnv::gas_price::<T>(instance, gas)
})
}
......
......@@ -14,15 +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,
},
ops::{
Add,
AddAssign,
Div,
DivAssign,
Mul,
MulAssign,
Sub,
SubAssign,
},
};
use num_traits::{
checked_pow,
......@@ -40,7 +46,7 @@ use num_traits::{
/// if needed.
pub trait BaseArithmetic:
Sized
+ From<u32>
+ From<u8>
+ Bounded
+ Ord
+ PartialOrd<Self>
......@@ -57,21 +63,19 @@ pub trait BaseArithmetic:
+ DivAssign<Self>
+ CheckedMul
+ Saturating
+ TryFrom<u16>
+ TryFrom<u32>
+ TryFrom<u64>
+ TryFrom<u128>
+ TryFrom<usize>
+ TryInto<u16>
+ TryInto<u32>
+ TryInto<u64>
+ TryInto<u128>
+ TryInto<usize>
// Further trait bounds from the original BaseArithmetic trait
// that we could use to extend ink!'s BaseArithmetic trait.
//
// From<u8> +
// From<u16> +
// From<u32> +
// TryFrom<u64> +
// TryFrom<u128> +
// TryFrom<usize> +
// TryInto<u8> +
// TryInto<u16> +
// TryInto<u32> +
// TryInto<u64> +
// TryInto<u128> +
// TryInto<usize> +
// UniqueSaturatedInto<u8> +
// UniqueSaturatedInto<u16> +
// UniqueSaturatedInto<u32> +
......@@ -92,7 +96,7 @@ pub trait BaseArithmetic:
impl<T> BaseArithmetic for T where
T: Sized
+ From<u32>
+ From<u8>
+ Bounded
+ Ord
+ PartialOrd<Self>
......@@ -108,6 +112,16 @@ impl<T> BaseArithmetic for T where
+ DivAssign<Self>
+ CheckedMul
+ Saturating
+ TryFrom<u16>
+ TryFrom<u32>
+ TryFrom<u64>
+ TryFrom<u128>
+ TryFrom<usize>
+ TryInto<u16>
+ TryInto<u32>
+ TryInto<u64>
+ TryInto<u128>
+ TryInto<usize>
{
}
......
......@@ -126,12 +126,12 @@ pub trait TypedEnv: Env {
/// For more details visit: [`ink_core::env::transferred_balance`]
fn transferred_balance<T: EnvTypes>(&mut self) -> Result<T::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`]
fn gas_price<T: EnvTypes>(&mut self) -> Result<T::Balance>;
fn gas_price<T: EnvTypes>(&mut self, gas: u64) -> Result<T::Balance>;
/// Returns the amount of gas left for the contract execution.
///
......
......@@ -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<T>(&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<T>(&self) -> Result<T::Balance>
where
......
......@@ -31,6 +31,8 @@ use crate::env::{
TypedEnv,
};
use ink_primitives::Key;
use core::convert::TryInto;
use num_traits::Bounded;
impl EnvInstance {
/// Returns the callee account.
......@@ -153,11 +155,15 @@ impl TypedEnv for EnvInstance {
.map_err(Into::into)
}
fn gas_price<T: EnvTypes>(&mut self) -> Result<T::Balance> {
self.chain_spec
/// Emulates gas price calculation
fn gas_price<T: EnvTypes>(&mut self, gas: u64) -> Result<T::Balance> {
use crate::env::arithmetic::Saturating as _;
let gas_price = self.chain_spec
.gas_price::<T>()
.map_err(|_| scale::Error::from("could not decode gas price"))
.map_err(Into::into)
.map_err(|_| scale::Error::from("could not decode gas price"))?;
Ok(gas_price.saturating_mul(gas.try_into().unwrap_or_else(|_| Bounded::max_value())))
}
fn gas_left<T: EnvTypes>(&mut self) -> Result<T::Balance> {
......
......@@ -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 {
......
......@@ -25,6 +25,7 @@ use super::{
use crate::env::{
EnvTypes,
Result,
engine::off_chain::db::ChainSpec,
};
use ink_prelude::string::String;
......@@ -210,6 +211,17 @@ 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: F) -> Result<()>
where
F: FnOnce(&mut ChainSpec)
{
<EnvInstance as OnInstance>::on_instance(|instance| {
f(instance.chain_spec_mut())
});
Ok(())
}
/// Returns the contents of the past performed environmental `println` in order.
pub fn recorded_printlns() -> impl Iterator<Item = String> {
<EnvInstance as OnInstance>::on_instance(|instance| {
......
......@@ -68,3 +68,19 @@ fn key_add_sub() -> Result<()> {
Ok(())
})
}
#[test]
fn gas_price() -> env::Result<()> {
env::test::run_test::<env::DefaultEnvTypes, _>(|_| {
let gas_price= 2u32;
env::test::update_chain_spec(|chain_spec| {
chain_spec.set_gas_price::<env::DefaultEnvTypes>(gas_price.into())
})?;
assert_eq!(2u128, env::gas_price::<env::DefaultEnvTypes>(1).unwrap());
assert_eq!(20u128, env::gas_price::<env::DefaultEnvTypes>(10).unwrap());
assert_eq!(6u128, env::gas_price::<env::DefaultEnvTypes>(3).unwrap());
Ok(())
})
}
......@@ -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();
......@@ -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) }
}
......
......@@ -208,10 +208,6 @@ impl TypedEnv for EnvInstance {
self.get_property::<T::Balance>(ext::value_transferred)
}
fn gas_price<T: EnvTypes>(&mut self) -> Result<T::Balance> {
self.get_property::<T::Balance>(ext::gas_price)
}
fn gas_left<T: EnvTypes>(&mut self) -> Result<T::Balance> {
self.get_property::<T::Balance>(ext::gas_left)
}
......@@ -380,6 +376,11 @@ impl TypedEnv for EnvInstance {
ext::transfer(destination, value)
}
fn gas_price<T: EnvTypes>(&mut self, gas: u64) -> Result<T::Balance> {
ext::gas_price(gas);
self.decode_scratch_buffer().map_err(Into::into)
}
fn random<T>(&mut self, subject: &[u8]) -> Result<T::Hash>
where
T: EnvTypes,
......
......@@ -104,13 +104,13 @@ where
env::transferred_balance::<T>().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::<T>().expect("couldn't decode gas price")
pub fn gas_price(self, gas: u64) -> T::Balance {
env::gas_price::<T>(gas).expect("couldn't decode gas price")
}
/// Returns the amount of gas left for the contract execution.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment