pallet_session_validator_management/migrations/
v1.rs

1//! Implements storage migration of the `session-validator-management` pallet from v0 to v1.
2#[cfg(feature = "try-runtime")]
3extern crate alloc;
4use frame_support::traits::UncheckedOnRuntimeUpgrade;
5#[cfg(feature = "try-runtime")]
6use {
7	alloc::vec::Vec, parity_scale_codec::Encode, sp_session_validator_management::CommitteeMember,
8};
9
10use super::v0;
11
12/// [VersionedMigration] parametrized for v0 to v1 migration.
13pub type LegacyToV1Migration<T> = frame_support::migrations::VersionedMigration<
14	0, // The migration will only execute when the on-chain storage version is 0
15	1, // The on-chain storage version will be set to 1 after the migration is complete
16	InnerMigrateV0ToV1<T>,
17	crate::pallet::Pallet<T>,
18	<T as frame_system::Config>::DbWeight,
19>;
20
21/// Helper type used internally for migration. Use [LegacyToV1Migration] in your runtime instead.
22pub struct InnerMigrateV0ToV1<T: crate::Config>(core::marker::PhantomData<T>);
23
24impl<T: crate::pallet::Config> UncheckedOnRuntimeUpgrade for InnerMigrateV0ToV1<T>
25where
26	T::CommitteeMember: From<(T::AuthorityId, T::AuthorityKeys)>,
27{
28	fn on_runtime_upgrade() -> sp_runtime::Weight {
29		use sp_core::Get;
30		use sp_runtime::BoundedVec;
31
32		let current_committee_v0 = v0::CurrentCommittee::<T>::get();
33		let current_committee_v1 = crate::pallet::CommitteeInfo::<
34			T::ScEpochNumber,
35			T::CommitteeMember,
36			T::MaxValidators,
37		> {
38			epoch: current_committee_v0.epoch,
39			committee: BoundedVec::truncate_from(
40				current_committee_v0.committee.into_iter().map(From::from).collect(),
41			),
42		};
43
44		crate::CurrentCommittee::<T>::put(current_committee_v1);
45
46		let Some(next_committee_v0) = v0::NextCommittee::<T>::get() else {
47			return T::DbWeight::get().reads_writes(2, 1);
48		};
49		let next_committee_v1 = crate::pallet::CommitteeInfo::<
50			T::ScEpochNumber,
51			T::CommitteeMember,
52			T::MaxValidators,
53		> {
54			epoch: next_committee_v0.epoch,
55			committee: BoundedVec::truncate_from(
56				next_committee_v0.committee.into_iter().map(From::from).collect(),
57			),
58		};
59
60		crate::NextCommittee::<T>::put(next_committee_v1);
61
62		T::DbWeight::get().reads_writes(2, 2)
63	}
64
65	#[cfg(feature = "try-runtime")]
66	fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
67		let current_committee_v0 = v0::CurrentCommittee::<T>::get();
68		let next_committee_v0 = v0::NextCommittee::<T>::get();
69		Ok((current_committee_v0, next_committee_v0).encode())
70	}
71
72	#[cfg(feature = "try-runtime")]
73	fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
74		use frame_support::ensure;
75		use parity_scale_codec::Decode;
76		use v0::LegacyCommitteeInfo;
77
78		let (current_committee_v0, next_committee_v0): (
79			LegacyCommitteeInfo<
80				T::ScEpochNumber,
81				T::AuthorityId,
82				T::AuthorityKeys,
83				T::MaxValidators,
84			>,
85			Option<
86				LegacyCommitteeInfo<
87					T::ScEpochNumber,
88					T::AuthorityId,
89					T::AuthorityKeys,
90					T::MaxValidators,
91				>,
92			>,
93		) = Decode::decode(&mut state.as_slice())
94			.expect("Previously encoded state should be decodable");
95
96		let current_committee_v1 = crate::CurrentCommittee::<T>::get();
97		let next_committee_v1 = crate::NextCommittee::<T>::get();
98
99		ensure!(
100			current_committee_v0.epoch == current_committee_v1.epoch,
101			"current epoch should be preserved"
102		);
103
104		ensure!(
105			current_committee_v0.committee.to_vec()
106				== (current_committee_v1.committee.iter())
107					.map(|member| (member.authority_id(), member.authority_keys()))
108					.collect::<Vec<_>>(),
109			"current committee membership should be preserved"
110		);
111
112		if next_committee_v0.is_none() && next_committee_v0.is_none() {
113			return Ok(());
114		}
115
116		ensure!(next_committee_v0.is_some(), "V0 next committee should be Some if V1 is");
117		ensure!(next_committee_v1.is_some(), "V1 next committee should be Some if V0 is");
118
119		let next_committee_v0 = next_committee_v0.unwrap();
120		let next_committee_v1 = next_committee_v1.unwrap();
121
122		ensure!(
123			next_committee_v0.epoch == next_committee_v1.epoch,
124			"next epoch should be preserved"
125		);
126
127		ensure!(
128			next_committee_v0.committee.to_vec()
129				== (next_committee_v1.committee.iter())
130					.map(|member| (member.authority_id(), member.authority_keys()))
131					.collect::<Vec<_>>(),
132			"next committee membership should be preserved"
133		);
134
135		Ok(())
136	}
137}