From 81da185f635128d045418be6a372c0aa2c17435c Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Thu, 4 Jul 2024 00:12:15 +0800 Subject: [PATCH 01/28] feat: setup pallet-parameters in westend runtime --- Cargo.lock | 1 + polkadot/runtime/westend/Cargo.toml | 9 ++++++- polkadot/runtime/westend/src/lib.rs | 40 ++++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b08e96f4bbe..8297c2b19750 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23615,6 +23615,7 @@ dependencies = [ "pallet-nomination-pools-runtime-api", "pallet-offences", "pallet-offences-benchmarking", + "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-recovery", diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index 5a7805c05161..ec23c7632160 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -72,6 +72,7 @@ pallet-multisig = { workspace = true } pallet-nomination-pools = { workspace = true } pallet-conviction-voting = { workspace = true } pallet-offences = { workspace = true } +pallet-parameters = { workspace = true } pallet-preimage = { workspace = true } pallet-proxy = { workspace = true } pallet-recovery = { workspace = true } @@ -174,6 +175,7 @@ std = [ "pallet-nomination-pools/std", "pallet-offences-benchmarking?/std", "pallet-offences/std", + "pallet-parameters/std", "pallet-preimage/std", "pallet-proxy/std", "pallet-recovery/std", @@ -261,6 +263,7 @@ runtime-benchmarks = [ "pallet-nomination-pools/runtime-benchmarks", "pallet-offences-benchmarking/runtime-benchmarks", "pallet-offences/runtime-benchmarks", + "pallet-parameters/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-recovery/runtime-benchmarks", @@ -319,6 +322,7 @@ try-runtime = [ "pallet-multisig/try-runtime", "pallet-nomination-pools/try-runtime", "pallet-offences/try-runtime", + "pallet-parameters/try-runtime", "pallet-preimage/try-runtime", "pallet-proxy/try-runtime", "pallet-recovery/try-runtime", @@ -348,7 +352,10 @@ metadata-hash = ["substrate-wasm-builder/metadata-hash"] # Set timing constants (e.g. session period) to faster versions to speed up testing. fast-runtime = [] -runtime-metrics = ["polkadot-runtime-parachains/runtime-metrics", "sp-io/with-tracing"] +runtime-metrics = [ + "polkadot-runtime-parachains/runtime-metrics", + "sp-io/with-tracing", +] # A feature that should be enabled when the runtime should be built for on-chain # deployment. This will disable stuff that shouldn't be part of the on-chain wasm diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index ca58a6390109..1977f4824fcb 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -24,12 +24,14 @@ use codec::{Decode, Encode, MaxEncodedLen}; use frame_election_provider_support::{bounds::ElectionBoundsBuilder, onchain, SequentialPhragmen}; use frame_support::{ derive_impl, + dynamic_params::{dynamic_pallet_params, dynamic_params}, genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, Contains, EitherOf, - EitherOfDiverse, EverythingBut, FromContains, InstanceFilter, KeyOwnerProofSystem, - LinearStoragePrice, ProcessMessage, ProcessMessageError, VariantCountOf, WithdrawReasons, + EitherOfDiverse, EnsureOriginWithArg, EverythingBut, FromContains, InstanceFilter, + KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, ProcessMessageError, + VariantCountOf, WithdrawReasons, }, weights::{ConstantMultiplier, WeightMeter, WeightToFee as _}, PalletId, @@ -241,6 +243,35 @@ parameter_types! { pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); } +/// Dynamic params that can be adjusted at runtime. +#[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] +pub mod dynamic_params { + use super::*; +} + +impl pallet_parameters::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeParameters = RuntimeParameters; + type AdminOrigin = DynamicParameterOrigin; + // TODO: add benchmarking and update weight info + type WeightInfo = (); +} + +/// Defines what origin can modify which dynamic parameters. +pub struct DynamicParameterOrigin; +impl EnsureOriginWithArg for DynamicParameterOrigin { + type Success = (); + + fn try_origin( + origin: RuntimeOrigin, + key: &RuntimeParametersKey, + ) -> Result { + use crate::{dynamic_params::*, governance::*}; + // TODO: update to correct origin + frame_system::ensure_root(origin.clone()).map_err(|_| origin) + } +} + impl pallet_preimage::Config for Runtime { type WeightInfo = weights::pallet_preimage::WeightInfo; type RuntimeEvent = RuntimeEvent; @@ -1008,7 +1039,8 @@ impl InstanceFilter for ProxyType { matches!( c, RuntimeCall::Staking(..) | - RuntimeCall::Session(..) | RuntimeCall::Utility(..) | + RuntimeCall::Session(..) | + RuntimeCall::Utility(..) | RuntimeCall::FastUnstake(..) | RuntimeCall::VoterList(..) | RuntimeCall::NominationPools(..) @@ -1475,6 +1507,8 @@ mod runtime { pub type Offences = pallet_offences; #[runtime::pallet_index(27)] pub type Historical = session_historical; + #[runtime::pallet_index(70)] + pub type Parameters = pallet_parameters; #[runtime::pallet_index(8)] pub type Session = pallet_session; From e84a47215bf49df8b9b6478d602fff36068de473 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Thu, 4 Jul 2024 00:37:58 +0800 Subject: [PATCH 02/28] feat: introduce dynamic params for staking reward params --- polkadot/runtime/westend/src/lib.rs | 37 ++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 1977f4824fcb..e0f4de9309e4 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -247,6 +247,23 @@ parameter_types! { #[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] pub mod dynamic_params { use super::*; + + #[dynamic_pallet_params] + #[codec(index = 0)] + pub mod staking_reward_curve { + #[codec(index = 0)] + pub static MinInflation: u32 = 0_025_000; + #[codec(index = 1)] + pub static MaxInflation: u32 = 0_100_000; + #[codec(index = 2)] + pub static IdealStake: u32 = 0_500_000; + #[codec(index = 3)] + pub static Falloff: u32 = 0_050_000; + #[codec(index = 4)] + pub static MaxPieceCount: u32 = 40; + #[codec(index = 5)] + pub static TestPrecision: u32 = 0_005_000; + } } impl pallet_parameters::Config for Runtime { @@ -266,9 +283,13 @@ impl EnsureOriginWithArg for DynamicParamet origin: RuntimeOrigin, key: &RuntimeParametersKey, ) -> Result { - use crate::{dynamic_params::*, governance::*}; + use crate::{dynamic_params::*, governance::*, RuntimeParametersKey::*}; // TODO: update to correct origin - frame_system::ensure_root(origin.clone()).map_err(|_| origin) + + match key { + StakingRewardCurve(_) => frame_system::ensure_root(origin.clone()), + } + .map_err(|_| origin) } } @@ -629,12 +650,12 @@ impl pallet_bags_list::Config for Runtime { pallet_staking_reward_curve::build! { const REWARD_CURVE: PiecewiseLinear<'static> = curve!( - min_inflation: 0_025_000, - max_inflation: 0_100_000, - ideal_stake: 0_500_000, - falloff: 0_050_000, - max_piece_count: 40, - test_precision: 0_005_000, + min_inflation: 0_025_000, // dynamic_params::staking_reward_curve::MinInflation, + max_inflation: 0_100_000, // dynamic_params::staking_reward_curve::MaxInflation::get(), + ideal_stake: 0_500_000, // dynamic_params::staking_reward_curve::IdealStake::get(), + falloff: 0_050_000, // dynamic_params::staking_reward_curve::Falloff::get(), + max_piece_count: 40, // dynamic_params::staking_reward_curve::MaxPieceCount::get(), + test_precision: 0_005_000, // dynamic_params::staking_reward_curve::TestPrecision::get(), ); } From e8d2ec57f5f9d88f0ff0b76643e2cf2aac7db700 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Fri, 5 Jul 2024 00:57:47 +0800 Subject: [PATCH 03/28] feat: add new era relay payout function --- polkadot/runtime/common/src/impls.rs | 49 +++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 709cc69cdbea..f230b5b0172b 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -24,7 +24,7 @@ use frame_support::traits::{ }; use pallet_treasury::TreasuryAccountId; use polkadot_primitives::Balance; -use sp_runtime::{traits::TryConvert, Perquintill, RuntimeDebug}; +use sp_runtime::{traits::{TryConvert, Saturating}, Perquintill, RuntimeDebug}; use xcm::VersionedLocation; /// Logic for the author to get a portion of fees. @@ -67,6 +67,53 @@ where } } +pub struct EraPayoutParams { + pub total_staked: Balance, + pub total_stakable: Balance, + pub ideal_stake: Perquintill, + pub max_annual_inflation: Perquintill, + pub min_annual_inflation: Perquintill, + pub falloff: Perquintill, + pub period_fraction: Perquintill, + pub legacy_auction_proportion: Option, +} + +pub fn relay_era_payout(params: EraPayoutParams) -> (Balance, Balance) { + let EraPayoutParams { + total_staked, + total_stakable, + ideal_stake, + max_annual_inflation, + min_annual_inflation, + falloff, + period_fraction, + legacy_auction_proportion, + } = params; + + let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation); + + let ideal_stake = ideal_stake.saturating_sub(legacy_auction_proportion.unwrap_or_default()); + + let stake = Perquintill::from_rational(total_staked, total_stakable); + let adjustment = pallet_staking_reward_fn::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 * total_stakable; + let staking_payout = (period_fraction * staking_inflation) * total_stakable; + let rest = max_payout.saturating_sub(staking_payout); + + let other_issuance = total_stakable.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) +} + + +#[deprecated = "use relay_era_payout instead which supports dynamic parameters"] pub fn era_payout( total_staked: Balance, total_stakable: Balance, From 77a28cc380ce42bdad3c9f355acec1fa685ba5d0 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Fri, 5 Jul 2024 00:58:55 +0800 Subject: [PATCH 04/28] feat: add new era payout fn with dynamic params --- polkadot/runtime/westend/src/lib.rs | 139 ++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 26 deletions(-) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index e0f4de9309e4..698072f519c3 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -29,9 +29,9 @@ use frame_support::{ parameter_types, traits::{ fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, Contains, EitherOf, - EitherOfDiverse, EnsureOriginWithArg, EverythingBut, FromContains, InstanceFilter, - KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, ProcessMessageError, - VariantCountOf, WithdrawReasons, + EitherOfDiverse, EnsureOrigin, EnsureOriginWithArg, EverythingBut, FromContains, + InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, + ProcessMessageError, VariantCountOf, WithdrawReasons, }, weights::{ConstantMultiplier, WeightMeter, WeightToFee as _}, PalletId, @@ -39,6 +39,7 @@ use frame_support::{ use frame_system::{EnsureRoot, EnsureSigned}; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; use pallet_identity::legacy::IdentityInfo; +use pallet_nis::WithMaximumOf; use pallet_session::historical as session_historical; use pallet_transaction_payment::{FeeDetails, FungibleAdapter, RuntimeDispatchInfo}; use polkadot_primitives::{ @@ -47,15 +48,15 @@ use polkadot_primitives::{ GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, NodeFeatures, Nonce, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, - ValidatorIndex, ValidatorSignature, PARACHAIN_KEY_TYPE_ID, + ValidatorIndex, ValidatorSignature, LOWEST_PUBLIC_ID, PARACHAIN_KEY_TYPE_ID, }; use polkadot_runtime_common::{ assigned_slots, auctions, crowdloan, elections::OnChainAccuracy, identity_migrator, impl_runtime_weights, impls::{ - ContainsParts, LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, - VersionedLocationConverter, + relay_era_payout, ContainsParts, EraPayoutParams, LocatableAssetConverter, ToAuthor, + VersionedLocatableAsset, VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, traits::{Leaser, OnSwap}, @@ -250,19 +251,35 @@ pub mod dynamic_params { #[dynamic_pallet_params] #[codec(index = 0)] - pub mod staking_reward_curve { + pub mod nis { + use super::*; + #[codec(index = 0)] - pub static MinInflation: u32 = 0_025_000; + pub static Target: Perquintill = Perquintill::zero(); + + #[codec(index = 1)] + pub static MinBid: Balance = 100 * UNITS; + } + + #[dynamic_pallet_params] + #[codec(index = 1)] + pub mod inflation { + // TODO: should these values be updated to match the new inflation pallet? + #[codec(index = 0)] + pub static MinInflation: Perquintill = Perquintill::from_rational(25u64, 1000u64); + #[codec(index = 1)] - pub static MaxInflation: u32 = 0_100_000; + pub static MaxInflation: Perquintill = Perquintill::from_rational(100u64, 1000u64); + #[codec(index = 2)] - pub static IdealStake: u32 = 0_500_000; + pub static IdealStake: Perquintill = Perquintill::from_rational(500u64, 1000u64); + #[codec(index = 3)] - pub static Falloff: u32 = 0_050_000; + pub static Falloff: Perquintill = Perquintill::from_rational(50u64, 1000u64); + + // TODO: what should be the default here? #[codec(index = 4)] - pub static MaxPieceCount: u32 = 40; - #[codec(index = 5)] - pub static TestPrecision: u32 = 0_005_000; + pub static UseAuctionSlots: bool = false; } } @@ -287,7 +304,9 @@ impl EnsureOriginWithArg for DynamicParamet // TODO: update to correct origin match key { - StakingRewardCurve(_) => frame_system::ensure_root(origin.clone()), + Nis(nis::ParametersKey::MinBid(_)) => StakingAdmin::ensure_origin(origin.clone()), + Nis(nis::ParametersKey::Target(_)) => GeneralAdmin::ensure_origin(origin.clone()), + Inflation(_) => frame_system::ensure_root(origin.clone()), } .map_err(|_| origin) } @@ -648,15 +667,79 @@ impl pallet_bags_list::Config for Runtime { type Score = sp_npos_elections::VoteWeight; } -pallet_staking_reward_curve::build! { - const REWARD_CURVE: PiecewiseLinear<'static> = curve!( - min_inflation: 0_025_000, // dynamic_params::staking_reward_curve::MinInflation, - max_inflation: 0_100_000, // dynamic_params::staking_reward_curve::MaxInflation::get(), - ideal_stake: 0_500_000, // dynamic_params::staking_reward_curve::IdealStake::get(), - falloff: 0_050_000, // dynamic_params::staking_reward_curve::Falloff::get(), - max_piece_count: 40, // dynamic_params::staking_reward_curve::MaxPieceCount::get(), - test_precision: 0_005_000, // dynamic_params::staking_reward_curve::TestPrecision::get(), - ); +// parameter_types! { +// pub const NisBasePeriod: BlockNumber = 30 * DAYS; +// pub MinReceipt: Perquintill = Perquintill::from_rational(1u64, 10_000_000u64); +// pub const IntakePeriod: BlockNumber = 5 * MINUTES; +// pub MaxIntakeWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; +// pub const ThawThrottle: (Perquintill, BlockNumber) = (Perquintill::from_percent(25), 5); +// pub const NisPalletId: PalletId = PalletId(*b"py/nis "); +// } + +// impl pallet_nis::Config for Runtime { +// type WeightInfo = weights::pallet_nis::WeightInfo; +// type RuntimeEvent = RuntimeEvent; +// type Currency = Balances; +// type CurrencyBalance = Balance; +// type FundOrigin = frame_system::EnsureSigned; +// type Counterpart = NisCounterpartBalances; +// type CounterpartAmount = WithMaximumOf>; +// type Deficit = (); // Mint +// type IgnoredIssuance = (); +// type Target = dynamic_params::nis::Target; +// type PalletId = NisPalletId; +// type QueueCount = ConstU32<300>; +// type MaxQueueLen = ConstU32<1000>; +// type FifoQueueLen = ConstU32<250>; +// type BasePeriod = NisBasePeriod; +// type MinBid = dynamic_params::nis::MinBid; +// type MinReceipt = MinReceipt; +// type IntakePeriod = IntakePeriod; +// type MaxIntakeWeight = MaxIntakeWeight; +// type ThawThrottle = ThawThrottle; +// type RuntimeHoldReason = RuntimeHoldReason; +// #[cfg(feature = "runtime-benchmarks")] +// type BenchmarkSetup = (); +// } + +pub struct EraPayout; +impl pallet_staking::EraPayout for EraPayout { + fn era_payout( + total_staked: Balance, + _total_issuance: Balance, + era_duration_millis: u64, + ) -> (Balance, Balance) { + let auctioned_slots: u64 = 0; + // TODO: figure out if using parachains here makes sense + // // all para-ids that are currently active. + // let auctioned_slots = Paras::parachains() + // .into_iter() + // // all active para-ids that do not belong to a system 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; + + let use_auctioned_slots = dynamic_params::inflation::UseAuctionSlots::get(); + let params = EraPayoutParams { + total_staked, + // TODO: update this to use NIS issuance + total_stakable: 1, + // total_stakable: Nis::issuance().other, + ideal_stake: dynamic_params::inflation::IdealStake::get(), + max_annual_inflation: dynamic_params::inflation::MaxInflation::get(), + min_annual_inflation: dynamic_params::inflation::MinInflation::get(), + falloff: dynamic_params::inflation::Falloff::get(), + period_fraction: Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR), + legacy_auction_proportion: if use_auctioned_slots { + Some(Perquintill::from_rational(auctioned_slots.min(60), 200)) + } else { + None + }, + }; + relay_era_payout(params) + } } parameter_types! { @@ -666,7 +749,6 @@ parameter_types! { pub const BondingDuration: sp_staking::EraIndex = 2; // 1 era in which slashes can be cancelled (6 hours). pub const SlashDeferDuration: sp_staking::EraIndex = 1; - pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; pub const MaxExposurePageSize: u32 = 64; // Note: this is not really correct as Max Nominators is (MaxExposurePageSize * page_count) but // this is an unbounded number. We just set it to a reasonably high value, 1 full page @@ -690,7 +772,7 @@ impl pallet_staking::Config for Runtime { type SlashDeferDuration = SlashDeferDuration; type AdminOrigin = EitherOf, StakingAdmin>; type SessionInterface = Self; - type EraPayout = pallet_staking::ConvertCurve; + type EraPayout = EraPayout; type MaxExposurePageSize = MaxExposurePageSize; type NextNewSession = Session; type ElectionProvider = ElectionProviderMultiPhase; @@ -1530,6 +1612,11 @@ mod runtime { pub type Historical = session_historical; #[runtime::pallet_index(70)] pub type Parameters = pallet_parameters; + // NIS pallet. + // #[runtime::pallet_index(71)] + // pub type Nis = pallet_nis; + // #[runtime::pallet_index(72)] + // pub type NisCounterpartBalances = pallet_balances::Instance2; #[runtime::pallet_index(8)] pub type Session = pallet_session; From b010d0bf4199afe5d2ea10a423c90a79b71f3dff Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Fri, 5 Jul 2024 21:12:28 +0800 Subject: [PATCH 05/28] fix: total stakable value + remove NIS --- polkadot/runtime/westend/src/lib.rs | 56 ++--------------------------- 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 698072f519c3..4244034ccfda 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -39,7 +39,6 @@ use frame_support::{ use frame_system::{EnsureRoot, EnsureSigned}; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; use pallet_identity::legacy::IdentityInfo; -use pallet_nis::WithMaximumOf; use pallet_session::historical as session_historical; use pallet_transaction_payment::{FeeDetails, FungibleAdapter, RuntimeDispatchInfo}; use polkadot_primitives::{ @@ -667,40 +666,6 @@ impl pallet_bags_list::Config for Runtime { type Score = sp_npos_elections::VoteWeight; } -// parameter_types! { -// pub const NisBasePeriod: BlockNumber = 30 * DAYS; -// pub MinReceipt: Perquintill = Perquintill::from_rational(1u64, 10_000_000u64); -// pub const IntakePeriod: BlockNumber = 5 * MINUTES; -// pub MaxIntakeWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10; -// pub const ThawThrottle: (Perquintill, BlockNumber) = (Perquintill::from_percent(25), 5); -// pub const NisPalletId: PalletId = PalletId(*b"py/nis "); -// } - -// impl pallet_nis::Config for Runtime { -// type WeightInfo = weights::pallet_nis::WeightInfo; -// type RuntimeEvent = RuntimeEvent; -// type Currency = Balances; -// type CurrencyBalance = Balance; -// type FundOrigin = frame_system::EnsureSigned; -// type Counterpart = NisCounterpartBalances; -// type CounterpartAmount = WithMaximumOf>; -// type Deficit = (); // Mint -// type IgnoredIssuance = (); -// type Target = dynamic_params::nis::Target; -// type PalletId = NisPalletId; -// type QueueCount = ConstU32<300>; -// type MaxQueueLen = ConstU32<1000>; -// type FifoQueueLen = ConstU32<250>; -// type BasePeriod = NisBasePeriod; -// type MinBid = dynamic_params::nis::MinBid; -// type MinReceipt = MinReceipt; -// type IntakePeriod = IntakePeriod; -// type MaxIntakeWeight = MaxIntakeWeight; -// type ThawThrottle = ThawThrottle; -// type RuntimeHoldReason = RuntimeHoldReason; -// #[cfg(feature = "runtime-benchmarks")] -// type BenchmarkSetup = (); -// } pub struct EraPayout; impl pallet_staking::EraPayout for EraPayout { @@ -709,31 +674,19 @@ impl pallet_staking::EraPayout for EraPayout { _total_issuance: Balance, era_duration_millis: u64, ) -> (Balance, Balance) { - let auctioned_slots: u64 = 0; - // TODO: figure out if using parachains here makes sense - // // all para-ids that are currently active. - // let auctioned_slots = Paras::parachains() - // .into_iter() - // // all active para-ids that do not belong to a system 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; let use_auctioned_slots = dynamic_params::inflation::UseAuctionSlots::get(); let params = EraPayoutParams { total_staked, - // TODO: update this to use NIS issuance - total_stakable: 1, - // total_stakable: Nis::issuance().other, + total_stakable: Balances::total_issuance(), ideal_stake: dynamic_params::inflation::IdealStake::get(), max_annual_inflation: dynamic_params::inflation::MaxInflation::get(), min_annual_inflation: dynamic_params::inflation::MinInflation::get(), falloff: dynamic_params::inflation::Falloff::get(), period_fraction: Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR), legacy_auction_proportion: if use_auctioned_slots { - Some(Perquintill::from_rational(auctioned_slots.min(60), 200)) + Some(Perquintill::from_rational(60u64, 200u64)) } else { None }, @@ -1612,11 +1565,6 @@ mod runtime { pub type Historical = session_historical; #[runtime::pallet_index(70)] pub type Parameters = pallet_parameters; - // NIS pallet. - // #[runtime::pallet_index(71)] - // pub type Nis = pallet_nis; - // #[runtime::pallet_index(72)] - // pub type NisCounterpartBalances = pallet_balances::Instance2; #[runtime::pallet_index(8)] pub type Session = pallet_session; From 30caa8cfb564b57e98886dec301d6f4b90f498b6 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Fri, 5 Jul 2024 21:25:13 +0800 Subject: [PATCH 06/28] chore: remove unused weight params --- polkadot/runtime/westend/src/lib.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 4244034ccfda..5db37b95e8ba 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -250,20 +250,7 @@ pub mod dynamic_params { #[dynamic_pallet_params] #[codec(index = 0)] - pub mod nis { - use super::*; - - #[codec(index = 0)] - pub static Target: Perquintill = Perquintill::zero(); - - #[codec(index = 1)] - pub static MinBid: Balance = 100 * UNITS; - } - - #[dynamic_pallet_params] - #[codec(index = 1)] pub mod inflation { - // TODO: should these values be updated to match the new inflation pallet? #[codec(index = 0)] pub static MinInflation: Perquintill = Perquintill::from_rational(25u64, 1000u64); @@ -276,7 +263,6 @@ pub mod dynamic_params { #[codec(index = 3)] pub static Falloff: Perquintill = Perquintill::from_rational(50u64, 1000u64); - // TODO: what should be the default here? #[codec(index = 4)] pub static UseAuctionSlots: bool = false; } @@ -288,6 +274,7 @@ impl pallet_parameters::Config for Runtime { type AdminOrigin = DynamicParameterOrigin; // TODO: add benchmarking and update weight info type WeightInfo = (); + // type WeightInfo = weights::pallet_parameters::WeightInfo; } /// Defines what origin can modify which dynamic parameters. @@ -300,11 +287,8 @@ impl EnsureOriginWithArg for DynamicParamet key: &RuntimeParametersKey, ) -> Result { use crate::{dynamic_params::*, governance::*, RuntimeParametersKey::*}; - // TODO: update to correct origin match key { - Nis(nis::ParametersKey::MinBid(_)) => StakingAdmin::ensure_origin(origin.clone()), - Nis(nis::ParametersKey::Target(_)) => GeneralAdmin::ensure_origin(origin.clone()), Inflation(_) => frame_system::ensure_root(origin.clone()), } .map_err(|_| origin) @@ -1845,6 +1829,7 @@ mod benches { [pallet_multisig, Multisig] [pallet_nomination_pools, NominationPoolsBench::] [pallet_offences, OffencesBench::] + [pallet_parameters, Parameters] [pallet_preimage, Preimage] [pallet_proxy, Proxy] [pallet_recovery, Recovery] From 08b9287c2d06599970f8c97f24c51a13f7bb12a8 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Fri, 5 Jul 2024 21:29:57 +0800 Subject: [PATCH 07/28] build: remove unused reward staking curve pallet --- Cargo.lock | 1 - polkadot/runtime/westend/Cargo.toml | 1 - polkadot/runtime/westend/src/lib.rs | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8297c2b19750..96346c27c776 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23626,7 +23626,6 @@ dependencies = [ "pallet-session-benchmarking", "pallet-society", "pallet-staking", - "pallet-staking-reward-curve", "pallet-staking-runtime-api", "pallet-state-trie-migration", "pallet-sudo", diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index ec23c7632160..b8f1dcd231ae 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -81,7 +81,6 @@ pallet-scheduler = { workspace = true } pallet-session = { workspace = true } pallet-society = { workspace = true } pallet-staking = { workspace = true } -pallet-staking-reward-curve = { workspace = true, default-features = true } pallet-staking-runtime-api = { workspace = true } pallet-delegated-staking = { workspace = true } pallet-state-trie-migration = { workspace = true } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 5db37b95e8ba..cf3c309d3719 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -47,7 +47,7 @@ use polkadot_primitives::{ GroupRotationInfo, Hash, Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, Moment, NodeFeatures, Nonce, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionInfo, Signature, ValidationCode, ValidationCodeHash, ValidatorId, - ValidatorIndex, ValidatorSignature, LOWEST_PUBLIC_ID, PARACHAIN_KEY_TYPE_ID, + ValidatorIndex, ValidatorSignature, PARACHAIN_KEY_TYPE_ID, }; use polkadot_runtime_common::{ assigned_slots, auctions, crowdloan, From 282aa21d98a70e641e3c2daad077b3e5fc1e781e Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Fri, 5 Jul 2024 21:44:40 +0800 Subject: [PATCH 08/28] chore: remove unused era_payout function --- polkadot/runtime/common/src/impls.rs | 68 ++++++++++------------------ 1 file changed, 24 insertions(+), 44 deletions(-) diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index f230b5b0172b..49c1abfa1ef5 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -112,47 +112,6 @@ pub fn relay_era_payout(params: EraPayoutParams) -> (Balance, Balance) { (staking_payout, rest) } - -#[deprecated = "use relay_era_payout instead which supports dynamic parameters"] -pub fn era_payout( - total_staked: Balance, - total_stakable: 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, total_stakable); - 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 * total_stakable; - let staking_payout = (period_fraction * staking_inflation) * total_stakable; - let rest = max_payout.saturating_sub(staking_payout); - - let other_issuance = total_stakable.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) -} - /// Versioned locatable asset type which contains both an XCM `location` and `asset_id` to identify /// an asset which exists on some chain. #[derive( @@ -471,13 +430,34 @@ mod tests { } #[test] - fn era_payout_should_give_sensible_results() { + fn relay_era_payout_should_give_sensible_results() { + let params = EraPayoutParams { + total_staked: 75, + total_stakable: 100, + ideal_stake: Perquintill::from_percent(75), + max_annual_inflation: Perquintill::from_percent(10), + min_annual_inflation: Perquintill::from_rational(25u64, 1000u64), + falloff: Perquintill::from_percent(5), + period_fraction: Perquintill::one(), + legacy_auction_proportion: None, + }; assert_eq!( - era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), + relay_era_payout(params), (10, 0) ); + + let params = EraPayoutParams { + total_staked: 80, + total_stakable: 100, + ideal_stake: Perquintill::from_percent(75), + max_annual_inflation: Perquintill::from_percent(10), + min_annual_inflation: Perquintill::from_rational(25u64, 1000u64), + falloff: Perquintill::from_percent(5), + period_fraction: Perquintill::one(), + legacy_auction_proportion: None, + }; assert_eq!( - era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), + relay_era_payout(params), (6, 4) ); } From ff9e782604a1b9f4448569af1e3abcd7f7ef5c20 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Fri, 5 Jul 2024 21:46:13 +0800 Subject: [PATCH 09/28] chore: leave deprecated function in crate --- polkadot/runtime/common/src/impls.rs | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 49c1abfa1ef5..5dece6d33a0a 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -112,6 +112,46 @@ pub fn relay_era_payout(params: EraPayoutParams) -> (Balance, Balance) { (staking_payout, rest) } +#[deprecated = "use relay_era_payout instead which supports dynamic parameters"] +pub fn era_payout( + total_staked: Balance, + total_stakable: 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, total_stakable); + 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 * total_stakable; + let staking_payout = (period_fraction * staking_inflation) * total_stakable; + let rest = max_payout.saturating_sub(staking_payout); + + let other_issuance = total_stakable.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) +} + /// Versioned locatable asset type which contains both an XCM `location` and `asset_id` to identify /// an asset which exists on some chain. #[derive( @@ -429,6 +469,18 @@ mod tests { ); } + #[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] fn relay_era_payout_should_give_sensible_results() { let params = EraPayoutParams { From ae01d4542686a352ba7231c446438341d80610ed Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Wed, 10 Jul 2024 07:39:18 +0200 Subject: [PATCH 10/28] test: add unit test to ensure payout logic is same using legacy auction param --- polkadot/runtime/common/src/impls.rs | 66 +++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 5dece6d33a0a..2258aa8b298a 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -24,7 +24,10 @@ use frame_support::traits::{ }; use pallet_treasury::TreasuryAccountId; use polkadot_primitives::Balance; -use sp_runtime::{traits::{TryConvert, Saturating}, Perquintill, RuntimeDebug}; +use sp_runtime::{ + traits::{Saturating, TryConvert}, + Perquintill, RuntimeDebug, +}; use xcm::VersionedLocation; /// Logic for the author to get a portion of fees. @@ -493,10 +496,7 @@ mod tests { period_fraction: Perquintill::one(), legacy_auction_proportion: None, }; - assert_eq!( - relay_era_payout(params), - (10, 0) - ); + assert_eq!(relay_era_payout(params), (10, 0)); let params = EraPayoutParams { total_staked: 80, @@ -508,9 +508,63 @@ mod tests { period_fraction: Perquintill::one(), legacy_auction_proportion: None, }; + assert_eq!(relay_era_payout(params), (6, 4)); + } + + #[test] + fn relay_era_payout_should_give_same_results_as_era_payout() { + let total_staked = 1_000_000; + let total_stakable = 2_000_000; + let max_annual_inflation = Perquintill::from_percent(10); + let period_fraction = Perquintill::from_percent(25); + let auctioned_slots = 30; + + let params = EraPayoutParams { + total_staked, + total_stakable, + ideal_stake: Perquintill::from_percent(75), + max_annual_inflation, + min_annual_inflation: Perquintill::from_rational(25u64, 1000u64), + falloff: Perquintill::from_percent(5), + period_fraction, + legacy_auction_proportion: Some(Perquintill::from_rational(auctioned_slots.min(60), 200u64)), + }; assert_eq!( relay_era_payout(params), - (6, 4) + era_payout( + total_staked, + total_stakable, + max_annual_inflation, + period_fraction, + auctioned_slots, + ), + ); + + let total_staked = 1_900_000; + let total_stakable = 2_000_000; + let auctioned_slots = 60; + + + let params = EraPayoutParams { + total_staked, + total_stakable, + ideal_stake: Perquintill::from_percent(75), + max_annual_inflation, + min_annual_inflation: Perquintill::from_rational(25u64, 1000u64), + falloff: Perquintill::from_percent(5), + period_fraction, + legacy_auction_proportion: Some(Perquintill::from_rational(auctioned_slots.min(60), 200u64)), + }; + + assert_eq!( + era_payout( + total_staked, + total_stakable, + max_annual_inflation, + period_fraction, + auctioned_slots, + ), + relay_era_payout(params), ); } } From aa563f598bde92c4d6a458efaeefd86f1869c5dc Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Wed, 10 Jul 2024 07:53:20 +0200 Subject: [PATCH 11/28] fix: add allow deprecated macro for tests --- polkadot/runtime/common/src/impls.rs | 121 ++++++++++++++------------- 1 file changed, 61 insertions(+), 60 deletions(-) diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 2258aa8b298a..42dffd20f3ac 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -24,10 +24,7 @@ use frame_support::traits::{ }; use pallet_treasury::TreasuryAccountId; use polkadot_primitives::Balance; -use sp_runtime::{ - traits::{Saturating, TryConvert}, - Perquintill, RuntimeDebug, -}; +use sp_runtime::{traits::TryConvert, Perquintill, RuntimeDebug}; use xcm::VersionedLocation; /// Logic for the author to get a portion of fees. @@ -82,6 +79,8 @@ pub struct EraPayoutParams { } pub fn relay_era_payout(params: EraPayoutParams) -> (Balance, Balance) { + use sp_runtime::traits::Saturating; + let EraPayoutParams { total_staked, total_stakable, @@ -474,14 +473,12 @@ mod tests { #[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) - ); + #[allow(deprecated)] + let payout = era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0); + assert_eq!(payout, (10, 0)); + #[allow(deprecated)] + let payout = era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0); + assert_eq!(payout, (6, 4)); } #[test] @@ -513,58 +510,62 @@ mod tests { #[test] fn relay_era_payout_should_give_same_results_as_era_payout() { - let total_staked = 1_000_000; - let total_stakable = 2_000_000; - let max_annual_inflation = Perquintill::from_percent(10); - let period_fraction = Perquintill::from_percent(25); - let auctioned_slots = 30; - - let params = EraPayoutParams { - total_staked, - total_stakable, - ideal_stake: Perquintill::from_percent(75), - max_annual_inflation, - min_annual_inflation: Perquintill::from_rational(25u64, 1000u64), - falloff: Perquintill::from_percent(5), - period_fraction, - legacy_auction_proportion: Some(Perquintill::from_rational(auctioned_slots.min(60), 200u64)), - }; - assert_eq!( - relay_era_payout(params), - era_payout( - total_staked, - total_stakable, - max_annual_inflation, - period_fraction, - auctioned_slots, - ), - ); + let total_staked = 1_000_000; + let total_stakable = 2_000_000; + let max_annual_inflation = Perquintill::from_percent(10); + let period_fraction = Perquintill::from_percent(25); + let auctioned_slots = 30; - let total_staked = 1_900_000; - let total_stakable = 2_000_000; - let auctioned_slots = 60; + let params = EraPayoutParams { + total_staked, + total_stakable, + ideal_stake: Perquintill::from_percent(75), + max_annual_inflation, + min_annual_inflation: Perquintill::from_rational(25u64, 1000u64), + falloff: Perquintill::from_percent(5), + period_fraction, + legacy_auction_proportion: Some(Perquintill::from_rational( + auctioned_slots.min(60), + 200u64, + )), + }; + #[allow(deprecated)] + let payout = era_payout( + total_staked, + total_stakable, + max_annual_inflation, + period_fraction, + auctioned_slots, + ); + assert_eq!(relay_era_payout(params), payout); - let params = EraPayoutParams { - total_staked, - total_stakable, - ideal_stake: Perquintill::from_percent(75), - max_annual_inflation, - min_annual_inflation: Perquintill::from_rational(25u64, 1000u64), - falloff: Perquintill::from_percent(5), - period_fraction, - legacy_auction_proportion: Some(Perquintill::from_rational(auctioned_slots.min(60), 200u64)), - }; + let total_staked = 1_900_000; + let total_stakable = 2_000_000; + let auctioned_slots = 60; - assert_eq!( - era_payout( - total_staked, - total_stakable, - max_annual_inflation, - period_fraction, - auctioned_slots, - ), - relay_era_payout(params), + let params = EraPayoutParams { + total_staked, + total_stakable, + ideal_stake: Perquintill::from_percent(75), + max_annual_inflation, + min_annual_inflation: Perquintill::from_rational(25u64, 1000u64), + falloff: Perquintill::from_percent(5), + period_fraction, + legacy_auction_proportion: Some(Perquintill::from_rational( + auctioned_slots.min(60), + 200u64, + )), + }; + #[allow(deprecated)] + let payout = era_payout( + total_staked, + total_stakable, + max_annual_inflation, + period_fraction, + auctioned_slots, ); + + assert_eq!(relay_era_payout(params), payout); } } From ae0a72d08efc3db7de445b77471b1ed68be56566 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Wed, 10 Jul 2024 08:07:31 +0200 Subject: [PATCH 12/28] fix: missing default trait for runtimeparameters --- polkadot/runtime/westend/src/lib.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 5611a1b698f2..cb60911f16c4 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -29,7 +29,7 @@ use frame_support::{ parameter_types, traits::{ fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, Contains, EitherOf, - EitherOfDiverse, EnsureOrigin, EnsureOriginWithArg, EverythingBut, FromContains, + EitherOfDiverse, EnsureOriginWithArg, EverythingBut, FromContains, InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, ProcessMessageError, VariantCountOf, WithdrawReasons, }, @@ -87,7 +87,6 @@ use sp_consensus_beefy::{ use sp_core::{ConstU8, OpaqueMetadata, RuntimeDebug, H256}; use sp_runtime::{ create_runtime_str, - curve::PiecewiseLinear, generic, impl_opaque_keys, traits::{ AccountIdConversion, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, @@ -268,6 +267,17 @@ pub mod dynamic_params { } } + +#[cfg(feature = "runtime-benchmarks")] +impl Default for RuntimeParameters { + fn default() -> Self { + RuntimeParameters::Inflation(dynamic_params::inflation::Parameters::MinInflation( + dynamic_params::inflation::MinInflation, + Some(Perquintill::from_rational(25u64, 1000u64)), + )) + } +} + impl pallet_parameters::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeParameters = RuntimeParameters; @@ -286,13 +296,19 @@ impl EnsureOriginWithArg for DynamicParamet origin: RuntimeOrigin, key: &RuntimeParametersKey, ) -> Result { - use crate::{dynamic_params::*, governance::*, RuntimeParametersKey::*}; + use crate::RuntimeParametersKey::*; match key { Inflation(_) => frame_system::ensure_root(origin.clone()), } .map_err(|_| origin) } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin(_key: &RuntimeParametersKey) -> Result { + // Provide the origin for the parameter returned by `Default`: + Ok(RuntimeOrigin::root()) + } } impl pallet_preimage::Config for Runtime { From 451f622e68b5123903379a87061f2efb5760c0f6 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Wed, 10 Jul 2024 08:24:59 +0200 Subject: [PATCH 13/28] docs: add comments for era payout params --- polkadot/runtime/common/src/impls.rs | 8 ++++++++ polkadot/runtime/westend/src/lib.rs | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 42dffd20f3ac..75644f2c4e1a 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -68,13 +68,21 @@ where } pub struct EraPayoutParams { + /// Total staked amount. pub total_staked: Balance, + /// Total stakable amount. pub total_stakable: Balance, + /// Ideal stake ratio, which is deducted by `legacy_auction_proportion` if not `None`. pub ideal_stake: Perquintill, + /// Maximum inflation rate. pub max_annual_inflation: Perquintill, + /// Minimum inflation rate. pub min_annual_inflation: Perquintill, + /// Falloff used to calculate era payouts. pub falloff: Perquintill, + /// Fraction of the era period used to calculate era payouts. pub period_fraction: Perquintill, + /// Legacy auction proportion, which substracts from `ideal_stake` if not `None`. pub legacy_auction_proportion: Option, } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index cb60911f16c4..ee2350f41a9b 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -247,21 +247,28 @@ parameter_types! { pub mod dynamic_params { use super::*; + /// Parameters used to calculate era payouts, see [`polkadot_runtime_common::impls::EraPayoutParams`]. #[dynamic_pallet_params] #[codec(index = 0)] pub mod inflation { + /// Minimum inflation rate used to calculate era payouts. #[codec(index = 0)] pub static MinInflation: Perquintill = Perquintill::from_rational(25u64, 1000u64); + /// Maximum inflation rate used to calculate era payouts. #[codec(index = 1)] pub static MaxInflation: Perquintill = Perquintill::from_rational(100u64, 1000u64); + /// Ideal stake ratio used to calculate era payouts. #[codec(index = 2)] pub static IdealStake: Perquintill = Perquintill::from_rational(500u64, 1000u64); + /// Falloff used to calculate era payouts. #[codec(index = 3)] pub static Falloff: Perquintill = Perquintill::from_rational(50u64, 1000u64); + /// Whether to use auction slots or not in the calculation of era payouts. If set to true, + /// the `legacy_auction_proportion` of 60% will be used in the calculation of era payouts. #[codec(index = 4)] pub static UseAuctionSlots: bool = false; } From e866cd95c4ed7577de537e8981cf7c3caad904bb Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Fri, 12 Jul 2024 05:14:09 +0800 Subject: [PATCH 14/28] doc: update stakable amount description Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- polkadot/runtime/common/src/impls.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 75644f2c4e1a..2644dafdf369 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -71,6 +71,8 @@ pub struct EraPayoutParams { /// Total staked amount. pub total_staked: Balance, /// Total stakable amount. + /// + /// Usually, this is equal to the total issuance, except if a large part of the issuance is locked in another sub-system. pub total_stakable: Balance, /// Ideal stake ratio, which is deducted by `legacy_auction_proportion` if not `None`. pub ideal_stake: Perquintill, From 833d20921ae2d784754f03de8e3a2be6983ef0f1 Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Thu, 11 Jul 2024 23:15:43 +0200 Subject: [PATCH 15/28] refactor: move deprecated fn to test module --- polkadot/runtime/common/src/impls.rs | 86 ++++++++++++++-------------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 2644dafdf369..0532276cb291 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -124,46 +124,6 @@ pub fn relay_era_payout(params: EraPayoutParams) -> (Balance, Balance) { (staking_payout, rest) } -#[deprecated = "use relay_era_payout instead which supports dynamic parameters"] -pub fn era_payout( - total_staked: Balance, - total_stakable: 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, total_stakable); - 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 * total_stakable; - let staking_payout = (period_fraction * staking_inflation) * total_stakable; - let rest = max_payout.saturating_sub(staking_payout); - - let other_issuance = total_stakable.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) -} - /// Versioned locatable asset type which contains both an XCM `location` and `asset_id` to identify /// an asset which exists on some chain. #[derive( @@ -429,6 +389,46 @@ mod tests { t.into() } + pub fn era_payout( + total_staked: Balance, + total_stakable: 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, total_stakable); + 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 * total_stakable; + let staking_payout = (period_fraction * staking_inflation) * total_stakable; + let rest = max_payout.saturating_sub(staking_payout); + + let other_issuance = total_stakable.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) + } + + #[test] fn test_fees_and_tip_split() { new_test_ext().execute_with(|| { @@ -483,10 +483,9 @@ mod tests { #[test] fn era_payout_should_give_sensible_results() { - #[allow(deprecated)] let payout = era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0); assert_eq!(payout, (10, 0)); - #[allow(deprecated)] + let payout = era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0); assert_eq!(payout, (6, 4)); } @@ -540,7 +539,6 @@ mod tests { )), }; - #[allow(deprecated)] let payout = era_payout( total_staked, total_stakable, @@ -567,7 +565,7 @@ mod tests { 200u64, )), }; - #[allow(deprecated)] + let payout = era_payout( total_staked, total_stakable, From 8843d73b6e6d9b3224491c8b49881b7b5b782fb7 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 17 Jul 2024 17:22:55 +0100 Subject: [PATCH 16/28] works --- Cargo.lock | 2 + polkadot/runtime/common/src/impls.rs | 22 ++++-- polkadot/runtime/westend/src/lib.rs | 79 ++++++++++++++----- polkadot/runtime/westend/src/weights/mod.rs | 1 + .../frame/staking/runtime-api/Cargo.toml | 4 +- .../frame/staking/runtime-api/src/lib.rs | 15 ++++ 6 files changed, 95 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52f765826f2f..ee587b94230a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11550,7 +11550,9 @@ name = "pallet-staking-runtime-api" version = "14.0.0" dependencies = [ "parity-scale-codec", + "scale-info", "sp-api", + "sp-arithmetic", "sp-staking", ] diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 34184ffd361b..7fdff814a2d5 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -67,12 +67,14 @@ where } } +/// Parameters passed into [`relay_era_payout`] function. pub struct EraPayoutParams { /// Total staked amount. pub total_staked: Balance, /// Total stakable amount. /// - /// Usually, this is equal to the total issuance, except if a large part of the issuance is locked in another sub-system. + /// Usually, this is equal to the total issuance, except if a large part of the issuance is + /// locked in another sub-system. pub total_stakable: Balance, /// Ideal stake ratio, which is deducted by `legacy_auction_proportion` if not `None`. pub ideal_stake: Perquintill, @@ -88,6 +90,8 @@ pub struct EraPayoutParams { pub legacy_auction_proportion: Option, } +/// A specialized function to compute the inflation of the staking system, tailored for polkadot +/// relay chains, such as Polkadot, Kusama and Westend. pub fn relay_era_payout(params: EraPayoutParams) -> (Balance, Balance) { use sp_runtime::traits::Saturating; @@ -389,7 +393,7 @@ mod tests { t.into() } - pub fn era_payout( + pub fn deprecated_era_payout( total_staked: Balance, total_stakable: Balance, max_annual_inflation: Perquintill, @@ -421,14 +425,14 @@ mod tests { let other_issuance = total_stakable.saturating_sub(total_staked); if total_staked > other_issuance { - let _cap_rest = Perquintill::from_rational(other_issuance, total_staked) * staking_payout; + 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) } - #[test] fn test_fees_and_tip_split() { new_test_ext().execute_with(|| { @@ -483,10 +487,12 @@ mod tests { #[test] fn era_payout_should_give_sensible_results() { - let payout = era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0); + let payout = + deprecated_era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0); assert_eq!(payout, (10, 0)); - let payout = era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0); + let payout = + deprecated_era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0); assert_eq!(payout, (6, 4)); } @@ -539,7 +545,7 @@ mod tests { )), }; - let payout = era_payout( + let payout = deprecated_era_payout( total_staked, total_stakable, max_annual_inflation, @@ -566,7 +572,7 @@ mod tests { )), }; - let payout = era_payout( + let payout = deprecated_era_payout( total_staked, total_stakable, max_annual_inflation, diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index f8dc6d1d865e..43ad2b3d791d 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -36,9 +36,9 @@ use frame_support::{ parameter_types, traits::{ fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, Contains, EitherOf, - EitherOfDiverse, EnsureOriginWithArg, EverythingBut, FromContains, - InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, - ProcessMessageError, VariantCountOf, WithdrawReasons, + EitherOfDiverse, EnsureOriginWithArg, EverythingBut, FromContains, InstanceFilter, + KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, ProcessMessageError, + VariantCountOf, WithdrawReasons, }, weights::{ConstantMultiplier, WeightMeter, WeightToFee as _}, PalletId, @@ -93,11 +93,10 @@ use sp_consensus_beefy::{ }; use sp_core::{ConstU8, OpaqueMetadata, RuntimeDebug, H256}; use sp_runtime::{ - create_runtime_str, - generic, impl_opaque_keys, + create_runtime_str, generic, impl_opaque_keys, traits::{ AccountIdConversion, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, - IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion, Verify, + IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion, Saturating, Verify, }, transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, @@ -250,7 +249,8 @@ parameter_types! { pub mod dynamic_params { use super::*; - /// Parameters used to calculate era payouts, see [`polkadot_runtime_common::impls::EraPayoutParams`]. + /// Parameters used to calculate era payouts, see + /// [`polkadot_runtime_common::impls::EraPayoutParams`]. #[dynamic_pallet_params] #[codec(index = 0)] pub mod inflation { @@ -260,11 +260,11 @@ pub mod dynamic_params { /// Maximum inflation rate used to calculate era payouts. #[codec(index = 1)] - pub static MaxInflation: Perquintill = Perquintill::from_rational(100u64, 1000u64); + pub static MaxInflation: Perquintill = Perquintill::from_rational(10u64, 100u64); /// Ideal stake ratio used to calculate era payouts. #[codec(index = 2)] - pub static IdealStake: Perquintill = Perquintill::from_rational(500u64, 1000u64); + pub static IdealStake: Perquintill = Perquintill::from_rational(50u64, 100u64); /// Falloff used to calculate era payouts. #[codec(index = 3)] @@ -277,7 +277,6 @@ pub mod dynamic_params { } } - #[cfg(feature = "runtime-benchmarks")] impl Default for RuntimeParameters { fn default() -> Self { @@ -292,9 +291,7 @@ impl pallet_parameters::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeParameters = RuntimeParameters; type AdminOrigin = DynamicParameterOrigin; - // TODO: add benchmarking and update weight info - type WeightInfo = (); - // type WeightInfo = weights::pallet_parameters::WeightInfo; + type WeightInfo = weights::pallet_parameters::WeightInfo; } /// Defines what origin can modify which dynamic parameters. @@ -676,27 +673,31 @@ impl pallet_bags_list::Config for Runtime { type Score = sp_npos_elections::VoteWeight; } - pub struct EraPayout; impl pallet_staking::EraPayout for EraPayout { fn era_payout( total_staked: Balance, - _total_issuance: Balance, + total_issuance: Balance, era_duration_millis: u64, ) -> (Balance, Balance) { const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; - let use_auctioned_slots = dynamic_params::inflation::UseAuctionSlots::get(); let params = EraPayoutParams { total_staked, - total_stakable: Balances::total_issuance(), + total_stakable: total_issuance, ideal_stake: dynamic_params::inflation::IdealStake::get(), max_annual_inflation: dynamic_params::inflation::MaxInflation::get(), min_annual_inflation: dynamic_params::inflation::MinInflation::get(), falloff: dynamic_params::inflation::Falloff::get(), period_fraction: Perquintill::from_rational(era_duration_millis, MILLISECONDS_PER_YEAR), - legacy_auction_proportion: if use_auctioned_slots { - Some(Perquintill::from_rational(60u64, 200u64)) + legacy_auction_proportion: if dynamic_params::inflation::UseAuctionSlots::get() { + let auctioned_slots = parachains_paras::Parachains::::get() + .into_iter() + // all active para-ids that do not belong to a system chain is the number of + // parachains that we should take into account for inflation. + .filter(|i| *i >= 2000.into()) + .count() as u64; + Some(Perquintill::from_rational(auctioned_slots.min(60), 200u64)) } else { None }, @@ -2449,6 +2450,10 @@ sp_api::impl_runtime_apis! { fn pending_rewards(era: sp_staking::EraIndex, account: AccountId) -> bool { Staking::api_pending_rewards(era, account) } + + fn inflation_info() -> pallet_staking_runtime_api::InflationInfo { + Runtime::staking_inflation_info() + } } #[cfg(feature = "try-runtime")] @@ -2735,6 +2740,42 @@ sp_api::impl_runtime_apis! { } } +impl Runtime { + fn staking_inflation_info() -> pallet_staking_runtime_api::InflationInfo { + use pallet_staking::{ActiveEra, EraPayout, ErasTotalStake}; + + let (staked, start) = ActiveEra::::get() + .map(|ae| (ErasTotalStake::::get(ae.index), ae.start.unwrap_or(0))) + .unwrap_or((0, 0)); + let stake_able_issuance = Balances::total_issuance(); + let staking_rate = Perquintill::from_rational(staked, stake_able_issuance); + + let ideal_staking_rate = dynamic_params::inflation::IdealStake::get(); + let inflation = if dynamic_params::inflation::UseAuctionSlots::get() { + let auctioned_slots = parachains_paras::Parachains::::get() + .into_iter() + // all active para-ids that do not belong to a system chain is the number of + // parachains that we should take into account for inflation. + .filter(|i| *i >= 2000.into()) + .count() as u64; + ideal_staking_rate + .saturating_sub(Perquintill::from_rational(auctioned_slots.min(60), 200u64)) + } else { + ideal_staking_rate + }; + + let now_as_millis_u64 = pallet_timestamp::Now::::get(); + let era_duration = (now_as_millis_u64.saturating_sub(start)).saturated_into::(); + let next_mint = ::EraPayout::era_payout( + staked, + stake_able_issuance, + era_duration, + ); + + pallet_staking_runtime_api::InflationInfo { staking_rate, inflation, next_mint } + } +} + #[cfg(all(test, feature = "try-runtime"))] mod remote_tests { use super::*; diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs index f6a9008d7187..d92802c8751d 100644 --- a/polkadot/runtime/westend/src/weights/mod.rs +++ b/polkadot/runtime/westend/src/weights/mod.rs @@ -28,6 +28,7 @@ pub mod pallet_indices; pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_nomination_pools; +pub mod pallet_parameters; pub mod pallet_preimage; pub mod pallet_proxy; pub mod pallet_referenda_fellowship_referenda; diff --git a/substrate/frame/staking/runtime-api/Cargo.toml b/substrate/frame/staking/runtime-api/Cargo.toml index 624279624bc8..f68e0b22e356 100644 --- a/substrate/frame/staking/runtime-api/Cargo.toml +++ b/substrate/frame/staking/runtime-api/Cargo.toml @@ -17,9 +17,11 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { features = ["derive"], workspace = true } +scale-info = { features = ["derive"], workspace = true } sp-api = { workspace = true } sp-staking = { workspace = true } +sp-arithmetic = { workspace = true } [features] default = ["std"] -std = ["codec/std", "sp-api/std", "sp-staking/std"] +std = ["codec/std", "scale-info/std", "sp-api/std", "sp-staking/std", "sp-arithmetic/std"] diff --git a/substrate/frame/staking/runtime-api/src/lib.rs b/substrate/frame/staking/runtime-api/src/lib.rs index 7955f4184a43..d29e6fe4a2e6 100644 --- a/substrate/frame/staking/runtime-api/src/lib.rs +++ b/substrate/frame/staking/runtime-api/src/lib.rs @@ -21,6 +21,18 @@ use codec::Codec; +/// Return type of [`StakingApi::inflation_info`]. +#[derive(codec::Encode, codec::Decode, scale_info::TypeInfo)] +pub struct InflationInfo { + /// The percentage of the tokens currently staked. + pub staking_rate: sp_arithmetic::Perquintill, + /// The inflation per annum based on the above, and possibly other parameters. + pub inflation: sp_arithmetic::Perquintill, + /// A "best effort prediction" of the next inflation amount, based on the current system + /// parameters. + pub next_mint: (u128, u128), +} + sp_api::decl_runtime_apis! { pub trait StakingApi where @@ -35,5 +47,8 @@ sp_api::decl_runtime_apis! { /// Returns true if validator `account` has pages to be claimed for the given era. fn pending_rewards(era: sp_staking::EraIndex, account: AccountId) -> bool; + + /// Returns a set of information about the staking rate. + fn inflation_info() -> InflationInfo; } } From 704e13cde327bebb8585c90699d718e786dd46f4 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 17 Jul 2024 17:28:39 +0100 Subject: [PATCH 17/28] add weight file --- .../westend/src/weights/pallet_parameters.rs | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 polkadot/runtime/westend/src/weights/pallet_parameters.rs diff --git a/polkadot/runtime/westend/src/weights/pallet_parameters.rs b/polkadot/runtime/westend/src/weights/pallet_parameters.rs new file mode 100644 index 000000000000..2e131ce55f31 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_parameters.rs @@ -0,0 +1,63 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `pallet_parameters` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-04-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-anb7yjbi-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_parameters +// --chain=westend +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/westend/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_parameters`. +pub struct WeightInfo(PhantomData); +impl pallet_parameters::WeightInfo for WeightInfo { + /// Storage: `Parameters::Parameters` (r:1 w:1) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + fn set_parameter() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3493` + // Minimum execution time: 6_937_000 picoseconds. + Weight::from_parts(7_242_000, 0) + .saturating_add(Weight::from_parts(0, 3493)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} From 4884a4899f341b33cc9d3d37def4ece1bf4881c7 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 17 Jul 2024 17:37:17 +0100 Subject: [PATCH 18/28] fmt toml --- substrate/frame/staking/runtime-api/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/staking/runtime-api/Cargo.toml b/substrate/frame/staking/runtime-api/Cargo.toml index f68e0b22e356..fab079312de9 100644 --- a/substrate/frame/staking/runtime-api/Cargo.toml +++ b/substrate/frame/staking/runtime-api/Cargo.toml @@ -24,4 +24,4 @@ sp-arithmetic = { workspace = true } [features] default = ["std"] -std = ["codec/std", "scale-info/std", "sp-api/std", "sp-staking/std", "sp-arithmetic/std"] +std = ["codec/std", "scale-info/std", "sp-api/std", "sp-arithmetic/std", "sp-staking/std"] From ede367ab2c8c1cf1cd143eb88e5dd6255a0eff17 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 17 Jul 2024 17:52:54 +0100 Subject: [PATCH 19/28] remove api --- polkadot/runtime/westend/src/lib.rs | 36 ------------------- .../frame/staking/runtime-api/Cargo.toml | 3 +- .../frame/staking/runtime-api/src/lib.rs | 15 -------- 3 files changed, 1 insertion(+), 53 deletions(-) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 43ad2b3d791d..f021457de786 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2740,42 +2740,6 @@ sp_api::impl_runtime_apis! { } } -impl Runtime { - fn staking_inflation_info() -> pallet_staking_runtime_api::InflationInfo { - use pallet_staking::{ActiveEra, EraPayout, ErasTotalStake}; - - let (staked, start) = ActiveEra::::get() - .map(|ae| (ErasTotalStake::::get(ae.index), ae.start.unwrap_or(0))) - .unwrap_or((0, 0)); - let stake_able_issuance = Balances::total_issuance(); - let staking_rate = Perquintill::from_rational(staked, stake_able_issuance); - - let ideal_staking_rate = dynamic_params::inflation::IdealStake::get(); - let inflation = if dynamic_params::inflation::UseAuctionSlots::get() { - let auctioned_slots = parachains_paras::Parachains::::get() - .into_iter() - // all active para-ids that do not belong to a system chain is the number of - // parachains that we should take into account for inflation. - .filter(|i| *i >= 2000.into()) - .count() as u64; - ideal_staking_rate - .saturating_sub(Perquintill::from_rational(auctioned_slots.min(60), 200u64)) - } else { - ideal_staking_rate - }; - - let now_as_millis_u64 = pallet_timestamp::Now::::get(); - let era_duration = (now_as_millis_u64.saturating_sub(start)).saturated_into::(); - let next_mint = ::EraPayout::era_payout( - staked, - stake_able_issuance, - era_duration, - ); - - pallet_staking_runtime_api::InflationInfo { staking_rate, inflation, next_mint } - } -} - #[cfg(all(test, feature = "try-runtime"))] mod remote_tests { use super::*; diff --git a/substrate/frame/staking/runtime-api/Cargo.toml b/substrate/frame/staking/runtime-api/Cargo.toml index fab079312de9..badacff84c5b 100644 --- a/substrate/frame/staking/runtime-api/Cargo.toml +++ b/substrate/frame/staking/runtime-api/Cargo.toml @@ -20,8 +20,7 @@ codec = { features = ["derive"], workspace = true } scale-info = { features = ["derive"], workspace = true } sp-api = { workspace = true } sp-staking = { workspace = true } -sp-arithmetic = { workspace = true } [features] default = ["std"] -std = ["codec/std", "scale-info/std", "sp-api/std", "sp-arithmetic/std", "sp-staking/std"] +std = ["codec/std", "scale-info/std", "sp-api/std", "sp-staking/std"] diff --git a/substrate/frame/staking/runtime-api/src/lib.rs b/substrate/frame/staking/runtime-api/src/lib.rs index d29e6fe4a2e6..7955f4184a43 100644 --- a/substrate/frame/staking/runtime-api/src/lib.rs +++ b/substrate/frame/staking/runtime-api/src/lib.rs @@ -21,18 +21,6 @@ use codec::Codec; -/// Return type of [`StakingApi::inflation_info`]. -#[derive(codec::Encode, codec::Decode, scale_info::TypeInfo)] -pub struct InflationInfo { - /// The percentage of the tokens currently staked. - pub staking_rate: sp_arithmetic::Perquintill, - /// The inflation per annum based on the above, and possibly other parameters. - pub inflation: sp_arithmetic::Perquintill, - /// A "best effort prediction" of the next inflation amount, based on the current system - /// parameters. - pub next_mint: (u128, u128), -} - sp_api::decl_runtime_apis! { pub trait StakingApi where @@ -47,8 +35,5 @@ sp_api::decl_runtime_apis! { /// Returns true if validator `account` has pages to be claimed for the given era. fn pending_rewards(era: sp_staking::EraIndex, account: AccountId) -> bool; - - /// Returns a set of information about the staking rate. - fn inflation_info() -> InflationInfo; } } From c866a69c4bac2728236117da21a5ee1aba3a6cfc Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 17 Jul 2024 17:53:34 +0100 Subject: [PATCH 20/28] update lock --- Cargo.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5df951cfc99b..726ae2fd903b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11552,7 +11552,6 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-arithmetic", "sp-staking", ] From 7ce4449f7477c371d204ee02a2a45985be33f259 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 17 Jul 2024 17:58:39 +0100 Subject: [PATCH 21/28] fix --- Cargo.lock | 3 ++- polkadot/runtime/westend/src/lib.rs | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 726ae2fd903b..ee587b94230a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11552,6 +11552,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", + "sp-arithmetic", "sp-staking", ] @@ -19856,6 +19857,7 @@ name = "sp-blockchain" version = "28.0.0" dependencies = [ "futures", + "log", "parity-scale-codec", "parking_lot 0.12.3", "schnellru", @@ -19866,7 +19868,6 @@ dependencies = [ "sp-runtime", "sp-state-machine", "thiserror", - "tracing", ] [[package]] diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index f021457de786..58f6f1ed72d7 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2450,10 +2450,6 @@ sp_api::impl_runtime_apis! { fn pending_rewards(era: sp_staking::EraIndex, account: AccountId) -> bool { Staking::api_pending_rewards(era, account) } - - fn inflation_info() -> pallet_staking_runtime_api::InflationInfo { - Runtime::staking_inflation_info() - } } #[cfg(feature = "try-runtime")] From e8037dee9a75f4d6f9b9cbfc447bf044bedd238a Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 17 Jul 2024 18:07:30 +0100 Subject: [PATCH 22/28] remove more unused stuff --- Cargo.lock | 4 +--- substrate/frame/staking/runtime-api/Cargo.toml | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee587b94230a..27f149c7edb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11550,9 +11550,7 @@ name = "pallet-staking-runtime-api" version = "14.0.0" dependencies = [ "parity-scale-codec", - "scale-info", "sp-api", - "sp-arithmetic", "sp-staking", ] @@ -19857,7 +19855,6 @@ name = "sp-blockchain" version = "28.0.0" dependencies = [ "futures", - "log", "parity-scale-codec", "parking_lot 0.12.3", "schnellru", @@ -19868,6 +19865,7 @@ dependencies = [ "sp-runtime", "sp-state-machine", "thiserror", + "tracing", ] [[package]] diff --git a/substrate/frame/staking/runtime-api/Cargo.toml b/substrate/frame/staking/runtime-api/Cargo.toml index badacff84c5b..624279624bc8 100644 --- a/substrate/frame/staking/runtime-api/Cargo.toml +++ b/substrate/frame/staking/runtime-api/Cargo.toml @@ -17,10 +17,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { features = ["derive"], workspace = true } -scale-info = { features = ["derive"], workspace = true } sp-api = { workspace = true } sp-staking = { workspace = true } [features] default = ["std"] -std = ["codec/std", "scale-info/std", "sp-api/std", "sp-staking/std"] +std = ["codec/std", "sp-api/std", "sp-staking/std"] From 8d62d466fbf80cc92ecd7ad908ab29ecfdced0aa Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 18 Jul 2024 11:10:17 +0100 Subject: [PATCH 23/28] add prodoc --- prdoc/pr_4938.prdoc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 prdoc/pr_4938.prdoc diff --git a/prdoc/pr_4938.prdoc b/prdoc/pr_4938.prdoc new file mode 100644 index 000000000000..9120fe427b3a --- /dev/null +++ b/prdoc/pr_4938.prdoc @@ -0,0 +1,17 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: introduce pallet-parameters to Westend to parameterize inflation + +doc: + - audience: Runtime User + description: | + This PR adds `pallet-parameters` to the Westend runtime, and makes the inflation formula be + adjustable based on this. + + Moreover, the old `era_payout` function has been removed from `polkadot_runtime_common` and is + replaced by `relay_era_payout`. This function is only meant to be used in the Polkadot relay + chains, and other users are encouraged to provide their own implementation of `type + EraPayout`. + +crates: [ ] From d8760c7ba1d72e4c0668f8506f6a1fc863f620d1 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 18 Jul 2024 11:18:08 +0100 Subject: [PATCH 24/28] add release related stuff --- Cargo.lock | 2 +- polkadot/runtime/common/Cargo.toml | 2 +- prdoc/pr_4938.prdoc | 6 +++++- prdoc/pr_4943.prdoc | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1d10d3bbfa3..55c27930446e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13930,7 +13930,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" -version = "7.0.0" +version = "8.0.0" dependencies = [ "bitvec", "frame-benchmarking", diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index cda6f3240dd2..d1b08909cb76 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-runtime-common" -version = "7.0.0" +version = "8.0.0" description = "Pallets and constants used in Relay Chain networks." authors.workspace = true edition.workspace = true diff --git a/prdoc/pr_4938.prdoc b/prdoc/pr_4938.prdoc index 9120fe427b3a..acc2a7c98e0e 100644 --- a/prdoc/pr_4938.prdoc +++ b/prdoc/pr_4938.prdoc @@ -14,4 +14,8 @@ doc: chains, and other users are encouraged to provide their own implementation of `type EraPayout`. -crates: [ ] +crates: + - name: westend-runtime + bump: major + - name: polkadot-runtime-common + bump: major diff --git a/prdoc/pr_4943.prdoc b/prdoc/pr_4943.prdoc index 705325126060..a8db0f9e1ea1 100644 --- a/prdoc/pr_4943.prdoc +++ b/prdoc/pr_4943.prdoc @@ -8,6 +8,6 @@ doc: description: | This PR fixes a bug in the docs located in the definition of frozen balances. In addition, it extends that definition for completeness. -crates: +crates: - name: frame-support - bump: patch \ No newline at end of file + bump: patch From 026dcb64729a45f57dcaaea6237b25343b27078f Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 18 Jul 2024 11:27:23 +0100 Subject: [PATCH 25/28] revert --- Cargo.lock | 2 +- polkadot/runtime/common/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55c27930446e..c1d10d3bbfa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13930,7 +13930,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" -version = "8.0.0" +version = "7.0.0" dependencies = [ "bitvec", "frame-benchmarking", diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index d1b08909cb76..cda6f3240dd2 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-runtime-common" -version = "8.0.0" +version = "7.0.0" description = "Pallets and constants used in Relay Chain networks." authors.workspace = true edition.workspace = true From 2e128ac05c83cd32a6c765c184ba5eb06ac2939a Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 18 Jul 2024 10:36:29 +0000 Subject: [PATCH 26/28] ".git/.scripts/commands/fmt/fmt.sh" --- polkadot/runtime/westend/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 58f6f1ed72d7..08fa11514278 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1106,8 +1106,7 @@ impl InstanceFilter for ProxyType { matches!( c, RuntimeCall::Staking(..) | - RuntimeCall::Session(..) | - RuntimeCall::Utility(..) | + RuntimeCall::Session(..) | RuntimeCall::Utility(..) | RuntimeCall::FastUnstake(..) | RuntimeCall::VoterList(..) | RuntimeCall::NominationPools(..) From 8a6d11e7a261a126434dc07a62d5e9c5fd1bd0dc Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 18 Jul 2024 12:15:02 +0100 Subject: [PATCH 27/28] remove unused --- polkadot/runtime/westend/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 58f6f1ed72d7..0fe55e14fdd7 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -96,7 +96,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ AccountIdConversion, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, - IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion, Saturating, Verify, + IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion, Verify, }, transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, From e520f23729d56b86468b279b0ac2a2fa1c122033 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 18 Jul 2024 13:57:22 +0100 Subject: [PATCH 28/28] Empty-Commit