From 6e520eb4eb01644316765af638317eea1b94f97e Mon Sep 17 00:00:00 2001 From: Marcus Pang Yu Yang Date: Tue, 23 Jul 2024 05:42:11 +0800 Subject: [PATCH] feat: introduce pallet-parameters to Westend to parameterize inflation (#4938) Fixes #4907 ## Changes - Add `pallet-parameters` to Westend runtime - Add `relay_era_payout` function to Polkadot runtime common + deprecate previous `era_payout` function - Add unit tests for `relay_era_payout`, matching previous unit tests for `era_payout` - Remove `pallet_staking_reward_curve` in Westend runtime - Add `dynamic_params` to replace constants used for `pallet_staking_reward_curve` Polkadot address: 5DybbVdLvVWd7MiA1YwkzLUNL1ThMDicozbuLc8v9pQEScPQ --------- Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: kianenigma Co-authored-by: command-bot <> --- Cargo.lock | 2 +- polkadot/runtime/common/src/impls.rs | 194 +++++++++++++++--- polkadot/runtime/westend/Cargo.toml | 5 +- polkadot/runtime/westend/src/lib.rs | 134 ++++++++++-- polkadot/runtime/westend/src/weights/mod.rs | 1 + .../westend/src/weights/pallet_parameters.rs | 63 ++++++ prdoc/pr_4938.prdoc | 21 ++ prdoc/pr_4943.prdoc | 4 +- 8 files changed, 379 insertions(+), 45 deletions(-) create mode 100644 polkadot/runtime/westend/src/weights/pallet_parameters.rs create mode 100644 prdoc/pr_4938.prdoc diff --git a/Cargo.lock b/Cargo.lock index 82dd5bfaffa6..a6265a340759 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23535,6 +23535,7 @@ dependencies = [ "pallet-nomination-pools-runtime-api", "pallet-offences", "pallet-offences-benchmarking", + "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-recovery", @@ -23545,7 +23546,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/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index 9d61cd018731..7fdff814a2d5 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -67,29 +67,51 @@ where } } -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; +/// 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. + 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, +} + +/// 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; - let min_annual_inflation = Perquintill::from_rational(25u64, 1000u64); - let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation); + let EraPayoutParams { + total_staked, + total_stakable, + ideal_stake, + max_annual_inflation, + min_annual_inflation, + falloff, + period_fraction, + legacy_auction_proportion, + } = params; - // 30% reserved for up to 60 slots. - let auction_proportion = Perquintill::from_rational(auctioned_slots.min(60), 200u64); + let delta_annual_inflation = max_annual_inflation.saturating_sub(min_annual_inflation); - // 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 ideal_stake = ideal_stake.saturating_sub(legacy_auction_proportion.unwrap_or_default()); let stake = Perquintill::from_rational(total_staked, total_stakable); - let falloff = Perquintill::from_percent(5); - let adjustment = compute_inflation(stake, ideal_stake, falloff); + let adjustment = pallet_staking_reward_fn::compute_inflation(stake, ideal_stake, falloff); let staking_inflation = min_annual_inflation.saturating_add(delta_annual_inflation * adjustment); @@ -371,6 +393,46 @@ mod tests { t.into() } + pub fn deprecated_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(|| { @@ -425,13 +487,99 @@ 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) + let payout = + deprecated_era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0); + assert_eq!(payout, (10, 0)); + + let payout = + deprecated_era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0); + assert_eq!(payout, (6, 4)); + } + + #[test] + 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!(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!(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, + )), + }; + + let payout = deprecated_era_payout( + total_staked, + total_stakable, + max_annual_inflation, + period_fraction, + auctioned_slots, ); - assert_eq!( - era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0,), - (6, 4) + assert_eq!(relay_era_payout(params), payout); + + 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, + )), + }; + + let payout = deprecated_era_payout( + total_staked, + total_stakable, + max_annual_inflation, + period_fraction, + auctioned_slots, ); + + assert_eq!(relay_era_payout(params), payout); } } diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index d2bafb33d2cb..4226595cd2ff 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -71,6 +71,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 } @@ -79,7 +80,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 } @@ -173,6 +173,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", @@ -260,6 +261,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", @@ -318,6 +320,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", diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index f5da0e5502d6..13a69050c342 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -31,12 +31,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, @@ -59,8 +61,8 @@ use polkadot_runtime_common::{ 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}, @@ -91,9 +93,7 @@ use sp_consensus_beefy::{ }; use sp_core::{ConstU8, OpaqueMetadata, RuntimeDebug, H256}; use sp_runtime::{ - create_runtime_str, - curve::PiecewiseLinear, - 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, @@ -244,6 +244,80 @@ 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::*; + + /// 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(10u64, 100u64); + + /// Ideal stake ratio used to calculate era payouts. + #[codec(index = 2)] + pub static IdealStake: Perquintill = Perquintill::from_rational(50u64, 100u64); + + /// 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; + } +} + +#[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; + type AdminOrigin = DynamicParameterOrigin; + type WeightInfo = weights::pallet_parameters::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::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 { type WeightInfo = weights::pallet_preimage::WeightInfo; type RuntimeEvent = RuntimeEvent; @@ -596,15 +670,37 @@ 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, - max_inflation: 0_100_000, - ideal_stake: 0_500_000, - falloff: 0_050_000, - max_piece_count: 40, - test_precision: 0_005_000, - ); +pub struct EraPayout; +impl pallet_staking::EraPayout for EraPayout { + fn era_payout( + total_staked: Balance, + total_issuance: Balance, + era_duration_millis: u64, + ) -> (Balance, Balance) { + const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; + + let params = EraPayoutParams { + total_staked, + 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 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 + }, + }; + relay_era_payout(params) + } } parameter_types! { @@ -614,7 +710,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 @@ -638,7 +733,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; @@ -1475,6 +1570,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; @@ -1756,6 +1853,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] diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs index 313a45111175..2248e421e639 100644 --- a/polkadot/runtime/westend/src/weights/mod.rs +++ b/polkadot/runtime/westend/src/weights/mod.rs @@ -29,6 +29,7 @@ pub mod pallet_message_queue; pub mod pallet_mmr; 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/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)) + } +} diff --git a/prdoc/pr_4938.prdoc b/prdoc/pr_4938.prdoc new file mode 100644 index 000000000000..acc2a7c98e0e --- /dev/null +++ b/prdoc/pr_4938.prdoc @@ -0,0 +1,21 @@ +# 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: + - 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