--- a/pallets/app-promotion/src/lib.rs +++ b/pallets/app-promotion/src/lib.rs @@ -278,10 +278,6 @@ pub type PreviousCalculatedRecord = StorageValue; - // #[pallet::storage] - // pub(crate) type UpgradedToFreezes = - // StorageValue; - #[pallet::hooks] impl Hooks> for Pallet { /// Block overflow is impossible due to the fact that the unstake algorithm in on_initialize @@ -302,6 +298,12 @@ block_pending.into_iter().for_each(|(staker, amount)| { Self::get_frozen_balance(&staker).map(|b| { let new_state = b.checked_sub(&amount).unwrap_or_default(); + + // In this case, setting a new state for the frozen funds cannot fail + // because the state change goes in the direction of decreasing the frozen funds + // and the validity of this transition is ensured by the fact + // that we cannot (in the current implementation) unfreeze more funds + // than were originally frozen by the pallet. Either way, `on_initialize()` cannot fail. Self::set_freeze_unchecked(&staker, new_state); }); }); @@ -309,133 +311,6 @@ ::WeightInfo::on_initialize(counter) } - - // fn on_runtime_upgrade() -> Weight { - // use scale_info::prelude::collections::HashSet; - // let mut consumed_weight = Weight::zero(); - // let mut add_weight = |reads, writes, weight| { - // consumed_weight += T::DbWeight::get().reads_writes(reads, writes); - // consumed_weight += weight; - // }; - - // let mut stakes_unstakes = vec![]; - - // if >::get() { - // add_weight(1, 0, Weight::zero()); - // return consumed_weight; - // } else { - // add_weight(1, 1, Weight::zero()); - // >::set(true); - // } - // >::iter_keys().for_each(|(staker_id, _)| { - // add_weight(1, 0, Weight::zero()); - // stakes_unstakes.push(staker_id); - // }); - - // >::iter().for_each(|(_, v)| { - // add_weight(1, 0, Weight::zero()); - // v.into_iter().for_each(|(staker, _)| { - // stakes_unstakes.push(staker); - // }); - // }); - - // // filter duplicated id. - // stakes_unstakes = stakes_unstakes - // .into_iter() - // .map(|key| key) - // .collect::>() - // .into_iter() - // .collect(); - - // stakes_unstakes - // .map(|a| (a, >::get_locked_balance(&a).amount)) - // .for_each(|(staker, amount)| { - // <::Currency as LockableCurrency>::remove_lock( - // LOCK_IDENTIFIER, - // &staker, - // ); - // <::Currency as MutateFreeze>::set_freeze( - // &::FreezeIdentifier::get(), - // &staker, - // amount, - // ); - // add_weight(1, 2, Weight::zero()) - // }); - - // consumed_weight - // } - - // #[cfg(feature = "try-runtime")] - // fn pre_upgrade() -> Result, &'static str> { - // use sp_std::collections::btree_map::BTreeMap; - // if >::get() { - // return Ok(Default::default()); - // } - // // Staker -> (total (stakes and unstakes) locked by promotion); - // let mut pre_state: BTreeMap> = BTreeMap::new(); - - // >::iter().for_each(|((staker, _), (amount, _))| { - // if let Some(locked_balance) = pre_state.get_mut(&staker) { - // *locked_balance += amount; - // } else { - // pre_state.insert(staker, amount); - // } - // }); - - // >::iter().for_each(|(_, v)| { - // v.into_iter().for_each(|(staker, amount)| { - // if let Some(locked_balance) = pre_state.get_mut(&staker) { - // *locked_balance += amount; - // } else { - // pre_state.insert(staker, amount); - // } - // }) - // }); - - // Ok(pre_state.encode()) - // } - - // #[cfg(feature = "try-runtime")] - // fn post_upgrade(pre_state: Vec) -> Result<(), &'static str> { - // use sp_std::collections::btree_map::BTreeMap; - - // if >::get() { - // return Ok(()); - // } - - // let mut is_ok = true; - - // let pre_state: BTreeMap> = - // Decode::decode(&mut &pre_state[..]).map_err(|_| "failed to decode pre_state")?; - // for (staker, frozen_by_promo) in pre_state.into_iter() { - // let storage_freeze_state = <::Currency as InspectFreeze< - // T::AccountId, - // >>::balance_frozen( - // &::FreezeIdentifier::get(), staker - // ); - // if storage_freeze_state != frozen_by_promo { - // is_ok = false; - // log::error!( - // "Incorrect frozen balance for {:?}. New balance: {:?}. Before runtime upgrade: locked by promo - {:?}", - // staker, storage_freeze_state, frozen_by_promo - // ); - // } - - // if !>::get_locked_balance(&staker).amount.is_zero() { - // is_ok = false; - // log::error!( - // "Incorrect(non-zero) locked by app promo balance for {:?}", - // staker - // ); - // } - // } - - // if is_ok { - // Ok(()) - // } else { - // Err("Incorrect balance for some of stakers... See logs") - // } - // } } #[pallet::call] @@ -903,12 +778,16 @@ .into_iter() .for_each(|b| pendings.append(&mut PendingUnstake::::take(b).into_inner())); - pendings.into_iter().for_each(|(staker, amount)| { - Self::get_frozen_balance(&staker).map(|b| { - let new_state = b.checked_sub(&amount).unwrap_or_default(); - Self::set_freeze_unchecked(&staker, new_state); - }); - }); + pendings + .into_iter() + .try_for_each(|(staker, amount)| -> Result<(), DispatchError> { + if let Some(b) = Self::get_frozen_balance(&staker) { + let new_state = b.checked_sub(&amount).unwrap_or_default(); + Self::set_freeze_with_result(&staker, new_state)?; + } + + Ok(()) + })?; Ok(()) } @@ -1017,18 +896,6 @@ Ok(()) } - - /// Adds the balance to locked by the pallet. - /// - /// - `staker`: staker account. - /// - `amount`: amount of added locked funds. - // fn add_lock_balance(staker: &T::AccountId, amount: BalanceOf) -> DispatchResult { - // Self::get_locked_balance(staker) - // .map_or(>::default(), |l| l.amount) - // .checked_add(&amount) - // .map(|new_lock| Self::set_lock_unchecked(staker, new_lock)) - // .ok_or(ArithmeticError::Overflow.into()) - // } /// Adds the balance to frozen by the pallet. /// @@ -1042,32 +909,12 @@ .ok_or::(ArithmeticError::Overflow.into())? } - /// Sets the new state of a balance locked by the pallet. - /// - /// - `staker`: staker account. - /// - `amount`: amount of locked funds. - // fn set_lock_unchecked(staker: &T::AccountId, amount: BalanceOf) { - // if amount.is_zero() { - // <::Currency as LockableCurrency>::remove_lock( - // LOCK_IDENTIFIER, - // &staker, - // ); - // } else { - // <::Currency as LockableCurrency>::set_lock( - // LOCK_IDENTIFIER, - // staker, - // amount, - // WithdrawReasons::all(), - // ) - // } - // } - /// Sets the new state of a balance frozen by the pallet. /// /// - `staker`: staker account. /// - `amount`: amount of frozen funds. fn set_freeze_unchecked(staker: &T::AccountId, amount: BalanceOf) { - Self::set_freeze_with_result(staker, amount); + let _ = Self::set_freeze_with_result(staker, amount); } /// Sets the new state of a balance frozen by the pallet.