referrerpolicy=no-referrer-when-downgrade

polkadot_runtime_parachains/disputes/
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
17//! Storage migration(s) related to disputes pallet
18
19use frame_support::traits::StorageVersion;
20
21pub mod v1 {
22	use super::*;
23	use crate::disputes::{Config, Pallet};
24	use alloc::vec::Vec;
25	use frame_support::{
26		pallet_prelude::*, storage_alias, traits::OnRuntimeUpgrade, weights::Weight,
27	};
28	use polkadot_primitives::SessionIndex;
29
30	#[storage_alias]
31	type SpamSlots<T: Config> = StorageMap<Pallet<T>, Twox64Concat, SessionIndex, Vec<u32>>;
32
33	pub struct MigrateToV1<T>(core::marker::PhantomData<T>);
34	impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> {
35		fn on_runtime_upgrade() -> Weight {
36			let mut weight: Weight = Weight::zero();
37
38			if StorageVersion::get::<Pallet<T>>() < 1 {
39				log::info!(target: crate::disputes::LOG_TARGET, "Migrating disputes storage to v1");
40				weight += migrate_to_v1::<T>();
41				StorageVersion::new(1).put::<Pallet<T>>();
42				weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1));
43			} else {
44				log::info!(
45					target: crate::disputes::LOG_TARGET,
46					"Disputes storage up to date - no need for migration"
47				);
48			}
49
50			weight
51		}
52
53		#[cfg(feature = "try-runtime")]
54		fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
55			log::trace!(
56				target: crate::disputes::LOG_TARGET,
57				"SpamSlots before migration: {}",
58				SpamSlots::<T>::iter().count()
59			);
60			ensure!(
61				StorageVersion::get::<Pallet<T>>() == 0,
62				"Storage version should be less than `1` before the migration",
63			);
64			Ok(Vec::new())
65		}
66
67		#[cfg(feature = "try-runtime")]
68		fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
69			log::trace!(target: crate::disputes::LOG_TARGET, "Running post_upgrade()");
70			ensure!(
71				StorageVersion::get::<Pallet<T>>() >= 1,
72				"Storage version should be `1` after the migration"
73			);
74			ensure!(
75				SpamSlots::<T>::iter().count() == 0,
76				"SpamSlots should be empty after the migration"
77			);
78			Ok(())
79		}
80	}
81
82	/// Migrates the pallet storage to the most recent version, checking and setting the
83	/// `StorageVersion`.
84	pub fn migrate_to_v1<T: Config>() -> Weight {
85		let mut weight: Weight = Weight::zero();
86
87		// SpamSlots should not contain too many keys so removing everything at once should be safe
88		let res = SpamSlots::<T>::clear(u32::MAX, None);
89		// `loops` is the number of iterations => used to calculate read weights
90		// `backend` is the number of keys removed from the backend => used to calculate write
91		// weights
92		weight = weight
93			.saturating_add(T::DbWeight::get().reads_writes(res.loops as u64, res.backend as u64));
94
95		weight
96	}
97}