mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 07:01:05 +00:00
Extended Balance Type for Staking's Election (#2134)
* First draft of extended balance type * Test cleanup. * Update staking docs. * Add a good failing test case for quintill * Bring back saturating. * Some final fixes * A few more. * Update wasm; Bump spec; * Re-bump. * Custom lossy conversion from currency to vote * remove print * Fix reverse conversion issue. * void. Re-trigger ci.
This commit is contained in:
@@ -254,82 +254,48 @@ impl From<codec::Compact<Perbill>> for Perbill {
|
||||
}
|
||||
}
|
||||
|
||||
/// Perquintill is parts-per-quintillion. It stores a value between 0 and 1 in fixed point and
|
||||
/// PerU128 is parts-per-u128-max-value. It stores a value between 0 and 1 in fixed point and
|
||||
/// provides a means to multiply some other value by that.
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Perquintill(u64);
|
||||
pub struct PerU128(u128);
|
||||
|
||||
const QUINTILLION: u64 = 1_000_000_000_000_000_000;
|
||||
const U128: u128 = u128::max_value();
|
||||
|
||||
impl Perquintill {
|
||||
impl PerU128 {
|
||||
/// Nothing.
|
||||
pub fn zero() -> Self { Self(0) }
|
||||
|
||||
/// Everything.
|
||||
pub fn one() -> Self { Self(QUINTILLION) }
|
||||
pub fn one() -> Self { Self(U128) }
|
||||
|
||||
/// Construct new instance where `x` is in quintillionths. Value equivalent to `x / 1,000,000,000,000,000,000`.
|
||||
pub fn from_quintillionths(x: u64) -> Self { Self(x.min(QUINTILLION)) }
|
||||
|
||||
/// Construct new instance where `x` is in billionths. Value equivalent to `x / 1,000,000,000`.
|
||||
pub fn from_billionths(x: u64) -> Self { Self(x.min(1_000_000_000) * 1_000_000_000 ) }
|
||||
|
||||
/// Construct new instance where `x` is in millionths. Value equivalent to `x / 1,000,000`.
|
||||
pub fn from_millionths(x: u64) -> Self { Self(x.min(1_000_000) * 1000_000_000_000) }
|
||||
/// Construct new instance where `x` is parts in u128::max_value. Equal to x/U128::max_value.
|
||||
pub fn from_max_value(x: u128) -> Self { Self(x) }
|
||||
|
||||
/// Construct new instance where `x` is denominator and the nominator is 1.
|
||||
pub fn from_xth(x: u64) -> Self { Self(QUINTILLION / x.min(QUINTILLION)) }
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
/// Construct new instance whose value is equal to `x` (between 0 and 1).
|
||||
pub fn from_fraction(x: f64) -> Self { Self((x.max(0.0).min(1.0) * QUINTILLION as f64) as u64) }
|
||||
pub fn from_xth(x: u128) -> Self { Self(U128/x.max(1)) }
|
||||
}
|
||||
|
||||
impl ::rstd::ops::Deref for Perquintill {
|
||||
type Target = u64;
|
||||
impl ::rstd::ops::Deref for PerU128 {
|
||||
type Target = u128;
|
||||
|
||||
fn deref(&self) -> &u64 {
|
||||
fn deref(&self) -> &u128 {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> ::rstd::ops::Mul<N> for Perquintill
|
||||
where
|
||||
N: traits::As<u64>
|
||||
{
|
||||
type Output = N;
|
||||
fn mul(self, b: N) -> Self::Output {
|
||||
<N as traits::As<u64>>::sa(b.as_().saturating_mul(self.0) / QUINTILLION)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl From<f64> for Perquintill {
|
||||
fn from(x: f64) -> Perquintill {
|
||||
Perquintill::from_fraction(x)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl From<f32> for Perquintill {
|
||||
fn from(x: f32) -> Perquintill {
|
||||
Perquintill::from_fraction(x as f64)
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::CompactAs for Perquintill {
|
||||
type As = u64;
|
||||
fn encode_as(&self) -> &u64 {
|
||||
impl codec::CompactAs for PerU128 {
|
||||
type As = u128;
|
||||
fn encode_as(&self) -> &u128 {
|
||||
&self.0
|
||||
}
|
||||
fn decode_from(x: u64) -> Perquintill {
|
||||
Perquintill(x)
|
||||
fn decode_from(x: u128) -> PerU128 {
|
||||
Self(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<codec::Compact<Perquintill>> for Perquintill {
|
||||
fn from(x: codec::Compact<Perquintill>) -> Perquintill {
|
||||
impl From<codec::Compact<PerU128>> for PerU128 {
|
||||
fn from(x: codec::Compact<PerU128>) -> PerU128 {
|
||||
x.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,35 @@ impl<A, B: Default> Convert<A, B> for () {
|
||||
fn convert(_: A) -> B { Default::default() }
|
||||
}
|
||||
|
||||
/// A structure that converts the currency type into a lossy u64
|
||||
/// And back from u128
|
||||
pub struct CurrencyToVoteHandler;
|
||||
|
||||
impl Convert<u128, u64> for CurrencyToVoteHandler {
|
||||
fn convert(x: u128) -> u64 {
|
||||
if x >> 96 == 0 {
|
||||
// Remove dust; divide by 2^32
|
||||
(x >> 32) as u64
|
||||
} else {
|
||||
u64::max_value()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Convert<u128, u128> for CurrencyToVoteHandler {
|
||||
fn convert(x: u128) -> u128 {
|
||||
// if it practically fits in u64
|
||||
if x >> 64 == 0 {
|
||||
// Add zero dust; multiply by 2^32
|
||||
x << 32
|
||||
}
|
||||
else {
|
||||
// 0000_0000_FFFF_FFFF_FFFF_FFFF_0000_0000
|
||||
(u64::max_value() << 32) as u128
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A structure that performs identity conversion.
|
||||
pub struct Identity;
|
||||
impl<T> Convert<T, T> for Identity {
|
||||
|
||||
Reference in New Issue
Block a user