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

make the thresholds between unsorted bags adjustable #9230

Conversation

coriolinus
Copy link
Contributor

@coriolinus coriolinus commented Jun 29, 2021

Adjustable thresholds make it possible to increase specificity in the event that a particular bag is overfilled. "Overfull" is a social construct, not a technical one.

Adds to #9081.

@github-actions github-actions bot added the A3-in_progress Pull request is in progress. No review needed at this stage. label Jun 29, 2021
@kianenigma
Copy link
Contributor

On this occasion only, I think it is more clear if you directly add this stuff to the base PR, not a new one.

@coriolinus
Copy link
Contributor Author

On this occasion only, I think it is more clear if you directly add this stuff to the base PR, not a new one.

I separated it because I'm not yet happy with the abstraction I introduced. As mentioned above, right now bag split/merge operations are inefficient, which implies that more design is necessary. Once I have this in a place where I'm happy with the bag fundamentals, I'm going to merge it into the base PR, to be reviewed / merged into master in one go.

This reorganizes bag storage such that bags are always referred to
by their upper threshold. This in turn means that adding and removing
bags is cheaper; you only need to migrate certain voters, not all of them.
The macro approach seems to be a non-starter; that only really works
if we're throwing around numeric literals everywhere, and that's just
not nice in this case.

Instead, let's write helper functions and make it really easy to
generate the tables in separate, permanent files, which humans
can then edit.
This isn't yet done, becuase it seems to take a Very Long Time to run,
and it really shouldn't. Need to look into that.

Still, it's a lot closer than it was this morning.
Turns out that when you're working in exponential space, you need
to divide, not subtract, in order to keep the math working properly.

Also neaten up the output a little bit to make it easier to read.
@coriolinus
Copy link
Contributor Author

I'm now happy with the abstractions we have here. I'm going to self-review it one more time, then merge it into the other PR for external review in that context.

frame/staking/src/mock.rs Outdated Show resolved Hide resolved
@coriolinus coriolinus marked this pull request as ready for review July 5, 2021 12:30
@github-actions github-actions bot added A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Jul 5, 2021
@coriolinus coriolinus added A3-in_progress Pull request is in progress. No review needed at this stage. and removed A0-please_review Pull request needs code review. labels Jul 5, 2021
@coriolinus coriolinus added 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. D5-nicetohaveaudit ⚠️ PR contains trivial changes to logic that should be properly reviewed. A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Jul 5, 2021
@coriolinus
Copy link
Contributor Author

Going to ignore the polkadot companion and benches etc here, because this is not going to be merged into master, but into another PR. That's where those issues will be addressed.

}
}

impl Runtime {
Copy link
Contributor

Choose a reason for hiding this comment

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

placing this here would inevitable mean that you cannot re-use it in polkadot, since we don't have this crate in polkadot. I recommend a simple version that just lives in pallet-staking or sth.

You can address it later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, probably the ideal solution is to move this little helper into its own repo so it can depend on (and produce bag threshold lists for) polkadot, substrate node, etc.

The other option I was considering was to just copy the crate wholesale into polkadot/runtime/common and make appropriate modifications there. It would mean we'd have separate binaries, but it would also mean that each one could be simpler.

///
/// # Expressing the constant
///
/// This constant must be sorted in strictly increasing order. Duplicate items are not
Copy link
Contributor

Choose a reason for hiding this comment

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

both of these can and should be checked in an integrity_test

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, and in fact they are, here.

/// - If `VoterBagThresholds::get().is_empty()`, then all voters are put into the same bag,
/// and iteration is strictly in insertion order.
/// - If `VoterBagThresholds::get().len() == 64`, and the thresholds are determined
/// according to the procedure given above, then the constant ratio is equal to 2.
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this the case? I think there is a missing maximum size of the thresholds that we're making this deduction based of?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, that comment is very slightly inaccurate: it's actually the case that the constant ratio is 2 when there are 65 thresholds.

If you think of it from the other way around, if you wanted to split the u64 space into geometric thresholds as simply as possible, you'd make the thresholds list be (0..64).map(|n| 1 << n).chain(std::iter::once(u64::MAX)). Of course, that ends up being 65 items long. That also assumes that the existential deposit is 1.

We demo that in the list of test thresholds.

);
);

assert!(
Copy link
Contributor

Choose a reason for hiding this comment

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

ahh, it already is :D

@@ -3141,7 +3202,7 @@ impl<T: Config> Pallet<T> {
/// Move a stash account from one bag to another, depositing an event on success.
///
/// If the stash changed bags, returns `Some((from, to))`.
pub fn do_rebag(stash: &T::AccountId) -> Option<(BagIdx, BagIdx)> {
pub fn do_rebag(stash: &T::AccountId) -> Option<(VoteWeight, VoteWeight)> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I can guess that there's no more BagIdx around, and each bag is identified by its lower weight now?

Not a big deal, but FYI this is slightly inefficient for the rebag tx. You would have an easier time submitting two indices than two VoteWeights, but anyways.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Upper weight, but yes, that's fundamentally it. Agree that it's slightly less efficient, but we had to do it like that to make it efficient to change the bags with a change of runtime.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah that's well worth it IMO. re-binary-searching the bags list should not be super time consuming.

Copy link
Contributor

@kianenigma kianenigma left a comment

Choose a reason for hiding this comment

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

Seems like a big change, I prefer reviewing it in the base PR then. Looks in the correct direction!

Copy link
Contributor

@kianenigma kianenigma left a comment

Choose a reason for hiding this comment

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

Seems like a big change, I prefer reviewing it in the base PR then. Looks in the correct direction!

@coriolinus coriolinus merged commit b73fd7f into prgn-nominator-unsorted-bags Jul 5, 2021
@coriolinus coriolinus deleted the prgn-unsorted-bags-adjustable-thresholds branch July 5, 2021 13:25
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. D5-nicetohaveaudit ⚠️ PR contains trivial changes to logic that should be properly reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants