From b3f3487d7bce2b1613dceb15afc4a6293c9cbc60 Mon Sep 17 00:00:00 2001 From: librelois <c@elo.tf> Date: Tue, 25 Jan 2022 20:51:27 +0100 Subject: [PATCH] feat(certs): don't ask for idty index anymore --- pallets/certification/src/lib.rs | 180 +++++++++++++++++---------- pallets/certification/src/mock.rs | 4 +- pallets/certification/src/tests.rs | 32 ++--- pallets/certification/src/traits.rs | 10 ++ pallets/certification/src/types.rs | 2 +- pallets/duniter-wot/src/lib.rs | 71 +++++++---- pallets/duniter-wot/src/mock.rs | 6 +- pallets/duniter-wot/src/tests.rs | 12 +- pallets/duniter-wot/src/types.rs | 77 +----------- pallets/identity/src/lib.rs | 6 + pallets/membership/src/lib.rs | 1 + runtime/common/src/pallets_config.rs | 8 +- runtime/gdev/src/lib.rs | 92 +++++++------- 13 files changed, 257 insertions(+), 244 deletions(-) diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs index 82571189f..a1d6063bb 100644 --- a/pallets/certification/src/lib.rs +++ b/pallets/certification/src/lib.rs @@ -39,7 +39,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use sp_runtime::traits::Saturating; + use sp_runtime::traits::{Convert, Saturating}; use sp_std::collections::btree_map::BTreeMap; /// The current storage version. @@ -52,13 +52,9 @@ pub mod pallet { #[pallet::config] pub trait Config<I: 'static = ()>: frame_system::Config { - /// Origin allowed to add a certification - type AddCertOrigin: EnsureOrigin<(Self::Origin, Self::IdtyIndex, Self::IdtyIndex)>; #[pallet::constant] /// Minimum duration between two certifications issued by the same issuer type CertPeriod: Get<Self::BlockNumber>; - /// Origin allowed to delete a certification - type DelCertOrigin: EnsureOrigin<(Self::Origin, Self::IdtyIndex, Self::IdtyIndex)>; /// Because this pallet emits events, it depends on the runtime's definition of an event. type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>; /// A short identity index. @@ -71,6 +67,10 @@ pub mod pallet { + MaybeSerializeDeserialize + Debug + MaxEncodedLen; + /// Something that give the IdtyIndex on an account id + type IdtyIndexOf: Convert<Self::AccountId, Option<Self::IdtyIndex>>; + /// + type IsCertAllowed: IsCertAllowed<Self::IdtyIndex>; #[pallet::constant] /// Maximum number of active certifications by issuer type MaxByIssuer: Get<u32>; @@ -199,7 +199,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn idty_cert_meta)] pub type StorageIdtyCertMeta<T: Config<I>, I: 'static = ()> = - StorageMap<_, Twox64Concat, T::IdtyIndex, IdtyCertMeta<T::BlockNumber>, OptionQuery>; + StorageMap<_, Twox64Concat, T::IdtyIndex, IdtyCertMeta<T::BlockNumber>, ValueQuery>; /// Certifications by issuer #[pallet::storage] @@ -259,10 +259,16 @@ pub mod pallet { #[pallet::error] pub enum Error<T, I = ()> { + /// Certification non autorisée + CertNotAllowed, + /// Issuer not found + IssuerNotFound, /// An identity must receive certifications before it can issue them. IdtyMustReceiveCertsBeforeCanIssue, /// This identity has already issued the maximum number of certifications IssuedTooManyCert, + /// Receiver not found + ReceiverNotFound, /// Not enough certifications received NotEnoughCertReceived, /// This certification has already been issued or renewed recently @@ -283,26 +289,22 @@ pub mod pallet { #[pallet::call] impl<T: Config<I>, I: 'static> Pallet<T, I> { #[pallet::weight(0)] - pub fn add_cert( + pub fn force_add_cert( origin: OriginFor<T>, issuer: T::IdtyIndex, receiver: T::IdtyIndex, + verify_rules: bool, ) -> DispatchResultWithPostInfo { - T::AddCertOrigin::ensure_origin((origin, issuer, receiver))?; - frame_support::runtime_print!("add_cert({:?}, {:?}): origin OK", issuer, receiver); + ensure_root(origin)?; let block_number = frame_system::pallet::Pallet::<T>::block_number(); - let (create, issuer_issued_count) = if let Ok(mut issuer_idty_cert_meta) = - <StorageIdtyCertMeta<T, I>>::try_get(issuer) - { + let create = if verify_rules { + let issuer_idty_cert_meta = <StorageIdtyCertMeta<T, I>>::get(issuer); + if issuer_idty_cert_meta.received_count == 0 { + return Err(Error::<T, I>::IdtyMustReceiveCertsBeforeCanIssue.into()); + } // Verify rules CertPeriod and MaxByIssuer - frame_support::runtime_print!( - "add_cert({:?}, {:?}): Verify rules CertPeriod and MaxByIssuer", - issuer, - receiver - ); - if issuer_idty_cert_meta.received_count < T::MinReceivedCertToBeAbleToIssueCert::get() { @@ -314,12 +316,7 @@ pub mod pallet { } // Verify rule CertRenewablePeriod - frame_support::runtime_print!( - "add_cert({:?}, {:?}): Verify rule CertRenewablePeriod", - issuer, - receiver - ); - let create = if let Ok(CertValue { renewable_on, .. }) = + if let Ok(CertValue { renewable_on, .. }) = <StorageCertsByIssuer<T, I>>::try_get(issuer, receiver) { if renewable_on > block_number { @@ -328,27 +325,102 @@ pub mod pallet { false } else { true - }; + } + } else { + !StorageCertsByIssuer::<T, I>::contains_key(issuer, receiver) + }; - // Write StorageIdtyCertMeta for issuer - issuer_idty_cert_meta.issued_count = - issuer_idty_cert_meta.issued_count.saturating_add(1); - let issuer_issued_count = issuer_idty_cert_meta.issued_count; - issuer_idty_cert_meta.next_issuable_on = block_number + T::CertPeriod::get(); - <StorageIdtyCertMeta<T, I>>::insert(issuer, issuer_idty_cert_meta); + Self::do_add_cert(block_number, create, issuer, receiver) + } + #[pallet::weight(0)] + pub fn add_cert( + origin: OriginFor<T>, + receiver: T::AccountId, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let issuer = T::IdtyIndexOf::convert(who).ok_or(Error::<T, I>::IssuerNotFound)?; + let receiver = + T::IdtyIndexOf::convert(receiver).ok_or(Error::<T, I>::ReceiverNotFound)?; + if !T::IsCertAllowed::is_cert_allowed(issuer, receiver) { + return Err(Error::<T, I>::CertNotAllowed.into()); + } - (create, issuer_issued_count) - } else { - // An identity must receive certifications before it can issue them. + let issuer_idty_cert_meta = <StorageIdtyCertMeta<T, I>>::get(issuer); + if issuer_idty_cert_meta.received_count == 0 { return Err(Error::<T, I>::IdtyMustReceiveCertsBeforeCanIssue.into()); + } + + let block_number = frame_system::pallet::Pallet::<T>::block_number(); + + // Verify rules CertPeriod and MaxByIssuer + if issuer_idty_cert_meta.received_count < T::MinReceivedCertToBeAbleToIssueCert::get() { + return Err(Error::<T, I>::NotEnoughCertReceived.into()); + } else if issuer_idty_cert_meta.next_issuable_on > block_number { + return Err(Error::<T, I>::NotRespectCertPeriod.into()); + } else if issuer_idty_cert_meta.issued_count >= T::MaxByIssuer::get() { + return Err(Error::<T, I>::IssuedTooManyCert.into()); + } + + // Verify rule CertRenewablePeriod + let create = if let Ok(CertValue { renewable_on, .. }) = + <StorageCertsByIssuer<T, I>>::try_get(issuer, receiver) + { + if renewable_on > block_number { + return Err(Error::<T, I>::NotRespectRenewablePeriod.into()); + } + false + } else { + true }; + Self::do_add_cert(block_number, create, issuer, receiver) + } + + #[pallet::weight(0)] + pub fn del_cert( + origin: OriginFor<T>, + issuer: T::IdtyIndex, + receiver: T::IdtyIndex, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + Self::remove_cert_inner(issuer, receiver, None); + Ok(().into()) + } + + #[pallet::weight(0)] + pub fn remove_all_certs_received_by( + origin: OriginFor<T>, + idty_index: T::IdtyIndex, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + if let Ok(issuers) = <StorageCertsByReceiver<T, I>>::try_get(idty_index) { + for issuer in issuers { + Self::remove_cert_inner(issuer, idty_index, None); + } + } + Ok(().into()) + } + } + + // INTERNAL FUNCTIONS // + + impl<T: Config<I>, I: 'static> Pallet<T, I> { + fn do_add_cert( + block_number: T::BlockNumber, + create: bool, + issuer: T::IdtyIndex, + receiver: T::IdtyIndex, + ) -> DispatchResultWithPostInfo { + // Write StorageIdtyCertMeta for issuer + let issuer_issued_count = + StorageIdtyCertMeta::<T, I>::mutate(issuer, |issuer_idty_cert_meta| { + issuer_idty_cert_meta.issued_count = + issuer_idty_cert_meta.issued_count.saturating_add(1); + issuer_idty_cert_meta.next_issuable_on = block_number + T::CertPeriod::get(); + issuer_idty_cert_meta.issued_count + }); + // Write StorageIdtyCertMeta for receiver - frame_support::runtime_print!( - "add_cert({:?}, {:?}): Write StorageIdtyCertMeta for receiver", - issuer, - receiver - ); let receiver_received_count = <StorageIdtyCertMeta<T, I>>::mutate_exists(receiver, |cert_meta_opt| { let cert_meta = cert_meta_opt.get_or_insert(IdtyCertMeta::default()); @@ -390,36 +462,6 @@ pub mod pallet { Ok(().into()) } - - #[pallet::weight(0)] - pub fn del_cert( - origin: OriginFor<T>, - issuer: T::IdtyIndex, - receiver: T::IdtyIndex, - ) -> DispatchResultWithPostInfo { - T::DelCertOrigin::ensure_origin((origin, issuer, receiver))?; - Self::remove_cert_inner(issuer, receiver, None); - Ok(().into()) - } - - #[pallet::weight(0)] - pub fn remove_all_certs_received_by( - origin: OriginFor<T>, - idty_index: T::IdtyIndex, - ) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - if let Ok(issuers) = <StorageCertsByReceiver<T, I>>::try_get(idty_index) { - for issuer in issuers { - Self::remove_cert_inner(issuer, idty_index, None); - } - } - Ok(().into()) - } - } - - // INTERNAL FUNCTIONS // - - impl<T: Config<I>, I: 'static> Pallet<T, I> { fn prune_certifications(block_number: T::BlockNumber) -> Weight { let mut total_weight: Weight = 0; diff --git a/pallets/certification/src/mock.rs b/pallets/certification/src/mock.rs index 53cd1347a..b33804637 100644 --- a/pallets/certification/src/mock.rs +++ b/pallets/certification/src/mock.rs @@ -100,11 +100,11 @@ parameter_types! { } impl pallet_certification::Config for Test { - type AddCertOrigin = EnsureRoot; type CertPeriod = CertPeriod; - type DelCertOrigin = EnsureRoot; type Event = Event; type IdtyIndex = IdtyIndex; + type IdtyIndexOf = sp_runtime::traits::ConvertInto; + type IsCertAllowed = (); type MaxByIssuer = MaxByIssuer; type MinReceivedCertToBeAbleToIssueCert = MinReceivedCertToBeAbleToIssueCert; type OnNewcert = (); diff --git a/pallets/certification/src/tests.rs b/pallets/certification/src/tests.rs index 030a6d6d3..25b32f01b 100644 --- a/pallets/certification/src/tests.rs +++ b/pallets/certification/src/tests.rs @@ -30,7 +30,7 @@ fn test_must_receive_cert_before_can_issue() { }) .execute_with(|| { assert_eq!( - DefaultCertification::add_cert(Origin::root(), 0, 1), + DefaultCertification::add_cert(Origin::signed(0), 1), Err(Error::<Test, _>::IdtyMustReceiveCertsBeforeCanIssue.into()) ); }); @@ -60,29 +60,29 @@ fn test_genesis_build() { // Verify state of idty 0 assert_eq!( DefaultCertification::idty_cert_meta(0), - Some(crate::IdtyCertMeta { + crate::IdtyCertMeta { issued_count: 2, next_issuable_on: 2, received_count: 2, - }) + } ); // Verify state of idty 1 assert_eq!( DefaultCertification::idty_cert_meta(1), - Some(crate::IdtyCertMeta { + crate::IdtyCertMeta { issued_count: 2, next_issuable_on: 0, received_count: 2, - }) + } ); // Verify state of idty 2 assert_eq!( DefaultCertification::idty_cert_meta(2), - Some(crate::IdtyCertMeta { + crate::IdtyCertMeta { issued_count: 2, next_issuable_on: 1, received_count: 2, - }) + } ); // Cert 2->1 must be removable at block #3 assert_eq!( @@ -91,7 +91,7 @@ fn test_genesis_build() { ); // Cert 2->0 cannot be renewed before #5 assert_eq!( - DefaultCertification::add_cert(Origin::root(), 2, 0), + DefaultCertification::add_cert(Origin::signed(2), 0), Err(Error::<Test, _>::NotRespectRenewablePeriod.into()) ); @@ -122,18 +122,18 @@ fn test_cert_period() { }) .execute_with(|| { assert_eq!( - DefaultCertification::add_cert(Origin::root(), 0, 2), + DefaultCertification::add_cert(Origin::signed(0), 2), Err(Error::<Test, _>::NotRespectCertPeriod.into()) ); run_to_block(CertPeriod::get()); - assert_ok!(DefaultCertification::add_cert(Origin::root(), 0, 2)); + assert_ok!(DefaultCertification::add_cert(Origin::signed(0), 2)); run_to_block(CertPeriod::get() + 1); assert_eq!( - DefaultCertification::add_cert(Origin::root(), 0, 3), + DefaultCertification::add_cert(Origin::signed(0), 3), Err(Error::<Test, _>::NotRespectCertPeriod.into()) ); run_to_block((2 * CertPeriod::get()) + 1); - assert_ok!(DefaultCertification::add_cert(Origin::root(), 0, 3)); + assert_ok!(DefaultCertification::add_cert(Origin::signed(0), 3)); }); } @@ -150,17 +150,17 @@ fn test_renewable_period() { .execute_with(|| { run_to_block(CertPeriod::get()); assert_eq!( - DefaultCertification::add_cert(Origin::root(), 0, 1), + DefaultCertification::add_cert(Origin::signed(0), 1), Err(Error::<Test, _>::NotRespectRenewablePeriod.into()) ); run_to_block(RenewablePeriod::get()); - assert_ok!(DefaultCertification::add_cert(Origin::root(), 0, 1)); + assert_ok!(DefaultCertification::add_cert(Origin::signed(0), 1)); run_to_block(RenewablePeriod::get() + CertPeriod::get()); assert_eq!( - DefaultCertification::add_cert(Origin::root(), 0, 1), + DefaultCertification::add_cert(Origin::signed(0), 1), Err(Error::<Test, _>::NotRespectRenewablePeriod.into()) ); run_to_block((2 * RenewablePeriod::get()) + 1); - assert_ok!(DefaultCertification::add_cert(Origin::root(), 0, 1)); + assert_ok!(DefaultCertification::add_cert(Origin::signed(0), 1)); }); } diff --git a/pallets/certification/src/traits.rs b/pallets/certification/src/traits.rs index cde9ade86..ebcd7aef4 100644 --- a/pallets/certification/src/traits.rs +++ b/pallets/certification/src/traits.rs @@ -14,6 +14,16 @@ // You should have received a copy of the GNU Affero General Public License // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>. +pub trait IsCertAllowed<IdtyIndex> { + fn is_cert_allowed(issuer: IdtyIndex, receiver: IdtyIndex) -> bool; +} + +impl<IdtyIndex> IsCertAllowed<IdtyIndex> for () { + fn is_cert_allowed(_issuer: IdtyIndex, _receiver: IdtyIndex) -> bool { + true + } +} + pub trait OnNewcert<IdtyIndex> { fn on_new_cert( issuer: IdtyIndex, diff --git a/pallets/certification/src/types.rs b/pallets/certification/src/types.rs index daf5d954f..d1b858f9f 100644 --- a/pallets/certification/src/types.rs +++ b/pallets/certification/src/types.rs @@ -27,7 +27,7 @@ pub struct CertValue<BlockNumber> { } #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)] -pub struct IdtyCertMeta<BlockNumber> { +pub struct IdtyCertMeta<BlockNumber: Default> { pub issued_count: u32, pub next_issuable_on: BlockNumber, pub received_count: u32, diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs index f74ff0d0b..b2e70823f 100644 --- a/pallets/duniter-wot/src/lib.rs +++ b/pallets/duniter-wot/src/lib.rs @@ -131,13 +131,10 @@ where + pallet_membership::Config<I, MetaData = MembershipMetaData<AccountId>>, { fn can_create_identity(creator: IdtyIndex) -> bool { - if let Some(cert_meta) = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator) { - cert_meta.received_count >= T::MinCertForCreateIdtyRight::get() - && cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number() - && cert_meta.issued_count < T::MaxByIssuer::get() - } else { - false - } + let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator); + cert_meta.received_count >= T::MinCertForCreateIdtyRight::get() + && cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number() + && cert_meta.issued_count < T::MaxByIssuer::get() } fn can_confirm_identity(idty_index: IdtyIndex, owner_key: AccountId) -> bool { pallet_membership::Pallet::<T, I>::request_membership( @@ -156,6 +153,39 @@ where } } +impl<T: Config<I>, I: 'static> pallet_certification::traits::IsCertAllowed<IdtyIndex> + for Pallet<T, I> +{ + fn is_cert_allowed(issuer: IdtyIndex, receiver: IdtyIndex) -> bool { + if let Some(issuer_data) = pallet_identity::Pallet::<T>::identity(issuer) { + if issuer_data.status != IdtyStatus::Validated { + return false; + } + if let Some(receiver_data) = pallet_identity::Pallet::<T>::identity(receiver) { + match receiver_data.status { + IdtyStatus::ConfirmedByOwner => true, + IdtyStatus::Created => false, + IdtyStatus::Disabled => { + pallet_membership::Pallet::<T, I>::is_in_pending_memberships(receiver) + } + IdtyStatus::Validated => { + pallet_membership::Pallet::<T, I>::is_member(&receiver) + || pallet_membership::Pallet::<T, I>::is_in_pending_memberships( + receiver, + ) + } + } + } else { + // Receiver not found + false + } + } else { + // Issuer not found + false + } + } +} + impl<T: Config<I>, I: 'static> sp_membership::traits::IsIdtyAllowedToRenewMembership<IdtyIndex> for Pallet<T, I> { @@ -207,20 +237,18 @@ where } sp_membership::Event::<IdtyIndex, MetaData>::MembershipRenewed(_) => {} sp_membership::Event::<IdtyIndex, MetaData>::MembershipRequested(idty_index) => { - if let Some(idty_cert_meta) = - pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index) - { - let received_count = idty_cert_meta.received_count; + let idty_cert_meta = + pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index); + let received_count = idty_cert_meta.received_count; - // TODO insert `receiver` in distance queue if received_count >= MinCertForMembership - if received_count >= T::MinCertForMembership::get() as u32 { - // TODO insert `receiver` in distance queue - if Self::dispath_idty_call(pallet_identity::Call::validate_identity { - idty_index: *idty_index, - }) && received_count == T::MinReceivedCertToBeAbleToIssueCert::get() - { - Self::do_apply_first_issuable_on(*idty_index); - } + // TODO insert `receiver` in distance queue if received_count >= MinCertForMembership + if received_count >= T::MinCertForMembership::get() as u32 { + // TODO insert `receiver` in distance queue + if Self::dispath_idty_call(pallet_identity::Call::validate_identity { + idty_index: *idty_index, + }) && received_count == T::MinReceivedCertToBeAbleToIssueCert::get() + { + Self::do_apply_first_issuable_on(*idty_index); } } } @@ -239,10 +267,11 @@ impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pall fn on_idty_change(idty_index: IdtyIndex, idty_event: IdtyEvent<T>) -> Weight { match idty_event { IdtyEvent::Created { creator } => { - if let Err(e) = <pallet_certification::Pallet<T, I>>::add_cert( + if let Err(e) = <pallet_certification::Pallet<T, I>>::force_add_cert( frame_system::Origin::<T>::Root.into(), creator, idty_index, + true, ) { sp_std::if_std! { println!("{:?}", e) diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs index 8534b70dc..e0683621f 100644 --- a/pallets/duniter-wot/src/mock.rs +++ b/pallets/duniter-wot/src/mock.rs @@ -148,18 +148,18 @@ impl pallet_membership::Config<Instance1> for Test { // Cert parameter_types! { pub const MaxByIssuer: u8 = 8; - pub const MinReceivedCertToBeAbleToIssueCert: u32 = 3; + pub const MinReceivedCertToBeAbleToIssueCert: u32 = 2; pub const CertRenewablePeriod: u64 = 4; pub const CertPeriod: u64 = 2; pub const ValidityPeriod: u64 = 10; } impl pallet_certification::Config<Instance1> for Test { - type AddCertOrigin = pallet_duniter_wot::AddCertOrigin<Test, Instance1>; type CertPeriod = CertPeriod; - type DelCertOrigin = pallet_duniter_wot::DelCertOrigin<Test, Instance1>; type Event = Event; type IdtyIndex = IdtyIndex; + type IdtyIndexOf = Identity; + type IsCertAllowed = DuniterWot; type MaxByIssuer = MaxByIssuer; type MinReceivedCertToBeAbleToIssueCert = MinReceivedCertToBeAbleToIssueCert; type OnNewcert = DuniterWot; diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs index 8176a1e17..8d420ccee 100644 --- a/pallets/duniter-wot/src/tests.rs +++ b/pallets/duniter-wot/src/tests.rs @@ -19,7 +19,6 @@ use crate::mock::*; use crate::WotDiff; use frame_support::assert_err; use frame_support::assert_ok; -use frame_support::error::BadOrigin; use frame_support::instances::Instance1; use frame_system::{EventRecord, Phase}; use pallet_identity::{IdtyName, IdtyStatus}; @@ -32,9 +31,7 @@ fn test_genesis_build() { assert_eq!(Identity::identities_count(), 3); assert_eq!(Identity::identity(1).unwrap().next_creatable_identity_on, 0); assert_eq!( - pallet_certification::Pallet::<Test, Instance1>::idty_cert_meta(1) - .unwrap() - .next_issuable_on, + pallet_certification::Pallet::<Test, Instance1>::idty_cert_meta(1).next_issuable_on, 2 ); }); @@ -110,7 +107,7 @@ fn test_new_idty_validation() { // Bob should be able to certify Ferdie run_to_block(4); - assert_ok!(Cert::add_cert(Origin::signed(2), 2, 6)); + assert_ok!(Cert::add_cert(Origin::signed(2), 6)); let events = System::events(); // 3 events should have occurred: NewCert, MembershipAcquired and IdtyValidated @@ -229,7 +226,10 @@ fn test_idty_membership_expire_them_requested() { assert_eq!(Identity::identity(3).unwrap().status, IdtyStatus::Disabled); // Alice can't renew it's cert to Charlie - assert_err!(Cert::add_cert(Origin::signed(1), 1, 3), BadOrigin); + assert_err!( + Cert::add_cert(Origin::signed(1), 3), + pallet_certification::Error::<Test, Instance1>::CertNotAllowed + ); // Charlie should be able to request membership run_to_block(6); diff --git a/pallets/duniter-wot/src/types.rs b/pallets/duniter-wot/src/types.rs index 639eda216..c70663fb2 100644 --- a/pallets/duniter-wot/src/types.rs +++ b/pallets/duniter-wot/src/types.rs @@ -14,83 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>. -use crate::{Config, IdtyIndex}; +use crate::IdtyIndex; use frame_support::pallet_prelude::*; -use pallet_identity::IdtyStatus; -use sp_membership::traits::IsInPendingMemberships; -use sp_runtime::traits::IsMember; - -pub struct AddCertOrigin<T, I>(core::marker::PhantomData<(T, I)>); -impl<T: Config<I>, I: 'static> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> - for AddCertOrigin<T, I> -{ - type Success = (); - - fn try_origin( - o: (T::Origin, IdtyIndex, IdtyIndex), - ) -> Result<Self::Success, (T::Origin, IdtyIndex, IdtyIndex)> { - match o.0.clone().into() { - Ok(frame_system::RawOrigin::Root) => Ok(()), - Ok(frame_system::RawOrigin::Signed(who)) => { - if let Some(idty_index) = pallet_identity::Pallet::<T>::identity_index_of(who) { - if o.1 == idty_index { - if let Some(receiver) = pallet_identity::Pallet::<T>::identity(o.2) { - match receiver.status { - IdtyStatus::ConfirmedByOwner => Ok(()), - IdtyStatus::Created => Err(o), - IdtyStatus::Disabled => { - if pallet_membership::Pallet::<T, I>::is_in_pending_memberships(o.2) - { - Ok(()) - } else { - Err(o) - } - } - IdtyStatus::Validated => { - if pallet_membership::Pallet::<T, I>::is_member(&o.2) - || pallet_membership::Pallet::<T, I>::is_in_pending_memberships( - o.2, - ) - { - Ok(()) - } else { - Err(o) - } - } - } - } else { - // Receiver not found - Err(o) - } - } else { - // Bad key - Err(o) - } - } else { - // Issuer not found - Err(o) - } - } - _ => Err(o), - } - } -} - -pub struct DelCertOrigin<T, I>(core::marker::PhantomData<(T, I)>); -impl<T: Config<I>, I: 'static> EnsureOrigin<(T::Origin, IdtyIndex, IdtyIndex)> - for DelCertOrigin<T, I> -{ - type Success = (); - - fn try_origin( - o: (T::Origin, IdtyIndex, IdtyIndex), - ) -> Result<Self::Success, (T::Origin, IdtyIndex, IdtyIndex)> { - match o.0.clone().into() { - Ok(frame_system::Origin::<T>::Root) => Ok(()), - _ => Err(o), - } - } -} #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] pub struct MembershipMetaData<AccountId>(pub AccountId); diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs index 34e80c90c..9e3b7f54b 100644 --- a/pallets/identity/src/lib.rs +++ b/pallets/identity/src/lib.rs @@ -229,6 +229,10 @@ pub mod pallet { let creator_idty_val = Identities::<T>::try_get(&creator).map_err(|_| Error::<T>::IdtyNotFound)?; + if IdentityIndexOf::<T>::contains_key(&owner_key) { + return Err(Error::<T>::IdtyAlreadyCreated.into()); + } + if !T::EnsureIdtyCallAllowed::can_create_identity(creator) { return Err(Error::<T>::CreatorNotAllowedToCreateIdty.into()); } @@ -418,6 +422,8 @@ pub mod pallet { CreatorNotAllowedToCreateIdty, /// Identity already confirmed IdtyAlreadyConfirmed, + /// Identity already created + IdtyAlreadyCreated, /// Identity already validated IdtyAlreadyValidated, /// You are not allowed to create a new identity now diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs index 69b98c6f3..ee6b19d28 100644 --- a/pallets/membership/src/lib.rs +++ b/pallets/membership/src/lib.rs @@ -67,6 +67,7 @@ pub mod pallet { type ExternalizeMembershipStorage: Get<bool>; /// Something that identifies an identity type IdtyId: Copy + MaybeSerializeDeserialize + Parameter + Ord; + /// Something that give the IdtyId on an account id type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyId>>; /// Optional metadata type MetaData: Parameter + Validate<Self::AccountId>; diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs index 4bf4251a0..53a3ff52b 100644 --- a/runtime/common/src/pallets_config.rs +++ b/runtime/common/src/pallets_config.rs @@ -312,11 +312,11 @@ macro_rules! pallets_config { } impl pallet_certification::Config<Instance1> for Runtime { - type AddCertOrigin = pallet_duniter_wot::AddCertOrigin<Runtime, Instance1>; type CertPeriod = CertPeriod; - type DelCertOrigin = pallet_duniter_wot::DelCertOrigin<Runtime, Instance1>; type Event = Event; type IdtyIndex = IdtyIndex; + type IdtyIndexOf = Identity; + type IsCertAllowed = Wot; type MaxByIssuer = MaxByIssuer; type MinReceivedCertToBeAbleToIssueCert = MinReceivedCertToBeAbleToIssueCert; type OnNewcert = Wot; @@ -352,11 +352,11 @@ macro_rules! pallets_config { } impl pallet_certification::Config<Instance2> for Runtime { - type AddCertOrigin = pallet_duniter_wot::AddCertOrigin<Runtime, Instance2>; type CertPeriod = SmithCertPeriod; - type DelCertOrigin = pallet_duniter_wot::DelCertOrigin<Runtime, Instance2>; type Event = Event; type IdtyIndex = IdtyIndex; + type IdtyIndexOf = Identity; + type IsCertAllowed = SmithsSubWot; type MaxByIssuer = SmithMaxByIssuer; type MinReceivedCertToBeAbleToIssueCert = SmithMinReceivedCertToBeAbleToIssueCert; type OnNewcert = SmithsSubWot; diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs index 9532d549f..e1c00d78c 100644 --- a/runtime/gdev/src/lib.rs +++ b/runtime/gdev/src/lib.rs @@ -138,53 +138,53 @@ impl frame_support::traits::Contains<Call> for BaseCallFilter { // Configure FRAME pallets to include in runtime. common_runtime::pallets_config! { -// Dynamic parameters -pub type EpochDuration = pallet_duniter_test_parameters::BabeEpochDuration<Runtime>; -pub type CertPeriod = pallet_duniter_test_parameters::CertPeriod<Runtime>; -pub type MaxByIssuer = pallet_duniter_test_parameters::CertMaxByIssuer<Runtime>; -pub type MinReceivedCertToBeAbleToIssueCert = - pallet_duniter_test_parameters::CertMinReceivedCertToIssueCert<Runtime>; -pub type CertRenewablePeriod = pallet_duniter_test_parameters::CertRenewablePeriod<Runtime>; -pub type ValidityPeriod = pallet_duniter_test_parameters::CertValidityPeriod<Runtime>; -pub type ConfirmPeriod = pallet_duniter_test_parameters::IdtyConfirmPeriod<Runtime>; -pub type IdtyCreationPeriod = pallet_duniter_test_parameters::IdtyCreationPeriod<Runtime>; -pub type MaxDisabledPeriod = pallet_duniter_test_parameters::IdtyMaxDisabledPeriod<Runtime>; -pub type MembershipPeriod = pallet_duniter_test_parameters::MembershipPeriod<Runtime>; -pub type RenewablePeriod = pallet_duniter_test_parameters::MembershipRenewablePeriod<Runtime>; -pub type PendingMembershipPeriod = pallet_duniter_test_parameters::PendingMembershipPeriod<Runtime>; -pub type UdCreationPeriod = pallet_duniter_test_parameters::UdCreationPeriod<Runtime>; -pub type UdFirstReeval = pallet_duniter_test_parameters::UdFirstReeval<Runtime>; -pub type UdReevalPeriod = pallet_duniter_test_parameters::UdReevalPeriod<Runtime>; -pub type UdReevalPeriodInBlocks = pallet_duniter_test_parameters::UdReevalPeriodInBlocks<Runtime>; -pub type WotFirstCertIssuableOn = pallet_duniter_test_parameters::WotFirstCertIssuableOn<Runtime>; -pub type WotMinCertForMembership = pallet_duniter_test_parameters::WotMinCertForMembership<Runtime>; -pub type WotMinCertForCreateIdtyRight = - pallet_duniter_test_parameters::WotMinCertForCreateIdtyRight<Runtime>; -pub type SmithCertPeriod = pallet_duniter_test_parameters::SmithCertPeriod<Runtime>; -pub type SmithMaxByIssuer = pallet_duniter_test_parameters::SmithCertMaxByIssuer<Runtime>; -pub type SmithMinReceivedCertToBeAbleToIssueCert = - pallet_duniter_test_parameters::SmithCertMinReceivedCertToIssueCert<Runtime>; -pub type SmithCertRenewablePeriod = - pallet_duniter_test_parameters::SmithCertRenewablePeriod<Runtime>; -pub type SmithValidityPeriod = pallet_duniter_test_parameters::SmithCertValidityPeriod<Runtime>; -pub type SmithMembershipPeriod = pallet_duniter_test_parameters::SmithMembershipPeriod<Runtime>; -pub type SmithPendingMembershipPeriod = - pallet_duniter_test_parameters::SmithPendingMembershipPeriod<Runtime>; -pub type SmithRenewablePeriod = - pallet_duniter_test_parameters::SmithMembershipRenewablePeriod<Runtime>; -pub type SmithsWotFirstCertIssuableOn = - pallet_duniter_test_parameters::SmithsWotFirstCertIssuableOn<Runtime>; -pub type SmithsWotMinCertForMembership = - pallet_duniter_test_parameters::SmithsWotMinCertForMembership<Runtime>; + // Dynamic parameters + pub type EpochDuration = pallet_duniter_test_parameters::BabeEpochDuration<Runtime>; + pub type CertPeriod = pallet_duniter_test_parameters::CertPeriod<Runtime>; + pub type MaxByIssuer = pallet_duniter_test_parameters::CertMaxByIssuer<Runtime>; + pub type MinReceivedCertToBeAbleToIssueCert = + pallet_duniter_test_parameters::CertMinReceivedCertToIssueCert<Runtime>; + pub type CertRenewablePeriod = pallet_duniter_test_parameters::CertRenewablePeriod<Runtime>; + pub type ValidityPeriod = pallet_duniter_test_parameters::CertValidityPeriod<Runtime>; + pub type ConfirmPeriod = pallet_duniter_test_parameters::IdtyConfirmPeriod<Runtime>; + pub type IdtyCreationPeriod = pallet_duniter_test_parameters::IdtyCreationPeriod<Runtime>; + pub type MaxDisabledPeriod = pallet_duniter_test_parameters::IdtyMaxDisabledPeriod<Runtime>; + pub type MembershipPeriod = pallet_duniter_test_parameters::MembershipPeriod<Runtime>; + pub type RenewablePeriod = pallet_duniter_test_parameters::MembershipRenewablePeriod<Runtime>; + pub type PendingMembershipPeriod = pallet_duniter_test_parameters::PendingMembershipPeriod<Runtime>; + pub type UdCreationPeriod = pallet_duniter_test_parameters::UdCreationPeriod<Runtime>; + pub type UdFirstReeval = pallet_duniter_test_parameters::UdFirstReeval<Runtime>; + pub type UdReevalPeriod = pallet_duniter_test_parameters::UdReevalPeriod<Runtime>; + pub type UdReevalPeriodInBlocks = pallet_duniter_test_parameters::UdReevalPeriodInBlocks<Runtime>; + pub type WotFirstCertIssuableOn = pallet_duniter_test_parameters::WotFirstCertIssuableOn<Runtime>; + pub type WotMinCertForMembership = pallet_duniter_test_parameters::WotMinCertForMembership<Runtime>; + pub type WotMinCertForCreateIdtyRight = + pallet_duniter_test_parameters::WotMinCertForCreateIdtyRight<Runtime>; + pub type SmithCertPeriod = pallet_duniter_test_parameters::SmithCertPeriod<Runtime>; + pub type SmithMaxByIssuer = pallet_duniter_test_parameters::SmithCertMaxByIssuer<Runtime>; + pub type SmithMinReceivedCertToBeAbleToIssueCert = + pallet_duniter_test_parameters::SmithCertMinReceivedCertToIssueCert<Runtime>; + pub type SmithCertRenewablePeriod = + pallet_duniter_test_parameters::SmithCertRenewablePeriod<Runtime>; + pub type SmithValidityPeriod = pallet_duniter_test_parameters::SmithCertValidityPeriod<Runtime>; + pub type SmithMembershipPeriod = pallet_duniter_test_parameters::SmithMembershipPeriod<Runtime>; + pub type SmithPendingMembershipPeriod = + pallet_duniter_test_parameters::SmithPendingMembershipPeriod<Runtime>; + pub type SmithRenewablePeriod = + pallet_duniter_test_parameters::SmithMembershipRenewablePeriod<Runtime>; + pub type SmithsWotFirstCertIssuableOn = + pallet_duniter_test_parameters::SmithsWotFirstCertIssuableOn<Runtime>; + pub type SmithsWotMinCertForMembership = + pallet_duniter_test_parameters::SmithsWotMinCertForMembership<Runtime>; -impl pallet_duniter_test_parameters::Config for Runtime { - type CertCount = u32; - type PeriodCount = Balance; -} -impl pallet_sudo::Config for Runtime { - type Event = Event; - type Call = Call; -} + impl pallet_duniter_test_parameters::Config for Runtime { + type CertCount = u32; + type PeriodCount = Balance; + } + impl pallet_sudo::Config for Runtime { + type Event = Event; + type Call = Call; + } } // Create the runtime by composing the FRAME pallets that were previously configured. -- GitLab