1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
// Copyright 2021 Centrifuge Foundation (centrifuge.io).
//
// This file is part of the Centrifuge chain project.
// Centrifuge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version (see http://www.gnu.org/licenses).
// Centrifuge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//! Centrifuge Runtime-Common Migrations
pub mod foreign_investments_v2;
pub mod increase_storage_version;
pub mod liquidity_pools_v2;
pub mod nuke;
pub mod permissions_v1;
pub mod precompile_account_codes;
pub mod restricted_location;
pub mod technical_comittee;
pub mod utils {
use frame_support::storage::unhashed;
use sp_arithmetic::traits::Saturating;
/// Iterates keys of storage and removes undecodable keys
///
/// WARNING: USE WITH EXTREME CAUTION! Ensure the cleanup can be performed
/// beforehand!
pub fn remove_undecodable_storage_keys<T: parity_scale_codec::Decode + Sized>(
prefix: [u8; 32],
) -> (u64, u64) {
let mut previous_key = prefix.clone().to_vec();
let mut reads: u64 = 1;
let mut writes: u64 = 0;
while let Some(next) =
sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))
{
reads.saturating_accrue(1);
previous_key = next;
let maybe_value = unhashed::get::<T>(&previous_key);
match maybe_value {
Some(_) => continue,
None => {
log::debug!(
"Removing key which could not be decoded at {:?}",
previous_key
);
unhashed::kill(&previous_key);
writes.saturating_accrue(1);
continue;
}
}
}
(reads, writes)
}
/// Iterates all keys of a storage and returns the count.
///
/// NOTE: Necessary because `Storage::<T>::iter().count()` does not account
/// for keys which cannot be decoded.
pub fn count_storage_keys(prefix: [u8; 32]) -> u32 {
let mut previous_key = prefix.clone().to_vec();
let mut n: u32 = 0;
while let Some(next) =
sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))
{
n.saturating_accrue(1);
previous_key = next;
}
n
}
}