From 20fa029ebb1faa0dc13245c0e8329078ef83fdca Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 6 Oct 2023 15:41:44 +0200 Subject: [PATCH 01/37] add migration extrinsics to identity --- substrate/frame/alliance/src/mock.rs | 2 + substrate/frame/identity/src/benchmarking.rs | 69 ++++++++- substrate/frame/identity/src/lib.rs | 145 ++++++++++++++++++- substrate/frame/identity/src/tests.rs | 54 +++++++ substrate/frame/identity/src/weights.rs | 78 ++++++++++ 5 files changed, 345 insertions(+), 3 deletions(-) diff --git a/substrate/frame/alliance/src/mock.rs b/substrate/frame/alliance/src/mock.rs index 82dbbe9c0bb9..33d466de6c99 100644 --- a/substrate/frame/alliance/src/mock.rs +++ b/substrate/frame/alliance/src/mock.rs @@ -123,6 +123,8 @@ impl pallet_identity::Config for Test { type MaxRegistrars = MaxRegistrars; type Slashed = (); type RegistrarOrigin = EnsureOneOrRoot; + type ReapOrigin = EnsureOneOrRoot; + type ReapIdentityHandler = (); type ForceOrigin = EnsureTwoOrRoot; type WeightInfo = (); } diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index 4b51d23f6b34..275eeb547297 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -26,6 +26,7 @@ use frame_benchmarking::v1::{account, benchmarks, whitelisted_caller, BenchmarkE use frame_support::{ ensure, traits::{EnsureOrigin, Get}, + BoundedVec, }; use frame_system::RawOrigin; use sp_runtime::traits::Bounded; @@ -441,12 +442,78 @@ benchmarks! { let sup = account("super", 0, SEED); let _ = add_sub_accounts::(&sup, s)?; let sup_origin = RawOrigin::Signed(sup).into(); - Identity::::add_sub(sup_origin, T::Lookup::unlookup(caller.clone()), Data::Raw(vec![0; 32].try_into().unwrap()))?; + Identity::::add_sub( + sup_origin, + T::Lookup::unlookup(caller.clone()), + Data::Raw(vec![0; 32].try_into().unwrap()) + )?; ensure!(SuperOf::::contains_key(&caller), "Sub doesn't exists"); }: _(RawOrigin::Signed(caller.clone())) verify { ensure!(!SuperOf::::contains_key(&caller), "Sub not removed"); } + reap_identity { + let s in 0 .. T::MaxSubAccounts::get(); + let target: T::AccountId = account("target", 0, SEED); + let target_lookup = T::Lookup::unlookup(target.clone()); + let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); + let origin = + T::ReapOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + // set identity + let info = create_identity_info::(1); + Identity::::set_identity( + RawOrigin::Signed(target.clone()).into(), + Box::new(info.clone()) + )?; + // set `s` subs + let _ = add_sub_accounts::(&target, s)?; + }: _(origin, target_lookup, s) + verify { + assert_last_event::(Event::::IdentityReaped { who: target }.into()); + } + + poke_deposit { + let caller: T::AccountId = whitelisted_caller(); + let target: T::AccountId = account("target", 0, SEED); + let target_lookup = T::Lookup::unlookup(target.clone()); + let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); + let additional_fields = 0; + + // insert identity into storage with zero deposit + IdentityOf::::insert( + &target, + Registration { + judgements: BoundedVec::default(), + deposit: Zero::zero(), + info: create_identity_info::(additional_fields), + }, + ); + + // insert subs into storage with zero deposit + let sub_account = account("sub", 0, SEED); + let subs = BoundedVec::<_, T::MaxSubAccounts>::try_from(vec![sub_account]).unwrap(); + SubsOf::::insert::< + &T::AccountId, + (BalanceOf, BoundedVec) + >( + &target, + (Zero::zero(), subs) + ); + + // expected deposits + let expected_id_deposit = T::FieldDeposit::get() + .saturating_mul(additional_fields.into()) + .saturating_add(T::BasicDeposit::get()); + let expected_sub_deposit = T::SubAccountDeposit::get(); // only 1 + }: _(RawOrigin::Signed(caller.clone()), target_lookup) + verify { + assert_last_event::(Event::::DepositUpdated { + who: target, + identity: expected_id_deposit, + subs: expected_sub_deposit + }.into()); + } + impl_benchmark_test_suite!(Identity, crate::tests::new_test_ext(), crate::tests::Test); } diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index f192ee2b461b..f339eb5eb2cb 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -78,7 +78,10 @@ mod tests; mod types; pub mod weights; -use frame_support::traits::{BalanceStatus, Currency, OnUnbalanced, ReservableCurrency}; +use frame_support::{ + pallet_prelude::DispatchResult, + traits::{BalanceStatus, Currency, Get, OnUnbalanced, ReservableCurrency}, +}; use sp_runtime::traits::{AppendZerosInput, Hash, Saturating, StaticLookup, Zero}; use sp_std::prelude::*; pub use weights::WeightInfo; @@ -147,6 +150,12 @@ pub mod pallet { /// The origin which may add or remove registrars. Root can always do this. type RegistrarOrigin: EnsureOrigin; + /// The origin that can reap an account's identity info. + type ReapOrigin: EnsureOrigin; + + /// A handler for what to do when an identity is reaped. + type ReapIdentityHandler: OnReapIdentity; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -265,6 +274,11 @@ pub mod pallet { /// A sub-identity was cleared, and the given deposit repatriated from the /// main identity account to the sub-identity account. SubIdentityRevoked { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf }, + /// The identity and all sub accounts were reaped for `who`. + IdentityReaped { who: T::AccountId }, + /// The deposits held for `who` were updated. `identity` is the new deposit held for + /// identity info, and `subs` is the new deposit held for the sub-accounts. + DepositUpdated { who: T::AccountId, identity: BalanceOf, subs: BalanceOf }, } #[pallet::call] @@ -407,7 +421,7 @@ pub mod pallet { ); let (old_deposit, old_ids) = >::get(&sender); - let new_deposit = T::SubAccountDeposit::get() * >::from(subs.len() as u32); + let new_deposit = Self::subs_deposit(subs.len() as u32); let not_other_sub = subs.iter().filter_map(|i| SuperOf::::get(&i.0)).all(|i| i.0 == sender); @@ -959,6 +973,98 @@ pub mod pallet { }); Ok(()) } + + /// Reap an identity, clearing associated storage items and refunding any deposits. Calls + /// the `ReapIdentityHandler`, which can be implemented in the runtime. This function is + /// very similar to (a) `clear_identity`, but called on a `target` account instead of self; + /// and (b) `kill_identity`, but without imposing a slash. + /// + /// Parameters: + /// - `target`: The account for which to reap identity state. + /// - `num_subs`: Witness data. The maximum number of sub accounts that `target` has. + /// + /// Origin must be the `ReapOrigin`. + #[pallet::call_index(15)] + #[pallet::weight(T::WeightInfo::reap_identity(*num_subs))] + pub fn reap_identity( + origin: OriginFor, + target: AccountIdLookupOf, + num_subs: u32, + ) -> DispatchResult { + // `ReapOrigin` to be set to `EnsureSigned` (i.e. anyone) on chain where we + // want to reap data (i.e. Relay) and `EnsureRoot` on chains where we want "normal" + // functionality (i.e. the People Chain). + T::ReapOrigin::ensure_origin(origin)?; + let who = T::Lookup::lookup(target)?; + + // `take` any storage items keyed by `target` + let id = >::take(&who).ok_or(Error::::NotNamed)?; + let (subs_deposit, sub_ids) = >::take(&who); + // check witness data + ensure!(sub_ids.len() as u32 <= num_subs, Error::::TooManySubAccounts); + for sub in sub_ids.iter() { + >::remove(sub); + } + + // unreserve any deposits + let deposit = id.total_deposit().saturating_add(subs_deposit); + let err_amount = T::Currency::unreserve(&who, deposit); + debug_assert!(err_amount.is_zero()); + + // Finally, call the handler. + T::ReapIdentityHandler::on_reap_identity(&who)?; + Self::deposit_event(Event::IdentityReaped { who }); + Ok(()) + } + + /// Update the deposits held by `target` for its identity info. + /// + /// Parameters: + /// - `target`: The account for which to update deposits. + /// + /// May be called by any signed origin. + #[pallet::call_index(16)] + #[pallet::weight(T::WeightInfo::poke_deposit())] + pub fn poke_deposit(origin: OriginFor, target: AccountIdLookupOf) -> DispatchResult { + // anyone or root (so that the system can call it for identity migration) + let _ = ensure_signed_or_root(origin)?; + let target = T::Lookup::lookup(target)?; + + // Identity Deposit + ensure!(IdentityOf::::contains_key(&target), Error::::NoIdentity); + let new_id_deposit = IdentityOf::::try_mutate( + &target, + |registration| -> Result, DispatchError> { + if let Some(reg) = registration { + // Calculate what deposit should be + let field_deposit = BalanceOf::::from(reg.info.additional.len() as u32) + .saturating_mul(T::FieldDeposit::get()); + let new_id_deposit = T::BasicDeposit::get().saturating_add(field_deposit); + + // Update account + let _ = Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?; + + reg.deposit = new_id_deposit; + return Ok(new_id_deposit) + } else { + return Err(Error::::NoIdentity.into()) + } + }, + )?; + + // Subs Deposit + let (current_subs_deposit, subs_of) = SubsOf::::take(&target); + let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); + let _ = Self::rejig_deposit(&target, current_subs_deposit, new_subs_deposit)?; + SubsOf::::insert(&target, (new_subs_deposit, subs_of)); + + Self::deposit_event(Event::DepositUpdated { + who: target, + identity: new_id_deposit, + subs: new_subs_deposit, + }); + Ok(()) + } } } @@ -972,9 +1078,44 @@ impl Pallet { .collect() } + /// Calculate the deposit required for a number of `sub` accounts. + fn subs_deposit(subs: u32) -> BalanceOf { + T::SubAccountDeposit::get().saturating_mul(>::from(subs)) + } + + /// Take the `current` deposit that `who` is holding, and update it to a `new` one. + fn rejig_deposit( + who: &T::AccountId, + current: BalanceOf, + new: BalanceOf, + ) -> DispatchResult { + if new > current { + T::Currency::reserve(who, new - current)?; + } else if new < current { + let err_amount = T::Currency::unreserve(who, current - new); + debug_assert!(err_amount.is_zero()); + } + Ok(()) + } + /// Check if the account has corresponding identity information by the identity field. pub fn has_identity(who: &T::AccountId, fields: u64) -> bool { IdentityOf::::get(who) .map_or(false, |registration| (registration.info.fields().0.bits() & fields) == fields) } } + +pub trait OnReapIdentity { + /// What to do when an identity is reaped. For example, the implementation could send an XCM + /// program to another chain. Concretely, a type implementing this trait in the Polkadot + /// runtime would teleport enough DOT to the People Chain to cover the Identity deposit there. + /// + /// This could also directly include `Transact { poke_deposit(..), ..}` + fn on_reap_identity(who: &AccountId) -> DispatchResult; +} + +impl OnReapIdentity for () { + fn on_reap_identity(_who: &AccountId) -> DispatchResult { + Ok(()) + } +} diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 1532980574c2..1290fce01df1 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -108,6 +108,8 @@ impl pallet_identity::Config for Test { type MaxAdditionalFields = MaxAdditionalFields; type MaxRegistrars = MaxRegistrars; type RegistrarOrigin = EnsureOneOrRoot; + type ReapOrigin = EnsureOneOrRoot; + type ReapIdentityHandler = (); type ForceOrigin = EnsureTwoOrRoot; type WeightInfo = (); } @@ -619,3 +621,55 @@ fn test_has_identity() { )); }); } + +#[test] +fn reap_identity_works() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten()))); + assert_ok!(Identity::set_subs( + RuntimeOrigin::signed(10), + vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))] + )); + // 10 for identity, 10 for sub + assert_eq!(Balances::free_balance(10), 80); + assert_ok!(Identity::reap_identity(RuntimeOrigin::signed(1), 10, 1)); + // no identity or subs + assert!(Identity::identity(10).is_none()); + assert!(Identity::super_of(20).is_none()); + // balance is unreserved + assert_eq!(Balances::free_balance(10), 100); + }); +} + +#[test] +fn poke_deposit_works() { + new_test_ext().execute_with(|| { + // Set a custom registration with 0 deposit + IdentityOf::::insert( + &10, + Registration { judgements: BoundedVec::default(), deposit: Zero::zero(), info: ten() }, + ); + assert!(Identity::identity(10).is_some()); + // Set a sub with zero deposit + SubsOf::::insert::<&u64, (u64, BoundedVec>)>( + &10, + (0, vec![20].try_into().unwrap()), + ); + SuperOf::::insert(&20, (&10, Data::Raw(vec![1; 1].try_into().unwrap()))); + // Balance is free + assert_eq!(Balances::free_balance(10), 100); + + // poke + assert_ok!(Identity::poke_deposit(RuntimeOrigin::signed(1), 10)); + + // free balance reduced by 20 + assert_eq!(Balances::free_balance(10), 80); + // new registration deposit is 10 + assert_eq!( + Identity::identity(&10), + Some(Registration { judgements: BoundedVec::default(), deposit: 10, info: ten() }) + ); + // new subs deposit is 10 vv + assert_eq!(Identity::subs_of(10), (10, vec![20].try_into().unwrap())); + }); +} diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index 02fcd7db3c95..5f6cbaa4a315 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -68,6 +68,8 @@ pub trait WeightInfo { fn rename_sub(s: u32, ) -> Weight; fn remove_sub(s: u32, ) -> Weight; fn quit_sub(s: u32, ) -> Weight; + fn reap_identity(s: u32, ) -> Weight; + fn poke_deposit() -> Weight; } /// Weights for pallet_identity using the Substrate node and recommended hardware. @@ -363,6 +365,44 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// The range of component `s` is `[0, 100]`. + fn reap_identity(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `673 + s * (32 ±0)` + // Estimated: `11003` + // Minimum execution time: 312_504_000 picoseconds. + Weight::from_parts(372_110_300, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 481_670 + .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `628` + // Estimated: `11003` + // Minimum execution time: 525_039_000 picoseconds. + Weight::from_parts(554_552_000, 0) + .saturating_add(Weight::from_parts(0, 11003)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } } // For backwards compatibility and tests @@ -657,4 +697,42 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// The range of component `s` is `[0, 100]`. + fn reap_identity(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `673 + s * (32 ±0)` + // Estimated: `11003` + // Minimum execution time: 312_504_000 picoseconds. + Weight::from_parts(372_110_300, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 481_670 + .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `628` + // Estimated: `11003` + // Minimum execution time: 525_039_000 picoseconds. + Weight::from_parts(554_552_000, 0) + .saturating_add(Weight::from_parts(0, 11003)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } } From 7becd9e2f0fe312aa3844eab58d09704bbcd54fb Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 6 Oct 2023 15:42:07 +0200 Subject: [PATCH 02/37] add to runtimes --- polkadot/runtime/rococo/src/lib.rs | 2 + .../rococo/src/weights/pallet_identity.rs | 38 +++++++++++++++++++ polkadot/runtime/westend/src/lib.rs | 2 + .../westend/src/weights/pallet_identity.rs | 38 +++++++++++++++++++ substrate/bin/node/runtime/src/lib.rs | 2 + 5 files changed, 82 insertions(+) diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 4bdcc1237394..7ab2e35e43c3 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -589,6 +589,8 @@ impl pallet_identity::Config for Runtime { type Slashed = Treasury; type ForceOrigin = EitherOf, GeneralAdmin>; type RegistrarOrigin = EitherOf, GeneralAdmin>; + type ReapOrigin = EnsureRoot; + type ReapIdentityHandler = (); type WeightInfo = weights::pallet_identity::WeightInfo; } diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs index e10c042dde6a..a5b4d031c033 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -351,4 +351,42 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// The range of component `s` is `[0, 100]`. + fn reap_identity(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `673 + s * (32 ±0)` + // Estimated: `11003` + // Minimum execution time: 312_504_000 picoseconds. + Weight::from_parts(372_110_300, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 481_670 + .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `628` + // Estimated: `11003` + // Minimum execution time: 525_039_000 picoseconds. + Weight::from_parts(554_552_000, 0) + .saturating_add(Weight::from_parts(0, 11003)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 6085b6e37455..7a7caedcb886 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -856,6 +856,8 @@ impl pallet_identity::Config for Runtime { type MaxRegistrars = MaxRegistrars; type ForceOrigin = EitherOf, GeneralAdmin>; type RegistrarOrigin = EitherOf, GeneralAdmin>; + type ReapOrigin = EnsureRoot; + type ReapIdentityHandler = (); type WeightInfo = weights::pallet_identity::WeightInfo; } diff --git a/polkadot/runtime/westend/src/weights/pallet_identity.rs b/polkadot/runtime/westend/src/weights/pallet_identity.rs index 8c11482ebdc1..67c23d89398c 100644 --- a/polkadot/runtime/westend/src/weights/pallet_identity.rs +++ b/polkadot/runtime/westend/src/weights/pallet_identity.rs @@ -356,4 +356,42 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// The range of component `s` is `[0, 100]`. + fn reap_identity(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `673 + s * (32 ±0)` + // Estimated: `11003` + // Minimum execution time: 312_504_000 picoseconds. + Weight::from_parts(372_110_300, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 481_670 + .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `628` + // Estimated: `11003` + // Minimum execution time: 525_039_000 picoseconds. + Weight::from_parts(554_552_000, 0) + .saturating_add(Weight::from_parts(0, 11003)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } } diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index f018639b732e..6474428efbf0 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1467,6 +1467,8 @@ impl pallet_identity::Config for Runtime { type Slashed = Treasury; type ForceOrigin = EnsureRootOrHalfCouncil; type RegistrarOrigin = EnsureRootOrHalfCouncil; + type ReapOrigin = EnsureRoot; + type ReapIdentityHandler = (); type WeightInfo = pallet_identity::weights::SubstrateWeight; } From fd39b82bd41746577101708e1a006c6d5f76fc87 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 6 Oct 2023 16:37:05 +0200 Subject: [PATCH 03/37] adjust trait --- substrate/frame/identity/src/lib.rs | 17 ++++++++++++----- substrate/frame/identity/src/weights.rs | 10 +++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index f339eb5eb2cb..d3e140498f1d 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -999,9 +999,11 @@ pub mod pallet { // `take` any storage items keyed by `target` let id = >::take(&who).ok_or(Error::::NotNamed)?; + let fields = id.info.additional.len() as u32; let (subs_deposit, sub_ids) = >::take(&who); // check witness data - ensure!(sub_ids.len() as u32 <= num_subs, Error::::TooManySubAccounts); + let actual_subs = sub_ids.len() as u32; + ensure!(actual_subs <= num_subs, Error::::TooManySubAccounts); for sub in sub_ids.iter() { >::remove(sub); } @@ -1012,7 +1014,7 @@ pub mod pallet { debug_assert!(err_amount.is_zero()); // Finally, call the handler. - T::ReapIdentityHandler::on_reap_identity(&who)?; + T::ReapIdentityHandler::on_reap_identity(&who, fields, actual_subs)?; Self::deposit_event(Event::IdentityReaped { who }); Ok(()) } @@ -1110,12 +1112,17 @@ pub trait OnReapIdentity { /// program to another chain. Concretely, a type implementing this trait in the Polkadot /// runtime would teleport enough DOT to the People Chain to cover the Identity deposit there. /// - /// This could also directly include `Transact { poke_deposit(..), ..}` - fn on_reap_identity(who: &AccountId) -> DispatchResult; + /// This could also directly include `Transact { poke_deposit(..), ..}`. + /// + /// Inputs + /// - `who`: Whose identity was reaped. + /// - `fields`: The number of `additional_fields` they had. + /// - `subs`: The number of sub-accounts they had. + fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult; } impl OnReapIdentity for () { - fn on_reap_identity(_who: &AccountId) -> DispatchResult { + fn on_reap_identity(_who: &AccountId, _fields: u32, _subs: u32) -> DispatchResult { Ok(()) } } diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index 5f6cbaa4a315..928271ccd9d9 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -715,9 +715,9 @@ impl WeightInfo for () { .saturating_add(Weight::from_parts(0, 11003)) // Standard Error: 481_670 .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(2)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) } /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) @@ -732,7 +732,7 @@ impl WeightInfo for () { // Minimum execution time: 525_039_000 picoseconds. Weight::from_parts(554_552_000, 0) .saturating_add(Weight::from_parts(0, 11003)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) } } From 24b9d0d6fdc1a95bf43b1df0ade169cfe50a5959 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 7 Oct 2023 20:57:38 +0200 Subject: [PATCH 04/37] Add OnReapIdentity implementation for Relay Chain --- polkadot/runtime/rococo/src/impls.rs | 99 ++++++++++++++++++++++++++++ polkadot/runtime/rococo/src/lib.rs | 18 ++++- substrate/frame/identity/src/lib.rs | 1 + 3 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 polkadot/runtime/rococo/src/impls.rs diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs new file mode 100644 index 000000000000..f4b4411505d2 --- /dev/null +++ b/polkadot/runtime/rococo/src/impls.rs @@ -0,0 +1,99 @@ +use crate::xcm_config; +use frame_support::pallet_prelude::DispatchResult; +use frame_system::RawOrigin; +use pallet_identity::OnReapIdentity; +use primitives::Balance; +use rococo_runtime_constants::currency::*; +use sp_std::{marker::PhantomData, prelude::*}; +use xcm::{latest::prelude::*, /* v2::OriginKind, */ VersionedMultiLocation, VersionedXcm}; +use xcm_executor::traits::TransactAsset; + +/// Type that implements `OnReapIdentity` that will send the deposit needed to store the same +/// information on a parachain, sends the deposit there, and then updates it. +pub struct ToParachainIdentityReaper(PhantomData); +impl OnReapIdentity for ToParachainIdentityReaper +where + T: frame_system::Config + pallet_xcm::Config, + AccountId: Into<[u8; 32]> + Clone, +{ + fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { + // calculate deposit needed on parachains + // assume `relay_deposit / 100 + ED + buffer` + // buffer to cover tx fees on para, maybe ED + let para_basic_deposit = 1000 * CENTS / 100; + let para_field_deposit = 250 * CENTS / 100; + let para_sub_account_deposit = 200 * CENTS / 100; + let para_existential_deposit = EXISTENTIAL_DEPOSIT / 10; + let id_deposit = + para_basic_deposit.saturating_add(para_field_deposit.saturating_mul(fields as Balance)); + + let subs_deposit = para_sub_account_deposit.saturating_mul(subs as Balance); + + let total_to_send = id_deposit + .saturating_add(subs_deposit) + .saturating_add(para_existential_deposit.saturating_mul(2)); + + // define asset / destination from relay perspective + let roc: MultiAssets = + vec![MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }] + .into(); + // todo: people chain para id + let destination: MultiLocation = MultiLocation::new(0, Parachain(1000)); + + // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support + // unpaid teleports. + + // check out + xcm_config::LocalAssetTransactor::can_check_out( + &destination, + &roc.inner().first().unwrap(), // <- safe unwrap since we just set `roc`. + // not used in AssetTransactor + &XcmContext { origin: None, message_id: [0; 32], topic: None }, + ) + .map_err(|_| pallet_xcm::Error::::InvalidAsset)?; + xcm_config::LocalAssetTransactor::check_out( + &destination, + &roc.inner().first().unwrap(), // <- safe unwrap since we just set `roc`. + // not used in AssetTransactor + &XcmContext { origin: None, message_id: [0; 32], topic: None }, + ); + + // reanchor + let roc_reanchored: MultiAssets = vec![MultiAsset { + id: Concrete(MultiLocation::new(1, Here)), + fun: Fungible(total_to_send), + }] + .into(); + + // Actual program to execute on People Chain. + let program: Xcm<()> = Xcm(vec![ + // Unpaid as this is constructed by the system, once per user. The user shouldn't have + // their balance reduced by teleport fees for the favor of migrating. + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + // Receive the asset into holding. + ReceiveTeleportedAsset(roc_reanchored), + // Deposit into the user's account. + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: Junction::AccountId32 { network: None, id: who.clone().into() } + .into_location() + .into(), + }, + // // Poke the deposit to reserve the appropriate amount on the parachain. + // Transact { + // origin_kind: OriginKind::Superuser, + // require_weight_at_most: Weight {ref_time: 2_000_000_000, proof_size: 16_384}, + // // Need People Chain runtime to encode call. + // call: DoubleEncoded { encoded: /* pallet_identity::poke_deposit(who) */ }, + // }, + ]); + + // send + let _ = >::send( + RawOrigin::Root.into(), + Box::new(VersionedMultiLocation::V3(destination)), + Box::new(VersionedXcm::V3(program)), + )?; + Ok(()) + } +} diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 7ab2e35e43c3..55a4af3cbed1 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -102,6 +102,10 @@ mod weights; // XCM configurations. pub mod xcm_config; +// Implemented types. +mod impls; +use impls::ToParachainIdentityReaper; + // Governance and configurations. pub mod governance; use governance::{ @@ -150,7 +154,15 @@ pub fn native_version() -> NativeVersion { pub struct IdentityCalls; impl Contains for IdentityCalls { fn contains(c: &RuntimeCall) -> bool { - matches!(c, RuntimeCall::Identity(_)) + match c { + // Allow calls to reap identity and poke deposit + RuntimeCall::Identity(pallet_identity::Call::reap_identity { .. }) | + RuntimeCall::Identity(pallet_identity::Call::poke_deposit { .. }) => false, + // Block all other calls to identity + RuntimeCall::Identity(_) => true, + // Allow all other calls + _ => false, + } } } @@ -589,8 +601,10 @@ impl pallet_identity::Config for Runtime { type Slashed = Treasury; type ForceOrigin = EitherOf, GeneralAdmin>; type RegistrarOrigin = EitherOf, GeneralAdmin>; + // Should be `EnsureRoot` until the parachain launches with Identity state. Then, it will be + // `EnsureSigned` to allow deposit migration. type ReapOrigin = EnsureRoot; - type ReapIdentityHandler = (); + type ReapIdentityHandler = ToParachainIdentityReaper; type WeightInfo = weights::pallet_identity::WeightInfo; } diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index d3e140498f1d..3bf16c3074f7 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -1107,6 +1107,7 @@ impl Pallet { } } +/// Trait to handle reaping identity from state. pub trait OnReapIdentity { /// What to do when an identity is reaped. For example, the implementation could send an XCM /// program to another chain. Concretely, a type implementing this trait in the Polkadot From 96b2add4b9ccb45eccfc143ea891a9625d9be0b7 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Mon, 9 Oct 2023 15:53:31 +0200 Subject: [PATCH 05/37] add license --- polkadot/runtime/rococo/src/impls.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index f4b4411505d2..569f197c0f08 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -1,3 +1,19 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + use crate::xcm_config; use frame_support::pallet_prelude::DispatchResult; use frame_system::RawOrigin; From f9ac75e5da95173f27b9f20bb7611316aab56051 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 10 Oct 2023 15:26:22 +0200 Subject: [PATCH 06/37] add ability to lock and unlock pallet --- polkadot/runtime/rococo/src/lib.rs | 1 + .../rococo/src/weights/pallet_identity.rs | 22 +++++++++ polkadot/runtime/westend/src/lib.rs | 1 + .../westend/src/weights/pallet_identity.rs | 22 +++++++++ substrate/bin/node/runtime/src/lib.rs | 1 + substrate/frame/identity/src/benchmarking.rs | 18 +++++++ substrate/frame/identity/src/lib.rs | 49 +++++++++++++++++++ substrate/frame/identity/src/tests.rs | 1 + substrate/frame/identity/src/weights.rs | 46 +++++++++++++++++ 9 files changed, 161 insertions(+) diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 55a4af3cbed1..e7e5278700ae 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -605,6 +605,7 @@ impl pallet_identity::Config for Runtime { // `EnsureSigned` to allow deposit migration. type ReapOrigin = EnsureRoot; type ReapIdentityHandler = ToParachainIdentityReaper; + type LockerOrigin = EnsureRoot; type WeightInfo = weights::pallet_identity::WeightInfo; } diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs index a5b4d031c033..e5ee81798f67 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -389,4 +389,26 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } + /// Storage: `Identity::Locked` (r:0 w:1) + /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn lock_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 43_286_000 picoseconds. + Weight::from_parts(51_523_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::Locked` (r:0 w:1) + /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn unlock_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 42_243_000 picoseconds. + Weight::from_parts(52_907_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 7a7caedcb886..ac8146888f91 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -858,6 +858,7 @@ impl pallet_identity::Config for Runtime { type RegistrarOrigin = EitherOf, GeneralAdmin>; type ReapOrigin = EnsureRoot; type ReapIdentityHandler = (); + type LockerOrigin = EnsureRoot; type WeightInfo = weights::pallet_identity::WeightInfo; } diff --git a/polkadot/runtime/westend/src/weights/pallet_identity.rs b/polkadot/runtime/westend/src/weights/pallet_identity.rs index 67c23d89398c..f64887294d7f 100644 --- a/polkadot/runtime/westend/src/weights/pallet_identity.rs +++ b/polkadot/runtime/westend/src/weights/pallet_identity.rs @@ -394,4 +394,26 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } + /// Storage: `Identity::Locked` (r:0 w:1) + /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn lock_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 43_286_000 picoseconds. + Weight::from_parts(51_523_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::Locked` (r:0 w:1) + /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn unlock_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 42_243_000 picoseconds. + Weight::from_parts(52_907_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 6474428efbf0..ea47c622f74d 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1469,6 +1469,7 @@ impl pallet_identity::Config for Runtime { type RegistrarOrigin = EnsureRootOrHalfCouncil; type ReapOrigin = EnsureRoot; type ReapIdentityHandler = (); + type LockerOrigin = EnsureRoot; type WeightInfo = pallet_identity::weights::SubstrateWeight; } diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index 275eeb547297..22800dd3ae7b 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -515,5 +515,23 @@ benchmarks! { }.into()); } + lock_pallet { + let origin = + T::LockerOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + Identity::::unlock_pallet(origin.clone())?; + }: _(origin) + verify { + assert!(Locked::::get()); + } + + unlock_pallet { + let origin = + T::LockerOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + Identity::::lock_pallet(origin.clone())?; + }: _(origin) + verify { + assert!(!Locked::::get()); + } + impl_benchmark_test_suite!(Identity, crate::tests::new_test_ext(), crate::tests::Test); } diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 3bf16c3074f7..a7feab3da0e4 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -156,6 +156,9 @@ pub mod pallet { /// A handler for what to do when an identity is reaped. type ReapIdentityHandler: OnReapIdentity; + /// The origin that can lock calls to the pallet. + type LockerOrigin: EnsureOrigin; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -163,6 +166,11 @@ pub mod pallet { #[pallet::pallet] pub struct Pallet(_); + /// `true` if the pallet is locked for migration. Should be removed after migration. + #[pallet::storage] + #[pallet::getter(fn locked)] + pub(super) type Locked = StorageValue<_, bool, ValueQuery>; + /// Information that is pertinent to identify the entity behind an account. /// /// TWOX-NOTE: OK ― `AccountId` is a secure hash. @@ -248,6 +256,8 @@ pub mod pallet { JudgementForDifferentIdentity, /// Error that occurs when there is an issue paying for judgement. JudgementPaymentFailed, + /// The pallet is locked to prevent state changes. + PalletLocked, } #[pallet::event] @@ -300,6 +310,7 @@ pub mod pallet { origin: OriginFor, account: AccountIdLookupOf, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); T::RegistrarOrigin::ensure_origin(origin)?; let account = T::Lookup::lookup(account)?; @@ -345,6 +356,7 @@ pub mod pallet { origin: OriginFor, info: Box>, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let extra_fields = info.additional.len() as u32; ensure!(extra_fields <= T::MaxAdditionalFields::get(), Error::::TooManyFields); @@ -413,6 +425,7 @@ pub mod pallet { origin: OriginFor, subs: Vec<(T::AccountId, Data)>, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; ensure!(>::contains_key(&sender), Error::::NotFound); ensure!( @@ -480,6 +493,7 @@ pub mod pallet { T::MaxAdditionalFields::get(), // X ))] pub fn clear_identity(origin: OriginFor) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let (subs_deposit, sub_ids) = >::take(&sender); @@ -533,6 +547,7 @@ pub mod pallet { #[pallet::compact] reg_index: RegistrarIndex, #[pallet::compact] max_fee: BalanceOf, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let registrars = >::get(); let registrar = registrars @@ -593,6 +608,7 @@ pub mod pallet { origin: OriginFor, reg_index: RegistrarIndex, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let mut id = >::get(&sender).ok_or(Error::::NoIdentity)?; @@ -638,6 +654,7 @@ pub mod pallet { #[pallet::compact] index: RegistrarIndex, #[pallet::compact] fee: BalanceOf, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let who = ensure_signed(origin)?; let registrars = >::mutate(|rs| -> Result { @@ -675,6 +692,7 @@ pub mod pallet { #[pallet::compact] index: RegistrarIndex, new: AccountIdLookupOf, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let who = ensure_signed(origin)?; let new = T::Lookup::lookup(new)?; @@ -713,6 +731,7 @@ pub mod pallet { #[pallet::compact] index: RegistrarIndex, fields: IdentityFields, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let who = ensure_signed(origin)?; let registrars = >::mutate(|rs| -> Result { @@ -764,6 +783,7 @@ pub mod pallet { judgement: Judgement>, identity: T::Hash, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let target = T::Lookup::lookup(target)?; ensure!(!judgement.has_deposit(), Error::::InvalidJudgement); @@ -835,6 +855,7 @@ pub mod pallet { origin: OriginFor, target: AccountIdLookupOf, ) -> DispatchResultWithPostInfo { + ensure!(!Self::locked(), Error::::PalletLocked); T::ForceOrigin::ensure_origin(origin)?; // Figure out who we're meant to be clearing. @@ -873,6 +894,7 @@ pub mod pallet { sub: AccountIdLookupOf, data: Data, ) -> DispatchResult { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let sub = T::Lookup::lookup(sub)?; ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); @@ -909,6 +931,7 @@ pub mod pallet { sub: AccountIdLookupOf, data: Data, ) -> DispatchResult { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let sub = T::Lookup::lookup(sub)?; ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); @@ -927,6 +950,7 @@ pub mod pallet { #[pallet::call_index(13)] #[pallet::weight(T::WeightInfo::remove_sub(T::MaxSubAccounts::get()))] pub fn remove_sub(origin: OriginFor, sub: AccountIdLookupOf) -> DispatchResult { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); let sub = T::Lookup::lookup(sub)?; @@ -957,6 +981,7 @@ pub mod pallet { #[pallet::call_index(14)] #[pallet::weight(T::WeightInfo::quit_sub(T::MaxSubAccounts::get()))] pub fn quit_sub(origin: OriginFor) -> DispatchResult { + ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let (sup, _) = SuperOf::::take(&sender).ok_or(Error::::NotSub)?; SubsOf::::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| { @@ -991,6 +1016,7 @@ pub mod pallet { target: AccountIdLookupOf, num_subs: u32, ) -> DispatchResult { + // No locked check: used for migration. // `ReapOrigin` to be set to `EnsureSigned` (i.e. anyone) on chain where we // want to reap data (i.e. Relay) and `EnsureRoot` on chains where we want "normal" // functionality (i.e. the People Chain). @@ -1028,6 +1054,7 @@ pub mod pallet { #[pallet::call_index(16)] #[pallet::weight(T::WeightInfo::poke_deposit())] pub fn poke_deposit(origin: OriginFor, target: AccountIdLookupOf) -> DispatchResult { + // No locked check: used for migration. // anyone or root (so that the system can call it for identity migration) let _ = ensure_signed_or_root(origin)?; let target = T::Lookup::lookup(target)?; @@ -1067,6 +1094,28 @@ pub mod pallet { }); Ok(()) } + + /// Lock the pallet. + /// + /// Origin must be the `LockerOrigin`. + #[pallet::call_index(17)] + #[pallet::weight(T::WeightInfo::lock_pallet())] + pub fn lock_pallet(origin: OriginFor) -> DispatchResult { + T::LockerOrigin::ensure_origin(origin)?; + Locked::::put(true); + Ok(()) + } + + /// Unlock the pallet. + /// + /// Origin must be the `LockerOrigin`. + #[pallet::call_index(18)] + #[pallet::weight(T::WeightInfo::unlock_pallet())] + pub fn unlock_pallet(origin: OriginFor) -> DispatchResult { + T::LockerOrigin::ensure_origin(origin)?; + Locked::::put(false); + Ok(()) + } } } diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 1290fce01df1..9f5e0b5bd1c3 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -111,6 +111,7 @@ impl pallet_identity::Config for Test { type ReapOrigin = EnsureOneOrRoot; type ReapIdentityHandler = (); type ForceOrigin = EnsureTwoOrRoot; + type LockerOrigin = EnsureOneOrRoot; type WeightInfo = (); } diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index 928271ccd9d9..b63352870c15 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -70,6 +70,8 @@ pub trait WeightInfo { fn quit_sub(s: u32, ) -> Weight; fn reap_identity(s: u32, ) -> Weight; fn poke_deposit() -> Weight; + fn lock_pallet() -> Weight; + fn unlock_pallet() -> Weight; } /// Weights for pallet_identity using the Substrate node and recommended hardware. @@ -403,6 +405,28 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } + /// Storage: `Identity::Locked` (r:0 w:1) + /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn lock_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 43_286_000 picoseconds. + Weight::from_parts(51_523_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::Locked` (r:0 w:1) + /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn unlock_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 42_243_000 picoseconds. + Weight::from_parts(52_907_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } } // For backwards compatibility and tests @@ -735,4 +759,26 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3)) .saturating_add(RocksDbWeight::get().writes(3)) } + /// Storage: `Identity::Locked` (r:0 w:1) + /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn lock_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 43_286_000 picoseconds. + Weight::from_parts(51_523_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + /// Storage: `Identity::Locked` (r:0 w:1) + /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn unlock_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 42_243_000 picoseconds. + Weight::from_parts(52_907_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) + } } From 4f45cc8f51d5556ee4df85241b5de9e35a98866d Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 10 Oct 2023 15:41:31 +0200 Subject: [PATCH 07/37] address most of review comments --- substrate/frame/identity/src/lib.rs | 34 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index a7feab3da0e4..27c0198e8701 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -1064,28 +1064,30 @@ pub mod pallet { let new_id_deposit = IdentityOf::::try_mutate( &target, |registration| -> Result, DispatchError> { - if let Some(reg) = registration { - // Calculate what deposit should be - let field_deposit = BalanceOf::::from(reg.info.additional.len() as u32) - .saturating_mul(T::FieldDeposit::get()); - let new_id_deposit = T::BasicDeposit::get().saturating_add(field_deposit); + let reg = registration.as_mut().ok_or(Error::::NoIdentity)?; + // Calculate what deposit should be + let field_deposit = T::FieldDeposit::get() + .saturating_mul(BalanceOf::::from(reg.info.additional.len() as u32)); + let new_id_deposit = T::BasicDeposit::get().saturating_add(field_deposit); - // Update account - let _ = Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?; + // Update account + Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?; - reg.deposit = new_id_deposit; - return Ok(new_id_deposit) - } else { - return Err(Error::::NoIdentity.into()) - } + reg.deposit = new_id_deposit; + Ok(new_id_deposit) }, )?; // Subs Deposit - let (current_subs_deposit, subs_of) = SubsOf::::take(&target); - let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); - let _ = Self::rejig_deposit(&target, current_subs_deposit, new_subs_deposit)?; - SubsOf::::insert(&target, (new_subs_deposit, subs_of)); + let new_subs_deposit = SubsOf::::try_mutate( + &target, + |(current_subs_deposit, subs_of)| -> Result, DispatchError> { + let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); + Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?; + *current_subs_deposit = new_subs_deposit; + Ok(new_subs_deposit) + }, + )?; Self::deposit_event(Event::DepositUpdated { who: target, From 0b3708efed48d9b07d42cdd5bc3330deb74707b3 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 10 Oct 2023 15:50:00 +0200 Subject: [PATCH 08/37] fix alliance test config --- substrate/frame/alliance/src/mock.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/substrate/frame/alliance/src/mock.rs b/substrate/frame/alliance/src/mock.rs index 33d466de6c99..202a0d0cc1b7 100644 --- a/substrate/frame/alliance/src/mock.rs +++ b/substrate/frame/alliance/src/mock.rs @@ -126,6 +126,7 @@ impl pallet_identity::Config for Test { type ReapOrigin = EnsureOneOrRoot; type ReapIdentityHandler = (); type ForceOrigin = EnsureTwoOrRoot; + type LockerOrigin = EnsureTwoOrRoot; type WeightInfo = (); } From 7ae9df0eaa12ea0a81e0657b57b253a9bfbdb502 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 11 Oct 2023 15:46:41 +0200 Subject: [PATCH 09/37] benchmark reap_identity properly --- .../rococo/src/weights/pallet_identity.rs | 33 ++++++--- .../westend/src/weights/pallet_identity.rs | 33 ++++++--- substrate/frame/identity/src/benchmarking.rs | 27 +++++++- substrate/frame/identity/src/lib.rs | 14 ++-- substrate/frame/identity/src/tests.rs | 2 +- substrate/frame/identity/src/weights.rs | 68 +++++++++++++------ 6 files changed, 128 insertions(+), 49 deletions(-) diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs index e5ee81798f67..8da3ce4c239c 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -355,23 +355,36 @@ impl pallet_identity::WeightInfo for WeightInfo { /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) /// Storage: `Identity::SubsOf` (r:1 w:1) /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Identity::SuperOf` (r:0 w:100) /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. - fn reap_identity(s: u32, ) -> Weight { + /// The range of component `r` is `[0, 20]`. + fn reap_identity(s: u32, r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `673 + s * (32 ±0)` - // Estimated: `11003` - // Minimum execution time: 312_504_000 picoseconds. - Weight::from_parts(372_110_300, 0) + // Measured: `882 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11003 + r * (8 ±1) + s * (33 ±0)` + // Minimum execution time: 890_684_000 picoseconds. + Weight::from_parts(985_014_414, 0) .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 481_670 - .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) + // Standard Error: 512_018 + .saturating_add(Weight::from_parts(14_124_295, 0).saturating_mul(s.into())) + // Standard Error: 2_560_094 + .saturating_add(Weight::from_parts(219_854, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) } /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) diff --git a/polkadot/runtime/westend/src/weights/pallet_identity.rs b/polkadot/runtime/westend/src/weights/pallet_identity.rs index f64887294d7f..8cc91af62d49 100644 --- a/polkadot/runtime/westend/src/weights/pallet_identity.rs +++ b/polkadot/runtime/westend/src/weights/pallet_identity.rs @@ -360,23 +360,36 @@ impl pallet_identity::WeightInfo for WeightInfo { /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) /// Storage: `Identity::SubsOf` (r:1 w:1) /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Identity::SuperOf` (r:0 w:100) /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. - fn reap_identity(s: u32, ) -> Weight { + /// The range of component `r` is `[0, 20]`. + fn reap_identity(s: u32, r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `673 + s * (32 ±0)` - // Estimated: `11003` - // Minimum execution time: 312_504_000 picoseconds. - Weight::from_parts(372_110_300, 0) + // Measured: `882 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11003 + r * (8 ±1) + s * (33 ±0)` + // Minimum execution time: 890_684_000 picoseconds. + Weight::from_parts(985_014_414, 0) .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 481_670 - .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) + // Standard Error: 512_018 + .saturating_add(Weight::from_parts(14_124_295, 0).saturating_mul(s.into())) + // Standard Error: 2_560_094 + .saturating_add(Weight::from_parts(219_854, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) } /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index 22800dd3ae7b..922f1e7e5bff 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -455,20 +455,45 @@ benchmarks! { reap_identity { let s in 0 .. T::MaxSubAccounts::get(); + let r in 0 .. T::MaxRegistrars::get() => add_registrars::(r)?; + + // target let target: T::AccountId = account("target", 0, SEED); + let target_origin = + ::RuntimeOrigin::from(RawOrigin::Signed(target.clone())); let target_lookup = T::Lookup::unlookup(target.clone()); let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); + + //origin let origin = T::ReapOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + // set identity let info = create_identity_info::(1); Identity::::set_identity( RawOrigin::Signed(target.clone()).into(), Box::new(info.clone()) )?; + // set `s` subs let _ = add_sub_accounts::(&target, s)?; - }: _(origin, target_lookup, s) + + // provide judgements + for ii in 0..r { + let registrar: T::AccountId = account("registrar", ii, SEED); + let balance_to_use = T::Currency::minimum_balance() * 10u32.into(); + let _ = T::Currency::make_free_balance_be(®istrar, balance_to_use); + + Identity::::request_judgement(target_origin.clone(), ii, 10u32.into())?; + Identity::::provide_judgement( + RawOrigin::Signed(registrar).into(), + ii, + target_lookup.clone(), + Judgement::Reasonable, + T::Hashing::hash_of(&info), + )?; + } + }: _(origin, target_lookup) verify { assert_last_event::(Event::::IdentityReaped { who: target }.into()); } diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 27c0198e8701..444e5aa0f796 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -498,7 +498,7 @@ pub mod pallet { let (subs_deposit, sub_ids) = >::take(&sender); let id = >::take(&sender).ok_or(Error::::NotNamed)?; - let deposit = id.total_deposit() + subs_deposit; + let deposit = id.total_deposit().saturating_add(subs_deposit); for sub in sub_ids.iter() { >::remove(sub); } @@ -1010,12 +1010,14 @@ pub mod pallet { /// /// Origin must be the `ReapOrigin`. #[pallet::call_index(15)] - #[pallet::weight(T::WeightInfo::reap_identity(*num_subs))] + #[pallet::weight(T::WeightInfo::reap_identity( + T::MaxRegistrars::get(), + T::MaxSubAccounts::get() + ))] pub fn reap_identity( origin: OriginFor, target: AccountIdLookupOf, - num_subs: u32, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { // No locked check: used for migration. // `ReapOrigin` to be set to `EnsureSigned` (i.e. anyone) on chain where we // want to reap data (i.e. Relay) and `EnsureRoot` on chains where we want "normal" @@ -1025,11 +1027,11 @@ pub mod pallet { // `take` any storage items keyed by `target` let id = >::take(&who).ok_or(Error::::NotNamed)?; + let registrars = id.judgements.len() as u32; let fields = id.info.additional.len() as u32; let (subs_deposit, sub_ids) = >::take(&who); // check witness data let actual_subs = sub_ids.len() as u32; - ensure!(actual_subs <= num_subs, Error::::TooManySubAccounts); for sub in sub_ids.iter() { >::remove(sub); } @@ -1042,7 +1044,7 @@ pub mod pallet { // Finally, call the handler. T::ReapIdentityHandler::on_reap_identity(&who, fields, actual_subs)?; Self::deposit_event(Event::IdentityReaped { who }); - Ok(()) + Ok(Some(T::WeightInfo::reap_identity(registrars, actual_subs)).into()) } /// Update the deposits held by `target` for its identity info. diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 9f5e0b5bd1c3..7d3f44acb8e9 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -633,7 +633,7 @@ fn reap_identity_works() { )); // 10 for identity, 10 for sub assert_eq!(Balances::free_balance(10), 80); - assert_ok!(Identity::reap_identity(RuntimeOrigin::signed(1), 10, 1)); + assert_ok!(Identity::reap_identity(RuntimeOrigin::signed(1), 10)); // no identity or subs assert!(Identity::identity(10).is_none()); assert!(Identity::super_of(20).is_none()); diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index b63352870c15..91adede22e18 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -68,7 +68,7 @@ pub trait WeightInfo { fn rename_sub(s: u32, ) -> Weight; fn remove_sub(s: u32, ) -> Weight; fn quit_sub(s: u32, ) -> Weight; - fn reap_identity(s: u32, ) -> Weight; + fn reap_identity(r: u32, s: u32, ) -> Weight; fn poke_deposit() -> Weight; fn lock_pallet() -> Weight; fn unlock_pallet() -> Weight; @@ -371,23 +371,36 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) /// Storage: `Identity::SubsOf` (r:1 w:1) /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Identity::SuperOf` (r:0 w:100) /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. - fn reap_identity(s: u32, ) -> Weight { + /// The range of component `r` is `[0, 20]`. + fn reap_identity(s: u32, r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `673 + s * (32 ±0)` - // Estimated: `11003` - // Minimum execution time: 312_504_000 picoseconds. - Weight::from_parts(372_110_300, 0) + // Measured: `882 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11003 + r * (8 ±1) + s * (33 ±0)` + // Minimum execution time: 890_684_000 picoseconds. + Weight::from_parts(985_014_414, 0) .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 481_670 - .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) + // Standard Error: 512_018 + .saturating_add(Weight::from_parts(14_124_295, 0).saturating_mul(s.into())) + // Standard Error: 2_560_094 + .saturating_add(Weight::from_parts(219_854, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) } /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) @@ -725,23 +738,36 @@ impl WeightInfo for () { /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) /// Storage: `Identity::SubsOf` (r:1 w:1) /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Identity::SuperOf` (r:0 w:100) /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. - fn reap_identity(s: u32, ) -> Weight { + /// The range of component `r` is `[0, 20]`. + fn reap_identity(s: u32, r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `673 + s * (32 ±0)` - // Estimated: `11003` - // Minimum execution time: 312_504_000 picoseconds. - Weight::from_parts(372_110_300, 0) + // Measured: `882 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11003 + r * (8 ±1) + s * (33 ±0)` + // Minimum execution time: 890_684_000 picoseconds. + Weight::from_parts(985_014_414, 0) .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 481_670 - .saturating_add(Weight::from_parts(14_580_194, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(2)) + // Standard Error: 512_018 + .saturating_add(Weight::from_parts(14_124_295, 0).saturating_mul(s.into())) + // Standard Error: 2_560_094 + .saturating_add(Weight::from_parts(219_854, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(8)) + .saturating_add(RocksDbWeight::get().writes(5)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) } /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) From b517c91ae60ba09bc0b79719c58f80605a14c589 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 11 Oct 2023 16:09:19 +0200 Subject: [PATCH 10/37] put deposit info into separate function --- polkadot/runtime/rococo/src/impls.rs | 39 +++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index 569f197c0f08..3306aea38e38 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -27,27 +27,42 @@ use xcm_executor::traits::TransactAsset; /// Type that implements `OnReapIdentity` that will send the deposit needed to store the same /// information on a parachain, sends the deposit there, and then updates it. pub struct ToParachainIdentityReaper(PhantomData); -impl OnReapIdentity for ToParachainIdentityReaper -where - T: frame_system::Config + pallet_xcm::Config, - AccountId: Into<[u8; 32]> + Clone, -{ - fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { - // calculate deposit needed on parachains - // assume `relay_deposit / 100 + ED + buffer` - // buffer to cover tx fees on para, maybe ED +impl ToParachainIdentityReaper { + /// Calculate the balance needed on the remote chain based on the `IdentityInfo` and `Subs` on + /// this chain. The total includes: + /// + /// - Identity basic deposit + /// - Extra fields deposit + /// - Sub accounts deposit + /// - 2x existential deposit (1 for account existence, 1 such that the user can transact) + /// + /// This implementation is speculative and subject to change based on the remote chain's + /// configuration. + fn calculate_remote_deposit(fields: u32, subs: u32) -> Balance { + // remote deposit constants let para_basic_deposit = 1000 * CENTS / 100; let para_field_deposit = 250 * CENTS / 100; let para_sub_account_deposit = 200 * CENTS / 100; let para_existential_deposit = EXISTENTIAL_DEPOSIT / 10; + + // pallet deposits let id_deposit = para_basic_deposit.saturating_add(para_field_deposit.saturating_mul(fields as Balance)); - let subs_deposit = para_sub_account_deposit.saturating_mul(subs as Balance); - let total_to_send = id_deposit + id_deposit .saturating_add(subs_deposit) - .saturating_add(para_existential_deposit.saturating_mul(2)); + .saturating_add(para_existential_deposit.saturating_mul(2)) + } +} + +impl OnReapIdentity for ToParachainIdentityReaper +where + T: frame_system::Config + pallet_xcm::Config, + AccountId: Into<[u8; 32]> + Clone, +{ + fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { + let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective let roc: MultiAssets = From c4b45d788a0de86eff8fe911f3e5547872b5dd07 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 11 Oct 2023 18:24:35 +0200 Subject: [PATCH 11/37] update benchmarks to v2 --- substrate/frame/identity/src/benchmarking.rs | 74 +++++++++++++------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index 9c1f2a5ceaf2..02646b8aff95 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -566,9 +566,12 @@ mod benchmarks { Ok(()) } - reap_identity { - let s in 0 .. T::MaxSubAccounts::get(); - let r in 0 .. T::MaxRegistrars::get() => add_registrars::(r)?; + #[benchmark] + fn reap_identity( + r: Linear<0, { T::MaxRegistrars::get() }>, + s: Linear<0, { T::MaxSubAccounts::get() }>, + ) -> Result<(), BenchmarkError> { + add_registrars::(r)?; // target let target: T::AccountId = account("target", 0, SEED); @@ -585,7 +588,7 @@ mod benchmarks { let info = create_identity_info::(1); Identity::::set_identity( RawOrigin::Signed(target.clone()).into(), - Box::new(info.clone()) + Box::new(info.clone()), )?; // set `s` subs @@ -594,7 +597,7 @@ mod benchmarks { // provide judgements for ii in 0..r { let registrar: T::AccountId = account("registrar", ii, SEED); - let balance_to_use = T::Currency::minimum_balance() * 10u32.into(); + let balance_to_use = T::Currency::minimum_balance() * 10u32.into(); let _ = T::Currency::make_free_balance_be(®istrar, balance_to_use); Identity::::request_judgement(target_origin.clone(), ii, 10u32.into())?; @@ -606,12 +609,17 @@ mod benchmarks { T::Hashing::hash_of(&info), )?; } - }: _(origin, target_lookup) - verify { + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, target_lookup); + assert_last_event::(Event::::IdentityReaped { who: target }.into()); + + Ok(()) } - poke_deposit { + #[benchmark] + fn poke_deposit() -> Result<(), BenchmarkError> { let caller: T::AccountId = whitelisted_caller(); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); @@ -633,42 +641,56 @@ mod benchmarks { let subs = BoundedVec::<_, T::MaxSubAccounts>::try_from(vec![sub_account]).unwrap(); SubsOf::::insert::< &T::AccountId, - (BalanceOf, BoundedVec) - >( - &target, - (Zero::zero(), subs) - ); + (BalanceOf, BoundedVec), + >(&target, (Zero::zero(), subs)); // expected deposits let expected_id_deposit = T::FieldDeposit::get() .saturating_mul(additional_fields.into()) .saturating_add(T::BasicDeposit::get()); let expected_sub_deposit = T::SubAccountDeposit::get(); // only 1 - }: _(RawOrigin::Signed(caller.clone()), target_lookup) - verify { - assert_last_event::(Event::::DepositUpdated { - who: target, - identity: expected_id_deposit, - subs: expected_sub_deposit - }.into()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), target_lookup); + + assert_last_event::( + Event::::DepositUpdated { + who: target, + identity: expected_id_deposit, + subs: expected_sub_deposit, + } + .into(), + ); + + Ok(()) } - lock_pallet { + #[benchmark] + fn lock_pallet() -> Result<(), BenchmarkError> { let origin = T::LockerOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; Identity::::unlock_pallet(origin.clone())?; - }: _(origin) - verify { + + #[extrinsic_call] + _(origin as T::RuntimeOrigin); + assert!(Locked::::get()); + + Ok(()) } - unlock_pallet { + #[benchmark] + fn unlock_pallet() -> Result<(), BenchmarkError> { let origin = T::LockerOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; Identity::::lock_pallet(origin.clone())?; - }: _(origin) - verify { + + #[extrinsic_call] + _(origin as T::RuntimeOrigin); + assert!(!Locked::::get()); + + Ok(()) } impl_benchmark_test_suite!(Identity, crate::tests::new_test_ext(), crate::tests::Test); From 776910c0122b981a0ebebe19a52c41a4a86a403f Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 14 Oct 2023 16:15:30 +0200 Subject: [PATCH 12/37] test that correct functions get locked --- substrate/frame/identity/src/lib.rs | 1 - substrate/frame/identity/src/tests.rs | 96 +++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 444e5aa0f796..35c4c4187fb6 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -1006,7 +1006,6 @@ pub mod pallet { /// /// Parameters: /// - `target`: The account for which to reap identity state. - /// - `num_subs`: Witness data. The maximum number of sub accounts that `target` has. /// /// Origin must be the `ReapOrigin`. #[pallet::call_index(15)] diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 7d3f44acb8e9..c5f0f94c4a7b 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -674,3 +674,99 @@ fn poke_deposit_works() { assert_eq!(Identity::subs_of(10), (10, vec![20].try_into().unwrap())); }); } + +#[test] +fn pallet_locks_and_unlocks() { + new_test_ext().execute_with(|| { + // Can add registrars and reap + let one_as_origin = RuntimeOrigin::signed(1); + // Killer + let two_as_origin = RuntimeOrigin::signed(2); + // Registrar + let three_as_origin = RuntimeOrigin::signed(3); + // Sets identity + let ten_as_origin = RuntimeOrigin::signed(10); + // Sets identity + let twenty_as_origin = RuntimeOrigin::signed(20); + // Sub data to use + let data = Data::Raw(vec![40; 1].try_into().unwrap()); + + // Set some state before locking so that calls are sensible + assert_ok!(Identity::add_registrar(one_as_origin.clone(), 3)); + assert_ok!(Identity::set_identity(ten_as_origin.clone(), Box::new(ten()))); + assert_ok!(Identity::request_judgement(ten_as_origin.clone(), 0, 10)); + + // Lock + assert_ok!(Identity::lock_pallet(one_as_origin.clone())); + + // Almost everything is uncallable + assert_noop!( + Identity::add_registrar(one_as_origin.clone(), 1), + Error::::PalletLocked + ); + assert_noop!( + Identity::set_identity(twenty_as_origin.clone(), Box::new(twenty())), + Error::::PalletLocked + ); + assert_noop!( + Identity::set_subs(ten_as_origin.clone(), vec![(20, data.clone())]), + Error::::PalletLocked + ); + assert_noop!(Identity::clear_identity(ten_as_origin.clone()), Error::::PalletLocked); + assert_noop!( + Identity::request_judgement(twenty_as_origin.clone(), 0, 10), + Error::::PalletLocked + ); + assert_noop!( + Identity::cancel_request(twenty_as_origin.clone(), 0), + Error::::PalletLocked + ); + assert_noop!( + Identity::set_fee(three_as_origin.clone(), 0, 10), + Error::::PalletLocked + ); + assert_noop!( + Identity::set_account_id(three_as_origin.clone(), 0, 4), + Error::::PalletLocked + ); + assert_noop!( + Identity::set_fields( + three_as_origin.clone(), + 0, + IdentityFields(IdentityField::Display | IdentityField::Legal) + ), + Error::::PalletLocked + ); + assert_noop!( + Identity::provide_judgement( + three_as_origin, + 0, + 10, + Judgement::Reasonable, + BlakeTwo256::hash_of(&ten()) + ), + Error::::PalletLocked + ); + assert_noop!(Identity::kill_identity(two_as_origin, 10), Error::::PalletLocked); + assert_noop!( + Identity::add_sub(ten_as_origin.clone(), 1, data.clone()), + Error::::PalletLocked + ); + assert_noop!( + Identity::rename_sub(ten_as_origin.clone(), 1, data), + Error::::PalletLocked + ); + assert_noop!(Identity::remove_sub(ten_as_origin.clone(), 1), Error::::PalletLocked); + assert_noop!(Identity::quit_sub(one_as_origin.clone()), Error::::PalletLocked); + + // Reap and Poke are still callable for migration + assert_ok!(Identity::poke_deposit(one_as_origin.clone(), 10)); + assert_ok!(Identity::reap_identity(one_as_origin.clone(), 10)); + + // Unlock still needs to be callable, obviously + assert_ok!(Identity::unlock_pallet(one_as_origin)); + + // And pallet works + assert_ok!(Identity::set_identity(twenty_as_origin, Box::new(twenty()))); + }); +} From 88a9923ce75057c1db1836087cf10891488519b2 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 17 Oct 2023 09:21:24 +0200 Subject: [PATCH 13/37] no need to filter with pallet lock --- polkadot/runtime/rococo/src/lib.rs | 27 ++++----------------------- polkadot/runtime/westend/src/lib.rs | 15 ++------------- 2 files changed, 6 insertions(+), 36 deletions(-) diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 707ea8aa6880..5f8788d911d7 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -67,9 +67,9 @@ use frame_support::{ genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ - fungible::HoldConsideration, Contains, EitherOf, EitherOfDiverse, EverythingBut, - InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage, - ProcessMessageError, StorageMapShim, WithdrawReasons, + fungible::HoldConsideration, EitherOf, EitherOfDiverse, Everything, InstanceFilter, + KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError, + StorageMapShim, WithdrawReasons, }, weights::{ConstantMultiplier, WeightMeter}, PalletId, @@ -157,32 +157,13 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } -/// A type to identify calls to the Identity pallet. These will be filtered to prevent invocation, -/// locking the state of the pallet and preventing further updates to identities and sub-identities. -/// The locked state will be the genesis state of a new system chain and then removed from the Relay -/// Chain. -pub struct IdentityCalls; -impl Contains for IdentityCalls { - fn contains(c: &RuntimeCall) -> bool { - match c { - // Allow calls to reap identity and poke deposit - RuntimeCall::Identity(pallet_identity::Call::reap_identity { .. }) | - RuntimeCall::Identity(pallet_identity::Call::poke_deposit { .. }) => false, - // Block all other calls to identity - RuntimeCall::Identity(_) => true, - // Allow all other calls - _ => false, - } - } -} - parameter_types! { pub const Version: RuntimeVersion = VERSION; pub const SS58Prefix: u8 = 42; } impl frame_system::Config for Runtime { - type BaseCallFilter = EverythingBut; + type BaseCallFilter = Everything; type BlockWeights = BlockWeights; type BlockLength = BlockLength; type DbWeight = RocksDbWeight; diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 308cff4c158e..e140b10f6acd 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -31,7 +31,7 @@ use frame_support::{ genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ - fungible::HoldConsideration, ConstU32, Contains, EitherOf, EitherOfDiverse, EverythingBut, + fungible::HoldConsideration, ConstU32, EitherOf, EitherOfDiverse, Everything, InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, ProcessMessageError, WithdrawReasons, }, @@ -160,24 +160,13 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } -/// A type to identify calls to the Identity pallet. These will be filtered to prevent invocation, -/// locking the state of the pallet and preventing further updates to identities and sub-identities. -/// The locked state will be the genesis state of a new system chain and then removed from the Relay -/// Chain. -pub struct IdentityCalls; -impl Contains for IdentityCalls { - fn contains(c: &RuntimeCall) -> bool { - matches!(c, RuntimeCall::Identity(_)) - } -} - parameter_types! { pub const Version: RuntimeVersion = VERSION; pub const SS58Prefix: u8 = 42; } impl frame_system::Config for Runtime { - type BaseCallFilter = EverythingBut; + type BaseCallFilter = Everything; type BlockWeights = BlockWeights; type BlockLength = BlockLength; type RuntimeOrigin = RuntimeOrigin; From 390ce01480b8ef5b02a35a7dd23cc448e5fbc124 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 24 Oct 2023 15:01:55 +0200 Subject: [PATCH 14/37] fix compile errors on merge --- substrate/frame/identity/src/benchmarking.rs | 4 ++-- substrate/frame/identity/src/lib.rs | 6 ++++-- substrate/frame/identity/src/tests.rs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index 31ce065a7410..df8bc7dd6dc8 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -561,7 +561,7 @@ mod benchmarks { T::ReapOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; // set identity - let info = create_identity_info::(1); + let info = T::IdentityInformation::create_identity_info(1); Identity::::set_identity( RawOrigin::Signed(target.clone()).into(), Box::new(info.clone()), @@ -608,7 +608,7 @@ mod benchmarks { Registration { judgements: BoundedVec::default(), deposit: Zero::zero(), - info: create_identity_info::(additional_fields), + info: T::IdentityInformation::create_identity_info(additional_fields), }, ); diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 4ccadfd1a3db..8ec05c786bf8 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -990,7 +990,8 @@ pub mod pallet { // `take` any storage items keyed by `target` let id = >::take(&who).ok_or(Error::::NotNamed)?; let registrars = id.judgements.len() as u32; - let fields = id.info.additional.len() as u32; + #[allow(deprecated)] + let fields = id.info.additional() as u32; let (subs_deposit, sub_ids) = >::take(&who); // check witness data let actual_subs = sub_ids.len() as u32; @@ -1030,8 +1031,9 @@ pub mod pallet { |registration| -> Result, DispatchError> { let reg = registration.as_mut().ok_or(Error::::NoIdentity)?; // Calculate what deposit should be + #[allow(deprecated)] let field_deposit = T::FieldDeposit::get() - .saturating_mul(BalanceOf::::from(reg.info.additional.len() as u32)); + .saturating_mul(BalanceOf::::from(reg.info.additional() as u32)); let new_id_deposit = T::BasicDeposit::get().saturating_add(field_deposit); // Update account diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 2d33b412ff63..172f83e5fceb 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -777,7 +777,7 @@ fn pallet_locks_and_unlocks() { Identity::set_fields( three_as_origin.clone(), 0, - IdentityFields(IdentityField::Display | IdentityField::Legal) + IdentityFields(SimpleIdentityField::Display | SimpleIdentityField::Legal) ), Error::::PalletLocked ); From 9da0726970a8711ddebd209c46675708d68244a9 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 25 Oct 2023 19:16:57 +0200 Subject: [PATCH 15/37] add poke call encoding to handler impl --- polkadot/runtime/rococo/src/impls.rs | 54 +++++++++++++++++++--------- polkadot/runtime/rococo/src/lib.rs | 2 +- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index 3306aea38e38..06461ccd9c4c 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -18,16 +18,33 @@ use crate::xcm_config; use frame_support::pallet_prelude::DispatchResult; use frame_system::RawOrigin; use pallet_identity::OnReapIdentity; +use parity_scale_codec::{Decode, Encode}; use primitives::Balance; use rococo_runtime_constants::currency::*; +use sp_runtime::RuntimeDebug; use sp_std::{marker::PhantomData, prelude::*}; -use xcm::{latest::prelude::*, /* v2::OriginKind, */ VersionedMultiLocation, VersionedXcm}; +use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; +/// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any +/// remote calls. +#[derive(Encode, Decode, RuntimeDebug)] +enum PeopleRuntimePallets { + #[codec(index = 50)] + Identity(IdentityCalls), +} + +/// Call encoding for the calls needed from the Identity pallet. +#[derive(Encode, Decode, RuntimeDebug)] +enum IdentityCalls { + #[codec(index = 16)] + PokeDeposit(AccountId), +} + /// Type that implements `OnReapIdentity` that will send the deposit needed to store the same /// information on a parachain, sends the deposit there, and then updates it. -pub struct ToParachainIdentityReaper(PhantomData); -impl ToParachainIdentityReaper { +pub struct ToParachainIdentityReaper(PhantomData<(Runtime, AccountId)>); +impl ToParachainIdentityReaper { /// Calculate the balance needed on the remote chain based on the `IdentityInfo` and `Subs` on /// this chain. The total includes: /// @@ -56,20 +73,22 @@ impl ToParachainIdentityReaper { } } -impl OnReapIdentity for ToParachainIdentityReaper +impl OnReapIdentity for ToParachainIdentityReaper where - T: frame_system::Config + pallet_xcm::Config, - AccountId: Into<[u8; 32]> + Clone, + Runtime: frame_system::Config + pallet_xcm::Config, + AccountId: Into<[u8; 32]> + Clone + Encode, { fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { + use crate::impls::IdentityCalls::PokeDeposit; + let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective let roc: MultiAssets = vec![MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }] .into(); - // todo: people chain para id - let destination: MultiLocation = MultiLocation::new(0, Parachain(1000)); + // TODO: confirm people chain para id. Tentatively 1004. + let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support // unpaid teleports. @@ -81,7 +100,7 @@ where // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ) - .map_err(|_| pallet_xcm::Error::::InvalidAsset)?; + .map_err(|_| pallet_xcm::Error::::InvalidAsset)?; xcm_config::LocalAssetTransactor::check_out( &destination, &roc.inner().first().unwrap(), // <- safe unwrap since we just set `roc`. @@ -96,6 +115,8 @@ where }] .into(); + let poke = PeopleRuntimePallets::::Identity(PokeDeposit(who.clone())); + // Actual program to execute on People Chain. let program: Xcm<()> = Xcm(vec![ // Unpaid as this is constructed by the system, once per user. The user shouldn't have @@ -110,17 +131,16 @@ where .into_location() .into(), }, - // // Poke the deposit to reserve the appropriate amount on the parachain. - // Transact { - // origin_kind: OriginKind::Superuser, - // require_weight_at_most: Weight {ref_time: 2_000_000_000, proof_size: 16_384}, - // // Need People Chain runtime to encode call. - // call: DoubleEncoded { encoded: /* pallet_identity::poke_deposit(who) */ }, - // }, + // Poke the deposit to reserve the appropriate amount on the parachain. + Transact { + origin_kind: OriginKind::Superuser, + require_weight_at_most: Weight::from_parts(2_000_000_000, 16_384), + call: poke.encode().into(), + }, ]); // send - let _ = >::send( + let _ = >::send( RawOrigin::Root.into(), Box::new(VersionedMultiLocation::V3(destination)), Box::new(VersionedXcm::V3(program)), diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index f4b2782e97e7..2790690c9f52 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -623,7 +623,7 @@ impl pallet_identity::Config for Runtime { // Should be `EnsureRoot` until the parachain launches with Identity state. Then, it will be // `EnsureSigned` to allow deposit migration. type ReapOrigin = EnsureRoot; - type ReapIdentityHandler = ToParachainIdentityReaper; + type ReapIdentityHandler = ToParachainIdentityReaper; type LockerOrigin = EnsureRoot; type WeightInfo = weights::pallet_identity::WeightInfo; } From 255893d1dd7be0a56b8667972a87133bb94fd498 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 25 Oct 2023 19:19:17 +0200 Subject: [PATCH 16/37] don't need RuntimeDebug --- polkadot/runtime/rococo/src/impls.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index 06461ccd9c4c..7252f79cb2ea 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -21,21 +21,20 @@ use pallet_identity::OnReapIdentity; use parity_scale_codec::{Decode, Encode}; use primitives::Balance; use rococo_runtime_constants::currency::*; -use sp_runtime::RuntimeDebug; use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; /// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any /// remote calls. -#[derive(Encode, Decode, RuntimeDebug)] +#[derive(Encode, Decode)] enum PeopleRuntimePallets { #[codec(index = 50)] Identity(IdentityCalls), } /// Call encoding for the calls needed from the Identity pallet. -#[derive(Encode, Decode, RuntimeDebug)] +#[derive(Encode, Decode)] enum IdentityCalls { #[codec(index = 16)] PokeDeposit(AccountId), From 298931a4681b4d1692c172d62b85699c1d6c79cc Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Tue, 31 Oct 2023 13:24:19 +0100 Subject: [PATCH 17/37] Reduce Impact on Identity Pallet in Migration (#2088) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses https://github.com/paritytech/polkadot-sdk/pull/1814#pullrequestreview-1701818579 - Removes `lock`/`unlock` extrinsics - Moves `reap_identity` and `poke_deposit` into special migration pallet to avoid adding new one-time calls to the Identity pallet --------- Co-authored-by: Bastian Köcher --- Cargo.lock | 1 + polkadot/runtime/common/Cargo.toml | 4 + .../runtime/common/src/identity_migrator.rs | 137 +++++++++++ polkadot/runtime/common/src/lib.rs | 1 + polkadot/runtime/rococo/src/impls.rs | 14 +- polkadot/runtime/rococo/src/lib.rs | 18 +- .../rococo/src/weights/pallet_identity.rs | 22 -- polkadot/runtime/westend/src/lib.rs | 3 - .../westend/src/weights/pallet_identity.rs | 22 -- substrate/bin/node/runtime/src/lib.rs | 3 - substrate/frame/alliance/src/mock.rs | 3 - substrate/frame/identity/src/benchmarking.rs | 60 ++--- substrate/frame/identity/src/lib.rs | 230 ++++++------------ substrate/frame/identity/src/tests.rs | 103 +------- substrate/frame/identity/src/weights.rs | 46 ---- 15 files changed, 254 insertions(+), 413 deletions(-) create mode 100644 polkadot/runtime/common/src/identity_migrator.rs diff --git a/Cargo.lock b/Cargo.lock index a8d679c6ce8b..9ff20b1e1017 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12721,6 +12721,7 @@ dependencies = [ "pallet-balances", "pallet-election-provider-multi-phase", "pallet-fast-unstake", + "pallet-identity", "pallet-session", "pallet-staking", "pallet-staking-reward-fn", diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index 18332156d99a..f34fd71af28e 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -30,6 +30,7 @@ sp-npos-elections = { path = "../../../substrate/primitives/npos-elections", def pallet-authorship = { path = "../../../substrate/frame/authorship", default-features = false } pallet-balances = { path = "../../../substrate/frame/balances", default-features = false } pallet-fast-unstake = { path = "../../../substrate/frame/fast-unstake", default-features = false } +pallet-identity = { path = "../../../substrate/frame/identity", default-features = false } pallet-session = { path = "../../../substrate/frame/session", default-features = false } frame-support = { path = "../../../substrate/frame/support", default-features = false } pallet-staking = { path = "../../../substrate/frame/staking", default-features = false } @@ -85,6 +86,7 @@ std = [ "pallet-balances/std", "pallet-election-provider-multi-phase/std", "pallet-fast-unstake/std", + "pallet-identity/std", "pallet-session/std", "pallet-staking-reward-fn/std", "pallet-staking/std", @@ -124,6 +126,7 @@ runtime-benchmarks = [ "pallet-balances/runtime-benchmarks", "pallet-election-provider-multi-phase/runtime-benchmarks", "pallet-fast-unstake/runtime-benchmarks", + "pallet-identity/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", @@ -147,6 +150,7 @@ try-runtime = [ "pallet-balances/try-runtime", "pallet-election-provider-multi-phase/try-runtime", "pallet-fast-unstake/try-runtime", + "pallet-identity/try-runtime", "pallet-session/try-runtime", "pallet-staking/try-runtime", "pallet-timestamp/try-runtime", diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs new file mode 100644 index 000000000000..d3ccc8df7803 --- /dev/null +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -0,0 +1,137 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! This pallet is designed to go into a source chain and destination chain to migrate data. The +//! design motivations are: +//! +//! - Call some function on the source chain that executes some migration (clearing state, +//! forwarding an XCM program). +//! - Call some function (probably from an XCM program) on the destination chain. +//! - Avoid cluttering the source pallet with new dispatchables that are unrelated to its +//! functionality and only used for migration. +//! +//! After the migration is complete, the pallet may be removed from both chains' runtimes. + +use frame_support::{dispatch::DispatchResult, traits::Currency}; +pub use pallet::*; +use pallet_identity::{self, WeightInfo}; +use sp_core::Get; + +type BalanceOf = <::Currency as Currency< + ::AccountId, +>>::Balance; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::{ + dispatch::{DispatchResultWithPostInfo, PostDispatchInfo}, + pallet_prelude::*, + traits::EnsureOrigin, + }; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config + pallet_identity::Config { + /// Overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The origin that can reap identities. Expected to be `EnsureSigned` on the + /// source chain such that anyone can all this function. + type Reaper: EnsureOrigin; + + /// A handler for what to do when an identity is reaped. + type ReapIdentityHandler: OnReapIdentity; + + /// Weight information for the extrinsics in the pallet. + type WeightInfo: pallet_identity::WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// The identity and all sub accounts were reaped for `who`. + IdentityReaped { who: T::AccountId }, + /// The deposits held for `who` were updated. `identity` is the new deposit held for + /// identity info, and `subs` is the new deposit held for the sub-accounts. + DepositUpdated { who: T::AccountId, identity: BalanceOf, subs: BalanceOf }, + } + + #[pallet::call] + impl Pallet { + /// Reap the Identity Info of `who` from the Relay Chain, unreserving any deposits held and + /// removing storage items associated with `who`. + #[pallet::call_index(0)] + #[pallet::weight(::WeightInfo::reap_identity( + T::MaxRegistrars::get(), + T::MaxSubAccounts::get() + ))] + pub fn reap_identity( + origin: OriginFor, + who: T::AccountId, + ) -> DispatchResultWithPostInfo { + T::Reaper::ensure_origin(origin)?; + let (registrars, fields, subs) = pallet_identity::Pallet::::reap_identity(&who)?; + T::ReapIdentityHandler::on_reap_identity(&who, fields, subs)?; + Self::deposit_event(Event::IdentityReaped { who }); + let post = PostDispatchInfo { + actual_weight: Some(::WeightInfo::reap_identity( + registrars, subs, + )), + pays_fee: Pays::No, + }; + Ok(post) + } + + /// Update the deposit of `who`. Meant to be called by the system with an XCM `Transact` + /// Instruction. + #[pallet::call_index(1)] + #[pallet::weight(::WeightInfo::poke_deposit())] + pub fn poke_deposit(origin: OriginFor, who: T::AccountId) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + let (id_deposit, subs_deposit) = pallet_identity::Pallet::::poke_deposit(&who)?; + Self::deposit_event(Event::DepositUpdated { + who, + identity: id_deposit, + subs: subs_deposit, + }); + Ok(Pays::No.into()) + } + } +} + +/// Trait to handle reaping identity from state. +pub trait OnReapIdentity { + /// What to do when an identity is reaped. For example, the implementation could send an XCM + /// program to another chain. Concretely, a type implementing this trait in the Polkadot + /// runtime would teleport enough DOT to the People Chain to cover the Identity deposit there. + /// + /// This could also directly include `Transact { poke_deposit(..), ..}`. + /// + /// Inputs + /// - `who`: Whose identity was reaped. + /// - `fields`: The number of `additional_fields` they had. + /// - `subs`: The number of sub-accounts they had. + fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult; +} + +impl OnReapIdentity for () { + fn on_reap_identity(_who: &AccountId, _fields: u32, _subs: u32) -> DispatchResult { + Ok(()) + } +} diff --git a/polkadot/runtime/common/src/lib.rs b/polkadot/runtime/common/src/lib.rs index 46a9f7d12cd4..2788c35a7409 100644 --- a/polkadot/runtime/common/src/lib.rs +++ b/polkadot/runtime/common/src/lib.rs @@ -23,6 +23,7 @@ pub mod auctions; pub mod claims; pub mod crowdloan; pub mod elections; +pub mod identity_migrator; pub mod impls; pub mod paras_registrar; pub mod paras_sudo_wrapper; diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index 7252f79cb2ea..0f33979f128d 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -17,10 +17,10 @@ use crate::xcm_config; use frame_support::pallet_prelude::DispatchResult; use frame_system::RawOrigin; -use pallet_identity::OnReapIdentity; use parity_scale_codec::{Decode, Encode}; use primitives::Balance; use rococo_runtime_constants::currency::*; +use runtime_common::identity_migrator::OnReapIdentity; use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; @@ -29,14 +29,14 @@ use xcm_executor::traits::TransactAsset; /// remote calls. #[derive(Encode, Decode)] enum PeopleRuntimePallets { - #[codec(index = 50)] - Identity(IdentityCalls), + #[codec(index = 248)] + IdentityMigrator(IdentityMigratorCalls), } /// Call encoding for the calls needed from the Identity pallet. #[derive(Encode, Decode)] -enum IdentityCalls { - #[codec(index = 16)] +enum IdentityMigratorCalls { + #[codec(index = 1)] PokeDeposit(AccountId), } @@ -78,7 +78,7 @@ where AccountId: Into<[u8; 32]> + Clone + Encode, { fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { - use crate::impls::IdentityCalls::PokeDeposit; + use crate::impls::IdentityMigratorCalls::PokeDeposit; let total_to_send = Self::calculate_remote_deposit(fields, subs); @@ -114,7 +114,7 @@ where }] .into(); - let poke = PeopleRuntimePallets::::Identity(PokeDeposit(who.clone())); + let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); // Actual program to execute on People Chain. let program: Xcm<()> = Xcm(vec![ diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 2790690c9f52..8be97ce67a0a 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -30,7 +30,7 @@ use primitives::{ ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, }; use runtime_common::{ - assigned_slots, auctions, claims, crowdloan, impl_runtime_weights, + assigned_slots, auctions, claims, crowdloan, identity_migrator, impl_runtime_weights, impls::{ LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedMultiLocationConverter, }, @@ -620,11 +620,6 @@ impl pallet_identity::Config for Runtime { type Slashed = Treasury; type ForceOrigin = EitherOf, GeneralAdmin>; type RegistrarOrigin = EitherOf, GeneralAdmin>; - // Should be `EnsureRoot` until the parachain launches with Identity state. Then, it will be - // `EnsureSigned` to allow deposit migration. - type ReapOrigin = EnsureRoot; - type ReapIdentityHandler = ToParachainIdentityReaper; - type LockerOrigin = EnsureRoot; type WeightInfo = weights::pallet_identity::WeightInfo; } @@ -1080,6 +1075,14 @@ impl auctions::Config for Runtime { type WeightInfo = weights::runtime_common_auctions::WeightInfo; } +impl identity_migrator::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + // To be changed to `EnsureSigned` once there is a People Chain to migrate to. + type Reaper = EnsureRoot; + type ReapIdentityHandler = ToParachainIdentityReaper; + type WeightInfo = weights::pallet_identity::WeightInfo; +} + type NisCounterpartInstance = pallet_balances::Instance2; impl pallet_balances::Config for Runtime { type Balance = Balance; @@ -1368,6 +1371,9 @@ construct_runtime! { // Pallet for sending XCM. XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + // Pallet for migrating Identity to a parachain. To be removed post-migration. + IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 250, AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event, Config} = 251, diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs index 8da3ce4c239c..e2d33ebb3e0c 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -402,26 +402,4 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Identity::Locked` (r:0 w:1) - /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - fn lock_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 43_286_000 picoseconds. - Weight::from_parts(51_523_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Identity::Locked` (r:0 w:1) - /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - fn unlock_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 42_243_000 picoseconds. - Weight::from_parts(52_907_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) - } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 76affb68337f..9ee4f3cf23e5 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -881,9 +881,6 @@ impl pallet_identity::Config for Runtime { type MaxRegistrars = MaxRegistrars; type ForceOrigin = EitherOf, GeneralAdmin>; type RegistrarOrigin = EitherOf, GeneralAdmin>; - type ReapOrigin = EnsureRoot; - type ReapIdentityHandler = (); - type LockerOrigin = EnsureRoot; type WeightInfo = weights::pallet_identity::WeightInfo; } diff --git a/polkadot/runtime/westend/src/weights/pallet_identity.rs b/polkadot/runtime/westend/src/weights/pallet_identity.rs index 8cc91af62d49..d120b0fc5c1f 100644 --- a/polkadot/runtime/westend/src/weights/pallet_identity.rs +++ b/polkadot/runtime/westend/src/weights/pallet_identity.rs @@ -407,26 +407,4 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Identity::Locked` (r:0 w:1) - /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - fn lock_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 43_286_000 picoseconds. - Weight::from_parts(51_523_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Identity::Locked` (r:0 w:1) - /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - fn unlock_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 42_243_000 picoseconds. - Weight::from_parts(52_907_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) - } } diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 9262bde7f048..f4c8a5940a3c 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1480,9 +1480,6 @@ impl pallet_identity::Config for Runtime { type Slashed = Treasury; type ForceOrigin = EnsureRootOrHalfCouncil; type RegistrarOrigin = EnsureRootOrHalfCouncil; - type ReapOrigin = EnsureRoot; - type ReapIdentityHandler = (); - type LockerOrigin = EnsureRoot; type WeightInfo = pallet_identity::weights::SubstrateWeight; } diff --git a/substrate/frame/alliance/src/mock.rs b/substrate/frame/alliance/src/mock.rs index b0fa378556b4..a5970bc7af67 100644 --- a/substrate/frame/alliance/src/mock.rs +++ b/substrate/frame/alliance/src/mock.rs @@ -125,10 +125,7 @@ impl pallet_identity::Config for Test { type MaxRegistrars = MaxRegistrars; type Slashed = (); type RegistrarOrigin = EnsureOneOrRoot; - type ReapOrigin = EnsureOneOrRoot; - type ReapIdentityHandler = (); type ForceOrigin = EnsureTwoOrRoot; - type LockerOrigin = EnsureTwoOrRoot; type WeightInfo = (); } diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index df8bc7dd6dc8..906c185e1cc6 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -556,10 +556,6 @@ mod benchmarks { let target_lookup = T::Lookup::unlookup(target.clone()); let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); - //origin - let origin = - T::ReapOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - // set identity let info = T::IdentityInformation::create_identity_info(1); Identity::::set_identity( @@ -586,19 +582,20 @@ mod benchmarks { )?; } - #[extrinsic_call] - _(origin as T::RuntimeOrigin, target_lookup); + #[block] + { + let _ = Identity::::reap_identity(&target); + } - assert_last_event::(Event::::IdentityReaped { who: target }.into()); + assert!(IdentityOf::::get(&target).is_none()); + assert_eq!(SubsOf::::get(&target).0, Zero::zero()); Ok(()) } #[benchmark] fn poke_deposit() -> Result<(), BenchmarkError> { - let caller: T::AccountId = whitelisted_caller(); let target: T::AccountId = account("target", 0, SEED); - let target_lookup = T::Lookup::unlookup(target.clone()); let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); let additional_fields = 0; @@ -626,45 +623,16 @@ mod benchmarks { .saturating_add(T::BasicDeposit::get()); let expected_sub_deposit = T::SubAccountDeposit::get(); // only 1 - #[extrinsic_call] - _(RawOrigin::Signed(caller), target_lookup); - - assert_last_event::( - Event::::DepositUpdated { - who: target, - identity: expected_id_deposit, - subs: expected_sub_deposit, - } - .into(), - ); - - Ok(()) - } - - #[benchmark] - fn lock_pallet() -> Result<(), BenchmarkError> { - let origin = - T::LockerOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - Identity::::unlock_pallet(origin.clone())?; - - #[extrinsic_call] - _(origin as T::RuntimeOrigin); - - assert!(Locked::::get()); - - Ok(()) - } - - #[benchmark] - fn unlock_pallet() -> Result<(), BenchmarkError> { - let origin = - T::LockerOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - Identity::::lock_pallet(origin.clone())?; + #[block] + { + let _ = Identity::::poke_deposit(&target); + } - #[extrinsic_call] - _(origin as T::RuntimeOrigin); + let info = IdentityOf::::get(&target).unwrap(); + assert_eq!(info.deposit, expected_id_deposit); - assert!(!Locked::::get()); + let subs = SubsOf::::get(&target); + assert_eq!(subs.0, expected_sub_deposit); Ok(()) } diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 8ec05c786bf8..17c9d7789f3d 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -80,7 +80,8 @@ mod types; pub mod weights; use frame_support::{ - pallet_prelude::DispatchResult, + ensure, + pallet_prelude::{DispatchError, DispatchResult, DispatchResultWithPostInfo}, traits::{BalanceStatus, Currency, Get, OnUnbalanced, ReservableCurrency}, }; use sp_runtime::traits::{AppendZerosInput, Hash, Saturating, StaticLookup, Zero}; @@ -154,15 +155,6 @@ pub mod pallet { /// The origin which may add or remove registrars. Root can always do this. type RegistrarOrigin: EnsureOrigin; - /// The origin that can reap an account's identity info. - type ReapOrigin: EnsureOrigin; - - /// A handler for what to do when an identity is reaped. - type ReapIdentityHandler: OnReapIdentity; - - /// The origin that can lock calls to the pallet. - type LockerOrigin: EnsureOrigin; - /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -297,11 +289,6 @@ pub mod pallet { /// A sub-identity was cleared, and the given deposit repatriated from the /// main identity account to the sub-identity account. SubIdentityRevoked { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf }, - /// The identity and all sub accounts were reaped for `who`. - IdentityReaped { who: T::AccountId }, - /// The deposits held for `who` were updated. `identity` is the new deposit held for - /// identity info, and `subs` is the new deposit held for the sub-accounts. - DepositUpdated { who: T::AccountId, identity: BalanceOf, subs: BalanceOf }, } #[pallet::call] @@ -961,129 +948,6 @@ pub mod pallet { }); Ok(()) } - - /// Reap an identity, clearing associated storage items and refunding any deposits. Calls - /// the `ReapIdentityHandler`, which can be implemented in the runtime. This function is - /// very similar to (a) `clear_identity`, but called on a `target` account instead of self; - /// and (b) `kill_identity`, but without imposing a slash. - /// - /// Parameters: - /// - `target`: The account for which to reap identity state. - /// - /// Origin must be the `ReapOrigin`. - #[pallet::call_index(15)] - #[pallet::weight(T::WeightInfo::reap_identity( - T::MaxRegistrars::get(), - T::MaxSubAccounts::get() - ))] - pub fn reap_identity( - origin: OriginFor, - target: AccountIdLookupOf, - ) -> DispatchResultWithPostInfo { - // No locked check: used for migration. - // `ReapOrigin` to be set to `EnsureSigned` (i.e. anyone) on chain where we - // want to reap data (i.e. Relay) and `EnsureRoot` on chains where we want "normal" - // functionality (i.e. the People Chain). - T::ReapOrigin::ensure_origin(origin)?; - let who = T::Lookup::lookup(target)?; - - // `take` any storage items keyed by `target` - let id = >::take(&who).ok_or(Error::::NotNamed)?; - let registrars = id.judgements.len() as u32; - #[allow(deprecated)] - let fields = id.info.additional() as u32; - let (subs_deposit, sub_ids) = >::take(&who); - // check witness data - let actual_subs = sub_ids.len() as u32; - for sub in sub_ids.iter() { - >::remove(sub); - } - - // unreserve any deposits - let deposit = id.total_deposit().saturating_add(subs_deposit); - let err_amount = T::Currency::unreserve(&who, deposit); - debug_assert!(err_amount.is_zero()); - - // Finally, call the handler. - T::ReapIdentityHandler::on_reap_identity(&who, fields, actual_subs)?; - Self::deposit_event(Event::IdentityReaped { who }); - Ok(Some(T::WeightInfo::reap_identity(registrars, actual_subs)).into()) - } - - /// Update the deposits held by `target` for its identity info. - /// - /// Parameters: - /// - `target`: The account for which to update deposits. - /// - /// May be called by any signed origin. - #[pallet::call_index(16)] - #[pallet::weight(T::WeightInfo::poke_deposit())] - pub fn poke_deposit(origin: OriginFor, target: AccountIdLookupOf) -> DispatchResult { - // No locked check: used for migration. - // anyone or root (so that the system can call it for identity migration) - let _ = ensure_signed_or_root(origin)?; - let target = T::Lookup::lookup(target)?; - - // Identity Deposit - ensure!(IdentityOf::::contains_key(&target), Error::::NoIdentity); - let new_id_deposit = IdentityOf::::try_mutate( - &target, - |registration| -> Result, DispatchError> { - let reg = registration.as_mut().ok_or(Error::::NoIdentity)?; - // Calculate what deposit should be - #[allow(deprecated)] - let field_deposit = T::FieldDeposit::get() - .saturating_mul(BalanceOf::::from(reg.info.additional() as u32)); - let new_id_deposit = T::BasicDeposit::get().saturating_add(field_deposit); - - // Update account - Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?; - - reg.deposit = new_id_deposit; - Ok(new_id_deposit) - }, - )?; - - // Subs Deposit - let new_subs_deposit = SubsOf::::try_mutate( - &target, - |(current_subs_deposit, subs_of)| -> Result, DispatchError> { - let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); - Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?; - *current_subs_deposit = new_subs_deposit; - Ok(new_subs_deposit) - }, - )?; - - Self::deposit_event(Event::DepositUpdated { - who: target, - identity: new_id_deposit, - subs: new_subs_deposit, - }); - Ok(()) - } - - /// Lock the pallet. - /// - /// Origin must be the `LockerOrigin`. - #[pallet::call_index(17)] - #[pallet::weight(T::WeightInfo::lock_pallet())] - pub fn lock_pallet(origin: OriginFor) -> DispatchResult { - T::LockerOrigin::ensure_origin(origin)?; - Locked::::put(true); - Ok(()) - } - - /// Unlock the pallet. - /// - /// Origin must be the `LockerOrigin`. - #[pallet::call_index(18)] - #[pallet::weight(T::WeightInfo::unlock_pallet())] - pub fn unlock_pallet(origin: OriginFor) -> DispatchResult { - T::LockerOrigin::ensure_origin(origin)?; - Locked::::put(false); - Ok(()) - } } } @@ -1122,25 +986,83 @@ impl Pallet { IdentityOf::::get(who) .map_or(false, |registration| (registration.info.has_identity(fields))) } -} -/// Trait to handle reaping identity from state. -pub trait OnReapIdentity { - /// What to do when an identity is reaped. For example, the implementation could send an XCM - /// program to another chain. Concretely, a type implementing this trait in the Polkadot - /// runtime would teleport enough DOT to the People Chain to cover the Identity deposit there. + /// Reap an identity, clearing associated storage items and refunding any deposits. This + /// function is very similar to (a) `clear_identity`, but called on a `target` account instead + /// of self; and (b) `kill_identity`, but without imposing a slash. /// - /// This could also directly include `Transact { poke_deposit(..), ..}`. + /// Parameters: + /// - `target`: The account for which to reap identity state. /// - /// Inputs - /// - `who`: Whose identity was reaped. - /// - `fields`: The number of `additional_fields` they had. - /// - `subs`: The number of sub-accounts they had. - fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult; -} + /// Return type is a tuple of the number of registrars, additional fields, and sub accounts, + /// respectively. + /// + /// NOTE: This function is here temporarily for migration of Identity info from the Polkadot + /// Relay Chain into a system parachain. It will be removed after the migration. + pub fn reap_identity(who: &T::AccountId) -> Result<(u32, u32, u32), DispatchError> { + // `take` any storage items keyed by `target` + // identity + let id = >::take(&who).ok_or(Error::::NotNamed)?; + let registrars = id.judgements.len() as u32; + #[allow(deprecated)] + let fields = id.info.additional() as u32; + + // subs + let (subs_deposit, sub_ids) = >::take(&who); + let actual_subs = sub_ids.len() as u32; + for sub in sub_ids.iter() { + >::remove(sub); + } -impl OnReapIdentity for () { - fn on_reap_identity(_who: &AccountId, _fields: u32, _subs: u32) -> DispatchResult { - Ok(()) + // unreserve any deposits + let deposit = id.total_deposit().saturating_add(subs_deposit); + let err_amount = T::Currency::unreserve(&who, deposit); + debug_assert!(err_amount.is_zero()); + Ok((registrars, fields, actual_subs)) + } + + /// Update the deposits held by `target` for its identity info. + /// + /// Parameters: + /// - `target`: The account for which to update deposits. + /// + /// Return type is a tuple of the new Identity and Subs deposits, respectively. + /// + /// NOTE: This function is here temporarily for migration of Identity info from the Polkadot + /// Relay Chain into a system parachain. It will be removed after the migration. + pub fn poke_deposit( + target: &T::AccountId, + ) -> Result<(BalanceOf, BalanceOf), DispatchError> { + // Identity Deposit + ensure!(IdentityOf::::contains_key(&target), Error::::NoIdentity); + let new_id_deposit = IdentityOf::::try_mutate( + &target, + |registration| -> Result, DispatchError> { + let reg = registration.as_mut().ok_or(Error::::NoIdentity)?; + // Calculate what deposit should be + #[allow(deprecated)] + let field_deposit = T::FieldDeposit::get() + .saturating_mul(BalanceOf::::from(reg.info.additional() as u32)); + let new_id_deposit = T::BasicDeposit::get().saturating_add(field_deposit); + + // Update account + Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?; + + reg.deposit = new_id_deposit; + Ok(new_id_deposit) + }, + )?; + + // Subs Deposit + let new_subs_deposit = SubsOf::::try_mutate( + &target, + |(current_subs_deposit, subs_of)| -> Result, DispatchError> { + let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); + Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?; + *current_subs_deposit = new_subs_deposit; + Ok(new_subs_deposit) + }, + )?; + Ok((new_id_deposit, new_subs_deposit)) } } diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 172f83e5fceb..3f21ee29913f 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -113,10 +113,7 @@ impl pallet_identity::Config for Test { type IdentityInformation = IdentityInfo; type MaxRegistrars = MaxRegistrars; type RegistrarOrigin = EnsureOneOrRoot; - type ReapOrigin = EnsureOneOrRoot; - type ReapIdentityHandler = (); type ForceOrigin = EnsureTwoOrRoot; - type LockerOrigin = EnsureOneOrRoot; type WeightInfo = (); } @@ -677,7 +674,7 @@ fn reap_identity_works() { )); // 10 for identity, 10 for sub assert_eq!(Balances::free_balance(10), 80); - assert_ok!(Identity::reap_identity(RuntimeOrigin::signed(1), 10)); + assert_ok!(Identity::reap_identity(&10)); // no identity or subs assert!(Identity::identity(10).is_none()); assert!(Identity::super_of(20).is_none()); @@ -705,7 +702,7 @@ fn poke_deposit_works() { assert_eq!(Balances::free_balance(10), 100); // poke - assert_ok!(Identity::poke_deposit(RuntimeOrigin::signed(1), 10)); + assert_ok!(Identity::poke_deposit(&10)); // free balance reduced by 20 assert_eq!(Balances::free_balance(10), 80); @@ -718,99 +715,3 @@ fn poke_deposit_works() { assert_eq!(Identity::subs_of(10), (10, vec![20].try_into().unwrap())); }); } - -#[test] -fn pallet_locks_and_unlocks() { - new_test_ext().execute_with(|| { - // Can add registrars and reap - let one_as_origin = RuntimeOrigin::signed(1); - // Killer - let two_as_origin = RuntimeOrigin::signed(2); - // Registrar - let three_as_origin = RuntimeOrigin::signed(3); - // Sets identity - let ten_as_origin = RuntimeOrigin::signed(10); - // Sets identity - let twenty_as_origin = RuntimeOrigin::signed(20); - // Sub data to use - let data = Data::Raw(vec![40; 1].try_into().unwrap()); - - // Set some state before locking so that calls are sensible - assert_ok!(Identity::add_registrar(one_as_origin.clone(), 3)); - assert_ok!(Identity::set_identity(ten_as_origin.clone(), Box::new(ten()))); - assert_ok!(Identity::request_judgement(ten_as_origin.clone(), 0, 10)); - - // Lock - assert_ok!(Identity::lock_pallet(one_as_origin.clone())); - - // Almost everything is uncallable - assert_noop!( - Identity::add_registrar(one_as_origin.clone(), 1), - Error::::PalletLocked - ); - assert_noop!( - Identity::set_identity(twenty_as_origin.clone(), Box::new(twenty())), - Error::::PalletLocked - ); - assert_noop!( - Identity::set_subs(ten_as_origin.clone(), vec![(20, data.clone())]), - Error::::PalletLocked - ); - assert_noop!(Identity::clear_identity(ten_as_origin.clone()), Error::::PalletLocked); - assert_noop!( - Identity::request_judgement(twenty_as_origin.clone(), 0, 10), - Error::::PalletLocked - ); - assert_noop!( - Identity::cancel_request(twenty_as_origin.clone(), 0), - Error::::PalletLocked - ); - assert_noop!( - Identity::set_fee(three_as_origin.clone(), 0, 10), - Error::::PalletLocked - ); - assert_noop!( - Identity::set_account_id(three_as_origin.clone(), 0, 4), - Error::::PalletLocked - ); - assert_noop!( - Identity::set_fields( - three_as_origin.clone(), - 0, - IdentityFields(SimpleIdentityField::Display | SimpleIdentityField::Legal) - ), - Error::::PalletLocked - ); - assert_noop!( - Identity::provide_judgement( - three_as_origin, - 0, - 10, - Judgement::Reasonable, - BlakeTwo256::hash_of(&ten()) - ), - Error::::PalletLocked - ); - assert_noop!(Identity::kill_identity(two_as_origin, 10), Error::::PalletLocked); - assert_noop!( - Identity::add_sub(ten_as_origin.clone(), 1, data.clone()), - Error::::PalletLocked - ); - assert_noop!( - Identity::rename_sub(ten_as_origin.clone(), 1, data), - Error::::PalletLocked - ); - assert_noop!(Identity::remove_sub(ten_as_origin.clone(), 1), Error::::PalletLocked); - assert_noop!(Identity::quit_sub(one_as_origin.clone()), Error::::PalletLocked); - - // Reap and Poke are still callable for migration - assert_ok!(Identity::poke_deposit(one_as_origin.clone(), 10)); - assert_ok!(Identity::reap_identity(one_as_origin.clone(), 10)); - - // Unlock still needs to be callable, obviously - assert_ok!(Identity::unlock_pallet(one_as_origin)); - - // And pallet works - assert_ok!(Identity::set_identity(twenty_as_origin, Box::new(twenty()))); - }); -} diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index 91adede22e18..07ab48ccd899 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -70,8 +70,6 @@ pub trait WeightInfo { fn quit_sub(s: u32, ) -> Weight; fn reap_identity(r: u32, s: u32, ) -> Weight; fn poke_deposit() -> Weight; - fn lock_pallet() -> Weight; - fn unlock_pallet() -> Weight; } /// Weights for pallet_identity using the Substrate node and recommended hardware. @@ -418,28 +416,6 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Identity::Locked` (r:0 w:1) - /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - fn lock_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 43_286_000 picoseconds. - Weight::from_parts(51_523_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Identity::Locked` (r:0 w:1) - /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - fn unlock_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 42_243_000 picoseconds. - Weight::from_parts(52_907_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) - } } // For backwards compatibility and tests @@ -785,26 +761,4 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3)) .saturating_add(RocksDbWeight::get().writes(3)) } - /// Storage: `Identity::Locked` (r:0 w:1) - /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - fn lock_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 43_286_000 picoseconds. - Weight::from_parts(51_523_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(RocksDbWeight::get().writes(1)) - } - /// Storage: `Identity::Locked` (r:0 w:1) - /// Proof: `Identity::Locked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - fn unlock_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 42_243_000 picoseconds. - Weight::from_parts(52_907_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(RocksDbWeight::get().writes(1)) - } } From 8e70450308ae93a1b9e6b4fc6c60fcedf566fca7 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 3 Nov 2023 20:44:33 +0100 Subject: [PATCH 18/37] actually merge master --- substrate/frame/identity/src/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index fd2b2ff762fa..aa57c05bb741 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -405,12 +405,7 @@ pub mod pallet { ); let (old_deposit, old_ids) = >::get(&sender); -<<<<<<< HEAD let new_deposit = Self::subs_deposit(subs.len() as u32); -======= - let new_deposit = - T::SubAccountDeposit::get().saturating_mul(>::from(subs.len() as u32)); ->>>>>>> origin let not_other_sub = subs.iter().filter_map(|i| SuperOf::::get(&i.0)).all(|i| i.0 == sender); From 4aaa862513d69305e5bf6ea15b7609917fb003aa Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 3 Nov 2023 21:16:26 +0100 Subject: [PATCH 19/37] update identity pallet --- substrate/frame/identity/src/benchmarking.rs | 13 +++---- substrate/frame/identity/src/lib.rs | 19 +++++----- substrate/frame/identity/src/tests.rs | 37 ++++++++++++++------ 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index 118eb9c0d86c..9b5dc02e36af 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -539,7 +539,7 @@ mod benchmarks { let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); // set identity - let info = T::IdentityInformation::create_identity_info(1); + let info = T::IdentityInformation::create_identity_info(); Identity::::set_identity( RawOrigin::Signed(target.clone()).into(), Box::new(info.clone()), @@ -579,7 +579,7 @@ mod benchmarks { fn poke_deposit() -> Result<(), BenchmarkError> { let target: T::AccountId = account("target", 0, SEED); let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); - let additional_fields = 0; + let default_info = T::IdentityInformation::create_identity_info(); // insert identity into storage with zero deposit IdentityOf::::insert( @@ -587,7 +587,7 @@ mod benchmarks { Registration { judgements: BoundedVec::default(), deposit: Zero::zero(), - info: T::IdentityInformation::create_identity_info(additional_fields), + info: default_info.clone(), }, ); @@ -600,9 +600,10 @@ mod benchmarks { >(&target, (Zero::zero(), subs)); // expected deposits - let expected_id_deposit = T::FieldDeposit::get() - .saturating_mul(additional_fields.into()) - .saturating_add(T::BasicDeposit::get()); + let expected_id_deposit = T::BasicDeposit::get().saturating_add( + T::ByteDeposit::get() + .saturating_mul(>::from(default_info.encoded_size() as u32)), + ); let expected_sub_deposit = T::SubAccountDeposit::get(); // only 1 #[block] diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index aa57c05bb741..2246ee24d086 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -79,8 +79,10 @@ mod tests; mod types; pub mod weights; +use codec::Encode; use frame_support::{ - pallet_prelude::DispatchResult, + ensure, + pallet_prelude::{DispatchError, DispatchResult}, traits::{BalanceStatus, Currency, Get, OnUnbalanced, ReservableCurrency}, }; use sp_runtime::traits::{AppendZerosInput, Hash, Saturating, StaticLookup, Zero}; @@ -955,7 +957,7 @@ impl Pallet { /// Parameters: /// - `target`: The account for which to reap identity state. /// - /// Return type is a tuple of the number of registrars, additional fields, and sub accounts, + /// Return type is a tuple of the number of registrars, `IdentityInfo` bytes, and sub accounts, /// respectively. /// /// NOTE: This function is here temporarily for migration of Identity info from the Polkadot @@ -965,8 +967,7 @@ impl Pallet { // identity let id = >::take(&who).ok_or(Error::::NotNamed)?; let registrars = id.judgements.len() as u32; - #[allow(deprecated)] - let fields = id.info.additional() as u32; + let encoded_byte_size = id.info.encoded_size() as u32; // subs let (subs_deposit, sub_ids) = >::take(&who); @@ -979,7 +980,7 @@ impl Pallet { let deposit = id.total_deposit().saturating_add(subs_deposit); let err_amount = T::Currency::unreserve(&who, deposit); debug_assert!(err_amount.is_zero()); - Ok((registrars, fields, actual_subs)) + Ok((registrars, encoded_byte_size, actual_subs)) } /// Update the deposits held by `target` for its identity info. @@ -1001,10 +1002,10 @@ impl Pallet { |registration| -> Result, DispatchError> { let reg = registration.as_mut().ok_or(Error::::NoIdentity)?; // Calculate what deposit should be - #[allow(deprecated)] - let field_deposit = T::FieldDeposit::get() - .saturating_mul(BalanceOf::::from(reg.info.additional() as u32)); - let new_id_deposit = T::BasicDeposit::get().saturating_add(field_deposit); + let encoded_byte_size = reg.info.encoded_size() as u32; + let byte_deposit = + T::ByteDeposit::get().saturating_mul(>::from(encoded_byte_size)); + let new_id_deposit = T::BasicDeposit::get().saturating_add(byte_deposit); // Update account Self::rejig_deposit(&target, reg.deposit, new_id_deposit)?; diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index a27a2bd604ab..78074df933a7 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -716,29 +716,38 @@ fn test_has_identity() { #[test] fn reap_identity_works() { new_test_ext().execute_with(|| { - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten()))); + let ten_info = ten(); + assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten_info.clone()))); assert_ok!(Identity::set_subs( RuntimeOrigin::signed(10), vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))] )); - // 10 for identity, 10 for sub - assert_eq!(Balances::free_balance(10), 80); + // deposit is correct + let id_deposit = id_deposit(&ten_info); + let subs_deposit: u64 = <::SubAccountDeposit as Get>::get(); + assert_eq!(Balances::free_balance(10), 1000 - id_deposit - subs_deposit); + // reap assert_ok!(Identity::reap_identity(&10)); // no identity or subs assert!(Identity::identity(10).is_none()); assert!(Identity::super_of(20).is_none()); // balance is unreserved - assert_eq!(Balances::free_balance(10), 100); + assert_eq!(Balances::free_balance(10), 1000); }); } #[test] fn poke_deposit_works() { new_test_ext().execute_with(|| { + let ten_info = ten(); // Set a custom registration with 0 deposit IdentityOf::::insert( &10, - Registration { judgements: BoundedVec::default(), deposit: Zero::zero(), info: ten() }, + Registration { + judgements: BoundedVec::default(), + deposit: Zero::zero(), + info: ten_info.clone(), + }, ); assert!(Identity::identity(10).is_some()); // Set a sub with zero deposit @@ -748,19 +757,25 @@ fn poke_deposit_works() { ); SuperOf::::insert(&20, (&10, Data::Raw(vec![1; 1].try_into().unwrap()))); // Balance is free - assert_eq!(Balances::free_balance(10), 100); + assert_eq!(Balances::free_balance(10), 1000); // poke assert_ok!(Identity::poke_deposit(&10)); - // free balance reduced by 20 - assert_eq!(Balances::free_balance(10), 80); + // free balance reduced correctly + let id_deposit = id_deposit(&ten_info); + let subs_deposit: u64 = <::SubAccountDeposit as Get>::get(); + assert_eq!(Balances::free_balance(10), 1000 - id_deposit - subs_deposit); // new registration deposit is 10 assert_eq!( Identity::identity(&10), - Some(Registration { judgements: BoundedVec::default(), deposit: 10, info: ten() }) + Some(Registration { + judgements: BoundedVec::default(), + deposit: id_deposit, + info: ten() + }) ); - // new subs deposit is 10 vv - assert_eq!(Identity::subs_of(10), (10, vec![20].try_into().unwrap())); + // new subs deposit is 10 vvvvvvvvvvvv + assert_eq!(Identity::subs_of(10), (subs_deposit, vec![20].try_into().unwrap())); }); } From 70f708b200614d2672f3a65c5653dfeb821d7a64 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 3 Nov 2023 21:30:23 +0100 Subject: [PATCH 20/37] migrator updates --- polkadot/runtime/common/src/identity_migrator.rs | 6 +++--- polkadot/runtime/rococo/src/impls.rs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index d3ccc8df7803..6f5ebc7fe509 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -125,13 +125,13 @@ pub trait OnReapIdentity { /// /// Inputs /// - `who`: Whose identity was reaped. - /// - `fields`: The number of `additional_fields` they had. + /// - `bytes`: The byte size of `IdentityInfo`. /// - `subs`: The number of sub-accounts they had. - fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult; + fn on_reap_identity(who: &AccountId, bytes: u32, subs: u32) -> DispatchResult; } impl OnReapIdentity for () { - fn on_reap_identity(_who: &AccountId, _fields: u32, _subs: u32) -> DispatchResult { + fn on_reap_identity(_who: &AccountId, _bytes: u32, _subs: u32) -> DispatchResult { Ok(()) } } diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index 0f33979f128d..05f7d0cebbc2 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -48,22 +48,22 @@ impl ToParachainIdentityReaper { /// this chain. The total includes: /// /// - Identity basic deposit - /// - Extra fields deposit + /// - `IdentityInfo` byte deposit /// - Sub accounts deposit /// - 2x existential deposit (1 for account existence, 1 such that the user can transact) /// /// This implementation is speculative and subject to change based on the remote chain's /// configuration. - fn calculate_remote_deposit(fields: u32, subs: u32) -> Balance { + fn calculate_remote_deposit(bytes: u32, subs: u32) -> Balance { // remote deposit constants let para_basic_deposit = 1000 * CENTS / 100; - let para_field_deposit = 250 * CENTS / 100; + let para_byte_deposit = MILLICENTS; let para_sub_account_deposit = 200 * CENTS / 100; let para_existential_deposit = EXISTENTIAL_DEPOSIT / 10; // pallet deposits let id_deposit = - para_basic_deposit.saturating_add(para_field_deposit.saturating_mul(fields as Balance)); + para_basic_deposit.saturating_add(para_byte_deposit.saturating_mul(bytes as Balance)); let subs_deposit = para_sub_account_deposit.saturating_mul(subs as Balance); id_deposit From 180352d7d5c09de76ecdcc1199c9dca054cbf027 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sun, 5 Nov 2023 16:45:01 +0100 Subject: [PATCH 21/37] reap benchmark --- .../runtime/common/src/identity_migrator.rs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index 6f5ebc7fe509..7e801d20643d 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -135,3 +135,91 @@ impl OnReapIdentity for () { Ok(()) } } + +#[cfg(feature = "runtime-benchmarks")] +use frame_benchmarking::{account, impl_benchmark_test_suite, v2::*, BenchmarkError}; +#[cfg(feature = "runtime-benchmarks")] +#[benchmarks] +mod benchmarks { + use super::*; + use frame_support::traits::EnsureOrigin; + use frame_system::RawOrigin; + use pallet_identity::{Data, IdentityInformationProvider, Judgement, Pallet as Identity}; + use sp_runtime::traits::{Hash, StaticLookup}; + + const SEED: u32 = 0; + + #[benchmark] + fn reap_identity( + r: Linear<0, { T::MaxRegistrars::get() }>, + s: Linear<0, { T::MaxSubAccounts::get() }>, + ) -> Result<(), BenchmarkError> { + // set up target + let target: T::AccountId = account("target", 0, SEED); + let target_origin = + ::RuntimeOrigin::from(RawOrigin::Signed(target.clone())); + let target_lookup = T::Lookup::unlookup(target.clone()); + let _ = T::Currency::make_free_balance_be(&target, >::from(1_000_000u32)); + + // add registrars + for ii in 0..r { + let registrar: T::AccountId = account("registrar", ii, SEED); + let registrar_lookup = T::Lookup::unlookup(registrar.clone()); + let _ = ::Currency::make_free_balance_be( + ®istrar, + >::from(1_000_000u32), + ); + let registrar_origin = T::RegistrarOrigin::try_successful_origin() + .expect("RegistrarOrigin has no successful origin required for the benchmark"); + Identity::::add_registrar(registrar_origin, registrar_lookup)?; + Identity::::set_fee(RawOrigin::Signed(registrar.clone()).into(), ii, 10u32.into())?; + let fields = ::IdentityInformation::all_fields(); + Identity::::set_fields(RawOrigin::Signed(registrar.clone()).into(), ii, fields)?; + } + + // set identity + let info = ::IdentityInformation::create_identity_info(); + Identity::::set_identity( + RawOrigin::Signed(target.clone()).into(), + Box::new(info.clone()), + )?; + + // create and set subs + let mut subs = Vec::new(); + let data = Data::Raw(vec![0; 32].try_into().unwrap()); + for ii in 0..s { + let sub_account = account("sub", ii, SEED); + subs.push((sub_account, data.clone())); + } + Identity::::set_subs(target_origin.clone(), subs.clone())?; + + // provide judgements + for ii in 0..r { + let registrar: T::AccountId = account("registrar", ii, SEED); + Identity::::request_judgement(target_origin.clone(), ii, 10u32.into())?; + Identity::::provide_judgement( + RawOrigin::Signed(registrar).into(), + ii, + target_lookup.clone(), + Judgement::Reasonable, + ::Hashing::hash_of(&info), + )?; + } + + let origin = T::Reaper::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, target.clone()); + + let fields = ::IdentityInformation::all_fields(); + assert!(!Identity::::has_identity(&target, fields)); + assert_eq!(Identity::::subs(&target).len(), 0); + + Ok(()) + } + + // #[benchmark] + // fn poke_deposit() {} + + impl_benchmark_test_suite!(Migrator, crate::tests::new_test_ext(), crate::tests::Test); +} From 9bf64991c8cff3ba1d307897eb87a59d02457739 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Mon, 6 Nov 2023 13:24:19 +0100 Subject: [PATCH 22/37] remove migration benchmarks from pallet_identity --- .../runtime/common/src/identity_migrator.rs | 87 +++++++++++++-- .../runtime/common/src/integration_tests.rs | 29 ++++- polkadot/runtime/rococo/src/lib.rs | 2 +- .../rococo/src/weights/pallet_identity.rs | 51 --------- .../westend/src/weights/pallet_identity.rs | 51 --------- substrate/frame/identity/src/benchmarking.rs | 97 ---------------- substrate/frame/identity/src/lib.rs | 30 +++++ substrate/frame/identity/src/weights.rs | 104 ------------------ 8 files changed, 139 insertions(+), 312 deletions(-) diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index 7e801d20643d..0fd0757b829c 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -24,11 +24,35 @@ //! //! After the migration is complete, the pallet may be removed from both chains' runtimes. -use frame_support::{dispatch::DispatchResult, traits::Currency}; +use frame_support::{dispatch::DispatchResult, traits::Currency, weights::Weight}; pub use pallet::*; -use pallet_identity::{self, WeightInfo}; +use pallet_identity; use sp_core::Get; +pub trait WeightInfo { + fn reap_identity(r: u32, s: u32) -> Weight; + fn poke_deposit() -> Weight; +} + +impl WeightInfo for () { + fn reap_identity(_r: u32, _s: u32) -> Weight { + Weight::MAX + } + fn poke_deposit() -> Weight { + Weight::MAX + } +} + +pub struct TestWeightInfo; +impl WeightInfo for TestWeightInfo { + fn reap_identity(_r: u32, _s: u32) -> Weight { + Weight::zero() + } + fn poke_deposit() -> Weight { + Weight::zero() + } +} + type BalanceOf = <::Currency as Currency< ::AccountId, >>::Balance; @@ -59,7 +83,7 @@ pub mod pallet { type ReapIdentityHandler: OnReapIdentity; /// Weight information for the extrinsics in the pallet. - type WeightInfo: pallet_identity::WeightInfo; + type WeightInfo: WeightInfo; } #[pallet::event] @@ -145,10 +169,21 @@ mod benchmarks { use frame_support::traits::EnsureOrigin; use frame_system::RawOrigin; use pallet_identity::{Data, IdentityInformationProvider, Judgement, Pallet as Identity}; - use sp_runtime::traits::{Hash, StaticLookup}; + use parity_scale_codec::Encode; + use sp_runtime::{ + traits::{Hash, StaticLookup}, + Saturating, + }; const SEED: u32 = 0; + fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); + } + #[benchmark] fn reap_identity( r: Linear<0, { T::MaxRegistrars::get() }>, @@ -211,6 +246,8 @@ mod benchmarks { #[extrinsic_call] _(origin as T::RuntimeOrigin, target.clone()); + assert_last_event::(Event::::IdentityReaped { who: target.clone() }.into()); + let fields = ::IdentityInformation::all_fields(); assert!(!Identity::::has_identity(&target, fields)); assert_eq!(Identity::::subs(&target).len(), 0); @@ -218,8 +255,44 @@ mod benchmarks { Ok(()) } - // #[benchmark] - // fn poke_deposit() {} + #[benchmark] + fn poke_deposit() -> Result<(), BenchmarkError> { + let target: T::AccountId = account("target", 0, SEED); + let _ = T::Currency::make_free_balance_be(&target, >::from(1_000_000u32)); + let info = ::IdentityInformation::create_identity_info(); + + let _ = Identity::::set_identity_no_deposit(&target, info.clone()); + + let sub_account: T::AccountId = account("sub", 0, SEED); + let _ = Identity::::set_sub_no_deposit(&target, sub_account.clone()); + + // expected deposits + let expected_id_deposit = ::BasicDeposit::get() + .saturating_add( + ::ByteDeposit::get() + .saturating_mul(>::from(info.encoded_size() as u32)), + ); + // only 1 sub + let expected_sub_deposit = ::SubAccountDeposit::get(); + + #[extrinsic_call] + _(RawOrigin::Root, target.clone()); + + assert_last_event::( + Event::::DepositUpdated { + who: target, + identity: expected_id_deposit, + subs: expected_sub_deposit, + } + .into(), + ); + + Ok(()) + } - impl_benchmark_test_suite!(Migrator, crate::tests::new_test_ext(), crate::tests::Test); + impl_benchmark_test_suite!( + IdentityMigrator, + crate::integration_tests::new_test_ext(), + crate::integration_tests::Test, + ); } diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index d5a32775fd49..793f75e79cd1 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -17,7 +17,7 @@ //! Mocking utilities for testing with real pallets. use crate::{ - auctions, crowdloan, + auctions, crowdloan, identity_migrator, mock::{conclude_pvf_checking, validators_public_keys}, paras_registrar, slot_range::SlotRange, @@ -32,6 +32,7 @@ use frame_support::{ }; use frame_support_test::TestRandomness; use frame_system::EnsureRoot; +use pallet_identity::{self, legacy::IdentityInfo}; use parity_scale_codec::Encode; use primitives::{ BlockNumber, HeadData, Id as ParaId, SessionIndex, ValidationCode, LOWEST_PUBLIC_ID, @@ -88,6 +89,10 @@ frame_support::construct_runtime!( Auctions: auctions::{Pallet, Call, Storage, Event}, Crowdloan: crowdloan::{Pallet, Call, Storage, Event}, Slots: slots::{Pallet, Call, Storage, Event}, + + // Migrators + Identity: pallet_identity::{Pallet, Call, Storage, Event}, + IdentityMigrator: identity_migrator::{Pallet, Call, Event}, } ); @@ -274,6 +279,28 @@ impl crowdloan::Config for Test { type WeightInfo = crate::crowdloan::TestWeightInfo; } +impl pallet_identity::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Slashed = (); + type BasicDeposit = ConstU32<100>; + type ByteDeposit = ConstU32<10>; + type SubAccountDeposit = ConstU32<100>; + type MaxSubAccounts = ConstU32<2>; + type IdentityInformation = IdentityInfo>; + type MaxRegistrars = ConstU32<20>; + type RegistrarOrigin = EnsureRoot; + type ForceOrigin = EnsureRoot; + type WeightInfo = (); +} + +impl identity_migrator::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Reaper = EnsureRoot; + type ReapIdentityHandler = (); + type WeightInfo = crate::identity_migrator::TestWeightInfo; +} + /// Create a new set of test externalities. pub fn new_test_ext() -> TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index cb4e558be1f6..436c15f38331 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1079,7 +1079,7 @@ impl identity_migrator::Config for Runtime { // To be changed to `EnsureSigned` once there is a People Chain to migrate to. type Reaper = EnsureRoot; type ReapIdentityHandler = ToParachainIdentityReaper; - type WeightInfo = weights::pallet_identity::WeightInfo; + type WeightInfo = (); } type NisCounterpartInstance = pallet_balances::Instance2; diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs index dd20fbb5054e..e8c25269ac37 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -334,55 +334,4 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// The range of component `s` is `[0, 100]`. - /// The range of component `r` is `[0, 20]`. - fn reap_identity(s: u32, r: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `882 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11003 + r * (8 ±1) + s * (33 ±0)` - // Minimum execution time: 890_684_000 picoseconds. - Weight::from_parts(985_014_414, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 512_018 - .saturating_add(Weight::from_parts(14_124_295, 0).saturating_mul(s.into())) - // Standard Error: 2_560_094 - .saturating_add(Weight::from_parts(219_854, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(5)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) - .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) - .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) - } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - fn poke_deposit() -> Weight { - // Proof Size summary in bytes: - // Measured: `628` - // Estimated: `11003` - // Minimum execution time: 525_039_000 picoseconds. - Weight::from_parts(554_552_000, 0) - .saturating_add(Weight::from_parts(0, 11003)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) - } } diff --git a/polkadot/runtime/westend/src/weights/pallet_identity.rs b/polkadot/runtime/westend/src/weights/pallet_identity.rs index 427d4447aad8..dea631b9316b 100644 --- a/polkadot/runtime/westend/src/weights/pallet_identity.rs +++ b/polkadot/runtime/westend/src/weights/pallet_identity.rs @@ -338,55 +338,4 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// The range of component `s` is `[0, 100]`. - /// The range of component `r` is `[0, 20]`. - fn reap_identity(s: u32, r: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `882 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11003 + r * (8 ±1) + s * (33 ±0)` - // Minimum execution time: 890_684_000 picoseconds. - Weight::from_parts(985_014_414, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 512_018 - .saturating_add(Weight::from_parts(14_124_295, 0).saturating_mul(s.into())) - // Standard Error: 2_560_094 - .saturating_add(Weight::from_parts(219_854, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(5)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) - .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) - .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) - } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - fn poke_deposit() -> Weight { - // Proof Size summary in bytes: - // Measured: `628` - // Estimated: `11003` - // Minimum execution time: 525_039_000 picoseconds. - Weight::from_parts(554_552_000, 0) - .saturating_add(Weight::from_parts(0, 11003)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) - } } diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index 9b5dc02e36af..3d976bd6c881 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -28,7 +28,6 @@ use frame_benchmarking::{ use frame_support::{ ensure, traits::{EnsureOrigin, Get}, - BoundedVec, }; use frame_system::RawOrigin; use sp_runtime::traits::Bounded; @@ -524,101 +523,5 @@ mod benchmarks { Ok(()) } - #[benchmark] - fn reap_identity( - r: Linear<0, { T::MaxRegistrars::get() }>, - s: Linear<0, { T::MaxSubAccounts::get() }>, - ) -> Result<(), BenchmarkError> { - add_registrars::(r)?; - - // target - let target: T::AccountId = account("target", 0, SEED); - let target_origin = - ::RuntimeOrigin::from(RawOrigin::Signed(target.clone())); - let target_lookup = T::Lookup::unlookup(target.clone()); - let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); - - // set identity - let info = T::IdentityInformation::create_identity_info(); - Identity::::set_identity( - RawOrigin::Signed(target.clone()).into(), - Box::new(info.clone()), - )?; - - // set `s` subs - let _ = add_sub_accounts::(&target, s)?; - - // provide judgements - for ii in 0..r { - let registrar: T::AccountId = account("registrar", ii, SEED); - let balance_to_use = T::Currency::minimum_balance() * 10u32.into(); - let _ = T::Currency::make_free_balance_be(®istrar, balance_to_use); - - Identity::::request_judgement(target_origin.clone(), ii, 10u32.into())?; - Identity::::provide_judgement( - RawOrigin::Signed(registrar).into(), - ii, - target_lookup.clone(), - Judgement::Reasonable, - T::Hashing::hash_of(&info), - )?; - } - - #[block] - { - let _ = Identity::::reap_identity(&target); - } - - assert!(IdentityOf::::get(&target).is_none()); - assert_eq!(SubsOf::::get(&target).0, Zero::zero()); - - Ok(()) - } - - #[benchmark] - fn poke_deposit() -> Result<(), BenchmarkError> { - let target: T::AccountId = account("target", 0, SEED); - let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); - let default_info = T::IdentityInformation::create_identity_info(); - - // insert identity into storage with zero deposit - IdentityOf::::insert( - &target, - Registration { - judgements: BoundedVec::default(), - deposit: Zero::zero(), - info: default_info.clone(), - }, - ); - - // insert subs into storage with zero deposit - let sub_account = account("sub", 0, SEED); - let subs = BoundedVec::<_, T::MaxSubAccounts>::try_from(vec![sub_account]).unwrap(); - SubsOf::::insert::< - &T::AccountId, - (BalanceOf, BoundedVec), - >(&target, (Zero::zero(), subs)); - - // expected deposits - let expected_id_deposit = T::BasicDeposit::get().saturating_add( - T::ByteDeposit::get() - .saturating_mul(>::from(default_info.encoded_size() as u32)), - ); - let expected_sub_deposit = T::SubAccountDeposit::get(); // only 1 - - #[block] - { - let _ = Identity::::poke_deposit(&target); - } - - let info = IdentityOf::::get(&target).unwrap(); - assert_eq!(info.deposit, expected_id_deposit); - - let subs = SubsOf::::get(&target); - assert_eq!(subs.0, expected_sub_deposit); - - Ok(()) - } - impl_benchmark_test_suite!(Identity, crate::tests::new_test_ext(), crate::tests::Test); } diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 2246ee24d086..97682eed3bba 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -1027,4 +1027,34 @@ impl Pallet { )?; Ok((new_id_deposit, new_subs_deposit)) } + + /// Set an identity with zero deposit. Only used for benchmarking that involves `rejig_deposit`. + #[cfg(feature = "runtime-benchmarks")] + pub fn set_identity_no_deposit( + who: &T::AccountId, + info: T::IdentityInformation, + ) -> DispatchResult { + use frame_support::BoundedVec; + IdentityOf::::insert( + &who, + Registration { + judgements: BoundedVec::default(), + deposit: Zero::zero(), + info: info.clone(), + }, + ); + Ok(()) + } + + /// Set subs with zero deposit. Only used for benchmarking that involves `rejig_deposit`. + #[cfg(feature = "runtime-benchmarks")] + pub fn set_sub_no_deposit(who: &T::AccountId, sub: T::AccountId) -> DispatchResult { + use frame_support::BoundedVec; + let subs = BoundedVec::<_, T::MaxSubAccounts>::try_from(vec![sub]).unwrap(); + SubsOf::::insert::< + &T::AccountId, + (BalanceOf, BoundedVec), + >(&who, (Zero::zero(), subs)); + Ok(()) + } } diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index b2b2f615d4f6..95898e6c6cdf 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -68,8 +68,6 @@ pub trait WeightInfo { fn rename_sub(s: u32, ) -> Weight; fn remove_sub(s: u32, ) -> Weight; fn quit_sub(s: u32, ) -> Weight; - fn reap_identity(r: u32, s: u32, ) -> Weight; - fn poke_deposit() -> Weight; } /// Weights for pallet_identity using the Substrate node and recommended hardware. @@ -347,57 +345,6 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// The range of component `s` is `[0, 100]`. - /// The range of component `r` is `[0, 20]`. - fn reap_identity(s: u32, r: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `882 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11003 + r * (8 ±1) + s * (33 ±0)` - // Minimum execution time: 890_684_000 picoseconds. - Weight::from_parts(985_014_414, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 512_018 - .saturating_add(Weight::from_parts(14_124_295, 0).saturating_mul(s.into())) - // Standard Error: 2_560_094 - .saturating_add(Weight::from_parts(219_854, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(5)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) - .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) - .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) - } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - fn poke_deposit() -> Weight { - // Proof Size summary in bytes: - // Measured: `628` - // Estimated: `11003` - // Minimum execution time: 525_039_000 picoseconds. - Weight::from_parts(554_552_000, 0) - .saturating_add(Weight::from_parts(0, 11003)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) - } } // For backwards compatibility and tests @@ -674,55 +621,4 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// The range of component `s` is `[0, 100]`. - /// The range of component `r` is `[0, 20]`. - fn reap_identity(s: u32, r: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `882 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11003 + r * (8 ±1) + s * (33 ±0)` - // Minimum execution time: 890_684_000 picoseconds. - Weight::from_parts(985_014_414, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 512_018 - .saturating_add(Weight::from_parts(14_124_295, 0).saturating_mul(s.into())) - // Standard Error: 2_560_094 - .saturating_add(Weight::from_parts(219_854, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8)) - .saturating_add(RocksDbWeight::get().writes(5)) - .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) - .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) - .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) - } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - fn poke_deposit() -> Weight { - // Proof Size summary in bytes: - // Measured: `628` - // Estimated: `11003` - // Minimum execution time: 525_039_000 picoseconds. - Weight::from_parts(554_552_000, 0) - .saturating_add(Weight::from_parts(0, 11003)) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(3)) - } } From 48a33d6fc96fc07e282ef6f575c8f0a438316697 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Mon, 6 Nov 2023 14:04:01 +0100 Subject: [PATCH 23/37] add to define_benchmarks --- polkadot/runtime/common/src/identity_migrator.rs | 6 +++--- polkadot/runtime/rococo/src/lib.rs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index 0fd0757b829c..430f22c1bf9f 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -194,7 +194,7 @@ mod benchmarks { let target_origin = ::RuntimeOrigin::from(RawOrigin::Signed(target.clone())); let target_lookup = T::Lookup::unlookup(target.clone()); - let _ = T::Currency::make_free_balance_be(&target, >::from(1_000_000u32)); + let _ = T::Currency::make_free_balance_be(&target, >::from(u32::MAX)); // add registrars for ii in 0..r { @@ -202,7 +202,7 @@ mod benchmarks { let registrar_lookup = T::Lookup::unlookup(registrar.clone()); let _ = ::Currency::make_free_balance_be( ®istrar, - >::from(1_000_000u32), + >::from(u32::MAX), ); let registrar_origin = T::RegistrarOrigin::try_successful_origin() .expect("RegistrarOrigin has no successful origin required for the benchmark"); @@ -258,7 +258,7 @@ mod benchmarks { #[benchmark] fn poke_deposit() -> Result<(), BenchmarkError> { let target: T::AccountId = account("target", 0, SEED); - let _ = T::Currency::make_free_balance_be(&target, >::from(1_000_000u32)); + let _ = T::Currency::make_free_balance_be(&target, >::from(u32::MAX)); let info = ::IdentityInformation::create_identity_info(); let _ = Identity::::set_identity_no_deposit(&target, info.clone()); diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 436c15f38331..e0e13717894d 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1554,6 +1554,7 @@ mod benches { [runtime_common::auctions, Auctions] [runtime_common::crowdloan, Crowdloan] [runtime_common::claims, Claims] + [runtime_common::identity_migrator, IdentityMigrator] [runtime_common::slots, Slots] [runtime_common::paras_registrar, Registrar] [runtime_parachains::configuration, Configuration] From 750c440c18267ffd0e8f41ec456a96d73607354a Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 7 Nov 2023 07:42:36 +0100 Subject: [PATCH 24/37] fix runtime errors --- .../runtime/common/src/identity_migrator.rs | 43 ++++---- polkadot/runtime/rococo/src/lib.rs | 4 +- polkadot/runtime/rococo/src/weights/mod.rs | 1 + .../runtime_common_identity_migrator.rs | 97 +++++++++++++++++++ 4 files changed, 121 insertions(+), 24 deletions(-) create mode 100644 polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index 430f22c1bf9f..f32a3ca415a3 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -29,6 +29,9 @@ pub use pallet::*; use pallet_identity; use sp_core::Get; +#[cfg(feature = "runtime-benchmarks")] +use frame_benchmarking::{account, impl_benchmark_test_suite, v2::*, BenchmarkError}; + pub trait WeightInfo { fn reap_identity(r: u32, s: u32) -> Weight; fn poke_deposit() -> Weight; @@ -160,8 +163,6 @@ impl OnReapIdentity for () { } } -#[cfg(feature = "runtime-benchmarks")] -use frame_benchmarking::{account, impl_benchmark_test_suite, v2::*, BenchmarkError}; #[cfg(feature = "runtime-benchmarks")] #[benchmarks] mod benchmarks { @@ -171,9 +172,10 @@ mod benchmarks { use pallet_identity::{Data, IdentityInformationProvider, Judgement, Pallet as Identity}; use parity_scale_codec::Encode; use sp_runtime::{ - traits::{Hash, StaticLookup}, + traits::{Bounded, Hash, StaticLookup}, Saturating, }; + use sp_std::{boxed::Box, vec::Vec, *}; const SEED: u32 = 0; @@ -194,23 +196,7 @@ mod benchmarks { let target_origin = ::RuntimeOrigin::from(RawOrigin::Signed(target.clone())); let target_lookup = T::Lookup::unlookup(target.clone()); - let _ = T::Currency::make_free_balance_be(&target, >::from(u32::MAX)); - - // add registrars - for ii in 0..r { - let registrar: T::AccountId = account("registrar", ii, SEED); - let registrar_lookup = T::Lookup::unlookup(registrar.clone()); - let _ = ::Currency::make_free_balance_be( - ®istrar, - >::from(u32::MAX), - ); - let registrar_origin = T::RegistrarOrigin::try_successful_origin() - .expect("RegistrarOrigin has no successful origin required for the benchmark"); - Identity::::add_registrar(registrar_origin, registrar_lookup)?; - Identity::::set_fee(RawOrigin::Signed(registrar.clone()).into(), ii, 10u32.into())?; - let fields = ::IdentityInformation::all_fields(); - Identity::::set_fields(RawOrigin::Signed(registrar.clone()).into(), ii, fields)?; - } + let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); // set identity let info = ::IdentityInformation::create_identity_info(); @@ -228,9 +214,22 @@ mod benchmarks { } Identity::::set_subs(target_origin.clone(), subs.clone())?; - // provide judgements + // add registrars and provide judgements + let registrar_origin = T::RegistrarOrigin::try_successful_origin() + .expect("RegistrarOrigin has no successful origin required for the benchmark"); for ii in 0..r { let registrar: T::AccountId = account("registrar", ii, SEED); + let registrar_lookup = T::Lookup::unlookup(registrar.clone()); + let _ = ::Currency::make_free_balance_be( + ®istrar, + ::Currency::minimum_balance(), + ); + + Identity::::add_registrar(registrar_origin.clone(), registrar_lookup)?; + Identity::::set_fee(RawOrigin::Signed(registrar.clone()).into(), ii, 10u32.into())?; + let fields = ::IdentityInformation::all_fields(); + Identity::::set_fields(RawOrigin::Signed(registrar.clone()).into(), ii, fields)?; + Identity::::request_judgement(target_origin.clone(), ii, 10u32.into())?; Identity::::provide_judgement( RawOrigin::Signed(registrar).into(), @@ -258,7 +257,7 @@ mod benchmarks { #[benchmark] fn poke_deposit() -> Result<(), BenchmarkError> { let target: T::AccountId = account("target", 0, SEED); - let _ = T::Currency::make_free_balance_be(&target, >::from(u32::MAX)); + let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); let info = ::IdentityInformation::create_identity_info(); let _ = Identity::::set_identity_no_deposit(&target, info.clone()); diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index e0e13717894d..30660e178487 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1079,7 +1079,7 @@ impl identity_migrator::Config for Runtime { // To be changed to `EnsureSigned` once there is a People Chain to migrate to. type Reaper = EnsureRoot; type ReapIdentityHandler = ToParachainIdentityReaper; - type WeightInfo = (); + type WeightInfo = weights::runtime_common_identity_migrator::WeightInfo; } type NisCounterpartInstance = pallet_balances::Instance2; @@ -1343,7 +1343,7 @@ construct_runtime! { // NIS pallet. Nis: pallet_nis::{Pallet, Call, Storage, Event, HoldReason} = 38, -// pub type NisCounterpartInstance = pallet_balances::Instance2; + // pub type NisCounterpartInstance = pallet_balances::Instance2; NisCounterpartBalances: pallet_balances:: = 45, // Parachains pallets. Start indices at 50 to leave room. diff --git a/polkadot/runtime/rococo/src/weights/mod.rs b/polkadot/runtime/rococo/src/weights/mod.rs index 9c563a67d98b..bd2079ce8277 100644 --- a/polkadot/runtime/rococo/src/weights/mod.rs +++ b/polkadot/runtime/rococo/src/weights/mod.rs @@ -46,6 +46,7 @@ pub mod runtime_common_assigned_slots; pub mod runtime_common_auctions; pub mod runtime_common_claims; pub mod runtime_common_crowdloan; +pub mod runtime_common_identity_migrator; pub mod runtime_common_paras_registrar; pub mod runtime_common_slots; pub mod runtime_parachains_assigner_on_demand; diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs b/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs new file mode 100644 index 000000000000..cec357453b67 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs @@ -0,0 +1,97 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for `runtime_common::identity_migrator` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-11-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `sbtb`, CPU: `13th Gen Intel(R) Core(TM) i7-1365U` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=2 +// --repeat=1 +// --pallet=runtime_common::identity_migrator +// --extrinsic=* +// --output=./migrator-release.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::identity_migrator`. +pub struct WeightInfo(PhantomData); +impl runtime_common::identity_migrator::WeightInfo for WeightInfo { + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// The range of component `r` is `[0, 20]`. + /// The range of component `s` is `[0, 100]`. + fn reap_identity(r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `7292 + r * (8 ±0) + s * (32 ±0)` + // Estimated: `11003 + r * (8 ±0) + s * (33 ±0)` + // Minimum execution time: 163_756_000 picoseconds. + Weight::from_parts(158_982_500, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_143_629 + .saturating_add(Weight::from_parts(238_675, 0).saturating_mul(r.into())) + // Standard Error: 228_725 + .saturating_add(Weight::from_parts(1_529_645, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) + } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `7229` + // Estimated: `11003` + // Minimum execution time: 137_570_000 picoseconds. + Weight::from_parts(137_570_000, 0) + .saturating_add(Weight::from_parts(0, 11003)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} From 00309697020645e7a4295a3f6c779a1326b9b594 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 7 Nov 2023 07:52:43 +0100 Subject: [PATCH 25/37] remove pallet lock leftovers --- substrate/frame/identity/src/lib.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 97682eed3bba..ce085815c873 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -157,11 +157,6 @@ pub mod pallet { #[pallet::pallet] pub struct Pallet(_); - /// `true` if the pallet is locked for migration. Should be removed after migration. - #[pallet::storage] - #[pallet::getter(fn locked)] - pub(super) type Locked = StorageValue<_, bool, ValueQuery>; - /// Information that is pertinent to identify the entity behind an account. /// /// TWOX-NOTE: OK ― `AccountId` is a secure hash. @@ -254,8 +249,6 @@ pub mod pallet { JudgementForDifferentIdentity, /// Error that occurs when there is an issue paying for judgement. JudgementPaymentFailed, - /// The pallet is locked to prevent state changes. - PalletLocked, } #[pallet::event] @@ -300,7 +293,6 @@ pub mod pallet { origin: OriginFor, account: AccountIdLookupOf, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); T::RegistrarOrigin::ensure_origin(origin)?; let account = T::Lookup::lookup(account)?; @@ -338,7 +330,6 @@ pub mod pallet { origin: OriginFor, info: Box, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let encoded_byte_size = info.encoded_size() as u32; let byte_deposit = @@ -398,7 +389,6 @@ pub mod pallet { origin: OriginFor, subs: Vec<(T::AccountId, Data)>, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; ensure!(>::contains_key(&sender), Error::::NotFound); ensure!( @@ -459,7 +449,6 @@ pub mod pallet { T::MaxSubAccounts::get(), ))] pub fn clear_identity(origin: OriginFor) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let (subs_deposit, sub_ids) = >::take(&sender); @@ -505,7 +494,6 @@ pub mod pallet { #[pallet::compact] reg_index: RegistrarIndex, #[pallet::compact] max_fee: BalanceOf, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let registrars = >::get(); let registrar = registrars @@ -556,7 +544,6 @@ pub mod pallet { origin: OriginFor, reg_index: RegistrarIndex, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let mut id = >::get(&sender).ok_or(Error::::NoIdentity)?; @@ -597,7 +584,6 @@ pub mod pallet { #[pallet::compact] index: RegistrarIndex, #[pallet::compact] fee: BalanceOf, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let who = ensure_signed(origin)?; let registrars = >::mutate(|rs| -> Result { @@ -631,7 +617,6 @@ pub mod pallet { #[pallet::compact] index: RegistrarIndex, new: AccountIdLookupOf, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let who = ensure_signed(origin)?; let new = T::Lookup::lookup(new)?; @@ -666,7 +651,6 @@ pub mod pallet { #[pallet::compact] index: RegistrarIndex, fields: ::FieldsIdentifier, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let who = ensure_signed(origin)?; let registrars = @@ -705,7 +689,6 @@ pub mod pallet { judgement: Judgement>, identity: T::Hash, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let target = T::Lookup::lookup(target)?; ensure!(!judgement.has_deposit(), Error::::InvalidJudgement); @@ -768,7 +751,6 @@ pub mod pallet { origin: OriginFor, target: AccountIdLookupOf, ) -> DispatchResultWithPostInfo { - ensure!(!Self::locked(), Error::::PalletLocked); T::ForceOrigin::ensure_origin(origin)?; // Figure out who we're meant to be clearing. @@ -804,7 +786,6 @@ pub mod pallet { sub: AccountIdLookupOf, data: Data, ) -> DispatchResult { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let sub = T::Lookup::lookup(sub)?; ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); @@ -841,7 +822,6 @@ pub mod pallet { sub: AccountIdLookupOf, data: Data, ) -> DispatchResult { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let sub = T::Lookup::lookup(sub)?; ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); @@ -860,7 +840,6 @@ pub mod pallet { #[pallet::call_index(13)] #[pallet::weight(T::WeightInfo::remove_sub(T::MaxSubAccounts::get()))] pub fn remove_sub(origin: OriginFor, sub: AccountIdLookupOf) -> DispatchResult { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); let sub = T::Lookup::lookup(sub)?; @@ -891,7 +870,6 @@ pub mod pallet { #[pallet::call_index(14)] #[pallet::weight(T::WeightInfo::quit_sub(T::MaxSubAccounts::get()))] pub fn quit_sub(origin: OriginFor) -> DispatchResult { - ensure!(!Self::locked(), Error::::PalletLocked); let sender = ensure_signed(origin)?; let (sup, _) = SuperOf::::take(&sender).ok_or(Error::::NotSub)?; SubsOf::::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| { From ed0d8e96abe2294e607765fe110bd159783ea0f7 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 7 Nov 2023 08:10:51 +0100 Subject: [PATCH 26/37] disable calls to identity (again) --- polkadot/runtime/rococo/src/lib.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 30660e178487..038900f9650b 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -67,9 +67,9 @@ use frame_support::{ genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ - fungible::HoldConsideration, EitherOf, EitherOfDiverse, Everything, InstanceFilter, - KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError, - StorageMapShim, WithdrawReasons, + fungible::HoldConsideration, Contains, EitherOf, EitherOfDiverse, EverythingBut, + InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage, + ProcessMessageError, StorageMapShim, WithdrawReasons, }, weights::{ConstantMultiplier, WeightMeter}, PalletId, @@ -161,13 +161,24 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } +/// A type to identify calls to the Identity pallet. These will be filtered to prevent invocation, +/// locking the state of the pallet and preventing further updates to identities and sub-identities. +/// The locked state will be the genesis state of a new system chain and then removed from the Relay +/// Chain. +pub struct IdentityCalls; +impl Contains for IdentityCalls { + fn contains(c: &RuntimeCall) -> bool { + matches!(c, RuntimeCall::Identity(_)) + } +} + parameter_types! { pub const Version: RuntimeVersion = VERSION; pub const SS58Prefix: u8 = 42; } impl frame_system::Config for Runtime { - type BaseCallFilter = Everything; + type BaseCallFilter = EverythingBut; type BlockWeights = BlockWeights; type BlockLength = BlockLength; type DbWeight = RocksDbWeight; From cb7bda04db3f08f8c39457816a345d1288cd232f Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 7 Nov 2023 16:48:40 +0100 Subject: [PATCH 27/37] fix benchmark test suite --- polkadot/runtime/common/src/identity_migrator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index f32a3ca415a3..c80633c981d5 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -166,7 +166,7 @@ impl OnReapIdentity for () { #[cfg(feature = "runtime-benchmarks")] #[benchmarks] mod benchmarks { - use super::*; + use super::{Pallet as IdentityMigrator, *}; use frame_support::traits::EnsureOrigin; use frame_system::RawOrigin; use pallet_identity::{Data, IdentityInformationProvider, Judgement, Pallet as Identity}; From 76258bebb60d0591c470c81c7a9ecd0e8f465822 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 7 Nov 2023 18:34:21 +0100 Subject: [PATCH 28/37] make unused imports happy --- polkadot/runtime/common/src/identity_migrator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index c80633c981d5..4ad7dfeddb7a 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -166,7 +166,7 @@ impl OnReapIdentity for () { #[cfg(feature = "runtime-benchmarks")] #[benchmarks] mod benchmarks { - use super::{Pallet as IdentityMigrator, *}; + use super::*; use frame_support::traits::EnsureOrigin; use frame_system::RawOrigin; use pallet_identity::{Data, IdentityInformationProvider, Judgement, Pallet as Identity}; @@ -290,7 +290,7 @@ mod benchmarks { } impl_benchmark_test_suite!( - IdentityMigrator, + Pallet, crate::integration_tests::new_test_ext(), crate::integration_tests::Test, ); From ace6f4133029d7622ff366ec08fdb99fe3ffed40 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Thu, 9 Nov 2023 09:09:33 +0100 Subject: [PATCH 29/37] correct and clarify some docs --- .../runtime/common/src/identity_migrator.rs | 18 +++++++++++++----- polkadot/runtime/rococo/src/impls.rs | 8 +++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index 4ad7dfeddb7a..cc2c3ce7773c 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -22,7 +22,8 @@ //! - Avoid cluttering the source pallet with new dispatchables that are unrelated to its //! functionality and only used for migration. //! -//! After the migration is complete, the pallet may be removed from both chains' runtimes. +//! After the migration is complete, the pallet may be removed from both chains' runtimes as well as +//! the `polkadot-runtime-common` crate. use frame_support::{dispatch::DispatchResult, traits::Currency, weights::Weight}; pub use pallet::*; @@ -56,6 +57,7 @@ impl WeightInfo for TestWeightInfo { } } +// Must use the same `Balance` as `T`'s Identity pallet to handle deposits. type BalanceOf = <::Currency as Currency< ::AccountId, >>::Balance; @@ -101,8 +103,8 @@ pub mod pallet { #[pallet::call] impl Pallet { - /// Reap the Identity Info of `who` from the Relay Chain, unreserving any deposits held and - /// removing storage items associated with `who`. + /// Reap the `IdentityInfo` of `who` from the Identity pallet of `T`, unreserving any + /// deposits held and removing storage items associated with `who`. #[pallet::call_index(0)] #[pallet::weight(::WeightInfo::reap_identity( T::MaxRegistrars::get(), @@ -113,8 +115,11 @@ pub mod pallet { who: T::AccountId, ) -> DispatchResultWithPostInfo { T::Reaper::ensure_origin(origin)?; - let (registrars, fields, subs) = pallet_identity::Pallet::::reap_identity(&who)?; - T::ReapIdentityHandler::on_reap_identity(&who, fields, subs)?; + // - number of registrars (required to calculate weight) + // - byte size of `IdentityInfo` (required to calculate remote deposit) + // - number of sub accounts (required to calculate both weight and remote deposit) + let (registrars, bytes, subs) = pallet_identity::Pallet::::reap_identity(&who)?; + T::ReapIdentityHandler::on_reap_identity(&who, bytes, subs)?; Self::deposit_event(Event::IdentityReaped { who }); let post = PostDispatchInfo { actual_weight: Some(::WeightInfo::reap_identity( @@ -218,6 +223,7 @@ mod benchmarks { let registrar_origin = T::RegistrarOrigin::try_successful_origin() .expect("RegistrarOrigin has no successful origin required for the benchmark"); for ii in 0..r { + // registrar account let registrar: T::AccountId = account("registrar", ii, SEED); let registrar_lookup = T::Lookup::unlookup(registrar.clone()); let _ = ::Currency::make_free_balance_be( @@ -225,11 +231,13 @@ mod benchmarks { ::Currency::minimum_balance(), ); + // add registrar Identity::::add_registrar(registrar_origin.clone(), registrar_lookup)?; Identity::::set_fee(RawOrigin::Signed(registrar.clone()).into(), ii, 10u32.into())?; let fields = ::IdentityInformation::all_fields(); Identity::::set_fields(RawOrigin::Signed(registrar.clone()).into(), ii, fields)?; + // request and provide judgement Identity::::request_judgement(target_origin.clone(), ii, 10u32.into())?; Identity::::provide_judgement( RawOrigin::Signed(registrar).into(), diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index 05f7d0cebbc2..f33e9e1b752b 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -26,14 +26,15 @@ use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; /// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any -/// remote calls. +/// remote calls. The codec index must correspond to the index of `IdentityMigrator` in the +/// `construct_runtime` of the remote chain. #[derive(Encode, Decode)] enum PeopleRuntimePallets { #[codec(index = 248)] IdentityMigrator(IdentityMigratorCalls), } -/// Call encoding for the calls needed from the Identity pallet. +/// Call encoding for the calls needed from the Identity Migrator pallet. #[derive(Encode, Decode)] enum IdentityMigratorCalls { #[codec(index = 1)] @@ -51,9 +52,6 @@ impl ToParachainIdentityReaper { /// - `IdentityInfo` byte deposit /// - Sub accounts deposit /// - 2x existential deposit (1 for account existence, 1 such that the user can transact) - /// - /// This implementation is speculative and subject to change based on the remote chain's - /// configuration. fn calculate_remote_deposit(bytes: u32, subs: u32) -> Balance { // remote deposit constants let para_basic_deposit = 1000 * CENTS / 100; From de3e4e8c7612cb629b079d160527e7a50dd9e5d8 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 11 Nov 2023 14:56:40 +0100 Subject: [PATCH 30/37] nits --- polkadot/runtime/rococo/src/impls.rs | 4 ++-- substrate/frame/identity/src/lib.rs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index f33e9e1b752b..c0647cbb5740 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -93,14 +93,14 @@ where // check out xcm_config::LocalAssetTransactor::can_check_out( &destination, - &roc.inner().first().unwrap(), // <- safe unwrap since we just set `roc`. + &roc.inner().first().expect("`roc` was just set and has a `first()`; qed."), // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ) .map_err(|_| pallet_xcm::Error::::InvalidAsset)?; xcm_config::LocalAssetTransactor::check_out( &destination, - &roc.inner().first().unwrap(), // <- safe unwrap since we just set `roc`. + &roc.inner().first().expect("`roc` was just set and has a `first()`; qed."), // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ); diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index ce085815c873..189a98fecdf3 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -974,7 +974,6 @@ impl Pallet { target: &T::AccountId, ) -> Result<(BalanceOf, BalanceOf), DispatchError> { // Identity Deposit - ensure!(IdentityOf::::contains_key(&target), Error::::NoIdentity); let new_id_deposit = IdentityOf::::try_mutate( &target, |registration| -> Result, DispatchError> { From be3801503841455732f9f0814df7723a01a30cf3 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 11 Nov 2023 15:29:12 +0100 Subject: [PATCH 31/37] add westend config --- polkadot/runtime/westend/src/impls.rs | 147 ++++++++++++++++++ polkadot/runtime/westend/src/lib.rs | 33 +++- polkadot/runtime/westend/src/weights/mod.rs | 1 + .../runtime_common_identity_migrator.rs | 97 ++++++++++++ 4 files changed, 275 insertions(+), 3 deletions(-) create mode 100644 polkadot/runtime/westend/src/impls.rs create mode 100644 polkadot/runtime/westend/src/weights/runtime_common_identity_migrator.rs diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs new file mode 100644 index 000000000000..b3d60dc088f3 --- /dev/null +++ b/polkadot/runtime/westend/src/impls.rs @@ -0,0 +1,147 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::xcm_config; +use frame_support::pallet_prelude::DispatchResult; +use frame_system::RawOrigin; +use parity_scale_codec::{Decode, Encode}; +use primitives::Balance; +use westend_runtime_constants::currency::*; +use runtime_common::identity_migrator::OnReapIdentity; +use sp_std::{marker::PhantomData, prelude::*}; +use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm_executor::traits::TransactAsset; + +/// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any +/// remote calls. The codec index must correspond to the index of `IdentityMigrator` in the +/// `construct_runtime` of the remote chain. +#[derive(Encode, Decode)] +enum PeopleRuntimePallets { + #[codec(index = 248)] + IdentityMigrator(IdentityMigratorCalls), +} + +/// Call encoding for the calls needed from the Identity Migrator pallet. +#[derive(Encode, Decode)] +enum IdentityMigratorCalls { + #[codec(index = 1)] + PokeDeposit(AccountId), +} + +/// Type that implements `OnReapIdentity` that will send the deposit needed to store the same +/// information on a parachain, sends the deposit there, and then updates it. +pub struct ToParachainIdentityReaper(PhantomData<(Runtime, AccountId)>); +impl ToParachainIdentityReaper { + /// Calculate the balance needed on the remote chain based on the `IdentityInfo` and `Subs` on + /// this chain. The total includes: + /// + /// - Identity basic deposit + /// - `IdentityInfo` byte deposit + /// - Sub accounts deposit + /// - 2x existential deposit (1 for account existence, 1 such that the user can transact) + fn calculate_remote_deposit(bytes: u32, subs: u32) -> Balance { + // remote deposit constants + let para_basic_deposit = 1000 * CENTS / 100; + let para_byte_deposit = MILLICENTS; + let para_sub_account_deposit = 200 * CENTS / 100; + let para_existential_deposit = EXISTENTIAL_DEPOSIT / 10; + + // pallet deposits + let id_deposit = + para_basic_deposit.saturating_add(para_byte_deposit.saturating_mul(bytes as Balance)); + let subs_deposit = para_sub_account_deposit.saturating_mul(subs as Balance); + + id_deposit + .saturating_add(subs_deposit) + .saturating_add(para_existential_deposit.saturating_mul(2)) + } +} + +impl OnReapIdentity for ToParachainIdentityReaper +where + Runtime: frame_system::Config + pallet_xcm::Config, + AccountId: Into<[u8; 32]> + Clone + Encode, +{ + fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { + use crate::impls::IdentityMigratorCalls::PokeDeposit; + + let total_to_send = Self::calculate_remote_deposit(fields, subs); + + // define asset / destination from relay perspective + let wnd: MultiAssets = + vec![MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }] + .into(); + // TODO: confirm people chain para id. Tentatively 1004. + let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); + + // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support + // unpaid teleports. + + // check out + xcm_config::LocalAssetTransactor::can_check_out( + &destination, + &wnd.inner().first().expect("`wnd` was just set and has a `first()`; qed."), + // not used in AssetTransactor + &XcmContext { origin: None, message_id: [0; 32], topic: None }, + ) + .map_err(|_| pallet_xcm::Error::::InvalidAsset)?; + xcm_config::LocalAssetTransactor::check_out( + &destination, + &wnd.inner().first().expect("`wnd` was just set and has a `first()`; qed."), + // not used in AssetTransactor + &XcmContext { origin: None, message_id: [0; 32], topic: None }, + ); + + // reanchor + let wnd_reanchored: MultiAssets = vec![MultiAsset { + id: Concrete(MultiLocation::new(1, Here)), + fun: Fungible(total_to_send), + }] + .into(); + + let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); + + // Actual program to execute on People Chain. + let program: Xcm<()> = Xcm(vec![ + // Unpaid as this is constructed by the system, once per user. The user shouldn't have + // their balance reduced by teleport fees for the favor of migrating. + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + // Receive the asset into holding. + ReceiveTeleportedAsset(wnd_reanchored), + // Deposit into the user's account. + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: Junction::AccountId32 { network: None, id: who.clone().into() } + .into_location() + .into(), + }, + // Poke the deposit to reserve the appropriate amount on the parachain. + Transact { + origin_kind: OriginKind::Superuser, + require_weight_at_most: Weight::from_parts(2_000_000_000, 16_384), + call: poke.encode().into(), + }, + ]); + + // send + let _ = >::send( + RawOrigin::Root.into(), + Box::new(VersionedMultiLocation::V3(destination)), + Box::new(VersionedXcm::V3(program)), + )?; + Ok(()) + } +} diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index ec94973af4f3..1c468ece6752 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -31,7 +31,7 @@ use frame_support::{ genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ - fungible::HoldConsideration, ConstU32, EitherOf, EitherOfDiverse, Everything, + fungible::HoldConsideration, ConstU32, Contains, EitherOf, EitherOfDiverse, EverythingBut, InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, ProcessMessageError, WithdrawReasons, }, @@ -54,7 +54,7 @@ use primitives::{ ValidatorSignature, PARACHAIN_KEY_TYPE_ID, }; use runtime_common::{ - assigned_slots, auctions, crowdloan, + assigned_slots, auctions, crowdloan, identity_migrator, elections::OnChainAccuracy, impl_runtime_weights, impls::{ @@ -119,6 +119,10 @@ mod bag_thresholds; mod weights; pub mod xcm_config; +// Implemented types. +mod impls; +use impls::ToParachainIdentityReaper; + // Governance and configurations. pub mod governance; use governance::{ @@ -161,13 +165,24 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } +/// A type to identify calls to the Identity pallet. These will be filtered to prevent invocation, +/// locking the state of the pallet and preventing further updates to identities and sub-identities. +/// The locked state will be the genesis state of a new system chain and then removed from the Relay +/// Chain. +pub struct IdentityCalls; +impl Contains for IdentityCalls { + fn contains(c: &RuntimeCall) -> bool { + matches!(c, RuntimeCall::Identity(_)) + } +} + parameter_types! { pub const Version: RuntimeVersion = VERSION; pub const SS58Prefix: u8 = 42; } impl frame_system::Config for Runtime { - type BaseCallFilter = Everything; + type BaseCallFilter = EverythingBut; type BlockWeights = BlockWeights; type BlockLength = BlockLength; type RuntimeOrigin = RuntimeOrigin; @@ -1328,6 +1343,14 @@ impl auctions::Config for Runtime { type WeightInfo = weights::runtime_common_auctions::WeightInfo; } +impl identity_migrator::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + // To be changed to `EnsureSigned` once there is a People Chain to migrate to. + type Reaper = EnsureRoot; + type ReapIdentityHandler = ToParachainIdentityReaper; + type WeightInfo = weights::runtime_common_identity_migrator::WeightInfo; +} + parameter_types! { pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls"); pub const MaxPointsToBalance: u8 = 10; @@ -1491,6 +1514,9 @@ construct_runtime! { // Root testing pallet. RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event} = 102, + + // Pallet for migrating Identity to a parachain. To be removed post-migration. + IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, } } @@ -1585,6 +1611,7 @@ mod benches { [runtime_common::assigned_slots, AssignedSlots] [runtime_common::auctions, Auctions] [runtime_common::crowdloan, Crowdloan] + [runtime_common::identity_migrator, IdentityMigrator] [runtime_common::paras_registrar, Registrar] [runtime_common::slots, Slots] [runtime_parachains::configuration, Configuration] diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs index 9ae6798d70b6..3841579088a9 100644 --- a/polkadot/runtime/westend/src/weights/mod.rs +++ b/polkadot/runtime/westend/src/weights/mod.rs @@ -46,6 +46,7 @@ pub mod pallet_xcm; pub mod runtime_common_assigned_slots; pub mod runtime_common_auctions; pub mod runtime_common_crowdloan; +pub mod runtime_common_identity_migrator; pub mod runtime_common_paras_registrar; pub mod runtime_common_slots; pub mod runtime_parachains_configuration; diff --git a/polkadot/runtime/westend/src/weights/runtime_common_identity_migrator.rs b/polkadot/runtime/westend/src/weights/runtime_common_identity_migrator.rs new file mode 100644 index 000000000000..cec357453b67 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_common_identity_migrator.rs @@ -0,0 +1,97 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for `runtime_common::identity_migrator` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-11-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `sbtb`, CPU: `13th Gen Intel(R) Core(TM) i7-1365U` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=2 +// --repeat=1 +// --pallet=runtime_common::identity_migrator +// --extrinsic=* +// --output=./migrator-release.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::identity_migrator`. +pub struct WeightInfo(PhantomData); +impl runtime_common::identity_migrator::WeightInfo for WeightInfo { + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// The range of component `r` is `[0, 20]`. + /// The range of component `s` is `[0, 100]`. + fn reap_identity(r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `7292 + r * (8 ±0) + s * (32 ±0)` + // Estimated: `11003 + r * (8 ±0) + s * (33 ±0)` + // Minimum execution time: 163_756_000 picoseconds. + Weight::from_parts(158_982_500, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_143_629 + .saturating_add(Weight::from_parts(238_675, 0).saturating_mul(r.into())) + // Standard Error: 228_725 + .saturating_add(Weight::from_parts(1_529_645, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) + .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) + } + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + fn poke_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `7229` + // Estimated: `11003` + // Minimum execution time: 137_570_000 picoseconds. + Weight::from_parts(137_570_000, 0) + .saturating_add(Weight::from_parts(0, 11003)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} From 1c670b771048791390b1730a129ba280966f75de Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 11 Nov 2023 15:32:54 +0100 Subject: [PATCH 32/37] fmt --- polkadot/runtime/westend/src/impls.rs | 2 +- polkadot/runtime/westend/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index b3d60dc088f3..4f15357a116c 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -19,9 +19,9 @@ use frame_support::pallet_prelude::DispatchResult; use frame_system::RawOrigin; use parity_scale_codec::{Decode, Encode}; use primitives::Balance; -use westend_runtime_constants::currency::*; use runtime_common::identity_migrator::OnReapIdentity; use sp_std::{marker::PhantomData, prelude::*}; +use westend_runtime_constants::currency::*; use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 1c468ece6752..4a85307eb4b2 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -54,9 +54,9 @@ use primitives::{ ValidatorSignature, PARACHAIN_KEY_TYPE_ID, }; use runtime_common::{ - assigned_slots, auctions, crowdloan, identity_migrator, + assigned_slots, auctions, crowdloan, elections::OnChainAccuracy, - impl_runtime_weights, + identity_migrator, impl_runtime_weights, impls::{ LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedMultiLocationConverter, }, From 836f824eab34a6f4ee6cf60010917d7f64d70cb5 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 14 Nov 2023 21:17:46 +0100 Subject: [PATCH 33/37] set deposits for parachains --- polkadot/runtime/rococo/src/impls.rs | 17 +++++++++++++---- polkadot/runtime/westend/src/impls.rs | 24 +++++++++++++----------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index c0647cbb5740..d89db64ef1f6 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -53,10 +53,19 @@ impl ToParachainIdentityReaper { /// - Sub accounts deposit /// - 2x existential deposit (1 for account existence, 1 such that the user can transact) fn calculate_remote_deposit(bytes: u32, subs: u32) -> Balance { - // remote deposit constants - let para_basic_deposit = 1000 * CENTS / 100; - let para_byte_deposit = MILLICENTS; - let para_sub_account_deposit = 200 * CENTS / 100; + // Remote deposit constants. Parachain uses `deposit / 100` + // Source: + // https://github.com/paritytech/polkadot-sdk/blob/a146918/cumulus/parachains/common/src/rococo.rs#L29 + // + // Parachain Deposit Configuration: + // + // pub const BasicDeposit: Balance = deposit(1, 17); + // pub const ByteDeposit: Balance = deposit(0, 1); + // pub const SubAccountDeposit: Balance = deposit(1, 53); + // pub const EXISTENTIAL_DEPOSIT: Balance = constants::currency::EXISTENTIAL_DEPOSIT / 10; + let para_basic_deposit = deposit(1, 17) / 100; + let para_byte_deposit = deposit(0, 1) / 100; + let para_sub_account_deposit = deposit(1, 53) / 100; let para_existential_deposit = EXISTENTIAL_DEPOSIT / 10; // pallet deposits diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index 4f15357a116c..043735629a5d 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -45,18 +45,20 @@ enum IdentityMigratorCalls { /// information on a parachain, sends the deposit there, and then updates it. pub struct ToParachainIdentityReaper(PhantomData<(Runtime, AccountId)>); impl ToParachainIdentityReaper { - /// Calculate the balance needed on the remote chain based on the `IdentityInfo` and `Subs` on - /// this chain. The total includes: - /// - /// - Identity basic deposit - /// - `IdentityInfo` byte deposit - /// - Sub accounts deposit - /// - 2x existential deposit (1 for account existence, 1 such that the user can transact) fn calculate_remote_deposit(bytes: u32, subs: u32) -> Balance { - // remote deposit constants - let para_basic_deposit = 1000 * CENTS / 100; - let para_byte_deposit = MILLICENTS; - let para_sub_account_deposit = 200 * CENTS / 100; + // Remote deposit constants. Parachain uses `deposit / 100` + // Source: + // https://github.com/paritytech/polkadot-sdk/blob/a146918/cumulus/parachains/common/src/westend.rs#L28 + // + // Parachain Deposit Configuration: + // + // pub const BasicDeposit: Balance = deposit(1, 17); + // pub const ByteDeposit: Balance = deposit(0, 1); + // pub const SubAccountDeposit: Balance = deposit(1, 53); + // pub const EXISTENTIAL_DEPOSIT: Balance = constants::currency::EXISTENTIAL_DEPOSIT / 10; + let para_basic_deposit = deposit(1, 17) / 100; + let para_byte_deposit = deposit(0, 1) / 100; + let para_sub_account_deposit = deposit(1, 53) / 100; let para_existential_deposit = EXISTENTIAL_DEPOSIT / 10; // pallet deposits From d698705b5a03563e7f56c8d42ac1238edc27a227 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Tue, 14 Nov 2023 21:20:01 +0100 Subject: [PATCH 34/37] replace accidentally deleted docs --- polkadot/runtime/westend/src/impls.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index 043735629a5d..c87bcbb0ddcd 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -45,6 +45,13 @@ enum IdentityMigratorCalls { /// information on a parachain, sends the deposit there, and then updates it. pub struct ToParachainIdentityReaper(PhantomData<(Runtime, AccountId)>); impl ToParachainIdentityReaper { + /// Calculate the balance needed on the remote chain based on the `IdentityInfo` and `Subs` on + /// this chain. The total includes: + /// + /// - Identity basic deposit + /// - `IdentityInfo` byte deposit + /// - Sub accounts deposit + /// - 2x existential deposit (1 for account existence, 1 such that the user can transact) fn calculate_remote_deposit(bytes: u32, subs: u32) -> Balance { // Remote deposit constants. Parachain uses `deposit / 100` // Source: From ea5d6a31ba502eade833a17bfdd6cce4af3e6c44 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 15 Nov 2023 06:57:45 +0100 Subject: [PATCH 35/37] use benchmarked weight --- polkadot/runtime/rococo/src/impls.rs | 12 ++++++++---- polkadot/runtime/westend/src/impls.rs | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index d89db64ef1f6..e32ed366f5c4 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -20,7 +20,7 @@ use frame_system::RawOrigin; use parity_scale_codec::{Decode, Encode}; use primitives::Balance; use rococo_runtime_constants::currency::*; -use runtime_common::identity_migrator::OnReapIdentity; +use runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; @@ -85,7 +85,10 @@ where AccountId: Into<[u8; 32]> + Clone + Encode, { fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { - use crate::impls::IdentityMigratorCalls::PokeDeposit; + use crate::{ + impls::IdentityMigratorCalls::PokeDeposit, + weights::runtime_common_identity_migrator::WeightInfo as MigratorWeights, + }; let total_to_send = Self::calculate_remote_deposit(fields, subs); @@ -93,7 +96,7 @@ where let roc: MultiAssets = vec![MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }] .into(); - // TODO: confirm people chain para id. Tentatively 1004. + // People Chain: ParaId 1004 let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support @@ -122,6 +125,7 @@ where .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); + let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); // Actual program to execute on People Chain. let program: Xcm<()> = Xcm(vec![ @@ -140,7 +144,7 @@ where // Poke the deposit to reserve the appropriate amount on the parachain. Transact { origin_kind: OriginKind::Superuser, - require_weight_at_most: Weight::from_parts(2_000_000_000, 16_384), + require_weight_at_most: remote_weight_limit, call: poke.encode().into(), }, ]); diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index c87bcbb0ddcd..25ee1b48a523 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -19,7 +19,7 @@ use frame_support::pallet_prelude::DispatchResult; use frame_system::RawOrigin; use parity_scale_codec::{Decode, Encode}; use primitives::Balance; -use runtime_common::identity_migrator::OnReapIdentity; +use runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use sp_std::{marker::PhantomData, prelude::*}; use westend_runtime_constants::currency::*; use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; @@ -85,7 +85,10 @@ where AccountId: Into<[u8; 32]> + Clone + Encode, { fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult { - use crate::impls::IdentityMigratorCalls::PokeDeposit; + use crate::{ + impls::IdentityMigratorCalls::PokeDeposit, + weights::runtime_common_identity_migrator::WeightInfo as MigratorWeights, + }; let total_to_send = Self::calculate_remote_deposit(fields, subs); @@ -93,7 +96,7 @@ where let wnd: MultiAssets = vec![MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }] .into(); - // TODO: confirm people chain para id. Tentatively 1004. + // People Chain: ParaId 1004 let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support @@ -122,6 +125,7 @@ where .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); + let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); // Actual program to execute on People Chain. let program: Xcm<()> = Xcm(vec![ @@ -140,7 +144,7 @@ where // Poke the deposit to reserve the appropriate amount on the parachain. Transact { origin_kind: OriginKind::Superuser, - require_weight_at_most: Weight::from_parts(2_000_000_000, 16_384), + require_weight_at_most: remote_weight_limit, call: poke.encode().into(), }, ]); From bf42286cbfec914d831176840ea3773e17610e39 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 15 Nov 2023 07:14:12 +0100 Subject: [PATCH 36/37] new xcm errors --- polkadot/runtime/rococo/src/impls.rs | 2 +- polkadot/runtime/westend/src/impls.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index e32ed366f5c4..8416ce3f7ae3 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -109,7 +109,7 @@ where // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ) - .map_err(|_| pallet_xcm::Error::::InvalidAsset)?; + .map_err(|_| pallet_xcm::Error::::CannotCheckOutTeleport)?; xcm_config::LocalAssetTransactor::check_out( &destination, &roc.inner().first().expect("`roc` was just set and has a `first()`; qed."), diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index 25ee1b48a523..09847cc2fdd1 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -109,7 +109,7 @@ where // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ) - .map_err(|_| pallet_xcm::Error::::InvalidAsset)?; + .map_err(|_| pallet_xcm::Error::::CannotCheckOutTeleport)?; xcm_config::LocalAssetTransactor::check_out( &destination, &wnd.inner().first().expect("`wnd` was just set and has a `first()`; qed."), From 73426e7f5c5114f1b36d29a13cfba20a37e4beec Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 15 Nov 2023 13:36:28 +0100 Subject: [PATCH 37/37] apply basti review --- polkadot/runtime/rococo/src/impls.rs | 8 +++----- polkadot/runtime/rococo/src/lib.rs | 6 +++--- polkadot/runtime/westend/src/impls.rs | 8 +++----- polkadot/runtime/westend/src/lib.rs | 6 +++--- substrate/frame/identity/src/lib.rs | 3 +-- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index 8416ce3f7ae3..71b1091eeb6c 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -93,9 +93,7 @@ where let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective - let roc: MultiAssets = - vec![MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }] - .into(); + let roc = MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }; // People Chain: ParaId 1004 let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); @@ -105,14 +103,14 @@ where // check out xcm_config::LocalAssetTransactor::can_check_out( &destination, - &roc.inner().first().expect("`roc` was just set and has a `first()`; qed."), + &roc, // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ) .map_err(|_| pallet_xcm::Error::::CannotCheckOutTeleport)?; xcm_config::LocalAssetTransactor::check_out( &destination, - &roc.inner().first().expect("`roc` was just set and has a `first()`; qed."), + &roc, // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ); diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 59c79a19e5f0..277c9981dab8 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -174,8 +174,8 @@ pub fn native_version() -> NativeVersion { /// locking the state of the pallet and preventing further updates to identities and sub-identities. /// The locked state will be the genesis state of a new system chain and then removed from the Relay /// Chain. -pub struct IdentityCalls; -impl Contains for IdentityCalls { +pub struct IsIdentityCall; +impl Contains for IsIdentityCall { fn contains(c: &RuntimeCall) -> bool { matches!(c, RuntimeCall::Identity(_)) } @@ -187,7 +187,7 @@ parameter_types! { } impl frame_system::Config for Runtime { - type BaseCallFilter = EverythingBut; + type BaseCallFilter = EverythingBut; type BlockWeights = BlockWeights; type BlockLength = BlockLength; type DbWeight = RocksDbWeight; diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index 09847cc2fdd1..801055949654 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -93,9 +93,7 @@ where let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective - let wnd: MultiAssets = - vec![MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }] - .into(); + let wnd = MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }; // People Chain: ParaId 1004 let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); @@ -105,14 +103,14 @@ where // check out xcm_config::LocalAssetTransactor::can_check_out( &destination, - &wnd.inner().first().expect("`wnd` was just set and has a `first()`; qed."), + &wnd, // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ) .map_err(|_| pallet_xcm::Error::::CannotCheckOutTeleport)?; xcm_config::LocalAssetTransactor::check_out( &destination, - &wnd.inner().first().expect("`wnd` was just set and has a `first()`; qed."), + &wnd, // not used in AssetTransactor &XcmContext { origin: None, message_id: [0; 32], topic: None }, ); diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index ea9c69c46bbf..2e8394b0ee4c 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -169,8 +169,8 @@ pub fn native_version() -> NativeVersion { /// locking the state of the pallet and preventing further updates to identities and sub-identities. /// The locked state will be the genesis state of a new system chain and then removed from the Relay /// Chain. -pub struct IdentityCalls; -impl Contains for IdentityCalls { +pub struct IsIdentityCall; +impl Contains for IsIdentityCall { fn contains(c: &RuntimeCall) -> bool { matches!(c, RuntimeCall::Identity(_)) } @@ -182,7 +182,7 @@ parameter_types! { } impl frame_system::Config for Runtime { - type BaseCallFilter = EverythingBut; + type BaseCallFilter = EverythingBut; type BlockWeights = BlockWeights; type BlockLength = BlockLength; type RuntimeOrigin = RuntimeOrigin; diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 189a98fecdf3..133f9eeb4bef 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -1011,11 +1011,10 @@ impl Pallet { who: &T::AccountId, info: T::IdentityInformation, ) -> DispatchResult { - use frame_support::BoundedVec; IdentityOf::::insert( &who, Registration { - judgements: BoundedVec::default(), + judgements: Default::default(), deposit: Zero::zero(), info: info.clone(), },