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 2 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 @@ -51,5 +50,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::gas::{Gas, GasMeter, Token};
use crate::rent;

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

pub type AccountIdOf<T> = <T as frame_system::Trait>::AccountId;
Expand Down Expand Up @@ -204,8 +205,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 @@ -869,11 +870,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 @@ -105,7 +105,7 @@ use codec::{Codec, Encode, Decode};
use sp_io::hashing::blake2_256;
use sp_runtime::{
traits::{
Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member,
Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, Convert,
},
RuntimeDebug,
};
Expand All @@ -120,6 +120,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 @@ -291,9 +292,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 @@ -314,10 +316,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 @@ -373,6 +378,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 @@ -32,7 +32,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 @@ -143,17 +143,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 @@ -167,6 +160,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 @@ -375,8 +376,8 @@ mod tests {
)
)
}
fn get_weight_price(&self) -> BalanceOf<Self::T> {
1312_u32.into()
fn get_weight_price(&self, weight: Weight) -> BalanceOf<Self::T> {
(weight * 1312).into()
niklasad1 marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -483,8 +484,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 @@ -1060,7 +1061,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 @@ -1076,7 +1077,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 @@ -688,12 +688,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 @@ -372,23 +372,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 @@ -398,6 +381,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