@@ -13,7 +13,10 @@ use pallet_grandpa::{
1313 fg_primitives, AuthorityId as GrandpaId , AuthorityList as GrandpaAuthorityList ,
1414} ;
1515
16- use frame_support:: pallet_prelude:: { DispatchError , DispatchResult , Get } ;
16+ use frame_support:: {
17+ pallet_prelude:: { DispatchError , DispatchResult , Get } ,
18+ traits:: OnRuntimeUpgrade ,
19+ } ;
1720use frame_system:: { EnsureNever , EnsureRoot , RawOrigin } ;
1821
1922use pallet_registry:: CanRegisterIdentity ;
@@ -271,7 +274,7 @@ pub const EXISTENTIAL_DEPOSIT: u64 = 500;
271274
272275impl pallet_balances:: Config for Runtime {
273276 type MaxLocks = ConstU32 < 50 > ;
274- type MaxReserves = ( ) ;
277+ type MaxReserves = ConstU32 < 50 > ;
275278 type ReserveIdentifier = [ u8 ; 8 ] ;
276279 // The type for recording an account's balance.
277280 type Balance = Balance ;
@@ -282,10 +285,10 @@ impl pallet_balances::Config for Runtime {
282285 type AccountStore = System ;
283286 type WeightInfo = pallet_balances:: weights:: SubstrateWeight < Runtime > ;
284287
285- type RuntimeHoldReason = ( ) ;
286- type FreezeIdentifier = ( ) ;
287- type MaxHolds = ( ) ;
288- type MaxFreezes = ( ) ;
288+ type RuntimeHoldReason = RuntimeHoldReason ;
289+ type FreezeIdentifier = RuntimeFreezeReason ;
290+ type MaxHolds = ConstU32 < 50 > ;
291+ type MaxFreezes = ConstU32 < 50 > ;
289292}
290293
291294pub struct LinearWeightToFee < C > ( sp_std:: marker:: PhantomData < C > ) ;
@@ -1144,6 +1147,123 @@ pub type SignedExtra = (
11441147 pallet_commitments:: CommitmentsSignedExtension < Runtime > ,
11451148) ;
11461149
1150+ mod account_data_migration {
1151+ use super :: * ;
1152+ use frame_support:: log;
1153+ use pallet_balances:: ExtraFlags ;
1154+
1155+ mod prev {
1156+ use super :: * ;
1157+ use frame_support:: { pallet_prelude:: ValueQuery , storage_alias, Blake2_128Concat } ;
1158+
1159+ #[ derive( Encode , Decode , Clone , PartialEq , Eq , Default , Debug ) ]
1160+ pub struct AccountData < Balance > {
1161+ pub free : Balance ,
1162+ pub reserved : Balance ,
1163+ pub misc_frozen : Balance ,
1164+ pub fee_frozen : Balance ,
1165+ }
1166+
1167+ #[ storage_alias]
1168+ pub type Account < T : frame_system:: pallet:: Config > = StorageMap <
1169+ frame_system:: pallet:: Pallet < T > ,
1170+ Blake2_128Concat ,
1171+ AccountId ,
1172+ AccountData < Balance > ,
1173+ ValueQuery ,
1174+ > ;
1175+ }
1176+
1177+ const TARGET : & ' static str = "runtime::account_data_migration" ;
1178+ pub struct Migration ;
1179+ impl OnRuntimeUpgrade for Migration {
1180+ /// Save pre-upgrade account ids to check are decodable post-upgrade.
1181+ #[ cfg( feature = "try-runtime" ) ]
1182+ fn pre_upgrade ( ) -> Result < Vec < u8 > , sp_runtime:: TryRuntimeError > {
1183+ let account_ids = prev:: Account :: < Runtime > :: iter_keys ( ) . collect :: < Vec < _ > > ( ) ;
1184+ log:: info!( target: TARGET , "pre-upgrade" ) ;
1185+
1186+ Ok ( account_ids. encode ( ) )
1187+ }
1188+
1189+ /// Ensures post-upgrade that
1190+ /// 1. Number of accounts has not changed.
1191+ /// 2. Each account exists in storage and decodes.
1192+ /// 3. Each account has a provider val >0.
1193+ #[ cfg( feature = "try-runtime" ) ]
1194+ fn post_upgrade ( state : Vec < u8 > ) -> Result < ( ) , sp_runtime:: TryRuntimeError > {
1195+ use frame_support:: ensure;
1196+ log:: info!( target: TARGET , "Running post-upgrade..." ) ;
1197+
1198+ let pre_upgrade_account_ids: Vec < <Runtime as frame_system:: Config >:: AccountId > =
1199+ Decode :: decode ( & mut & state[ ..] ) . expect ( "pre_upgrade provides a valid state; qed" ) ;
1200+
1201+ // Ensure number of accounts has not changed.
1202+ let account_ids = prev:: Account :: < Runtime > :: iter_keys ( ) . collect :: < Vec < _ > > ( ) ;
1203+ ensure ! (
1204+ pre_upgrade_account_ids. len( ) == account_ids. len( ) ,
1205+ "number of accounts has changed"
1206+ ) ;
1207+
1208+ for acc in account_ids {
1209+ // Ensure account exists in storage and decodes.
1210+ match frame_system:: pallet:: Account :: < Runtime > :: try_get ( & acc) {
1211+ Ok ( d) => {
1212+ ensure ! ( d. data. free > 0 || d. data. reserved > 0 , "account has 0 bal" ) ;
1213+ }
1214+ _ => {
1215+ panic ! ( "account not found" )
1216+ }
1217+ } ;
1218+
1219+ // Ensure account provider is >0.
1220+ ensure ! (
1221+ frame_system:: Pallet :: <Runtime >:: providers( & acc) > 0 ,
1222+ "provider == 0"
1223+ ) ;
1224+ }
1225+
1226+ log:: info!( target: TARGET , "post-upgrade success ✅" ) ;
1227+ Ok ( ( ) )
1228+ }
1229+
1230+ /// Migrates AccountData storage to the new format, bumping providers where required.
1231+ fn on_runtime_upgrade ( ) -> Weight {
1232+ // Pull the storage in the previous format into memory
1233+ let accounts = prev:: Account :: < Runtime > :: iter ( ) . collect :: < Vec < _ > > ( ) ;
1234+ log:: info!( target: TARGET , "Migrating {} accounts..." , accounts. len( ) ) ;
1235+
1236+ for ( acc, data) in accounts. clone ( ) . into_iter ( ) {
1237+ // Move account to new data format
1238+ let new_data = pallet_balances:: AccountData {
1239+ free : data. free ,
1240+ reserved : data. reserved ,
1241+ frozen : data. misc_frozen . saturating_add ( data. fee_frozen ) ,
1242+ flags : ExtraFlags :: old_logic ( ) ,
1243+ } ;
1244+ frame_system:: pallet:: Account :: < Runtime > :: mutate ( acc. clone ( ) , |a| {
1245+ a. data = new_data;
1246+ } ) ;
1247+
1248+ // Ensure provider
1249+ if frame_system:: Pallet :: < Runtime > :: providers ( & acc) == 0 {
1250+ frame_system:: Pallet :: < Runtime > :: inc_providers ( & acc) ;
1251+ }
1252+
1253+ // Ensure upgraded
1254+ pallet_balances:: Pallet :: < Runtime , ( ) > :: ensure_upgraded ( & acc) ;
1255+ }
1256+
1257+ log:: info!( target: TARGET , "Migrated {} accounts ✅" , accounts. len( ) ) ;
1258+
1259+ // R/W not important for solo chain.
1260+ return <Runtime as frame_system:: Config >:: DbWeight :: get ( ) . reads_writes ( 0u64 , 0u64 ) ;
1261+ }
1262+ }
1263+ }
1264+
1265+ type Migrations = account_data_migration:: Migration ;
1266+
11471267// Unchecked extrinsic type as expected by this runtime.
11481268pub type UncheckedExtrinsic =
11491269 generic:: UncheckedExtrinsic < Address , RuntimeCall , Signature , SignedExtra > ;
@@ -1156,6 +1276,7 @@ pub type Executive = frame_executive::Executive<
11561276 frame_system:: ChainContext < Runtime > ,
11571277 Runtime ,
11581278 AllPalletsWithSystem ,
1279+ Migrations ,
11591280> ;
11601281
11611282#[ cfg( feature = "runtime-benchmarks" ) ]
0 commit comments