Skip to content
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] Currency <> Fungible migration #5501

Merged
merged 200 commits into from
Jan 16, 2025

Conversation

Ank4n
Copy link
Contributor

@Ank4n Ank4n commented Aug 27, 2024

Migrate staking currency from traits::LockableCurrency to traits::fungible::holds.

Resolves part of #226.

Changes

Nomination Pool

TransferStake is now incompatible with fungible migration as old pools were not meant to have additional ED. Since they are anyways deprecated, removed its usage from all test runtimes.

Staking

  • Config: Currency becomes of type Fungible while OldCurrency is the LockableCurrency used before.
  • Lazy migration of accounts. Any ledger update will create a new hold with no extra reads/writes. A permissionless extrinsic migrate_currency() releases the old lock along with some housekeeping.
  • Staking now requires ED to be left free. It also adds no consumer to staking accounts.
  • If hold cannot be applied to all stake, the un-holdable part is force withdrawn from the ledger.

Delegated Staking

The pallet does not add provider for agents anymore.

Migration stats

Polkadot

Total accounts that can be migrated: 59564
Accounts failing to migrate: 0
Accounts with stake force withdrawn greater than ED: 59
Total force withdrawal: 29591.26 DOT

Kusama

Total accounts that can be migrated: 26311
Accounts failing to migrate: 0
Accounts with stake force withdrawn greater than ED: 48
Total force withdrawal: 1036.05 KSM

Full logs here.

Note about locks (freeze) vs holds

With locks or freezes, staking could use total balance of an account. But with holds, the account needs to be left with at least Existential Deposit in free balance. This would also affect nomination pools which till now has been able to stake all funds contributed to it. An alternate version of this PR is #5658 where staking pallet does not add any provider, but means pools and delegated-staking pallet has to provide for these accounts and makes the end to end logic (of provider and consumer ref) lot less intuitive and prone to bug.

This PR now introduces requirement for stakers to maintain ED in their free balance. This helps with removing the bug prone incrementing and decrementing of consumers and providers.

TODO

  • Test: Vesting + governance locked funds can be staked.
  • can Call::restore_ledger be removed? @gpestana
  • Ensure unclaimed withdrawals is not affected by no provider for pool accounts.
  • Investigate kusama accounts with balance between 0 and ED.
  • Permissionless call to release lock.
  • Migration of consumer (dec) and provider (inc) for direct stakers.
  • force unstake if hold cannot be applied to all stake.
  • Fix try state checks (it thinks nothing is staked for unmigrated ledgers).
  • Bench migrate_currency.
  • Virtual Staker migration test.
  • Ensure total issuance is upto date when minting rewards.

Followup

@Ank4n Ank4n changed the base branch from master to ankan/staking-migrate-currency-to-fungible August 27, 2024 12:20
Copy link
Contributor

@muharem muharem left a comment

Choose a reason for hiding this comment

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

Looks good to me. But consider this approve as from someone who is not an expert in the staking topic

impl DelegationInterface for DelegateMock {
type Balance = Balance;
type AccountId = AccountId;
fn agent_balance(agent: Agent<Self::AccountId>) -> Option<Self::Balance> {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is basically the "staked, and active in staking (minus pending slash)" balance?

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

@@ -1331,11 +1344,12 @@ fn disable_pool_operations_on_non_migrated() {
assert_ok!(Pools::migrate_pool_to_delegate_stake(RuntimeOrigin::signed(10), 1));
assert_eq!(
Copy link
Contributor

Choose a reason for hiding this comment

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

This file had really good tests, I learned a lot by reading them!

@kianenigma
Copy link
Contributor

kianenigma commented Jan 10, 2025

PR is in good shape, and thanks to incremental code, the changes are easy to digest, good work!

@Ank4n
Copy link
Contributor Author

Ank4n commented Jan 13, 2025

About the amounts of force_withdraw: Ideally we need to check the status of the old corrupt ledgers, and make sure they are eliminated before this. As @muharem said, with 59 accounts, I would expect 59*ED to be force removed from staking. Update: the 12k account is indeed one that is still in a corrupt state and we will try to force_unstake it fully in the next runtime upgrade: polkadot-fellows/runtimes#527 (comment)

There are probably more accounts that are affected. 59 is the count of accounts that had more than ED withdrawn from them.

We need to add a guide for wallets to this, explaining how they should adapt to this. For directs stakers, it is likely not a big deal as they are likely reading the ledger.total, and not inspecting STAKING_LOCK anymore. For pools, it will be substantial.

There are runtime apis to query pool and member balance. How should we promote it?

@Ank4n Ank4n enabled auto-merge January 16, 2025 18:20
@paritytech-workflow-stopper
Copy link

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/12815031300
Failed job name: test-linux-stable

@Ank4n Ank4n added this pull request to the merge queue Jan 16, 2025
auto-merge was automatically disabled January 16, 2025 19:45

Pull Request is not mergeable

Merged via the queue into master with commit f5673cf Jan 16, 2025
186 of 204 checks passed
@Ank4n Ank4n deleted the ankan/staking-migrate-currency-to-fungible-2 branch January 16, 2025 20:16
pepoviola added a commit that referenced this pull request Jan 20, 2025
Nathy-bajo pushed a commit to Nathy-bajo/polkadot-sdk that referenced this pull request Jan 21, 2025
Migrate staking currency from `traits::LockableCurrency` to
`traits::fungible::holds`.

Resolves part of paritytech#226.

## Changes
### Nomination Pool
TransferStake is now incompatible with fungible migration as old pools
were not meant to have additional ED. Since they are anyways deprecated,
removed its usage from all test runtimes.

### Staking
- Config: `Currency` becomes of type `Fungible` while `OldCurrency` is
the `LockableCurrency` used before.
- Lazy migration of accounts. Any ledger update will create a new hold
with no extra reads/writes. A permissionless extrinsic
`migrate_currency()` releases the old `lock` along with some
housekeeping.
- Staking now requires ED to be left free. It also adds no consumer to
staking accounts.
- If hold cannot be applied to all stake, the un-holdable part is force
withdrawn from the ledger.

### Delegated Staking
The pallet does not add provider for agents anymore.

## Migration stats
### Polkadot
Total accounts that can be migrated: 59564
Accounts failing to migrate: 0
Accounts with stake force withdrawn greater than ED: 59
Total force withdrawal: 29591.26 DOT

### Kusama
Total accounts that can be migrated: 26311
Accounts failing to migrate: 0
Accounts with stake force withdrawn greater than ED: 48
Total force withdrawal: 1036.05 KSM


[Full logs here](https://hackmd.io/@ak0n/BklDuFra0).

## Note about locks (freeze) vs holds
With locks or freezes, staking could use total balance of an account.
But with holds, the account needs to be left with at least Existential
Deposit in free balance. This would also affect nomination pools which
till now has been able to stake all funds contributed to it. An
alternate version of this PR is
paritytech#5658 where staking
pallet does not add any provider, but means pools and delegated-staking
pallet has to provide for these accounts and makes the end to end logic
(of provider and consumer ref) lot less intuitive and prone to bug.

This PR now introduces requirement for stakers to maintain ED in their
free balance. This helps with removing the bug prone incrementing and
decrementing of consumers and providers.

## TODO
- [x] Test: Vesting + governance locked funds can be staked.
- [ ] can `Call::restore_ledger` be removed? @gpestana 
- [x] Ensure unclaimed withdrawals is not affected by no provider for
pool accounts.
- [x] Investigate kusama accounts with balance between 0 and ED.
- [x] Permissionless call to release lock.
- [x] Migration of consumer (dec) and provider (inc) for direct stakers.
- [x] force unstake if hold cannot be applied to all stake.
- [x] Fix try state checks (it thinks nothing is staked for unmigrated
ledgers).
- [x] Bench `migrate_currency`.
- [x] Virtual Staker migration test.
- [x] Ensure total issuance is upto date when minting rewards.

## Followup
- paritytech#5742

---------

Co-authored-by: command-bot <>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T2-pallets This PR/Issue is related to a particular pallet.
Projects
Status: Done
Status: Scheduled
Development

Successfully merging this pull request may close these issues.

7 participants