referrerpolicy=no-referrer-when-downgrade

pallet_grandpa/migrations/
v5.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18use crate::{BoundedAuthorityList, Pallet};
19use alloc::vec::Vec;
20use codec::Decode;
21use core::marker::PhantomData;
22use frame_support::{
23	migrations::VersionedMigration,
24	storage,
25	traits::{Get, UncheckedOnRuntimeUpgrade},
26	weights::Weight,
27};
28use sp_consensus_grandpa::AuthorityList;
29
30const GRANDPA_AUTHORITIES_KEY: &[u8] = b":grandpa_authorities";
31
32fn load_authority_list() -> AuthorityList {
33	storage::unhashed::get_raw(GRANDPA_AUTHORITIES_KEY).map_or_else(
34		|| Vec::new(),
35		|l| <(u8, AuthorityList)>::decode(&mut &l[..]).unwrap_or_default().1,
36	)
37}
38
39/// Actual implementation of [`MigrateV4ToV5`].
40pub struct UncheckedMigrateImpl<T>(PhantomData<T>);
41
42impl<T: crate::Config> UncheckedOnRuntimeUpgrade for UncheckedMigrateImpl<T> {
43	#[cfg(feature = "try-runtime")]
44	fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
45		use codec::Encode;
46
47		let authority_list_len = load_authority_list().len() as u32;
48
49		if authority_list_len > T::MaxAuthorities::get() {
50			return Err(
51				"Grandpa: `Config::MaxAuthorities` is smaller than the actual number of authorities.".into()
52			)
53		}
54
55		if authority_list_len == 0 {
56			return Err("Grandpa: Authority list is empty!".into())
57		}
58
59		Ok(authority_list_len.encode())
60	}
61
62	#[cfg(feature = "try-runtime")]
63	fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
64		let len = u32::decode(&mut &state[..]).unwrap();
65
66		frame_support::ensure!(
67			len == crate::Pallet::<T>::grandpa_authorities().len() as u32,
68			"Grandpa: pre-migrated and post-migrated list should have the same length"
69		);
70
71		frame_support::ensure!(
72			load_authority_list().is_empty(),
73			"Old authority list shouldn't exist anymore"
74		);
75
76		Ok(())
77	}
78
79	fn on_runtime_upgrade() -> Weight {
80		crate::Authorities::<T>::put(
81			&BoundedAuthorityList::<T::MaxAuthorities>::force_from(
82				load_authority_list(),
83				Some("Grandpa: `Config::MaxAuthorities` is smaller than the actual number of authorities.")
84			)
85		);
86
87		storage::unhashed::kill(GRANDPA_AUTHORITIES_KEY);
88
89		T::DbWeight::get().reads_writes(1, 2)
90	}
91}
92
93/// Migrate the storage from V4 to V5.
94///
95/// Switches from `GRANDPA_AUTHORITIES_KEY` to a normal FRAME storage item.
96pub type MigrateV4ToV5<T> = VersionedMigration<
97	4,
98	5,
99	UncheckedMigrateImpl<T>,
100	Pallet<T>,
101	<T as frame_system::Config>::DbWeight,
102>;