From 1644e9cea9670c79477b790a15cb89418013876d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 8 Apr 2019 07:26:34 +0200 Subject: [PATCH 01/14] Add failing test case --- srml/support/test/Cargo.toml | 2 +- srml/support/test/tests/instance.rs | 83 +------------ srml/support/test/tests/issue2219.rs | 173 +++++++++++++++++++++++++++ srml/support/test/tests/system.rs | 74 ++++++++++++ 4 files changed, 251 insertions(+), 81 deletions(-) create mode 100644 srml/support/test/tests/issue2219.rs create mode 100644 srml/support/test/tests/system.rs diff --git a/srml/support/test/Cargo.toml b/srml/support/test/Cargo.toml index 46a6d320681d4..1d8af73c8ed55 100644 --- a/srml/support/test/Cargo.toml +++ b/srml/support/test/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dev-dependencies] serde = { version = "1.0", default-features = false } serde_derive = { version = "1.0" } -parity-codec = { version = "3.3", default-features = false, features = ["derive"] } +parity-codec = { version = "3.4", default-features = false, features = ["derive"] } runtime_io = { package = "sr-io", path = "../../../core/sr-io", default-features = false } srml-support = { path = "../", default-features = false } inherents = { package = "substrate-inherents", path = "../../../core/inherents", default-features = false } diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index d5171f6ac7922..bf64dea6dacfa 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -16,14 +16,11 @@ #![recursion_limit="128"] -#[cfg(feature = "std")] -use serde_derive::Serialize; use runtime_io::{with_externalities, Blake2Hasher}; use srml_support::rstd::prelude::*; use srml_support::rstd as rstd; -use srml_support::codec::{Encode, Decode}; use srml_support::runtime_primitives::{generic, BuildStorage}; -use srml_support::runtime_primitives::traits::{BlakeTwo256, Block as _, Verify, Digest}; +use srml_support::runtime_primitives::traits::{BlakeTwo256, Block as _, Verify}; use srml_support::Parameter; use inherents::{ ProvideInherent, InherentData, InherentIdentifier, RuntimeString, MakeFatalError @@ -31,83 +28,9 @@ use inherents::{ use srml_support::{StorageValue, StorageMap, StorageDoubleMap}; use primitives::{H256, sr25519}; -pub trait Currency { -} - -// Mock -mod system { - use super::*; - - pub trait Trait: 'static + Eq + Clone { - type Origin: Into>> + From>; - type BlockNumber; - type Digest: Digest; - type Hash; - type AccountId; - type Event: From; - type Log: From> + Into>; - } +mod system; - pub type DigestItemOf = <::Digest as Digest>::Item; - - srml_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin { - pub fn deposit_event(_event: T::Event) { - } - } - } - impl Module { - pub fn deposit_log(_item: ::Item) { - unimplemented!(); - } - } - - srml_support::decl_event!( - pub enum Event { - ExtrinsicSuccess, - ExtrinsicFailed, - } - ); - - /// Origin for the system module. - #[derive(PartialEq, Eq, Clone)] - #[cfg_attr(feature = "std", derive(Debug))] - pub enum RawOrigin { - Root, - Signed(AccountId), - Inherent, - } - - impl From> for RawOrigin { - fn from(s: Option) -> RawOrigin { - match s { - Some(who) => RawOrigin::Signed(who), - None => RawOrigin::Inherent, - } - } - } - - pub type Origin = RawOrigin<::AccountId>; - - pub type Log = RawLog< - ::Hash, - >; - - #[cfg_attr(feature = "std", derive(Serialize, Debug))] - #[derive(Encode, Decode, PartialEq, Eq, Clone)] - pub enum RawLog { - ChangesTrieRoot(H), - } - - pub fn ensure_root(o: OuterOrigin) -> Result<(), &'static str> - where OuterOrigin: Into>> - { - match o.into() { - Some(RawOrigin::Root) => Ok(()), - _ => Err("bad origin: expected to be a root origin"), - } - } -} +pub trait Currency {} // Test for: // * No default instance diff --git a/srml/support/test/tests/issue2219.rs b/srml/support/test/tests/issue2219.rs new file mode 100644 index 0000000000000..dd96a9aa874d5 --- /dev/null +++ b/srml/support/test/tests/issue2219.rs @@ -0,0 +1,173 @@ +use srml_support::runtime_primitives::generic; +use srml_support::runtime_primitives::traits::{BlakeTwo256, Block as _, Verify}; +use srml_support::codec::{Encode, Decode}; +use primitives::{H256, sr25519}; +use serde_derive::{Serialize, Deserialize}; + +mod system; + +mod module { + use super::*; + + pub type Request = ( + ::AccountId, + Role, + ::BlockNumber, + ); + pub type Requests = Vec>; + + #[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Debug)] + pub enum Role { + Storage, + } + + #[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Debug)] + pub struct RoleParameters { + // minimum actors to maintain - if role is unstaking + // and remaining actors would be less that this value - prevent or punish for unstaking + pub min_actors: u32, + + // the maximum number of spots available to fill for a role + pub max_actors: u32, + + // payouts are made at this block interval + pub reward_period: T::BlockNumber, + + // minimum amount of time before being able to unstake + pub bonding_period: T::BlockNumber, + + // how long tokens remain locked for after unstaking + pub unbonding_period: T::BlockNumber, + + // minimum period required to be in service. unbonding before this time is highly penalized + pub min_service_period: T::BlockNumber, + + // "startup" time allowed for roles that need to sync their infrastructure + // with other providers before they are considered in service and punishable for + // not delivering required level of service. + pub startup_grace_period: T::BlockNumber, + } + + impl Default for RoleParameters { + fn default() -> Self { + Self { + max_actors: 10, + reward_period: T::BlockNumber::default(), + unbonding_period: T::BlockNumber::default(), + + // not currently used + min_actors: 5, + bonding_period: T::BlockNumber::default(), + min_service_period: T::BlockNumber::default(), + startup_grace_period: T::BlockNumber::default(), + } + } + } + + pub trait Trait: system::Trait {} + + srml_support::decl_module! { + pub struct Module for enum Call where origin: T::Origin {} + } + + #[derive(Encode, Decode, Copy, Clone, Serialize, Deserialize)] + pub struct Data { + pub data: T::BlockNumber, + } + + impl Default for Data { + fn default() -> Self { + Self { + data: T::BlockNumber::default(), + } + } + } + + srml_support::decl_storage! { + trait Store for Module as Actors { + /// requirements to enter and maintain status in roles + pub Parameters get(parameters) build(|config: &GenesisConfig| { + if config.enable_storage_role { + let storage_params: RoleParameters = Default::default(); + vec![(Role::Storage, storage_params)] + } else { + vec![] + } + }): map Role => Option>; + + /// the roles members can enter into + pub AvailableRoles get(available_roles) build(|config: &GenesisConfig| { + if config.enable_storage_role { + vec![(Role::Storage)] + } else { + vec![] + } + }): Vec; + + /// Actors list + pub ActorAccountIds get(actor_account_ids) : Vec; + + /// actor accounts associated with a role + pub AccountIdsByRole get(account_ids_by_role) : map Role => Vec; + + /// tokens locked until given block number + pub Bondage get(bondage) : map T::AccountId => T::BlockNumber; + + /// First step before enter a role is registering intent with a new account/key. + /// This is done by sending a role_entry_request() from the new account. + /// The member must then send a stake() transaction to approve the request and enter the desired role. + /// The account making the request will be bonded and must have + /// sufficient balance to cover the minimum stake for the role. + /// Bonding only occurs after successful entry into a role. + pub RoleEntryRequests get(role_entry_requests) : Requests; + + /// Entry request expires after this number of blocks + pub RequestLifeTime get(request_life_time) config(request_life_time) : u64 = 0; + } + add_extra_genesis { + config(enable_storage_role): bool; + } + } +} + +pub type Signature = sr25519::Signature; +pub type AccountId = ::Signer; +pub type BlockNumber = u64; +pub type Index = u64; +pub type Header = generic::Header; +pub type Block = generic::Block; +pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic; + +impl system::Trait for Runtime { + type Hash = H256; + type Origin = Origin; + type BlockNumber = BlockNumber; + type Digest = generic::Digest; + type AccountId = AccountId; + type Event = Event; + type Log = Log; +} + +impl module::Trait for Runtime {} + +srml_support::construct_runtime!( + pub enum Runtime with Log(InternalLog: DigestItem) where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Event, Log(ChangesTrieRoot)}, + Module: module::{Module, Call, Storage, Config}, + } +); + + +#[test] +fn create_genesis_config() { + GenesisConfig { + module: Some(module::GenesisConfig { + request_life_time: 0, + enable_storage_role: true, + }) + }; +} \ No newline at end of file diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs new file mode 100644 index 0000000000000..62f44f006ab58 --- /dev/null +++ b/srml/support/test/tests/system.rs @@ -0,0 +1,74 @@ +use serde_derive::Serialize; +use srml_support::runtime_primitives::traits::Digest; +use srml_support::codec::{Encode, Decode}; +use primitives::H256; + +pub trait Trait: 'static + Eq + Clone { + type Origin: Into>> + From>; + type BlockNumber: Decode + Encode + Clone + Default; + type Digest: Digest; + type Hash; + type AccountId: Encode + Decode; + type Event: From; + type Log: From> + Into>; +} + +pub type DigestItemOf = <::Digest as Digest>::Item; + +srml_support::decl_module! { + pub struct Module for enum Call where origin: T::Origin { + pub fn deposit_event(_event: T::Event) { + } + } +} +impl Module { + pub fn deposit_log(_item: ::Item) { + unimplemented!(); + } +} + +srml_support::decl_event!( + pub enum Event { + ExtrinsicSuccess, + ExtrinsicFailed, + } +); + +/// Origin for the system module. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Debug))] +pub enum RawOrigin { + Root, + Signed(AccountId), + Inherent, +} + +impl From> for RawOrigin { + fn from(s: Option) -> RawOrigin { + match s { + Some(who) => RawOrigin::Signed(who), + None => RawOrigin::Inherent, + } + } +} + +pub type Origin = RawOrigin<::AccountId>; + +pub type Log = RawLog< + ::Hash, +>; + +#[cfg_attr(feature = "std", derive(Serialize, Debug))] +#[derive(Encode, Decode, PartialEq, Eq, Clone)] +pub enum RawLog { + ChangesTrieRoot(H), +} + +pub fn ensure_root(o: OuterOrigin) -> Result<(), &'static str> + where OuterOrigin: Into>> +{ + match o.into() { + Some(RawOrigin::Root) => Ok(()), + _ => Err("bad origin: expected to be a root origin"), + } +} \ No newline at end of file From 6805d218b38ddd5a86dc307fbfa7b75bccb081da Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 23 Apr 2019 22:04:56 +0200 Subject: [PATCH 02/14] move storage maps to blake2_128 (#2268) * remove default hash, introduce twox_128 and blake2 * use blake2_128 & create ext_blake2_128 * refactor code * add benchmark * factorize generator * fix * parameterizable hasher * some fix * fix * fix * fix * metadata * fix * remove debug print * map -> blake2_256 * fix test * fix test * Apply suggestions from code review Co-Authored-By: thiolliere * impl twox 128 concat (#2353) * impl twox_128_concat * comment addressed * fix * impl twox_128->64_concat * fix test --- core/client/src/client.rs | 14 +- core/client/src/light/fetcher.rs | 6 +- core/executor/src/wasm_executor.rs | 56 ++- core/executor/wasm/src/lib.rs | 3 +- core/primitives/Cargo.toml | 6 +- core/primitives/benches/benches.rs | 60 +++ core/primitives/src/hashing.rs | 17 + 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 | 20 + core/sr-primitives/src/lib.rs | 8 - core/test-runtime/src/genesismap.rs | 4 +- core/test-runtime/src/system.rs | 24 +- node/executor/src/lib.rs | 26 +- node/runtime/src/lib.rs | 2 +- srml/executive/src/lib.rs | 2 +- srml/indices/src/lib.rs | 15 +- srml/metadata/src/lib.rs | 21 +- srml/support/procedural/src/storage/impls.rs | 138 ++++--- srml/support/procedural/src/storage/mod.rs | 76 +++- .../procedural/src/storage/transformation.rs | 93 ++--- srml/support/procedural/tools/src/syn_ext.rs | 2 +- srml/support/src/hashable.rs | 15 +- srml/support/src/lib.rs | 20 +- srml/support/src/metadata.rs | 14 +- srml/support/src/storage/child.rs | 0 srml/support/src/storage/hashed/generator.rs | 285 +++++++++++++++ srml/support/src/storage/hashed/mod.rs | 223 ++++++++++++ srml/support/src/storage/mod.rs | 247 ++----------- .../{generator.rs => storage_items.rs} | 341 ++++-------------- .../support/src/storage/unhashed/generator.rs | 19 +- srml/support/src/storage/unhashed/mod.rs | 2 +- 33 files changed, 1078 insertions(+), 693 deletions(-) create mode 100644 core/primitives/benches/benches.rs create mode 100644 srml/support/src/storage/child.rs create mode 100644 srml/support/src/storage/hashed/generator.rs create mode 100644 srml/support/src/storage/hashed/mod.rs rename srml/support/src/storage/{generator.rs => storage_items.rs} (72%) diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 099255bdf5d2d..2b4465f19cabe 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -1536,7 +1536,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}; @@ -1586,12 +1586,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 3f724c31c40ec..28df2f8bffdaa 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/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index ce41d86a18414..e687a1f4db210 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, ChildStorageKey}; 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_64, twox_128, twox_256, ed25519, sr25519, Pair}; use primitives::hexdisplay::HexDisplay; use primitives::sandbox as sandbox_primitives; use primitives::{H256, Blake2Hasher}; @@ -448,6 +448,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]); @@ -481,6 +505,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]) @@ -940,6 +979,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/Cargo.toml b/core/primitives/Cargo.toml index 5a8468b436736..02133e0655dc0 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -31,8 +31,10 @@ regex = {version = "1.1", optional = true } [dev-dependencies] substrate-serializer = { path = "../serializer" } -pretty_assertions = "0.6.1" -heapsize = "0.4.2" +pretty_assertions = "0.6" +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 new file mode 100644 index 0000000000000..b81ef9dc4252d --- /dev/null +++ b/core/primitives/benches/benches.rs @@ -0,0 +1,60 @@ +// 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. + +// 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 MAX_KEY_SIZE: u32 = 32; + +fn data_set() -> Vec> { + 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 { + 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); +} 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 eb309c04a3689..97f5480743cef 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_64, 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 09ef303a64251..5cf83921ad876 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-io/with_std.rs b/core/sr-io/with_std.rs index bf7147babb16c..3148cf2842ff0 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, twox_64, 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 f4b3c911546a3..66ad5541df061 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -273,7 +273,9 @@ 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_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); @@ -544,6 +546,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(); @@ -571,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/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 32d59b6b5a732..e1ec698a4a372 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -88,14 +88,6 @@ pub use serde::{Serialize, Deserialize, de::DeserializeOwned}; /// 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..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}; +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::get_or(&balance_of_key(who), 0) + storage::hashed::get_or(&blake2_256, &balance_of_key(who), 0) } pub fn nonce_of(who: AccountId) -> u64 { - storage::get_or(&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::get_or(&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::get_or(&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::put(&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::get_or(&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::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::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, 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/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index a09d8b31f6a6a..340220160ecbb 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -59,7 +59,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("node"), impl_name: create_runtime_str!("substrate-node"), authoring_version: 10, - spec_version: 64, + spec_version: 65, impl_version: 65, apis: RUNTIME_API_VERSIONS, }; diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index 69db7e5ff090e..271d7156acc6a 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -443,7 +443,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/metadata/src/lib.rs b/srml/metadata/src/lib.rs index 254e72cb115e0..5f8b57206b7c9 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -253,17 +253,30 @@ 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, + Twox64Concat, +} + /// A storage function type. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] pub enum StorageFunctionType { Plain(DecodeDifferentStr), Map { + hasher: StorageHasher, key: DecodeDifferentStr, value: DecodeDifferentStr, is_linked: bool, }, DoubleMap { + hasher: StorageHasher, key1: DecodeDifferentStr, key2: DecodeDifferentStr, value: DecodeDifferentStr, @@ -312,8 +325,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. @@ -336,7 +351,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/impls.rs b/srml/support/procedural/src/storage/impls.rs index 5a8f7f65d5d8e..2708fdb213386 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::hashed::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::HashedStorage<#scrate::Twox128>>(f: F, storage: &S) -> R { + let mut val = >::get(storage); let ret = f(&mut val); #mutate_impl ; @@ -130,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, @@ -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,11 +183,16 @@ 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::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + { type Query = #value_type; + type Hasher = #scrate::#hasher; + /// Get the prefix key in storage. fn prefix() -> &'static [u8] { #final_prefix @@ -190,26 +200,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::HashedStorage<#scrate::#hasher>>(key: &#kty, f: F, storage: &S) -> R { + let mut val = #as_map::get(key, storage); let ret = f(&mut val); #mutate_impl ; @@ -220,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, @@ -264,8 +274,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 +326,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::HashedStorage<#scrate::#hasher>, #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::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"); self.next = linkage.next; @@ -336,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>); } } }; @@ -365,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, ) { @@ -394,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> { @@ -433,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), @@ -451,9 +464,13 @@ 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::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + { type Query = #value_type; + type Hasher = #scrate::#hasher; + /// Get the prefix key in storage. fn prefix() -> &'static [u8] { #final_prefix @@ -467,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)); @@ -486,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); @@ -505,7 +522,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::HashedStorage<#scrate::#hasher>>(key: &#kty, f: F, storage: &S) -> R { use self::#inner_module::Utils; let key_for = &*#as_map::key_for(key); @@ -519,20 +536,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::hashed::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::HashedStorage<#scrate::#hasher>>(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(), @@ -542,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, @@ -593,11 +612,20 @@ 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_for(k1: &#k1ty) -> Vec { + let mut key = #as_double_map::prefix().to_vec(); + #scrate::codec::Encode::encode_to(k1, &mut key); + #scrate::Hashable::#hasher(&key).to_vec() + } + fn prefix() -> &'static [u8] { #final_prefix } @@ -608,17 +636,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/mod.rs b/srml/support/procedural/src/storage/mod.rs index 82290e0de458f..649a48a1813ed 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,19 +158,22 @@ 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), + Twox64Concat(ext::CustomToken), } #[derive(Parse, ToTokens, Debug)] @@ -175,6 +182,64 @@ struct DeclStorageDefault { pub expr: syn::Expr, } +#[derive(Parse, ToTokens, Debug)] +struct SetHasher { + pub hasher_keyword: ext::CustomToken, + pub inner: ext::Parens, +} + +#[derive(Debug, Clone)] +enum HasherKind { + Blake2_256, + Blake2_128, + Twox256, + Twox128, + Twox64Concat, +} + +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::Twox64Concat(_) => HasherKind::Twox64Concat, + } + } +} +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::Twox64Concat => quote!( Twox64Concat ), + } + } + + 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 ), + HasherKind::Twox64Concat => quote!( twox_64_concat), + } + } + + 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 ), + HasherKind::Twox64Concat => quote!( StorageHasher::Twox64Concat ), + } + } +} + 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 +251,9 @@ 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!(Twox256Keyword, "twox_256", "Twox_256 as keyword"); -custom_keyword!(Twox128Keyword, "twox_128", "Twox_128 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!(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/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index f00b5e8309bcc..205fccdea574d 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::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::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); } }} }, @@ -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); @@ -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.into_storage_hasher_struct(), 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.into_storage_hasher_struct(), 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.into_hashable_fn(), key1_type, key2_type, key2_hasher) }, }; impls.extend(implementation) @@ -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::hashed::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::hashed::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,42 +727,46 @@ 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 } => { + DeclStorageTypeInfosKind::Map { key_type, is_linked, hasher } => { + let hasher = hasher.into_metadata(); 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 { + hasher: #scrate::metadata::#hasher, + key: #scrate::metadata::DecodeDifferent::Encode(#kty), + value: #scrate::metadata::DecodeDifferent::Encode(#styp), is_linked: #is_linked, } } }, - DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, key2_hasher } => { + 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::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 { + hasher: #scrate::metadata::#hasher, + 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 +790,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 +810,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 +820,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; @@ -848,10 +852,12 @@ pub(crate) struct DeclStorageTypeInfos<'a> { enum DeclStorageTypeInfosKind<'a> { Simple, Map { + hasher: HasherKind, key_type: &'a syn::Type, is_linked: bool, }, DoubleMap { + hasher: HasherKind, key1_type: &'a syn::Type, key2_type: &'a syn::Type, key2_hasher: TokenStream2, @@ -871,14 +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()).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| 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| 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/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/hashable.rs b/srml/support/src/hashable.rs index 9199a0958d2e5..b3ee2b3612c1e 100644 --- a/srml/support/src/hashable.rs +++ b/srml/support/src/hashable.rs @@ -17,16 +17,24 @@ //! 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}; +use crate::storage::hashed::generator::StorageHasher; +use crate::Twox64Concat; +use crate::rstd::prelude::Vec; -/// Trait for available hash functions. +// 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_64_concat(&self) -> Vec; } 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) } @@ -36,4 +44,7 @@ impl Hashable for T { fn twox_256(&self) -> [u8; 32] { self.using_encoded(twox_256) } + 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 26ed8570588d9..073cab14d3043 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::generator::Storage as GenericStorage; -pub use self::storage::unhashed::generator::UnhashedStorage as GenericUnhashedStorage; +pub use self::storage::hashed::generator::{HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat}; +pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] pub mod dispatch; @@ -56,7 +56,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; @@ -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; @@ -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_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 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,6 +354,7 @@ mod tests { name: DecodeDifferent::Encode("Data"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ + hasher: StorageHasher::Twox64Concat, 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::Twox128, 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_256, 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::Twox64Concat, 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_256, 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_256, key1: DecodeDifferent::Encode("T::BlockNumber"), key2: DecodeDifferent::Encode("T::BlockNumber"), value: DecodeDifferent::Encode("T::BlockNumber"), diff --git a/srml/support/src/metadata.rs b/srml/support/src/metadata.rs index f7594d27b7c2b..407408b52c847 100644 --- a/srml/support/src/metadata.rs +++ b/srml/support/src/metadata.rs @@ -16,10 +16,14 @@ pub use srml_metadata::{ DecodeDifferent, FnEncode, RuntimeMetadata, - ModuleMetadata, RuntimeMetadataV3, + ModuleMetadata, RuntimeMetadataV4, DefaultByteGetter, RuntimeMetadataPrefixed, + StorageMetadata, StorageFunctionMetadata, + StorageFunctionType, StorageFunctionModifier, + DefaultByte, StorageHasher }; + /// Implements the metadata support for the given runtime and all its modules. /// /// Example: @@ -36,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() @@ -377,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"), 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/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs new file mode 100644 index 0000000000000..828d2a905dd0e --- /dev/null +++ b/srml/support/src/storage/hashed/generator.rs @@ -0,0 +1,285 @@ +// 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 HashedStorage trait + +use crate::codec; +use crate::rstd::prelude::{Vec, Box}; +#[cfg(feature = "std")] +use crate::storage::unhashed::generator::UnhashedStorage; +use runtime_io::{twox_64, twox_128, blake2_128, twox_256, blake2_256}; + +pub trait StorageHasher: 'static { + type Output: AsRef<[u8]>; + fn hash(x: &[u8]) -> Self::Output; +} + +/// Hash storage keys with `concat(twox128(key), key)` +pub struct Twox64Concat; +impl StorageHasher for Twox64Concat { + type Output = Vec; + fn hash(x: &[u8]) -> Vec { + twox_64(x) + .into_iter() + .chain(x.into_iter()) + .cloned() + .collect::>() + } +} + +#[test] +fn test_twox_64_concat() { + let r = Twox64Concat::hash(b"foo"); + assert_eq!(r.split_at(8), (&twox_128(b"foo")[..8], &b"foo"[..])) +} + +/// Hash storage keys with blake2 128 +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 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. + 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() + } + + /// Get a Vec of bytes from storage. + fn get_raw(&self, key: &[u8]) -> Option>; + + /// Put a raw byte slice into storage. + fn put_raw(&self, key: &[u8], value: &[u8]); +} + +// We use a construct like this during when genesis storage is being built. +#[cfg(feature = "std")] +impl HashedStorage for std::cell::RefCell<&mut sr_primitives::StorageOverlay> { + fn exists(&self, key: &[u8]) -> bool { + UnhashedStorage::exists(self, &H::hash(key).as_ref()) + } + + fn get(&self, key: &[u8]) -> Option { + UnhashedStorage::get(self, &H::hash(key).as_ref()) + } + + fn put(&self, key: &[u8], val: &T) { + UnhashedStorage::put(self, &H::hash(key).as_ref(), val) + } + + fn kill(&self, key: &[u8]) { + UnhashedStorage::kill(self, &H::hash(key).as_ref()) + } + + fn get_raw(&self, key: &[u8]) -> Option> { + UnhashedStorage::get_raw(self, &H::hash(key).as_ref()) + } + + fn put_raw(&self, key: &[u8], value: &[u8]) { + UnhashedStorage::put_raw(self, &H::hash(key).as_ref(), value) + } +} + +/// 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: HashedStorage>(f: F, storage: &S) -> R; + + /// Clear the storage value. + fn kill>(storage: &S) { + storage.kill(Self::key()) + } + + /// Append the given items to the value in the storage. + /// + /// `T` is required to implement `codec::EncodeAppend`. + fn append( + items: &[I], storage: &S + ) -> Result<(), &'static str> where T: codec::EncodeAppend { + let new_val = ::append( + storage.get_raw(Self::key()).unwrap_or_default(), + items, + ).ok_or_else(|| "Could not append given item")?; + storage.put_raw(Self::key(), &new_val); + Ok(()) + } +} + +/// 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; + + type Hasher: StorageHasher; + + /// 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: 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; + + /// Enumerate all elements in the map. + 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 new file mode 100644 index 0000000000000..5c65cf0513b26 --- /dev/null +++ b/srml/support/src/storage/hashed/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 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}; + +/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. +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 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 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, 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 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 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 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 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, 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 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 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 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 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. +/// +/// 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]; + + /// 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(&twox_128, &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(&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(&twox_128, &index.to_keyed_vec(Self::PREFIX), item); + } + } + + fn clear_item(index: u32) { + if index < Self::count() { + kill(&twox_128, &index.to_keyed_vec(Self::PREFIX)); + } + } + + fn item(index: u32) -> Self::Item { + 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(&twox_128, &b"len".to_keyed_vec(Self::PREFIX), &count); + } + + fn count() -> u32 { + get_or_default(&twox_128, &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(&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(&twox_128, b":test", &x); + let y: i64 = get(&twox_128, 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(&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(&twox_128, b":test", &x); + let y: bool = get(&twox_128, 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::, _, _>(&twox_128, 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(&twox_128, b":test", &x); + }); + + with_externalities(&mut t, || { + 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 74b55673e76db..89039cd816b3e 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -18,12 +18,14 @@ use crate::rstd::prelude::*; use crate::rstd::borrow::Borrow; -use runtime_io::{self, twox_128}; -use crate::codec::{Codec, Encode, Decode, KeyedVec, Input, EncodeAppend}; +use codec::{Codec, Encode, Decode, KeyedVec, Input, EncodeAppend}; +use hashed::generator::{HashedStorage, StorageHasher}; +use unhashed::generator::UnhashedStorage; #[macro_use] -pub mod generator; +pub mod storage_items; pub mod unhashed; +pub mod hashed; struct IncrementalInput<'a> { key: &'a [u8], @@ -54,104 +56,32 @@ impl<'a> Input for IncrementalChildInput<'a> { } } - -/// 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) -} - /// The underlying runtime storage. pub struct RuntimeStorage; -impl crate::GenericStorage for RuntimeStorage { +impl HashedStorage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { - exists(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 { - get(key) + hashed::get(&H::hash, key) } /// Put a value in under a key. fn put(&self, key: &[u8], val: &T) { - put(key, val) + hashed::put(&H::hash, key, val) } /// Remove the bytes of a key from storage. fn kill(&self, key: &[u8]) { - kill(key) + hashed::kill(&H::hash, key) } /// Take a value from storage, deleting it after reading. fn take(&self, key: &[u8]) -> Option { - take(key) + hashed::take(&H::hash, key) } fn get_raw(&self, key: &[u8]) -> Option> { @@ -163,7 +93,7 @@ impl crate::GenericStorage for RuntimeStorage { } } -impl crate::GenericUnhashedStorage for RuntimeStorage { +impl UnhashedStorage for RuntimeStorage { fn exists(&self, key: &[u8]) -> bool { unhashed::exists(key) } @@ -235,11 +165,11 @@ pub trait StorageValue { where T: EncodeAppend; } -impl StorageValue for U where U: 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) @@ -296,17 +226,17 @@ pub trait StorageList { fn clear(); } -impl StorageList for U where U: 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 { @@ -364,15 +294,15 @@ pub trait StorageMap { fn take>(key: KeyArg) -> Self::Query; } -impl StorageMap for U where U: 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 { @@ -412,13 +342,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: hashed::generator::EnumerableStorageMap { fn head() -> Option { - >::head(&RuntimeStorage) + >::head(&RuntimeStorage) } fn enumerate() -> Box> where K: 'static, V: 'static { - >::enumerate(&RuntimeStorage) + >::enumerate(&RuntimeStorage) } } @@ -525,72 +455,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 { @@ -681,71 +552,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 72% rename from srml/support/src/storage/generator.rs rename to srml/support/src/storage/storage_items.rs index 3d57d200e28af..720cac64c5361 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,204 +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() } - - /// Get a Vec of bytes from storage. - fn get_raw(&self, key: &[u8]) -> Option>; - - /// Put a raw byte slice into storage. - fn put_raw(&self, key: &[u8], value: &[u8]); -} - -// 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)) - } - - fn get_raw(&self, key: &[u8]) -> Option> { - UnhashedStorage::get_raw(self, key) - } - - fn put_raw(&self, key: &[u8], value: &[u8]) { - UnhashedStorage::put_raw(self, key, value) - } -} - -/// 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()) - } - - /// Append the given items to the value in the storage. - /// - /// `T` is required to implement `codec::EncodeAppend`. - fn append( - items: &[I], storage: &S - ) -> Result<(), &'static str> where T: codec::EncodeAppend { - let new_val = ::append( - storage.get_raw(Self::key()).unwrap_or_default(), - items, - ).ok_or_else(|| "Could not append given item")?; - storage.put_raw(Self::key(), &new_val); - Ok(()) - } -} - -/// 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] @@ -380,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::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::generator::StorageValue<$ty> for $name { + impl $crate::storage::hashed::generator::StorageValue<$ty> for $name { type Query = $gettype; /// Get the storage key. @@ -394,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::HashedStorage<$crate::Twox128>>(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), } }); @@ -428,15 +226,17 @@ 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::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::generator::StorageMap<$kty, $ty> for $name { + impl $crate::storage::hashed::generator::StorageMap<$kty, $ty> for $name { type Query = $gettype; + type Hasher = $crate::Blake2_256; + /// Get the prefix key in storage. fn prefix() -> &'static [u8] { $prefix @@ -450,31 +250,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::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::generator::StorageMap<$kty, $ty>>::key_for(key); + 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::GenericStorage>(key: &$kty, f: F, storage: &S) -> R { - let mut val = >::take(key, storage); + fn mutate R, S: $crate::HashedStorage>(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), } }); @@ -487,19 +287,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::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::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::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::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 @@ -520,43 +320,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::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::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::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::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::generator::StorageList<$ty>>::key_for(index)[..]) + 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 { - 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::hashed::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::hashed::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::hashed::generator::StorageList<$ty>>::len_key()[..]) } } }; @@ -584,35 +384,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::metadata::StorageHasher; 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); - } - - fn put_raw(&self, key: &[u8], value: &[u8]) { - self.borrow_mut().insert(key.to_owned(), value.to_owned()); - } - - fn get_raw(&self, key: &[u8]) -> Option> { - self.borrow().get(key).cloned() - } - } + use crate::storage::hashed::generator::*; storage_items! { Value: b"a" => u32; @@ -622,7 +398,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)); @@ -632,7 +409,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()); @@ -651,7 +429,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])); @@ -661,7 +440,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; } @@ -850,6 +629,7 @@ mod tests { name: DecodeDifferent::Encode("MAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -863,6 +643,7 @@ mod tests { name: DecodeDifferent::Encode("PUBMAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -876,6 +657,7 @@ mod tests { name: DecodeDifferent::Encode("MAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -889,6 +671,7 @@ mod tests { name: DecodeDifferent::Encode("PUBMAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -902,6 +685,7 @@ mod tests { name: DecodeDifferent::Encode("GETMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -915,6 +699,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -928,6 +713,7 @@ mod tests { name: DecodeDifferent::Encode("GETMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -941,6 +727,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: false, @@ -954,6 +741,7 @@ mod tests { name: DecodeDifferent::Encode("LINKEDMAPU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -967,6 +755,7 @@ mod tests { name: DecodeDifferent::Encode("PUBLINKEDMAPU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -980,6 +769,7 @@ mod tests { name: DecodeDifferent::Encode("GETLINKEDMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, @@ -993,6 +783,7 @@ mod tests { name: DecodeDifferent::Encode("PUBGETLINKEDMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map { + hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String"), is_linked: true, diff --git a/srml/support/src/storage/unhashed/generator.rs b/srml/support/src/storage/unhashed/generator.rs index 6993059c2a376..c7a4689b3e377 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::twox_128; use crate::rstd::vec::Vec; /// Abstraction around storage with unhashed access. @@ -65,26 +64,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 std::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) }) } @@ -121,11 +120,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); - twox_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 { 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 f683e1b8d35fe12d26625816eb5dd1a1ef99579a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 24 Apr 2019 09:27:14 +0200 Subject: [PATCH 03/14] Fix compilation and cleanup some docs --- core/test-runtime/wasm/Cargo.lock | 6 +-- node-template/runtime/wasm/Cargo.lock | 1 + node/runtime/wasm/Cargo.lock | 1 + srml/support/Cargo.toml | 4 +- srml/support/src/event.rs | 39 ++++++------------- srml/support/src/lib.rs | 4 +- srml/support/src/storage/hashed/generator.rs | 2 +- srml/support/src/storage/mod.rs | 4 +- .../support/src/storage/unhashed/generator.rs | 4 +- 9 files changed, 25 insertions(+), 40 deletions(-) diff --git a/core/test-runtime/wasm/Cargo.lock b/core/test-runtime/wasm/Cargo.lock index bff3e79986dfc..b637940459237 100644 --- a/core/test-runtime/wasm/Cargo.lock +++ b/core/test-runtime/wasm/Cargo.lock @@ -2223,7 +2223,6 @@ version = "1.0.0" dependencies = [ "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 1.0.0", "substrate-primitives 1.0.0", ] @@ -2238,7 +2237,6 @@ dependencies = [ "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 1.0.0", "sr-primitives 1.0.0", "sr-std 1.0.0", @@ -2577,7 +2575,7 @@ dependencies = [ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2595,7 +2593,6 @@ dependencies = [ "memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 1.0.0", "sr-primitives 1.0.0", "sr-std 1.0.0", @@ -2628,6 +2625,7 @@ dependencies = [ "memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 1.0.0", + "substrate-primitives 1.0.0", "trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/node-template/runtime/wasm/Cargo.lock b/node-template/runtime/wasm/Cargo.lock index 54d7822c750d4..c430e34fb8a2e 100644 --- a/node-template/runtime/wasm/Cargo.lock +++ b/node-template/runtime/wasm/Cargo.lock @@ -2751,6 +2751,7 @@ dependencies = [ "memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 1.0.0", + "substrate-primitives 1.0.0", "trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/node/runtime/wasm/Cargo.lock b/node/runtime/wasm/Cargo.lock index 93d79d7dbaf82..b14c919bb3d05 100644 --- a/node/runtime/wasm/Cargo.lock +++ b/node/runtime/wasm/Cargo.lock @@ -2901,6 +2901,7 @@ dependencies = [ "memory-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 1.0.0", + "substrate-primitives 1.0.0", "trie-db 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "trie-root 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index 5a6dc3d9eb1a6..ab16e98ee90ed 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] hex-literal = { version = "0.1.0", optional = true } serde = { version = "1.0", optional = true, features = ["derive"] } -parity-codec = { version = "3.5.1", default-features = false, features = ["derive"] } +codec = { package = "parity-codec", version = "3.5.1", default-features = false, features = ["derive"] } srml-metadata = { path = "../metadata", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false } @@ -30,7 +30,7 @@ std = [ "bitmask/std", "serde", "runtime_io/std", - "parity-codec/std", + "codec/std", "sr-std/std", "sr-primitives/std", "srml-metadata/std", diff --git a/srml/support/src/event.rs b/srml/support/src/event.rs index e4168c318ad12..739c9f660c2b9 100644 --- a/srml/support/src/event.rs +++ b/srml/support/src/event.rs @@ -24,29 +24,19 @@ pub use srml_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEn /// # Simple Event Example: /// /// ```rust -/// #[macro_use] -/// extern crate srml_support; -/// #[macro_use] -/// extern crate parity_codec as codec; -/// -/// decl_event!( -/// pub enum Event { +/// srml_support::decl_event!( +/// pub enum Event { /// Success, /// Failure(String), /// } /// ); +/// ///# fn main() {} /// ``` /// /// # Generic Event Example: /// /// ```rust -/// #[macro_use] -/// extern crate srml_support; -/// extern crate parity_codec as codec; -/// #[macro_use] -/// extern crate parity_codec; -/// /// trait Trait { /// type Balance; /// type Token; @@ -54,8 +44,8 @@ pub use srml_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEn /// /// mod event1 { /// // Event that specifies the generic parameter explicitly (`Balance`). -/// decl_event!( -/// pub enum Event where Balance = ::Balance { +/// srml_support::decl_event!( +/// pub enum Event where Balance = ::Balance { /// Message(Balance), /// } /// ); @@ -65,8 +55,8 @@ pub use srml_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEn /// // Event that uses the generic parameter `Balance`. /// // If no name for the generic parameter is specified explicitly, /// // the name will be taken from the type name of the trait. -/// decl_event!( -/// pub enum Event where ::Balance { +/// srml_support::decl_event!( +/// pub enum Event where ::Balance { /// Message(Balance), /// } /// ); @@ -74,12 +64,13 @@ pub use srml_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEn /// /// mod event3 { /// // And we even support declaring multiple generic parameters! -/// decl_event!( -/// pub enum Event where ::Balance, ::Token { +/// srml_support::decl_event!( +/// pub enum Event where ::Balance, ::Token { /// Message(Balance, Token), /// } /// ); /// } +/// ///# fn main() {} /// ``` /// @@ -88,12 +79,6 @@ pub use srml_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEn /// # Generic Event with Instance Example: /// /// ```rust -/// #[macro_use] -/// extern crate srml_support; -/// extern crate parity_codec as codec; -/// #[macro_use] -/// extern crate parity_codec; -/// ///# struct DefaultInstance; ///# trait Instance {} ///# impl Instance for DefaultInstance {} @@ -103,7 +88,7 @@ pub use srml_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEn /// } /// /// // For module with instances, DefaultInstance is optionnal -/// decl_event!( +/// srml_support::decl_event!( /// pub enum Event where /// ::Balance, /// ::Token @@ -504,7 +489,7 @@ macro_rules! __impl_outer_event_json_metadata { mod tests { use super::*; use serde::Serialize; - use parity_codec::{Encode, Decode}; + use codec::{Encode, Decode}; mod system { pub trait Trait { diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 073cab14d3043..78edc361d5e67 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -27,7 +27,7 @@ pub use serde; #[doc(hidden)] pub use sr_std as rstd; #[doc(hidden)] -pub use parity_codec as codec; +pub use codec; #[cfg(feature = "std")] #[doc(hidden)] pub use once_cell; @@ -179,7 +179,7 @@ macro_rules! for_each_tuple { #[cfg(test)] mod tests { use super::*; - use parity_codec::Codec; + use codec::Codec; use runtime_io::{with_externalities, Blake2Hasher}; use runtime_primitives::BuildStorage; pub use srml_metadata::{ diff --git a/srml/support/src/storage/hashed/generator.rs b/srml/support/src/storage/hashed/generator.rs index 828d2a905dd0e..12600a9eafa6a 100644 --- a/srml/support/src/storage/hashed/generator.rs +++ b/srml/support/src/storage/hashed/generator.rs @@ -195,7 +195,7 @@ pub trait StorageValue { /// Append the given items to the value in the storage. /// /// `T` is required to implement `codec::EncodeAppend`. - fn append( + fn append, I: codec::Encode>( items: &[I], storage: &S ) -> Result<(), &'static str> where T: codec::EncodeAppend { let new_val = ::append( diff --git a/srml/support/src/storage/mod.rs b/srml/support/src/storage/mod.rs index 89039cd816b3e..fb23383c9d113 100644 --- a/srml/support/src/storage/mod.rs +++ b/srml/support/src/storage/mod.rs @@ -85,11 +85,11 @@ impl HashedStorage for RuntimeStorage { } fn get_raw(&self, key: &[u8]) -> Option> { - get_raw(key) + hashed::get_raw(&H::hash, key) } fn put_raw(&self, key: &[u8], value: &[u8]) { - put_raw(key, value) + hashed::put_raw(&H::hash, key, value) } } diff --git a/srml/support/src/storage/unhashed/generator.rs b/srml/support/src/storage/unhashed/generator.rs index c7a4689b3e377..25592dce6d944 100644 --- a/srml/support/src/storage/unhashed/generator.rs +++ b/srml/support/src/storage/unhashed/generator.rs @@ -89,11 +89,11 @@ impl UnhashedStorage for std::cell::RefCell<&mut sr_primitives::StorageOverlay> } fn get_raw(&self, key: &[u8]) -> Option> { - self.0.borrow().get(key).cloned() + self.borrow().get(key).cloned() } fn put_raw(&self, key: &[u8], value: &[u8]) { - self.0.borrow_mut().insert(key.to_vec(), value.to_vec()); + self.borrow_mut().insert(key.to_vec(), value.to_vec()); } } From 09517d3a15a88e5401a8dcae70d89df68e53d637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 24 Apr 2019 10:52:59 +0200 Subject: [PATCH 04/14] Lol --- core/sr-primitives/src/lib.rs | 6 + srml/balances/src/lib.rs | 1 - srml/support/procedural/src/storage/mod.rs | 8 - .../procedural/src/storage/transformation.rs | 164 ++++++++++-------- srml/support/procedural/tools/src/syn_ext.rs | 163 ++++++----------- srml/support/src/lib.rs | 4 +- srml/support/src/storage/storage_items.rs | 4 +- srml/support/test/Cargo.toml | 2 +- srml/support/test/tests/instance.rs | 1 - 9 files changed, 156 insertions(+), 197 deletions(-) diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index e1ec698a4a372..963bb112ada46 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -99,6 +99,12 @@ pub trait BuildStorage: Sized { fn assimilate_storage(self, storage: &mut StorageOverlay, child_storage: &mut ChildrenStorageOverlay) -> Result<(), String>; } +#[cfg(feature = "std")] +pub trait CreateModuleGenesisStorage: Sized { + /// Create the module genesis storage into the given `storage` and `child_storage`. + fn create_module_genesis_storage(self, storage: &mut StorageOverlay, child_storage: &mut ChildrenStorageOverlay) -> Result<(), String>; +} + #[cfg(feature = "std")] impl BuildStorage for StorageOverlay { fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index 1e0521ca8caf2..601affa3d341f 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -328,7 +328,6 @@ decl_storage! { config(balances): Vec<(T::AccountId, T::Balance)>; config(vesting): Vec<(T::AccountId, T::BlockNumber, T::BlockNumber)>; // begin, length } - extra_genesis_skip_phantom_data_field; } decl_module! { diff --git a/srml/support/procedural/src/storage/mod.rs b/srml/support/procedural/src/storage/mod.rs index 649a48a1813ed..d89189a58f611 100644 --- a/srml/support/procedural/src/storage/mod.rs +++ b/srml/support/procedural/src/storage/mod.rs @@ -52,7 +52,6 @@ struct StorageDefinition { pub crate_ident: Ident, pub content: ext::Braces>, pub extra_genesis: Option, - pub extra_genesis_skip_phantom_data_field: Option, } #[derive(Parse, ToTokens, Debug)] @@ -67,12 +66,6 @@ struct AddExtraGenesis { pub content: ext::Braces, } -#[derive(Parse, ToTokens, Debug)] -struct ExtraGenesisSkipPhantomDataField { - pub genesis_phantom_keyword: ext::CustomToken, - pub token: Token![;], -} - #[derive(Parse, ToTokens, Debug)] struct AddExtraGenesisContent { pub lines: ext::Punctuated, @@ -255,5 +248,4 @@ 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!(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/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 205fccdea574d..eb247118addf1 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -19,7 +19,9 @@ // end::description[] use srml_support_procedural_tools::syn_ext as ext; -use srml_support_procedural_tools::{generate_crate_access, generate_hidden_includes, clean_type_string}; +use srml_support_procedural_tools::{ + generate_crate_access, generate_hidden_includes, clean_type_string +}; use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; @@ -65,11 +67,14 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { crate_ident: cratename, content: ext::Braces { content: storage_lines, ..}, extra_genesis, - extra_genesis_skip_phantom_data_field, .. } = def; - let instance_opts = match get_instance_opts(mod_instance, mod_instantiable, mod_default_instance) { + let instance_opts = match get_instance_opts( + mod_instance, + mod_instantiable, + mod_default_instance + ) { Ok(opts) => opts, Err(err) => return err.to_compile_error().into(), }; @@ -104,7 +109,6 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { &instance_opts, &storage_lines, &extra_genesis, - extra_genesis_skip_phantom_data_field.is_some(), )); let decl_storage_items = decl_storage_items( &scrate, @@ -114,6 +118,7 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { &cratename, &storage_lines, ); + let decl_store_items = decl_store_items( &storage_lines, ); @@ -185,7 +190,6 @@ fn decl_store_extra_genesis( instance_opts: &InstanceOpts, storage_lines: &ext::Punctuated, extra_genesis: &Option, - extra_genesis_skip_phantom_data_field: bool, ) -> Result { let InstanceOpts { @@ -202,8 +206,9 @@ fn decl_store_extra_genesis( let mut config_field = TokenStream2::new(); let mut config_field_default = TokenStream2::new(); let mut builders = TokenStream2::new(); - for sline in storage_lines.inner.iter() { + let mut assimilate_require_generic = false; + for sline in storage_lines.inner.iter() { let DeclStorageLine { attrs, name, @@ -234,7 +239,9 @@ fn decl_store_extra_genesis( ) ); }; - if type_infos.kind.is_simple() && ext::has_parametric_type(type_infos.value_type, traitinstance) { + + if type_infos.kind.is_simple() + && ext::type_contains_ident(type_infos.value_type, traitinstance) { is_trait_needed = true; has_trait_field = true; } @@ -259,8 +266,18 @@ fn decl_store_extra_genesis( quote!( #( #[ #attrs ] )* pub #ident: Vec<(#key1_type, #key2_type, #storage_type)>, ) }, }); - opt_build = Some(build.as_ref().map(|b| &b.expr.content).map(|b|quote!( #b )) - .unwrap_or_else(|| quote!( (|config: &GenesisConfig<#traitinstance, #instance>| config.#ident.clone()) ))); + opt_build = Some( + build + .as_ref() + .map(|b| { + assimilate_require_generic = ext::expr_contains_ident(&b.expr, traitinstance); + &b.expr.content + }) + .map(|b| quote!( #b )) + .unwrap_or_else(|| + quote!( (|config: &Self| config.#ident.clone()) ) + ) + ); let fielddefault = default_value.inner.as_ref().map(|d| &d.expr).map(|d| if type_infos.is_option { @@ -276,42 +293,40 @@ fn decl_store_extra_genesis( let typ = type_infos.typ; if let Some(builder) = opt_build { - is_trait_needed = true; builders.extend(match type_infos.kind { DeclStorageTypeInfosKind::Simple => { quote!{{ - use #scrate::rstd::{cell::RefCell, marker::PhantomData}; - use #scrate::codec::{Encode, Decode}; - let v = (#builder)(&self); - <#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageValue<#typ>>::put(&v, &storage); + < + #name<#traitinstance, #instance> as + #scrate::storage::hashed::generator::StorageValue<#typ> + >::put(&v, &storage); }} }, DeclStorageTypeInfosKind::Map { key_type, .. } => { quote!{{ - use #scrate::rstd::{cell::RefCell, marker::PhantomData}; - use #scrate::codec::{Encode, Decode}; - let data = (#builder)(&self); - for (k, v) in data.into_iter() { - <#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage); - } + data.into_iter().for_each(|(k, v)| { + < + #name<#traitinstance, #instance> as + #scrate::storage::hashed::generator::StorageMap<#key_type, #typ> + >::insert(&k, &v, &storage); + }); }} }, DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { quote!{{ - use #scrate::rstd::{cell::RefCell, marker::PhantomData}; - use #scrate::codec::{Encode, Decode}; - let data = (#builder)(&self); - for (k1, k2, v) in data.into_iter() { - <#name<#traitinstance, #instance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ>>::insert(&k1, &k2, &v, &storage); - } + data.into_iter().for_each(|(k1, k2, v)| { + < + #name<#traitinstance, #instance> as + #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> + >::insert(&k1, &k2, &v, &storage); + }); }} }, }); } - } let mut has_scall = false; @@ -330,7 +345,7 @@ fn decl_store_extra_genesis( default_value, .. }) => { - if ext::has_parametric_type(&extra_type, traitinstance) { + if ext::type_contains_ident(&extra_type, traitinstance) { is_trait_needed = true; has_trait_field = true; } @@ -351,6 +366,7 @@ fn decl_store_extra_genesis( if has_scall { return Err(Error::new(expr.span(), "Only one build expression allowed for extra genesis")); } + assimilate_require_generic = ext::expr_contains_ident(&expr, traitinstance); let content = &expr.content; scall = quote!( ( #content ) ); has_scall = true; @@ -363,7 +379,7 @@ fn decl_store_extra_genesis( let serde_bug_bound = if !serde_complete_bound.is_empty() { let mut b_ser = String::new(); let mut b_dser = String::new(); - // panic!("{:#?}", serde_complete_bound); + serde_complete_bound.into_iter().for_each(|bound| { let stype = quote!(#bound); b_ser.push_str(&format!("{} : {}::serde::Serialize, ", stype, scrate)); @@ -382,46 +398,31 @@ fn decl_store_extra_genesis( || !config_field.is_empty() || !genesis_extrafields.is_empty() || !builders.is_empty(); - Ok(if is_extra_genesis_needed { - let (fparam_struct, fparam_impl, sparam, ph_field, ph_default) = if is_trait_needed { - if (has_trait_field && instance.is_none()) || extra_genesis_skip_phantom_data_field { - // no phantom data required - ( - quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), - quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), - quote!(<#traitinstance, #instance>), - quote!(), - quote!(), - ) - } else { - // need phantom data - ( - quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), - quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), - quote!(<#traitinstance, #instance>), - - quote!{ - #[serde(skip)] - pub _genesis_phantom_data: #scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>, - }, - quote!{ - _genesis_phantom_data: Default::default(), - }, - ) - } + if is_extra_genesis_needed { + let (fparam_struct, fparam_impl, sparam, build_storage_impl) = if is_trait_needed { + ( + quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), + quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), + quote!(<#traitinstance, #instance>), + quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), + ) } else { // do not even need type parameter - (quote!(), quote!(), quote!(), quote!(), quote!()) + ( + quote!(), + quote!(), + quote!(), + quote!(<#traitinstance: #traittype>), + ) }; - quote!{ + Ok(quote!{ #[derive(#scrate::Serialize, #scrate::Deserialize)] #[cfg(feature = "std")] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] #serde_bug_bound pub struct GenesisConfig#fparam_struct { - #ph_field #config_field #genesis_extrafields } @@ -430,7 +431,6 @@ fn decl_store_extra_genesis( impl#fparam_impl Default for GenesisConfig#sparam { fn default() -> Self { GenesisConfig { - #ph_default #config_field_default #genesis_extrafields_default } @@ -438,10 +438,28 @@ 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; - let storage = RefCell::new(r); + impl#build_storage_impl GenesisConfig#sparam { + fn build_storage(self) -> std::result::Result< + ( + #scrate::runtime_primitives::StorageOverlay, + #scrate::runtime_primitives::ChildrenStorageOverlay, + ), + String + > { + let mut storage = Default::default(); + let mut child_storage = Default::default(); + self.assimilate_storage(&mut storage, &mut child_storage)?; + Ok((storage, child_storage)) + } + + /// Assimilate the storage for this module into pre-existing overlays. + fn assimilate_storage( + self, + storage: &mut #scrate::runtime_primitives::StorageOverlay, + child_storage: &mut #scrate::runtime_primitives::ChildrenStorageOverlay, + ) -> std::result::Result<(), String> { + use std::{cell::RefCell, marker::PhantomData}; + let storage = (RefCell::new(r), PhantomData::::default(), PhantomData::<#traitinstance>::default()); #builders @@ -452,10 +470,20 @@ fn decl_store_extra_genesis( Ok(()) } } - } + + #[cfg(feature = "std")] + impl#build_storage_impl #scrate::runtime_primitives::CreateModuleGenesisStorage<#traitinstance> for GenesisConfig#sparam { + fn create_module_genesis_storage( + self, + r: &mut #scrate::runtime_primitives::StorageOverlay, + c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay, + ) -> std::result::Result<(), String> { + } + } + }) } else { - quote!() - }) + Ok(quote!()) + } } fn decl_storage_items( @@ -515,7 +543,7 @@ fn decl_storage_items( impls.extend(quote! { /// Tag a type as an instance of a module. - /// + /// /// Defines storage prefixes, they must be unique. pub trait #instantiable: 'static { #const_impls diff --git a/srml/support/procedural/tools/src/syn_ext.rs b/srml/support/procedural/tools/src/syn_ext.rs index c6b0b4aefbd70..3839f133d5419 100644 --- a/srml/support/procedural/tools/src/syn_ext.rs +++ b/srml/support/procedural/tools/src/syn_ext.rs @@ -18,23 +18,20 @@ //! Extension to syn types, mainly for parsing // end::description[] -use syn::parse::{ - Parse, - ParseStream, - Result, +use syn::{ + visit::{Visit, self}, parse::{Parse, ParseStream, Result}, + token::CustomKeyword, Ident, }; -use syn::token::CustomKeyword; -use proc_macro2::TokenStream as T2; +use proc_macro2::TokenStream; use quote::{ToTokens, quote}; use std::iter::once; -use syn::Ident; use srml_support_procedural_tools_derive::{ToTokens, Parse}; /// stop parsing here getting remaining token as content /// Warn duplicate stream (part of) #[derive(Parse, ToTokens, Debug)] pub struct StopParse { - pub inner: T2, + pub inner: TokenStream, } // inner macro really dependant on syn naming convention, do not export @@ -56,8 +53,8 @@ macro_rules! groups_impl { } impl ToTokens for $name

{ - fn to_tokens(&self, tokens: &mut T2) { - let mut inner_stream = T2::new(); + fn to_tokens(&self, tokens: &mut TokenStream) { + let mut inner_stream = TokenStream::new(); self.content.to_tokens(&mut inner_stream); let token_tree: proc_macro2::TokenTree = proc_macro2::Group::new(proc_macro2::Delimiter::$deli, inner_stream).into(); @@ -87,9 +84,9 @@ impl Parse for CustomToken { } impl ToTokens for CustomToken { - fn to_tokens(&self, tokens: &mut T2) { + fn to_tokens(&self, tokens: &mut TokenStream) { use std::str::FromStr; - tokens.extend(T2::from_str(T::ident()).expect("custom keyword should parse to ident")); + tokens.extend(TokenStream::from_str(T::ident()).expect("custom keyword should parse to ident")); } } @@ -134,7 +131,7 @@ impl Parse for PunctuatedInner { } impl ToTokens for PunctuatedInner { - fn to_tokens(&self, tokens: &mut T2) { + fn to_tokens(&self, tokens: &mut TokenStream) { self.inner.to_tokens(tokens) } } @@ -154,7 +151,7 @@ impl Parse for Meta { } impl ToTokens for Meta { - fn to_tokens(&self, tokens: &mut T2) { + fn to_tokens(&self, tokens: &mut TokenStream) { match self.inner { syn::Meta::Word(ref ident) => { let ident = ident.clone(); @@ -184,7 +181,7 @@ impl Parse for OuterAttributes { } impl ToTokens for OuterAttributes { - fn to_tokens(&self, tokens: &mut T2) { + fn to_tokens(&self, tokens: &mut TokenStream) { for att in self.inner.iter() { att.to_tokens(tokens); } @@ -209,121 +206,59 @@ impl Parse for Opt

{ } impl ToTokens for Opt

{ - fn to_tokens(&self, tokens: &mut T2) { + fn to_tokens(&self, tokens: &mut TokenStream) { if let Some(ref p) = self.inner { p.to_tokens(tokens); } } } -pub fn extract_type_option(typ: &syn::Type) -> Option { +pub fn extract_type_option(typ: &syn::Type) -> Option { if let syn::Type::Path(ref path) = typ { - path.path.segments.last().and_then(|v| { - if v.value().ident == "Option" { - if let syn::PathArguments::AngleBracketed(ref a) = v.value().arguments { - let args = &a.args; - Some(quote!{ #args }) - } else { - None - } - } else { - None + let v = path.path.segments.last()?; + if v.value().ident == "Option" { + if let syn::PathArguments::AngleBracketed(ref a) = v.value().arguments { + let args = &a.args; + return Some(quote!{ #args }) } - }) - } else { - None + } } -} -pub fn is_parametric_type_def(typ: &syn::Type, default: bool) -> bool { - match *typ { - syn::Type::Path(ref path) => { - path.path.segments.iter().any(|v| { - if let syn::PathArguments::AngleBracketed(..) = v.arguments { - true - } else { - false - } - }) - }, - syn::Type::Slice(ref inner) => is_parametric_type_def(&inner.elem, default), - syn::Type::Array(ref inner) => is_parametric_type_def(&inner.elem, default), - syn::Type::Ptr(ref inner) => is_parametric_type_def(&inner.elem, default), - syn::Type::Reference(ref inner) => is_parametric_type_def(&inner.elem, default), - syn::Type::BareFn(ref inner) => inner.variadic.is_some(), - syn::Type::Never(..) => false, - syn::Type::Tuple(ref inner) => - inner.elems.iter().any(|t| is_parametric_type_def(t, default)), - syn::Type::TraitObject(..) => true, - syn::Type::ImplTrait(..) => true, - syn::Type::Paren(ref inner) => is_parametric_type_def(&inner.elem, default), - syn::Type::Group(ref inner) => is_parametric_type_def(&inner.elem, default), - syn::Type::Infer(..) => true, - syn::Type::Macro(..) => default, - syn::Type::Verbatim(..) => default, - } + None } -/// check if type has any type parameter, defaults to true for some cases. -pub fn is_parametric_type(typ: &syn::Type) -> bool { - is_parametric_type_def(typ, true) +/// Auxialary structure to check if a given `Ident` is contained in an ast. +struct ContainsIdent<'a> { + ident: &'a Ident, + result: bool, } -fn has_parametric_type_def_in_path(path: &syn::Path, ident: &Ident, default: bool) -> bool { - path.segments.iter().any(|v| { - if ident == &v.ident { - return true; - } - if let syn::PathArguments::AngleBracketed(ref a) = v.arguments { - for arg in a.args.iter() { - if let syn::GenericArgument::Type(ref typ) = arg { - if has_parametric_type_def(typ, ident, default) { - return true; - } - } - // potentially missing matches here - } - false - } else { - false +impl<'ast> Visit<'ast> for ContainsIdent<'ast> { + fn visit_ident(&mut self, input: &'ast Ident) { + if input == self.ident { + self.result = true; } - }) - -} -pub fn has_parametric_type_def(typ: &syn::Type, ident: &Ident, default: bool) -> bool { - match *typ { - syn::Type::Path(ref path) => has_parametric_type_def_in_path(&path.path, ident, default), - syn::Type::Slice(ref inner) => has_parametric_type_def(&inner.elem, ident, default), - syn::Type::Array(ref inner) => has_parametric_type_def(&inner.elem, ident, default), - syn::Type::Ptr(ref inner) => has_parametric_type_def(&inner.elem, ident, default), - syn::Type::Reference(ref inner) => has_parametric_type_def(&inner.elem, ident, default), - syn::Type::BareFn(ref inner) => inner.variadic.is_some(), - syn::Type::Never(..) => false, - syn::Type::Tuple(ref inner) => - inner.elems.iter().any(|t| has_parametric_type_def(t, ident, default)), - syn::Type::TraitObject(ref to) => { - to.bounds.iter().any(|bound| { - if let syn::TypeParamBound::Trait(ref t) = bound { - has_parametric_type_def_in_path(&t.path, ident, default) - } else { false } - }) - }, - syn::Type::ImplTrait(ref it) => { - it.bounds.iter().any(|bound| { - if let syn::TypeParamBound::Trait(ref t) = bound { - has_parametric_type_def_in_path(&t.path, ident, default) - } else { false } - }) - }, - syn::Type::Paren(ref inner) => has_parametric_type_def(&inner.elem, ident, default), - syn::Type::Group(ref inner) => has_parametric_type_def(&inner.elem, ident, default), - syn::Type::Infer(..) => default, - syn::Type::Macro(..) => default, - syn::Type::Verbatim(..) => default, } } -/// check if type has a type parameter, defaults to true for some cases. -pub fn has_parametric_type(typ: &syn::Type, ident: &Ident) -> bool { - has_parametric_type_def(typ, ident, true) +/// Check if a `Type` contains the given `Ident`. +pub fn type_contains_ident(typ: &syn::Type, ident: &Ident) -> bool { + let mut visit = ContainsIdent { + result: false, + ident, + }; + + visit::visit_type(&mut visit, typ); + visit.result } + +/// Check if a `Expr` contains the given `Ident`. +pub fn expr_contains_ident(expr: &syn::Expr, ident: &Ident) -> bool { + let mut visit = ContainsIdent { + result: false, + ident, + }; + + visit::visit_expr(&mut visit, expr); + visit.result +} \ No newline at end of file diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index 78edc361d5e67..aa32c6e81a187 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -181,7 +181,7 @@ mod tests { use super::*; use codec::Codec; use runtime_io::{with_externalities, Blake2Hasher}; - use runtime_primitives::BuildStorage; + use runtime_primitives::BuildStorageGen; pub use srml_metadata::{ DecodeDifferent, StorageMetadata, StorageFunctionMetadata, StorageFunctionType, StorageFunctionModifier, @@ -226,7 +226,7 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { - GenesisConfig::::default().build_storage().unwrap().0.into() + GenesisConfig::default().build_storage().unwrap().0.into() } type Map = Data; diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 720cac64c5361..989b37a173ab1 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -461,7 +461,7 @@ mod tests { // getters: pub / $default // we need at least one type which uses T, otherwise GenesisConfig will complain. GETU32 get(u32_getter): T::Origin; - pub PUBGETU32 get(pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32; + pub PUBGETU32 get(pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32; GETU32WITHCONFIG get(u32_getter_with_config) config(): u32; pub PUBGETU32WITHCONFIG get(pub_u32_getter_with_config) config(): u32; GETU32MYDEF get(u32_getter_mydef): Option = Some(4); @@ -831,7 +831,7 @@ mod tests { #[test] fn check_genesis_config() { - let config = GenesisConfig::::default(); + let config = GenesisConfig::default(); assert_eq!(config.u32_getter_with_config, 0u32); assert_eq!(config.pub_u32_getter_with_config, 0u32); diff --git a/srml/support/test/Cargo.toml b/srml/support/test/Cargo.toml index 12b584d018cbf..f6d84ba014bf6 100644 --- a/srml/support/test/Cargo.toml +++ b/srml/support/test/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "srml-support-test" version = "0.1.0" -authors = ["thiolliere "] +authors = ["Parity Technologies "] edition = "2018" [dev-dependencies] diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 2a5462c977cd2..7c21eaccb5ab9 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -145,7 +145,6 @@ mod module2 { pub LinkedMap config(linked_map): linked_map u64 => u64; pub DoubleMap config(double_map): double_map u64, blake2_256(u64) => u64; } - extra_genesis_skip_phantom_data_field; } srml_support::decl_event! { From 1c3fff9cbe3833616a8e6d32fbcbbd5b5d5709d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 29 Apr 2019 17:21:11 +0200 Subject: [PATCH 05/14] Remove traits from storage types that are not generic --- srml/support/procedural/src/storage/impls.rs | 125 ++++++++---- .../procedural/src/storage/transformation.rs | 178 +++++++++++++----- srml/support/procedural/tools/src/syn_ext.rs | 29 ++- srml/support/src/lib.rs | 11 +- srml/system/src/lib.rs | 18 +- 5 files changed, 262 insertions(+), 99 deletions(-) diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index 2708fdb213386..3d04baf4e13d1 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -14,10 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::storage::transformation::{DeclStorageTypeInfos, InstanceOpts}; + +use srml_support_procedural_tools::syn_ext as ext; use proc_macro2::TokenStream as TokenStream2; use syn; use quote::quote; -use crate::storage::transformation::{DeclStorageTypeInfos, InstanceOpts}; pub fn option_unwrap(is_option: bool) -> TokenStream2 { if !is_option { @@ -79,7 +81,6 @@ impl<'a, I: Iterator> Impls<'a, I> { }; let InstanceOpts { - comma_instance, equal_default_instance, bound_instantiable, instance, @@ -93,14 +94,27 @@ impl<'a, I: Iterator> Impls<'a, I> { quote!{ #prefix.as_bytes() } }; + let (struct_trait, impl_trait, trait_and_instance) = if ext::type_contains_ident( + value_type, traitinstance + ) { + ( + quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), + quote!(#traitinstance: #traittype, #instance #bound_instantiable), + quote!(#traitinstance, #instance), + ) + } else { + (quote!(#instance #bound_instantiable #equal_default_instance), quote!(#instance #bound_instantiable), quote!(#instance)) + }; + // generator for value quote!{ #( #[ #attrs ] )* - #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance> - (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); + #visibility struct #name<#struct_trait>( + #scrate::rstd::marker::PhantomData<(#trait_and_instance)> + ); - impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::hashed::generator::StorageValue<#typ> for #name<#traitinstance, #instance> + impl<#impl_trait> #scrate::storage::hashed::generator::StorageValue<#typ> + for #name<#trait_and_instance> { type Query = #value_type; @@ -166,7 +180,6 @@ impl<'a, I: Iterator> Impls<'a, I> { }; let InstanceOpts { - comma_instance, equal_default_instance, bound_instantiable, instance, @@ -180,14 +193,27 @@ impl<'a, I: Iterator> Impls<'a, I> { quote!{ #prefix.as_bytes() } }; + let (struct_trait, impl_trait, trait_and_instance) = if ext::type_contains_ident(value_type, traitinstance) + || ext::type_contains_ident(kty, traitinstance) + { + ( + quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), + quote!(#traitinstance: #traittype, #instance #bound_instantiable), + quote!(#traitinstance, #instance), + ) + } else { + (quote!(#instance #bound_instantiable #equal_default_instance), quote!(#instance #bound_instantiable), quote!(#instance)) + }; + // generator for map quote!{ #( #[ #attrs ] )* - #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance> - (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); + #visibility struct #name<#struct_trait>( + #scrate::rstd::marker::PhantomData<(#trait_and_instance)> + ); - impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + impl<#impl_trait> + #scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#trait_and_instance> { type Query = #value_type; @@ -246,7 +272,6 @@ impl<'a, I: Iterator> Impls<'a, I> { } = self; let InstanceOpts { - comma_instance, equal_default_instance, bound_instantiable, instance, @@ -293,6 +318,24 @@ impl<'a, I: Iterator> Impls<'a, I> { } }; + let (struct_trait, impl_trait, trait_and_instance, trait_lifetime) = if ext::type_contains_ident(value_type, traitinstance) + || ext::type_contains_ident(kty, traitinstance) + { + ( + quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), + quote!(#traitinstance: #traittype, #instance #bound_instantiable), + quote!(#traitinstance, #instance), + quote!(#traitinstance: 'static), + ) + } else { + ( + quote!(#instance #bound_instantiable #equal_default_instance), + quote!(#instance #bound_instantiable), + quote!(#instance), + quote!() + ) + }; + // generator for linked map let helpers = quote! { /// Linkage data of an element (it's successor and predecessor) @@ -326,15 +369,14 @@ impl<'a, I: Iterator> Impls<'a, I> { pub _data: #phantom_data, } - impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #traitinstance: #traittype, #instance #bound_instantiable> - Iterator for Enumerator<'a, S, #kty, (#typ, #traitinstance, #instance)> - where #traitinstance: 'a + impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #struct_trait> + Iterator for Enumerator<'a, S, #kty, (#typ, #trait_and_instance)> { type Item = (#kty, #typ); fn next(&mut self) -> Option { let next = self.next.take()?; - let key_for = + let key_for = as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>>::key_for(&next); let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for) @@ -344,7 +386,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - pub(crate) trait Utils<#traitinstance: #traittype, #instance #bound_instantiable> { + pub(crate) trait Utils<#struct_trait> { /// Update linkage when this element is removed. /// /// Takes care of updating previous and next elements points @@ -375,9 +417,9 @@ impl<'a, I: Iterator> Impls<'a, I> { let structure = quote! { #( #[ #attrs ] )* - #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>(#phantom_data<(#traitinstance #comma_instance)>); + #visibility struct #name<#struct_trait>(#phantom_data<(#trait_and_instance)>); - impl<#traitinstance: #traittype, #instance #bound_instantiable> self::#inner_module::Utils<#traitinstance, #instance> for #name<#traitinstance, #instance> { + impl<#impl_trait> self::#inner_module::Utils<#trait_and_instance> for #name<#trait_and_instance> { fn remove_linkage>( linkage: self::#inner_module::Linkage<#kty>, storage: &S, @@ -464,8 +506,8 @@ impl<'a, I: Iterator> Impls<'a, I> { #structure - impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#traitinstance, #instance> + impl<#impl_trait> + #scrate::storage::hashed::generator::StorageMap<#kty, #typ> for #name<#trait_and_instance> { type Query = #value_type; @@ -536,8 +578,10 @@ 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> + impl<#impl_trait> + #scrate::storage::hashed::generator::EnumerableStorageMap<#kty, #typ> for #name<#trait_and_instance> + where + #trait_lifetime { fn head>(storage: &S) -> Option<#kty> { use self::#inner_module::Utils; @@ -545,16 +589,19 @@ impl<'a, I: Iterator> Impls<'a, I> { Self::read_head(storage) } - fn enumerate<'a, S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &'a S) -> #scrate::rstd::boxed::Box + 'a> where - #kty: 'a, - #typ: 'a, + fn enumerate<'a, S: #scrate::HashedStorage<#scrate::#hasher>>( + storage: &'a S + ) -> #scrate::rstd::boxed::Box + 'a> + where + #kty: 'a, + #typ: 'a, { use self::#inner_module::{Utils, Enumerator}; #scrate::rstd::boxed::Box::new(Enumerator { next: Self::read_head(storage), storage, - _data: #phantom_data::<(#typ, #traitinstance, #instance)>::default(), + _data: #phantom_data::<(#typ, #trait_and_instance)>::default(), }) } } @@ -595,7 +642,6 @@ impl<'a, I: Iterator> Impls<'a, I> { }; let InstanceOpts { - comma_instance, equal_default_instance, bound_instantiable, instance, @@ -609,14 +655,27 @@ impl<'a, I: Iterator> Impls<'a, I> { quote!{ #prefix.as_bytes() } }; + let (struct_trait, impl_trait, trait_and_instance) = if ext::type_contains_ident(value_type, traitinstance) + || ext::type_contains_ident(k1ty, traitinstance) + || ext::type_contains_ident(k2ty, traitinstance) + { + ( + quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), + quote!(#traitinstance: #traittype, #instance #bound_instantiable), + quote!(#traitinstance, #instance), + ) + } else { + (quote!(#instance #bound_instantiable #equal_default_instance), quote!(#instance #bound_instantiable), quote!(#instance)) + }; + // generator for double map quote!{ #( #[ #attrs ] )* - #visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance> - (#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); + #visibility struct #name<#struct_trait> + (#scrate::rstd::marker::PhantomData<(#trait_and_instance)>); - impl<#traitinstance: #traittype, #instance #bound_instantiable> - #scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#traitinstance, #instance> + impl<#impl_trait> + #scrate::storage::unhashed::generator::StorageDoubleMap<#k1ty, #k2ty, #typ> for #name<#trait_and_instance> { type Query = #value_type; @@ -653,9 +712,7 @@ impl<'a, I: Iterator> Impls<'a, I> { #mutate_impl ; ret } - } } - } } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index eb247118addf1..0fa361cb95201 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -177,9 +177,10 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { } #extra_genesis - }; + println!("{}", expanded); + expanded.into() } @@ -193,7 +194,6 @@ fn decl_store_extra_genesis( ) -> Result { let InstanceOpts { - comma_instance, equal_default_instance, bound_instantiable, instance, @@ -201,7 +201,6 @@ fn decl_store_extra_genesis( } = instance_opts; let mut is_trait_needed = false; - let mut has_trait_field = false; let mut serde_complete_bound = std::collections::HashSet::new(); let mut config_field = TokenStream2::new(); let mut config_field_default = TokenStream2::new(); @@ -222,9 +221,16 @@ fn decl_store_extra_genesis( let type_infos = get_type_infos(storage_type); - let mut opt_build; + let opt_build = build + .as_ref() + .map(|b| { + assimilate_require_generic |= ext::expr_contains_ident(&b.expr.content, traitinstance); + &b.expr.content + }) + .map(|b| quote!( #b )); + // need build line - if let Some(ref config) = config { + let builder = if let Some(ref config) = config { let ident = if let Some(ident) = config.expr.content.as_ref() { quote!( #ident ) } else if let Some(ref getter) = getter { @@ -243,7 +249,6 @@ fn decl_store_extra_genesis( if type_infos.kind.is_simple() && ext::type_contains_ident(type_infos.value_type, traitinstance) { is_trait_needed = true; - has_trait_field = true; } serde_complete_bound.insert(type_infos.value_type); @@ -266,18 +271,6 @@ fn decl_store_extra_genesis( quote!( #( #[ #attrs ] )* pub #ident: Vec<(#key1_type, #key2_type, #storage_type)>, ) }, }); - opt_build = Some( - build - .as_ref() - .map(|b| { - assimilate_require_generic = ext::expr_contains_ident(&b.expr, traitinstance); - &b.expr.content - }) - .map(|b| quote!( #b )) - .unwrap_or_else(|| - quote!( (|config: &Self| config.#ident.clone()) ) - ) - ); let fielddefault = default_value.inner.as_ref().map(|d| &d.expr).map(|d| if type_infos.is_option { @@ -287,39 +280,72 @@ fn decl_store_extra_genesis( }).unwrap_or_else(|| quote!( Default::default() )); config_field_default.extend(quote!( #ident: #fielddefault, )); + + opt_build + .map(Some) + .unwrap_or_else(|| + Some(quote!( (|config: &Self| config.#ident.clone()) )) + ) } else { - opt_build = build.as_ref().map(|b| &b.expr.content).map(|b| quote!( #b )); - } + opt_build + }; let typ = type_infos.typ; - if let Some(builder) = opt_build { + if let Some(builder) = builder { + assimilate_require_generic = true; builders.extend(match type_infos.kind { DeclStorageTypeInfosKind::Simple => { + let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) { + assimilate_require_generic = true; + quote!(#traitinstance,) + } else { + quote!() + }; + quote!{{ let v = (#builder)(&self); < - #name<#traitinstance, #instance> as + #name<#struct_trait #instance> as #scrate::storage::hashed::generator::StorageValue<#typ> >::put(&v, &storage); }} }, DeclStorageTypeInfosKind::Map { key_type, .. } => { + let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) + || ext::type_contains_ident(key_type, traitinstance) + { + assimilate_require_generic = true; + quote!(#traitinstance,) + } else { + quote!() + }; + quote!{{ let data = (#builder)(&self); data.into_iter().for_each(|(k, v)| { < - #name<#traitinstance, #instance> as + #name<#struct_trait #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ> >::insert(&k, &v, &storage); }); }} }, DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { + let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) + || ext::type_contains_ident(key1_type, traitinstance) + || ext::type_contains_ident(key2_type, traitinstance) + { + assimilate_require_generic = true; + quote!(#traitinstance,) + } else { + quote!() + }; + quote!{{ let data = (#builder)(&self); data.into_iter().for_each(|(k1, k2, v)| { < - #name<#traitinstance, #instance> as + #name<#struct_trait #instance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> >::insert(&k1, &k2, &v, &storage); }); @@ -347,7 +373,6 @@ fn decl_store_extra_genesis( }) => { if ext::type_contains_ident(&extra_type, traitinstance) { is_trait_needed = true; - has_trait_field = true; } serde_complete_bound.insert(extra_type); @@ -366,7 +391,7 @@ fn decl_store_extra_genesis( if has_scall { return Err(Error::new(expr.span(), "Only one build expression allowed for extra genesis")); } - assimilate_require_generic = ext::expr_contains_ident(&expr, traitinstance); + assimilate_require_generic |= ext::expr_contains_ident(&expr.content, traitinstance); let content = &expr.content; scall = quote!( ( #content ) ); has_scall = true; @@ -375,7 +400,6 @@ fn decl_store_extra_genesis( } } - let serde_bug_bound = if !serde_complete_bound.is_empty() { let mut b_ser = String::new(); let mut b_dser = String::new(); @@ -416,7 +440,13 @@ fn decl_store_extra_genesis( ) }; - Ok(quote!{ + let (fn_generic, fn_traitinstance) = if !is_trait_needed && assimilate_require_generic { + (quote!( <#traitinstance: #traittype> ), quote!( #traitinstance )) + } else { + (quote!(), quote!()) + }; + + let res = quote!{ #[derive(#scrate::Serialize, #scrate::Deserialize)] #[cfg(feature = "std")] #[serde(rename_all = "camelCase")] @@ -438,8 +468,8 @@ fn decl_store_extra_genesis( } #[cfg(feature = "std")] - impl#build_storage_impl GenesisConfig#sparam { - fn build_storage(self) -> std::result::Result< + impl#fparam_impl GenesisConfig#sparam { + fn build_storage #fn_generic (self) -> std::result::Result< ( #scrate::runtime_primitives::StorageOverlay, #scrate::runtime_primitives::ChildrenStorageOverlay, @@ -448,18 +478,17 @@ fn decl_store_extra_genesis( > { let mut storage = Default::default(); let mut child_storage = Default::default(); - self.assimilate_storage(&mut storage, &mut child_storage)?; + self.assimilate_storage::<#fn_traitinstance> (&mut storage, &mut child_storage)?; Ok((storage, child_storage)) } /// Assimilate the storage for this module into pre-existing overlays. - fn assimilate_storage( + fn assimilate_storage #fn_generic ( self, - storage: &mut #scrate::runtime_primitives::StorageOverlay, - child_storage: &mut #scrate::runtime_primitives::ChildrenStorageOverlay, + r: &mut #scrate::runtime_primitives::StorageOverlay, + c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay, ) -> std::result::Result<(), String> { - use std::{cell::RefCell, marker::PhantomData}; - let storage = (RefCell::new(r), PhantomData::::default(), PhantomData::<#traitinstance>::default()); + let storage = std::cell::RefCell::new(r); #builders @@ -478,9 +507,12 @@ fn decl_store_extra_genesis( r: &mut #scrate::runtime_primitives::StorageOverlay, c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay, ) -> std::result::Result<(), String> { + self.assimilate_storage::<#fn_traitinstance> (r, c) } } - }) + }; + + Ok(res) } else { Ok(quote!()) } @@ -557,7 +589,13 @@ fn decl_storage_items( let ident = syn::Ident::new(&name, proc_macro2::Span::call_site()); (name, ident, quote! {#[doc=r"Module instance"]}) }) - .chain(default_instance.clone().map(|ident| (String::new(), ident, quote! {#[doc=r"Default module instance"]}))); + .chain( + default_instance + .clone() + .map(|ident| + (String::new(), ident, quote! {#[doc=r"Default module instance"]}) + ) + ); // Impl Instance trait for instances for (prefix, ident, doc) in instances { @@ -648,15 +686,39 @@ fn impl_store_items( instance: &Option, storage_lines: &ext::Punctuated, ) -> TokenStream2 { - storage_lines.inner.iter().map(|sline| &sline.name) - .fold(TokenStream2::new(), |mut items, name| { + storage_lines.inner + .iter() + .fold(TokenStream2::new(), |mut items, line| { + let name = &line.name; + let type_infos = get_type_infos(&line.storage_type); + let requires_trait = match type_infos.kind { + DeclStorageTypeInfosKind::Simple => { + ext::type_contains_ident(&type_infos.value_type, traitinstance) + }, + DeclStorageTypeInfosKind::Map { key_type, .. } => { + ext::type_contains_ident(&type_infos.value_type, traitinstance) + || ext::type_contains_ident(key_type, traitinstance) + } + DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { + ext::type_contains_ident(&type_infos.value_type, traitinstance) + || ext::type_contains_ident(key1_type, traitinstance) + || ext::type_contains_ident(key2_type, traitinstance) + } + }; + + let struct_trait = if requires_trait { + quote!(#traitinstance,) + } else { + quote!() + }; + items.extend( quote!( - type #name = #name<#traitinstance, #instance>; + type #name = #name<#struct_trait #instance>; ) ); items - }) + }) } fn impl_store_fns( @@ -687,29 +749,52 @@ fn impl_store_fns( let typ = type_infos.typ; let item = match type_infos.kind { DeclStorageTypeInfosKind::Simple => { + let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) { + quote!(#traitinstance,) + } else { + quote!() + }; + quote!{ #( #[ #attrs ] )* pub fn #get_fn() -> #value_type { - <#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage) + <#name<#struct_trait #instance> as #scrate::storage::hashed::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage) } } }, DeclStorageTypeInfosKind::Map { key_type, .. } => { + let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) + || ext::type_contains_ident(key_type, traitinstance) + { + quote!(#traitinstance,) + } else { + quote!() + }; + quote!{ #( #[ #attrs ] )* pub fn #get_fn>(key: K) -> #value_type { - <#name<#traitinstance, #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) + <#name<#struct_trait #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) } } } DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { + let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) + || ext::type_contains_ident(key1_type, traitinstance) + || ext::type_contains_ident(key2_type, traitinstance) + { + quote!(#traitinstance,) + } else { + quote!() + }; + quote!{ pub fn #get_fn(k1: KArg1, k2: KArg2) -> #value_type where KArg1: #scrate::rstd::borrow::Borrow<#key1_type>, KArg2: #scrate::rstd::borrow::Borrow<#key2_type>, { - <#name<#traitinstance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ>> :: get(k1.borrow(), k2.borrow(), &#scrate::storage::RuntimeStorage) + <#name<#struct_trait #instance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ>> :: get(k1.borrow(), k2.borrow(), &#scrate::storage::RuntimeStorage) } } } @@ -817,6 +902,7 @@ fn store_functions_to_metadata ( let str_name = name.to_string(); 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::metadata::StorageFunctionMetadata { name: #scrate::metadata::DecodeDifferent::Encode(#str_name), @@ -831,6 +917,7 @@ fn store_functions_to_metadata ( }, }; items.extend(item); + let def_get = quote! { #[doc(hidden)] pub struct #struct_name<#traitinstance, #instance #bound_instantiable #equal_default_instance>(pub #scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>); @@ -856,6 +943,7 @@ fn store_functions_to_metadata ( } } }; + default_getter_struct_def.extend(def_get); } (default_getter_struct_def, quote!{ diff --git a/srml/support/procedural/tools/src/syn_ext.rs b/srml/support/procedural/tools/src/syn_ext.rs index 3839f133d5419..365c0c8c64af0 100644 --- a/srml/support/procedural/tools/src/syn_ext.rs +++ b/srml/support/procedural/tools/src/syn_ext.rs @@ -22,7 +22,7 @@ use syn::{ visit::{Visit, self}, parse::{Parse, ParseStream, Result}, token::CustomKeyword, Ident, }; -use proc_macro2::TokenStream; +use proc_macro2::{ TokenStream, TokenTree }; use quote::{ToTokens, quote}; use std::iter::once; use srml_support_procedural_tools_derive::{ToTokens, Parse}; @@ -233,14 +233,35 @@ struct ContainsIdent<'a> { result: bool, } -impl<'ast> Visit<'ast> for ContainsIdent<'ast> { - fn visit_ident(&mut self, input: &'ast Ident) { - if input == self.ident { +impl<'ast> ContainsIdent<'ast> { + fn visit_tokenstream(&mut self, stream: TokenStream) { + stream.into_iter().for_each(|tt| + match tt { + TokenTree::Ident(id) => self.visit_ident(&id), + TokenTree::Group(ref group) => self.visit_tokenstream(group.stream()), + _ => {} + } + ) + } + + fn visit_ident(&mut self, ident: &Ident) { + if ident == self.ident { self.result = true; } } } +impl<'ast> Visit<'ast> for ContainsIdent<'ast> { + fn visit_ident(&mut self, input: &'ast Ident) { + self.visit_ident(input); + } + + fn visit_macro(&mut self, input: &'ast syn::Macro) { + self.visit_tokenstream(input.tts.clone()); + visit::visit_macro(self, input); + } +} + /// Check if a `Type` contains the given `Ident`. pub fn type_contains_ident(typ: &syn::Type, ident: &Ident) -> bool { let mut visit = ContainsIdent { diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index aa32c6e81a187..4a61451f84f3d 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -181,7 +181,6 @@ mod tests { use super::*; use codec::Codec; use runtime_io::{with_externalities, Blake2Hasher}; - use runtime_primitives::BuildStorageGen; pub use srml_metadata::{ DecodeDifferent, StorageMetadata, StorageFunctionMetadata, StorageFunctionType, StorageFunctionModifier, @@ -200,9 +199,7 @@ mod tests { use super::Trait; decl_module! { - pub struct Module for enum Call where origin: T::Origin { - - } + pub struct Module for enum Call where origin: T::Origin {} } } use self::module::Module; @@ -226,10 +223,10 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { - GenesisConfig::default().build_storage().unwrap().0.into() + GenesisConfig::default().build_storage::().unwrap().0.into() } - type Map = Data; + type Map = Data; #[test] fn linked_map_basic_insert_remove_should_work() { @@ -312,7 +309,7 @@ mod tests { #[test] fn double_map_basic_insert_remove_remove_prefix_should_work() { with_externalities(&mut new_test_ext(), || { - type DoubleMap = DataDM; + type DoubleMap = DataDM; // initialized during genesis assert_eq!(DoubleMap::get(&15u32, &16u32), 42u64); diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 92e7b6e73efef..59b941b5006e6 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -318,7 +318,7 @@ decl_storage! { add_extra_genesis { config(changes_trie_config): Option; - build(|storage: &mut primitives::StorageOverlay, _: &mut primitives::ChildrenStorageOverlay, config: &GenesisConfig| { + build(|storage: &mut primitives::StorageOverlay, _: &mut primitives::ChildrenStorageOverlay, config: &GenesisConfig| { use parity_codec::Encode; storage.insert(well_known_keys::EXTRINSIC_INDEX.to_vec(), 0u32.encode()); @@ -379,12 +379,12 @@ impl Module { /// Gets extrinsics count. pub fn extrinsic_count() -> u32 { - >::get().unwrap_or_default() + ExtrinsicCount::get().unwrap_or_default() } /// Gets a total length of all executed extrinsics. pub fn all_extrinsics_len() -> u32 { - >::get().unwrap_or_default() + AllExtrinsicsLen::get().unwrap_or_default() } /// Start the execution of a particular block. @@ -402,8 +402,8 @@ impl Module { /// Remove temporary "environment" entries in storage. pub fn finalize() -> T::Header { >::kill(); - >::kill(); - >::kill(); + ExtrinsicCount::kill(); + AllExtrinsicsLen::kill(); let number = >::take(); let parent_hash = >::take(); @@ -493,7 +493,7 @@ impl Module { /// NOTE: This function is called only when the block is being constructed locally. /// `execute_block` doesn't note any extrinsics. pub fn note_extrinsic(encoded_xt: Vec) { - >::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt); + ExtrinsicData::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt); } /// To be called immediately after an extrinsic has been applied. @@ -507,19 +507,19 @@ impl Module { let total_length = encoded_len.saturating_add(Self::all_extrinsics_len()); storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index); - >::put(&total_length); + AllExtrinsicsLen::put(&total_length); } /// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block /// has been called. pub fn note_finished_extrinsics() { let extrinsic_index: u32 = storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap_or_default(); - >::put(extrinsic_index); + ExtrinsicCount::put(extrinsic_index); } /// Remove all extrinsic data and save the extrinsics trie root. pub fn derive_extrinsics() { - let extrinsics = (0..>::get().unwrap_or_default()).map(>::take).collect(); + let extrinsics = (0..ExtrinsicCount::get().unwrap_or_default()).map(ExtrinsicData::take).collect(); let xts_root = extrinsics_data_root::(extrinsics); >::put(xts_root); } From 015ae733b3f22df02008387ec23e236c2b097737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 6 Jun 2019 18:48:48 +0200 Subject: [PATCH 06/14] Get instance test almost working as wanted --- Cargo.lock | 1 + core/sr-primitives/Cargo.toml | 2 + core/sr-primitives/src/lib.rs | 370 ++++++++++++------ node-template/runtime/src/template.rs | 2 +- node/primitives/src/lib.rs | 2 +- srml/assets/src/lib.rs | 2 +- srml/contract/src/lib.rs | 2 +- srml/council/src/motions.rs | 2 +- srml/council/src/seats.rs | 8 +- srml/democracy/src/lib.rs | 6 +- srml/session/src/lib.rs | 4 +- srml/staking/src/lib.rs | 8 +- srml/support/procedural/src/storage/impls.rs | 2 +- .../procedural/src/storage/transformation.rs | 17 +- srml/support/src/event.rs | 116 ++++-- srml/support/src/origin.rs | 132 +++++-- srml/support/src/runtime.rs | 148 +++---- srml/support/test/tests/instance.rs | 122 +++--- srml/support/test/tests/issue2219.rs | 29 +- srml/support/test/tests/system.rs | 2 +- srml/treasury/src/lib.rs | 46 +-- 21 files changed, 644 insertions(+), 379 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62880e324e635..c68e923d43d9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3176,6 +3176,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 1.0.0", diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index 5e4a13f0fef58..0f32940b5a923 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -13,6 +13,7 @@ substrate-primitives = { path = "../primitives", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } log = { version = "0.4", optional = true } +paste = { version = "0.1", optional = true } [dev-dependencies] serde_json = "1.0" @@ -22,6 +23,7 @@ default = ["std"] std = [ "num-traits/std", "serde", + "paste", "log", "rstd/std", "runtime_io/std", diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 963bb112ada46..cf2c54f04be06 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -26,6 +26,10 @@ pub use parity_codec as codec; #[doc(hidden)] pub use serde; +#[cfg(feature = "std")] +#[doc(hidden)] +pub use paste; + #[cfg(feature = "std")] pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay}; @@ -96,13 +100,21 @@ pub trait BuildStorage: Sized { Ok((storage, child_storage)) } /// Assimilate the storage for this module into pre-existing overlays. - fn assimilate_storage(self, storage: &mut StorageOverlay, child_storage: &mut ChildrenStorageOverlay) -> Result<(), String>; + fn assimilate_storage( + self, + storage: &mut StorageOverlay, + child_storage: &mut ChildrenStorageOverlay + ) -> Result<(), String>; } #[cfg(feature = "std")] -pub trait CreateModuleGenesisStorage: Sized { +pub trait CreateModuleGenesisStorage: Sized { /// Create the module genesis storage into the given `storage` and `child_storage`. - fn create_module_genesis_storage(self, storage: &mut StorageOverlay, child_storage: &mut ChildrenStorageOverlay) -> Result<(), String>; + fn create_module_genesis_storage( + self, + storage: &mut StorageOverlay, + child_storage: &mut ChildrenStorageOverlay + ) -> Result<(), String>; } #[cfg(feature = "std")] @@ -110,7 +122,12 @@ impl BuildStorage for StorageOverlay { fn build_storage(self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { Ok((self, Default::default())) } - fn assimilate_storage(self, storage: &mut StorageOverlay, _child_storage: &mut ChildrenStorageOverlay) -> Result<(), String> { + + fn assimilate_storage( + self, + storage: &mut StorageOverlay, + _child_storage: &mut ChildrenStorageOverlay + ) -> Result<(), String> { storage.extend(self); Ok(()) } @@ -485,26 +502,32 @@ pub fn verify_encoded_lazy(sig: &V, item: &T, signe /// Helper macro for `impl_outer_config` #[macro_export] macro_rules! __impl_outer_config_types { + // Generic + Instance ( - $concrete:ident $config:ident $snake:ident < $ignore:ident, $instance:path > $( $rest:tt )* + $concrete:ident $config:ident $snake:ident { $instance:ident } < $ignore:ident >; + $( $rest:tt )* ) => { #[cfg(any(feature = "std", test))] - pub type $config = $snake::GenesisConfig<$concrete, $instance>; - $crate::__impl_outer_config_types! {$concrete $($rest)*} + pub type $config = $snake::GenesisConfig<$concrete, $snake::$instance>; + $crate::__impl_outer_config_types! { $concrete $( $rest )* } }; + // Generic ( - $concrete:ident $config:ident $snake:ident < $ignore:ident > $( $rest:tt )* + $concrete:ident $config:ident $snake:ident < $ignore:ident >; + $( $rest:tt )* ) => { #[cfg(any(feature = "std", test))] pub type $config = $snake::GenesisConfig<$concrete>; - $crate::__impl_outer_config_types! {$concrete $($rest)*} + $crate::__impl_outer_config_types! { $concrete $( $rest )* } }; + // No Generic and maybe Instance ( - $concrete:ident $config:ident $snake:ident $( $rest:tt )* + $concrete:ident $config:ident $snake:ident $( { $instance:ident } )?; + $( $rest:tt )* ) => { #[cfg(any(feature = "std", test))] pub type $config = $snake::GenesisConfig; - __impl_outer_config_types! {$concrete $($rest)*} + $crate::__impl_outer_config_types! { $concrete $( $rest )* } }; ($concrete:ident) => () } @@ -519,30 +542,76 @@ macro_rules! __impl_outer_config_types { macro_rules! impl_outer_config { ( pub struct $main:ident for $concrete:ident { - $( $config:ident => $snake:ident $( < $generic:ident $(, $instance:path)? > )*, )* + $( $config:ident => + $snake:ident $( $instance:ident )? $( <$generic:ident> )*, )* } ) => { - $crate::__impl_outer_config_types! { $concrete $( $config $snake $( < $generic $(, $instance)? > )* )* } - #[cfg(any(feature = "std", test))] - #[derive($crate::serde::Serialize, $crate::serde::Deserialize)] - #[serde(rename_all = "camelCase")] - #[serde(deny_unknown_fields)] - pub struct $main { - $( - pub $snake: Option<$config>, - )* + $crate::__impl_outer_config_types! { + $concrete $( $config $snake $( { $instance } )? $( <$generic> )*; )* } - #[cfg(any(feature = "std", test))] - impl $crate::BuildStorage for $main { - fn assimilate_storage(self, top: &mut $crate::StorageOverlay, children: &mut $crate::ChildrenStorageOverlay) -> ::std::result::Result<(), String> { + + $crate::paste::item! { + #[cfg(any(feature = "std", test))] + #[derive($crate::serde::Serialize, $crate::serde::Deserialize)] + #[serde(rename_all = "camelCase")] + #[serde(deny_unknown_fields)] + pub struct $main { $( - if let Some(extra) = self.$snake { - extra.assimilate_storage(top, children)?; - } + pub [< $snake $(_ $instance )? >]: Option<$config>, )* - Ok(()) + } + #[cfg(any(feature = "std", test))] + impl $crate::BuildStorage for $main { + fn assimilate_storage( + self, + top: &mut $crate::StorageOverlay, + children: &mut $crate::ChildrenStorageOverlay + ) -> std::result::Result<(), String> { + $( + if let Some(extra) = self.[< $snake $(_ $instance )? >] { + $crate::impl_outer_config! { + @CALL_FN + $concrete; + $snake; + $( $instance )?; + extra; + top; + children; + } + } + )* + Ok(()) + } } } + }; + (@CALL_FN + $runtime:ident; + $module:ident; + $instance:ident; + $extra:ident; + $top:ident; + $children:ident; + ) => { + $crate::CreateModuleGenesisStorage::<$runtime, $module::$instance>::create_module_genesis_storage( + $extra, + $top, + $children, + )?; + }; + (@CALL_FN + $runtime:ident; + $module:ident; + ; + $extra:ident; + $top:ident; + $children:ident; + ) => { + $crate::CreateModuleGenesisStorage::<$runtime, $module::DefaultInstance>::create_module_genesis_storage( + $extra, + $top, + $children, + )?; } } @@ -566,7 +635,7 @@ macro_rules! impl_outer_log { ( $(#[$attr:meta])* pub enum $name:ident ($internal:ident: DigestItem<$( $genarg:ty ),*>) for $trait:ident { - $( $module:ident $(<$instance:path>)? ( $( $sitem:ident ),* ) ),* + $( $module:ident $( <$instance:ident> )? ( $( $sitem:ident ),* ) ),* } ) => { /// Wrapper for all possible log entries for the `$trait` runtime. Provides binary-compatible @@ -577,107 +646,190 @@ macro_rules! impl_outer_log { #[allow(non_camel_case_types)] pub struct $name($internal); - /// All possible log entries for the `$trait` runtime. `Encode`/`Decode` implementations - /// are auto-generated => it is not binary-compatible with `generic::DigestItem`. - #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] - #[cfg_attr(feature = "std", derive(Debug, $crate::serde::Serialize))] - $(#[$attr])* - #[allow(non_camel_case_types)] - pub enum InternalLog { - $( - $module($module::Log<$trait $(, $instance)? >), - )* - } + $crate::paste::item! { + /// All possible log entries for the `$trait` runtime. `Encode`/`Decode` implementations + /// are auto-generated => it is not binary-compatible with `generic::DigestItem`. + #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] + #[cfg_attr(feature = "std", derive(Debug, $crate::serde::Serialize))] + $(#[$attr])* + #[allow(non_camel_case_types)] + pub enum InternalLog { + $( + [< $module $( _ $instance )? >] ($module::Log<$trait $(, $module::$instance)? >), + )* + } - impl $name { - /// Try to convert `$name` into `generic::DigestItemRef`. Returns Some when - /// `self` is a 'system' log && it has been marked as 'system' in macro call. - /// Otherwise, None is returned. - #[allow(unreachable_patterns)] - fn dref<'a>(&'a self) -> Option<$crate::generic::DigestItemRef<'a, $($genarg),*>> { - match self.0 { - $($( - $internal::$module($module::RawLog::$sitem(ref v)) => - Some($crate::generic::DigestItemRef::$sitem(v)), - )*)* - _ => None, + impl $name { + /// Try to convert `$name` into `generic::DigestItemRef`. Returns Some when + /// `self` is a 'system' log && it has been marked as 'system' in macro call. + /// Otherwise, None is returned. + #[allow(unreachable_patterns)] + fn dref<'a>(&'a self) -> Option<$crate::generic::DigestItemRef<'a, $($genarg),*>> { + match &self.0 { + $( + $internal::[< $module $( _ $instance )? >] (item) => { + match item { + $( + $module::RawLog::$sitem(ref v) => + Some($crate::generic::DigestItemRef::$sitem(v)), + )* + _ => None, + } + } + )* + _ => None, + } } } - } - impl $crate::traits::DigestItem for $name { - type Hash = <$crate::generic::DigestItem<$($genarg),*> as $crate::traits::DigestItem>::Hash; - type AuthorityId = <$crate::generic::DigestItem<$($genarg),*> as $crate::traits::DigestItem>::AuthorityId; + impl $crate::traits::DigestItem for $name { + type Hash = <$crate::generic::DigestItem<$($genarg),*> + as $crate::traits::DigestItem>::Hash; + type AuthorityId = <$crate::generic::DigestItem<$($genarg),*> + as $crate::traits::DigestItem>::AuthorityId; - fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> { - self.dref().and_then(|dref| dref.as_authorities_change()) - } + fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> { + self.dref().and_then(|dref| dref.as_authorities_change()) + } - fn as_changes_trie_root(&self) -> Option<&Self::Hash> { - self.dref().and_then(|dref| dref.as_changes_trie_root()) + fn as_changes_trie_root(&self) -> Option<&Self::Hash> { + self.dref().and_then(|dref| dref.as_changes_trie_root()) + } } - } - impl From<$crate::generic::DigestItem<$($genarg),*>> for $name { - /// Converts `generic::DigestItem` into `$name`. If `generic::DigestItem` represents - /// a system item which is supported by the runtime, it is returned. - /// Otherwise we expect a `Other` log item. Trying to convert from anything other - /// will lead to panic in runtime, since the runtime does not supports this 'system' - /// log item. - #[allow(unreachable_patterns)] - fn from(gen: $crate::generic::DigestItem<$($genarg),*>) -> Self { - match gen { - $($( - $crate::generic::DigestItem::$sitem(value) => - $name($internal::$module($module::RawLog::$sitem(value))), - )*)* - _ => gen.as_other() - .and_then(|value| $crate::codec::Decode::decode(&mut &value[..])) - .map($name) - .expect("not allowed to fail in runtime"), + impl From<$crate::generic::DigestItem<$($genarg),*>> for $name { + /// Converts `generic::DigestItem` into `$name`. If `generic::DigestItem` represents + /// a system item which is supported by the runtime, it is returned. + /// Otherwise we expect a `Other` log item. Trying to convert from anything other + /// will lead to panic in runtime, since the runtime does not supports this 'system' + /// log item. + #[allow(unreachable_patterns)] + fn from(gen: $crate::generic::DigestItem<$($genarg),*>) -> Self { + $crate::impl_outer_log! { + @GEN_FROM_DIGESTITEM_MATCH + gen + $name + $internal + {} + $( + $module $( $instance )? { $( $sitem ),* }; + )* + } } } - } - impl $crate::codec::Decode for $name { - /// `generic::DigestItem` binary compatible decode. - fn decode(input: &mut I) -> Option { - let gen: $crate::generic::DigestItem<$($genarg),*> = - $crate::codec::Decode::decode(input)?; - Some($name::from(gen)) + impl $crate::codec::Decode for $name { + /// `generic::DigestItem` binary compatible decode. + fn decode(input: &mut I) -> Option { + let gen: $crate::generic::DigestItem<$($genarg),*> = + $crate::codec::Decode::decode(input)?; + Some($name::from(gen)) + } } - } - impl $crate::codec::Encode for $name { - /// `generic::DigestItem` binary compatible encode. - fn encode(&self) -> Vec { - match self.dref() { - Some(dref) => dref.encode(), - None => { - let gen: $crate::generic::DigestItem<$($genarg),*> = - $crate::generic::DigestItem::Other(self.0.encode()); - gen.encode() - }, + impl $crate::codec::Encode for $name { + /// `generic::DigestItem` binary compatible encode. + fn encode(&self) -> Vec { + match self.dref() { + Some(dref) => dref.encode(), + None => { + let gen: $crate::generic::DigestItem<$($genarg),*> = + $crate::generic::DigestItem::Other(self.0.encode()); + gen.encode() + }, + } } } - } - $( - impl From<$module::Log<$trait $(, $instance)? >> for $name { - /// Converts single module log item into `$name`. - fn from(x: $module::Log<$trait $(, $instance)? >) -> Self { - $name(x.into()) + $( + impl From<$module::Log<$trait $(, $module::$instance )? >> for $name { + /// Converts single module log item into `$name`. + fn from(x: $module::Log<$trait $(, $module::$instance )? >) -> Self { + $name(x.into()) + } } - } - impl From<$module::Log<$trait $(, $instance)? >> for InternalLog { - /// Converts single module log item into `$internal`. - fn from(x: $module::Log<$trait $(, $instance)? >) -> Self { - InternalLog::$module(x) + impl From<$module::Log<$trait $(, $module::$instance )? >> for InternalLog { + /// Converts single module log item into `$internal`. + fn from(x: $module::Log<$trait $(, $module::$instance )? >) -> Self { + InternalLog::[< $module $( _ $instance )? >](x) + } } + )* + } + }; + // With Instance + (@GEN_FROM_DIGESTITEM_MATCH + $gen:ident + $name:ident + $internal:ident + { $( $generated:tt )* } + $module:ident $instance:ident { $( $sitem:ident ),* }; + $( $impl_outer_log_match_instance_rest:tt )* + ) => { + $crate::impl_outer_log! { + @GEN_FROM_DIGESTITEM_MATCH + $gen + $name + $internal + { + $( $generated )* + $( + $crate::generic::DigestItem::$sitem(value) => + $name( + $internal::[< $module _ $instance >]( + $module::RawLog::$sitem(value) + ) + ), + )* } - )* + $( $impl_outer_log_match_instance_rest )* + } }; + // Without Instance + (@GEN_FROM_DIGESTITEM_MATCH + $gen:ident + $name:ident + $internal:ident + { $( $generated:tt )* } + $module:ident { $( $sitem:ident ),* }; + $( $impl_outer_log_match_rest:tt )* + ) => { + $crate::impl_outer_log! { + @GEN_FROM_DIGESTITEM_MATCH + $gen + $name + $internal + { + $( $generated )* + $( + $crate::generic::DigestItem::$sitem(value) => + $name( + $internal::$module( + $module::RawLog::$sitem(value) + ) + ), + )* + } + $( $impl_outer_log_match_rest )* + } + }; + // Final step, generate match + (@GEN_FROM_DIGESTITEM_MATCH + $gen:ident + $name:ident + $internal:ident + { $( $generated:tt )* } + ) => { + match $gen { + $( $generated )* + _ => $gen.as_other() + .and_then(|value| $crate::codec::Decode::decode(&mut &value[..])) + .map($name) + .expect("not allowed to fail in runtime"), + } + }; + } /// Simple blob to hold an extrinsic without committing to its format and ensure it is serialized diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index 636ee1ac09506..5b244d287cda9 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -46,7 +46,7 @@ decl_module! { // TODO: Code to execute when something calls this. // For example: the following line stores the passed in u32 in the storage - >::put(something); + Something::put(something); // here we are raising the Something event Self::deposit_event(RawEvent::SomethingStored(something, who)); diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 0d8906c47df81..d5f8cc3d96e6c 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -59,7 +59,7 @@ pub type Hash = primitives::H256; pub type Timestamp = u64; /// Header type. -/// +/// pub type Header = generic::Header>; /// Block type. pub type Block = generic::Block; diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index 3f7c1b3efc153..2c1b9340d6463 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -266,7 +266,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. fn new_test_ext() -> runtime_io::TestExternalities { - system::GenesisConfig::::default().build_storage().unwrap().0.into() + system::GenesisConfig::default().build_storage().unwrap().0.into() } #[test] diff --git a/srml/contract/src/lib.rs b/srml/contract/src/lib.rs index a5fa62f7ecfef..490e3878a0497 100644 --- a/srml/contract/src/lib.rs +++ b/srml/contract/src/lib.rs @@ -155,7 +155,7 @@ where fn trie_id(account_id: &T::AccountId) -> TrieId { // Note that skipping a value due to error is not an issue here. // We only need uniqueness, not sequence. - let new_seed = >::mutate(|v| v.wrapping_add(1)); + let new_seed = AccountCounter::mutate(|v| v.wrapping_add(1)); let mut buf = Vec::new(); buf.extend_from_slice(account_id.as_ref()); diff --git a/srml/council/src/motions.rs b/srml/council/src/motions.rs index 3bbe463780c46..ac16a355a3f99 100644 --- a/srml/council/src/motions.rs +++ b/srml/council/src/motions.rs @@ -80,7 +80,7 @@ decl_module! { Self::deposit_event(RawEvent::Executed(proposal_hash, ok)); } else { let index = Self::proposal_count(); - >::mutate(|i| *i += 1); + ProposalCount::mutate(|i| *i += 1); >::mutate(|proposals| proposals.push(proposal_hash)); >::insert(proposal_hash, *proposal); >::insert(proposal_hash, (index, threshold, vec![who.clone()], vec![])); diff --git a/srml/council/src/seats.rs b/srml/council/src/seats.rs index 9ace6227da636..6bb0be5ec9440 100644 --- a/srml/council/src/seats.rs +++ b/srml/council/src/seats.rs @@ -210,7 +210,7 @@ decl_module! { candidates[slot] = who; } >::put(candidates); - >::put(count as u32 + 1); + CandidateCount::put(count as u32 + 1); } /// Claim that `signed` is one of the top Self::carry_count() + current_vote().1 candidates. @@ -272,7 +272,7 @@ decl_module! { /// election when they expire. If more, then a new vote will be started if one is not already /// in progress. fn set_desired_seats(#[compact] count: u32) { - >::put(count); + DesiredSeats::put(count); } /// Remove a particular member. A tally will happen instantly (if not already in a presentation @@ -561,8 +561,8 @@ impl Module { Self::deposit_event(RawEvent::TallyFinalized(incoming, outgoing)); >::put(new_candidates); - >::put(count); - >::put(Self::vote_index() + 1); + CandidateCount::put(count); + VoteCount::put(Self::vote_index() + 1); Ok(()) } } diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 4bd7ad60aa1b6..43b143ddaf53b 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -97,7 +97,7 @@ decl_module! { .map_err(|_| "proposer's balance too low")?; let index = Self::public_prop_count(); - >::put(index + 1); + PublicPropCount::put(index + 1); >::insert(index, (value, vec![who.clone()])); let mut props = Self::public_props(); @@ -410,7 +410,7 @@ impl Module { Err("Cannot inject a referendum that ends earlier than preceeding referendum")? } - >::put(ref_index + 1); + ReferendumCount::put(ref_index + 1); >::insert(ref_index, ReferendumInfo { end, proposal, threshold, delay }); Self::deposit_event(RawEvent::Started(ref_index, threshold)); Ok(ref_index) @@ -485,7 +485,7 @@ impl Module { } else { Self::deposit_event(RawEvent::NotPassed(index)); } - >::put(index + 1); + NextTally::put(index + 1); Ok(()) } diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 255bb4f647416..b8476f6412c08 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -238,7 +238,7 @@ impl Module { // INTERNAL API (available to other runtime modules) /// Forces a new session, no origin. pub fn apply_force_new_session(apply_rewards: bool) -> Result { - >::put(apply_rewards); + ForcingNewSession::put(apply_rewards); Ok(()) } @@ -256,7 +256,7 @@ impl Module { // new set. // Check block number and call `rotate_session` if necessary. let is_final_block = ((block_number - Self::last_length_change()) % Self::length()).is_zero(); - let (should_end_session, apply_rewards) = >::take() + let (should_end_session, apply_rewards) = ForcingNewSession::take() .map_or((is_final_block, is_final_block), |apply_rewards| (true, apply_rewards)); if should_end_session { Self::rotate_session(is_final_block, apply_rewards); diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index cc3c708bb2843..6093a73228ab4 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -721,7 +721,7 @@ decl_module! { /// The ideal number of validators. fn set_validator_count(#[compact] new: u32) { - >::put(new); + ValidatorCount::put(new); } /// Force there to be a new era. This also forces a new session immediately after. @@ -732,7 +732,7 @@ decl_module! { /// Set the offline slash grace period. fn set_offline_slash_grace(#[compact] new: u32) { - >::put(new); + OfflineSlashGrace::put(new); } /// Set the validators who cannot be slashed (if any). @@ -757,7 +757,7 @@ decl_event!( impl Module { /// Just force_new_era without origin check. fn apply_force_new_era(apply_rewards: bool) -> Result { - >::put(()); + ForcingNewEra::put(()); >::apply_force_new_session(apply_rewards) } @@ -874,7 +874,7 @@ impl Module { } let session_index = >::current_index(); - if >::take().is_some() + if ForcingNewEra::take().is_some() || ((session_index - Self::last_era_length_change()) % Self::sessions_per_era()).is_zero() { Self::new_era(); diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index 3d04baf4e13d1..5126252141866 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -369,7 +369,7 @@ impl<'a, I: Iterator> Impls<'a, I> { pub _data: #phantom_data, } - impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #struct_trait> + impl<'a, S: #scrate::HashedStorage<#scrate::#hasher>, #impl_trait> Iterator for Enumerator<'a, S, #kty, (#typ, #trait_and_instance)> { type Item = (#kty, #typ); diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 0fa361cb95201..e72d23fcb62e6 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -179,8 +179,6 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream { #extra_genesis }; - println!("{}", expanded); - expanded.into() } @@ -428,7 +426,7 @@ fn decl_store_extra_genesis( quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), quote!(<#traitinstance, #instance>), - quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), + quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), ) } else { // do not even need type parameter @@ -436,16 +434,21 @@ fn decl_store_extra_genesis( quote!(), quote!(), quote!(), - quote!(<#traitinstance: #traittype>), + quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), ) }; let (fn_generic, fn_traitinstance) = if !is_trait_needed && assimilate_require_generic { - (quote!( <#traitinstance: #traittype> ), quote!( #traitinstance )) + ( + quote!( <#traitinstance: #traittype, #instance #bound_instantiable> ), + quote!( #traitinstance, #instance ) + ) } else { (quote!(), quote!()) }; + let impl_trait = quote!(CreateModuleGenesisStorage<#traitinstance, #instance>); + let res = quote!{ #[derive(#scrate::Serialize, #scrate::Deserialize)] #[cfg(feature = "std")] @@ -501,7 +504,9 @@ fn decl_store_extra_genesis( } #[cfg(feature = "std")] - impl#build_storage_impl #scrate::runtime_primitives::CreateModuleGenesisStorage<#traitinstance> for GenesisConfig#sparam { + impl#build_storage_impl #scrate::runtime_primitives::#impl_trait + for GenesisConfig#sparam + { fn create_module_genesis_storage( self, r: &mut #scrate::runtime_primitives::StorageOverlay, diff --git a/srml/support/src/event.rs b/srml/support/src/event.rs index 739c9f660c2b9..b64927b40d963 100644 --- a/srml/support/src/event.rs +++ b/srml/support/src/event.rs @@ -321,17 +321,15 @@ macro_rules! __events_to_metadata { } /// Constructs an Event type for a runtime. This is usually called automatically by the -/// construct_runtime macro. See also __create_decl_macro. +/// construct_runtime macro. #[macro_export] macro_rules! impl_outer_event { - // Macro transformations (to convert invocations with incomplete parameters to the canonical // form) - ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident { - $( $rest:tt $( <$t:ident $(, $rest_instance:path)? > )*, )* + $( $rest_event_without_system:tt )* } ) => { $crate::impl_outer_event!( @@ -339,14 +337,14 @@ macro_rules! impl_outer_event { $name; $runtime; system; - Modules { $( $rest $(<$t $(, $rest_instance)? >)*, )* }; + Modules { $( $rest_event_without_system )* }; ; ); }; ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident where system = $system:ident { - $( $rest:tt $( <$t:ident $(, $rest_instance:path)? > )*, )* + $( $rest_event_with_system:tt )* } ) => { $crate::impl_outer_event!( @@ -354,30 +352,74 @@ macro_rules! impl_outer_event { $name; $runtime; $system; - Modules { $( $rest $(<$t $(, $rest_instance)? >)*, )* }; + Modules { $( $rest_event_with_system )* }; ; ); }; + // Generic + Instance + ( + $(#[$attr:meta])*; + $name:ident; + $runtime:ident; + $system:ident; + Modules { + $module:ident $instance:ident, + $( $rest_event_generic_instance:tt )* + }; + $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; + ) => { + $crate::impl_outer_event!( + $( #[$attr] )*; + $name; + $runtime; + $system; + Modules { $( $rest_event_generic_instance )* }; + $( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event<$runtime>{ $instance },; + ); + }; + // Instance + ( + $(#[$attr:meta])*; + $name:ident; + $runtime:ident; + $system:ident; + Modules { + $module:ident $instance:ident, + $( $rest_event_instance:tt )* + }; + $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; + ) => { + $crate::impl_outer_event!( + $( #[$attr] )*; + $name; + $runtime; + $system; + Modules { $( $rest_event_instance )* }; + $( $module_name::Event $( <$generic_param> )* $( { $generic_instance } )?, )* $module::Event { $instance },; + ); + }; + // Generic ( $(#[$attr:meta])*; $name:ident; $runtime:ident; $system:ident; Modules { - $module:ident, - $( $rest:tt $( <$t:ident $(, $rest_instance:path)? > )*, )* + $module:ident, + $( $rest_event_generic:tt )* }; - $( $module_name:ident::Event $( <$generic_param:ident $(, $generic_instance:path)? > )*, )*; + $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; ) => { $crate::impl_outer_event!( $( #[$attr] )*; $name; $runtime; $system; - Modules { $( $rest $(<$t $(, $rest_instance)? >)*, )* }; - $( $module_name::Event $( <$generic_param $(, $generic_instance)? > )*, )* $module::Event<$runtime $(, $instance)? >,; + Modules { $( $rest_event_generic )* }; + $( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event<$runtime>,; ); }; + // No Generic and no Instance ( $(#[$attr:meta])*; $name:ident; @@ -385,30 +427,30 @@ macro_rules! impl_outer_event { $system:ident; Modules { $module:ident, - $( $rest:tt )* + $( $rest_event_no_generic_no_instance:tt )* }; - $( $module_name:ident::Event $( <$generic_param:ident $(, $generic_instance:path)? > )*, )*; + $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; ) => { $crate::impl_outer_event!( $( #[$attr] )*; $name; $runtime; $system; - Modules { $( $rest )* }; - $( $module_name::Event $( <$generic_param $(, $generic_instance)? > )*, )* $module::Event,; + Modules { $( $rest_event_no_generic_no_instance )* }; + $( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event,; ); }; // The main macro expansion that actually renders the Event enum code. - ( $(#[$attr:meta])*; $name:ident; $runtime:ident; $system:ident; Modules {}; - $( $module_name:ident::Event $( <$generic_param:ident $(, $generic_instance:path)? > )*, )*; + $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; ) => { + $crate::paste::item! { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode)] #[cfg_attr(feature = "std", derive(Debug))] @@ -417,7 +459,9 @@ macro_rules! impl_outer_event { pub enum $name { system($system::Event), $( - $module_name( $module_name::Event $( <$generic_param $(, $generic_instance)? > )* ), + [< $module_name $(_ $generic_instance )? >]( + $module_name::Event < $( $generic_param )? $(, $module_name::$generic_instance )? > + ), )* } impl From<$system::Event> for $name { @@ -426,17 +470,22 @@ macro_rules! impl_outer_event { } } $( - impl From<$module_name::Event $( <$generic_param $(, $generic_instance)? > )*> for $name { - fn from(x: $module_name::Event $( <$generic_param $(, $generic_instance)? > )*) -> Self { - $name::$module_name(x) + impl From<$module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >> for $name { + fn from(x: $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >) -> Self { + $name::[< $module_name $(_ $generic_instance )? >](x) } } )* + } $crate::__impl_outer_event_json_metadata!( $runtime; $name; $system; - $( $module_name::Event $( <$generic_param $(, $generic_instance)? > )*, )*; + $( + $module_name::Event + < $( $generic_param )? $(, $module_name::$generic_instance )? > + $( $generic_instance )?, + )*; ); } } @@ -448,7 +497,7 @@ macro_rules! __impl_outer_event_json_metadata { $runtime:ident; $event_name:ident; $system:ident; - $( $module_name:ident::Event $( <$generic_param:ident $(, $generic_instance:path)? > )*, )*; + $( $module_name:ident::Event < $( $generic_params:path ),* > $( $instance:ident )?, )*; ) => { impl $runtime { #[allow(dead_code)] @@ -461,7 +510,7 @@ macro_rules! __impl_outer_event_json_metadata { , ( stringify!($module_name), $crate::event::FnEncode( - $module_name::Event $( ::<$generic_param $(, $generic_instance)? > )* ::metadata + $module_name::Event ::< $( $generic_params ),* > ::metadata ) ) )* @@ -472,14 +521,17 @@ macro_rules! __impl_outer_event_json_metadata { pub fn __module_events_system() -> &'static [$crate::event::EventMetadata] { system::Event::metadata() } - $( - #[allow(dead_code)] - $crate::paste::item!{ - pub fn [< __module_events_ $module_name >] () -> &'static [$crate::event::EventMetadata] { - $module_name::Event $( ::<$generic_param $(, $generic_instance)? > )* ::metadata() + + $crate::paste::item! { + $( + #[allow(dead_code)] + pub fn [< __module_events_ $module_name $( _ $instance )? >] () -> + &'static [$crate::event::EventMetadata] + { + $module_name::Event ::< $( $generic_params ),* > ::metadata() } - } - )* + )* + } } } } diff --git a/srml/support/src/origin.rs b/srml/support/src/origin.rs index 2d97f218e0958..1ef922ce16a12 100644 --- a/srml/support/src/origin.rs +++ b/srml/support/src/origin.rs @@ -28,20 +28,20 @@ macro_rules! impl_outer_origin { ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident { - $( $module:ident $( <$generic:ident $(, $instance:path )? > )? ),* $(,)? + $( rest:tt )* } ) => { $crate::impl_outer_origin! { $(#[$attr])* pub enum $name for $runtime where system = system { - $( $module $( <$generic $(, $instance )? > )?, )* + $( $rest )* } } }; ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident where system = $system:ident { - $( $module:ident $( <$generic:ident $(, $instance:path )?> )? ),* $(,)? + $( $rest:tt )* } ) => { $crate::impl_outer_origin!( @@ -49,19 +49,40 @@ macro_rules! impl_outer_origin { $name; $runtime; $system; - Modules { $( $module $( <$generic $(, $instance )? > )*, )* }; + Modules { $( $rest )* }; ); }; - // Replace generic param with runtime + // Generic + Instance + ( + $(#[$attr:meta])*; + $name:ident; + $runtime:ident; + $system:ident; + Modules { + $module:ident $instance:ident , + $( $rest_module:tt )* + }; + $( $parsed:tt )* + ) => { + $crate::impl_outer_origin!( + $( #[$attr] )*; + $name; + $runtime; + $system; + Modules { $( $rest_module )* }; + $( $parsed )* $module <$runtime> { $instance }, + ); + }; + // Instance ( $(#[$attr:meta])*; $name:ident; $runtime:ident; $system:ident; Modules { - $module:ident $( )?, + $module:ident $instance:ident, $( $rest_module:tt )* }; $( $parsed:tt )* @@ -72,33 +93,80 @@ macro_rules! impl_outer_origin { $runtime; $system; Modules { $( $rest_module )* }; - $( $parsed )* $module $( <$runtime $(, $instance )? > )?, + $( $parsed )* $module { $instance }, ); }; - // The main macro expansion that actually renders the Origin enum code. + // Generic + ( + $(#[$attr:meta])*; + $name:ident; + $runtime:ident; + $system:ident; + Modules { + $module:ident , + $( $rest_module:tt )* + }; + $( $parsed:tt )* + ) => { + $crate::impl_outer_origin!( + $( #[$attr] )*; + $name; + $runtime; + $system; + Modules { $( $rest_module )* }; + $( $parsed )* $module <$runtime>, + ); + }; + // No Generic and no Instance + ( + $(#[$attr:meta])*; + $name:ident; + $runtime:ident; + $system:ident; + Modules { + $module:ident, + $( $rest_module:tt )* + }; + $( $parsed:tt )* + ) => { + $crate::impl_outer_origin!( + $( #[$attr] )*; + $name; + $runtime; + $system; + Modules { $( $rest_module )* }; + $( $parsed )* $module <$runtime>, + ); + }; + + // The main macro expansion that actually renders the Origin enum code. ( $(#[$attr:meta])*; $name:ident; $runtime:ident; $system:ident; Modules { }; - $( $module:ident $( <$generic_param:ident $(, $generic_instance:path )? > )* ,)* + $( $module:ident $( < $generic:ident > )? $( { $generic_instance:ident } )? ,)* ) => { - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug))] - $(#[$attr])* - #[allow(non_camel_case_types)] - pub enum $name { - system($system::Origin<$runtime>), - $( - $module($module::Origin $( <$generic_param $(, $generic_instance )? > )* ), - )* - #[allow(dead_code)] - Void($crate::Void) + $crate::paste::item! { + // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. + #[derive(Clone, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Debug))] + $(#[$attr])* + #[allow(non_camel_case_types)] + pub enum $name { + system($system::Origin<$runtime>), + $( + [< $module $( _ $generic_instance )? >] + ($module::Origin < $( $generic, )? $( $module::$generic_instance )? > ), + )* + #[allow(dead_code)] + Void($crate::Void) + } } + #[allow(dead_code)] impl $name { pub const INHERENT: Self = $name::system($system::RawOrigin::Inherent); @@ -127,17 +195,19 @@ macro_rules! impl_outer_origin { } } $( - impl From<$module::Origin $( <$generic_param $(, $generic_instance )? > )*> for $name { - fn from(x: $module::Origin $( <$generic_param $(, $generic_instance )? > )*) -> Self { - $name::$module(x) + $crate::paste::item! { + impl From<$module::Origin < $( $generic )? $(, $module::$generic_instance )? > > for $name { + fn from(x: $module::Origin < $( $generic )? $(, $module::$generic_instance )? >) -> Self { + $name::[< $module $( _ $generic_instance )? >](x) + } } - } - impl Into )*>> for $name { - fn into(self) -> Option<$module::Origin $( <$generic_param $(, $generic_instance )? > )*> { - if let $name::$module(l) = self { - Some(l) - } else { - None + impl Into>> for $name { + fn into(self) -> Option<$module::Origin < $( $generic )? $(, $module::$generic_instance )? > > { + if let $name::[< $module $( _ $generic_instance )? >](l) = self { + Some(l) + } else { + None + } } } } diff --git a/srml/support/src/runtime.rs b/srml/support/src/runtime.rs index 4f402da8d5b54..adb01cad180a5 100644 --- a/srml/support/src/runtime.rs +++ b/srml/support/src/runtime.rs @@ -59,9 +59,9 @@ /// - `Module` /// - `Call` /// - `Storage` -/// - `Event` or `Event` (if the event is generic) or `Event` (if also over instance) -/// - `Origin` or `Origin` (if the origin is generic) or `Origin` (if also over instance) -/// - `Config` or `Config` (if the config is generic) or `Config` (if also over instance) +/// - `Event` or `Event` (if the event is generic) +/// - `Origin` or `Origin` (if the origin is generic) +/// - `Config` or `Config` (if the config is generic) /// - `Log( $(IDENT),* )` /// - `Inherent $( (CALL) )*` - If the module provides/can check inherents. The optional parameter /// is for modules that use a `Call` from a different module as @@ -99,50 +99,28 @@ macro_rules! construct_runtime { $( $rest )* ); }; + // No modules given, expand to the default module set. ( { $( $preset:tt )* }; { $( $expanded:tt )* }; $name:ident: $module:ident, $( $rest:tt )* - ) => { - $crate::construct_runtime!( - { $( $preset )* }; - { $( $expanded )* $name: $module::{Module, Call, Storage, Event, Config}, }; - $( $rest )* - ); - }; - ( - { $( $preset:tt )* }; - { $( $expanded:tt )* }; - $name:ident: $module:ident::{ - default, - $( - $modules:ident - $( <$modules_generic:ident $(, $modules_instance:ident)?> )* - $( ( $( $modules_args:ident ),* ) )* - ),* - }, - $( $rest:tt )* ) => { $crate::construct_runtime!( { $( $preset )* }; { $( $expanded )* - $name: $module::{ - Module, Call, Storage, Event, Config, - $( - $modules $( <$modules_generic $(, $modules_instance)?> )* - $( ( $( $modules_args ),* ) )* - ),* - }, + $name: $module::{Module, Call, Storage, Event, Config}, }; $( $rest )* ); }; + // `default` identifier given, expand to default + given extra modules ( { $( $preset:tt )* }; { $( $expanded:tt )* }; $name:ident: $module:ident::{ + default, $( $modules:ident $( <$modules_generic:ident> )* @@ -156,6 +134,7 @@ macro_rules! construct_runtime { { $( $expanded )* $name: $module::{ + Module, Call, Storage, Event, Config, $( $modules $( <$modules_generic> )* $( ( $( $modules_args ),* ) )* @@ -165,13 +144,14 @@ macro_rules! construct_runtime { $( $rest )* ); }; - ( // Instance module: we indicate the generic instance `I` with the full instance path + // Take all modules as given by the user. + ( { $( $preset:tt )* }; { $( $expanded:tt )* }; - $name:ident: $module:ident ::< $module_instance:ident >::{ + $name:ident: $module:ident :: $( < $module_instance:ident >:: )? { $( $modules:ident - $( <$modules_generic:ident $(, $modules_instance:ident )?> )* + $( <$modules_generic:ident> )* $( ( $( $modules_args:ident ),* ) )* ),* }, @@ -181,9 +161,9 @@ macro_rules! construct_runtime { { $( $preset )* }; { $( $expanded )* - $name: $module::<$module_instance>::{ + $name: $module:: $( < $module_instance >:: )? { $( - $modules $( <$modules_generic $(, $modules_instance=$module::$module_instance)?> )* + $modules $( <$modules_generic> )* $( ( $( $modules_args ),* ) )* ),* }, @@ -191,9 +171,7 @@ macro_rules! construct_runtime { $( $rest )* ); }; - // The main macro expansion that actually renders the Runtime code. - ( { $runtime:ident; @@ -207,7 +185,7 @@ macro_rules! construct_runtime { $name:ident: $module:ident :: $( < $module_instance:ident >:: )? { $( $modules:ident - $( <$modules_generic:ident $(, I=$modules_instance:path)?> )* + $( <$modules_generic:ident> )* $( ( $( $modules_args:ident ),* ) )* ),* }, @@ -223,19 +201,20 @@ macro_rules! construct_runtime { impl $crate::runtime_primitives::traits::GetRuntimeBlockType for $runtime { type RuntimeBlock = $block; } - $crate::__decl_instance_import!( - $( $( $module < $module_instance > )? )* - ); $crate::__decl_outer_event!( $runtime; $( - $name: $module:: $( < $module_instance >:: )? { $( $modules $( <$modules_generic $(, $modules_instance)?> )* ),* } + $name: $module:: $( < $module_instance >:: )? { + $( $modules $( <$modules_generic> )* ),* + } ),* ); $crate::__decl_outer_origin!( $runtime; $( - $name: $module:: $( < $module_instance >:: )? { $( $modules $( <$modules_generic $(, $modules_instance)?> )* ),* } + $name: $module:: $( < $module_instance >:: )? { + $( $modules $( <$modules_generic> )* ),* + } ),* ); $crate::__decl_all_modules!( @@ -273,7 +252,7 @@ macro_rules! construct_runtime { {}; $( $name: $module:: $( < $module_instance >:: )? { - $( $modules $( <$modules_generic $(, $modules_instance)?> )* ),* + $( $modules $( <$modules_generic> )* ),* }, )* ); @@ -308,7 +287,7 @@ macro_rules! __create_decl_macro { ( $runtime:ident; $d( $name:ident : $module:ident:: $d( < $module_instance:ident >:: )? { - $d( $modules:ident $d( <$modules_generic:ident $d(, $modules_instance:path)?> ),* ),* + $d( $modules:ident $d( <$modules_generic:ident> ),* ),* }),* ) => { $d crate::$macro_name!(@inner @@ -317,7 +296,7 @@ macro_rules! __create_decl_macro { {}; $d( $name: $module:: $d( < $module_instance >:: )? { - $d( $modules $d( <$modules_generic $d(, $modules_instance)?> )* ),* + $d( $modules $d( <$modules_generic> )* ),* }, )* ); @@ -343,7 +322,7 @@ macro_rules! __create_decl_macro { $d( $system:ident )?; { $d( $parsed:tt )* }; $name:ident : $module:ident:: < $module_instance:ident >:: { - $macro_enum_name <$event_generic:ident, $event_instance:path> $d(, $ingore:ident $d( <$ignor:ident $d(, $ignore_instance:path)?> )* )* + $macro_enum_name <$event_generic:ident> $d(, $ingore:ident $d( <$ignor:ident> )* )* }, $d( $rest:tt )* ) => { @@ -352,33 +331,17 @@ macro_rules! __create_decl_macro { $d( $system )?; { $d( $parsed )* - $module $module_instance <$event_generic, $event_instance>, + $module $module_instance <$event_generic>, }; $d( $rest )* ); }; - (@inner - $runtime:ident; - $d( $system:ident )?; - { $d( $parsed:tt )* }; - $name:ident : $module:ident:: < $module_instance:ident >:: { - $macro_enum_name $d( <$event_generic:ident> )* $d(, $ingore:ident $d( <$ignor:ident $d(, $ignore_instance:path)?> )* )* - }, - $d( $rest:tt )* - ) => { - compile_error!{concat!{ - "Module `", stringify!{$name}, "` must have `", stringify!{$macro_enum_name}, "`", - " but has `", stringify!{$macro_enum_name} $d(, "<", stringify!{$event_generic}, ">")*, "`", - ": Instantiated modules must have ", stringify!{$macro_enum_name}, - " generic over instance to be able to convert to outer ", stringify!{$macro_enum_name} - }} - }; (@inner $runtime:ident; $d( $system:ident )?; { $d( $parsed:tt )* }; $name:ident : $module:ident:: { - $macro_enum_name $d( <$event_generic:ident $d(, $event_instance:path)?> )* $d(, $ingore:ident $d( <$ignor:ident $d(, $ignore_instance:path)?> )* )* + $macro_enum_name $d( <$event_generic:ident> )* $d(, $ingore:ident $d( <$ignor:ident> )* )* }, $d( $rest:tt )* ) => { @@ -387,7 +350,7 @@ macro_rules! __create_decl_macro { $d( $system )?; { $d( $parsed )* - $module $d( <$event_generic $d(, $event_instance)?> )*, + $module $d( <$event_generic> )*, }; $d( $rest )* ); @@ -397,7 +360,7 @@ macro_rules! __create_decl_macro { $d( $system:ident )?; { $d( $parsed:tt )* }; $name:ident : $module:ident:: $d( < $module_instance:ident >:: )? { - $ingore:ident $d( <$ignor:ident $d(, $ignore_instance:path)?> )* $d(, $modules:ident $d( <$modules_generic:ident $d(, $modules_instance:path)?> )* )* + $ingore:ident $d( <$ignor:ident> )* $d(, $modules:ident $d( <$modules_generic:ident> )* )* }, $d( $rest:tt )* ) => { @@ -405,7 +368,7 @@ macro_rules! __create_decl_macro { $runtime; $d( $system )?; { $d( $parsed )* }; - $name: $module:: $d( < $module_instance >:: )? { $d( $modules $d( <$modules_generic $d(, $modules_instance)?> )* ),* }, + $name: $module:: $d( < $module_instance >:: )? { $d( $modules $d( <$modules_generic> )* ),* }, $d( $rest )* ); }; @@ -426,16 +389,13 @@ macro_rules! __create_decl_macro { (@inner $runtime:ident; $system:ident; - { $d( $parsed_modules:ident $d( $instance:ident )? $d( <$parsed_generic:ident $d(, $parsed_instance_full_path:path)?> )* ,)* }; + { $d( $parsed_modules:ident $d( $instance:ident )? $d( <$parsed_generic:ident> )? ,)* }; ) => { - $d crate::paste::item! { - $d crate::$macro_outer_name! { - - pub enum $macro_enum_name for $runtime where system = $system { - $d( - [< $parsed_modules $d(_ $instance )? >] $d( <$parsed_generic $d(, $parsed_instance_full_path)?> )*, - )* - } + $d crate::$macro_outer_name! { + pub enum $macro_enum_name for $runtime where system = $system { + $d( + $parsed_modules $d( $instance )? $d( <$parsed_generic> )?, + )* } } } @@ -748,17 +708,15 @@ macro_rules! __decl_outer_log { $parsed_modules:ident $(< $parsed_instance:ident >)? ( $( $parsed_args:ident )* ) )* }; ) => { - $crate::paste::item! { - $crate::runtime_primitives::impl_outer_log!( - pub enum Log($log_internal: DigestItem<$( $log_genarg ),*>) for $runtime { - $( [< $parsed_modules $(_ $parsed_instance)? >] $(< $parsed_modules::$parsed_instance >)? ( $( $parsed_args ),* ) ),* - } - ); - } + $crate::runtime_primitives::impl_outer_log!( + pub enum Log($log_internal: DigestItem<$( $log_genarg ),*>) for $runtime { + $( $parsed_modules $(< $parsed_instance >)? ( $( $parsed_args ),* ) ),* + } + ); }; } -/// A private macro that generates GenesisConfig for the runtime. See impl_outer_config macro. +/// A private macro that generates GenesisConfig for the runtime. See `impl_outer_config!` macro. #[macro_export] #[doc(hidden)] macro_rules! __decl_outer_config { @@ -766,7 +724,8 @@ macro_rules! __decl_outer_config { $runtime:ident; { $( $parsed:tt )* }; $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { - Config $(< $config_generic:ident $(, $config_instance:path)?>)? $(, $modules:ident $( <$modules_generic:ident $(, $modules_instance:path)?> )* )* + Config $( <$config_generic:ident> )? + $(, $modules:ident $( <$modules_generic:ident> )* )* }, $( $rest:tt )* ) => { @@ -774,7 +733,7 @@ macro_rules! __decl_outer_config { $runtime; { $( $parsed )* - $module::$name $( $module_instance )? $(<$config_generic $(, $config_instance)?>)?, + $module::$name $( $module_instance )? $( <$config_generic> )?, }; $( $rest )* ); @@ -783,14 +742,15 @@ macro_rules! __decl_outer_config { $runtime:ident; { $( $parsed:tt )* }; $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { - $ingore:ident $( <$ignor:ident $(, $ignore_instance:path)?> )* $(, $modules:ident $( <$modules_generic:ident $(, $modules_instance:path)?> )* )* + $ingore:ident $( <$ignore_gen:ident> )* + $(, $modules:ident $( <$modules_generic:ident> )* )* }, $( $rest:tt )* ) => { $crate::__decl_outer_config!( $runtime; { $( $parsed )* }; - $name: $module:: $( < $module_instance >:: )? { $( $modules $( <$modules_generic $(, $modules_instance)?> )* ),* }, + $name: $module:: $( < $module_instance >:: )? { $( $modules $( <$modules_generic> )* ),* }, $( $rest )* ); }; @@ -808,13 +768,21 @@ macro_rules! __decl_outer_config { }; ( $runtime:ident; - {$( $parsed_modules:ident :: $parsed_name:ident $( $parsed_instance:ident )? $( < $parsed_generic:ident $(, $parsed_instance_full_path:path)? > )* ,)* }; + { + $( + $parsed_modules:ident :: $parsed_name:ident $( $parsed_instance:ident )? + $( + <$parsed_generic:ident> + )* + ,)* + }; ) => { $crate::paste::item! { $crate::runtime_primitives::impl_outer_config!( pub struct GenesisConfig for $runtime { $( - [< $parsed_name Config >] => [< $parsed_modules $( _ $parsed_instance)? >] $( < $parsed_generic $(, $parsed_instance_full_path)? > )*, + [< $parsed_name Config >] => + $parsed_modules $( $parsed_instance )? $( <$parsed_generic> )*, )* } ); diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 7c21eaccb5ab9..aed1945ef23fb 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -15,15 +15,13 @@ // along with Substrate. If not, see . #![recursion_limit="128"] +#![feature(trace_macros)] -#[cfg(feature = "std")] -use serde::Serialize; use runtime_io::{with_externalities, Blake2Hasher}; -use srml_support::rstd::prelude::*; -use srml_support::rstd as rstd; -use srml_support::runtime_primitives::{generic, BuildStorage}; -use srml_support::runtime_primitives::traits::{BlakeTwo256, Block as _, Verify}; -use srml_support::Parameter; +use srml_support::{ + Parameter, + runtime_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}, +}; use inherents::{ ProvideInherent, InherentData, InherentIdentifier, RuntimeString, MakeFatalError }; @@ -74,7 +72,7 @@ mod module1 { } srml_support::decl_event! { - pub enum Event where Phantom = rstd::marker::PhantomData { + pub enum Event where Phantom = std::marker::PhantomData { _Phantom(Phantom), AnotherVariant(u32), } @@ -84,7 +82,7 @@ mod module1 { #[cfg_attr(feature = "std", derive(Debug))] pub enum Origin, I> { Members(u32), - _Phantom(rstd::marker::PhantomData<(T, I)>), + _Phantom(std::marker::PhantomData<(T, I)>), } pub type Log = RawLog< @@ -96,7 +94,7 @@ mod module1 { #[cfg_attr(feature = "std", derive(serde::Serialize, Debug))] #[derive(parity_codec::Encode, parity_codec::Decode, PartialEq, Eq, Clone)] pub enum RawLog { - _Phantom(rstd::marker::PhantomData<(T, I)>), + _Phantom(std::marker::PhantomData<(T, I)>), AmountChange(u32), } @@ -111,7 +109,7 @@ mod module1 { unimplemented!(); } - fn check_inherent(_call: &Self::Call, _data: &InherentData) -> rstd::result::Result<(), Self::Error> { + fn check_inherent(_call: &Self::Call, _data: &InherentData) -> std::result::Result<(), Self::Error> { unimplemented!(); } } @@ -157,7 +155,7 @@ mod module2 { #[cfg_attr(feature = "std", derive(Debug))] pub enum Origin, I=DefaultInstance> { Members(u32), - _Phantom(rstd::marker::PhantomData<(T, I)>), + _Phantom(std::marker::PhantomData<(T, I)>), } pub type Log = RawLog< @@ -169,7 +167,7 @@ mod module2 { #[cfg_attr(feature = "std", derive(serde::Serialize, Debug))] #[derive(parity_codec::Encode, parity_codec::Decode, PartialEq, Eq, Clone)] pub enum RawLog { - _Phantom(rstd::marker::PhantomData<(T, I)>), + _Phantom(std::marker::PhantomData<(T, I)>), AmountChange(u32), } @@ -184,7 +182,7 @@ mod module2 { unimplemented!(); } - fn check_inherent(_call: &Self::Call, _data: &InherentData) -> rstd::result::Result<(), Self::Error> { + fn check_inherent(_call: &Self::Call, _data: &InherentData) -> std::result::Result<(), Self::Error> { unimplemented!(); } } @@ -260,6 +258,7 @@ impl system::Trait for Runtime { type Log = Log; } +trace_macros!(true); srml_support::construct_runtime!( pub enum Runtime with Log(InternalLog: DigestItem) where Block = Block, @@ -267,15 +266,16 @@ srml_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Event, Log(ChangesTrieRoot)}, - Module1_1: module1::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, - Module1_2: module1::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, + Module1_1: module1::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, + Module1_2: module1::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, Module2: module2::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, - Module2_1: module2::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, - Module2_2: module2::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, - Module2_3: module2::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, + Module2_1: module2::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, + Module2_2: module2::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, + Module2_3: module2::::{Module, Call, Storage, Event, Config, Origin, Log(), Inherent}, Module3: module3::{Module, Call}, } ); +trace_macros!(false); pub type Header = generic::Header; pub type Block = generic::Block; @@ -285,11 +285,9 @@ fn new_test_ext() -> runtime_io::TestExternalities { GenesisConfig{ module1_Instance1: Some(module1::GenesisConfig { value: 3, - .. Default::default() }), module1_Instance2: Some(module1::GenesisConfig { value: 4, - _genesis_phantom_data: Default::default(), }), module2: Some(module2::GenesisConfig { value: 4, @@ -311,48 +309,48 @@ fn new_test_ext() -> runtime_io::TestExternalities { #[test] fn storage_instance_independance() { with_externalities(&mut new_test_ext(), || { - let mut map = rstd::collections::btree_map::BTreeMap::new(); + let mut map = std::collections::btree_map::BTreeMap::new(); for key in [ module2::Value::::key().to_vec(), module2::Value::::key().to_vec(), module2::Value::::key().to_vec(), module2::Value::::key().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::Map::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::LinkedMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::DoubleMap::::prefix().to_vec(), - module2::Map::::key_for(0), - module2::Map::::key_for(0).to_vec(), - module2::Map::::key_for(0).to_vec(), - module2::Map::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0), - module2::LinkedMap::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0).to_vec(), - module2::LinkedMap::::key_for(0).to_vec(), - module2::Map::::key_for(1), - module2::Map::::key_for(1).to_vec(), - module2::Map::::key_for(1).to_vec(), - module2::Map::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1), - module2::LinkedMap::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1).to_vec(), - module2::LinkedMap::::key_for(1).to_vec(), - module2::DoubleMap::::prefix_for(1), - module2::DoubleMap::::prefix_for(1).to_vec(), - module2::DoubleMap::::prefix_for(1).to_vec(), - module2::DoubleMap::::prefix_for(1).to_vec(), - module2::DoubleMap::::key_for(1, 1), - module2::DoubleMap::::key_for(1, 1).to_vec(), - module2::DoubleMap::::key_for(1, 1).to_vec(), - module2::DoubleMap::::key_for(1, 1).to_vec(), + module2::Map::::prefix().to_vec(), + module2::Map::::prefix().to_vec(), + module2::Map::::prefix().to_vec(), + module2::Map::::prefix().to_vec(), + module2::LinkedMap::::prefix().to_vec(), + module2::LinkedMap::::prefix().to_vec(), + module2::LinkedMap::::prefix().to_vec(), + module2::LinkedMap::::prefix().to_vec(), + module2::DoubleMap::::prefix().to_vec(), + module2::DoubleMap::::prefix().to_vec(), + module2::DoubleMap::::prefix().to_vec(), + module2::DoubleMap::::prefix().to_vec(), + module2::Map::::key_for(0), + module2::Map::::key_for(0).to_vec(), + module2::Map::::key_for(0).to_vec(), + module2::Map::::key_for(0).to_vec(), + module2::LinkedMap::::key_for(0), + module2::LinkedMap::::key_for(0).to_vec(), + module2::LinkedMap::::key_for(0).to_vec(), + module2::LinkedMap::::key_for(0).to_vec(), + module2::Map::::key_for(1), + module2::Map::::key_for(1).to_vec(), + module2::Map::::key_for(1).to_vec(), + module2::Map::::key_for(1).to_vec(), + module2::LinkedMap::::key_for(1), + module2::LinkedMap::::key_for(1).to_vec(), + module2::LinkedMap::::key_for(1).to_vec(), + module2::LinkedMap::::key_for(1).to_vec(), + module2::DoubleMap::::prefix_for(1), + module2::DoubleMap::::prefix_for(1).to_vec(), + module2::DoubleMap::::prefix_for(1).to_vec(), + module2::DoubleMap::::prefix_for(1).to_vec(), + module2::DoubleMap::::key_for(1, 1), + module2::DoubleMap::::key_for(1, 1).to_vec(), + module2::DoubleMap::::key_for(1, 1).to_vec(), + module2::DoubleMap::::key_for(1, 1).to_vec(), ].iter() { assert!(map.insert(key, ()).is_none()) } @@ -363,9 +361,9 @@ fn storage_instance_independance() { fn storage_with_instance_basic_operation() { with_externalities(&mut new_test_ext(), || { type Value = module2::Value; - type Map = module2::Map; - type LinkedMap = module2::LinkedMap; - type DoubleMap = module2::DoubleMap; + type Map = module2::Map; + type LinkedMap = module2::LinkedMap; + type DoubleMap = module2::DoubleMap; assert_eq!(Value::exists(), true); assert_eq!(Value::get(), 4); @@ -417,4 +415,4 @@ fn storage_with_instance_basic_operation() { DoubleMap::remove(key1, key2); assert_eq!(DoubleMap::get(key1, key2), 0); }); -} +} \ No newline at end of file diff --git a/srml/support/test/tests/issue2219.rs b/srml/support/test/tests/issue2219.rs index dd96a9aa874d5..c0f2c4ef3ef28 100644 --- a/srml/support/test/tests/issue2219.rs +++ b/srml/support/test/tests/issue2219.rs @@ -1,8 +1,25 @@ +// 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 . + +/* use srml_support::runtime_primitives::generic; use srml_support::runtime_primitives::traits::{BlakeTwo256, Block as _, Verify}; use srml_support::codec::{Encode, Decode}; use primitives::{H256, sr25519}; -use serde_derive::{Serialize, Deserialize}; +use serde::{Serialize, Deserialize}; mod system; @@ -86,7 +103,7 @@ mod module { srml_support::decl_storage! { trait Store for Module as Actors { /// requirements to enter and maintain status in roles - pub Parameters get(parameters) build(|config: &GenesisConfig| { + pub Parameters get(parameters) build(|config: &GenesisConfig| { if config.enable_storage_role { let storage_params: RoleParameters = Default::default(); vec![(Role::Storage, storage_params)] @@ -96,7 +113,7 @@ mod module { }): map Role => Option>; /// the roles members can enter into - pub AvailableRoles get(available_roles) build(|config: &GenesisConfig| { + pub AvailableRoles get(available_roles) build(|config: &GenesisConfig| { if config.enable_storage_role { vec![(Role::Storage)] } else { @@ -157,11 +174,10 @@ srml_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Event, Log(ChangesTrieRoot)}, - Module: module::{Module, Call, Storage, Config}, + Module: module::{Module, Call, Storage, Config}, } ); - #[test] fn create_genesis_config() { GenesisConfig { @@ -170,4 +186,5 @@ fn create_genesis_config() { enable_storage_role: true, }) }; -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index 62f44f006ab58..4ccb25906f1f6 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -1,4 +1,4 @@ -use serde_derive::Serialize; +use serde::Serialize; use srml_support::runtime_primitives::traits::Digest; use srml_support::codec::{Encode, Decode}; use primitives::H256; diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index c0a43bc8f663d..d9cecd37f2bf4 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -15,47 +15,47 @@ // along with Substrate. If not, see . //! # Treasury Module -//! +//! //! The `treasury` module keeps account of currency in a `pot` and manages the subsequent //! deployment of these funds. -//! +//! //! ## Overview -//! +//! //! Funds for treasury are raised in two ways: //! 1. By minting new tokens, leading to inflation, and //! 2. By channeling tokens from transaction fees and slashing. -//! +//! //! Treasury funds can be used to pay for developers who provide software updates, -//! any changes decided by referenda, and to generally keep the system running smoothly. -//! +//! any changes decided by referenda, and to generally keep the system running smoothly. +//! //! Treasury can be used with other modules, such as to tax validator rewards in the `staking` module. -//! -//! ### Implementations -//! +//! +//! ### Implementations +//! //! The treasury module provides an implementation for the following trait: //! - `OnDilution` - Mint extra funds upon dilution; maintain the ratio of `portion` diluted to `total_issuance`. -//! +//! //! ## Interface -//! +//! //! ### Dispatchable Functions -//! +//! //! - `propose_spend` - Propose a spending proposal and stake a proposal deposit. //! - `set_pot` - Set the spendable balance of funds. //! - `configure` - Configure the module's proposal requirements. //! - `reject_proposal` - Reject a proposal and slash the deposit. //! - `approve_proposal` - Accept the proposal and return the deposit. -//! +//! //! Please refer to the [`Call`](./enum.Call.html) enum and its associated variants for documentation on each function. -//! +//! //! ### Public Functions -//! +//! //! See the [module](./struct.Module.html) for details on publicly available functions. -//! +//! //! ## Related Modules -//! +//! //! The treasury module depends on the `system` and `srml_support` modules as well as //! Substrate Core libraries and the Rust standard library. -//! +//! #![cfg_attr(not(feature = "std"), no_std)] @@ -113,7 +113,7 @@ decl_module! { .map_err(|_| "Proposer's balance too low")?; let c = Self::proposal_count(); - >::put(c + 1); + ProposalCount::put(c + 1); >::insert(c, Proposal { proposer, value, beneficiary, bond }); Self::deposit_event(RawEvent::Proposed(c)); @@ -132,10 +132,10 @@ decl_module! { #[compact] spend_period: T::BlockNumber, #[compact] burn: Permill ) { - >::put(proposal_bond); + ProposalBond::put(proposal_bond); >::put(proposal_bond_minimum); >::put(spend_period); - >::put(burn); + Burn::put(burn); } /// Reject a proposed spend. The original deposit will be slashed. @@ -155,7 +155,7 @@ decl_module! { ensure!(>::exists(proposal_id), "No proposal at that index"); - >::mutate(|v| v.push(proposal_id)); + Approvals::mutate(|v| v.push(proposal_id)); } fn on_finalize(n: T::BlockNumber) { @@ -244,7 +244,7 @@ impl Module { let mut missed_any = false; let mut imbalance = >::zero(); - >::mutate(|v| { + Approvals::mutate(|v| { v.retain(|&index| { // Should always be true, but shouldn't panic if false or we're screwed. if let Some(p) = Self::proposals(index) { From 7368827f9049533ad91da86e79ef132125c45be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 7 Jun 2019 16:04:11 +0200 Subject: [PATCH 07/14] Make `srml-support-test` compile again :) --- core/sr-primitives/src/lib.rs | 2 +- srml/support/procedural/src/storage/impls.rs | 12 +- .../procedural/src/storage/transformation.rs | 228 ++++++++++++------ srml/support/test/tests/instance.rs | 7 +- srml/support/test/tests/issue2219.rs | 4 +- 5 files changed, 166 insertions(+), 87 deletions(-) diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index cf2c54f04be06..07fdc135b690e 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -607,7 +607,7 @@ macro_rules! impl_outer_config { $top:ident; $children:ident; ) => { - $crate::CreateModuleGenesisStorage::<$runtime, $module::DefaultInstance>::create_module_genesis_storage( + $crate::CreateModuleGenesisStorage::<$runtime, $module::__InherentHiddenInstance>::create_module_genesis_storage( $extra, $top, $children, diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index 5126252141866..13fdc1a462dfb 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -18,7 +18,7 @@ use crate::storage::transformation::{DeclStorageTypeInfos, InstanceOpts}; use srml_support_procedural_tools::syn_ext as ext; use proc_macro2::TokenStream as TokenStream2; -use syn; +use syn::Ident; use quote::quote; pub fn option_unwrap(is_option: bool) -> TokenStream2 { @@ -88,7 +88,7 @@ impl<'a, I: Iterator> Impls<'a, I> { } = instance_opts; let final_prefix = if let Some(instance) = instance { - let const_name = syn::Ident::new(&format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site()); + let const_name = Ident::new(&format!("{}{}", PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site()); quote!{ #instance::#const_name.as_bytes() } } else { quote!{ #prefix.as_bytes() } @@ -103,11 +103,15 @@ impl<'a, I: Iterator> Impls<'a, I> { quote!(#traitinstance, #instance), ) } else { - (quote!(#instance #bound_instantiable #equal_default_instance), quote!(#instance #bound_instantiable), quote!(#instance)) + ( + quote!(#instance #bound_instantiable #equal_default_instance), + quote!(#instance #bound_instantiable), + quote!(#instance) + ) }; // generator for value - quote!{ + quote! { #( #[ #attrs ] )* #visibility struct #name<#struct_trait>( #scrate::rstd::marker::PhantomData<(#trait_and_instance)> diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index e72d23fcb62e6..3591ab88310f7 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! `decl_storage` macro transformation -// end::description[] use srml_support_procedural_tools::syn_ext as ext; use srml_support_procedural_tools::{ @@ -24,7 +22,7 @@ use srml_support_procedural_tools::{ }; use proc_macro::TokenStream; -use proc_macro2::TokenStream as TokenStream2; +use proc_macro2::{TokenStream as TokenStream2, Span}; use syn::{ Ident, @@ -41,6 +39,9 @@ use quote::quote; use super::*; const NUMBER_OF_INSTANCE: usize = 16; +const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable"; +const DEFAULT_INSTANCE_NAME: &str = "__GeneratedInstance"; +const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance"; // try macro but returning tokenized error macro_rules! try_tok(( $expre : expr ) => { @@ -421,12 +422,22 @@ fn decl_store_extra_genesis( || !genesis_extrafields.is_empty() || !builders.is_empty(); if is_extra_genesis_needed { + let (inherent_instance, inherent_bound_instantiable) = if instance.is_some() { + (instance.clone(), bound_instantiable.clone()) + } else { + let instantiable = Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()); + ( + Some(Ident::new(DEFAULT_INSTANCE_NAME, Span::call_site())), + quote!(: #instantiable), + ) + }; + let (fparam_struct, fparam_impl, sparam, build_storage_impl) = if is_trait_needed { ( quote!(<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>), quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), quote!(<#traitinstance, #instance>), - quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), + quote!(<#traitinstance: #traittype, #inherent_instance #inherent_bound_instantiable>), ) } else { // do not even need type parameter @@ -434,7 +445,7 @@ fn decl_store_extra_genesis( quote!(), quote!(), quote!(), - quote!(<#traitinstance: #traittype, #instance #bound_instantiable>), + quote!(<#traitinstance: #traittype, #inherent_instance #inherent_bound_instantiable>), ) }; @@ -447,7 +458,7 @@ fn decl_store_extra_genesis( (quote!(), quote!()) }; - let impl_trait = quote!(CreateModuleGenesisStorage<#traitinstance, #instance>); + let impl_trait = quote!(CreateModuleGenesisStorage<#traitinstance, #inherent_instance>); let res = quote!{ #[derive(#scrate::Serialize, #scrate::Deserialize)] @@ -523,6 +534,35 @@ fn decl_store_extra_genesis( } } +fn create_and_impl_instance( + prefix: &str, + ident: &Ident, + doc: &TokenStream2, + const_names: &[(Ident, String)], + scrate: &TokenStream2, + instantiable: &Ident, +) -> TokenStream2 { + let mut const_impls = TokenStream2::new(); + + for (const_name, partial_const_value) in const_names { + let const_value = format!("{}{}", partial_const_value, prefix); + const_impls.extend(quote! { + const #const_name: &'static str = #const_value; + }); + } + + quote! { + // Those trait are derived because of wrong bounds for generics + #[cfg_attr(feature = "std", derive(Debug))] + #[derive(Clone, Eq, PartialEq, #scrate::codec::Encode, #scrate::codec::Decode)] + #doc + pub struct #ident; + impl #instantiable for #ident { + #const_impls + } + } +} + fn decl_storage_items( scrate: &TokenStream2, traitinstance: &Ident, @@ -544,54 +584,69 @@ fn decl_storage_items( let build_prefix = |cratename, name| format!("{} {}", cratename, name); // Build Instantiable trait - if instance.is_some() { - let mut const_names = vec![]; + let mut const_names = vec![]; - for sline in storage_lines.inner.iter() { - let DeclStorageLine { - storage_type, - name, - .. - } = sline; + for sline in storage_lines.inner.iter() { + let DeclStorageLine { + storage_type, + name, + .. + } = sline; - let prefix = build_prefix(cratename, name); + let prefix = build_prefix(cratename, name); - let type_infos = get_type_infos(storage_type); + let type_infos = get_type_infos(storage_type); - let const_name = syn::Ident::new(&format!("{}{}", impls::PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site()); - let partial_const_value = prefix.clone(); - const_names.push((const_name, partial_const_value)); + let const_name = syn::Ident::new( + &format!("{}{}", impls::PREFIX_FOR, name.to_string()), proc_macro2::Span::call_site() + ); + let partial_const_value = prefix.clone(); + const_names.push((const_name, partial_const_value)); - if let DeclStorageTypeInfosKind::Map { is_linked: true, .. } = type_infos.kind { - let const_name = syn::Ident::new(&format!("{}{}", impls::HEAD_KEY_FOR, name.to_string()), proc_macro2::Span::call_site()); - let partial_const_value = format!("head of {}", prefix); - const_names.push((const_name, partial_const_value)); - } + if let DeclStorageTypeInfosKind::Map { is_linked: true, .. } = type_infos.kind { + let const_name = syn::Ident::new( + &format!("{}{}", impls::HEAD_KEY_FOR, name.to_string()), proc_macro2::Span::call_site() + ); + let partial_const_value = format!("head of {}", prefix); + const_names.push((const_name, partial_const_value)); } + } - // Declare Instance trait - { - let mut const_impls = TokenStream2::new(); - for (const_name, _) in &const_names { - const_impls.extend(quote! { - const #const_name: &'static str; - }); - } + let instantiable = instantiable + .clone() + .unwrap_or_else(|| Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); - impls.extend(quote! { - /// Tag a type as an instance of a module. - /// - /// Defines storage prefixes, they must be unique. - pub trait #instantiable: 'static { - #const_impls - } + // Declare Instance trait + { + let mut const_impls = TokenStream2::new(); + for (const_name, _) in &const_names { + const_impls.extend(quote! { + const #const_name: &'static str; }); } + let hide = if instance.is_some() { + quote!() + } else { + quote!(#[doc(hidden)]) + }; + + impls.extend(quote! { + /// Tag a type as an instance of a module. + /// + /// Defines storage prefixes, they must be unique. + #hide + pub trait #instantiable: 'static { + #const_impls + } + }); + } + + if instance.is_some() { let instances = (0..NUMBER_OF_INSTANCE) .map(|i| { let name = format!("Instance{}", i); - let ident = syn::Ident::new(&name, proc_macro2::Span::call_site()); + let ident = Ident::new(&name, proc_macro2::Span::call_site()); (name, ident, quote! {#[doc=r"Module instance"]}) }) .chain( @@ -604,26 +659,26 @@ fn decl_storage_items( // Impl Instance trait for instances for (prefix, ident, doc) in instances { - let mut const_impls = TokenStream2::new(); + impls.extend( + create_and_impl_instance(&prefix, &ident, &doc, &const_names, scrate, &instantiable) + ); + } + } - for (const_name, partial_const_value) in &const_names { - let const_value = format!("{}{}", partial_const_value, prefix); - const_impls.extend(quote! { - const #const_name: &'static str = #const_value; - }); - } + // The name of the inherently available instance. + let inherent_instance = Ident::new(INHERENT_INSTANCE_NAME, Span::call_site()); - impls.extend(quote! { - // Those trait are derived because of wrong bounds for generics - #[cfg_attr(feature = "std", derive(Debug))] - #[derive(Clone, Eq, PartialEq, #scrate::codec::Encode, #scrate::codec::Decode)] - #doc - pub struct #ident; - impl #instantiable for #ident { - #const_impls - } - }); - } + if default_instance.is_some() { + impls.extend(quote! { + #[doc(hidden)] + pub type #inherent_instance = #default_instance; + }); + } else { + impls.extend( + create_and_impl_instance( + "", &inherent_instance, "e!(#[doc(hidden)]), &const_names, scrate, &instantiable + ) + ); } for sline in storage_lines.inner.iter() { @@ -1030,29 +1085,29 @@ fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { #[derive(Default)] pub(crate) struct InstanceOpts { - pub instance: Option, - pub default_instance: Option, - pub instantiable: Option, + pub instance: Option, + pub default_instance: Option, + pub instantiable: Option, pub comma_instance: TokenStream2, pub equal_default_instance: TokenStream2, pub bound_instantiable: TokenStream2, } fn get_instance_opts( - instance: Option, - instantiable: Option, - default_instance: Option, -) -> syn::Result { - + instance: Option, + instantiable: Option, + default_instance: Option, +) -> Result { let right_syntax = "Should be $Instance: $Instantiable = $DefaultInstance"; match (instance, instantiable, default_instance) { - (Some(instance), Some(instantiable), default_instance_def) => { - let (equal_default_instance, default_instance) = if let Some(default_instance) = default_instance_def { - (quote!{= #default_instance}, Some(default_instance)) + (Some(instance), Some(instantiable), default_instance) => { + let (equal_default_instance, default_instance) = if let Some(def) = default_instance { + (quote!{= #def}, Some(def)) } else { - (quote!{}, None) + (quote!(), None) }; + Ok(InstanceOpts { comma_instance: quote!{, #instance}, equal_default_instance, @@ -1063,8 +1118,35 @@ fn get_instance_opts( }) }, (None, None, None) => Ok(Default::default()), - (Some(instance), None, _) => Err(syn::Error::new(instance.span(), format!("Expect instantiable trait bound for instance: {}. {}", instance, right_syntax))), - (None, Some(instantiable), _) => Err(syn::Error::new(instantiable.span(), format!("Expect instance generic for bound instantiable: {}. {}", instantiable, right_syntax))), - (None, _, Some(default_instance)) => Err(syn::Error::new(default_instance.span(), format!("Expect instance generic for default instance: {}. {}", default_instance, right_syntax))), + (Some(instance), None, _) => Err( + Error::new( + instance.span(), + format!( + "Expect instantiable trait bound for instance: {}. {}", + instance, + right_syntax, + ) + ) + ), + (None, Some(instantiable), _) => Err( + Error::new( + instantiable.span(), + format!( + "Expect instance generic for bound instantiable: {}. {}", + instantiable, + right_syntax, + ) + ) + ), + (None, _, Some(default_instance)) => Err( + Error::new( + default_instance.span(), + format!( + "Expect instance generic for default instance: {}. {}", + default_instance, + right_syntax, + ) + ) + ), } } diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index aed1945ef23fb..636baa99a09fc 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -13,9 +13,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . - #![recursion_limit="128"] -#![feature(trace_macros)] use runtime_io::{with_externalities, Blake2Hasher}; use srml_support::{ @@ -199,8 +197,7 @@ mod module3 { } srml_support::decl_module! { - pub struct Module for enum Call where origin: ::Origin { - } + pub struct Module for enum Call where origin: ::Origin {} } } @@ -258,7 +255,6 @@ impl system::Trait for Runtime { type Log = Log; } -trace_macros!(true); srml_support::construct_runtime!( pub enum Runtime with Log(InternalLog: DigestItem) where Block = Block, @@ -275,7 +271,6 @@ srml_support::construct_runtime!( Module3: module3::{Module, Call}, } ); -trace_macros!(false); pub type Header = generic::Header; pub type Block = generic::Block; diff --git a/srml/support/test/tests/issue2219.rs b/srml/support/test/tests/issue2219.rs index c0f2c4ef3ef28..42aadd83ecd2d 100644 --- a/srml/support/test/tests/issue2219.rs +++ b/srml/support/test/tests/issue2219.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -/* use srml_support::runtime_primitives::generic; use srml_support::runtime_primitives::traits::{BlakeTwo256, Block as _, Verify}; use srml_support::codec::{Encode, Decode}; @@ -186,5 +185,4 @@ fn create_genesis_config() { enable_storage_role: true, }) }; -} -*/ \ No newline at end of file +} \ No newline at end of file From 63b9ef8d3fd10e6243931913fca676fd7f4425ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 19 Jun 2019 22:48:58 +0200 Subject: [PATCH 08/14] Fixes test of srml-support --- srml/support/procedural/src/storage/impls.rs | 10 +++-- .../procedural/src/storage/transformation.rs | 17 ++++----- srml/support/procedural/tools/src/syn_ext.rs | 5 +-- srml/support/src/origin.rs | 4 +- srml/support/src/runtime.rs | 16 -------- srml/support/test/tests/final_keys.rs | 15 ++++---- srml/support/test/tests/instance.rs | 4 +- srml/support/test/tests/issue2219.rs | 8 ++-- srml/support/test/tests/system.rs | 38 ++++--------------- 9 files changed, 38 insertions(+), 79 deletions(-) diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index a52b654009c16..2322212ba9f62 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -210,7 +210,11 @@ impl<'a, I: Iterator> Impls<'a, I> { quote!(#traitinstance, #instance), ) } else { - (quote!(#instance #bound_instantiable #equal_default_instance), quote!(#instance #bound_instantiable), quote!(#instance)) + ( + quote!(#instance #bound_instantiable #equal_default_instance), + quote!(#instance #bound_instantiable), + quote!(#instance) + ) }; // generator for map @@ -265,8 +269,8 @@ impl<'a, I: Iterator> Impls<'a, I> { } } - impl<#traitinstance: 'static + #traittype, #instance #bound_instantiable> - #scrate::storage::hashed::generator::AppendableStorageMap<#kty, #typ> for #name<#traitinstance, #instance> + impl<#impl_trait> #scrate::storage::hashed::generator::AppendableStorageMap<#kty, #typ> + for #name<#trait_and_instance> {} } } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index dde4567f81455..3ad53d74538e1 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -221,6 +221,7 @@ fn decl_store_extra_genesis( let type_infos = get_type_infos(storage_type); let opt_build = build + .inner .as_ref() .map(|b| { assimilate_require_generic |= ext::expr_contains_ident(&b.expr.content, traitinstance); @@ -229,7 +230,7 @@ fn decl_store_extra_genesis( .map(|b| quote!( #b )); // need build line - let builder = if let Some(ref config) = config { + let builder = if let Some(ref config) = config.inner { let ident = if let Some(ident) = config.expr.content.as_ref() { quote!( #ident ) } else if let Some(ref getter) = getter.inner { @@ -317,7 +318,7 @@ fn decl_store_extra_genesis( < #name<#struct_trait #instance> as #scrate::storage::hashed::generator::StorageValue<#typ> - >::put(&v, &storage); + >::put(&v, storage); }} }, DeclStorageTypeInfosKind::Map { key_type, .. } => { @@ -336,7 +337,7 @@ fn decl_store_extra_genesis( < #name<#struct_trait #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ> - >::insert(&k, &v, &storage); + >::insert(&k, &v, storage); }); }} }, @@ -357,7 +358,7 @@ fn decl_store_extra_genesis( < #name<#struct_trait #instance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> - >::insert(&k1, &k2, &v, &storage); + >::insert(&k1, &k2, &v, storage); }); }} }, @@ -503,7 +504,7 @@ fn decl_store_extra_genesis( > { let mut storage = Default::default(); let mut child_storage = Default::default(); - self.assimilate_storage::<#fn_traitinstance> (&mut storage, &mut child_storage)?; + self.assimilate_storage::<#fn_traitinstance>(&mut storage, &mut child_storage)?; Ok((storage, child_storage)) } @@ -513,13 +514,11 @@ fn decl_store_extra_genesis( r: &mut #scrate::runtime_primitives::StorageOverlay, c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay, ) -> std::result::Result<(), String> { - let storage = std::cell::RefCell::new(r); + let storage = r; #builders - let r = storage.into_inner(); - - #scall(r, c, &self); + #scall(storage, c, &self); Ok(()) } diff --git a/srml/support/procedural/tools/src/syn_ext.rs b/srml/support/procedural/tools/src/syn_ext.rs index 506828cdc8f8a..1033ebcce2de5 100644 --- a/srml/support/procedural/tools/src/syn_ext.rs +++ b/srml/support/procedural/tools/src/syn_ext.rs @@ -18,10 +18,7 @@ //! Extension to syn types, mainly for parsing // end::description[] -use syn::{ - visit::{Visit, self}, parse::{Parse, ParseStream, Result}, - token::CustomKeyword, Ident, -}; +use syn::{visit::{Visit, self}, parse::{Parse, ParseStream, Result}, Ident}; use proc_macro2::{TokenStream, TokenTree}; use quote::{ToTokens, quote}; use std::iter::once; diff --git a/srml/support/src/origin.rs b/srml/support/src/origin.rs index 6a237b4b5e1c8..d2627ff529222 100644 --- a/srml/support/src/origin.rs +++ b/srml/support/src/origin.rs @@ -203,9 +203,9 @@ macro_rules! impl_outer_origin { } impl Into< $crate::rstd::result::Result< - $module::Origin < $( $generic )? $(, $module::$generic_instance )? >>, + $module::Origin < $( $generic )? $(, $module::$generic_instance )? >, $name, - > + >> for $name { fn into(self) -> $crate::rstd::result::Result< $module::Origin < $( $generic )? $(, $module::$generic_instance )? >, diff --git a/srml/support/src/runtime.rs b/srml/support/src/runtime.rs index 0386974223150..6afae17c3d38a 100644 --- a/srml/support/src/runtime.rs +++ b/srml/support/src/runtime.rs @@ -360,22 +360,6 @@ macro_rules! __create_decl_macro { $d( $rest )* ); }; - (@inner - $runtime:ident; - $d( $system:ident )?; - { $d( $parsed:tt )* }; - $name:ident : $module:ident:: < $module_instance:ident >:: { - $macro_enum_name $d( <$event_generic:ident> )* $d(, $ignore:ident $d( <$ignor:ident> )* )* - }, - $d( $rest:tt )* - ) => { - compile_error!{concat!{ - "Module `", stringify!{$name}, "` must have `", stringify!{$macro_enum_name}, "`", - " but has `", stringify!{$macro_enum_name} $d(, "<", stringify!{$event_generic}, ">")*, "`", - ": Instantiated modules must have ", stringify!{$macro_enum_name}, - " generic over instance to be able to convert to outer ", stringify!{$macro_enum_name} - }} - }; (@inner $runtime:ident; $d( $system:ident )?; diff --git a/srml/support/test/tests/final_keys.rs b/srml/support/test/tests/final_keys.rs index 549506df496c9..888ef48cb2f7d 100644 --- a/srml/support/test/tests/final_keys.rs +++ b/srml/support/test/tests/final_keys.rs @@ -17,7 +17,6 @@ use runtime_io::{with_externalities, Blake2Hasher}; use srml_support::{StorageValue, StorageMap, StorageDoubleMap}; use srml_support::storage::unhashed; -use srml_support::runtime_primitives::BuildStorage; use parity_codec::{Encode, Decode}; pub trait Trait { @@ -60,37 +59,37 @@ fn new_test_ext() -> runtime_io::TestExternalities { #[test] fn final_keys() { with_externalities(&mut new_test_ext(), || { - >::put(1); + Value::put(1); assert_eq!(unhashed::get::(&runtime_io::twox_128(b"Module Value")), Some(1u32)); - >::insert(1, 2); + Map::insert(1, 2); let mut k = b"Module Map".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); - >::insert(1, 2); + Map2::insert(1, 2); let mut k = b"Module Map2".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); - >::insert(1, 2); + LinkedMap::insert(1, 2); let mut k = b"Module LinkedMap".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::blake2_256(&k)), Some(2u32)); - >::insert(1, 2); + LinkedMap2::insert(1, 2); let mut k = b"Module LinkedMap2".to_vec(); k.extend(1u32.encode()); assert_eq!(unhashed::get::(&runtime_io::twox_128(&k)), Some(2u32)); - >::insert(1, 2, 3); + DoubleMap::insert(1, 2, 3); let mut k = b"Module DoubleMap".to_vec(); k.extend(1u32.encode()); let mut k = runtime_io::blake2_256(&k).to_vec(); k.extend(&runtime_io::blake2_256(&2u32.encode())); assert_eq!(unhashed::get::(&k), Some(3u32)); - >::insert(1, 2, 3); + DoubleMap2::insert(1, 2, 3); let mut k = b"Module DoubleMap2".to_vec(); k.extend(1u32.encode()); let mut k = runtime_io::twox_128(&k).to_vec(); diff --git a/srml/support/test/tests/instance.rs b/srml/support/test/tests/instance.rs index 18337f26e738b..f8497186e8675 100644 --- a/srml/support/test/tests/instance.rs +++ b/srml/support/test/tests/instance.rs @@ -219,10 +219,10 @@ srml_support::construct_runtime!( { System: system::{Module, Call, Event}, Module1_1: module1::::{ - Module, Call, Storage, Event, Config, Origin, Inherent + Module, Call, Storage, Event, Config, Origin, Inherent }, Module1_2: module1::::{ - Module, Call, Storage, Event, Config, Origin, Inherent + Module, Call, Storage, Event, Config, Origin, Inherent }, Module2: module2::{Module, Call, Storage, Event, Config, Origin, Inherent}, Module2_1: module2::::{ diff --git a/srml/support/test/tests/issue2219.rs b/srml/support/test/tests/issue2219.rs index 42aadd83ecd2d..185b5e24807a9 100644 --- a/srml/support/test/tests/issue2219.rs +++ b/srml/support/test/tests/issue2219.rs @@ -150,7 +150,7 @@ pub type Signature = sr25519::Signature; pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -pub type Header = generic::Header; +pub type Header = generic::Header; pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic; @@ -158,21 +158,19 @@ impl system::Trait for Runtime { type Hash = H256; type Origin = Origin; type BlockNumber = BlockNumber; - type Digest = generic::Digest; type AccountId = AccountId; type Event = Event; - type Log = Log; } impl module::Trait for Runtime {} srml_support::construct_runtime!( - pub enum Runtime with Log(InternalLog: DigestItem) where + pub enum Runtime where Block = Block, NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event, Log(ChangesTrieRoot)}, + System: system::{Module, Call, Event}, Module: module::{Module, Call, Storage, Config}, } ); diff --git a/srml/support/test/tests/system.rs b/srml/support/test/tests/system.rs index 4ccb25906f1f6..6483161211afc 100644 --- a/srml/support/test/tests/system.rs +++ b/srml/support/test/tests/system.rs @@ -1,31 +1,21 @@ -use serde::Serialize; -use srml_support::runtime_primitives::traits::Digest; use srml_support::codec::{Encode, Decode}; -use primitives::H256; pub trait Trait: 'static + Eq + Clone { - type Origin: Into>> + From>; + type Origin: Into, Self::Origin>> + + From>; + type BlockNumber: Decode + Encode + Clone + Default; - type Digest: Digest; type Hash; type AccountId: Encode + Decode; type Event: From; - type Log: From> + Into>; } -pub type DigestItemOf = <::Digest as Digest>::Item; - srml_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { pub fn deposit_event(_event: T::Event) { } } } -impl Module { - pub fn deposit_log(_item: ::Item) { - unimplemented!(); - } -} srml_support::decl_event!( pub enum Event { @@ -40,35 +30,23 @@ srml_support::decl_event!( pub enum RawOrigin { Root, Signed(AccountId), - Inherent, + None, } impl From> for RawOrigin { fn from(s: Option) -> RawOrigin { match s { Some(who) => RawOrigin::Signed(who), - None => RawOrigin::Inherent, + None => RawOrigin::None, } } } pub type Origin = RawOrigin<::AccountId>; -pub type Log = RawLog< - ::Hash, ->; - -#[cfg_attr(feature = "std", derive(Serialize, Debug))] -#[derive(Encode, Decode, PartialEq, Eq, Clone)] -pub enum RawLog { - ChangesTrieRoot(H), -} - +#[allow(dead_code)] pub fn ensure_root(o: OuterOrigin) -> Result<(), &'static str> - where OuterOrigin: Into>> + where OuterOrigin: Into, OuterOrigin>> { - match o.into() { - Some(RawOrigin::Root) => Ok(()), - _ => Err("bad origin: expected to be a root origin"), - } + o.into().map(|_| ()).map_err(|_| "bad origin: expected to be a root origin") } \ No newline at end of file From 762b5af38fd516fe02203f77e75dddd3e83cdb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 20 Jun 2019 10:23:39 +0200 Subject: [PATCH 09/14] Fix compilation --- Cargo.lock | 2 - core/client/db/src/utils.rs | 1 - core/sr-primitives/Cargo.toml | 3 +- core/sr-primitives/src/lib.rs | 10 +-- core/test-runtime/wasm/Cargo.lock | 1 + node-template/runtime/src/lib.rs | 2 +- node-template/runtime/src/template.rs | 2 +- node-template/runtime/wasm/Cargo.lock | 1 + node-template/src/chain_spec.rs | 1 - node/cli/src/chain_spec.rs | 4 - node/executor/src/lib.rs | 1 - node/runtime/src/lib.rs | 6 +- node/runtime/wasm/Cargo.lock | 1 + srml/assets/src/lib.rs | 8 +- srml/aura/src/mock.rs | 4 +- srml/babe/src/lib.rs | 2 +- srml/balances/src/mock.rs | 3 +- srml/contracts/src/lib.rs | 2 +- srml/contracts/src/tests.rs | 7 +- srml/council/src/lib.rs | 6 +- srml/council/src/seats.rs | 8 +- srml/democracy/src/lib.rs | 14 ++- srml/example/src/lib.rs | 5 +- srml/executive/src/lib.rs | 10 +-- srml/finality-tracker/Cargo.toml | 2 - srml/finality-tracker/src/lib.rs | 89 +++++++++---------- srml/grandpa/src/lib.rs | 4 +- srml/grandpa/src/mock.rs | 11 +-- srml/indices/src/mock.rs | 3 +- srml/session/src/lib.rs | 26 +++--- srml/staking/src/lib.rs | 6 +- srml/staking/src/mock.rs | 4 +- srml/staking/src/tests.rs | 4 +- .../procedural/src/storage/transformation.rs | 8 +- srml/support/src/lib.rs | 4 +- srml/support/src/origin.rs | 34 +++---- srml/support/src/storage/storage_items.rs | 12 +-- srml/system/src/lib.rs | 20 ++--- srml/timestamp/src/lib.rs | 10 +-- srml/treasury/src/lib.rs | 6 +- 40 files changed, 155 insertions(+), 192 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42bdd77a63dcf..32276657231e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3592,9 +3592,7 @@ dependencies = [ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", diff --git a/core/client/db/src/utils.rs b/core/client/db/src/utils.rs index a0b955a1a2f39..a4ab82b5d8b2d 100644 --- a/core/client/db/src/utils.rs +++ b/core/client/db/src/utils.rs @@ -189,7 +189,6 @@ pub fn block_id_to_lookup_key( /// Maps database error to client error pub fn db_err(err: io::Error) -> client::error::Error { - use std::error::Error; client::error::Error::Backend(format!("{}", err)) } diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index d17f6bc77e9dc..c9a6b18476fa3 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -13,7 +13,7 @@ substrate-primitives = { path = "../primitives", default-features = false } rstd = { package = "sr-std", path = "../sr-std", default-features = false } runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } log = { version = "0.4", optional = true } -paste = { version = "0.1", optional = true } +paste = { version = "0.1"} [dev-dependencies] serde_json = "1.0" @@ -24,7 +24,6 @@ default = ["std"] std = [ "num-traits/std", "serde", - "paste", "log", "rstd/std", "runtime_io/std", diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index 261c979b05be5..80696e9c0c720 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -28,7 +28,6 @@ pub use serde; #[doc(hidden)] pub use rstd; -#[cfg(feature = "std")] #[doc(hidden)] pub use paste; @@ -112,10 +111,11 @@ pub trait BuildStorage: Sized { ) -> Result<(), String>; } +/// Somethig that can build the genesis storage of a module. #[cfg(feature = "std")] -pub trait CreateModuleGenesisStorage: Sized { +pub trait BuildModuleGenesisStorage: Sized { /// Create the module genesis storage into the given `storage` and `child_storage`. - fn create_module_genesis_storage( + fn build_module_genesis_storage( self, storage: &mut StorageOverlay, child_storage: &mut ChildrenStorageOverlay @@ -665,7 +665,7 @@ macro_rules! impl_outer_config { $top:ident; $children:ident; ) => { - $crate::CreateModuleGenesisStorage::<$runtime, $module::$instance>::create_module_genesis_storage( + $crate::BuildModuleGenesisStorage::<$runtime, $module::$instance>::build_module_genesis_storage( $extra, $top, $children, @@ -679,7 +679,7 @@ macro_rules! impl_outer_config { $top:ident; $children:ident; ) => { - $crate::CreateModuleGenesisStorage::<$runtime, $module::__InherentHiddenInstance>::create_module_genesis_storage( + $crate::BuildModuleGenesisStorage::<$runtime, $module::__InherentHiddenInstance>::build_module_genesis_storage( $extra, $top, $children, diff --git a/core/test-runtime/wasm/Cargo.lock b/core/test-runtime/wasm/Cargo.lock index 833c31c3e429d..15fab56cdfa60 100644 --- a/core/test-runtime/wasm/Cargo.lock +++ b/core/test-runtime/wasm/Cargo.lock @@ -2311,6 +2311,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", diff --git a/node-template/runtime/src/lib.rs b/node-template/runtime/src/lib.rs index 9b99e7f08f495..40f4ce8c514d0 100644 --- a/node-template/runtime/src/lib.rs +++ b/node-template/runtime/src/lib.rs @@ -183,7 +183,7 @@ construct_runtime!( NodeBlock = opaque::Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{default, Config}, + System: system::{Module, Call, Storage, Config, Event}, Timestamp: timestamp::{Module, Call, Storage, Config, Inherent}, Aura: aura::{Module, Config, Inherent(Timestamp)}, Indices: indices::{default, Config}, diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index dfb777db8f326..e638dee41dcd1 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -106,7 +106,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. fn new_test_ext() -> runtime_io::TestExternalities { - system::GenesisConfig::::default().build_storage().unwrap().0.into() + system::GenesisConfig::default().build_storage::().unwrap().0.into() } #[test] diff --git a/node-template/runtime/wasm/Cargo.lock b/node-template/runtime/wasm/Cargo.lock index ae323203f61f9..6e924b8858cc4 100644 --- a/node-template/runtime/wasm/Cargo.lock +++ b/node-template/runtime/wasm/Cargo.lock @@ -2343,6 +2343,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", diff --git a/node-template/src/chain_spec.rs b/node-template/src/chain_spec.rs index f14cf41464a1b..b8cc7aef32e12 100644 --- a/node-template/src/chain_spec.rs +++ b/node-template/src/chain_spec.rs @@ -93,7 +93,6 @@ fn testnet_genesis(initial_authorities: Vec, endowed_accounts: Vec< system: Some(SystemConfig { code: include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/node_template_runtime_wasm.compact.wasm").to_vec(), changes_trie_config: Default::default(), - _genesis_phantom_data: Default::default(), }), aura: Some(AuraConfig { authorities: initial_authorities.clone(), diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index 672c75b1a94c6..e80d6f8cc49cf 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -103,7 +103,6 @@ fn staging_testnet_config_genesis() -> GenesisConfig { GenesisConfig { system: Some(SystemConfig { code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm").to_vec(), // FIXME change once we have #1252 - _genesis_phantom_data: Default::default(), changes_trie_config: Default::default(), }), balances: Some(BalancesConfig { @@ -189,7 +188,6 @@ fn staging_testnet_config_genesis() -> GenesisConfig { }), grandpa: Some(GrandpaConfig { authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(), - _genesis_phantom_data: Default::default(), }), } } @@ -293,7 +291,6 @@ pub fn testnet_genesis( GenesisConfig { system: Some(SystemConfig { code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm").to_vec(), - _genesis_phantom_data: Default::default(), changes_trie_config: Default::default(), }), indices: Some(IndicesConfig { @@ -358,7 +355,6 @@ pub fn testnet_genesis( }), grandpa: Some(GrandpaConfig { authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(), - _genesis_phantom_data: Default::default(), }), } } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 1622e92c6d31e..11eef940431c9 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -391,7 +391,6 @@ mod tests { contracts: Some(Default::default()), sudo: Some(Default::default()), grandpa: Some(GrandpaConfig { - _genesis_phantom_data: Default::default(), authorities: vec![], }), }.build_storage().unwrap().0); diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index ec529696a8e06..781e7aaf56204 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -247,19 +247,19 @@ construct_runtime!( NodeBlock = node_primitives::Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system, + System: system::{Module, Call, Storage, Config, Event}, Aura: aura::{Module, Config, Inherent(Timestamp)}, Timestamp: timestamp::{Module, Call, Storage, Config, Inherent}, Indices: indices, Balances: balances, Session: session::{Module, Call, Storage, Event, Config}, Staking: staking::{default, OfflineWorker}, - Democracy: democracy, + Democracy: democracy::{Module, Call, Storage, Config, Event}, Council: council::{Module, Call, Storage, Event}, CouncilMotions: council_motions::{Module, Call, Storage, Event, Origin}, CouncilSeats: council_seats::{Config}, FinalityTracker: finality_tracker::{Module, Call, Inherent}, - Grandpa: grandpa::{Module, Call, Storage, Config, Event}, + Grandpa: grandpa::{Module, Call, Storage, Config, Event}, Treasury: treasury, Contracts: contracts, Sudo: sudo, diff --git a/node/runtime/wasm/Cargo.lock b/node/runtime/wasm/Cargo.lock index 89c1bf93034c6..b754cc12208ee 100644 --- a/node/runtime/wasm/Cargo.lock +++ b/node/runtime/wasm/Cargo.lock @@ -2375,6 +2375,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index 1e8f17b5a94cf..b0306f44467c9 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -244,11 +244,7 @@ mod tests { use substrate_primitives::{H256, Blake2Hasher}; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. - use primitives::{ - BuildStorage, - traits::{BlakeTwo256, IdentityLookup}, - testing::Header - }; + use primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { pub enum Origin for Test {} @@ -280,7 +276,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. fn new_test_ext() -> runtime_io::TestExternalities { - system::GenesisConfig::default().build_storage().unwrap().0.into() + system::GenesisConfig::default().build_storage::().unwrap().0.into() } #[test] diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs index e9c43850f6e01..900ef21b32ea1 100644 --- a/srml/aura/src/mock.rs +++ b/srml/aura/src/mock.rs @@ -18,7 +18,7 @@ #![cfg(test)] -use primitives::{BuildStorage, traits::IdentityLookup, testing::{Header, UintAuthorityId}}; +use primitives::{traits::IdentityLookup, testing::{Header, UintAuthorityId}}; use srml_support::impl_outer_origin; use runtime_io; use substrate_primitives::{H256, Blake2Hasher}; @@ -55,7 +55,7 @@ impl Trait for Test { } pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(timestamp::GenesisConfig::{ minimum_period: 1, }.build_storage().unwrap().0); diff --git a/srml/babe/src/lib.rs b/srml/babe/src/lib.rs index 0cfc0fb8d059d..e03b17e5b39eb 100644 --- a/srml/babe/src/lib.rs +++ b/srml/babe/src/lib.rs @@ -135,7 +135,7 @@ impl OnTimestampSet for Module { impl Module { fn change_authorities(new: Vec) { - >::put(&new); + Authorities::put(&new); let log: DigestItem = DigestItem::Consensus(BABE_ENGINE_ID, new.encode()); >::deposit_log(log.into()); diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index ac5208ab90c2a..44e046b68192e 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -18,7 +18,6 @@ #![cfg(test)] -use primitives::BuildStorage; use primitives::{traits::{IdentityLookup}, testing::Header}; use substrate_primitives::{H256, Blake2Hasher}; use runtime_io; @@ -106,7 +105,7 @@ impl ExtBuilder { self } pub fn build(self) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(GenesisConfig:: { transaction_base_fee: self.transaction_base_fee, transaction_byte_fee: self.transaction_byte_fee, diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index b9c8976cc04be..58575ef897e59 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -256,7 +256,7 @@ where fn trie_id(account_id: &T::AccountId) -> TrieId { // Note that skipping a value due to error is not an issue here. // We only need uniqueness, not sequence. - let new_seed = >::mutate(|v| { + let new_seed = AccountCounter::mutate(|v| { *v = v.wrapping_add(1); *v }); diff --git a/srml/contracts/src/tests.rs b/srml/contracts/src/tests.rs index 61a81a4eb683b..7da97f778df78 100644 --- a/srml/contracts/src/tests.rs +++ b/srml/contracts/src/tests.rs @@ -117,7 +117,7 @@ impl TrieIdGenerator for DummyTrieIdGenerator { fn trie_id(account_id: &u64) -> TrieId { use substrate_primitives::storage::well_known_keys; - let new_seed = >::mutate(|v| { + let new_seed = super::AccountCounter::mutate(|v| { *v = v.wrapping_add(1); *v }); @@ -184,10 +184,7 @@ impl ExtBuilder { self } pub fn build(self) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default() - .build_storage() - .unwrap() - .0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend( balances::GenesisConfig:: { transaction_base_fee: 0, diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index 681bc731be895..c319708a31318 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -41,7 +41,7 @@ mod tests { use srml_support::{impl_outer_origin, impl_outer_event, impl_outer_dispatch, parameter_types}; pub use substrate_primitives::{H256, Blake2Hasher, u32_trait::{_1, _2, _3, _4}}; pub use primitives::{ - BuildStorage, traits::{BlakeTwo256, IdentityLookup}, testing::{Digest, DigestItem, Header} + traits::{BlakeTwo256, IdentityLookup}, testing::{Digest, DigestItem, Header} }; pub use {seats, motions}; @@ -172,8 +172,8 @@ mod tests { self } pub fn build(self) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; - t.extend(balances::GenesisConfig::{ + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; + t.extend(balances::GenesisConfig:: { transaction_base_fee: 0, transaction_byte_fee: 0, balances: vec![ diff --git a/srml/council/src/seats.rs b/srml/council/src/seats.rs index 5a9681d326e65..96097c987fe41 100644 --- a/srml/council/src/seats.rs +++ b/srml/council/src/seats.rs @@ -613,7 +613,7 @@ impl Module { let mut set = Self::voters(set_index); set[vec_index] = None; >::insert(set_index, set); - >::mutate(|c| *c = *c - 1); + VoterCount::mutate(|c| *c = *c - 1); Self::remove_all_approvals_of(voter); >::remove(voter); } @@ -683,7 +683,7 @@ impl Module { } T::Currency::reserve(&who, Self::voting_bond())?; - >::mutate(|c| *c = *c + 1); + VoterCount::mutate(|c| *c = *c + 1); } T::Currency::set_lock( @@ -815,7 +815,7 @@ impl Module { set.push(Some(who)); if len + 1 == VOTER_SET_SIZE { - >::put(index + 1); + NextVoterSet::put(index + 1); } } @@ -1356,7 +1356,7 @@ mod tests { let mut t = ExtBuilder::default().build(); with_externalities(&mut t, || { >::put(vec![0, 0, 1]); - >::put(1); + CandidateCount::put(1); >::insert(1, (0, 2)); }); t diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 934421f46aa3b..a2d037dd28cce 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -751,7 +751,7 @@ impl Module { Err("Cannot inject a referendum that ends earlier than preceeding referendum")? } - >::put(ref_index + 1); + ReferendumCount::put(ref_index + 1); let item = ReferendumInfo { end, proposal, threshold, delay }; >::insert(ref_index, item); Self::deposit_event(RawEvent::Started(ref_index, threshold)); @@ -775,7 +775,7 @@ impl Module { /// Table the next waiting proposal for a vote. fn launch_next(now: T::BlockNumber) -> Result { - if >::take() { + if LastTabledWasExternal::take() { Self::launch_public(now).or_else(|_| Self::launch_external(now)) } else { Self::launch_external(now).or_else(|_| Self::launch_public(now)) @@ -785,7 +785,7 @@ impl Module { /// Table the waiting external proposal for a vote, if there is one. fn launch_external(now: T::BlockNumber) -> Result { if let Some((proposal, threshold)) = >::take() { - >::put(true); + LastTabledWasExternal::put(true); Self::deposit_event(RawEvent::ExternalTabled); Self::inject_referendum( now + T::VotingPeriod::get(), @@ -917,9 +917,7 @@ mod tests { traits::Contains }; use substrate_primitives::{H256, Blake2Hasher}; - use primitives::BuildStorage; - use primitives::traits::{BlakeTwo256, IdentityLookup, Bounded}; - use primitives::testing::Header; + use primitives::{traits::{BlakeTwo256, IdentityLookup, Bounded}, testing::Header}; use balances::BalanceLock; use system::EnsureSignedBy; @@ -999,7 +997,7 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(balances::GenesisConfig::{ transaction_base_fee: 0, transaction_byte_fee: 0, @@ -1009,7 +1007,7 @@ mod tests { creation_fee: 0, vesting: vec![], }.build_storage().unwrap().0); - t.extend(GenesisConfig::::default().build_storage().unwrap().0); + t.extend(GenesisConfig::default().build_storage::().unwrap().0); runtime_io::TestExternalities::new(t) } diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index dd14b7198acd3..6630f9df56875 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -510,8 +510,7 @@ mod tests { // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. use sr_primitives::{ - BuildStorage, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, - testing::Header + traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, testing::Header }; impl_outer_origin! { @@ -551,7 +550,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. fn new_test_ext() -> sr_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; // We use default for brevity, but you can configure as desired if needed. t.extend(balances::GenesisConfig::::default().build_storage().unwrap().0); t.extend(GenesisConfig::{ diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index f4299abe47630..8c023da548e23 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -395,9 +395,9 @@ mod tests { use balances::Call; use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; - use primitives::BuildStorage; - use primitives::traits::{Header as HeaderT, BlakeTwo256, IdentityLookup}; - use primitives::testing::{Digest, Header, Block}; + use primitives::{ + traits::{Header as HeaderT, BlakeTwo256, IdentityLookup}, testing::{Digest, Header, Block} + }; use srml_support::{traits::Currency, impl_outer_origin, impl_outer_event}; use system; use hex_literal::hex; @@ -466,7 +466,7 @@ mod tests { #[test] fn balance_transfer_dispatch_works() { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(balances::GenesisConfig:: { transaction_base_fee: 10, transaction_byte_fee: 0, @@ -493,7 +493,7 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(balances::GenesisConfig::::default().build_storage().unwrap().0); t.into() } diff --git a/srml/finality-tracker/Cargo.toml b/srml/finality-tracker/Cargo.toml index e6cf47ab25a26..8b2f014ce2eb1 100644 --- a/srml/finality-tracker/Cargo.toml +++ b/srml/finality-tracker/Cargo.toml @@ -16,8 +16,6 @@ srml-system = { path = "../system", default-features = false } [dev-dependencies] substrate-primitives = { path = "../../core/primitives", default-features = false } sr-io = { path = "../../core/sr-io", default-features = false } -lazy_static = "1.0" -parking_lot = "0.8.0" [features] default = ["std"] diff --git a/srml/finality-tracker/src/lib.rs b/srml/finality-tracker/src/lib.rs index 6442fee543ab4..3bee1c2001cc2 100644 --- a/srml/finality-tracker/src/lib.rs +++ b/srml/finality-tracker/src/lib.rs @@ -261,13 +261,11 @@ mod tests { use sr_io::{with_externalities, TestExternalities}; use substrate_primitives::H256; - use primitives::BuildStorage; - use primitives::traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}; - use primitives::testing::Header; + use primitives::{ + traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}, testing::Header + }; use srml_support::impl_outer_origin; use srml_system as system; - use lazy_static::lazy_static; - use parking_lot::Mutex; #[derive(Clone, PartialEq, Debug)] pub struct StallEvent { @@ -275,65 +273,59 @@ mod tests { further_wait: u64, } - macro_rules! make_test_context { - () => { - #[derive(Clone, Eq, PartialEq)] - pub struct Test; + #[derive(Clone, Eq, PartialEq)] + pub struct Test; - impl_outer_origin! { - pub enum Origin for Test {} - } - - impl system::Trait for Test { - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = (); - } + impl_outer_origin! { + pub enum Origin for Test {} + } - type System = system::Module; + impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + } - lazy_static! { - static ref NOTIFICATIONS: Mutex> = Mutex::new(Vec::new()); - } + type System = system::Module; - pub struct StallTracker; - impl OnFinalizationStalled for StallTracker { - fn on_stalled(further_wait: u64, _median: u64) { - let now = System::block_number(); - NOTIFICATIONS.lock().push(StallEvent { at: now, further_wait }); - } - } - - impl Trait for Test { - type OnFinalizationStalled = StallTracker; - } + thread_local! { + static NOTIFICATIONS: std::cell::RefCell> = Default::default(); + } - type FinalityTracker = Module; + pub struct StallTracker; + impl OnFinalizationStalled for StallTracker { + fn on_stalled(further_wait: u64, _median: u64) { + let now = System::block_number(); + NOTIFICATIONS.with(|n| n.borrow_mut().push(StallEvent { at: now, further_wait })); } } + impl Trait for Test { + type OnFinalizationStalled = StallTracker; + } + + type FinalityTracker = Module; + #[test] fn median_works() { - make_test_context!(); - let t = system::GenesisConfig::::default().build_storage().unwrap().0; + let t = system::GenesisConfig::default().build_storage::().unwrap().0; with_externalities(&mut TestExternalities::new(t), || { FinalityTracker::update_hint(Some(500)); assert_eq!(FinalityTracker::median(), 250); - assert!(NOTIFICATIONS.lock().is_empty()); + assert!(NOTIFICATIONS.with(|n| n.borrow().is_empty())); }); } #[test] fn notifies_when_stalled() { - make_test_context!(); - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(GenesisConfig:: { window_size: 11, report_latency: 100 @@ -349,7 +341,7 @@ mod tests { } assert_eq!( - NOTIFICATIONS.lock().to_vec(), + NOTIFICATIONS.with(|n| n.borrow().clone()), vec![StallEvent { at: 105, further_wait: 10 }] ) }); @@ -357,8 +349,7 @@ mod tests { #[test] fn recent_notifications_prevent_stalling() { - make_test_context!(); - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(GenesisConfig:: { window_size: 11, report_latency: 100 @@ -377,7 +368,7 @@ mod tests { parent_hash = hdr.hash(); } - assert!(NOTIFICATIONS.lock().is_empty()); + assert!(NOTIFICATIONS.with(|n| n.borrow().is_empty())); }); } } diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs index 61610e91940fd..1ec1e206808ff 100644 --- a/srml/grandpa/src/lib.rs +++ b/srml/grandpa/src/lib.rs @@ -179,7 +179,7 @@ decl_module! { } if block_number == pending_change.scheduled_at + pending_change.delay { - >::put(&pending_change.next_authorities); + Authorities::put(&pending_change.next_authorities); Self::deposit_event( Event::NewAuthorities(pending_change.next_authorities) ); @@ -193,7 +193,7 @@ decl_module! { impl Module { /// Get the current set of authorities, along with their respective weights. pub fn grandpa_authorities() -> Vec<(AuthorityId, u64)> { - >::get() + Authorities::get() } /// Schedule a change in the authorities. diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index 80c99b9a3cfaa..3d1e2f1396a7e 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -18,9 +18,7 @@ #![cfg(test)] -use primitives::{ - BuildStorage, DigestItem, traits::IdentityLookup, testing::{Header, UintAuthorityId} -}; +use primitives::{DigestItem, traits::IdentityLookup, testing::{Header, UintAuthorityId}}; use runtime_io; use srml_support::{impl_outer_origin, impl_outer_event}; use substrate_primitives::{H256, Blake2Hasher}; @@ -72,11 +70,10 @@ pub fn to_authorities(vec: Vec<(u64, u64)>) -> Vec<(AuthorityId, u64)> { } pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; - t.extend(GenesisConfig:: { - _genesis_phantom_data: Default::default(), + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; + t.extend(GenesisConfig { authorities: to_authorities(authorities), - }.build_storage().unwrap().0); + }.build_storage::().unwrap().0); t.into() } diff --git a/srml/indices/src/mock.rs b/srml/indices/src/mock.rs index e2ea51e89d958..93726502d2736 100644 --- a/srml/indices/src/mock.rs +++ b/srml/indices/src/mock.rs @@ -20,7 +20,6 @@ use std::collections::HashSet; use ref_thread_local::{ref_thread_local, RefThreadLocal}; -use primitives::BuildStorage; use primitives::testing::Header; use substrate_primitives::{H256, Blake2Hasher}; use srml_support::impl_outer_origin; @@ -90,7 +89,7 @@ pub fn new_test_ext() -> runtime_io::TestExternalities { for i in 1..5 { h.insert(i); } } - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(GenesisConfig:: { ids: vec![1, 2, 3, 4] }.build_storage().unwrap().0); diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index 3ae7c9801299b..9a99e7b84cfa0 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -290,7 +290,7 @@ decl_module! { updates.push(None); continue; } - let mut active = >::get(i as u32); + let mut active = Active::get(i as u32); match active.binary_search_by(|k| k[..].cmp(&new_key)) { Ok(_) => return Err("duplicate key provided"), Err(pos) => active.insert(pos, new_key.to_owned()), @@ -310,12 +310,12 @@ decl_module! { // Update the active sets. for (i, active) in updates.into_iter().filter_map(|x| x) { - >::insert(i as u32, active); + Active::insert(i as u32, active); } // Set new keys value for next session. >::insert(who, keys); // Something changed. - >::put(true); + Changed::put(true); } /// Called when a block is finalized. Will rotate session if it is the last @@ -332,9 +332,9 @@ impl Module { /// Move on to next session: register the new authority set. pub fn rotate_session() { // Increment current session index. - let session_index = >::get(); + let session_index = CurrentIndex::get(); - let mut changed = >::take(); + let mut changed = Changed::take(); // See if we have a new validator set. let validators = if let Some(new) = T::OnSessionEnding::on_session_ending(session_index) { @@ -346,7 +346,7 @@ impl Module { }; let session_index = session_index + 1; - >::put(session_index); + CurrentIndex::put(session_index); // Record that this happened. Self::deposit_event(Event::NewSession(session_index)); @@ -361,7 +361,7 @@ impl Module { /// Disable the validator of index `i`. pub fn disable_index(i: usize) { T::SessionHandler::on_disabled(i); - >::put(true); + Changed::put(true); } /// Disable the validator identified by `c`. (If using with the staking module, this would be @@ -384,9 +384,9 @@ mod tests { use srml_support::{impl_outer_origin, assert_ok}; use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; - use primitives::BuildStorage; - use primitives::traits::{BlakeTwo256, IdentityLookup, OnInitialize}; - use primitives::testing::{Header, UintAuthorityId}; + use primitives::{ + traits::{BlakeTwo256, IdentityLookup, OnInitialize}, testing::{Header, UintAuthorityId} + }; impl_outer_origin!{ pub enum Origin for Test {} @@ -466,11 +466,11 @@ mod tests { type Session = Module; fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; - t.extend(timestamp::GenesisConfig::{ + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; + t.extend(timestamp::GenesisConfig:: { minimum_period: 5, }.build_storage().unwrap().0); - t.extend(GenesisConfig::{ + t.extend(GenesisConfig:: { validators: NEXT_VALIDATORS.with(|l| l.borrow().clone()), keys: NEXT_VALIDATORS.with(|l| l.borrow().iter().cloned().map(|i| (i, UintAuthorityId(i))).collect() diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 2159b2069d108..05394ebfcf897 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -1004,7 +1004,7 @@ impl Module { let reward = Self::current_session_reward(); >::mutate(|r| *r += reward); - if >::take() || session_index % T::SessionsPerEra::get() == 0 { + if ForceNewEra::take() || session_index % T::SessionsPerEra::get() == 0 { Self::new_era() } else { None @@ -1032,7 +1032,7 @@ impl Module { } // Increment current era. - >::mutate(|s| *s += 1); + CurrentEra::mutate(|s| *s += 1); // Reassign all Stakers. let (slot_stake, maybe_new_validators) = Self::select_validators(); @@ -1161,7 +1161,7 @@ impl Module { } fn apply_force_new_era() { - >::put(true); + ForceNewEra::put(true); } /// Call when a validator is determined to be offline. `count` is the diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index ea4fcbd8f9f01..0778017186d78 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -17,7 +17,7 @@ //! Test utilities use std::{collections::HashSet, cell::RefCell}; -use primitives::{BuildStorage, Perbill}; +use primitives::Perbill; use primitives::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize}; use primitives::testing::{Header, UintAuthorityId}; use substrate_primitives::{H256, Blake2Hasher}; @@ -179,7 +179,7 @@ impl ExtBuilder { self } pub fn build(self) -> runtime_io::TestExternalities { - let (mut t, mut c) = system::GenesisConfig::::default().build_storage().unwrap(); + let (mut t, mut c) = system::GenesisConfig::default().build_storage::().unwrap(); let balance_factor = if self.existential_deposit > 0 { 256 } else { diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 180ce130ae414..8fcee82a94af4 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -257,7 +257,7 @@ fn max_unstake_threshold_works() { validator_payment: 0, }); - >::put(Perbill::from_fraction(0.0001)); + OfflineSlash::put(Perbill::from_fraction(0.0001)); // Report each user 1 more than the max_unstake_threshold Staking::on_offline_validator(10, MAX_UNSTAKE_THRESHOLD as usize + 1); @@ -688,7 +688,7 @@ fn nominators_also_get_slashed() { assert_eq!(Staking::offline_slash_grace(), 0); // Account 10 has not been reported offline assert_eq!(Staking::slash_count(&10), 0); - >::put(Perbill::from_percent(12)); + OfflineSlash::put(Perbill::from_percent(12)); // Set payee to controller assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller)); diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 3ad53d74538e1..015dd8b1bf9e5 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -470,7 +470,7 @@ fn decl_store_extra_genesis( (quote!(), quote!()) }; - let impl_trait = quote!(CreateModuleGenesisStorage<#traitinstance, #inherent_instance>); + let impl_trait = quote!(BuildModuleGenesisStorage<#traitinstance, #inherent_instance>); let res = quote!{ #[derive(#scrate::Serialize, #scrate::Deserialize)] @@ -495,7 +495,7 @@ fn decl_store_extra_genesis( #[cfg(feature = "std")] impl#fparam_impl GenesisConfig#sparam { - fn build_storage #fn_generic (self) -> std::result::Result< + pub fn build_storage #fn_generic (self) -> std::result::Result< ( #scrate::runtime_primitives::StorageOverlay, #scrate::runtime_primitives::ChildrenStorageOverlay, @@ -509,7 +509,7 @@ fn decl_store_extra_genesis( } /// Assimilate the storage for this module into pre-existing overlays. - fn assimilate_storage #fn_generic ( + pub fn assimilate_storage #fn_generic ( self, r: &mut #scrate::runtime_primitives::StorageOverlay, c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay, @@ -528,7 +528,7 @@ fn decl_store_extra_genesis( impl#build_storage_impl #scrate::runtime_primitives::#impl_trait for GenesisConfig#sparam { - fn create_module_genesis_storage( + fn build_module_genesis_storage( self, r: &mut #scrate::runtime_primitives::StorageOverlay, c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay, diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index eb4b410bb37d5..df7e14fbb76e4 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -34,7 +34,9 @@ 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, Twox64Concat}; +pub use self::storage::hashed::generator::{ + HashedStorage, Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat +}; pub use self::storage::unhashed::generator::UnhashedStorage; #[macro_use] diff --git a/srml/support/src/origin.rs b/srml/support/src/origin.rs index d2627ff529222..f3fec6e3ae6ce 100644 --- a/srml/support/src/origin.rs +++ b/srml/support/src/origin.rs @@ -24,24 +24,24 @@ macro_rules! impl_outer_origin { // Macro transformations (to convert invocations with incomplete parameters to the canonical // form) - ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident { - $( rest:tt )* + $( $rest_without_system:tt )* } ) => { $crate::impl_outer_origin! { $(#[$attr])* pub enum $name for $runtime where system = system { - $( $rest )* + $( $rest_without_system )* } } }; + ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident where system = $system:ident { - $( $rest:tt )* + $( $rest_with_system:tt )* } ) => { $crate::impl_outer_origin!( @@ -49,7 +49,7 @@ macro_rules! impl_outer_origin { $name; $runtime; $system; - Modules { $( $rest )* }; + Modules { $( $rest_with_system )* }; ); }; @@ -60,8 +60,8 @@ macro_rules! impl_outer_origin { $runtime:ident; $system:ident; Modules { - $module:ident $instance:ident , - $( $rest_module:tt )* + $module:ident $instance:ident + $(, $( $rest_module:tt )* )? }; $( $parsed:tt )* ) => { @@ -70,7 +70,7 @@ macro_rules! impl_outer_origin { $name; $runtime; $system; - Modules { $( $rest_module )* }; + Modules { $( $( $rest_module )* )? }; $( $parsed )* $module <$runtime> { $instance }, ); }; @@ -82,8 +82,8 @@ macro_rules! impl_outer_origin { $runtime:ident; $system:ident; Modules { - $module:ident $instance:ident, - $( $rest_module:tt )* + $module:ident $instance:ident + $(, $rest_module:tt )* }; $( $parsed:tt )* ) => { @@ -104,8 +104,8 @@ macro_rules! impl_outer_origin { $runtime:ident; $system:ident; Modules { - $module:ident , - $( $rest_module:tt )* + $module:ident + $(, $( $rest_module:tt )* )? }; $( $parsed:tt )* ) => { @@ -114,7 +114,7 @@ macro_rules! impl_outer_origin { $name; $runtime; $system; - Modules { $( $rest_module )* }; + Modules { $( $( $rest_module )* )? }; $( $parsed )* $module <$runtime>, ); }; @@ -126,8 +126,8 @@ macro_rules! impl_outer_origin { $runtime:ident; $system:ident; Modules { - $module:ident, - $( $rest_module:tt )* + $module:ident + $(, $( $rest_module:tt )* )? }; $( $parsed:tt )* ) => { @@ -136,8 +136,8 @@ macro_rules! impl_outer_origin { $name; $runtime; $system; - Modules { $( $rest_module )* }; - $( $parsed )* $module <$runtime>, + Modules { $( $( $rest_module )* )? }; + $( $parsed )* $module, ); }; diff --git a/srml/support/src/storage/storage_items.rs b/srml/support/src/storage/storage_items.rs index 38f996a6853c1..7a2c2faaace90 100644 --- a/srml/support/src/storage/storage_items.rs +++ b/srml/support/src/storage/storage_items.rs @@ -820,13 +820,13 @@ mod test_map_vec_append { use runtime_io::{with_externalities, TestExternalities}; with_externalities(&mut TestExternalities::default(), || { - let _ = >::append(1, &[1, 2, 3]); - let _ = >::append(1, &[4, 5]); - assert_eq!(>::get(1), vec![1, 2, 3, 4, 5]); + let _ = MapVec::append(1, &[1, 2, 3]); + let _ = MapVec::append(1, &[4, 5]); + assert_eq!(MapVec::get(1), vec![1, 2, 3, 4, 5]); - let _ = >::append(&[1, 2, 3]); - let _ = >::append(&[4, 5]); - assert_eq!(>::get(), vec![1, 2, 3, 4, 5]); + let _ = JustVec::append(&[1, 2, 3]); + let _ = JustVec::append(&[4, 5]); + assert_eq!(JustVec::get(), vec![1, 2, 3, 4, 5]); }); } } diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index 51c7bd7f4ddff..75f0491d9d4c8 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -485,14 +485,14 @@ impl Module { // Index of the to be added event. let event_idx = { - let old_event_count = >::get(); + let old_event_count = EventCount::get(); let new_event_count = match old_event_count.checked_add(1) { // We've reached the maximum number of events at this block, just // don't do anything and leave the event_count unaltered. None => return, Some(nc) => nc, }; - >::put(new_event_count); + EventCount::put(new_event_count); old_event_count }; @@ -529,7 +529,7 @@ impl Module { /// Gets a total weight of all executed extrinsics. pub fn all_extrinsics_weight() -> u32 { - >::get().unwrap_or_default() + AllExtrinsicsWeight::get().unwrap_or_default() } /// Start the execution of a particular block. @@ -553,14 +553,14 @@ impl Module { *index = (*index + 1) % 81; }); >::kill(); - >::kill(); + EventCount::kill(); >::remove_prefix(&()); } /// Remove temporary "environment" entries in storage. pub fn finalize() -> T::Header { - >::kill(); - >::kill(); + ExtrinsicCount::kill(); + AllExtrinsicsWeight::kill(); let number = >::take(); let parent_hash = >::take(); @@ -713,7 +713,7 @@ impl Module { let total_length = encoded_len.saturating_add(Self::all_extrinsics_weight()); storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index); - >::put(&total_length); + AllExtrinsicsWeight::put(&total_length); } /// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block @@ -766,9 +766,7 @@ mod tests { use super::*; use runtime_io::with_externalities; use substrate_primitives::H256; - use primitives::BuildStorage; - use primitives::traits::{BlakeTwo256, IdentityLookup}; - use primitives::testing::Header; + use primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; use srml_support::impl_outer_origin; impl_outer_origin!{ @@ -801,7 +799,7 @@ mod tests { type System = Module; fn new_test_ext() -> runtime_io::TestExternalities { - GenesisConfig::::default().build_storage().unwrap().0.into() + GenesisConfig::default().build_storage::().unwrap().0.into() } #[test] diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index e9c0d85a20a05..7757eade15abf 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -333,9 +333,7 @@ mod tests { use srml_support::{impl_outer_origin, assert_ok}; use runtime_io::{with_externalities, TestExternalities}; use substrate_primitives::H256; - use runtime_primitives::BuildStorage; - use runtime_primitives::traits::{BlakeTwo256, IdentityLookup}; - use runtime_primitives::testing::Header; + use runtime_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { pub enum Origin for Test {} @@ -362,7 +360,7 @@ mod tests { #[test] fn timestamp_works() { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(GenesisConfig:: { minimum_period: 5, }.build_storage().unwrap().0); @@ -377,7 +375,7 @@ mod tests { #[test] #[should_panic(expected = "Timestamp must be updated only once in the block")] fn double_timestamp_should_fail() { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(GenesisConfig:: { minimum_period: 5, }.build_storage().unwrap().0); @@ -392,7 +390,7 @@ mod tests { #[test] #[should_panic(expected = "Timestamp must increment by at least between sequential blocks")] fn block_period_minimum_enforced() { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(GenesisConfig:: { minimum_period: 5, }.build_storage().unwrap().0); diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 664a9fac1978e..e46387ea89d00 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -336,9 +336,7 @@ mod tests { use runtime_io::with_externalities; use srml_support::{impl_outer_origin, assert_ok, assert_noop}; use substrate_primitives::{H256, Blake2Hasher}; - use runtime_primitives::BuildStorage; - use runtime_primitives::traits::{BlakeTwo256, OnFinalize, IdentityLookup}; - use runtime_primitives::testing::Header; + use runtime_primitives::{traits::{BlakeTwo256, OnFinalize, IdentityLookup}, testing::Header}; impl_outer_origin! { pub enum Origin for Test {} @@ -378,7 +376,7 @@ mod tests { type Treasury = Module; fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(balances::GenesisConfig::{ balances: vec![(0, 100), (1, 99), (2, 1)], transaction_base_fee: 0, From 311181fdf79fd8b797f2725ff0f9cb27b7097d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 20 Jun 2019 10:34:10 +0200 Subject: [PATCH 10/14] Break some lines --- srml/support/procedural/src/storage/impls.rs | 12 +++++++++--- .../support/procedural/src/storage/transformation.rs | 10 ++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/srml/support/procedural/src/storage/impls.rs b/srml/support/procedural/src/storage/impls.rs index 2322212ba9f62..e5cb4c93b4a3d 100644 --- a/srml/support/procedural/src/storage/impls.rs +++ b/srml/support/procedural/src/storage/impls.rs @@ -337,8 +337,10 @@ impl<'a, I: Iterator> Impls<'a, I> { } }; - let (struct_trait, impl_trait, trait_and_instance, trait_lifetime) = if ext::type_contains_ident(value_type, traitinstance) - || ext::type_contains_ident(kty, traitinstance) + let (struct_trait, impl_trait, trait_and_instance, trait_lifetime) = if ext::type_contains_ident( + value_type, + traitinstance + ) || ext::type_contains_ident(kty, traitinstance) { ( quote!(#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance), @@ -697,7 +699,11 @@ impl<'a, I: Iterator> Impls<'a, I> { quote!(#traitinstance, #instance), ) } else { - (quote!(#instance #bound_instantiable #equal_default_instance), quote!(#instance #bound_instantiable), quote!(#instance)) + ( + quote!(#instance #bound_instantiable #equal_default_instance), + quote!(#instance #bound_instantiable), + quote!(#instance) + ) }; // generator for double map diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 015dd8b1bf9e5..48c342d3f34af 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -847,7 +847,10 @@ fn impl_store_fns( quote!{ #( #[ #attrs ] )* pub fn #get_fn>(key: K) -> #value_type { - <#name<#struct_trait #instance> as #scrate::storage::hashed::generator::StorageMap<#key_type, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) + < + #name<#struct_trait #instance> as + #scrate::storage::hashed::generator::StorageMap<#key_type, #typ> + >::get(key.borrow(), &#scrate::storage::RuntimeStorage) } } } @@ -867,7 +870,10 @@ fn impl_store_fns( KArg1: #scrate::rstd::borrow::Borrow<#key1_type>, KArg2: #scrate::rstd::borrow::Borrow<#key2_type>, { - <#name<#struct_trait #instance> as #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ>> :: get(k1.borrow(), k2.borrow(), &#scrate::storage::RuntimeStorage) + < + #name<#struct_trait #instance> as + #scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ> + >::get(k1.borrow(), k2.borrow(), &#scrate::storage::RuntimeStorage) } } } From 69fe2dc4ed75197a53e82f4b0fde27448ad41220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 20 Jun 2019 22:00:02 +0200 Subject: [PATCH 11/14] Remove incorrect macro match arm --- srml/support/src/runtime.rs | 36 +++++------------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/srml/support/src/runtime.rs b/srml/support/src/runtime.rs index 6afae17c3d38a..4461e37518698 100644 --- a/srml/support/src/runtime.rs +++ b/srml/support/src/runtime.rs @@ -115,43 +115,17 @@ macro_rules! construct_runtime { $( $rest )* ); }; + // `default` identifier given, expand to default + given extra modules ( { $( $preset:tt )* }; { $( $expanded:tt )* }; $name:ident: $module:ident::{ default $(, - $modules:ident - $( <$modules_generic:ident $(, $modules_instance:ident)?> )* - $( ( $( $modules_args:ident ),* ) )* - )* - }, - $( $rest:tt )* - ) => { - $crate::construct_runtime!( - { $( $preset )* }; - { $( $expanded )* }; - $name: $module::{ - Module, Call, Storage, Event, Config - $(, - $modules $( <$modules_generic $(, $modules_instance)?> )* - $( ( $( $modules_args ),* ) )* - )* - }, - $( $rest )* - ); - }; - // `default` identifier given, expand to default + given extra modules - ( - { $( $preset:tt )* }; - { $( $expanded:tt )* }; - $name:ident: $module:ident::{ - default, - $( $modules:ident $( <$modules_generic:ident> )* $( ( $( $modules_args:ident ),* ) )* - ),* + )* }, $( $rest:tt )* ) => { @@ -160,11 +134,11 @@ macro_rules! construct_runtime { { $( $expanded )* $name: $module::{ - Module, Call, Storage, Event, Config, - $( + Module, Call, Storage, Event, Config + $(, $modules $( <$modules_generic> )* $( ( $( $modules_args ),* ) )* - ),* + )* }, }; $( $rest )* From 23d13b3d9b9c83de2291d42bf16d7089354fe6fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 21 Jun 2019 22:19:52 +0200 Subject: [PATCH 12/14] Integrates review feedback --- node-template/runtime/src/template.rs | 6 +-- srml/democracy/src/lib.rs | 2 +- srml/grandpa/src/mock.rs | 2 +- .../procedural/src/storage/transformation.rs | 50 +++++++++++-------- srml/support/src/lib.rs | 2 +- srml/support/test/tests/genesisconfig.rs | 44 ++++++++++++++++ 6 files changed, 76 insertions(+), 30 deletions(-) create mode 100644 srml/support/test/tests/genesisconfig.rs diff --git a/node-template/runtime/src/template.rs b/node-template/runtime/src/template.rs index e638dee41dcd1..3d53c08300ea9 100644 --- a/node-template/runtime/src/template.rs +++ b/node-template/runtime/src/template.rs @@ -72,11 +72,7 @@ mod tests { use runtime_io::with_externalities; use primitives::{H256, Blake2Hasher}; use support::{impl_outer_origin, assert_ok}; - use runtime_primitives::{ - BuildStorage, - traits::{BlakeTwo256, IdentityLookup}, - testing::Header, - }; + use runtime_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { pub enum Origin for Test {} diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index a2d037dd28cce..c962560cc9859 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -1007,7 +1007,7 @@ mod tests { creation_fee: 0, vesting: vec![], }.build_storage().unwrap().0); - t.extend(GenesisConfig::default().build_storage::().unwrap().0); + t.extend(GenesisConfig::default().build_storage().unwrap().0); runtime_io::TestExternalities::new(t) } diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs index 3d1e2f1396a7e..5f2aeee34f5cb 100644 --- a/srml/grandpa/src/mock.rs +++ b/srml/grandpa/src/mock.rs @@ -73,7 +73,7 @@ pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternaliti let mut t = system::GenesisConfig::default().build_storage::().unwrap().0; t.extend(GenesisConfig { authorities: to_authorities(authorities), - }.build_storage::().unwrap().0); + }.build_storage().unwrap().0); t.into() } diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs index 48c342d3f34af..5f82db5583456 100644 --- a/srml/support/procedural/src/storage/transformation.rs +++ b/srml/support/procedural/src/storage/transformation.rs @@ -204,7 +204,8 @@ fn decl_store_extra_genesis( let mut config_field = TokenStream2::new(); let mut config_field_default = TokenStream2::new(); let mut builders = TokenStream2::new(); - let mut assimilate_require_generic = false; + let mut assimilate_require_generic = instance.is_some(); + let mut builders_clone_bound = Vec::new(); for sline in storage_lines.inner.iter() { let DeclStorageLine { @@ -246,19 +247,36 @@ fn decl_store_extra_genesis( ); }; - if type_infos.kind.is_simple() - && ext::type_contains_ident(type_infos.value_type, traitinstance) { + if ext::type_contains_ident(type_infos.value_type, traitinstance) { is_trait_needed = true; } + if opt_build.is_none() { + builders_clone_bound.push(type_infos.value_type.clone()); + } + let value_type = &type_infos.value_type; serde_complete_bound.push(quote!( #value_type )); match type_infos.kind { - DeclStorageTypeInfosKind::Map { key_type, .. } => - serde_complete_bound.push(quote!( #key_type )), + DeclStorageTypeInfosKind::Map { key_type, .. } => { + serde_complete_bound.push(quote!( #key_type )); + is_trait_needed = is_trait_needed + || ext::type_contains_ident(key_type, traitinstance); + + if opt_build.is_none() { + builders_clone_bound.push(key_type.clone()); + } + }, DeclStorageTypeInfosKind::DoubleMap { key1_type, key2_type, .. } => { serde_complete_bound.push(quote!( #key1_type )); serde_complete_bound.push(quote!( #key2_type )); + is_trait_needed = is_trait_needed + || ext::type_contains_ident(key1_type, traitinstance) + || ext::type_contains_ident(key2_type, traitinstance); + if opt_build.is_none() { + builders_clone_bound.push(key1_type.clone()); + builders_clone_bound.push(key2_type.clone()); + } }, _ => {}, } @@ -292,18 +310,13 @@ fn decl_store_extra_genesis( config_field_default.extend(quote!( #ident: #fielddefault, )); - opt_build - .map(Some) - .unwrap_or_else(|| - Some(quote!( (|config: &Self| config.#ident.clone()) )) - ) + opt_build.or_else(|| Some(quote!( (|config: &Self| config.#ident.clone()) ))) } else { opt_build }; let typ = type_infos.typ; if let Some(builder) = builder { - assimilate_require_generic = true; builders.extend(match type_infos.kind { DeclStorageTypeInfosKind::Simple => { let struct_trait = if ext::type_contains_ident(&type_infos.value_type, traitinstance) { @@ -472,6 +485,8 @@ fn decl_store_extra_genesis( let impl_trait = quote!(BuildModuleGenesisStorage<#traitinstance, #inherent_instance>); + let builders_clone_bound = quote!( #( #builders_clone_bound: Clone ),* ); + let res = quote!{ #[derive(#scrate::Serialize, #scrate::Deserialize)] #[cfg(feature = "std")] @@ -494,7 +509,7 @@ fn decl_store_extra_genesis( } #[cfg(feature = "std")] - impl#fparam_impl GenesisConfig#sparam { + impl#fparam_impl GenesisConfig#sparam where #builders_clone_bound { pub fn build_storage #fn_generic (self) -> std::result::Result< ( #scrate::runtime_primitives::StorageOverlay, @@ -526,7 +541,7 @@ fn decl_store_extra_genesis( #[cfg(feature = "std")] impl#build_storage_impl #scrate::runtime_primitives::#impl_trait - for GenesisConfig#sparam + for GenesisConfig#sparam where #builders_clone_bound { fn build_module_genesis_storage( self, @@ -1059,15 +1074,6 @@ enum DeclStorageTypeInfosKind<'a> { } } -impl<'a> DeclStorageTypeInfosKind<'a> { - fn is_simple(&self) -> bool { - match *self { - DeclStorageTypeInfosKind::Simple => true, - _ => false, - } - } -} - fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { let (value_type, kind) = match storage_type { DeclStorageType::Simple(ref st) => (st, DeclStorageTypeInfosKind::Simple), diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index df7e14fbb76e4..7b011b3a11119 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -284,7 +284,7 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { - GenesisConfig::default().build_storage::().unwrap().0.into() + GenesisConfig::default().build_storage().unwrap().0.into() } type Map = Data; diff --git a/srml/support/test/tests/genesisconfig.rs b/srml/support/test/tests/genesisconfig.rs new file mode 100644 index 0000000000000..717c7105b587b --- /dev/null +++ b/srml/support/test/tests/genesisconfig.rs @@ -0,0 +1,44 @@ +// 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 . + +pub trait Trait { + type BlockNumber: parity_codec::Codec + Default; + type Origin; +} + +srml_support::decl_module! { + pub struct Module for enum Call where origin: T::Origin {} +} + +srml_support::decl_storage! { + trait Store for Module as Example { + pub AppendableDM config(t): double_map u32, blake2_256(T::BlockNumber) => Vec; + } +} + +struct Test; + +impl Trait for Test { + type BlockNumber = u32; + type Origin = (); +} + +#[test] +fn init_genesis_config() { + GenesisConfig:: { + t: Default::default(), + }; +} \ No newline at end of file From 8dd12b7d0a32730efe2eea4385e98ea7c2240be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 22 Jun 2019 09:26:01 +0200 Subject: [PATCH 13/14] Update documentation --- srml/support/procedural/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/srml/support/procedural/src/lib.rs b/srml/support/procedural/src/lib.rs index 280d2a317d14e..9c24c98f2483e 100644 --- a/srml/support/procedural/src/lib.rs +++ b/srml/support/procedural/src/lib.rs @@ -98,7 +98,7 @@ use proc_macro::TokenStream; /// /// Storage items are accessible in multiple ways: /// -/// * The structure: `Foo::` +/// * The structure: `Foo` or `Foo::` depending if the value type is generic or not. /// * The `Store` trait structure: ` as Store>::Foo` /// * The getter on the module that calls get on the structure: `Module::::foo()` /// @@ -136,9 +136,9 @@ use proc_macro::TokenStream; /// trait Store for Module, I: Instance=DefaultInstance> as Example {} /// ``` /// -/// Then the genesis config is generated with two generic parameters (i.e. `GenesisConfig`) -/// and storage items are accessible using two generic parameters, e.g.: -/// `>::get()` or `Dummy::::get()`. +/// Accessing the structure no requires the instance as generic parameter: +/// * `Foo::` if the value type is not generic +/// * `Foo::` if the value type is generic #[proc_macro] pub fn decl_storage(input: TokenStream) -> TokenStream { storage::transformation::decl_storage_impl(input) From 0fba321fe0a99eea0a73471a241e6c1589814245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 27 Jun 2019 12:31:59 +0200 Subject: [PATCH 14/14] Fix compilation --- Cargo.lock | 3 +-- core/test-runtime/wasm/Cargo.lock | 1 + node-template/runtime/wasm/Cargo.lock | 1 + node/runtime/wasm/Cargo.lock | 1 + srml/authorship/src/lib.rs | 7 +++---- srml/contracts/src/gas.rs | 2 +- srml/contracts/src/lib.rs | 4 ++-- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3409c247f686..c4046197a37f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3425,6 +3425,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3642,9 +3643,7 @@ dependencies = [ name = "srml-finality-tracker" version = "2.0.0" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", diff --git a/core/test-runtime/wasm/Cargo.lock b/core/test-runtime/wasm/Cargo.lock index 8158de71bc504..849412d19b8ee 100644 --- a/core/test-runtime/wasm/Cargo.lock +++ b/core/test-runtime/wasm/Cargo.lock @@ -2334,6 +2334,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", diff --git a/node-template/runtime/wasm/Cargo.lock b/node-template/runtime/wasm/Cargo.lock index c2e2a043c9854..f1691ede426ae 100644 --- a/node-template/runtime/wasm/Cargo.lock +++ b/node-template/runtime/wasm/Cargo.lock @@ -2366,6 +2366,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", diff --git a/node/runtime/wasm/Cargo.lock b/node/runtime/wasm/Cargo.lock index 048c03a00065e..4085234f271f9 100644 --- a/node/runtime/wasm/Cargo.lock +++ b/node/runtime/wasm/Cargo.lock @@ -2398,6 +2398,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-std 2.0.0", diff --git a/srml/authorship/src/lib.rs b/srml/authorship/src/lib.rs index 42deeceb628d4..8add05bb5930d 100644 --- a/srml/authorship/src/lib.rs +++ b/srml/authorship/src/lib.rs @@ -312,7 +312,6 @@ mod tests { use super::*; use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; - use primitives::BuildStorage; use primitives::traits::{BlakeTwo256, IdentityLookup}; use primitives::testing::Header; use primitives::generic::DigestItem; @@ -421,7 +420,7 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { - let t = system::GenesisConfig::::default().build_storage().unwrap().0; + let t = system::GenesisConfig::default().build_storage::().unwrap().0; t.into() } @@ -499,7 +498,7 @@ mod tests { ); assert!( - Authorship::verify_and_import_uncles(vec![uncle_a.clone()]).is_ok(); + Authorship::verify_and_import_uncles(vec![uncle_a.clone()]).is_ok() ); assert_eq!( @@ -551,7 +550,7 @@ mod tests { ); assert!( - Authorship::verify_and_import_uncles(vec![other_8]).is_ok(); + Authorship::verify_and_import_uncles(vec![other_8]).is_ok() ); } }); diff --git a/srml/contracts/src/gas.rs b/srml/contracts/src/gas.rs index 1251584b55a5e..634b11d3db2ef 100644 --- a/srml/contracts/src/gas.rs +++ b/srml/contracts/src/gas.rs @@ -253,7 +253,7 @@ pub fn refund_unused_gas( // Increase total spent gas. // This cannot overflow, since `gas_spent` is never greater than `block_gas_limit`, which // also has Gas type. - >::mutate(|block_gas_spent| *block_gas_spent += gas_spent); + GasSpent::mutate(|block_gas_spent| *block_gas_spent += gas_spent); // Refund gas left by the price it was bought at. let refund = gas_meter.gas_price * gas_left.unique_saturated_into(); diff --git a/srml/contracts/src/lib.rs b/srml/contracts/src/lib.rs index 95e47a30a03bf..93e54320f06b2 100644 --- a/srml/contracts/src/lib.rs +++ b/srml/contracts/src/lib.rs @@ -353,7 +353,7 @@ decl_module! { } Self::deposit_event(RawEvent::ScheduleUpdated(schedule.version)); - >::put(schedule); + CurrentSchedule::put(schedule); Ok(()) } @@ -609,7 +609,7 @@ decl_module! { } fn on_finalize() { - >::kill(); + GasSpent::kill(); } } }