apps
apps copied to clipboard
Feature request: Display information with regard to bags list nomination limits
With the coming of bags list to staking in 0.9160 there are two limits with regard to staking that will be essential for users to see:
-
What is the number of nominators that will be selected from the sorted list to be applied to the election. This number is dynamic and will be:
VoterSnapshotPerBlock - CounterForValidators
VoterSnapshotPerBlock
is the max number of voters, that includes validators, and is currently 22,500 -
Lowest stake in order for your nominations to be applied. It would be the stake of the last account in the ordered list.
Relevant issue for reference: https://github.com/polkadot-js/apps/issues/6460
- Lowest stake in order for your nominations to be applied. It would be the stake of the last account in the ordered list.
This is already displayed in Staking -> Targets -> min-nominated
All in all though, I think the stats
section can use a small revamp.
Let me break it down like this. We have 2 user groups, validators and nominators. Each have 2 variables:
- count, which has active and waiting sub-components.
- stake, which has minimum and threshold sub-components.
With the exception that the validator group has two minimums:
- minimum self-stake among validators
- minimum total stake amount validators
This leaves us with the following 4 boxes to show:
- nominator stake: minimum + threshold.
- nominator count: active + total.
- validator stake: self minimum + total minimum + threshold.
- validator count: active + total.
This is how you calculate all of the 4 bits of information needed here:
const b = (x: BN): string => api.createType('Balance', x).toHuman()
// a map from all nominators to their total stake.
const assignments: Map<AccountId32, BN> = new Map();
const currentEra = (await api.query.staking.currentEra()).unwrap();
const stakers = await api.query.staking.erasStakers.entries(currentEra);
stakers.map((x) => x[1].others).flat(1).forEach((x) => {
// @ts-ignore
const nominator: AccountId32 = x.who;
// @ts-ignore
const amount: Compact<u128> = x.value;
if (assignments.get(nominator)) {
assignments.set(nominator, amount.toBn().add(assignments.get(nominator)!))
} else {
assignments.set(nominator, amount.toBn())
}
})
// nominator stake
{
const threshold = await api.query.staking.minNominatorBond();
const stakes = Array.from(assignments.values());
stakes.sort((a, b) => a.cmp(b));
const min = stakes[0];
console.log(`nominator stake: threshold: ${b(threshold)} / min: ${b(min)}`)
}
// nominator count
{
const active = Array.from(assignments.keys()).length
const total = await api.query.staking.maxNominatorsCount();
console.log(`nominator count: active: ${active} / total: ${total}`)
}
// validator stake
{
const threshold = await api.query.staking.minValidatorBond();
const stakes = stakers.map((x) => x[1].total.toBn());
stakes.sort((a, b) => a.cmp(b));
const minTotal = stakes[0];
const selfStakes = stakers.map((x) => x[1].own.toBn());
selfStakes.sort((a, b) => a.cmp(b));
const minSelf = selfStakes[0];
console.log(`validator stake: threshold: ${b(threshold)} / minTotal: ${b(minTotal)} / minSelf ${b(minSelf)}`)
}
// validator count
{
const total = await api.query.staking.maxValidatorsCount();
console.log(`validator count: active: ${stakers.length} / total: ${total}`)
}
So, these are 4 boxes, each containing a pair of information, and they should go in the header of the "Staking -> Overview" page, in a separate row.
Once we have this, we can get rid of the following:
- "Staking -> Overview" has
validators
andwaiting
which can now be removed. - "Staking -> Targets" has
min nominated / threshold
which can now be removed.
@wirednkod @gilescope any of you interested in this?
A 1st draft of how @kianenigma idea could look can be seen below:
More terminology can be found here
A 1st draft of how @kianenigma idea could look can be seen below:
More terminology can be found here
Thank you @wirednkod !
Some feedback:
- Ideally for nominator stake threshold we would just display min intention stake and min electing stake. Electing is a bit more expensive to calc because of the bags list queries, but I think its the most useful for determining if a nominator will make it into the snapshot. The active threshold will just be confusing since it should normal equal electing, except for some strange edge cases that shouldn't effect decision making.
- For nominator counts we can similarly have max/current intention and max/current electing, forgoing active since it should equal electing.
- For validators we should display intention/ electable/ active. I am not sure where the current waiting number is coming from in the screenshot. But at the moment count for intention and electable should be the same, while count for active would be fixed at 297. Similarly the min thresholds for waiting and electable would be the same at the moment (until we impl the bags list for validators), while the min thresholds for active would vary after each election
Adding some clarifications prior to start implementing this.
The idea is to have 2 modes of the summary:
a) Minified with the minimum needed information (min active validator (how much stake I need to be an active validator) and min active nominator (how much stake I need to be an active nominator)):
b) An Expanded one with showing all information that will be available on the Overview screen.
NOMINATORS:
count: intention / electing / active max possible: intention / electing / active (stake) min: intention / electing / active
VALIDATORS:
count: intention / electable / active max possible: intention / electable / active (stake) min: intention / electable / active
Tasks will be split in 2 PRs a) Remove all the things that need to be removed, and add the (a) minimum values b) then add the full matrix in Expanded page, but if small parts of it (e.g. min electing nominator stake) are too hard to compute (lazy load)
cc @emostov @kianenigma