mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 10:27:59 +00:00
Non-Interactive Staking (#12610)
* Improve naming. * More improvements to naming * Fungible counterpart * Shared pot instead of reserve * Transferable receipts * Better naming * Use u128 for counterpart * Partial thawing * Docs * Remove AdminOrigin * Integrate into Kitchen Sink * Thaw throttling * Remove todo * Docs * Fix benchmarks * Building * Tests work * New benchmarks * Benchmarking tests * Test new defensive_saturating_* functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Formatting * Update frame/nis/src/lib.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Apply suggestions from code review Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Events added * Fix kitchensink * Update frame/nis/src/lib.rs Co-authored-by: Xiliang Chen <xlchen1291@gmail.com> * Review niggles * Remove genesis build requirements * Grumbles * Fixes * Fixes * Fixes * Update frame/nis/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update primitives/runtime/src/traits.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Formatting * Fixes * Fix node genesis config Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix node chain specs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use free asset ID as counterpart Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Account for rounding errors in fund_deficit bench Relaxes the check for the NIS account balance in the fund_deficit bench from equality from to checking for 99.999% equality. The exact deviation for the kitchensink runtime config is 1.24e-10 percent but could vary if the config is changed. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix * Rename * Fixes * Fixes * Formatting Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Xiliang Chen <xlchen1291@gmail.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
@@ -21,7 +21,7 @@ use crate::dispatch::Parameter;
|
||||
use codec::{CompactLen, Decode, DecodeLimit, Encode, EncodeLike, Input, MaxEncodedLen};
|
||||
use impl_trait_for_tuples::impl_for_tuples;
|
||||
use scale_info::{build::Fields, meta_type, Path, Type, TypeInfo, TypeParameter};
|
||||
use sp_arithmetic::traits::{CheckedAdd, CheckedMul, CheckedSub, Saturating};
|
||||
use sp_arithmetic::traits::{CheckedAdd, CheckedMul, CheckedSub, One, Saturating};
|
||||
use sp_core::bounded::bounded_vec::TruncateFrom;
|
||||
#[doc(hidden)]
|
||||
pub use sp_runtime::traits::{
|
||||
@@ -348,17 +348,25 @@ impl<T> DefensiveOption<T> for Option<T> {
|
||||
/// A variant of [`Defensive`] with the same rationale, for the arithmetic operations where in
|
||||
/// case an infallible operation fails, it saturates.
|
||||
pub trait DefensiveSaturating {
|
||||
/// Add `self` and `other` defensively.
|
||||
/// Return `self` plus `other` defensively.
|
||||
fn defensive_saturating_add(self, other: Self) -> Self;
|
||||
/// Subtract `other` from `self` defensively.
|
||||
/// Return `self` minus `other` defensively.
|
||||
fn defensive_saturating_sub(self, other: Self) -> Self;
|
||||
/// Multiply `self` and `other` defensively.
|
||||
/// Return the product of `self` and `other` defensively.
|
||||
fn defensive_saturating_mul(self, other: Self) -> Self;
|
||||
/// Increase `self` by `other` defensively.
|
||||
fn defensive_saturating_accrue(&mut self, other: Self);
|
||||
/// Reduce `self` by `other` defensively.
|
||||
fn defensive_saturating_reduce(&mut self, other: Self);
|
||||
/// Increment `self` by one defensively.
|
||||
fn defensive_saturating_inc(&mut self);
|
||||
/// Decrement `self` by one defensively.
|
||||
fn defensive_saturating_dec(&mut self);
|
||||
}
|
||||
|
||||
// NOTE: A bit unfortunate, since T has to be bound by all the traits needed. Could make it
|
||||
// `DefensiveSaturating<T>` to mitigate.
|
||||
impl<T: Saturating + CheckedAdd + CheckedMul + CheckedSub> DefensiveSaturating for T {
|
||||
impl<T: Saturating + CheckedAdd + CheckedMul + CheckedSub + One> DefensiveSaturating for T {
|
||||
fn defensive_saturating_add(self, other: Self) -> Self {
|
||||
self.checked_add(&other).defensive_unwrap_or_else(|| self.saturating_add(other))
|
||||
}
|
||||
@@ -368,6 +376,20 @@ impl<T: Saturating + CheckedAdd + CheckedMul + CheckedSub> DefensiveSaturating f
|
||||
fn defensive_saturating_mul(self, other: Self) -> Self {
|
||||
self.checked_mul(&other).defensive_unwrap_or_else(|| self.saturating_mul(other))
|
||||
}
|
||||
fn defensive_saturating_accrue(&mut self, other: Self) {
|
||||
// Use `replace` here since `take` would require `T: Default`.
|
||||
*self = sp_std::mem::replace(self, One::one()).defensive_saturating_add(other);
|
||||
}
|
||||
fn defensive_saturating_reduce(&mut self, other: Self) {
|
||||
// Use `replace` here since `take` would require `T: Default`.
|
||||
*self = sp_std::mem::replace(self, One::one()).defensive_saturating_sub(other);
|
||||
}
|
||||
fn defensive_saturating_inc(&mut self) {
|
||||
self.defensive_saturating_accrue(One::one());
|
||||
}
|
||||
fn defensive_saturating_dec(&mut self) {
|
||||
self.defensive_saturating_reduce(One::one());
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct an object by defensively truncating an input if the `TryFrom` conversion fails.
|
||||
@@ -1119,6 +1141,92 @@ mod test {
|
||||
use sp_core::bounded::{BoundedSlice, BoundedVec};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn defensive_saturating_accrue_works() {
|
||||
let mut v = 1_u32;
|
||||
v.defensive_saturating_accrue(2);
|
||||
assert_eq!(v, 3);
|
||||
v.defensive_saturating_accrue(u32::MAX);
|
||||
assert_eq!(v, u32::MAX);
|
||||
v.defensive_saturating_accrue(1);
|
||||
assert_eq!(v, u32::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic(expected = "Defensive")]
|
||||
fn defensive_saturating_accrue_panics() {
|
||||
let mut v = u32::MAX;
|
||||
v.defensive_saturating_accrue(1); // defensive failure
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn defensive_saturating_reduce_works() {
|
||||
let mut v = u32::MAX;
|
||||
v.defensive_saturating_reduce(3);
|
||||
assert_eq!(v, u32::MAX - 3);
|
||||
v.defensive_saturating_reduce(u32::MAX);
|
||||
assert_eq!(v, 0);
|
||||
v.defensive_saturating_reduce(1);
|
||||
assert_eq!(v, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic(expected = "Defensive")]
|
||||
fn defensive_saturating_reduce_panics() {
|
||||
let mut v = 0_u32;
|
||||
v.defensive_saturating_reduce(1); // defensive failure
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn defensive_saturating_inc_works() {
|
||||
let mut v = 0_u32;
|
||||
for i in 1..10 {
|
||||
v.defensive_saturating_inc();
|
||||
assert_eq!(v, i);
|
||||
}
|
||||
v += u32::MAX - 10;
|
||||
v.defensive_saturating_inc();
|
||||
assert_eq!(v, u32::MAX);
|
||||
v.defensive_saturating_inc();
|
||||
assert_eq!(v, u32::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic(expected = "Defensive")]
|
||||
fn defensive_saturating_inc_panics() {
|
||||
let mut v = u32::MAX;
|
||||
v.defensive_saturating_inc(); // defensive failure
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn defensive_saturating_dec_works() {
|
||||
let mut v = u32::MAX;
|
||||
for i in 1..10 {
|
||||
v.defensive_saturating_dec();
|
||||
assert_eq!(v, u32::MAX - i);
|
||||
}
|
||||
v -= u32::MAX - 10;
|
||||
v.defensive_saturating_dec();
|
||||
assert_eq!(v, 0);
|
||||
v.defensive_saturating_dec();
|
||||
assert_eq!(v, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
#[should_panic(expected = "Defensive")]
|
||||
fn defensive_saturating_dec_panics() {
|
||||
let mut v = 0_u32;
|
||||
v.defensive_saturating_dec(); // defensive failure
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn defensive_truncating_from_vec_defensive_works() {
|
||||
|
||||
Reference in New Issue
Block a user