diff --git a/pallets/distance/src/lib.rs b/pallets/distance/src/lib.rs index 17639fa025fda34c8a72f82ede6598050e512539..ab6892b438c3629fb52f341e4ad8c063747d6078 100644 --- a/pallets/distance/src/lib.rs +++ b/pallets/distance/src/lib.rs @@ -184,13 +184,10 @@ pub mod pallet { idty_index: T::IdtyIndex, who: T::AccountId, }, - /// A distance evaluation was updated. // TODO refac - EvaluationUpdated { evaluator: T::AccountId }, - /// A distance status was forced. // TODO check if necessary to differenciate - EvaluationStatusForced { - idty_index: T::IdtyIndex, - status: Option<(<T as frame_system::Config>::AccountId, DistanceStatus)>, - }, + /// Distance rule was found valid + EvaluatedValid { idty_index: T::IdtyIndex }, + /// Distance rule was found invalid + EvaluatedInvalid { idty_index: T::IdtyIndex }, } // ERRORS // @@ -329,7 +326,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - Self::do_valid_distance_status(identity); + Self::do_valid_distance_status(identity, None); Ok(()) } } @@ -405,15 +402,7 @@ pub mod pallet { // caller has an identity let idty_index = pallet_identity::IdentityIndexOf::<T>::get(who) .ok_or(Error::<T>::CallerHasNoIdentity)?; - // TODO some of the following can be moved to a "check idty call allowed" managed by wot - let idty = pallet_identity::Identities::<T>::get(idty_index) - .ok_or(Error::<T>::CallerIdentityNotFound)?; - // caller is member - ensure!( - idty.status == pallet_identity::IdtyStatus::NotMember - || idty.status == pallet_identity::IdtyStatus::Member, - Error::<T>::CallerNotMember - ); + // TODO "check idty call allowed" managed by wot that checks received cert count Self::check_request_distance_evaluation_common(idty_index)?; Ok(idty_index) } @@ -424,9 +413,10 @@ pub mod pallet { target: <T as pallet_identity::Config>::IdtyIndex, ) -> Result<(), DispatchError> { // caller has an identity - let caller_idty_index = pallet_identity::IdentityIndexOf::<T>::get(&who) + let caller_idty_index = pallet_identity::IdentityIndexOf::<T>::get(who) .ok_or(Error::<T>::CallerHasNoIdentity)?; // TODO some of the following can be moved to a "check idty call allowed" managed by wot + // which also checks certification count let caller_idty = pallet_identity::Identities::<T>::get(caller_idty_index) .ok_or(Error::<T>::CallerIdentityNotFound)?; // caller is member @@ -520,8 +510,6 @@ pub mod pallet { { median_acc.push(distance_value); } - - Self::deposit_event(Event::EvaluationUpdated { evaluator }); Ok(()) } else { // one author can only submit one evaluation @@ -531,24 +519,40 @@ pub mod pallet { } /// Set the distance status using IdtyIndex and AccountId - pub fn do_valid_distance_status(idty: <T as pallet_identity::Config>::IdtyIndex) { - // expiration session index - let expire_on = - pallet_session::Pallet::<T>::current_index() + T::ResultExpiration::get(); + pub fn do_valid_distance_status( + idty: <T as pallet_identity::Config>::IdtyIndex, + expire_on: Option<u32>, + ) { + // expiration session index if not given + let expire_on = expire_on.unwrap_or_else(|| { + pallet_session::Pallet::<T>::current_index() + T::ResultExpiration::get() + }); // index valid result ValidEvaluationResult::<T>::set(idty, Some(())); // schedule expiry ValidEvaluationExpireOn::<T>::append(expire_on, idty); // callback T::OnValidDistanceStatus::on_valid_distance_status(idty); - // TODO event + // deposit event + Self::deposit_event(Event::EvaluatedValid { idty_index: idty }); } } impl<T: Config> pallet_authority_members::OnNewSession for Pallet<T> { fn on_new_session(index: SessionIndex) { + // set evaluation block EvaluationBlock::<T>::set(frame_system::Pallet::<T>::parent_hash()); + // expire old valid results + if let Some(idties) = ValidEvaluationExpireOn::<T>::take(index) { + idties.into_iter().for_each(|i| { + ValidEvaluationResult::<T>::take(i); + }); + } + + // new expiration session number + let expire_on = index + T::ResultExpiration::get(); + // Apply the results from the current pool (which was previous session's result pool) // We take the results so the pool is left empty for the new session. #[allow(clippy::type_complexity)] @@ -557,46 +561,48 @@ pub mod pallet { <T as pallet_identity::Config>::IdtyIndex, > = Pallet::<T>::take_current_pool(index); for (idty, median_acc) in current_pool.evaluations.into_iter() { + // distance result + let mut distance_result: Option<bool> = None; + + // get result of the computation if let Some(median_result) = median_acc.get_median() { - // get result of the comutation let median = match median_result { MedianResult::One(m) => m, MedianResult::Two(m1, m2) => m1 + (m2 - m1) / 2, // Avoid overflow (since max is 1) }; - // distance status criterion - let is_distance_status_valid = median >= T::MinAccessibleReferees::get(); + // update distance result + distance_result = Some(median >= T::MinAccessibleReferees::get()); + } - // take requester and perform unreserve or slash - if let Some(requester) = PendingEvaluationRequest::<T>::take(idty) { - if is_distance_status_valid { + // take requester and perform unreserve or slash + if let Some(requester) = PendingEvaluationRequest::<T>::take(idty) { + match distance_result { + None => { + // no result, unreserve T::Currency::unreserve( &requester, <T as Config>::EvaluationPrice::get(), ); - } else { + } + Some(true) => { + // positive result, unreserve and apply + T::Currency::unreserve( + &requester, + <T as Config>::EvaluationPrice::get(), + ); + Self::do_valid_distance_status(idty, Some(expire_on)); + } + Some(false) => { + // negative result, slash and deposit event T::Currency::slash_reserved( &requester, <T as Config>::EvaluationPrice::get(), ); + Self::deposit_event(Event::EvaluatedInvalid { idty_index: idty }); } } - // if evaluation happened without request, it's ok to do nothing - - // if evaluation is positive, remember it for antispam - // and perform callbacks - if is_distance_status_valid { - Self::do_valid_distance_status(idty); - } else { - // TODO event - } - } - // when no result is published, all funds are unreserved - else if let Some(requester) = PendingEvaluationRequest::<T>::take(idty) { - <T as Config>::Currency::unreserve( - &requester, - <T as Config>::EvaluationPrice::get(), - ); } + // if evaluation happened without request, it's ok to do nothing } } } diff --git a/runtime/common/src/providers.rs b/runtime/common/src/providers.rs index 3f8bc76b81f142b3a015ecf72835e2f83ababfac..df5b31e9ecfa13183eb09c2e3bb5776075590c10 100644 --- a/runtime/common/src/providers.rs +++ b/runtime/common/src/providers.rs @@ -109,7 +109,7 @@ macro_rules! impl_benchmark_setup_handler { account: &<T as frame_system::Config>::AccountId, ) -> () { let _ = pallet_distance::Pallet::<T>::do_valid_distance_status( - *idty_id + *idty_id, None ); } fn add_cert(issuer: &IdtyIndex, receiver: &IdtyIndex) { diff --git a/runtime/gdev/tests/integration_tests.rs b/runtime/gdev/tests/integration_tests.rs index d03a902097cb9b06c6dc5aa0c21eea50f4ffd12d..177efe07df6516a3e63fd68d4747af4ddf55dfaa 100644 --- a/runtime/gdev/tests/integration_tests.rs +++ b/runtime/gdev/tests/integration_tests.rs @@ -440,11 +440,8 @@ fn test_identity_creation_workflow() { 5 )); assert_eq!( - Distance::identity_distance_status(5), - Some(( - AccountKeyring::Charlie.to_account_id(), - pallet_distance::DistanceStatus::Pending - )) + Distance::pending_evaluation_request(5), + Some(AccountKeyring::Charlie.to_account_id(),) ); run_to_block(51); // Pass 2 sessions @@ -681,13 +678,9 @@ fn test_ud_claimed_membership_on_and_off() { )); // alice claims back her membership - assert_ok!(Distance::force_set_distance_status( + assert_ok!(Distance::force_valid_distance_status( frame_system::RawOrigin::Root.into(), 1, - Some(( - AccountKeyring::Alice.to_account_id(), - pallet_distance::DistanceStatus::Valid - )) )); assert_ok!(Membership::claim_membership( frame_system::RawOrigin::Signed(AccountKeyring::Alice.to_account_id()).into() @@ -1133,13 +1126,9 @@ fn test_validate_new_idty_after_few_uds() { 2, 5, )); - assert_ok!(Distance::force_set_distance_status( + assert_ok!(Distance::force_valid_distance_status( frame_system::RawOrigin::Root.into(), 5, - Some(( - AccountKeyring::Bob.to_account_id(), - pallet_distance::DistanceStatus::Valid - )) )); assert_ok!(Membership::claim_membership( frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), @@ -1193,13 +1182,9 @@ fn test_claim_memberhsip_after_few_uds() { )); // eve should be able to claim her membership - assert_ok!(Distance::force_set_distance_status( + assert_ok!(Distance::force_valid_distance_status( frame_system::RawOrigin::Root.into(), 5, - Some(( - AccountKeyring::Eve.to_account_id(), - pallet_distance::DistanceStatus::Valid - )) )); assert_ok!(Membership::claim_membership( frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(),