polkadot-js / apps

Basic Polkadot/Substrate UI for interacting with a Polkadot and Substrate node. This is the main user-facing application, allowing access to all features available on Substrate chains.
https://dotapps.io
Apache License 2.0
1.75k stars 1.54k forks source link

Feature request: Display information with regard to bags list nomination limits #6918

Open michalisFr opened 2 years ago

michalisFr commented 2 years ago

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:

  1. 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

  2. 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

kianenigma commented 2 years ago
  1. 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

kianenigma commented 2 years ago

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:

  1. count, which has active and waiting sub-components.
  2. stake, which has minimum and threshold sub-components.

With the exception that the validator group has two minimums:

This leaves us with the following 4 boxes to show:

  1. nominator stake: minimum + threshold.
  2. nominator count: active + total.
  3. validator stake: self minimum + total minimum + threshold.
  4. 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:

kianenigma commented 2 years ago

@wirednkod @gilescope any of you interested in this?

wirednkod commented 2 years ago

A 1st draft of how @kianenigma idea could look can be seen below: idea-polkadot-apps

More terminology can be found here

emostov commented 2 years ago

A 1st draft of how @kianenigma idea could look can be seen below: idea-polkadot-apps

More terminology can be found here

Thank you @wirednkod !

Some feedback:

wirednkod commented 2 years ago

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)): Mnified

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

Expanded

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