Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Migrate Slot Depositors in Crowdloan Migration #5173

Merged
merged 3 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 66 additions & 4 deletions runtime/common/src/crowdloan/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use super::*;
use frame_support::generate_storage_alias;
use frame_support::{generate_storage_alias, Twox64Concat};

/// Migrations for using fund index to create fund accounts instead of para ID.
pub mod crowdloan_index_migration {
Expand All @@ -29,6 +29,11 @@ pub mod crowdloan_index_migration {
pub fn pre_migrate<T: Config>() -> Result<(), &'static str> {
// `NextTrieIndex` should have a value.
generate_storage_alias!(Crowdloan, NextTrieIndex => Value<FundIndex>);

generate_storage_alias!(
Slots,
Leases<T: Config> => Map<(Twox64Concat, ParaId), Vec<Option<(T::AccountId, BalanceOf<T>)>>>
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
);
let next_index = NextTrieIndex::get().unwrap_or_default();
ensure!(next_index > 0, "Next index is zero, which implies no migration is needed.");

Expand All @@ -38,7 +43,6 @@ pub mod crowdloan_index_migration {
next_index,
);

// Each fund should have some non-zero balance.
for (para_id, fund) in Funds::<T>::iter() {
let old_fund_account = old_fund_account_id::<T>(para_id);
let total_balance = CurrencyOf::<T>::total_balance(&old_fund_account);
Expand All @@ -49,10 +53,29 @@ pub mod crowdloan_index_migration {
para_id, old_fund_account, total_balance, fund.raised
);

// Each fund should have some non-zero balance.
ensure!(
total_balance >= fund.raised,
"Total balance is not equal to the funds raised."
);

let leases = Leases::<T>::get(para_id).unwrap_or_default();
let mut found_lease_deposit = false;
for maybe_deposit in leases.iter() {
if let Some((who, _amount)) = maybe_deposit {
if *who == old_fund_account {
found_lease_deposit = true;
break
}
}
}
if found_lease_deposit {
log::info!(
target: "runtime",
"para_id={:?}, old_fund_account={:?}, leases={:?}",
para_id, old_fund_account, leases,
);
}
}

Ok(())
Expand All @@ -66,6 +89,10 @@ pub mod crowdloan_index_migration {
// First migrate `NextTrieIndex` counter to `NextFundIndex`.
generate_storage_alias!(Crowdloan, NextTrieIndex => Value<FundIndex>);

generate_storage_alias!(
Slots,
Leases<T: Config> => Map<(Twox64Concat, ParaId), Vec<Option<(T::AccountId, BalanceOf<T>)>>>
);
let next_index = NextTrieIndex::take().unwrap_or_default();
NextFundIndex::<T>::set(next_index);

Expand All @@ -78,10 +105,21 @@ pub mod crowdloan_index_migration {

// Funds should only have a free balance and a reserve balance. Both of these are in the
// `Account` storage item, so we just swap them.
let account_info = frame_system::Account::<T>::take(old_fund_account);
frame_system::Account::<T>::insert(new_fund_account, account_info);
let account_info = frame_system::Account::<T>::take(&old_fund_account);
frame_system::Account::<T>::insert(&new_fund_account, account_info);
Copy link
Contributor

@emostov emostov Mar 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to make sure I understand, if this migration runs twice things break; we would overwrite new_fund_account here with some empty info?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but not sure if there is a way around this...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can and should guard the migration by something, either StorageVersion, custom storage, or at the minimum spec_verion


weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 2));

let mut leases = Leases::<T>::get(para_id).unwrap_or_default();
for maybe_deposit in leases.iter_mut() {
if let Some((who, _amount)) = maybe_deposit {
if *who == old_fund_account {
*who = new_fund_account.clone();
}
}
}

Leases::<T>::insert(para_id, leases);
}

weight
Expand All @@ -92,6 +130,11 @@ pub mod crowdloan_index_migration {
generate_storage_alias!(Crowdloan, NextTrieIndex => Value<FundIndex>);
ensure!(NextTrieIndex::get().is_none(), "NextTrieIndex still has a value.");

generate_storage_alias!(
Slots,
Leases<T: Config> => Map<(Twox64Concat, ParaId), Vec<Option<(T::AccountId, BalanceOf<T>)>>>
);

let next_index = NextFundIndex::<T>::get();
log::info!(
target: "runtime",
Expand Down Expand Up @@ -121,6 +164,25 @@ pub mod crowdloan_index_migration {
total_balance >= fund.raised,
"Total balance in new account is different than the funds raised."
);

let leases = Leases::<T>::get(para_id).unwrap_or_default();
let mut new_account_found = false;
for maybe_deposit in leases.iter() {
if let Some((who, _amount)) = maybe_deposit {
if *who == old_fund_account {
panic!("Old fund account found after migration!");
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
} else if *who == new_fund_account {
new_account_found = true;
}
}
}
if new_account_found {
log::info!(
target: "runtime",
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
"para_id={:?}, new_fund_account={:?}, leases={:?}",
para_id, new_fund_account, leases,
);
}
}

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion runtime/kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("kusama"),
impl_name: create_runtime_str!("parity-kusama"),
authoring_version: 2,
spec_version: 9180,
shawntabrizi marked this conversation as resolved.
Show resolved Hide resolved
spec_version: 9181,
impl_version: 0,
#[cfg(not(feature = "disable-runtime-api"))]
apis: RUNTIME_API_VERSIONS,
Expand Down
2 changes: 1 addition & 1 deletion runtime/polkadot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("polkadot"),
impl_name: create_runtime_str!("parity-polkadot"),
authoring_version: 0,
spec_version: 9180,
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
spec_version: 9181,
impl_version: 0,
#[cfg(not(feature = "disable-runtime-api"))]
apis: RUNTIME_API_VERSIONS,
Expand Down