Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

seal: Refactor ext_gas_price #6478

Merged
4 commits merged into from
Jun 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,7 @@ parameter_types! {
impl pallet_contracts::Trait for Runtime {
type Time = Timestamp;
type Randomness = RandomnessCollectiveFlip;
type Currency = Balances;
type Call = Call;
type Event = Event;
type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminer<Runtime>;
Expand All @@ -594,6 +595,7 @@ impl pallet_contracts::Trait for Runtime {
type SurchargeReward = SurchargeReward;
type MaxDepth = pallet_contracts::DefaultMaxDepth;
type MaxValueSize = pallet_contracts::DefaultMaxValueSize;
type WeightPrice = pallet_transaction_payment::Module<Self>;
}

impl pallet_sudo::Trait for Runtime {
Expand Down
2 changes: 0 additions & 2 deletions frame/contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ sp-sandbox = { version = "0.8.0-rc3", default-features = false, path = "../../pr
frame-support = { version = "2.0.0-rc3", default-features = false, path = "../support" }
frame-system = { version = "2.0.0-rc3", default-features = false, path = "../system" }
pallet-contracts-primitives = { version = "2.0.0-rc3", default-features = false, path = "common" }
pallet-transaction-payment = { version = "2.0.0-rc3", default-features = false, path = "../transaction-payment" }

[dev-dependencies]
wabt = "0.9.2"
Expand All @@ -52,5 +51,4 @@ std = [
"pwasm-utils/std",
"wasmi-validation/std",
"pallet-contracts-primitives/std",
"pallet-transaction-payment/std",
]
14 changes: 6 additions & 8 deletions frame/contracts/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ use crate::rent;
use crate::storage;

use sp_std::prelude::*;
use sp_runtime::traits::{Bounded, Zero};
use sp_runtime::traits::{Bounded, Zero, Convert};
use frame_support::{
storage::unhashed, dispatch::DispatchError,
traits::{ExistenceRequirement, Currency, Time, Randomness},
weights::Weight,
};

pub type AccountIdOf<T> = <T as frame_system::Trait>::AccountId;
Expand Down Expand Up @@ -216,8 +217,8 @@ pub trait Ext {
/// Returns `None` if the value doesn't exist.
fn get_runtime_storage(&self, key: &[u8]) -> Option<Vec<u8>>;

/// Returns the price of one weight unit.
fn get_weight_price(&self) -> BalanceOf<Self::T>;
/// Returns the price for the specified amount of weight.
fn get_weight_price(&self, weight: Weight) -> BalanceOf<Self::T>;
pepyakin marked this conversation as resolved.
Show resolved Hide resolved
}

/// Loader is a companion of the `Vm` trait. It loads an appropriate abstract
Expand Down Expand Up @@ -874,11 +875,8 @@ where
unhashed::get_raw(&key)
}

fn get_weight_price(&self) -> BalanceOf<Self::T> {
use pallet_transaction_payment::Module as Payment;
use sp_runtime::SaturatedConversion;
let price = Payment::<T>::weight_to_fee_with_adjustment::<u128>(1);
price.saturated_into()
fn get_weight_price(&self, weight: Weight) -> BalanceOf<Self::T> {
T::WeightPrice::convert(weight)
}
}

Expand Down
17 changes: 13 additions & 4 deletions frame/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ use sp_std::{prelude::*, marker::PhantomData, fmt::Debug};
use codec::{Codec, Encode, Decode};
use sp_runtime::{
traits::{
Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member,
Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, Convert,
},
RuntimeDebug,
};
Expand All @@ -117,6 +117,7 @@ use frame_support::traits::{OnUnbalanced, Currency, Get, Time, Randomness};
use frame_support::weights::GetDispatchInfo;
use frame_system::{self as system, ensure_signed, RawOrigin, ensure_root};
use pallet_contracts_primitives::{RentProjection, ContractAccessError};
use frame_support::weights::Weight;

pub type CodeHash<T> = <T as frame_system::Trait>::Hash;
pub type TrieId = Vec<u8>;
Expand Down Expand Up @@ -289,9 +290,10 @@ where
}
}

pub type BalanceOf<T> = <<T as pallet_transaction_payment::Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
pub type BalanceOf<T> =
<<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
pub type NegativeImbalanceOf<T> =
<<T as pallet_transaction_payment::Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;
<<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;

parameter_types! {
/// A reasonable default value for [`Trait::SignedClaimedHandicap`].
Expand All @@ -312,10 +314,13 @@ parameter_types! {
pub const DefaultMaxValueSize: u32 = 16_384;
}

pub trait Trait: frame_system::Trait + pallet_transaction_payment::Trait {
pub trait Trait: frame_system::Trait {
type Time: Time;
type Randomness: Randomness<Self::Hash>;

/// The currency in which fees are paid and contract balances are held.
type Currency: Currency<Self::AccountId>;

/// The outer call dispatch type.
type Call:
Parameter +
Expand Down Expand Up @@ -371,6 +376,10 @@ pub trait Trait: frame_system::Trait + pallet_transaction_payment::Trait {

/// The maximum size of a storage value in bytes.
type MaxValueSize: Get<u32>;

/// Used to answer contracts's queries regarding the current weight price. This is **not**
/// used to calculate the actual fee and is only for informational purposes.
type WeightPrice: Convert<Weight, BalanceOf<Self>>;
}

/// Simple contract address determiner.
Expand Down
12 changes: 3 additions & 9 deletions frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use frame_support::{
assert_ok, assert_err_ignore_postinfo, impl_outer_dispatch, impl_outer_event,
impl_outer_origin, parameter_types, StorageMap, StorageValue,
traits::{Currency, Get},
weights::{Weight, PostDispatchInfo, IdentityFee},
weights::{Weight, PostDispatchInfo},
};
use std::cell::RefCell;
use frame_system::{self as system, EventRecord, Phase};
Expand Down Expand Up @@ -169,17 +169,10 @@ impl Convert<Weight, BalanceOf<Self>> for Test {
}
}

impl pallet_transaction_payment::Trait for Test {
type Currency = Balances;
type OnTransactionPayment = ();
type TransactionByteFee = TransactionByteFee;
type WeightToFee = IdentityFee<BalanceOf<Self>>;
type FeeMultiplierUpdate = ();
}

impl Trait for Test {
type Time = Timestamp;
type Randomness = Randomness;
type Currency = Balances;
type Call = Call;
type DetermineContractAddress = DummyContractAddressFor;
type Event = MetaEvent;
Expand All @@ -193,6 +186,7 @@ impl Trait for Test {
type SurchargeReward = SurchargeReward;
type MaxDepth = MaxDepth;
type MaxValueSize = MaxValueSize;
type WeightPrice = Self;
}

type Balances = pallet_balances::Module<Test>;
Expand Down
13 changes: 7 additions & 6 deletions frame/contracts/src/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ mod tests {
use hex_literal::hex;
use assert_matches::assert_matches;
use sp_runtime::DispatchError;
use frame_support::weights::Weight;

const GAS_LIMIT: Gas = 10_000_000_000;

Expand Down Expand Up @@ -373,8 +374,8 @@ mod tests {
)
)
}
fn get_weight_price(&self) -> BalanceOf<Self::T> {
1312_u32.into()
fn get_weight_price(&self, weight: Weight) -> BalanceOf<Self::T> {
BalanceOf::<Self::T>::from(1312_u32).saturating_mul(weight.into())
}
}

Expand Down Expand Up @@ -479,8 +480,8 @@ mod tests {
fn get_runtime_storage(&self, key: &[u8]) -> Option<Vec<u8>> {
(**self).get_runtime_storage(key)
}
fn get_weight_price(&self) -> BalanceOf<Self::T> {
(**self).get_weight_price()
fn get_weight_price(&self, weight: Weight) -> BalanceOf<Self::T> {
(**self).get_weight_price(weight)
}
}

Expand Down Expand Up @@ -1056,7 +1057,7 @@ mod tests {

const CODE_GAS_PRICE: &str = r#"
(module
(import "env" "ext_gas_price" (func $ext_gas_price))
(import "env" "ext_gas_price" (func $ext_gas_price (param i64)))
(import "env" "ext_scratch_size" (func $ext_scratch_size (result i32)))
(import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32)))
(import "env" "memory" (memory 1 1))
Expand All @@ -1072,7 +1073,7 @@ mod tests {

(func (export "call")
;; This stores the gas price in the scratch buffer
(call $ext_gas_price)
(call $ext_gas_price (i64.const 1))

;; assert $ext_scratch_size == 8
(call $assert
Expand Down
8 changes: 5 additions & 3 deletions frame/contracts/src/wasm/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,12 +696,14 @@ define_env!(Env, <E: Ext>,
Ok(())
},

// Stores the gas price for the current transaction into the scratch buffer.
// Stores the price for the specified amount of gas in scratch buffer.
//
// The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten.
ext_gas_price(ctx) => {
// It is recommended to avoid specifying very small values for `gas` as the prices for a single
// gas can be smaller than one.
ext_gas_price(ctx, gas: u64) => {
ctx.scratch_buf.clear();
ctx.ext.get_weight_price().encode_to(&mut ctx.scratch_buf);
ctx.ext.get_weight_price(gas).encode_to(&mut ctx.scratch_buf);
Ok(())
},

Expand Down
33 changes: 15 additions & 18 deletions frame/transaction-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use sp_runtime::{
},
traits::{
Zero, Saturating, SignedExtension, SaturatedConversion, Convert, Dispatchable,
DispatchInfoOf, PostDispatchInfoOf, UniqueSaturatedFrom, UniqueSaturatedInto,
DispatchInfoOf, PostDispatchInfoOf,
},
};
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
Expand Down Expand Up @@ -340,23 +340,6 @@ impl<T: Trait> Module<T> where
tip
}
}
}

impl<T: Trait> Module<T> {
/// Compute the fee for the specified weight.
///
/// This fee is already adjusted by the per block fee adjustment factor and is therefore the
/// share that the weight contributes to the overall fee of a transaction.
///
/// This function is generic in order to supply the contracts module with a way to calculate the
/// gas price. The contracts module is not able to put the necessary `BalanceOf<T>` constraints
/// on its trait. This function is not to be used by this module.
pub fn weight_to_fee_with_adjustment<Balance>(weight: Weight) -> Balance where
Balance: UniqueSaturatedFrom<u128>
{
let fee: u128 = Self::weight_to_fee(weight).unique_saturated_into();
Balance::unique_saturated_from(NextFeeMultiplier::get().saturating_mul_acc_int(fee))
}

fn weight_to_fee(weight: Weight) -> BalanceOf<T> {
// cap the weight to the maximum defined in runtime, otherwise it will be the
Expand All @@ -366,6 +349,20 @@ impl<T: Trait> Module<T> {
}
}

impl<T> Convert<Weight, BalanceOf<T>> for Module<T> where
T: Trait,
BalanceOf<T>: FixedPointOperand,
{
/// Compute the fee for the specified weight.
///
/// This fee is already adjusted by the per block fee adjustment factor and is therefore the
/// share that the weight contributes to the overall fee of a transaction. It is mainly
/// for informational purposes and not used in the actual fee calculation.
fn convert(weight: Weight) -> BalanceOf<T> {
NextFeeMultiplier::get().saturating_mul_int(Self::weight_to_fee(weight))
}
}

/// Require the transactor pay for themselves and maybe include a tip to gain additional priority
/// in the queue.
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
Expand Down