Skip to content

Commit

Permalink
Merge pull request #261 from AurevoirXavier/try
Browse files Browse the repository at this point in the history
New `CurrencyToPower` and `PowerToVotes`
  • Loading branch information
hackfisher authored Feb 14, 2020
2 parents 908aee0 + 6048c31 commit ac93bd2
Show file tree
Hide file tree
Showing 13 changed files with 243 additions and 1,151 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion bin/node/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub type AccountIndex = u32;
pub type Balance = u128;

/// Power of an account.
pub type Power = u128;
pub type Power = u32;

/// Type used for expressing timestamp.
pub type Moment = u64;
Expand Down
26 changes: 2 additions & 24 deletions bin/node/runtime/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use sp_runtime::{
{Fixed64, Perbill},
};

use crate::{constants::supply::TOTAL_POWER, Authorship, Balances, MaximumBlockWeight, NegativeImbalance, System};
use node_primitives::{Balance, Power};
use crate::{Authorship, Balances, MaximumBlockWeight, NegativeImbalance, System};
use node_primitives::Balance;

pub struct Author;
impl OnUnbalanced<NegativeImbalance> for Author {
Expand All @@ -35,28 +35,6 @@ impl OnUnbalanced<NegativeImbalance> for Author {
}
}

/// Struct that handles the conversion of Balance -> `u64`. This is used for staking's election
/// calculation.
pub struct PowerToVoteHandler;

impl PowerToVoteHandler {
fn factor() -> Power {
(TOTAL_POWER / u64::max_value() as Power).max(1)
}
}

impl Convert<Power, u64> for PowerToVoteHandler {
fn convert(x: Power) -> u64 {
(x / Self::factor()) as u64
}
}

impl Convert<u128, Power> for PowerToVoteHandler {
fn convert(x: u128) -> Power {
x * Self::factor()
}
}

/// Convert from weight to balance via a simple coefficient multiplication
/// The associated type C encapsulates a constant in units of balance per weight
pub struct LinearWeightToFee<C>(sp_std::marker::PhantomData<C>);
Expand Down
16 changes: 7 additions & 9 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

/// Implementations of some helper traits passed into runtime modules as associated types.
pub mod impls;
use impls::{Author, LinearWeightToFee, PowerToVoteHandler, TargetedFeeAdjustment};
use impls::{Author, LinearWeightToFee, TargetedFeeAdjustment};
/// Constant values used within the runtime.
pub mod constants;
use constants::{currency::*, supply::*, time::*};
Expand All @@ -49,17 +49,15 @@ use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
use sp_api::impl_runtime_apis;
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use sp_core::{
u32_trait::{_1, _2, _3, _4},
u32_trait::{_1, _3, _4},
OpaqueMetadata,
};
use sp_inherents::{CheckInherentsResult, InherentData};
use sp_runtime::transaction_validity::TransactionValidity;
use sp_runtime::{
create_runtime_str,
curve::PiecewiseLinear,
generic, impl_opaque_keys,
create_runtime_str, generic, impl_opaque_keys,
traits::{self, BlakeTwo256, Block as BlockT, NumberFor, OpaqueKeys, SaturatedConversion, StaticLookup},
ApplyExtrinsicResult, Perbill, Permill,
ApplyExtrinsicResult, Perbill,
};
use sp_staking::SessionIndex;
use sp_std::vec::Vec;
Expand Down Expand Up @@ -242,7 +240,7 @@ impl pallet_session::Trait for Runtime {
}

impl pallet_session::historical::Trait for Runtime {
type FullIdentification = Exposure<AccountId, Balance>;
type FullIdentification = Exposure<AccountId, Power>;
type FullIdentificationOf = ExposureOf<Runtime>;
}

Expand Down Expand Up @@ -459,7 +457,7 @@ parameter_types! {

impl pallet_staking::Trait for Runtime {
type Time = Timestamp;
type PowerToVote = PowerToVoteHandler;
// type PowerToVotes = PowerToVotesHandler;
type Event = Event;
type SessionsPerEra = SessionsPerEra;
type BondingDurationInEra = BondingDurationInEra;
Expand Down Expand Up @@ -507,7 +505,7 @@ construct_runtime!(
Offences: pallet_offences::{Module, Call, Storage, Event},
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
Nicks: pallet_nicks::{Module, Call, Storage, Event<T>},

Balances: pallet_ring::{default, Error},
Kton: pallet_kton::{default, Error},
Staking: pallet_staking::{default, OfflineWorker},
Expand Down
16 changes: 1 addition & 15 deletions frame/staking/src/inflation.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
use frame_support::traits::Get;
use sp_core::U256;
use sp_runtime::{
traits::{IntegerSquareRoot, SaturatedConversion},
Perbill, Perquintill,
};
use sp_std::convert::TryInto;

use crate::{KtonBalance, Moment, MomentOf, Power, RingBalance, Trait};

type Balance = u128;

// power is a mixture of ring and kton
// power = ring_ratio * POWER_COUNT / 2 + kton_ratio * POWER_COUNT / 2
pub fn compute_balance_power<T, S>(active: S, pool: S) -> Power
where
T: Trait,
S: TryInto<Balance>,
{
Perquintill::from_rational_approximation(active.saturated_into::<Power>(), pool.saturated_into::<Power>().max(1))
* (T::TotalPower::get() / 2)
}
use crate::{Balance, KtonBalance, Moment, MomentOf, RingBalance, Trait};

// 1 - (99 / 100) ^ sqrt(year)
// <T: Trait + 'static>() -> RingBalance<T>
Expand Down
75 changes: 37 additions & 38 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,12 @@ mod types {
pub type Points = u32;
/// Type used for expressing timestamp.
pub type Moment = Timestamp;
/// Balance of an account.
pub type Balance = u128;
/// Power of an account.
pub type Power = u128;
pub type Power = u32;
/// Votes of an account.
pub type Votes = u32;

pub type RingBalance<T> = <RingCurrency<T> as Currency<AccountId<T>>>::Balance;
pub type RingPositiveImbalance<T> = <RingCurrency<T> as Currency<AccountId<T>>>::PositiveImbalance;
Expand Down Expand Up @@ -307,21 +311,21 @@ use frame_support::{
};
use frame_system::{self as system, ensure_root, ensure_signed};
use pallet_session::{historical::OnSessionEnding, SelectInitialValidators};
use sp_phragmen::{ExtendedBalance as Votes, PhragmenStakedAssignment};
use sp_phragmen::PhragmenStakedAssignment;
use sp_runtime::{
traits::{
Bounded, CheckedSub, Convert, EnsureOrigin, One, SaturatedConversion, Saturating, SimpleArithmetic,
StaticLookup, Zero,
},
Perbill, RuntimeDebug,
Perbill, Perquintill, RuntimeDebug,
};
#[cfg(feature = "std")]
use sp_runtime::{Deserialize, Serialize};
use sp_staking::{
offence::{Offence, OffenceDetails, OnOffenceHandler, ReportOffence},
SessionIndex,
};
use sp_std::{borrow::ToOwned, marker::PhantomData, vec, vec::Vec};
use sp_std::{borrow::ToOwned, convert::TryInto, marker::PhantomData, vec, vec::Vec};

use darwinia_support::{
LockIdentifier, LockableCurrency, NormalLock, StakingLock, WithdrawLock, WithdrawReason, WithdrawReasons,
Expand Down Expand Up @@ -645,12 +649,12 @@ pub trait Trait: frame_system::Trait {
/// Time used for computing era duration.
type Time: Time;

/// Convert a balance into a number used for election calculation.
/// This must fit into a `u64` but is allowed to be sensibly lossy.
/// TODO: #1377
/// The backward convert should be removed as the new Phragmen API returns ratio.
/// The post-processing needs it but will be moved to off-chain. TODO: #2908
type PowerToVote: Convert<Power, u64> + Convert<u128, Power>;
// /// Convert a balance into a number used for election calculation.
// /// This must fit into a `u64` but is allowed to be sensibly lossy.
// /// TODO: #1377
// /// The backward convert should be removed as the new Phragmen API returns ratio.
// /// The post-processing needs it but will be moved to off-chain. TODO: #2908
// type PowerToVotes: Convert<Power, Votes>;

/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;
Expand Down Expand Up @@ -778,7 +782,7 @@ decl_storage! {
config
.stakers
.iter()
.map(|&(_, _, r, _)| inflation::compute_balance_power::<T, _>(r, <Module<T>>::ring_pool()))
.map(|&(_, _, r, _)| <Module<T>>::currency_to_power::<_>(r, <Module<T>>::ring_pool()))
.min()
.unwrap_or_default()
}): Power;
Expand Down Expand Up @@ -1540,13 +1544,22 @@ decl_module! {
impl<T: Trait> Module<T> {
// PUBLIC IMMUTABLES

// power is a mixture of ring and kton
// power = ring_ratio * POWER_COUNT / 2 + kton_ratio * POWER_COUNT / 2
pub fn currency_to_power<S: TryInto<Balance>>(active: S, pool: S) -> Power {
(Perquintill::from_rational_approximation(
active.saturated_into::<Balance>(),
pool.saturated_into::<Balance>().max(1),
) * (T::TotalPower::get() as Balance / 2)) as _
}

/// The total power that can be slashed from a stash account as of right now.
pub fn slashable_power_of(stash: &T::AccountId) -> Power {
pub fn power_of(stash: &T::AccountId) -> Power {
Self::bonded(stash)
.and_then(Self::ledger)
.map(|l| {
inflation::compute_balance_power::<T, _>(l.active_ring, Self::ring_pool())
+ inflation::compute_balance_power::<T, _>(l.active_kton, Self::kton_pool())
Self::currency_to_power::<_>(l.active_ring, Self::ring_pool())
+ Self::currency_to_power::<_>(l.active_kton, Self::kton_pool())
})
.unwrap_or_default()
}
Expand Down Expand Up @@ -1873,12 +1886,13 @@ impl<T: Trait> Module<T> {

all_nominators.extend(nominator_votes);

let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::PowerToVote>(
let maybe_phragmen_result = sp_phragmen::elect::<_, _>(
Self::validator_count() as usize,
Self::minimum_validator_count().max(1) as usize,
all_validators,
all_nominators,
Self::slashable_power_of,
Self::power_of,
T::TotalPower::get(),
);

if let Some(phragmen_result) = maybe_phragmen_result {
Expand All @@ -1888,13 +1902,7 @@ impl<T: Trait> Module<T> {
.map(|(s, _)| s.clone())
.collect::<Vec<T::AccountId>>();
let assignments = phragmen_result.assignments;
let to_votes = |p: Power| <T::PowerToVote as Convert<Power, u64>>::convert(p) as Votes;
let to_power = |v: Votes| <T::PowerToVote as Convert<Votes, Power>>::convert(v);
let mut supports = sp_phragmen::build_support_map::<_, _, _, T::PowerToVote>(
&elected_stashes,
&assignments,
Self::slashable_power_of,
);
let mut supports = sp_phragmen::build_support_map::<_, _>(&elected_stashes, &assignments, Self::power_of);

if cfg!(feature = "equalize") {
let mut staked_assignments: Vec<(T::AccountId, Vec<PhragmenStakedAssignment<T::AccountId>>)> =
Expand All @@ -1910,22 +1918,16 @@ impl<T: Trait> Module<T> {
continue;
}
for (c, per_thing) in assignment.iter() {
let nominator_stake = to_votes(Self::slashable_power_of(n));
let nominator_stake = Self::power_of(n);
let other_stake = *per_thing * nominator_stake;
staked_assignment.push((c.clone(), other_stake));
}
staked_assignments.push((n.clone(), staked_assignment));
}

let tolerance = 0_u128;
let tolerance: Votes = 0;
let iterations = 2_usize;
sp_phragmen::equalize::<_, _, T::PowerToVote, _>(
staked_assignments,
&mut supports,
tolerance,
iterations,
Self::slashable_power_of,
);
sp_phragmen::equalize::<_, _>(staked_assignments, &mut supports, tolerance, iterations, Self::power_of);
}

// Clear Stakers.
Expand All @@ -1938,19 +1940,16 @@ impl<T: Trait> Module<T> {
for (c, s) in supports.into_iter() {
// build `struct exposure` from `support`
let exposure = Exposure {
own: to_power(s.own),
own: s.own,
// This might reasonably saturate and we cannot do much about it. The sum of
// someone's stake might exceed the balance type if they have the maximum amount
// of balance and receive some support. This is super unlikely to happen, yet
// we simulate it in some tests.
total: to_power(s.total),
total: s.total,
others: s
.others
.into_iter()
.map(|(who, value)| IndividualExposure {
who,
value: to_power(value),
})
.map(|(who, value)| IndividualExposure { who, value })
.collect::<Vec<IndividualExposure<_, _>>>(),
};
if exposure.total < slot_stake {
Expand Down
2 changes: 2 additions & 0 deletions frame/support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2018"
[dependencies]
# crates.io
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
num-traits = { version = "0.2.8", default-features = false }

# github.com
frame-support = { git = "https://github.com/paritytech/substrate.git", rev = "c2fccb36ffacd118fc3502aa93453580a07dc402", default-features = false }
Expand All @@ -17,6 +18,7 @@ sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate.gi
default = ["std"]
std = [
"codec/std",
"num-traits/std",

"frame-support/std",
"sp-runtime/std",
Expand Down
Loading

0 comments on commit ac93bd2

Please sign in to comment.