From 78b408eb2ce9b5cfd10557ee43b249594421202d Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux <hugo@trentesaux.fr> Date: Tue, 14 Nov 2023 13:35:05 +0100 Subject: [PATCH] remove membership metadata --- pallets/authority-members/src/benchmarking.rs | 2 +- pallets/authority-members/src/lib.rs | 8 +- pallets/authority-members/src/mock.rs | 1 - pallets/distance/src/mock.rs | 1 - pallets/duniter-wot/src/lib.rs | 58 +++++++++----- pallets/duniter-wot/src/mock.rs | 2 - pallets/duniter-wot/src/tests.rs | 7 +- pallets/membership/src/benchmarking.rs | 4 +- pallets/membership/src/lib.rs | 43 ++++------ pallets/membership/src/mock.rs | 1 - pallets/membership/src/tests.rs | 3 - primitives/membership/src/lib.rs | 4 +- primitives/membership/src/traits.rs | 8 +- resources/metadata.scale | Bin 133447 -> 133159 bytes runtime/common/src/entities.rs | 71 ----------------- runtime/common/src/handlers.rs | 51 +++--------- runtime/common/src/pallets_config.rs | 3 - runtime/gdev/tests/fixme_tests.rs | 75 ++++++++++++++++++ runtime/gdev/tests/integration_tests.rs | 66 +++++++++++++-- 19 files changed, 214 insertions(+), 194 deletions(-) create mode 100644 runtime/gdev/tests/fixme_tests.rs diff --git a/pallets/authority-members/src/benchmarking.rs b/pallets/authority-members/src/benchmarking.rs index d19e73ccf..c0dcc62b8 100644 --- a/pallets/authority-members/src/benchmarking.rs +++ b/pallets/authority-members/src/benchmarking.rs @@ -59,7 +59,7 @@ benchmarks! { let caller: T::AccountId = Members::<T>::get(id).unwrap().owner_key; let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); let validator_id = T::ValidatorIdOf::convert(caller.clone()).unwrap(); - let session_keys: T::KeysWrapper = pallet_session::NextKeys::<T>::get(validator_id).unwrap().into(); + let session_keys: T::Keys = pallet_session::NextKeys::<T>::get(validator_id).unwrap().into(); }: _<T::RuntimeOrigin>(caller_origin, session_keys) remove_member { let id: T::MemberId = OnlineAuthorities::<T>::get()[0]; diff --git a/pallets/authority-members/src/lib.rs b/pallets/authority-members/src/lib.rs index f5d86823d..7884482b3 100644 --- a/pallets/authority-members/src/lib.rs +++ b/pallets/authority-members/src/lib.rs @@ -66,7 +66,6 @@ pub mod pallet { pub trait Config: frame_system::Config + pallet_session::Config + pallet_session::historical::Config { - type KeysWrapper: Parameter + Into<Self::Keys> + From<Self::Keys>; type IsMember: IsMember<Self::MemberId>; type OnNewSession: OnNewSession; type OnRemovedMember: OnRemovedMember<Self::MemberId>; @@ -295,15 +294,12 @@ pub mod pallet { /// declare new session keys to replace current ones #[pallet::call_index(2)] #[pallet::weight(<T as pallet::Config>::WeightInfo::set_session_keys())] - pub fn set_session_keys( - origin: OriginFor<T>, - keys: T::KeysWrapper, - ) -> DispatchResultWithPostInfo { + pub fn set_session_keys(origin: OriginFor<T>, keys: T::Keys) -> DispatchResultWithPostInfo { let who = ensure_signed(origin.clone())?; let member_id = Self::verify_ownership_and_membership(&who)?; let _post_info = pallet_session::Call::<T>::set_keys { - keys: keys.into(), + keys, proof: vec![], } .dispatch_bypass_filter(origin)?; diff --git a/pallets/authority-members/src/mock.rs b/pallets/authority-members/src/mock.rs index c5cfce266..d04f0f47f 100644 --- a/pallets/authority-members/src/mock.rs +++ b/pallets/authority-members/src/mock.rs @@ -151,7 +151,6 @@ impl IsMember<u64> for TestIsSmithMember { } impl pallet_authority_members::Config for Test { - type KeysWrapper = MockSessionKeys; type IsMember = TestIsSmithMember; type MaxAuthorities = ConstU32<4>; type MemberId = u64; diff --git a/pallets/distance/src/mock.rs b/pallets/distance/src/mock.rs index 977c4228c..5d580b137 100644 --- a/pallets/distance/src/mock.rs +++ b/pallets/distance/src/mock.rs @@ -180,7 +180,6 @@ impl<T: pallet_identity::Config> sp_runtime::traits::Convert<T::AccountId, Optio } impl pallet_authority_members::Config for Test { - type KeysWrapper = MockSessionKeys; type IsMember = TestIsSmithMember; type MaxAuthorities = ConstU32<4>; type MemberId = u32; diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs index 1b3b9bdb6..eb9fc59e0 100644 --- a/pallets/duniter-wot/src/lib.rs +++ b/pallets/duniter-wot/src/lib.rs @@ -127,8 +127,8 @@ pub mod pallet { NotAllowedToRemoveIdty, /// Issuer can not emit cert because it is not validated IssuerCanNotEmitCert, - /// Can not issue cert to unconfirmed identity - CertToUnconfirmedIdty, + /// Can not issue cert to identity without membership or pending membership + CertToUndefined, /// Issuer or receiver not found IdtyNotFound, } @@ -164,11 +164,9 @@ where fn check_confirm_identity(idty_index: IdtyIndex) -> Result<(), DispatchError> { // main WoT automatic action if !T::IsSubWot::get() { - pallet_membership::Pallet::<T, I>::force_request_membership( - idty_index, - Default::default(), - ) - .map_err(|e| e.error)?; + // force add a membership request to the main WoT + pallet_membership::Pallet::<T, I>::force_request_membership(idty_index) + .map_err(|e| e.error)?; } // no constraints for subwot Ok(()) @@ -209,12 +207,16 @@ where // implement cert call checks impl<T: Config<I>, I: 'static> pallet_certification::traits::CheckCertAllowed<IdtyIndex> for Pallet<T, I> +// TODO add the following where clause once checks can be done on pallet instance +// where +// T: pallet_membership::Config<I>, { // check the following: // - issuer has identity // - issuer identity is validated // - receiver has identity // - receiver identity is confirmed or validated + // - receiver has membership // // /!\ do not check the following: // - receiver has membership @@ -224,7 +226,13 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::CheckCertAllowed<Id // - issuer can issue cert even if he lost his membership // (not renewed or passed below cert threshold and above again without claiming membership) // this is counterintuitive behavior but not a big problem + // + // TODO to fix this strange behavior, we will have to make the tests + // (CheckCertAllowed and CheckMembershipCallAllowed) run on the relevant instance + // i.e. Cert for Wot, SmithCert for SmithWot... + // → see issue #136 fn check_cert_allowed(issuer: IdtyIndex, receiver: IdtyIndex) -> Result<(), DispatchError> { + // issuer checks // ensure issuer has validated identity if let Some(issuer_data) = pallet_identity::Pallet::<T>::identity(issuer) { ensure!( @@ -234,15 +242,30 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::CheckCertAllowed<Id } else { return Err(Error::<T, I>::IdtyNotFound.into()); } + // issue #136 this has to be done on the correct instance of membership pallet + // // ensure issuer has membership + // if pallet_membership::Pallet::<T, I>::membership(issuer).is_none() { + // // improvement: give reason why issuer can not emit cert (not member) + // return Err(Error::<T, I>::IssuerCanNotEmitCert.into()); + // } + + // receiver checks // ensure receiver has confirmed or validated identity if let Some(receiver_data) = pallet_identity::Pallet::<T>::identity(receiver) { match receiver_data.status { IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => {} // able to receive cert - IdtyStatus::Created => return Err(Error::<T, I>::CertToUnconfirmedIdty.into()), + IdtyStatus::Created => return Err(Error::<T, I>::CertToUndefined.into()), }; } else { return Err(Error::<T, I>::IdtyNotFound.into()); } + // issue #136 this has to be done on the correct instance of membership pallet + // // ensure receiver has a membership or a pending membership + // if pallet_membership::Pallet::<T, I>::pending_membership(issuer).is_none() + // && pallet_membership::Pallet::<T, I>::membership(issuer).is_none() + // { + // return Err(Error::<T, I>::CertToUndefined.into()); + // } Ok(()) } } @@ -299,31 +322,30 @@ impl<T: Config<I>, I: 'static> sp_membership::traits::CheckMembershipCallAllowed } // implement membership event handler -impl<T: Config<I>, I: 'static, MetaData> sp_membership::traits::OnEvent<IdtyIndex, MetaData> - for Pallet<T, I> +impl<T: Config<I>, I: 'static> sp_membership::traits::OnEvent<IdtyIndex> for Pallet<T, I> where - T: pallet_membership::Config<I, MetaData = MetaData>, + T: pallet_membership::Config<I>, { - fn on_event(membership_event: &sp_membership::Event<IdtyIndex, MetaData>) -> Weight { + fn on_event(membership_event: &sp_membership::Event<IdtyIndex>) -> Weight { match membership_event { - sp_membership::Event::<IdtyIndex, MetaData>::MembershipAcquired(idty_index, _) => { + sp_membership::Event::<IdtyIndex>::MembershipAcquired(idty_index) => { if !T::IsSubWot::get() { // when membership is acquired, validate identity // (only used on first membership acquiry) pallet_identity::Pallet::<T>::try_validate_identity(*idty_index); } } - sp_membership::Event::<IdtyIndex, MetaData>::MembershipExpired(_) => {} + sp_membership::Event::<IdtyIndex>::MembershipExpired(_) => {} // Membership revocation cases: // - Triggered by main identity removal: the underlying identity will be removed by the // caller. // - Triggered by the membership pallet: it's only possible for a sub-wot, so we // should not remove the underlying identity // So, in any case, we must do nothing - sp_membership::Event::<IdtyIndex, MetaData>::MembershipRevoked(_) => {} - sp_membership::Event::<IdtyIndex, MetaData>::MembershipRenewed(_) => {} - sp_membership::Event::<IdtyIndex, MetaData>::MembershipRequested(_) => {} - sp_membership::Event::<IdtyIndex, MetaData>::PendingMembershipExpired(idty_index) => { + sp_membership::Event::<IdtyIndex>::MembershipRevoked(_) => {} + sp_membership::Event::<IdtyIndex>::MembershipRenewed(_) => {} + sp_membership::Event::<IdtyIndex>::MembershipRequested(_) => {} + sp_membership::Event::<IdtyIndex>::PendingMembershipExpired(idty_index) => { Self::dispatch_idty_call(pallet_identity::Call::remove_identity { idty_index: *idty_index, idty_name: None, diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs index cd25f68a9..29454df22 100644 --- a/pallets/duniter-wot/src/mock.rs +++ b/pallets/duniter-wot/src/mock.rs @@ -151,7 +151,6 @@ impl pallet_membership::Config<Instance1> for Test { type IdtyIdOf = IdentityIndexOf<Self>; type AccountIdOf = (); type MembershipPeriod = MembershipPeriod; - type MetaData = (); type OnEvent = DuniterWot; type RuntimeEvent = RuntimeEvent; type WeightInfo = (); @@ -209,7 +208,6 @@ impl pallet_membership::Config<Instance2> for Test { type IdtyIdOf = IdentityIndexOf<Self>; type AccountIdOf = (); type MembershipPeriod = SmithMembershipPeriod; - type MetaData = (); type OnEvent = SmithSubWot; type PendingMembershipPeriod = SmithPendingMembershipPeriod; type WeightInfo = (); diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs index 6cefede1f..24d0a2c14 100644 --- a/pallets/duniter-wot/src/tests.rs +++ b/pallets/duniter-wot/src/tests.rs @@ -79,10 +79,9 @@ fn test_join_smiths() { run_to_block(2); // Dave shoud be able to request smith membership - assert_ok!(SmithMembership::request_membership( - RuntimeOrigin::signed(4), - () - )); + assert_ok!(SmithMembership::request_membership(RuntimeOrigin::signed( + 4 + ),)); System::assert_has_event(RuntimeEvent::SmithMembership( pallet_membership::Event::MembershipRequested(4), )); diff --git a/pallets/membership/src/benchmarking.rs b/pallets/membership/src/benchmarking.rs index da0ce28b7..11c95849e 100644 --- a/pallets/membership/src/benchmarking.rs +++ b/pallets/membership/src/benchmarking.rs @@ -46,7 +46,7 @@ benchmarks_instance_pallet! { let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap(); let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); // Lazily prepare call as this extrinsic will always return an errror when in subwot - let call = Call::<T, I>::request_membership { metadata: T::MetaData ::default()}; + let call = Call::<T, I>::request_membership { }; }: { call.dispatch_bypass_filter(caller_origin).ok(); } @@ -58,7 +58,7 @@ benchmarks_instance_pallet! { claim_membership { let idty: T::IdtyId = 3.into(); Membership::<T, I>::take(idty); - PendingMembership::<T, I>::insert(idty.clone(), T::MetaData::default()); + PendingMembership::<T, I>::insert(idty.clone(), ()); let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap(); let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into(); T::BenchmarkSetupHandler::force_status_ok(&idty, &caller); diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs index 1b7a2d07e..3855bf927 100644 --- a/pallets/membership/src/lib.rs +++ b/pallets/membership/src/lib.rs @@ -81,13 +81,11 @@ pub mod pallet { type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyId>>; /// Something that gives the AccountId of an IdtyId type AccountIdOf: Convert<Self::IdtyId, Option<Self::AccountId>>; - /// Optional metadata - type MetaData: Default + Parameter + Validate<Self::AccountId>; #[pallet::constant] /// Maximum life span of a non-renewable membership (in number of blocks) type MembershipPeriod: Get<Self::BlockNumber>; /// On event handler - type OnEvent: OnEvent<Self::IdtyId, Self::MetaData>; + type OnEvent: OnEvent<Self::IdtyId>; #[pallet::constant] /// Maximum period (in number of blocks), where an identity can remain pending subscription. type PendingMembershipPeriod: Get<Self::BlockNumber>; @@ -140,11 +138,11 @@ pub mod pallet { pub type MembershipsExpireOn<T: Config<I>, I: 'static = ()> = StorageMap<_, Twox64Concat, T::BlockNumber, Vec<T::IdtyId>, ValueQuery>; - /// maps identity id to pending membership metadata + /// identities with pending membership request #[pallet::storage] #[pallet::getter(fn pending_membership)] pub type PendingMembership<T: Config<I>, I: 'static = ()> = - StorageMap<_, Twox64Concat, T::IdtyId, T::MetaData, OptionQuery>; + StorageMap<_, Twox64Concat, T::IdtyId, (), OptionQuery>; /// maps block number to the list of memberships set to expire at this block #[pallet::storage] @@ -181,8 +179,6 @@ pub mod pallet { #[pallet::error] pub enum Error<T, I = ()> { - /// Invalid meta data - InvalidMetaData, /// Identity id not found IdtyIdNotFound, /// Membership already acquired @@ -218,19 +214,14 @@ pub mod pallet { /// (only available for sub wot, automatic for main wot) #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::request_membership())] - pub fn request_membership( - origin: OriginFor<T>, - metadata: T::MetaData, - ) -> DispatchResultWithPostInfo { + pub fn request_membership(origin: OriginFor<T>) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; let idty_id = T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T, I>::IdtyIdNotFound)?; - if !metadata.validate(&who) { - return Err(Error::<T, I>::InvalidMetaData.into()); - } + T::CheckMembershipCallAllowed::check_idty_allowed_to_request_membership(&idty_id)?; - Self::do_request_membership(idty_id, metadata) + Self::do_request_membership(idty_id) } /// claim membership @@ -288,11 +279,8 @@ pub mod pallet { impl<T: Config<I>, I: 'static> Pallet<T, I> { /// force request membership - pub fn force_request_membership( - idty_id: T::IdtyId, - metadata: T::MetaData, - ) -> DispatchResultWithPostInfo { - Self::do_request_membership(idty_id, metadata) + pub fn force_request_membership(idty_id: T::IdtyId) -> DispatchResultWithPostInfo { + Self::do_request_membership(idty_id) } /// force expire membership @@ -336,10 +324,7 @@ pub mod pallet { } /// perform the membership request - fn do_request_membership( - idty_id: T::IdtyId, - metadata: T::MetaData, - ) -> DispatchResultWithPostInfo { + fn do_request_membership(idty_id: T::IdtyId) -> DispatchResultWithPostInfo { // checks if PendingMembership::<T, I>::contains_key(idty_id) { return Err(Error::<T, I>::MembershipAlreadyRequested.into()); @@ -352,7 +337,7 @@ pub mod pallet { let expire_on = block_number + T::PendingMembershipPeriod::get(); // apply membership request - PendingMembership::<T, I>::insert(idty_id, metadata); + PendingMembership::<T, I>::insert(idty_id, ()); PendingMembershipsExpireOn::<T, I>::append(expire_on, idty_id); Self::deposit_event(Event::MembershipRequested(idty_id)); T::OnEvent::on_event(&sp_membership::Event::MembershipRequested(idty_id)); @@ -371,10 +356,10 @@ pub mod pallet { /// perform membership claim fn do_claim_membership(idty_id: T::IdtyId) { - if let Some(metadata) = PendingMembership::<T, I>::take(idty_id) { + if PendingMembership::<T, I>::take(idty_id).is_some() { Self::insert_membership_and_schedule_expiry(idty_id); Self::deposit_event(Event::MembershipAcquired(idty_id)); - T::OnEvent::on_event(&sp_membership::Event::MembershipAcquired(idty_id, metadata)); + T::OnEvent::on_event(&sp_membership::Event::MembershipAcquired(idty_id)); } // else { unreachable if check_allowed_to_claim called before } } @@ -388,11 +373,11 @@ pub mod pallet { } } - /// perform mebership expiration + /// perform membership expiration // add pending membership and schedule expiry of pending membership fn do_expire_membership(idty_id: T::IdtyId, expire_on: T::BlockNumber) -> Weight { if Membership::<T, I>::take(idty_id).is_some() { - PendingMembership::<T, I>::insert(idty_id, T::MetaData::default()); + PendingMembership::<T, I>::insert(idty_id, ()); PendingMembershipsExpireOn::<T, I>::append(expire_on, idty_id); } // else should not happen diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs index d97f1f86a..74f44e85b 100644 --- a/pallets/membership/src/mock.rs +++ b/pallets/membership/src/mock.rs @@ -88,7 +88,6 @@ impl pallet_membership::Config for Test { type IdtyIdOf = ConvertInto; type AccountIdOf = ConvertInto; type MembershipPeriod = MembershipPeriod; - type MetaData = (); type OnEvent = (); type PendingMembershipPeriod = PendingMembershipPeriod; type RuntimeEvent = RuntimeEvent; diff --git a/pallets/membership/src/tests.rs b/pallets/membership/src/tests.rs index f11ab9680..a899b4424 100644 --- a/pallets/membership/src/tests.rs +++ b/pallets/membership/src/tests.rs @@ -148,7 +148,6 @@ fn test_membership_revocation() { run_to_block(5); assert_ok!(DefaultMembership::request_membership( RuntimeOrigin::signed(0), - () )); System::assert_has_event(RtEvent::DefaultMembership(Event::MembershipRequested(0))); }); @@ -162,7 +161,6 @@ fn test_pending_membership_expiration() { run_to_block(1); assert_ok!(DefaultMembership::request_membership( RuntimeOrigin::signed(0), - () )); System::assert_has_event(RtEvent::DefaultMembership(Event::MembershipRequested(0))); @@ -191,7 +189,6 @@ fn test_membership_workflow() { run_to_block(1); assert_ok!(DefaultMembership::request_membership( RuntimeOrigin::signed(0), - () )); System::assert_has_event(RtEvent::DefaultMembership(Event::MembershipRequested(0))); diff --git a/primitives/membership/src/lib.rs b/primitives/membership/src/lib.rs index 2d74c6230..f59fcde5d 100644 --- a/primitives/membership/src/lib.rs +++ b/primitives/membership/src/lib.rs @@ -27,9 +27,9 @@ use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -pub enum Event<IdtyId, MetaData = ()> { +pub enum Event<IdtyId> { /// A membership has acquired - MembershipAcquired(IdtyId, MetaData), + MembershipAcquired(IdtyId), /// A membership has expired MembershipExpired(IdtyId), /// A membership has renewed diff --git a/primitives/membership/src/traits.rs b/primitives/membership/src/traits.rs index 0480a64f3..2b68516ca 100644 --- a/primitives/membership/src/traits.rs +++ b/primitives/membership/src/traits.rs @@ -38,12 +38,12 @@ pub trait IsInPendingMemberships<IdtyId> { fn is_in_pending_memberships(idty_id: IdtyId) -> bool; } -pub trait OnEvent<IdtyId, MetaData> { - fn on_event(event: &crate::Event<IdtyId, MetaData>) -> Weight; +pub trait OnEvent<IdtyId> { + fn on_event(event: &crate::Event<IdtyId>) -> Weight; } -impl<IdtyId, MetaData> OnEvent<IdtyId, MetaData> for () { - fn on_event(_: &crate::Event<IdtyId, MetaData>) -> Weight { +impl<IdtyId> OnEvent<IdtyId> for () { + fn on_event(_: &crate::Event<IdtyId>) -> Weight { Weight::zero() } } diff --git a/resources/metadata.scale b/resources/metadata.scale index 2680c3b02a4ca74e19ed66cc13eb88883db14aef..157b25e4f0edd9fcfa7acfd37ac5e71a25f7c187 100644 GIT binary patch delta 4804 zcmX>;iDUT$4z}FXl0-h!jch+M7&#~Z&!}VkIJqu!7URdsl3A&Ytefkzidh&{Cl}_& zPY%kLW7M2nm|w>jIr&3=HA^KE<I>3wb7Ll-E>L8tWnw%D=J*t<GB!^BkRLz!VxbmG zD-+{guyAydF=OXs!}9pa?}{`TdnbR$PncX$tjMyIiE%Gj!OvnjmX$CQ%S&V!*MbfC zT%yi$l8NymSWQ)_2FqC{#+_geQ<*Z$MVRi^G9|{VU=8f$nv8cR8<w}SJY-^A305gq zA;b6*?1f1c@=T1(lRxIiZ5FKTQRR>cv9j_`tt{TWW}Xe>WRWGm7!@b;FLhy5oE);$ zhDnuadY&(%_++jH(u}g3)fT*AX4ITKaj6fZ?qvJrk(<qzu`@F2Znj^(o|RE|^7}Qx z5{68S9<GI@nPvIOi6xo&c{Uz83VwDB43pojk(gYxR*A)wiP3WMueAn~Pps8r^qu^D zZ3Ls~WW^1_leeuGW3yyp31+mNT)$3V!IOzmLL*E^Ay|`vQKC3CIX^E2Nr=G`tmol6 zD`s0Jp2;8Ah)y<MFU06LdBaU{M#sr<>lIX8nHUwKOD(Jw%uHe#7+jec7?>Rx7#KJh zJee36SU4=1Y?&B*!KQ$04usn*7m8^!lF;OZ>qRG<Y_Q=C1sf9xGA5E~vZ1cz<Y^le z8Dl5!*r35!xcT9R6h_9_$!?pX7!xNi+?36jIGJ~|5o79Phs`R|nM{lUVX4VB{soDJ zrK!H9IVG8iDJeyE3=FB0>o==&W->7_Fy%5a<W63{*_f%2Y4U45waHvt_#{i27(I%M zj7&`pEv>AAGt=`DOG=AU85l|@8*WkHNA+>#=7cTPEKIdblM4;yHvirs&&1fcS$elI z3uEhM|NZ>}jGdeBpTEV()XOwE-&$hx<%>s{7$<I?aV4ISapLA5SC=y~&YisA`eeq1 zlTB`1W}G;g<7O@6#K~<pHNl~*WQD^mj0_^K$tlH&EDTeb7#&hUOk}4rF)&P>%yUal zY9>5-Ok)`sW`d%}5ga{pC%fEI=UfO10zpQGrIYtRw%L60Rs|EwN+zCw$s0LDHb*~~ zWMW)9x%hq`<HpHM4^}a5oV@nIbjH1#T_5%_GH#rF<&mEBRwhORP!I>C7A0lo<k&GV zYz3LPlZj#HWZB31#(SAqB>W3NDU^jJgz+E~BZq)reqJgA1A{<ter_rY!$Bqn21W)j z#lpdGl!@W!<od_<j3*K9Ig9Kbri)C|tE(BMH&1*i&c=9k^UC+@nHX<Q-uFvwbNwef z4#u0C_x;+$#dvdiAuFRg(_N<N^P3r!rte{8T*>s1X>xp^==2&kMrX#S+YhiYYKSmC zoqm9g(P_K3G~*{m#;4QeWEs_&UNTMA3l*OpC(9_w{+5ZcCM-31a^Y6l?XzVW->{;H ztX5_WU}F3@{f{c+H57?&YK-;FoNqxPag>qa<McW$Mh(WV)0b;8S}^@&n*LCW(U<8j z({uxEMsKFCOp^tZB&JW*W^@9}MKKCbf1}NqBl?$#L#DVOJ~_WARUj-sGX)e(jN5Z{ z7+u*JS*JHzG8#^Ik6;wy<YZ=GVA{#Zz`OmwG2<~tMnRCA*z|x<Miq5YW|m+E1{MZM zW=086G=<nPFo-gP^5sKD2?j}!PElqCS&$AxXBLQBMI^O~AQdbOs?5l-sL6~Gi<->f zSk#>EXwE1zeY+W>IHT_L^Ja|djHc7Sn=$IhSu!(*1cOVL#G=ZuAh&>`RF};3)Z!8b zW(EdbkhTh8LuN*Uu%a}i{AM`)j5(td4=BTh6{Q6f<>#kOw=-vypKfWv7|Lh~(k3%~ zwFP4$7QMF9<t-T#86ClXQ+I_1geQ{cT)_b$A;91X@}(;?gD>;s1GOUC-&!)hWn>K8 ze%qSy4l`ru^adwJiRl;Y86yQFnHe=)D@uwI-EtDsiy0Uq!E%ZyVk``?%!~r1hDH_) z46)1%46N)7i6A#XVnj3*>X2L{hopjynSRTG(T6XSnNcPvHL*B9ub6=$6C&Z`$f(4b z3vy&CGeaTBFhkK&s5zBL=9EH|Uv*@R;j9EHFJ)$^g(z=?DsM$n-Uw12$khr`*~rY$ z$vl}+OltdAC&rIVjJ?yJyE1BVBfK(kx{Mp6Ez?xy$$Hb|w^z9_nlUlXoW9Y6F@<q1 z*b0$_P%D-qSuuTs2c!7(B2UJ2uB9Mr7BVxeWS)FsuGI9uo{W}EYe8(q?U7!fe6(@; zDj&u|wXNV-*<r%46Qp4;Gs9l60D~+O!$C0XD6<K}(dmx9jM|JRx99pYCNnagoqo}e zaT?>r=^6fvDU4UApY>-nWxNV<79`ZC+XgTSG2YxB5Wwio%y<_eA$<dq<{u)t`60;O z8w^jUe+*{S6MD(az`>Bo$iTqxl9`bugn{AZbi)wFGRC*lSA;OyGk%=@B7`xJ@h#j) zGscf_wu<^&XqbFOGXE>c{I|>uKf%5cU|{&mJlRlJdOC9$<2fcqmdS}*M5aFvV+><t zoo*M-c#eyc1(aVE1Q>Xye=LM%dL}`Z$uheowiib*sxvW)LL|;aF$yzEPJa-^xPei2 z`^0F*%S?=lU?~k%Xx`RjL6ifkU~@ScB^WeW7#NsTSr~L#CO<f@H2pyw<55P#?aSgB z`Itp*oKuTRLh?iNQc}}0^HNh7xL9Nvr=Lq=6f?|BNzE(CEU8o|&n(HvFD+5XP0dY8 zEh^5)EKtZVQYc8xOUcYjM-rX>BZ+Y?qv>>;R7Q#E>yjDuxh+{3Bp3x!5=#;-r@u&M zbYrxguAjn~DCo+<sNtDXQW;#5SW;Tdz+gFjVG3iWku3{yIpoNKQ4Tq>fXg8e#lpcL zz~Bn9D_F!6<UwB+24Aq31zcGe0$C>KTT5-<o65L~g)ww`Mi!$tQzXme1COPqFDPf^ z6Oyn1S?`(RmtW$RUz(S~z%c!3IinFH<8+A%MoUJf>5bWpMvTnUTPqk18Cj-puV8dx zWS#z}g0YV!mIYFOPQRGLSj3VD<!z77Wjx2ol*%%>;jzSY=X^#p#?0we`HT&Wt<!(! zGrBQmf@4ZP7aCKINHLWQadsgKL*evE1&r!^JDC`G7-fnRa|?1(i%X{;FJO#jECuV= zuY~HaMbcjh*1wZUfT0!?5S1(pjUYOgg`pLsNo@MeLPlN9P8LQTr;wu5)Zo+-8&E~j z$-<%l69CoTpo)Z-iGg8yV<Dr&^Z+MD>FG*Ej6#ePx0@C*#xpWbrB#w)nn|6QnTrw^ zTnoX$!ob3?bbD1bBO?>z%IP(=j4K$|PFJmC)L>i-3LC@e^>vKGj2pL4u47!o!nG9? zZaY~RcCt)9AD}ortC`W5aqskb&5W104}wiQ$|AvV6s%G7Bs3<@BE`hX=?7aFCkmeh z8FP|_;UZYiRTc?`s}Mamp?dBj>A5+5bt_{X*IkgFn=A|uStiE^if{L7W2|Rlddf0c zFH~~+-c&};>2Et2XEMH=-rmXB$@mszoHNr$mdSFD<))W(F$yq#o!;8TsLJ${W%`;f zMop%_EYtIJ7$vs9?_!+5$jCUop@%VAYa){fxO!t`Wo2MtFkxU|U}a@sU{T;?<z*FQ z6=juVRb<s=HDqProF352C^cQam(hTc7sPgD6a-OH(>L@os!#XtWt5)&sh3e{`cx20 zzmHLkTb7lP$F(StfkBpa@<k?*?InGTa|9R_rwh(!G+|Q(*{3<(dp@HAqw4gW`Ha$x znh^6A&1ckM)P=BL&Sz9$He}_Pd{16_yZQpg#r%xC(@(Ew^kNj;F1CSjH8Z2&_CuQ) zXEQR&PLJEl7|E!*eaBWtDHcZC>6dphRx#R6_uIudhtYBS>s^ciER4R}ZT2&AGO+|Q zPh^}Pc#tu1`h*3H9Md-)WIV<k%Dez1q`rO8Ax2|n#>DB@jxzQz7EVt-#%Re{JALjk zMqS3*?Wd11u4QKIoL+f~(T=fq`i@hKDvT4i-#x|nlbLbq^y}vs<r!yA|9+0qfN}12 zjq{9a7#UYizj}eOm~riN&x?%dj2owKyvSI>xOKbQCB`~N#+}=jUS^yOa=qnMMoY$n z(~GY%da0-~G45etJju)_<6e}Qmr{_(2xCZyfXc^IMuxM~AA&So+%A2MF_)QDlZo*F z$8^U1jAGjt-(+lNWW2du{WfD66XV_K^X@VRF+QFC@h;;urk~8yJMS?zF-A`3xzBio z=`Zv2NB0?nr7D>i-!L#TvWS?37Ni#?rlk58Wu|B5F)-Fn_kX~s$;djr@&ThIKPL+> z3#hbhWMcfmz$iHV-~&c8M$zd%9x&E1N^UQI$f(T7*gAdoBgTA2+3nnq850;86{qJs zVU%I)oZk6_F^6&I_HR!Z7c#QwvdHmFkNd=^HT~!_Mh8a2>1@v#)fi2;>po}9V`TK4 zKIa8v5M%H5_b(W^7#Rbn|9Z)&#TYvM-zUaTqCG4OENc{?^-yMNF}Nn0Zt$8>WU}rP z_US&a84DPfPT%{Q@d0Dx^m%U>)fr=_ulmZkjB(}m+_#LmjEsrXZ@**IU`(Cf^`6ms zy8U}bb|{-8AU{9Hh>-y-vxV{CcKZ*ELX3>P(}O-TRx+-ge&!=%IOERgDxVnj7$;5- z{=`_yICc8TPmCrcI1Mz~pgR4)YsR~bGpAR4Wi*7j?(Fu!Zy?vroxcA&qYmdn7DGl* zNMGFk<vXJ_6XVk92EQ0pnHRFGoF4IuQJeAV_Lg6a;Y^Ghr{DR*Sgx=Y6fFTksfDGf z#U;f-sfj6-jwP-I`N<iKj4Z4YTc;QQWlUwfJN@Qg#uCQ8)BXN2$}%3Dp7W1!597t@ zn*SLsc^)z`dNN8l1Qg|0R8IG2ViMcl@}Dt{h3_GYy-a9HW=>{FB?IHj=|7m6d>Efj zcV%HpV|+P%4GU8n<J;-RtV}K<jLeLoj4}oRMfnB!#fdpi`FSZHw|BELX)`i@oxYuo zX)@!->E7&2VN5?+wl8L9VqvWR%i_q$%A(-moRONG?U$bym0FY^oSK)CTExlP;{X;7 zE=WxdOD!tS%+KRx6|ew{g;YRA1X%?Pz#{Icd8x&j#iFbV5EZ`pMJ0(K7fZ4#Xn<At z<>w`*Dzf(IfO+AmnduoNin^>l3C<abMd_&_MTvREiOHZYYd~UUZfahMA#0B+D*zgY B(eeNQ delta 5005 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 SrR;#j%G}hv5=+(|T~+`eM+zJO diff --git a/runtime/common/src/entities.rs b/runtime/common/src/entities.rs index 823ae2a71..7ee895b7f 100644 --- a/runtime/common/src/entities.rs +++ b/runtime/common/src/entities.rs @@ -14,7 +14,6 @@ // 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 super::AccountId; use frame_support::pallet_prelude::*; use scale_info::TypeInfo; #[cfg(feature = "std")] @@ -34,40 +33,6 @@ macro_rules! declare_session_keys { pub authority_discovery: AuthorityDiscovery, } } - - #[derive(Clone, codec::Decode, Debug, codec::Encode, Eq, PartialEq)] - pub struct SessionKeysWrapper(pub SessionKeys); - - impl From<SessionKeysWrapper> for SessionKeys { - fn from(keys_wrapper: SessionKeysWrapper) -> SessionKeys { - keys_wrapper.0 - } - } - impl From<SessionKeys> for SessionKeysWrapper { - fn from(session_keys: SessionKeys) -> SessionKeysWrapper { - SessionKeysWrapper(session_keys) - } - } - - impl scale_info::TypeInfo for SessionKeysWrapper { - type Identity = [u8; 128]; - - fn type_info() -> scale_info::Type { - Self::Identity::type_info() - } - } - - // Dummy implementation only for benchmarking - impl Default for SessionKeysWrapper { - fn default() -> Self { - SessionKeysWrapper(SessionKeys{ - grandpa: sp_core::ed25519::Public([0u8; 32]).into(), - babe: sp_core::sr25519::Public([0u8; 32]).into(), - im_online: sp_core::sr25519::Public([0u8; 32]).into(), - authority_discovery: sp_core::sr25519::Public([0u8; 32]).into(), - }) - } - } } } } @@ -94,42 +59,6 @@ impl From<IdtyData> for pallet_universal_dividend::FirstEligibleUd { } } -#[cfg_attr(feature = "std", derive(Deserialize, Serialize))] -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct SmithMembershipMetaData<SessionKeysWrapper> { - pub owner_key: AccountId, - pub p2p_endpoint: sp_runtime::RuntimeString, - pub session_keys: SessionKeysWrapper, -} - -impl<SessionKeysWrapper: Default> Default for SmithMembershipMetaData<SessionKeysWrapper> { - #[cfg(not(feature = "runtime-benchmarks"))] - fn default() -> Self { - unreachable!() - } - #[cfg(feature = "runtime-benchmarks")] - // dummy implementation for benchmarking - fn default() -> Self { - SmithMembershipMetaData { - owner_key: AccountId::from([ - // Dave (FIXME avoid stupid metadata) - 48, 103, 33, 33, 29, 84, 4, 189, 157, 168, 142, 2, 4, 54, 10, 26, 154, 184, 184, - 124, 102, 193, 188, 47, 205, 211, 127, 60, 34, 34, 204, 32, - ]), - p2p_endpoint: sp_runtime::RuntimeString::default(), - session_keys: SessionKeysWrapper::default(), - } - } -} - -impl<SessionKeysWrapper> sp_membership::traits::Validate<AccountId> - for SmithMembershipMetaData<SessionKeysWrapper> -{ - fn validate(&self, who: &AccountId) -> bool { - &self.owner_key == who - } -} - #[cfg_attr(feature = "std", derive(Deserialize, Serialize))] #[derive( Encode, Decode, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, TypeInfo, diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs index e05a97d4f..540054ab3 100644 --- a/runtime/common/src/handlers.rs +++ b/runtime/common/src/handlers.rs @@ -71,14 +71,14 @@ where // membership event runtime handler pub struct OnMembershipEventHandler<Inner, Runtime>(core::marker::PhantomData<(Inner, Runtime)>); impl< - Inner: sp_membership::traits::OnEvent<IdtyIndex, ()>, + Inner: sp_membership::traits::OnEvent<IdtyIndex>, Runtime: frame_system::Config<AccountId = AccountId> + pallet_identity::Config<IdtyData = IdtyData, IdtyIndex = IdtyIndex> - + pallet_membership::Config<Instance1, MetaData = ()> + + pallet_membership::Config<Instance1> + pallet_universal_dividend::Config, - > sp_membership::traits::OnEvent<IdtyIndex, ()> for OnMembershipEventHandler<Inner, Runtime> + > sp_membership::traits::OnEvent<IdtyIndex> for OnMembershipEventHandler<Inner, Runtime> { - fn on_event(membership_event: &sp_membership::Event<IdtyIndex, ()>) -> Weight { + fn on_event(membership_event: &sp_membership::Event<IdtyIndex>) -> Weight { (match membership_event { // when membership is removed, call on_removed_member handler which auto claims UD sp_membership::Event::MembershipRevoked(idty_index) @@ -97,7 +97,7 @@ impl< } } // when main membership is acquired, it starts getting right to UD - sp_membership::Event::MembershipAcquired(idty_index, _) => { + sp_membership::Event::MembershipAcquired(idty_index) => { pallet_identity::Identities::<Runtime>::mutate_exists(idty_index, |idty_val_opt| { if let Some(ref mut idty_val) = idty_val_opt { idty_val.data = IdtyData { @@ -123,43 +123,18 @@ pub struct OnSmithMembershipEventHandler<Inner, Runtime>( ); impl< IdtyIndex: Copy + Parameter, - SessionKeysWrapper: Clone, - Inner: sp_membership::traits::OnEvent<IdtyIndex, SmithMembershipMetaData<SessionKeysWrapper>>, + Inner: sp_membership::traits::OnEvent<IdtyIndex>, Runtime: frame_system::Config<AccountId = AccountId> + pallet_identity::Config<IdtyIndex = IdtyIndex> - + pallet_authority_members::Config<KeysWrapper = SessionKeysWrapper, MemberId = IdtyIndex> - + pallet_membership::Config< - Instance2, - MetaData = SmithMembershipMetaData<SessionKeysWrapper>, - >, - > sp_membership::traits::OnEvent<IdtyIndex, SmithMembershipMetaData<SessionKeysWrapper>> - for OnSmithMembershipEventHandler<Inner, Runtime> + + pallet_authority_members::Config<MemberId = IdtyIndex> + + pallet_membership::Config<Instance2>, + > sp_membership::traits::OnEvent<IdtyIndex> for OnSmithMembershipEventHandler<Inner, Runtime> { - fn on_event( - membership_event: &sp_membership::Event< - IdtyIndex, - SmithMembershipMetaData<SessionKeysWrapper>, - >, - ) -> Weight { + fn on_event(membership_event: &sp_membership::Event<IdtyIndex>) -> Weight { (match membership_event { - sp_membership::Event::MembershipAcquired( - _idty_index, - SmithMembershipMetaData { - owner_key, - session_keys, - .. - }, - ) => { - let call = pallet_authority_members::Call::<Runtime>::set_session_keys { - keys: session_keys.clone(), - }; - if let Err(e) = call.dispatch_bypass_filter( - frame_system::Origin::<Runtime>::Signed(owner_key.clone()).into(), - ) { - sp_std::if_std! { - println!("fail to set session keys: {:?}", e) - } - } + sp_membership::Event::MembershipAcquired(_idty_index) => { + // nothing when smith membership acquired + // user will have to claim authority membership Weight::zero() } sp_membership::Event::MembershipRevoked(idty_index) => { diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs index 6b4954128..80efaf60f 100644 --- a/runtime/common/src/pallets_config.rs +++ b/runtime/common/src/pallets_config.rs @@ -236,7 +236,6 @@ macro_rules! pallets_config { } impl pallet_authority_members::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type KeysWrapper = opaque::SessionKeysWrapper; type IsMember = SmithMembership; type OnNewSession = OnNewSessionHandler<Runtime>; type OnRemovedMember = OnRemovedAuthorityMemberHandler<Runtime>; @@ -488,7 +487,6 @@ macro_rules! pallets_config { type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>; type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>; type MembershipPeriod = MembershipPeriod; - type MetaData = (); type OnEvent = OnMembershipEventHandler<Wot, Runtime>; type PendingMembershipPeriod = PendingMembershipPeriod; type RuntimeEvent = RuntimeEvent; @@ -538,7 +536,6 @@ macro_rules! pallets_config { type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>; type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>; type MembershipPeriod = SmithMembershipPeriod; - type MetaData = SmithMembershipMetaData<opaque::SessionKeysWrapper>; type OnEvent = OnSmithMembershipEventHandler<SmithSubWot, Runtime>; type PendingMembershipPeriod = SmithPendingMembershipPeriod; type RuntimeEvent = RuntimeEvent; diff --git a/runtime/gdev/tests/fixme_tests.rs b/runtime/gdev/tests/fixme_tests.rs new file mode 100644 index 000000000..28b9777e8 --- /dev/null +++ b/runtime/gdev/tests/fixme_tests.rs @@ -0,0 +1,75 @@ +// Copyright 2021 Axiom-Team +// +// This file is part of Duniter-v2S. +// +// Duniter-v2S is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// Duniter-v2S is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// 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/>. + +// these integration tests show current behavior that is counter-intuitive or outside specs +// they should failed after the related issue is fixed + +mod common; + +use common::*; +use frame_support::assert_ok; +use gdev_runtime::*; +use sp_keyring::AccountKeyring; + +/// issue #136 +/// a smith should not be able to add a smith cert to an +/// identity who has no smith membership or pending membership +#[test] +fn can_add_smith_cert_without_pending_membership_or_membership() { + // 3 smith (1. Alice, 2. Bob, 3. Charlie) + // 4 identities (4. Dave) + ExtBuilder::new(1, 3, 4).build().execute_with(|| { + run_to_block(1); + + // FIXME Bob can add new smith cert to to dave even he did not requested smith membership + assert_ok!(SmithCert::add_cert( + frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(), + 2, // bob + 4 // dave + )); + }); +} + +/// issue #136 +/// an identity should not be able to add cert +/// when its membership is suspended +#[test] +fn can_still_issue_cert_when_membership_lost() { + ExtBuilder::new(1, 3, 4).build().execute_with(|| { + run_to_block(1); + + // expire Bob membership (could happen for negative distance evaluation for example) + assert_ok!(Membership::force_expire_membership( + 2, // Bob + )); + System::assert_has_event(RuntimeEvent::Membership( + pallet_membership::Event::MembershipExpired(2), + )); + + // FIXME this should not be possible + assert_ok!(Cert::add_cert( + frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(), + 2, // Bob + 3, // Charlie + )); + System::assert_has_event(RuntimeEvent::Cert( + pallet_certification::Event::RenewedCert { + issuer: 2, + receiver: 3, + }, + )); + }); +} diff --git a/runtime/gdev/tests/integration_tests.rs b/runtime/gdev/tests/integration_tests.rs index b05256314..982a7ccc9 100644 --- a/runtime/gdev/tests/integration_tests.rs +++ b/runtime/gdev/tests/integration_tests.rs @@ -676,14 +676,6 @@ fn test_smith_certification() { 2 // bob )); - // THIS IS STRANGE BEHAVIOR - // bob can add new smith cert to to dave even he did not requested smith membership - assert_ok!(SmithCert::add_cert( - frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(), - 2, // bob - 4 // dave - )); - // charlie can not add new cert to eve (no identity) assert_noop!( SmithCert::add_cert( @@ -697,6 +689,64 @@ fn test_smith_certification() { }); } +/// test the full process to join smith from main wot member to authority member +#[test] +fn test_smith_process() { + ExtBuilder::new(1, 3, 4).with_initial_balances(vec![(AccountKeyring::Dave.to_account_id(), 1_000)]) + .build().execute_with(|| { + run_to_block(1); + + let alice = AccountKeyring::Alice.to_account_id(); + let bob = AccountKeyring::Bob.to_account_id(); + let charlie = AccountKeyring::Charlie.to_account_id(); + + // Eve can not request smith membership because not member of the smith wot + assert_noop!(SmithMembership::request_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into()), + pallet_membership::Error::<gdev_runtime::Runtime, pallet_membership::Instance2>::IdtyIdNotFound, + ); + + // Dave can request smith membership (currently optional) + assert_ok!(SmithMembership::request_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), + )); + + assert_eq!(SmithMembership::pending_membership(5), None); // none for Eve + assert_eq!(SmithMembership::pending_membership(4), Some(())); // Dave + + // then Alice Bob and Charlie can certify Dave + assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(alice).into(), 1, 4)); + assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(bob).into(), 2, 4)); + assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(charlie).into(), 3, 4)); + + // with these three smith certs, Dave can claim membership + assert_ok!(SmithMembership::claim_membership( + frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), + )); + + // Dave is then member of the smith wot + assert_eq!(SmithMembership::membership(4), Some(sp_membership::MembershipData { + expire_on: 1001, // 1 + 1000 + })); + + // Dave can set his (dummy) session keys + assert_ok!(AuthorityMembers::set_session_keys( + frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), + gdev_runtime::opaque::SessionKeys{ + grandpa: sp_core::ed25519::Public([0u8; 32]).into(), + babe: sp_core::sr25519::Public([0u8; 32]).into(), + im_online: sp_core::sr25519::Public([0u8; 32]).into(), + authority_discovery: sp_core::sr25519::Public([0u8; 32]).into(), + } + )); + + // Dave can go online + assert_ok!(AuthorityMembers::go_online( + frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(), + )); + }) +} + /// test create new account with balance lower than existential deposit // the treasury gets the dust #[test] -- GitLab