pallet_dapp_staking/
migration.rs

1// This file is part of Astar.
2
3// Copyright (C) Stake Technologies Pte.Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6// Astar is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// Astar is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with Astar. If not, see <http://www.gnu.org/licenses/>.
18
19use super::*;
20use core::marker::PhantomData;
21use frame_support::traits::UncheckedOnRuntimeUpgrade;
22
23#[cfg(feature = "try-runtime")]
24mod try_runtime_imports {
25    pub use sp_runtime::TryRuntimeError;
26}
27
28#[cfg(feature = "try-runtime")]
29use try_runtime_imports::*;
30
31/// Exports for versioned migration `type`s for this pallet.
32pub mod versioned_migrations {
33    use super::*;
34
35    /// Migration V11 to V12:
36    /// - Migrate `StaticTierParams` to remove `slot_number_args` and `DynamicPercentage`
37    pub type V11ToV12<T> = frame_support::migrations::VersionedMigration<
38        11,
39        12,
40        v12::VersionMigrateV11ToV12<T>,
41        Pallet<T>,
42        <T as frame_system::Config>::DbWeight,
43    >;
44}
45
46mod v12 {
47    use super::*;
48
49    /// Old `TierThreshold` enum that includes the removed `DynamicPercentage` variant.
50    #[derive(Encode, Decode, Clone)]
51    pub enum OldTierThreshold {
52        FixedPercentage {
53            required_percentage: Perbill,
54        },
55        DynamicPercentage {
56            percentage: Perbill,
57            minimum_required_percentage: Perbill,
58            maximum_possible_percentage: Perbill,
59        },
60    }
61
62    /// Old `TierParameters` shape (with `slot_number_args` field).
63    #[derive(Encode, Decode, Clone)]
64    pub struct OldTierParameters<NT: Get<u32>> {
65        pub reward_portion: BoundedVec<Permill, NT>,
66        pub slot_distribution: BoundedVec<Permill, NT>,
67        pub tier_thresholds: BoundedVec<OldTierThreshold, NT>,
68        pub slot_number_args: (u64, u64),
69        pub tier_rank_multipliers: BoundedVec<u32, NT>,
70    }
71
72    pub struct VersionMigrateV11ToV12<T>(PhantomData<T>);
73
74    impl<T: Config> UncheckedOnRuntimeUpgrade for VersionMigrateV11ToV12<T> {
75        fn on_runtime_upgrade() -> Weight {
76            let mut reads: u64 = 0;
77            let mut writes: u64 = 0;
78
79            // Migrate StaticTierParams to new shape (remove slot_number_args, convert DynamicPercentage)
80            reads += 1;
81            let result = StaticTierParams::<T>::translate::<OldTierParameters<T::NumberOfTiers>, _>(
82                |maybe_old_params| match maybe_old_params {
83                    Some(old_params) => {
84                        let new_tier_thresholds: Vec<TierThreshold> = old_params
85                            .tier_thresholds
86                            .iter()
87                            .map(|t| match t {
88                                OldTierThreshold::FixedPercentage {
89                                    required_percentage,
90                                } => TierThreshold::FixedPercentage {
91                                    required_percentage: *required_percentage,
92                                },
93                                OldTierThreshold::DynamicPercentage { percentage, .. } => {
94                                    TierThreshold::FixedPercentage {
95                                        required_percentage: *percentage,
96                                    }
97                                }
98                            })
99                            .collect();
100
101                        Some(TierParameters {
102                            reward_portion: old_params.reward_portion,
103                            slot_distribution: old_params.slot_distribution,
104                            tier_thresholds: BoundedVec::truncate_from(new_tier_thresholds),
105                            tier_rank_multipliers: old_params.tier_rank_multipliers,
106                        })
107                    }
108                    None => None,
109                },
110            );
111
112            if result.is_err() {
113                log::error!(
114                    target: LOG_TARGET,
115                    "Failed to translate StaticTierParams from old type to new v12 type. \
116                     Enabling maintenance mode."
117                );
118                ActiveProtocolState::<T>::mutate(|state| {
119                    state.maintenance = true;
120                });
121                reads += 1;
122                writes += 1;
123            } else {
124                writes += 1;
125                log::info!(
126                    target: LOG_TARGET,
127                    "StaticTierParams migrated to v12 successfully"
128                );
129            }
130
131            T::DbWeight::get().reads_writes(reads, writes)
132        }
133
134        #[cfg(feature = "try-runtime")]
135        fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
136            log::info!(target: LOG_TARGET, "V11ToV12 pre-upgrade: checking state");
137            Ok(Vec::new())
138        }
139
140        #[cfg(feature = "try-runtime")]
141        fn post_upgrade(_data: Vec<u8>) -> Result<(), TryRuntimeError> {
142            // Verify storage version
143            ensure!(
144                Pallet::<T>::on_chain_storage_version() == StorageVersion::new(12),
145                "Storage version should be 12"
146            );
147
148            // Verify StaticTierParams can be decoded with new type
149            let params = StaticTierParams::<T>::get();
150            ensure!(
151                params.is_valid(),
152                "StaticTierParams invalid after migration"
153            );
154
155            Ok(())
156        }
157    }
158}