diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs index b38935291c7ef8e63e4090dd4ce4dac3a6bff2ee..3ffbcf506f7e623cb162a8c9bb8487021a858b82 100644 --- a/pallets/duniter-wot/src/lib.rs +++ b/pallets/duniter-wot/src/lib.rs @@ -135,25 +135,26 @@ where if !T::IsSubWot::get() { let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator); // perform all checks + // 1. check that identity has the right to create an identity + // identity can be member with 5 certifications and still not reach identity creation threshold which could be higher (6, 7...) ensure!( cert_meta.received_count >= T::MinCertForCreateIdtyRight::get(), - Error::<T, I>::NotEnoughReceivedCertsToCreateIdty // TODO only member identities should be allowed to create identity + Error::<T, I>::NotEnoughReceivedCertsToCreateIdty ); + // 2. check that issuer can emit one more certification + // (this is only a partial check) ensure!( cert_meta.issued_count < T::MaxByIssuer::get(), Error::<T, I>::MaxEmittedCertsReached ); + // 3. check that issuer respects certification creation period ensure!( cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number(), Error::<T, I>::IdtyCreationPeriodNotRespected ); - // TODO think about the difference between certification interval and identity creation interval - // if we merge these concepts, it should become a certification check - // TODO add a certification check for cert creation period (done through create_cert ?) } - // TODO make these trait implementation work on instances rather than static - // and avoid checking IsSubWot: smith subwot can never prevent from creating identity - // no constraints for subwot + // TODO make these trait implementation work on instances rather than static to avoid checking IsSubWot + // smith subwot can never prevent from creating identity Ok(()) } // TODO uniformize naming between changing "identity owner key" and "identity address" diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs index e7cea0abf25cf45133aa62e0388dcc66ebbb02fa..1894516457b1c273f61479b5b6074a7cbb7251f5 100644 --- a/pallets/identity/src/lib.rs +++ b/pallets/identity/src/lib.rs @@ -298,28 +298,12 @@ pub mod pallet { // Verification phase // let who = ensure_signed(origin)?; - let creator = - IdentityIndexOf::<T>::try_get(&who).map_err(|_| Error::<T>::IdtyIndexNotFound)?; - 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()); - } - - // run checks for identity creation - T::CheckIdtyCallAllowed::check_create_identity(creator)?; - let block_number = frame_system::pallet::Pallet::<T>::block_number(); - - // TODO move this to a certification check - if creator_idty_val.next_creatable_identity_on > block_number { - return Err(Error::<T>::NotRespectIdtyCreationPeriod.into()); - } + let creator_index = Self::check_create_identity(&who, &owner_key, block_number)?; // Apply phase // frame_system::Pallet::<T>::inc_sufficients(&owner_key); - <Identities<T>>::mutate_exists(creator, |idty_val_opt| { + <Identities<T>>::mutate_exists(creator_index, |idty_val_opt| { if let Some(ref mut idty_val) = idty_val_opt { idty_val.next_creatable_identity_on = block_number + T::IdtyCreationPeriod::get(); @@ -347,7 +331,13 @@ pub mod pallet { idty_index, owner_key: owner_key.clone(), }); - T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Created { creator, owner_key }); + T::OnIdtyChange::on_idty_change( + idty_index, + &IdtyEvent::Created { + creator: creator_index, + owner_key, + }, + ); Ok(().into()) } @@ -649,6 +639,8 @@ pub mod pallet { InvalidSignature, /// Invalid revocation key. InvalidRevocationKey, + /// Issuer is not member and can not perform this action + IssuerNotMember, /// Identity creation period is not respected. NotRespectIdtyCreationPeriod, /// Owner key already changed recently. @@ -846,6 +838,47 @@ pub mod pallet { IdentityChangeSchedule::<T>::append(next_scheduled, idty_id); next_scheduled } + + /// check create identity + // first internal checks + // then other pallet checks trough trait + fn check_create_identity( + issuer_key: &T::AccountId, + receiver_key: &T::AccountId, + block_number: T::BlockNumber, + ) -> Result<T::IdtyIndex, DispatchError> { + // first get issuer details + let creator_index = IdentityIndexOf::<T>::try_get(&issuer_key) + .map_err(|_| Error::<T>::IdtyIndexNotFound)?; + let creator_idty_val = + Identities::<T>::try_get(creator_index).map_err(|_| Error::<T>::IdtyNotFound)?; + + // --- some checks can be done internally + // 1. issuer is member + ensure!( + creator_idty_val.status == IdtyStatus::Member, + Error::<T>::IssuerNotMember + ); + + // 2. issuer respects identity creation period + // (TODO is it only for certification or is there another reason?) + ensure!( + creator_idty_val.next_creatable_identity_on <= block_number, + Error::<T>::NotRespectIdtyCreationPeriod + ); + + // 3. receiver key is not already used by another identity + ensure!( + !IdentityIndexOf::<T>::contains_key(&receiver_key), + Error::<T>::IdtyAlreadyCreated + ); + + // --- other checks depend on other pallets + // run checks for identity creation + T::CheckIdtyCallAllowed::check_create_identity(creator_index)?; + + Ok(creator_index) + } } }