diff --git a/pallets/identity/src/keys.rs b/pallets/identity/src/keys.rs index 223b8548a3..995b633083 100644 --- a/pallets/identity/src/keys.rs +++ b/pallets/identity/src/keys.rs @@ -14,9 +14,9 @@ // along with this program. If not, see . use crate::{ - types, AccountKeyRefCount, Config, DidKeys, DidRecords, Error, IsDidFrozen, KeyRecords, Module, - MultiPurposeNonce, OffChainAuthorizationNonce, ParentDid, PermissionedCallOriginData, RawEvent, - RpcDidRecords, + types, AccountKeyRefCount, ChildDid, Config, DidKeys, DidRecords, Error, IsDidFrozen, + KeyRecords, Module, MultiPurposeNonce, OffChainAuthorizationNonce, ParentDid, + PermissionedCallOriginData, RawEvent, RpcDidRecords, }; use codec::{Decode, Encode as _}; use core::mem; @@ -472,6 +472,7 @@ impl Module { Self::deposit_event(RawEvent::DidCreated(child_did, key.clone(), vec![])); // Link new identity to parent identity. ParentDid::insert(child_did, parent_did); + ChildDid::insert(parent_did, child_did, true); Self::deposit_event(RawEvent::ChildDidCreated(parent_did, child_did, key)); Ok(()) @@ -542,6 +543,7 @@ impl Module { // Link new identity to parent identity. ParentDid::insert(child_did, parent_did); + ChildDid::insert(parent_did, child_did, true); Self::deposit_event(RawEvent::ChildDidCreated(parent_did, child_did, key)); } @@ -566,6 +568,7 @@ impl Module { // Unlink child identity from parent identity. ParentDid::remove(child_did); + ChildDid::remove(parent_did, child_did); Self::deposit_event(RawEvent::ChildDidUnlinked( caller_did, parent_did, child_did, diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs index 7bac7f962e..ff67a3cc0b 100644 --- a/pallets/identity/src/lib.rs +++ b/pallets/identity/src/lib.rs @@ -116,7 +116,7 @@ use polymesh_primitives::{ pub type Event = polymesh_common_utilities::traits::identity::Event; -storage_migration_ver!(3); +storage_migration_ver!(4); decl_storage! { trait Store for Module as Identity { @@ -170,7 +170,7 @@ decl_storage! { pub CddAuthForPrimaryKeyRotation get(fn cdd_auth_for_primary_key_rotation): bool; /// Storage version. - StorageVersion get(fn storage_version) build(|_| Version::new(3)): Version; + StorageVersion get(fn storage_version) build(|_| Version::new(4)): Version; /// How many "strong" references to the account key. /// @@ -185,6 +185,10 @@ decl_storage! { /// Parent identity if the DID is a child Identity. pub ParentDid get(fn parent_did): map hasher(identity) IdentityId => Option; + + /// All child identities of a parent (i.e ParentDID, ChildDID, true) + pub ChildDid get(fn child_did): + double_map hasher(identity) IdentityId, hasher(identity) IdentityId => bool; } add_extra_genesis { // Identities at genesis. @@ -247,8 +251,8 @@ decl_module! { fn deposit_event() = default; fn on_runtime_upgrade() -> Weight { - storage_migrate_on!(StorageVersion, 3, { - migration::migrate_to_v3::(); + storage_migrate_on!(StorageVersion, 4, { + migration::migrate_to_v4::(); }); Weight::zero() } @@ -768,151 +772,16 @@ pub mod migration { use super::*; use sp_runtime::runtime_logger::RuntimeLogger; - mod v2 { - use super::*; - use polymesh_primitives::{CountryCode, Moment}; - use scale_info::TypeInfo; - - type ScopeId = IdentityId; - - #[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, Debug, Hash)] - pub enum ClaimV1 { - Accredited(Scope), - Affiliate(Scope), - BuyLockup(Scope), - SellLockup(Scope), - CustomerDueDiligence(CddId), - KnowYourCustomer(Scope), - Jurisdiction(CountryCode, Scope), - Exempted(Scope), - Blocked(Scope), - InvestorUniqueness(Scope, ScopeId, CddId), - NoData, - InvestorUniquenessV2(CddId), - Custom(CustomClaimTypeId, Option), - } - - impl ClaimV1 { - pub fn try_into(self) -> Option { - match self { - Self::Accredited(scope) => Some(Claim::Accredited(scope)), - Self::Affiliate(scope) => Some(Claim::Affiliate(scope)), - Self::BuyLockup(scope) => Some(Claim::BuyLockup(scope)), - Self::SellLockup(scope) => Some(Claim::SellLockup(scope)), - Self::CustomerDueDiligence(cdd) => Some(Claim::CustomerDueDiligence(cdd)), - Self::KnowYourCustomer(scope) => Some(Claim::KnowYourCustomer(scope)), - Self::Jurisdiction(cc, scope) => Some(Claim::Jurisdiction(cc, scope)), - Self::Exempted(scope) => Some(Claim::Exempted(scope)), - Self::Blocked(scope) => Some(Claim::Blocked(scope)), - Self::Custom(type_id, scope) => Some(Claim::Custom(type_id, scope)), - _ => None, - } - } - } - - #[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq)] - pub struct IdentityClaimV1 { - pub claim_issuer: IdentityId, - pub issuance_date: Moment, - pub last_update_date: Moment, - pub expiry: Option, - pub claim: ClaimV1, - } - - impl IdentityClaimV1 { - pub fn try_into(self) -> Option { - let claim = self.claim.try_into()?; - Some(IdentityClaim { - claim_issuer: self.claim_issuer, - issuance_date: self.issuance_date, - last_update_date: self.last_update_date, - expiry: self.expiry, - claim, - }) - } - } - - #[derive(Encode, Decode, TypeInfo)] - #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)] - pub enum ClaimTypeV1 { - Accredited, - Affiliate, - BuyLockup, - SellLockup, - CustomerDueDiligence, - KnowYourCustomer, - Jurisdiction, - Exempted, - Blocked, - InvestorUniqueness, - NoType, - InvestorUniquenessV2, - Custom(CustomClaimTypeId), - } - - #[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, Debug, PartialOrd, Ord)] - pub struct Claim1stKeyV1 { - pub target: IdentityId, - pub claim_type: ClaimTypeV1, - } - - decl_storage! { - trait Store for Module as Identity { - pub Claims: double_map hasher(twox_64_concat) Claim1stKeyV1, hasher(blake2_128_concat) Claim2ndKey => Option; - } - } - - decl_module! { - pub struct Module for enum Call where origin: T::RuntimeOrigin { } - } - } - - pub fn migrate_to_v3() { + pub fn migrate_to_v4() { RuntimeLogger::init(); - log::info!(" >>> Migrating Identity.Claims."); - migrate_claims::(); - log::info!(" >>> All Claims have been migrated."); + log::info!(" >>> Initializing ChildDid storage"); + initialize_child_did::(); + log::info!(" >>> ChildDid has been initialized"); } - fn migrate_claims() { - let mut same = 0; - let mut converted = 0; - let mut removed = 0; - let mut remap = Vec::new(); - // Migrate all Claims - v2::Claims::translate::(|old_key1, key2, old_claim| { - if let Some(claim) = old_claim.try_into() { - let claim_type = claim.claim.claim_type(); - let new_key1 = Claim1stKey { - target: old_key1.target, - claim_type, - }; - // Need to move `ClaimType::Custom(_)` to new key1. - match claim_type { - ClaimType::Custom(_) => { - converted += 1; - remap.push((new_key1, key2, claim)); - // Remove value from old key. - None - } - _ => { - // No convert/migration need. - same += 1; - Some(claim) - } - } - } else { - removed += 1; - None - } - }); - - // Re-add claims with changed `key1` values. - for (key1, key2, claim) in remap { - Claims::insert(key1, key2, claim); + fn initialize_child_did() { + for (child_did, parent_did) in ParentDid::iter() { + ChildDid::insert(parent_did, child_did, true); } - log::info!( - "> Migrated Claims: converted={converted}, removed={removed}, unchanged={same}." - ); } } diff --git a/pallets/runtime/tests/src/identity_test.rs b/pallets/runtime/tests/src/identity_test.rs index 7929abcfba..b6d2babf9e 100644 --- a/pallets/runtime/tests/src/identity_test.rs +++ b/pallets/runtime/tests/src/identity_test.rs @@ -17,7 +17,7 @@ use frame_support::{ }; use pallet_asset::SecurityToken; use pallet_balances as balances; -use pallet_identity::{CustomClaimIdSequence, CustomClaims, CustomClaimsInverse}; +use pallet_identity::{ChildDid, CustomClaimIdSequence, CustomClaims, CustomClaimsInverse}; use polymesh_common_utilities::{ constants::currency::POLY, traits::{ @@ -2111,6 +2111,8 @@ fn do_child_identity_test() { // Ensure bob has a new identity. assert!(valid_cdd(bob)); assert_ne!(bob.did, alice.did); + assert_eq!(ParentDid::get(bob.did), Some(alice.did)); + assert_eq!(ChildDid::get(alice.did, bob.did), true); // Attach secondary key to child identity. let ferdie = User::new_with(bob.did, AccountKeyring::Ferdie); @@ -2174,6 +2176,8 @@ fn do_child_identity_test() { // Unlink child from parent again. exec_ok!(Identity::unlink_child_identity(bob.origin(), bob_did)); + assert_eq!(ParentDid::get(bob.did), None); + assert_eq!(ChildDid::get(alice.did, bob.did), false); assert!(valid_cdd(bob)); @@ -2183,6 +2187,8 @@ fn do_child_identity_test() { let ferdie_did = did_of(ferdie).expect("Ferdie's new identity"); let ferdie = User::new_with(ferdie_did, AccountKeyring::Ferdie); assert!(valid_cdd(ferdie)); + assert_eq!(ParentDid::get(ferdie.did), Some(bob.did)); + assert_eq!(ChildDid::get(bob.did, ferdie.did), true); } #[test]