diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 71af5d9417..2b8750d2de 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -75,8 +75,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 117, - impl_version: 117, + spec_version: 118, + impl_version: 118, apis: RUNTIME_API_VERSIONS, }; diff --git a/substrate/srml/generic-asset/src/lib.rs b/substrate/srml/generic-asset/src/lib.rs index 884f4e9b9b..60947e68eb 100644 --- a/substrate/srml/generic-asset/src/lib.rs +++ b/substrate/srml/generic-asset/src/lib.rs @@ -336,7 +336,7 @@ decl_module! { >::put(next_id); >::insert(id, &options.initial_issuance); - >::insert(&id, &origin, options.initial_issuance); + >::insert(&id, &origin, &options.initial_issuance); >::insert(&id, permissions); Self::deposit_event(RawEvent::Created(id, origin, options)); @@ -560,7 +560,7 @@ impl Module { let permissions: PermissionVersions = options.permissions.clone().into(); >::insert(asset_id, &options.initial_issuance); - >::insert(&asset_id, &account_id, options.initial_issuance); + >::insert(&asset_id, &account_id, &options.initial_issuance); >::insert(&asset_id, permissions); Self::deposit_event(RawEvent::Created(asset_id, account_id, options)); @@ -768,13 +768,13 @@ impl Module { /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that /// the caller will do this. fn set_reserved_balance(asset_id: &T::AssetId, who: &T::AccountId, balance: T::Balance) { - >::insert(asset_id, who, balance); + >::insert(asset_id, who, &balance); } /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that /// the caller will do this. fn set_free_balance(asset_id: &T::AssetId, who: &T::AccountId, balance: T::Balance) { - >::insert(asset_id, who, balance); + >::insert(asset_id, who, &balance); } fn set_lock( diff --git a/substrate/srml/im-online/src/lib.rs b/substrate/srml/im-online/src/lib.rs index f1868c599b..e2b23f1dbd 100644 --- a/substrate/srml/im-online/src/lib.rs +++ b/substrate/srml/im-online/src/lib.rs @@ -200,13 +200,13 @@ decl_module! { ensure_none(origin)?; let current_session = >::current_index(); - let exists = >::exists(current_session, &heartbeat.authority_id); + let exists = >::exists(¤t_session, &heartbeat.authority_id); if !exists { let now = >::block_number(); Self::deposit_event(RawEvent::HeartbeatReceived(now, heartbeat.authority_id.clone())); let network_state = heartbeat.network_state.encode(); - >::insert(current_session, &heartbeat.authority_id, network_state); + >::insert(¤t_session, &heartbeat.authority_id, &network_state); } } @@ -301,13 +301,13 @@ impl Module { Some(start) => { // iterate over every session for index in start..curr { - if >::exists(index, authority_id) { + if >::exists(&index, authority_id) { return true; } } false }, - None => >::exists(curr, authority_id), + None => >::exists(&curr, authority_id), } } @@ -315,7 +315,7 @@ impl Module { /// during the current session. Otherwise `false`. pub fn is_online_in_current_session(authority_id: &T::AuthorityId) -> bool { let current_session = >::current_index(); - >::exists(current_session, authority_id) + >::exists(¤t_session, authority_id) } /// Session has just changed. @@ -345,10 +345,10 @@ impl Module { match LastNewEraStart::get() { Some(start) => { for index in start..curr { - >::remove_prefix(index); + >::remove_prefix(&index); } }, - None => >::remove_prefix(curr), + None => >::remove_prefix(&curr), } } } diff --git a/substrate/srml/session/src/lib.rs b/substrate/srml/session/src/lib.rs index 5495cdbe65..d425c44e2e 100644 --- a/substrate/srml/session/src/lib.rs +++ b/substrate/srml/session/src/lib.rs @@ -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; } -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 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, 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. + KeyOwner: double_map hasher(twox_64_concat) Vec, blake2_256((KeyTypeId, Vec)) => Option; } add_extra_genesis { config(keys): Vec<(T::ValidatorId, T::Keys)>; @@ -354,6 +362,10 @@ decl_event!( 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; + fn deposit_event() = default; /// Sets the session key(s) of the function caller to `key`. @@ -494,47 +506,31 @@ impl Module { } } - // Child trie storage. - fn load_keys(v: &T::ValidatorId) -> Option { - storage::unhashed::get(&dedup_trie_key::(v)) + >::get(DEDUP_KEY_PREFIX, v) } fn take_keys(v: &T::ValidatorId) -> Option { - storage::unhashed::take(&dedup_trie_key::(v)) + >::take(DEDUP_KEY_PREFIX, v) } fn put_keys(v: &T::ValidatorId, keys: &T::Keys) { - storage::unhashed::put(&dedup_trie_key::(v), keys) + >::insert(DEDUP_KEY_PREFIX, v, keys); } fn key_owner(id: KeyTypeId, key_data: &[u8]) -> Option { - storage::unhashed::get(&dedup_trie_key::(&(id, key_data))) + >::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::(&(id, key_data)), v); + >::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::(&(id, key_data))); + >::remove(DEDUP_KEY_PREFIX, &(id, key_data.to_vec())); } } -fn dedup_trie_key(key: &K) -> [u8; 32 + DEDUP_KEY_LEN] { - key.using_encoded(|s| { - // take at most 32 bytes from the hash of the value. - let hash = ::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 OnFreeBalanceZero for Module { fn on_free_balance_zero(who: &T::ValidatorId) { Self::prune_dead_keys(who); diff --git a/substrate/srml/support/procedural/src/lib.rs b/substrate/srml/support/procedural/src/lib.rs index f6da2f751d..78051ee8f2 100644 --- a/substrate/srml/support/procedural/src/lib.rs +++ b/substrate/srml/support/procedural/src/lib.rs @@ -18,7 +18,7 @@ //! Proc macro of Support code for the runtime. // end::description[] -#![recursion_limit="256"] +#![recursion_limit="512"] extern crate proc_macro; diff --git a/substrate/srml/support/procedural/src/storage/impls.rs b/substrate/srml/support/procedural/src/storage/impls.rs index d5dc91635b..45d7fada9f 100644 --- a/substrate/srml/support/procedural/src/storage/impls.rs +++ b/substrate/srml/support/procedural/src/storage/impls.rs @@ -694,13 +694,18 @@ impl<'a, I: Iterator> Impls<'a, I> { let mutate_impl = if !is_option { quote!{ - #as_double_map::insert(key1, key2, &val, storage) + #as_double_map::insert(k1, k2, &val, storage) } } else { quote!{ match val { - Some(ref val) => #as_double_map::insert(key1, key2, &val, storage), - None => #as_double_map::remove(key1, key2, storage), + Some(ref val) => #as_double_map::insert::( + k1, + k2, + val, + storage, + ), + None => #as_double_map::remove(k1, k2, storage), } } }; @@ -751,7 +756,10 @@ impl<'a, I: Iterator> Impls<'a, I> { { type Query = #value_type; - fn prefix_for(k1: &#k1ty) -> Vec { + fn prefix_for(k1: &KArg1) -> #scrate::rstd::vec::Vec where + KArg1: ?Sized + #scrate::codec::Encode, + #k1ty: #scrate::rstd::borrow::Borrow, + { use #scrate::storage::hashed::generator::StorageHasher; let mut key = #as_double_map::prefix().to_vec(); @@ -763,7 +771,15 @@ impl<'a, I: Iterator> Impls<'a, I> { #final_prefix } - fn key_for(k1: &#k1ty, k2: &#k2ty) -> Vec { + fn key_for( + k1: &KArg1, + k2: &KArg2, + ) -> #scrate::rstd::vec::Vec where + #k1ty: #scrate::rstd::borrow::Borrow, + #k2ty: #scrate::rstd::borrow::Borrow, + KArg1: ?Sized + #scrate::codec::Encode, + KArg2: ?Sized + #scrate::codec::Encode, + { use #scrate::storage::hashed::generator::StorageHasher; let mut key = #as_double_map::prefix_for(k1); @@ -771,25 +787,50 @@ impl<'a, I: Iterator> Impls<'a, I> { key } - fn get(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query { - let key = #as_double_map::key_for(key1, key2); + fn get( + k1: &KArg1, + k2: &KArg2, + storage: &S, + ) -> Self::Query where + #k1ty: #scrate::rstd::borrow::Borrow, + #k2ty: #scrate::rstd::borrow::Borrow, + KArg1: ?Sized + #scrate::codec::Encode, + KArg2: ?Sized + #scrate::codec::Encode, + { + let key = #as_double_map::key_for(k1, k2); storage.get(&key).#option_simple_1(|| #fielddefault) } - fn take(key1: &#k1ty, key2: &#k2ty, storage: &mut S) -> Self::Query { - let key = #as_double_map::key_for(key1, key2); + fn take( + k1: &KArg1, + k2: &KArg2, + storage: &mut S, + ) -> Self::Query where + #k1ty: #scrate::rstd::borrow::Borrow, + #k2ty: #scrate::rstd::borrow::Borrow, + KArg1: ?Sized + #scrate::codec::Encode, + KArg2: ?Sized + #scrate::codec::Encode, + { + let key = #as_double_map::key_for(k1, k2); storage.take(&key).#option_simple_1(|| #fielddefault) } - fn mutate(key1: &#k1ty, key2: &#k2ty, f: F, storage: &mut S) -> R - where + fn mutate( + k1: &KArg1, + k2: &KArg2, + f: F, + storage: &mut S, + ) -> R where + #k1ty: #scrate::rstd::borrow::Borrow, + #k2ty: #scrate::rstd::borrow::Borrow, + KArg1: ?Sized + #scrate::codec::Encode, + KArg2: ?Sized + #scrate::codec::Encode, F: FnOnce(&mut Self::Query) -> R, - S: #scrate::UnhashedStorage, { - let mut val = #as_double_map::get(key1, key2, storage); + let mut val = #as_double_map::get(k1, k2, storage); let ret = f(&mut val); - #mutate_impl ; + #mutate_impl; ret } } diff --git a/substrate/srml/support/procedural/src/storage/transformation.rs b/substrate/srml/support/procedural/src/storage/transformation.rs index 6f0cf93179..ae0531c57d 100644 --- a/substrate/srml/support/procedural/src/storage/transformation.rs +++ b/substrate/srml/support/procedural/src/storage/transformation.rs @@ -905,15 +905,17 @@ fn impl_store_fns( }; quote!{ - pub fn #get_fn(k1: KArg1, k2: KArg2) -> #value_type + pub fn #get_fn(k1: &KArg1, k2: &KArg2) -> #value_type where - KArg1: #scrate::rstd::borrow::Borrow<#key1_type>, - KArg2: #scrate::rstd::borrow::Borrow<#key2_type>, + #key1_type: #scrate::rstd::borrow::Borrow, + #key2_type: #scrate::rstd::borrow::Borrow, + KArg1: ?Sized + #scrate::codec::Encode, + KArg2: ?Sized + #scrate::codec::Encode, { < #name<#struct_trait #instance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::get(k1.borrow(), k2.borrow(), &#scrate::storage::RuntimeStorage) + >::get(k1, k2, &#scrate::storage::RuntimeStorage) } } } diff --git a/substrate/srml/support/src/double_map.rs b/substrate/srml/support/src/double_map.rs index d35570ae4f..aec7f497a6 100644 --- a/substrate/srml/support/src/double_map.rs +++ b/substrate/srml/support/src/double_map.rs @@ -34,8 +34,8 @@ use sr_std::borrow::Borrow; /// /// Hasher are implemented in derive_key* methods. pub trait StorageDoubleMapWithHasher { - type Key1: Codec; - type Key2: Codec; + type Key1: Encode; + type Key2: Encode; type Value: Codec + Default; const PREFIX: &'static [u8]; diff --git a/substrate/srml/support/src/lib.rs b/substrate/srml/support/src/lib.rs index 361fef969b..e1300c5925 100644 --- a/substrate/srml/support/src/lib.rs +++ b/substrate/srml/support/src/lib.rs @@ -387,32 +387,32 @@ mod tests { // get / insert / take let key1 = 17u32; let key2 = 18u32; - assert_eq!(DoubleMap::get(key1, key2), 0u64); - DoubleMap::insert(key1, key2, 4u64); - assert_eq!(DoubleMap::get(key1, key2), 4u64); - assert_eq!(DoubleMap::take(key1, key2), 4u64); - assert_eq!(DoubleMap::get(key1, key2), 0u64); + assert_eq!(DoubleMap::get(&key1, &key2), 0u64); + DoubleMap::insert(&key1, &key2, &4u64); + assert_eq!(DoubleMap::get(&key1, &key2), 4u64); + assert_eq!(DoubleMap::take(&key1, &key2), 4u64); + assert_eq!(DoubleMap::get(&key1, &key2), 0u64); // mutate - DoubleMap::mutate(key1, key2, |val| { + DoubleMap::mutate(&key1, &key2, |val| { *val = 15; }); - assert_eq!(DoubleMap::get(key1, key2), 15u64); + assert_eq!(DoubleMap::get(&key1, &key2), 15u64); // remove - DoubleMap::remove(key1, key2); - assert_eq!(DoubleMap::get(key1, key2), 0u64); + DoubleMap::remove(&key1, &key2); + assert_eq!(DoubleMap::get(&key1, &key2), 0u64); // remove prefix - DoubleMap::insert(key1, key2, 4u64); - DoubleMap::insert(key1, key2+1, 4u64); - DoubleMap::insert(key1+1, key2, 4u64); - DoubleMap::insert(key1+1, key2+1, 4u64); - DoubleMap::remove_prefix(key1); - assert_eq!(DoubleMap::get(key1, key2), 0u64); - assert_eq!(DoubleMap::get(key1, key2+1), 0u64); - assert_eq!(DoubleMap::get(key1+1, key2), 4u64); - assert_eq!(DoubleMap::get(key1+1, key2+1), 4u64); + DoubleMap::insert(&key1, &key2, &4u64); + DoubleMap::insert(&key1, &(key2 + 1), &4u64); + DoubleMap::insert(&(key1 + 1), &key2, &4u64); + DoubleMap::insert(&(key1 + 1), &(key2 + 1), &4u64); + DoubleMap::remove_prefix(&key1); + assert_eq!(DoubleMap::get(&key1, &key2), 0u64); + assert_eq!(DoubleMap::get(&key1, &(key2 + 1)), 0u64); + assert_eq!(DoubleMap::get(&(key1 + 1), &key2), 4u64); + assert_eq!(DoubleMap::get(&(key1 + 1), &(key2 + 1)), 4u64); }); } @@ -425,9 +425,9 @@ mod tests { let key1 = 17u32; let key2 = 18u32; - DoubleMap::insert(key1, key2, vec![1]); - DoubleMap::append(key1, key2, &[2, 3]).unwrap(); - assert_eq!(DoubleMap::get(key1, key2), vec![1, 2, 3]); + DoubleMap::insert(&key1, &key2, &vec![1]); + DoubleMap::append(&key1, &key2, &[2, 3]).unwrap(); + assert_eq!(DoubleMap::get(&key1, &key2), &[1, 2, 3]); }); } diff --git a/substrate/srml/support/src/storage/mod.rs b/substrate/srml/support/src/storage/mod.rs index db9e4bc31d..446855b55c 100644 --- a/substrate/srml/support/src/storage/mod.rs +++ b/substrate/srml/support/src/storage/mod.rs @@ -104,7 +104,7 @@ impl UnhashedStorage for RuntimeStorage { } /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T) { + fn put(&mut self, key: &[u8], val: &T) { unhashed::put(key, val) } @@ -332,60 +332,83 @@ impl EnumerableStorageMap for U /// is a hash of a `Key2`. /// /// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the trie. -pub trait StorageDoubleMap { +pub trait StorageDoubleMap { /// The type that get/take returns. type Query; - /// Get the prefix key in storage. fn prefix() -> &'static [u8]; - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for, KArg2: Borrow>(k1: KArg1, k2: KArg2) -> Vec; - - /// Get the storage prefix used to fetch keys corresponding to a specific key1. - fn prefix_for>(k1: KArg1) -> Vec; - - /// true if the value is defined in storage. - fn exists, KArg2: Borrow>(k1: KArg1, k2: KArg2) -> bool; - - /// Load the value associated with the given key from the map. - fn get, KArg2: Borrow>(k1: KArg1, k2: KArg2) -> Self::Query; - - /// Take the value under a key. - fn take, KArg2: Borrow>(k1: KArg1, k2: KArg2) -> Self::Query; - - /// Store a value to be associated with the given key from the map. - fn insert, KArg2: Borrow, VArg: Borrow>(k1: KArg1, k2: KArg2, val: VArg); - - /// Remove the value under a key. - fn remove, KArg2: Borrow>(k1: KArg1, k2: KArg2); - - /// Removes all entries that shares the `k1` as the first key. - fn remove_prefix>(k1: KArg1); - - /// Mutate the value under a key. - fn mutate(k1: KArg1, k2: KArg2, f: F) -> R + fn key_for(k1: &KArg1, k2: &KArg2) -> Vec where - KArg1: Borrow, - KArg2: Borrow, + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode; + + fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow; + + fn exists(k1: &KArg1, k2: &KArg2) -> bool + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode; + + fn get(k1: &KArg1, k2: &KArg2) -> Self::Query + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode; + + fn take(k1: &KArg1, k2: &KArg2) -> Self::Query + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode; + + fn insert(k1: &KArg1, k2: &KArg2, val: &VArg) + where + K1: Borrow, + K2: Borrow, + V: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + VArg: ?Sized + Encode; + + fn remove(k1: &KArg1, k2: &KArg2) + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode; + + fn remove_prefix(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow; + + fn mutate(k1: &KArg1, k2: &KArg2, f: F) -> R + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, F: FnOnce(&mut Self::Query) -> R; - /// Append the given items to the value under the key specified. - /// - /// `V` is required to implement `codec::EncodeAppend`. fn append( - k1: KArg1, - k2: KArg2, + k1: &KArg1, + k2: &KArg2, items: &[I], ) -> Result<(), &'static str> where - KArg1: Borrow, - KArg2: Borrow, + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, I: codec::Encode, V: EncodeAppend; } -impl StorageDoubleMap for U +impl StorageDoubleMap for U where U: unhashed::generator::StorageDoubleMap { @@ -395,59 +418,101 @@ where >::prefix() } - fn key_for, KArg2: Borrow>(k1: KArg1, k2: KArg2) -> Vec { - >::key_for(k1.borrow(), k2.borrow()) + fn key_for(k1: &KArg1, k2: &KArg2) -> Vec + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { + >::key_for(k1, k2) } - fn prefix_for>(k1: KArg1) -> Vec { - >::prefix_for(k1.borrow()) + fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow { + >::prefix_for(k1) } - fn exists, KArg2: Borrow>(k1: KArg1, k2: KArg2) -> bool { - U::exists(k1.borrow(), k2.borrow(), &RuntimeStorage) + fn exists(k1: &KArg1, k2: &KArg2) -> bool + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { + U::exists(k1, k2, &RuntimeStorage) } - fn get, KArg2: Borrow>(k1: KArg1, k2: KArg2) -> Self::Query { - U::get(k1.borrow(), k2.borrow(), &RuntimeStorage) + fn get(k1: &KArg1, k2: &KArg2) -> Self::Query + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { + U::get(k1, k2, &RuntimeStorage) } - fn take, KArg2: Borrow>(k1: KArg1, k2: KArg2) -> Self::Query { + fn take(k1: &KArg1, k2: &KArg2) -> Self::Query + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { U::take(k1.borrow(), k2.borrow(), &mut RuntimeStorage) } - fn insert, KArg2: Borrow, VArg: Borrow>(k1: KArg1, k2: KArg2, val: VArg) { - U::insert(k1.borrow(), k2.borrow(), val.borrow(), &mut RuntimeStorage) - } - - fn remove, KArg2: Borrow>(k1: KArg1, k2: KArg2) { - U::remove(k1.borrow(), k2.borrow(), &mut RuntimeStorage) - } - - fn remove_prefix>(k1: KArg1) { - U::remove_prefix(k1.borrow(), &mut RuntimeStorage) - } - - fn mutate(k1: KArg1, k2: KArg2, f: F) -> R + fn insert(k1: &KArg1, k2: &KArg2, val: &VArg) where - KArg1: Borrow, - KArg2: Borrow, + K1: Borrow, + K2: Borrow, + V: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + VArg: ?Sized + Encode, + { + U::insert(k1, k2, val, &mut RuntimeStorage) + } + + fn remove(k1: &KArg1, k2: &KArg2) + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + { + U::remove(k1, k2, &mut RuntimeStorage) + } + + fn remove_prefix(k1: &KArg1) where KArg1: ?Sized + Encode, K1: Borrow { + U::remove_prefix(k1, &mut RuntimeStorage) + } + + fn mutate(k1: &KArg1, k2: &KArg2, f: F) -> R + where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, F: FnOnce(&mut Self::Query) -> R { - U::mutate(k1.borrow(), k2.borrow(), f, &mut RuntimeStorage) + U::mutate(k1, k2, f, &mut RuntimeStorage) } fn append( - k1: KArg1, - k2: KArg2, + k1: &KArg1, + k2: &KArg2, items: &[I], ) -> Result<(), &'static str> where - KArg1: Borrow, - KArg2: Borrow, + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, I: codec::Encode, V: EncodeAppend, { - U::append(k1.borrow(), k2.borrow(), items, &mut RuntimeStorage) + U::append(k1, k2, items, &mut RuntimeStorage) } } diff --git a/substrate/srml/support/src/storage/unhashed/generator.rs b/substrate/srml/support/src/storage/unhashed/generator.rs index 3c56ae0ac5..26cb4b73e5 100644 --- a/substrate/srml/support/src/storage/unhashed/generator.rs +++ b/substrate/srml/support/src/storage/unhashed/generator.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::codec; -use crate::rstd::vec::Vec; +use crate::codec::{self, Encode, EncodeAppend}; +use crate::rstd::{borrow::Borrow, vec::Vec}; /// Abstraction around storage with unhashed access. pub trait UnhashedStorage { @@ -38,7 +38,7 @@ pub trait UnhashedStorage { } /// Put a value in under a key. - fn put(&mut self, key: &[u8], val: &T); + fn put(&mut self, key: &[u8], val: &T); /// Remove the bytes of a key from storage. fn kill(&mut self, key: &[u8]); @@ -82,7 +82,7 @@ impl UnhashedStorage for sr_primitives::StorageOverlay { .map(|x| codec::Decode::decode(&mut x.as_slice()).expect("Unable to decode expected type.")) } - fn put(&mut self, key: &[u8], val: &T) { + fn put(&mut self, key: &[u8], val: &T) { self.insert(key.to_vec(), codec::Encode::encode(val)); } @@ -117,7 +117,7 @@ impl UnhashedStorage for sr_primitives::StorageOverlay { /// is a hash of a `Key2`. /// /// /!\ be careful while choosing the Hash, indeed malicious could craft second keys to lower the trie. -pub trait StorageDoubleMap { +pub trait StorageDoubleMap { /// The type that get/take returns. type Query; @@ -125,50 +125,110 @@ pub trait StorageDoubleMap fn prefix() -> &'static [u8]; /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(k1: &K1, k2: &K2) -> Vec; + fn key_for( + k1: &KArg1, + k2: &KArg2, + ) -> Vec where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode; /// Get the storage prefix used to fetch keys corresponding to a specific key1. - fn prefix_for(k1: &K1) -> Vec; + fn prefix_for(k1: &KArg1) -> Vec where KArg1: ?Sized + Encode, K1: Borrow; /// true if the value is defined in storage. - fn exists(k1: &K1, k2: &K2, storage: &S) -> bool { + fn exists( + k1: &KArg1, + k2: &KArg2, + storage: &S, + ) -> bool where K1: Borrow, K2: Borrow, KArg1: ?Sized + Encode, KArg2: ?Sized + Encode { storage.exists(&Self::key_for(k1, k2)) } /// Load the value associated with the given key from the map. - fn get(k1: &K1, k2: &K2, storage: &S) -> Self::Query; + fn get( + k1: &KArg1, + k2: &KArg2, + storage: &S, + ) -> Self::Query where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode; /// Take the value under a key. - fn take(k1: &K1, k2: &K2, storage: &mut S) -> Self::Query; + fn take( + k1: &KArg1, + k2: &KArg2, + storage: &mut S, + ) -> Self::Query where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode; /// Store a value to be associated with the given key from the map. - fn insert(k1: &K1, k2: &K2, val: &V, storage: &mut S) { + fn insert( + k1: &KArg1, + k2: &KArg2, + val: &VArg, + storage: &mut S, + ) where + K1: Borrow, + K2: Borrow, + V: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + VArg: ?Sized + Encode, + { storage.put(&Self::key_for(k1, k2), val); } /// Remove the value under a key. - fn remove(k1: &K1, k2: &K2, storage: &mut S) { + fn remove( + k1: &KArg1, + k2: &KArg2, + storage: &mut S, + ) where K1: Borrow, K2: Borrow, KArg1: ?Sized + Encode, KArg2: ?Sized + Encode { storage.kill(&Self::key_for(k1, k2)); } /// Removes all entries that shares the `k1` as the first key. - fn remove_prefix(k1: &K1, storage: &mut S) { + fn remove_prefix( + k1: &KArg1, + storage: &mut S, + ) where KArg1: ?Sized + Encode, K1: Borrow { storage.kill_prefix(&Self::prefix_for(k1)); } /// Mutate the value under a key. - fn mutate R, S: UnhashedStorage>(k1: &K1, k2: &K2, f: F, storage: &mut S) -> R; + fn mutate( + k1: &KArg1, + k2: &KArg2, + f: F, + storage: &mut S, + ) -> R where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, + F: FnOnce(&mut Self::Query) -> R; /// Append the given items to the value under the key specified. - fn append( - k1: &K1, - k2: &K2, + fn append( + k1: &KArg1, + k2: &KArg2, items: &[I], storage: &mut S, ) -> Result<(), &'static str> where + K1: Borrow, + K2: Borrow, + KArg1: ?Sized + Encode, + KArg2: ?Sized + Encode, I: codec::Encode, - V: codec::EncodeAppend, + V: EncodeAppend, { let key = Self::key_for(k1, k2); let new_val = ::append( diff --git a/substrate/srml/support/src/storage/unhashed/mod.rs b/substrate/srml/support/src/storage/unhashed/mod.rs index 40e18d0cd2..77e6c2b37b 100644 --- a/substrate/srml/support/src/storage/unhashed/mod.rs +++ b/substrate/srml/support/src/storage/unhashed/mod.rs @@ -51,7 +51,7 @@ pub fn get_or_else T>(key: &[u8], default_valu } /// Put `value` in storage under `key`. -pub fn put(key: &[u8], value: &T) { +pub fn put(key: &[u8], value: &T) { value.using_encoded(|slice| runtime_io::set_storage(key, slice)); } diff --git a/substrate/srml/support/test/tests/final_keys.rs b/substrate/srml/support/test/tests/final_keys.rs index 888ef48cb2..54c08d5e5f 100644 --- a/substrate/srml/support/test/tests/final_keys.rs +++ b/substrate/srml/support/test/tests/final_keys.rs @@ -29,7 +29,7 @@ srml_support::decl_module! { } srml_support::decl_storage!{ - trait Store for Module as Module { + trait Store for Module as FinalKeys { pub Value config(value): u32; pub Map: map u32 => u32; @@ -60,37 +60,37 @@ fn new_test_ext() -> runtime_io::TestExternalities { fn final_keys() { with_externalities(&mut new_test_ext(), || { Value::put(1); - assert_eq!(unhashed::get::(&runtime_io::twox_128(b"Module Value")), Some(1u32)); + assert_eq!(unhashed::get::(&runtime_io::twox_128(b"FinalKeys Value")), Some(1u32)); Map::insert(1, 2); - let mut k = b"Module Map".to_vec(); + let mut k = b"FinalKeys Map".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); Map2::insert(1, 2); - let mut k = b"Module Map2".to_vec(); + let mut k = b"FinalKeys Map2".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); LinkedMap::insert(1, 2); - let mut k = b"Module LinkedMap".to_vec(); + let mut k = b"FinalKeys LinkedMap".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); LinkedMap2::insert(1, 2); - let mut k = b"Module LinkedMap2".to_vec(); + let mut k = b"FinalKeys LinkedMap2".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); - DoubleMap::insert(1, 2, 3); - let mut k = b"Module DoubleMap".to_vec(); + DoubleMap::insert(&1, &2, &3); + let mut k = b"FinalKeys DoubleMap".to_vec(); k.extend(1u32.encode()); let mut k = runtime_io::blake2_256(&k).to_vec(); k.extend(&runtime_io::blake2_256(&2u32.encode())); assert_eq!(unhashed::get::(&k), Some(3u32)); - DoubleMap2::insert(1, 2, 3); - let mut k = b"Module DoubleMap2".to_vec(); + DoubleMap2::insert(&1, &2, &3); + let mut k = b"FinalKeys DoubleMap2".to_vec(); k.extend(1u32.encode()); let mut k = runtime_io::twox_128(&k).to_vec(); k.extend(&runtime_io::blake2_128(&2u32.encode())); diff --git a/substrate/srml/support/test/tests/instance.rs b/substrate/srml/support/test/tests/instance.rs index a5f40878e0..4702105bba 100644 --- a/substrate/srml/support/test/tests/instance.rs +++ b/substrate/srml/support/test/tests/instance.rs @@ -335,14 +335,14 @@ fn storage_instance_independance() { module2::LinkedMap::::key_for(1).to_vec(), module2::LinkedMap::::key_for(1).to_vec(), module2::LinkedMap::::key_for(1).to_vec(), - module2::DoubleMap::::prefix_for(1), - module2::DoubleMap::::prefix_for(1).to_vec(), - module2::DoubleMap::::prefix_for(1).to_vec(), - module2::DoubleMap::::prefix_for(1).to_vec(), - module2::DoubleMap::::key_for(1, 1), - module2::DoubleMap::::key_for(1, 1).to_vec(), - module2::DoubleMap::::key_for(1, 1).to_vec(), - module2::DoubleMap::::key_for(1, 1).to_vec(), + module2::DoubleMap::::prefix_for(&1), + module2::DoubleMap::::prefix_for(&1).to_vec(), + module2::DoubleMap::::prefix_for(&1).to_vec(), + module2::DoubleMap::::prefix_for(&1).to_vec(), + module2::DoubleMap::::key_for(&1, &1), + module2::DoubleMap::::key_for(&1, &1).to_vec(), + module2::DoubleMap::::key_for(&1, &1).to_vec(), + module2::DoubleMap::::key_for(&1, &1).to_vec(), ].iter() { assert!(map.insert(key, ()).is_none()) } @@ -396,15 +396,15 @@ fn storage_with_instance_basic_operation() { let key1 = 1; let key2 = 1; - assert_eq!(DoubleMap::exists(0, 0), true); - assert_eq!(DoubleMap::exists(key1, key2), false); - DoubleMap::insert(key1, key2, 1); - assert_eq!(DoubleMap::get(key1, key2), 1); - assert_eq!(DoubleMap::take(key1, key2), 1); - assert_eq!(DoubleMap::get(key1, key2), 0); - DoubleMap::mutate(key1, key2, |a| *a=2); - assert_eq!(DoubleMap::get(key1, key2), 2); - DoubleMap::remove(key1, key2); - assert_eq!(DoubleMap::get(key1, key2), 0); + assert_eq!(DoubleMap::exists(&0, &0), true); + assert_eq!(DoubleMap::exists(&key1, &key2), false); + DoubleMap::insert(&key1, &key2, &1); + assert_eq!(DoubleMap::get(&key1, &key2), 1); + assert_eq!(DoubleMap::take(&key1, &key2), 1); + assert_eq!(DoubleMap::get(&key1, &key2), 0); + DoubleMap::mutate(&key1, &key2, |a| *a=2); + assert_eq!(DoubleMap::get(&key1, &key2), 2); + DoubleMap::remove(&key1, &key2); + assert_eq!(DoubleMap::get(&key1, &key2), 0); }); }