Skip to content

Commit 86b0a85

Browse files
committed
rearrange mod structure
1 parent f461d83 commit 86b0a85

File tree

3 files changed

+161
-162
lines changed

3 files changed

+161
-162
lines changed

runtime/src/migrations.rs

Lines changed: 0 additions & 162 deletions
This file was deleted.
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
use crate::*;
2+
use frame_support::log;
3+
use pallet_balances::ExtraFlags;
4+
5+
mod prev {
6+
use super::*;
7+
use frame_support::{pallet_prelude::ValueQuery, storage_alias, Blake2_128Concat};
8+
9+
#[derive(
10+
Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen,
11+
)]
12+
pub struct AccountDataStruct<Balance> {
13+
pub free: Balance,
14+
pub reserved: Balance,
15+
pub misc_frozen: Balance,
16+
pub fee_frozen: Balance,
17+
}
18+
19+
#[derive(
20+
Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen,
21+
)]
22+
pub struct AccountStruct<Balance> {
23+
pub nonce: u32,
24+
pub consumers: u32,
25+
pub providers: u32,
26+
pub sufficients: u32,
27+
pub data: AccountDataStruct<Balance>,
28+
}
29+
30+
#[storage_alias]
31+
pub type Account<T: frame_system::pallet::Config> = StorageMap<
32+
frame_system::pallet::Pallet<T>,
33+
Blake2_128Concat,
34+
AccountId,
35+
AccountStruct<Balance>,
36+
ValueQuery,
37+
>;
38+
}
39+
40+
const TARGET: &'static str = "runtime::account_data_migration";
41+
pub struct Migration;
42+
impl OnRuntimeUpgrade for Migration {
43+
/// Save pre-upgrade account ids to check are decodable post-upgrade.
44+
#[cfg(feature = "try-runtime")]
45+
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
46+
use sp_std::collections::btree_map::BTreeMap;
47+
log::info!(target: TARGET, "pre-upgrade");
48+
49+
// Save the expected post-migration account state.
50+
let mut expected_account: BTreeMap<
51+
AccountId,
52+
frame_system::AccountInfo<u32, pallet_balances::AccountData<Balance>>,
53+
> = BTreeMap::new();
54+
55+
for (acc_id, acc) in prev::Account::<Runtime>::iter() {
56+
let expected_data = pallet_balances::AccountData {
57+
free: acc.data.free,
58+
reserved: acc.data.reserved,
59+
frozen: acc.data.misc_frozen.saturating_add(acc.data.fee_frozen),
60+
flags: ExtraFlags::default(),
61+
};
62+
63+
// `ensure_upgraded` bumps the consumers if there is a non zero reserved balance and no frozen balance.
64+
// https://github.com/paritytech/polkadot-sdk/blob/305d311d5c732fcc4629f3295768f1ed44ef434c/substrate/frame/balances/src/lib.rs#L785
65+
let expected_consumers = if acc.data.reserved > 0 && expected_data.frozen == 0 {
66+
acc.consumers + 1
67+
} else {
68+
acc.consumers
69+
};
70+
let expected_acc = frame_system::AccountInfo {
71+
nonce: acc.nonce,
72+
consumers: expected_consumers,
73+
providers: acc.providers,
74+
sufficients: acc.sufficients,
75+
data: expected_data,
76+
};
77+
expected_account.insert(acc_id, expected_acc);
78+
}
79+
80+
Ok(expected_account.encode())
81+
}
82+
83+
/// Migrates Account storage to the new format, and calls `ensure_upgraded` for them.
84+
fn on_runtime_upgrade() -> Weight {
85+
// Pull the storage in the previous format into memory
86+
let accounts = prev::Account::<Runtime>::iter().collect::<Vec<_>>();
87+
log::info!(target: TARGET, "Migrating {} accounts...", accounts.len());
88+
89+
for (acc_id, acc_info) in accounts.clone().into_iter() {
90+
let prev_data = acc_info.clone().data;
91+
92+
// Move account to new data format
93+
let new_data = pallet_balances::AccountData {
94+
free: prev_data.free,
95+
reserved: prev_data.reserved,
96+
frozen: prev_data.misc_frozen.saturating_add(prev_data.fee_frozen),
97+
flags: ExtraFlags::old_logic(),
98+
};
99+
let new_account = frame_system::AccountInfo {
100+
nonce: acc_info.nonce,
101+
consumers: acc_info.consumers,
102+
providers: acc_info.providers,
103+
sufficients: acc_info.sufficients,
104+
data: new_data,
105+
};
106+
frame_system::pallet::Account::<Runtime>::insert(acc_id.clone(), new_account);
107+
108+
// Ensure upgraded
109+
pallet_balances::Pallet::<Runtime, ()>::ensure_upgraded(&acc_id);
110+
}
111+
112+
log::info!(target: TARGET, "Migrated {} accounts ✅", accounts.len());
113+
114+
// R/W not important for solo chain.
115+
<Runtime as frame_system::Config>::DbWeight::get().reads_writes(0u64, 0u64)
116+
}
117+
118+
/// Ensures post-upgrade that every Account entry matches what is expected.
119+
#[cfg(feature = "try-runtime")]
120+
fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
121+
use frame_support::ensure;
122+
use sp_std::collections::btree_map::BTreeMap;
123+
124+
log::info!(target: TARGET, "Running post-upgrade...");
125+
126+
let expected_accounts: BTreeMap<
127+
AccountId,
128+
frame_system::AccountInfo<u32, pallet_balances::AccountData<Balance>>,
129+
> = Decode::decode(&mut &state[..]).expect("decoding state failed");
130+
131+
// Ensure the actual post-migration state matches the expected
132+
for (acc_id, acc) in frame_system::pallet::Account::<Runtime>::iter() {
133+
let expected = expected_accounts.get(&acc_id).expect("account not found");
134+
135+
// New system logic nukes the account if no providers or sufficients.
136+
if acc.providers > 0 || acc.sufficients > 0 {
137+
ensure!(acc.nonce == expected.nonce, "nonce mismatch");
138+
ensure!(acc.consumers == expected.consumers, "consumers mismatch");
139+
ensure!(acc.providers == expected.providers, "providers mismatch");
140+
ensure!(
141+
acc.sufficients == expected.sufficients,
142+
"sufficients mismatch"
143+
);
144+
ensure!(acc.data.free == expected.data.free, "data.free mismatch");
145+
ensure!(
146+
acc.data.reserved == expected.data.reserved,
147+
"data.reserved mismatch"
148+
);
149+
ensure!(
150+
acc.data.frozen == expected.data.frozen,
151+
"data.frozen mismatch"
152+
);
153+
ensure!(acc.data.flags == expected.data.flags, "data.flags mismatch");
154+
}
155+
}
156+
157+
log::info!(target: TARGET, "post-upgrade success ✅");
158+
Ok(())
159+
}
160+
}

runtime/src/migrations/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod account_data_migration;

0 commit comments

Comments
 (0)