mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 11:27:58 +00:00
staking: Flexible generation of reward curve and associated tweaks (#8327)
* Initial abstraction * Alter rest of APIs * Fixes * Some extra getters in Gilt pallet. * Refactor Gilt to avoid u128 conversions * Simplify and improve pow in per_things * Add scalar division to per_things * Renaming from_fraction -> from_float, drop _approximation * Fixes * Fixes * Fixes * Fixes * Make stuff build * Fixes * Fixes * Fixes * Fixes * Update .gitignore Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/gilt/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/gilt/src/mock.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Fixes * Fixes * Fixes Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
@@ -782,6 +782,51 @@ impl<T: Config> SessionInterface<<T as frame_system::Config>::AccountId> for T w
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for determining how much of a balance should be paid out on the current era.
|
||||
pub trait EraPayout<Balance> {
|
||||
/// Determine the payout for this era.
|
||||
///
|
||||
/// Returns the amount to be paid to stakers in this era, as well as whatever else should be
|
||||
/// paid out ("the rest").
|
||||
fn era_payout(
|
||||
total_staked: Balance,
|
||||
total_issuance: Balance,
|
||||
era_duration_millis: u64,
|
||||
) -> (Balance, Balance);
|
||||
}
|
||||
|
||||
impl<Balance: Default> EraPayout<Balance> for () {
|
||||
fn era_payout(
|
||||
_total_staked: Balance,
|
||||
_total_issuance: Balance,
|
||||
_era_duration_millis: u64,
|
||||
) -> (Balance, Balance) {
|
||||
(Default::default(), Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConvertCurve<T>(sp_std::marker::PhantomData<T>);
|
||||
impl<
|
||||
Balance: AtLeast32BitUnsigned + Clone,
|
||||
T: Get<&'static PiecewiseLinear<'static>>,
|
||||
> EraPayout<Balance> for ConvertCurve<T> {
|
||||
fn era_payout(
|
||||
total_staked: Balance,
|
||||
total_issuance: Balance,
|
||||
era_duration_millis: u64,
|
||||
) -> (Balance, Balance) {
|
||||
let (validator_payout, max_payout) = inflation::compute_total_payout(
|
||||
&T::get(),
|
||||
total_staked,
|
||||
total_issuance,
|
||||
// Duration of era; more than u64::MAX is rewarded as u64::MAX.
|
||||
era_duration_millis,
|
||||
);
|
||||
let rest = max_payout.saturating_sub(validator_payout.clone());
|
||||
(validator_payout, rest)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
|
||||
/// The staking balance.
|
||||
type Currency: LockableCurrency<Self::AccountId, Moment = Self::BlockNumber>;
|
||||
@@ -838,9 +883,9 @@ pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
|
||||
/// Interface for interacting with a session module.
|
||||
type SessionInterface: self::SessionInterface<Self::AccountId>;
|
||||
|
||||
/// The NPoS reward curve used to define yearly inflation.
|
||||
/// The payout for validators and the system for the current era.
|
||||
/// See [Era payout](./index.html#era-payout).
|
||||
type RewardCurve: Get<&'static PiecewiseLinear<'static>>;
|
||||
type EraPayout: EraPayout<BalanceOf<Self>>;
|
||||
|
||||
/// Something that can estimate the next session change, accurately or as a best effort guess.
|
||||
type NextNewSession: EstimateNextNewSession<Self::BlockNumber>;
|
||||
@@ -2413,7 +2458,7 @@ impl<T: Config> Module<T> {
|
||||
|
||||
// This is the fraction of the total reward that the validator and the
|
||||
// nominators will get.
|
||||
let validator_total_reward_part = Perbill::from_rational_approximation(
|
||||
let validator_total_reward_part = Perbill::from_rational(
|
||||
validator_reward_points,
|
||||
total_reward_points,
|
||||
);
|
||||
@@ -2428,7 +2473,7 @@ impl<T: Config> Module<T> {
|
||||
|
||||
let validator_leftover_payout = validator_total_payout - validator_commission_payout;
|
||||
// Now let's calculate how this is split to the validator.
|
||||
let validator_exposure_part = Perbill::from_rational_approximation(
|
||||
let validator_exposure_part = Perbill::from_rational(
|
||||
exposure.own,
|
||||
exposure.total,
|
||||
);
|
||||
@@ -2445,7 +2490,7 @@ impl<T: Config> Module<T> {
|
||||
// Lets now calculate how this is split to the nominators.
|
||||
// Reward only the clipped exposures. Note this is not necessarily sorted.
|
||||
for nominator in exposure.others.iter() {
|
||||
let nominator_exposure_part = Perbill::from_rational_approximation(
|
||||
let nominator_exposure_part = Perbill::from_rational(
|
||||
nominator.value,
|
||||
exposure.total,
|
||||
);
|
||||
@@ -2837,15 +2882,10 @@ impl<T: Config> Module<T> {
|
||||
if let Some(active_era_start) = active_era.start {
|
||||
let now_as_millis_u64 = T::UnixTime::now().as_millis().saturated_into::<u64>();
|
||||
|
||||
let era_duration = now_as_millis_u64 - active_era_start;
|
||||
let (validator_payout, max_payout) = inflation::compute_total_payout(
|
||||
&T::RewardCurve::get(),
|
||||
Self::eras_total_stake(&active_era.index),
|
||||
T::Currency::total_issuance(),
|
||||
// Duration of era; more than u64::MAX is rewarded as u64::MAX.
|
||||
era_duration.saturated_into::<u64>(),
|
||||
);
|
||||
let rest = max_payout.saturating_sub(validator_payout);
|
||||
let era_duration = (now_as_millis_u64 - active_era_start).saturated_into::<u64>();
|
||||
let staked = Self::eras_total_stake(&active_era.index);
|
||||
let issuance = T::Currency::total_issuance();
|
||||
let (validator_payout, rest) = T::EraPayout::era_payout(staked, issuance, era_duration);
|
||||
|
||||
Self::deposit_event(RawEvent::EraPayout(active_era.index, validator_payout, rest));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user