mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 00:41:03 +00:00
Weight annotation. (#3157)
* Make extrinsics extensible. Also Remove old extrinsic types. * Rest of mockup. Add tips. * Fix some build issues * Runtiem builds :) * Substrate builds. * Fix a doc test * Compact encoding * Extract out the era logic into an extension * Weight Check signed extension. (#3115) * Weight signed extension. * Revert a bit + test for check era. * Update Cargo.toml * Update node/cli/src/factory_impl.rs * Update node/executor/src/lib.rs * Update node/executor/src/lib.rs * Don't use len for weight - use data. * Operational Transaction; second attempt (#3138) * working poc added. * some fixes. * Update doc. * Fix all tests + final logic. * more refactoring. * nits. * System block limit in bytes. * Silent the storage macro warnings. * More logic more tests. * Fix import. * Refactor names. * Fix build. * Update srml/balances/src/lib.rs * Final refactor. * Bump transaction version * Fix weight mult test. * Fix more tests and improve doc. * Bump. * Make some tests work again. * Fix subkey. * Remove todos + bump. * First draft of annotating weights. * Refactor weight to u64. * More refactoring and tests. * New convert for weight to fee * more tests. * remove merge redundancy. * Fix system test. * Bring back subkey stuff. * a few stress tests. * fix some of the grumbles. * Final nits. * Update srml/system/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Scale weights by 1000. * Bump. * Fix decl_storage test.
This commit is contained in:
committed by
Bastian Köcher
parent
80472956f8
commit
002acb9373
@@ -161,10 +161,10 @@ use srml_support::traits::{
|
||||
use srml_support::dispatch::Result;
|
||||
use primitives::traits::{
|
||||
Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug,
|
||||
Saturating, Bounded, SignedExtension, SaturatedConversion, DispatchError
|
||||
Saturating, Bounded, SignedExtension, SaturatedConversion, DispatchError, Convert,
|
||||
};
|
||||
use primitives::transaction_validity::{TransactionPriority, ValidTransaction};
|
||||
use primitives::weights::DispatchInfo;
|
||||
use primitives::weights::{DispatchInfo, SimpleDispatchInfo, Weight};
|
||||
use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root};
|
||||
|
||||
mod mock;
|
||||
@@ -206,6 +206,9 @@ pub trait Subtrait<I: Instance = DefaultInstance>: system::Trait {
|
||||
|
||||
/// The fee to be paid for making a transaction; the per-byte portion.
|
||||
type TransactionByteFee: Get<Self::Balance>;
|
||||
|
||||
/// Convert a weight value into a deductible fee based on the currency type.
|
||||
type WeightToFee: Convert<Weight, Self::Balance>;
|
||||
}
|
||||
|
||||
pub trait Trait<I: Instance = DefaultInstance>: system::Trait {
|
||||
@@ -249,6 +252,9 @@ pub trait Trait<I: Instance = DefaultInstance>: system::Trait {
|
||||
|
||||
/// The fee to be paid for making a transaction; the per-byte portion.
|
||||
type TransactionByteFee: Get<Self::Balance>;
|
||||
|
||||
/// Convert a weight value into a deductible fee based on the currency type.
|
||||
type WeightToFee: Convert<Weight, Self::Balance>;
|
||||
}
|
||||
|
||||
impl<T: Trait<I>, I: Instance> Subtrait<I> for T {
|
||||
@@ -260,6 +266,7 @@ impl<T: Trait<I>, I: Instance> Subtrait<I> for T {
|
||||
type CreationFee = T::CreationFee;
|
||||
type TransactionBaseFee = T::TransactionBaseFee;
|
||||
type TransactionByteFee = T::TransactionByteFee;
|
||||
type WeightToFee = T::WeightToFee;
|
||||
}
|
||||
|
||||
decl_event!(
|
||||
@@ -428,6 +435,7 @@ decl_module! {
|
||||
/// `T::DustRemoval::on_unbalanced` and `T::OnFreeBalanceZero::on_free_balance_zero`.
|
||||
///
|
||||
/// # </weight>
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(1_000_000)]
|
||||
pub fn transfer(
|
||||
origin,
|
||||
dest: <T::Lookup as StaticLookup>::Source,
|
||||
@@ -451,6 +459,7 @@ decl_module! {
|
||||
/// - Independent of the arguments.
|
||||
/// - Contains a limited number of reads and writes.
|
||||
/// # </weight>
|
||||
#[weight = SimpleDispatchInfo::FixedOperational(500_000)]
|
||||
fn set_balance(
|
||||
origin,
|
||||
who: <T::Lookup as StaticLookup>::Source,
|
||||
@@ -766,6 +775,7 @@ impl<T: Subtrait<I>, I: Instance> system::Trait for ElevatedTrait<T, I> {
|
||||
type BlockHashCount = T::BlockHashCount;
|
||||
type MaximumBlockWeight = T::MaximumBlockWeight;
|
||||
type MaximumBlockLength = T::MaximumBlockLength;
|
||||
type AvailableBlockRatio = T::AvailableBlockRatio;
|
||||
}
|
||||
impl<T: Subtrait<I>, I: Instance> Trait<I> for ElevatedTrait<T, I> {
|
||||
type Balance = T::Balance;
|
||||
@@ -780,6 +790,7 @@ impl<T: Subtrait<I>, I: Instance> Trait<I> for ElevatedTrait<T, I> {
|
||||
type CreationFee = T::CreationFee;
|
||||
type TransactionBaseFee = T::TransactionBaseFee;
|
||||
type TransactionByteFee = T::TransactionByteFee;
|
||||
type WeightToFee = T::WeightToFee;
|
||||
}
|
||||
|
||||
impl<T: Trait<I>, I: Instance> Currency<T::AccountId> for Module<T, I>
|
||||
@@ -1171,19 +1182,23 @@ impl<T: Trait<I>, I: Instance> TakeFees<T, I> {
|
||||
/// - (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 {
|
||||
// length fee
|
||||
let len_fee = if info.pay_length_fee() {
|
||||
let len = T::Balance::from(len as u32);
|
||||
let base = T::TransactionBaseFee::get();
|
||||
let byte = T::TransactionByteFee::get();
|
||||
base.saturating_add(byte.saturating_mul(len))
|
||||
let per_byte = T::TransactionByteFee::get();
|
||||
base.saturating_add(per_byte.saturating_mul(len))
|
||||
} else {
|
||||
Zero::zero()
|
||||
};
|
||||
|
||||
// weight fee
|
||||
let weight = info.weight;
|
||||
let weight_fee: T::Balance = <system::Module<T>>::next_weight_multiplier().apply_to(weight).into();
|
||||
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(<T as system::Trait>::MaximumBlockWeight::get());
|
||||
let weight_update = <system::Module<T>>::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)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use primitives::{traits::IdentityLookup, testing::Header, weights::{DispatchInfo, Weight}};
|
||||
use primitives::{Perbill, traits::{Convert, IdentityLookup}, testing::Header, weights::{DispatchInfo, Weight}};
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use runtime_io;
|
||||
use srml_support::{impl_outer_origin, parameter_types};
|
||||
@@ -36,6 +36,8 @@ thread_local! {
|
||||
static CREATION_FEE: RefCell<u64> = RefCell::new(0);
|
||||
static TRANSACTION_BASE_FEE: RefCell<u64> = RefCell::new(0);
|
||||
static TRANSACTION_BYTE_FEE: RefCell<u64> = RefCell::new(1);
|
||||
static TRANSACTION_WEIGHT_FEE: RefCell<u64> = RefCell::new(1);
|
||||
static WEIGHT_TO_FEE: RefCell<u64> = RefCell::new(1);
|
||||
}
|
||||
|
||||
pub struct ExistentialDeposit;
|
||||
@@ -63,6 +65,13 @@ impl Get<u64> for TransactionByteFee {
|
||||
fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) }
|
||||
}
|
||||
|
||||
pub struct WeightToFee(u64);
|
||||
impl Convert<Weight, u64> 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;
|
||||
@@ -70,6 +79,7 @@ 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;
|
||||
@@ -85,6 +95,7 @@ impl system::Trait for Runtime {
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type MaximumBlockWeight = MaximumBlockWeight;
|
||||
type MaximumBlockLength = MaximumBlockLength;
|
||||
type AvailableBlockRatio = AvailableBlockRatio;
|
||||
}
|
||||
impl Trait for Runtime {
|
||||
type Balance = u64;
|
||||
@@ -99,11 +110,13 @@ impl Trait for Runtime {
|
||||
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,
|
||||
@@ -115,6 +128,7 @@ impl Default for ExtBuilder {
|
||||
Self {
|
||||
transaction_base_fee: 0,
|
||||
transaction_byte_fee: 0,
|
||||
weight_to_fee: 0,
|
||||
existential_deposit: 0,
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
@@ -124,9 +138,10 @@ impl Default for ExtBuilder {
|
||||
}
|
||||
}
|
||||
impl ExtBuilder {
|
||||
pub fn transaction_fees(mut self, base_fee: u64, byte_fee: u64) -> Self {
|
||||
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 {
|
||||
@@ -159,6 +174,7 @@ impl ExtBuilder {
|
||||
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<Blake2Hasher> {
|
||||
self.set_associated_consts();
|
||||
|
||||
@@ -114,7 +114,7 @@ fn lock_reasons_should_work() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(1)
|
||||
.monied(true).transaction_fees(0, 1)
|
||||
.monied(true).transaction_fees(0, 1, 0)
|
||||
.build(),
|
||||
|| {
|
||||
Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into());
|
||||
@@ -752,15 +752,37 @@ fn signed_extension_take_fees_work() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(10)
|
||||
.transaction_fees(10, 1)
|
||||
.transaction_fees(10, 1, 5)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
let len = 10;
|
||||
assert!(TakeFees::<Runtime>::from(0).pre_dispatch(&1, info_from_weight(0), len).is_ok());
|
||||
assert_eq!(Balances::free_balance(&1), 100 - 20);
|
||||
assert!(TakeFees::<Runtime>::from(5 /* tipped */).pre_dispatch(&1, info_from_weight(0), len).is_ok());
|
||||
assert!(TakeFees::<Runtime>::from(0).pre_dispatch(&1, info_from_weight(5), len).is_ok());
|
||||
assert_eq!(Balances::free_balance(&1), 100 - 20 - 25);
|
||||
assert!(TakeFees::<Runtime>::from(5 /* tipped */).pre_dispatch(&1, 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() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(1000)
|
||||
.transaction_fees(0, 0, 1)
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
use primitives::weights::Weight;
|
||||
|
||||
// maximum weight possible
|
||||
assert!(TakeFees::<Runtime>::from(0).pre_dispatch(&1, 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 - <Runtime as system::Trait>::MaximumBlockWeight::get()) as u64
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user