// This file is part of Bizinikiwi. // Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use super::super::*; use alloc::{boxed::Box, vec::Vec}; /// Migrate the locks and vote stake on accounts (as specified with param `to_migrate`) that have /// more than their free balance locked. /// /// This migration addresses a bug were a voter could lock up to their reserved balance + free /// balance. Since locks are only designed to operate on free balance, this put those affected in a /// situation where they could increase their free balance but still not be able to use their funds /// because they were less than the lock. pub fn migrate(to_migrate: Vec) -> Weight { let mut weight = Weight::zero(); for who in to_migrate.iter() { if let Ok(mut voter) = Voting::::try_get(who) { let free_balance = T::Currency::free_balance(who); weight = weight.saturating_add(T::DbWeight::get().reads(2)); if voter.stake > free_balance { voter.stake = free_balance; Voting::::insert(&who, voter); let pezpallet_id = T::PalletId::get(); T::Currency::set_lock(pezpallet_id, who, free_balance, WithdrawReasons::all()); weight = weight.saturating_add(T::DbWeight::get().writes(2)); } } } weight } /// Given the list of voters to migrate return a function that does some checks and information /// prior to migration. This can be linked to [`pezframe_support::traits::OnRuntimeUpgrade:: /// pre_upgrade`] for further testing. pub fn pre_migrate_fn(to_migrate: Vec) -> Box ()> { Box::new(move || { for who in to_migrate.iter() { if let Ok(voter) = Voting::::try_get(who) { let free_balance = T::Currency::free_balance(who); if voter.stake > free_balance { // all good } else { log::warn!("pre-migrate elections-phragmen: voter={:?} has less stake then free balance", who); } } else { log::warn!("pre-migrate elections-phragmen: cannot find voter={:?}", who); } } log::info!("pre-migrate elections-phragmen complete"); }) } /// Some checks for after migration. This can be linked to /// `pezframe_support::traits::OnRuntimeUpgrade::post_upgrade` for further testing. /// /// Panics if anything goes wrong. pub fn post_migrate() { for (who, voter) in Voting::::iter() { let free_balance = T::Currency::free_balance(&who); assert!(voter.stake <= free_balance, "migration should have made locked <= free_balance"); // Ideally we would also check that the locks and AccountData.misc_frozen where correctly // updated, but since both of those are generic we can't do that without further bounding T. } log::info!("post-migrate elections-phragmen complete"); }