From c24960320a3e11eb5f683f5af1407e4d96d77dea Mon Sep 17 00:00:00 2001 From: thiolliere Date: Fri, 12 Apr 2019 17:32:37 +0200 Subject: [PATCH 01/22] remove default hash, introduce twox_128 and blake2 --- core/client/src/client.rs | 14 +- core/client/src/light/fetcher.rs | 6 +- core/rpc/src/state/tests.rs | 6 +- core/sr-primitives/src/lib.rs | 8 - core/test-runtime/src/genesismap.rs | 4 +- core/test-runtime/src/system.rs | 22 +- node/executor/src/lib.rs | 26 +- srml/executive/src/lib.rs | 2 +- srml/indices/src/lib.rs | 15 +- srml/support/procedural/src/storage/impls.rs | 122 ++++---- .../procedural/src/storage/transformation.rs | 68 ++-- srml/support/src/lib.rs | 7 +- srml/support/src/metadata.rs | 4 + .../src/storage/blake2_256/generator.rs | 125 ++++++++ srml/support/src/storage/blake2_256/mod.rs | 95 ++++++ srml/support/src/storage/child.rs | 0 srml/support/src/storage/mod.rs | 262 +++------------- .../{generator.rs => storage_items.rs} | 291 ++++-------------- .../support/src/storage/twox_128/generator.rs | 143 +++++++++ srml/support/src/storage/twox_128/mod.rs | 223 ++++++++++++++ .../support/src/storage/unhashed/generator.rs | 16 +- srml/support/src/storage/unhashed/mod.rs | 2 +- 22 files changed, 852 insertions(+), 609 deletions(-) create mode 100644 srml/support/src/storage/blake2_256/generator.rs create mode 100644 srml/support/src/storage/blake2_256/mod.rs create mode 100644 srml/support/src/storage/child.rs rename srml/support/src/storage/{generator.rs => storage_items.rs} (74%) create mode 100644 srml/support/src/storage/twox_128/generator.rs create mode 100644 srml/support/src/storage/twox_128/mod.rs diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 041933cfffaff..dbf130f733246 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1534,7 +1534,7 @@ impl backend::AuxStore for Client pub(crate) mod tests { use std::collections::HashMap; use super::*; - use primitives::twox_128; + use primitives::blake2_256; use runtime_primitives::traits::DigestItem as DigestItemT; use runtime_primitives::generic::DigestItem; use test_client::{self, TestClient, AccountKeyring}; @@ -1584,12 +1584,12 @@ pub(crate) mod tests { } // prepare test cases - let alice = twox_128(&runtime::system::balance_of_key(AccountKeyring::Alice.into())).to_vec(); - let bob = twox_128(&runtime::system::balance_of_key(AccountKeyring::Bob.into())).to_vec(); - let charlie = twox_128(&runtime::system::balance_of_key(AccountKeyring::Charlie.into())).to_vec(); - let dave = twox_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); - let eve = twox_128(&runtime::system::balance_of_key(AccountKeyring::Eve.into())).to_vec(); - let ferdie = twox_128(&runtime::system::balance_of_key(AccountKeyring::Ferdie.into())).to_vec(); + let alice = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Alice.into())).to_vec(); + let bob = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Bob.into())).to_vec(); + let charlie = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Charlie.into())).to_vec(); + let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let eve = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Eve.into())).to_vec(); + let ferdie = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Ferdie.into())).to_vec(); let test_cases = vec![ (1, 4, alice.clone(), vec![(4, 0), (1, 0)]), (1, 3, alice.clone(), vec![(1, 0)]), diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 4cbbc819b3141..7ddd6ee2f6d1a 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -404,7 +404,7 @@ pub mod tests { use crate::light::fetcher::{Fetcher, FetchChecker, LightDataChecker, RemoteCallRequest, RemoteHeaderRequest}; use crate::light::blockchain::tests::{DummyStorage, DummyBlockchain}; - use primitives::{twox_128, Blake2Hasher}; + use primitives::{blake2_256, Blake2Hasher}; use primitives::storage::{StorageKey, well_known_keys}; use runtime_primitives::generic::BlockId; use state_machine::Backend; @@ -587,7 +587,7 @@ pub mod tests { // we're testing this test case here: // (1, 4, dave.clone(), vec![(4, 0), (1, 1), (1, 0)]), let (remote_client, remote_roots, _) = prepare_client_with_key_changes(); - let dave = twox_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); let dave = StorageKey(dave); // 'fetch' changes proof from remote node: @@ -699,7 +699,7 @@ pub mod tests { let (remote_client, remote_roots, _) = prepare_client_with_key_changes(); let local_cht_root = cht::compute_root::( 4, 0, remote_roots.iter().cloned().map(|ct| Ok(Some(ct)))).unwrap(); - let dave = twox_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); let dave = StorageKey(dave); // 'fetch' changes proof from remote node: diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index a63b8489eb090..dee64de13442e 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -17,7 +17,7 @@ use super::*; use self::error::{Error, ErrorKind}; -use sr_io::twox_128; +use sr_io::blake2_256; use assert_matches::assert_matches; use consensus::BlockOrigin; use test_client::{self, runtime, AccountKeyring, TestClient, BlockBuilderExt}; @@ -88,7 +88,7 @@ fn should_send_initial_storage_changes_and_notifications() { { let api = State::new(Arc::new(test_client::new()), Subscriptions::new(remote)); - let alice_balance_key = twox_128(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); + let alice_balance_key = blake2_256(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); api.subscribe_storage(Default::default(), subscriber, Some(vec![ StorageKey(alice_balance_key.to_vec()), @@ -147,7 +147,7 @@ fn should_query_storage() { let block2_hash = add_block(1); let genesis_hash = client.genesis_hash(); - let alice_balance_key = twox_128(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); + let alice_balance_key = blake2_256(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); let mut expected = vec![ StorageChangeSet { diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 5167e57072a2b..f59ea101d651b 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -90,14 +90,6 @@ pub use serde_derive::{Serialize, Deserialize}; /// Complex storage builder stuff. #[cfg(feature = "std")] pub trait BuildStorage: Sized { - /// Hash given slice. - /// - /// Default to xx128 hashing. - fn hash(data: &[u8]) -> [u8; 16] { - let r = runtime_io::twox_128(data); - log::trace!(target: "build_storage", "{} <= {}", substrate_primitives::hexdisplay::HexDisplay::from(&r), ascii_format(data)); - r - } /// Build the storage out of this builder. fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { let mut storage = Default::default(); diff --git a/core/test-runtime/src/genesismap.rs b/core/test-runtime/src/genesismap.rs index 13e9e5ec9a55d..be1c784a52778 100644 --- a/core/test-runtime/src/genesismap.rs +++ b/core/test-runtime/src/genesismap.rs @@ -17,7 +17,7 @@ //! Tool for creating the genesis block. use std::collections::HashMap; -use runtime_io::twox_128; +use runtime_io::{blake2_256, twox_128}; use super::AccountId; use parity_codec::{Encode, KeyedVec, Joiner}; use primitives::{ChangesTrieConfiguration, map, storage::well_known_keys}; @@ -47,7 +47,7 @@ impl GenesisConfig { let wasm_runtime = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm").to_vec(); let mut map: HashMap, Vec> = self.balances.iter() .map(|&(ref account, balance)| (account.to_keyed_vec(b"balance:"), vec![].and(&balance))) - .map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec())) + .map(|(k, v)| (blake2_256(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ (well_known_keys::CODE.into(), wasm_runtime), (well_known_keys::HEAP_PAGES.into(), vec![].and(&(16 as u64))), diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index 266b7130d4167..130688cb1bf53 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -45,11 +45,11 @@ pub fn balance_of_key(who: AccountId) -> Vec { } pub fn balance_of(who: AccountId) -> u64 { - storage::get_or(&balance_of_key(who), 0) + storage::blake2_256::get_or(&balance_of_key(who), 0) } pub fn nonce_of(who: AccountId) -> u64 { - storage::get_or(&who.to_keyed_vec(NONCE_OF), 0) + storage::blake2_256::get_or(&who.to_keyed_vec(NONCE_OF), 0) } /// Get authorities at given block. @@ -152,7 +152,7 @@ pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { let tx = utx.transfer(); let nonce_key = tx.from.to_keyed_vec(NONCE_OF); - let expected_nonce: u64 = storage::get_or(&nonce_key, 0); + let expected_nonce: u64 = storage::blake2_256::get_or(&nonce_key, 0); if tx.nonce < expected_nonce { return TransactionValidity::Invalid(ApplyError::Stale as i8); } @@ -241,26 +241,26 @@ fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { // check nonce let nonce_key = tx.from.to_keyed_vec(NONCE_OF); - let expected_nonce: u64 = storage::get_or(&nonce_key, 0); + let expected_nonce: u64 = storage::blake2_256::get_or(&nonce_key, 0); if !(tx.nonce == expected_nonce) { return Err(ApplyError::Stale) } // increment nonce in storage - storage::put(&nonce_key, &(expected_nonce + 1)); + storage::blake2_256::put(&nonce_key, &(expected_nonce + 1)); // check sender balance let from_balance_key = tx.from.to_keyed_vec(BALANCE_OF); - let from_balance: u64 = storage::get_or(&from_balance_key, 0); + let from_balance: u64 = storage::blake2_256::get_or(&from_balance_key, 0); // enact transfer if !(tx.amount <= from_balance) { return Err(ApplyError::CantPay) } let to_balance_key = tx.to.to_keyed_vec(BALANCE_OF); - let to_balance: u64 = storage::get_or(&to_balance_key, 0); - storage::put(&from_balance_key, &(from_balance - tx.amount)); - storage::put(&to_balance_key, &(to_balance + tx.amount)); + let to_balance: u64 = storage::blake2_256::get_or(&to_balance_key, 0); + storage::blake2_256::put(&from_balance_key, &(from_balance - tx.amount)); + storage::blake2_256::put(&to_balance_key, &(to_balance + tx.amount)); Ok(ApplyOutcome::Success) } @@ -295,7 +295,7 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { mod tests { use super::*; - use runtime_io::{with_externalities, twox_128, TestExternalities}; + use runtime_io::{with_externalities, twox_128, blake2_256, TestExternalities}; use parity_codec::{Joiner, KeyedVec}; use substrate_test_client::{AuthorityKeyring, AccountKeyring}; use crate::{Header, Transfer}; @@ -313,7 +313,7 @@ mod tests { twox_128(&0u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Alice.to_raw_public().to_vec(), twox_128(&1u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Bob.to_raw_public().to_vec(), twox_128(&2u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Charlie.to_raw_public().to_vec(), - twox_128(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + blake2_256(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ]) } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index c855a4e6f00c5..d1a8e0cda3583 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -34,7 +34,7 @@ mod tests { use keyring::{AuthorityKeyring, AccountKeyring}; use runtime_support::{Hashable, StorageValue, StorageMap, traits::Currency}; use state_machine::{CodeExecutor, Externalities, TestExternalities}; - use primitives::{twox_128, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, + use primitives::{twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded}; use node_primitives::{Hash, BlockNumber, AccountId}; use runtime_primitives::traits::{Header as HeaderT, Hash as HashT}; @@ -119,13 +119,13 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, map![ - twox_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -152,13 +152,13 @@ mod tests { #[test] fn bad_extrinsic_with_native_equivalent_code_gives_error() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, map![ - twox_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -185,13 +185,13 @@ mod tests { #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, map![ - twox_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -222,13 +222,13 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, map![ - twox_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -796,13 +796,13 @@ mod tests { fn panic_execution_gives_error() { let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm"); let mut t = TestExternalities::::new_with_code(foreign_code, map![ - twox_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -818,13 +818,13 @@ mod tests { fn successful_execution_gives_ok() { let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm"); let mut t = TestExternalities::::new_with_code(foreign_code, map![ - twox_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index 37b1b709f76e9..bf504d0918b6d 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -397,7 +397,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("49cd58a254ccf6abc4a023d9a22dcfc421e385527a250faec69f8ad0d8ed3e48").into(), + state_root: hex!("4c10fddf15e63c91ff2aa13ab3a9b7f6b19938d533829489e72ba40278a08fac").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs index 76261796c8b78..4a6010f800dec 100644 --- a/srml/indices/src/lib.rs +++ b/srml/indices/src/lib.rs @@ -96,16 +96,17 @@ decl_storage! { }): T::AccountIndex; /// The enumeration sets. - pub EnumSet get(enum_set): map T::AccountIndex => Vec; + pub EnumSet get(enum_set) build(|config: &GenesisConfig| { + (0..(config.ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE) + .map(|i| ( + T::AccountIndex::sa(i), + config.ids[i * ENUM_SET_SIZE..config.ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned(), + )) + .collect::>() + }): map T::AccountIndex => Vec; } add_extra_genesis { config(ids): Vec; - build(|storage: &mut primitives::StorageOverlay, _: &mut primitives::ChildrenStorageOverlay, config: &GenesisConfig| { - for i in 0..(config.ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE { - storage.insert(GenesisConfig::::hash(&>::key_for(T::AccountIndex::sa(i))).to_vec(), - config.ids[i * ENUM_SET_SIZE..config.ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned().encode()); - } - }); } } diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index 5a8f7f65d5d8e..f9500b62ff9cb 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -67,13 +67,13 @@ impl<'a, I: Iterator> Impls<'a, I> { let mutate_impl = if !is_option { quote!{ - >::put(&val, storage) + >::put(&val, storage) } } else { quote!{ match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), + Some(ref val) => >::put(&val, storage), + None => >::kill(storage), } } }; @@ -96,9 +96,12 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for value quote!{ #( #[ #attrs ] )* - #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#scrate::storage::generator::PhantomData<(#traitinstance #comma_instance)>); + #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance> + (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::StorageValue<#typ> for #name<#traitinstance, #instance> { + impl<#traitinstance: #traittype, #instance #bound_instantiable> + #scrate::storage::twox_128::generator::StorageValue<#typ> for #name<#traitinstance, #instance> + { type Query = #value_type; /// Get the storage key. @@ -107,20 +110,20 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value from the provided storage instance. - fn get(storage: &S) -> Self::Query { - storage.get(>::key()) + fn get(storage: &S) -> Self::Query { + storage.get(>::key()) .#option_simple_1(|| #fielddefault) } /// Take a value from storage, removing it afterwards. - fn take(storage: &S) -> Self::Query { - storage.take(>::key()) + fn take(storage: &S) -> Self::Query { + storage.take(>::key()) .#option_simple_1(|| #fielddefault) } /// Mutate the value under a key. - fn mutate R, S: #scrate::GenericStorage>(f: F, storage: &S) -> R { - let mut val = >::get(storage); + fn mutate R, S: #scrate::Twox128Storage>(f: F, storage: &S) -> R { + let mut val = >::get(storage); let ret = f(&mut val); #mutate_impl ; @@ -147,15 +150,17 @@ impl<'a, I: Iterator> Impls<'a, I> { let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; let option_simple_1 = option_unwrap(is_option); + let as_map = quote!{ > }; + let mutate_impl = if !is_option { quote!{ - >::insert(key, &val, storage) + #as_map::insert(key, &val, storage) } } else { quote!{ match val { - Some(ref val) => >::insert(key, &val, storage), - None => >::remove(key, storage), + Some(ref val) => #as_map::insert(key, &val, storage), + None => #as_map::remove(key, storage), } } }; @@ -178,9 +183,12 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for map quote!{ #( #[ #attrs ] )* - #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#scrate::storage::generator::PhantomData<(#traitinstance #comma_instance)>); + #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance> + (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> { + impl<#traitinstance: #traittype, #instance #bound_instantiable> + #scrate::storage::blake2_256::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + { type Query = #value_type; /// Get the prefix key in storage. @@ -190,26 +198,26 @@ impl<'a, I: Iterator> Impls<'a, I> { /// Get the storage key used to fetch a value corresponding to a specific key. fn key_for(x: &#kty) -> #scrate::rstd::vec::Vec { - let mut key = >::prefix().to_vec(); + let mut key = #as_map::prefix().to_vec(); #scrate::codec::Encode::encode_to(x, &mut key); key } /// Load the value associated with the given key from the map. - fn get(key: &#kty, storage: &S) -> Self::Query { - let key = >::key_for(key); + fn get(key: &#kty, storage: &S) -> Self::Query { + let key = #as_map::key_for(key); storage.get(&key[..]).#option_simple_1(|| #fielddefault) } /// Take the value, reading and removing it. - fn take(key: &#kty, storage: &S) -> Self::Query { - let key = >::key_for(key); + fn take(key: &#kty, storage: &S) -> Self::Query { + let key = #as_map::key_for(key); storage.take(&key[..]).#option_simple_1(|| #fielddefault) } /// Mutate the value under a key - fn mutate R, S: #scrate::GenericStorage>(key: &#kty, f: F, storage: &S) -> R { - let mut val = >::get(key, storage); + fn mutate R, S: #scrate::Blake2_256Storage>(key: &#kty, f: F, storage: &S) -> R { + let mut val = #as_map::get(key, storage); let ret = f(&mut val); #mutate_impl ; @@ -264,8 +272,8 @@ impl<'a, I: Iterator> Impls<'a, I> { let name_lowercase = name.to_string().to_lowercase(); let inner_module = syn::Ident::new(&format!("__linked_map_details_for_{}_do_not_use", name_lowercase), name.span()); let linkage = syn::Ident::new(&format!("__LinkageFor{}DoNotUse", name), name.span()); - let phantom_data = quote! { #scrate::storage::generator::PhantomData }; - let as_map = quote!{ > }; + let phantom_data = quote! { #scrate::rstd::marker::PhantomData }; + let as_map = quote!{ > }; let put_or_insert = quote! { match linkage { Some(linkage) => storage.put(key_for, &(val, linkage)), @@ -316,14 +324,17 @@ impl<'a, I: Iterator> Impls<'a, I> { pub _data: #phantom_data, } - impl<'a, S: #scrate::GenericStorage, #traitinstance: #traittype, #instance #bound_instantiable> Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)> + impl<'a, S: #scrate::Blake2_256Storage, #traitinstance: #traittype, #instance #bound_instantiable> + Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)> where #traitinstance: 'a { type Item = (#kty, #typ); fn next(&mut self) -> Option { let next = self.next.take()?; - let key_for = as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(&next); + let key_for = + as #scrate::storage::blake2_256::generator::StorageMap<#kty, #typ>>::key_for(&next); + let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for) .expect("previous/next only contain existing entires; we enumerate using next; entry exists; qed"); self.next = linkage.next; @@ -336,26 +347,26 @@ impl<'a, I: Iterator> Impls<'a, I> { /// /// Takes care of updating previous and next elements points /// as well as updates head if the element is first or last. - fn remove_linkage(linkage: Linkage<#kty>, storage: &S); + fn remove_linkage(linkage: Linkage<#kty>, storage: &S); /// Read the contained data and it's linkage. - fn read_with_linkage(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>; + fn read_with_linkage(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>; /// Generate linkage for newly inserted element. /// /// Takes care of updating head and previous head's pointer. - fn new_head_linkage( + fn new_head_linkage( storage: &S, key: &#kty, ) -> Linkage<#kty>; /// Read current head pointer. - fn read_head(storage: &S) -> Option<#kty>; + fn read_head(storage: &S) -> Option<#kty>; /// Overwrite current head pointer. /// /// If `None` is given head is removed from storage. - fn write_head(storage: &S, head: Option<&#kty>); + fn write_head(storage: &S, head: Option<&#kty>); } } }; @@ -365,7 +376,7 @@ impl<'a, I: Iterator> Impls<'a, I> { #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#phantom_data<(#traitinstance #comma_instance)>); impl<#traitinstance: #traittype, #instance #bound_instantiable> self::#inner_module::Utils<#traitinstance, #instance> for #name<#traitinstance, #instance> { - fn remove_linkage( + fn remove_linkage( linkage: self::#inner_module::Linkage<#kty>, storage: &S, ) { @@ -394,14 +405,14 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - fn read_with_linkage( + fn read_with_linkage( storage: &S, key: &[u8], ) -> Option<(#value_type, self::#inner_module::Linkage<#kty>)> { storage.get(key) } - fn new_head_linkage( + fn new_head_linkage( storage: &S, key: &#kty, ) -> self::#inner_module::Linkage<#kty> { @@ -433,11 +444,11 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - fn read_head(storage: &S) -> Option<#kty> { + fn read_head(storage: &S) -> Option<#kty> { storage.get(#final_head_key) } - fn write_head(storage: &S, head: Option<&#kty>) { + fn write_head(storage: &S, head: Option<&#kty>) { match head { Some(head) => storage.put(#final_head_key, head), None => storage.kill(#final_head_key), @@ -451,7 +462,9 @@ impl<'a, I: Iterator> Impls<'a, I> { #structure - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> { + impl<#traitinstance: #traittype, #instance #bound_instantiable> + #scrate::storage::blake2_256::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + { type Query = #value_type; /// Get the prefix key in storage. @@ -467,12 +480,12 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value associated with the given key from the map. - fn get(key: &#kty, storage: &S) -> Self::Query { + fn get(key: &#kty, storage: &S) -> Self::Query { storage.get(&*#as_map::key_for(key)).#option_simple_1(|| #fielddefault) } /// Take the value, reading and removing it. - fn take(key: &#kty, storage: &S) -> Self::Query { + fn take(key: &#kty, storage: &S) -> Self::Query { use self::#inner_module::Utils; let res: Option<(#value_type, self::#inner_module::Linkage<#kty>)> = storage.take(&*#as_map::key_for(key)); @@ -486,12 +499,12 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Remove the value under a key. - fn remove(key: &#kty, storage: &S) { + fn remove(key: &#kty, storage: &S) { #as_map::take(key, storage); } /// Store a value to be associated with the given key from the map. - fn insert(key: &#kty, val: &#typ, storage: &S) { + fn insert(key: &#kty, val: &#typ, storage: &S) { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -505,7 +518,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Mutate the value under a key - fn mutate R, S: #scrate::GenericStorage>(key: &#kty, f: F, storage: &S) -> R { + fn mutate R, S: #scrate::Blake2_256Storage>(key: &#kty, f: F, storage: &S) -> R { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -519,20 +532,22 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> #scrate::storage::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> { - fn head(storage: &S) -> Option<#kty> { + impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> + #scrate::storage::blake2_256::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> + { + fn head(storage: &S) -> Option<#kty> { use self::#inner_module::Utils; Self::read_head(storage) } - fn enumerate<'a, S: #scrate::GenericStorage>(storage: &'a S) -> #scrate::storage::generator::Box + 'a> where + fn enumerate<'a, S: #scrate::Blake2_256Storage>(storage: &'a S) -> #scrate::rstd::boxed::Box + 'a> where #kty: 'a, #typ: 'a, { use self::#inner_module::{Utils, Enumerator}; - #scrate::storage::generator::Box::new(Enumerator { + #scrate::rstd::boxed::Box::new(Enumerator { next: Self::read_head(storage), storage, _data: #phantom_data::<(#typ, #traitinstance, #instance)>::default(), @@ -593,9 +608,12 @@ impl<'a, I: Iterator> Impls<'a, I> { // generator for double map quote!{ #( #[ #attrs ] )* - #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#scrate::storage::generator::PhantomData<(#traitinstance #comma_instance)>); + #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance> + (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#traitinstance, #instance> { + impl<#traitinstance: #traittype, #instance #bound_instantiable> + #scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#traitinstance, #instance> + { type Query = #value_type; fn prefix() -> &'static [u8] { @@ -608,17 +626,17 @@ impl<'a, I: Iterator> Impls<'a, I> { key } - fn get(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query { + fn get(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query { let key = #as_double_map::key_for(key1, key2); storage.get(&key).#option_simple_1(|| #fielddefault) } - fn take(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query { + fn take(key1: &#k1ty, key2: &#k2ty, storage: &S) -> Self::Query { let key = #as_double_map::key_for(key1, key2); storage.take(&key).#option_simple_1(|| #fielddefault) } - fn mutate R, S: #scrate::GenericUnhashedStorage>(key1: &#k1ty, key2: &#k2ty, f: F, storage: &S) -> R { + fn mutate R, S: #scrate::UnhashedStorage>(key1: &#k1ty, key2: &#k2ty, f: F, storage: &S) -> R { let mut val = #as_double_map::get(key1, key2, storage); let ret = f(&mut val); diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index f00b5e8309bcc..3d87bb95f8848 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -156,13 +156,13 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> #module_ident<#traitinstance, #instance> { #impl_store_fns #[doc(hidden)] - pub fn store_metadata() -> #scrate::storage::generator::StorageMetadata { - #scrate::storage::generator::StorageMetadata { - functions: #scrate::storage::generator::DecodeDifferent::Encode(#store_functions_to_metadata) , + pub fn store_metadata() -> #scrate::metadata::StorageMetadata { + #scrate::metadata::StorageMetadata { + functions: #scrate::metadata::DecodeDifferent::Encode(#store_functions_to_metadata) , } } #[doc(hidden)] - pub fn store_metadata_functions() -> &'static [#scrate::storage::generator::StorageFunctionMetadata] { + pub fn store_metadata_functions() -> &'static [#scrate::metadata::StorageFunctionMetadata] { #store_functions_to_metadata } #[doc(hidden)] @@ -284,7 +284,7 @@ fn decl_store_extra_genesis( use #scrate::codec::{Encode, Decode}; let v = (#builder)(&self); - <#name<#traitinstance, #instance> as #scrate::storage::generator::StorageValue<#typ>>::put(&v, &storage); + <#name<#traitinstance, #instance> as #scrate::storage::twox_128::generator::StorageValue<#typ>>::put(&v, &storage); }} }, DeclStorageTypeInfosKind::Map { key_type, .. } => { @@ -294,7 +294,7 @@ fn decl_store_extra_genesis( let data = (#builder)(&self); for (k, v) in data.into_iter() { - <#name<#traitinstance, #instance> as #scrate::storage::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage); + <#name<#traitinstance, #instance> as #scrate::storage::blake2_256::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage); } }} }, @@ -402,7 +402,7 @@ fn decl_store_extra_genesis( quote!{ #[serde(skip)] - pub _genesis_phantom_data: #scrate::storage::generator::PhantomData<(#traitinstance #comma_instance)>, + pub _genesis_phantom_data: #scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>, }, quote!{ _genesis_phantom_data: Default::default(), @@ -440,12 +440,12 @@ fn decl_store_extra_genesis( #[cfg(feature = "std")] impl#fparam_impl #scrate::runtime_primitives::BuildStorage for GenesisConfig#sparam { fn assimilate_storage(self, r: &mut #scrate::runtime_primitives::StorageOverlay, c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay) -> ::std::result::Result<(), String> { - use #scrate::rstd::{cell::RefCell, marker::PhantomData}; - let storage = (RefCell::new(r), PhantomData::::default()); + use #scrate::rstd::cell::RefCell; + let storage = RefCell::new(r); #builders - let r = storage.0.into_inner(); + let r = storage.into_inner(); #scall(r, c, &self); @@ -662,15 +662,15 @@ fn impl_store_fns( quote!{ #( #[ #attrs ] )* pub fn #get_fn() -> #value_type { - <#name<#traitinstance, #instance> as #scrate::storage::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage) + <#name<#traitinstance, #instance> as #scrate::storage::twox_128::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage) } } }, DeclStorageTypeInfosKind::Map { key_type, .. } => { quote!{ #( #[ #attrs ] )* - pub fn #get_fn>(key: K) -> #value_type { - <#name<#traitinstance, #instance> as #scrate::storage::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) + pub fn #get_fn>(key: K) -> #value_type { + <#name<#traitinstance, #instance> as #scrate::storage::blake2_256::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) } } } @@ -678,8 +678,8 @@ fn impl_store_fns( quote!{ pub fn #get_fn(k1: KArg1, k2: KArg2) -> #value_type where - KArg1: #scrate::storage::generator::Borrow<#key1_type>, - KArg2: #scrate::storage::generator::Borrow<#key2_type>, + KArg1: #scrate::rstd::borrow::Borrow<#key1_type>, + KArg2: #scrate::rstd::borrow::Borrow<#key2_type>, { <#name<#traitinstance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ>> :: get(k1.borrow(), k2.borrow(), &#scrate::storage::RuntimeStorage) } @@ -727,17 +727,17 @@ fn store_functions_to_metadata ( let stype = match type_infos.kind { DeclStorageTypeInfosKind::Simple => { quote!{ - #scrate::storage::generator::StorageFunctionType::Plain( - #scrate::storage::generator::DecodeDifferent::Encode(#styp), + #scrate::metadata::StorageFunctionType::Plain( + #scrate::metadata::DecodeDifferent::Encode(#styp), ) } }, DeclStorageTypeInfosKind::Map { key_type, is_linked } => { let kty = clean_type_string("e!(#key_type).to_string()); quote!{ - #scrate::storage::generator::StorageFunctionType::Map { - key: #scrate::storage::generator::DecodeDifferent::Encode(#kty), - value: #scrate::storage::generator::DecodeDifferent::Encode(#styp), + #scrate::metadata::StorageFunctionType::Map { + key: #scrate::metadata::DecodeDifferent::Encode(#kty), + value: #scrate::metadata::DecodeDifferent::Encode(#styp), is_linked: #is_linked, } } @@ -747,22 +747,22 @@ fn store_functions_to_metadata ( let k2ty = clean_type_string("e!(#key2_type).to_string()); let k2_hasher = clean_type_string(&key2_hasher.to_string()); quote!{ - #scrate::storage::generator::StorageFunctionType::DoubleMap { - key1: #scrate::storage::generator::DecodeDifferent::Encode(#k1ty), - key2: #scrate::storage::generator::DecodeDifferent::Encode(#k2ty), - value: #scrate::storage::generator::DecodeDifferent::Encode(#styp), - key2_hasher: #scrate::storage::generator::DecodeDifferent::Encode(#k2_hasher), + #scrate::metadata::StorageFunctionType::DoubleMap { + key1: #scrate::metadata::DecodeDifferent::Encode(#k1ty), + key2: #scrate::metadata::DecodeDifferent::Encode(#k2ty), + value: #scrate::metadata::DecodeDifferent::Encode(#styp), + key2_hasher: #scrate::metadata::DecodeDifferent::Encode(#k2_hasher), } } }, }; let modifier = if type_infos.is_option { quote!{ - #scrate::storage::generator::StorageFunctionModifier::Optional + #scrate::metadata::StorageFunctionModifier::Optional } } else { quote!{ - #scrate::storage::generator::StorageFunctionModifier::Default + #scrate::metadata::StorageFunctionModifier::Default } }; let default = default_value.inner.as_ref().map(|d| &d.expr) @@ -786,16 +786,16 @@ fn store_functions_to_metadata ( let struct_name = proc_macro2::Ident::new(&("__GetByteStruct".to_string() + &str_name), name.span()); let cache_name = proc_macro2::Ident::new(&("__CACHE_GET_BYTE_STRUCT_".to_string() + &str_name), name.span()); let item = quote! { - #scrate::storage::generator::StorageFunctionMetadata { - name: #scrate::storage::generator::DecodeDifferent::Encode(#str_name), + #scrate::metadata::StorageFunctionMetadata { + name: #scrate::metadata::DecodeDifferent::Encode(#str_name), modifier: #modifier, ty: #stype, - default: #scrate::storage::generator::DecodeDifferent::Encode( - #scrate::storage::generator::DefaultByteGetter( + default: #scrate::metadata::DecodeDifferent::Encode( + #scrate::metadata::DefaultByteGetter( &#struct_name::<#traitinstance, #instance>(#scrate::rstd::marker::PhantomData) ) ), - documentation: #scrate::storage::generator::DecodeDifferent::Encode(&[ #docs ]), + documentation: #scrate::metadata::DecodeDifferent::Encode(&[ #docs ]), }, }; items.extend(item); @@ -806,7 +806,7 @@ fn store_functions_to_metadata ( #[allow(non_upper_case_globals)] static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::rstd::vec::Vec> = #scrate::once_cell::sync::OnceCell::INIT; #[cfg(feature = "std")] - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::DefaultByte for #struct_name<#traitinstance, #instance> { + impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte for #struct_name<#traitinstance, #instance> { fn default_byte(&self) -> #scrate::rstd::vec::Vec { use #scrate::codec::Encode; #cache_name.get_or_init(|| { @@ -816,7 +816,7 @@ fn store_functions_to_metadata ( } } #[cfg(not(feature = "std"))] - impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::storage::generator::DefaultByte for #struct_name<#traitinstance, #instance> { + impl<#traitinstance: #traittype, #instance #bound_instantiable> #scrate::metadata::DefaultByte for #struct_name<#traitinstance, #instance> { fn default_byte(&self) -> #scrate::rstd::vec::Vec { use #scrate::codec::Encode; let def_val: #value_type = #default; diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index d99db6ddb8287..bb8b2873839b3 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -35,8 +35,9 @@ pub use once_cell; pub use paste; pub use sr_primitives as runtime_primitives; -pub use self::storage::generator::Storage as GenericStorage; -pub use self::storage::unhashed::generator::UnhashedStorage as GenericUnhashedStorage; +pub use self::storage::twox_128::generator::Twox128Storage; +pub use self::storage::blake2_256::generator::Blake2_256Storage; +pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] pub mod dispatch; @@ -56,7 +57,7 @@ pub mod inherent; mod double_map; pub mod traits; -pub use self::storage::{StorageVec, StorageList, StorageValue, StorageMap, EnumerableStorageMap, StorageDoubleMap}; +pub use self::storage::{StorageList, StorageValue, StorageMap, EnumerableStorageMap, StorageDoubleMap}; pub use self::hashable::Hashable; pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType}; pub use self::double_map::StorageDoubleMapWithHasher; diff --git a/srml/support/src/metadata.rs b/srml/support/src/metadata.rs index f7594d27b7c2b..7ff39fd25687d 100644 --- a/srml/support/src/metadata.rs +++ b/srml/support/src/metadata.rs @@ -18,8 +18,12 @@ pub use srml_metadata::{ DecodeDifferent, FnEncode, RuntimeMetadata, ModuleMetadata, RuntimeMetadataV3, DefaultByteGetter, RuntimeMetadataPrefixed, + StorageMetadata, StorageFunctionMetadata, + StorageFunctionType, StorageFunctionModifier, + DefaultByte, }; + /// Implements the metadata support for the given runtime and all its modules. /// /// Example: diff --git a/srml/support/src/storage/blake2_256/generator.rs b/srml/support/src/storage/blake2_256/generator.rs new file mode 100644 index 0000000000000..f48a9026bef41 --- /dev/null +++ b/srml/support/src/storage/blake2_256/generator.rs @@ -0,0 +1,125 @@ +// Copyright 2019 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 . + +//! Abstract storage to use on Blake2_256Storage trait + +use crate::codec; +use crate::rstd::prelude::{Vec, Box}; +#[cfg(feature = "std")] +use crate::storage::unhashed::generator::UnhashedStorage; +#[cfg(feature = "std")] +use runtime_io::blake2_256; + +/// Abstraction around storage. +pub trait Blake2_256Storage { + /// true if the key exists in storage. + fn exists(&self, key: &[u8]) -> bool; + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. + fn get(&self, key: &[u8]) -> Option; + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if + /// it's not there. + fn require(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") } + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's + /// default is returned if it's not there. + fn get_or_default(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() } + + /// Put a value in under a key. + fn put(&self, key: &[u8], val: &T); + + /// Remove the bytes of a key from storage. + fn kill(&self, key: &[u8]); + + /// Take a value from storage, deleting it after reading. + fn take(&self, key: &[u8]) -> Option { + let value = self.get(key); + self.kill(key); + value + } + + /// Take a value from storage, deleting it after reading. + fn take_or_panic(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") } + + /// Take a value from storage, deleting it after reading. + fn take_or_default(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() } +} + +// We use a construct like this during when genesis storage is being built. +#[cfg(feature = "std")] +impl Blake2_256Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { + fn exists(&self, key: &[u8]) -> bool { + UnhashedStorage::exists(self, &blake2_256(key)) + } + + fn get(&self, key: &[u8]) -> Option { + UnhashedStorage::get(self, &blake2_256(key)) + } + + fn put(&self, key: &[u8], val: &T) { + UnhashedStorage::put(self, &blake2_256(key), val) + } + + fn kill(&self, key: &[u8]) { + UnhashedStorage::kill(self, &blake2_256(key)) + } +} + +/// A strongly-typed map in storage. +pub trait StorageMap { + /// 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(x: &K) -> Vec; + + /// true if the value is defined in storage. + fn exists(key: &K, storage: &S) -> bool { + storage.exists(&Self::key_for(key)[..]) + } + + /// Load the value associated with the given key from the map. + fn get(key: &K, storage: &S) -> Self::Query; + + /// Take the value under a key. + fn take(key: &K, storage: &S) -> Self::Query; + + /// Store a value to be associated with the given key from the map. + fn insert(key: &K, val: &V, storage: &S) { + storage.put(&Self::key_for(key)[..], val); + } + + /// Remove the value under a key. + fn remove(key: &K, storage: &S) { + storage.kill(&Self::key_for(key)[..]); + } + + /// Mutate the value under a key. + fn mutate R, S: Blake2_256Storage>(key: &K, f: F, storage: &S) -> R; +} + +/// A `StorageMap` with enumerable entries. +pub trait EnumerableStorageMap: StorageMap { + /// Return current head element. + fn head(storage: &S) -> Option; + + /// Enumerate all elements in the map. + fn enumerate<'a, S: Blake2_256Storage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; +} diff --git a/srml/support/src/storage/blake2_256/mod.rs b/srml/support/src/storage/blake2_256/mod.rs new file mode 100644 index 0000000000000..2bf0351bf448b --- /dev/null +++ b/srml/support/src/storage/blake2_256/mod.rs @@ -0,0 +1,95 @@ +// Copyright 2019 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 . + +//! Operation on runtime storage using blake2 256 to hash keys + +pub mod generator; + +use super::unhashed; +use crate::rstd::prelude::*; +use crate::codec::{Encode, Decode}; +use runtime_io::blake2_256; + +/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. +pub fn get(key: &[u8]) -> Option { + unhashed::get(&blake2_256(key)) +} + +/// Return the value of the item in storage under `key`, or the type's default if there is no +/// explicit entry. +pub fn get_or_default(key: &[u8]) -> T { + unhashed::get_or_default(&blake2_256(key)) +} + +/// Return the value of the item in storage under `key`, or `default_value` if there is no +/// explicit entry. +pub fn get_or(key: &[u8], default_value: T) -> T { + unhashed::get_or(&blake2_256(key), default_value) +} + +/// Return the value of the item in storage under `key`, or `default_value()` if there is no +/// explicit entry. +pub fn get_or_else T>(key: &[u8], default_value: F) -> T { + unhashed::get_or_else(&blake2_256(key), default_value) +} + +/// Put `value` in storage under `key`. +pub fn put(key: &[u8], value: &T) { + unhashed::put(&blake2_256(key), value) +} + +/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. +pub fn take(key: &[u8]) -> Option { + unhashed::take(&blake2_256(key)) +} + +/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, +/// the default for its type. +pub fn take_or_default(key: &[u8]) -> T { + unhashed::take_or_default(&blake2_256(key)) +} + +/// Return the value of the item in storage under `key`, or `default_value` if there is no +/// explicit entry. Ensure there is no explicit entry on return. +pub fn take_or(key: &[u8], default_value: T) -> T { + unhashed::take_or(&blake2_256(key), default_value) +} + +/// Return the value of the item in storage under `key`, or `default_value()` if there is no +/// explicit entry. Ensure there is no explicit entry on return. +pub fn take_or_else T>(key: &[u8], default_value: F) -> T { + unhashed::take_or_else(&blake2_256(key), default_value) +} + +/// Check to see if `key` has an explicit entry in storage. +pub fn exists(key: &[u8]) -> bool { + unhashed::exists(&blake2_256(key)) +} + +/// Ensure `key` has no explicit entry in storage. +pub fn kill(key: &[u8]) { + unhashed::kill(&blake2_256(key)) +} + +/// Get a Vec of bytes from storage. +pub fn get_raw(key: &[u8]) -> Option> { + unhashed::get_raw(&blake2_256(key)) +} + +/// Put a raw byte slice into storage. +pub fn put_raw(key: &[u8], value: &[u8]) { + unhashed::put_raw(&blake2_256(key), value) +} diff --git a/srml/support/src/storage/child.rs b/srml/support/src/storage/child.rs new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index b1b8766b9028a..c0b1b8b25d08c 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -18,12 +18,13 @@ use crate::rstd::prelude::*; use crate::rstd::borrow::Borrow; -use runtime_io::{self, twox_128}; use crate::codec::{Codec, Encode, Decode, KeyedVec, Input}; #[macro_use] -pub mod generator; +pub mod storage_items; pub mod unhashed; +pub mod twox_128; +pub mod blake2_256; struct IncrementalInput<'a> { key: &'a [u8], @@ -54,108 +55,62 @@ impl<'a> Input for IncrementalChildInput<'a> { } } +/// The underlying runtime storage. +pub struct RuntimeStorage; -/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. -pub fn get(key: &[u8]) -> Option { - unhashed::get(&twox_128(key)) -} - -/// Return the value of the item in storage under `key`, or the type's default if there is no -/// explicit entry. -pub fn get_or_default(key: &[u8]) -> T { - unhashed::get_or_default(&twox_128(key)) -} - -/// Return the value of the item in storage under `key`, or `default_value` if there is no -/// explicit entry. -pub fn get_or(key: &[u8], default_value: T) -> T { - unhashed::get_or(&twox_128(key), default_value) -} - -/// Return the value of the item in storage under `key`, or `default_value()` if there is no -/// explicit entry. -pub fn get_or_else T>(key: &[u8], default_value: F) -> T { - unhashed::get_or_else(&twox_128(key), default_value) -} - -/// Put `value` in storage under `key`. -pub fn put(key: &[u8], value: &T) { - unhashed::put(&twox_128(key), value) -} - -/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. -pub fn take(key: &[u8]) -> Option { - unhashed::take(&twox_128(key)) -} - -/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, -/// the default for its type. -pub fn take_or_default(key: &[u8]) -> T { - unhashed::take_or_default(&twox_128(key)) -} - -/// Return the value of the item in storage under `key`, or `default_value` if there is no -/// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or(key: &[u8], default_value: T) -> T { - unhashed::take_or(&twox_128(key), default_value) -} - -/// Return the value of the item in storage under `key`, or `default_value()` if there is no -/// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or_else T>(key: &[u8], default_value: F) -> T { - unhashed::take_or_else(&twox_128(key), default_value) -} +impl twox_128::generator::Twox128Storage for RuntimeStorage { + fn exists(&self, key: &[u8]) -> bool { + twox_128::exists(key) + } -/// Check to see if `key` has an explicit entry in storage. -pub fn exists(key: &[u8]) -> bool { - unhashed::exists(&twox_128(key)) -} + /// Load the bytes of a key from storage. Can panic if the type is incorrect. + fn get(&self, key: &[u8]) -> Option { + twox_128::get(key) + } -/// Ensure `key` has no explicit entry in storage. -pub fn kill(key: &[u8]) { - unhashed::kill(&twox_128(key)) -} + /// Put a value in under a key. + fn put(&self, key: &[u8], val: &T) { + twox_128::put(key, val) + } -/// Get a Vec of bytes from storage. -pub fn get_raw(key: &[u8]) -> Option> { - unhashed::get_raw(&twox_128(key)) -} + /// Remove the bytes of a key from storage. + fn kill(&self, key: &[u8]) { + twox_128::kill(key) + } -/// Put a raw byte slice into storage. -pub fn put_raw(key: &[u8], value: &[u8]) { - unhashed::put_raw(&twox_128(key), value) + /// Take a value from storage, deleting it after reading. + fn take(&self, key: &[u8]) -> Option { + twox_128::take(key) + } } -/// The underlying runtime storage. -pub struct RuntimeStorage; - -impl crate::GenericStorage for RuntimeStorage { +impl blake2_256::generator::Blake2_256Storage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { - exists(key) + blake2_256::exists(key) } /// Load the bytes of a key from storage. Can panic if the type is incorrect. fn get(&self, key: &[u8]) -> Option { - get(key) + blake2_256::get(key) } /// Put a value in under a key. fn put(&self, key: &[u8], val: &T) { - put(key, val) + blake2_256::put(key, val) } /// Remove the bytes of a key from storage. fn kill(&self, key: &[u8]) { - kill(key) + blake2_256::kill(key) } /// Take a value from storage, deleting it after reading. fn take(&self, key: &[u8]) -> Option { - take(key) + blake2_256::take(key) } } -impl crate::GenericUnhashedStorage for RuntimeStorage { +impl unhashed::generator::UnhashedStorage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { unhashed::exists(key) } @@ -213,11 +168,11 @@ pub trait StorageValue { fn take() -> Self::Query; } -impl StorageValue for U where U: generator::StorageValue { +impl StorageValue for U where U: twox_128::generator::StorageValue { type Query = U::Query; fn key() -> &'static [u8] { - >::key() + >::key() } fn exists() -> bool { U::exists(&RuntimeStorage) @@ -269,17 +224,17 @@ pub trait StorageList { fn clear(); } -impl StorageList for U where U: generator::StorageList { +impl StorageList for U where U: twox_128::generator::StorageList { fn prefix() -> &'static [u8] { - >::prefix() + >::prefix() } fn len_key() -> Vec { - >::len_key() + >::len_key() } fn key_for(index: u32) -> Vec { - >::key_for(index) + >::key_for(index) } fn items() -> Vec { @@ -337,15 +292,15 @@ pub trait StorageMap { fn take>(key: KeyArg) -> Self::Query; } -impl StorageMap for U where U: generator::StorageMap { +impl StorageMap for U where U: blake2_256::generator::StorageMap { type Query = U::Query; fn prefix() -> &'static [u8] { - >::prefix() + >::prefix() } fn key_for>(key: KeyArg) -> Vec { - >::key_for(key.borrow()) + >::key_for(key.borrow()) } fn exists>(key: KeyArg) -> bool { @@ -385,13 +340,13 @@ pub trait EnumerableStorageMap: StorageMap { fn enumerate() -> Box> where K: 'static, V: 'static; } -impl EnumerableStorageMap for U where U: generator::EnumerableStorageMap { +impl EnumerableStorageMap for U where U: blake2_256::generator::EnumerableStorageMap { fn head() -> Option { - >::head(&RuntimeStorage) + >::head(&RuntimeStorage) } fn enumerate() -> Box> where K: 'static, V: 'static { - >::enumerate(&RuntimeStorage) + >::enumerate(&RuntimeStorage) } } @@ -498,72 +453,13 @@ where } } -/// A trait to conveniently store a vector of storable data. -pub trait StorageVec { - type Item: Default + Sized + Codec; - const PREFIX: &'static [u8]; - - /// Get the current set of items. - fn items() -> Vec { - (0..Self::count()).into_iter().map(Self::item).collect() - } - - /// Set the current set of items. - fn set_items(items: I) - where - I: IntoIterator, - T: Borrow, - { - let mut count: u32 = 0; - - for i in items.into_iter() { - put(&count.to_keyed_vec(Self::PREFIX), i.borrow()); - count = count.checked_add(1).expect("exceeded runtime storage capacity"); - } - - Self::set_count(count); - } - - /// Push an item. - fn push(item: &Self::Item) { - let len = Self::count(); - put(&len.to_keyed_vec(Self::PREFIX), item); - Self::set_count(len + 1); - } - - fn set_item(index: u32, item: &Self::Item) { - if index < Self::count() { - put(&index.to_keyed_vec(Self::PREFIX), item); - } - } - - fn clear_item(index: u32) { - if index < Self::count() { - kill(&index.to_keyed_vec(Self::PREFIX)); - } - } - - fn item(index: u32) -> Self::Item { - get_or_default(&index.to_keyed_vec(Self::PREFIX)) - } - - fn set_count(count: u32) { - (count..Self::count()).for_each(Self::clear_item); - put(&b"len".to_keyed_vec(Self::PREFIX), &count); - } - - fn count() -> u32 { - get_or_default(&b"len".to_keyed_vec(Self::PREFIX)) - } -} - /// child storage NOTE could replace unhashed by having only one kind of storage (root being null storage /// key (storage_key can become Option<&[u8]>). /// This module is a currently only a variant of unhashed with additional `storage_key`. /// Note that `storage_key` must be unique and strong (strong in the sense of being long enough to /// avoid collision from a resistant hash function (which unique implies)). pub mod child { - use super::{runtime_io, Codec, Decode, Vec, IncrementalChildInput}; + use super::{Codec, Decode, Vec, IncrementalChildInput}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(storage_key: &[u8], key: &[u8]) -> Option { @@ -654,71 +550,3 @@ pub mod child { pub use super::unhashed::StorageVec; } - -#[cfg(test)] -mod tests { - use super::*; - use runtime_io::{twox_128, TestExternalities, with_externalities}; - - #[test] - fn integers_can_be_stored() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - let x = 69u32; - put(b":test", &x); - let y: u32 = get(b":test").unwrap(); - assert_eq!(x, y); - }); - with_externalities(&mut t, || { - let x = 69426942i64; - put(b":test", &x); - let y: i64 = get(b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn bools_can_be_stored() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - let x = true; - put(b":test", &x); - let y: bool = get(b":test").unwrap(); - assert_eq!(x, y); - }); - - with_externalities(&mut t, || { - let x = false; - put(b":test", &x); - let y: bool = get(b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn vecs_can_be_retrieved() { - let mut t = TestExternalities::default(); - with_externalities(&mut t, || { - runtime_io::set_storage(&twox_128(b":test"), b"\x2cHello world"); - let x = b"Hello world".to_vec(); - let y = get::>(b":test").unwrap(); - assert_eq!(x, y); - - }); - } - - #[test] - fn vecs_can_be_stored() { - let mut t = TestExternalities::default(); - let x = b"Hello world".to_vec(); - - with_externalities(&mut t, || { - put(b":test", &x); - }); - - with_externalities(&mut t, || { - let y: Vec = get(b":test").unwrap(); - assert_eq!(x, y); - }); - } -} diff --git a/srml/support/src/storage/generator.rs b/srml/support/src/storage/storage_items.rs similarity index 74% rename from srml/support/src/storage/generator.rs rename to srml/support/src/storage/storage_items.rs index 97bfc6dc200ec..54c239c4b8fda 100644 --- a/srml/support/src/storage/generator.rs +++ b/srml/support/src/storage/storage_items.rs @@ -46,10 +46,6 @@ //!# fn main() { } //! ``` -use crate::codec; -use crate::rstd::vec::Vec; -#[cfg(feature = "std")] -use crate::storage::unhashed::generator::UnhashedStorage; #[doc(hidden)] pub use crate::rstd::borrow::Borrow; #[doc(hidden)] @@ -57,176 +53,6 @@ pub use crate::rstd::marker::PhantomData; #[doc(hidden)] pub use crate::rstd::boxed::Box; -pub use srml_metadata::{ - DecodeDifferent, StorageMetadata, StorageFunctionMetadata, - StorageFunctionType, StorageFunctionModifier, - DefaultByte, DefaultByteGetter, -}; - -/// Abstraction around storage. -pub trait Storage { - /// true if the key exists in storage. - fn exists(&self, key: &[u8]) -> bool; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if - /// it's not there. - fn require(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's - /// default is returned if it's not there. - fn get_or_default(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() } - - /// Put a value in under a key. - fn put(&self, key: &[u8], val: &T); - - /// Remove the bytes of a key from storage. - fn kill(&self, key: &[u8]); - - /// Take a value from storage, deleting it after reading. - fn take(&self, key: &[u8]) -> Option { - let value = self.get(key); - self.kill(key); - value - } - - /// Take a value from storage, deleting it after reading. - fn take_or_panic(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") } - - /// Take a value from storage, deleting it after reading. - fn take_or_default(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() } -} - -// We use a construct like this during when genesis storage is being built. -#[cfg(feature = "std")] -impl Storage for (crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay>, PhantomData) { - fn exists(&self, key: &[u8]) -> bool { - UnhashedStorage::exists(self, &S::hash(key)) - } - - fn get(&self, key: &[u8]) -> Option { - UnhashedStorage::get(self, &S::hash(key)) - } - - fn put(&self, key: &[u8], val: &T) { - UnhashedStorage::put(self, &S::hash(key), val) - } - - fn kill(&self, key: &[u8]) { - UnhashedStorage::kill(self, &S::hash(key)) - } -} - -/// A strongly-typed value kept in storage. -pub trait StorageValue { - /// The type that get/take returns. - type Query; - - /// Get the storage key. - fn key() -> &'static [u8]; - - /// true if the value is defined in storage. - fn exists(storage: &S) -> bool { - storage.exists(Self::key()) - } - - /// Load the value from the provided storage instance. - fn get(storage: &S) -> Self::Query; - - /// Take a value from storage, removing it afterwards. - fn take(storage: &S) -> Self::Query; - - /// Store a value under this key into the provided storage instance. - fn put(val: &T, storage: &S) { - storage.put(Self::key(), val) - } - - /// Mutate this value - fn mutate R, S: Storage>(f: F, storage: &S) -> R; - - /// Clear the storage value. - fn kill(storage: &S) { - storage.kill(Self::key()) - } -} - -/// A strongly-typed list in storage. -pub trait StorageList { - /// Get the prefix key in storage. - fn prefix() -> &'static [u8]; - - /// Get the key used to put the length field. - fn len_key() -> Vec; - - /// Get the storage key used to fetch a value at a given index. - fn key_for(index: u32) -> Vec; - - /// Read out all the items. - fn items(storage: &S) -> Vec; - - /// Set the current set of items. - fn set_items(items: &[T], storage: &S); - - /// Set the item at the given index. - fn set_item(index: u32, item: &T, storage: &S); - - /// Load the value at given index. Returns `None` if the index is out-of-bounds. - fn get(index: u32, storage: &S) -> Option; - - /// Load the length of the list - fn len(storage: &S) -> u32; - - /// Clear the list. - fn clear(storage: &S); -} - -/// A strongly-typed map in storage. -pub trait StorageMap { - /// 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(x: &K) -> Vec; - - /// true if the value is defined in storage. - fn exists(key: &K, storage: &S) -> bool { - storage.exists(&Self::key_for(key)[..]) - } - - /// Load the value associated with the given key from the map. - fn get(key: &K, storage: &S) -> Self::Query; - - /// Take the value under a key. - fn take(key: &K, storage: &S) -> Self::Query; - - /// Store a value to be associated with the given key from the map. - fn insert(key: &K, val: &V, storage: &S) { - storage.put(&Self::key_for(key)[..], val); - } - - /// Remove the value under a key. - fn remove(key: &K, storage: &S) { - storage.kill(&Self::key_for(key)[..]); - } - - /// Mutate the value under a key. - fn mutate R, S: Storage>(key: &K, f: F, storage: &S) -> R; -} - -/// A `StorageMap` with enumerable entries. -pub trait EnumerableStorageMap: StorageMap { - /// Return current head element. - fn head(storage: &S) -> Option; - - /// Enumerate all elements in the map. - fn enumerate<'a, S: Storage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; -} - // FIXME #1466 Remove this in favor of `decl_storage` macro. /// Declares strongly-typed wrappers around codec-compatible types in storage. #[macro_export] @@ -352,12 +178,12 @@ macro_rules! __storage_items_internal { // generator for values. (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $key => $ty } - pub fn $get_fn() -> $gettype { <$name as $crate::storage::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) } + pub fn $get_fn() -> $gettype { <$name as $crate::storage::twox_128::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) } }; (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { $($vis)* struct $name; - impl $crate::storage::generator::StorageValue<$ty> for $name { + impl $crate::storage::twox_128::generator::StorageValue<$ty> for $name { type Query = $gettype; /// Get the storage key. @@ -366,29 +192,29 @@ macro_rules! __storage_items_internal { } /// Load the value from the provided storage instance. - fn get(storage: &S) -> Self::Query { + fn get(storage: &S) -> Self::Query { storage.$getter($key) } /// Take a value from storage, removing it afterwards. - fn take(storage: &S) -> Self::Query { + fn take(storage: &S) -> Self::Query { storage.$taker($key) } /// Mutate this value. - fn mutate R, S: $crate::GenericStorage>(f: F, storage: &S) -> R { - let mut val = >::get(storage); + fn mutate R, S: $crate::Twox128Storage>(f: F, storage: &S) -> R { + let mut val = >::get(storage); let ret = f(&mut val); $crate::__handle_wrap_internal!($wraptype { // raw type case - >::put(&val, storage) + >::put(&val, storage) } { // Option<> type case match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), + Some(ref val) => >::put(&val, storage), + None => >::kill(storage), } }); @@ -400,13 +226,13 @@ macro_rules! __storage_items_internal { (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] } pub fn $get_fn>(key: K) -> $gettype { - <$name as $crate::storage::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) + <$name as $crate::storage::blake2_256::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) } }; (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $($vis)* struct $name; - impl $crate::storage::generator::StorageMap<$kty, $ty> for $name { + impl $crate::storage::blake2_256::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; /// Get the prefix key in storage. @@ -422,31 +248,31 @@ macro_rules! __storage_items_internal { } /// Load the value associated with the given key from the map. - fn get(key: &$kty, storage: &S) -> Self::Query { - let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); + fn get(key: &$kty, storage: &S) -> Self::Query { + let key = <$name as $crate::storage::blake2_256::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$getter(&key[..]) } /// Take the value, reading and removing it. - fn take(key: &$kty, storage: &S) -> Self::Query { - let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); + fn take(key: &$kty, storage: &S) -> Self::Query { + let key = <$name as $crate::storage::blake2_256::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$taker(&key[..]) } /// Mutate the value under a key. - fn mutate R, S: $crate::GenericStorage>(key: &$kty, f: F, storage: &S) -> R { - let mut val = >::take(key, storage); + fn mutate R, S: $crate::Blake2_256Storage>(key: &$kty, f: F, storage: &S) -> R { + let mut val = >::take(key, storage); let ret = f(&mut val); $crate::__handle_wrap_internal!($wraptype { // raw type case - >::insert(key, &val, storage) + >::insert(key, &val, storage) } { // Option<> type case match val { - Some(ref val) => >::insert(key, &val, storage), - None => >::remove(key, storage), + Some(ref val) => >::insert(key, &val, storage), + None => >::remove(key, storage), } }); @@ -459,19 +285,19 @@ macro_rules! __storage_items_internal { $($vis)* struct $name; impl $name { - fn clear_item(index: u32, storage: &S) { - if index < <$name as $crate::storage::generator::StorageList<$ty>>::len(storage) { - storage.kill(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index)); + fn clear_item(index: u32, storage: &S) { + if index < <$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage) { + storage.kill(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::key_for(index)); } } - fn set_len(count: u32, storage: &S) { - (count..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage)).for_each(|i| $name::clear_item(i, storage)); - storage.put(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key(), &count); + fn set_len(count: u32, storage: &S) { + (count..<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage)).for_each(|i| $name::clear_item(i, storage)); + storage.put(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len_key(), &count); } } - impl $crate::storage::generator::StorageList<$ty> for $name { + impl $crate::storage::twox_128::generator::StorageList<$ty> for $name { /// Get the prefix key in storage. fn prefix() -> &'static [u8] { $prefix @@ -492,43 +318,43 @@ macro_rules! __storage_items_internal { } /// Read out all the items. - fn items(storage: &S) -> $crate::rstd::vec::Vec<$ty> { - (0..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage)) - .map(|i| <$name as $crate::storage::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed")) + fn items(storage: &S) -> $crate::rstd::vec::Vec<$ty> { + (0..<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage)) + .map(|i| <$name as $crate::storage::twox_128::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed")) .collect() } /// Set the current set of items. - fn set_items(items: &[$ty], storage: &S) { + fn set_items(items: &[$ty], storage: &S) { $name::set_len(items.len() as u32, storage); items.iter() .enumerate() - .for_each(|(i, item)| <$name as $crate::storage::generator::StorageList<$ty>>::set_item(i as u32, item, storage)); + .for_each(|(i, item)| <$name as $crate::storage::twox_128::generator::StorageList<$ty>>::set_item(i as u32, item, storage)); } - fn set_item(index: u32, item: &$ty, storage: &S) { - if index < <$name as $crate::storage::generator::StorageList<$ty>>::len(storage) { - storage.put(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index)[..], item); + fn set_item(index: u32, item: &$ty, storage: &S) { + if index < <$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage) { + storage.put(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::key_for(index)[..], item); } } /// Load the value at given index. Returns `None` if the index is out-of-bounds. - fn get(index: u32, storage: &S) -> Option<$ty> { - storage.get(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index)[..]) + fn get(index: u32, storage: &S) -> Option<$ty> { + storage.get(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::key_for(index)[..]) } /// Load the length of the list. - fn len(storage: &S) -> u32 { - storage.get(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key()).unwrap_or_default() + fn len(storage: &S) -> u32 { + storage.get(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len_key()).unwrap_or_default() } /// Clear the list. - fn clear(storage: &S) { - for i in 0..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage) { + fn clear(storage: &S) { + for i in 0..<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage) { $name::clear_item(i, storage); } - storage.kill(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key()[..]) + storage.kill(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len_key()[..]) } } }; @@ -556,27 +382,11 @@ macro_rules! __handle_wrap_internal { mod tests { use std::collections::HashMap; use std::cell::RefCell; - use codec::{Decode, Encode}; use super::*; + use crate::metadata::*; use crate::rstd::marker::PhantomData; - - impl Storage for RefCell, Vec>> { - fn exists(&self, key: &[u8]) -> bool { - self.borrow_mut().get(key).is_some() - } - - fn get(&self, key: &[u8]) -> Option { - self.borrow_mut().get(key).map(|v| T::decode(&mut &v[..]).unwrap()) - } - - fn put(&self, key: &[u8], val: &T) { - self.borrow_mut().insert(key.to_owned(), val.encode()); - } - - fn kill(&self, key: &[u8]) { - self.borrow_mut().remove(key); - } - } + use crate::storage::twox_128::generator::*; + use crate::storage::blake2_256::generator::*; storage_items! { Value: b"a" => u32; @@ -586,7 +396,8 @@ mod tests { #[test] fn value() { - let storage = RefCell::new(HashMap::new()); + let mut overlay = HashMap::new(); + let storage = RefCell::new(&mut overlay); assert!(Value::get(&storage).is_none()); Value::put(&100_000, &storage); assert_eq!(Value::get(&storage), Some(100_000)); @@ -596,7 +407,8 @@ mod tests { #[test] fn list() { - let storage = RefCell::new(HashMap::new()); + let mut overlay = HashMap::new(); + let storage = RefCell::new(&mut overlay); assert_eq!(List::len(&storage), 0); assert!(List::items(&storage).is_empty()); @@ -615,7 +427,8 @@ mod tests { #[test] fn map() { - let storage = RefCell::new(HashMap::new()); + let mut overlay = HashMap::new(); + let storage = RefCell::new(&mut overlay); assert!(Map::get(&5, &storage).is_none()); Map::insert(&5, &[1; 32], &storage); assert_eq!(Map::get(&5, &storage), Some([1; 32])); @@ -625,7 +438,7 @@ mod tests { } pub trait Trait { - type Origin: codec::Encode + codec::Decode + ::std::default::Default; + type Origin: crate::codec::Encode + crate::codec::Decode + ::std::default::Default; type BlockNumber; } diff --git a/srml/support/src/storage/twox_128/generator.rs b/srml/support/src/storage/twox_128/generator.rs new file mode 100644 index 0000000000000..905047fecc752 --- /dev/null +++ b/srml/support/src/storage/twox_128/generator.rs @@ -0,0 +1,143 @@ +// Copyright 2019 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 . + +//! Abstract storage to use on Twox128Storage trait + +use crate::codec; +use crate::rstd::vec::Vec; +#[cfg(feature = "std")] +use crate::storage::unhashed::generator::UnhashedStorage; +#[cfg(feature = "std")] +use runtime_io::twox_128; + +/// Abstraction around storage. +pub trait Twox128Storage { + /// true if the key exists in storage. + fn exists(&self, key: &[u8]) -> bool; + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. + fn get(&self, key: &[u8]) -> Option; + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if + /// it's not there. + fn require(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") } + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's + /// default is returned if it's not there. + fn get_or_default(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() } + + /// Put a value in under a key. + fn put(&self, key: &[u8], val: &T); + + /// Remove the bytes of a key from storage. + fn kill(&self, key: &[u8]); + + /// Take a value from storage, deleting it after reading. + fn take(&self, key: &[u8]) -> Option { + let value = self.get(key); + self.kill(key); + value + } + + /// Take a value from storage, deleting it after reading. + fn take_or_panic(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") } + + /// Take a value from storage, deleting it after reading. + fn take_or_default(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() } +} + +// We use a construct like this during when genesis storage is being built. +#[cfg(feature = "std")] +impl Twox128Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { + fn exists(&self, key: &[u8]) -> bool { + UnhashedStorage::exists(self, &twox_128(key)) + } + + fn get(&self, key: &[u8]) -> Option { + UnhashedStorage::get(self, &twox_128(key)) + } + + fn put(&self, key: &[u8], val: &T) { + UnhashedStorage::put(self, &twox_128(key), val) + } + + fn kill(&self, key: &[u8]) { + UnhashedStorage::kill(self, &twox_128(key)) + } +} + +/// A strongly-typed value kept in storage. +pub trait StorageValue { + /// The type that get/take returns. + type Query; + + /// Get the storage key. + fn key() -> &'static [u8]; + + /// true if the value is defined in storage. + fn exists(storage: &S) -> bool { + storage.exists(Self::key()) + } + + /// Load the value from the provided storage instance. + fn get(storage: &S) -> Self::Query; + + /// Take a value from storage, removing it afterwards. + fn take(storage: &S) -> Self::Query; + + /// Store a value under this key into the provided storage instance. + fn put(val: &T, storage: &S) { + storage.put(Self::key(), val) + } + + /// Mutate this value + fn mutate R, S: Twox128Storage>(f: F, storage: &S) -> R; + + /// Clear the storage value. + fn kill(storage: &S) { + storage.kill(Self::key()) + } +} + +/// A strongly-typed list in storage. +pub trait StorageList { + /// Get the prefix key in storage. + fn prefix() -> &'static [u8]; + + /// Get the key used to put the length field. + fn len_key() -> Vec; + + /// Get the storage key used to fetch a value at a given index. + fn key_for(index: u32) -> Vec; + + /// Read out all the items. + fn items(storage: &S) -> Vec; + + /// Set the current set of items. + fn set_items(items: &[T], storage: &S); + + /// Set the item at the given index. + fn set_item(index: u32, item: &T, storage: &S); + + /// Load the value at given index. Returns `None` if the index is out-of-bounds. + fn get(index: u32, storage: &S) -> Option; + + /// Load the length of the list + fn len(storage: &S) -> u32; + + /// Clear the list. + fn clear(storage: &S); +} diff --git a/srml/support/src/storage/twox_128/mod.rs b/srml/support/src/storage/twox_128/mod.rs new file mode 100644 index 0000000000000..c0221c56f61a5 --- /dev/null +++ b/srml/support/src/storage/twox_128/mod.rs @@ -0,0 +1,223 @@ +// Copyright 2019 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 . + +//! Operation on runtime storage using twox 128 to hash keys + +pub mod generator; + +use super::unhashed; +use crate::rstd::prelude::*; +use crate::rstd::borrow::Borrow; +use runtime_io::{self, twox_128}; +use crate::codec::{Codec, Encode, Decode, KeyedVec}; + +/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. +pub fn get(key: &[u8]) -> Option { + unhashed::get(&twox_128(key)) +} + +/// Return the value of the item in storage under `key`, or the type's default if there is no +/// explicit entry. +pub fn get_or_default(key: &[u8]) -> T { + unhashed::get_or_default(&twox_128(key)) +} + +/// Return the value of the item in storage under `key`, or `default_value` if there is no +/// explicit entry. +pub fn get_or(key: &[u8], default_value: T) -> T { + unhashed::get_or(&twox_128(key), default_value) +} + +/// Return the value of the item in storage under `key`, or `default_value()` if there is no +/// explicit entry. +pub fn get_or_else T>(key: &[u8], default_value: F) -> T { + unhashed::get_or_else(&twox_128(key), default_value) +} + +/// Put `value` in storage under `key`. +pub fn put(key: &[u8], value: &T) { + unhashed::put(&twox_128(key), value) +} + +/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. +pub fn take(key: &[u8]) -> Option { + unhashed::take(&twox_128(key)) +} + +/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, +/// the default for its type. +pub fn take_or_default(key: &[u8]) -> T { + unhashed::take_or_default(&twox_128(key)) +} + +/// Return the value of the item in storage under `key`, or `default_value` if there is no +/// explicit entry. Ensure there is no explicit entry on return. +pub fn take_or(key: &[u8], default_value: T) -> T { + unhashed::take_or(&twox_128(key), default_value) +} + +/// Return the value of the item in storage under `key`, or `default_value()` if there is no +/// explicit entry. Ensure there is no explicit entry on return. +pub fn take_or_else T>(key: &[u8], default_value: F) -> T { + unhashed::take_or_else(&twox_128(key), default_value) +} + +/// Check to see if `key` has an explicit entry in storage. +pub fn exists(key: &[u8]) -> bool { + unhashed::exists(&twox_128(key)) +} + +/// Ensure `key` has no explicit entry in storage. +pub fn kill(key: &[u8]) { + unhashed::kill(&twox_128(key)) +} + +/// Get a Vec of bytes from storage. +pub fn get_raw(key: &[u8]) -> Option> { + unhashed::get_raw(&twox_128(key)) +} + +/// Put a raw byte slice into storage. +pub fn put_raw(key: &[u8], value: &[u8]) { + unhashed::put_raw(&twox_128(key), value) +} + +/// A trait to conveniently store a vector of storable data. +pub trait StorageVec { + type Item: Default + Sized + Codec; + const PREFIX: &'static [u8]; + + /// Get the current set of items. + fn items() -> Vec { + (0..Self::count()).into_iter().map(Self::item).collect() + } + + /// Set the current set of items. + fn set_items(items: I) + where + I: IntoIterator, + T: Borrow, + { + let mut count: u32 = 0; + + for i in items.into_iter() { + put(&count.to_keyed_vec(Self::PREFIX), i.borrow()); + count = count.checked_add(1).expect("exceeded runtime storage capacity"); + } + + Self::set_count(count); + } + + /// Push an item. + fn push(item: &Self::Item) { + let len = Self::count(); + put(&len.to_keyed_vec(Self::PREFIX), item); + Self::set_count(len + 1); + } + + fn set_item(index: u32, item: &Self::Item) { + if index < Self::count() { + put(&index.to_keyed_vec(Self::PREFIX), item); + } + } + + fn clear_item(index: u32) { + if index < Self::count() { + kill(&index.to_keyed_vec(Self::PREFIX)); + } + } + + fn item(index: u32) -> Self::Item { + get_or_default(&index.to_keyed_vec(Self::PREFIX)) + } + + fn set_count(count: u32) { + (count..Self::count()).for_each(Self::clear_item); + put(&b"len".to_keyed_vec(Self::PREFIX), &count); + } + + fn count() -> u32 { + get_or_default(&b"len".to_keyed_vec(Self::PREFIX)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use runtime_io::{twox_128, TestExternalities, with_externalities}; + + #[test] + fn integers_can_be_stored() { + let mut t = TestExternalities::default(); + with_externalities(&mut t, || { + let x = 69u32; + put(b":test", &x); + let y: u32 = get(b":test").unwrap(); + assert_eq!(x, y); + }); + with_externalities(&mut t, || { + let x = 69426942i64; + put(b":test", &x); + let y: i64 = get(b":test").unwrap(); + assert_eq!(x, y); + }); + } + + #[test] + fn bools_can_be_stored() { + let mut t = TestExternalities::default(); + with_externalities(&mut t, || { + let x = true; + put(b":test", &x); + let y: bool = get(b":test").unwrap(); + assert_eq!(x, y); + }); + + with_externalities(&mut t, || { + let x = false; + put(b":test", &x); + let y: bool = get(b":test").unwrap(); + assert_eq!(x, y); + }); + } + + #[test] + fn vecs_can_be_retrieved() { + let mut t = TestExternalities::default(); + with_externalities(&mut t, || { + runtime_io::set_storage(&twox_128(b":test"), b"\x2cHello world"); + let x = b"Hello world".to_vec(); + let y = get::>(b":test").unwrap(); + assert_eq!(x, y); + + }); + } + + #[test] + fn vecs_can_be_stored() { + let mut t = TestExternalities::default(); + let x = b"Hello world".to_vec(); + + with_externalities(&mut t, || { + put(b":test", &x); + }); + + with_externalities(&mut t, || { + let y: Vec = get(b":test").unwrap(); + assert_eq!(x, y); + }); + } +} diff --git a/srml/support/src/storage/unhashed/generator.rs b/srml/support/src/storage/unhashed/generator.rs index 2b046013bb944..d29d269beb692 100644 --- a/srml/support/src/storage/unhashed/generator.rs +++ b/srml/support/src/storage/unhashed/generator.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use crate::codec; -use runtime_io::twox_128; +use runtime_io::blake2_256; use crate::rstd::vec::Vec; /// Abstraction around storage with unhashed access. @@ -59,26 +59,26 @@ pub trait UnhashedStorage { // We use a construct like this during when genesis storage is being built. #[cfg(feature = "std")] -impl UnhashedStorage for (crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay>, H) { +impl UnhashedStorage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { fn exists(&self, key: &[u8]) -> bool { - self.0.borrow().contains_key(key) + self.borrow().contains_key(key) } fn get(&self, key: &[u8]) -> Option { - self.0.borrow().get(key) + self.borrow().get(key) .map(|x| codec::Decode::decode(&mut x.as_slice()).expect("Unable to decode expected type.")) } fn put(&self, key: &[u8], val: &T) { - self.0.borrow_mut().insert(key.to_vec(), codec::Encode::encode(val)); + self.borrow_mut().insert(key.to_vec(), codec::Encode::encode(val)); } fn kill(&self, key: &[u8]) { - self.0.borrow_mut().remove(key); + self.borrow_mut().remove(key); } fn kill_prefix(&self, prefix: &[u8]) { - self.0.borrow_mut().retain(|key, _| { + self.borrow_mut().retain(|key, _| { !key.starts_with(prefix) }) } @@ -110,7 +110,7 @@ pub trait StorageDoubleMap fn prefix_for(k1: &K1) -> Vec { let mut key = Self::prefix().to_vec(); codec::Encode::encode_to(k1, &mut key); - twox_128(&key).to_vec() + blake2_256(&key).to_vec() } /// true if the value is defined in storage. diff --git a/srml/support/src/storage/unhashed/mod.rs b/srml/support/src/storage/unhashed/mod.rs index 225c6756b80de..40e18d0cd212a 100644 --- a/srml/support/src/storage/unhashed/mod.rs +++ b/srml/support/src/storage/unhashed/mod.rs @@ -17,7 +17,7 @@ //! Operation on unhashed runtime storage use crate::rstd::borrow::Borrow; -use super::{runtime_io, Codec, Encode, Decode, KeyedVec, Vec, IncrementalInput}; +use super::{Codec, Encode, Decode, KeyedVec, Vec, IncrementalInput}; pub mod generator; From 285a30dc908d0e6424146ba7747151082ba805c5 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 15 Apr 2019 16:18:41 +0200 Subject: [PATCH 02/22] use blake2_128 & create ext_blake2_128 --- core/client/src/client.rs | 14 ++--- core/client/src/light/fetcher.rs | 6 +-- core/executor/src/wasm_executor.rs | 32 ++++++++++- core/executor/wasm/src/lib.rs | 3 +- core/primitives/src/lib.rs | 2 +- core/rpc/src/state/tests.rs | 6 +-- core/sr-io/with_std.rs | 4 +- core/sr-io/without_std.rs | 10 ++++ core/test-runtime/src/genesismap.rs | 4 +- core/test-runtime/src/system.rs | 22 ++++---- node/executor/src/lib.rs | 27 +++++----- node/runtime/src/lib.rs | 4 +- srml/executive/src/lib.rs | 2 +- srml/support/procedural/src/storage/impls.rs | 54 +++++++++---------- .../procedural/src/storage/transformation.rs | 4 +- srml/support/src/lib.rs | 2 +- .../{blake2_256 => blake2_128}/generator.rs | 32 +++++------ .../storage/{blake2_256 => blake2_128}/mod.rs | 28 +++++----- srml/support/src/storage/mod.rs | 26 ++++----- srml/support/src/storage/storage_items.rs | 24 ++++----- .../support/src/storage/unhashed/generator.rs | 4 +- 21 files changed, 176 insertions(+), 134 deletions(-) rename srml/support/src/storage/{blake2_256 => blake2_128}/generator.rs (80%) rename srml/support/src/storage/{blake2_256 => blake2_128}/mod.rs (83%) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index dbf130f733246..6b21643949024 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1534,7 +1534,7 @@ impl backend::AuxStore for Client pub(crate) mod tests { use std::collections::HashMap; use super::*; - use primitives::blake2_256; + use primitives::blake2_128; use runtime_primitives::traits::DigestItem as DigestItemT; use runtime_primitives::generic::DigestItem; use test_client::{self, TestClient, AccountKeyring}; @@ -1584,12 +1584,12 @@ pub(crate) mod tests { } // prepare test cases - let alice = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Alice.into())).to_vec(); - let bob = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Bob.into())).to_vec(); - let charlie = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Charlie.into())).to_vec(); - let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); - let eve = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Eve.into())).to_vec(); - let ferdie = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Ferdie.into())).to_vec(); + let alice = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Alice.into())).to_vec(); + let bob = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Bob.into())).to_vec(); + let charlie = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Charlie.into())).to_vec(); + let dave = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let eve = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Eve.into())).to_vec(); + let ferdie = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Ferdie.into())).to_vec(); let test_cases = vec![ (1, 4, alice.clone(), vec![(4, 0), (1, 0)]), (1, 3, alice.clone(), vec![(1, 0)]), diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 7ddd6ee2f6d1a..bb38777eeed39 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -404,7 +404,7 @@ pub mod tests { use crate::light::fetcher::{Fetcher, FetchChecker, LightDataChecker, RemoteCallRequest, RemoteHeaderRequest}; use crate::light::blockchain::tests::{DummyStorage, DummyBlockchain}; - use primitives::{blake2_256, Blake2Hasher}; + use primitives::{blake2_128, Blake2Hasher}; use primitives::storage::{StorageKey, well_known_keys}; use runtime_primitives::generic::BlockId; use state_machine::Backend; @@ -587,7 +587,7 @@ pub mod tests { // we're testing this test case here: // (1, 4, dave.clone(), vec![(4, 0), (1, 1), (1, 0)]), let (remote_client, remote_roots, _) = prepare_client_with_key_changes(); - let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let dave = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); let dave = StorageKey(dave); // 'fetch' changes proof from remote node: @@ -699,7 +699,7 @@ pub mod tests { let (remote_client, remote_roots, _) = prepare_client_with_key_changes(); let local_cht_root = cht::compute_root::( 4, 0, remote_roots.iter().cloned().map(|ct| Ok(Some(ct)))).unwrap(); - let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let dave = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); let dave = StorageKey(dave); // 'fetch' changes proof from remote node: diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index 42af29e9bae03..fce4b34711301 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -28,7 +28,7 @@ use wasmi::memory_units::{Pages}; use state_machine::Externalities; use crate::error::{Error, ErrorKind, Result}; use crate::wasm_utils::UserError; -use primitives::{blake2_256, twox_128, twox_256, ed25519, sr25519, Pair}; +use primitives::{blake2_128, blake2_256, twox_128, twox_256, ed25519, sr25519, Pair}; use primitives::hexdisplay::HexDisplay; use primitives::sandbox as sandbox_primitives; use primitives::{H256, Blake2Hasher}; @@ -451,6 +451,21 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, this.memory.set(out, &result).map_err(|_| UserError("Invalid attempt to set result in ext_twox_256"))?; Ok(()) }, + ext_blake2_128(data: *const u8, len: u32, out: *mut u8) => { + let result: [u8; 16] = if len == 0 { + let hashed = blake2_128(&[0u8; 0]); + this.hash_lookup.insert(hashed.to_vec(), vec![]); + hashed + } else { + let key = this.memory.get(data, len as usize).map_err(|_| UserError("Invalid attempt to get key in ext_blake2_128"))?; + let hashed_key = blake2_128(&key); + this.hash_lookup.insert(hashed_key.to_vec(), key); + hashed_key + }; + + this.memory.set(out, &result).map_err(|_| UserError("Invalid attempt to set result in ext_blake2_128"))?; + Ok(()) + }, ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => { let result: [u8; 32] = if len == 0 { blake2_256(&[0u8; 0]) @@ -910,6 +925,21 @@ mod tests { ); } + #[test] + fn blake2_128_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + assert_eq!( + WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_128", &[]).unwrap(), + blake2_128(&b""[..]).encode() + ); + assert_eq!( + WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_blake2_128", b"Hello world!").unwrap(), + blake2_128(&b"Hello world!"[..]).encode() + ); + } + + #[test] fn twox_256_should_work() { let mut ext = TestExternalities::default(); diff --git a/core/executor/wasm/src/lib.rs b/core/executor/wasm/src/lib.rs index dda9c617333a8..294c21d146ee0 100644 --- a/core/executor/wasm/src/lib.rs +++ b/core/executor/wasm/src/lib.rs @@ -7,7 +7,7 @@ use alloc::vec::Vec; use alloc::slice; use runtime_io::{ - set_storage, storage, clear_prefix, print, blake2_256, + set_storage, storage, clear_prefix, print, blake2_128, blake2_256, twox_128, twox_256, ed25519_verify, sr25519_verify, enumerated_trie_root }; @@ -68,6 +68,7 @@ impl_stubs!( input.to_vec() }, test_blake2_256 => |input| blake2_256(input).to_vec(), + test_blake2_128 => |input| blake2_128(input).to_vec(), test_twox_256 => |input| twox_256(input).to_vec(), test_twox_128 => |input| twox_128(input).to_vec(), test_ed25519_verify => |input: &[u8]| { diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index f078b5446f53b..c8a1de0a80417 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -46,7 +46,7 @@ pub use impl_serde::serialize as bytes; #[cfg(feature = "std")] pub mod hashing; #[cfg(feature = "std")] -pub use hashing::{blake2_256, twox_128, twox_256}; +pub use hashing::{blake2_128, blake2_256, twox_128, twox_256}; #[cfg(feature = "std")] pub mod hexdisplay; pub mod crypto; diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index dee64de13442e..13b57c97b7b87 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -17,7 +17,7 @@ use super::*; use self::error::{Error, ErrorKind}; -use sr_io::blake2_256; +use sr_io::blake2_128; use assert_matches::assert_matches; use consensus::BlockOrigin; use test_client::{self, runtime, AccountKeyring, TestClient, BlockBuilderExt}; @@ -88,7 +88,7 @@ fn should_send_initial_storage_changes_and_notifications() { { let api = State::new(Arc::new(test_client::new()), Subscriptions::new(remote)); - let alice_balance_key = blake2_256(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); + let alice_balance_key = blake2_128(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); api.subscribe_storage(Default::default(), subscriber, Some(vec![ StorageKey(alice_balance_key.to_vec()), @@ -147,7 +147,7 @@ fn should_query_storage() { let block2_hash = add_block(1); let genesis_hash = client.genesis_hash(); - let alice_balance_key = blake2_256(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); + let alice_balance_key = blake2_128(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); let mut expected = vec![ StorageChangeSet { diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index 1f4ce56fc9b0e..186db06de3a80 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -18,8 +18,8 @@ pub use parity_codec as codec; // re-export hashing functions. pub use primitives::{ - blake2_256, twox_128, twox_256, ed25519, Blake2Hasher, sr25519, - Pair + blake2_128, blake2_256, twox_128, twox_256, ed25519, Blake2Hasher, + sr25519, Pair }; pub use tiny_keccak::keccak256 as keccak_256; // Switch to this after PoC-3 diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index e4e32bd17d581..574c40842925d 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -273,6 +273,7 @@ extern_functions! { /// Hash calculation and verification fn ext_blake2_256_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8); + fn ext_blake2_128(data: *const u8, len: u32, out: *mut u8); fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); fn ext_twox_256(data: *const u8, len: u32, out: *mut u8); @@ -544,6 +545,15 @@ pub fn blake2_256(data: &[u8]) -> [u8; 32] { result } +/// Conduct a 128-bit Blake2 hash. +pub fn blake2_128(data: &[u8]) -> [u8; 16] { + let mut result: [u8; 16] = Default::default(); + unsafe { + ext_blake2_128.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); + } + result +} + /// Conduct a 256-bit Keccak hash. pub fn keccak_256(data: &[u8]) -> [u8; 32] { let mut result: [u8; 32] = Default::default(); diff --git a/core/test-runtime/src/genesismap.rs b/core/test-runtime/src/genesismap.rs index be1c784a52778..9cbf9a699ea65 100644 --- a/core/test-runtime/src/genesismap.rs +++ b/core/test-runtime/src/genesismap.rs @@ -17,7 +17,7 @@ //! Tool for creating the genesis block. use std::collections::HashMap; -use runtime_io::{blake2_256, twox_128}; +use runtime_io::{blake2_128, twox_128}; use super::AccountId; use parity_codec::{Encode, KeyedVec, Joiner}; use primitives::{ChangesTrieConfiguration, map, storage::well_known_keys}; @@ -47,7 +47,7 @@ impl GenesisConfig { let wasm_runtime = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm").to_vec(); let mut map: HashMap, Vec> = self.balances.iter() .map(|&(ref account, balance)| (account.to_keyed_vec(b"balance:"), vec![].and(&balance))) - .map(|(k, v)| (blake2_256(&k[..])[..].to_vec(), v.to_vec())) + .map(|(k, v)| (blake2_128(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ (well_known_keys::CODE.into(), wasm_runtime), (well_known_keys::HEAP_PAGES.into(), vec![].and(&(16 as u64))), diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index 130688cb1bf53..89e433e6c0923 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -45,11 +45,11 @@ pub fn balance_of_key(who: AccountId) -> Vec { } pub fn balance_of(who: AccountId) -> u64 { - storage::blake2_256::get_or(&balance_of_key(who), 0) + storage::blake2_128::get_or(&balance_of_key(who), 0) } pub fn nonce_of(who: AccountId) -> u64 { - storage::blake2_256::get_or(&who.to_keyed_vec(NONCE_OF), 0) + storage::blake2_128::get_or(&who.to_keyed_vec(NONCE_OF), 0) } /// Get authorities at given block. @@ -152,7 +152,7 @@ pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { let tx = utx.transfer(); let nonce_key = tx.from.to_keyed_vec(NONCE_OF); - let expected_nonce: u64 = storage::blake2_256::get_or(&nonce_key, 0); + let expected_nonce: u64 = storage::blake2_128::get_or(&nonce_key, 0); if tx.nonce < expected_nonce { return TransactionValidity::Invalid(ApplyError::Stale as i8); } @@ -241,26 +241,26 @@ fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { // check nonce let nonce_key = tx.from.to_keyed_vec(NONCE_OF); - let expected_nonce: u64 = storage::blake2_256::get_or(&nonce_key, 0); + let expected_nonce: u64 = storage::blake2_128::get_or(&nonce_key, 0); if !(tx.nonce == expected_nonce) { return Err(ApplyError::Stale) } // increment nonce in storage - storage::blake2_256::put(&nonce_key, &(expected_nonce + 1)); + storage::blake2_128::put(&nonce_key, &(expected_nonce + 1)); // check sender balance let from_balance_key = tx.from.to_keyed_vec(BALANCE_OF); - let from_balance: u64 = storage::blake2_256::get_or(&from_balance_key, 0); + let from_balance: u64 = storage::blake2_128::get_or(&from_balance_key, 0); // enact transfer if !(tx.amount <= from_balance) { return Err(ApplyError::CantPay) } let to_balance_key = tx.to.to_keyed_vec(BALANCE_OF); - let to_balance: u64 = storage::blake2_256::get_or(&to_balance_key, 0); - storage::blake2_256::put(&from_balance_key, &(from_balance - tx.amount)); - storage::blake2_256::put(&to_balance_key, &(to_balance + tx.amount)); + let to_balance: u64 = storage::blake2_128::get_or(&to_balance_key, 0); + storage::blake2_128::put(&from_balance_key, &(from_balance - tx.amount)); + storage::blake2_128::put(&to_balance_key, &(to_balance + tx.amount)); Ok(ApplyOutcome::Success) } @@ -295,7 +295,7 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { mod tests { use super::*; - use runtime_io::{with_externalities, twox_128, blake2_256, TestExternalities}; + use runtime_io::{with_externalities, twox_128, blake2_128, TestExternalities}; use parity_codec::{Joiner, KeyedVec}; use substrate_test_client::{AuthorityKeyring, AccountKeyring}; use crate::{Header, Transfer}; @@ -313,7 +313,7 @@ mod tests { twox_128(&0u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Alice.to_raw_public().to_vec(), twox_128(&1u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Bob.to_raw_public().to_vec(), twox_128(&2u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Charlie.to_raw_public().to_vec(), - blake2_256(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + blake2_128(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ]) } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index d1a8e0cda3583..f2435be9c18d8 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -34,7 +34,7 @@ mod tests { use keyring::{AuthorityKeyring, AccountKeyring}; use runtime_support::{Hashable, StorageValue, StorageMap, traits::Currency}; use state_machine::{CodeExecutor, Externalities, TestExternalities}; - use primitives::{twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, + use primitives::{twox_128, blake2_128, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded}; use node_primitives::{Hash, BlockNumber, AccountId}; use runtime_primitives::traits::{Header as HeaderT, Hash as HashT}; @@ -119,13 +119,13 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, map![ - blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -152,13 +152,13 @@ mod tests { #[test] fn bad_extrinsic_with_native_equivalent_code_gives_error() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, map![ - blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -170,6 +170,7 @@ mod tests { true, None, ).0; + println!("{:?}", r); assert!(r.is_ok()); let v = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, @@ -185,13 +186,13 @@ mod tests { #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, map![ - blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -222,13 +223,13 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, map![ - blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -796,13 +797,13 @@ mod tests { fn panic_execution_gives_error() { let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm"); let mut t = TestExternalities::::new_with_code(foreign_code, map![ - blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -818,13 +819,13 @@ mod tests { fn successful_execution_gives_ok() { let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm"); let mut t = TestExternalities::::new_with_code(foreign_code, map![ - blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index 79b0124f13b2b..94b910ed00b90 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -59,8 +59,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("node"), impl_name: create_runtime_str!("substrate-node"), authoring_version: 10, - spec_version: 57, - impl_version: 57, + spec_version: 58, + impl_version: 58, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index bf504d0918b6d..c8318e0caacc1 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -397,7 +397,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("4c10fddf15e63c91ff2aa13ab3a9b7f6b19938d533829489e72ba40278a08fac").into(), + state_root: hex!("bb9795ce18dac049e2eba0bee41c6d7c2d34129e532668a66f5ab8e5e89addeb").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index f9500b62ff9cb..b77cd9d26aa01 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -150,7 +150,7 @@ impl<'a, I: Iterator> Impls<'a, I> { let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; let option_simple_1 = option_unwrap(is_option); - let as_map = quote!{ > }; + let as_map = quote!{ > }; let mutate_impl = if !is_option { quote!{ @@ -187,7 +187,7 @@ impl<'a, I: Iterator> Impls<'a, I> { (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::blake2_256::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + #scrate::storage::blake2_128::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> { type Query = #value_type; @@ -204,19 +204,19 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value associated with the given key from the map. - fn get(key: &#kty, storage: &S) -> Self::Query { + fn get(key: &#kty, storage: &S) -> Self::Query { let key = #as_map::key_for(key); storage.get(&key[..]).#option_simple_1(|| #fielddefault) } /// Take the value, reading and removing it. - fn take(key: &#kty, storage: &S) -> Self::Query { + fn take(key: &#kty, storage: &S) -> Self::Query { let key = #as_map::key_for(key); storage.take(&key[..]).#option_simple_1(|| #fielddefault) } /// Mutate the value under a key - fn mutate R, S: #scrate::Blake2_256Storage>(key: &#kty, f: F, storage: &S) -> R { + fn mutate R, S: #scrate::Blake2_128Storage>(key: &#kty, f: F, storage: &S) -> R { let mut val = #as_map::get(key, storage); let ret = f(&mut val); @@ -273,7 +273,7 @@ impl<'a, I: Iterator> Impls<'a, I> { let inner_module = syn::Ident::new(&format!("__linked_map_details_for_{}_do_not_use", name_lowercase), name.span()); let linkage = syn::Ident::new(&format!("__LinkageFor{}DoNotUse", name), name.span()); let phantom_data = quote! { #scrate::rstd::marker::PhantomData }; - let as_map = quote!{ > }; + let as_map = quote!{ > }; let put_or_insert = quote! { match linkage { Some(linkage) => storage.put(key_for, &(val, linkage)), @@ -324,7 +324,7 @@ impl<'a, I: Iterator> Impls<'a, I> { pub _data: #phantom_data, } - impl<'a, S: #scrate::Blake2_256Storage, #traitinstance: #traittype, #instance #bound_instantiable> + impl<'a, S: #scrate::Blake2_128Storage, #traitinstance: #traittype, #instance #bound_instantiable> Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)> where #traitinstance: 'a { @@ -333,7 +333,7 @@ impl<'a, I: Iterator> Impls<'a, I> { fn next(&mut self) -> Option { let next = self.next.take()?; let key_for = - as #scrate::storage::blake2_256::generator::StorageMap<#kty, #typ>>::key_for(&next); + as #scrate::storage::blake2_128::generator::StorageMap<#kty, #typ>>::key_for(&next); let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for) .expect("previous/next only contain existing entires; we enumerate using next; entry exists; qed"); @@ -347,26 +347,26 @@ impl<'a, I: Iterator> Impls<'a, I> { /// /// Takes care of updating previous and next elements points /// as well as updates head if the element is first or last. - fn remove_linkage(linkage: Linkage<#kty>, storage: &S); + fn remove_linkage(linkage: Linkage<#kty>, storage: &S); /// Read the contained data and it's linkage. - fn read_with_linkage(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>; + fn read_with_linkage(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>; /// Generate linkage for newly inserted element. /// /// Takes care of updating head and previous head's pointer. - fn new_head_linkage( + fn new_head_linkage( storage: &S, key: &#kty, ) -> Linkage<#kty>; /// Read current head pointer. - fn read_head(storage: &S) -> Option<#kty>; + fn read_head(storage: &S) -> Option<#kty>; /// Overwrite current head pointer. /// /// If `None` is given head is removed from storage. - fn write_head(storage: &S, head: Option<&#kty>); + fn write_head(storage: &S, head: Option<&#kty>); } } }; @@ -376,7 +376,7 @@ impl<'a, I: Iterator> Impls<'a, I> { #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#phantom_data<(#traitinstance #comma_instance)>); impl<#traitinstance: #traittype, #instance #bound_instantiable> self::#inner_module::Utils<#traitinstance, #instance> for #name<#traitinstance, #instance> { - fn remove_linkage( + fn remove_linkage( linkage: self::#inner_module::Linkage<#kty>, storage: &S, ) { @@ -405,14 +405,14 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - fn read_with_linkage( + fn read_with_linkage( storage: &S, key: &[u8], ) -> Option<(#value_type, self::#inner_module::Linkage<#kty>)> { storage.get(key) } - fn new_head_linkage( + fn new_head_linkage( storage: &S, key: &#kty, ) -> self::#inner_module::Linkage<#kty> { @@ -444,11 +444,11 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - fn read_head(storage: &S) -> Option<#kty> { + fn read_head(storage: &S) -> Option<#kty> { storage.get(#final_head_key) } - fn write_head(storage: &S, head: Option<&#kty>) { + fn write_head(storage: &S, head: Option<&#kty>) { match head { Some(head) => storage.put(#final_head_key, head), None => storage.kill(#final_head_key), @@ -463,7 +463,7 @@ impl<'a, I: Iterator> Impls<'a, I> { #structure impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::blake2_256::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + #scrate::storage::blake2_128::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> { type Query = #value_type; @@ -480,12 +480,12 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value associated with the given key from the map. - fn get(key: &#kty, storage: &S) -> Self::Query { + fn get(key: &#kty, storage: &S) -> Self::Query { storage.get(&*#as_map::key_for(key)).#option_simple_1(|| #fielddefault) } /// Take the value, reading and removing it. - fn take(key: &#kty, storage: &S) -> Self::Query { + fn take(key: &#kty, storage: &S) -> Self::Query { use self::#inner_module::Utils; let res: Option<(#value_type, self::#inner_module::Linkage<#kty>)> = storage.take(&*#as_map::key_for(key)); @@ -499,12 +499,12 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Remove the value under a key. - fn remove(key: &#kty, storage: &S) { + fn remove(key: &#kty, storage: &S) { #as_map::take(key, storage); } /// Store a value to be associated with the given key from the map. - fn insert(key: &#kty, val: &#typ, storage: &S) { + fn insert(key: &#kty, val: &#typ, storage: &S) { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -518,7 +518,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Mutate the value under a key - fn mutate R, S: #scrate::Blake2_256Storage>(key: &#kty, f: F, storage: &S) -> R { + fn mutate R, S: #scrate::Blake2_128Storage>(key: &#kty, f: F, storage: &S) -> R { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -533,15 +533,15 @@ impl<'a, I: Iterator> Impls<'a, I> { } impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> - #scrate::storage::blake2_256::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> + #scrate::storage::blake2_128::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> { - fn head(storage: &S) -> Option<#kty> { + fn head(storage: &S) -> Option<#kty> { use self::#inner_module::Utils; Self::read_head(storage) } - fn enumerate<'a, S: #scrate::Blake2_256Storage>(storage: &'a S) -> #scrate::rstd::boxed::Box + 'a> where + fn enumerate<'a, S: #scrate::Blake2_128Storage>(storage: &'a S) -> #scrate::rstd::boxed::Box + 'a> where #kty: 'a, #typ: 'a, { diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 3d87bb95f8848..69a0cf8cc8d56 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -294,7 +294,7 @@ fn decl_store_extra_genesis( let data = (#builder)(&self); for (k, v) in data.into_iter() { - <#name<#traitinstance, #instance> as #scrate::storage::blake2_256::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage); + <#name<#traitinstance, #instance> as #scrate::storage::blake2_128::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage); } }} }, @@ -670,7 +670,7 @@ fn impl_store_fns( quote!{ #( #[ #attrs ] )* pub fn #get_fn>(key: K) -> #value_type { - <#name<#traitinstance, #instance> as #scrate::storage::blake2_256::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) + <#name<#traitinstance, #instance> as #scrate::storage::blake2_128::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) } } } diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index bb8b2873839b3..022c1c5c27e4a 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -36,7 +36,7 @@ pub use paste; pub use sr_primitives as runtime_primitives; pub use self::storage::twox_128::generator::Twox128Storage; -pub use self::storage::blake2_256::generator::Blake2_256Storage; +pub use self::storage::blake2_128::generator::Blake2_128Storage; pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] diff --git a/srml/support/src/storage/blake2_256/generator.rs b/srml/support/src/storage/blake2_128/generator.rs similarity index 80% rename from srml/support/src/storage/blake2_256/generator.rs rename to srml/support/src/storage/blake2_128/generator.rs index f48a9026bef41..94ec1910a8f4c 100644 --- a/srml/support/src/storage/blake2_256/generator.rs +++ b/srml/support/src/storage/blake2_128/generator.rs @@ -14,17 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Abstract storage to use on Blake2_256Storage trait +//! Abstract storage to use on Blake2_128Storage trait use crate::codec; use crate::rstd::prelude::{Vec, Box}; #[cfg(feature = "std")] use crate::storage::unhashed::generator::UnhashedStorage; #[cfg(feature = "std")] -use runtime_io::blake2_256; +use runtime_io::blake2_128; /// Abstraction around storage. -pub trait Blake2_256Storage { +pub trait Blake2_128Storage { /// true if the key exists in storage. fn exists(&self, key: &[u8]) -> bool; @@ -61,21 +61,21 @@ pub trait Blake2_256Storage { // We use a construct like this during when genesis storage is being built. #[cfg(feature = "std")] -impl Blake2_256Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { +impl Blake2_128Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { fn exists(&self, key: &[u8]) -> bool { - UnhashedStorage::exists(self, &blake2_256(key)) + UnhashedStorage::exists(self, &blake2_128(key)) } fn get(&self, key: &[u8]) -> Option { - UnhashedStorage::get(self, &blake2_256(key)) + UnhashedStorage::get(self, &blake2_128(key)) } fn put(&self, key: &[u8], val: &T) { - UnhashedStorage::put(self, &blake2_256(key), val) + UnhashedStorage::put(self, &blake2_128(key), val) } fn kill(&self, key: &[u8]) { - UnhashedStorage::kill(self, &blake2_256(key)) + UnhashedStorage::kill(self, &blake2_128(key)) } } @@ -91,35 +91,35 @@ pub trait StorageMap { fn key_for(x: &K) -> Vec; /// true if the value is defined in storage. - fn exists(key: &K, storage: &S) -> bool { + fn exists(key: &K, storage: &S) -> bool { storage.exists(&Self::key_for(key)[..]) } /// Load the value associated with the given key from the map. - fn get(key: &K, storage: &S) -> Self::Query; + fn get(key: &K, storage: &S) -> Self::Query; /// Take the value under a key. - fn take(key: &K, storage: &S) -> Self::Query; + fn take(key: &K, storage: &S) -> Self::Query; /// Store a value to be associated with the given key from the map. - fn insert(key: &K, val: &V, storage: &S) { + fn insert(key: &K, val: &V, storage: &S) { storage.put(&Self::key_for(key)[..], val); } /// Remove the value under a key. - fn remove(key: &K, storage: &S) { + fn remove(key: &K, storage: &S) { storage.kill(&Self::key_for(key)[..]); } /// Mutate the value under a key. - fn mutate R, S: Blake2_256Storage>(key: &K, f: F, storage: &S) -> R; + fn mutate R, S: Blake2_128Storage>(key: &K, f: F, storage: &S) -> R; } /// A `StorageMap` with enumerable entries. pub trait EnumerableStorageMap: StorageMap { /// Return current head element. - fn head(storage: &S) -> Option; + fn head(storage: &S) -> Option; /// Enumerate all elements in the map. - fn enumerate<'a, S: Blake2_256Storage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; + fn enumerate<'a, S: Blake2_128Storage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; } diff --git a/srml/support/src/storage/blake2_256/mod.rs b/srml/support/src/storage/blake2_128/mod.rs similarity index 83% rename from srml/support/src/storage/blake2_256/mod.rs rename to srml/support/src/storage/blake2_128/mod.rs index 2bf0351bf448b..d8642e1a54efa 100644 --- a/srml/support/src/storage/blake2_256/mod.rs +++ b/srml/support/src/storage/blake2_128/mod.rs @@ -21,75 +21,75 @@ pub mod generator; use super::unhashed; use crate::rstd::prelude::*; use crate::codec::{Encode, Decode}; -use runtime_io::blake2_256; +use runtime_io::blake2_128; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { - unhashed::get(&blake2_256(key)) + unhashed::get(&blake2_128(key)) } /// Return the value of the item in storage under `key`, or the type's default if there is no /// explicit entry. pub fn get_or_default(key: &[u8]) -> T { - unhashed::get_or_default(&blake2_256(key)) + unhashed::get_or_default(&blake2_128(key)) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. pub fn get_or(key: &[u8], default_value: T) -> T { - unhashed::get_or(&blake2_256(key), default_value) + unhashed::get_or(&blake2_128(key), default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. pub fn get_or_else T>(key: &[u8], default_value: F) -> T { - unhashed::get_or_else(&blake2_256(key), default_value) + unhashed::get_or_else(&blake2_128(key), default_value) } /// Put `value` in storage under `key`. pub fn put(key: &[u8], value: &T) { - unhashed::put(&blake2_256(key), value) + unhashed::put(&blake2_128(key), value) } /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. pub fn take(key: &[u8]) -> Option { - unhashed::take(&blake2_256(key)) + unhashed::take(&blake2_128(key)) } /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, /// the default for its type. pub fn take_or_default(key: &[u8]) -> T { - unhashed::take_or_default(&blake2_256(key)) + unhashed::take_or_default(&blake2_128(key)) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. Ensure there is no explicit entry on return. pub fn take_or(key: &[u8], default_value: T) -> T { - unhashed::take_or(&blake2_256(key), default_value) + unhashed::take_or(&blake2_128(key), default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. Ensure there is no explicit entry on return. pub fn take_or_else T>(key: &[u8], default_value: F) -> T { - unhashed::take_or_else(&blake2_256(key), default_value) + unhashed::take_or_else(&blake2_128(key), default_value) } /// Check to see if `key` has an explicit entry in storage. pub fn exists(key: &[u8]) -> bool { - unhashed::exists(&blake2_256(key)) + unhashed::exists(&blake2_128(key)) } /// Ensure `key` has no explicit entry in storage. pub fn kill(key: &[u8]) { - unhashed::kill(&blake2_256(key)) + unhashed::kill(&blake2_128(key)) } /// Get a Vec of bytes from storage. pub fn get_raw(key: &[u8]) -> Option> { - unhashed::get_raw(&blake2_256(key)) + unhashed::get_raw(&blake2_128(key)) } /// Put a raw byte slice into storage. pub fn put_raw(key: &[u8], value: &[u8]) { - unhashed::put_raw(&blake2_256(key), value) + unhashed::put_raw(&blake2_128(key), value) } diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index c0b1b8b25d08c..0a6a921c8bd35 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -24,7 +24,7 @@ use crate::codec::{Codec, Encode, Decode, KeyedVec, Input}; pub mod storage_items; pub mod unhashed; pub mod twox_128; -pub mod blake2_256; +pub mod blake2_128; struct IncrementalInput<'a> { key: &'a [u8], @@ -84,29 +84,29 @@ impl twox_128::generator::Twox128Storage for RuntimeStorage { } } -impl blake2_256::generator::Blake2_256Storage for RuntimeStorage { +impl blake2_128::generator::Blake2_128Storage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { - blake2_256::exists(key) + blake2_128::exists(key) } /// Load the bytes of a key from storage. Can panic if the type is incorrect. fn get(&self, key: &[u8]) -> Option { - blake2_256::get(key) + blake2_128::get(key) } /// Put a value in under a key. fn put(&self, key: &[u8], val: &T) { - blake2_256::put(key, val) + blake2_128::put(key, val) } /// Remove the bytes of a key from storage. fn kill(&self, key: &[u8]) { - blake2_256::kill(key) + blake2_128::kill(key) } /// Take a value from storage, deleting it after reading. fn take(&self, key: &[u8]) -> Option { - blake2_256::take(key) + blake2_128::take(key) } } @@ -292,15 +292,15 @@ pub trait StorageMap { fn take>(key: KeyArg) -> Self::Query; } -impl StorageMap for U where U: blake2_256::generator::StorageMap { +impl StorageMap for U where U: blake2_128::generator::StorageMap { type Query = U::Query; fn prefix() -> &'static [u8] { - >::prefix() + >::prefix() } fn key_for>(key: KeyArg) -> Vec { - >::key_for(key.borrow()) + >::key_for(key.borrow()) } fn exists>(key: KeyArg) -> bool { @@ -340,13 +340,13 @@ pub trait EnumerableStorageMap: StorageMap { fn enumerate() -> Box> where K: 'static, V: 'static; } -impl EnumerableStorageMap for U where U: blake2_256::generator::EnumerableStorageMap { +impl EnumerableStorageMap for U where U: blake2_128::generator::EnumerableStorageMap { fn head() -> Option { - >::head(&RuntimeStorage) + >::head(&RuntimeStorage) } fn enumerate() -> Box> where K: 'static, V: 'static { - >::enumerate(&RuntimeStorage) + >::enumerate(&RuntimeStorage) } } diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 54c239c4b8fda..ac589f4d7fba8 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -226,13 +226,13 @@ macro_rules! __storage_items_internal { (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] } pub fn $get_fn>(key: K) -> $gettype { - <$name as $crate::storage::blake2_256::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) + <$name as $crate::storage::blake2_128::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) } }; (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $($vis)* struct $name; - impl $crate::storage::blake2_256::generator::StorageMap<$kty, $ty> for $name { + impl $crate::storage::blake2_128::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; /// Get the prefix key in storage. @@ -248,31 +248,31 @@ macro_rules! __storage_items_internal { } /// Load the value associated with the given key from the map. - fn get(key: &$kty, storage: &S) -> Self::Query { - let key = <$name as $crate::storage::blake2_256::generator::StorageMap<$kty, $ty>>::key_for(key); + fn get(key: &$kty, storage: &S) -> Self::Query { + let key = <$name as $crate::storage::blake2_128::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$getter(&key[..]) } /// Take the value, reading and removing it. - fn take(key: &$kty, storage: &S) -> Self::Query { - let key = <$name as $crate::storage::blake2_256::generator::StorageMap<$kty, $ty>>::key_for(key); + fn take(key: &$kty, storage: &S) -> Self::Query { + let key = <$name as $crate::storage::blake2_128::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$taker(&key[..]) } /// Mutate the value under a key. - fn mutate R, S: $crate::Blake2_256Storage>(key: &$kty, f: F, storage: &S) -> R { - let mut val = >::take(key, storage); + fn mutate R, S: $crate::Blake2_128Storage>(key: &$kty, f: F, storage: &S) -> R { + let mut val = >::take(key, storage); let ret = f(&mut val); $crate::__handle_wrap_internal!($wraptype { // raw type case - >::insert(key, &val, storage) + >::insert(key, &val, storage) } { // Option<> type case match val { - Some(ref val) => >::insert(key, &val, storage), - None => >::remove(key, storage), + Some(ref val) => >::insert(key, &val, storage), + None => >::remove(key, storage), } }); @@ -386,7 +386,7 @@ mod tests { use crate::metadata::*; use crate::rstd::marker::PhantomData; use crate::storage::twox_128::generator::*; - use crate::storage::blake2_256::generator::*; + use crate::storage::blake2_128::generator::*; storage_items! { Value: b"a" => u32; diff --git a/srml/support/src/storage/unhashed/generator.rs b/srml/support/src/storage/unhashed/generator.rs index d29d269beb692..55177ae09b5c2 100644 --- a/srml/support/src/storage/unhashed/generator.rs +++ b/srml/support/src/storage/unhashed/generator.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use crate::codec; -use runtime_io::blake2_256; +use runtime_io::blake2_128; use crate::rstd::vec::Vec; /// Abstraction around storage with unhashed access. @@ -110,7 +110,7 @@ pub trait StorageDoubleMap fn prefix_for(k1: &K1) -> Vec { let mut key = Self::prefix().to_vec(); codec::Encode::encode_to(k1, &mut key); - blake2_256(&key).to_vec() + blake2_128(&key).to_vec() } /// true if the value is defined in storage. From 701e62359be230f065a119f83f3325700d11c305 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 16 Apr 2019 15:45:23 +0200 Subject: [PATCH 03/22] refactor code --- core/test-runtime/src/system.rs | 20 +-- srml/support/procedural/src/storage/impls.rs | 26 ++-- .../procedural/src/storage/transformation.rs | 8 +- srml/support/src/hashable.rs | 6 +- srml/support/src/lib.rs | 4 +- .../src/storage/blake2_128/generator.rs | 125 ------------------ srml/support/src/storage/blake2_128/mod.rs | 95 ------------- .../storage/{twox_128 => hashed}/generator.rs | 105 ++++++++++++++- .../src/storage/{twox_128 => hashed}/mod.rs | 95 ++++++------- srml/support/src/storage/mod.rs | 52 ++++---- srml/support/src/storage/storage_items.rs | 59 ++++----- 11 files changed, 241 insertions(+), 354 deletions(-) delete mode 100644 srml/support/src/storage/blake2_128/generator.rs delete mode 100644 srml/support/src/storage/blake2_128/mod.rs rename srml/support/src/storage/{twox_128 => hashed}/generator.rs (56%) rename srml/support/src/storage/{twox_128 => hashed}/mod.rs (62%) diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index 89e433e6c0923..daa0841fbce91 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -18,7 +18,7 @@ //! and depositing logs. use rstd::prelude::*; -use runtime_io::{storage_root, enumerated_trie_root, storage_changes_root, twox_128}; +use runtime_io::{storage_root, enumerated_trie_root, storage_changes_root, twox_128, blake2_128}; use runtime_support::storage::{self, StorageValue, StorageMap}; use runtime_support::storage_items; use runtime_primitives::traits::{Hash as HashT, BlakeTwo256, Digest as DigestT}; @@ -45,11 +45,11 @@ pub fn balance_of_key(who: AccountId) -> Vec { } pub fn balance_of(who: AccountId) -> u64 { - storage::blake2_128::get_or(&balance_of_key(who), 0) + storage::hashed::get_or(&blake2_128, &balance_of_key(who), 0) } pub fn nonce_of(who: AccountId) -> u64 { - storage::blake2_128::get_or(&who.to_keyed_vec(NONCE_OF), 0) + storage::hashed::get_or(&blake2_128, &who.to_keyed_vec(NONCE_OF), 0) } /// Get authorities at given block. @@ -152,7 +152,7 @@ pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { let tx = utx.transfer(); let nonce_key = tx.from.to_keyed_vec(NONCE_OF); - let expected_nonce: u64 = storage::blake2_128::get_or(&nonce_key, 0); + let expected_nonce: u64 = storage::hashed::get_or(&blake2_128, &nonce_key, 0); if tx.nonce < expected_nonce { return TransactionValidity::Invalid(ApplyError::Stale as i8); } @@ -241,26 +241,26 @@ fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { // check nonce let nonce_key = tx.from.to_keyed_vec(NONCE_OF); - let expected_nonce: u64 = storage::blake2_128::get_or(&nonce_key, 0); + let expected_nonce: u64 = storage::hashed::get_or(&blake2_128, &nonce_key, 0); if !(tx.nonce == expected_nonce) { return Err(ApplyError::Stale) } // increment nonce in storage - storage::blake2_128::put(&nonce_key, &(expected_nonce + 1)); + storage::hashed::put(&blake2_128, &nonce_key, &(expected_nonce + 1)); // check sender balance let from_balance_key = tx.from.to_keyed_vec(BALANCE_OF); - let from_balance: u64 = storage::blake2_128::get_or(&from_balance_key, 0); + let from_balance: u64 = storage::hashed::get_or(&blake2_128, &from_balance_key, 0); // enact transfer if !(tx.amount <= from_balance) { return Err(ApplyError::CantPay) } let to_balance_key = tx.to.to_keyed_vec(BALANCE_OF); - let to_balance: u64 = storage::blake2_128::get_or(&to_balance_key, 0); - storage::blake2_128::put(&from_balance_key, &(from_balance - tx.amount)); - storage::blake2_128::put(&to_balance_key, &(to_balance + tx.amount)); + let to_balance: u64 = storage::hashed::get_or(&blake2_128, &to_balance_key, 0); + storage::hashed::put(&blake2_128, &from_balance_key, &(from_balance - tx.amount)); + storage::hashed::put(&blake2_128, &to_balance_key, &(to_balance + tx.amount)); Ok(ApplyOutcome::Success) } diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index b77cd9d26aa01..d7ce57efcdbaa 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -67,13 +67,13 @@ impl<'a, I: Iterator> Impls<'a, I> { let mutate_impl = if !is_option { quote!{ - >::put(&val, storage) + >::put(&val, storage) } } else { quote!{ match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), + Some(ref val) => >::put(&val, storage), + None => >::kill(storage), } } }; @@ -100,7 +100,7 @@ impl<'a, I: Iterator> Impls<'a, I> { (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::twox_128::generator::StorageValue<#typ> for #name<#traitinstance, #instance> + #scrate::storage::hashed::generator::StorageValue<#typ> for #name<#traitinstance, #instance> { type Query = #value_type; @@ -111,19 +111,19 @@ impl<'a, I: Iterator> Impls<'a, I> { /// Load the value from the provided storage instance. fn get(storage: &S) -> Self::Query { - storage.get(>::key()) + storage.get(>::key()) .#option_simple_1(|| #fielddefault) } /// Take a value from storage, removing it afterwards. fn take(storage: &S) -> Self::Query { - storage.take(>::key()) + storage.take(>::key()) .#option_simple_1(|| #fielddefault) } /// Mutate the value under a key. fn mutate R, S: #scrate::Twox128Storage>(f: F, storage: &S) -> R { - let mut val = >::get(storage); + let mut val = >::get(storage); let ret = f(&mut val); #mutate_impl ; @@ -150,7 +150,7 @@ impl<'a, I: Iterator> Impls<'a, I> { let DeclStorageTypeInfos { typ, value_type, is_option, .. } = type_infos; let option_simple_1 = option_unwrap(is_option); - let as_map = quote!{ > }; + let as_map = quote!{ > }; let mutate_impl = if !is_option { quote!{ @@ -187,7 +187,7 @@ impl<'a, I: Iterator> Impls<'a, I> { (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::blake2_128::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + #scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> { type Query = #value_type; @@ -273,7 +273,7 @@ impl<'a, I: Iterator> Impls<'a, I> { let inner_module = syn::Ident::new(&format!("__linked_map_details_for_{}_do_not_use", name_lowercase), name.span()); let linkage = syn::Ident::new(&format!("__LinkageFor{}DoNotUse", name), name.span()); let phantom_data = quote! { #scrate::rstd::marker::PhantomData }; - let as_map = quote!{ > }; + let as_map = quote!{ > }; let put_or_insert = quote! { match linkage { Some(linkage) => storage.put(key_for, &(val, linkage)), @@ -333,7 +333,7 @@ impl<'a, I: Iterator> Impls<'a, I> { fn next(&mut self) -> Option { let next = self.next.take()?; let key_for = - as #scrate::storage::blake2_128::generator::StorageMap<#kty, #typ>>::key_for(&next); + as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>>::key_for(&next); let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for) .expect("previous/next only contain existing entires; we enumerate using next; entry exists; qed"); @@ -463,7 +463,7 @@ impl<'a, I: Iterator> Impls<'a, I> { #structure impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::blake2_128::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + #scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> { type Query = #value_type; @@ -533,7 +533,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> - #scrate::storage::blake2_128::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> + #scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> { fn head(storage: &S) -> Option<#kty> { use self::#inner_module::Utils; diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 69a0cf8cc8d56..de85a78c349a6 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -284,7 +284,7 @@ fn decl_store_extra_genesis( use #scrate::codec::{Encode, Decode}; let v = (#builder)(&self); - <#name<#traitinstance, #instance> as #scrate::storage::twox_128::generator::StorageValue<#typ>>::put(&v, &storage); + <#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageValue<#typ>>::put(&v, &storage); }} }, DeclStorageTypeInfosKind::Map { key_type, .. } => { @@ -294,7 +294,7 @@ fn decl_store_extra_genesis( let data = (#builder)(&self); for (k, v) in data.into_iter() { - <#name<#traitinstance, #instance> as #scrate::storage::blake2_128::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage); + <#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage); } }} }, @@ -662,7 +662,7 @@ fn impl_store_fns( quote!{ #( #[ #attrs ] )* pub fn #get_fn() -> #value_type { - <#name<#traitinstance, #instance> as #scrate::storage::twox_128::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage) + <#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage) } } }, @@ -670,7 +670,7 @@ fn impl_store_fns( quote!{ #( #[ #attrs ] )* pub fn #get_fn>(key: K) -> #value_type { - <#name<#traitinstance, #instance> as #scrate::storage::blake2_128::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) + <#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) } } } diff --git a/srml/support/src/hashable.rs b/srml/support/src/hashable.rs index 886c88b23a3e8..52b1fba234a8a 100644 --- a/srml/support/src/hashable.rs +++ b/srml/support/src/hashable.rs @@ -17,15 +17,19 @@ //! Hashable trait. use crate::codec::Codec; -use runtime_io::{blake2_256, twox_128, twox_256}; +use runtime_io::{blake2_128, blake2_256, twox_128, twox_256}; pub trait Hashable: Sized { + fn blake2_128(&self) -> [u8; 16]; fn blake2_256(&self) -> [u8; 32]; fn twox_128(&self) -> [u8; 16]; fn twox_256(&self) -> [u8; 32]; } impl Hashable for T { + fn blake2_128(&self) -> [u8; 16] { + self.using_encoded(blake2_128) + } fn blake2_256(&self) -> [u8; 32] { self.using_encoded(blake2_256) } diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 022c1c5c27e4a..fb8b5f7758b2e 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -35,8 +35,8 @@ pub use once_cell; pub use paste; pub use sr_primitives as runtime_primitives; -pub use self::storage::twox_128::generator::Twox128Storage; -pub use self::storage::blake2_128::generator::Blake2_128Storage; +pub use self::storage::hashed::generator::Twox128Storage; +pub use self::storage::hashed::generator::Blake2_128Storage; pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] diff --git a/srml/support/src/storage/blake2_128/generator.rs b/srml/support/src/storage/blake2_128/generator.rs deleted file mode 100644 index 94ec1910a8f4c..0000000000000 --- a/srml/support/src/storage/blake2_128/generator.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2019 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 . - -//! Abstract storage to use on Blake2_128Storage trait - -use crate::codec; -use crate::rstd::prelude::{Vec, Box}; -#[cfg(feature = "std")] -use crate::storage::unhashed::generator::UnhashedStorage; -#[cfg(feature = "std")] -use runtime_io::blake2_128; - -/// Abstraction around storage. -pub trait Blake2_128Storage { - /// true if the key exists in storage. - fn exists(&self, key: &[u8]) -> bool; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if - /// it's not there. - fn require(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's - /// default is returned if it's not there. - fn get_or_default(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() } - - /// Put a value in under a key. - fn put(&self, key: &[u8], val: &T); - - /// Remove the bytes of a key from storage. - fn kill(&self, key: &[u8]); - - /// Take a value from storage, deleting it after reading. - fn take(&self, key: &[u8]) -> Option { - let value = self.get(key); - self.kill(key); - value - } - - /// Take a value from storage, deleting it after reading. - fn take_or_panic(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") } - - /// Take a value from storage, deleting it after reading. - fn take_or_default(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() } -} - -// We use a construct like this during when genesis storage is being built. -#[cfg(feature = "std")] -impl Blake2_128Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { - fn exists(&self, key: &[u8]) -> bool { - UnhashedStorage::exists(self, &blake2_128(key)) - } - - fn get(&self, key: &[u8]) -> Option { - UnhashedStorage::get(self, &blake2_128(key)) - } - - fn put(&self, key: &[u8], val: &T) { - UnhashedStorage::put(self, &blake2_128(key), val) - } - - fn kill(&self, key: &[u8]) { - UnhashedStorage::kill(self, &blake2_128(key)) - } -} - -/// A strongly-typed map in storage. -pub trait StorageMap { - /// 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(x: &K) -> Vec; - - /// true if the value is defined in storage. - fn exists(key: &K, storage: &S) -> bool { - storage.exists(&Self::key_for(key)[..]) - } - - /// Load the value associated with the given key from the map. - fn get(key: &K, storage: &S) -> Self::Query; - - /// Take the value under a key. - fn take(key: &K, storage: &S) -> Self::Query; - - /// Store a value to be associated with the given key from the map. - fn insert(key: &K, val: &V, storage: &S) { - storage.put(&Self::key_for(key)[..], val); - } - - /// Remove the value under a key. - fn remove(key: &K, storage: &S) { - storage.kill(&Self::key_for(key)[..]); - } - - /// Mutate the value under a key. - fn mutate R, S: Blake2_128Storage>(key: &K, f: F, storage: &S) -> R; -} - -/// A `StorageMap` with enumerable entries. -pub trait EnumerableStorageMap: StorageMap { - /// Return current head element. - fn head(storage: &S) -> Option; - - /// Enumerate all elements in the map. - fn enumerate<'a, S: Blake2_128Storage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; -} diff --git a/srml/support/src/storage/blake2_128/mod.rs b/srml/support/src/storage/blake2_128/mod.rs deleted file mode 100644 index d8642e1a54efa..0000000000000 --- a/srml/support/src/storage/blake2_128/mod.rs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2019 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 . - -//! Operation on runtime storage using blake2 256 to hash keys - -pub mod generator; - -use super::unhashed; -use crate::rstd::prelude::*; -use crate::codec::{Encode, Decode}; -use runtime_io::blake2_128; - -/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. -pub fn get(key: &[u8]) -> Option { - unhashed::get(&blake2_128(key)) -} - -/// Return the value of the item in storage under `key`, or the type's default if there is no -/// explicit entry. -pub fn get_or_default(key: &[u8]) -> T { - unhashed::get_or_default(&blake2_128(key)) -} - -/// Return the value of the item in storage under `key`, or `default_value` if there is no -/// explicit entry. -pub fn get_or(key: &[u8], default_value: T) -> T { - unhashed::get_or(&blake2_128(key), default_value) -} - -/// Return the value of the item in storage under `key`, or `default_value()` if there is no -/// explicit entry. -pub fn get_or_else T>(key: &[u8], default_value: F) -> T { - unhashed::get_or_else(&blake2_128(key), default_value) -} - -/// Put `value` in storage under `key`. -pub fn put(key: &[u8], value: &T) { - unhashed::put(&blake2_128(key), value) -} - -/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. -pub fn take(key: &[u8]) -> Option { - unhashed::take(&blake2_128(key)) -} - -/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, -/// the default for its type. -pub fn take_or_default(key: &[u8]) -> T { - unhashed::take_or_default(&blake2_128(key)) -} - -/// Return the value of the item in storage under `key`, or `default_value` if there is no -/// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or(key: &[u8], default_value: T) -> T { - unhashed::take_or(&blake2_128(key), default_value) -} - -/// Return the value of the item in storage under `key`, or `default_value()` if there is no -/// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or_else T>(key: &[u8], default_value: F) -> T { - unhashed::take_or_else(&blake2_128(key), default_value) -} - -/// Check to see if `key` has an explicit entry in storage. -pub fn exists(key: &[u8]) -> bool { - unhashed::exists(&blake2_128(key)) -} - -/// Ensure `key` has no explicit entry in storage. -pub fn kill(key: &[u8]) { - unhashed::kill(&blake2_128(key)) -} - -/// Get a Vec of bytes from storage. -pub fn get_raw(key: &[u8]) -> Option> { - unhashed::get_raw(&blake2_128(key)) -} - -/// Put a raw byte slice into storage. -pub fn put_raw(key: &[u8], value: &[u8]) { - unhashed::put_raw(&blake2_128(key), value) -} diff --git a/srml/support/src/storage/twox_128/generator.rs b/srml/support/src/storage/hashed/generator.rs similarity index 56% rename from srml/support/src/storage/twox_128/generator.rs rename to srml/support/src/storage/hashed/generator.rs index 905047fecc752..d042aeed731e0 100644 --- a/srml/support/src/storage/twox_128/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -17,11 +17,11 @@ //! Abstract storage to use on Twox128Storage trait use crate::codec; -use crate::rstd::vec::Vec; +use crate::rstd::prelude::{Vec, Box}; #[cfg(feature = "std")] use crate::storage::unhashed::generator::UnhashedStorage; #[cfg(feature = "std")] -use runtime_io::twox_128; +use runtime_io::{twox_128, blake2_128}; /// Abstraction around storage. pub trait Twox128Storage { @@ -79,6 +79,62 @@ impl Twox128Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOv } } +/// Abstraction around storage. +pub trait Blake2_128Storage { + /// true if the key exists in storage. + fn exists(&self, key: &[u8]) -> bool; + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. + fn get(&self, key: &[u8]) -> Option; + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if + /// it's not there. + fn require(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") } + + /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's + /// default is returned if it's not there. + fn get_or_default(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() } + + /// Put a value in under a key. + fn put(&self, key: &[u8], val: &T); + + /// Remove the bytes of a key from storage. + fn kill(&self, key: &[u8]); + + /// Take a value from storage, deleting it after reading. + fn take(&self, key: &[u8]) -> Option { + let value = self.get(key); + self.kill(key); + value + } + + /// Take a value from storage, deleting it after reading. + fn take_or_panic(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") } + + /// Take a value from storage, deleting it after reading. + fn take_or_default(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() } +} + +// We use a construct like this during when genesis storage is being built. +#[cfg(feature = "std")] +impl Blake2_128Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { + fn exists(&self, key: &[u8]) -> bool { + UnhashedStorage::exists(self, &blake2_128(key)) + } + + fn get(&self, key: &[u8]) -> Option { + UnhashedStorage::get(self, &blake2_128(key)) + } + + fn put(&self, key: &[u8], val: &T) { + UnhashedStorage::put(self, &blake2_128(key), val) + } + + fn kill(&self, key: &[u8]) { + UnhashedStorage::kill(self, &blake2_128(key)) + } +} + /// A strongly-typed value kept in storage. pub trait StorageValue { /// The type that get/take returns. @@ -141,3 +197,48 @@ pub trait StorageList { /// Clear the list. fn clear(storage: &S); } + +/// A strongly-typed map in storage. +pub trait StorageMap { + /// 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(x: &K) -> Vec; + + /// true if the value is defined in storage. + fn exists(key: &K, storage: &S) -> bool { + storage.exists(&Self::key_for(key)[..]) + } + + /// Load the value associated with the given key from the map. + fn get(key: &K, storage: &S) -> Self::Query; + + /// Take the value under a key. + fn take(key: &K, storage: &S) -> Self::Query; + + /// Store a value to be associated with the given key from the map. + fn insert(key: &K, val: &V, storage: &S) { + storage.put(&Self::key_for(key)[..], val); + } + + /// Remove the value under a key. + fn remove(key: &K, storage: &S) { + storage.kill(&Self::key_for(key)[..]); + } + + /// Mutate the value under a key. + fn mutate R, S: Blake2_128Storage>(key: &K, f: F, storage: &S) -> R; +} + +/// A `StorageMap` with enumerable entries. +pub trait EnumerableStorageMap: StorageMap { + /// Return current head element. + fn head(storage: &S) -> Option; + + /// Enumerate all elements in the map. + fn enumerate<'a, S: Blake2_128Storage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; +} diff --git a/srml/support/src/storage/twox_128/mod.rs b/srml/support/src/storage/hashed/mod.rs similarity index 62% rename from srml/support/src/storage/twox_128/mod.rs rename to srml/support/src/storage/hashed/mod.rs index c0221c56f61a5..3fe7968aaf669 100644 --- a/srml/support/src/storage/twox_128/mod.rs +++ b/srml/support/src/storage/hashed/mod.rs @@ -14,88 +14,91 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Operation on runtime storage using twox 128 to hash keys +//! Operation on runtime storage using hashed keys. pub mod generator; - use super::unhashed; use crate::rstd::prelude::*; use crate::rstd::borrow::Borrow; use runtime_io::{self, twox_128}; use crate::codec::{Codec, Encode, Decode, KeyedVec}; +type HashFn = Fn(&[u8]) -> [u8; 16]; + /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. -pub fn get(key: &[u8]) -> Option { - unhashed::get(&twox_128(key)) +pub fn get(hash: &HashFn, key: &[u8]) -> Option { + unhashed::get(&hash(key)) } /// Return the value of the item in storage under `key`, or the type's default if there is no /// explicit entry. -pub fn get_or_default(key: &[u8]) -> T { - unhashed::get_or_default(&twox_128(key)) +pub fn get_or_default(hash: &HashFn, key: &[u8]) -> T { + unhashed::get_or_default(&hash(key)) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. -pub fn get_or(key: &[u8], default_value: T) -> T { - unhashed::get_or(&twox_128(key), default_value) +pub fn get_or(hash: &HashFn, key: &[u8], default_value: T) -> T { + unhashed::get_or(&hash(key), default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. -pub fn get_or_else T>(key: &[u8], default_value: F) -> T { - unhashed::get_or_else(&twox_128(key), default_value) +pub fn get_or_else T>(hash: &HashFn, key: &[u8], default_value: F) -> T { + unhashed::get_or_else(&hash(key), default_value) } /// Put `value` in storage under `key`. -pub fn put(key: &[u8], value: &T) { - unhashed::put(&twox_128(key), value) +pub fn put(hash: &HashFn, key: &[u8], value: &T) { + unhashed::put(&hash(key), value) } /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. -pub fn take(key: &[u8]) -> Option { - unhashed::take(&twox_128(key)) +pub fn take(hash: &HashFn, key: &[u8]) -> Option { + unhashed::take(&hash(key)) } /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, /// the default for its type. -pub fn take_or_default(key: &[u8]) -> T { - unhashed::take_or_default(&twox_128(key)) +pub fn take_or_default(hash: &HashFn, key: &[u8]) -> T { + unhashed::take_or_default(&hash(key)) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or(key: &[u8], default_value: T) -> T { - unhashed::take_or(&twox_128(key), default_value) +pub fn take_or(hash: &HashFn, key: &[u8], default_value: T) -> T { + unhashed::take_or(&hash(key), default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or_else T>(key: &[u8], default_value: F) -> T { - unhashed::take_or_else(&twox_128(key), default_value) +pub fn take_or_else T>(hash: &HashFn, key: &[u8], default_value: F) -> T { + unhashed::take_or_else(&hash(key), default_value) } /// Check to see if `key` has an explicit entry in storage. -pub fn exists(key: &[u8]) -> bool { - unhashed::exists(&twox_128(key)) +pub fn exists(hash: &HashFn, key: &[u8]) -> bool { + unhashed::exists(&hash(key)) } /// Ensure `key` has no explicit entry in storage. -pub fn kill(key: &[u8]) { - unhashed::kill(&twox_128(key)) +pub fn kill(hash: &HashFn, key: &[u8]) { + unhashed::kill(&hash(key)) } /// Get a Vec of bytes from storage. -pub fn get_raw(key: &[u8]) -> Option> { - unhashed::get_raw(&twox_128(key)) +pub fn get_raw(hash: &HashFn, key: &[u8]) -> Option> { + unhashed::get_raw(&hash(key)) } /// Put a raw byte slice into storage. -pub fn put_raw(key: &[u8], value: &[u8]) { - unhashed::put_raw(&twox_128(key), value) +pub fn put_raw(hash: &HashFn, key: &[u8], value: &[u8]) { + unhashed::put_raw(&hash(key), value) } /// A trait to conveniently store a vector of storable data. +/// +/// It uses twox_128 hasher. Final keys in trie are `twox_128(concatenation(PREFIX,count))` pub trait StorageVec { type Item: Default + Sized + Codec; const PREFIX: &'static [u8]; @@ -114,7 +117,7 @@ pub trait StorageVec { let mut count: u32 = 0; for i in items.into_iter() { - put(&count.to_keyed_vec(Self::PREFIX), i.borrow()); + put(&twox_128, &count.to_keyed_vec(Self::PREFIX), i.borrow()); count = count.checked_add(1).expect("exceeded runtime storage capacity"); } @@ -124,33 +127,33 @@ pub trait StorageVec { /// Push an item. fn push(item: &Self::Item) { let len = Self::count(); - put(&len.to_keyed_vec(Self::PREFIX), item); + put(&twox_128, &len.to_keyed_vec(Self::PREFIX), item); Self::set_count(len + 1); } fn set_item(index: u32, item: &Self::Item) { if index < Self::count() { - put(&index.to_keyed_vec(Self::PREFIX), item); + put(&twox_128, &index.to_keyed_vec(Self::PREFIX), item); } } fn clear_item(index: u32) { if index < Self::count() { - kill(&index.to_keyed_vec(Self::PREFIX)); + kill(&twox_128, &index.to_keyed_vec(Self::PREFIX)); } } fn item(index: u32) -> Self::Item { - get_or_default(&index.to_keyed_vec(Self::PREFIX)) + get_or_default(&twox_128, &index.to_keyed_vec(Self::PREFIX)) } fn set_count(count: u32) { (count..Self::count()).for_each(Self::clear_item); - put(&b"len".to_keyed_vec(Self::PREFIX), &count); + put(&twox_128, &b"len".to_keyed_vec(Self::PREFIX), &count); } fn count() -> u32 { - get_or_default(&b"len".to_keyed_vec(Self::PREFIX)) + get_or_default(&twox_128, &b"len".to_keyed_vec(Self::PREFIX)) } } @@ -164,14 +167,14 @@ mod tests { let mut t = TestExternalities::default(); with_externalities(&mut t, || { let x = 69u32; - put(b":test", &x); - let y: u32 = get(b":test").unwrap(); + put(&twox_128, b":test", &x); + let y: u32 = get(&twox_128, b":test").unwrap(); assert_eq!(x, y); }); with_externalities(&mut t, || { let x = 69426942i64; - put(b":test", &x); - let y: i64 = get(b":test").unwrap(); + put(&twox_128, b":test", &x); + let y: i64 = get(&twox_128, b":test").unwrap(); assert_eq!(x, y); }); } @@ -181,15 +184,15 @@ mod tests { let mut t = TestExternalities::default(); with_externalities(&mut t, || { let x = true; - put(b":test", &x); - let y: bool = get(b":test").unwrap(); + put(&twox_128, b":test", &x); + let y: bool = get(&twox_128, b":test").unwrap(); assert_eq!(x, y); }); with_externalities(&mut t, || { let x = false; - put(b":test", &x); - let y: bool = get(b":test").unwrap(); + put(&twox_128, b":test", &x); + let y: bool = get(&twox_128, b":test").unwrap(); assert_eq!(x, y); }); } @@ -200,7 +203,7 @@ mod tests { with_externalities(&mut t, || { runtime_io::set_storage(&twox_128(b":test"), b"\x2cHello world"); let x = b"Hello world".to_vec(); - let y = get::>(b":test").unwrap(); + let y = get::>(&twox_128, b":test").unwrap(); assert_eq!(x, y); }); @@ -212,11 +215,11 @@ mod tests { let x = b"Hello world".to_vec(); with_externalities(&mut t, || { - put(b":test", &x); + put(&twox_128, b":test", &x); }); with_externalities(&mut t, || { - let y: Vec = get(b":test").unwrap(); + let y: Vec = get(&twox_128, b":test").unwrap(); assert_eq!(x, y); }); } diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index 0a6a921c8bd35..98684dfcc7fed 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -19,12 +19,12 @@ use crate::rstd::prelude::*; use crate::rstd::borrow::Borrow; use crate::codec::{Codec, Encode, Decode, KeyedVec, Input}; +use runtime_io::{twox_128, blake2_128}; #[macro_use] pub mod storage_items; pub mod unhashed; -pub mod twox_128; -pub mod blake2_128; +pub mod hashed; struct IncrementalInput<'a> { key: &'a [u8], @@ -58,55 +58,55 @@ impl<'a> Input for IncrementalChildInput<'a> { /// The underlying runtime storage. pub struct RuntimeStorage; -impl twox_128::generator::Twox128Storage for RuntimeStorage { +impl hashed::generator::Twox128Storage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { - twox_128::exists(key) + hashed::exists(&twox_128, key) } /// Load the bytes of a key from storage. Can panic if the type is incorrect. fn get(&self, key: &[u8]) -> Option { - twox_128::get(key) + hashed::get(&twox_128, key) } /// Put a value in under a key. fn put(&self, key: &[u8], val: &T) { - twox_128::put(key, val) + hashed::put(&twox_128, key, val) } /// Remove the bytes of a key from storage. fn kill(&self, key: &[u8]) { - twox_128::kill(key) + hashed::kill(&twox_128, key) } /// Take a value from storage, deleting it after reading. fn take(&self, key: &[u8]) -> Option { - twox_128::take(key) + hashed::take(&twox_128, key) } } -impl blake2_128::generator::Blake2_128Storage for RuntimeStorage { +impl hashed::generator::Blake2_128Storage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { - blake2_128::exists(key) + hashed::exists(&blake2_128, key) } /// Load the bytes of a key from storage. Can panic if the type is incorrect. fn get(&self, key: &[u8]) -> Option { - blake2_128::get(key) + hashed::get(&blake2_128, key) } /// Put a value in under a key. fn put(&self, key: &[u8], val: &T) { - blake2_128::put(key, val) + hashed::put(&blake2_128, key, val) } /// Remove the bytes of a key from storage. fn kill(&self, key: &[u8]) { - blake2_128::kill(key) + hashed::kill(&blake2_128, key) } /// Take a value from storage, deleting it after reading. fn take(&self, key: &[u8]) -> Option { - blake2_128::take(key) + hashed::take(&blake2_128, key) } } @@ -168,11 +168,11 @@ pub trait StorageValue { fn take() -> Self::Query; } -impl StorageValue for U where U: twox_128::generator::StorageValue { +impl StorageValue for U where U: hashed::generator::StorageValue { type Query = U::Query; fn key() -> &'static [u8] { - >::key() + >::key() } fn exists() -> bool { U::exists(&RuntimeStorage) @@ -224,17 +224,17 @@ pub trait StorageList { fn clear(); } -impl StorageList for U where U: twox_128::generator::StorageList { +impl StorageList for U where U: hashed::generator::StorageList { fn prefix() -> &'static [u8] { - >::prefix() + >::prefix() } fn len_key() -> Vec { - >::len_key() + >::len_key() } fn key_for(index: u32) -> Vec { - >::key_for(index) + >::key_for(index) } fn items() -> Vec { @@ -292,15 +292,15 @@ pub trait StorageMap { fn take>(key: KeyArg) -> Self::Query; } -impl StorageMap for U where U: blake2_128::generator::StorageMap { +impl StorageMap for U where U: hashed::generator::StorageMap { type Query = U::Query; fn prefix() -> &'static [u8] { - >::prefix() + >::prefix() } fn key_for>(key: KeyArg) -> Vec { - >::key_for(key.borrow()) + >::key_for(key.borrow()) } fn exists>(key: KeyArg) -> bool { @@ -340,13 +340,13 @@ pub trait EnumerableStorageMap: StorageMap { fn enumerate() -> Box> where K: 'static, V: 'static; } -impl EnumerableStorageMap for U where U: blake2_128::generator::EnumerableStorageMap { +impl EnumerableStorageMap for U where U: hashed::generator::EnumerableStorageMap { fn head() -> Option { - >::head(&RuntimeStorage) + >::head(&RuntimeStorage) } fn enumerate() -> Box> where K: 'static, V: 'static { - >::enumerate(&RuntimeStorage) + >::enumerate(&RuntimeStorage) } } diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index ac589f4d7fba8..1d3049ee7c4ba 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -178,12 +178,12 @@ macro_rules! __storage_items_internal { // generator for values. (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $key => $ty } - pub fn $get_fn() -> $gettype { <$name as $crate::storage::twox_128::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) } + pub fn $get_fn() -> $gettype { <$name as $crate::storage::hashed::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) } }; (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => { $($vis)* struct $name; - impl $crate::storage::twox_128::generator::StorageValue<$ty> for $name { + impl $crate::storage::hashed::generator::StorageValue<$ty> for $name { type Query = $gettype; /// Get the storage key. @@ -203,18 +203,18 @@ macro_rules! __storage_items_internal { /// Mutate this value. fn mutate R, S: $crate::Twox128Storage>(f: F, storage: &S) -> R { - let mut val = >::get(storage); + let mut val = >::get(storage); let ret = f(&mut val); $crate::__handle_wrap_internal!($wraptype { // raw type case - >::put(&val, storage) + >::put(&val, storage) } { // Option<> type case match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), + Some(ref val) => >::put(&val, storage), + None => >::kill(storage), } }); @@ -226,13 +226,13 @@ macro_rules! __storage_items_internal { (($($vis:tt)*) ($get_fn:ident) ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $crate::__storage_items_internal!{ ($($vis)*) () ($wraptype $gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] } pub fn $get_fn>(key: K) -> $gettype { - <$name as $crate::storage::blake2_128::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) + <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) } }; (($($vis:tt)*) () ($wraptype:ident $gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => { $($vis)* struct $name; - impl $crate::storage::blake2_128::generator::StorageMap<$kty, $ty> for $name { + impl $crate::storage::hashed::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; /// Get the prefix key in storage. @@ -249,30 +249,30 @@ macro_rules! __storage_items_internal { /// Load the value associated with the given key from the map. fn get(key: &$kty, storage: &S) -> Self::Query { - let key = <$name as $crate::storage::blake2_128::generator::StorageMap<$kty, $ty>>::key_for(key); + let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$getter(&key[..]) } /// Take the value, reading and removing it. fn take(key: &$kty, storage: &S) -> Self::Query { - let key = <$name as $crate::storage::blake2_128::generator::StorageMap<$kty, $ty>>::key_for(key); + let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$taker(&key[..]) } /// Mutate the value under a key. fn mutate R, S: $crate::Blake2_128Storage>(key: &$kty, f: F, storage: &S) -> R { - let mut val = >::take(key, storage); + let mut val = >::take(key, storage); let ret = f(&mut val); $crate::__handle_wrap_internal!($wraptype { // raw type case - >::insert(key, &val, storage) + >::insert(key, &val, storage) } { // Option<> type case match val { - Some(ref val) => >::insert(key, &val, storage), - None => >::remove(key, storage), + Some(ref val) => >::insert(key, &val, storage), + None => >::remove(key, storage), } }); @@ -286,18 +286,18 @@ macro_rules! __storage_items_internal { impl $name { fn clear_item(index: u32, storage: &S) { - if index < <$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage) { - storage.kill(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::key_for(index)); + if index < <$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { + storage.kill(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)); } } fn set_len(count: u32, storage: &S) { - (count..<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage)).for_each(|i| $name::clear_item(i, storage)); - storage.put(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len_key(), &count); + (count..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage)).for_each(|i| $name::clear_item(i, storage)); + storage.put(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len_key(), &count); } } - impl $crate::storage::twox_128::generator::StorageList<$ty> for $name { + impl $crate::storage::hashed::generator::StorageList<$ty> for $name { /// Get the prefix key in storage. fn prefix() -> &'static [u8] { $prefix @@ -319,8 +319,8 @@ macro_rules! __storage_items_internal { /// Read out all the items. fn items(storage: &S) -> $crate::rstd::vec::Vec<$ty> { - (0..<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage)) - .map(|i| <$name as $crate::storage::twox_128::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed")) + (0..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage)) + .map(|i| <$name as $crate::storage::hashed::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed")) .collect() } @@ -329,32 +329,32 @@ macro_rules! __storage_items_internal { $name::set_len(items.len() as u32, storage); items.iter() .enumerate() - .for_each(|(i, item)| <$name as $crate::storage::twox_128::generator::StorageList<$ty>>::set_item(i as u32, item, storage)); + .for_each(|(i, item)| <$name as $crate::storage::hashed::generator::StorageList<$ty>>::set_item(i as u32, item, storage)); } fn set_item(index: u32, item: &$ty, storage: &S) { - if index < <$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage) { - storage.put(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::key_for(index)[..], item); + if index < <$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { + storage.put(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)[..], item); } } /// Load the value at given index. Returns `None` if the index is out-of-bounds. fn get(index: u32, storage: &S) -> Option<$ty> { - storage.get(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::key_for(index)[..]) + storage.get(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)[..]) } /// Load the length of the list. fn len(storage: &S) -> u32 { - storage.get(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len_key()).unwrap_or_default() + storage.get(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len_key()).unwrap_or_default() } /// Clear the list. fn clear(storage: &S) { - for i in 0..<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len(storage) { + for i in 0..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { $name::clear_item(i, storage); } - storage.kill(&<$name as $crate::storage::twox_128::generator::StorageList<$ty>>::len_key()[..]) + storage.kill(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len_key()[..]) } } }; @@ -385,8 +385,7 @@ mod tests { use super::*; use crate::metadata::*; use crate::rstd::marker::PhantomData; - use crate::storage::twox_128::generator::*; - use crate::storage::blake2_128::generator::*; + use crate::storage::hashed::generator::*; storage_items! { Value: b"a" => u32; From 6eb0f853cc0a78cc6e625e4787cd26856b49fd65 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 17 Apr 2019 16:01:34 +0200 Subject: [PATCH 04/22] add benchmark --- core/primitives/Cargo.toml | 1 + core/primitives/benches/benches.rs | 56 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 core/primitives/benches/benches.rs diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index d3222a5ea4609..efe189f525e13 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -34,6 +34,7 @@ regex = {version = "1.1", optional = true } substrate-serializer = { path = "../serializer" } pretty_assertions = "0.5" heapsize = "0.4" +hex-literal = "0.1" [features] default = ["std"] diff --git a/core/primitives/benches/benches.rs b/core/primitives/benches/benches.rs new file mode 100644 index 0000000000000..1e9eb40042d69 --- /dev/null +++ b/core/primitives/benches/benches.rs @@ -0,0 +1,56 @@ +// Copyright 2019 Parity Technologies +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![feature(test)] + +extern crate test; +use hex_literal::{hex, hex_impl}; +use substrate_primitives::hashing::{twox_128, blake2_128}; + +const RANDOM: [u8; 968] = hex!("a494a9df75845413c3b2732f1e54c5ace3474a77ed311d08cdb491b60408901d0ca7485d72a64d47bae1c4c3a91403650283c7432347f5c068cc1b07d843c2275bf8d8d11f9ca7a6d32c99e5b0b21d057a8ceaecc075afc2a34a82d3a36f8efb99a8e8c244db1e7e0d7f5d72bca68f209f04eef2aad9f04f772effc532f9e84fc8c663880cef8021f7926a0900e6d636ac5f57de8007ccb8d2fa348a27c7211f07fae5ef275c1ab54eacafde539079b2d106f254ab242a7e530460e7ed99d9771746ce2f5a08f68833a9109b0f57764964d66fee6616a5fef8a9de13701c470d1f3511c3960c7d92bc3e0e2a56833f0ec0354f7d0360960c87bdf0adfea9bf167917b221de806bf9279870f2adc2f9117ffd584a3e065905ed9d7e327e5fa3ca8a1f7e9947026b0db868ab7138a355daf67b742c0aa1eea22e94c865608babe2677880179e6bd990713d1e7a2421fe38e66983918d4a1028530fa24cbb372b9f207a7611f5cf0e0f73c859d85751d7324bb73fa23d8899531a9cb05eb367a65773622947b6fe228c78a34b612748e9717bcb3bc1c0354ca89dfd15a544f8076ad9f48ca36f259b0fbbc891f34095de03baaa93f7d84685a15383b658d62c854808031218c15dd9a2b8f7db070912c9f7b1e8b20bb282a84d338b04cf94c8283e04ddf156c5795acbe829e3944184a77e711d62bf8f1d5a0ed1b5adf85fbd91dee6f7f977271c0949d018858e94c7dd5380a8337fa3936e4a4286c6b7c7c4103d590e369f12bec1621f94a2c80726247b6911bd9b8c65d5039b2e96098e5b52b4d7ab636f39115292314e0afb38ce17a69e93838a69ce23d684065f25fda0e601f3ee56431effed7b118a80dea0bccdecd8775e9ff96bcd31a7a805317c3650ea4c4a1df6adbe184e762a24bc9359eac4e81b2253b9a3dd5086974506ad6655b0be3b903837c2c73844239f19b9ba6fe1ac1b9f9c78c1cca223a5affd21a2442bef064c14c2b8ff88cd65e8bc7432b61516f3250803636e31028a62f540966aa1471eee46cc95d3590f272d7eb2ab8273ad0f4442cf197e759498445bb60bf87f394142ede5796f0f9353a8ddb34e9b6edd4c82149b65b6d3480ad3af534cd2e5646a12de6a1500a20613f2cf23a81ace0abd3d25a767522cb79e301342f564aaebd567723e5df0cfd4973fcb6b8ed66fe543abf969c22685ffc504068c347dc28c2f1bf62710cc9ed11386906b69bded1e6a8232d4f9980db3e1eca8268ba420cd5b9fb69bdb090562af0167bac782e954909a5a84f53cb067aaadbf5635ebc1b7d9304aee0407c2d14f1ea95d132483a335435b090cf0e1a7d3e2ba3adc40d21042119ed005df10"); + +const MAX_KEY_SIZE: u32 = 32; + +fn data_set() -> Vec> { + let mut rnd = RANDOM.iter().cycle(); + let mut res = Vec::new(); + for size in 1..=MAX_KEY_SIZE { + for _ in 0..1_000 { + let value = (0..size) + .map(|_| rnd.next().unwrap().clone()) + .collect(); + res.push(value); + } + } + res +} + +fn bench_hash_128(b: &mut test::Bencher, f: &Fn(&[u8]) -> [u8; 16]) { + let data_set = data_set(); + b.iter(|| { + for data in &data_set { + let _a = f(data); + } + }); +} + +#[bench] +fn bench_blake2_128(b: &mut test::Bencher) { + bench_hash_128(b, &blake2_128); +} + +#[bench] +fn bench_twox_128(b: &mut test::Bencher) { + bench_hash_128(b, &twox_128); +} From f626f7626aef8ba0d30dbd2c49549132b629e5aa Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 17 Apr 2019 17:37:22 +0200 Subject: [PATCH 05/22] factorize generator --- srml/support/procedural/src/storage/impls.rs | 48 ++++---- srml/support/src/lib.rs | 3 +- srml/support/src/storage/hashed/generator.rs | 116 +++++++------------ srml/support/src/storage/mod.rs | 43 ++----- srml/support/src/storage/storage_items.rs | 28 ++--- 5 files changed, 88 insertions(+), 150 deletions(-) diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index d7ce57efcdbaa..65d35ef87e22c 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -110,19 +110,19 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value from the provided storage instance. - fn get(storage: &S) -> Self::Query { + fn get>(storage: &S) -> Self::Query { storage.get(>::key()) .#option_simple_1(|| #fielddefault) } /// Take a value from storage, removing it afterwards. - fn take(storage: &S) -> Self::Query { + fn take>(storage: &S) -> Self::Query { storage.take(>::key()) .#option_simple_1(|| #fielddefault) } /// Mutate the value under a key. - fn mutate R, S: #scrate::Twox128Storage>(f: F, storage: &S) -> R { + fn mutate R, S: #scrate::HashedStorage<#scrate::Twox>>(f: F, storage: &S) -> R { let mut val = >::get(storage); let ret = f(&mut val); @@ -204,19 +204,19 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value associated with the given key from the map. - fn get(key: &#kty, storage: &S) -> Self::Query { + fn get>(key: &#kty, storage: &S) -> Self::Query { let key = #as_map::key_for(key); storage.get(&key[..]).#option_simple_1(|| #fielddefault) } /// Take the value, reading and removing it. - fn take(key: &#kty, storage: &S) -> Self::Query { + fn take>(key: &#kty, storage: &S) -> Self::Query { let key = #as_map::key_for(key); storage.take(&key[..]).#option_simple_1(|| #fielddefault) } /// Mutate the value under a key - fn mutate R, S: #scrate::Blake2_128Storage>(key: &#kty, f: F, storage: &S) -> R { + fn mutate R, S: #scrate::HashedStorage<#scrate::Blake2>>(key: &#kty, f: F, storage: &S) -> R { let mut val = #as_map::get(key, storage); let ret = f(&mut val); @@ -324,7 +324,7 @@ impl<'a, I: Iterator> Impls<'a, I> { pub _data: #phantom_data, } - impl<'a, S: #scrate::Blake2_128Storage, #traitinstance: #traittype, #instance #bound_instantiable> + impl<'a, S: #scrate::HashedStorage<#scrate::Blake2>, #traitinstance: #traittype, #instance #bound_instantiable> Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)> where #traitinstance: 'a { @@ -347,26 +347,26 @@ impl<'a, I: Iterator> Impls<'a, I> { /// /// Takes care of updating previous and next elements points /// as well as updates head if the element is first or last. - fn remove_linkage(linkage: Linkage<#kty>, storage: &S); + fn remove_linkage>(linkage: Linkage<#kty>, storage: &S); /// Read the contained data and it's linkage. - fn read_with_linkage(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>; + fn read_with_linkage>(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>; /// Generate linkage for newly inserted element. /// /// Takes care of updating head and previous head's pointer. - fn new_head_linkage( + fn new_head_linkage>( storage: &S, key: &#kty, ) -> Linkage<#kty>; /// Read current head pointer. - fn read_head(storage: &S) -> Option<#kty>; + fn read_head>(storage: &S) -> Option<#kty>; /// Overwrite current head pointer. /// /// If `None` is given head is removed from storage. - fn write_head(storage: &S, head: Option<&#kty>); + fn write_head>(storage: &S, head: Option<&#kty>); } } }; @@ -376,7 +376,7 @@ impl<'a, I: Iterator> Impls<'a, I> { #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#phantom_data<(#traitinstance #comma_instance)>); impl<#traitinstance: #traittype, #instance #bound_instantiable> self::#inner_module::Utils<#traitinstance, #instance> for #name<#traitinstance, #instance> { - fn remove_linkage( + fn remove_linkage>( linkage: self::#inner_module::Linkage<#kty>, storage: &S, ) { @@ -405,14 +405,14 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - fn read_with_linkage( + fn read_with_linkage>( storage: &S, key: &[u8], ) -> Option<(#value_type, self::#inner_module::Linkage<#kty>)> { storage.get(key) } - fn new_head_linkage( + fn new_head_linkage>( storage: &S, key: &#kty, ) -> self::#inner_module::Linkage<#kty> { @@ -444,11 +444,11 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - fn read_head(storage: &S) -> Option<#kty> { + fn read_head>(storage: &S) -> Option<#kty> { storage.get(#final_head_key) } - fn write_head(storage: &S, head: Option<&#kty>) { + fn write_head>(storage: &S, head: Option<&#kty>) { match head { Some(head) => storage.put(#final_head_key, head), None => storage.kill(#final_head_key), @@ -480,12 +480,12 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value associated with the given key from the map. - fn get(key: &#kty, storage: &S) -> Self::Query { + fn get>(key: &#kty, storage: &S) -> Self::Query { storage.get(&*#as_map::key_for(key)).#option_simple_1(|| #fielddefault) } /// Take the value, reading and removing it. - fn take(key: &#kty, storage: &S) -> Self::Query { + fn take>(key: &#kty, storage: &S) -> Self::Query { use self::#inner_module::Utils; let res: Option<(#value_type, self::#inner_module::Linkage<#kty>)> = storage.take(&*#as_map::key_for(key)); @@ -499,12 +499,12 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Remove the value under a key. - fn remove(key: &#kty, storage: &S) { + fn remove>(key: &#kty, storage: &S) { #as_map::take(key, storage); } /// Store a value to be associated with the given key from the map. - fn insert(key: &#kty, val: &#typ, storage: &S) { + fn insert>(key: &#kty, val: &#typ, storage: &S) { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -518,7 +518,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Mutate the value under a key - fn mutate R, S: #scrate::Blake2_128Storage>(key: &#kty, f: F, storage: &S) -> R { + fn mutate R, S: #scrate::HashedStorage<#scrate::Blake2>>(key: &#kty, f: F, storage: &S) -> R { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -535,13 +535,13 @@ impl<'a, I: Iterator> Impls<'a, I> { impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> #scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> { - fn head(storage: &S) -> Option<#kty> { + fn head>(storage: &S) -> Option<#kty> { use self::#inner_module::Utils; Self::read_head(storage) } - fn enumerate<'a, S: #scrate::Blake2_128Storage>(storage: &'a S) -> #scrate::rstd::boxed::Box + 'a> where + fn enumerate<'a, S: #scrate::HashedStorage<#scrate::Blake2>>(storage: &'a S) -> #scrate::rstd::boxed::Box + 'a> where #kty: 'a, #typ: 'a, { diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index fb8b5f7758b2e..52f000fe7cfb0 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -35,8 +35,7 @@ pub use once_cell; pub use paste; pub use sr_primitives as runtime_primitives; -pub use self::storage::hashed::generator::Twox128Storage; -pub use self::storage::hashed::generator::Blake2_128Storage; +pub use self::storage::hashed::generator::{HashedStorage, Twox, Blake2}; pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index d042aeed731e0..17419a5fa5896 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Abstract storage to use on Twox128Storage trait +//! Abstract storage to use on HashedStorage trait use crate::codec; use crate::rstd::prelude::{Vec, Box}; @@ -23,64 +23,28 @@ use crate::storage::unhashed::generator::UnhashedStorage; #[cfg(feature = "std")] use runtime_io::{twox_128, blake2_128}; -/// Abstraction around storage. -pub trait Twox128Storage { - /// true if the key exists in storage. - fn exists(&self, key: &[u8]) -> bool; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option; - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if - /// it's not there. - fn require(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's - /// default is returned if it's not there. - fn get_or_default(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() } - - /// Put a value in under a key. - fn put(&self, key: &[u8], val: &T); - - /// Remove the bytes of a key from storage. - fn kill(&self, key: &[u8]); - - /// Take a value from storage, deleting it after reading. - fn take(&self, key: &[u8]) -> Option { - let value = self.get(key); - self.kill(key); - value - } - - /// Take a value from storage, deleting it after reading. - fn take_or_panic(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") } - - /// Take a value from storage, deleting it after reading. - fn take_or_default(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() } +pub trait StorageHasher { + fn hash(x: &[u8]) -> [u8; 16]; } -// We use a construct like this during when genesis storage is being built. -#[cfg(feature = "std")] -impl Twox128Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { - fn exists(&self, key: &[u8]) -> bool { - UnhashedStorage::exists(self, &twox_128(key)) - } - - fn get(&self, key: &[u8]) -> Option { - UnhashedStorage::get(self, &twox_128(key)) - } - - fn put(&self, key: &[u8], val: &T) { - UnhashedStorage::put(self, &twox_128(key), val) +/// Hash storage keys with blake2 128 +pub struct Blake2; +impl StorageHasher for Blake2 { + fn hash(x: &[u8]) -> [u8; 16] { + blake2_128(x) } +} - fn kill(&self, key: &[u8]) { - UnhashedStorage::kill(self, &twox_128(key)) +/// Hash storage keys with twox 128 +pub struct Twox; +impl StorageHasher for Twox { + fn hash(x: &[u8]) -> [u8; 16] { + twox_128(x) } } /// Abstraction around storage. -pub trait Blake2_128Storage { +pub trait HashedStorage { /// true if the key exists in storage. fn exists(&self, key: &[u8]) -> bool; @@ -117,21 +81,21 @@ pub trait Blake2_128Storage { // We use a construct like this during when genesis storage is being built. #[cfg(feature = "std")] -impl Blake2_128Storage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { +impl HashedStorage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { fn exists(&self, key: &[u8]) -> bool { - UnhashedStorage::exists(self, &blake2_128(key)) + UnhashedStorage::exists(self, &H::hash(key)) } fn get(&self, key: &[u8]) -> Option { - UnhashedStorage::get(self, &blake2_128(key)) + UnhashedStorage::get(self, &H::hash(key)) } fn put(&self, key: &[u8], val: &T) { - UnhashedStorage::put(self, &blake2_128(key), val) + UnhashedStorage::put(self, &H::hash(key), val) } fn kill(&self, key: &[u8]) { - UnhashedStorage::kill(self, &blake2_128(key)) + UnhashedStorage::kill(self, &H::hash(key)) } } @@ -144,26 +108,26 @@ pub trait StorageValue { fn key() -> &'static [u8]; /// true if the value is defined in storage. - fn exists(storage: &S) -> bool { + fn exists>(storage: &S) -> bool { storage.exists(Self::key()) } /// Load the value from the provided storage instance. - fn get(storage: &S) -> Self::Query; + fn get>(storage: &S) -> Self::Query; /// Take a value from storage, removing it afterwards. - fn take(storage: &S) -> Self::Query; + fn take>(storage: &S) -> Self::Query; /// Store a value under this key into the provided storage instance. - fn put(val: &T, storage: &S) { + fn put>(val: &T, storage: &S) { storage.put(Self::key(), val) } /// Mutate this value - fn mutate R, S: Twox128Storage>(f: F, storage: &S) -> R; + fn mutate R, S: HashedStorage>(f: F, storage: &S) -> R; /// Clear the storage value. - fn kill(storage: &S) { + fn kill>(storage: &S) { storage.kill(Self::key()) } } @@ -180,22 +144,22 @@ pub trait StorageList { fn key_for(index: u32) -> Vec; /// Read out all the items. - fn items(storage: &S) -> Vec; + fn items>(storage: &S) -> Vec; /// Set the current set of items. - fn set_items(items: &[T], storage: &S); + fn set_items>(items: &[T], storage: &S); /// Set the item at the given index. - fn set_item(index: u32, item: &T, storage: &S); + fn set_item>(index: u32, item: &T, storage: &S); /// Load the value at given index. Returns `None` if the index is out-of-bounds. - fn get(index: u32, storage: &S) -> Option; + fn get>(index: u32, storage: &S) -> Option; /// Load the length of the list - fn len(storage: &S) -> u32; + fn len>(storage: &S) -> u32; /// Clear the list. - fn clear(storage: &S); + fn clear>(storage: &S); } /// A strongly-typed map in storage. @@ -210,35 +174,35 @@ pub trait StorageMap { fn key_for(x: &K) -> Vec; /// true if the value is defined in storage. - fn exists(key: &K, storage: &S) -> bool { + fn exists>(key: &K, storage: &S) -> bool { storage.exists(&Self::key_for(key)[..]) } /// Load the value associated with the given key from the map. - fn get(key: &K, storage: &S) -> Self::Query; + fn get>(key: &K, storage: &S) -> Self::Query; /// Take the value under a key. - fn take(key: &K, storage: &S) -> Self::Query; + fn take>(key: &K, storage: &S) -> Self::Query; /// Store a value to be associated with the given key from the map. - fn insert(key: &K, val: &V, storage: &S) { + fn insert>(key: &K, val: &V, storage: &S) { storage.put(&Self::key_for(key)[..], val); } /// Remove the value under a key. - fn remove(key: &K, storage: &S) { + fn remove>(key: &K, storage: &S) { storage.kill(&Self::key_for(key)[..]); } /// Mutate the value under a key. - fn mutate R, S: Blake2_128Storage>(key: &K, f: F, storage: &S) -> R; + fn mutate R, S: HashedStorage>(key: &K, f: F, storage: &S) -> R; } /// A `StorageMap` with enumerable entries. pub trait EnumerableStorageMap: StorageMap { /// Return current head element. - fn head(storage: &S) -> Option; + fn head>(storage: &S) -> Option; /// Enumerate all elements in the map. - fn enumerate<'a, S: Blake2_128Storage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; + fn enumerate<'a, S: HashedStorage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; } diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index 98684dfcc7fed..5bcb662f1258e 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -19,7 +19,8 @@ use crate::rstd::prelude::*; use crate::rstd::borrow::Borrow; use crate::codec::{Codec, Encode, Decode, KeyedVec, Input}; -use runtime_io::{twox_128, blake2_128}; +use hashed::generator::{HashedStorage, StorageHasher}; +use unhashed::generator::UnhashedStorage; #[macro_use] pub mod storage_items; @@ -58,59 +59,33 @@ impl<'a> Input for IncrementalChildInput<'a> { /// The underlying runtime storage. pub struct RuntimeStorage; -impl hashed::generator::Twox128Storage for RuntimeStorage { +impl HashedStorage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { - hashed::exists(&twox_128, key) + hashed::exists(&H::hash, key) } /// Load the bytes of a key from storage. Can panic if the type is incorrect. fn get(&self, key: &[u8]) -> Option { - hashed::get(&twox_128, key) + hashed::get(&H::hash, key) } /// Put a value in under a key. fn put(&self, key: &[u8], val: &T) { - hashed::put(&twox_128, key, val) + hashed::put(&H::hash, key, val) } /// Remove the bytes of a key from storage. fn kill(&self, key: &[u8]) { - hashed::kill(&twox_128, key) + hashed::kill(&H::hash, key) } /// Take a value from storage, deleting it after reading. fn take(&self, key: &[u8]) -> Option { - hashed::take(&twox_128, key) + hashed::take(&H::hash, key) } } -impl hashed::generator::Blake2_128Storage for RuntimeStorage { - fn exists(&self, key: &[u8]) -> bool { - hashed::exists(&blake2_128, key) - } - - /// Load the bytes of a key from storage. Can panic if the type is incorrect. - fn get(&self, key: &[u8]) -> Option { - hashed::get(&blake2_128, key) - } - - /// Put a value in under a key. - fn put(&self, key: &[u8], val: &T) { - hashed::put(&blake2_128, key, val) - } - - /// Remove the bytes of a key from storage. - fn kill(&self, key: &[u8]) { - hashed::kill(&blake2_128, key) - } - - /// Take a value from storage, deleting it after reading. - fn take(&self, key: &[u8]) -> Option { - hashed::take(&blake2_128, key) - } -} - -impl unhashed::generator::UnhashedStorage for RuntimeStorage { +impl UnhashedStorage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { unhashed::exists(key) } diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 1d3049ee7c4ba..c7a20c7ed9158 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -192,17 +192,17 @@ macro_rules! __storage_items_internal { } /// Load the value from the provided storage instance. - fn get(storage: &S) -> Self::Query { + fn get>(storage: &S) -> Self::Query { storage.$getter($key) } /// Take a value from storage, removing it afterwards. - fn take(storage: &S) -> Self::Query { + fn take>(storage: &S) -> Self::Query { storage.$taker($key) } /// Mutate this value. - fn mutate R, S: $crate::Twox128Storage>(f: F, storage: &S) -> R { + fn mutate R, S: $crate::HashedStorage<$crate::Twox>>(f: F, storage: &S) -> R { let mut val = >::get(storage); let ret = f(&mut val); @@ -248,19 +248,19 @@ macro_rules! __storage_items_internal { } /// Load the value associated with the given key from the map. - fn get(key: &$kty, storage: &S) -> Self::Query { + fn get>(key: &$kty, storage: &S) -> Self::Query { let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$getter(&key[..]) } /// Take the value, reading and removing it. - fn take(key: &$kty, storage: &S) -> Self::Query { + fn take>(key: &$kty, storage: &S) -> Self::Query { let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$taker(&key[..]) } /// Mutate the value under a key. - fn mutate R, S: $crate::Blake2_128Storage>(key: &$kty, f: F, storage: &S) -> R { + fn mutate R, S: $crate::HashedStorage<$crate::Blake2>>(key: &$kty, f: F, storage: &S) -> R { let mut val = >::take(key, storage); let ret = f(&mut val); @@ -285,13 +285,13 @@ macro_rules! __storage_items_internal { $($vis)* struct $name; impl $name { - fn clear_item(index: u32, storage: &S) { + fn clear_item>(index: u32, storage: &S) { if index < <$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { storage.kill(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)); } } - fn set_len(count: u32, storage: &S) { + fn set_len>(count: u32, storage: &S) { (count..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage)).for_each(|i| $name::clear_item(i, storage)); storage.put(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len_key(), &count); } @@ -318,38 +318,38 @@ macro_rules! __storage_items_internal { } /// Read out all the items. - fn items(storage: &S) -> $crate::rstd::vec::Vec<$ty> { + fn items>(storage: &S) -> $crate::rstd::vec::Vec<$ty> { (0..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage)) .map(|i| <$name as $crate::storage::hashed::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed")) .collect() } /// Set the current set of items. - fn set_items(items: &[$ty], storage: &S) { + fn set_items>(items: &[$ty], storage: &S) { $name::set_len(items.len() as u32, storage); items.iter() .enumerate() .for_each(|(i, item)| <$name as $crate::storage::hashed::generator::StorageList<$ty>>::set_item(i as u32, item, storage)); } - fn set_item(index: u32, item: &$ty, storage: &S) { + fn set_item>(index: u32, item: &$ty, storage: &S) { if index < <$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { storage.put(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)[..], item); } } /// Load the value at given index. Returns `None` if the index is out-of-bounds. - fn get(index: u32, storage: &S) -> Option<$ty> { + fn get>(index: u32, storage: &S) -> Option<$ty> { storage.get(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)[..]) } /// Load the length of the list. - fn len(storage: &S) -> u32 { + fn len>(storage: &S) -> u32 { storage.get(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len_key()).unwrap_or_default() } /// Clear the list. - fn clear(storage: &S) { + fn clear>(storage: &S) { for i in 0..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { $name::clear_item(i, storage); } From d366476baec948c38df07ae91eae99b1eaf7efdb Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 17 Apr 2019 17:43:39 +0200 Subject: [PATCH 06/22] fix --- srml/support/src/storage/hashed/generator.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index 17419a5fa5896..d48c6e4490a23 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -20,7 +20,6 @@ use crate::codec; use crate::rstd::prelude::{Vec, Box}; #[cfg(feature = "std")] use crate::storage::unhashed::generator::UnhashedStorage; -#[cfg(feature = "std")] use runtime_io::{twox_128, blake2_128}; pub trait StorageHasher { From bb0082262564282b085322ab5e702c746397b756 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 17:11:17 +0200 Subject: [PATCH 07/22] parameterizable hasher --- srml/metadata/src/lib.rs | 10 ++ srml/support/procedural/src/storage/impls.rs | 65 ++++++----- srml/support/procedural/src/storage/mod.rs | 29 ++++- .../procedural/src/storage/transformation.rs | 21 ++-- srml/support/src/lib.rs | 2 +- srml/support/src/storage/hashed/generator.rs | 102 ++++++++++++------ srml/support/src/storage/hashed/mod.rs | 54 +++++----- srml/support/src/storage/mod.rs | 2 +- .../support/src/storage/unhashed/generator.rs | 7 +- 9 files changed, 184 insertions(+), 108 deletions(-) diff --git a/srml/metadata/src/lib.rs b/srml/metadata/src/lib.rs index 9b03daafa65d3..558ed93543da7 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -253,6 +253,16 @@ impl std::fmt::Debug for DefaultByteGetter { } } +/// Hasher used by storage maps +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub enum StorageHasher { + Blake2_128, + Blake2_256, + Twox128, + Twox256, +} + /// A storage function type. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index 65d35ef87e22c..b1a8262c99b87 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -110,19 +110,19 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query { + fn get>(storage: &S) -> Self::Query { storage.get(>::key()) .#option_simple_1(|| #fielddefault) } /// Take a value from storage, removing it afterwards. - fn take>(storage: &S) -> Self::Query { + fn take>(storage: &S) -> Self::Query { storage.take(>::key()) .#option_simple_1(|| #fielddefault) } /// Mutate the value under a key. - fn mutate R, S: #scrate::HashedStorage<#scrate::Twox>>(f: F, storage: &S) -> R { + fn mutate R, S: #scrate::HashedStorage<#scrate::Twox128>>(f: F, storage: &S) -> R { let mut val = >::get(storage); let ret = f(&mut val); @@ -133,7 +133,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - pub fn map(self, kty: &syn::Type) -> TokenStream2 { + pub fn map(self, hasher: TokenStream2, kty: &syn::Type) -> TokenStream2 { let Self { scrate, visibility, @@ -191,6 +191,8 @@ impl<'a, I: Iterator> Impls<'a, I> { { type Query = #value_type; + type Hasher = #scrate::#hasher; + /// Get the prefix key in storage. fn prefix() -> &'static [u8] { #final_prefix @@ -204,19 +206,19 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value associated with the given key from the map. - fn get>(key: &#kty, storage: &S) -> Self::Query { + fn get>(key: &#kty, storage: &S) -> Self::Query { let key = #as_map::key_for(key); storage.get(&key[..]).#option_simple_1(|| #fielddefault) } /// Take the value, reading and removing it. - fn take>(key: &#kty, storage: &S) -> Self::Query { + fn take>(key: &#kty, storage: &S) -> Self::Query { let key = #as_map::key_for(key); storage.take(&key[..]).#option_simple_1(|| #fielddefault) } /// Mutate the value under a key - fn mutate R, S: #scrate::HashedStorage<#scrate::Blake2>>(key: &#kty, f: F, storage: &S) -> R { + fn mutate R, S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, f: F, storage: &S) -> R { let mut val = #as_map::get(key, storage); let ret = f(&mut val); @@ -228,7 +230,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - pub fn linked_map(self, kty: &syn::Type) -> TokenStream2 { + pub fn linked_map(self, hasher: TokenStream2, kty: &syn::Type) -> TokenStream2 { let Self { scrate, visibility, @@ -324,7 +326,7 @@ impl<'a, I: Iterator> Impls<'a, I> { pub _data: #phantom_data, } - impl<'a, S: #scrate::HashedStorage<#scrate::Blake2>, #traitinstance: #traittype, #instance #bound_instantiable> + impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #traitinstance: #traittype, #instance #bound_instantiable> Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)> where #traitinstance: 'a { @@ -347,26 +349,26 @@ impl<'a, I: Iterator> Impls<'a, I> { /// /// Takes care of updating previous and next elements points /// as well as updates head if the element is first or last. - fn remove_linkage>(linkage: Linkage<#kty>, storage: &S); + fn remove_linkage>(linkage: Linkage<#kty>, storage: &S); /// Read the contained data and it's linkage. - fn read_with_linkage>(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>; + fn read_with_linkage>(storage: &S, key: &[u8]) -> Option<(#value_type, Linkage<#kty>)>; /// Generate linkage for newly inserted element. /// /// Takes care of updating head and previous head's pointer. - fn new_head_linkage>( + fn new_head_linkage>( storage: &S, key: &#kty, ) -> Linkage<#kty>; /// Read current head pointer. - fn read_head>(storage: &S) -> Option<#kty>; + fn read_head>(storage: &S) -> Option<#kty>; /// Overwrite current head pointer. /// /// If `None` is given head is removed from storage. - fn write_head>(storage: &S, head: Option<&#kty>); + fn write_head>(storage: &S, head: Option<&#kty>); } } }; @@ -376,7 +378,7 @@ impl<'a, I: Iterator> Impls<'a, I> { #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#phantom_data<(#traitinstance #comma_instance)>); impl<#traitinstance: #traittype, #instance #bound_instantiable> self::#inner_module::Utils<#traitinstance, #instance> for #name<#traitinstance, #instance> { - fn remove_linkage>( + fn remove_linkage>( linkage: self::#inner_module::Linkage<#kty>, storage: &S, ) { @@ -405,14 +407,14 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - fn read_with_linkage>( + fn read_with_linkage>( storage: &S, key: &[u8], ) -> Option<(#value_type, self::#inner_module::Linkage<#kty>)> { storage.get(key) } - fn new_head_linkage>( + fn new_head_linkage>( storage: &S, key: &#kty, ) -> self::#inner_module::Linkage<#kty> { @@ -444,11 +446,11 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - fn read_head>(storage: &S) -> Option<#kty> { + fn read_head>(storage: &S) -> Option<#kty> { storage.get(#final_head_key) } - fn write_head>(storage: &S, head: Option<&#kty>) { + fn write_head>(storage: &S, head: Option<&#kty>) { match head { Some(head) => storage.put(#final_head_key, head), None => storage.kill(#final_head_key), @@ -467,6 +469,8 @@ impl<'a, I: Iterator> Impls<'a, I> { { type Query = #value_type; + type Hasher = #scrate::#hasher; + /// Get the prefix key in storage. fn prefix() -> &'static [u8] { #final_prefix @@ -480,12 +484,12 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Load the value associated with the given key from the map. - fn get>(key: &#kty, storage: &S) -> Self::Query { + fn get>(key: &#kty, storage: &S) -> Self::Query { storage.get(&*#as_map::key_for(key)).#option_simple_1(|| #fielddefault) } /// Take the value, reading and removing it. - fn take>(key: &#kty, storage: &S) -> Self::Query { + fn take>(key: &#kty, storage: &S) -> Self::Query { use self::#inner_module::Utils; let res: Option<(#value_type, self::#inner_module::Linkage<#kty>)> = storage.take(&*#as_map::key_for(key)); @@ -499,12 +503,12 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Remove the value under a key. - fn remove>(key: &#kty, storage: &S) { + fn remove>(key: &#kty, storage: &S) { #as_map::take(key, storage); } /// Store a value to be associated with the given key from the map. - fn insert>(key: &#kty, val: &#typ, storage: &S) { + fn insert>(key: &#kty, val: &#typ, storage: &S) { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -518,7 +522,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } /// Mutate the value under a key - fn mutate R, S: #scrate::HashedStorage<#scrate::Blake2>>(key: &#kty, f: F, storage: &S) -> R { + fn mutate R, S: #scrate::HashedStorage<#scrate::#hasher>>(key: &#kty, f: F, storage: &S) -> R { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -535,13 +539,13 @@ impl<'a, I: Iterator> Impls<'a, I> { impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> #scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> { - fn head>(storage: &S) -> Option<#kty> { + fn head>(storage: &S) -> Option<#kty> { use self::#inner_module::Utils; Self::read_head(storage) } - fn enumerate<'a, S: #scrate::HashedStorage<#scrate::Blake2>>(storage: &'a S) -> #scrate::rstd::boxed::Box + 'a> where + fn enumerate<'a, S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &'a S) -> #scrate::rstd::boxed::Box + 'a> where #kty: 'a, #typ: 'a, { @@ -557,7 +561,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - pub fn double_map(self, k1ty: &syn::Type, k2ty: &syn::Type, k2_hasher: TokenStream2) -> TokenStream2 { + pub fn double_map(self, hasher: TokenStream2, k1ty: &syn::Type, k2ty: &syn::Type, k2_hasher: TokenStream2) -> TokenStream2 { let Self { scrate, visibility, @@ -616,6 +620,13 @@ impl<'a, I: Iterator> Impls<'a, I> { { type Query = #value_type; + fn prefix_for(k1: &K1) -> Vec { + let mut key = Self::prefix().to_vec(); + codec::Encode::encode_to(k1, &mut key); + key.extend(&#scrate::Hashable::#k2_hasher(k2)); + #scrate::Hashable::#k2_hasher(&key).to_vec() + } + fn prefix() -> &'static [u8] { #final_prefix } diff --git a/srml/support/procedural/src/storage/mod.rs b/srml/support/procedural/src/storage/mod.rs index 82290e0de458f..fcacb65792184 100644 --- a/srml/support/procedural/src/storage/mod.rs +++ b/srml/support/procedural/src/storage/mod.rs @@ -23,6 +23,8 @@ use srml_support_procedural_tools::{ToTokens, Parse, custom_keyword, custom_keyw use syn::{Ident, Token}; use syn::token::CustomKeyword; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; mod impls; @@ -138,6 +140,7 @@ enum DeclStorageType { #[derive(Parse, ToTokens, Debug)] struct DeclStorageMap { pub map_keyword: ext::CustomToken, + pub hasher: Option, pub key: syn::Type, pub ass_keyword: Token![=>], pub value: syn::Type, @@ -146,6 +149,7 @@ struct DeclStorageMap { #[derive(Parse, ToTokens, Debug)] struct DeclStorageLinkedMap { pub map_keyword: ext::CustomToken, + pub hasher: Option, pub key: syn::Type, pub ass_keyword: Token![=>], pub value: syn::Type, @@ -154,17 +158,19 @@ struct DeclStorageLinkedMap { #[derive(Parse, ToTokens, Debug)] struct DeclStorageDoubleMap { pub map_keyword: ext::CustomToken, + pub hasher: Option, pub key1: syn::Type, pub comma_keyword: Token![,], - pub key2_hasher: DeclStorageDoubleMapHasher, + pub key2_hasher: Hasher, pub key2: ext::Parens, pub ass_keyword: Token![=>], pub value: syn::Type, } #[derive(Parse, ToTokens, Debug)] -enum DeclStorageDoubleMapHasher { +enum Hasher { Blake2_256(ext::CustomToken), + Blake2_128(ext::CustomToken), Twox256(ext::CustomToken), Twox128(ext::CustomToken), } @@ -175,6 +181,23 @@ struct DeclStorageDefault { pub expr: syn::Expr, } +#[derive(Parse, ToTokens, Debug)] +struct SetHasher { + pub hasher_keyword: ext::CustomToken, + pub inner: ext::Parens, +} + +impl SetHasher { + fn into_storage_hasher(&self) -> TokenStream2 { + match self.inner.content { + Hasher::Blake2_256(_) => quote!( Blake2_256 ), + Hasher::Blake2_128(_) => quote!( Blake2_128 ), + Hasher::Twox256(_) => quote!( Twox256 ), + Hasher::Twox128(_) => quote!( Twox128 ), + } + } +} + custom_keyword_impl!(SpecificHiddenCrate, "hiddencrate", "hiddencrate as keyword"); custom_keyword_impl!(DeclStorageConfig, "config", "build as keyword"); custom_keyword!(ConfigKeyword, "config", "config as keyword"); @@ -186,6 +209,8 @@ custom_keyword!(MapKeyword, "map", "map as keyword"); custom_keyword!(LinkedMapKeyword, "linked_map", "linked_map as keyword"); custom_keyword!(DoubleMapKeyword, "double_map", "double_map as keyword"); custom_keyword!(Blake2_256Keyword, "blake2_256", "Blake2_256 as keyword"); +custom_keyword!(Blake2_128Keyword, "blake2_128", "Blake2_128 as keyword"); custom_keyword!(Twox256Keyword, "twox_256", "Twox_256 as keyword"); custom_keyword!(Twox128Keyword, "twox_128", "Twox_128 as keyword"); custom_keyword_impl!(ExtraGenesisSkipPhantomDataField, "extra_genesis_skip_phantom_data_field", "extra_genesis_skip_phantom_data_field as keyword"); +custom_keyword_impl!(SetHasher, "hasher", "storage hasher"); diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index de85a78c349a6..5cd705feb6694 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -589,14 +589,14 @@ fn decl_storage_items( DeclStorageTypeInfosKind::Simple => { i.simple_value() }, - DeclStorageTypeInfosKind::Map { key_type, is_linked: false } => { - i.map(key_type) + DeclStorageTypeInfosKind::Map { key_type, is_linked: false, hasher } => { + i.map(hasher, key_type) }, - DeclStorageTypeInfosKind::Map { key_type, is_linked: true } => { - i.linked_map(key_type) + DeclStorageTypeInfosKind::Map { key_type, is_linked: true, hasher } => { + i.linked_map(hasher, key_type) }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher } => { - i.double_map(key1_type, key2_type, key2_hasher) + DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => { + i.double_map(hasher, key1_type, key2_type, key2_hasher) }, }; impls.extend(implementation) @@ -732,7 +732,7 @@ fn store_functions_to_metadata ( ) } }, - DeclStorageTypeInfosKind::Map { key_type, is_linked } => { + DeclStorageTypeInfosKind::Map { key_type, is_linked, hasher } => { let kty = clean_type_string("e!(#key_type).to_string()); quote!{ #scrate::metadata::StorageFunctionType::Map { @@ -742,7 +742,7 @@ fn store_functions_to_metadata ( } } }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher } => { + DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => { let k1ty = clean_type_string("e!(#key1_type).to_string()); let k2ty = clean_type_string("e!(#key2_type).to_string()); let k2_hasher = clean_type_string(&key2_hasher.to_string()); @@ -848,10 +848,12 @@ pub(crate) struct DeclStorageTypeInfos<'a> { enum DeclStorageTypeInfosKind<'a> { Simple, Map { + hasher: TokenStream2, key_type: &'a syn::Type, is_linked: bool, }, DoubleMap { + hasher: TokenStream2, key1_type: &'a syn::Type, key2_type: &'a syn::Type, key2_hasher: TokenStream2, @@ -871,14 +873,17 @@ fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { let (value_type, kind) = match storage_type { DeclStorageType::Simple(ref st) => (st, DeclStorageTypeInfosKind::Simple), DeclStorageType::Map(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { + hasher: map.hasher.as_ref().map(|h| h.into_storage_hasher()).unwrap_or_else(|| quote! (Blake2_128)), key_type: &map.key, is_linked: false, }), DeclStorageType::LinkedMap(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { + hasher: map.hasher.as_ref().map(|h| h.into_storage_hasher()).unwrap_or_else(|| quote! (Blake2_128)), key_type: &map.key, is_linked: true, }), DeclStorageType::DoubleMap(ref map) => (&map.value, DeclStorageTypeInfosKind::DoubleMap { + hasher: map.hasher.as_ref().map(|h| quote! ( #h )).unwrap_or_else(|| quote! ( blake2_128 )), key1_type: &map.key1, key2_type: &map.key2.content, key2_hasher: { let h = &map.key2_hasher; quote! { #h } }, diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 52f000fe7cfb0..1c8dc5d152bea 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -35,7 +35,7 @@ pub use once_cell; pub use paste; pub use sr_primitives as runtime_primitives; -pub use self::storage::hashed::generator::{HashedStorage, Twox, Blake2}; +pub use self::storage::hashed::generator::{HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128}; pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index d48c6e4490a23..4e6513b5bf6dd 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -20,28 +20,49 @@ use crate::codec; use crate::rstd::prelude::{Vec, Box}; #[cfg(feature = "std")] use crate::storage::unhashed::generator::UnhashedStorage; -use runtime_io::{twox_128, blake2_128}; +use runtime_io::{twox_128, blake2_128, twox_256, blake2_256}; -pub trait StorageHasher { - fn hash(x: &[u8]) -> [u8; 16]; +pub trait StorageHasher: 'static { + type Output: AsRef<[u8]>; + fn hash(x: &[u8]) -> Self::Output; } /// Hash storage keys with blake2 128 -pub struct Blake2; -impl StorageHasher for Blake2 { +pub struct Blake2_128; +impl StorageHasher for Blake2_128 { + type Output = [u8; 16]; fn hash(x: &[u8]) -> [u8; 16] { blake2_128(x) } } +/// Hash storage keys with blake2 256 +pub struct Blake2_256; +impl StorageHasher for Blake2_256 { + type Output = [u8; 32]; + fn hash(x: &[u8]) -> [u8; 32] { + blake2_256(x) + } +} + /// Hash storage keys with twox 128 -pub struct Twox; -impl StorageHasher for Twox { +pub struct Twox128; +impl StorageHasher for Twox128 { + type Output = [u8; 16]; fn hash(x: &[u8]) -> [u8; 16] { twox_128(x) } } +/// Hash storage keys with twox 256 +pub struct Twox256; +impl StorageHasher for Twox256 { + type Output = [u8; 32]; + fn hash(x: &[u8]) -> [u8; 32] { + twox_256(x) + } +} + /// Abstraction around storage. pub trait HashedStorage { /// true if the key exists in storage. @@ -52,11 +73,15 @@ pub trait HashedStorage { /// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if /// it's not there. - fn require(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") } + fn require(&self, key: &[u8]) -> T { + self.get(key).expect("Required values must be in storage") + } /// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's /// default is returned if it's not there. - fn get_or_default(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() } + fn get_or_default(&self, key: &[u8]) -> T { + self.get(key).unwrap_or_default() + } /// Put a value in under a key. fn put(&self, key: &[u8], val: &T); @@ -72,29 +97,33 @@ pub trait HashedStorage { } /// Take a value from storage, deleting it after reading. - fn take_or_panic(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") } + fn take_or_panic(&self, key: &[u8]) -> T { + self.take(key).expect("Required values must be in storage") + } /// Take a value from storage, deleting it after reading. - fn take_or_default(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() } + fn take_or_default(&self, key: &[u8]) -> T { + self.take(key).unwrap_or_default() + } } // We use a construct like this during when genesis storage is being built. #[cfg(feature = "std")] impl HashedStorage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { fn exists(&self, key: &[u8]) -> bool { - UnhashedStorage::exists(self, &H::hash(key)) + UnhashedStorage::exists(self, &H::hash(key).as_ref()) } fn get(&self, key: &[u8]) -> Option { - UnhashedStorage::get(self, &H::hash(key)) + UnhashedStorage::get(self, &H::hash(key).as_ref()) } fn put(&self, key: &[u8], val: &T) { - UnhashedStorage::put(self, &H::hash(key), val) + UnhashedStorage::put(self, &H::hash(key).as_ref(), val) } fn kill(&self, key: &[u8]) { - UnhashedStorage::kill(self, &H::hash(key)) + UnhashedStorage::kill(self, &H::hash(key).as_ref()) } } @@ -107,32 +136,33 @@ pub trait StorageValue { fn key() -> &'static [u8]; /// true if the value is defined in storage. - fn exists>(storage: &S) -> bool { + fn exists>(storage: &S) -> bool { storage.exists(Self::key()) } /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query; + fn get>(storage: &S) -> Self::Query; /// Take a value from storage, removing it afterwards. - fn take>(storage: &S) -> Self::Query; + fn take>(storage: &S) -> Self::Query; /// Store a value under this key into the provided storage instance. - fn put>(val: &T, storage: &S) { + fn put>(val: &T, storage: &S) { storage.put(Self::key(), val) } /// Mutate this value - fn mutate R, S: HashedStorage>(f: F, storage: &S) -> R; + fn mutate R, S: HashedStorage>(f: F, storage: &S) -> R; /// Clear the storage value. - fn kill>(storage: &S) { + fn kill>(storage: &S) { storage.kill(Self::key()) } } /// A strongly-typed list in storage. pub trait StorageList { + type Hasher: StorageHasher; /// Get the prefix key in storage. fn prefix() -> &'static [u8]; @@ -143,22 +173,22 @@ pub trait StorageList { fn key_for(index: u32) -> Vec; /// Read out all the items. - fn items>(storage: &S) -> Vec; + fn items>(storage: &S) -> Vec; /// Set the current set of items. - fn set_items>(items: &[T], storage: &S); + fn set_items>(items: &[T], storage: &S); /// Set the item at the given index. - fn set_item>(index: u32, item: &T, storage: &S); + fn set_item>(index: u32, item: &T, storage: &S); /// Load the value at given index. Returns `None` if the index is out-of-bounds. - fn get>(index: u32, storage: &S) -> Option; + fn get>(index: u32, storage: &S) -> Option; /// Load the length of the list - fn len>(storage: &S) -> u32; + fn len>(storage: &S) -> u32; /// Clear the list. - fn clear>(storage: &S); + fn clear>(storage: &S); } /// A strongly-typed map in storage. @@ -166,6 +196,8 @@ pub trait StorageMap { /// The type that get/take returns. type Query; + type Hasher: StorageHasher; + /// Get the prefix key in storage. fn prefix() -> &'static [u8]; @@ -173,35 +205,35 @@ pub trait StorageMap { fn key_for(x: &K) -> Vec; /// true if the value is defined in storage. - fn exists>(key: &K, storage: &S) -> bool { + fn exists>(key: &K, storage: &S) -> bool { storage.exists(&Self::key_for(key)[..]) } /// Load the value associated with the given key from the map. - fn get>(key: &K, storage: &S) -> Self::Query; + fn get>(key: &K, storage: &S) -> Self::Query; /// Take the value under a key. - fn take>(key: &K, storage: &S) -> Self::Query; + fn take>(key: &K, storage: &S) -> Self::Query; /// Store a value to be associated with the given key from the map. - fn insert>(key: &K, val: &V, storage: &S) { + fn insert>(key: &K, val: &V, storage: &S) { storage.put(&Self::key_for(key)[..], val); } /// Remove the value under a key. - fn remove>(key: &K, storage: &S) { + fn remove>(key: &K, storage: &S) { storage.kill(&Self::key_for(key)[..]); } /// Mutate the value under a key. - fn mutate R, S: HashedStorage>(key: &K, f: F, storage: &S) -> R; + fn mutate R, S: HashedStorage>(key: &K, f: F, storage: &S) -> R; } /// A `StorageMap` with enumerable entries. pub trait EnumerableStorageMap: StorageMap { /// Return current head element. - fn head>(storage: &S) -> Option; + fn head>(storage: &S) -> Option; /// Enumerate all elements in the map. - fn enumerate<'a, S: HashedStorage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; + fn enumerate<'a, S: HashedStorage>(storage: &'a S) -> Box + 'a> where K: 'a, V: 'a; } diff --git a/srml/support/src/storage/hashed/mod.rs b/srml/support/src/storage/hashed/mod.rs index 3fe7968aaf669..b638bd2292961 100644 --- a/srml/support/src/storage/hashed/mod.rs +++ b/srml/support/src/storage/hashed/mod.rs @@ -23,77 +23,75 @@ use crate::rstd::borrow::Borrow; use runtime_io::{self, twox_128}; use crate::codec::{Codec, Encode, Decode, KeyedVec}; -type HashFn = Fn(&[u8]) -> [u8; 16]; - /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. -pub fn get(hash: &HashFn, key: &[u8]) -> Option { - unhashed::get(&hash(key)) +pub fn get R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) -> Option { + unhashed::get(&hash(key).as_ref()) } /// Return the value of the item in storage under `key`, or the type's default if there is no /// explicit entry. -pub fn get_or_default(hash: &HashFn, key: &[u8]) -> T { - unhashed::get_or_default(&hash(key)) +pub fn get_or_default R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) -> T { + unhashed::get_or_default(&hash(key).as_ref()) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. -pub fn get_or(hash: &HashFn, key: &[u8], default_value: T) -> T { - unhashed::get_or(&hash(key), default_value) +pub fn get_or R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8], default_value: T) -> T { + unhashed::get_or(&hash(key).as_ref(), default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. -pub fn get_or_else T>(hash: &HashFn, key: &[u8], default_value: F) -> T { - unhashed::get_or_else(&hash(key), default_value) +pub fn get_or_else T, HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8], default_value: F) -> T { + unhashed::get_or_else(&hash(key).as_ref(), default_value) } /// Put `value` in storage under `key`. -pub fn put(hash: &HashFn, key: &[u8], value: &T) { - unhashed::put(&hash(key), value) +pub fn put R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8], value: &T) { + unhashed::put(&hash(key).as_ref(), value) } /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. -pub fn take(hash: &HashFn, key: &[u8]) -> Option { - unhashed::take(&hash(key)) +pub fn take R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) -> Option { + unhashed::take(&hash(key).as_ref()) } /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, /// the default for its type. -pub fn take_or_default(hash: &HashFn, key: &[u8]) -> T { - unhashed::take_or_default(&hash(key)) +pub fn take_or_default R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) -> T { + unhashed::take_or_default(&hash(key).as_ref()) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or(hash: &HashFn, key: &[u8], default_value: T) -> T { - unhashed::take_or(&hash(key), default_value) +pub fn take_or R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8], default_value: T) -> T { + unhashed::take_or(&hash(key).as_ref(), default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or_else T>(hash: &HashFn, key: &[u8], default_value: F) -> T { - unhashed::take_or_else(&hash(key), default_value) +pub fn take_or_else T, HashFn: Fn(&[u8]) -> R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8], default_value: F) -> T { + unhashed::take_or_else(&hash(key).as_ref(), default_value) } /// Check to see if `key` has an explicit entry in storage. -pub fn exists(hash: &HashFn, key: &[u8]) -> bool { - unhashed::exists(&hash(key)) +pub fn exists R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) -> bool { + unhashed::exists(&hash(key).as_ref()) } /// Ensure `key` has no explicit entry in storage. -pub fn kill(hash: &HashFn, key: &[u8]) { - unhashed::kill(&hash(key)) +pub fn kill R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) { + unhashed::kill(&hash(key).as_ref()) } /// Get a Vec of bytes from storage. -pub fn get_raw(hash: &HashFn, key: &[u8]) -> Option> { - unhashed::get_raw(&hash(key)) +pub fn get_raw R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8]) -> Option> { + unhashed::get_raw(&hash(key).as_ref()) } /// Put a raw byte slice into storage. -pub fn put_raw(hash: &HashFn, key: &[u8], value: &[u8]) { - unhashed::put_raw(&hash(key), value) +pub fn put_raw R, R: AsRef<[u8]>>(hash: &HashFn, key: &[u8], value: &[u8]) { + unhashed::put_raw(&hash(key).as_ref(), value) } /// A trait to conveniently store a vector of storable data. diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index 5bcb662f1258e..eaf1282764bba 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -59,7 +59,7 @@ impl<'a> Input for IncrementalChildInput<'a> { /// The underlying runtime storage. pub struct RuntimeStorage; -impl HashedStorage for RuntimeStorage { +impl HashedStorage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { hashed::exists(&H::hash, key) } diff --git a/srml/support/src/storage/unhashed/generator.rs b/srml/support/src/storage/unhashed/generator.rs index 55177ae09b5c2..b2a920714487b 100644 --- a/srml/support/src/storage/unhashed/generator.rs +++ b/srml/support/src/storage/unhashed/generator.rs @@ -15,7 +15,6 @@ // along with Substrate. If not, see . use crate::codec; -use runtime_io::blake2_128; use crate::rstd::vec::Vec; /// Abstraction around storage with unhashed access. @@ -107,11 +106,7 @@ pub trait StorageDoubleMap fn key_for(k1: &K1, k2: &K2) -> Vec; /// Get the storage prefix used to fetch keys corresponding to a specific key1. - fn prefix_for(k1: &K1) -> Vec { - let mut key = Self::prefix().to_vec(); - codec::Encode::encode_to(k1, &mut key); - blake2_128(&key).to_vec() - } + fn prefix_for(k1: &K1) -> Vec; /// true if the value is defined in storage. fn exists(k1: &K1, k2: &K2, storage: &S) -> bool { From f1f749174a9f3b67a379b92df5bb283d9c92956c Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 17:20:28 +0200 Subject: [PATCH 08/22] some fix --- srml/support/src/storage/hashed/generator.rs | 1 - srml/support/src/storage/storage_items.rs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index 4e6513b5bf6dd..c50032408b2ef 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -162,7 +162,6 @@ pub trait StorageValue { /// A strongly-typed list in storage. pub trait StorageList { - type Hasher: StorageHasher; /// Get the prefix key in storage. fn prefix() -> &'static [u8]; diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index c7a20c7ed9158..f27918e7b2d67 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -235,6 +235,8 @@ macro_rules! __storage_items_internal { impl $crate::storage::hashed::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; + type Hasher = $crate::Twox128; + /// Get the prefix key in storage. fn prefix() -> &'static [u8] { $prefix From ab4e9980b640ef6e8534cac57f9a3fcc61a46602 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 17:24:05 +0200 Subject: [PATCH 09/22] fix --- srml/support/src/storage/hashed/mod.rs | 2 +- srml/support/src/storage/storage_items.rs | 28 +++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/srml/support/src/storage/hashed/mod.rs b/srml/support/src/storage/hashed/mod.rs index b638bd2292961..8ab6ca64ca9a7 100644 --- a/srml/support/src/storage/hashed/mod.rs +++ b/srml/support/src/storage/hashed/mod.rs @@ -201,7 +201,7 @@ mod tests { with_externalities(&mut t, || { runtime_io::set_storage(&twox_128(b":test"), b"\x2cHello world"); let x = b"Hello world".to_vec(); - let y = get::>(&twox_128, b":test").unwrap(); + let y = get::, _, _>(&twox_128, b":test").unwrap(); assert_eq!(x, y); }); diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index f27918e7b2d67..a17422ea6c8bb 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -192,17 +192,17 @@ macro_rules! __storage_items_internal { } /// Load the value from the provided storage instance. - fn get>(storage: &S) -> Self::Query { + fn get>(storage: &S) -> Self::Query { storage.$getter($key) } /// Take a value from storage, removing it afterwards. - fn take>(storage: &S) -> Self::Query { + fn take>(storage: &S) -> Self::Query { storage.$taker($key) } /// Mutate this value. - fn mutate R, S: $crate::HashedStorage<$crate::Twox>>(f: F, storage: &S) -> R { + fn mutate R, S: $crate::HashedStorage<$crate::Twox128>>(f: F, storage: &S) -> R { let mut val = >::get(storage); let ret = f(&mut val); @@ -250,19 +250,19 @@ macro_rules! __storage_items_internal { } /// Load the value associated with the given key from the map. - fn get>(key: &$kty, storage: &S) -> Self::Query { + fn get>(key: &$kty, storage: &S) -> Self::Query { let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$getter(&key[..]) } /// Take the value, reading and removing it. - fn take>(key: &$kty, storage: &S) -> Self::Query { + fn take>(key: &$kty, storage: &S) -> Self::Query { let key = <$name as $crate::storage::hashed::generator::StorageMap<$kty, $ty>>::key_for(key); storage.$taker(&key[..]) } /// Mutate the value under a key. - fn mutate R, S: $crate::HashedStorage<$crate::Blake2>>(key: &$kty, f: F, storage: &S) -> R { + fn mutate R, S: $crate::HashedStorage>(key: &$kty, f: F, storage: &S) -> R { let mut val = >::take(key, storage); let ret = f(&mut val); @@ -287,13 +287,13 @@ macro_rules! __storage_items_internal { $($vis)* struct $name; impl $name { - fn clear_item>(index: u32, storage: &S) { + fn clear_item>(index: u32, storage: &S) { if index < <$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { storage.kill(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)); } } - fn set_len>(count: u32, storage: &S) { + fn set_len>(count: u32, storage: &S) { (count..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage)).for_each(|i| $name::clear_item(i, storage)); storage.put(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len_key(), &count); } @@ -320,38 +320,38 @@ macro_rules! __storage_items_internal { } /// Read out all the items. - fn items>(storage: &S) -> $crate::rstd::vec::Vec<$ty> { + fn items>(storage: &S) -> $crate::rstd::vec::Vec<$ty> { (0..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage)) .map(|i| <$name as $crate::storage::hashed::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed")) .collect() } /// Set the current set of items. - fn set_items>(items: &[$ty], storage: &S) { + fn set_items>(items: &[$ty], storage: &S) { $name::set_len(items.len() as u32, storage); items.iter() .enumerate() .for_each(|(i, item)| <$name as $crate::storage::hashed::generator::StorageList<$ty>>::set_item(i as u32, item, storage)); } - fn set_item>(index: u32, item: &$ty, storage: &S) { + fn set_item>(index: u32, item: &$ty, storage: &S) { if index < <$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { storage.put(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)[..], item); } } /// Load the value at given index. Returns `None` if the index is out-of-bounds. - fn get>(index: u32, storage: &S) -> Option<$ty> { + fn get>(index: u32, storage: &S) -> Option<$ty> { storage.get(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::key_for(index)[..]) } /// Load the length of the list. - fn len>(storage: &S) -> u32 { + fn len>(storage: &S) -> u32 { storage.get(&<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len_key()).unwrap_or_default() } /// Clear the list. - fn clear>(storage: &S) { + fn clear>(storage: &S) { for i in 0..<$name as $crate::storage::hashed::generator::StorageList<$ty>>::len(storage) { $name::clear_item(i, storage); } From 6a688122e3200371012c73237c1f96bf7ea43d70 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 17:28:16 +0200 Subject: [PATCH 10/22] fix --- srml/support/procedural/src/storage/impls.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index b1a8262c99b87..40bbd43be0214 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -620,11 +620,10 @@ impl<'a, I: Iterator> Impls<'a, I> { { type Query = #value_type; - fn prefix_for(k1: &K1) -> Vec { + fn prefix_for(k1: &#k1ty) -> Vec { let mut key = Self::prefix().to_vec(); - codec::Encode::encode_to(k1, &mut key); - key.extend(&#scrate::Hashable::#k2_hasher(k2)); - #scrate::Hashable::#k2_hasher(&key).to_vec() + #scrate::codec::Encode::encode_to(k1, &mut key); + #scrate::Hashable::#hasher(&key).to_vec() } fn prefix() -> &'static [u8] { From 5b4e552aeae7ee87b99dc4c27e5e977a1f75b437 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 17:29:53 +0200 Subject: [PATCH 11/22] fix --- srml/support/procedural/src/storage/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index 40bbd43be0214..2708fdb213386 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -621,7 +621,7 @@ impl<'a, I: Iterator> Impls<'a, I> { type Query = #value_type; fn prefix_for(k1: &#k1ty) -> Vec { - let mut key = Self::prefix().to_vec(); + let mut key = #as_double_map::prefix().to_vec(); #scrate::codec::Encode::encode_to(k1, &mut key); #scrate::Hashable::#hasher(&key).to_vec() } From 3f60245893ca73da768ea43f00666a68527a993b Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 17:54:02 +0200 Subject: [PATCH 12/22] metadata --- srml/metadata/src/lib.rs | 10 ++-- srml/support/procedural/src/storage/mod.rs | 49 ++++++++++++++++--- .../procedural/src/storage/transformation.rs | 20 +++++--- srml/support/procedural/tools/src/syn_ext.rs | 2 +- srml/support/src/metadata.rs | 12 ++--- 5 files changed, 68 insertions(+), 25 deletions(-) diff --git a/srml/metadata/src/lib.rs b/srml/metadata/src/lib.rs index 558ed93543da7..8a502f637f723 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -269,11 +269,13 @@ pub enum StorageHasher { pub enum StorageFunctionType { Plain(DecodeDifferentStr), Map { + hasher: StorageHasher, key: DecodeDifferentStr, value: DecodeDifferentStr, is_linked: bool, }, DoubleMap { + hasher: StorageHasher, key1: DecodeDifferentStr, key2: DecodeDifferentStr, value: DecodeDifferentStr, @@ -322,8 +324,10 @@ pub enum RuntimeMetadata { V1(RuntimeMetadataDeprecated), /// Version 2 for runtime metadata. No longer used. V2(RuntimeMetadataDeprecated), - /// Version 3 for runtime metadata. - V3(RuntimeMetadataV3), + /// Version 3 for runtime metadata. No longer used. + V3(RuntimeMetadataDeprecated), + /// Version 4 for runtime metadata. + V4(RuntimeMetadataV4), } /// Enum that should fail. @@ -346,7 +350,7 @@ impl Decode for RuntimeMetadataDeprecated { /// The metadata of a runtime. #[derive(Eq, Encode, PartialEq)] #[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] -pub struct RuntimeMetadataV3 { +pub struct RuntimeMetadataV4 { pub modules: DecodeDifferentArray, } diff --git a/srml/support/procedural/src/storage/mod.rs b/srml/support/procedural/src/storage/mod.rs index fcacb65792184..4b8ea331b0896 100644 --- a/srml/support/procedural/src/storage/mod.rs +++ b/srml/support/procedural/src/storage/mod.rs @@ -187,13 +187,48 @@ struct SetHasher { pub inner: ext::Parens, } -impl SetHasher { - fn into_storage_hasher(&self) -> TokenStream2 { - match self.inner.content { - Hasher::Blake2_256(_) => quote!( Blake2_256 ), - Hasher::Blake2_128(_) => quote!( Blake2_128 ), - Hasher::Twox256(_) => quote!( Twox256 ), - Hasher::Twox128(_) => quote!( Twox128 ), +#[derive(Debug, Clone)] +enum HasherKind { + Blake2_256, + Blake2_128, + Twox256, + Twox128, +} + +impl HasherKind { + fn from_set_hasher(set_hasher: &SetHasher) -> Self { + match set_hasher.inner.content { + Hasher::Blake2_256(_) => HasherKind::Blake2_256, + Hasher::Blake2_128(_) => HasherKind::Blake2_128, + Hasher::Twox256(_) => HasherKind::Twox256, + Hasher::Twox128(_) => HasherKind::Twox128, + } + } + + fn into_storage_hasher_struct(&self) -> TokenStream2 { + match self { + HasherKind::Blake2_256 => quote!( Blake2_256 ), + HasherKind::Blake2_128 => quote!( Blake2_128 ), + HasherKind::Twox256 => quote!( Twox256 ), + HasherKind::Twox128 => quote!( Twox128 ), + } + } + + fn into_hashable_fn(&self) -> TokenStream2 { + match self { + HasherKind::Blake2_256 => quote!( blake2_256 ), + HasherKind::Blake2_128 => quote!( blake2_128 ), + HasherKind::Twox256 => quote!( twox_256 ), + HasherKind::Twox128 => quote!( twox_128 ), + } + } + + fn into_metadata(&self) -> TokenStream2 { + match self { + HasherKind::Blake2_256 => quote!( StorageHasher::Blake2_256 ), + HasherKind::Blake2_128 => quote!( StorageHasher::Blake2_128 ), + HasherKind::Twox256 => quote!( StorageHasher::Twox256 ), + HasherKind::Twox128 => quote!( StorageHasher::Twox128 ), } } } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 5cd705feb6694..bc8c6485da899 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -590,13 +590,13 @@ fn decl_storage_items( i.simple_value() }, DeclStorageTypeInfosKind::Map { key_type, is_linked: false, hasher } => { - i.map(hasher, key_type) + i.map(hasher.into_storage_hasher_struct(), key_type) }, DeclStorageTypeInfosKind::Map { key_type, is_linked: true, hasher } => { - i.linked_map(hasher, key_type) + i.linked_map(hasher.into_storage_hasher_struct(), key_type) }, DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => { - i.double_map(hasher, key1_type, key2_type, key2_hasher) + i.double_map(hasher.into_hashable_fn(), key1_type, key2_type, key2_hasher) }, }; impls.extend(implementation) @@ -733,9 +733,11 @@ fn store_functions_to_metadata ( } }, DeclStorageTypeInfosKind::Map { key_type, is_linked, hasher } => { + let hasher = hasher.into_metadata(); let kty = clean_type_string("e!(#key_type).to_string()); quote!{ #scrate::metadata::StorageFunctionType::Map { + hasher: #scrate::metadata::#hasher, key: #scrate::metadata::DecodeDifferent::Encode(#kty), value: #scrate::metadata::DecodeDifferent::Encode(#styp), is_linked: #is_linked, @@ -743,11 +745,13 @@ fn store_functions_to_metadata ( } }, DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher, hasher } => { + let hasher = hasher.into_metadata(); let k1ty = clean_type_string("e!(#key1_type).to_string()); let k2ty = clean_type_string("e!(#key2_type).to_string()); let k2_hasher = clean_type_string(&key2_hasher.to_string()); quote!{ #scrate::metadata::StorageFunctionType::DoubleMap { + hasher: #scrate::metadata::#hasher, key1: #scrate::metadata::DecodeDifferent::Encode(#k1ty), key2: #scrate::metadata::DecodeDifferent::Encode(#k2ty), value: #scrate::metadata::DecodeDifferent::Encode(#styp), @@ -848,12 +852,12 @@ pub(crate) struct DeclStorageTypeInfos<'a> { enum DeclStorageTypeInfosKind<'a> { Simple, Map { - hasher: TokenStream2, + hasher: HasherKind, key_type: &'a syn::Type, is_linked: bool, }, DoubleMap { - hasher: TokenStream2, + hasher: HasherKind, key1_type: &'a syn::Type, key2_type: &'a syn::Type, key2_hasher: TokenStream2, @@ -873,17 +877,17 @@ fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { let (value_type, kind) = match storage_type { DeclStorageType::Simple(ref st) => (st, DeclStorageTypeInfosKind::Simple), DeclStorageType::Map(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.as_ref().map(|h| h.into_storage_hasher()).unwrap_or_else(|| quote! (Blake2_128)), + hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_128), key_type: &map.key, is_linked: false, }), DeclStorageType::LinkedMap(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.as_ref().map(|h| h.into_storage_hasher()).unwrap_or_else(|| quote! (Blake2_128)), + hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_128), key_type: &map.key, is_linked: true, }), DeclStorageType::DoubleMap(ref map) => (&map.value, DeclStorageTypeInfosKind::DoubleMap { - hasher: map.hasher.as_ref().map(|h| quote! ( #h )).unwrap_or_else(|| quote! ( blake2_128 )), + hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_128), key1_type: &map.key1, key2_type: &map.key2.content, key2_hasher: { let h = &map.key2_hasher; quote! { #h } }, diff --git a/srml/support/procedural/tools/src/syn_ext.rs b/srml/support/procedural/tools/src/syn_ext.rs index c2136b2cd8f96..c6b0b4aefbd70 100644 --- a/srml/support/procedural/tools/src/syn_ext.rs +++ b/srml/support/procedural/tools/src/syn_ext.rs @@ -72,7 +72,7 @@ groups_impl!(Braces, Brace, Brace, parse_braces); groups_impl!(Brackets, Bracket, Bracket, parse_brackets); groups_impl!(Parens, Paren, Parenthesis, parse_parens); -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct CustomToken(std::marker::PhantomData); impl Parse for CustomToken { diff --git a/srml/support/src/metadata.rs b/srml/support/src/metadata.rs index 7ff39fd25687d..407408b52c847 100644 --- a/srml/support/src/metadata.rs +++ b/srml/support/src/metadata.rs @@ -16,11 +16,11 @@ pub use srml_metadata::{ DecodeDifferent, FnEncode, RuntimeMetadata, - ModuleMetadata, RuntimeMetadataV3, + ModuleMetadata, RuntimeMetadataV4, DefaultByteGetter, RuntimeMetadataPrefixed, StorageMetadata, StorageFunctionMetadata, StorageFunctionType, StorageFunctionModifier, - DefaultByte, + DefaultByte, StorageHasher }; @@ -40,8 +40,8 @@ macro_rules! impl_runtime_metadata { ) => { impl $runtime { pub fn metadata() -> $crate::metadata::RuntimeMetadataPrefixed { - $crate::metadata::RuntimeMetadata::V3 ( - $crate::metadata::RuntimeMetadataV3 { + $crate::metadata::RuntimeMetadata::V4 ( + $crate::metadata::RuntimeMetadataV4 { modules: $crate::__runtime_modules_to_metadata!($runtime;; $( $rest )*), } ).into() @@ -381,8 +381,8 @@ mod tests { event_module2::Module with Event Storage Call, ); - const EXPECTED_METADATA: RuntimeMetadata = RuntimeMetadata::V3( - RuntimeMetadataV3 { + const EXPECTED_METADATA: RuntimeMetadata = RuntimeMetadata::V4( + RuntimeMetadataV4 { modules: DecodeDifferent::Encode(&[ ModuleMetadata { name: DecodeDifferent::Encode("system"), From 7a2f4e98a2800b49545352524ada7931ff29eb13 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 18:00:50 +0200 Subject: [PATCH 13/22] fix --- srml/support/src/lib.rs | 8 +++++++- srml/support/src/storage/storage_items.rs | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 1c8dc5d152bea..73d05fb9778d0 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -185,7 +185,7 @@ mod tests { pub use srml_metadata::{ DecodeDifferent, StorageMetadata, StorageFunctionMetadata, StorageFunctionType, StorageFunctionModifier, - DefaultByte, DefaultByteGetter, + DefaultByte, DefaultByteGetter, StorageHasher }; pub use rstd::marker::PhantomData; @@ -354,6 +354,7 @@ mod tests { name: DecodeDifferent::Encode("Data"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("u64"), is_linked: true }, default: DecodeDifferent::Encode( @@ -365,6 +366,7 @@ mod tests { name: DecodeDifferent::Encode("GenericData"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), is_linked: true }, default: DecodeDifferent::Encode( @@ -376,6 +378,7 @@ mod tests { name: DecodeDifferent::Encode("GenericData2"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map{ + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), is_linked: true }, default: DecodeDifferent::Encode( @@ -387,6 +390,7 @@ mod tests { name: DecodeDifferent::Encode("DataDM"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::DoubleMap{ + hasher: StorageHasher::Blake2_128, key1: DecodeDifferent::Encode("u32"), key2: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("u64"), @@ -401,6 +405,7 @@ mod tests { name: DecodeDifferent::Encode("GenericDataDM"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::DoubleMap{ + hasher: StorageHasher::Blake2_128, key1: DecodeDifferent::Encode("T::BlockNumber"), key2: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), @@ -415,6 +420,7 @@ mod tests { name: DecodeDifferent::Encode("GenericData2DM"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::DoubleMap{ + hasher: StorageHasher::Blake2_128, key1: DecodeDifferent::Encode("T::BlockNumber"), key2: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index a17422ea6c8bb..68816107a8f5d 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -386,6 +386,7 @@ mod tests { use std::cell::RefCell; use super::*; use crate::metadata::*; + use crate::metadata::StorageHasher; use crate::rstd::marker::PhantomData; use crate::storage::hashed::generator::*; @@ -628,6 +629,7 @@ mod tests { name: DecodeDifferent::Encode("MAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -641,6 +643,7 @@ mod tests { name: DecodeDifferent::Encode("PUBMAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -654,6 +657,7 @@ mod tests { name: DecodeDifferent::Encode("MAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -667,6 +671,7 @@ mod tests { name: DecodeDifferent::Encode("PUBMAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -680,6 +685,7 @@ mod tests { name: DecodeDifferent::Encode("GETMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -693,6 +699,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -706,6 +713,7 @@ mod tests { name: DecodeDifferent::Encode("GETMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -719,6 +727,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -732,6 +741,7 @@ mod tests { name: DecodeDifferent::Encode("LINKEDMAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -745,6 +755,7 @@ mod tests { name: DecodeDifferent::Encode("PUBLINKEDMAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -758,6 +769,7 @@ mod tests { name: DecodeDifferent::Encode("GETLINKEDMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -771,6 +783,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETLINKEDMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_128, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, From 5d0ee9f7e6bbd1d288f52299400e19976d736155 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 18:05:07 +0200 Subject: [PATCH 14/22] remove debug print --- node/executor/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index f2435be9c18d8..6c1ef4a4c7c08 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -170,7 +170,6 @@ mod tests { true, None, ).0; - println!("{:?}", r); assert!(r.is_ok()); let v = executor().call::<_, NeverNativeValue, fn() -> _>( &mut t, From 90640b3efa76c653bb3e5874c3bde7e45db482cf Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 18:25:21 +0200 Subject: [PATCH 15/22] map -> blake2_256 --- core/client/src/client.rs | 14 +++++----- core/client/src/light/fetcher.rs | 6 ++--- core/rpc/src/state/tests.rs | 6 ++--- core/test-runtime/src/genesismap.rs | 4 +-- core/test-runtime/src/system.rs | 24 ++++++++--------- node/executor/src/lib.rs | 26 +++++++++---------- .../procedural/src/storage/transformation.rs | 6 ++--- srml/support/src/storage/storage_items.rs | 26 +++++++++---------- 8 files changed, 56 insertions(+), 56 deletions(-) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 6b21643949024..dbf130f733246 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1534,7 +1534,7 @@ impl backend::AuxStore for Client pub(crate) mod tests { use std::collections::HashMap; use super::*; - use primitives::blake2_128; + use primitives::blake2_256; use runtime_primitives::traits::DigestItem as DigestItemT; use runtime_primitives::generic::DigestItem; use test_client::{self, TestClient, AccountKeyring}; @@ -1584,12 +1584,12 @@ pub(crate) mod tests { } // prepare test cases - let alice = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Alice.into())).to_vec(); - let bob = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Bob.into())).to_vec(); - let charlie = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Charlie.into())).to_vec(); - let dave = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); - let eve = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Eve.into())).to_vec(); - let ferdie = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Ferdie.into())).to_vec(); + let alice = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Alice.into())).to_vec(); + let bob = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Bob.into())).to_vec(); + let charlie = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Charlie.into())).to_vec(); + let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let eve = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Eve.into())).to_vec(); + let ferdie = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Ferdie.into())).to_vec(); let test_cases = vec![ (1, 4, alice.clone(), vec![(4, 0), (1, 0)]), (1, 3, alice.clone(), vec![(1, 0)]), diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index bb38777eeed39..7ddd6ee2f6d1a 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -404,7 +404,7 @@ pub mod tests { use crate::light::fetcher::{Fetcher, FetchChecker, LightDataChecker, RemoteCallRequest, RemoteHeaderRequest}; use crate::light::blockchain::tests::{DummyStorage, DummyBlockchain}; - use primitives::{blake2_128, Blake2Hasher}; + use primitives::{blake2_256, Blake2Hasher}; use primitives::storage::{StorageKey, well_known_keys}; use runtime_primitives::generic::BlockId; use state_machine::Backend; @@ -587,7 +587,7 @@ pub mod tests { // we're testing this test case here: // (1, 4, dave.clone(), vec![(4, 0), (1, 1), (1, 0)]), let (remote_client, remote_roots, _) = prepare_client_with_key_changes(); - let dave = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); let dave = StorageKey(dave); // 'fetch' changes proof from remote node: @@ -699,7 +699,7 @@ pub mod tests { let (remote_client, remote_roots, _) = prepare_client_with_key_changes(); let local_cht_root = cht::compute_root::( 4, 0, remote_roots.iter().cloned().map(|ct| Ok(Some(ct)))).unwrap(); - let dave = blake2_128(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); + let dave = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Dave.into())).to_vec(); let dave = StorageKey(dave); // 'fetch' changes proof from remote node: diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 13b57c97b7b87..dee64de13442e 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -17,7 +17,7 @@ use super::*; use self::error::{Error, ErrorKind}; -use sr_io::blake2_128; +use sr_io::blake2_256; use assert_matches::assert_matches; use consensus::BlockOrigin; use test_client::{self, runtime, AccountKeyring, TestClient, BlockBuilderExt}; @@ -88,7 +88,7 @@ fn should_send_initial_storage_changes_and_notifications() { { let api = State::new(Arc::new(test_client::new()), Subscriptions::new(remote)); - let alice_balance_key = blake2_128(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); + let alice_balance_key = blake2_256(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); api.subscribe_storage(Default::default(), subscriber, Some(vec![ StorageKey(alice_balance_key.to_vec()), @@ -147,7 +147,7 @@ fn should_query_storage() { let block2_hash = add_block(1); let genesis_hash = client.genesis_hash(); - let alice_balance_key = blake2_128(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); + let alice_balance_key = blake2_256(&test_runtime::system::balance_of_key(AccountKeyring::Alice.into())); let mut expected = vec![ StorageChangeSet { diff --git a/core/test-runtime/src/genesismap.rs b/core/test-runtime/src/genesismap.rs index 9cbf9a699ea65..be1c784a52778 100644 --- a/core/test-runtime/src/genesismap.rs +++ b/core/test-runtime/src/genesismap.rs @@ -17,7 +17,7 @@ //! Tool for creating the genesis block. use std::collections::HashMap; -use runtime_io::{blake2_128, twox_128}; +use runtime_io::{blake2_256, twox_128}; use super::AccountId; use parity_codec::{Encode, KeyedVec, Joiner}; use primitives::{ChangesTrieConfiguration, map, storage::well_known_keys}; @@ -47,7 +47,7 @@ impl GenesisConfig { let wasm_runtime = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm").to_vec(); let mut map: HashMap, Vec> = self.balances.iter() .map(|&(ref account, balance)| (account.to_keyed_vec(b"balance:"), vec![].and(&balance))) - .map(|(k, v)| (blake2_128(&k[..])[..].to_vec(), v.to_vec())) + .map(|(k, v)| (blake2_256(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ (well_known_keys::CODE.into(), wasm_runtime), (well_known_keys::HEAP_PAGES.into(), vec![].and(&(16 as u64))), diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index daa0841fbce91..51f12966dc84e 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -18,7 +18,7 @@ //! and depositing logs. use rstd::prelude::*; -use runtime_io::{storage_root, enumerated_trie_root, storage_changes_root, twox_128, blake2_128}; +use runtime_io::{storage_root, enumerated_trie_root, storage_changes_root, twox_128, blake2_256}; use runtime_support::storage::{self, StorageValue, StorageMap}; use runtime_support::storage_items; use runtime_primitives::traits::{Hash as HashT, BlakeTwo256, Digest as DigestT}; @@ -45,11 +45,11 @@ pub fn balance_of_key(who: AccountId) -> Vec { } pub fn balance_of(who: AccountId) -> u64 { - storage::hashed::get_or(&blake2_128, &balance_of_key(who), 0) + storage::hashed::get_or(&blake2_256, &balance_of_key(who), 0) } pub fn nonce_of(who: AccountId) -> u64 { - storage::hashed::get_or(&blake2_128, &who.to_keyed_vec(NONCE_OF), 0) + storage::hashed::get_or(&blake2_256, &who.to_keyed_vec(NONCE_OF), 0) } /// Get authorities at given block. @@ -152,7 +152,7 @@ pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { let tx = utx.transfer(); let nonce_key = tx.from.to_keyed_vec(NONCE_OF); - let expected_nonce: u64 = storage::hashed::get_or(&blake2_128, &nonce_key, 0); + let expected_nonce: u64 = storage::hashed::get_or(&blake2_256, &nonce_key, 0); if tx.nonce < expected_nonce { return TransactionValidity::Invalid(ApplyError::Stale as i8); } @@ -241,26 +241,26 @@ fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { // check nonce let nonce_key = tx.from.to_keyed_vec(NONCE_OF); - let expected_nonce: u64 = storage::hashed::get_or(&blake2_128, &nonce_key, 0); + let expected_nonce: u64 = storage::hashed::get_or(&blake2_256, &nonce_key, 0); if !(tx.nonce == expected_nonce) { return Err(ApplyError::Stale) } // increment nonce in storage - storage::hashed::put(&blake2_128, &nonce_key, &(expected_nonce + 1)); + storage::hashed::put(&blake2_256, &nonce_key, &(expected_nonce + 1)); // check sender balance let from_balance_key = tx.from.to_keyed_vec(BALANCE_OF); - let from_balance: u64 = storage::hashed::get_or(&blake2_128, &from_balance_key, 0); + let from_balance: u64 = storage::hashed::get_or(&blake2_256, &from_balance_key, 0); // enact transfer if !(tx.amount <= from_balance) { return Err(ApplyError::CantPay) } let to_balance_key = tx.to.to_keyed_vec(BALANCE_OF); - let to_balance: u64 = storage::hashed::get_or(&blake2_128, &to_balance_key, 0); - storage::hashed::put(&blake2_128, &from_balance_key, &(from_balance - tx.amount)); - storage::hashed::put(&blake2_128, &to_balance_key, &(to_balance + tx.amount)); + let to_balance: u64 = storage::hashed::get_or(&blake2_256, &to_balance_key, 0); + storage::hashed::put(&blake2_256, &from_balance_key, &(from_balance - tx.amount)); + storage::hashed::put(&blake2_256, &to_balance_key, &(to_balance + tx.amount)); Ok(ApplyOutcome::Success) } @@ -295,7 +295,7 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { mod tests { use super::*; - use runtime_io::{with_externalities, twox_128, blake2_128, TestExternalities}; + use runtime_io::{with_externalities, twox_128, blake2_256, TestExternalities}; use parity_codec::{Joiner, KeyedVec}; use substrate_test_client::{AuthorityKeyring, AccountKeyring}; use crate::{Header, Transfer}; @@ -313,7 +313,7 @@ mod tests { twox_128(&0u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Alice.to_raw_public().to_vec(), twox_128(&1u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Bob.to_raw_public().to_vec(), twox_128(&2u32.to_keyed_vec(well_known_keys::AUTHORITY_PREFIX)).to_vec() => AuthorityKeyring::Charlie.to_raw_public().to_vec(), - blake2_128(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + blake2_256(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ]) } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 6c1ef4a4c7c08..d1a8e0cda3583 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -34,7 +34,7 @@ mod tests { use keyring::{AuthorityKeyring, AccountKeyring}; use runtime_support::{Hashable, StorageValue, StorageMap, traits::Currency}; use state_machine::{CodeExecutor, Externalities, TestExternalities}; - use primitives::{twox_128, blake2_128, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, + use primitives::{twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded}; use node_primitives::{Hash, BlockNumber, AccountId}; use runtime_primitives::traits::{Header as HeaderT, Hash as HashT}; @@ -119,13 +119,13 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, map![ - blake2_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -152,13 +152,13 @@ mod tests { #[test] fn bad_extrinsic_with_native_equivalent_code_gives_error() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, map![ - blake2_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -185,13 +185,13 @@ mod tests { #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, map![ - blake2_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -222,13 +222,13 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, map![ - blake2_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -796,13 +796,13 @@ mod tests { fn panic_execution_gives_error() { let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm"); let mut t = TestExternalities::::new_with_code(foreign_code, map![ - blake2_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![70u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); @@ -818,13 +818,13 @@ mod tests { fn successful_execution_gives_ok() { let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm"); let mut t = TestExternalities::::new_with_code(foreign_code, map![ - blake2_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + blake2_256(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - blake2_128(&>::key_for(0)).to_vec() => vec![0u8; 32], + blake2_256(&>::key_for(0)).to_vec() => vec![0u8; 32], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16] ]); diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index bc8c6485da899..01557a1b77bee 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -877,17 +877,17 @@ fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { let (value_type, kind) = match storage_type { DeclStorageType::Simple(ref st) => (st, DeclStorageTypeInfosKind::Simple), DeclStorageType::Map(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_128), + hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_256), key_type: &map.key, is_linked: false, }), DeclStorageType::LinkedMap(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_128), + hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_256), key_type: &map.key, is_linked: true, }), DeclStorageType::DoubleMap(ref map) => (&map.value, DeclStorageTypeInfosKind::DoubleMap { - hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_128), + hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_256), key1_type: &map.key1, key2_type: &map.key2.content, key2_hasher: { let h = &map.key2_hasher; quote! { #h } }, diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 68816107a8f5d..720cac64c5361 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -235,7 +235,7 @@ macro_rules! __storage_items_internal { impl $crate::storage::hashed::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; - type Hasher = $crate::Twox128; + type Hasher = $crate::Blake2_256; /// Get the prefix key in storage. fn prefix() -> &'static [u8] { @@ -629,7 +629,7 @@ mod tests { name: DecodeDifferent::Encode("MAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -643,7 +643,7 @@ mod tests { name: DecodeDifferent::Encode("PUBMAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -657,7 +657,7 @@ mod tests { name: DecodeDifferent::Encode("MAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -671,7 +671,7 @@ mod tests { name: DecodeDifferent::Encode("PUBMAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -685,7 +685,7 @@ mod tests { name: DecodeDifferent::Encode("GETMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -699,7 +699,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -713,7 +713,7 @@ mod tests { name: DecodeDifferent::Encode("GETMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -727,7 +727,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -741,7 +741,7 @@ mod tests { name: DecodeDifferent::Encode("LINKEDMAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -755,7 +755,7 @@ mod tests { name: DecodeDifferent::Encode("PUBLINKEDMAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -769,7 +769,7 @@ mod tests { name: DecodeDifferent::Encode("GETLINKEDMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -783,7 +783,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETLINKEDMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, From 1aed8a9f130096d2d9b5b8eb04c67406bc41e73a Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 18:28:17 +0200 Subject: [PATCH 16/22] fix test --- srml/executive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index c8318e0caacc1..bf504d0918b6d 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -397,7 +397,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("bb9795ce18dac049e2eba0bee41c6d7c2d34129e532668a66f5ab8e5e89addeb").into(), + state_root: hex!("4c10fddf15e63c91ff2aa13ab3a9b7f6b19938d533829489e72ba40278a08fac").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, From 6739bc1c4ef541dfb621cf6e75f195c59e1aad8d Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 18:43:59 +0200 Subject: [PATCH 17/22] fix test --- srml/support/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 73d05fb9778d0..c1718da0eae3b 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -354,7 +354,7 @@ mod tests { name: DecodeDifferent::Encode("Data"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("u64"), is_linked: true }, default: DecodeDifferent::Encode( @@ -366,7 +366,7 @@ mod tests { name: DecodeDifferent::Encode("GenericData"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), is_linked: true }, default: DecodeDifferent::Encode( @@ -378,7 +378,7 @@ mod tests { name: DecodeDifferent::Encode("GenericData2"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map{ - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), is_linked: true }, default: DecodeDifferent::Encode( @@ -390,7 +390,7 @@ mod tests { name: DecodeDifferent::Encode("DataDM"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::DoubleMap{ - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key1: DecodeDifferent::Encode("u32"), key2: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("u64"), @@ -405,7 +405,7 @@ mod tests { name: DecodeDifferent::Encode("GenericDataDM"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::DoubleMap{ - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key1: DecodeDifferent::Encode("T::BlockNumber"), key2: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), @@ -420,7 +420,7 @@ mod tests { name: DecodeDifferent::Encode("GenericData2DM"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::DoubleMap{ - hasher: StorageHasher::Blake2_128, + hasher: StorageHasher::Blake2_256, key1: DecodeDifferent::Encode("T::BlockNumber"), key2: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), From ef518377c9bcfef9ff7933fdba3075fe26b85550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 23 Apr 2019 19:38:43 +0200 Subject: [PATCH 18/22] Apply suggestions from code review Co-Authored-By: thiolliere --- srml/support/src/storage/hashed/generator.rs | 2 +- srml/support/src/storage/hashed/mod.rs | 1 - srml/support/src/storage/unhashed/generator.rs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index c50032408b2ef..e659139a4b0bd 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -109,7 +109,7 @@ pub trait HashedStorage { // We use a construct like this during when genesis storage is being built. #[cfg(feature = "std")] -impl HashedStorage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { +impl HashedStorage for std::cell::RefCell<&mut sr_primitives::StorageOverlay> { fn exists(&self, key: &[u8]) -> bool { UnhashedStorage::exists(self, &H::hash(key).as_ref()) } diff --git a/srml/support/src/storage/hashed/mod.rs b/srml/support/src/storage/hashed/mod.rs index 8ab6ca64ca9a7..5c65cf0513b26 100644 --- a/srml/support/src/storage/hashed/mod.rs +++ b/srml/support/src/storage/hashed/mod.rs @@ -203,7 +203,6 @@ mod tests { let x = b"Hello world".to_vec(); let y = get::, _, _>(&twox_128, b":test").unwrap(); assert_eq!(x, y); - }); } diff --git a/srml/support/src/storage/unhashed/generator.rs b/srml/support/src/storage/unhashed/generator.rs index b2a920714487b..f485057157176 100644 --- a/srml/support/src/storage/unhashed/generator.rs +++ b/srml/support/src/storage/unhashed/generator.rs @@ -58,7 +58,7 @@ pub trait UnhashedStorage { // We use a construct like this during when genesis storage is being built. #[cfg(feature = "std")] -impl UnhashedStorage for crate::rstd::cell::RefCell<&mut sr_primitives::StorageOverlay> { +impl UnhashedStorage for std::cell::RefCell<&mut sr_primitives::StorageOverlay> { fn exists(&self, key: &[u8]) -> bool { self.borrow().contains_key(key) } From 2e465dba84ca619c7d76692f337e3c492ced78ca Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 19:57:57 +0200 Subject: [PATCH 19/22] impl twox 128 concat (#2353) * impl twox_128_concat * comment addressed --- core/primitives/Cargo.toml | 1 + core/primitives/benches/benches.rs | 8 ++++++-- srml/metadata/src/lib.rs | 1 + srml/support/procedural/src/storage/mod.rs | 18 +++++++++++++----- .../procedural/src/storage/transformation.rs | 6 +++--- srml/support/src/hashable.rs | 7 +++++++ srml/support/src/lib.rs | 14 +++++++------- srml/support/src/storage/hashed/generator.rs | 18 ++++++++++++++++++ 8 files changed, 56 insertions(+), 17 deletions(-) diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index efe189f525e13..6a03aa3d394e6 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -35,6 +35,7 @@ substrate-serializer = { path = "../serializer" } pretty_assertions = "0.5" heapsize = "0.4" hex-literal = "0.1" +rand = "0.6" [features] default = ["std"] diff --git a/core/primitives/benches/benches.rs b/core/primitives/benches/benches.rs index 1e9eb40042d69..b81ef9dc4252d 100644 --- a/core/primitives/benches/benches.rs +++ b/core/primitives/benches/benches.rs @@ -12,18 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. +// TODO: Move benchmark to criterion #2354 #![feature(test)] extern crate test; use hex_literal::{hex, hex_impl}; use substrate_primitives::hashing::{twox_128, blake2_128}; -const RANDOM: [u8; 968] = hex!("a494a9df75845413c3b2732f1e54c5ace3474a77ed311d08cdb491b60408901d0ca7485d72a64d47bae1c4c3a91403650283c7432347f5c068cc1b07d843c2275bf8d8d11f9ca7a6d32c99e5b0b21d057a8ceaecc075afc2a34a82d3a36f8efb99a8e8c244db1e7e0d7f5d72bca68f209f04eef2aad9f04f772effc532f9e84fc8c663880cef8021f7926a0900e6d636ac5f57de8007ccb8d2fa348a27c7211f07fae5ef275c1ab54eacafde539079b2d106f254ab242a7e530460e7ed99d9771746ce2f5a08f68833a9109b0f57764964d66fee6616a5fef8a9de13701c470d1f3511c3960c7d92bc3e0e2a56833f0ec0354f7d0360960c87bdf0adfea9bf167917b221de806bf9279870f2adc2f9117ffd584a3e065905ed9d7e327e5fa3ca8a1f7e9947026b0db868ab7138a355daf67b742c0aa1eea22e94c865608babe2677880179e6bd990713d1e7a2421fe38e66983918d4a1028530fa24cbb372b9f207a7611f5cf0e0f73c859d85751d7324bb73fa23d8899531a9cb05eb367a65773622947b6fe228c78a34b612748e9717bcb3bc1c0354ca89dfd15a544f8076ad9f48ca36f259b0fbbc891f34095de03baaa93f7d84685a15383b658d62c854808031218c15dd9a2b8f7db070912c9f7b1e8b20bb282a84d338b04cf94c8283e04ddf156c5795acbe829e3944184a77e711d62bf8f1d5a0ed1b5adf85fbd91dee6f7f977271c0949d018858e94c7dd5380a8337fa3936e4a4286c6b7c7c4103d590e369f12bec1621f94a2c80726247b6911bd9b8c65d5039b2e96098e5b52b4d7ab636f39115292314e0afb38ce17a69e93838a69ce23d684065f25fda0e601f3ee56431effed7b118a80dea0bccdecd8775e9ff96bcd31a7a805317c3650ea4c4a1df6adbe184e762a24bc9359eac4e81b2253b9a3dd5086974506ad6655b0be3b903837c2c73844239f19b9ba6fe1ac1b9f9c78c1cca223a5affd21a2442bef064c14c2b8ff88cd65e8bc7432b61516f3250803636e31028a62f540966aa1471eee46cc95d3590f272d7eb2ab8273ad0f4442cf197e759498445bb60bf87f394142ede5796f0f9353a8ddb34e9b6edd4c82149b65b6d3480ad3af534cd2e5646a12de6a1500a20613f2cf23a81ace0abd3d25a767522cb79e301342f564aaebd567723e5df0cfd4973fcb6b8ed66fe543abf969c22685ffc504068c347dc28c2f1bf62710cc9ed11386906b69bded1e6a8232d4f9980db3e1eca8268ba420cd5b9fb69bdb090562af0167bac782e954909a5a84f53cb067aaadbf5635ebc1b7d9304aee0407c2d14f1ea95d132483a335435b090cf0e1a7d3e2ba3adc40d21042119ed005df10"); const MAX_KEY_SIZE: u32 = 32; fn data_set() -> Vec> { - let mut rnd = RANDOM.iter().cycle(); + use rand::SeedableRng; + use rand::Rng; + + let rnd: [u8; 32] = rand::rngs::StdRng::seed_from_u64(12).gen(); + let mut rnd = rnd.iter().cycle(); let mut res = Vec::new(); for size in 1..=MAX_KEY_SIZE { for _ in 0..1_000 { diff --git a/srml/metadata/src/lib.rs b/srml/metadata/src/lib.rs index 8a502f637f723..cf24d7fbc0f42 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -261,6 +261,7 @@ pub enum StorageHasher { Blake2_256, Twox128, Twox256, + Twox128Concat, } /// A storage function type. diff --git a/srml/support/procedural/src/storage/mod.rs b/srml/support/procedural/src/storage/mod.rs index 4b8ea331b0896..c4974746d7e34 100644 --- a/srml/support/procedural/src/storage/mod.rs +++ b/srml/support/procedural/src/storage/mod.rs @@ -173,6 +173,7 @@ enum Hasher { Blake2_128(ext::CustomToken), Twox256(ext::CustomToken), Twox128(ext::CustomToken), + Twox128Concat(ext::CustomToken), } #[derive(Parse, ToTokens, Debug)] @@ -193,24 +194,28 @@ enum HasherKind { Blake2_128, Twox256, Twox128, + Twox128Concat, } -impl HasherKind { - fn from_set_hasher(set_hasher: &SetHasher) -> Self { +impl From<&SetHasher> for HasherKind { + fn from(set_hasher: &SetHasher) -> Self { match set_hasher.inner.content { Hasher::Blake2_256(_) => HasherKind::Blake2_256, Hasher::Blake2_128(_) => HasherKind::Blake2_128, Hasher::Twox256(_) => HasherKind::Twox256, Hasher::Twox128(_) => HasherKind::Twox128, + Hasher::Twox128Concat(_) => HasherKind::Twox128Concat, } } - +} +impl HasherKind { fn into_storage_hasher_struct(&self) -> TokenStream2 { match self { HasherKind::Blake2_256 => quote!( Blake2_256 ), HasherKind::Blake2_128 => quote!( Blake2_128 ), HasherKind::Twox256 => quote!( Twox256 ), HasherKind::Twox128 => quote!( Twox128 ), + HasherKind::Twox128Concat => quote!( Twox128Concat ), } } @@ -220,6 +225,7 @@ impl HasherKind { HasherKind::Blake2_128 => quote!( blake2_128 ), HasherKind::Twox256 => quote!( twox_256 ), HasherKind::Twox128 => quote!( twox_128 ), + HasherKind::Twox128Concat => quote!( twox_128_concat), } } @@ -229,6 +235,7 @@ impl HasherKind { HasherKind::Blake2_128 => quote!( StorageHasher::Blake2_128 ), HasherKind::Twox256 => quote!( StorageHasher::Twox256 ), HasherKind::Twox128 => quote!( StorageHasher::Twox128 ), + HasherKind::Twox128Concat => quote!( StorageHasher::Twox128Concat ), } } } @@ -245,7 +252,8 @@ custom_keyword!(LinkedMapKeyword, "linked_map", "linked_map as keyword"); custom_keyword!(DoubleMapKeyword, "double_map", "double_map as keyword"); custom_keyword!(Blake2_256Keyword, "blake2_256", "Blake2_256 as keyword"); custom_keyword!(Blake2_128Keyword, "blake2_128", "Blake2_128 as keyword"); -custom_keyword!(Twox256Keyword, "twox_256", "Twox_256 as keyword"); -custom_keyword!(Twox128Keyword, "twox_128", "Twox_128 as keyword"); +custom_keyword!(Twox256Keyword, "twox_256", "Twox256 as keyword"); +custom_keyword!(Twox128Keyword, "twox_128", "Twox128 as keyword"); +custom_keyword!(Twox128ConcatKeyword, "twox_128_concat", "Twox128Concat as keyword"); custom_keyword_impl!(ExtraGenesisSkipPhantomDataField, "extra_genesis_skip_phantom_data_field", "extra_genesis_skip_phantom_data_field as keyword"); custom_keyword_impl!(SetHasher, "hasher", "storage hasher"); diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 01557a1b77bee..205fccdea574d 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -877,17 +877,17 @@ fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { let (value_type, kind) = match storage_type { DeclStorageType::Simple(ref st) => (st, DeclStorageTypeInfosKind::Simple), DeclStorageType::Map(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_256), + hasher: map.hasher.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), key_type: &map.key, is_linked: false, }), DeclStorageType::LinkedMap(ref map) => (&map.value, DeclStorageTypeInfosKind::Map { - hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_256), + hasher: map.hasher.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), key_type: &map.key, is_linked: true, }), DeclStorageType::DoubleMap(ref map) => (&map.value, DeclStorageTypeInfosKind::DoubleMap { - hasher: map.hasher.as_ref().map(|h| HasherKind::from_set_hasher(h)).unwrap_or(HasherKind::Blake2_256), + hasher: map.hasher.as_ref().map(|h| h.into()).unwrap_or(HasherKind::Blake2_256), key1_type: &map.key1, key2_type: &map.key2.content, key2_hasher: { let h = &map.key2_hasher; quote! { #h } }, diff --git a/srml/support/src/hashable.rs b/srml/support/src/hashable.rs index 52b1fba234a8a..b6ee79f9473ed 100644 --- a/srml/support/src/hashable.rs +++ b/srml/support/src/hashable.rs @@ -18,12 +18,16 @@ use crate::codec::Codec; use runtime_io::{blake2_128, blake2_256, twox_128, twox_256}; +use crate::storage::hashed::generator::StorageHasher; +use crate::Twox128Concat; +use crate::rstd::prelude::Vec; pub trait Hashable: Sized { fn blake2_128(&self) -> [u8; 16]; fn blake2_256(&self) -> [u8; 32]; fn twox_128(&self) -> [u8; 16]; fn twox_256(&self) -> [u8; 32]; + fn twox_128_concat(&self) -> Vec; } impl Hashable for T { @@ -39,4 +43,7 @@ impl Hashable for T { fn twox_256(&self) -> [u8; 32] { self.using_encoded(twox_256) } + fn twox_128_concat(&self) -> Vec { + self.using_encoded(Twox128Concat::hash) + } } diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index c1718da0eae3b..5c5b142a54e0d 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -35,7 +35,7 @@ pub use once_cell; pub use paste; pub use sr_primitives as runtime_primitives; -pub use self::storage::hashed::generator::{HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128}; +pub use self::storage::hashed::generator::{HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128, Twox128Concat}; pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] @@ -209,11 +209,11 @@ mod tests { decl_storage! { trait Store for Module as Example { - pub Data get(data) build(|_| vec![(15u32, 42u64)]): linked_map u32 => u64; - pub GenericData get(generic_data): linked_map T::BlockNumber => T::BlockNumber; + pub Data get(data) build(|_| vec![(15u32, 42u64)]): linked_map hasher(twox_128_concat) u32 => u64; + pub GenericData get(generic_data): linked_map hasher(twox_128) T::BlockNumber => T::BlockNumber; pub GenericData2 get(generic_data2): linked_map T::BlockNumber => Option; - pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): double_map u32, blake2_256(u32) => u64; + pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): double_map hasher(twox_128_concat) u32, blake2_256(u32) => u64; pub GenericDataDM: double_map T::BlockNumber, twox_128(T::BlockNumber) => T::BlockNumber; pub GenericData2DM: double_map T::BlockNumber, twox_256(T::BlockNumber) => Option; } @@ -354,7 +354,7 @@ mod tests { name: DecodeDifferent::Encode("Data"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ - hasher: StorageHasher::Blake2_256, + hasher: StorageHasher::Twox128Concat, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("u64"), is_linked: true }, default: DecodeDifferent::Encode( @@ -366,7 +366,7 @@ mod tests { name: DecodeDifferent::Encode("GenericData"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ - hasher: StorageHasher::Blake2_256, + hasher: StorageHasher::Twox128, key: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), is_linked: true }, default: DecodeDifferent::Encode( @@ -390,7 +390,7 @@ mod tests { name: DecodeDifferent::Encode("DataDM"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::DoubleMap{ - hasher: StorageHasher::Blake2_256, + hasher: StorageHasher::Twox128Concat, key1: DecodeDifferent::Encode("u32"), key2: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("u64"), diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index e659139a4b0bd..b36994d6380eb 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -27,6 +27,24 @@ pub trait StorageHasher: 'static { fn hash(x: &[u8]) -> Self::Output; } +/// Hash storage keys with `concat(twox128(key), key)` +pub struct Twox128Concat; +impl StorageHasher for Twox128Concat { + type Output = Vec; + fn hash(x: &[u8]) -> Vec { + twox_128(x) + .into_iter() + .chain(x.iter().cloned()) + .collect::>() + } +} + +#[test] +fn test_twox_128_concat() { + let r = Twox128Concat::hash(b"foo"); + assert_eq!(r.split_at(16), (&twox_128(b"foo")[..], &b"foo"[..])) +} + /// Hash storage keys with blake2 128 pub struct Blake2_128; impl StorageHasher for Blake2_128 { From 14040b299c56f4e006ba61f3dd08a0470c065827 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 20:00:16 +0200 Subject: [PATCH 20/22] fix --- srml/support/src/storage/hashed/generator.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index b36994d6380eb..7e45f37e90f8b 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -34,7 +34,8 @@ impl StorageHasher for Twox128Concat { fn hash(x: &[u8]) -> Vec { twox_128(x) .into_iter() - .chain(x.iter().cloned()) + .chain(x.into_iter()) + .cloned() .collect::>() } } From 7c5befdffd41212275b62a21410d0ada63bb4518 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 20:28:13 +0200 Subject: [PATCH 21/22] impl twox_128->64_concat --- core/executor/src/wasm_executor.rs | 26 +++++++++++++++++++- core/primitives/src/hashing.rs | 17 +++++++++++++ core/primitives/src/lib.rs | 2 +- core/sr-io/with_std.rs | 2 +- core/sr-io/without_std.rs | 10 ++++++++ srml/metadata/src/lib.rs | 2 +- srml/support/procedural/src/storage/mod.rs | 14 +++++------ srml/support/src/hashable.rs | 9 ++++--- srml/support/src/lib.rs | 10 ++++---- srml/support/src/storage/hashed/generator.rs | 14 +++++------ 10 files changed, 79 insertions(+), 27 deletions(-) diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index fce4b34711301..d3fab07fc16a1 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -28,7 +28,7 @@ use wasmi::memory_units::{Pages}; use state_machine::Externalities; use crate::error::{Error, ErrorKind, Result}; use crate::wasm_utils::UserError; -use primitives::{blake2_128, blake2_256, twox_128, twox_256, ed25519, sr25519, Pair}; +use primitives::{blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Pair}; use primitives::hexdisplay::HexDisplay; use primitives::sandbox as sandbox_primitives; use primitives::{H256, Blake2Hasher}; @@ -418,6 +418,30 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, ext_chain_id() -> u64 => { Ok(this.ext.chain_id()) }, + ext_twox_64(data: *const u8, len: u32, out: *mut u8) => { + let result: [u8; 8] = if len == 0 { + let hashed = twox_64(&[0u8; 0]); + debug_trace!(target: "xxhash", "XXhash: '' -> {}", HexDisplay::from(&hashed)); + this.hash_lookup.insert(hashed.to_vec(), vec![]); + hashed + } else { + let key = this.memory.get(data, len as usize).map_err(|_| UserError("Invalid attempt to get key in ext_twox_64"))?; + let hashed_key = twox_64(&key); + debug_trace!(target: "xxhash", "XXhash: {} -> {}", + if let Ok(_skey) = ::std::str::from_utf8(&key) { + _skey + } else { + &format!("{}", HexDisplay::from(&key)) + }, + HexDisplay::from(&hashed_key) + ); + this.hash_lookup.insert(hashed_key.to_vec(), key); + hashed_key + }; + + this.memory.set(out, &result).map_err(|_| UserError("Invalid attempt to set result in ext_twox_64"))?; + Ok(()) + }, ext_twox_128(data: *const u8, len: u32, out: *mut u8) => { let result: [u8; 16] = if len == 0 { let hashed = twox_128(&[0u8; 0]); diff --git a/core/primitives/src/hashing.rs b/core/primitives/src/hashing.rs index 814048fea848d..87312ce6e46e9 100644 --- a/core/primitives/src/hashing.rs +++ b/core/primitives/src/hashing.rs @@ -55,6 +55,23 @@ pub fn blake2_128(data: &[u8]) -> [u8; 16] { r } +/// Do a XX 64-bit hash and place result in `dest`. +pub fn twox_64_into(data: &[u8], dest: &mut [u8; 8]) { + use ::core::hash::Hasher; + let mut h0 = twox_hash::XxHash::with_seed(0); + h0.write(data); + let r0 = h0.finish(); + use byteorder::{ByteOrder, LittleEndian}; + LittleEndian::write_u64(&mut dest[0..8], r0); +} + +/// Do a XX 64-bit hash and return result. +pub fn twox_64(data: &[u8]) -> [u8; 8] { + let mut r: [u8; 8] = [0; 8]; + twox_64_into(data, &mut r); + r +} + /// Do a XX 128-bit hash and place result in `dest`. pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) { use ::core::hash::Hasher; diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index c8a1de0a80417..f800f096db6c3 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -46,7 +46,7 @@ pub use impl_serde::serialize as bytes; #[cfg(feature = "std")] pub mod hashing; #[cfg(feature = "std")] -pub use hashing::{blake2_128, blake2_256, twox_128, twox_256}; +pub use hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256}; #[cfg(feature = "std")] pub mod hexdisplay; pub mod crypto; diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index 186db06de3a80..d694b1457d2c1 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -18,7 +18,7 @@ pub use parity_codec as codec; // re-export hashing functions. pub use primitives::{ - blake2_128, blake2_256, twox_128, twox_256, ed25519, Blake2Hasher, + blake2_128, blake2_256, twox_128, twox_256, twox_64, ed25519, Blake2Hasher, sr25519, Pair }; pub use tiny_keccak::keccak256 as keccak_256; diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 024b26511967a..456ae3cef7ee3 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -275,6 +275,7 @@ extern_functions! { fn ext_blake2_256_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8); fn ext_blake2_128(data: *const u8, len: u32, out: *mut u8); fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); + fn ext_twox_64(data: *const u8, len: u32, out: *mut u8); fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); fn ext_twox_256(data: *const u8, len: u32, out: *mut u8); fn ext_keccak_256(data: *const u8, len: u32, out: *mut u8); @@ -581,6 +582,15 @@ pub fn twox_128(data: &[u8]) -> [u8; 16] { result } +/// Conduct two XX hashes to give a 64-bit result. +pub fn twox_64(data: &[u8]) -> [u8; 8] { + let mut result: [u8; 8] = Default::default(); + unsafe { + ext_twox_64.get()(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); + } + result +} + /// Verify a ed25519 signature. pub fn ed25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool { unsafe { diff --git a/srml/metadata/src/lib.rs b/srml/metadata/src/lib.rs index cf24d7fbc0f42..8749b37cac039 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -261,7 +261,7 @@ pub enum StorageHasher { Blake2_256, Twox128, Twox256, - Twox128Concat, + Twox64Concat, } /// A storage function type. diff --git a/srml/support/procedural/src/storage/mod.rs b/srml/support/procedural/src/storage/mod.rs index c4974746d7e34..649a48a1813ed 100644 --- a/srml/support/procedural/src/storage/mod.rs +++ b/srml/support/procedural/src/storage/mod.rs @@ -173,7 +173,7 @@ enum Hasher { Blake2_128(ext::CustomToken), Twox256(ext::CustomToken), Twox128(ext::CustomToken), - Twox128Concat(ext::CustomToken), + Twox64Concat(ext::CustomToken), } #[derive(Parse, ToTokens, Debug)] @@ -194,7 +194,7 @@ enum HasherKind { Blake2_128, Twox256, Twox128, - Twox128Concat, + Twox64Concat, } impl From<&SetHasher> for HasherKind { @@ -204,7 +204,7 @@ impl From<&SetHasher> for HasherKind { Hasher::Blake2_128(_) => HasherKind::Blake2_128, Hasher::Twox256(_) => HasherKind::Twox256, Hasher::Twox128(_) => HasherKind::Twox128, - Hasher::Twox128Concat(_) => HasherKind::Twox128Concat, + Hasher::Twox64Concat(_) => HasherKind::Twox64Concat, } } } @@ -215,7 +215,7 @@ impl HasherKind { HasherKind::Blake2_128 => quote!( Blake2_128 ), HasherKind::Twox256 => quote!( Twox256 ), HasherKind::Twox128 => quote!( Twox128 ), - HasherKind::Twox128Concat => quote!( Twox128Concat ), + HasherKind::Twox64Concat => quote!( Twox64Concat ), } } @@ -225,7 +225,7 @@ impl HasherKind { HasherKind::Blake2_128 => quote!( blake2_128 ), HasherKind::Twox256 => quote!( twox_256 ), HasherKind::Twox128 => quote!( twox_128 ), - HasherKind::Twox128Concat => quote!( twox_128_concat), + HasherKind::Twox64Concat => quote!( twox_64_concat), } } @@ -235,7 +235,7 @@ impl HasherKind { HasherKind::Blake2_128 => quote!( StorageHasher::Blake2_128 ), HasherKind::Twox256 => quote!( StorageHasher::Twox256 ), HasherKind::Twox128 => quote!( StorageHasher::Twox128 ), - HasherKind::Twox128Concat => quote!( StorageHasher::Twox128Concat ), + HasherKind::Twox64Concat => quote!( StorageHasher::Twox64Concat ), } } } @@ -254,6 +254,6 @@ custom_keyword!(Blake2_256Keyword, "blake2_256", "Blake2_256 as keyword"); custom_keyword!(Blake2_128Keyword, "blake2_128", "Blake2_128 as keyword"); custom_keyword!(Twox256Keyword, "twox_256", "Twox256 as keyword"); custom_keyword!(Twox128Keyword, "twox_128", "Twox128 as keyword"); -custom_keyword!(Twox128ConcatKeyword, "twox_128_concat", "Twox128Concat as keyword"); +custom_keyword!(Twox64ConcatKeyword, "twox_64_concat", "Twox64Concat as keyword"); custom_keyword_impl!(ExtraGenesisSkipPhantomDataField, "extra_genesis_skip_phantom_data_field", "extra_genesis_skip_phantom_data_field as keyword"); custom_keyword_impl!(SetHasher, "hasher", "storage hasher"); diff --git a/srml/support/src/hashable.rs b/srml/support/src/hashable.rs index b6ee79f9473ed..b3ee2b3612c1e 100644 --- a/srml/support/src/hashable.rs +++ b/srml/support/src/hashable.rs @@ -19,15 +19,16 @@ use crate::codec::Codec; use runtime_io::{blake2_128, blake2_256, twox_128, twox_256}; use crate::storage::hashed::generator::StorageHasher; -use crate::Twox128Concat; +use crate::Twox64Concat; use crate::rstd::prelude::Vec; +// This trait must be kept coherent with srml-support-procedural HasherKind usage pub trait Hashable: Sized { fn blake2_128(&self) -> [u8; 16]; fn blake2_256(&self) -> [u8; 32]; fn twox_128(&self) -> [u8; 16]; fn twox_256(&self) -> [u8; 32]; - fn twox_128_concat(&self) -> Vec; + fn twox_64_concat(&self) -> Vec; } impl Hashable for T { @@ -43,7 +44,7 @@ impl Hashable for T { fn twox_256(&self) -> [u8; 32] { self.using_encoded(twox_256) } - fn twox_128_concat(&self) -> Vec { - self.using_encoded(Twox128Concat::hash) + fn twox_64_concat(&self) -> Vec { + self.using_encoded(Twox64Concat::hash) } } diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 5c5b142a54e0d..4e9325c867fc9 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -35,7 +35,7 @@ pub use once_cell; pub use paste; pub use sr_primitives as runtime_primitives; -pub use self::storage::hashed::generator::{HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128, Twox128Concat}; +pub use self::storage::hashed::generator::{HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat}; pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] @@ -209,11 +209,11 @@ mod tests { decl_storage! { trait Store for Module as Example { - pub Data get(data) build(|_| vec![(15u32, 42u64)]): linked_map hasher(twox_128_concat) u32 => u64; + pub Data get(data) build(|_| vec![(15u32, 42u64)]): linked_map hasher(twox_64_concat) u32 => u64; pub GenericData get(generic_data): linked_map hasher(twox_128) T::BlockNumber => T::BlockNumber; pub GenericData2 get(generic_data2): linked_map T::BlockNumber => Option; - pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): double_map hasher(twox_128_concat) u32, blake2_256(u32) => u64; + pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): double_map hasher(twox_64_concat) u32, blake2_256(u32) => u64; pub GenericDataDM: double_map T::BlockNumber, twox_128(T::BlockNumber) => T::BlockNumber; pub GenericData2DM: double_map T::BlockNumber, twox_256(T::BlockNumber) => Option; } @@ -354,7 +354,7 @@ mod tests { name: DecodeDifferent::Encode("Data"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ - hasher: StorageHasher::Twox128Concat, + hasher: StorageHasher::Twox64Concat, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("u64"), is_linked: true }, default: DecodeDifferent::Encode( @@ -390,7 +390,7 @@ mod tests { name: DecodeDifferent::Encode("DataDM"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::DoubleMap{ - hasher: StorageHasher::Twox128Concat, + hasher: StorageHasher::Twox64Concat, key1: DecodeDifferent::Encode("u32"), key2: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("u64"), diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index 7e45f37e90f8b..c1b8308aa26fc 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -20,7 +20,7 @@ use crate::codec; use crate::rstd::prelude::{Vec, Box}; #[cfg(feature = "std")] use crate::storage::unhashed::generator::UnhashedStorage; -use runtime_io::{twox_128, blake2_128, twox_256, blake2_256}; +use runtime_io::{twox_64, twox_128, blake2_128, twox_256, blake2_256}; pub trait StorageHasher: 'static { type Output: AsRef<[u8]>; @@ -28,11 +28,11 @@ pub trait StorageHasher: 'static { } /// Hash storage keys with `concat(twox128(key), key)` -pub struct Twox128Concat; -impl StorageHasher for Twox128Concat { +pub struct Twox64Concat; +impl StorageHasher for Twox64Concat { type Output = Vec; fn hash(x: &[u8]) -> Vec { - twox_128(x) + twox_64(x) .into_iter() .chain(x.into_iter()) .cloned() @@ -41,9 +41,9 @@ impl StorageHasher for Twox128Concat { } #[test] -fn test_twox_128_concat() { - let r = Twox128Concat::hash(b"foo"); - assert_eq!(r.split_at(16), (&twox_128(b"foo")[..], &b"foo"[..])) +fn test_twox_64_concat() { + let r = Twox64Concat::hash(b"foo"); + assert_eq!(r.split_at(16), (&twox_128(b"foo")[..8], &b"foo"[..])) } /// Hash storage keys with blake2 128 From 1a8a211713d0294f4e505a7765864533231b06bf Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 20:31:09 +0200 Subject: [PATCH 22/22] fix test --- srml/support/src/storage/hashed/generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index c1b8308aa26fc..06ec85995d25e 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -43,7 +43,7 @@ impl StorageHasher for Twox64Concat { #[test] fn test_twox_64_concat() { let r = Twox64Concat::hash(b"foo"); - assert_eq!(r.split_at(16), (&twox_128(b"foo")[..8], &b"foo"[..])) + assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..])) } /// Hash storage keys with blake2 128