1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi 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
// Tanssi 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 Tanssi.  If not, see <http://www.gnu.org/licenses/>
16
// Copyright (C) Moondance Labs Ltd.
17
// This file is part of Tanssi.
18

            
19
// Tanssi is free software: you can redistribute it and/or modify
20
// it under the terms of the GNU General Public License as published by
21
// the Free Software Foundation, either version 3 of the License, or
22
// (at your option) any later version.
23

            
24
// Tanssi is distributed in the hope that it will be useful,
25
// but WITHOUT ANY WARRANTY; without even the implied warranty of
26
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
// GNU General Public License for more details.
28

            
29
// You should have received a copy of the GNU General Public License
30
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>
31

            
32
//! # Migrations
33
//!
34
//! This module acts as a registry where each migration is defined. Each migration should implement
35
//! the "Migration" trait declared in the pallet-migrations crate.
36

            
37
#[cfg(feature = "try-runtime")]
38
use frame_support::ensure;
39

            
40
use {
41
    cumulus_primitives_core::ParaId,
42
    frame_support::{
43
        migration::{clear_storage_prefix, storage_key_iter},
44
        pallet_prelude::GetStorageVersion,
45
        traits::{
46
            fungible::MutateHold, OnRuntimeUpgrade, PalletInfoAccess, ReservableCurrency,
47
            StorageVersion,
48
        },
49
        weights::Weight,
50
        Blake2_128Concat, BoundedVec, StoragePrefixedMap,
51
    },
52
    pallet_configuration::{weights::WeightInfo as _, HostConfiguration},
53
    pallet_foreign_asset_creator::{AssetId, AssetIdToForeignAsset, ForeignAssetToAssetId},
54
    pallet_migrations::{GetMigrations, Migration},
55
    pallet_registrar::HoldReason,
56
    sp_core::Get,
57
    sp_std::{collections::btree_set::BTreeSet, marker::PhantomData, prelude::*},
58
};
59

            
60
#[derive(
61
    Clone,
62
    parity_scale_codec::Encode,
63
    parity_scale_codec::Decode,
64
    PartialEq,
65
    sp_core::RuntimeDebug,
66
    scale_info::TypeInfo,
67
)]
68
struct HostConfigurationV1 {
69
    pub max_collators: u32,
70
    pub min_orchestrator_collators: u32,
71
    pub max_orchestrator_collators: u32,
72
    pub collators_per_container: u32,
73
    pub full_rotation_period: u32,
74
}
75

            
76
pub struct MigrateConfigurationParathreads<T>(pub PhantomData<T>);
77
impl<T> Migration for MigrateConfigurationParathreads<T>
78
where
79
    T: pallet_configuration::Config,
80
{
81
2
    fn friendly_name(&self) -> &str {
82
2
        "TM_MigrateConfigurationParathreads"
83
2
    }
84

            
85
1
    fn migrate(&self, _available_weight: Weight) -> Weight {
86
1
        const CONFIGURATION_ACTIVE_CONFIG_KEY: &[u8] =
87
1
            &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385");
88
1
        const CONFIGURATION_PENDING_CONFIGS_KEY: &[u8] =
89
1
            &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22d53b4123b2e186e07fb7bad5dda5f55c0");
90
1
        let default_config = HostConfiguration::default();
91
1

            
92
1
        // Modify active config
93
1
        let old_config: HostConfigurationV1 =
94
1
            frame_support::storage::unhashed::get(CONFIGURATION_ACTIVE_CONFIG_KEY)
95
1
                .expect("configuration.activeConfig should have value");
96
1
        let new_config = HostConfiguration {
97
1
            max_collators: old_config.max_collators,
98
1
            min_orchestrator_collators: old_config.min_orchestrator_collators,
99
1
            max_orchestrator_collators: old_config.max_orchestrator_collators,
100
1
            collators_per_container: old_config.collators_per_container,
101
1
            full_rotation_period: old_config.full_rotation_period,
102
1
            collators_per_parathread: default_config.collators_per_parathread,
103
1
            parathreads_per_collator: default_config.parathreads_per_collator,
104
1
            target_container_chain_fullness: default_config.target_container_chain_fullness,
105
1
        };
106
1
        frame_support::storage::unhashed::put(CONFIGURATION_ACTIVE_CONFIG_KEY, &new_config);
107
1

            
108
1
        // Modify pending configs, if any
109
1
        let old_pending_configs: Vec<(u32, HostConfigurationV1)> =
110
1
            frame_support::storage::unhashed::get(CONFIGURATION_PENDING_CONFIGS_KEY)
111
1
                .unwrap_or_default();
112
1
        let mut new_pending_configs: Vec<(u32, HostConfiguration)> = vec![];
113

            
114
3
        for (session_index, old_config) in old_pending_configs {
115
2
            let new_config = HostConfiguration {
116
2
                max_collators: old_config.max_collators,
117
2
                min_orchestrator_collators: old_config.min_orchestrator_collators,
118
2
                max_orchestrator_collators: old_config.max_orchestrator_collators,
119
2
                collators_per_container: old_config.collators_per_container,
120
2
                full_rotation_period: old_config.full_rotation_period,
121
2
                collators_per_parathread: default_config.collators_per_parathread,
122
2
                parathreads_per_collator: default_config.parathreads_per_collator,
123
2
                target_container_chain_fullness: default_config.target_container_chain_fullness,
124
2
            };
125
2
            new_pending_configs.push((session_index, new_config));
126
2
        }
127

            
128
1
        if !new_pending_configs.is_empty() {
129
1
            frame_support::storage::unhashed::put(
130
1
                CONFIGURATION_PENDING_CONFIGS_KEY,
131
1
                &new_pending_configs,
132
1
            );
133
1
        }
134

            
135
1
        <T as pallet_configuration::Config>::WeightInfo::set_config_with_u32()
136
1
    }
137

            
138
    /// Run a standard pre-runtime test. This works the same way as in a normal runtime upgrade.
139
    #[cfg(feature = "try-runtime")]
140
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
141
        const CONFIGURATION_ACTIVE_CONFIG_KEY: &[u8] =
142
            &hex_literal::hex!("06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385");
143

            
144
        let old_config_bytes =
145
            frame_support::storage::unhashed::get_raw(CONFIGURATION_ACTIVE_CONFIG_KEY)
146
                .expect("configuration.activeConfig should have value");
147
        assert_eq!(old_config_bytes.len(), 20);
148

            
149
        use parity_scale_codec::Encode;
150
        Ok((old_config_bytes).encode())
151
    }
152

            
153
    /// Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
154
    #[cfg(feature = "try-runtime")]
155
    fn post_upgrade(
156
        &self,
157
        _number_of_invulnerables: Vec<u8>,
158
    ) -> Result<(), sp_runtime::DispatchError> {
159
        let new_config = pallet_configuration::Pallet::<T>::config();
160
        let default_config = HostConfiguration::default();
161
        assert_eq!(
162
            new_config.collators_per_parathread,
163
            default_config.collators_per_parathread
164
        );
165
        assert_eq!(
166
            new_config.parathreads_per_collator,
167
            default_config.collators_per_parathread
168
        );
169
        assert_eq!(
170
            new_config.target_container_chain_fullness,
171
            default_config.target_container_chain_fullness
172
        );
173

            
174
        Ok(())
175
    }
176
}
177

            
178
pub struct MigrateServicesPaymentAddCollatorAssignmentCredits<T>(pub PhantomData<T>);
179
impl<T> Migration for MigrateServicesPaymentAddCollatorAssignmentCredits<T>
180
where
181
    T: pallet_services_payment::Config + pallet_registrar::Config,
182
{
183
2
    fn friendly_name(&self) -> &str {
184
2
        "TM_MigrateServicesPaymentAddCollatorAssignmentCredits"
185
2
    }
186

            
187
2
    fn migrate(&self, _available_weight: Weight) -> Weight {
188
2
        // For each parachain in pallet_registrar (active, pending or pending_verification),
189
2
        // insert `MaxCreditsStored` to pallet_services_payment,
190
2
        // and mark that parachain as "given_free_credits".
191
2
        let mut para_ids = BTreeSet::new();
192
2
        let active = pallet_registrar::RegisteredParaIds::<T>::get();
193
2
        let pending = pallet_registrar::PendingParaIds::<T>::get();
194
2

            
195
2
        let paused = pallet_registrar::Paused::<T>::get();
196
2
        para_ids.extend(active);
197
2
        para_ids.extend(pending.into_iter().flat_map(|(_session, active)| active));
198
2
        para_ids.extend(paused);
199
2

            
200
2
        let reads = 3 + 2 * para_ids.len() as u64;
201
2
        let writes = 2 * para_ids.len() as u64;
202

            
203
6
        for para_id in para_ids {
204
4
            // 2 reads 2 writes
205
4
            pallet_services_payment::Pallet::<T>::set_free_collator_assignment_credits(
206
4
                &para_id,
207
4
                T::FreeCollatorAssignmentCredits::get(),
208
4
            );
209
4
        }
210

            
211
2
        let db_weights = T::DbWeight::get();
212
2
        db_weights.reads_writes(reads, writes)
213
2
    }
214
    /// Run a standard pre-runtime test. This works the same way as in a normal runtime upgrade.
215
    #[cfg(feature = "try-runtime")]
216
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
217
        let mut para_ids = BTreeSet::new();
218
        let active = pallet_registrar::RegisteredParaIds::<T>::get();
219
        let pending = pallet_registrar::PendingParaIds::<T>::get();
220
        let paused = pallet_registrar::Paused::<T>::get();
221
        para_ids.extend(active);
222
        para_ids.extend(pending.into_iter().flat_map(|(_session, active)| active));
223
        para_ids.extend(paused);
224

            
225
        for para_id in para_ids {
226
            assert!(
227
                pallet_services_payment::CollatorAssignmentCredits::<T>::get(para_id).is_none()
228
            );
229
        }
230

            
231
        Ok(vec![])
232
    }
233

            
234
    // Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
235
    #[cfg(feature = "try-runtime")]
236
    fn post_upgrade(&self, _result: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
237
        let mut para_ids = BTreeSet::new();
238
        let active = pallet_registrar::RegisteredParaIds::<T>::get();
239
        let pending = pallet_registrar::PendingParaIds::<T>::get();
240
        let paused = pallet_registrar::Paused::<T>::get();
241
        para_ids.extend(active);
242
        para_ids.extend(pending.into_iter().flat_map(|(_session, active)| active));
243
        para_ids.extend(paused);
244

            
245
        for para_id in para_ids {
246
            assert_eq!(
247
                pallet_services_payment::CollatorAssignmentCredits::<T>::get(para_id),
248
                Some(T::FreeCollatorAssignmentCredits::get())
249
            );
250
        }
251

            
252
        Ok(())
253
    }
254
}
255

            
256
pub struct PolkadotXcmMigrationFixVersion<T, PolkadotXcm>(pub PhantomData<(T, PolkadotXcm)>);
257
impl<T, PolkadotXcm> Migration for PolkadotXcmMigrationFixVersion<T, PolkadotXcm>
258
where
259
    PolkadotXcm: GetStorageVersion + PalletInfoAccess,
260
    T: cumulus_pallet_xcmp_queue::Config,
261
{
262
354
    fn friendly_name(&self) -> &str {
263
354
        "MM_PolkadotXcmMigrationFixVersion"
264
354
    }
265

            
266
    fn migrate(&self, _available_weight: Weight) -> Weight {
267
        if <PolkadotXcm as GetStorageVersion>::on_chain_storage_version() == 0 {
268
            StorageVersion::new(1).put::<PolkadotXcm>();
269
            return T::DbWeight::get().writes(1);
270
        }
271
        Weight::default()
272
    }
273

            
274
    #[cfg(feature = "try-runtime")]
275
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
276
        ensure!(
277
            <PolkadotXcm as GetStorageVersion>::on_chain_storage_version() == 0,
278
            "PolkadotXcm storage version should be 0"
279
        );
280
        Ok(vec![])
281
    }
282

            
283
    // Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
284
    #[cfg(feature = "try-runtime")]
285
    fn post_upgrade(&self, _state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
286
        ensure!(
287
            <PolkadotXcm as GetStorageVersion>::on_chain_storage_version() == 1,
288
            "PolkadotXcm storage version should be 1"
289
        );
290
        Ok(())
291
    }
292
}
293

            
294
pub struct XcmpQueueMigrationFixVersion<T, XcmpQueue>(pub PhantomData<(T, XcmpQueue)>);
295
impl<T, XcmpQueue> Migration for XcmpQueueMigrationFixVersion<T, XcmpQueue>
296
where
297
    XcmpQueue: GetStorageVersion + PalletInfoAccess,
298
    T: cumulus_pallet_xcmp_queue::Config,
299
{
300
354
    fn friendly_name(&self) -> &str {
301
354
        "MM_XcmpQueueMigrationFixVersion"
302
354
    }
303

            
304
    fn migrate(&self, _available_weight: Weight) -> Weight {
305
        if <XcmpQueue as GetStorageVersion>::on_chain_storage_version() == 0 {
306
            StorageVersion::new(2).put::<XcmpQueue>();
307
            return T::DbWeight::get().writes(1);
308
        }
309
        Weight::default()
310
    }
311

            
312
    #[cfg(feature = "try-runtime")]
313
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
314
        ensure!(
315
            <XcmpQueue as GetStorageVersion>::on_chain_storage_version() == 0,
316
            "XcmpQueue storage version should be 0"
317
        );
318
        Ok(vec![])
319
    }
320

            
321
    // Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
322
    #[cfg(feature = "try-runtime")]
323
    fn post_upgrade(&self, _state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
324
        // Greater than because the post_upgrade is run after all the migrations, so
325
        // it can be greater if the following XcmpQueue migrations are applied in the
326
        // same runtime
327
        ensure!(
328
            <XcmpQueue as GetStorageVersion>::on_chain_storage_version() >= 2,
329
            "XcmpQueue storage version should be at least 2"
330
        );
331
        Ok(())
332
    }
333
}
334

            
335
pub struct XcmpQueueMigrationV3<T>(pub PhantomData<T>);
336
impl<T> Migration for XcmpQueueMigrationV3<T>
337
where
338
    T: cumulus_pallet_xcmp_queue::Config,
339
{
340
354
    fn friendly_name(&self) -> &str {
341
354
        "MM_XcmpQueueMigrationV3"
342
354
    }
343

            
344
    fn migrate(&self, _available_weight: Weight) -> Weight {
345
        cumulus_pallet_xcmp_queue::migration::v3::MigrationToV3::<T>::on_runtime_upgrade()
346
    }
347

            
348
    // #[cfg(feature = "try-runtime")]
349
    // let mut pre_upgrade_result: Vec<u8>;
350

            
351
    #[cfg(feature = "try-runtime")]
352
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
353
        cumulus_pallet_xcmp_queue::migration::v3::MigrationToV3::<T>::pre_upgrade()
354
    }
355

            
356
    // Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
357
    #[cfg(feature = "try-runtime")]
358
    fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
359
        cumulus_pallet_xcmp_queue::migration::v3::MigrationToV3::<T>::post_upgrade(state)
360
    }
361
}
362

            
363
pub struct XcmpQueueMigrationV4<T>(pub PhantomData<T>);
364
impl<T> Migration for XcmpQueueMigrationV4<T>
365
where
366
    T: cumulus_pallet_xcmp_queue::Config,
367
{
368
355
    fn friendly_name(&self) -> &str {
369
355
        "MM_XcmpQueueMigrationV4"
370
355
    }
371

            
372
    fn migrate(&self, _available_weight: Weight) -> Weight {
373
        cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4::<T>::on_runtime_upgrade()
374
    }
375

            
376
    #[cfg(feature = "try-runtime")]
377
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
378
        cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4::<T>::pre_upgrade()
379
    }
380

            
381
    // Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
382
    #[cfg(feature = "try-runtime")]
383
    fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
384
        cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4::<T>::post_upgrade(state)
385
    }
386
}
387

            
388
pub struct RegistrarPendingVerificationValueToMap<T>(pub PhantomData<T>);
389
impl<T> Migration for RegistrarPendingVerificationValueToMap<T>
390
where
391
    T: pallet_registrar::Config,
392
{
393
2
    fn friendly_name(&self) -> &str {
394
2
        "TM_RegistrarPendingVerificationValueToMap"
395
2
    }
396

            
397
1
    fn migrate(&self, _available_weight: Weight) -> Weight {
398
1
        let para_ids: Vec<ParaId> = frame_support::storage::unhashed::take(
399
1
            &frame_support::storage::storage_prefix(b"Registrar", b"PendingVerification"),
400
1
        )
401
1
        .unwrap_or_default();
402
1

            
403
1
        let total_weight = T::DbWeight::get()
404
1
            .reads(1)
405
1
            .saturating_add(T::DbWeight::get().writes(1));
406

            
407
5
        for para_id in para_ids {
408
4
            total_weight.saturating_add(T::DbWeight::get().writes(1));
409
4
            pallet_registrar::PendingVerification::<T>::insert(para_id, ());
410
4
        }
411

            
412
1
        total_weight
413
1
    }
414

            
415
    #[cfg(feature = "try-runtime")]
416
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
417
        Ok(vec![])
418
    }
419

            
420
    // Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
421
    #[cfg(feature = "try-runtime")]
422
    fn post_upgrade(&self, _state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
423
        Ok(())
424
    }
425
}
426

            
427
pub struct RegistrarParaManagerMigration<T>(pub PhantomData<T>);
428
impl<T> Migration for RegistrarParaManagerMigration<T>
429
where
430
    T: pallet_registrar::Config,
431
{
432
2
    fn friendly_name(&self) -> &str {
433
2
        "TM_RegistrarParaManagerMigration"
434
2
    }
435

            
436
    fn migrate(&self, _available_weight: Weight) -> Weight {
437
        let mut total_weight = Weight::default();
438
        for (para_id, deposit) in pallet_registrar::RegistrarDeposit::<T>::iter() {
439
            pallet_registrar::ParaManager::<T>::insert(para_id, deposit.creator);
440
            total_weight = total_weight.saturating_add(
441
                T::DbWeight::get()
442
                    .reads(1)
443
                    .saturating_add(T::DbWeight::get().writes(1)),
444
            );
445
        }
446

            
447
        total_weight
448
    }
449

            
450
    #[cfg(feature = "try-runtime")]
451
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
452
        Ok(vec![])
453
    }
454

            
455
    #[cfg(feature = "try-runtime")]
456
    fn post_upgrade(&self, _state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
457
        Ok(())
458
    }
459
}
460

            
461
pub struct RegistrarReserveToHoldMigration<T>(pub PhantomData<T>);
462
impl<T> Migration for RegistrarReserveToHoldMigration<T>
463
where
464
    T: pallet_registrar::Config,
465
    T: pallet_balances::Config,
466
    <T as pallet_balances::Config>::RuntimeHoldReason: From<pallet_registrar::HoldReason>,
467
    <T as pallet_balances::Config>::Balance: From<
468
        <<T as pallet_registrar::Config>::Currency as frame_support::traits::fungible::Inspect<
469
            T::AccountId,
470
        >>::Balance,
471
    >,
472
    <T as pallet_balances::Config>::Balance: From<u128>,
473
{
474
2
    fn friendly_name(&self) -> &str {
475
2
        "TM_RegistrarReserveToHoldMigration"
476
2
    }
477

            
478
2
    fn migrate(&self, _available_weight: Weight) -> Weight {
479
2
        let mut total_weight = Weight::default();
480
4
        for (_para_id, deposit) in pallet_registrar::RegistrarDeposit::<T>::iter() {
481
2
            pallet_balances::Pallet::<T>::unreserve(&deposit.creator, deposit.deposit.into());
482
2
            let _ = pallet_balances::Pallet::<T>::hold(
483
2
                &HoldReason::RegistrarDeposit.into(),
484
2
                &deposit.creator,
485
2
                deposit.deposit.into(),
486
2
            );
487
2
            total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(2, 2));
488
2
        }
489

            
490
2
        total_weight
491
2
    }
492

            
493
    #[cfg(feature = "try-runtime")]
494
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
495
        use frame_support::traits::fungible::InspectHold;
496

            
497
        for (_para_id, deposit) in pallet_registrar::RegistrarDeposit::<T>::iter() {
498
            ensure!(
499
                pallet_balances::Pallet::<T>::reserved_balance(&deposit.creator)
500
                    >= deposit.deposit.into(),
501
                "Reserved balanced cannot be less than deposit amount"
502
            );
503

            
504
            ensure!(
505
                pallet_balances::Pallet::<T>::balance_on_hold(
506
                    &HoldReason::RegistrarDeposit.into(),
507
                    &deposit.creator
508
                ) == 0u128.into(),
509
                "Balance on hold for RegistrarDeposit should be 0"
510
            );
511
        }
512
        Ok(vec![])
513
    }
514

            
515
    #[cfg(feature = "try-runtime")]
516
    fn post_upgrade(&self, _state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
517
        use frame_support::traits::fungible::InspectHold;
518

            
519
        for (_para_id, deposit) in pallet_registrar::RegistrarDeposit::<T>::iter() {
520
            ensure!(
521
                pallet_balances::Pallet::<T>::balance_on_hold(
522
                    &HoldReason::RegistrarDeposit.into(),
523
                    &deposit.creator
524
                ) >= deposit.deposit.into(),
525
                "Balance on hold for RegistrarDeposit should be deposit"
526
            );
527
        }
528

            
529
        Ok(())
530
    }
531
}
532
pub struct MigrateToLatestXcmVersion<Runtime>(PhantomData<Runtime>);
533
impl<Runtime> Migration for MigrateToLatestXcmVersion<Runtime>
534
where
535
    pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>:
536
        frame_support::traits::OnRuntimeUpgrade,
537
{
538
1
    fn friendly_name(&self) -> &str {
539
1
        "MM_MigrateToLatestXcmVersion"
540
1
    }
541

            
542
    fn migrate(&self, _available_weight: Weight) -> Weight {
543
        pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::on_runtime_upgrade()
544
    }
545

            
546
    #[cfg(feature = "try-runtime")]
547
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
548
        pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::pre_upgrade()
549
    }
550

            
551
    #[cfg(feature = "try-runtime")]
552
    fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
553
        pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::post_upgrade(state)
554
    }
555
}
556

            
557
pub struct DataPreserversAssignmentsMigration<T>(pub PhantomData<T>);
558
impl<T> Migration for DataPreserversAssignmentsMigration<T>
559
where
560
    T: pallet_data_preservers::Config + pallet_registrar::Config,
561
    T::AccountId: From<[u8; 32]>,
562
{
563
2
    fn friendly_name(&self) -> &str {
564
2
        "TM_DataPreserversAssignmentsMigration"
565
2
    }
566

            
567
2
    fn migrate(&self, _available_weight: Weight) -> Weight {
568
2
        use {
569
2
            frame_support::BoundedBTreeSet,
570
2
            frame_system::RawOrigin,
571
2
            pallet_data_preservers::{AssignmentPayment, ParaIdsFilter, Profile, ProfileMode},
572
2
        };
573
2

            
574
2
        let mut total_weight = Weight::default();
575
2

            
576
2
        let (request, _extra, witness) = T::AssignmentPayment::free_variant_values()
577
2
            .expect("free variant values are necessary to perform migration");
578
2

            
579
2
        let dummy_profile_owner = T::AccountId::from([0u8; 32]);
580
2

            
581
2
        let pallet_prefix: &[u8] = b"DataPreservers";
582
2
        let storage_item_prefix: &[u8] = b"BootNodes";
583
2
        let bootnodes_storage: Vec<_> = storage_key_iter::<
584
2
            ParaId,
585
2
            BoundedVec<BoundedVec<u8, T::MaxNodeUrlLen>, T::MaxAssignmentsPerParaId>,
586
2
            Blake2_128Concat,
587
2
        >(pallet_prefix, storage_item_prefix)
588
2
        .collect();
589
2

            
590
2
        total_weight = total_weight.saturating_add(
591
2
            T::DbWeight::get()
592
2
                .reads(bootnodes_storage.len() as u64)
593
2
                .saturating_add(T::DbWeight::get().writes(bootnodes_storage.len() as u64)),
594
2
        );
595

            
596
6
        for (para_id, bootnodes) in bootnodes_storage {
597
12
            for bootnode_url in bootnodes {
598
8
                let profile = Profile {
599
8
                    url: bootnode_url,
600
8
                    para_ids: ParaIdsFilter::Whitelist({
601
8
                        let mut set = BoundedBTreeSet::new();
602
8
                        set.try_insert(para_id).expect("to be in bound");
603
8
                        set
604
8
                    }),
605
8
                    mode: ProfileMode::Bootnode,
606
8
                    assignment_request: request.clone(),
607
8
                };
608
8

            
609
8
                let profile_id = pallet_data_preservers::NextProfileId::<T>::get();
610

            
611
8
                if let Some(weight) = pallet_data_preservers::Pallet::<T>::force_create_profile(
612
8
                    RawOrigin::Root.into(),
613
8
                    profile,
614
8
                    dummy_profile_owner.clone(),
615
8
                )
616
8
                .expect("to create profile")
617
8
                .actual_weight
618
                {
619
                    total_weight = total_weight.saturating_add(weight);
620
8
                }
621

            
622
8
                if let Some(weight) = pallet_data_preservers::Pallet::<T>::force_start_assignment(
623
8
                    RawOrigin::Root.into(),
624
8
                    profile_id,
625
8
                    para_id,
626
8
                    witness.clone(),
627
8
                )
628
8
                .expect("to start assignment")
629
8
                .actual_weight
630
                {
631
                    total_weight = total_weight.saturating_add(weight);
632
8
                }
633
            }
634
        }
635

            
636
2
        let _ = clear_storage_prefix(pallet_prefix, storage_item_prefix, &[], None, None);
637
2

            
638
2
        total_weight
639
2
    }
640

            
641
    #[cfg(feature = "try-runtime")]
642
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
643
        use parity_scale_codec::Encode;
644

            
645
        let pallet_prefix: &[u8] = b"DataPreservers";
646
        let storage_item_prefix: &[u8] = b"BootNodes";
647
        let state: Vec<_> = storage_key_iter::<
648
            ParaId,
649
            BoundedVec<BoundedVec<u8, T::MaxNodeUrlLen>, T::MaxAssignmentsPerParaId>,
650
            Blake2_128Concat,
651
        >(pallet_prefix, storage_item_prefix)
652
        .collect();
653

            
654
        Ok(state.encode())
655
    }
656

            
657
    #[cfg(feature = "try-runtime")]
658
    fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
659
        use parity_scale_codec::Decode;
660

            
661
        let pallet_prefix: &[u8] = b"DataPreservers";
662
        let storage_item_prefix: &[u8] = b"BootNodes";
663

            
664
        let pre_state: Vec<(ParaId, Vec<Vec<u8>>)> =
665
            Decode::decode(&mut &state[..]).expect("state to be decoded properly");
666

            
667
        for (para_id, bootnodes) in pre_state {
668
            let assignments = pallet_data_preservers::Assignments::<T>::get(para_id);
669
            assert_eq!(assignments.len(), bootnodes.len());
670

            
671
            let profiles: Vec<_> =
672
                pallet_data_preservers::Pallet::<T>::assignments_profiles(para_id).collect();
673

            
674
            for bootnode in bootnodes {
675
                assert_eq!(
676
                    profiles
677
                        .iter()
678
                        .filter(|profile| profile.url == bootnode)
679
                        .count(),
680
                    1
681
                );
682
            }
683
        }
684

            
685
        assert_eq!(
686
            storage_key_iter::<
687
                ParaId,
688
                BoundedVec<BoundedVec<u8, T::MaxNodeUrlLen>, T::MaxAssignmentsPerParaId>,
689
                Blake2_128Concat,
690
            >(pallet_prefix, storage_item_prefix)
691
            .count(),
692
            0
693
        );
694

            
695
        Ok(())
696
    }
697
}
698

            
699
pub struct ForeignAssetCreatorMigration<Runtime>(pub PhantomData<Runtime>);
700

            
701
impl<Runtime> Migration for ForeignAssetCreatorMigration<Runtime>
702
where
703
    Runtime: pallet_foreign_asset_creator::Config,
704
    <Runtime as pallet_foreign_asset_creator::Config>::ForeignAsset:
705
        TryFrom<staging_xcm::v3::MultiLocation>,
706
{
707
178
    fn friendly_name(&self) -> &str {
708
178
        "TM_ForeignAssetCreatorMigration"
709
178
    }
710

            
711
1
    fn migrate(&self, _available_weight: Weight) -> Weight {
712
1
        use frame_support::pallet_prelude::*;
713
1

            
714
1
        use staging_xcm::v3::MultiLocation as OldLocation;
715
1

            
716
1
        let pallet_prefix = AssetIdToForeignAsset::<Runtime>::pallet_prefix();
717
1
        let asset_id_to_foreign_asset_storage_prefix =
718
1
            AssetIdToForeignAsset::<Runtime>::storage_prefix();
719
1
        let foreign_asset_to_asset_id_prefix = ForeignAssetToAssetId::<Runtime>::storage_prefix();
720
1

            
721
1
        // Data required to migrate ForeignAsset values
722
1
        // Read all the data into memory.
723
1
        let asset_id_to_foreign_asset_data: Vec<_> =
724
1
            storage_key_iter::<AssetId<Runtime>, OldLocation, Blake2_128Concat>(
725
1
                pallet_prefix,
726
1
                asset_id_to_foreign_asset_storage_prefix,
727
1
            )
728
1
            .drain()
729
1
            .collect();
730
1

            
731
1
        // Data required to migrate ForeignAsset keys
732
1
        let foreign_asset_to_asset_id_data: Vec<_> =
733
1
            storage_key_iter::<OldLocation, AssetId<Runtime>, Blake2_128Concat>(
734
1
                pallet_prefix,
735
1
                foreign_asset_to_asset_id_prefix,
736
1
            )
737
1
            .drain()
738
1
            .collect();
739
1

            
740
1
        let migrated_count = asset_id_to_foreign_asset_data
741
1
            .len()
742
1
            .saturating_add(foreign_asset_to_asset_id_data.len());
743
1

            
744
1
        log::info!("Migrating {:?} elements", migrated_count);
745

            
746
        // Write to the new storage with removed and added fields
747
3
        for (asset_id, old_location) in asset_id_to_foreign_asset_data {
748
2
            if let Ok(new_location) = Runtime::ForeignAsset::try_from(old_location) {
749
2
                AssetIdToForeignAsset::<Runtime>::insert(asset_id, new_location);
750
2
            } else {
751
                log::warn!("Location could not be converted safely to xcmV4")
752
            }
753
        }
754

            
755
3
        for (old_location, asset_id) in foreign_asset_to_asset_id_data {
756
2
            if let Ok(new_location) = Runtime::ForeignAsset::try_from(old_location) {
757
2
                ForeignAssetToAssetId::<Runtime>::insert(new_location, asset_id);
758
2
            } else {
759
                log::warn!("Location could not be converted safely to xcmV4")
760
            }
761
        }
762

            
763
        // One db read and one db write per element, plus the on-chain storage
764
1
        Runtime::DbWeight::get().reads_writes(migrated_count as u64, 2 * migrated_count as u64)
765
1
    }
766

            
767
    #[cfg(feature = "try-runtime")]
768
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
769
        Ok(vec![])
770
    }
771

            
772
    #[cfg(feature = "try-runtime")]
773
    fn post_upgrade(&self, _state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
774
        Ok(())
775
    }
776
}
777

            
778
pub struct FlashboxMigrations<Runtime>(PhantomData<Runtime>);
779

            
780
impl<Runtime> GetMigrations for FlashboxMigrations<Runtime>
781
where
782
    Runtime: pallet_balances::Config,
783
    Runtime: pallet_configuration::Config,
784
    Runtime: pallet_registrar::Config,
785
    Runtime: pallet_data_preservers::Config,
786
    Runtime: pallet_services_payment::Config,
787
    Runtime: pallet_data_preservers::Config,
788
    Runtime::AccountId: From<[u8; 32]>,
789
    <Runtime as pallet_balances::Config>::RuntimeHoldReason: From<pallet_registrar::HoldReason>,
790
    <Runtime as pallet_balances::Config>::Balance: From<<<Runtime as pallet_registrar::Config>::Currency as frame_support::traits::fungible::Inspect<Runtime::AccountId>>::Balance>,
791
    <Runtime as pallet_balances::Config>::Balance: From<u128>,
792
{
793
1
    fn get_migrations() -> Vec<Box<dyn Migration>> {
794
1
        //let migrate_services_payment =
795
1
        //    MigrateServicesPaymentAddCredits::<Runtime>(Default::default());
796
1
        //let migrate_boot_nodes = MigrateBootNodes::<Runtime>(Default::default());
797
1
        let migrate_config_parathread_params =
798
1
            MigrateConfigurationParathreads::<Runtime>(Default::default());
799
1

            
800
1
        let migrate_add_collator_assignment_credits =
801
1
            MigrateServicesPaymentAddCollatorAssignmentCredits::<Runtime>(Default::default());
802
1
        let migrate_registrar_pending_verification =
803
1
            RegistrarPendingVerificationValueToMap::<Runtime>(Default::default());
804
1
        let migrate_registrar_manager =
805
1
            RegistrarParaManagerMigration::<Runtime>(Default::default());
806
1
        let migrate_data_preservers_assignments =
807
1
            DataPreserversAssignmentsMigration::<Runtime>(Default::default());
808
1
        let migrate_registrar_reserves = RegistrarReserveToHoldMigration::<Runtime>(Default::default());
809
1

            
810
1
        vec![
811
1
            // Applied in runtime 400
812
1
            //Box::new(migrate_services_payment),
813
1
            // Applied in runtime 400
814
1
            //Box::new(migrate_boot_nodes),
815
1
            // Applied in runtime 400
816
1
            Box::new(migrate_config_parathread_params),
817
1
            Box::new(migrate_add_collator_assignment_credits),
818
1
            Box::new(migrate_registrar_pending_verification),
819
1
            Box::new(migrate_registrar_manager),
820
1
            Box::new(migrate_data_preservers_assignments),
821
1
            Box::new(migrate_registrar_reserves),
822
1
        ]
823
1
    }
824
}
825

            
826
pub struct DanceboxMigrations<Runtime>(PhantomData<Runtime>);
827

            
828
impl<Runtime> GetMigrations for DanceboxMigrations<Runtime>
829
where
830
    Runtime: pallet_pooled_staking::Config,
831
    Runtime: pallet_registrar::Config,
832
    Runtime: pallet_balances::Config,
833
    Runtime: pallet_configuration::Config,
834
    Runtime: pallet_services_payment::Config,
835
    Runtime: cumulus_pallet_xcmp_queue::Config,
836
    Runtime: pallet_data_preservers::Config,
837
    Runtime: pallet_xcm::Config,
838
    <Runtime as pallet_balances::Config>::RuntimeHoldReason:
839
        From<pallet_pooled_staking::HoldReason>,
840
    Runtime: pallet_foreign_asset_creator::Config,
841
    <Runtime as pallet_foreign_asset_creator::Config>::ForeignAsset:
842
        TryFrom<staging_xcm::v3::MultiLocation>,
843
    <Runtime as pallet_balances::Config>::RuntimeHoldReason:
844
        From<pallet_registrar::HoldReason>,
845
    Runtime::AccountId: From<[u8; 32]>,
846
    <Runtime as pallet_balances::Config>::Balance: From<<<Runtime as pallet_registrar::Config>::Currency as frame_support::traits::fungible::Inspect<Runtime::AccountId>>::Balance>,
847
    <Runtime as pallet_balances::Config>::Balance: From<u128>,
848
{
849
1
    fn get_migrations() -> Vec<Box<dyn Migration>> {
850
1
        // let migrate_invulnerables = MigrateInvulnerables::<Runtime>(Default::default());
851
1
        // let migrate_holds = MigrateHoldReason::<Runtime>(Default::default());
852
1
        // let migrate_config = MigrateConfigurationFullRotationPeriod::<Runtime>(Default::default());
853
1
        // let migrate_xcm = PolkadotXcmMigration::<Runtime>(Default::default());
854
1
        // let migrate_xcmp_queue = XcmpQueueMigration::<Runtime>(Default::default());
855
1
        // let migrate_services_payment =
856
1
        //     MigrateServicesPaymentAddCredits::<Runtime>(Default::default());
857
1
        // let migrate_boot_nodes = MigrateBootNodes::<Runtime>(Default::default());
858
1
        // let migrate_hold_reason_runtime_enum =
859
1
        //     MigrateHoldReasonRuntimeEnum::<Runtime>(Default::default());
860
1

            
861
1
        let migrate_config_parathread_params =
862
1
            MigrateConfigurationParathreads::<Runtime>(Default::default());
863
1
        let migrate_add_collator_assignment_credits =
864
1
            MigrateServicesPaymentAddCollatorAssignmentCredits::<Runtime>(Default::default());
865
1
        let migrate_xcmp_queue_v4 = XcmpQueueMigrationV4::<Runtime>(Default::default());
866
1
        let migrate_registrar_pending_verification =
867
1
            RegistrarPendingVerificationValueToMap::<Runtime>(Default::default());
868
1
        let migrate_registrar_manager =
869
1
            RegistrarParaManagerMigration::<Runtime>(Default::default());
870
1
        let migrate_data_preservers_assignments =
871
1
            DataPreserversAssignmentsMigration::<Runtime>(Default::default());
872
1

            
873
1
        let migrate_pallet_xcm_v4 = MigrateToLatestXcmVersion::<Runtime>(Default::default());
874
1
        let foreign_asset_creator_migration =
875
1
            ForeignAssetCreatorMigration::<Runtime>(Default::default());
876
1
        let migrate_registrar_reserves = RegistrarReserveToHoldMigration::<Runtime>(Default::default());
877
1

            
878
1
        vec![
879
1
            // Applied in runtime 200
880
1
            //Box::new(migrate_invulnerables),
881
1
            // Applied in runtime 200
882
1
            //Box::new(migrate_holds),
883
1
            // Applied in runtime 300
884
1
            //Box::new(migrate_config),
885
1
            // Applied in runtime 300
886
1
            //Box::new(migrate_xcm),
887
1
            // Applied in runtime 300
888
1
            //Box::new(migrate_xcmp_queue),
889
1
            // Applied in runtime 400
890
1
            //Box::new(migrate_services_payment),
891
1
            // Applied in runtime 400
892
1
            //Box::new(migrate_hold_reason_runtime_enum),
893
1
            // Applied in runtime 400
894
1
            //Box::new(migrate_boot_nodes),
895
1
            Box::new(migrate_config_parathread_params),
896
1
            Box::new(migrate_add_collator_assignment_credits),
897
1
            Box::new(migrate_xcmp_queue_v4),
898
1
            Box::new(migrate_registrar_pending_verification),
899
1
            Box::new(migrate_registrar_manager),
900
1
            Box::new(migrate_pallet_xcm_v4),
901
1
            Box::new(foreign_asset_creator_migration),
902
1
            Box::new(migrate_data_preservers_assignments),
903
1
            Box::new(migrate_registrar_reserves)
904
1
        ]
905
1
    }
906
}
907

            
908
pub struct StarlightMigrations<Runtime>(PhantomData<Runtime>);
909

            
910
impl<Runtime> GetMigrations for StarlightMigrations<Runtime> {
911
1
    fn get_migrations() -> Vec<Box<dyn Migration>> {
912
1
        vec![]
913
1
    }
914
}