Skip to content

Commit 3c46699

Browse files
authored
Merge pull request #337 from opentensor/feat/accounts-migration
fix: account data migration
2 parents b310e93 + f3afe83 commit 3c46699

File tree

1 file changed

+127
-6
lines changed

1 file changed

+127
-6
lines changed

runtime/src/lib.rs

Lines changed: 127 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
};
1720
use frame_system::{EnsureNever, EnsureRoot, RawOrigin};
1821

1922
use pallet_registry::CanRegisterIdentity;
@@ -271,7 +274,7 @@ pub const EXISTENTIAL_DEPOSIT: u64 = 500;
271274

272275
impl 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

291294
pub 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.
11481268
pub 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

Comments
 (0)