Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
b042a93
Make extrinsics extensible.
gavofyork Jul 11, 2019
37f6ae0
Rest of mockup. Add tips.
gavofyork Jul 11, 2019
2e5b1f4
Fix some build issues
gavofyork Jul 11, 2019
b7646ec
Runtiem builds :)
gavofyork Jul 11, 2019
a871c9f
Substrate builds.
kianenigma Jul 12, 2019
8e7c803
Fix a doc test
gavofyork Jul 13, 2019
a824b56
Compact encoding
gavofyork Jul 13, 2019
5de080f
Extract out the era logic into an extension
gavofyork Jul 15, 2019
a8789b9
Weight Check signed extension. (#3115)
kianenigma Jul 16, 2019
7d96429
Merge remote-tracking branch 'origin/master' into gav-extensble-trans…
gavofyork Jul 16, 2019
30b4ba7
Don't use len for weight - use data.
gavofyork Jul 16, 2019
2a9c9df
Merge remote-tracking branch 'origin/master' into gav-extensble-trans…
gavofyork Jul 19, 2019
342efb5
Operational Transaction; second attempt (#3138)
kianenigma Jul 19, 2019
b8f564e
Bump transaction version
jacogr Jul 19, 2019
07fdfe2
Merge branch 'gav-extensble-transactions' of github.com:paritytech/su…
jacogr Jul 19, 2019
7f33006
Master.into()
kianenigma Jul 19, 2019
36063fe
Merge branch 'gav-extensble-transactions' of github.com:paritytech/su…
kianenigma Jul 19, 2019
7a0fbc9
Fix weight mult test.
kianenigma Jul 19, 2019
84fa279
Fix more tests and improve doc.
kianenigma Jul 19, 2019
f4d4579
Bump.
kianenigma Jul 19, 2019
def6425
Merge remote-tracking branch 'origin/master' into gav-extensble-trans…
gavofyork Jul 20, 2019
d12713a
Make some tests work again.
kianenigma Jul 20, 2019
3350f9c
Fix subkey.
kianenigma Jul 20, 2019
b788507
Remove todos + bump.
kianenigma Jul 20, 2019
b9b6b53
First draft of annotating weights.
kianenigma Jul 21, 2019
045681e
Refactor weight to u64.
kianenigma Jul 22, 2019
bfcfa36
More refactoring and tests.
kianenigma Jul 23, 2019
107801f
One hell of a merge conflict.
kianenigma Jul 23, 2019
c100df9
New convert for weight to fee
kianenigma Jul 23, 2019
f5d33c6
more tests.
kianenigma Jul 23, 2019
0c1c268
remove merge redundancy.
kianenigma Jul 23, 2019
6a0a1d4
Fix system test.
kianenigma Jul 24, 2019
b06ef82
Master.into()
kianenigma Jul 24, 2019
c3e0ee3
Bring back subkey stuff.
kianenigma Jul 24, 2019
5b0c715
a few stress tests.
kianenigma Jul 24, 2019
e683829
fix some of the grumbles.
kianenigma Jul 24, 2019
ce11fc5
Merge branch 'master' of github.com:paritytech/substrate into kiz-ann…
kianenigma Jul 24, 2019
0b592e2
Final nits.
kianenigma Jul 24, 2019
ee970d1
Merge branch 'master' into kiz-annotate-weights
Demi-Marie Jul 24, 2019
58191a3
Update srml/system/src/lib.rs
kianenigma Jul 24, 2019
67b268a
Master.into()
kianenigma Jul 25, 2019
0d9133f
Merge conflicts.
kianenigma Jul 25, 2019
ec6554f
Scale weights by 1000.
kianenigma Jul 25, 2019
a25e4be
Bump.
kianenigma Jul 25, 2019
5724771
Fix decl_storage test.
kianenigma Jul 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
More refactoring and tests.
  • Loading branch information
kianenigma committed Jul 23, 2019
commit bfcfa36d311c2b59f8730fe715c3acd5ed5f912a
6 changes: 3 additions & 3 deletions core/sr-primitives/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub use crate::transaction_validity::TransactionPriority;
use crate::traits::Bounded;

/// Numeric range of a transaction weight.
pub type Weight = u64;
pub type Weight = u32;

/// A generalized group of dispatch types. This is only distinguishing normal, user-triggered transactions
/// (`Normal`) and anything beyond which serves a higher purpose to the system (`Operational`).
Expand Down Expand Up @@ -144,11 +144,11 @@ pub enum SimpleDispatchInfo {
impl<T> WeighData<T> for SimpleDispatchInfo {
fn weigh_data(&self, _: T) -> Weight {
match self {
SimpleDispatchInfo::FixedNormal(w) => *w * 1000,
SimpleDispatchInfo::FixedNormal(w) => *w,
SimpleDispatchInfo::MaxNormal => Bounded::max_value(),
SimpleDispatchInfo::FreeNormal => Bounded::min_value(),

SimpleDispatchInfo::FixedOperational(w) => *w * 1000,
SimpleDispatchInfo::FixedOperational(w) => *w,
SimpleDispatchInfo::MaxOperational => Bounded::max_value(),
SimpleDispatchInfo::FreeOperational => Bounded::min_value(),
}
Expand Down
13 changes: 5 additions & 8 deletions node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
use parity_codec::{Encode, Decode};
use rstd::prelude::*;
#[cfg(feature = "std")]
use primitives::bytes;
use primitives::{ed25519, sr25519, OpaqueMetadata};
use sr_primitives::{
ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str,
traits::{self, NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify}, weights::Weight,
traits::{NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify}, weights::Weight,
};
use client::{
block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api},
Expand Down Expand Up @@ -169,8 +164,9 @@ parameter_types! {
pub const ExistentialDeposit: u128 = 500;
pub const TransferFee: u128 = 0;
pub const CreationFee: u128 = 0;
pub const TransactionBaseFee: u128 = 1;
pub const TransactionByteFee: u128 = 0;
pub const TransactionBaseFee: u128 = 0;
pub const TransactionByteFee: u128 = 1;
pub const TransactionWeightFee: u128 = 1;
}

impl balances::Trait for Runtime {
Expand All @@ -191,6 +187,7 @@ impl balances::Trait for Runtime {
type CreationFee = CreationFee;
type TransactionBaseFee = TransactionBaseFee;
type TransactionByteFee = TransactionByteFee;
type TransactionWeightFee = TransactionWeightFee;
}

impl sudo::Trait for Runtime {
Expand Down
2 changes: 1 addition & 1 deletion node-template/runtime/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ mod tests {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: Weight = 1024;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75));
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
}
impl system::Trait for Test {
type Origin = Origin;
Expand Down
109 changes: 88 additions & 21 deletions node/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ mod tests {
use node_primitives::{Hash, BlockNumber, AccountId, Balance, Index};
use runtime_primitives::traits::{Header as HeaderT, Hash as HashT};
use runtime_primitives::{generic::Era, ApplyOutcome, ApplyError, ApplyResult, Perbill};
use runtime_primitives::weights::{WeightMultiplier, SimpleDispatchInfo, GetDispatchInfo, WeighData, Weight};
use runtime_primitives::weights::{WeightMultiplier, GetDispatchInfo, Weight};
use {balances, contracts, indices, staking, system, timestamp};
use contracts::ContractAddressFor;
use system::{EventRecord, Phase};
Expand Down Expand Up @@ -82,22 +82,25 @@ mod tests {

type TestExternalities<H> = CoreTestExternalities<H, u64>;

/// Default transfer fee
fn transfer_fee<E: Encode>(extrinsic: &E) -> Balance {
let length_fee = <TransactionBaseFee as Get<Balance>>::get() +
<TransactionByteFee as Get<Balance>>::get() *
(extrinsic.encode().len() as Balance);
let weight_fee = default_transfer_call().get_dispatch_info().weight as Balance;
// TODO: with this we have 100% accurate fee estimation. Should probably be able to get rid
// of `assert_eq_error_rate!` now. But it makes test mockup much more complicated because
// the fee for each block can only be estimated _before_ that block.
let mut weight_fee = default_transfer_call().get_dispatch_info().weight as Balance;
weight_fee = weight_fee * 1_000_000 as Balance;
// NOTE: we don't need this anymore, but in case needed, this makes the fee accurate over
// multiple blocks.
// weight_fee = <system::Module<Runtime>>::next_weight_multiplier().apply_to(weight_fee as u32) as Balance;
length_fee + weight_fee
}

fn multiplier_target() -> Weight {
/// Get the target weight of the fee multiplier.
fn _multiplier_target() -> Weight {
<MaximumBlockWeight as Get<Weight>>::get() / 4
}

/// Default creation fee.
fn creation_fee() -> Balance {
<CreationFee as Get<Balance>>::get()
}
Expand Down Expand Up @@ -972,21 +975,6 @@ mod tests {

let mut tt = new_test_ext(COMPACT_CODE, false);

// This test can either use `fill_block()`, which is controversial, or should be dropped.
// NOTE: This assumes that system::remark has the default.
// let num_to_exhaust = (multiplier_target() + 100) / SimpleDispatchInfo::default().weigh_data(());
// println!("++ Generating {} transactions to fill {} weight units", num_to_exhaust, multiplier_target() + 100);
// let mut xts = (0..num_to_exhaust).map(|i| CheckedExtrinsic {
// signed: Some((charlie(), signed_extra(i.into(), 0))),
// function: Call::System(system::Call::remark(vec![0; 1])),
// }).collect::<Vec<CheckedExtrinsic>>();
// xts.insert(0, CheckedExtrinsic {
// signed: None,
// function: Call::Timestamp(timestamp::Call::set(42)),
// });

println!("++ Generated all extrinsics. Constructing blocks.");

// big one in terms of weight.
let block1 = construct_block(
&mut tt,
Expand Down Expand Up @@ -1057,6 +1045,85 @@ mod tests {
});
}

#[test]
fn transaction_fee_is_correct_ultimate() {
// This uses the exact values of substrate-node.
//
// weight of transfer call as of now: 1_000
// if weight of 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.
// (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`)
let mut t = TestExternalities::<Blake2Hasher>::new_with_code(COMPACT_CODE, map![
blake2_256(&<balances::FreeBalance<Runtime>>::key_for(alice())).to_vec() => {
(100 * DOLLARS).encode()
},
blake2_256(&<balances::FreeBalance<Runtime>>::key_for(bob())).to_vec() => {
(10 * DOLLARS).encode()
},
twox_128(<balances::TotalIssuance<Runtime>>::key()).to_vec() => {
(110 * DOLLARS).encode()
},
twox_128(<indices::NextEnumSet<Runtime>>::key()).to_vec() => vec![0u8; 16],
blake2_256(&<system::BlockHash<Runtime>>::key_for(0)).to_vec() => vec![0u8; 32]
]);

let tip = 1_000_000;
let xt = sign(CheckedExtrinsic {
signed: Some((alice(), signed_extra(0, tip))),
function: Call::Balances(default_transfer_call()),
});

let r = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_initialize_block",
&vec![].and(&from_block_number(1u64)),
true,
None,
).0;

assert!(r.is_ok());
let r = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"BlockBuilder_apply_extrinsic",
&vec![].and(&xt.clone()),
true,
None,
).0;
assert!(r.is_ok());

runtime_io::with_externalities(&mut t, || {
assert_eq!(Balances::total_balance(&bob()), (10 + 69) * DOLLARS);
// Components deducted from alice's balances:
// - Weight fee
// - Length fee
// - Tip
// - Creation-fee of bob's account.
let mut balance_alice = (100 - 69) * DOLLARS;

let length_fee = <TransactionBaseFee as Get<Balance>>::get() +
<TransactionByteFee as Get<Balance>>::get() *
(xt.clone().encode().len() as Balance);
println!("++ len fee = {:?}", length_fee);
balance_alice -= length_fee;

// TODO: the 1_000_000 should go away.
let weight_fee = default_transfer_call().get_dispatch_info().weight as Balance * 1_000_000;
// we know that weight to fee multiplier is effect-less in block 1.
assert_eq!(weight_fee as Balance, MILLICENTS);
balance_alice -= weight_fee;
println!("++ wei fee = {:?}", weight_fee);

balance_alice -= tip;
println!("++ tip fee = {:?}", tip);

// TODO: why again??? creation fee should not be deducted here.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gavofyork do you know why this keeps happening? even though Bob has some initial balance, the creation fee is deducted from alice upon sending the transfer. It is also the same for some other tests.

At some point I put a log here and this was false. no clue what's going on.
https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L870

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more prints needed, then. shouldn't be hard to track down.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

false alarm. It is just transfer_fee. let fee = if would_create { T::CreationFee::get() } else { T::TransferFee::get() };.

balance_alice -= creation_fee();

assert_eq!(Balances::total_balance(&alice()), balance_alice);
});
}

#[cfg(feature = "benchmarks")]
mod benches {
use super::*;
Expand Down
4 changes: 2 additions & 2 deletions node/runtime/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ mod tests {
});

// Some values that are all above the target and will cause an increase.
let target_weight = TARGET_BLOCK_FULLNESS * <MaximumBlockWeight as Get<Weight>>::get();
vec![target_weight + 100, target_weight * 2, target_weight * 4]
let t = target();
vec![t + 100, t * 2, t * 4]
.into_iter()
.for_each(|i| {
let fm = WeightMultiplierUpdateHandler::convert((
Expand Down
4 changes: 3 additions & 1 deletion node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub type DealWithFees = SplitTwoWays<

parameter_types! {
pub const BlockHashCount: BlockNumber = 250;
pub const MaximumBlockWeight: Weight = 1_000_000_000;
pub const MaximumBlockWeight: Weight = 1_000_000;
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also note that the normal size limit of the node is now 5mb.

}
Expand Down Expand Up @@ -143,6 +143,7 @@ parameter_types! {
pub const CreationFee: Balance = 1 * CENTS;
pub const TransactionBaseFee: Balance = 1 * CENTS;
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
pub const TransactionWeightFee: Balance = MILLICENTS / 1000;
}

impl balances::Trait for Runtime {
Expand All @@ -158,6 +159,7 @@ impl balances::Trait for Runtime {
type CreationFee = CreationFee;
type TransactionBaseFee = TransactionBaseFee;
type TransactionByteFee = TransactionByteFee;
type TransactionWeightFee = TransactionWeightFee;
}

parameter_types! {
Expand Down
26 changes: 19 additions & 7 deletions srml/balances/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>;

/// The amount of fee deducted oer unit of weight.
type TransactionWeightFee: Get<Self::Balance>;
}

pub trait Trait<I: Instance = DefaultInstance>: system::Trait {
Expand Down Expand Up @@ -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>;

/// The amount of fee deducted oer unit of weight.
type TransactionWeightFee: Get<Self::Balance>;
}

impl<T: Trait<I>, I: Instance> Subtrait<I> for T {
Expand All @@ -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 TransactionWeightFee = T::TransactionWeightFee;
}

decl_event!(
Expand Down Expand Up @@ -783,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 TransactionWeightFee = T::TransactionWeightFee;
}

impl<T: Trait<I>, I: Instance> Currency<T::AccountId> for Module<T, I>
Expand Down Expand Up @@ -1174,20 +1182,24 @@ 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).saturated_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());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this kinda sucks that every signed extension using weight must cap it itself if they want to. This is because in the details of the WeighData we don't know the MaximumBlockWeight. Might be able to improve it by further abstracting type Weight: u32 into some other custom type and give it a custom implementation of Bounded by the runtime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also do the same in system CheckWeight. Might be debatable.

I had the assumption that the weight fo one individual tx cannot go beyond the weight of the entire block. Even if thee annotationa sets the weight to infinity the runtime checks interpret it as whatever MaximumBlockWeight of the node is.

If this does not exist, then Max variants of weight are actually a footgun, using it will cause a much higher fee and won't bring any benefit.

let weight_fee: T::Balance = <system::Module<T>>::next_weight_multiplier()
.apply_to(capped_weight).saturated_into();
let per_weight = T::TransactionWeightFee::get();
weight_fee.saturating_mul(per_weight)
};

len_fee.saturating_add(weight_fee).saturating_add(tip)
}
Expand Down
13 changes: 12 additions & 1 deletion srml/balances/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ 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);
}

pub struct ExistentialDeposit;
Expand Down Expand Up @@ -63,6 +64,11 @@ impl Get<u64> for TransactionByteFee {
fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) }
}

pub struct TransactionWeightFee;
impl Get<u64> for TransactionWeightFee {
fn get() -> u64 { TRANSACTION_WEIGHT_FEE.with(|v| *v.borrow()) }
}

// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Runtime;
Expand Down Expand Up @@ -101,11 +107,13 @@ impl Trait for Runtime {
type CreationFee = CreationFee;
type TransactionBaseFee = TransactionBaseFee;
type TransactionByteFee = TransactionByteFee;
type TransactionWeightFee = TransactionWeightFee;
}

pub struct ExtBuilder {
transaction_base_fee: u64,
transaction_byte_fee: u64,
transaction_weight_fee: u64,
existential_deposit: u64,
transfer_fee: u64,
creation_fee: u64,
Expand All @@ -117,6 +125,7 @@ impl Default for ExtBuilder {
Self {
transaction_base_fee: 0,
transaction_byte_fee: 0,
transaction_weight_fee: 0,
existential_deposit: 0,
transfer_fee: 0,
creation_fee: 0,
Expand All @@ -126,9 +135,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.transaction_weight_fee = weight_fee;
self
}
pub fn existential_deposit(mut self, existential_deposit: u64) -> Self {
Expand Down Expand Up @@ -161,6 +171,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);
TRANSACTION_WEIGHT_FEE.with(|v| *v.borrow_mut() = self.transaction_weight_fee);
}
pub fn build(self) -> runtime_io::TestExternalities<Blake2Hasher> {
self.set_associated_consts();
Expand Down
Loading