From 3ee919efbad969ec7f7bbb91cbe4045d9c0443d7 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 10 Oct 2019 19:32:48 +0200 Subject: [PATCH 01/11] Checkpoint --- Cargo.lock | 13 ++++ Cargo.toml | 1 + srml/balances/src/tests.rs | 19 +++++ srml/transaction-payment/Cargo.toml | 26 +++++++ srml/transaction-payment/src/lib.rs | 112 ++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 srml/transaction-payment/Cargo.toml create mode 100644 srml/transaction-payment/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 8a1ead4978680..c702dab1f6c84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4439,6 +4439,19 @@ dependencies = [ "substrate-primitives 2.0.0", ] +[[package]] +name = "srml-transaction-payment" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "sr-std 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "substrate-primitives 2.0.0", +] + [[package]] name = "srml-treasury" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 7e34a0bd6ccd0..5a8fe5923a936 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,6 +105,7 @@ members = [ "srml/system", "srml/timestamp", "srml/treasury", + "srml/transaction-payment", "srml/utility", "node/cli", "node/executor", diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index b4745c2253e4f..42c99714deee9 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -823,3 +823,22 @@ fn burn_must_work() { } ); } + +#[test] +fn can_have_free_fee() { + set_and_run_with_externalities( + &mut ExtBuilder::default() + .monied(true) + .build(), + || { + let check = Balances::withdraw( + &1101, + 0u64, + WithdrawReason::TransactionPayment, + ExistenceRequirement::KeepAlive, + ); + assert_eq!(Balances::free_balance(1101), 0); + assert!(check.is_ok()); + } + ); +} diff --git a/srml/transaction-payment/Cargo.toml b/srml/transaction-payment/Cargo.toml new file mode 100644 index 0000000000000..15b41e7ceef1a --- /dev/null +++ b/srml/transaction-payment/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "srml-transaction-payment" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +support = { package = "srml-support", path = "../support", default-features = false } +system = { package = "srml-system", path = "../system", default-features = false } + +[dev-dependencies] +runtime-io = { package = "sr-io", path = "../../core/sr-io" } +primitives = { package = "substrate-primitives", path = "../../core/primitives" } + +[features] +default = ["std"] +std = [ + "codec/std", + "rstd/std", + "sr-primitives/std", + "support/std", + "system/std", +] diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs new file mode 100644 index 0000000000000..9986597223dff --- /dev/null +++ b/srml/transaction-payment/src/lib.rs @@ -0,0 +1,112 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! # Transaction Payment Module +//! +//! This module provides the logic needed to approve that a transaction is paying the _absolute +//! minimum_ amount required to be included on-chain. Note that this is similar, but by no means the +//! same as what a typical blockchain system names _transaction fee_. Substrate makes no assumption +//! about the type of the transactions, ergo no assumption is also made about the existence of a +//! fee. +//! +//! Hence, the primitives that this module uses to _charge an inclusion payment_ from the dispatch +//! origin are rather simple and static (as opposed to dynamic and complicated systems like gas +//! metering). +//! +//! +//! +//! + +// The way that it should work is that the system module assumes that the concept of weight is fixed +// it will try and use an external module to estimate how mcuh fee does a weigth number correspond to. +// so in the long term I suspect the TakeFee to actully go into the system module (maybe also here but) +// the rational is that the weight system os **mandatory**. + +#![cfg_attr(not(feature = "std"), no_std)] + +use rstd::prelude::*; +use codec::{Codec, Encode, Decode}; +use support::{ + StorageValue, Parameter, decl_event, decl_storage, decl_module, + traits::{Currency, Get}, + dispatch::Result, +}; +use sr_primitives::{ + transaction_validity::{ + TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, + TransactionValidity, + }, + traits::{ + Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, + Saturating, Bounded, SignedExtension, SaturatedConversion, Convert, + }, + weights::Weight, +}; +use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; + + +// Imagine this going into support. +/// Something that can convert a weight type into a _deductible currency_. +pub trait WeightToFee { + fn weight_to_fee(w: Weight) -> B; +} + +impl WeightToFee for () { + fn weight_to_fee(_: Weight) -> B { + Zero::zero() + } +} + +pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +pub trait Trait: system::Trait { + /// The currency type of the chain. + type Currency: Currency + Codec; + + /// The fee to be paid for making a transaction; the base. + type TransactionBaseFee: Get; + + /// The fee to be paid for making a transaction; the per-byte portion. + type TransactionByteFee: Get; +} + +decl_storage! { + trait Store for Module as Balances { + + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + /// The fee to be paid for making a transaction; the base. + const TransactionBaseFee: T::Currency = T::TransactionBaseFee::get(); + + /// The fee to be paid for making a transaction; the per-byte portion. + const TransactionByteFee: T::Currency = T::TransactionByteFee::get(); + + // user dispatchables? nada. + } +} + +impl Module {} + +impl WeightToFee> for Module { + fn weight_to_fee(w: Weight) -> BalanceOf { + // assume this module implements a simple multiplier + Zero::zero() + } +} From 89261e8824519a57e277e6bab32783b900f5472d Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 11 Oct 2019 15:29:39 +0200 Subject: [PATCH 02/11] Initial draft that compiles --- Cargo.lock | 1 + core/sr-primitives/src/sr_arithmetic.rs | 4 + node-template/runtime/Cargo.toml | 2 + srml/transaction-payment/src/lib.rs | 155 ++++++++++++++++++------ 4 files changed, 123 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c702dab1f6c84..ed8efdd973431 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2563,6 +2563,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-client 2.0.0", "substrate-consensus-babe-primitives 2.0.0", "substrate-offchain-primitives 2.0.0", diff --git a/core/sr-primitives/src/sr_arithmetic.rs b/core/sr-primitives/src/sr_arithmetic.rs index 043a383a33244..1a73613c38d1d 100644 --- a/core/sr-primitives/src/sr_arithmetic.rs +++ b/core/sr-primitives/src/sr_arithmetic.rs @@ -558,6 +558,10 @@ impl Fixed64 { Self(int.saturating_mul(DIV)) } + pub fn one() -> Self { + Self(DIV) + } + /// Return the accuracy of the type. Given that this function returns the value `X`, it means /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. pub fn accuracy() -> i64 { diff --git a/node-template/runtime/Cargo.toml b/node-template/runtime/Cargo.toml index 76821b6dfd8a2..96484c16aef91 100644 --- a/node-template/runtime/Cargo.toml +++ b/node-template/runtime/Cargo.toml @@ -24,6 +24,7 @@ randomness-collective-flip = { package = "srml-randomness-collective-flip", path system = { package = "srml-system", path = "../../srml/system", default_features = false } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default_features = false } sudo = { package = "srml-sudo", path = "../../srml/sudo", default_features = false } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment", default_features = false } sr-primitives = { path = "../../core/sr-primitives", default_features = false } client = { package = "substrate-client", path = "../../core/client", default_features = false } offchain-primitives = { package = "substrate-offchain-primitives", path = "../../core/offchain/primitives", default-features = false } @@ -51,6 +52,7 @@ std = [ "system/std", "timestamp/std", "sudo/std", + "transaction-payment/std", "version/std", "serde", "safe-mix/std", diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index 9986597223dff..4fb2ffd27f254 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -22,10 +22,6 @@ //! about the type of the transactions, ergo no assumption is also made about the existence of a //! fee. //! -//! Hence, the primitives that this module uses to _charge an inclusion payment_ from the dispatch -//! origin are rather simple and static (as opposed to dynamic and complicated systems like gas -//! metering). -//! //! //! //! @@ -38,75 +34,156 @@ #![cfg_attr(not(feature = "std"), no_std)] use rstd::prelude::*; -use codec::{Codec, Encode, Decode}; +use codec::{Encode, Decode}; use support::{ - StorageValue, Parameter, decl_event, decl_storage, decl_module, - traits::{Currency, Get}, - dispatch::Result, + decl_storage, decl_module, + traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason}, }; use sr_primitives::{ + Fixed64, transaction_validity::{ TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, TransactionValidity, }, - traits::{ - Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, - Saturating, Bounded, SignedExtension, SaturatedConversion, Convert, - }, - weights::Weight, + traits::{Zero, Saturating, SignedExtension, SaturatedConversion, Convert}, + weights::{Weight, DispatchInfo}, }; -use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; - - -// Imagine this going into support. -/// Something that can convert a weight type into a _deductible currency_. -pub trait WeightToFee { - fn weight_to_fee(w: Weight) -> B; -} - -impl WeightToFee for () { - fn weight_to_fee(_: Weight) -> B { - Zero::zero() - } -} +type Multiplier = Fixed64; pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = + <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: system::Trait { /// The currency type of the chain. - type Currency: Currency + Codec; + type Currency: Currency; + + /// Handler for the unbalanced reduction when taking transaction fees. + type OnTransactionPayment: OnUnbalanced>; /// The fee to be paid for making a transaction; the base. - type TransactionBaseFee: Get; + type TransactionBaseFee: Get>; /// The fee to be paid for making a transaction; the per-byte portion. - type TransactionByteFee: Get; + type TransactionByteFee: Get>; + + /// Convert a weight value into a deductible fee based on the currency type. + type WeightToFee: Convert>; + + /// Update the multiplier of the next block, based on the previous block's weight. + // TODO: maybe this does not need previous weight and can just read it + type FeeMultiplierUpdate: Convert<(Weight, Multiplier), Multiplier>; } decl_storage! { trait Store for Module as Balances { - + NextFeeMultiplier get(next_fee_multiplier): Multiplier = Multiplier::one(); } } decl_module! { pub struct Module for enum Call where origin: T::Origin { /// The fee to be paid for making a transaction; the base. - const TransactionBaseFee: T::Currency = T::TransactionBaseFee::get(); + const TransactionBaseFee: BalanceOf = T::TransactionBaseFee::get(); /// The fee to be paid for making a transaction; the per-byte portion. - const TransactionByteFee: T::Currency = T::TransactionByteFee::get(); - - // user dispatchables? nada. + const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); + + fn on_finalize() { + let current_weight = >::all_extrinsics_weight(); + NextFeeMultiplier::mutate(|fm| { + *fm = T::FeeMultiplierUpdate::convert((current_weight, *fm)) + }); + } } } impl Module {} -impl WeightToFee> for Module { - fn weight_to_fee(w: Weight) -> BalanceOf { - // assume this module implements a simple multiplier - Zero::zero() +/// Require the transactor pay for themselves and maybe include a tip to gain additional priority +/// in the queue. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); + +impl ChargeTransactionPayment { + /// utility constructor. Used only in client/factory code. + pub fn from(fee: BalanceOf) -> Self { + Self(fee) + } + + /// Compute the final fee value for a particular transaction. + /// + /// The final fee is composed of: + /// - _length-fee_: This is the amount paid merely to pay for size of the transaction. + /// - _weight-fee_: This amount is computed based on the weight of the transaction. Unlike + /// size-fee, this is not input dependent and reflects the _complexity_ of the execution + /// and the time it consumes. + /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed + /// transactions can have a tip. + fn compute_fee(len: usize, info: DispatchInfo, tip: BalanceOf) -> BalanceOf { + let len_fee = if info.pay_length_fee() { + let len = >::from(len as u32); + let base = T::TransactionBaseFee::get(); + let per_byte = T::TransactionByteFee::get(); + base.saturating_add(per_byte.saturating_mul(len)) + } else { + Zero::zero() + }; + + let weight_fee = { + // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` + // maximum of its data type, which is not desired. + let capped_weight = info.weight.min(::MaximumBlockWeight::get()); + let fee = T::WeightToFee::convert(capped_weight); + let fee_update = NextFeeMultiplier::get(); + let adjusted_fee = fee_update.saturated_multiply_accumulate(fee); + adjusted_fee + }; + + len_fee.saturating_add(weight_fee).saturating_add(tip) } } + +#[cfg(feature = "std")] +impl rstd::fmt::Debug for ChargeTransactionPayment { + fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + self.0.fmt(f) + } +} + +impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync { + type AccountId = T::AccountId; + type Call = T::Call; + type AdditionalSigned = (); + type Pre = (); + fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + + fn validate( + &self, + who: &Self::AccountId, + _call: &Self::Call, + info: DispatchInfo, + len: usize, + ) -> TransactionValidity { + // pay any fees. + let fee = Self::compute_fee(len, info, self.0); + let imbalance = match T::Currency::withdraw( + who, + fee, + WithdrawReason::TransactionPayment, + ExistenceRequirement::KeepAlive, + ) { + Ok(imbalance) => imbalance, + Err(_) => return InvalidTransaction::Payment.into(), + }; + T::OnTransactionPayment::on_unbalanced(imbalance); + + let mut r = ValidTransaction::default(); + // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which + // will be a bit more than setting the priority to tip. For now, this is enough. + r.priority = fee.saturated_into::(); + Ok(r) + } +} + From dc1d41c31499e7db5ac79f654c477288020ddfc0 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 11 Oct 2019 15:57:33 +0200 Subject: [PATCH 03/11] Better doc --- srml/transaction-payment/src/lib.rs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index 4fb2ffd27f254..28df06baa279e 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -16,20 +16,14 @@ //! # Transaction Payment Module //! -//! This module provides the logic needed to approve that a transaction is paying the _absolute -//! minimum_ amount required to be included on-chain. Note that this is similar, but by no means the -//! same as what a typical blockchain system names _transaction fee_. Substrate makes no assumption -//! about the type of the transactions, ergo no assumption is also made about the existence of a -//! fee. +//! This module provides the basic logic needed to pay the absolute minimum amount needed for a +//! transaction to be included. This includes: +//! - _weight fee_: A fee proportional to amount of Weight a transaction consumes. (TODO: explain +//! what weight is or link somewhere) +//! - _length fee_: A fee proportional to the encoded length of the transaction. //! -//! -//! -//! - -// The way that it should work is that the system module assumes that the concept of weight is fixed -// it will try and use an external module to estimate how mcuh fee does a weigth number correspond to. -// so in the long term I suspect the TakeFee to actully go into the system module (maybe also here but) -// the rational is that the weight system os **mandatory**. +//! Additionally, this module allows all transactions to include an optional tip. Tip increases the +//! priority of the transaction, giving it a higher chance to be included. #![cfg_attr(not(feature = "std"), no_std)] @@ -136,6 +130,7 @@ impl ChargeTransactionPayment { // maximum of its data type, which is not desired. let capped_weight = info.weight.min(::MaximumBlockWeight::get()); let fee = T::WeightToFee::convert(capped_weight); + // TODO #3291 apply this to both weights, not just one. let fee_update = NextFeeMultiplier::get(); let adjusted_fee = fee_update.saturated_multiply_accumulate(fee); adjusted_fee From f828055830b3a74441985972cb67fdbe2f185e9c Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 11 Oct 2019 16:03:18 +0200 Subject: [PATCH 04/11] Better doc --- srml/balances/src/tests.rs | 19 ------------------- srml/transaction-payment/src/lib.rs | 9 +++++++-- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 42c99714deee9..b4745c2253e4f 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -823,22 +823,3 @@ fn burn_must_work() { } ); } - -#[test] -fn can_have_free_fee() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .monied(true) - .build(), - || { - let check = Balances::withdraw( - &1101, - 0u64, - WithdrawReason::TransactionPayment, - ExistenceRequirement::KeepAlive, - ); - assert_eq!(Balances::free_balance(1101), 0); - assert!(check.is_ok()); - } - ); -} diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index 28df06baa279e..bc2de0308e1a6 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -21,9 +21,14 @@ //! - _weight fee_: A fee proportional to amount of Weight a transaction consumes. (TODO: explain //! what weight is or link somewhere) //! - _length fee_: A fee proportional to the encoded length of the transaction. +//! - _tip_: An optional tip. Tip increases the priority of the transaction, giving it a higher +//! chance to be included by the transaction queue. //! -//! Additionally, this module allows all transactions to include an optional tip. Tip increases the -//! priority of the transaction, giving it a higher chance to be included. +//! Additionally, this module allows one to configure: +//! - The mapping between one unit of weight to one unit of fee via [`WeightToFee`]. +//! - A means of updating the fee for the next block, via defining a multiplier, based on the +//! final state of the chain at the end of the previous block. This can be configured via +//! [`FeeMultiplierUpdate`] #![cfg_attr(not(feature = "std"), no_std)] From fac73b7a6402e394ad150baff06a3059c0c50cdc Mon Sep 17 00:00:00 2001 From: kianenigma Date: Sat, 12 Oct 2019 16:39:16 +0200 Subject: [PATCH 05/11] Extract payment stuff from balances --- Cargo.lock | 8 + core/sr-primitives/src/sr_arithmetic.rs | 4 - node-template/runtime/src/lib.rs | 19 +- node/cli/Cargo.toml | 1 + node/cli/src/factory_impl.rs | 2 +- node/cli/src/service.rs | 4 +- node/executor/Cargo.toml | 1 + node/executor/src/lib.rs | 2 +- node/runtime/Cargo.toml | 2 + node/runtime/src/impls.rs | 2 +- node/runtime/src/lib.rs | 18 +- node/testing/Cargo.toml | 1 + node/testing/src/keyring.rs | 2 +- srml/balances/Cargo.toml | 1 + srml/balances/src/lib.rs | 140 +-------------- srml/balances/src/mock.rs | 55 ++---- srml/balances/src/tests.rs | 58 ++---- srml/contracts/src/lib.rs | 2 +- srml/contracts/src/tests.rs | 6 - srml/council/src/lib.rs | 6 - srml/democracy/src/lib.rs | 6 - srml/elections-phragmen/src/lib.rs | 6 - srml/elections/src/mock.rs | 6 - srml/example/src/lib.rs | 6 - srml/executive/Cargo.toml | 1 + srml/executive/src/lib.rs | 17 +- srml/scored-pool/src/mock.rs | 6 - srml/staking/src/mock.rs | 6 - srml/transaction-payment/Cargo.toml | 1 + srml/transaction-payment/src/lib.rs | 225 +++++++++++++++++++++++- srml/treasury/src/lib.rs | 6 - srml/utility/src/lib.rs | 6 - subkey/Cargo.toml | 1 + subkey/src/main.rs | 2 +- 34 files changed, 306 insertions(+), 323 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed8efdd973431..06220c869cbc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2355,6 +2355,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-authority-discovery 2.0.0", "substrate-basic-authorship 2.0.0", @@ -2401,6 +2402,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "srml-treasury 2.0.0", "substrate-executor 2.0.0", "substrate-primitives 2.0.0", @@ -2499,6 +2501,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "srml-treasury 2.0.0", "srml-utility 2.0.0", "substrate-authority-discovery-primitives 2.0.0", @@ -2591,6 +2594,7 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", + "srml-transaction-payment 2.0.0", "srml-treasury 2.0.0", "substrate-client 2.0.0", "substrate-executor 2.0.0", @@ -3991,6 +3995,7 @@ dependencies = [ "sr-std 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", ] @@ -4116,6 +4121,7 @@ dependencies = [ "srml-indices 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-primitives 2.0.0", ] @@ -4448,6 +4454,7 @@ dependencies = [ "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-std 2.0.0", + "srml-balances 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "substrate-primitives 2.0.0", @@ -4570,6 +4577,7 @@ dependencies = [ "sr-primitives 2.0.0", "srml-balances 2.0.0", "srml-system 2.0.0", + "srml-transaction-payment 2.0.0", "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/core/sr-primitives/src/sr_arithmetic.rs b/core/sr-primitives/src/sr_arithmetic.rs index 1a73613c38d1d..043a383a33244 100644 --- a/core/sr-primitives/src/sr_arithmetic.rs +++ b/core/sr-primitives/src/sr_arithmetic.rs @@ -558,10 +558,6 @@ impl Fixed64 { Self(int.saturating_mul(DIV)) } - pub fn one() -> Self { - Self(DIV) - } - /// Return the accuracy of the type. Given that this function returns the value `X`, it means /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. pub fn accuracy() -> i64 { diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 0e9b8050f018f..a0a1c539932b8 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -172,12 +172,13 @@ impl system::Trait for Runtime { type Origin = Origin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; - /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok. + /// Maximum weight of each block. type MaximumBlockWeight = MaximumBlockWeight; /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. type MaximumBlockLength = MaximumBlockLength; /// Portion of the block weight that is available to all normal transactions. type AvailableBlockRatio = AvailableBlockRatio; + /// Version of the runtime. type Version = Version; } @@ -223,8 +224,6 @@ parameter_types! { pub const ExistentialDeposit: u128 = 500; pub const TransferFee: u128 = 0; pub const CreationFee: u128 = 0; - pub const TransactionBaseFee: u128 = 0; - pub const TransactionByteFee: u128 = 1; } impl balances::Trait for Runtime { @@ -236,15 +235,25 @@ impl balances::Trait for Runtime { type OnNewAccount = Indices; /// The ubiquitous event type. type Event = Event; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; +} + +parameter_types! { + pub const TransactionBaseFee: Balance = 0; + pub const TransactionByteFee: Balance = 1; +} + +impl transaction_payment::Trait for Runtime { + type Currency = balances::Module; + type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); } impl sudo::Trait for Runtime { @@ -293,7 +302,7 @@ pub type SignedExtra = ( system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + transaction_payment::ChargeTransactionPayment ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index ca3ec92630789..afb7846da888c 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -45,6 +45,7 @@ finality_tracker = { package = "srml-finality-tracker", path = "../../srml/final contracts = { package = "srml-contracts", path = "../../srml/contracts" } system = { package = "srml-system", path = "../../srml/system" } balances = { package = "srml-balances", path = "../../srml/balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } support = { package = "srml-support", path = "../../srml/support", default-features = false } im_online = { package = "srml-im-online", path = "../../srml/im-online", default-features = false } sr-authority-discovery = { package = "srml-authority-discovery", path = "../../srml/authority-discovery", default-features = false } diff --git a/node/cli/src/factory_impl.rs b/node/cli/src/factory_impl.rs index 827b8e308c8f1..84c24f2af090b 100644 --- a/node/cli/src/factory_impl.rs +++ b/node/cli/src/factory_impl.rs @@ -56,7 +56,7 @@ impl FactoryState { system::CheckEra::from(Era::mortal(256, phase)), system::CheckNonce::from(index), system::CheckWeight::new(), - balances::TakeFees::from(0), + transaction_payment::ChargeTransactionPayment::from(0), Default::default(), ) } diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 7012a3d6ce0ad..485cd325b0ec1 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -528,14 +528,14 @@ mod tests { let check_era = system::CheckEra::from(Era::Immortal); let check_nonce = system::CheckNonce::from(index); let check_weight = system::CheckWeight::new(); - let take_fees = balances::TakeFees::from(0); + let payment = transaction_payment::ChargeTransactionPayment::from(0); let extra = ( check_version, check_genesis, check_era, check_nonce, check_weight, - take_fees, + payment, Default::default(), ); let raw_payload = SignedPayload::from_raw( diff --git a/node/executor/Cargo.toml b/node/executor/Cargo.toml index 63f1c8c0f4f3a..1908443ca9519 100644 --- a/node/executor/Cargo.toml +++ b/node/executor/Cargo.toml @@ -22,6 +22,7 @@ test-client = { package = "substrate-test-client", path = "../../core/test-clien sr-primitives = { path = "../../core/sr-primitives" } runtime_support = { package = "srml-support", path = "../../srml/support" } balances = { package = "srml-balances", path = "../../srml/balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } session = { package = "srml-session", path = "../../srml/session" } system = { package = "srml-system", path = "../../srml/system" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 40c1e08f9b7ad..66499eb69d2e1 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -97,7 +97,7 @@ mod tests { // NOTE: this is really hard to apply, since the multiplier of each block needs to be fetched // before the block, while we compute this after the block. // weight = >::next_weight_multiplier().apply_to(weight); - let weight_fee = ::WeightToFee::convert(weight); + let weight_fee = ::WeightToFee::convert(weight); length_fee + weight_fee + TransferFee::get() } diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index a47d65210096f..a125f3baa4c48 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -50,6 +50,7 @@ system = { package = "srml-system", path = "../../srml/system", default-features timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default-features = false } treasury = { package = "srml-treasury", path = "../../srml/treasury", default-features = false } utility = { package = "srml-utility", path = "../../srml/utility", default-features = false } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment", default-features = false } [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.2", path = "../../core/utils/wasm-builder-runner" } @@ -96,5 +97,6 @@ std = [ "timestamp/std", "treasury/std", "utility/std", + "transaction-payment/std", "version/std", ] diff --git a/node/runtime/src/impls.rs b/node/runtime/src/impls.rs index 2e1fcc8826e03..6c0c59b20044d 100644 --- a/node/runtime/src/impls.rs +++ b/node/runtime/src/impls.rs @@ -196,7 +196,7 @@ mod tests { if wm == next { break; } wm = next; iterations += 1; - let fee = ::WeightToFee::convert(wm.apply_to(tx_weight)); + let fee = ::WeightToFee::convert(wm.apply_to(tx_weight)); println!( "iteration {}, new wm = {:?}. Fee at this point is: {} millicents, {} cents, {} dollars", iterations, diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 6ecce4c481457..670a0bd7ec3b3 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -161,8 +161,6 @@ parameter_types! { pub const ExistentialDeposit: Balance = 1 * DOLLARS; pub const TransferFee: Balance = 1 * CENTS; pub const CreationFee: Balance = 1 * CENTS; - pub const TransactionBaseFee: Balance = 1 * CENTS; - pub const TransactionByteFee: Balance = 10 * MILLICENTS; } impl balances::Trait for Runtime { @@ -170,15 +168,25 @@ impl balances::Trait for Runtime { type OnFreeBalanceZero = ((Staking, Contracts), Session); type OnNewAccount = Indices; type Event = Event; - type TransactionPayment = DealWithFees; type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; +} + +parameter_types! { + pub const TransactionBaseFee: Balance = 1 * CENTS; + pub const TransactionByteFee: Balance = 10 * MILLICENTS; +} + +impl transaction_payment::Trait for Runtime { + type Currency = Balances; + type OnTransactionPayment = DealWithFees; type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = WeightToFee; + type FeeMultiplierUpdate = (); } parameter_types! { @@ -480,7 +488,7 @@ impl system::offchain::CreateTransaction for Runtim system::CheckEra::::from(generic::Era::mortal(period, current_block)), system::CheckNonce::::from(index), system::CheckWeight::::new(), - balances::TakeFees::::from(tip), + transaction_payment::ChargeTransactionPayment::::from(tip), Default::default(), ); let raw_payload = SignedPayload::new(call, extra).ok()?; @@ -540,7 +548,7 @@ pub type SignedExtra = ( system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees, + transaction_payment::ChargeTransactionPayment, contracts::CheckBlockGasLimit, ); /// Unchecked extrinsic type as expected by this runtime. diff --git a/node/testing/Cargo.toml b/node/testing/Cargo.toml index e622e35d4aad0..8a4c08ed11bd2 100644 --- a/node/testing/Cargo.toml +++ b/node/testing/Cargo.toml @@ -27,4 +27,5 @@ system = { package = "srml-system", path = "../../srml/system" } test-client = { package = "substrate-test-client", path = "../../core/test-client" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } treasury = { package = "srml-treasury", path = "../../srml/treasury" } +transaction-payment = { package = "srml-transaction-payment", path = "../../srml/transaction-payment" } wabt = "0.9.2" diff --git a/node/testing/src/keyring.rs b/node/testing/src/keyring.rs index 0c6eb478cc5a0..853ca0ef6d7a0 100644 --- a/node/testing/src/keyring.rs +++ b/node/testing/src/keyring.rs @@ -72,7 +72,7 @@ pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { system::CheckEra::from(Era::mortal(256, 0)), system::CheckNonce::from(nonce), system::CheckWeight::new(), - balances::TakeFees::from(extra_fee), + transaction_payment::ChargeTransactionPayment::from(extra_fee), Default::default(), ) } diff --git a/srml/balances/Cargo.toml b/srml/balances/Cargo.toml index d2b6e00d98e8b..f7f6041c6bb16 100644 --- a/srml/balances/Cargo.toml +++ b/srml/balances/Cargo.toml @@ -17,6 +17,7 @@ system = { package = "srml-system", path = "../system", default-features = false [dev-dependencies] runtime-io = { package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } +transaction-payment = { package = "srml-transaction-payment", path = "../transaction-payment" } [features] default = ["std"] diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 03e32e1ddf295..877d479932ddf 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -86,17 +86,6 @@ //! //! - `vesting_balance` - Get the amount that is currently being vested and cannot be transferred out of this account. //! -//! ### Signed Extensions -//! -//! The balances module defines the following extensions: -//! -//! - [`TakeFees`]: Consumes fees proportional to the length and weight of the transaction. -//! Additionally, it can contain a single encoded payload as a `tip`. The inclusion priority -//! is increased proportional to the tip. -//! -//! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed -//! extensions included in a chain. -//! //! ## Usage //! //! The following examples show how to use the Balances module in your custom module. @@ -171,15 +160,11 @@ use support::{ dispatch::Result, }; use sr_primitives::{ - transaction_validity::{ - TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, - TransactionValidity, - }, traits::{ Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, - Saturating, Bounded, SignedExtension, SaturatedConversion, Convert, + Saturating, Bounded, }, - weights::{DispatchInfo, SimpleDispatchInfo, Weight}, + weights::SimpleDispatchInfo, }; use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; @@ -210,15 +195,6 @@ pub trait Subtrait: system::Trait { /// The fee required to create an account. type CreationFee: Get; - - /// The fee to be paid for making a transaction; the base. - type TransactionBaseFee: Get; - - /// The fee to be paid for making a transaction; the per-byte portion. - type TransactionByteFee: Get; - - /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: Convert; } pub trait Trait: system::Trait { @@ -235,9 +211,6 @@ pub trait Trait: system::Trait { /// Handler for when a new account is created. type OnNewAccount: OnNewAccount; - /// Handler for the unbalanced reduction when taking transaction fees. - type TransactionPayment: OnUnbalanced>; - /// Handler for the unbalanced reduction when taking fees associated with balance /// transfer (which may also include account creation). type TransferPayment: OnUnbalanced>; @@ -256,15 +229,6 @@ pub trait Trait: system::Trait { /// The fee required to create an account. type CreationFee: Get; - - /// The fee to be paid for making a transaction; the base. - type TransactionBaseFee: Get; - - /// The fee to be paid for making a transaction; the per-byte portion. - type TransactionByteFee: Get; - - /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: Convert; } impl, I: Instance> Subtrait for T { @@ -274,9 +238,6 @@ impl, I: Instance> Subtrait for T { type ExistentialDeposit = T::ExistentialDeposit; type TransferFee = T::TransferFee; type CreationFee = T::CreationFee; - type TransactionBaseFee = T::TransactionBaseFee; - type TransactionByteFee = T::TransactionByteFee; - type WeightToFee = T::WeightToFee; } decl_event!( @@ -414,12 +375,6 @@ decl_module! { /// The fee required to create an account. const CreationFee: T::Balance = T::CreationFee::get(); - /// The fee to be paid for making a transaction; the base. - const TransactionBaseFee: T::Balance = T::TransactionBaseFee::get(); - - /// The fee to be paid for making a transaction; the per-byte portion. - const TransactionByteFee: T::Balance = T::TransactionByteFee::get(); - fn deposit_event() = default; /// Transfer some liquid free balance to another account. @@ -776,7 +731,7 @@ mod imbalances { // This works as long as `increase_total_issuance_by` doesn't use the Imbalance // types (basically for charging fees). // This should eventually be refactored so that the three type items that do -// depend on the Imbalance type (TransactionPayment, TransferPayment, DustRemoval) +// depend on the Imbalance type (TransferPayment, DustRemoval) // are placed in their own SRML module. struct ElevatedTrait, I: Instance>(T, I); impl, I: Instance> Clone for ElevatedTrait { @@ -809,15 +764,11 @@ impl, I: Instance> Trait for ElevatedTrait { type OnFreeBalanceZero = T::OnFreeBalanceZero; type OnNewAccount = T::OnNewAccount; type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = T::ExistentialDeposit; type TransferFee = T::TransferFee; type CreationFee = T::CreationFee; - type TransactionBaseFee = T::TransactionBaseFee; - type TransactionByteFee = T::TransactionByteFee; - type WeightToFee = T::WeightToFee; } impl, I: Instance> Currency for Module @@ -1187,91 +1138,6 @@ where } } -/// Require the transactor pay for themselves and maybe include a tip to gain additional priority -/// in the queue. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct TakeFees, I: Instance = DefaultInstance>(#[codec(compact)] T::Balance); - -impl, I: Instance> TakeFees { - /// utility constructor. Used only in client/factory code. - pub fn from(fee: T::Balance) -> Self { - Self(fee) - } - - /// Compute the final fee value for a particular transaction. - /// - /// The final fee is composed of: - /// - _length-fee_: This is the amount paid merely to pay for size of the transaction. - /// - _weight-fee_: This amount is computed based on the weight of the transaction. Unlike - /// size-fee, this is not input dependent and reflects the _complexity_ of the execution - /// and the time it consumes. - /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed - /// transactions can have a tip. - fn compute_fee(len: usize, info: DispatchInfo, tip: T::Balance) -> T::Balance { - let len_fee = if info.pay_length_fee() { - let len = T::Balance::from(len as u32); - let base = T::TransactionBaseFee::get(); - let per_byte = T::TransactionByteFee::get(); - base.saturating_add(per_byte.saturating_mul(len)) - } else { - Zero::zero() - }; - - let weight_fee = { - // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` - // maximum of its data type, which is not desired. - let capped_weight = info.weight.min(::MaximumBlockWeight::get()); - let weight_update = >::next_weight_multiplier(); - let adjusted_weight = weight_update.apply_to(capped_weight); - T::WeightToFee::convert(adjusted_weight) - }; - - len_fee.saturating_add(weight_fee).saturating_add(tip) - } -} - -#[cfg(feature = "std")] -impl, I: Instance> rstd::fmt::Debug for TakeFees { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - self.0.fmt(f) - } -} - -impl, I: Instance + Clone + Eq> SignedExtension for TakeFees { - type AccountId = T::AccountId; - type Call = T::Call; - type AdditionalSigned = (); - type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } - - fn validate( - &self, - who: &Self::AccountId, - _call: &Self::Call, - info: DispatchInfo, - len: usize, - ) -> TransactionValidity { - // pay any fees. - let fee = Self::compute_fee(len, info, self.0); - let imbalance = match >::withdraw( - who, - fee, - WithdrawReason::TransactionPayment, - ExistenceRequirement::KeepAlive, - ) { - Ok(imbalance) => imbalance, - Err(_) => return InvalidTransaction::Payment.into(), - }; - T::TransactionPayment::on_unbalanced(imbalance); - - let mut r = ValidTransaction::default(); - // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which - // will be a bit more than setting the priority to tip. For now, this is enough. - r.priority = fee.saturated_into::(); - Ok(r) - } -} - impl, I: Instance> IsDeadAccount for Module where T::Balance: MaybeSerializeDebug diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index a909795178913..54fe850609315 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -18,7 +18,7 @@ #![cfg(test)] -use sr_primitives::{Perbill, traits::{Convert, IdentityLookup}, testing::Header, +use sr_primitives::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header, weights::{DispatchInfo, Weight}}; use primitives::H256; use runtime_io; @@ -35,10 +35,6 @@ thread_local! { static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); static TRANSFER_FEE: RefCell = RefCell::new(0); static CREATION_FEE: RefCell = RefCell::new(0); - static TRANSACTION_BASE_FEE: RefCell = RefCell::new(0); - static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); - static TRANSACTION_WEIGHT_FEE: RefCell = RefCell::new(1); - static WEIGHT_TO_FEE: RefCell = RefCell::new(1); } pub struct ExistentialDeposit; @@ -56,23 +52,6 @@ impl Get for CreationFee { fn get() -> u64 { CREATION_FEE.with(|v| *v.borrow()) } } -pub struct TransactionBaseFee; -impl Get for TransactionBaseFee { - fn get() -> u64 { TRANSACTION_BASE_FEE.with(|v| *v.borrow()) } -} - -pub struct TransactionByteFee; -impl Get for TransactionByteFee { - fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) } -} - -pub struct WeightToFee(u64); -impl Convert for WeightToFee { - fn convert(t: Weight) -> u64 { - WEIGHT_TO_FEE.with(|v| *v.borrow() * (t as u64)) - } -} - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; @@ -100,26 +79,31 @@ impl system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); } +parameter_types! { + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 1; +} +impl transaction_payment::Trait for Runtime { + type Currency = Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); + } impl Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = WeightToFee; } pub struct ExtBuilder { - transaction_base_fee: u64, - transaction_byte_fee: u64, - weight_to_fee: u64, existential_deposit: u64, transfer_fee: u64, creation_fee: u64, @@ -129,9 +113,6 @@ pub struct ExtBuilder { impl Default for ExtBuilder { fn default() -> Self { Self { - transaction_base_fee: 0, - transaction_byte_fee: 0, - weight_to_fee: 0, existential_deposit: 0, transfer_fee: 0, creation_fee: 0, @@ -141,12 +122,6 @@ impl Default for ExtBuilder { } } impl ExtBuilder { - pub fn transaction_fees(mut self, base_fee: u64, byte_fee: u64, weight_fee: u64) -> Self { - self.transaction_base_fee = base_fee; - self.transaction_byte_fee = byte_fee; - self.weight_to_fee = weight_fee; - self - } pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { self.existential_deposit = existential_deposit; self @@ -175,9 +150,6 @@ impl ExtBuilder { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); TRANSFER_FEE.with(|v| *v.borrow_mut() = self.transfer_fee); CREATION_FEE.with(|v| *v.borrow_mut() = self.creation_fee); - TRANSACTION_BASE_FEE.with(|v| *v.borrow_mut() = self.transaction_base_fee); - TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.transaction_byte_fee); - WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee); } pub fn build(self) -> runtime_io::TestExternalities { self.set_associated_consts(); @@ -211,7 +183,6 @@ impl ExtBuilder { pub type System = system::Module; pub type Balances = Module; - pub const CALL: &::Call = &(); /// create a transaction info struct from weight. Handy to avoid building the whole struct. diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index b4745c2253e4f..a61e68fc4c99d 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -20,12 +20,13 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; -use sr_primitives::set_and_run_with_externalities; +use sr_primitives::{set_and_run_with_externalities, traits::SignedExtension}; use support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency} }; +use transaction_payment::ChargeTransactionPayment; use system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; @@ -115,7 +116,7 @@ fn lock_reasons_should_work() { set_and_run_with_externalities( &mut ExtBuilder::default() .existential_deposit(1) - .monied(true).transaction_fees(0, 1, 0) + .monied(true) .build(), || { Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into()); @@ -125,8 +126,9 @@ fn lock_reasons_should_work() { ); assert_ok!(>::reserve(&1, 1)); // NOTE: this causes a fee payment. - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + // TODO: maybe don't depend on this. + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), @@ -139,8 +141,8 @@ fn lock_reasons_should_work() { >::reserve(&1, 1), "account liquidity restrictions prevent withdrawal" ); - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), @@ -150,8 +152,8 @@ fn lock_reasons_should_work() { Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::TransactionPayment.into()); assert_ok!(>::transfer(&1, &2, 1)); assert_ok!(>::reserve(&1, 1)); - assert!( as SignedExtension>::pre_dispatch( - TakeFees::from(1), + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), &1, CALL, info_from_weight(1), @@ -768,46 +770,6 @@ fn liquid_funds_should_transfer_with_delayed_vesting() { ); } -#[test] -fn signed_extension_take_fees_work() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .transaction_fees(10, 1, 5) - .monied(true) - .build(), - || { - let len = 10; - assert!(TakeFees::::from(0).pre_dispatch(&1, CALL, info_from_weight(5), len).is_ok()); - assert_eq!(Balances::free_balance(&1), 100 - 20 - 25); - assert!(TakeFees::::from(5 /* tipped */).pre_dispatch(&1, CALL, info_from_weight(3), len).is_ok()); - assert_eq!(Balances::free_balance(&1), 100 - 20 - 25 - 20 - 5 - 15); - } - ); -} - -#[test] -fn signed_extension_take_fees_is_bounded() { - set_and_run_with_externalities( - &mut ExtBuilder::default() - .existential_deposit(1000) - .transaction_fees(0, 0, 1) - .monied(true) - .build(), - || { - use sr_primitives::weights::Weight; - - // maximum weight possible - assert!(TakeFees::::from(0).pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10).is_ok()); - // fee will be proportional to what is the actual maximum weight in the runtime. - assert_eq!( - Balances::free_balance(&1), - (10000 - ::MaximumBlockWeight::get()) as u64 - ); - } - ); -} - #[test] fn burn_must_work() { set_and_run_with_externalities( diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 678fc65d769cb..3d8a455ad7b83 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -442,7 +442,7 @@ where } /// The default dispatch fee computor computes the fee in the same way that -/// the implementation of `TakeFees` for the Balances module does. Note that this only takes a fixed +/// the implementation of `ChargeTransactionPayment` for the Balances module does. Note that this only takes a fixed /// fee based on size. Unlike the balances module, weight-fee is applied. pub struct DefaultDispatchFeeComputor(PhantomData); impl ComputeDispatchFee<::Call, BalanceOf> for DefaultDispatchFeeComputor { diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 9d02419b17621..96ae06960c7b4 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -96,8 +96,6 @@ parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: u32 = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; - pub const BalancesTransactionBaseFee: u64 = 0; - pub const BalancesTransactionByteFee: u64 = 0; pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl system::Trait for Test { @@ -123,15 +121,11 @@ impl balances::Trait for Test { type OnFreeBalanceZero = Contract; type OnNewAccount = (); type Event = MetaEvent; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = BalancesTransactionBaseFee; - type TransactionByteFee = BalancesTransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const MinimumPeriod: u64 = 1; diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index e65cf9ace19ca..b724fd291e5ea 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -127,24 +127,18 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 1; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); type Event = Event; - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type Error = Error; type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const LaunchPeriod: u64 = 1; diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 477e6818c969b..ff626c1bfc5b3 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -1030,23 +1030,17 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const LaunchPeriod: u64 = 2; diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 1405536267eda..68c17b816206b 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -628,8 +628,6 @@ mod tests { pub const ExistentialDeposit: u64 = 1; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { @@ -637,15 +635,11 @@ mod tests { type OnNewAccount = (); type OnFreeBalanceZero = (); type Event = Event; - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { diff --git a/srml/elections/src/mock.rs b/srml/elections/src/mock.rs index b9e548e1ed2a4..7e1a8b0edaff0 100644 --- a/srml/elections/src/mock.rs +++ b/srml/elections/src/mock.rs @@ -60,23 +60,17 @@ parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); type Event = Event; - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 08adf9efa77bf..4dc23bcdafef6 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -679,23 +679,17 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } impl Trait for Test { type Event = (); diff --git a/srml/executive/Cargo.toml b/srml/executive/Cargo.toml index a87eed40b75df..92191a7aac4db 100644 --- a/srml/executive/Cargo.toml +++ b/srml/executive/Cargo.toml @@ -18,6 +18,7 @@ hex-literal = "0.2.1" primitives = { package = "substrate-primitives", path = "../../core/primitives" } srml-indices = { path = "../indices" } balances = { package = "srml-balances", path = "../balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../transaction-payment" } [features] default = ["std"] diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index f1509f1760cf1..6814cdc91f22f 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -358,23 +358,30 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 10; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = MetaEvent; - type TransactionPayment = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; + } + + parameter_types! { + pub const TransactionBaseFee: u64 = 10; + pub const TransactionByteFee: u64 = 0; + } + impl transaction_payment::Trait for Runtime { + type Currency = Balances; + type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); } impl ValidateUnsigned for Runtime { @@ -392,7 +399,7 @@ mod tests { system::CheckEra, system::CheckNonce, system::CheckWeight, - balances::TakeFees + transaction_payment::ChargeTransactionPayment ); type TestXt = sr_primitives::testing::TestXt; type Executive = super::Executive, system::ChainContext, Runtime, ()>; @@ -402,7 +409,7 @@ mod tests { system::CheckEra::from(Era::Immortal), system::CheckNonce::from(nonce), system::CheckWeight::new(), - balances::TakeFees::from(fee) + transaction_payment::ChargeTransactionPayment::from(fee) ) } diff --git a/srml/scored-pool/src/mock.rs b/srml/scored-pool/src/mock.rs index 92a16bf25d6f6..2a7370b05e282 100644 --- a/srml/scored-pool/src/mock.rs +++ b/srml/scored-pool/src/mock.rs @@ -52,8 +52,6 @@ parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl system::Trait for Test { @@ -80,15 +78,11 @@ impl balances::Trait for Test { type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } thread_local! { diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 9055d7db87429..533370be9d603 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -129,23 +129,17 @@ impl system::Trait for Test { parameter_types! { pub const TransferFee: Balance = 0; pub const CreationFee: Balance = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = Balance; type OnFreeBalanceZero = Staking; type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const Period: BlockNumber = 1; diff --git a/srml/transaction-payment/Cargo.toml b/srml/transaction-payment/Cargo.toml index 15b41e7ceef1a..7f8eddab19d98 100644 --- a/srml/transaction-payment/Cargo.toml +++ b/srml/transaction-payment/Cargo.toml @@ -14,6 +14,7 @@ system = { package = "srml-system", path = "../system", default-features = false [dev-dependencies] runtime-io = { package = "sr-io", path = "../../core/sr-io" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } +balances = { package = "srml-balances", path = "../balances" } [features] default = ["std"] diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index bc2de0308e1a6..59db331ac060d 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -49,9 +49,9 @@ use sr_primitives::{ }; type Multiplier = Fixed64; -pub type BalanceOf = +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub type NegativeImbalanceOf = +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: system::Trait { @@ -77,7 +77,7 @@ pub trait Trait: system::Trait { decl_storage! { trait Store for Module as Balances { - NextFeeMultiplier get(next_fee_multiplier): Multiplier = Multiplier::one(); + NextFeeMultiplier get(next_fee_multiplier): Multiplier = Default::default(); // todo explicit zero } } @@ -103,9 +103,9 @@ impl Module {} /// Require the transactor pay for themselves and maybe include a tip to gain additional priority /// in the queue. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); +pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); -impl ChargeTransactionPayment { +impl ChargeTransactionPayment { /// utility constructor. Used only in client/factory code. pub fn from(fee: BalanceOf) -> Self { Self(fee) @@ -140,19 +140,18 @@ impl ChargeTransactionPayment { let adjusted_fee = fee_update.saturated_multiply_accumulate(fee); adjusted_fee }; - len_fee.saturating_add(weight_fee).saturating_add(tip) } } #[cfg(feature = "std")] -impl rstd::fmt::Debug for ChargeTransactionPayment { +impl rstd::fmt::Debug for ChargeTransactionPayment { fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - self.0.fmt(f) + write!(f, "ChargeTransactionPayment<{:?}>", self.0) } } -impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync { +impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync { type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = (); @@ -187,3 +186,211 @@ impl SignedExtension for ChargeTransactionPayment where BalanceOf::Call = &(); + + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct Runtime; + + impl_outer_origin!{ + pub enum Origin for Runtime {} + } + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + + impl system::Trait for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type WeightMultiplierUpdate = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + + parameter_types! { + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + pub const ExistentialDeposit: u64 = 0; + } + + impl balances::Trait for Runtime { + type Balance = u64; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + } + + thread_local! { + static TRANSACTION_BASE_FEE: RefCell = RefCell::new(0); + static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); + static WEIGHT_TO_FEE: RefCell = RefCell::new(1); + } + + pub struct TransactionBaseFee; + impl Get for TransactionBaseFee { + fn get() -> u64 { TRANSACTION_BASE_FEE.with(|v| *v.borrow()) } + } + + pub struct TransactionByteFee; + impl Get for TransactionByteFee { + fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) } + } + + pub struct WeightToFee(u64); + impl Convert for WeightToFee { + fn convert(t: Weight) -> u64 { + WEIGHT_TO_FEE.with(|v| *v.borrow() * (t as u64)) + } + } + + impl Trait for Runtime { + type Currency = balances::Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = WeightToFee; + type FeeMultiplierUpdate = (); + } + + type System = system::Module; + type Balances = balances::Module; + + pub struct ExtBuilder { + balance_factor: u64, + base_fee: u64, + byte_fee: u64, + weight_to_fee: u64 + } + + impl Default for ExtBuilder { + fn default() -> Self { + Self { + balance_factor: 1, + base_fee: 0, + byte_fee: 1, + weight_to_fee: 1, + } + } + } + + impl ExtBuilder { + pub fn fees(mut self, base: u64, byte: u64, weight: u64) -> Self { + self.base_fee = base; + self.byte_fee = byte; + self.weight_to_fee = weight; + self + } + pub fn balance_factor(mut self, factor: u64) -> Self { + self.balance_factor = factor; + self + } + fn set_constants(&self) { + TRANSACTION_BASE_FEE.with(|v| *v.borrow_mut() = self.base_fee); + TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.byte_fee); + WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee); + } + pub fn build(self) -> runtime_io::TestExternalities { + self.set_constants(); + let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + balances::GenesisConfig:: { + balances: vec![ + (1, 10 * self.balance_factor), + (2, 20 * self.balance_factor), + (3, 30 * self.balance_factor), + (4, 40 * self.balance_factor), + (5, 50 * self.balance_factor), + (6, 60 * self.balance_factor) + ], + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + t.into() + } + } + + /// create a transaction info struct from weight. Handy to avoid building the whole struct. + pub fn info_from_weight(w: Weight) -> DispatchInfo { + DispatchInfo { weight: w, ..Default::default() } + } + + #[test] + fn signed_extension_transaction_payment_work() { + set_and_run_with_externalities(&mut + ExtBuilder::default() + .balance_factor(10) // 100 + .fees(5, 1, 1) // 5 fixed, 1 per byte, 1 per weight + .build(), || + { + let len = 10; + assert!( + ChargeTransactionPayment::::from(0) + .pre_dispatch(&1, CALL, info_from_weight(5), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&1), 100 - 5 - 5 - 10); + + assert!( + ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, info_from_weight(3), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&2), 200 - 5 - 10 - 3 - 5); + }); + } + + #[test] + fn signed_extension_transaction_payment_is_bounded() { + set_and_run_with_externalities(&mut + ExtBuilder::default() + .balance_factor(1000) + .fees(0, 0, 1) + .build(), || + { + use sr_primitives::weights::Weight; + + // maximum weight possible + assert!( + ChargeTransactionPayment::::from(0) + .pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10) + .is_ok() + ); + // fee will be proportional to what is the actual maximum weight in the runtime. + assert_eq!( + Balances::free_balance(&1), + (10000 - ::MaximumBlockWeight::get()) as u64 + ); + }); + } +} + diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 8ccc260fa788d..511a2749f61e2 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -396,23 +396,17 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } parameter_types! { pub const ProposalBond: Permill = Permill::from_percent(5); diff --git a/srml/utility/src/lib.rs b/srml/utility/src/lib.rs index a9009a3a7e1c1..7e2bdd0ec8566 100644 --- a/srml/utility/src/lib.rs +++ b/srml/utility/src/lib.rs @@ -114,23 +114,17 @@ mod tests { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; - pub const TransactionBaseFee: u64 = 0; - pub const TransactionByteFee: u64 = 0; } impl balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); type Event = (); - type TransactionPayment = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type TransferFee = TransferFee; type CreationFee = CreationFee; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = (); } impl Trait for Test { type Event = (); diff --git a/subkey/Cargo.toml b/subkey/Cargo.toml index 1b1a697d0fa67..3f76e3f92c20b 100644 --- a/subkey/Cargo.toml +++ b/subkey/Cargo.toml @@ -19,6 +19,7 @@ hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.0.0" } system = { package = "srml-system", path = "../srml/system" } balances = { package = "srml-balances", path = "../srml/balances" } +transaction-payment = { package = "srml-transaction-payment", path = "../srml/transaction-payment" } [features] bench = [] diff --git a/subkey/src/main.rs b/subkey/src/main.rs index 973502b3d6810..2596513ab28b5 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -363,7 +363,7 @@ fn create_extrinsic( system::CheckEra::::from(Era::Immortal), system::CheckNonce::::from(i), system::CheckWeight::::new(), - balances::TakeFees::::from(f), + transaction_payment::ChargeTransactionPayment::::from(f), Default::default(), ) }; From 9b9971d15cca20a6e018b2573d306a3eefdcff8c Mon Sep 17 00:00:00 2001 From: kianenigma Date: Mon, 14 Oct 2019 10:52:13 +0200 Subject: [PATCH 06/11] Extract multiplier update stuff from system --- core/sr-primitives/src/sr_arithmetic.rs | 39 ++++- core/sr-primitives/src/weights.rs | 76 ---------- core/test-runtime/src/lib.rs | 1 - node-template/runtime/src/lib.rs | 2 - node-template/runtime/src/template.rs | 1 - node/executor/src/lib.rs | 25 +-- node/runtime/src/constants.rs | 8 +- node/runtime/src/impls.rs | 168 +++++++++++++-------- node/runtime/src/lib.rs | 6 +- srml/assets/src/lib.rs | 1 - srml/aura/src/mock.rs | 1 - srml/authority-discovery/src/lib.rs | 1 - srml/authorship/src/lib.rs | 1 - srml/babe/src/mock.rs | 1 - srml/balances/src/lib.rs | 1 - srml/balances/src/mock.rs | 1 - srml/collective/src/lib.rs | 1 - srml/contracts/src/tests.rs | 1 - srml/council/src/lib.rs | 1 - srml/democracy/src/lib.rs | 1 - srml/elections-phragmen/src/lib.rs | 1 - srml/elections/src/mock.rs | 1 - srml/example/src/lib.rs | 1 - srml/executive/src/lib.rs | 3 +- srml/finality-tracker/src/lib.rs | 1 - srml/generic-asset/src/lib.rs | 1 - srml/generic-asset/src/mock.rs | 1 - srml/grandpa/src/mock.rs | 1 - srml/im-online/src/mock.rs | 1 - srml/indices/src/mock.rs | 1 - srml/membership/src/lib.rs | 1 - srml/offences/src/mock.rs | 1 - srml/randomness-collective-flip/src/lib.rs | 1 - srml/scored-pool/src/mock.rs | 1 - srml/session/src/mock.rs | 1 - srml/staking/src/mock.rs | 1 - srml/system/benches/bench.rs | 1 - srml/system/src/lib.rs | 28 +--- srml/timestamp/src/lib.rs | 1 - srml/transaction-payment/src/lib.rs | 1 - srml/treasury/src/lib.rs | 1 - srml/utility/src/lib.rs | 1 - 42 files changed, 164 insertions(+), 224 deletions(-) diff --git a/core/sr-primitives/src/sr_arithmetic.rs b/core/sr-primitives/src/sr_arithmetic.rs index 043a383a33244..5f5b5dc1e523b 100644 --- a/core/sr-primitives/src/sr_arithmetic.rs +++ b/core/sr-primitives/src/sr_arithmetic.rs @@ -543,7 +543,6 @@ implement_per_thing!( /// An unsigned fixed point number. Can hold any value in the range [-9_223_372_036, 9_223_372_036] /// with fixed point accuracy of one billion. -#[cfg_attr(feature = "std", derive(Debug))] #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Fixed64(i64); @@ -668,6 +667,13 @@ impl CheckedAdd for Fixed64 { } } +#[cfg(feature = "std")] +impl rstd::fmt::Debug for Fixed64 { + fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000) + } +} + /// Infinite precision unsigned integer for substrate runtime. pub mod biguint { use super::Zero; @@ -981,8 +987,6 @@ pub mod biguint { let mut q = Self::with_capacity(m + 1); let mut r = Self::with_capacity(n); - debug_assert!(other.msb() != 0); - // PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are // safe. let normalizer_bits = other.msb().leading_zeros() as Single; @@ -2136,6 +2140,35 @@ mod tests_fixed64 { assert_eq!(max(), Fixed64::from_natural(9_223_372_037)); } + #[test] + fn fixed_64_growth_decrease_curve() { + let test_set = vec![0u32, 1, 10, 1000, 1_000_000_000]; + + // negative (1/2) + let mut fm = Fixed64::from_rational(-1, 2); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i) as i32, i as i32 - i as i32 / 2); + }); + + // unit (1) multiplier + fm = Fixed64::from_parts(0); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i); + }); + + // i.5 multiplier + fm = Fixed64::from_rational(1, 2); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i * 3 / 2); + }); + + // dual multiplier + fm = Fixed64::from_rational(1, 1); + test_set.clone().into_iter().for_each(|i| { + assert_eq!(fm.saturated_multiply_accumulate(i), i * 2); + }); + } + macro_rules! saturating_mul_acc_test { ($num_type:tt) => { assert_eq!( diff --git a/core/sr-primitives/src/weights.rs b/core/sr-primitives/src/weights.rs index 28f1b2fe0cfc4..2ffd4ee3917e1 100644 --- a/core/sr-primitives/src/weights.rs +++ b/core/sr-primitives/src/weights.rs @@ -23,9 +23,6 @@ //! Note that the decl_module macro _cannot_ enforce this and will simply fail if an invalid struct //! (something that does not implement `Weighable`) is passed in. -use crate::{Fixed64, traits::Saturating}; -use crate::codec::{Encode, Decode}; - pub use crate::transaction_validity::TransactionPriority; use crate::traits::Bounded; @@ -167,76 +164,3 @@ impl Default for SimpleDispatchInfo { SimpleDispatchInfo::FixedNormal(10_000) } } - -/// Representation of a weight multiplier. This represents how a fee value can be computed from a -/// weighted transaction. -/// -/// This is basically a wrapper for the `Fixed64` type a slightly tailored multiplication to u32 -/// in the form of the `apply_to` method. -#[cfg_attr(feature = "std", derive(Debug))] -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct WeightMultiplier(Fixed64); - -impl WeightMultiplier { - /// Apply the inner Fixed64 as a weight multiplier to a weight value. - /// - /// This will perform a saturated `weight + weight * self.0`. - pub fn apply_to(&self, weight: Weight) -> Weight { - self.0.saturated_multiply_accumulate(weight) - } - - /// build self from raw parts per billion. - #[cfg(feature = "std")] - pub fn from_parts(parts: i64) -> Self { - Self(Fixed64::from_parts(parts)) - } - - /// build self from a fixed64 value. - pub fn from_fixed(f: Fixed64) -> Self { - Self(f) - } - - /// Approximate the fraction `n/d`. - pub fn from_rational(n: i64, d: u64) -> Self { - Self(Fixed64::from_rational(n, d)) - } -} - -impl Saturating for WeightMultiplier { - fn saturating_add(self, rhs: Self) -> Self { - Self(self.0.saturating_add(rhs.0)) - } - fn saturating_mul(self, rhs: Self) -> Self { - Self(self.0.saturating_mul(rhs.0)) - - } - fn saturating_sub(self, rhs: Self) -> Self { - Self(self.0.saturating_sub(rhs.0)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn multiplier_apply_to_works() { - let test_set = vec![0, 1, 10, 1000, 1_000_000_000]; - - // negative (1/2) - let mut fm = WeightMultiplier::from_rational(-1, 2); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i) as i32, i as i32 - i as i32 / 2); }); - - // unit (1) multiplier - fm = WeightMultiplier::from_parts(0); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i); }); - - // i.5 multiplier - fm = WeightMultiplier::from_rational(1, 2); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i * 3 / 2); }); - - // dual multiplier - fm = WeightMultiplier::from_rational(1, 1); - test_set.clone().into_iter().for_each(|i| { assert_eq!(fm.apply_to(i), i * 2); }); - } -} diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index e75cb69149d8d..1c7571aacabcb 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -382,7 +382,6 @@ impl srml_system::Trait for Runtime { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index a0a1c539932b8..053de44c57a3d 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -166,8 +166,6 @@ impl system::Trait for Runtime { type Header = generic::Header; /// The ubiquitous event type. type Event = Event; - /// Update weight (to fee) multiplier per-block. - type WeightMultiplierUpdate = (); /// The ubiquitous origin type. type Origin = Origin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index 0266890dd801e..b1d4f4e7cec6d 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -101,7 +101,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 66499eb69d2e1..e95d671a417fa 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -46,16 +46,16 @@ mod tests { traits::{CodeExecutor, Externalities}, storage::well_known_keys, }; use sr_primitives::{ - assert_eq_error_rate, + assert_eq_error_rate, Fixed64, traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult, - transaction_validity::InvalidTransaction, weights::{WeightMultiplier, GetDispatchInfo}, + transaction_validity::InvalidTransaction, weights::GetDispatchInfo, }; use contracts::ContractAddressFor; use substrate_executor::{NativeExecutor, WasmExecutionMethod}; use system::{EventRecord, Phase}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, - System, Event, TransferFee, TransactionBaseFee, TransactionByteFee, + System, TransactionPayment, Event, TransferFee, TransactionBaseFee, TransactionByteFee, constants::currency::*, impls::WeightToFee, }; use node_primitives::{Balance, Hash, BlockNumber}; @@ -96,7 +96,7 @@ mod tests { let weight = default_transfer_call().get_dispatch_info().weight; // NOTE: this is really hard to apply, since the multiplier of each block needs to be fetched // before the block, while we compute this after the block. - // weight = >::next_weight_multiplier().apply_to(weight); + // weight = TransactionPayment::next_fee_multiplier().apply_to(weight); let weight_fee = ::WeightToFee::convert(weight); length_fee + weight_fee + TransferFee::get() } @@ -890,13 +890,14 @@ mod tests { #[test] - fn weight_multiplier_increases_and_decreases_on_big_weight() { + fn fee_multiplier_increases_and_decreases_on_big_weight() { let mut t = new_test_ext(COMPACT_CODE, false); - let mut prev_multiplier = WeightMultiplier::default(); + // initial fee multiplier must be zero + let mut prev_multiplier = Fixed64::from_parts(0); sr_primitives::set_and_run_with_externalities(&mut t, || { - assert_eq!(System::next_weight_multiplier(), prev_multiplier); + assert_eq!(TransactionPayment::next_fee_multiplier(), prev_multiplier); }); let mut tt = new_test_ext(COMPACT_CODE, false); @@ -946,9 +947,9 @@ mod tests { None, ).0.unwrap(); - // weight multiplier is increased for next block. + // fee multiplier is increased for next block. sr_primitives::set_and_run_with_externalities(&mut t, || { - let fm = System::next_weight_multiplier(); + let fm = TransactionPayment::next_fee_multiplier(); println!("After a big block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm > prev_multiplier); prev_multiplier = fm; @@ -965,7 +966,7 @@ mod tests { // weight multiplier is increased for next block. sr_primitives::set_and_run_with_externalities(&mut t, || { - let fm = System::next_weight_multiplier(); + let fm = TransactionPayment::next_fee_multiplier(); println!("After a small block: {:?} -> {:?}", prev_multiplier, fm); assert!(fm < prev_multiplier); }); @@ -978,7 +979,7 @@ mod tests { // weight of transfer call as of now: 1_000_000 // if weight of the cheapest weight would be 10^7, this would be 10^9, which is: // - 1 MILLICENTS in substrate node. - // - 1 milldot based on current polkadot runtime. + // - 1 milli-dot based on current polkadot runtime. // (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`) let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ >::hashed_key_for(alice()) => { @@ -1052,6 +1053,7 @@ mod tests { fn block_weight_capacity_report() { // Just report how many transfer calls you could fit into a block. The number should at least // be a few hundred (250 at the time of writing but can change over time). Runs until panic. + use node_primitives::Index; // execution ext. let mut t = new_test_ext(COMPACT_CODE, false); @@ -1118,6 +1120,7 @@ mod tests { // Just report how big a block can get. Executes until panic. Should be ignored unless if // manually inspected. The number should at least be a few megabytes (5 at the time of // writing but can change over time). + use node_primitives::Index; // execution ext. let mut t = new_test_ext(COMPACT_CODE, false); diff --git a/node/runtime/src/constants.rs b/node/runtime/src/constants.rs index 79d3dbd8eb2bc..ca57bdc8ba9fc 100644 --- a/node/runtime/src/constants.rs +++ b/node/runtime/src/constants.rs @@ -67,10 +67,10 @@ pub mod time { pub const DAYS: BlockNumber = HOURS * 24; } -// CRITICAL NOTE: The system module maintains two constants: a _maximum_ block weight and a -// _ratio_ of it yielding the portion which is accessible to normal transactions (reserving the rest -// for operational ones). `TARGET_BLOCK_FULLNESS` is entirely independent and the system module is -// not aware of if, nor should it care about it. This constant simply denotes on which ratio of the +// CRITICAL NOTE: The system module maintains two constants: a _maximum_ block weight and a _ratio_ +// of it yielding the portion which is accessible to normal transactions (reserving the rest for +// operational ones). `TARGET_BLOCK_FULLNESS` is entirely independent and the system module is not +// aware of if, nor should it care about it. This constant simply denotes on which ratio of the // _maximum_ block weight we tweak the fees. It does NOT care about the type of the dispatch. // // For the system to be configured in a sane way, `TARGET_BLOCK_FULLNESS` should always be less than diff --git a/node/runtime/src/impls.rs b/node/runtime/src/impls.rs index 6c0c59b20044d..703516e1de3e2 100644 --- a/node/runtime/src/impls.rs +++ b/node/runtime/src/impls.rs @@ -17,7 +17,7 @@ //! Some configurable implementations as associated type for the substrate runtime. use node_primitives::Balance; -use sr_primitives::weights::{Weight, WeightMultiplier}; +use sr_primitives::weights::Weight; use sr_primitives::traits::{Convert, Saturating}; use sr_primitives::Fixed64; use support::traits::{OnUnbalanced, Currency}; @@ -82,10 +82,10 @@ impl Convert for WeightToFee { /// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2) /// /// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct WeightMultiplierUpdateHandler; +pub struct FeeMultiplierUpdateHandler; -impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierUpdateHandler { - fn convert(previous_state: (Weight, WeightMultiplier)) -> WeightMultiplier { +impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { + fn convert(previous_state: (Weight, Fixed64)) -> Fixed64 { let (block_weight, multiplier) = previous_state; let max_weight = MaximumBlockWeight::get(); let target_weight = (TARGET_BLOCK_FULLNESS * max_weight) as u128; @@ -113,17 +113,17 @@ impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierU // Note: this is merely bounded by how big the multiplier and the inner value can go, // not by any economical reasoning. let excess = first_term.saturating_add(second_term); - multiplier.saturating_add(WeightMultiplier::from_fixed(excess)) + multiplier.saturating_add(excess) } else { - // first_term > second_term + // Proof: first_term > second_term. Safe subtraction. let negative = first_term - second_term; - multiplier.saturating_sub(WeightMultiplier::from_fixed(negative)) + multiplier.saturating_sub(negative) // despite the fact that apply_to saturates weight (final fee cannot go below 0) // it is crucially important to stop here and don't further reduce the weight fee // multiplier. While at -1, it means that the network is so un-congested that all // transactions have no weight fee. We stop here and only increase if the network // became more busy. - .max(WeightMultiplier::from_rational(-1, 1)) + .max(Fixed64::from_rational(-1, 1)) } } } @@ -132,7 +132,6 @@ impl Convert<(Weight, WeightMultiplier), WeightMultiplier> for WeightMultiplierU mod tests { use super::*; use sr_primitives::weights::Weight; - use sr_primitives::Perbill; use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; use crate::constants::currency::*; @@ -146,7 +145,7 @@ mod tests { // poc reference implementation. #[allow(dead_code)] - fn weight_multiplier_update(block_weight: Weight) -> Perbill { + fn fee_multiplier_update(block_weight: Weight, previous: Fixed64) -> Fixed64 { let block_weight = block_weight as f32; let v: f32 = 0.00004; @@ -157,53 +156,84 @@ mod tests { // Current saturation in terms of weight let s = block_weight; - let fm = 1.0 + (v * (s/m - ss/m)) + (v.powi(2) * (s/m - ss/m).powi(2)) / 2.0; - // return a per-bill-like value. - let fm = if fm >= 1.0 { fm - 1.0 } else { 1.0 - fm }; - Perbill::from_parts((fm * 1_000_000_000_f32) as u32) + let fm = (v * (s/m - ss/m)) + (v.powi(2) * (s/m - ss/m).powi(2)) / 2.0; + let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32) as i64); + previous.saturating_add(addition_fm) } - fn wm(parts: i64) -> WeightMultiplier { - WeightMultiplier::from_parts(parts) + fn fm(parts: i64) -> Fixed64 { + Fixed64::from_parts(parts) + } + + #[test] + fn fee_multiplier_update_poc_works() { + let fm = Fixed64::from_rational(0, 1); + let test_set = vec![ + // TODO: this has a rounding error and fails. + // (0, fm.clone()), + (100, fm.clone()), + (target(), fm.clone()), + (max() / 2, fm.clone()), + (max(), fm.clone()), + ]; + test_set.into_iter().for_each(|(w, fm)| { + assert_eq!( + fee_multiplier_update(w, fm), + FeeMultiplierUpdateHandler::convert((w, fm)), + "failed for weight {} and prev fm {:?}", + w, + fm, + ); + }) } #[test] fn empty_chain_simulation() { // just a few txs per_block. let block_weight = 1000; - let mut wm = WeightMultiplier::default(); + let mut fm = Fixed64::default(); let mut iterations: u64 = 0; loop { - let next = WeightMultiplierUpdateHandler::convert((block_weight, wm)); - wm = next; - if wm == WeightMultiplier::from_rational(-1, 1) { break; } + let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); + fm = next; + if fm == Fixed64::from_rational(-1, 1) { break; } iterations += 1; } - println!("iteration {}, new wm = {:?}. Weight fee is now zero", iterations, wm); + println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); } #[test] #[ignore] fn congested_chain_simulation() { // `cargo test congested_chain_simulation -- --nocapture` to get some insight. + // almost full. The entire quota of normal transactions is taken. let block_weight = AvailableBlockRatio::get() * max(); - let tx_weight = 1000; - let mut wm = WeightMultiplier::default(); + + // default minimum substrate weight + let tx_weight = 10_000u32; + + // initial value of system + let mut fm = Fixed64::default(); + assert_eq!(fm, Fixed64::from_parts(0)); + let mut iterations: u64 = 0; loop { - let next = WeightMultiplierUpdateHandler::convert((block_weight, wm)); - if wm == next { break; } - wm = next; + let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); + if fm == next { break; } + fm = next; iterations += 1; - let fee = ::WeightToFee::convert(wm.apply_to(tx_weight)); + let fee = ::WeightToFee::convert(tx_weight); + let adjusted_fee = fm.saturated_multiply_accumulate(fee); println!( - "iteration {}, new wm = {:?}. Fee at this point is: {} millicents, {} cents, {} dollars", + "iteration {}, new fm = {:?}. Fee at this point is: \ + {} units, {} millicents, {} cents, {} dollars", iterations, - wm, - fee / MILLICENTS, - fee / CENTS, - fee / DOLLARS + fm, + adjusted_fee, + adjusted_fee / MILLICENTS, + adjusted_fee / CENTS, + adjusted_fee / DOLLARS ); } } @@ -212,65 +242,65 @@ mod tests { fn stateless_weight_mul() { // Light block. Fee is reduced a little. assert_eq!( - WeightMultiplierUpdateHandler::convert((target() / 4, WeightMultiplier::default())), - wm(-7500) + FeeMultiplierUpdateHandler::convert((target() / 4, Fixed64::default())), + fm(-7500) ); // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. assert_eq!( - WeightMultiplierUpdateHandler::convert((target() / 2, WeightMultiplier::default())), - wm(-5000) + FeeMultiplierUpdateHandler::convert((target() / 2, Fixed64::default())), + fm(-5000) ); // ideal. Original fee. No changes. assert_eq!( - WeightMultiplierUpdateHandler::convert((target(), WeightMultiplier::default())), - wm(0) + FeeMultiplierUpdateHandler::convert((target(), Fixed64::default())), + fm(0) ); // // More than ideal. Fee is increased. assert_eq!( - WeightMultiplierUpdateHandler::convert(((target() * 2), WeightMultiplier::default())), - wm(10000) + FeeMultiplierUpdateHandler::convert(((target() * 2), Fixed64::default())), + fm(10000) ); } #[test] fn stateful_weight_mul_grow_to_infinity() { assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, WeightMultiplier::default())), - wm(10000) + FeeMultiplierUpdateHandler::convert((target() * 2, Fixed64::default())), + fm(10000) ); assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(10000))), - wm(20000) + FeeMultiplierUpdateHandler::convert((target() * 2, fm(10000))), + fm(20000) ); assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(20000))), - wm(30000) + FeeMultiplierUpdateHandler::convert((target() * 2, fm(20000))), + fm(30000) ); // ... assert_eq!( - WeightMultiplierUpdateHandler::convert((target() * 2, wm(1_000_000_000))), - wm(1_000_000_000 + 10000) + FeeMultiplierUpdateHandler::convert((target() * 2, fm(1_000_000_000))), + fm(1_000_000_000 + 10000) ); } #[test] fn stateful_weight_mil_collapse_to_minus_one() { assert_eq!( - WeightMultiplierUpdateHandler::convert((0, WeightMultiplier::default())), - wm(-10000) + FeeMultiplierUpdateHandler::convert((0, Fixed64::default())), + fm(-10000) ); assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(-10000))), - wm(-20000) + FeeMultiplierUpdateHandler::convert((0, fm(-10000))), + fm(-20000) ); assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(-20000))), - wm(-30000) + FeeMultiplierUpdateHandler::convert((0, fm(-20000))), + fm(-30000) ); // ... assert_eq!( - WeightMultiplierUpdateHandler::convert((0, wm(1_000_000_000 * -1))), - wm(-1_000_000_000) + FeeMultiplierUpdateHandler::convert((0, fm(1_000_000_000 * -1))), + fm(-1_000_000_000) ); } @@ -278,20 +308,30 @@ mod tests { fn weight_to_fee_should_not_overflow_on_large_weights() { let kb = 1024 as Weight; let mb = kb * kb; - let max_fm = WeightMultiplier::from_fixed(Fixed64::from_natural(i64::max_value())); - - vec![0, 1, 10, 1000, kb, 10 * kb, 100 * kb, mb, 10 * mb, Weight::max_value() / 2, Weight::max_value()] - .into_iter() - .for_each(|i| { - WeightMultiplierUpdateHandler::convert((i, WeightMultiplier::default())); - }); + let max_fm = Fixed64::from_natural(i64::max_value()); + + vec![ + 0, + 1, + 10, + 1000, + kb, + 10 * kb, + 100 * kb, + mb, + 10 * mb, + Weight::max_value() / 2, + Weight::max_value() + ].into_iter().for_each(|i| { + FeeMultiplierUpdateHandler::convert((i, Fixed64::default())); + }); // Some values that are all above the target and will cause an increase. let t = target(); vec![t + 100, t * 2, t * 4] .into_iter() .for_each(|i| { - let fm = WeightMultiplierUpdateHandler::convert(( + let fm = FeeMultiplierUpdateHandler::convert(( i, max_fm )); diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 670a0bd7ec3b3..56505d8cf323c 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -65,7 +65,7 @@ pub use staking::StakerStatus; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{CurrencyToVoteHandler, WeightMultiplierUpdateHandler, Author, WeightToFee}; +use impls::{CurrencyToVoteHandler, FeeMultiplierUpdateHandler, Author, WeightToFee}; /// Constant values used within the runtime. pub mod constants; @@ -125,7 +125,6 @@ impl system::Trait for Runtime { type AccountId = AccountId; type Lookup = Indices; type Header = generic::Header; - type WeightMultiplierUpdate = WeightMultiplierUpdateHandler; type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; @@ -186,7 +185,7 @@ impl transaction_payment::Trait for Runtime { type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type WeightToFee = WeightToFee; - type FeeMultiplierUpdate = (); + type FeeMultiplierUpdate = FeeMultiplierUpdateHandler; } parameter_types! { @@ -512,6 +511,7 @@ construct_runtime!( Authorship: authorship::{Module, Call, Storage, Inherent}, Indices: indices, Balances: balances::{default, Error}, + TransactionPayment: transaction_payment::{Module, Storage}, // TODO double check this Staking: staking::{default, OfflineWorker}, Session: session::{Module, Call, Storage, Event, Config}, Democracy: democracy::{Module, Call, Storage, Config, Event}, diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index e7f258483fa3c..4097273cf59f8 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -274,7 +274,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs index 7ebfd2a533304..5c55e8bdd58df 100644 --- a/srml/aura/src/mock.rs +++ b/srml/aura/src/mock.rs @@ -54,7 +54,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/authority-discovery/src/lib.rs b/srml/authority-discovery/src/lib.rs index 38d587ba0555a..e3632d8eaa7a6 100644 --- a/srml/authority-discovery/src/lib.rs +++ b/srml/authority-discovery/src/lib.rs @@ -204,7 +204,6 @@ mod tests { type AccountId = AuthorityId; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index 0033e532217e4..930c0b5004fb5 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -443,7 +443,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/babe/src/mock.rs b/srml/babe/src/mock.rs index 582299f11cf5c..5a6b80a2a6717 100644 --- a/srml/babe/src/mock.rs +++ b/srml/babe/src/mock.rs @@ -62,7 +62,6 @@ impl system::Trait for Test { type AccountId = DummyValidatorId; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 877d479932ddf..94a72fc355cfc 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -751,7 +751,6 @@ impl, I: Instance> system::Trait for ElevatedTrait { type AccountId = T::AccountId; type Lookup = T::Lookup; type Header = T::Header; - type WeightMultiplierUpdate = T::WeightMultiplierUpdate; type Event = (); type BlockHashCount = T::BlockHashCount; type MaximumBlockWeight = T::MaximumBlockWeight; diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index 54fe850609315..27e87fc43ba77 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -71,7 +71,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/collective/src/lib.rs b/srml/collective/src/lib.rs index 7ae352266ae26..a6e558edfd038 100644 --- a/srml/collective/src/lib.rs +++ b/srml/collective/src/lib.rs @@ -406,7 +406,6 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 96ae06960c7b4..02df9beebfd75 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -108,7 +108,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index b724fd291e5ea..195202c8734a4 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -114,7 +114,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = Event; type Error = Error; type BlockHashCount = BlockHashCount; diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index ff626c1bfc5b3..68715901ed7d4 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -1018,7 +1018,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/elections-phragmen/src/lib.rs b/srml/elections-phragmen/src/lib.rs index 68c17b816206b..a450be1377ee9 100644 --- a/srml/elections-phragmen/src/lib.rs +++ b/srml/elections-phragmen/src/lib.rs @@ -616,7 +616,6 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; diff --git a/srml/elections/src/mock.rs b/srml/elections/src/mock.rs index 7e1a8b0edaff0..baf3e26b89ea7 100644 --- a/srml/elections/src/mock.rs +++ b/srml/elections/src/mock.rs @@ -48,7 +48,6 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 4dc23bcdafef6..79b92f8b8470e 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -667,7 +667,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index 6814cdc91f22f..331e8809dab85 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -348,7 +348,6 @@ mod tests { type Header = Header; type Event = MetaEvent; type BlockHashCount = BlockHashCount; - type WeightMultiplierUpdate = (); type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; @@ -458,7 +457,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("a6378d7fdd31029d13718d54bdff10a370e75cc624aaf94a90e7e7d4a24e0bcc").into(), + state_root: hex!("f0d1d66255c2e5b40580eb8b93ddbe732491478487f85e358e1d167d369e398e").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index f00762fcdfe14..aff924ca4a544 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -298,7 +298,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/generic-asset/src/lib.rs b/srml/generic-asset/src/lib.rs index 6791ee5785263..ca49e2f1cdd53 100644 --- a/srml/generic-asset/src/lib.rs +++ b/srml/generic-asset/src/lib.rs @@ -1056,7 +1056,6 @@ impl system::Trait for ElevatedTrait { type MaximumBlockWeight = T::MaximumBlockWeight; type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; - type WeightMultiplierUpdate = (); type BlockHashCount = T::BlockHashCount; type Version = T::Version; } diff --git a/srml/generic-asset/src/mock.rs b/srml/generic-asset/src/mock.rs index c0f9f154b8349..57b13760fa03d 100644 --- a/srml/generic-asset/src/mock.rs +++ b/srml/generic-asset/src/mock.rs @@ -56,7 +56,6 @@ impl system::Trait for Test { type Lookup = IdentityLookup; type Header = Header; type Event = TestEvent; - type WeightMultiplierUpdate = (); type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index 8d585e4b4679e..fcacbade20490 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -57,7 +57,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/im-online/src/mock.rs b/srml/im-online/src/mock.rs index c2869136dc886..e50e7779e9fcd 100644 --- a/srml/im-online/src/mock.rs +++ b/srml/im-online/src/mock.rs @@ -111,7 +111,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/indices/src/mock.rs b/srml/indices/src/mock.rs index 59d84279a9d5a..427fd87c47e7d 100644 --- a/srml/indices/src/mock.rs +++ b/srml/indices/src/mock.rs @@ -81,7 +81,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = Indices; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/membership/src/lib.rs b/srml/membership/src/lib.rs index 1a6ca82986608..9319111dc512b 100644 --- a/srml/membership/src/lib.rs +++ b/srml/membership/src/lib.rs @@ -227,7 +227,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/offences/src/mock.rs b/srml/offences/src/mock.rs index 01891ce32b43c..f9c79390819e0 100644 --- a/srml/offences/src/mock.rs +++ b/srml/offences/src/mock.rs @@ -78,7 +78,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/randomness-collective-flip/src/lib.rs b/srml/randomness-collective-flip/src/lib.rs index 4ad0095fdfebc..d03c9cdcd3f51 100644 --- a/srml/randomness-collective-flip/src/lib.rs +++ b/srml/randomness-collective-flip/src/lib.rs @@ -183,7 +183,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/scored-pool/src/mock.rs b/srml/scored-pool/src/mock.rs index 2a7370b05e282..394f486a8bec3 100644 --- a/srml/scored-pool/src/mock.rs +++ b/srml/scored-pool/src/mock.rs @@ -64,7 +64,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/session/src/mock.rs b/srml/session/src/mock.rs index 736d3fa4da920..d680fdc96b015 100644 --- a/srml/session/src/mock.rs +++ b/srml/session/src/mock.rs @@ -168,7 +168,6 @@ impl system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index 533370be9d603..5a733af656fd9 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -118,7 +118,6 @@ impl system::Trait for Test { type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/system/benches/bench.rs b/srml/system/benches/bench.rs index 89e9af95259f2..07dc7a57dc468 100644 --- a/srml/system/benches/bench.rs +++ b/srml/system/benches/bench.rs @@ -70,7 +70,6 @@ impl system::Trait for Runtime { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 065b23bda18fb..73bf9bb3f7b8d 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -97,13 +97,13 @@ use rstd::marker::PhantomData; use sr_version::RuntimeVersion; use sr_primitives::{ generic::{self, Era}, Perbill, ApplyError, ApplyOutcome, DispatchError, - weights::{Weight, DispatchInfo, DispatchClass, WeightMultiplier, SimpleDispatchInfo}, + weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo}, transaction_validity::{ ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError, InvalidTransaction, TransactionValidity, }, traits::{ - self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Convert, Lookup, LookupError, + self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Lookup, LookupError, SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, SaturatedConversion, MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup, One, Bounded, }, @@ -188,14 +188,6 @@ pub trait Trait: 'static + Eq + Clone { /// (e.g. Indices module) may provide more functional/efficient alternatives. type Lookup: StaticLookup; - /// Handler for updating the weight multiplier at the end of each block. - /// - /// It receives the current block's weight as input and returns the next weight multiplier for next - /// block. - /// - /// Note that passing `()` will keep the value constant. - type WeightMultiplierUpdate: Convert<(Weight, WeightMultiplier), WeightMultiplier>; - /// The block header. type Header: Parameter + traits::Header< Number = Self::BlockNumber, @@ -381,9 +373,6 @@ decl_storage! { AllExtrinsicsWeight: Option; /// Total length (in bytes) for all extrinsics put together, for the current block. AllExtrinsicsLen: Option; - /// The next weight multiplier. This should be updated at the end of each block based on the - /// saturation level (weight). - pub NextWeightMultiplier get(next_weight_multiplier): WeightMultiplier = Default::default(); /// Map of block numbers to block hashes. pub BlockHash get(block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash; /// Extrinsics data for the current block (maps an extrinsic's index to its data). @@ -612,17 +601,6 @@ impl Module { AllExtrinsicsLen::get().unwrap_or_default() } - /// Update the next weight multiplier. - /// - /// This should be called at then end of each block, before `all_extrinsics_weight` is cleared. - pub fn update_weight_multiplier() { - // update the multiplier based on block weight. - let current_weight = Self::all_extrinsics_weight(); - NextWeightMultiplier::mutate(|fm| { - *fm = T::WeightMultiplierUpdate::convert((current_weight, *fm)) - }); - } - /// Start the execution of a particular block. pub fn initialize( number: &T::BlockNumber, @@ -645,7 +623,6 @@ impl Module { /// Remove temporary "environment" entries in storage. pub fn finalize() -> T::Header { ExtrinsicCount::kill(); - Self::update_weight_multiplier(); AllExtrinsicsWeight::kill(); AllExtrinsicsLen::kill(); @@ -1121,7 +1098,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = u16; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 8ed3aa8dc0e60..2483fb2837319 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -351,7 +351,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index 59db331ac060d..e3ce2cc1749ee 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -226,7 +226,6 @@ mod tests { type Lookup = IdentityLookup; type Header = Header; type Event = (); - type WeightMultiplierUpdate = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 511a2749f61e2..f69511354c7f6 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -384,7 +384,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; diff --git a/srml/utility/src/lib.rs b/srml/utility/src/lib.rs index 7e2bdd0ec8566..57b8a0573ab1e 100644 --- a/srml/utility/src/lib.rs +++ b/srml/utility/src/lib.rs @@ -102,7 +102,6 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type WeightMultiplierUpdate = (); type Event = (); type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; From 41968ee0a664b8be33cfd575dfe2ff6a5ee3d702 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Mon, 14 Oct 2019 11:58:06 +0200 Subject: [PATCH 07/11] Some fixes. --- Cargo.lock | 4 ---- node-template/runtime/src/lib.rs | 1 + node/runtime/src/impls.rs | 1 - srml/balances/src/mock.rs | 14 +++++++------- srml/balances/src/tests.rs | 11 +---------- srml/transaction-payment/src/lib.rs | 15 +++++++-------- 6 files changed, 16 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8087cd370b4be..acaad84fe3ff0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2355,12 +2355,8 @@ dependencies = [ "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", -<<<<<<< HEAD "srml-transaction-payment 2.0.0", - "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", -======= "structopt 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ->>>>>>> 64192122e3ce9d059bb15ab3e674aa6ddf670cc8 "substrate-authority-discovery 2.0.0", "substrate-basic-authorship 2.0.0", "substrate-chain-spec 2.0.0", diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 053de44c57a3d..da49ad4474cba 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -276,6 +276,7 @@ construct_runtime!( Grandpa: grandpa::{Module, Call, Storage, Config, Event}, Indices: indices::{default, Config}, Balances: balances::{default, Error}, + TransactionPayment: transaction_payment::{Module, Storage}, Sudo: sudo, // Used for the module template in `./template.rs` TemplateModule: template::{Module, Call, Storage, Event}, diff --git a/node/runtime/src/impls.rs b/node/runtime/src/impls.rs index 703516e1de3e2..219384502032c 100644 --- a/node/runtime/src/impls.rs +++ b/node/runtime/src/impls.rs @@ -144,7 +144,6 @@ mod tests { } // poc reference implementation. - #[allow(dead_code)] fn fee_multiplier_update(block_weight: Weight, previous: Fixed64) -> Fixed64 { let block_weight = block_weight as f32; let v: f32 = 0.00004; diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index 27e87fc43ba77..600d0e6fb7879 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -83,13 +83,13 @@ parameter_types! { pub const TransactionByteFee: u64 = 1; } impl transaction_payment::Trait for Runtime { - type Currency = Module; - type OnTransactionPayment = (); - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = ConvertInto; - type FeeMultiplierUpdate = (); - } + type Currency = Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); +} impl Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 2b2c66b4e159a..839ac67991c83 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -20,20 +20,13 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; -<<<<<<< HEAD -use sr_primitives::{set_and_run_with_externalities, traits::SignedExtension}; -======= ->>>>>>> 64192122e3ce9d059bb15ab3e674aa6ddf670cc8 +use sr_primitives::traits::SignedExtension; use support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency} }; -<<<<<<< HEAD use transaction_payment::ChargeTransactionPayment; -======= -use sr_primitives::weights::DispatchClass; ->>>>>>> 64192122e3ce9d059bb15ab3e674aa6ddf670cc8 use system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; @@ -123,7 +116,6 @@ fn lock_reasons_should_work() { ExtBuilder::default() .existential_deposit(1) .monied(true) - .transaction_fees(0, 1, 0) .build() .execute_with(|| { Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into()); @@ -133,7 +125,6 @@ fn lock_reasons_should_work() { ); assert_ok!(>::reserve(&1, 1)); // NOTE: this causes a fee payment. - // TODO: maybe don't depend on this. assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(1), &1, diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index b3af572ba638a..40771fb403a94 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -77,7 +77,7 @@ pub trait Trait: system::Trait { decl_storage! { trait Store for Module as Balances { - NextFeeMultiplier get(next_fee_multiplier): Multiplier = Default::default(); // todo explicit zero + NextFeeMultiplier get(next_fee_multiplier): Multiplier = Multiplier::from_parts(0); } } @@ -192,12 +192,12 @@ mod tests { use support::{parameter_types, impl_outer_origin}; use primitives::H256; use sr_primitives::{ - Perbill, set_and_run_with_externalities, + Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, + weights::DispatchClass, }; use rstd::cell::RefCell; - use crate as transaction_payment; const CALL: &::Call = &(); @@ -283,7 +283,6 @@ mod tests { type FeeMultiplierUpdate = (); } - type System = system::Module; type Balances = balances::Module; pub struct ExtBuilder { @@ -395,8 +394,8 @@ mod tests { #[test] fn signed_extension_allows_free_transactions() { ExtBuilder::default() - .transaction_fees(100, 1, 1) - .monied(false) + .fees(100, 1, 1) + .balance_factor(0) .build() .execute_with(|| { @@ -410,7 +409,7 @@ mod tests { }; let len = 100; assert!( - TakeFees::::from(0) + ChargeTransactionPayment::::from(0) .validate(&1, CALL, operational_transaction , len) .is_ok() ); @@ -421,7 +420,7 @@ mod tests { class: DispatchClass::Normal }; assert!( - TakeFees::::from(0) + ChargeTransactionPayment::::from(0) .validate(&1, CALL, free_transaction , len) .is_err() ); From 19e16a6e237f3fa053b43c04cff0fd8cc9a2f0b6 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Mon, 14 Oct 2019 17:46:06 +0200 Subject: [PATCH 08/11] Update len-fee as well --- node/executor/src/lib.rs | 65 +++++++++++++++++++---------- srml/transaction-payment/src/lib.rs | 39 +++++++++++++---- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 0e0196fff7a95..6aac4c1bd058f 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -46,7 +46,7 @@ mod tests { traits::{CodeExecutor, Externalities}, storage::well_known_keys, }; use sr_primitives::{ - assert_eq_error_rate, Fixed64, + Fixed64, traits::{Header as HeaderT, Hash as HashT, Convert}, ApplyResult, transaction_validity::InvalidTransaction, weights::GetDispatchInfo, }; @@ -88,17 +88,15 @@ mod tests { } /// Default transfer fee - fn transfer_fee(extrinsic: &E) -> Balance { + fn transfer_fee(extrinsic: &E, fm: Fixed64) -> Balance { let length_fee = TransactionBaseFee::get() + TransactionByteFee::get() * (extrinsic.encode().len() as Balance); let weight = default_transfer_call().get_dispatch_info().weight; - // NOTE: this is really hard to apply, since the multiplier of each block needs to be fetched - // before the block, while we compute this after the block. - // weight = TransactionPayment::next_fee_multiplier().apply_to(weight); let weight_fee = ::WeightToFee::convert(weight); - length_fee + weight_fee + TransferFee::get() + + fm.saturated_multiply_accumulate(length_fee + weight_fee) + TransferFee::get() } fn default_transfer_call() -> balances::Call { @@ -217,6 +215,10 @@ mod tests { None, ).0; assert!(r.is_ok()); + + let mut fm: Fixed64 = Default::default(); + t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "BlockBuilder_apply_extrinsic", @@ -227,7 +229,7 @@ mod tests { assert!(r.is_ok()); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -253,6 +255,10 @@ mod tests { None, ).0; assert!(r.is_ok()); + + let mut fm: Fixed64 = Default::default(); + t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "BlockBuilder_apply_extrinsic", @@ -263,7 +269,7 @@ mod tests { assert!(r.is_ok()); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -425,6 +431,10 @@ mod tests { let (block1, block2) = blocks(); + let mut fm: Fixed64 = Default::default(); + let mut alice_last_known_balance: Balance = Default::default(); + t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "Core_execute_block", @@ -434,8 +444,9 @@ mod tests { ).0.unwrap(); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); + alice_last_known_balance = Balances::total_balance(&alice()); let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), @@ -460,6 +471,9 @@ mod tests { ]; assert_eq!(System::events(), events); }); + + t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "Core_execute_block", @@ -471,15 +485,13 @@ mod tests { t.execute_with(|| { // NOTE: fees differ slightly in tests that execute more than one block due to the // weight update. Hence, using `assert_eq_error_rate`. - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&alice()), - 32 * DOLLARS - 2 * transfer_fee(&xt()), - 10_000 + alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), ); - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&bob()), - 179 * DOLLARS - transfer_fee(&xt()), - 10_000 + 179 * DOLLARS - transfer_fee(&xt(), fm), ); let events = vec![ EventRecord { @@ -532,6 +544,10 @@ mod tests { let (block1, block2) = blocks(); + let mut fm: Fixed64 = Default::default(); + let mut alice_last_known_balance: Balance = Default::default(); + t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "Core_execute_block", @@ -541,10 +557,13 @@ mod tests { ).0.unwrap(); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); + alice_last_known_balance = Balances::total_balance(&alice()); }); + t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "Core_execute_block", @@ -554,15 +573,13 @@ mod tests { ).0.unwrap(); t.execute_with(|| { - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&alice()), - 32 * DOLLARS - 2 * transfer_fee(&xt()), - 10_000 + alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), ); - assert_eq_error_rate!( + assert_eq!( Balances::total_balance(&bob()), - 179 * DOLLARS - 1 * transfer_fee(&xt()), - 10_000 + 179 * DOLLARS - 1 * transfer_fee(&xt(), fm), ); }); } @@ -824,6 +841,8 @@ mod tests { None, ).0; assert!(r.is_ok()); + let mut fm: Fixed64 = Default::default(); + t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "BlockBuilder_apply_extrinsic", @@ -837,7 +856,7 @@ mod tests { .expect("Extrinsic did not fail"); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt())); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt(), fm)); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index 40771fb403a94..0cfb05d956e2e 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -134,13 +134,15 @@ impl ChargeTransactionPayment { // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` // maximum of its data type, which is not desired. let capped_weight = info.weight.min(::MaximumBlockWeight::get()); - let fee = T::WeightToFee::convert(capped_weight); - // TODO #3291 apply this to both weights, not just one. - let fee_update = NextFeeMultiplier::get(); - let adjusted_fee = fee_update.saturated_multiply_accumulate(fee); - adjusted_fee + T::WeightToFee::convert(capped_weight) }; - len_fee.saturating_add(weight_fee).saturating_add(tip) + + // everything except for tip + let basic_fee = len_fee.saturating_add(weight_fee); + let fee_update = NextFeeMultiplier::get(); + let adjusted_fee = fee_update.saturated_multiply_accumulate(basic_fee); + + adjusted_fee.saturating_add(tip) } } @@ -151,7 +153,9 @@ impl rstd::fmt::Debug for ChargeTransactionPayment { } } -impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync { +impl SignedExtension for ChargeTransactionPayment + where BalanceOf: Send + Sync +{ type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = (); @@ -426,6 +430,27 @@ mod tests { ); }); } + + #[test] + fn signed_ext_length_fee_is_also_updated_per_congestion() { + ExtBuilder::default() + .fees(5, 1, 1) + .balance_factor(10) + .build() + .execute_with(|| + { + // all fees should be x1.5 + NextFeeMultiplier::put(Fixed64::from_rational(1, 2)); + let len = 10; + + assert!( + ChargeTransactionPayment::::from(10) // tipped + .pre_dispatch(&1, CALL, info_from_weight(3), len) + .is_ok() + ); + assert_eq!(Balances::free_balance(&1), 100 - 10 - (5 + 10 + 3) * 3 / 2); + }) + } } From a5b12f6d40ce77e806ef2f6eedfdbd401fe0fa4e Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 16 Oct 2019 17:12:44 +0200 Subject: [PATCH 09/11] some review comments. --- node/executor/src/lib.rs | 23 +++++++++-------------- srml/transaction-payment/src/lib.rs | 5 ++--- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 6aac4c1bd058f..3558987716bd3 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -88,7 +88,7 @@ mod tests { } /// Default transfer fee - fn transfer_fee(extrinsic: &E, fm: Fixed64) -> Balance { + fn transfer_fee(extrinsic: &E, fee_multiplier: Fixed64) -> Balance { let length_fee = TransactionBaseFee::get() + TransactionByteFee::get() * (extrinsic.encode().len() as Balance); @@ -96,7 +96,7 @@ mod tests { let weight = default_transfer_call().get_dispatch_info().weight; let weight_fee = ::WeightToFee::convert(weight); - fm.saturated_multiply_accumulate(length_fee + weight_fee) + TransferFee::get() + fee_multiplier.saturated_multiply_accumulate(length_fee + weight_fee) + TransferFee::get() } fn default_transfer_call() -> balances::Call { @@ -216,8 +216,7 @@ mod tests { ).0; assert!(r.is_ok()); - let mut fm: Fixed64 = Default::default(); - t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, @@ -256,8 +255,7 @@ mod tests { ).0; assert!(r.is_ok()); - let mut fm: Fixed64 = Default::default(); - t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, @@ -431,9 +429,8 @@ mod tests { let (block1, block2) = blocks(); - let mut fm: Fixed64 = Default::default(); let mut alice_last_known_balance: Balance = Default::default(); - t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, @@ -472,7 +469,7 @@ mod tests { assert_eq!(System::events(), events); }); - t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + fm = t.execute_with(TransactionPayment::next_fee_multiplier); executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, @@ -544,9 +541,8 @@ mod tests { let (block1, block2) = blocks(); - let mut fm: Fixed64 = Default::default(); let mut alice_last_known_balance: Balance = Default::default(); - t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, @@ -562,7 +558,7 @@ mod tests { alice_last_known_balance = Balances::total_balance(&alice()); }); - t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + fm = t.execute_with(TransactionPayment::next_fee_multiplier); executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, @@ -841,8 +837,7 @@ mod tests { None, ).0; assert!(r.is_ok()); - let mut fm: Fixed64 = Default::default(); - t.execute_with(|| { fm = TransactionPayment::next_fee_multiplier(); }); + let fm = t.execute_with(TransactionPayment::next_fee_multiplier); let r = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, "BlockBuilder_apply_extrinsic", diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index 0cfb05d956e2e..f2e815fcd40ab 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -18,8 +18,7 @@ //! //! This module provides the basic logic needed to pay the absolute minimum amount needed for a //! transaction to be included. This includes: -//! - _weight fee_: A fee proportional to amount of Weight a transaction consumes. (TODO: explain -//! what weight is or link somewhere) +//! - _weight fee_: A fee proportional to amount of weight a transaction consumes. //! - _length fee_: A fee proportional to the encoded length of the transaction. //! - _tip_: An optional tip. Tip increases the priority of the transaction, giving it a higher //! chance to be included by the transaction queue. @@ -55,7 +54,7 @@ type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: system::Trait { - /// The currency type of the chain. + /// The currency type in which fees will be paid. type Currency: Currency; /// Handler for the unbalanced reduction when taking transaction fees. From dfdae52a6d7c92bc997d5f688c96ae5245da5afb Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 16 Oct 2019 17:33:17 +0200 Subject: [PATCH 10/11] Remove todo --- node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 1a991deea11a9..24d87ed6596b1 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -511,7 +511,7 @@ construct_runtime!( Authorship: authorship::{Module, Call, Storage, Inherent}, Indices: indices, Balances: balances::{default, Error}, - TransactionPayment: transaction_payment::{Module, Storage}, // TODO double check this + TransactionPayment: transaction_payment::{Module, Storage}, Staking: staking::{default, OfflineWorker}, Session: session::{Module, Call, Storage, Event, Config}, Democracy: democracy::{Module, Call, Storage, Config, Event}, From 693a8f0850ca8f7aabda2a2722e1be358b8254c5 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 17 Oct 2019 14:01:56 +0200 Subject: [PATCH 11/11] bump --- node/runtime/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 916612e69a7a7..fdf0bfdc144bb 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -84,8 +84,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 177, - impl_version: 177, + spec_version: 178, + impl_version: 178, apis: RUNTIME_API_VERSIONS, };