diff --git a/frame/nomination-pools/src/lib.rs b/frame/nomination-pools/src/lib.rs index fd8ae8ab76b08..dc40a6a7d41fd 100644 --- a/frame/nomination-pools/src/lib.rs +++ b/frame/nomination-pools/src/lib.rs @@ -1329,13 +1329,31 @@ pub mod pallet { MetadataExceedsMaxLen, /// Some error occurred that should never happen. This should be reported to the /// maintainers. - DefensiveError, + Defensive(DefensiveError), /// Not enough points. Ty unbonding less. NotEnoughPointsToUnbond, /// Partial unbonding now allowed permissionlessly. PartialUnbondNotAllowedPermissionlessly, } + #[derive(Encode, Decode, PartialEq, TypeInfo, frame_support::PalletError)] + pub enum DefensiveError { + /// There isn't enough space in the unbond pool. + NotEnoughSpaceInUnbondPool, + /// A (bonded) pool id does not exist. + PoolNotFound, + /// A reward pool does not exist. In all cases this is a system logic error. + RewardPoolNotFound, + /// A sub pool does not exist. + SubPoolsNotFound, + } + + impl From for Error { + fn from(e: DefensiveError) -> Error { + Error::::Defensive(e) + } + } + #[pallet::call] impl Pallet { /// Stake funds with a pool. The amount to bond is transferred from the member to the @@ -1366,7 +1384,7 @@ pub mod pallet { // We just need its total earnings at this point in time, but we don't need to write it // because we are not adjusting its points (all other values can calculated virtual). let reward_pool = RewardPool::::get_and_update(pool_id) - .defensive_ok_or_else(|| Error::::RewardPoolNotFound)?; + .defensive_ok_or::>(DefensiveError::RewardPoolNotFound.into())?; bonded_pool.try_inc_members()?; let points_issued = bonded_pool.try_bond_funds(&who, amount, BondType::Later)?; @@ -1530,14 +1548,16 @@ pub mod pallet { .try_insert(unbond_era, UnbondPool::default()) // The above call to `maybe_merge_pools` should ensure there is // always enough space to insert. - .defensive_map_err(|_| Error::::DefensiveError)?; + .defensive_map_err::, _>(|_| { + DefensiveError::NotEnoughSpaceInUnbondPool.into() + })?; } sub_pools .with_era .get_mut(&unbond_era) // The above check ensures the pool exists. - .defensive_ok_or_else(|| Error::::DefensiveError)? + .defensive_ok_or::>(DefensiveError::PoolNotFound.into())? .issue(unbonding_balance); Self::deposit_event(Event::::Unbonded { @@ -1607,9 +1627,9 @@ pub mod pallet { let current_era = T::StakingInterface::current_era(); let bonded_pool = BondedPool::::get(member.pool_id) - .defensive_ok_or_else(|| Error::::PoolNotFound)?; + .defensive_ok_or::>(DefensiveError::PoolNotFound.into())?; let mut sub_pools = SubPoolsStorage::::get(member.pool_id) - .defensive_ok_or_else(|| Error::::SubPoolsNotFound)?; + .defensive_ok_or::>(DefensiveError::SubPoolsNotFound.into())?; bonded_pool.ok_to_withdraw_unbonded_with( &caller, @@ -2027,9 +2047,9 @@ impl Pallet { ) -> Result<(PoolMember, BondedPool, RewardPool), Error> { let member = PoolMembers::::get(&who).ok_or(Error::::PoolMemberNotFound)?; let bonded_pool = - BondedPool::::get(member.pool_id).defensive_ok_or(Error::::PoolNotFound)?; + BondedPool::::get(member.pool_id).defensive_ok_or(DefensiveError::PoolNotFound)?; let reward_pool = - RewardPools::::get(member.pool_id).defensive_ok_or(Error::::PoolNotFound)?; + RewardPools::::get(member.pool_id).defensive_ok_or(DefensiveError::PoolNotFound)?; Ok((member, bonded_pool, reward_pool)) }