3

In the docs for CurrencyToVote it says

the total issuance being passed in implies that the implementation must be aware of the fact that its values can affect the outcome. This implies that if the vote value is dependent on the total issuance, it should never be written to storage for later re-use.

And in U128CurrencyToVote (used by Polkadot), balances get divided by how many times the total issuance fits into a u64.

But the BagsList pallet stores these weights here and uses them for ordering. Does this mean that every time the total issuance hits a multiple of u64::MAX, new updates in the list are wildly out of sync with previous inserts (with those previous inserts having a much larger weight)?

It also feels a little silly to use a u64 type for vote weights when the total_issuance in pallet-balances already has to fit into a Balance type which is a u128 for most chains.

1 Answer 1

4

Question:

In the docs for CurrencyToVote it says

the total issuance being passed in implies that the implementation must be aware of the fact that its values can affect the outcome. This implies that if the vote value is dependent on the total issuance, it should never be written to storage for later re-use.

And in U128CurrencyToVote (used by Polkadot), balances get divided by how many times the total issuance fits into a u64.

But the BagsList pallet stores these weights here and uses them for ordering. Does this mean that every time the total issuance hits a multiple of u64::MAX, new updates in the list are wildly out of sync with previous inserts (with those previous inserts having a much larger weight)?

Answer:

Short answer: yes.

When using the bags list as the SortedListProvider for pallet staking, once the total issuance increases over a multiple of u64::MAX, new inserts will be out of sync. In this case rebag should be called on all the nodes already in the list. The rebag extrinsic is permissionless and thus the network can (and is incentivized to) "organically" self adjust.

If one had a chain where they expected the total issuance would cross u64::MAX multiples frequently, this probably would be a suboptimal design choice.

So to remedy the aforementioned issue the bags list could be made more extensible by having a configurable Weight type (probably something that impls PartialOrd). For example if Balance was a u128, the Weight for the bags list could be set to a u128 and then the VoteWeightProvider could be defined to simply return the bonded balance of the account. (PRs welcome!) As far as I know, in the staking use case, the bags list itself doesn't need to use a u64 for ordering weight (someone please correct me if I am wrong). The actual vote weight is calculated on the spot when collecting the voters (see pallet_staking::Pallet::get_npos_voters).

Question:

It also feels a little silly to use a u64 type for vote weights when the total_issuance in pallet-balances already has to fit into a Balance type which is a u128 for most chains.

Answer:

Looking at the pallet_staking::Config::CurrencyToVote docs we see:

Convert a balance into a number used for election calculation. This must fit into a u64 but is allowed to be sensibly lossy. The u64 is used to communicate with the frame_election_provider_support crate which accepts u64 numbers and does operations in 128.

This is hinting that the election algorithmns need a type which can be extended to avoid overflowing arithmetic. And it does have one: ExtendedBalance, a u128. Tangential, in theory one could use a u128 for vote weight and a u256 for the arithmetic, but a u256 is not supported in rust and presumably other impls would have some negative performance consequences.

1
  • Thanks for the answer! I'd be curious what stuff the election calculation does that could lead to needing a value larger than the currency's total_issuance (and thus not being guaranteed to fit into the Balance type). Time to dig through some code!
    – Willter
    Feb 23, 2022 at 22:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.