diff --git a/frame/balances/src/migration.rs b/frame/balances/src/migration.rs
index 4412a38ca14bb..bbd6652e3a5ad 100644
--- a/frame/balances/src/migration.rs
+++ b/frame/balances/src/migration.rs
@@ -1,3 +1,21 @@
+// Copyright 2020 Parity Technologies (UK) Ltd.
+// This file is part of Substrate.
+
+// Substrate 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.
+
+// Substrate 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.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate. If not, see .
+
+//! Temporary migrations of the balances module.
+
use super::*;
pub fn on_runtime_upgrade, I: Instance>() {
diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs
index 62c122fad3026..226003d933450 100644
--- a/frame/session/src/lib.rs
+++ b/frame/session/src/lib.rs
@@ -342,8 +342,6 @@ pub trait Trait: frame_system::Trait {
type DisabledValidatorsThreshold: Get;
}
-const DEDUP_KEY_PREFIX: &[u8] = b":session:keys";
-
decl_storage! {
trait Store for Module as Session {
/// The current set of validators.
@@ -366,20 +364,10 @@ decl_storage! {
DisabledValidators get(fn disabled_validators): Vec;
/// The next session keys for a validator.
- ///
- /// The first key is always `DEDUP_KEY_PREFIX` to have all the data in the same branch of
- /// the trie. Having all data in the same branch should prevent slowing down other queries.
- // TODO: Migrate to a normal map now https://github.com/paritytech/substrate/issues/4917
- NextKeys: double_map hasher(twox_64_concat) Vec, hasher(blake2_256) T::ValidatorId
- => Option;
+ NextKeys: map hasher(blake2_256) T::ValidatorId => Option;
- /// The owner of a key. The second key is the `KeyTypeId` + the encoded key.
- ///
- /// The first key is always `DEDUP_KEY_PREFIX` to have all the data in the same branch of
- /// the trie. Having all data in the same branch should prevent slowing down other queries.
- // TODO: Migrate to a normal map now https://github.com/paritytech/substrate/issues/4917
- KeyOwner: double_map hasher(twox_64_concat) Vec, hasher(blake2_256) (KeyTypeId, Vec)
- => Option;
+ /// The owner of a key. The key is the `KeyTypeId` + the encoded key.
+ KeyOwner: map hasher(blake2_256) (KeyTypeId, Vec) => Option;
}
add_extra_genesis {
config(keys): Vec<(T::AccountId, T::ValidatorId, T::Keys)>;
@@ -460,10 +448,6 @@ decl_error! {
decl_module! {
pub struct Module for enum Call where origin: T::Origin {
- /// Used as first key for `NextKeys` and `KeyOwner` to put all the data into the same branch
- /// of the trie.
- const DEDUP_KEY_PREFIX: &[u8] = DEDUP_KEY_PREFIX;
-
type Error = Error;
fn deposit_event() = default;
@@ -514,10 +498,36 @@ decl_module! {
Self::rotate_session();
}
}
+
+ /// Called when the runtime is upgraded.
+ fn on_runtime_upgrade() {
+ Self::migrate();
+ }
}
}
impl Module {
+ /// Move keys from NextKeys and KeyOwner, if any exist.
+ fn migrate() {
+ use frame_support::storage::migration::{put_storage_value, StorageIterator};
+ sp_runtime::print("Migrating session's double-maps...");
+
+ let prefix = {
+ const DEDUP_KEY_PREFIX: &[u8] = b":session:keys";
+ let encoded_prefix_key_hash = codec::Encode::encode(&DEDUP_KEY_PREFIX);
+ let mut h = sp_io::hashing::twox_64(&encoded_prefix_key_hash[..]).to_vec();
+ h.extend(&encoded_prefix_key_hash[..]);
+ h
+ };
+
+ for (hash, value) in StorageIterator::::with_suffix(b"Session", b"NextKeys", &prefix[..]).drain() {
+ put_storage_value(b"Session", b"NextKeys", &hash, value);
+ }
+ for (hash, value) in StorageIterator::::with_suffix(b"Session", b"KeyOwner", &prefix[..]).drain() {
+ put_storage_value(b"Session", b"KeyOwner", &hash, value);
+ }
+ }
+
/// Move on to next session. Register new validator set and session keys. Changes
/// to the validator set have a session of delay to take effect. This allows for
/// equivocation punishment after a fork.
@@ -704,27 +714,27 @@ impl Module {
}
fn load_keys(v: &T::ValidatorId) -> Option {
- >::get(DEDUP_KEY_PREFIX, v)
+ >::get(v)
}
fn take_keys(v: &T::ValidatorId) -> Option {
- >::take(DEDUP_KEY_PREFIX, v)
+ >::take(v)
}
fn put_keys(v: &T::ValidatorId, keys: &T::Keys) {
- >::insert(DEDUP_KEY_PREFIX, v, keys);
+ >::insert(v, keys);
}
fn key_owner(id: KeyTypeId, key_data: &[u8]) -> Option {
- >::get(DEDUP_KEY_PREFIX, (id, key_data))
+ >::get((id, key_data))
}
fn put_key_owner(id: KeyTypeId, key_data: &[u8], v: &T::ValidatorId) {
- >::insert(DEDUP_KEY_PREFIX, (id, key_data), v)
+ >::insert((id, key_data), v)
}
fn clear_key_owner(id: KeyTypeId, key_data: &[u8]) {
- >::remove(DEDUP_KEY_PREFIX, (id, key_data));
+ >::remove((id, key_data));
}
}
diff --git a/frame/support/src/storage/migration.rs b/frame/support/src/storage/migration.rs
index 291dceb4ea111..df9758ba69839 100644
--- a/frame/support/src/storage/migration.rs
+++ b/frame/support/src/storage/migration.rs
@@ -22,7 +22,7 @@ use crate::{StorageHasher, Twox128};
/// Utility to iterate through raw items in storage.
pub struct StorageIterator {
- prefix: [u8; 32],
+ prefix: Vec,
previous_key: Vec,
drain: bool,
_phantom: ::sp_std::marker::PhantomData,
@@ -31,11 +31,19 @@ pub struct StorageIterator {
impl StorageIterator {
/// Construct iterator to iterate over map items in `module` for the map called `item`.
pub fn new(module: &[u8], item: &[u8]) -> Self {
- let mut prefix = [0u8; 32];
- prefix[0..16].copy_from_slice(&Twox128::hash(module));
- prefix[16..32].copy_from_slice(&Twox128::hash(item));
- Self { prefix, previous_key: prefix[..].to_vec(), drain: false, _phantom: Default::default() }
+ Self::with_suffix(module, item, &[][..])
}
+
+ /// Construct iterator to iterate over map items in `module` for the map called `item`.
+ pub fn with_suffix(module: &[u8], item: &[u8], suffix: &[u8]) -> Self {
+ let mut prefix = Vec::new();
+ prefix.extend_from_slice(&Twox128::hash(module));
+ prefix.extend_from_slice(&Twox128::hash(item));
+ prefix.extend_from_slice(suffix);
+ let previous_key = prefix.clone();
+ Self { prefix, previous_key, drain: false, _phantom: Default::default() }
+ }
+
/// Mutate this iterator into a draining iterator; items iterated are removed from storage.
pub fn drain(mut self) -> Self {
self.drain = true;
@@ -59,7 +67,7 @@ impl Iterator for StorageIterator {
if self.drain {
frame_support::storage::unhashed::kill(&next);
}
- Some((self.previous_key[32..].to_vec(), value))
+ Some((self.previous_key[self.prefix.len()..].to_vec(), value))
}
None => continue,
}