Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce Impact on Identity Pallet in Migration #2088

Merged
merged 3 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions polkadot/runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down
137 changes: 137 additions & 0 deletions polkadot/runtime/common/src/identity_migrator.rs
Original file line number Diff line number Diff line change
@@ -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<T> = <<T as pallet_identity::Config>::Currency as Currency<
<T as frame_system::Config>::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<T>(_);

#[pallet::config]
pub trait Config: frame_system::Config + pallet_identity::Config {
/// Overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

/// The origin that can reap identities. Expected to be `EnsureSigned<AccountId>` on the
/// source chain such that anyone can all this function.
type Reaper: EnsureOrigin<Self::RuntimeOrigin>;

/// A handler for what to do when an identity is reaped.
type ReapIdentityHandler: OnReapIdentity<Self::AccountId>;

/// 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<T: Config> {
/// 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<T>, subs: BalanceOf<T> },
}

#[pallet::call]
impl<T: Config> Pallet<T> {
/// 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(<T as pallet::Config>::WeightInfo::reap_identity(
T::MaxRegistrars::get(),
T::MaxSubAccounts::get()
))]
pub fn reap_identity(
origin: OriginFor<T>,
who: T::AccountId,
) -> DispatchResultWithPostInfo {
T::Reaper::ensure_origin(origin)?;
let (registrars, fields, subs) = pallet_identity::Pallet::<T>::reap_identity(&who)?;
T::ReapIdentityHandler::on_reap_identity(&who, fields, subs)?;
Self::deposit_event(Event::IdentityReaped { who });
let post = PostDispatchInfo {
actual_weight: Some(<T as pallet::Config>::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(<T as pallet::Config>::WeightInfo::poke_deposit())]
pub fn poke_deposit(origin: OriginFor<T>, who: T::AccountId) -> DispatchResultWithPostInfo {
ensure_root(origin)?;
let (id_deposit, subs_deposit) = pallet_identity::Pallet::<T>::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<AccountId> {
/// 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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fields should not be required anymore after @georgepisaltu pr. So, you can also directly remove it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I will address any downstream changes. My PR is still more a proposal on how to do the migration. George's should definitely be merged first.

}

impl<AccountId> OnReapIdentity<AccountId> for () {
fn on_reap_identity(_who: &AccountId, _fields: u32, _subs: u32) -> DispatchResult {
Ok(())
}
}
1 change: 1 addition & 0 deletions polkadot/runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 7 additions & 7 deletions polkadot/runtime/rococo/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -29,14 +29,14 @@ use xcm_executor::traits::TransactAsset;
/// remote calls.
#[derive(Encode, Decode)]
enum PeopleRuntimePallets<AccountId: Encode> {
#[codec(index = 50)]
Identity(IdentityCalls<AccountId>),
#[codec(index = 248)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this references the index on the relay chain now.
may be TODO to correct this when we know the index on people chain

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, definitely

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should use subxt to generate the Call enum for us 🤔 (but probably overkill :P)

IdentityMigrator(IdentityMigratorCalls<AccountId>),
}

/// Call encoding for the calls needed from the Identity pallet.
#[derive(Encode, Decode)]
enum IdentityCalls<AccountId: Encode> {
#[codec(index = 16)]
enum IdentityMigratorCalls<AccountId: Encode> {
#[codec(index = 1)]
PokeDeposit(AccountId),
}

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -114,7 +114,7 @@ where
}]
.into();

let poke = PeopleRuntimePallets::<AccountId>::Identity(PokeDeposit(who.clone()));
let poke = PeopleRuntimePallets::<AccountId>::IdentityMigrator(PokeDeposit(who.clone()));

// Actual program to execute on People Chain.
let program: Xcm<()> = Xcm(vec![
Expand Down
18 changes: 12 additions & 6 deletions polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down Expand Up @@ -620,11 +620,6 @@ impl pallet_identity::Config for Runtime {
type Slashed = Treasury;
type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
type RegistrarOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
// Should be `EnsureRoot` until the parachain launches with Identity state. Then, it will be
// `EnsureSigned<Self::AccountId>` to allow deposit migration.
type ReapOrigin = EnsureRoot<Self::AccountId>;
type ReapIdentityHandler = ToParachainIdentityReaper<Runtime, Self::AccountId>;
type LockerOrigin = EnsureRoot<Self::AccountId>;
type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
}

Expand Down Expand Up @@ -1080,6 +1075,14 @@ impl auctions::Config for Runtime {
type WeightInfo = weights::runtime_common_auctions::WeightInfo<Runtime>;
}

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<AccountId>;
type ReapIdentityHandler = ToParachainIdentityReaper<Runtime, Self::AccountId>;
type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
}

type NisCounterpartInstance = pallet_balances::Instance2;
impl pallet_balances::Config<NisCounterpartInstance> for Runtime {
type Balance = Balance;
Expand Down Expand Up @@ -1368,6 +1371,9 @@ construct_runtime! {
// Pallet for sending XCM.
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>} = 99,

// Pallet for migrating Identity to a parachain. To be removed post-migration.
IdentityMigrator: identity_migrator::{Pallet, Call, Event<T>} = 248,

ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 250,
AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event<T>, Config<T>} = 251,

Expand Down
22 changes: 0 additions & 22 deletions polkadot/runtime/rococo/src/weights/pallet_identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,26 +402,4 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
.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))
}
}
3 changes: 0 additions & 3 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,9 +881,6 @@ impl pallet_identity::Config for Runtime {
type MaxRegistrars = MaxRegistrars;
type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
type RegistrarOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
type ReapOrigin = EnsureRoot<Self::AccountId>;
type ReapIdentityHandler = ();
type LockerOrigin = EnsureRoot<Self::AccountId>;
type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
}

Expand Down
22 changes: 0 additions & 22 deletions polkadot/runtime/westend/src/weights/pallet_identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,26 +407,4 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
.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))
}
}
3 changes: 0 additions & 3 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1480,9 +1480,6 @@ impl pallet_identity::Config for Runtime {
type Slashed = Treasury;
type ForceOrigin = EnsureRootOrHalfCouncil;
type RegistrarOrigin = EnsureRootOrHalfCouncil;
type ReapOrigin = EnsureRoot<Self::AccountId>;
type ReapIdentityHandler = ();
type LockerOrigin = EnsureRoot<Self::AccountId>;
type WeightInfo = pallet_identity::weights::SubstrateWeight<Runtime>;
}

Expand Down
3 changes: 0 additions & 3 deletions substrate/frame/alliance/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ();
}

Expand Down
Loading