improve staking interface methods (#14023)

* improve staking interface methods

* fix

* fix

* fix build

* restart

* fix

---------

Co-authored-by: parity-processbot <>
This commit is contained in:
Kian Paimani
2023-04-27 13:27:12 +02:00
committed by GitHub
parent 31e1329da0
commit 2320bdd388
8 changed files with 99 additions and 24 deletions
+1 -12
View File
@@ -311,6 +311,7 @@ use sp_runtime::{
traits::{AtLeast32BitUnsigned, Convert, Saturating, StaticLookup, Zero},
Perbill, Perquintill, Rounding, RuntimeDebug,
};
pub use sp_staking::StakerStatus;
use sp_staking::{
offence::{Offence, OffenceError, ReportOffence},
EraIndex, SessionIndex,
@@ -381,18 +382,6 @@ impl<AccountId: Ord> Default for EraRewardPoints<AccountId> {
}
}
/// Indicates the initial status of the staker.
#[derive(RuntimeDebug, TypeInfo)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize, Clone))]
pub enum StakerStatus<AccountId> {
/// Chilling.
Idle,
/// Declared desire in validating or already participating in it.
Validator,
/// Nominating for a group of other stakers.
Nominator(Vec<AccountId>),
}
/// A destination account for payment.
#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub enum RewardDestination<AccountId> {
+28 -2
View File
@@ -22,6 +22,7 @@ use frame_election_provider_support::{
SortedListProvider, VoteWeight, VoterOf,
};
use frame_support::{
defensive,
dispatch::WithPostDispatchInfo,
pallet_prelude::*,
traits::{
@@ -1608,7 +1609,7 @@ impl<T: Config> StakingInterface for Pallet<T> {
Self::current_era().unwrap_or(Zero::zero())
}
fn stake(who: &Self::AccountId) -> Result<Stake<Self>, DispatchError> {
fn stake(who: &Self::AccountId) -> Result<Stake<BalanceOf<T>>, DispatchError> {
Self::bonded(who)
.and_then(|c| Self::ledger(c))
.map(|l| Stake { total: l.total, active: l.active })
@@ -1662,8 +1663,33 @@ impl<T: Config> StakingInterface for Pallet<T> {
Self::nominate(RawOrigin::Signed(ctrl).into(), targets)
}
fn status(
who: &Self::AccountId,
) -> Result<sp_staking::StakerStatus<Self::AccountId>, DispatchError> {
let is_bonded = Self::bonded(who).is_some();
if !is_bonded {
return Err(Error::<T>::NotStash.into())
}
let is_validator = Validators::<T>::contains_key(&who);
let is_nominator = Nominators::<T>::get(&who);
use sp_staking::StakerStatus;
match (is_validator, is_nominator.is_some()) {
(false, false) => Ok(StakerStatus::Idle),
(true, false) => Ok(StakerStatus::Validator),
(false, true) => Ok(StakerStatus::Nominator(
is_nominator.expect("is checked above; qed").targets.into_inner(),
)),
(true, true) => {
defensive!("cannot be both validators and nominator");
Err(Error::<T>::BadState.into())
},
}
}
sp_staking::runtime_benchmarks_enabled! {
fn nominations(who: Self::AccountId) -> Option<Vec<T::AccountId>> {
fn nominations(who: &Self::AccountId) -> Option<Vec<T::AccountId>> {
Nominators::<T>::get(who).map(|n| n.targets.into_inner())
}
+23
View File
@@ -5824,4 +5824,27 @@ mod staking_interface {
));
});
}
#[test]
fn status() {
ExtBuilder::default().build_and_execute(|| {
// stash of a validator is identified as a validator
assert_eq!(Staking::status(&11).unwrap(), StakerStatus::Validator);
// .. but not the controller.
assert!(Staking::status(&10).is_err());
// stash of nominator is identified as a nominator
assert_eq!(Staking::status(&101).unwrap(), StakerStatus::Nominator(vec![11, 21]));
// .. but not the controller.
assert!(Staking::status(&100).is_err());
// stash of chilled is identified as a chilled
assert_eq!(Staking::status(&41).unwrap(), StakerStatus::Idle);
// .. but not the controller.
assert!(Staking::status(&40).is_err());
// random other account.
assert!(Staking::status(&42).is_err());
})
}
}