-
Notifications
You must be signed in to change notification settings - Fork 684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Staking] Approval Stake tracking #443
Comments
Discussed below |
NOT RELEVANT ANYMORE @kianenigma I'm not sure if we need
According to the current logic in the old PR of yours we'll still need to do most of the operations on Staking side, because we need to do things like chill_stash, where we need to know My proposal would be as follows - we use fn validator(who: &AccountId, active: bool); // covers all the cases validating/chilled/nominating while keeping the score in StorageMap, because really we still do most of the operations in Staking, just calling methods on `OnStakerUpdate` interface instead of `bags-list` instance.
fn kill(who: &AccountId); // covers the case when we need to remove the account from the staking system
fn active_stake_increased(who: &AccountId, balance: BalanceOf<Self>); // makes necessary modifications to all relevant entries in the storage map and TargetList
fn active_stake_decreased(who: &AccountId, balance: BalanceOf<Self>)); // makes necessary modifications to all relevant entries in the storage map and TargetList Otherwise if we wanted to take care of all the logic that currently lives in Staking - in
So basically my proposal is to use ApprovalStake as a fairly thin wrapper around |
Additionally, we also need to take care of this: https://github.com/paritytech/substrate/blob/845780086e0ecad3fb334ad6d038c599ba53af54/frame/staking/src/pallet/impls.rs#L863 . |
After discussing this, we've decided to go with the approach where the approval stake tracker (TargetList + storage) is an event listener and so is the VoterList tracker. Most of the tracking logic has to go into the tracker pallet and use StakingInterface to fetch necessary data, like stash balances and Nominations. |
Make sure all the events are fired post-action (if pre-data is needed we pass it as an arg) OnStakingUpdate {
on_update_ledger(who: &AccountId, old_ledger: sp_staking::Stake...);
on_nominator_add(who: &AccountId, old_nominations: Vec<AccountId>);
on_validator_add(who: &AccountId);
on_validator_remove(who: &AccountId); // only fire this event when this is an actual Validator
on_nominator_remove(who: &AccountId, nominations: Vec<AccountId>); // only fire this if this is an actual Nominator
on_reaped(who: &AccountId); -> basically `kill_stash`
} |
As a temp solution we only take care of TargetList which is not actually used, while maintaining the VoterList logic. This will duplicate the logic for now, but that's fine for testing. (Basically we'll have a set of the same rules within the eventListener and in Staking). So the first iteration: |
This PR refactors the staking ledger logic to encapsulate all reads and mutations of `Ledger`, `Bonded`, `Payee` and stake locks within the `StakingLedger` struct implementation. With these changes, all the reads and mutations to the `Ledger`, `Payee` and `Bonded` storage map should be done through the methods exposed by StakingLedger to ensure the data and lock consistency of the operations. The new introduced methods that mutate and read Ledger are: - `ledger.update()`: inserts/updates a staking ledger in storage; updates staking locks accordingly (and ledger.bond(), which is synthatic sugar for ledger.update()) - `ledger.kill()`: removes all Bonded and StakingLedger related data for a given ledger; updates staking locks accordingly; `StakingLedger::get(account)`: queries both the `Bonded` and `Ledger` storages and returns a `Option<StakingLedger>`. The pallet impl exposes fn ledger(account) as synthatic sugar for `StakingLedger::get(account)`. Retrieving a ledger with `StakingLedger::get()` can be done by providing either a stash or controller account. The input must be wrapped in a `StakingAccount` variant (Stash or Controller) which is treated accordingly. This simplifies the caller API but will eventually be deprecated once we completely get rid of the controller account in staking. However, this refactor will help with the work necessary when completely removing the controller. Other goals: - No logical changes have been introduced in this PR; - No breaking changes or updates in wallets required; - No new storage items or need to perform storage migrations; - Centralise the changes to bonds and ledger updates to simplify the OnStakingUpdate updates to the target list (related to #443) Note: it would be great to prevent or at least raise a warning if `Ledger<T>`, `Payee<T>` and `Bonded<T>` storage types are accessed outside the `StakingLedger` implementation. This PR should not get blocked by that feature, but there's a tracking issue here #149 Related and step towards #443
This PR refactors the staking ledger logic to encapsulate all reads and mutations of `Ledger`, `Bonded`, `Payee` and stake locks within the `StakingLedger` struct implementation. With these changes, all the reads and mutations to the `Ledger`, `Payee` and `Bonded` storage map should be done through the methods exposed by StakingLedger to ensure the data and lock consistency of the operations. The new introduced methods that mutate and read Ledger are: - `ledger.update()`: inserts/updates a staking ledger in storage; updates staking locks accordingly (and ledger.bond(), which is synthatic sugar for ledger.update()) - `ledger.kill()`: removes all Bonded and StakingLedger related data for a given ledger; updates staking locks accordingly; `StakingLedger::get(account)`: queries both the `Bonded` and `Ledger` storages and returns a `Option<StakingLedger>`. The pallet impl exposes fn ledger(account) as synthatic sugar for `StakingLedger::get(account)`. Retrieving a ledger with `StakingLedger::get()` can be done by providing either a stash or controller account. The input must be wrapped in a `StakingAccount` variant (Stash or Controller) which is treated accordingly. This simplifies the caller API but will eventually be deprecated once we completely get rid of the controller account in staking. However, this refactor will help with the work necessary when completely removing the controller. Other goals: - No logical changes have been introduced in this PR; - No breaking changes or updates in wallets required; - No new storage items or need to perform storage migrations; - Centralise the changes to bonds and ledger updates to simplify the OnStakingUpdate updates to the target list (related to paritytech#443) Note: it would be great to prevent or at least raise a warning if `Ledger<T>`, `Payee<T>` and `Bonded<T>` storage types are accessed outside the `StakingLedger` implementation. This PR should not get blocked by that feature, but there's a tracking issue here paritytech#149 Related and step towards paritytech#443
This is basically a redesign and revival of the original PR: paritytech/substrate#11013 .
The first part is done here: paritytech/substrate#12034 and merely introduces a TargetList without any significant logic changes.
The work on the second part is done here: paritytech/substrate#12744
After discussing this with @kianenigma we decided to take a slightly different approach than in the original PR. The approach is different in that instead of keeping all of the potential validators in the TargetList with their score up-to-date, which among other things introduces:
The solution:
We need to introduce another pallet, let's call it
pallet-stake-tracker
. The pallet will be passed two instances ofbags-list
that would serve as aTargetList
andVoterList
and expose an interface forpallet-staking
to interact with.How this works:
Interface:
Storage Map
Keeps track of participant's approval stake
TargetList
One valid approach is to have an instance of
bags-list
that is being passed topallet-approval-stake
, what we currently callTargetList
. Have thepallet-approval-stake
be a score provider for it via aforementionedStorage Map
.SortedListProvider
Implement a
SortedListProvider
interface forpallet-approval-stake
to expose the underlyingTargetList
andVoterList
topallet-staking
. The idea behind this is we want to make sure that theTargetList
is updated only bypallet-approval-stake
and exposed in a read-only format topallet-staking
. This is going to be achieved by making sure that most of the methods exposed bySortedListProvider
are going to be a noop inpallet-approval-stake
implementation.Config examples
pallet-approval-stake:
pallet-staking:
The text was updated successfully, but these errors were encountered: