mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 20:41:02 +00:00
Update polkadot inflation to take into account auctions (#5872)
* Update polkadot inflation to take into account auctions * a possible solution -- but needs a rather untrivial data seeding * some additional comments * Use LOWEST_PUBLIC_ID as a guide to filter out system/common good para ids * Fixes * move tests * fix Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Generated
+1
-1
@@ -3291,7 +3291,6 @@ dependencies = [
|
|||||||
"pallet-session-benchmarking",
|
"pallet-session-benchmarking",
|
||||||
"pallet-society",
|
"pallet-society",
|
||||||
"pallet-staking",
|
"pallet-staking",
|
||||||
"pallet-staking-reward-fn",
|
|
||||||
"pallet-timestamp",
|
"pallet-timestamp",
|
||||||
"pallet-tips",
|
"pallet-tips",
|
||||||
"pallet-transaction-payment",
|
"pallet-transaction-payment",
|
||||||
@@ -7029,6 +7028,7 @@ dependencies = [
|
|||||||
"pallet-election-provider-multi-phase",
|
"pallet-election-provider-multi-phase",
|
||||||
"pallet-session",
|
"pallet-session",
|
||||||
"pallet-staking",
|
"pallet-staking",
|
||||||
|
"pallet-staking-reward-fn",
|
||||||
"pallet-timestamp",
|
"pallet-timestamp",
|
||||||
"pallet-transaction-payment",
|
"pallet-transaction-payment",
|
||||||
"pallet-treasury",
|
"pallet-treasury",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "m
|
|||||||
pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
|
pallet-staking-reward-fn = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
@@ -84,6 +85,7 @@ std = [
|
|||||||
"pallet-beefy-mmr/std",
|
"pallet-beefy-mmr/std",
|
||||||
"pallet-session/std",
|
"pallet-session/std",
|
||||||
"pallet-staking/std",
|
"pallet-staking/std",
|
||||||
|
"pallet-staking-reward-fn/std",
|
||||||
"pallet-timestamp/std",
|
"pallet-timestamp/std",
|
||||||
"pallet-vesting/std",
|
"pallet-vesting/std",
|
||||||
"pallet-transaction-payment/std",
|
"pallet-transaction-payment/std",
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
use crate::NegativeImbalance;
|
use crate::NegativeImbalance;
|
||||||
use frame_support::traits::{Currency, Imbalance, OnUnbalanced};
|
use frame_support::traits::{Currency, Imbalance, OnUnbalanced};
|
||||||
|
use primitives::v2::Balance;
|
||||||
|
use sp_runtime::Perquintill;
|
||||||
|
|
||||||
/// Logic for the author to get a portion of fees.
|
/// Logic for the author to get a portion of fees.
|
||||||
pub struct ToAuthor<R>(sp_std::marker::PhantomData<R>);
|
pub struct ToAuthor<R>(sp_std::marker::PhantomData<R>);
|
||||||
@@ -57,6 +59,45 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn era_payout(
|
||||||
|
total_staked: Balance,
|
||||||
|
non_gilt_issuance: Balance,
|
||||||
|
max_annual_inflation: Perquintill,
|
||||||
|
period_fraction: Perquintill,
|
||||||
|
auctioned_slots: u64,
|
||||||
|
) -> (Balance, Balance) {
|
||||||
|
use pallet_staking_reward_fn::compute_inflation;
|
||||||
|
use sp_runtime::traits::Saturating;
|
||||||
|
|
||||||
|
let min_annual_inflation = Perquintill::from_rational(25u64, 1000u64);
|
||||||
|
let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation);
|
||||||
|
|
||||||
|
// 30% reserved for up to 60 slots.
|
||||||
|
let auction_proportion = Perquintill::from_rational(auctioned_slots.min(60), 200u64);
|
||||||
|
|
||||||
|
// Therefore the ideal amount at stake (as a percentage of total issuance) is 75% less the
|
||||||
|
// amount that we expect to be taken up with auctions.
|
||||||
|
let ideal_stake = Perquintill::from_percent(75).saturating_sub(auction_proportion);
|
||||||
|
|
||||||
|
let stake = Perquintill::from_rational(total_staked, non_gilt_issuance);
|
||||||
|
let falloff = Perquintill::from_percent(5);
|
||||||
|
let adjustment = compute_inflation(stake, ideal_stake, falloff);
|
||||||
|
let staking_inflation =
|
||||||
|
min_annual_inflation.saturating_add(delta_annual_inflation * adjustment);
|
||||||
|
|
||||||
|
let max_payout = period_fraction * max_annual_inflation * non_gilt_issuance;
|
||||||
|
let staking_payout = (period_fraction * staking_inflation) * non_gilt_issuance;
|
||||||
|
let rest = max_payout.saturating_sub(staking_payout);
|
||||||
|
|
||||||
|
let other_issuance = non_gilt_issuance.saturating_sub(total_staked);
|
||||||
|
if total_staked > other_issuance {
|
||||||
|
let _cap_rest = Perquintill::from_rational(other_issuance, total_staked) * staking_payout;
|
||||||
|
// We don't do anything with this, but if we wanted to, we could introduce a cap on the
|
||||||
|
// treasury amount with: `rest = rest.min(cap_rest);`
|
||||||
|
}
|
||||||
|
(staking_payout, rest)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -209,4 +250,44 @@ mod tests {
|
|||||||
assert_eq!(Balances::free_balance(Treasury::account_id()), 8);
|
assert_eq!(Balances::free_balance(Treasury::account_id()), 8);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compute_inflation_should_give_sensible_results() {
|
||||||
|
assert_eq!(
|
||||||
|
pallet_staking_reward_fn::compute_inflation(
|
||||||
|
Perquintill::from_percent(75),
|
||||||
|
Perquintill::from_percent(75),
|
||||||
|
Perquintill::from_percent(5),
|
||||||
|
),
|
||||||
|
Perquintill::one()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
pallet_staking_reward_fn::compute_inflation(
|
||||||
|
Perquintill::from_percent(50),
|
||||||
|
Perquintill::from_percent(75),
|
||||||
|
Perquintill::from_percent(5),
|
||||||
|
),
|
||||||
|
Perquintill::from_rational(2u64, 3u64)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
pallet_staking_reward_fn::compute_inflation(
|
||||||
|
Perquintill::from_percent(80),
|
||||||
|
Perquintill::from_percent(75),
|
||||||
|
Perquintill::from_percent(5),
|
||||||
|
),
|
||||||
|
Perquintill::from_rational(1u64, 2u64)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn era_payout_should_give_sensible_results() {
|
||||||
|
assert_eq!(
|
||||||
|
era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0,),
|
||||||
|
(10, 0)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0,),
|
||||||
|
(6, 4)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ pallet-session = { git = "https://github.com/paritytech/substrate", branch = "ma
|
|||||||
pallet-society = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
pallet-society = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
pallet-staking-reward-fn = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
|
||||||
frame-system = {git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
frame-system = {git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
@@ -170,7 +169,6 @@ std = [
|
|||||||
"pallet-session/std",
|
"pallet-session/std",
|
||||||
"pallet-society/std",
|
"pallet-society/std",
|
||||||
"pallet-staking/std",
|
"pallet-staking/std",
|
||||||
"pallet-staking-reward-fn/std",
|
|
||||||
"pallet-timestamp/std",
|
"pallet-timestamp/std",
|
||||||
"pallet-tips/std",
|
"pallet-tips/std",
|
||||||
"pallet-treasury/std",
|
"pallet-treasury/std",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use primitives::v2::{
|
|||||||
CoreState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage,
|
CoreState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage,
|
||||||
Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes,
|
Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes,
|
||||||
SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
||||||
|
LOWEST_PUBLIC_ID,
|
||||||
};
|
};
|
||||||
use runtime_common::{
|
use runtime_common::{
|
||||||
auctions, claims, crowdloan, impl_runtime_weights, impls::DealWithFees, paras_registrar,
|
auctions, claims, crowdloan, impl_runtime_weights, impls::DealWithFees, paras_registrar,
|
||||||
@@ -504,45 +505,6 @@ impl pallet_bags_list::Config<VoterBagsListInstance> for Runtime {
|
|||||||
type Score = sp_npos_elections::VoteWeight;
|
type Score = sp_npos_elections::VoteWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn era_payout(
|
|
||||||
total_staked: Balance,
|
|
||||||
non_gilt_issuance: Balance,
|
|
||||||
max_annual_inflation: Perquintill,
|
|
||||||
period_fraction: Perquintill,
|
|
||||||
auctioned_slots: u64,
|
|
||||||
) -> (Balance, Balance) {
|
|
||||||
use pallet_staking_reward_fn::compute_inflation;
|
|
||||||
use sp_arithmetic::traits::Saturating;
|
|
||||||
|
|
||||||
let min_annual_inflation = Perquintill::from_rational(25u64, 1000u64);
|
|
||||||
let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation);
|
|
||||||
|
|
||||||
// 30% reserved for up to 60 slots.
|
|
||||||
let auction_proportion = Perquintill::from_rational(auctioned_slots.min(60), 200u64);
|
|
||||||
|
|
||||||
// Therefore the ideal amount at stake (as a percentage of total issuance) is 75% less the amount that we expect
|
|
||||||
// to be taken up with auctions.
|
|
||||||
let ideal_stake = Perquintill::from_percent(75).saturating_sub(auction_proportion);
|
|
||||||
|
|
||||||
let stake = Perquintill::from_rational(total_staked, non_gilt_issuance);
|
|
||||||
let falloff = Perquintill::from_percent(5);
|
|
||||||
let adjustment = compute_inflation(stake, ideal_stake, falloff);
|
|
||||||
let staking_inflation =
|
|
||||||
min_annual_inflation.saturating_add(delta_annual_inflation * adjustment);
|
|
||||||
|
|
||||||
let max_payout = period_fraction * max_annual_inflation * non_gilt_issuance;
|
|
||||||
let staking_payout = (period_fraction * staking_inflation) * non_gilt_issuance;
|
|
||||||
let rest = max_payout.saturating_sub(staking_payout);
|
|
||||||
|
|
||||||
let other_issuance = non_gilt_issuance.saturating_sub(total_staked);
|
|
||||||
if total_staked > other_issuance {
|
|
||||||
let _cap_rest = Perquintill::from_rational(other_issuance, total_staked) * staking_payout;
|
|
||||||
// We don't do anything with this, but if we wanted to, we could introduce a cap on the treasury amount
|
|
||||||
// with: `rest = rest.min(cap_rest);`
|
|
||||||
}
|
|
||||||
(staking_payout, rest)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct EraPayout;
|
pub struct EraPayout;
|
||||||
impl pallet_staking::EraPayout<Balance> for EraPayout {
|
impl pallet_staking::EraPayout<Balance> for EraPayout {
|
||||||
fn era_payout(
|
fn era_payout(
|
||||||
@@ -550,13 +512,18 @@ impl pallet_staking::EraPayout<Balance> for EraPayout {
|
|||||||
_total_issuance: Balance,
|
_total_issuance: Balance,
|
||||||
era_duration_millis: u64,
|
era_duration_millis: u64,
|
||||||
) -> (Balance, Balance) {
|
) -> (Balance, Balance) {
|
||||||
// TODO: #3011 Update with proper auctioned slots tracking.
|
// all para-ids that are currently active.
|
||||||
// This should be fine for the first year of parachains.
|
let auctioned_slots = Paras::parachains()
|
||||||
let auctioned_slots: u64 = auctions::Pallet::<Runtime>::auction_counter().into();
|
.into_iter()
|
||||||
|
// all active para-ids that do not belong to a system or common good chain is the number
|
||||||
|
// of parachains that we should take into account for inflation.
|
||||||
|
.filter(|i| *i >= LOWEST_PUBLIC_ID)
|
||||||
|
.count() as u64;
|
||||||
|
|
||||||
const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10);
|
const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10);
|
||||||
const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
|
const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
|
||||||
|
|
||||||
era_payout(
|
runtime_common::impls::era_payout(
|
||||||
total_staked,
|
total_staked,
|
||||||
Gilt::issuance().non_gilt,
|
Gilt::issuance().non_gilt,
|
||||||
MAX_ANNUAL_INFLATION,
|
MAX_ANNUAL_INFLATION,
|
||||||
|
|||||||
@@ -137,40 +137,6 @@ fn nominator_limit() {
|
|||||||
println!("can support {} nominators to yield a weight of {}", active, weight_with(active));
|
println!("can support {} nominators to yield a weight of {}", active, weight_with(active));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn compute_inflation_should_give_sensible_results() {
|
|
||||||
assert_eq!(
|
|
||||||
pallet_staking_reward_fn::compute_inflation(
|
|
||||||
Perquintill::from_percent(75),
|
|
||||||
Perquintill::from_percent(75),
|
|
||||||
Perquintill::from_percent(5),
|
|
||||||
),
|
|
||||||
Perquintill::one()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
pallet_staking_reward_fn::compute_inflation(
|
|
||||||
Perquintill::from_percent(50),
|
|
||||||
Perquintill::from_percent(75),
|
|
||||||
Perquintill::from_percent(5),
|
|
||||||
),
|
|
||||||
Perquintill::from_rational(2u64, 3u64)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
pallet_staking_reward_fn::compute_inflation(
|
|
||||||
Perquintill::from_percent(80),
|
|
||||||
Perquintill::from_percent(75),
|
|
||||||
Perquintill::from_percent(5),
|
|
||||||
),
|
|
||||||
Perquintill::from_rational(1u64, 2u64)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn era_payout_should_give_sensible_results() {
|
|
||||||
assert_eq!(era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), (10, 0));
|
|
||||||
assert_eq!(era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), (6, 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn call_size() {
|
fn call_size() {
|
||||||
RuntimeCall::assert_size_under(230);
|
RuntimeCall::assert_size_under(230);
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ use primitives::v2::{
|
|||||||
CoreState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage,
|
CoreState, GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage,
|
||||||
Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes,
|
Moment, Nonce, OccupiedCoreAssumption, PersistedValidationData, ScrapedOnChainVotes,
|
||||||
SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
|
||||||
|
LOWEST_PUBLIC_ID,
|
||||||
};
|
};
|
||||||
use sp_core::OpaqueMetadata;
|
use sp_core::OpaqueMetadata;
|
||||||
use sp_mmr_primitives as mmr;
|
use sp_mmr_primitives as mmr;
|
||||||
@@ -536,6 +537,35 @@ type SlashCancelOrigin = EitherOfDiverse<
|
|||||||
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 4>,
|
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 4>,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
pub struct EraPayout;
|
||||||
|
impl pallet_staking::EraPayout<Balance> for EraPayout {
|
||||||
|
fn era_payout(
|
||||||
|
total_staked: Balance,
|
||||||
|
total_issuance: Balance,
|
||||||
|
era_duration_millis: u64,
|
||||||
|
) -> (Balance, Balance) {
|
||||||
|
// all para-ids that are not active.
|
||||||
|
let auctioned_slots = Paras::parachains()
|
||||||
|
.into_iter()
|
||||||
|
// all active para-ids that do not belong to a system or common good chain is the number
|
||||||
|
// of parachains that we should take into account for inflation.
|
||||||
|
.filter(|i| *i >= LOWEST_PUBLIC_ID)
|
||||||
|
.count() as u64;
|
||||||
|
|
||||||
|
const MAX_ANNUAL_INFLATION: Perquintill = Perquintill::from_percent(10);
|
||||||
|
const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100;
|
||||||
|
|
||||||
|
runtime_common::impls::era_payout(
|
||||||
|
total_staked,
|
||||||
|
// Polkadot has no notion of gilts, the entire issuance is non-guilt.
|
||||||
|
total_issuance,
|
||||||
|
MAX_ANNUAL_INFLATION,
|
||||||
|
Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR),
|
||||||
|
auctioned_slots,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl pallet_staking::Config for Runtime {
|
impl pallet_staking::Config for Runtime {
|
||||||
type MaxNominations = MaxNominations;
|
type MaxNominations = MaxNominations;
|
||||||
type Currency = Balances;
|
type Currency = Balances;
|
||||||
@@ -552,7 +582,7 @@ impl pallet_staking::Config for Runtime {
|
|||||||
// A super-majority of the council can cancel the slash.
|
// A super-majority of the council can cancel the slash.
|
||||||
type SlashCancelOrigin = SlashCancelOrigin;
|
type SlashCancelOrigin = SlashCancelOrigin;
|
||||||
type SessionInterface = Self;
|
type SessionInterface = Self;
|
||||||
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
|
type EraPayout = EraPayout;
|
||||||
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
|
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
|
||||||
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
|
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
|
||||||
type NextNewSession = Session;
|
type NextNewSession = Session;
|
||||||
|
|||||||
Reference in New Issue
Block a user