referrerpolicy=no-referrer-when-downgrade

cumulus_pallet_xcmp_queue/migration/
v6.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3// SPDX-License-Identifier: Apache-2.0
4
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// 	http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17//! Migrates the storage to version 6.
18
19use crate::*;
20use frame_support::{pallet_prelude::*, traits::UncheckedOnRuntimeUpgrade};
21
22/// [`VersionedMigration`](frame_support::migrations::VersionedMigration), that is performed only
23/// when the on-chain version is 5.
24pub type MigrateV5ToV6<T> = frame_support::migrations::VersionedMigration<
25	5,
26	6,
27	unversioned::UncheckedMigrateV5ToV6<T>,
28	Pallet<T>,
29	<T as frame_system::Config>::DbWeight,
30>;
31
32// V5 storage aliases
33mod v5 {
34	use super::*;
35
36	#[derive(Clone, Eq, PartialEq, Encode, Decode, TypeInfo, Debug, MaxEncodedLen)]
37	pub struct OutboundChannelDetails {
38		/// The `ParaId` of the parachain that this channel is connected with.
39		pub recipient: ParaId,
40		/// The state of the channel.
41		pub state: OutboundState,
42		/// Whether any signals exist in this channel.
43		pub signals_exist: bool,
44		/// The index of the first outbound message.
45		pub first_index: u16,
46		/// The index of the last outbound message.
47		pub last_index: u16,
48	}
49
50	#[frame_support::storage_alias]
51	pub(super) type OutboundXcmpStatus<T: Config> = StorageValue<
52		Pallet<T>,
53		BoundedVec<OutboundChannelDetails, <T as Config>::MaxActiveOutboundChannels>,
54		ValueQuery,
55	>;
56}
57
58mod unversioned {
59	use super::*;
60	pub struct UncheckedMigrateV5ToV6<T: Config>(PhantomData<T>);
61}
62
63impl<T: Config> UncheckedOnRuntimeUpgrade for unversioned::UncheckedMigrateV5ToV6<T> {
64	fn on_runtime_upgrade() -> frame_support::weights::Weight {
65		// We use `Vec` instead of `BoundedVec` for `pre` in order to avoid any decoding error
66		// in case `T::MaxActiveOutboundChannels` is decreased in the same runtime upgrade where
67		// the migration is executed.
68		let translate = |pre: Vec<v5::OutboundChannelDetails>|
69		 -> BoundedVec<OutboundChannelDetails, T::MaxActiveOutboundChannels> {
70			BoundedVec::defensive_truncate_from(
71				pre.iter()
72					.map(|pre_channel_details| OutboundChannelDetails {
73						recipient: pre_channel_details.recipient,
74						state: pre_channel_details.state,
75						signals_exist: pre_channel_details.signals_exist,
76						first_index: pre_channel_details.first_index,
77						last_index: pre_channel_details.last_index,
78						// The new field added by the migration.
79						flags: OutboundChannelFlags::empty(),
80					})
81					.collect(),
82			)
83		};
84
85		if OutboundXcmpStatus::<T>::translate(|pre| pre.map(translate)).is_err() {
86			defensive!(
87				"unexpected error when performing translation of the OutboundXcmpStatus type \
88				during storage upgrade to v6"
89			);
90		}
91
92		// We need to account for the proof size and ref time of reading and writing
93		// `OutboundChannelDetails` once.
94		let proof_size = 2 * BoundedVec::<
95			OutboundChannelDetails,
96			<T as Config>::MaxActiveOutboundChannels,
97		>::max_encoded_len();
98		Weight::from_parts(0, proof_size as u64)
99			.saturating_add(T::DbWeight::get().reads_writes(1, 1))
100	}
101}