Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
180 commits
Select commit Hold shift + click to select a range
b93e24c
trait reward provider
Ank4n Jan 18, 2026
f84ec1b
move EraPayout from staking pallet to sp-staking
Ank4n Jan 18, 2026
bda2627
dap reward provider impl
Ank4n Jan 18, 2026
89621fb
remove EraPayout dec from pallet-staking (old)
Ank4n Jan 18, 2026
cbaddcd
fix nom pool test
Ank4n Jan 18, 2026
22e7e46
use Era payout from sp-staking in westend and wah
Ank4n Jan 18, 2026
34a0c50
fix import
Ank4n Jan 18, 2026
a012364
staking takes reward provider as dependency
Ank4n Jan 18, 2026
4293d60
impl payout new and legacy
Ank4n Jan 18, 2026
c0a8059
impl staking
Ank4n Jan 18, 2026
18e5efd
2 failing tests
Ank4n Jan 18, 2026
0b21639
assert against dap events
Ank4n Jan 18, 2026
95467ba
fmt
Ank4n Jan 18, 2026
5d1344f
fix test delegate stake
Ank4n Jan 18, 2026
d7a2721
fix wah compile
Ank4n Jan 18, 2026
d982723
add dap tests
Ank4n Jan 18, 2026
bd214a4
fmt
Ank4n Jan 18, 2026
fe2a8b4
clippy fixes
Ank4n Jan 18, 2026
6a4f441
fix test runtime
Ank4n Jan 18, 2026
2a89dc4
cleanup event and integration test
Ank4n Jan 18, 2026
97c368f
fix compile
Ank4n Jan 18, 2026
4e1a670
hard deprecate minting
Ank4n Jan 18, 2026
8cc88cb
fmt
Ank4n Jan 18, 2026
6c6a88c
fix trait definition
Ank4n Jan 19, 2026
8389b87
remove stuff from dap that we want to move to staking
Ank4n Jan 19, 2026
4a744b6
remove irrelevant tests from dap
Ank4n Jan 19, 2026
140d4a1
add budget config
Ank4n Jan 19, 2026
e13a612
minor
Ank4n Jan 19, 2026
2b5a220
tests for budget config
Ank4n Jan 19, 2026
c631455
add EraPayoutV2
Ank4n Jan 19, 2026
33b4020
core logic ok
Ank4n Jan 19, 2026
bec3339
add separate reward module
Ank4n Jan 19, 2026
0ee94bd
rename EraRewardPots to EraRewardManager
Ank4n Jan 19, 2026
4165566
minor
Ank4n Jan 19, 2026
55c6bc6
add seed and sequential account provider
Ank4n Jan 19, 2026
d8b2669
mock looks good
Ank4n Jan 19, 2026
e79f9d8
rounding down reward causes mismatch of values
Ank4n Jan 19, 2026
ce41bd9
fix benc
Ank4n Jan 19, 2026
98ac21c
fix runtimes
Ank4n Jan 19, 2026
b411fb2
fmt
Ank4n Jan 19, 2026
3ffa87a
Merge branch 'master' into ankn-dap-rewire
Ank4n Jan 19, 2026
7ac5ef6
fix staking warnings
Ank4n Jan 19, 2026
b5d43f0
Merge branch 'master' into ankn-dap-rewire
Ank4n Feb 2, 2026
90d970c
Merge branch 'master' into ankn-dap-rewire
Ank4n Feb 10, 2026
fad951e
fix compile
Ank4n Feb 10, 2026
211e422
fmt
Ank4n Feb 10, 2026
e6d3de4
Merge branch 'master' into ankn-dap-rewire
Ank4n Feb 19, 2026
dbfa9a7
config params for self stake
Ank4n Feb 22, 2026
125eb85
all tests pass
Ank4n Feb 22, 2026
56d7ab0
track total weight
Ank4n Feb 22, 2026
0c13ff1
traitify self stake incentive calculation
Ank4n Feb 22, 2026
3cf38d7
sp-arithmetic dependency
Ank4n Feb 22, 2026
3d692a5
add storage to track individual validator incentive since we calculat…
Ank4n Feb 22, 2026
7b605fd
validate optimum is less than cap
Ank4n Feb 22, 2026
3f86532
incentive calculation function
Ank4n Feb 22, 2026
6fcfb47
integrate incentive reward in payout
Ank4n Feb 22, 2026
59dfda8
fix tests
Ank4n Feb 22, 2026
f019ef9
Merge branch 'master' into ankn-dap-rewire
Ank4n Feb 24, 2026
88e512d
refactor payout logic
Ank4n Feb 24, 2026
3474c1f
fmt
Ank4n Feb 24, 2026
2aeaf4b
fix ahm test and era cleanups
Ank4n Feb 24, 2026
0c5db85
incentive paid event
Ank4n Feb 25, 2026
2e03c8b
don't break old event and refactor reward dest -> account
Ank4n Feb 25, 2026
72e627b
minor
Ank4n Feb 25, 2026
73c7766
warn about using try_state(false)
Ank4n Feb 25, 2026
6d837a1
all green
Ank4n Feb 25, 2026
1e9c3bc
the one with feedbacks
Ank4n Feb 26, 2026
74498bc
feedback fixes
Ank4n Feb 26, 2026
a613cfc
fix test
Ank4n Feb 26, 2026
da945d7
trait for validator incentive payout
Ank4n Mar 2, 2026
6a81167
Vesting duration as config, plus trait that implements incentive payout
Ank4n Mar 2, 2026
2b763f2
add test dependency to pallet vesting
Ank4n Mar 2, 2026
e43dfba
fix mock ah runtime compile
Ank4n Mar 2, 2026
fcada7a
fix mock runtimes
Ank4n Mar 4, 2026
8a6c033
add a vested payout trait that does not depend on currency or fungible
Ank4n Mar 4, 2026
fe8ac61
implement vested payout trait
Ank4n Mar 4, 2026
efa5315
validator incentive impl
Ank4n Mar 4, 2026
9850daf
fmt
Ank4n Mar 4, 2026
8d642a2
add max commission
Ank4n Mar 4, 2026
6a05504
weights for set max commission
Ank4n Mar 4, 2026
ab3692b
missing bench
Ank4n Mar 4, 2026
ed96b58
fix mock, and some warnigns
Ank4n Mar 4, 2026
8c62935
self stake incentive curve test
Ank4n Mar 4, 2026
bccc793
max commission tests
Ank4n Mar 4, 2026
e97dd2e
Merge branch 'master' into ankn-dap-rewire
Ank4n Mar 9, 2026
ce207f3
Generic Budget (#11319)
Ank4n Mar 10, 2026
db21ae2
Merge branch 'master' into ankn-dap-rewire
Ank4n Mar 10, 2026
f902eee
refactor tests
Ank4n Mar 4, 2026
3f845fd
improve validator incentive tests
Ank4n Mar 4, 2026
2153b5a
add migration for last inflation timestamp
Ank4n Mar 10, 2026
bfb8c75
note about no provider
Ank4n Mar 10, 2026
babcee1
staking mock setup
Ank4n Mar 10, 2026
dd2a598
improve era rotation tests
Ank4n Mar 10, 2026
4523de2
validator incentive
Ank4n Mar 10, 2026
07e64aa
remove era duration capping since we drip per block now
Ank4n Mar 10, 2026
054cc82
fix mock runtime and bench
Ank4n Mar 10, 2026
411802c
fix staking async test parachain runtime
Ank4n Mar 10, 2026
904584a
fix runtimes
Ank4n Mar 10, 2026
1d12d7a
fix weight
Ank4n Mar 10, 2026
397a1c3
fmt
Ank4n Mar 10, 2026
41eb583
fix wah runtime
Ank4n Mar 10, 2026
b37da3e
ci fix
Ank4n Mar 11, 2026
a253c09
Merge branch 'master' into ankn-dap-rewire
Ank4n Mar 11, 2026
0bb77a3
taplo
Ank4n Mar 11, 2026
7102aa8
add new config for calculating vesting period with first unlock
Ank4n Mar 11, 2026
0685512
fix mock
Ank4n Mar 11, 2026
1c7691a
add blocks per session to runtimes
Ank4n Mar 11, 2026
39d6a7d
update prdoc
Ank4n Mar 11, 2026
cc93cc9
vesting e2e test
Ank4n Mar 11, 2026
1f8b1e8
hard assertion
Ank4n Mar 11, 2026
d052471
refactor vesting unti tests
Ank4n Mar 11, 2026
e3600f7
fmt
Ank4n Mar 11, 2026
b94e24d
clippy fix
Ank4n Mar 11, 2026
43be832
track actual transfer
Ank4n Mar 11, 2026
93622b8
add incentive weight for payout bench
Ank4n Mar 11, 2026
6951ef5
track actual minted
Ank4n Mar 11, 2026
54a14fb
storage version bump
Ank4n Mar 11, 2026
419560b
fmt
Ank4n Mar 11, 2026
d99af9b
fix docs and deactivate mints to buffer
Ank4n Mar 12, 2026
680e2d6
ci fix
Ank4n Mar 12, 2026
37b0096
refactor unclaimed reward sink trait
Ank4n Mar 12, 2026
e536b32
add root gates extrinsic to dap for moving funds in and out of buffer
Ank4n Mar 12, 2026
74261ab
tests for new dap calls
Ank4n Mar 12, 2026
2e83a86
fix mock
Ank4n Mar 12, 2026
48d191c
update staking unclaimed reward sink usage
Ank4n Mar 12, 2026
4333a64
fmt
Ank4n Mar 12, 2026
ffb0e60
add migration for initial budget config
Ank4n Mar 13, 2026
8345eb2
fmt
Ank4n Mar 13, 2026
e39203a
Merge branch 'master' into ankn-dap-rewire
Ank4n Mar 13, 2026
21cb84b
fix vesting exit bug
Ank4n Mar 14, 2026
b4ceedc
vesting tests
Ank4n Mar 14, 2026
41dad0f
vesting e2e missing unbond withdraw test
Ank4n Mar 14, 2026
068f235
dont panic in weights
Ank4n Mar 14, 2026
721d7aa
add helper to advance era until target
Ank4n Mar 14, 2026
6987db9
unbond withdraw vesting test
Ank4n Mar 14, 2026
b6b1cd9
check vest balance increase correct
Ank4n Mar 14, 2026
da4d1d2
full vest on early exit
Ank4n Mar 14, 2026
65ae827
Merge remote-tracking branch 'origin/master' into ankn-dap-rewire
sigurpol Mar 18, 2026
957f6d0
Merge branch 'master' into ankn-dap-rewire
Ank4n Mar 23, 2026
7b80e83
treasury funds are also deactivaed so no need to activate buffer ouflows
Ank4n Mar 24, 2026
d98849b
Use Get trait for timestamp provider
Ank4n Mar 24, 2026
8a2cafd
add test to ensure inflation cadence is lower than era length
Ank4n Mar 24, 2026
de465f9
fix comment
Ank4n Mar 24, 2026
431386e
defensive error on budget allocation empty
Ank4n Mar 24, 2026
ac361e6
minor
Ank4n Mar 24, 2026
3828d34
Merge branch 'master' into ankn-dap-rewire
Ank4n Mar 24, 2026
336f464
only enable test account providers in test
Ank4n Mar 24, 2026
1478a06
reexport EraPayout
Ank4n Mar 24, 2026
4b6e069
reduce visibility for reward fns
Ank4n Mar 24, 2026
bbae9d2
rename inflation -> issuance
Ank4n Mar 25, 2026
0ec9f62
fmt + fix mock
Ank4n Mar 25, 2026
5d70a18
try state checks
Ank4n Mar 25, 2026
f0418f7
run try state checks with unit tests
Ank4n Mar 25, 2026
ccdd8ee
fmt
Ank4n Mar 25, 2026
5c5c9ca
simplify staker reward calculator
Ank4n Mar 25, 2026
9cfbe02
fmt
Ank4n Mar 25, 2026
6528f04
Merge branch 'master' into ankn-dap-rewire
Ank4n Mar 25, 2026
19d1e80
check ErasValidatorIncentiveAllocation and ErasValidatorIncentive to …
Ank4n Mar 25, 2026
f5da09e
remane EraPotAccountProvider to EraPots
Ank4n Mar 25, 2026
6884365
fmt
Ank4n Mar 25, 2026
fc20498
rename the accessor staker reward fn
Ank4n Mar 25, 2026
0c6564e
fix overwriting of incentives
Ank4n Mar 25, 2026
c90c81d
fmt
Ank4n Mar 25, 2026
b1f38ee
use u64 to accumulate budget
Ank4n Mar 25, 2026
f7719e4
fmt
Ank4n Mar 25, 2026
2f32300
Merge branch 'master' into ankn-dap-rewire
Ank4n Mar 27, 2026
275d2ee
remove extra trait for UnclaimedRewardSink
Ank4n Mar 27, 2026
1e359ff
bench
Ank4n Mar 27, 2026
183a359
final fix
Ank4n Mar 27, 2026
ac44402
fmt
Ank4n Mar 27, 2026
f83c235
move EraRewardAllocation to staking async crate
Ank4n Mar 27, 2026
3fffcda
fmt
Ank4n Mar 27, 2026
df284ee
Merge branch 'master' into ankn-dap-rewire
Ank4n Apr 1, 2026
a4960b6
rogue conflict marker
Ank4n Apr 1, 2026
a734be9
fix compile
Ank4n Mar 31, 2026
91bc4c0
safe math and private fn
Ank4n Mar 31, 2026
b8c97dc
fmt
Ank4n Apr 1, 2026
a59c7aa
long name
Ank4n Apr 1, 2026
1b1b053
fmt
Ank4n Apr 1, 2026
7ed3039
Merge branch 'master' into ankn-dap-rewire
Ank4n Apr 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 47 additions & 1 deletion cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ use sp_version::RuntimeVersion;
use testnet_parachains_constants::westend::{
consensus::*, currency::*, snowbridge::EthereumNetwork, time::*,
};
use westend_runtime_constants::time::DAYS as RC_DAYS;
use westend_runtime_constants::time::{DAYS as RC_DAYS, HOURS as RC_HOURS};
use xcm_config::{
ForeignAssetsConvertedConcreteId, LocationToAccountId, PoolAssetsConvertedConcreteId,
PoolAssetsPalletLocation, TrustBackedAssetsConvertedConcreteId,
Expand Down Expand Up @@ -1581,6 +1581,37 @@ parameter_types! {
);
}

/// Provides the initial `LastIssuanceTimestamp` for DAP migration.
pub struct DapLastIssuanceTimestamp;
impl frame_support::traits::Get<u64> for DapLastIssuanceTimestamp {
fn get() -> u64 {
pallet_staking_async::ActiveEra::<Runtime>::get()
.and_then(|era| era.start)
.unwrap_or(0)
}
}

/// Default budget: 85% staker rewards, 15% buffer, 0% validator incentive.
///
/// Keys are read from `BudgetRecipients` registered in the runtime config.
pub struct DefaultDapBudget;
impl frame_support::traits::Get<pallet_dap::BudgetAllocationMap> for DefaultDapBudget {
fn get() -> pallet_dap::BudgetAllocationMap {
use sp_runtime::Perbill;
use sp_staking::budget::BudgetRecipientList;

let recipients = <Runtime as pallet_dap::Config>::BudgetRecipients::recipients();
// [dap, StakerRewardRecipient, ValidatorIncentiveRecipient]
let percentages = [Perbill::from_percent(15), Perbill::from_percent(85), Perbill::zero()];

let mut map = pallet_dap::BudgetAllocationMap::new();
for ((key, _), perbill) in recipients.into_iter().zip(percentages) {
let _ = map.try_insert(key, perbill);
}
map
}
}

/// Migrations to apply on runtime upgrade.
pub type Migrations = (
// v9420
Expand Down Expand Up @@ -1620,6 +1651,8 @@ pub type Migrations = (
// permanent
pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
cumulus_pallet_aura_ext::migration::MigrateV0ToV1<Runtime>,
// unreleased
pallet_dap::migrations::MigrateV1ToV2<Runtime, DapLastIssuanceTimestamp, DefaultDapBudget>,
);

/// Asset Hub Westend has some undecodable storage, delete it.
Expand Down Expand Up @@ -2899,6 +2932,19 @@ fn ensure_key_ss58() {
assert_eq!(acc, RootMigController::sorted_members()[0]);
}

#[test]
fn issuance_cadence_smaller_than_era_length() {
use crate::staking::{RelaySessionDuration, SessionsPerEra};
let era_length_ms = SessionsPerEra::get() as u64 *
RelaySessionDuration::get() as u64 *
RELAY_CHAIN_SLOT_DURATION_MILLIS as u64;
let cadence = <Runtime as pallet_dap::Config>::IssuanceCadence::get();
assert!(
cadence < era_length_ms,
"IssuanceCadence ({cadence}ms) must be smaller than era length ({era_length_ms}ms)"
);
}

#[test]
fn ensure_epmb_weights_sane() {
use sp_io::TestExternalities;
Expand Down
60 changes: 34 additions & 26 deletions cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,29 +228,20 @@ impl pallet_bags_list::Config<VoterBagsListInstance> for Runtime {
type WeightInfo = weights::pallet_bags_list::WeightInfo<Runtime>;
}

pub struct EraPayout;
impl pallet_staking_async::EraPayout<Balance> for EraPayout {
fn era_payout(
_total_staked: Balance,
_total_issuance: Balance,
era_duration_millis: u64,
) -> (Balance, Balance) {
pub struct PolkadotIssuanceCurve;
impl sp_staking::budget::IssuanceCurve<Balance> for PolkadotIssuanceCurve {
fn issue(_total_issuance: Balance, elapsed_millis: u64) -> Balance {
const MILLISECONDS_PER_YEAR: u64 = (1000 * 3600 * 24 * 36525) / 100;
// A normal-sized era will have 1 / 365.25 here:
let relative_era_len =
FixedU128::from_rational(era_duration_millis.into(), MILLISECONDS_PER_YEAR.into());
let relative_period =
FixedU128::from_rational(elapsed_millis.into(), MILLISECONDS_PER_YEAR.into());

// Fixed total TI that we use as baseline for the issuance.
let fixed_total_issuance: i128 = 5_216_342_402_773_185_773;
let fixed_inflation_rate = FixedU128::from_rational(8, 100);
let yearly_emission = fixed_inflation_rate.saturating_mul_int(fixed_total_issuance);

let era_emission = relative_era_len.saturating_mul_int(yearly_emission);
// 15% to treasury, as per Polkadot ref 1139.
let to_treasury = FixedU128::from_rational(15, 100).saturating_mul_int(era_emission);
let to_stakers = era_emission.saturating_sub(to_treasury);

(to_stakers.saturated_into(), to_treasury.saturated_into())
let period_emission = relative_period.saturating_mul_int(yearly_emission);
period_emission.saturated_into()
}
}

Expand All @@ -268,8 +259,8 @@ parameter_types! {
pub const MaxControllersInDeprecationBatch: u32 = 751;
// alias for 16, which is the max nominations per nominator in the runtime.
pub const MaxNominations: u32 = <NposCompactSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
pub const MaxEraDuration: u64 = RelaySessionDuration::get() as u64 * RELAY_CHAIN_SLOT_DURATION_MILLIS as u64 * SessionsPerEra::get() as u64;
pub MaxPruningItems: u32 = 100;
pub const StakingPalletId: PalletId = PalletId(*b"py/stkng");
}

impl pallet_staking_async::Config for Runtime {
Expand All @@ -281,13 +272,15 @@ impl pallet_staking_async::Config for Runtime {
type CurrencyToVote = sp_staking::currency_to_vote::SaturatingCurrencyToVote;
type RewardRemainder = Dap;
type Slash = Dap;
type UnclaimedRewardHandler = Dap;
type Reward = ();
type GeneralPots = pallet_staking_async::Seed<StakingPalletId>;
type EraPots = pallet_staking_async::Seed<StakingPalletId>;
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
type NominatorFastUnbondDuration = NominatorFastUnbondDuration;
type SlashDeferDuration = SlashDeferDuration;
type AdminOrigin = EitherOf<EnsureRoot<AccountId>, StakingAdmin>;
type EraPayout = EraPayout;
type MaxExposurePageSize = MaxExposurePageSize;
type ElectionProvider = MultiBlockElection;
type VoterList = VoterList;
Expand All @@ -300,8 +293,15 @@ impl pallet_staking_async::Config for Runtime {
type EventListeners = (NominationPools, DelegatedStaking);
type PlanningEraOffset = ConstU32<6>;
type RcClientInterface = StakingRcClient;
type MaxEraDuration = MaxEraDuration;
type MaxPruningItems = MaxPruningItems;
type StakerRewardCalculator =
pallet_staking_async::reward::DefaultStakerRewardCalculator<Runtime>;
/// Vest validator incentive rewards over 2 days (in relay chain blocks).
type VestingDuration = ConstU32<{ 2 * RC_DAYS }>;
/// Relay chain session length in RC blocks (1 hour on Westend).
type BlocksPerSession = ConstU32<RC_HOURS>;
type ValidatorIncentivePayout =
pallet_staking_async::VestedIncentivePayout<pallet_vesting::Pallet<Runtime>>;
type WeightInfo = weights::pallet_staking_async::WeightInfo<Runtime>;
}

Expand Down Expand Up @@ -344,22 +344,30 @@ impl pallet_staking_async_rc_client::Config for Runtime {

parameter_types! {
pub const DapPalletId: frame_support::PalletId = frame_support::PalletId(*b"dap/buff");
/// Minimum time (ms) between issuance drips. 60s = drip at most once per minute.
/// Drip inflation every 60 seconds. Must be smaller than era length.
/// When adding DAP to other runtimes, copy the `issuance_cadence_smaller_than_era_length`
/// test from this runtime.
pub const IssuanceCadence: u64 = 60_000;
/// Safety ceiling (ms) for elapsed time in a single drip. Prevents over-minting after stalls.
/// Safety ceiling on elapsed time per drip: 10 minutes.
/// Prevents over-minting if blocks are delayed or chain stalls.
pub const MaxElapsedPerDrip: u64 = 600_000;
}

impl pallet_dap::Config for Runtime {
type Currency = Balances;
type PalletId = DapPalletId;
/// Noop — DAP does not mint until budget drip is enabled.
type IssuanceCurve = ();
type BudgetRecipients = (pallet_dap::Pallet<Runtime>,);
type Time = pallet_timestamp::Pallet<Runtime>;
type IssuanceCurve = PolkadotIssuanceCurve;
type BudgetRecipients = (
Dap,
pallet_staking_async::StakerRewardRecipient<pallet_staking_async::Seed<StakingPalletId>>,
pallet_staking_async::ValidatorIncentiveRecipient<
pallet_staking_async::Seed<StakingPalletId>,
>,
);
type Time = Timestamp;
type IssuanceCadence = IssuanceCadence;
type MaxElapsedPerDrip = MaxElapsedPerDrip;
type BudgetOrigin = frame_system::EnsureRoot<AccountId>;
type BudgetOrigin = EnsureRoot<AccountId>;
type WeightInfo = ();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,14 @@ impl<T: frame_system::Config> pallet_staking_async::WeightInfo for WeightInfo<T>
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(1))
}
fn set_max_commission() -> Weight {
// TODO(ank4n): Run benchmarks
todo!()
}
fn set_validator_self_stake_incentive_config() -> Weight {
// TODO(ank4n): Run benchmarks
todo!()
}
/// Storage: `System::Account` (r:1 w:0)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Staking::VirtualStakers` (r:1 w:0)
Expand Down
2 changes: 1 addition & 1 deletion polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ impl pallet_bags_list::Config<VoterBagsListInstance> for Runtime {
}

pub struct EraPayout;
impl pallet_staking::EraPayout<Balance> for EraPayout {
impl sp_staking::EraPayout<Balance> for EraPayout {
fn era_payout(
_total_staked: Balance,
_total_issuance: Balance,
Expand Down
2 changes: 1 addition & 1 deletion polkadot/runtime/westend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ use frame_support::{
WhitelistedStorageKeys,
},
};
use pallet_staking::EraPayout;
use sp_core::{crypto::Ss58Codec, hexdisplay::HexDisplay};
use sp_keyring::Sr25519Keyring::{self, Alice};
use sp_runtime::generic::Era;
use sp_staking::EraPayout;
use xcm_runtime_apis::conversions::LocationToAccountHelper;

const MILLISECONDS_PER_HOUR: u64 = 60 * 60 * 1000;
Expand Down
52 changes: 52 additions & 0 deletions prdoc/pr_10844.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
title: "Move era reward minting to DAP with era-based allocation in Staking"
doc:
- audience: Runtime Dev
description: |-
Rewires staking reward minting by introducing DAP as the central inflation engine.

**DAP (`pallet-dap`)**: Becomes a generic inflation drip and distribution engine. Inflation
is minted per-block (configurable cadence) via `InflationCurve` and distributed across
registered `BudgetRecipient` implementors through a governance-updatable `BudgetAllocation`
map. New budget categories can be added without changing DAP code.

**Staking (`pallet-staking-async`)**: At era boundaries, staking snapshots accumulated
reward pots (filled continuously by DAP) into era-specific accounts. Adds a validator
self-stake incentive: a sqrt-based weight function rewards validators for increasing their
own stake with governance-configurable thresholds (`OptimumSelfStake`, `HardCapSelfStake`,
`SelfStakeSlopeFactor`). Payouts can be immediate or vested via `ValidatorIncentivePayout`.

**Incentive vesting batch conversion**: To avoid exhausting `MaxVestingSchedules` (typically
28), validator incentive rewards are accumulated under a `HoldReason::IncentiveVesting` hold
and batch-converted to a vesting schedule every `BondingDuration` eras. At conversion, a
retroactive unlock fraction (`BondingDuration / vesting_eras`) is released as liquid,
and the remainder is vested over the remaining duration, where
`vesting_eras = VestingDuration / (BlocksPerSession * SessionsPerEra)`. New config type
`BlocksPerSession` (in relay chain blocks) is required alongside `VestingDuration`.

**Primitives (`sp-staking`)**: New traits -- `InflationCurve`, `BudgetRecipient`,
`UnclaimedRewardSink`, `StakerRewardCalculator`.

crates:
- name: pallet-dap
bump: major
- name: pallet-staking-async
bump: major
- name: sp-staking
bump: major
- name: pallet-nomination-pools
bump: patch
- name: pallet-nomination-pools-benchmarking
bump: patch
- name: pallet-nomination-pools-test-delegate-stake
bump: patch
validate: false
- name: frame-support
bump: minor
- name: pallet-staking
bump: patch
- name: pallet-vesting
bump: minor
- name: westend-runtime
bump: patch
- name: asset-hub-westend-runtime
bump: patch
2 changes: 1 addition & 1 deletion substrate/frame/dap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub mod pallet {
use frame_system::pallet_prelude::*;

/// The in-code storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
Expand Down
19 changes: 5 additions & 14 deletions substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,6 @@ pallet_staking_reward_curve::build! {
parameter_types! {
pub const RewardCurve: &'static sp_runtime::curve::PiecewiseLinear<'static> = &I_NPOS;
pub static BondingDuration: u32 = 3;
pub static EraPayout: (Balance, Balance) = (1000, 100);
}

/// A simple EraPayout implementation for testing that returns fixed values.
pub struct TestEraPayout;
impl pallet_staking_async::EraPayout<Balance> for TestEraPayout {
fn era_payout(
_total_staked: Balance,
_total_issuance: Balance,
_era_duration_millis: u64,
) -> (Balance, Balance) {
EraPayout::get()
}
}

/// A mock RcClientInterface for tests that don't need actual session/validator set management.
Expand All @@ -126,13 +113,17 @@ impl pallet_staking_async::Config for Runtime {
type Currency = Balances;
type AdminOrigin = frame_system::EnsureRoot<Self::AccountId>;
type BondingDuration = BondingDuration;
type EraPayout = TestEraPayout;
type ElectionProvider =
frame_election_provider_support::NoElection<(AccountId, BlockNumber, Staking, (), ())>;
type VoterList = VoterList;
type TargetList = pallet_staking_async::UseValidatorsMap<Self>;
type EventListeners = (Pools, DelegatedStaking);
type RcClientInterface = MockRcClient;
type VestingDuration = ConstU64<0>;
type BlocksPerSession = ConstU64<1>;
type ValidatorIncentivePayout = pallet_staking_async::ImmediateIncentivePayout<Balances>;
type StakerRewardCalculator =
pallet_staking_async::reward::DefaultStakerRewardCalculator<Runtime>;
}

parameter_types! {
Expand Down
5 changes: 5 additions & 0 deletions substrate/frame/staking-async/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rand_chacha = { workspace = true }
scale-info = { features = ["derive", "serde"], workspace = true }
serde = { features = ["alloc", "derive"], workspace = true }
sp-application-crypto = { features = ["serde"], workspace = true }
sp-arithmetic = { workspace = true }
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-npos-elections = { workspace = true }
Expand All @@ -42,6 +43,7 @@ frame-benchmarking = { workspace = true, default-features = true }
frame-support = { features = ["experimental"], workspace = true, default-features = true }
pallet-bags-list = { workspace = true, default-features = true }
pallet-balances = { workspace = true, default-features = true }
pallet-dap = { workspace = true, default-features = true }
rand_chacha = { workspace = true, default-features = true }
sp-tracing = { workspace = true, default-features = true }
substrate-test-utils = { workspace = true }
Expand All @@ -64,6 +66,7 @@ std = [
"scale-info/std",
"serde/std",
"sp-application-crypto/std",
"sp-arithmetic/std",
"sp-core/std",
"sp-core/std",
"sp-io/std",
Expand All @@ -79,6 +82,7 @@ runtime-benchmarks = [
"frame-system/runtime-benchmarks",
"pallet-bags-list/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-dap/runtime-benchmarks",
"pallet-staking-async-rc-client/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"sp-staking/runtime-benchmarks",
Expand All @@ -89,6 +93,7 @@ try-runtime = [
"frame-system/try-runtime",
"pallet-bags-list/try-runtime",
"pallet-balances/try-runtime",
"pallet-dap/try-runtime",
"pallet-staking-async-rc-client/try-runtime",
"sp-runtime/try-runtime",
]
Loading
Loading