diff --git a/pallets/distance/src/lib.rs b/pallets/distance/src/lib.rs index d4b14b9180b61fb9e8dacaca9160a154a87b3f62..8bdcc60b342516d416bcd529ae5306bf3c18c20f 100644 --- a/pallets/distance/src/lib.rs +++ b/pallets/distance/src/lib.rs @@ -234,7 +234,8 @@ pub mod pallet { pallet_identity::IdentityIndexOf::<T>::get(&who).ok_or(Error::<T>::NoIdentity)?; ensure!( - IdentityDistanceStatus::<T>::get(idty).is_none(), + IdentityDistanceStatus::<T>::get(idty) + != Some((who.clone(), DistanceStatus::Pending)), Error::<T>::AlreadyInEvaluation ); @@ -479,24 +480,23 @@ pub mod pallet { MedianResult::One(m) => m, MedianResult::Two(m1, m2) => m1 + (m2 - m1) / 2, // Avoid overflow (since max is 1) }; - if median >= T::MinAccessibleReferees::get() { - IdentityDistanceStatus::<T>::mutate(idty, |entry| { - entry.as_mut().map(|(account_id, status)| { + IdentityDistanceStatus::<T>::mutate(idty, |entry| { + entry.as_mut().map(|(account_id, status)| { + if median >= T::MinAccessibleReferees::get() { T::Currency::unreserve( account_id, <T as Config>::EvaluationPrice::get(), ); *status = DistanceStatus::Valid; - }) + } else { + <T as Config>::Currency::slash_reserved( + &account_id, + <T as Config>::EvaluationPrice::get(), + ); + *status = DistanceStatus::Invalid; + } }); - } else if let Some((account_id, _status)) = - IdentityDistanceStatus::<T>::take(idty) - { - <T as Config>::Currency::slash_reserved( - &account_id, - <T as Config>::EvaluationPrice::get(), - ); - } + }); } else if let Some((account_id, _status)) = IdentityDistanceStatus::<T>::take(idty) { <T as Config>::Currency::unreserve( diff --git a/pallets/distance/src/types.rs b/pallets/distance/src/types.rs index 8a3613344fd711661fefd1ff854c3dae71b41dab..95ab967e2476983ea4b8f9b87ae23b8b3fb329b3 100644 --- a/pallets/distance/src/types.rs +++ b/pallets/distance/src/types.rs @@ -28,6 +28,8 @@ pub enum DistanceStatus { Pending, /// Identity respects the distance Valid, + /// Identity doesn't respect the distance + Invalid, } /// Pool where distance evaluation requests and results are stored diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs index 25a8a37b8a76c056a6efc686c2acdccd1c98726b..82a70d0a4d194ba1d2946dc3d6824314a8662d41 100644 --- a/pallets/duniter-wot/src/lib.rs +++ b/pallets/duniter-wot/src/lib.rs @@ -110,7 +110,8 @@ pub mod pallet { /// Insufficient certifications received to claim membership. NotEnoughCertsToClaimMembership, /// Distance has not received a positive evaluation. - DistanceNotOk, + DistanceIsInvalid, + DistanceNotEvaluated, /// Identity is not allowed to request membership. IdtyNotAllowedToRequestMembership, /// Identity not allowed to renew membership. @@ -296,10 +297,7 @@ impl<T: Config<I>, I: 'static> sp_membership::traits::CheckMembershipCallAllowed idty_cert_meta.received_count >= T::MinCertForMembership::get(), Error::<T, I>::NotEnoughCertsToClaimMembership ); - ensure!( - T::IsDistanceOk::is_distance_ok(idty_index), - Error::<T, I>::DistanceNotOk, - ); + T::IsDistanceOk::is_distance_ok(idty_index)?; Ok(()) } @@ -310,10 +308,7 @@ impl<T: Config<I>, I: 'static> sp_membership::traits::CheckMembershipCallAllowed idty_value.status == IdtyStatus::Validated, Error::<T, I>::IdtyNotAllowedToRenewMembership ); - ensure!( - T::IsDistanceOk::is_distance_ok(idty_index), - Error::<T, I>::DistanceNotOk, - ); + T::IsDistanceOk::is_distance_ok(idty_index)?; } else { return Err(Error::<T, I>::IdtyNotFound.into()); } diff --git a/pallets/duniter-wot/src/traits.rs b/pallets/duniter-wot/src/traits.rs index 7c3d7b220a2f46a68bfdef90e19e8420e3b5a219..6934ce454bdf2c1cbc318158ba8647671804dca7 100644 --- a/pallets/duniter-wot/src/traits.rs +++ b/pallets/duniter-wot/src/traits.rs @@ -14,14 +14,16 @@ // You should have received a copy of the GNU Affero General Public License // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. +use crate::DispatchError; + pub trait IsDistanceOk<IdtyId> { - fn is_distance_ok(idty_id: &IdtyId) -> bool; + fn is_distance_ok(idty_id: &IdtyId) -> Result<(), DispatchError>; } pub struct DistanceAlwaysOk; impl<IdtyId> IsDistanceOk<IdtyId> for DistanceAlwaysOk { - fn is_distance_ok(_idty_id: &IdtyId) -> bool { - true + fn is_distance_ok(_idty_id: &IdtyId) -> Result<(), DispatchError> { + Ok(()) } } diff --git a/runtime/common/src/providers.rs b/runtime/common/src/providers.rs index 9680798aa405cf46d70470eabf8d9ccd42721e14..65403aa6aef9debd2067a7dc8cd461fca76d51e1 100644 --- a/runtime/common/src/providers.rs +++ b/runtime/common/src/providers.rs @@ -17,6 +17,7 @@ use crate::{entities::IdtyData, AccountId, IdtyIndex}; use core::marker::PhantomData; use pallet_universal_dividend::FirstEligibleUd; +use sp_runtime::DispatchError; use sp_std::boxed::Box; use sp_std::vec::Vec; @@ -112,13 +113,16 @@ pub struct MainWotIsDistanceOk<T>(PhantomData<T>); impl<T> pallet_duniter_wot::traits::IsDistanceOk<<T as pallet_identity::Config>::IdtyIndex> for MainWotIsDistanceOk<T> where - T: pallet_distance::Config, + T: pallet_distance::Config + pallet_duniter_wot::Config<frame_support::instances::Instance1>, { - fn is_distance_ok(idty_id: &<T as pallet_identity::Config>::IdtyIndex) -> bool { - matches!( - pallet_distance::Pallet::<T>::identity_distance_status(idty_id), - Some((_, pallet_distance::DistanceStatus::Valid)) - ) + fn is_distance_ok( + idty_id: &<T as pallet_identity::Config>::IdtyIndex, + ) -> Result<(), DispatchError> { + match pallet_distance::Pallet::<T>::identity_distance_status(idty_id) { + Some((_, pallet_distance::DistanceStatus::Valid)) => Ok(()).into(), + Some((_, pallet_distance::DistanceStatus::Invalid)) => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceIsInvalid.into()), + _ => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceNotEvaluated.into()), + } } }