Implement RFC #104: Stale Nomination Reward Curve#11961
Open
shawntabrizi wants to merge 15 commits intomasterfrom
Open
Implement RFC #104: Stale Nomination Reward Curve#11961shawntabrizi wants to merge 15 commits intomasterfrom
shawntabrizi wants to merge 15 commits intomasterfrom
Conversation
Replace the hardcoded 10/10 era constants with a `NominationStalenessCurve` trait wired through `Config`. - `LinearStalenessCurve<GracePeriod, DecayPeriod, Floor>` — piecewise-linear decay, fully configurable. - `NoNominationStaleness` — no-op default that preserves pre-staleness behaviour. - `migrations::nomination_staleness::reset_all_nomination_submitted_in` and try-runtime helpers, ready to be wrapped in a versioned migration when production runtimes opt in. Storage version is intentionally not bumped. The mock runtime defaults the curve to disabled (`grace = u32::MAX`) so existing tests are unaffected. 14 new tests cover the curve at boundaries, refresh-trigger semantics (`nominate` resets, `bond_extra`/`chill` do not), snapshot weight reduction, exclusion at floor 0, and the migration helper. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
shawntabrizi
commented
May 1, 2026
| /// Intended to be called from inside a versioned `on_runtime_upgrade` when the | ||
| /// nomination-staleness mechanism is first enabled on a runtime. See the module | ||
| /// docs for context. | ||
| pub fn reset_all_nomination_submitted_in<T: Config>() -> Weight { |
Member
Author
There was a problem hiding this comment.
This migration is only needed if we decide to start all nominators as fresh. Maybe an alternative approach would be to hard code a block number which we treat any block before this as starting at that block number.
Some other tricks like this.
kianenigma
reviewed
May 4, 2026
Contributor
kianenigma
left a comment
There was a problem hiding this comment.
Should be implemented on staking-async pallet, otherwise the structure looks good.
Move `NominationStalenessCurve`, `NoNominationStaleness`, and `LinearStalenessCurve` from `pallet-staking` into `sp-staking` so both `pallet-staking` and `pallet-staking-async` consume the same definitions. Apply the same staleness mechanism to `pallet-staking-async`: - New `Config::NominationStalenessCurve` associated type, defaulting to `NoNominationStaleness` in `TestDefaultConfig`. - Multiplier applied at the snapshot site in `get_npos_voters`. Mirrors the change in `pallet-staking`. - `migrations::nomination_staleness` helpers (`reset_all_nomination_submitted_in` plus try-runtime pre/post helpers), ready to be wrapped in a versioned migration when a runtime opts in. Storage version intentionally not bumped. - Mock wires `LinearStalenessCurve` over mutable `parameter_types!` so individual tests can configure the curve. Defaults disable it (`grace = u32::MAX`). - 14 new tests under `tests::nomination_staleness` mirroring the `pallet-staking` suite. `pallet-staking` and its tests continue to compile and pass (225/225). `pallet-staking-async` tests pass (274/274, +14 from this PR). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Member
Author
|
Added the same changes to staking-async (so now both pallets have these changes), and moved the common traits and impls into |
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Qualify links to `NoNominationStaleness` and `reset_all_nomination_submitted_in` so rustdoc can resolve them from their respective scopes (the Config trait doc and the migrations module doc are both outside the scope where the bare names resolve). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Implements RFC #104: Stale Nomination Reward Curve.
A nominator's voter weight is multiplied by a configurable decay function based on how long it has been since they last called
nominate. The multiplier is applied at the election snapshot input only; reward distribution downstream is unchanged, so a stale nominator's "lost" share of validator rewards naturally flows to that validator's non-stale co-nominators through existing exposure-based payout math.The mechanism is applied to both
pallet-stakingandpallet-staking-async. The shared trait and default impls live insp-stakingso the two pallets consume the same definitions.What's implemented
sp-stakingNominationStalenessCurvetrait.NoNominationStalenessthat preserves pre-staleness behaviour.LinearStalenessCurve<GracePeriod, DecayPeriod, Floor>.pallet-stakingandpallet-staking-asyncEach pallet adds:
Config::NominationStalenessCurveassociated type.TestDefaultConfigdefaults toNoNominationStaleness.submitted_infield onNominationsis now consumed at the election snapshot site (get_npos_voters) to compute the per-voter multiplier.migrations::nomination_staleness::reset_all_nomination_submitted_inplus try-runtime pre/post helpers, ready to be wrapped in a versioned migration when a runtime opts in. Storage version is intentionally not bumped in this PR.LinearStalenessCurveover mutableparameter_types!. Defaults disable the curve (grace = u32::MAX) so existing tests are unaffected.tests::nomination_staleness:nominateresets even with same targets,bond_extradoes not,chillremoves the entry entirely.Test status
pallet-staking: 225/225 tests pass.pallet-staking-async: 274/274 tests pass (+14 from this PR).sp-staking: compiles clean (including under--all-featuresfortry-runtime).Not in this PR
LinearStalenessCurve<28, 140, 0>into Polkadot / Kusama / Westend runtime configs. Production runtimes should opt in once the RFC is approved.OnRuntimeUpgradewrapper around the migration helpers.pallet-nomination-poolsexercising pool-level freshness.Review focus
NominationStalenessCurveandLinearStalenessCurveinsp-staking.get_npos_voters. These are the single points of behavioural change.28 / 140 / 0); see the RFC's Unresolved Questions for context.