-
Notifications
You must be signed in to change notification settings - Fork 645
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
Reap pool member whose balance goes below ED #5769
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2995,6 +2995,41 @@ | |
Ok(Pays::No.into()) | ||
} | ||
|
||
/// Remove the member if stake falls below the existential deposit. | ||
#[pallet::call_index(26)] | ||
// FIXME weight functions | ||
#[pallet::weight(T::WeightInfo::reap_member_below_ed())] | ||
pub fn reap_member_below_ed( | ||
origin: OriginFor<T>, | ||
member_account: AccountIdLookupOf<T>, | ||
num_slashing_spans: u32, | ||
) -> DispatchResult { | ||
let _ = ensure_signed(origin)?; | ||
let account = T::Lookup::lookup(member_account)?; | ||
let member = PoolMembers::<T>::get(&account).ok_or(Error::<T>::PoolMemberNotFound)?; | ||
let bonded_pool = BondedPool::<T>::get(member.pool_id) | ||
.defensive_ok_or::<Error<T>>(DefensiveError::PoolNotFound.into())?; | ||
let sub_pools = SubPoolsStorage::<T>::get(member.pool_id).ok_or(Error::<T>::SubPoolsNotFound)?; | ||
|
||
let balance = member.total_balance(); | ||
let ed = T::Currency::minimum_balance(); | ||
|
||
// FIXME is weight info needed in return? | ||
if balance < ed { | ||
Self::do_reap_member(account.clone(), &member, &bonded_pool, num_slashing_spans); | ||
|
||
if account == bonded_pool.roles.depositor { | ||
Pallet::<T>::dissolve_pool(bonded_pool); | ||
} else { | ||
bonded_pool.dec_members().put(); | ||
SubPoolsStorage::<T>::insert(member.pool_id, sub_pools); | ||
} | ||
} | ||
|
||
Ok(()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is basically a service for the greater good of the chain. If the account has been successfully reaped it would make sense to return fees at the end. |
||
} | ||
|
||
|
||
/// Migrates delegated funds from the pool account to the `member_account`. | ||
/// | ||
/// Fails unless [`crate::pallet::Config::StakeAdapter`] is of strategy type: | ||
|
@@ -4020,6 +4055,39 @@ | |
T::StakeAdapter::total_balance(Pool::from(Self::generate_bonded_account(pool_id))) | ||
.unwrap_or_default() | ||
} | ||
|
||
fn do_reap_member( | ||
member_account: T::AccountId, | ||
pool_member: &PoolMember<T>, | ||
bonded_pool: &BondedPool<T>, | ||
num_slashing_spans: u32, | ||
) { | ||
ClaimPermissions::<T>::remove(&member_account); | ||
PoolMembers::<T>::remove(&member_account); | ||
|
||
let member = Member::from(member_account.clone()); | ||
let pool = Pool::from(bonded_pool.bonded_account()); | ||
|
||
// Ensure any dangling delegation is withdrawn. | ||
let dangling_withdrawal = match T::StakeAdapter::member_delegation_balance(member.clone()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The general approach looks fine to me. Good next step would be to write an integration test (delegate-stake and transfer stake) to ensure the stake is updated and storages are cleaned as expected. |
||
Some(amount) => { | ||
T::StakeAdapter::member_withdraw( | ||
member, | ||
pool, | ||
amount, | ||
num_slashing_spans, | ||
); | ||
amount | ||
}, | ||
None => Zero::zero(), | ||
}; | ||
|
||
Self::deposit_event(Event::<T>::MemberRemoved { | ||
pool_id: pool_member.pool_id, | ||
member: member_account, | ||
released_balance: dangling_withdrawal, | ||
}); | ||
} | ||
} | ||
|
||
impl<T: Config> sp_staking::OnStakingUpdate<T::AccountId, BalanceOf<T>> for Pallet<T> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could just put a constant value in here before you create the benchmarks. then the compiler won't complain.