Switch srml-session keys to decl_storage! (#3184)

* Switch `srml-session` keys to `decl_storage!`

* Expose `DEDUP_KEY_PREFIX` in constants

* Fix test

* Bump spec version
This commit is contained in:
Bastian Köcher
2019-07-24 10:40:04 +02:00
committed by Gavin Wood
parent c8dab27f35
commit 5d58d583e3
14 changed files with 365 additions and 201 deletions
+26 -30
View File
@@ -120,14 +120,12 @@
#![cfg_attr(not(feature = "std"), no_std)]
use rstd::{prelude::*, marker::PhantomData, ops::{Sub, Rem}};
use parity_codec::{Decode, Encode};
use parity_codec::Decode;
use primitives::KeyTypeId;
use primitives::traits::{Convert, Zero, Member, OpaqueKeys, TypedKey, Hash};
use primitives::traits::{Convert, Zero, Member, OpaqueKeys, TypedKey};
use srml_support::{
dispatch::Result,
storage,
ConsensusEngineId, StorageValue, for_each_tuple, decl_module,
decl_event, decl_storage,
dispatch::Result, ConsensusEngineId, StorageValue, StorageDoubleMap, for_each_tuple,
decl_module, decl_event, decl_storage,
};
use srml_support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter};
use system::{self, ensure_signed};
@@ -283,8 +281,7 @@ pub trait Trait: system::Trait {
type SelectInitialValidators: SelectInitialValidators<Self::ValidatorId>;
}
const DEDUP_KEY_LEN: usize = 13;
const DEDUP_KEY_PREFIX: &[u8; DEDUP_KEY_LEN] = b":session:keys";
const DEDUP_KEY_PREFIX: &[u8] = b":session:keys";
decl_storage! {
trait Store for Module<T: Trait> as Session {
@@ -304,6 +301,17 @@ decl_storage! {
/// will be used to determine the validator's session keys.
QueuedKeys get(queued_keys): Vec<(T::ValidatorId, T::Keys)>;
/// 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.
NextKeys: double_map hasher(twox_64_concat) Vec<u8>, blake2_256(T::ValidatorId) => Option<T::Keys>;
/// 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.
KeyOwner: double_map hasher(twox_64_concat) Vec<u8>, blake2_256((KeyTypeId, Vec<u8>)) => Option<T::ValidatorId>;
}
add_extra_genesis {
config(keys): Vec<(T::ValidatorId, T::Keys)>;
@@ -354,6 +362,10 @@ decl_event!(
decl_module! {
pub struct Module<T: Trait> 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;
fn deposit_event() = default;
/// Sets the session key(s) of the function caller to `key`.
@@ -494,47 +506,31 @@ impl<T: Trait> Module<T> {
}
}
// Child trie storage.
fn load_keys(v: &T::ValidatorId) -> Option<T::Keys> {
storage::unhashed::get(&dedup_trie_key::<T, _>(v))
<NextKeys<T>>::get(DEDUP_KEY_PREFIX, v)
}
fn take_keys(v: &T::ValidatorId) -> Option<T::Keys> {
storage::unhashed::take(&dedup_trie_key::<T, _>(v))
<NextKeys<T>>::take(DEDUP_KEY_PREFIX, v)
}
fn put_keys(v: &T::ValidatorId, keys: &T::Keys) {
storage::unhashed::put(&dedup_trie_key::<T, _>(v), keys)
<NextKeys<T>>::insert(DEDUP_KEY_PREFIX, v, keys);
}
fn key_owner(id: KeyTypeId, key_data: &[u8]) -> Option<T::ValidatorId> {
storage::unhashed::get(&dedup_trie_key::<T, _>(&(id, key_data)))
<KeyOwner<T>>::get(DEDUP_KEY_PREFIX, &(id, key_data.to_vec()))
}
fn put_key_owner(id: KeyTypeId, key_data: &[u8], v: &T::ValidatorId) {
storage::unhashed::put(&dedup_trie_key::<T, _>(&(id, key_data)), v);
<KeyOwner<T>>::insert(DEDUP_KEY_PREFIX, &(id, key_data.to_vec()), v)
}
fn clear_key_owner(id: KeyTypeId, key_data: &[u8]) {
storage::unhashed::kill(&dedup_trie_key::<T, _>(&(id, key_data)));
<KeyOwner<T>>::remove(DEDUP_KEY_PREFIX, &(id, key_data.to_vec()));
}
}
fn dedup_trie_key<T: Trait, K: Encode>(key: &K) -> [u8; 32 + DEDUP_KEY_LEN] {
key.using_encoded(|s| {
// take at most 32 bytes from the hash of the value.
let hash = <T as system::Trait>::Hashing::hash(s);
let hash: &[u8] = hash.as_ref();
let len = rstd::cmp::min(hash.len(), 32);
let mut data = [0; 32 + DEDUP_KEY_LEN];
data[..DEDUP_KEY_LEN].copy_from_slice(DEDUP_KEY_PREFIX);
data[DEDUP_KEY_LEN..][..len].copy_from_slice(hash);
data
})
}
impl<T: Trait> OnFreeBalanceZero<T::ValidatorId> for Module<T> {
fn on_free_balance_zero(who: &T::ValidatorId) {
Self::prune_dead_keys(who);