Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Store validator self-vote in bags-list, and allow them to be trimmed for election #10821

Merged
merged 22 commits into from
Mar 23, 2022

Conversation

kianenigma
Copy link
Contributor

@kianenigma kianenigma commented Feb 8, 2022

Context

Historically, in the staking pallet, we’ve always had the assumption that all validators are implicitly also voting for themselves. We don’t actually make them a nominator though. Instead, once the time for election comes, we inject their self-votes.

In the past, in the days that there wasn’t much pressure on us about how many nominators we can have, we opted for a super simple solution to do this. Namely, when staking wants to create the snapshot of voters, we always first iterate validators and inject their self-vote, and then continue with the actual nominators.

To demonstrate the problem that this causes, consider Polkadot, where around 1k validator candidates exists, around 22k nominators, and the maximum number of voters that we can put in a snapshot is 22,5k.

The issue here is that those 1k validators are essentially filling the first slots of the 22,5k limit, while some random nominators are being left out. This in itself is not an issue. Nomination was never an inclusive operation, and lots of limits are imposed on who can be a nominator. But, the issue here is that those 1k self-votes are not justified to be FIRST in to fill the 22,5k limit. In other words, those 1k validators might have very little amount of self-stake, but a very high amount of self-nomination, and their self-nomination might not be included, while their self-stake is guaranteed to be included.

Solution

Our proposal to solve this issue, and generally both simplify and improve this process is to utilize the bags-list pallet. Currently, bags-list is only tracking the nominator votes. Now, we inject each validator’s self-vote (prospectively) into the bags-list as well. As you see in the PR, this simplifies the code a lot. Moreover, while we still guarantee that all validators (up to the chain limit) can be inlaced in the election, the self-stake of some might be dropped for the election.

In effect this might lead to the new situation where a validator is elected, with a self-stake of 0. In other words, they have some amount bonded (ledger.active), but their self-stake (aka. exposure.own) is 0.


Follow-ups in other PRs, just writing them down as ideas:

  • Make staking tests run with both types of SortedListPorivder and clean the invariant checks.
  • Make on_insert accept a reference.
  • Rename type SortedListProvider to type VoterProvider.

polkadot companion: paritytech/polkadot#5088

@kianenigma kianenigma added A0-please_review Pull request needs code review. B0-silent Changes should not be mentioned in any release notes C1-low PR touches the given topic and has a low impact on builders. D9-needsaudit 👮 PR contains changes to fund-managing logic that should be properly reviewed and externally audited labels Feb 8, 2022
@emostov
Copy link
Contributor

emostov commented Feb 10, 2022

Just noting that in the future if we want to get rid of the nominators map and the validators map, we could instead have the bags list node have a generic field which could be used with some enum like

enum StakerType<T: Config> {
   Nominator { nominations: Nominations<T> },
   Validator { prefs: ValidatorPreferences } 
}

Then, we would only have to worry about updating the bags list and we can create abstractions for reading nominators vs validators from the bags list, which should be efficient because we can just read from the Node storage map

frame/staking/src/tests.rs Outdated Show resolved Hide resolved
assert_eq!(
Staking::voters(Some(3))
Staking::voters(Some(2))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth adding a similar test but instead pass Some(1), resulting in just in no voters taken?

frame/staking/src/tests.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@emostov emostov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm but just want to make sure I understand how this test works before approving: https://github.com/paritytech/substrate/pull/10821/files#r804031477

@miloskriz
Copy link

dear @kianenigma, dear all, hello:

Please consider the following concern that raises as part of the Thousands Validator Programme (TVP):

In the context of this PR is written

But, the issue here is that those 1k self-votes are not justified to be FIRST in to fill the 22,5k limit. In other words, those 1k validators might have very little amount of self-stake, but a very high amount of self-nomination, and their self-nomination might not be included, while their self-stake is guaranteed to be included

However, please note that the above is not true for most of the validators in the TVP and actually, the opposite applies: most of these validators self-stake all of their available balances in their own validator nodes, instead of having separate self-nomination bonds.

The self-stake in Polkadot's TVP participants is certainly not trivial and amounts to more than 5'000 DOTs (and sometimes as high as 10'000 DOTs) which could potentially be excluded from the rewards when the kind W3F/Parity's nominations are received.

Thus, I would appreciate if you could elaborate a bit more on the consequences for the validators in the TVP and if this PR is enacted, whether it will be possible to consider also expanding the rights of the self-stakes to nominate other validators. That way we will really be on a level / fair playground.

Thanks!

@kianenigma
Copy link
Contributor Author

The interpretation is correct: if a validator self-stake is not active, then it does not contribute to their reward.

BUT, and this is a big BUT: it will only be NOT active if it is less than whatever is the minimum nomination threshold.

So, if you want to make sure you earn money from your self stake, called S, you need to make sure that it is more than the min-active-nominator threshold, T. and if S is less than T, with the same justification that a nominator who has less than T does not receive rewards, your self-stake does not generate rewards either, which IMO is totally fair.

So to recap:

However, please note that the above is not true for most of the validators in the TVP and actually, the opposite applies: most of these validators self-stake all of their available balances in their own validator nodes, instead of having separate self-nomination bonds.

As noted, in this case, these stakes WILL be included, as long as they are above the threshold to be an active nominator.

@kianenigma
Copy link
Contributor Author

bot merge

@paritytech-processbot paritytech-processbot bot merged commit 7a09b82 into master Mar 23, 2022
@paritytech-processbot paritytech-processbot bot deleted the kiz-validators-in-bags branch March 23, 2022 14:17
grishasobol pushed a commit to gear-tech/substrate that referenced this pull request Mar 28, 2022
…for election (paritytech#10821)

* Implement the new validator-in-bags-list scenario + migration

* Apply suggestions from code review

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>

* some review comments

* guard the migration

* some review comments

* Fix tests 🤦‍♂️

* Fix build

* fix weight_of_fn

* reformat line width

* make const

* use weight of fn cached

* SortedListProvider -> VoterList

* Fix all build and docs

* check post migration

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>
grishasobol pushed a commit to gear-tech/substrate that referenced this pull request Mar 28, 2022
…for election (paritytech#10821)

* Implement the new validator-in-bags-list scenario + migration

* Apply suggestions from code review

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>

* some review comments

* guard the migration

* some review comments

* Fix tests 🤦‍♂️

* Fix build

* fix weight_of_fn

* reformat line width

* make const

* use weight of fn cached

* SortedListProvider -> VoterList

* Fix all build and docs

* check post migration

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>
grishasobol pushed a commit to gear-tech/substrate that referenced this pull request Mar 28, 2022
…for election (paritytech#10821)

* Implement the new validator-in-bags-list scenario + migration

* Apply suggestions from code review

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>

* some review comments

* guard the migration

* some review comments

* Fix tests 🤦‍♂️

* Fix build

* fix weight_of_fn

* reformat line width

* make const

* use weight of fn cached

* SortedListProvider -> VoterList

* Fix all build and docs

* check post migration

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>
@jakoblell jakoblell added D1-audited 👍 PR contains changes to fund-managing logic that has been properly reviewed and externally audited and removed D9-needsaudit 👮 PR contains changes to fund-managing logic that should be properly reviewed and externally audited labels Apr 20, 2022
DaviRain-Su pushed a commit to octopus-network/substrate that referenced this pull request Aug 23, 2022
…for election (paritytech#10821)

* Implement the new validator-in-bags-list scenario + migration

* Apply suggestions from code review

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>

* some review comments

* guard the migration

* some review comments

* Fix tests 🤦‍♂️

* Fix build

* fix weight_of_fn

* reformat line width

* make const

* use weight of fn cached

* SortedListProvider -> VoterList

* Fix all build and docs

* check post migration

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>
ark0f pushed a commit to gear-tech/substrate that referenced this pull request Feb 27, 2023
…for election (paritytech#10821)

* Implement the new validator-in-bags-list scenario + migration

* Apply suggestions from code review

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>

* some review comments

* guard the migration

* some review comments

* Fix tests 🤦‍♂️

* Fix build

* fix weight_of_fn

* reformat line width

* make const

* use weight of fn cached

* SortedListProvider -> VoterList

* Fix all build and docs

* check post migration

Co-authored-by: Zeke Mostov <z.mostov@gmail.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review. B0-silent Changes should not be mentioned in any release notes C1-low PR touches the given topic and has a low impact on builders. D1-audited 👍 PR contains changes to fund-managing logic that has been properly reviewed and externally audited
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants