pallet_elections_phragmen/migrations/
v3.rs1use super::super::LOG_TARGET;
21use crate::{Config, Pallet};
22use alloc::vec::Vec;
23use codec::{Decode, Encode, FullCodec};
24use frame_support::{
25 pallet_prelude::ValueQuery, traits::StorageVersion, weights::Weight, Twox64Concat,
26};
27use sp_runtime::RuntimeDebug;
28
29#[derive(Encode, Decode, Clone, Default, RuntimeDebug, PartialEq)]
30struct SeatHolder<AccountId, Balance> {
31 who: AccountId,
32 stake: Balance,
33 deposit: Balance,
34}
35
36#[derive(Encode, Decode, Clone, Default, RuntimeDebug, PartialEq)]
37struct Voter<AccountId, Balance> {
38 votes: Vec<AccountId>,
39 stake: Balance,
40 deposit: Balance,
41}
42
43pub trait V2ToV3 {
45 type AccountId: 'static + FullCodec;
47
48 type Balance: 'static + FullCodec + Copy;
50}
51
52#[frame_support::storage_alias]
53type Candidates<V, T: Config> =
54 StorageValue<Pallet<T>, Vec<(<V as V2ToV3>::AccountId, <V as V2ToV3>::Balance)>, ValueQuery>;
55
56#[frame_support::storage_alias]
57type Members<V, T: Config> = StorageValue<
58 Pallet<T>,
59 Vec<SeatHolder<<V as V2ToV3>::AccountId, <V as V2ToV3>::Balance>>,
60 ValueQuery,
61>;
62
63#[frame_support::storage_alias]
64type RunnersUp<V, T: Config> = StorageValue<
65 Pallet<T>,
66 Vec<SeatHolder<<V as V2ToV3>::AccountId, <V as V2ToV3>::Balance>>,
67 ValueQuery,
68>;
69
70#[frame_support::storage_alias]
71type Voting<V, T: Config> = StorageMap<
72 Pallet<T>,
73 Twox64Concat,
74 <V as V2ToV3>::AccountId,
75 Voter<<V as V2ToV3>::AccountId, <V as V2ToV3>::Balance>,
76>;
77
78pub fn apply<V: V2ToV3, T: Config>(
88 old_voter_bond: V::Balance,
89 old_candidacy_bond: V::Balance,
90) -> Weight {
91 let storage_version = StorageVersion::get::<Pallet<T>>();
92 log::info!(
93 target: LOG_TARGET,
94 "Running migration for elections-phragmen with storage version {:?}",
95 storage_version,
96 );
97
98 if storage_version <= 2 {
99 migrate_voters_to_recorded_deposit::<V, T>(old_voter_bond);
100 migrate_candidates_to_recorded_deposit::<V, T>(old_candidacy_bond);
101 migrate_runners_up_to_recorded_deposit::<V, T>(old_candidacy_bond);
102 migrate_members_to_recorded_deposit::<V, T>(old_candidacy_bond);
103
104 StorageVersion::new(3).put::<Pallet<T>>();
105
106 Weight::MAX
107 } else {
108 log::warn!(
109 target: LOG_TARGET,
110 "Attempted to apply migration to V3 but failed because storage version is {:?}",
111 storage_version,
112 );
113 Weight::zero()
114 }
115}
116
117pub fn migrate_voters_to_recorded_deposit<V: V2ToV3, T: Config>(old_deposit: V::Balance) {
119 Voting::<V, T>::translate::<(V::Balance, Vec<V::AccountId>), _>(|_who, (stake, votes)| {
120 Some(Voter { votes, stake, deposit: old_deposit })
121 });
122
123 log::info!(target: LOG_TARGET, "migrated {} voter accounts.", Voting::<V, T>::iter().count());
124}
125
126pub fn migrate_candidates_to_recorded_deposit<V: V2ToV3, T: Config>(old_deposit: V::Balance) {
128 let _ = Candidates::<V, T>::translate::<Vec<V::AccountId>, _>(|maybe_old_candidates| {
129 maybe_old_candidates.map(|old_candidates| {
130 log::info!(target: LOG_TARGET, "migrated {} candidate accounts.", old_candidates.len());
131 old_candidates.into_iter().map(|c| (c, old_deposit)).collect::<Vec<_>>()
132 })
133 });
134}
135
136pub fn migrate_members_to_recorded_deposit<V: V2ToV3, T: Config>(old_deposit: V::Balance) {
138 let _ = Members::<V, T>::translate::<Vec<(V::AccountId, V::Balance)>, _>(|maybe_old_members| {
139 maybe_old_members.map(|old_members| {
140 log::info!(target: LOG_TARGET, "migrated {} member accounts.", old_members.len());
141 old_members
142 .into_iter()
143 .map(|(who, stake)| SeatHolder { who, stake, deposit: old_deposit })
144 .collect::<Vec<_>>()
145 })
146 });
147}
148
149pub fn migrate_runners_up_to_recorded_deposit<V: V2ToV3, T: Config>(old_deposit: V::Balance) {
151 let _ = RunnersUp::<V, T>::translate::<Vec<(V::AccountId, V::Balance)>, _>(
152 |maybe_old_runners_up| {
153 maybe_old_runners_up.map(|old_runners_up| {
154 log::info!(
155 target: LOG_TARGET,
156 "migrated {} runner-up accounts.",
157 old_runners_up.len(),
158 );
159 old_runners_up
160 .into_iter()
161 .map(|(who, stake)| SeatHolder { who, stake, deposit: old_deposit })
162 .collect::<Vec<_>>()
163 })
164 },
165 );
166}