19
19
20
20
use super :: * ;
21
21
use codec:: { Decode , Encode } ;
22
- use frame_support:: traits:: { Instance , OnRuntimeUpgrade } ;
22
+ use frame_support:: traits:: { Defensive , DefensiveOption , Instance , OnRuntimeUpgrade } ;
23
23
24
24
#[ cfg( feature = "try-runtime" ) ]
25
25
use sp_runtime:: TryRuntimeError ;
@@ -28,20 +28,18 @@ use sp_runtime::TryRuntimeError;
28
28
const TARGET : & ' static str = "runtime::society::migration" ;
29
29
30
30
/// This migration moves all the state to v2 of Society.
31
- pub struct MigrateToV2 < T : Config < I > , I : ' static , PastPayouts > (
31
+ pub struct VersionUncheckedMigrateToV2 < T : Config < I > , I : ' static , PastPayouts > (
32
32
sp_std:: marker:: PhantomData < ( T , I , PastPayouts ) > ,
33
33
) ;
34
34
35
35
impl <
36
36
T : Config < I > ,
37
37
I : Instance + ' static ,
38
38
PastPayouts : Get < Vec < ( <T as frame_system:: Config >:: AccountId , BalanceOf < T , I > ) > > ,
39
- > OnRuntimeUpgrade for MigrateToV2 < T , I , PastPayouts >
39
+ > OnRuntimeUpgrade for VersionUncheckedMigrateToV2 < T , I , PastPayouts >
40
40
{
41
41
#[ cfg( feature = "try-runtime" ) ]
42
42
fn pre_upgrade ( ) -> Result < Vec < u8 > , TryRuntimeError > {
43
- ensure ! ( can_migrate:: <T , I >( ) , "pallet_society: already upgraded" ) ;
44
-
45
43
let current = Pallet :: < T , I > :: current_storage_version ( ) ;
46
44
let onchain = Pallet :: < T , I > :: on_chain_storage_version ( ) ;
47
45
ensure ! ( onchain == 0 && current == 2 , "pallet_society: invalid version" ) ;
@@ -50,16 +48,16 @@ impl<
50
48
}
51
49
52
50
fn on_runtime_upgrade ( ) -> Weight {
53
- let current = Pallet :: < T , I > :: current_storage_version ( ) ;
54
51
let onchain = Pallet :: < T , I > :: on_chain_storage_version ( ) ;
55
- if current == 2 && onchain == 0 {
56
- from_original :: < T , I > ( & mut PastPayouts :: get ( ) )
57
- } else {
52
+ if onchain < 2 {
58
53
log:: info!(
59
- "Running migration with current storage version {:?} / onchain {:?}" ,
60
- current ,
54
+ target : TARGET ,
55
+ "Running migration against onchain version {:?}" ,
61
56
onchain
62
57
) ;
58
+ from_original :: < T , I > ( & mut PastPayouts :: get ( ) ) . defensive_unwrap_or ( Weight :: MAX )
59
+ } else {
60
+ log:: warn!( "Unexpected onchain version: {:?} (expected 0)" , onchain) ;
63
61
T :: DbWeight :: get ( ) . reads ( 1 )
64
62
}
65
63
}
95
93
}
96
94
}
97
95
96
+ /// [`VersionUncheckedMigrateToV2`] wrapped in a
97
+ /// [`frame_support::migrations::VersionedRuntimeUpgrade`], ensuring the migration is only performed
98
+ /// when on-chain version is 0.
99
+ #[ cfg( feature = "experimental" ) ]
100
+ pub type VersionCheckedMigrateToV2 < T , I , PastPayouts > =
101
+ frame_support:: migrations:: VersionedRuntimeUpgrade <
102
+ 0 ,
103
+ 2 ,
104
+ VersionUncheckedMigrateToV2 < T , I , PastPayouts > ,
105
+ crate :: pallet:: Pallet < T , I > ,
106
+ <T as frame_system:: Config >:: DbWeight ,
107
+ > ;
108
+
98
109
pub ( crate ) mod old {
99
110
use super :: * ;
100
111
use frame_support:: storage_alias;
@@ -180,10 +191,6 @@ pub(crate) mod old {
180
191
StorageMap < Pallet < T , I > , Twox64Concat , <T as frame_system:: Config >:: AccountId , Vote > ;
181
192
}
182
193
183
- pub fn can_migrate < T : Config < I > , I : Instance + ' static > ( ) -> bool {
184
- old:: Members :: < T , I > :: exists ( )
185
- }
186
-
187
194
/// Will panic if there are any inconsistencies in the pallet's state or old keys remaining.
188
195
pub fn assert_internal_consistency < T : Config < I > , I : Instance + ' static > ( ) {
189
196
// Check all members are valid data.
@@ -235,15 +242,7 @@ pub fn assert_internal_consistency<T: Config<I>, I: Instance + 'static>() {
235
242
236
243
pub fn from_original < T : Config < I > , I : Instance + ' static > (
237
244
past_payouts : & mut [ ( <T as frame_system:: Config >:: AccountId , BalanceOf < T , I > ) ] ,
238
- ) -> Weight {
239
- // First check that this is the original state layout. This is easy since the original layout
240
- // contained the Members value, and this value no longer exists in the new layout.
241
- if !old:: Members :: < T , I > :: exists ( ) {
242
- log:: warn!( target: TARGET , "Skipping MigrateToV2 migration since it appears unapplicable" ) ;
243
- // Already migrated or no data to migrate: Bail.
244
- return T :: DbWeight :: get ( ) . reads ( 1 )
245
- }
246
-
245
+ ) -> Result < Weight , & ' static str > {
247
246
// Migrate Bids from old::Bids (just a trunctation).
248
247
Bids :: < T , I > :: put ( BoundedVec :: < _ , T :: MaxBids > :: truncate_from ( old:: Bids :: < T , I > :: take ( ) ) ) ;
249
248
@@ -281,6 +280,36 @@ pub fn from_original<T: Config<I>, I: Instance + 'static>(
281
280
let record = MemberRecord { index : member_count, rank : 0 , strikes, vouching } ;
282
281
Members :: < T , I > :: insert ( & member, record) ;
283
282
MemberByIndex :: < T , I > :: insert ( member_count, & member) ;
283
+
284
+ // The founder must be the first member in Society V2. If we find the founder not in index
285
+ // zero, we swap it with the first member.
286
+ if member == Founder :: < T , I > :: get ( ) . defensive_ok_or ( "founder must always be set" ) ? &&
287
+ member_count > 0
288
+ {
289
+ let member_to_swap = MemberByIndex :: < T , I > :: get ( 0 )
290
+ . defensive_ok_or ( "member_count > 0, we must have at least 1 member" ) ?;
291
+ // Swap the founder with the first member in MemberByIndex.
292
+ MemberByIndex :: < T , I > :: swap ( 0 , member_count) ;
293
+ // Update the indicies of the swapped member MemberRecords.
294
+ Members :: < T , I > :: mutate ( & member, |m| {
295
+ if let Some ( member) = m {
296
+ member. index = 0 ;
297
+ } else {
298
+ frame_support:: defensive!(
299
+ "Member somehow disapeared from storage after it was inserted"
300
+ ) ;
301
+ }
302
+ } ) ;
303
+ Members :: < T , I > :: mutate ( & member_to_swap, |m| {
304
+ if let Some ( member) = m {
305
+ member. index = member_count;
306
+ } else {
307
+ frame_support:: defensive!(
308
+ "Member somehow disapeared from storage after it was queried"
309
+ ) ;
310
+ }
311
+ } ) ;
312
+ }
284
313
member_count. saturating_inc ( ) ;
285
314
}
286
315
MemberCount :: < T , I > :: put ( member_count) ;
@@ -317,7 +346,7 @@ pub fn from_original<T: Config<I>, I: Instance + 'static>(
317
346
old:: Defender :: < T , I > :: kill ( ) ;
318
347
let _ = old:: DefenderVotes :: < T , I > :: clear ( u32:: MAX , None ) ;
319
348
320
- T :: BlockWeights :: get ( ) . max_block
349
+ Ok ( T :: BlockWeights :: get ( ) . max_block )
321
350
}
322
351
323
352
pub fn from_raw_past_payouts < T : Config < I > , I : Instance + ' static > (
0 commit comments