refactor: Transaction-Payment module (#3816)

* Initial draft that compiles

* Extract payment stuff from balances

* Extract multiplier update stuff from system

* Some fixes.

* Update len-fee as well

* some review comments.

* Remove todo

* bump
This commit is contained in:
Kian Paimani
2019-10-17 14:21:32 +02:00
committed by GitHub
parent 1711483fb6
commit 183c188111
59 changed files with 784 additions and 596 deletions
@@ -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!(
@@ -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); });
}
}