referrerpolicy=no-referrer-when-downgrade

polkadot_runtime_common/slots/
migration.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17use super::*;
18use crate::crowdloan;
19use sp_runtime::traits::AccountIdConversion;
20
21/// Migrations for using fund index to create fund accounts instead of para ID.
22pub mod slots_crowdloan_index_migration {
23	use super::*;
24
25	// The old way we generated fund accounts.
26	fn old_fund_account_id<T: Config + crowdloan::Config>(index: ParaId) -> T::AccountId {
27		<T as crowdloan::Config>::PalletId::get().into_sub_account_truncating(index)
28	}
29
30	pub fn pre_migrate<T: Config + crowdloan::Config>() -> Result<(), &'static str> {
31		for (para_id, leases) in Leases::<T>::iter() {
32			let old_fund_account = old_fund_account_id::<T>(para_id);
33
34			for (who, _amount) in leases.iter().flatten() {
35				if *who == old_fund_account {
36					let crowdloan =
37						crowdloan::Funds::<T>::get(para_id).ok_or("no crowdloan found")?;
38					log::info!(
39						target: "runtime",
40						"para_id={:?}, old_fund_account={:?}, fund_id={:?}, leases={:?}",
41						para_id, old_fund_account, crowdloan.fund_index, leases,
42					);
43					break
44				}
45			}
46		}
47
48		Ok(())
49	}
50
51	pub fn migrate<T: Config + crowdloan::Config>() -> frame_support::weights::Weight {
52		let mut weight = Weight::zero();
53
54		for (para_id, mut leases) in Leases::<T>::iter() {
55			weight = weight.saturating_add(T::DbWeight::get().reads(2));
56			// the para id must have a crowdloan
57			if let Some(fund) = crowdloan::Funds::<T>::get(para_id) {
58				let old_fund_account = old_fund_account_id::<T>(para_id);
59				let new_fund_account = crowdloan::Pallet::<T>::fund_account_id(fund.fund_index);
60
61				// look for places the old account is used, and replace with the new account.
62				for (who, _amount) in leases.iter_mut().flatten() {
63					if *who == old_fund_account {
64						*who = new_fund_account.clone();
65					}
66				}
67
68				// insert the changes.
69				weight = weight.saturating_add(T::DbWeight::get().writes(1));
70				Leases::<T>::insert(para_id, leases);
71			}
72		}
73
74		weight
75	}
76
77	pub fn post_migrate<T: Config + crowdloan::Config>() -> Result<(), &'static str> {
78		for (para_id, leases) in Leases::<T>::iter() {
79			let old_fund_account = old_fund_account_id::<T>(para_id);
80			log::info!(target: "runtime", "checking para_id: {:?}", para_id);
81			// check the old fund account doesn't exist anywhere.
82			for (who, _amount) in leases.iter().flatten() {
83				if *who == old_fund_account {
84					panic!("old fund account found after migration!");
85				}
86			}
87		}
88		Ok(())
89	}
90}