1
// Copyright 2019-2022 PureStake Inc.
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam 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
// Moonbeam 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 Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
//! # Migrations
18
//!
19
//! This module acts as a registry where each migration is defined. Each migration should implement
20
//! the "Migration" trait declared in the pallet-migrations crate.
21

            
22
use frame_support::{traits::OnRuntimeUpgrade, weights::Weight};
23
use frame_system::pallet_prelude::BlockNumberFor;
24
use pallet_migrations::{GetMigrations, Migration};
25
use sp_std::{marker::PhantomData, prelude::*, vec};
26

            
27
pub struct MigrateToLatestXcmVersion<Runtime>(PhantomData<Runtime>);
28
impl<Runtime> Migration for MigrateToLatestXcmVersion<Runtime>
29
where
30
	pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>: OnRuntimeUpgrade,
31
{
32
3
	fn friendly_name(&self) -> &str {
33
3
		"MM_MigrateToLatestXcmVersion"
34
3
	}
35

            
36
	fn migrate(&self, _available_weight: Weight) -> Weight {
37
		pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::on_runtime_upgrade()
38
	}
39

            
40
	#[cfg(feature = "try-runtime")]
41
	fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
42
		pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::pre_upgrade()
43
	}
44

            
45
	#[cfg(feature = "try-runtime")]
46
	fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
47
		pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::post_upgrade(state)
48
	}
49
}
50

            
51
pub struct MigrateCodeToStateTrieV1<Runtime>(PhantomData<Runtime>);
52
impl<Runtime> Migration for MigrateCodeToStateTrieV1<Runtime>
53
where
54
	Runtime: frame_system::Config,
55
{
56
3
	fn friendly_name(&self) -> &str {
57
3
		"MM_MigrateCodeToStateTrieVersion1"
58
3
	}
59

            
60
	fn migrate(&self, _available_weight: Weight) -> Weight {
61
		use cumulus_primitives_storage_weight_reclaim::get_proof_size;
62
		use sp_core::Get;
63

            
64
		let proof_size_before: u64 = get_proof_size().unwrap_or(0);
65

            
66
		let key = sp_core::storage::well_known_keys::CODE;
67
		let data = sp_io::storage::get(&key);
68
		if let Some(data) = data {
69
			sp_io::storage::set(&key, &data);
70
		}
71

            
72
		let proof_size_after: u64 = get_proof_size().unwrap_or(0);
73
		let proof_size_diff = proof_size_after.saturating_sub(proof_size_before);
74

            
75
		Weight::from_parts(0, proof_size_diff)
76
			.saturating_add(<Runtime as frame_system::Config>::DbWeight::get().reads_writes(1, 1))
77
	}
78

            
79
	#[cfg(feature = "try-runtime")]
80
	fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
81
		use parity_scale_codec::Encode;
82

            
83
		let key = sp_core::storage::well_known_keys::CODE;
84
		let data = sp_io::storage::get(&key);
85
		Ok(Encode::encode(&data))
86
	}
87

            
88
	#[cfg(feature = "try-runtime")]
89
	fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
90
		use frame_support::ensure;
91
		use parity_scale_codec::Encode;
92
		use sp_core::storage::StorageKey;
93

            
94
		let key = StorageKey(sp_core::storage::well_known_keys::CODE.to_vec());
95
		let data = sp_io::storage::get(key.as_ref());
96

            
97
		ensure!(Encode::encode(&data) == state, "Invalid state");
98

            
99
		Ok(())
100
	}
101
}
102

            
103
#[derive(parity_scale_codec::Decode, Eq, Ord, PartialEq, PartialOrd)]
104
enum OldAssetType {
105
	Xcm(xcm::v3::Location),
106
}
107

            
108
pub struct MigrateXcmFeesAssetsMeatdata<Runtime>(PhantomData<Runtime>);
109
impl<Runtime> Migration for MigrateXcmFeesAssetsMeatdata<Runtime>
110
where
111
	Runtime: pallet_transaction_payment::Config,
112
	Runtime: pallet_xcm_weight_trader::Config,
113
{
114
	fn friendly_name(&self) -> &str {
115
		"MM_MigrateXcmFeesAssetsMetadata"
116
	}
117

            
118
	fn migrate(&self, _available_weight: Weight) -> Weight {
119
		let supported_assets =
120
			if let Some(supported_assets) = frame_support::storage::migration::get_storage_value::<
121
				Vec<OldAssetType>,
122
			>(b"AssetManager", b"SupportedFeePaymentAssets", &[])
123
			{
124
				sp_std::collections::btree_set::BTreeSet::from_iter(
125
					supported_assets
126
						.into_iter()
127
						.map(|OldAssetType::Xcm(location_v3)| location_v3),
128
				)
129
			} else {
130
				return Weight::default();
131
			};
132

            
133
		let mut assets: Vec<(xcm::v4::Location, (bool, u128))> = Vec::new();
134

            
135
		for (OldAssetType::Xcm(location_v3), units_per_seconds) in
136
			frame_support::storage::migration::storage_key_iter::<
137
				OldAssetType,
138
				u128,
139
				frame_support::Blake2_128Concat,
140
			>(b"AssetManager", b"AssetTypeUnitsPerSecond")
141
		{
142
			let enabled = supported_assets.get(&location_v3).is_some();
143

            
144
			if let Ok(location_v4) = location_v3.try_into() {
145
				assets.push((location_v4, (enabled, units_per_seconds)));
146
			}
147
		}
148

            
149
		//***** Start mutate storage *****//
150

            
151
		// Write asset metadata in new pallet_xcm_weight_trader
152
		use frame_support::weights::WeightToFee as _;
153
		for (asset_location, (enabled, units_per_second)) in assets {
154
			let native_amount_per_second: u128 =
155
				<Runtime as pallet_transaction_payment::Config>::WeightToFee::weight_to_fee(
156
					&Weight::from_parts(
157
						frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND,
158
						0,
159
					),
160
				)
161
				.try_into()
162
				.unwrap_or(u128::MAX);
163
			let relative_price: u128 = native_amount_per_second
164
				.saturating_mul(10u128.pow(pallet_xcm_weight_trader::RELATIVE_PRICE_DECIMALS))
165
				.saturating_div(units_per_second);
166
			pallet_xcm_weight_trader::SupportedAssets::<Runtime>::insert(
167
				asset_location,
168
				(enabled, relative_price),
169
			);
170
		}
171

            
172
		// Remove storage value AssetManager::SupportedFeePaymentAssets
173
		frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix(
174
			b"AssetManager",
175
			b"SupportedFeePaymentAssets",
176
		));
177

            
178
		// Remove storage map AssetManager::AssetTypeUnitsPerSecond
179
		let _ = frame_support::storage::migration::clear_storage_prefix(
180
			b"AssetManager",
181
			b"AssetTypeUnitsPerSecond",
182
			&[],
183
			None,
184
			None,
185
		);
186

            
187
		Weight::default()
188
	}
189

            
190
	#[cfg(feature = "try-runtime")]
191
	fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
192
		Ok(Default::default())
193
	}
194

            
195
	#[cfg(feature = "try-runtime")]
196
	fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
197
		assert!(frame_support::storage::migration::storage_key_iter::<
198
			OldAssetType,
199
			u128,
200
			frame_support::Blake2_128Concat,
201
		>(b"AssetManager", b"AssetTypeUnitsPerSecond")
202
		.next()
203
		.is_none());
204

            
205
		Ok(())
206
	}
207
}
208

            
209
pub struct MigrateStakingParachainBondConfig<Runtime>(PhantomData<Runtime>);
210
impl<Runtime> Migration for MigrateStakingParachainBondConfig<Runtime>
211
where
212
	Runtime: pallet_parachain_staking::Config,
213
{
214
3
	fn friendly_name(&self) -> &str {
215
3
		"MM_MigrateStakingParachainBondConfig"
216
3
	}
217

            
218
	fn migrate(&self, _available_weight: Weight) -> Weight {
219
		pallet_parachain_staking::migrations::MigrateParachainBondConfig::<Runtime>::on_runtime_upgrade()
220
	}
221

            
222
	#[cfg(feature = "try-runtime")]
223
	fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
224
		pallet_parachain_staking::migrations::MigrateParachainBondConfig::<Runtime>::pre_upgrade()
225
	}
226

            
227
	#[cfg(feature = "try-runtime")]
228
	fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
229
		pallet_parachain_staking::migrations::MigrateParachainBondConfig::<Runtime>::post_upgrade(
230
			state,
231
		)
232
	}
233
}
234

            
235
pub struct CommonMigrations<Runtime>(PhantomData<Runtime>);
236

            
237
impl<Runtime> GetMigrations for CommonMigrations<Runtime>
238
where
239
	Runtime: pallet_xcm::Config
240
		+ pallet_transaction_payment::Config
241
		+ pallet_xcm_weight_trader::Config
242
		+ pallet_parachain_staking::Config,
243
	Runtime::AccountId: Default,
244
	BlockNumberFor<Runtime>: Into<u64>,
245
{
246
3
	fn get_migrations() -> Vec<Box<dyn Migration>> {
247
3
		// let migration_author_mapping_twox_to_blake = AuthorMappingTwoXToBlake::<Runtime> {
248
3
		// 	0: Default::default(),
249
3
		// };
250
3

            
251
3
		// let migration_parachain_staking_purge_stale_storage =
252
3
		// 	ParachainStakingPurgeStaleStorage::<Runtime>(Default::default());
253
3
		// let migration_parachain_staking_manual_exits =
254
3
		// 	ParachainStakingManualExits::<Runtime>(Default::default());
255
3
		// let migration_parachain_staking_increase_max_delegations_per_candidate =
256
3
		// 	ParachainStakingIncreaseMaxDelegationsPerCandidate::<Runtime>(Default::default());
257
3
		// let migration_parachain_staking_split_candidate_state =
258
3
		// 	ParachainStakingSplitCandidateState::<Runtime>(Default::default());
259
3
		// let migration_parachain_staking_patch_incorrect_delegation_sums =
260
3
		//	ParachainStakingPatchIncorrectDelegationSums::<Runtime>(Default::default());
261
3

            
262
3
		// let migration_scheduler_v3 = SchedulerMigrationV3::<Runtime>(Default::default());
263
3

            
264
3
		// let migration_base_fee = MigrateBaseFeePerGas::<Runtime>(Default::default());
265
3

            
266
3
		// TODO: this is a lot of allocation to do upon every get() call. this *should* be avoided
267
3
		// except when pallet_migrations undergoes a runtime upgrade -- but TODO: review
268
3

            
269
3
		// let migration_author_slot_filter_eligible_ratio_to_eligibility_count =
270
3
		// 	AuthorSlotFilterEligibleRatioToEligiblityCount::<Runtime>(Default::default());
271
3
		// let migration_author_mapping_add_keys_to_registration_info =
272
3
		// 	AuthorMappingAddKeysToRegistrationInfo::<Runtime>(Default::default());
273
3
		// let staking_delegator_state_requests =
274
3
		// 	ParachainStakingSplitDelegatorStateIntoDelegationScheduledRequests::<Runtime>(
275
3
		// 		Default::default(),
276
3
		// 	);
277
3
		// let migration_author_mapping_add_account_id_to_nimbus_lookup =
278
3
		//	AuthorMappingAddAccountIdToNimbusLookup::<Runtime>(Default::default());
279
3

            
280
3
		// let xcm_transactor_max_weight =
281
3
		// 	XcmTransactorMaxTransactWeight::<Runtime>(Default::default());
282
3

            
283
3
		// let asset_manager_units_with_asset_type =
284
3
		// 	AssetManagerUnitsWithAssetType::<Runtime>(Default::default());
285
3

            
286
3
		// let asset_manager_populate_asset_type_id_storage =
287
3
		// 	AssetManagerPopulateAssetTypeIdStorage::<Runtime>(Default::default());
288
3

            
289
3
		// let asset_manager_change_statemine_prefixes = AssetManagerChangeStateminePrefixes::<
290
3
		// 	Runtime,
291
3
		// 	StatemineParaIdInfo,
292
3
		// 	StatemineAssetsInstanceInfo,
293
3
		// >(Default::default());
294
3

            
295
3
		// let xcm_supported_assets = XcmPaymentSupportedAssets::<Runtime>(Default::default());
296
3

            
297
3
		// let migration_elasticity = MigrateBaseFeeElasticity::<Runtime>(Default::default());
298
3
		//let staking_at_stake_auto_compound =
299
3
		//	ParachainStakingMigrateAtStakeAutoCompound::<Runtime>(Default::default());
300
3

            
301
3
		//let scheduler_to_v4 = SchedulerMigrationV4::<Runtime>(Default::default());
302
3
		//let democracy_migration_hash_to_bounded_call =
303
3
		//	DemocracryMigrationHashToBoundedCall::<Runtime>(Default::default());
304
3
		//let preimage_migration_hash_to_bounded_call =
305
3
		//	PreimageMigrationHashToBoundedCall::<Runtime>(Default::default());
306
3
		//let asset_manager_to_xcm_v3 =
307
3
		//	PalletAssetManagerMigrateXcmV2ToV3::<Runtime>(Default::default());
308
3
		//let xcm_transactor_to_xcm_v3 =
309
3
		//	PalletXcmTransactorMigrateXcmV2ToV3::<Runtime>(Default::default());
310
3
		//let remove_min_bond_for_old_orbiter_collators =
311
3
		//	RemoveMinBondForOrbiterCollators::<Runtime>(Default::default());
312
3
		// let missing_balances_migrations = MissingBalancesMigrations::<Runtime>(Default::default());
313
3
		// let fix_pallet_versions =
314
3
		// 	FixIncorrectPalletVersions::<Runtime, Treasury, OpenTech>(Default::default());
315
3
		// let pallet_referenda_migrate_v0_to_v1 =
316
3
		// 	PalletReferendaMigrateV0ToV1::<Runtime>(Default::default());
317
3
		//let pallet_collective_drop_gov_v1_collectives =
318
3
		//	PalletCollectiveDropGovV1Collectives::<Runtime>(Default::default());
319
3
		//let pallet_staking_round = PalletStakingRoundMigration::<Runtime>(Default::default());
320
3

            
321
3
		vec![
322
3
			// completed in runtime 800
323
3
			// Box::new(migration_author_mapping_twox_to_blake),
324
3
			// completed in runtime 900
325
3
			// completed in runtime 1000
326
3
			// Box::new(migration_parachain_staking_purge_stale_storage),
327
3
			// completed in runtime 1000
328
3
			// Box::new(migration_parachain_staking_manual_exits),
329
3
			// completed in runtime 1101
330
3
			// Box::new(migration_parachain_staking_increase_max_delegations_per_candidate),
331
3
			// completed in runtime 1201
332
3
			// Box::new(migration_parachain_staking_split_candidate_state),
333
3
			// completed in runtime 1201
334
3
			// Box::new(xcm_transactor_max_weight),
335
3
			// completed in runtime 1201
336
3
			// Box::new(asset_manager_units_with_asset_type),
337
3
			// completed in runtime 1201
338
3
			// Box::new(asset_manager_change_statemine_prefixes),
339
3
			// completed in runtime 1201
340
3
			// Box::new(asset_manager_populate_asset_type_id_storage),
341
3
			// completed in runtime 1300
342
3
			// Box::new(migration_scheduler_v3),
343
3
			// completed in runtime 1300
344
3
			// Box::new(migration_parachain_staking_patch_incorrect_delegation_sums),
345
3
			// completed in runtime 1300
346
3
			// Box::new(migration_base_fee),
347
3
			// completed in runtime 1300
348
3
			// Box::new(xcm_supported_assets),
349
3
			// completed in runtime 1500
350
3
			// Box::new(migration_author_slot_filter_eligible_ratio_to_eligibility_count),
351
3
			// Box::new(migration_author_mapping_add_keys_to_registration_info),
352
3
			// Box::new(staking_delegator_state_requests),
353
3
			// completed in runtime 1600
354
3
			// Box::new(migration_author_mapping_add_account_id_to_nimbus_lookup),
355
3
			// completed in runtime 1600
356
3
			// Box::new(xcm_transactor_transact_signed),
357
3
			// completed in runtime 1700
358
3
			//Box::new(migration_elasticity),
359
3
			// completed in runtime 1900
360
3
			//Box::new(staking_at_stake_auto_compound),
361
3
			// completed in runtime 2000
362
3
			//Box::new(scheduler_to_v4),
363
3
			//Box::new(democracy_migration_hash_to_bounded_call),
364
3
			//Box::new(preimage_migration_hash_to_bounded_call),
365
3
			// completed in runtime 2100
366
3
			//Box::new(asset_manager_to_xcm_v3),
367
3
			//Box::new(xcm_transactor_to_xcm_v3),
368
3
			// completed in runtime 2600
369
3
			//Box::new(remove_min_bond_for_old_orbiter_collators),
370
3
			// completed in runtime 2700
371
3
			// Box::new(missing_balances_migrations),
372
3
			// Box::new(fix_pallet_versions),
373
3
			// Box::new(pallet_referenda_migrate_v0_to_v1),
374
3
			// completed in runtime 2800
375
3
			//Box::new(pallet_collective_drop_gov_v1_collectives),
376
3
			// completed in runtime 2801
377
3
			// Box::new(pallet_staking_round),
378
3
			// Box::new(pallet_collective_drop_gov_v1_collectives),
379
3
			// completed in runtime 2900
380
3
			// Box::new(remove_pallet_democracy),
381
3
			// Box::new(remove_collectives_addresses
382
3
			// completed in runtime 3200
383
3
			// Box::new(MigrateXcmFeesAssetsMeatdata::<Runtime>(Default::default())),
384
3
			// complete in runtime 3300
385
3
			Box::new(MigrateCodeToStateTrieV1::<Runtime>(Default::default())),
386
3
			Box::new(MigrateStakingParachainBondConfig::<Runtime>(
387
3
				Default::default(),
388
3
			)),
389
3
			// permanent migrations
390
3
			Box::new(MigrateToLatestXcmVersion::<Runtime>(Default::default())),
391
3
		]
392
3
	}
393
}