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

[Feature] P2 Staking Tracker #12744

Closed
wants to merge 37 commits into from
Closed

Conversation

ruseinov
Copy link
Contributor

@ruseinov ruseinov commented Nov 20, 2022

This is the second of a series of PRs aimed at reviving #11013
Work on: paritytech/polkadot-sdk#443

@ruseinov ruseinov changed the title [Enhancement] P2 Staking Tracker [Feature] P2 Staking Tracker Nov 20, 2022
@ruseinov
Copy link
Contributor Author

bot rebase

@paritytech-processbot
Copy link

Rebased

@ruseinov
Copy link
Contributor Author

bot rebase

@paritytech-processbot
Copy link

Rebased

Cargo.toml Show resolved Hide resolved
@@ -757,6 +765,31 @@ impl pallet_bags_list::Config<VoterBagsListInstance> for Runtime {
type WeightInfo = pallet_bags_list::weights::SubstrateWeight<Runtime>;
}

/// A special VoterList instance used to test the StakeTracker.
Copy link
Contributor

Choose a reason for hiding this comment

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

impl blocks should not be documented. Trait definitions should be. If you want to put some doc here, it should start with //.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just a rough draft so far, I basically put some random docs here in there to define the intention. The documentation will be refined! Thanks for looking into this.

Comment on lines +552 to +553
type VoterList = VoterListTracker;
type TargetList = TargetList;
Copy link
Contributor

Choose a reason for hiding this comment

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

the names in two lines are not consistent -- either both somethingTracker or neither.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea here is that the TargetList is not used in Staking yet, so we can start tracking it in staking-tracker and then passing it to Staking without any migrations.
Since VoterList already exists - I had to add a suffix.

/// Once this becomes the source of truth - we should make sure `TargetList` and `VoterList`
/// are passed to Staking as `ReadOnlySortedListProvider`.
///
/// NOTE: Once we have more implementors of EventListener - this could be done similarly to
Copy link
Contributor

Choose a reason for hiding this comment

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

Good comment educational-wise, but toward the end it should go away IMO. The fact that OnStakingUpdate can be a tuple is abstracted and not something that staking needs to know about. All staking knows is that OnStakingUpdate is something that will notify anyone who's interested in these updates.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess this can stay until we switch staking to the new lists.

@kianenigma
Copy link
Contributor

Here's my brain dump on the migration:

  1. Either do it in one block, but for that you need to provide some stats of how many storage RW you are doing, how much weight, so we have an idea of how much of a slow block it is going to be. You also have to dry-run the migration in WASM to make sure it is fine memory-wise.

  2. Do it over multiple blocks, during which we should freeze any transactions going to staking. Otherwise we need to deal with: what if someone updates their nomination while the initial migration is happening? lots of edge cases here. Perhaps solvable, but I think now allowing staking operations for e.g. 10 blocks is probably fine.

I am inclined to vouch for doing option 1, but as of recently, we lifted the Polkadot max nomination intention limit, so someone can attack this migration. We should, unfortunately, but maturely, opt for option 2.

Perhaps the concurrency issues are not too hard and we can do it in a easy-going manner on-idle.

@ruseinov
Copy link
Contributor Author

ruseinov commented Jan 4, 2023

bot rebase

@paritytech-processbot
Copy link

Error: Command 'Command { std: "git" "merge" "origin/master" "--no-ff" "--no-edit", kill_on_drop: false }' failed with status Some(1); output: no output


// This will panic if the validator is not in the map, but this should never happen!
ApprovalStake::<T>::mutate(who, |x: &mut Option<BalanceOf<T>>| {
x.map(|b| b.saturating_sub(Self::slashable_balance_of(who)))
Copy link
Contributor

Choose a reason for hiding this comment

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

mutate expects you to mutate x. what you are doing here is returning some value from the closure, which will not update x at all. If you had at least one test, this would have been caught by now ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah yeah, it should assign to *x.

let _ = T::VoterList::on_remove(who).defensive();
for validator in nominations {
ApprovalStake::<T>::mutate(&validator, |x: &mut Option<BalanceOf<T>>| {
x.map(|b| b.saturating_sub(score))
Copy link
Contributor

Choose a reason for hiding this comment

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

same.

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.

I think this PR is moving slower than I expected, and I anticipate it could still be due to its large size.

If you want, we can split it even further:

Part 1

  • Add EventListeners to staking, and have stake-tracker only track changes to VotersList to EventListeners instead.
  • By that, I mean we would replace a few calls to T::VotersList::blah to T::EventListeners::on_blah
  • This should be really straightforward and easy to verify. It won't need a migration either.
  • As the outcome we would see:
impl pallet_staking::Config for Runtime {

    type VoterList = <Runtime as pallet_stake_tracker::Config>::VoterList;
    type TargetList = ValidatorsMap 
  • We can also move some tests around, and make sure the StakingEvents is well tested.

Part 2

Then, importantly, without needing to make any changes to staking, we make pallet-stake-tracker to also track targets. This will need a single migration to initiate the approval stakes.

Staking would still use type TargetList = ValidatorsMap.

We can, again, do a lot of extensive unit tests here to make sure things are right. We can also test this new TargetList instance that is not used anywhere in an offchain bot and make sure all the approval stakes are correct in all blocks.


Part 3

Finally, once enough time has passed and we are sure, we flip to

impl pallet_staking::Config for Runtime {

    type VoterList = <Runtime as pallet_stake_tracker::Config>::VoterList;
    type TargetList = <Runtime as pallet_stake_tracker::Config>::TargetList; 

Ofc you would be working on these in parallel, but I think splitting it further will help us get to some tangible outcome faster, and it will reviews easier.

ruseinov and others added 2 commits January 4, 2023 14:30
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
@paritytech-cicd-pr
Copy link

The CI pipeline was cancelled due to failure one of the required jobs.
Job name: test-linux-stable
Logs: https://gitlab.parity.io/parity/mirrors/substrate/-/jobs/2222619

@kianenigma
Copy link
Contributor

closing as it will be replaced by smaller pieces to keep the projects and PR lists tidy.

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.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants