pallet_staking_async_rc_runtime/
impls.rs1use crate::xcm_config;
18use alloc::{boxed::Box, vec};
19use codec::{Decode, Encode};
20use core::marker::PhantomData;
21use frame_support::pallet_prelude::DispatchResult;
22use frame_system::RawOrigin;
23use pallet_staking_async_rc_runtime_constants::currency::*;
24use polkadot_primitives::Balance;
25use polkadot_runtime_common::identity_migrator::{OnReapIdentity, WeightInfo};
26use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm};
27use xcm_executor::traits::TransactAsset;
28
29#[derive(Encode, Decode)]
33enum PeopleRuntimePallets<AccountId: Encode> {
34 #[codec(index = 248)]
35 IdentityMigrator(IdentityMigratorCalls<AccountId>),
36}
37
38#[derive(Encode, Decode)]
40enum IdentityMigratorCalls<AccountId: Encode> {
41 #[codec(index = 1)]
42 PokeDeposit(AccountId),
43}
44
45pub struct ToParachainIdentityReaper<Runtime, AccountId>(PhantomData<(Runtime, AccountId)>);
48impl<Runtime, AccountId> ToParachainIdentityReaper<Runtime, AccountId> {
49 fn calculate_remote_deposit(bytes: u32, subs: u32) -> Balance {
57 let para_basic_deposit = deposit(1, 17) / 100;
68 let para_byte_deposit = deposit(0, 1) / 100;
69 let para_sub_account_deposit = deposit(1, 53) / 100;
70 let para_existential_deposit = EXISTENTIAL_DEPOSIT / 10;
71
72 let id_deposit =
74 para_basic_deposit.saturating_add(para_byte_deposit.saturating_mul(bytes as Balance));
75 let subs_deposit = para_sub_account_deposit.saturating_mul(subs as Balance);
76
77 id_deposit
78 .saturating_add(subs_deposit)
79 .saturating_add(para_existential_deposit.saturating_mul(2))
80 }
81}
82
83impl<Runtime, AccountId> OnReapIdentity<AccountId> for ToParachainIdentityReaper<Runtime, AccountId>
86where
87 Runtime: frame_system::Config + pallet_xcm::Config,
88 AccountId: Into<[u8; 32]> + Clone + Encode,
89{
90 fn on_reap_identity(who: &AccountId, fields: u32, subs: u32) -> DispatchResult {
91 use crate::{
92 impls::IdentityMigratorCalls::PokeDeposit,
93 weights::polkadot_runtime_common_identity_migrator::WeightInfo as MigratorWeights,
94 };
95
96 let total_to_send = Self::calculate_remote_deposit(fields, subs);
97
98 let wnd = Asset { id: AssetId(Here.into_location()), fun: Fungible(total_to_send) };
100 let destination: Location = Location::new(0, Parachain(1004));
102
103 let who_origin =
108 Junction::AccountId32 { network: None, id: who.clone().into() }.into_location();
109 let _withdrawn = xcm_config::LocalAssetTransactor::withdraw_asset(&wnd, &who_origin, None)
110 .map_err(|err| {
111 log::error!(
112 target: "runtime::on_reap_identity",
113 "withdraw_asset(what: {:?}, who_origin: {:?}) error: {:?}",
114 wnd, who_origin, err
115 );
116 pallet_xcm::Error::<Runtime>::LowBalance
117 })?;
118
119 xcm_config::LocalAssetTransactor::can_check_out(
121 &destination,
122 &wnd,
123 &XcmContext { origin: None, message_id: [0; 32], topic: None },
125 )
126 .map_err(|err| {
127 log::error!(
128 target: "runtime::on_reap_identity",
129 "can_check_out(destination: {:?}, asset: {:?}, _) error: {:?}",
130 destination, wnd, err
131 );
132 pallet_xcm::Error::<Runtime>::CannotCheckOutTeleport
133 })?;
134 xcm_config::LocalAssetTransactor::check_out(
135 &destination,
136 &wnd,
137 &XcmContext { origin: None, message_id: [0; 32], topic: None },
139 );
140
141 let wnd_reanchored: Assets =
143 vec![Asset { id: AssetId(Location::new(1, Here)), fun: Fungible(total_to_send) }]
144 .into();
145
146 let poke = PeopleRuntimePallets::<AccountId>::IdentityMigrator(PokeDeposit(who.clone()));
147 let remote_weight_limit = MigratorWeights::<Runtime>::poke_deposit().saturating_mul(2);
148
149 let program: Xcm<()> = Xcm(vec![
151 UnpaidExecution { weight_limit: Unlimited, check_origin: None },
154 ReceiveTeleportedAsset(wnd_reanchored),
156 DepositAsset {
158 assets: Wild(AllCounted(1)),
159 beneficiary: Junction::AccountId32 { network: None, id: who.clone().into() }
160 .into_location()
161 .into(),
162 },
163 Transact {
165 origin_kind: OriginKind::Superuser,
166 call: poke.encode().into(),
167 fallback_max_weight: Some(remote_weight_limit),
168 },
169 ]);
170
171 let _ = <pallet_xcm::Pallet<Runtime>>::send(
173 RawOrigin::Root.into(),
174 Box::new(VersionedLocation::from(destination)),
175 Box::new(VersionedXcm::from(program)),
176 )?;
177 Ok(())
178 }
179
180 #[cfg(feature = "runtime-benchmarks")]
181 fn ensure_successful_identity_reaping(_: &AccountId, _: u32, _: u32) {
182 crate::Dmp::make_parachain_reachable(1004);
183 }
184}