Fixes TotalValueLocked out of sync in nomination pools (#3052)

The `TotalLockedValue` storage value in nomination pools pallet may get
out of sync if the staking pallet does implicit withdrawal of unlocking
chunks belonging to a bonded pool stash. This fix is based on a new
method in the `OnStakingUpdate` traits, `on_withdraw`, which allows the
nomination pools pallet to adjust the `TotalLockedValue` every time
there is an implicit or explicit withdrawal from a bonded pool's stash.

This PR also adds a migration that checks and updates the on-chain TVL
if it got out of sync due to the bug this PR fixes.

**Changes to `trait OnStakingUpdate`**

In order for staking to notify the nomination pools pallet that chunks
where withdrew, we add a new method, `on_withdraw` to the
`OnStakingUpdate` trait. The nomination pools pallet filters the
withdraws that are related to bonded pool accounts and updates the
`TotalValueLocked` accordingly.

**Others**
- Adds try-state checks to the EPM/staking e2e tests
- Adds tests for auto withdrawing in the context of nomination pools

**To-do**
- [x] check if we need a migration to fix the current `TotalValueLocked`
(run try-runtime)
- [x] migrations to fix the current on-chain TVL value 

  **Kusama**:
```
TotalValueLocked: 99.4559 kKSM
TotalValueLocked (calculated) 99.4559 kKSM
```
⚠️ **Westend**:
```
TotalValueLocked: 18.4060 kWND
TotalValueLocked (calculated) 18.4050 kWND
```
**Polkadot**: TVL not released yet.

Closes https://github.com/paritytech/polkadot-sdk/issues/3055

---------

Co-authored-by: command-bot <>
Co-authored-by: Ross Bulat <ross@parity.io>
Co-authored-by: Dónal Murray <donal.murray@parity.io>
This commit is contained in:
Gonçalo Pestana
2024-02-08 19:03:22 +01:00
committed by GitHub
parent c36c51cac3
commit aac07af03c
12 changed files with 383 additions and 74 deletions
+4 -1
View File
@@ -41,7 +41,7 @@ use sp_runtime::{
use sp_staking::{
currency_to_vote::CurrencyToVote,
offence::{DisableStrategy, OffenceDetails, OnOffenceHandler},
EraIndex, Page, SessionIndex, Stake,
EraIndex, OnStakingUpdate, Page, SessionIndex, Stake,
StakingAccount::{self, Controller, Stash},
StakingInterface,
};
@@ -150,6 +150,9 @@ impl<T: Config> Pallet<T> {
// Already checked that this won't overflow by entry condition.
let value = old_total.defensive_saturating_sub(new_total);
Self::deposit_event(Event::<T>::Withdrawn { stash, amount: value });
// notify listeners.
T::EventListeners::on_withdraw(controller, value);
}
Ok(used_weight)
+1 -1
View File
@@ -275,7 +275,7 @@ pub mod pallet {
/// Something that listens to staking updates and performs actions based on the data it
/// receives.
///
/// WARNING: this only reports slashing events for the time being.
/// WARNING: this only reports slashing and withdraw events for the time being.
type EventListeners: sp_staking::OnStakingUpdate<Self::AccountId, BalanceOf<Self>>;
/// Some parameters of the benchmarking.