diff --git a/pallets/distance/src/benchmarking.rs b/pallets/distance/src/benchmarking.rs index cb7283931f426bd09f6457ad38afadc84f13132b..c389b354c211c700c7bbe702d58f60c86f3b4341 100644 --- a/pallets/distance/src/benchmarking.rs +++ b/pallets/distance/src/benchmarking.rs @@ -75,7 +75,7 @@ benchmarks! { |idty_val| idty_val.as_mut().unwrap().status = pallet_identity::IdtyStatus::Unvalidated); }: _<T::RuntimeOrigin>(caller_origin.clone(), target) verify { - assert!(PendingEvaluationRequest::<T>::get(&target) == Some(caller.clone()), "Request not added"); + assert!(PendingEvaluationRequest::<T>::get(target) == Some(caller.clone()), "Request not added"); assert_has_event::<T>(Event::<T>::EvaluationRequested { idty_index: target, who: caller }.into()); } diff --git a/pallets/distance/src/lib.rs b/pallets/distance/src/lib.rs index 8f0e7df822660fe2fbee8287addddcf96b06e91e..3a0f01ff4c275f9d30e2098feb6187986ae6ac1b 100644 --- a/pallets/distance/src/lib.rs +++ b/pallets/distance/src/lib.rs @@ -464,6 +464,8 @@ pub mod pallet { Pallet::<T>::mutate_current_pool( pallet_session::CurrentIndex::<T>::get(), // TODO look |current_pool| { + // TODO not needed if called in extrinsics only + // since extrinsics are transactional by default ensure!( current_pool.evaluations.len() < (MAX_EVALUATIONS_PER_SESSION as usize), Error::<T>::QueueFull diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs index 0f6bed36a15ec67cb8d171020e6cb08eee4a4074..b0264bc1fc5017cd1299c072edb4a286b49c9168 100644 --- a/pallets/duniter-wot/src/lib.rs +++ b/pallets/duniter-wot/src/lib.rs @@ -366,23 +366,42 @@ impl<T: Config<I> + pallet_distance::Config, I: 'static> fn on_valid_distance_status(idty_index: IdtyIndex) { if let Some(identity) = pallet_identity::Identities::<T>::get(idty_index) { match identity.status { - IdtyStatus::Unconfirmed => { /* should not happen */ } + IdtyStatus::Unconfirmed | IdtyStatus::Revoked => { + // IdtyStatus::Unconfirmed + // distance evaluation request should never happen for unconfirmed identity + // IdtyStatus::Revoked + // the identity can have been revoked during distance evaluation by the oracle + } + IdtyStatus::Unvalidated | IdtyStatus::NotMember => { - // ok to fail - let r = pallet_membership::Pallet::<T, I>::try_claim_membership(idty_index); - sp_std::if_std! { - if let Err(e) = r { - print!("failed to claim identity when distance status was ok: "); - println!("{:?}", idty_index); - println!("reason: {:?}", e); - } - } + // IdtyStatus::Unvalidated + // normal scenario for first entry + // IdtyStatus::NotMember + // normal scenario for re-entry + // the following can fail if a certification expired during distance evaluation + // otherwise it should succeed + let _ = pallet_membership::Pallet::<T, I>::try_claim_membership(idty_index); + // sp_std::if_std! { + // if let Err(e) = r { + // print!("failed to claim identity when distance status was found ok: "); + // println!("{:?}", idty_index); + // println!("reason: {:?}", e); + // } + // } } IdtyStatus::Member => { - // ok to fail + // IdtyStatus::Member + // normal scenario for renewal + // should succeed let _ = pallet_membership::Pallet::<T, I>::try_renew_membership(idty_index); + // sp_std::if_std! { + // if let Err(e) = r { + // print!("failed to renew identity when distance status was found ok: "); + // println!("{:?}", idty_index); + // println!("reason: {:?}", e); + // } + // } } - IdtyStatus::Revoked => { /* should not happen */ } } } else { // identity was removed before distance status was found diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs index 99f9a317af73b19ff1fa545e0b029de266f9fcd3..c098d4bb506e80ecf1f19c1bac6a6c856624f766 100644 --- a/pallets/membership/src/lib.rs +++ b/pallets/membership/src/lib.rs @@ -174,6 +174,8 @@ pub mod pallet { MembershipAlreadyAcquired, /// Membership not found. MembershipNotFound, + /// Already member, can not claim membership + AlreadyMember, } // HOOKS // @@ -260,6 +262,12 @@ pub mod pallet { /// check that membership can be claimed pub fn check_allowed_to_claim(idty_id: T::IdtyId) -> Result<(), DispatchError> { + // no-op is error + ensure!( + Membership::<T, I>::get(idty_id).is_none(), + Error::<T, I>::AlreadyMember + ); + // enough certifications and distance rule for example T::CheckMembershipCallAllowed::check_idty_allowed_to_claim_membership(&idty_id)?; Ok(()) diff --git a/runtime/gdev/tests/integration_tests.rs b/runtime/gdev/tests/integration_tests.rs index 177efe07df6516a3e63fd68d4747af4ddf55dfaa..573b249f8b83cfcc1c3cc7b8a38ee2ab4e69f6e6 100644 --- a/runtime/gdev/tests/integration_tests.rs +++ b/runtime/gdev/tests/integration_tests.rs @@ -310,7 +310,7 @@ fn test_remove_identity() { }); } -/// test identity is validated when membership is claimed +/// test identity is "validated" (= membership is claimed) when distance is evaluated positively #[test] fn test_validate_identity_when_claim() { ExtBuilder::new(1, 3, 4) @@ -345,11 +345,14 @@ fn test_validate_identity_when_claim() { 5 )); + // eve request distance evaluation for herself assert_ok!(Distance::request_distance_evaluation( frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), )); - run_to_block(51); // Pass 2 sessions + // Pass 2 sessions + run_to_block(51); + // simulate an evaluation published by smith Alice assert_ok!(Distance::force_update_evaluation( frame_system::RawOrigin::Root.into(), AccountKeyring::Alice.to_account_id(), @@ -357,22 +360,28 @@ fn test_validate_identity_when_claim() { distances: vec![Perbill::one()], } )); - run_to_block(76); // Pass 1 session - - // eve can claim her membership - assert_ok!(Membership::claim_membership( - frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), + run_to_block(75); // Pass 1 session + System::assert_has_event(RuntimeEvent::Distance( + pallet_distance::Event::EvaluatedValid { idty_index: 5 }, )); + // eve can not claim her membership manually because it is done automatically + assert_noop!( + Membership::claim_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), + ), + pallet_membership::Error::<Runtime, pallet_membership::Instance1>::AlreadyMember + ); + + // println!("{:?}", System::events()); System::assert_has_event(RuntimeEvent::Membership( pallet_membership::Event::MembershipAdded { member: 5, - expire_on: 76 + expire_on: 75 + <Runtime as pallet_membership::Config<Instance1>>::MembershipPeriod::get( ), }, )); - // not possible anymore to validate identity of someone else }); } @@ -677,14 +686,18 @@ fn test_ud_claimed_membership_on_and_off() { }, )); - // alice claims back her membership + // alice claims back her membership through distance evaluation assert_ok!(Distance::force_valid_distance_status( frame_system::RawOrigin::Root.into(), 1, )); - assert_ok!(Membership::claim_membership( - frame_system::RawOrigin::Signed(AccountKeyring::Alice.to_account_id()).into() - )); + // it can not be done manually + assert_noop!( + Membership::claim_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Alice.to_account_id()).into(), + ), + pallet_membership::Error::<Runtime, pallet_membership::Instance1>::AlreadyMember + ); System::assert_has_event(RuntimeEvent::Membership( pallet_membership::Event::MembershipAdded { member: 1, @@ -1119,20 +1132,25 @@ fn test_validate_new_idty_after_few_uds() { pallet_identity::IdtyName::from("Eve"), )); - // At next block, Bob should be able to certify and validate the new identity + // At next block, Bob should be able to certify the new identity run_to_block(23); assert_ok!(Cert::add_cert( frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(), 2, 5, )); + // valid distance status should trigger identity validation assert_ok!(Distance::force_valid_distance_status( frame_system::RawOrigin::Root.into(), 5, )); - assert_ok!(Membership::claim_membership( - frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), - )); + // and it is not possible to call it manually + assert_noop!( + Membership::claim_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), + ), + pallet_membership::Error::<Runtime, pallet_membership::Instance1>::AlreadyMember + ); // The new member should have first_eligible_ud equal to three assert!(Identity::identity(5).is_some()); @@ -1181,14 +1199,18 @@ fn test_claim_memberhsip_after_few_uds() { 5, )); - // eve should be able to claim her membership + // eve membership should be able to be claimed through distance evaluation assert_ok!(Distance::force_valid_distance_status( frame_system::RawOrigin::Root.into(), 5, )); - assert_ok!(Membership::claim_membership( - frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), - )); + // but not manually + assert_noop!( + Membership::claim_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(), + ), + pallet_membership::Error::<Runtime, pallet_membership::Instance1>::AlreadyMember + ); // The new member should have first_eligible_ud equal to three assert!(Identity::identity(5).is_some());