Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

staking: Flexible generation of reward curve and associated tweaks #8327

Merged
26 commits merged into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ rls*.log
.cargo/
.cargo-remote.toml
*.bin
*.iml
2 changes: 1 addition & 1 deletion bin/node/runtime/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ mod multiplier_tests {
let t1 = v * (s/m - ss/m);
let t2 = v.powi(2) * (s/m - ss/m).powi(2) / 2.0;
let next_float = previous_float * (1.0 + t1 + t2);
Multiplier::from_fraction(next_float)
Multiplier::from_float(next_float)
}

fn run_with_system_weight<F>(w: Weight, assertions: F) where F: Fn() -> () {
Expand Down
9 changes: 5 additions & 4 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ parameter_types! {
pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;
pub const MaxIterations: u32 = 10;
// 0.05%. The higher the value, the more strict solution acceptance becomes.
pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
pub MinSolutionScoreBump: Perbill = Perbill::from_rational(5u32, 10_000);
pub OffchainSolutionWeightLimit: Weight = RuntimeBlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed")
Expand All @@ -496,7 +496,7 @@ impl pallet_staking::Config for Runtime {
pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>
>;
type SessionInterface = Self;
type RewardCurve = RewardCurve;
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type NextNewSession = Session;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type ElectionLookahead = ElectionLookahead;
Expand All @@ -520,7 +520,7 @@ parameter_types! {
pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
pallet_election_provider_multi_phase::FallbackStrategy::Nothing;

pub SolutionImprovementThreshold: Perbill = Perbill::from_rational_approximation(1u32, 10_000);
pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(1u32, 10_000);

// miner configs
pub const MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64;
Expand Down Expand Up @@ -767,7 +767,7 @@ parameter_types! {
pub const DepositPerContract: Balance = TombstoneDeposit::get();
pub const DepositPerStorageByte: Balance = deposit(0, 1);
pub const DepositPerStorageItem: Balance = deposit(1, 0);
pub RentFraction: Perbill = Perbill::from_rational_approximation(1u32, 30 * DAYS);
pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS);
pub const SurchargeReward: Balance = 150 * MILLICENTS;
pub const SignedClaimHandicap: u32 = 2;
pub const MaxDepth: u32 = 32;
Expand Down Expand Up @@ -1065,6 +1065,7 @@ parameter_types! {
impl pallet_gilt::Config for Runtime {
type Event = Event;
type Currency = Balances;
type CurrencyBalance = Balance;
type AdminOrigin = frame_system::EnsureRoot<AccountId>;
type Deficit = ();
type Surplus = ();
Expand Down
2 changes: 1 addition & 1 deletion frame/babe/src/equivocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl<FullIdentification: Clone> Offence<FullIdentification>

fn slash_fraction(offenders_count: u32, validator_set_count: u32) -> Perbill {
// the formula is min((3k / n)^2, 1)
let x = Perbill::from_rational_approximation(3 * offenders_count, validator_set_count);
let x = Perbill::from_rational(3 * offenders_count, validator_set_count);
// _ ^ 2
x.square()
}
Expand Down
2 changes: 1 addition & 1 deletion frame/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ impl<T: Config> frame_support::traits::EstimateNextSessionRotation<T::BlockNumbe
let elapsed = CurrentSlot::get().saturating_sub(Self::current_epoch_start()) + 1;

(
Some(Percent::from_rational_approximation(
Some(Percent::from_rational(
*elapsed,
T::EpochDuration::get(),
)),
Expand Down
2 changes: 1 addition & 1 deletion frame/babe/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ impl pallet_staking::Config for Test {
type SlashCancelOrigin = frame_system::EnsureRoot<Self::AccountId>;
type SessionInterface = Self;
type UnixTime = pallet_timestamp::Module<Test>;
type RewardCurve = RewardCurve;
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type NextNewSession = Session;
type ElectionLookahead = ElectionLookahead;
Expand Down
2 changes: 1 addition & 1 deletion frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ parameter_types! {
pub const DepositPerContract: u64 = 8 * DepositPerStorageByte::get();
pub const DepositPerStorageByte: u64 = 10_000;
pub const DepositPerStorageItem: u64 = 10_000;
pub RentFraction: Perbill = Perbill::from_rational_approximation(4u32, 10_000u32);
pub RentFraction: Perbill = Perbill::from_rational(4u32, 10_000u32);
pub const SurchargeReward: u64 = 500_000;
pub const MaxDepth: u32 = 100;
pub const MaxValueSize: u32 = 16_384;
Expand Down
60 changes: 48 additions & 12 deletions frame/gilt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub mod weights;
pub mod pallet {
use sp_std::prelude::*;
use sp_arithmetic::{Perquintill, PerThing};
use sp_runtime::traits::{Zero, Saturating, SaturatedConversion};
use sp_runtime::traits::{Zero, Saturating};
use frame_support::traits::{Currency, OnUnbalanced, ReservableCurrency};
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
Expand All @@ -96,7 +96,13 @@ pub mod pallet {
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;

/// Currency type that this works on.
type Currency: ReservableCurrency<Self::AccountId>;
type Currency: ReservableCurrency<Self::AccountId, Balance=Self::CurrencyBalance>;

/// Just the `Currency::Balance` type; we have this item to allow us to constrain it to
/// `From<u64>`.
type CurrencyBalance:
sp_runtime::traits::AtLeast32BitUnsigned + codec::FullCodec + Copy
+ MaybeSerializeDeserialize + sp_std::fmt::Debug + Default + From<u64>;
Comment on lines +101 to +105
Copy link
Contributor

@kianenigma kianenigma Mar 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only alternative that I can think of is to add a where <T::Currency as _>::Balance: From<u64> to most functions of this pallet, and while this is not pretty either, I guess it has less footprint than sprinkling wheres.


/// Origin required for setting the target proportion to be under gilt.
type AdminOrigin: EnsureOrigin<Self::Origin>;
Expand Down Expand Up @@ -448,11 +454,10 @@ pub mod pallet {
// Multiply the proportion it is by the total issued.
let total_issuance = T::Currency::total_issuance().saturating_sub(T::IgnoredIssuance::get());
ActiveTotal::<T>::mutate(|totals| {
let nongilt_issuance: u128 = total_issuance.saturating_sub(totals.frozen)
.saturated_into();
let nongilt_issuance = total_issuance.saturating_sub(totals.frozen);
let effective_issuance = totals.proportion.left_from_one()
.saturating_reciprocal_mul(nongilt_issuance);
let gilt_value: BalanceOf<T> = (gilt.proportion * effective_issuance).saturated_into();
let gilt_value = gilt.proportion * effective_issuance;

totals.frozen = totals.frozen.saturating_sub(gilt.amount);
totals.proportion = totals.proportion.saturating_sub(gilt.proportion);
Expand Down Expand Up @@ -488,7 +493,40 @@ pub mod pallet {
}
}

/// Issuance information returned by `issuance()`.
pub struct IssuanceInfo<Balance> {
/// The balance held in reserve over all active gilts.
pub reserved: Balance,
/// The issuance not held in reserve for active gilts. Together with `reserved` this sums to
/// `Currency::total_issuance`.
pub non_gilt: Balance,
/// The balance that `reserved` is effectively worth, at present. This is not issued funds
/// and could be less than `reserved` (though in most cases should be greater).
pub effective: Balance,
}

impl<T: Config> Pallet<T> {
/// Get the target amount of Gilts that we're aiming for.
pub fn target() -> Perquintill {
ActiveTotal::<T>::get().target
}

/// Returns information on the issuance of gilts.
pub fn issuance() -> IssuanceInfo<BalanceOf<T>> {
let totals = ActiveTotal::<T>::get();

let total_issuance = T::Currency::total_issuance();
let non_gilt = total_issuance.saturating_sub(totals.frozen);
let effective = totals.proportion.left_from_one()
.saturating_reciprocal_mul(non_gilt);

IssuanceInfo {
reserved: totals.frozen,
non_gilt,
effective,
}
}

/// Attempt to enlarge our gilt-set from bids in order to satisfy our desired target amount
/// of funds frozen into gilts.
pub fn pursue_target(max_bids: u32) -> Weight {
Expand All @@ -497,11 +535,10 @@ pub mod pallet {
let missing = totals.target.saturating_sub(totals.proportion);

let total_issuance = T::Currency::total_issuance().saturating_sub(T::IgnoredIssuance::get());
let nongilt_issuance: u128 = total_issuance.saturating_sub(totals.frozen)
.saturated_into();
let nongilt_issuance = total_issuance.saturating_sub(totals.frozen);
let effective_issuance = totals.proportion.left_from_one()
.saturating_reciprocal_mul(nongilt_issuance);
let intake: BalanceOf<T> = (missing * effective_issuance).saturated_into();
let intake = missing * effective_issuance;

let (bids_taken, queues_hit) = Self::enlarge(intake, max_bids);
let first_from_each_queue = T::WeightInfo::pursue_target_per_queue(queues_hit);
Expand Down Expand Up @@ -550,13 +587,12 @@ pub mod pallet {
qs[queue_index].1 = qs[queue_index].1.saturating_sub(bid.amount);

// Now to activate the bid...
let nongilt_issuance: u128 = total_issuance.saturating_sub(totals.frozen)
.saturated_into();
let nongilt_issuance = total_issuance.saturating_sub(totals.frozen);
let effective_issuance = totals.proportion.left_from_one()
.saturating_reciprocal_mul(nongilt_issuance);
let n: u128 = amount.saturated_into();
let n = amount;
let d = effective_issuance;
let proportion = Perquintill::from_rational_approximation(n, d);
let proportion = Perquintill::from_rational(n, d);
let who = bid.who;
let index = totals.index;
totals.frozen += bid.amount;
Expand Down
1 change: 1 addition & 0 deletions frame/gilt/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ ord_parameter_types! {
impl pallet_gilt::Config for Test {
type Event = Event;
type Currency = Balances;
type CurrencyBalance = <Self as pallet_balances::Config>::Balance;
type AdminOrigin = frame_system::EnsureSignedBy<One, Self::AccountId>;
type Deficit = ();
type Surplus = ();
Expand Down
2 changes: 1 addition & 1 deletion frame/grandpa/src/equivocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ impl<FullIdentification: Clone> Offence<FullIdentification>

fn slash_fraction(offenders_count: u32, validator_set_count: u32) -> Perbill {
// the formula is min((3k / n)^2, 1)
let x = Perbill::from_rational_approximation(3 * offenders_count, validator_set_count);
let x = Perbill::from_rational(3 * offenders_count, validator_set_count);
// _ ^ 2
x.square()
}
Expand Down
2 changes: 1 addition & 1 deletion frame/grandpa/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ impl pallet_staking::Config for Test {
type SlashCancelOrigin = frame_system::EnsureRoot<Self::AccountId>;
type SessionInterface = Self;
type UnixTime = pallet_timestamp::Module<Test>;
type RewardCurve = RewardCurve;
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type NextNewSession = Session;
type ElectionLookahead = ElectionLookahead;
Expand Down
8 changes: 2 additions & 6 deletions frame/im-online/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,7 @@ use frame_support::{
},
Parameter,
};
use frame_system::ensure_none;
use frame_system::offchain::{
SendTransactionTypes,
SubmitTransaction,
};
use frame_system::{ensure_none, offchain::{SendTransactionTypes, SubmitTransaction}};
pub use weights::WeightInfo;

pub mod sr25519 {
Expand Down Expand Up @@ -813,7 +809,7 @@ impl<Offender: Clone> Offence<Offender> for UnresponsivenessOffence<Offender> {
// basically, 10% can be offline with no slash, but after that, it linearly climbs up to 7%
// when 13/30 are offline (around 5% when 1/3 are offline).
if let Some(threshold) = offenders.checked_sub(validator_set_count / 10 + 1) {
let x = Perbill::from_rational_approximation(3 * threshold, validator_set_count);
let x = Perbill::from_rational(3 * threshold, validator_set_count);
x.saturating_mul(Perbill::from_percent(7))
} else {
Perbill::default()
Expand Down
2 changes: 1 addition & 1 deletion frame/offences/benchmarking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ impl pallet_staking::Config for Test {
type SlashCancelOrigin = frame_system::EnsureRoot<Self::AccountId>;
type BondingDuration = ();
type SessionInterface = Self;
type RewardCurve = RewardCurve;
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type NextNewSession = Session;
type ElectionLookahead = ();
type Call = Call;
Expand Down
2 changes: 1 addition & 1 deletion frame/session/benchmarking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl pallet_staking::Config for Test {
type SlashCancelOrigin = frame_system::EnsureRoot<Self::AccountId>;
type BondingDuration = ();
type SessionInterface = Self;
type RewardCurve = RewardCurve;
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type NextNewSession = Session;
type ElectionLookahead = ();
type Call = Call;
Expand Down
4 changes: 2 additions & 2 deletions frame/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,12 @@ impl<
// (0% is never returned).
let progress = if now >= offset {
let current = (now - offset) % period.clone() + One::one();
Some(Percent::from_rational_approximation(
Some(Percent::from_rational(
current.clone(),
period.clone(),
))
} else {
Some(Percent::from_rational_approximation(
Some(Percent::from_rational(
now + One::one(),
offset,
))
Expand Down
2 changes: 1 addition & 1 deletion frame/staking/fuzzer/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl pallet_staking::Config for Test {
type SlashCancelOrigin = frame_system::EnsureRoot<Self::AccountId>;
type BondingDuration = ();
type SessionInterface = Self;
type RewardCurve = RewardCurve;
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type NextNewSession = Session;
type ElectionLookahead = ();
type Call = Call;
Expand Down
2 changes: 1 addition & 1 deletion frame/staking/src/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn compute_total_payout<N>(
// Milliseconds per year for the Julian year (365.25 days).
const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;

let portion = Perbill::from_rational_approximation(era_duration as u64, MILLISECONDS_PER_YEAR);
let portion = Perbill::from_rational(era_duration as u64, MILLISECONDS_PER_YEAR);
let payout = portion * yearly_inflation.calculate_for_fraction_times_denominator(
npos_token_staked,
total_tokens.clone(),
Expand Down
Loading