66#[ cfg( feature = "std" ) ]
77include ! ( concat!( env!( "OUT_DIR" ) , "/wasm_binary.rs" ) ) ;
88
9- use codec:: Encode ;
9+ use codec:: { Decode , Encode } ;
1010
1111use pallet_commitments:: CanCommit ;
1212use 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 ;
@@ -263,7 +266,7 @@ pub const EXISTENTIAL_DEPOSIT: u64 = 500;
263266
264267impl pallet_balances:: Config for Runtime {
265268 type MaxLocks = ConstU32 < 50 > ;
266- type MaxReserves = ( ) ;
269+ type MaxReserves = ConstU32 < 50 > ;
267270 type ReserveIdentifier = [ u8 ; 8 ] ;
268271 // The type for recording an account's balance.
269272 type Balance = Balance ;
@@ -274,10 +277,10 @@ impl pallet_balances::Config for Runtime {
274277 type AccountStore = System ;
275278 type WeightInfo = pallet_balances:: weights:: SubstrateWeight < Runtime > ;
276279
277- type RuntimeHoldReason = ( ) ;
278- type FreezeIdentifier = ( ) ;
279- type MaxHolds = ( ) ;
280- type MaxFreezes = ( ) ;
280+ type RuntimeHoldReason = RuntimeHoldReason ;
281+ type FreezeIdentifier = RuntimeFreezeReason ;
282+ type MaxHolds = ConstU32 < 50 > ;
283+ type MaxFreezes = ConstU32 < 50 > ;
281284}
282285
283286pub struct LinearWeightToFee < C > ( sp_std:: marker:: PhantomData < C > ) ;
@@ -1017,6 +1020,119 @@ pub type SignedExtra = (
10171020 pallet_commitments:: CommitmentsSignedExtension < Runtime > ,
10181021) ;
10191022
1023+ mod account_data_migration {
1024+ use super :: * ;
1025+ use frame_support:: log;
1026+ use pallet_balances:: ExtraFlags ;
1027+
1028+ mod prev {
1029+ use super :: * ;
1030+ use frame_support:: { pallet_prelude:: ValueQuery , storage_alias, Blake2_128Concat } ;
1031+
1032+ #[ derive( Encode , Decode , Clone , PartialEq , Eq , Default , Debug ) ]
1033+ pub struct AccountData < Balance > {
1034+ pub free : Balance ,
1035+ pub reserved : Balance ,
1036+ pub misc_frozen : Balance ,
1037+ pub fee_frozen : Balance ,
1038+ }
1039+
1040+ #[ storage_alias]
1041+ pub type Account < T : frame_system:: pallet:: Config > = StorageMap <
1042+ frame_system:: pallet:: Pallet < T > ,
1043+ Blake2_128Concat ,
1044+ AccountId ,
1045+ AccountData < Balance > ,
1046+ ValueQuery ,
1047+ > ;
1048+ }
1049+
1050+ const TARGET : & ' static str = "runtime::account_data_migration" ;
1051+ pub struct Migration ;
1052+ impl OnRuntimeUpgrade for Migration {
1053+ /// Save pre-upgrade account ids to check are decodable post-upgrade.
1054+ #[ cfg( feature = "try-runtime" ) ]
1055+ fn pre_upgrade ( ) -> Result < Vec < u8 > , sp_runtime:: TryRuntimeError > {
1056+ let account_ids = prev:: Account :: < Runtime > :: iter_keys ( ) . collect :: < Vec < _ > > ( ) ;
1057+ log:: info!( target: TARGET , "pre-upgrade" ) ;
1058+
1059+ Ok ( account_ids. encode ( ) )
1060+ }
1061+
1062+ /// Ensures post-upgrade that
1063+ /// 1. Number of accounts has not changed.
1064+ /// 2. Each account exists in storage and decodes.
1065+ /// 3. Each account has a provider val >0.
1066+ #[ cfg( feature = "try-runtime" ) ]
1067+ fn post_upgrade ( state : Vec < u8 > ) -> Result < ( ) , sp_runtime:: TryRuntimeError > {
1068+ use frame_support:: ensure;
1069+ log:: info!( target: TARGET , "Running post-upgrade..." ) ;
1070+
1071+ let pre_upgrade_account_ids: Vec < <Runtime as frame_system:: Config >:: AccountId > =
1072+ Decode :: decode ( & mut & state[ ..] ) . expect ( "pre_upgrade provides a valid state; qed" ) ;
1073+
1074+ // Ensure number of accounts has not changed.
1075+ let account_ids = prev:: Account :: < Runtime > :: iter_keys ( ) . collect :: < Vec < _ > > ( ) ;
1076+ ensure ! (
1077+ pre_upgrade_account_ids. len( ) == account_ids. len( ) ,
1078+ "number of accounts has changed"
1079+ ) ;
1080+
1081+ for acc in account_ids {
1082+ // Ensure account exists in storage and decodes.
1083+ ensure ! (
1084+ frame_system:: pallet:: Account :: <Runtime >:: try_get( & acc) . is_ok( ) ,
1085+ "account not found"
1086+ ) ;
1087+
1088+ // Ensure account provider is >0.
1089+ ensure ! (
1090+ frame_system:: Pallet :: <Runtime >:: providers( & acc) > 0 ,
1091+ "provider == 0"
1092+ ) ;
1093+ }
1094+
1095+ log:: info!( target: TARGET , "post-upgrade success ✅" ) ;
1096+ Ok ( ( ) )
1097+ }
1098+
1099+ /// Migrates AccountData storage to the new format, bumping providers where required.
1100+ fn on_runtime_upgrade ( ) -> Weight {
1101+ // Pull the storage in the previous format into memory
1102+ let accounts = prev:: Account :: < Runtime > :: iter ( ) . collect :: < Vec < _ > > ( ) ;
1103+ log:: info!( target: TARGET , "Migrating {} accounts..." , accounts. len( ) ) ;
1104+
1105+ for ( acc, data) in accounts. clone ( ) . into_iter ( ) {
1106+ // Move account to new data format
1107+ let new_data = pallet_balances:: AccountData {
1108+ free : data. free ,
1109+ reserved : data. reserved ,
1110+ frozen : data. misc_frozen . saturating_add ( data. fee_frozen ) ,
1111+ flags : ExtraFlags :: old_logic ( ) ,
1112+ } ;
1113+ frame_system:: pallet:: Account :: < Runtime > :: mutate ( acc. clone ( ) , |a| {
1114+ a. data = new_data;
1115+ } ) ;
1116+
1117+ // Ensure provider
1118+ if frame_system:: Pallet :: < Runtime > :: providers ( & acc) == 0 {
1119+ frame_system:: Pallet :: < Runtime > :: inc_providers ( & acc) ;
1120+ }
1121+
1122+ // Ensure upgraded
1123+ pallet_balances:: Pallet :: < Runtime , ( ) > :: ensure_upgraded ( & acc) ;
1124+ }
1125+
1126+ log:: info!( target: TARGET , "Migrated ✅" ) ;
1127+
1128+ // R/W not important for solo chain.
1129+ return <Runtime as frame_system:: Config >:: DbWeight :: get ( ) . reads_writes ( 0u64 , 0u64 ) ;
1130+ }
1131+ }
1132+ }
1133+
1134+ type Migrations = account_data_migration:: Migration ;
1135+
10201136// Unchecked extrinsic type as expected by this runtime.
10211137pub type UncheckedExtrinsic =
10221138 generic:: UncheckedExtrinsic < Address , RuntimeCall , Signature , SignedExtra > ;
@@ -1029,6 +1145,7 @@ pub type Executive = frame_executive::Executive<
10291145 frame_system:: ChainContext < Runtime > ,
10301146 Runtime ,
10311147 AllPalletsWithSystem ,
1148+ Migrations ,
10321149> ;
10331150
10341151#[ cfg( feature = "runtime-benchmarks" ) ]
0 commit comments