mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Implement a proper generic resolution in decl_storage! (#2913)
* Add failing test case * 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 <gui.thiolliere@gmail.com> * impl twox 128 concat (#2353) * impl twox_128_concat * comment addressed * fix * impl twox_128->64_concat * fix test * Fix compilation and cleanup some docs * Lol * Remove traits from storage types that are not generic * Get instance test almost working as wanted * Make `srml-support-test` compile again :) * Fixes test of srml-support * Fix compilation * Break some lines * Remove incorrect macro match arm * Integrates review feedback * Update documentation * Fix compilation
This commit is contained in:
Generated
+1
-2
@@ -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",
|
||||
|
||||
@@ -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"}
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1.0"
|
||||
|
||||
@@ -28,6 +28,9 @@ pub use serde;
|
||||
#[doc(hidden)]
|
||||
pub use rstd;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use paste;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use runtime_io::{StorageOverlay, ChildrenStorageOverlay};
|
||||
|
||||
@@ -101,7 +104,22 @@ 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>;
|
||||
}
|
||||
|
||||
/// Somethig that can build the genesis storage of a module.
|
||||
#[cfg(feature = "std")]
|
||||
pub trait BuildModuleGenesisStorage<T, I>: Sized {
|
||||
/// Create the module genesis storage into the given `storage` and `child_storage`.
|
||||
fn build_module_genesis_storage(
|
||||
self,
|
||||
storage: &mut StorageOverlay,
|
||||
child_storage: &mut ChildrenStorageOverlay
|
||||
) -> Result<(), String>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@@ -585,26 +603,32 @@ pub fn verify_encoded_lazy<V: Verify, T: codec::Encode>(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) => ()
|
||||
}
|
||||
@@ -619,30 +643,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::BuildModuleGenesisStorage::<$runtime, $module::$instance>::build_module_genesis_storage(
|
||||
$extra,
|
||||
$top,
|
||||
$children,
|
||||
)?;
|
||||
};
|
||||
(@CALL_FN
|
||||
$runtime:ident;
|
||||
$module:ident;
|
||||
;
|
||||
$extra:ident;
|
||||
$top:ident;
|
||||
$children:ident;
|
||||
) => {
|
||||
$crate::BuildModuleGenesisStorage::<$runtime, $module::__InherentHiddenInstance>::build_module_genesis_storage(
|
||||
$extra,
|
||||
$top,
|
||||
$children,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -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",
|
||||
|
||||
@@ -183,7 +183,7 @@ construct_runtime!(
|
||||
NodeBlock = opaque::Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic
|
||||
{
|
||||
System: system::{default, Config<T>},
|
||||
System: system::{Module, Call, Storage, Config, Event},
|
||||
Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
|
||||
Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
|
||||
Indices: indices::{default, Config<T>},
|
||||
|
||||
@@ -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
|
||||
<Something<T>>::put(something);
|
||||
Something::put(something);
|
||||
|
||||
// here we are raising the Something event
|
||||
Self::deposit_event(RawEvent::SomethingStored(something, who));
|
||||
@@ -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 {}
|
||||
@@ -106,7 +102,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<Blake2Hasher> {
|
||||
system::GenesisConfig::<Test>::default().build_storage().unwrap().0.into()
|
||||
system::GenesisConfig::default().build_storage::<Test>().unwrap().0.into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+1
@@ -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",
|
||||
|
||||
@@ -93,7 +93,6 @@ fn testnet_genesis(initial_authorities: Vec<AuthorityId>, 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(),
|
||||
|
||||
@@ -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 {
|
||||
@@ -191,7 +190,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(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -274,7 +272,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(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -246,19 +246,19 @@ construct_runtime!(
|
||||
NodeBlock = node_primitives::Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic
|
||||
{
|
||||
System: system,
|
||||
System: system::{Module, Call, Storage, Config, Event},
|
||||
Aura: aura::{Module, Config<T>, Inherent(Timestamp)},
|
||||
Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
|
||||
Indices: indices,
|
||||
Balances: balances,
|
||||
Session: session::{Module, Call, Storage, Event, Config<T>},
|
||||
Staking: staking::{default, OfflineWorker},
|
||||
Democracy: democracy,
|
||||
Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
|
||||
Council: council::{Module, Call, Storage, Event<T>},
|
||||
CouncilMotions: council_motions::{Module, Call, Storage, Event<T>, Origin<T>},
|
||||
CouncilSeats: council_seats::{Config<T>},
|
||||
FinalityTracker: finality_tracker::{Module, Call, Inherent},
|
||||
Grandpa: grandpa::{Module, Call, Storage, Config<T>, Event},
|
||||
Grandpa: grandpa::{Module, Call, Storage, Config, Event},
|
||||
Treasury: treasury,
|
||||
Contracts: contracts,
|
||||
Sudo: sudo,
|
||||
|
||||
Generated
+1
@@ -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",
|
||||
|
||||
@@ -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<Blake2Hasher> {
|
||||
system::GenesisConfig::<Test>::default().build_storage().unwrap().0.into()
|
||||
system::GenesisConfig::default().build_storage::<Test>().unwrap().0.into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -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<u64>) -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(timestamp::GenesisConfig::<Test>{
|
||||
minimum_period: 1,
|
||||
}.build_storage().unwrap().0);
|
||||
|
||||
@@ -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<Blake2Hasher> {
|
||||
let t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
let t = system::GenesisConfig::default().build_storage::<Test>().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()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -135,7 +135,7 @@ impl<T: Trait> OnTimestampSet<T::Moment> for Module<T> {
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
fn change_authorities(new: Vec<AuthorityId>) {
|
||||
<Authorities<T>>::put(&new);
|
||||
Authorities::put(&new);
|
||||
|
||||
let log: DigestItem<T::Hash> = DigestItem::Consensus(BABE_ENGINE_ID, new.encode());
|
||||
<system::Module<T>>::deposit_log(log.into());
|
||||
|
||||
@@ -335,7 +335,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! {
|
||||
|
||||
@@ -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<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Runtime>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Runtime>().unwrap().0;
|
||||
t.extend(GenesisConfig::<Runtime> {
|
||||
transaction_base_fee: self.transaction_base_fee,
|
||||
transaction_byte_fee: self.transaction_byte_fee,
|
||||
|
||||
@@ -253,7 +253,7 @@ pub fn refund_unused_gas<T: Trait>(
|
||||
// Increase total spent gas.
|
||||
// This cannot overflow, since `gas_spent` is never greater than `block_gas_limit`, which
|
||||
// also has Gas type.
|
||||
<GasSpent<T>>::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();
|
||||
|
||||
@@ -257,7 +257,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 = <AccountCounter<T>>::mutate(|v| {
|
||||
let new_seed = AccountCounter::mutate(|v| {
|
||||
*v = v.wrapping_add(1);
|
||||
*v
|
||||
});
|
||||
@@ -353,7 +353,7 @@ decl_module! {
|
||||
}
|
||||
|
||||
Self::deposit_event(RawEvent::ScheduleUpdated(schedule.version));
|
||||
<CurrentSchedule<T>>::put(schedule);
|
||||
CurrentSchedule::put(schedule);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -609,7 +609,7 @@ decl_module! {
|
||||
}
|
||||
|
||||
fn on_finalize() {
|
||||
<GasSpent<T>>::kill();
|
||||
GasSpent::kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ impl TrieIdGenerator<u64> for DummyTrieIdGenerator {
|
||||
fn trie_id(account_id: &u64) -> TrieId {
|
||||
use substrate_primitives::storage::well_known_keys;
|
||||
|
||||
let new_seed = <super::AccountCounter<Test>>::mutate(|v| {
|
||||
let new_seed = super::AccountCounter::mutate(|v| {
|
||||
*v = v.wrapping_add(1);
|
||||
*v
|
||||
});
|
||||
@@ -183,10 +183,7 @@ impl ExtBuilder {
|
||||
self
|
||||
}
|
||||
pub fn build(self) -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default()
|
||||
.build_storage()
|
||||
.unwrap()
|
||||
.0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(
|
||||
balances::GenesisConfig::<Test> {
|
||||
transaction_base_fee: 0,
|
||||
|
||||
@@ -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<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
t.extend(balances::GenesisConfig::<Test>{
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(balances::GenesisConfig::<Test> {
|
||||
transaction_base_fee: 0,
|
||||
transaction_byte_fee: 0,
|
||||
balances: vec![
|
||||
|
||||
@@ -139,7 +139,7 @@ decl_module! {
|
||||
Self::deposit_event(RawEvent::Executed(proposal_hash, ok));
|
||||
} else {
|
||||
let index = Self::proposal_count();
|
||||
<ProposalCount<T>>::mutate(|i| *i += 1);
|
||||
ProposalCount::mutate(|i| *i += 1);
|
||||
<Proposals<T>>::mutate(|proposals| proposals.push(proposal_hash));
|
||||
<ProposalOf<T>>::insert(proposal_hash, *proposal);
|
||||
let votes = Votes { index, threshold, ayes: vec![who.clone()], nays: vec![] };
|
||||
|
||||
@@ -329,7 +329,7 @@ decl_module! {
|
||||
candidates[slot] = who;
|
||||
}
|
||||
<Candidates<T>>::put(candidates);
|
||||
<CandidateCount<T>>::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.
|
||||
@@ -409,7 +409,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) {
|
||||
<DesiredSeats<T>>::put(count);
|
||||
DesiredSeats::put(count);
|
||||
}
|
||||
|
||||
/// Remove a particular member from the council. This is effective immediately.
|
||||
@@ -613,7 +613,7 @@ impl<T: Trait> Module<T> {
|
||||
let mut set = Self::voters(set_index);
|
||||
set[vec_index] = None;
|
||||
<Voters<T>>::insert(set_index, set);
|
||||
<VoterCount<T>>::mutate(|c| *c = *c - 1);
|
||||
VoterCount::mutate(|c| *c = *c - 1);
|
||||
Self::remove_all_approvals_of(voter);
|
||||
<VoterInfoOf<T>>::remove(voter);
|
||||
}
|
||||
@@ -683,7 +683,7 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
|
||||
T::Currency::reserve(&who, Self::voting_bond())?;
|
||||
<VoterCount<T>>::mutate(|c| *c = *c + 1);
|
||||
VoterCount::mutate(|c| *c = *c + 1);
|
||||
}
|
||||
|
||||
T::Currency::set_lock(
|
||||
@@ -802,8 +802,8 @@ impl<T: Trait> Module<T> {
|
||||
Self::deposit_event(RawEvent::TallyFinalized(incoming, outgoing));
|
||||
|
||||
<Candidates<T>>::put(new_candidates);
|
||||
<CandidateCount<T>>::put(count);
|
||||
<VoteCount<T>>::put(Self::vote_index() + 1);
|
||||
CandidateCount::put(count);
|
||||
VoteCount::put(Self::vote_index() + 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -815,7 +815,7 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
set.push(Some(who));
|
||||
if len + 1 == VOTER_SET_SIZE {
|
||||
<NextVoterSet<T>>::put(index + 1);
|
||||
NextVoterSet::put(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1356,7 +1356,7 @@ mod tests {
|
||||
let mut t = ExtBuilder::default().build();
|
||||
with_externalities(&mut t, || {
|
||||
<Candidates<Test>>::put(vec![0, 0, 1]);
|
||||
<CandidateCount<Test>>::put(1);
|
||||
CandidateCount::put(1);
|
||||
<RegisterInfoOf<Test>>::insert(1, (0, 2));
|
||||
});
|
||||
t
|
||||
|
||||
@@ -337,7 +337,7 @@ decl_module! {
|
||||
.map_err(|_| "proposer's balance too low")?;
|
||||
|
||||
let index = Self::public_prop_count();
|
||||
<PublicPropCount<T>>::put(index + 1);
|
||||
PublicPropCount::put(index + 1);
|
||||
<DepositOf<T>>::insert(index, (value, vec![who.clone()]));
|
||||
|
||||
let mut props = Self::public_props();
|
||||
@@ -751,7 +751,7 @@ impl<T: Trait> Module<T> {
|
||||
Err("Cannot inject a referendum that ends earlier than preceeding referendum")?
|
||||
}
|
||||
|
||||
<ReferendumCount<T>>::put(ref_index + 1);
|
||||
ReferendumCount::put(ref_index + 1);
|
||||
let item = ReferendumInfo { end, proposal, threshold, delay };
|
||||
<ReferendumInfoOf<T>>::insert(ref_index, item);
|
||||
Self::deposit_event(RawEvent::Started(ref_index, threshold));
|
||||
@@ -775,7 +775,7 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
/// Table the next waiting proposal for a vote.
|
||||
fn launch_next(now: T::BlockNumber) -> Result {
|
||||
if <LastTabledWasExternal<T>>::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<T: Trait> Module<T> {
|
||||
/// Table the waiting external proposal for a vote, if there is one.
|
||||
fn launch_external(now: T::BlockNumber) -> Result {
|
||||
if let Some((proposal, threshold)) = <NextExternal<T>>::take() {
|
||||
<LastTabledWasExternal<T>>::put(true);
|
||||
LastTabledWasExternal::put(true);
|
||||
Self::deposit_event(RawEvent::ExternalTabled);
|
||||
Self::inject_referendum(
|
||||
now + T::VotingPeriod::get(),
|
||||
@@ -875,7 +875,7 @@ impl<T: Trait> Module<T> {
|
||||
} else {
|
||||
Self::deposit_event(RawEvent::NotPassed(index));
|
||||
}
|
||||
<NextTally<T>>::put(index + 1);
|
||||
NextTally::put(index + 1);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -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<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(balances::GenesisConfig::<Test>{
|
||||
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::<Test>::default().build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::default().build_storage().unwrap().0);
|
||||
runtime_io::TestExternalities::new(t)
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
// We use default for brevity, but you can configure as desired if needed.
|
||||
t.extend(balances::GenesisConfig::<Test>::default().build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
|
||||
@@ -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::<Runtime>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Runtime>().unwrap().0;
|
||||
t.extend(balances::GenesisConfig::<Runtime> {
|
||||
transaction_base_fee: 10,
|
||||
transaction_byte_fee: 0,
|
||||
@@ -493,7 +493,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Runtime>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Runtime>().unwrap().0;
|
||||
t.extend(balances::GenesisConfig::<Runtime>::default().build_storage().unwrap().0);
|
||||
t.into()
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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_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<u64>;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
}
|
||||
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<u64>;
|
||||
type Header = Header;
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
type System = system::Module<Test>;
|
||||
type System = system::Module<Test>;
|
||||
|
||||
lazy_static! {
|
||||
static ref NOTIFICATIONS: Mutex<Vec<StallEvent>> = Mutex::new(Vec::new());
|
||||
}
|
||||
thread_local! {
|
||||
static NOTIFICATIONS: std::cell::RefCell<Vec<StallEvent>> = Default::default();
|
||||
}
|
||||
|
||||
pub struct StallTracker;
|
||||
impl OnFinalizationStalled<u64> 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;
|
||||
}
|
||||
|
||||
type FinalityTracker = Module<Test>;
|
||||
pub struct StallTracker;
|
||||
impl OnFinalizationStalled<u64> 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>;
|
||||
|
||||
#[test]
|
||||
fn median_works() {
|
||||
make_test_context!();
|
||||
let t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
let t = system::GenesisConfig::default().build_storage::<Test>().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::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
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::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
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()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ decl_module! {
|
||||
}
|
||||
|
||||
if block_number == pending_change.scheduled_at + pending_change.delay {
|
||||
<Authorities<T>>::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<T: Trait> Module<T> {
|
||||
/// Get the current set of authorities, along with their respective weights.
|
||||
pub fn grandpa_authorities() -> Vec<(AuthorityId, u64)> {
|
||||
<Authorities<T>>::get()
|
||||
Authorities::get()
|
||||
}
|
||||
|
||||
/// Schedule a change in the authorities.
|
||||
|
||||
@@ -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,9 +70,8 @@ pub fn to_authorities(vec: Vec<(u64, u64)>) -> Vec<(AuthorityId, u64)> {
|
||||
}
|
||||
|
||||
pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
_genesis_phantom_data: Default::default(),
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(GenesisConfig {
|
||||
authorities: to_authorities(authorities),
|
||||
}.build_storage().unwrap().0);
|
||||
t.into()
|
||||
|
||||
@@ -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<Blake2Hasher> {
|
||||
for i in 1..5 { h.insert(i); }
|
||||
}
|
||||
|
||||
let mut t = system::GenesisConfig::<Runtime>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Runtime>().unwrap().0;
|
||||
t.extend(GenesisConfig::<Runtime> {
|
||||
ids: vec![1, 2, 3, 4]
|
||||
}.build_storage().unwrap().0);
|
||||
|
||||
@@ -293,7 +293,7 @@ decl_module! {
|
||||
updates.push(None);
|
||||
continue;
|
||||
}
|
||||
let mut active = <Active<T>>::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()),
|
||||
@@ -313,12 +313,12 @@ decl_module! {
|
||||
|
||||
// Update the active sets.
|
||||
for (i, active) in updates.into_iter().filter_map(|x| x) {
|
||||
<Active<T>>::insert(i as u32, active);
|
||||
Active::insert(i as u32, active);
|
||||
}
|
||||
// Set new keys value for next session.
|
||||
<NextKeyFor<T>>::insert(who, keys);
|
||||
// Something changed.
|
||||
<Changed<T>>::put(true);
|
||||
Changed::put(true);
|
||||
}
|
||||
|
||||
/// Called when a block is finalized. Will rotate session if it is the last
|
||||
@@ -335,9 +335,9 @@ impl<T: Trait> Module<T> {
|
||||
/// Move on to next session: register the new authority set.
|
||||
pub fn rotate_session() {
|
||||
// Increment current session index.
|
||||
let session_index = <CurrentIndex<T>>::get();
|
||||
let session_index = CurrentIndex::get();
|
||||
|
||||
let mut changed = <Changed<T>>::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) {
|
||||
@@ -349,7 +349,7 @@ impl<T: Trait> Module<T> {
|
||||
};
|
||||
|
||||
let session_index = session_index + 1;
|
||||
<CurrentIndex<T>>::put(session_index);
|
||||
CurrentIndex::put(session_index);
|
||||
|
||||
// Record that this happened.
|
||||
Self::deposit_event(Event::NewSession(session_index));
|
||||
@@ -364,7 +364,7 @@ impl<T: Trait> Module<T> {
|
||||
/// Disable the validator of index `i`.
|
||||
pub fn disable_index(i: usize) {
|
||||
T::SessionHandler::on_disabled(i);
|
||||
<Changed<T>>::put(true);
|
||||
Changed::put(true);
|
||||
}
|
||||
|
||||
/// Disable the validator identified by `c`. (If using with the staking module, this would be
|
||||
@@ -405,9 +405,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 {}
|
||||
@@ -487,11 +487,11 @@ mod tests {
|
||||
type Session = Module<Test>;
|
||||
|
||||
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
t.extend(timestamp::GenesisConfig::<Test>{
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(timestamp::GenesisConfig::<Test> {
|
||||
minimum_period: 5,
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
validators: NEXT_VALIDATORS.with(|l| l.borrow().clone()),
|
||||
keys: NEXT_VALIDATORS.with(|l|
|
||||
l.borrow().iter().cloned().map(|i| (i, UintAuthorityId(i))).collect()
|
||||
|
||||
@@ -866,7 +866,7 @@ decl_module! {
|
||||
|
||||
/// The ideal number of validators.
|
||||
fn set_validator_count(#[compact] new: u32) {
|
||||
<ValidatorCount<T>>::put(new);
|
||||
ValidatorCount::put(new);
|
||||
}
|
||||
|
||||
// ----- Root calls.
|
||||
@@ -885,7 +885,7 @@ decl_module! {
|
||||
|
||||
/// Set the offline slash grace period.
|
||||
fn set_offline_slash_grace(#[compact] new: u32) {
|
||||
<OfflineSlashGrace<T>>::put(new);
|
||||
OfflineSlashGrace::put(new);
|
||||
}
|
||||
|
||||
/// Set the validators who cannot be slashed (if any).
|
||||
@@ -1004,7 +1004,7 @@ impl<T: Trait> Module<T> {
|
||||
let reward = Self::current_session_reward();
|
||||
<CurrentEraReward<T>>::mutate(|r| *r += reward);
|
||||
|
||||
if <ForceNewEra<T>>::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<T: Trait> Module<T> {
|
||||
}
|
||||
|
||||
// Increment current era.
|
||||
<CurrentEra<T>>::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<T: Trait> Module<T> {
|
||||
}
|
||||
|
||||
fn apply_force_new_era() {
|
||||
<ForceNewEra<T>>::put(true);
|
||||
ForceNewEra::put(true);
|
||||
}
|
||||
|
||||
/// Call when a validator is determined to be offline. `count` is the
|
||||
|
||||
@@ -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<Blake2Hasher> {
|
||||
let (mut t, mut c) = system::GenesisConfig::<Test>::default().build_storage().unwrap();
|
||||
let (mut t, mut c) = system::GenesisConfig::default().build_storage::<Test>().unwrap();
|
||||
let balance_factor = if self.existential_deposit > 0 {
|
||||
256
|
||||
} else {
|
||||
|
||||
@@ -257,7 +257,7 @@ fn max_unstake_threshold_works() {
|
||||
validator_payment: 0,
|
||||
});
|
||||
|
||||
<OfflineSlash<Test>>::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);
|
||||
@@ -696,7 +696,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);
|
||||
<OfflineSlash<Test>>::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));
|
||||
|
||||
@@ -98,7 +98,7 @@ use proc_macro::TokenStream;
|
||||
///
|
||||
/// Storage items are accessible in multiple ways:
|
||||
///
|
||||
/// * The structure: `Foo::<T>`
|
||||
/// * The structure: `Foo` or `Foo::<T>` depending if the value type is generic or not.
|
||||
/// * The `Store` trait structure: `<Module<T> as Store>::Foo`
|
||||
/// * The getter on the module that calls get on the structure: `Module::<T>::foo()`
|
||||
///
|
||||
@@ -136,9 +136,9 @@ use proc_macro::TokenStream;
|
||||
/// trait Store for Module<T: Trait<I>, I: Instance=DefaultInstance> as Example {}
|
||||
/// ```
|
||||
///
|
||||
/// Then the genesis config is generated with two generic parameters (i.e. `GenesisConfig<T, I>`)
|
||||
/// and storage items are accessible using two generic parameters, e.g.:
|
||||
/// `<Dummy<T, I>>::get()` or `Dummy::<T, I>::get()`.
|
||||
/// Accessing the structure no requires the instance as generic parameter:
|
||||
/// * `Foo::<I>` if the value type is not generic
|
||||
/// * `Foo::<T, I>` if the value type is generic
|
||||
#[proc_macro]
|
||||
pub fn decl_storage(input: TokenStream) -> TokenStream {
|
||||
storage::transformation::decl_storage_impl(input)
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use syn;
|
||||
use quote::quote;
|
||||
use crate::storage::transformation::{DeclStorageTypeInfos, InstanceOpts};
|
||||
|
||||
use srml_support_procedural_tools::syn_ext as ext;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use syn::Ident;
|
||||
use quote::quote;
|
||||
|
||||
pub fn option_unwrap(is_option: bool) -> TokenStream2 {
|
||||
if !is_option {
|
||||
// raw type case
|
||||
@@ -79,7 +81,6 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
};
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -87,20 +88,37 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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() }
|
||||
};
|
||||
|
||||
// generator for value
|
||||
quote!{
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#traitinstance: #traittype, #instance #bound_instantiable #equal_default_instance>
|
||||
(#scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>);
|
||||
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)
|
||||
)
|
||||
};
|
||||
|
||||
impl<#traitinstance: #traittype, #instance #bound_instantiable>
|
||||
#scrate::storage::hashed::generator::StorageValue<#typ> for #name<#traitinstance, #instance>
|
||||
// generator for value
|
||||
quote! {
|
||||
#( #[ #attrs ] )*
|
||||
#visibility struct #name<#struct_trait>(
|
||||
#scrate::rstd::marker::PhantomData<(#trait_and_instance)>
|
||||
);
|
||||
|
||||
impl<#impl_trait> #scrate::storage::hashed::generator::StorageValue<#typ>
|
||||
for #name<#trait_and_instance>
|
||||
{
|
||||
type Query = #value_type;
|
||||
|
||||
@@ -170,7 +188,6 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
};
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -184,14 +201,31 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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;
|
||||
|
||||
@@ -235,8 +269,8 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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>
|
||||
{}
|
||||
}
|
||||
}
|
||||
@@ -257,7 +291,6 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
} = self;
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -304,6 +337,26 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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)
|
||||
@@ -337,15 +390,14 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
pub _data: #phantom_data<V>,
|
||||
}
|
||||
|
||||
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>, #impl_trait>
|
||||
Iterator for Enumerator<'a, S, #kty, (#typ, #trait_and_instance)>
|
||||
{
|
||||
type Item = (#kty, #typ);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let next = self.next.take()?;
|
||||
let key_for = <super::#name<#traitinstance, #instance>
|
||||
let key_for = <super::#name<#trait_and_instance>
|
||||
as #scrate::storage::hashed::generator::StorageMap<#kty, #typ>>::key_for(&next);
|
||||
|
||||
let (val, linkage): (#typ, Linkage<#kty>) = self.storage.get(&*key_for)
|
||||
@@ -355,7 +407,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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
|
||||
@@ -388,9 +440,9 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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<S: #scrate::HashedStorage<#scrate::#hasher>>(
|
||||
linkage: self::#inner_module::Linkage<#kty>,
|
||||
storage: &mut S,
|
||||
@@ -477,8 +529,8 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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;
|
||||
|
||||
@@ -553,8 +605,10 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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<S: #scrate::HashedStorage<#scrate::#hasher>>(storage: &S) -> Option<#kty> {
|
||||
use self::#inner_module::Utils;
|
||||
@@ -562,18 +616,20 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
Self::read_head(storage)
|
||||
}
|
||||
|
||||
fn enumerate<'a, S>(storage: &'a S) -> #scrate::rstd::boxed::Box<dyn Iterator<Item = (#kty, #typ)> + 'a>
|
||||
where
|
||||
S: #scrate::HashedStorage<#scrate::#hasher>,
|
||||
#kty: 'a,
|
||||
#typ: 'a,
|
||||
fn enumerate<'a, S>(
|
||||
storage: &'a S
|
||||
) -> #scrate::rstd::boxed::Box<dyn Iterator<Item = (#kty, #typ)> + 'a>
|
||||
where
|
||||
S: #scrate::HashedStorage<#scrate::#hasher>,
|
||||
#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(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -620,7 +676,6 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
};
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -634,14 +689,31 @@ impl<'a, I: Iterator<Item=syn::Meta>> 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;
|
||||
|
||||
@@ -686,9 +758,7 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> {
|
||||
#mutate_impl ;
|
||||
ret
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ struct StorageDefinition {
|
||||
pub crate_ident: Ident,
|
||||
pub content: ext::Braces<ext::Punctuated<DeclStorageLine, Token![;]>>,
|
||||
pub extra_genesis: ext::Opt<AddExtraGenesis>,
|
||||
pub extra_genesis_skip_phantom_data_field: ext::Opt<ExtraGenesisSkipPhantomDataField>,
|
||||
}
|
||||
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
@@ -82,12 +81,6 @@ struct AddExtraGenesis {
|
||||
pub content: ext::Braces<AddExtraGenesisContent>,
|
||||
}
|
||||
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
struct ExtraGenesisSkipPhantomDataField {
|
||||
pub genesis_phantom_keyword: keyword::extra_genesis_skip_phantom_data_field,
|
||||
pub token: Token![;],
|
||||
}
|
||||
|
||||
#[derive(Parse, ToTokens, Debug)]
|
||||
struct AddExtraGenesisContent {
|
||||
pub lines: ext::Punctuated<AddExtraGenesisLineEnum, Token![;]>,
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// tag::description[]
|
||||
//! `decl_storage` macro transformation
|
||||
// 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;
|
||||
use proc_macro2::{TokenStream as TokenStream2, Span};
|
||||
|
||||
use syn::{
|
||||
Ident,
|
||||
@@ -39,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 ) => {
|
||||
@@ -65,11 +68,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 +110,6 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream {
|
||||
&instance_opts,
|
||||
&storage_lines,
|
||||
&extra_genesis.inner,
|
||||
extra_genesis_skip_phantom_data_field.inner.is_some(),
|
||||
));
|
||||
let decl_storage_items = decl_storage_items(
|
||||
&scrate,
|
||||
@@ -114,6 +119,7 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream {
|
||||
&cratename,
|
||||
&storage_lines,
|
||||
);
|
||||
|
||||
let decl_store_items = decl_store_items(
|
||||
&storage_lines,
|
||||
);
|
||||
@@ -172,7 +178,6 @@ pub fn decl_storage_impl(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
#extra_genesis
|
||||
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
@@ -185,11 +190,9 @@ fn decl_store_extra_genesis(
|
||||
instance_opts: &InstanceOpts,
|
||||
storage_lines: &ext::Punctuated<DeclStorageLine, Token![;]>,
|
||||
extra_genesis: &Option<AddExtraGenesis>,
|
||||
extra_genesis_skip_phantom_data_field: bool,
|
||||
) -> Result<TokenStream2> {
|
||||
|
||||
let InstanceOpts {
|
||||
comma_instance,
|
||||
equal_default_instance,
|
||||
bound_instantiable,
|
||||
instance,
|
||||
@@ -197,13 +200,14 @@ fn decl_store_extra_genesis(
|
||||
} = instance_opts;
|
||||
|
||||
let mut is_trait_needed = false;
|
||||
let mut has_trait_field = false;
|
||||
let mut serde_complete_bound = Vec::new();
|
||||
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 = instance.is_some();
|
||||
let mut builders_clone_bound = Vec::new();
|
||||
|
||||
for sline in storage_lines.inner.iter() {
|
||||
let DeclStorageLine {
|
||||
attrs,
|
||||
name,
|
||||
@@ -217,9 +221,17 @@ fn decl_store_extra_genesis(
|
||||
|
||||
let type_infos = get_type_infos(storage_type);
|
||||
|
||||
let opt_build;
|
||||
let opt_build = build
|
||||
.inner
|
||||
.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.inner {
|
||||
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 {
|
||||
@@ -234,19 +246,37 @@ fn decl_store_extra_genesis(
|
||||
)
|
||||
);
|
||||
};
|
||||
if type_infos.kind.is_simple() && ext::has_parametric_type(type_infos.value_type, traitinstance) {
|
||||
|
||||
if ext::type_contains_ident(type_infos.value_type, traitinstance) {
|
||||
is_trait_needed = true;
|
||||
has_trait_field = 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());
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
@@ -270,8 +300,6 @@ fn decl_store_extra_genesis(
|
||||
quote!( #( #[ #attrs ] )* pub #ident: Vec<(#key1_type, #key2_type, #storage_type)>, )
|
||||
},
|
||||
});
|
||||
opt_build = Some(build.inner.as_ref().map(|b| &b.expr.content).map(|b|quote!( #b ))
|
||||
.unwrap_or_else(|| quote!( (|config: &GenesisConfig<#traitinstance, #instance>| config.#ident.clone()) )));
|
||||
|
||||
let fielddefault = default_value.inner.as_ref().map(|d| &d.expr).map(|d|
|
||||
if type_infos.is_option {
|
||||
@@ -281,48 +309,74 @@ fn decl_store_extra_genesis(
|
||||
}).unwrap_or_else(|| quote!( Default::default() ));
|
||||
|
||||
config_field_default.extend(quote!( #ident: #fielddefault, ));
|
||||
|
||||
opt_build.or_else(|| Some(quote!( (|config: &Self| config.#ident.clone()) )))
|
||||
} else {
|
||||
opt_build = build.inner.as_ref().map(|b| &b.expr.content).map(|b| quote!( #b ));
|
||||
}
|
||||
opt_build
|
||||
};
|
||||
|
||||
let typ = type_infos.typ;
|
||||
if let Some(builder) = opt_build {
|
||||
is_trait_needed = true;
|
||||
if let Some(builder) = builder {
|
||||
builders.extend(match type_infos.kind {
|
||||
DeclStorageTypeInfosKind::Simple => {
|
||||
quote!{{
|
||||
use #scrate::rstd::{cell::RefCell, marker::PhantomData};
|
||||
use #scrate::codec::{Encode, Decode};
|
||||
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 #scrate::storage::hashed::generator::StorageValue<#typ>>::put(&v, storage);
|
||||
<
|
||||
#name<#struct_trait #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 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);
|
||||
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<#struct_trait #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 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);
|
||||
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<#struct_trait #instance> as
|
||||
#scrate::storage::unhashed::generator::StorageDoubleMap<#key1_type, #key2_type, #typ>
|
||||
>::insert(&k1, &k2, &v, storage);
|
||||
});
|
||||
}}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let mut has_scall = false;
|
||||
@@ -341,9 +395,8 @@ 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;
|
||||
}
|
||||
|
||||
serde_complete_bound.push(quote!( #extra_type ));
|
||||
@@ -362,6 +415,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.content, traitinstance);
|
||||
let content = &expr.content;
|
||||
scall = quote!( ( #content ) );
|
||||
has_scall = true;
|
||||
@@ -370,7 +424,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();
|
||||
@@ -393,46 +446,54 @@ 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>),
|
||||
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),
|
||||
)
|
||||
};
|
||||
|
||||
quote!{
|
||||
#[serde(skip)]
|
||||
pub _genesis_phantom_data: #scrate::rstd::marker::PhantomData<(#traitinstance #comma_instance)>,
|
||||
},
|
||||
quote!{
|
||||
_genesis_phantom_data: Default::default(),
|
||||
},
|
||||
)
|
||||
}
|
||||
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, #inherent_instance #inherent_bound_instantiable>),
|
||||
)
|
||||
} else {
|
||||
// do not even need type parameter
|
||||
(quote!(), quote!(), quote!(), quote!(), quote!())
|
||||
(
|
||||
quote!(),
|
||||
quote!(),
|
||||
quote!(),
|
||||
quote!(<#traitinstance: #traittype, #inherent_instance #inherent_bound_instantiable>),
|
||||
)
|
||||
};
|
||||
quote!{
|
||||
|
||||
let (fn_generic, fn_traitinstance) = if !is_trait_needed && assimilate_require_generic {
|
||||
(
|
||||
quote!( <#traitinstance: #traittype, #instance #bound_instantiable> ),
|
||||
quote!( #traitinstance, #instance )
|
||||
)
|
||||
} else {
|
||||
(quote!(), quote!())
|
||||
};
|
||||
|
||||
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")]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#serde_bug_bound
|
||||
pub struct GenesisConfig#fparam_struct {
|
||||
#ph_field
|
||||
#config_field
|
||||
#genesis_extrafields
|
||||
}
|
||||
@@ -441,7 +502,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
|
||||
}
|
||||
@@ -449,23 +509,83 @@ 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> {
|
||||
impl#fparam_impl GenesisConfig#sparam where #builders_clone_bound {
|
||||
pub fn build_storage #fn_generic (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::<#fn_traitinstance>(&mut storage, &mut child_storage)?;
|
||||
Ok((storage, child_storage))
|
||||
}
|
||||
|
||||
/// Assimilate the storage for this module into pre-existing overlays.
|
||||
pub fn assimilate_storage #fn_generic (
|
||||
self,
|
||||
r: &mut #scrate::runtime_primitives::StorageOverlay,
|
||||
c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay,
|
||||
) -> std::result::Result<(), String> {
|
||||
let storage = r;
|
||||
|
||||
#builders
|
||||
|
||||
let r = storage;
|
||||
|
||||
#scall(r, c, &self);
|
||||
#scall(storage, c, &self);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl#build_storage_impl #scrate::runtime_primitives::#impl_trait
|
||||
for GenesisConfig#sparam where #builders_clone_bound
|
||||
{
|
||||
fn build_module_genesis_storage(
|
||||
self,
|
||||
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 {
|
||||
quote!()
|
||||
})
|
||||
Ok(quote!())
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
@@ -489,82 +609,103 @@ 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();
|
||||
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(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 {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
impls.extend(
|
||||
create_and_impl_instance(&prefix, &ident, &doc, &const_names, scrate, &instantiable)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// The name of the inherently available instance.
|
||||
let inherent_instance = Ident::new(INHERENT_INSTANCE_NAME, Span::call_site());
|
||||
|
||||
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() {
|
||||
let DeclStorageLine {
|
||||
attrs,
|
||||
@@ -630,15 +771,39 @@ fn impl_store_items(
|
||||
instance: &Option<syn::Ident>,
|
||||
storage_lines: &ext::Punctuated<DeclStorageLine, Token![;]>,
|
||||
) -> 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(
|
||||
@@ -669,29 +834,61 @@ 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<K: #scrate::rstd::borrow::Borrow<#key_type>>(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<KArg1, KArg2>(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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -799,6 +996,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),
|
||||
@@ -813,6 +1011,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)>);
|
||||
@@ -838,6 +1037,7 @@ fn store_functions_to_metadata (
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
default_getter_struct_def.extend(def_get);
|
||||
}
|
||||
(default_getter_struct_def, quote!{
|
||||
@@ -874,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),
|
||||
@@ -919,29 +1110,29 @@ fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos {
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct InstanceOpts {
|
||||
pub instance: Option<syn::Ident>,
|
||||
pub default_instance: Option<syn::Ident>,
|
||||
pub instantiable: Option<syn::Ident>,
|
||||
pub instance: Option<Ident>,
|
||||
pub default_instance: Option<Ident>,
|
||||
pub instantiable: Option<Ident>,
|
||||
pub comma_instance: TokenStream2,
|
||||
pub equal_default_instance: TokenStream2,
|
||||
pub bound_instantiable: TokenStream2,
|
||||
}
|
||||
|
||||
fn get_instance_opts(
|
||||
instance: Option<syn::Ident>,
|
||||
instantiable: Option<syn::Ident>,
|
||||
default_instance: Option<syn::Ident>,
|
||||
) -> syn::Result<InstanceOpts> {
|
||||
|
||||
instance: Option<Ident>,
|
||||
instantiable: Option<Ident>,
|
||||
default_instance: Option<Ident>,
|
||||
) -> Result<InstanceOpts> {
|
||||
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,
|
||||
@@ -952,8 +1143,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,
|
||||
)
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,22 +18,17 @@
|
||||
//! Extension to syn types, mainly for parsing
|
||||
// end::description[]
|
||||
|
||||
use syn::parse::{
|
||||
Parse,
|
||||
ParseStream,
|
||||
Result,
|
||||
};
|
||||
use proc_macro2::TokenStream as T2;
|
||||
use syn::{visit::{Visit, self}, parse::{Parse, ParseStream, Result}, Ident};
|
||||
use proc_macro2::{TokenStream, TokenTree};
|
||||
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
|
||||
@@ -55,8 +50,8 @@ macro_rules! groups_impl {
|
||||
}
|
||||
|
||||
impl<P: ToTokens> ToTokens for $name<P> {
|
||||
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();
|
||||
@@ -107,7 +102,7 @@ impl<P: Parse, T: Parse> Parse for PunctuatedInner<P,T,NoTrailing> {
|
||||
}
|
||||
|
||||
impl<P: ToTokens, T: ToTokens, V> ToTokens for PunctuatedInner<P,T,V> {
|
||||
fn to_tokens(&self, tokens: &mut T2) {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
self.inner.to_tokens(tokens)
|
||||
}
|
||||
}
|
||||
@@ -127,7 +122,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();
|
||||
@@ -157,7 +152,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);
|
||||
}
|
||||
@@ -182,121 +177,80 @@ impl<P: Parse> Parse for Opt<P> {
|
||||
}
|
||||
|
||||
impl<P: ToTokens> ToTokens for Opt<P> {
|
||||
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<T2> {
|
||||
pub fn extract_type_option(typ: &syn::Type) -> Option<TokenStream> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Auxialary structure to check if a given `Ident` is contained in an ast.
|
||||
struct ContainsIdent<'a> {
|
||||
ident: &'a Ident,
|
||||
result: bool,
|
||||
}
|
||||
|
||||
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()),
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
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,
|
||||
fn visit_ident(&mut self, ident: &Ident) {
|
||||
if ident == self.ident {
|
||||
self.result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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)
|
||||
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 {
|
||||
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
|
||||
}
|
||||
@@ -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<T $(, $instance:path)? >,
|
||||
$( $rest:tt $( <$t:ident $(, $rest_instance:path)? > )*, )*
|
||||
$module:ident $instance:ident<T>,
|
||||
$( $rest_event_generic_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 $(<$t $(, $rest_instance)? >)*, )* };
|
||||
$( $module_name::Event $( <$generic_param $(, $generic_instance)? > )*, )* $module::Event<$runtime $(, $instance)? >,;
|
||||
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<T>,
|
||||
$( $rest_event_generic:tt )*
|
||||
};
|
||||
$( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*;
|
||||
) => {
|
||||
$crate::impl_outer_event!(
|
||||
$( #[$attr] )*;
|
||||
$name;
|
||||
$runtime;
|
||||
$system;
|
||||
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()
|
||||
}
|
||||
}
|
||||
)*
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
@@ -239,7 +241,6 @@ mod tests {
|
||||
use super::*;
|
||||
use codec::Codec;
|
||||
use runtime_io::{with_externalities, Blake2Hasher};
|
||||
use runtime_primitives::BuildStorage;
|
||||
pub use srml_metadata::{
|
||||
DecodeDifferent, StorageMetadata, StorageFunctionMetadata,
|
||||
StorageFunctionType, StorageFunctionModifier,
|
||||
@@ -258,9 +259,7 @@ mod tests {
|
||||
use super::Trait;
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
|
||||
|
||||
}
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
|
||||
}
|
||||
}
|
||||
use self::module::Module;
|
||||
@@ -286,10 +285,10 @@ mod tests {
|
||||
}
|
||||
|
||||
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
GenesisConfig::<Test>::default().build_storage().unwrap().0.into()
|
||||
GenesisConfig::default().build_storage().unwrap().0.into()
|
||||
}
|
||||
|
||||
type Map = Data<Test>;
|
||||
type Map = Data;
|
||||
|
||||
#[test]
|
||||
fn linked_map_basic_insert_remove_should_work() {
|
||||
@@ -372,7 +371,7 @@ mod tests {
|
||||
#[test]
|
||||
fn double_map_basic_insert_remove_remove_prefix_should_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
type DoubleMap = DataDM<Test>;
|
||||
type DoubleMap = DataDM;
|
||||
// initialized during genesis
|
||||
assert_eq!(DoubleMap::get(&15u32, &16u32), 42u64);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
$( $module:ident $( <$generic:ident $(, $instance:path )? > )? ),* $(,)?
|
||||
$( $rest_without_system:tt )*
|
||||
}
|
||||
) => {
|
||||
$crate::impl_outer_origin! {
|
||||
$(#[$attr])*
|
||||
pub enum $name for $runtime where system = system {
|
||||
$( $module $( <$generic $(, $instance )? > )?, )*
|
||||
$( $rest_without_system )*
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
pub enum $name:ident for $runtime:ident where system = $system:ident {
|
||||
$( $module:ident $( <$generic:ident $(, $instance:path )?> )? ),* $(,)?
|
||||
$( $rest_with_system:tt )*
|
||||
}
|
||||
) => {
|
||||
$crate::impl_outer_origin!(
|
||||
@@ -49,20 +49,41 @@ macro_rules! impl_outer_origin {
|
||||
$name;
|
||||
$runtime;
|
||||
$system;
|
||||
Modules { $( $module $( <$generic $(, $instance )? > )*, )* };
|
||||
Modules { $( $rest_with_system )* };
|
||||
);
|
||||
};
|
||||
|
||||
// Replace generic param with runtime
|
||||
|
||||
// Generic + Instance
|
||||
(
|
||||
$(#[$attr:meta])*;
|
||||
$name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
Modules {
|
||||
$module:ident $( <T $(, $instance:path )? > )?,
|
||||
$( $rest_module:tt )*
|
||||
$module:ident $instance:ident <T>
|
||||
$(, $( $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 $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 },
|
||||
);
|
||||
};
|
||||
|
||||
// Generic
|
||||
(
|
||||
$(#[$attr:meta])*;
|
||||
$name:ident;
|
||||
$runtime:ident;
|
||||
$system:ident;
|
||||
Modules {
|
||||
$module:ident <T>
|
||||
$(, $( $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,
|
||||
);
|
||||
};
|
||||
|
||||
// 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 NONE: Self = $name::system($system::RawOrigin::None);
|
||||
@@ -127,23 +195,27 @@ 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<$crate::rstd::result::Result<
|
||||
$module::Origin $( <$generic_param $(, $generic_instance )? > )*,
|
||||
$name
|
||||
>> for $name {
|
||||
fn into(self) -> $crate::rstd::result::Result<
|
||||
$module::Origin $( <$generic_param $(, $generic_instance )? > )*,
|
||||
Self
|
||||
> {
|
||||
if let $name::$module(l) = self {
|
||||
Ok(l)
|
||||
} else {
|
||||
Err(self)
|
||||
impl Into<
|
||||
$crate::rstd::result::Result<
|
||||
$module::Origin < $( $generic )? $(, $module::$generic_instance )? >,
|
||||
$name,
|
||||
>>
|
||||
for $name {
|
||||
fn into(self) -> $crate::rstd::result::Result<
|
||||
$module::Origin < $( $generic )? $(, $module::$generic_instance )? >,
|
||||
Self,
|
||||
> {
|
||||
if let $name::[< $module $( _ $generic_instance )? >](l) = self {
|
||||
Ok(l)
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,9 +61,9 @@
|
||||
/// - `Module`
|
||||
/// - `Call`
|
||||
/// - `Storage`
|
||||
/// - `Event` or `Event<T>` (if the event is generic) or `Event<T, I>` (if also over instance)
|
||||
/// - `Origin` or `Origin<T>` (if the origin is generic) or `Origin<T, I>` (if also over instance)
|
||||
/// - `Config` or `Config<T>` (if the config is generic) or `Config<T, I>` (if also over instance)
|
||||
/// - `Event` or `Event<T>` (if the event is generic)
|
||||
/// - `Origin` or `Origin<T>` (if the origin is generic)
|
||||
/// - `Config` or `Config<T>` (if the config is generic)
|
||||
/// - `Inherent $( (CALL) )*` - If the module provides/can check inherents. The optional parameter
|
||||
/// is for modules that use a `Call` from a different module as
|
||||
/// inherent.
|
||||
@@ -101,6 +101,7 @@ macro_rules! construct_runtime {
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
// No modules given, expand to the default module set.
|
||||
(
|
||||
{ $( $preset:tt )* };
|
||||
{ $( $expanded:tt )* };
|
||||
@@ -114,6 +115,7 @@ macro_rules! construct_runtime {
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
// `default` identifier given, expand to default + given extra modules
|
||||
(
|
||||
{ $( $preset:tt )* };
|
||||
{ $( $expanded:tt )* };
|
||||
@@ -121,7 +123,7 @@ macro_rules! construct_runtime {
|
||||
default
|
||||
$(,
|
||||
$modules:ident
|
||||
$( <$modules_generic:ident $(, $modules_instance:ident)?> )*
|
||||
$( <$modules_generic:ident> )*
|
||||
$( ( $( $modules_args:ident ),* ) )*
|
||||
)*
|
||||
},
|
||||
@@ -129,21 +131,24 @@ macro_rules! construct_runtime {
|
||||
) => {
|
||||
$crate::construct_runtime!(
|
||||
{ $( $preset )* };
|
||||
{ $( $expanded )* };
|
||||
$name: $module::{
|
||||
Module, Call, Storage, Event<T>, Config<T>
|
||||
$(,
|
||||
$modules $( <$modules_generic $(, $modules_instance)?> )*
|
||||
$( ( $( $modules_args ),* ) )*
|
||||
)*
|
||||
},
|
||||
{
|
||||
$( $expanded )*
|
||||
$name: $module::{
|
||||
Module, Call, Storage, Event<T>, Config<T>
|
||||
$(,
|
||||
$modules $( <$modules_generic> )*
|
||||
$( ( $( $modules_args ),* ) )*
|
||||
)*
|
||||
},
|
||||
};
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
// Take all modules as given by the user.
|
||||
(
|
||||
{ $( $preset:tt )* };
|
||||
{ $( $expanded:tt )* };
|
||||
$name:ident: $module:ident::{
|
||||
$name:ident: $module:ident :: $( < $module_instance:ident >:: )? {
|
||||
$(
|
||||
$modules:ident
|
||||
$( <$modules_generic:ident> )*
|
||||
@@ -156,7 +161,7 @@ macro_rules! construct_runtime {
|
||||
{ $( $preset )* };
|
||||
{
|
||||
$( $expanded )*
|
||||
$name: $module::{
|
||||
$name: $module:: $( < $module_instance >:: )? {
|
||||
$(
|
||||
$modules $( <$modules_generic> )*
|
||||
$( ( $( $modules_args ),* ) )*
|
||||
@@ -166,35 +171,7 @@ macro_rules! construct_runtime {
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
( // Instance module: we indicate the generic instance `I` with the full instance path
|
||||
{ $( $preset:tt )* };
|
||||
{ $( $expanded:tt )* };
|
||||
$name:ident: $module:ident ::< $module_instance:ident >::{
|
||||
$(
|
||||
$modules:ident
|
||||
$( <$modules_generic:ident $(, $modules_instance:ident )?> )*
|
||||
$( ( $( $modules_args:ident ),* ) )*
|
||||
),*
|
||||
},
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
$crate::construct_runtime!(
|
||||
{ $( $preset )* };
|
||||
{
|
||||
$( $expanded )*
|
||||
$name: $module::<$module_instance>::{
|
||||
$(
|
||||
$modules $( <$modules_generic $(, $modules_instance=$module::$module_instance)?> )*
|
||||
$( ( $( $modules_args ),* ) )*
|
||||
),*
|
||||
},
|
||||
};
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
|
||||
// The main macro expansion that actually renders the Runtime code.
|
||||
|
||||
(
|
||||
{
|
||||
$runtime:ident;
|
||||
@@ -207,7 +184,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 +200,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!(
|
||||
@@ -265,7 +243,7 @@ macro_rules! construct_runtime {
|
||||
{};
|
||||
$(
|
||||
$name: $module:: $( < $module_instance >:: )? {
|
||||
$( $modules $( <$modules_generic $(, $modules_instance)?> )* ),*
|
||||
$( $modules $( <$modules_generic> )* ),*
|
||||
},
|
||||
)*
|
||||
);
|
||||
@@ -307,7 +285,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
|
||||
@@ -316,7 +294,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> )* ),*
|
||||
},
|
||||
)*
|
||||
);
|
||||
@@ -342,7 +320,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(, $ignore:ident $d( <$ignor:ident $d(, $ignore_instance:path)?> )* )*
|
||||
$macro_enum_name <$event_generic:ident> $d(, $ingore:ident $d( <$ignor:ident> )* )*
|
||||
},
|
||||
$d( $rest:tt )*
|
||||
) => {
|
||||
@@ -351,33 +329,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(, $ignore:ident $d( <$ignor:ident $d(, $ignore_instance:path)?> )* )*
|
||||
},
|
||||
$d( $rest:tt )*
|
||||
) => {
|
||||
compile_error!{concat!{
|
||||
"Module `", stringify!{$name}, "` must have `", stringify!{$macro_enum_name}, "<T, I>`",
|
||||
" 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(, $ignore:ident $d( <$ignor:ident $d(, $ignore_instance:path)?> )* )*
|
||||
$macro_enum_name $d( <$event_generic:ident> )* $d(, $ignore:ident $d( <$ignor:ident> )* )*
|
||||
},
|
||||
$d( $rest:tt )*
|
||||
) => {
|
||||
@@ -386,7 +348,7 @@ macro_rules! __create_decl_macro {
|
||||
$d( $system )?;
|
||||
{
|
||||
$d( $parsed )*
|
||||
$module $d( <$event_generic $d(, $event_instance)?> )*,
|
||||
$module $d( <$event_generic> )*,
|
||||
};
|
||||
$d( $rest )*
|
||||
);
|
||||
@@ -396,7 +358,7 @@ macro_rules! __create_decl_macro {
|
||||
$d( $system:ident )?;
|
||||
{ $d( $parsed:tt )* };
|
||||
$name:ident : $module:ident:: $d( < $module_instance:ident >:: )? {
|
||||
$ignore: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 )*
|
||||
) => {
|
||||
@@ -404,7 +366,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 )*
|
||||
);
|
||||
};
|
||||
@@ -425,16 +387,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> )?,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -668,7 +627,7 @@ macro_rules! __decl_runtime_metadata {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
@@ -676,7 +635,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 )*
|
||||
) => {
|
||||
@@ -684,7 +644,7 @@ macro_rules! __decl_outer_config {
|
||||
$runtime;
|
||||
{
|
||||
$( $parsed )*
|
||||
$module::$name $( $module_instance )? $(<$config_generic $(, $config_instance)?>)?,
|
||||
$module::$name $( $module_instance )? $( <$config_generic> )?,
|
||||
};
|
||||
$( $rest )*
|
||||
);
|
||||
@@ -693,14 +653,15 @@ macro_rules! __decl_outer_config {
|
||||
$runtime:ident;
|
||||
{ $( $parsed:tt )* };
|
||||
$name:ident: $module:ident:: $( < $module_instance:ident >:: )? {
|
||||
$ignore: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 )*
|
||||
);
|
||||
};
|
||||
@@ -718,13 +679,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> )*,
|
||||
)*
|
||||
}
|
||||
);
|
||||
|
||||
@@ -346,7 +346,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<T>| 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<u32> = Some(4);
|
||||
@@ -716,7 +716,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn check_genesis_config() {
|
||||
let config = GenesisConfig::<TraitImpl>::default();
|
||||
let config = GenesisConfig::default();
|
||||
assert_eq!(config.u32_getter_with_config, 0u32);
|
||||
assert_eq!(config.pub_u32_getter_with_config, 0u32);
|
||||
|
||||
@@ -820,13 +820,13 @@ mod test_map_vec_append {
|
||||
use runtime_io::{with_externalities, TestExternalities};
|
||||
|
||||
with_externalities(&mut TestExternalities::default(), || {
|
||||
let _ = <MapVec<Test>>::append(1, &[1, 2, 3]);
|
||||
let _ = <MapVec<Test>>::append(1, &[4, 5]);
|
||||
assert_eq!(<MapVec<Test>>::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 _ = <JustVec<Test>>::append(&[1, 2, 3]);
|
||||
let _ = <JustVec<Test>>::append(&[4, 5]);
|
||||
assert_eq!(<JustVec<Test>>::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]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Blake2Hasher> {
|
||||
#[test]
|
||||
fn final_keys() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
<Value<Test>>::put(1);
|
||||
Value::put(1);
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::twox_128(b"Module Value")), Some(1u32));
|
||||
|
||||
<Map<Test>>::insert(1, 2);
|
||||
Map::insert(1, 2);
|
||||
let mut k = b"Module Map".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::blake2_256(&k)), Some(2u32));
|
||||
|
||||
<Map2<Test>>::insert(1, 2);
|
||||
Map2::insert(1, 2);
|
||||
let mut k = b"Module Map2".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::twox_128(&k)), Some(2u32));
|
||||
|
||||
<LinkedMap<Test>>::insert(1, 2);
|
||||
LinkedMap::insert(1, 2);
|
||||
let mut k = b"Module LinkedMap".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::blake2_256(&k)), Some(2u32));
|
||||
|
||||
<LinkedMap2<Test>>::insert(1, 2);
|
||||
LinkedMap2::insert(1, 2);
|
||||
let mut k = b"Module LinkedMap2".to_vec();
|
||||
k.extend(1u32.encode());
|
||||
assert_eq!(unhashed::get::<u32>(&runtime_io::twox_128(&k)), Some(2u32));
|
||||
|
||||
<DoubleMap<Test>>::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::<u32>(&k), Some(3u32));
|
||||
|
||||
<DoubleMap2<Test>>::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();
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
pub trait Trait {
|
||||
type BlockNumber: parity_codec::Codec + Default;
|
||||
type Origin;
|
||||
}
|
||||
|
||||
srml_support::decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
|
||||
}
|
||||
|
||||
srml_support::decl_storage! {
|
||||
trait Store for Module<T: Trait> as Example {
|
||||
pub AppendableDM config(t): double_map u32, blake2_256(T::BlockNumber) => Vec<u32>;
|
||||
}
|
||||
}
|
||||
|
||||
struct Test;
|
||||
|
||||
impl Trait for Test {
|
||||
type BlockNumber = u32;
|
||||
type Origin = ();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_genesis_config() {
|
||||
GenesisConfig::<Test> {
|
||||
t: Default::default(),
|
||||
};
|
||||
}
|
||||
@@ -13,84 +13,22 @@
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#![recursion_limit="128"]
|
||||
|
||||
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
|
||||
};
|
||||
use srml_support::{StorageValue, StorageMap, StorageDoubleMap};
|
||||
use primitives::{H256, sr25519};
|
||||
|
||||
pub trait Currency {
|
||||
}
|
||||
mod system;
|
||||
|
||||
// Mock
|
||||
mod system {
|
||||
use super::*;
|
||||
|
||||
pub trait Trait: 'static + Eq + Clone {
|
||||
type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
|
||||
+ From<RawOrigin<Self::AccountId>>;
|
||||
type BlockNumber;
|
||||
type Hash;
|
||||
type AccountId;
|
||||
type Event: From<Event>;
|
||||
}
|
||||
|
||||
pub type DigestItemOf<T> = generic::DigestItem<<T as Trait>::Hash>;
|
||||
|
||||
srml_support::decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
|
||||
pub fn deposit_event(_event: T::Event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: Trait> Module<T> {
|
||||
pub fn deposit_log(_item: DigestItemOf<T>) {
|
||||
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<AccountId> {
|
||||
Root,
|
||||
Signed(AccountId),
|
||||
None,
|
||||
}
|
||||
|
||||
impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
|
||||
fn from(s: Option<AccountId>) -> RawOrigin<AccountId> {
|
||||
match s {
|
||||
Some(who) => RawOrigin::Signed(who),
|
||||
None => RawOrigin::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Origin<T> = RawOrigin<<T as Trait>::AccountId>;
|
||||
|
||||
pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), &'static str>
|
||||
where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
|
||||
{
|
||||
o.into().map(|_| ()).map_err(|_| "bad origin: expected to be a root origin")
|
||||
}
|
||||
}
|
||||
pub trait Currency {}
|
||||
|
||||
// Test for:
|
||||
// * No default instance
|
||||
@@ -123,7 +61,7 @@ mod module1 {
|
||||
}
|
||||
|
||||
srml_support::decl_event! {
|
||||
pub enum Event<T, I> where Phantom = rstd::marker::PhantomData<T> {
|
||||
pub enum Event<T, I> where Phantom = std::marker::PhantomData<T> {
|
||||
_Phantom(Phantom),
|
||||
AnotherVariant(u32),
|
||||
}
|
||||
@@ -133,7 +71,7 @@ mod module1 {
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum Origin<T: Trait<I>, I> {
|
||||
Members(u32),
|
||||
_Phantom(rstd::marker::PhantomData<(T, I)>),
|
||||
_Phantom(std::marker::PhantomData<(T, I)>),
|
||||
}
|
||||
|
||||
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"12345678";
|
||||
@@ -147,7 +85,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!();
|
||||
}
|
||||
}
|
||||
@@ -180,7 +118,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! {
|
||||
@@ -193,7 +130,7 @@ mod module2 {
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum Origin<T: Trait<I>, I=DefaultInstance> {
|
||||
Members(u32),
|
||||
_Phantom(rstd::marker::PhantomData<(T, I)>),
|
||||
_Phantom(std::marker::PhantomData<(T, I)>),
|
||||
}
|
||||
|
||||
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"12345678";
|
||||
@@ -207,7 +144,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!();
|
||||
}
|
||||
}
|
||||
@@ -224,8 +161,7 @@ mod module3 {
|
||||
}
|
||||
|
||||
srml_support::decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: <T as system::Trait>::Origin {
|
||||
}
|
||||
pub struct Module<T: Trait> for enum Call where origin: <T as system::Trait>::Origin {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,12 +218,22 @@ srml_support::construct_runtime!(
|
||||
UncheckedExtrinsic = UncheckedExtrinsic
|
||||
{
|
||||
System: system::{Module, Call, Event},
|
||||
Module1_1: module1::<Instance1>::{Module, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>, Inherent},
|
||||
Module1_2: module1::<Instance2>::{Module, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>, Inherent},
|
||||
Module1_1: module1::<Instance1>::{
|
||||
Module, Call, Storage, Event<T>, Config, Origin<T>, Inherent
|
||||
},
|
||||
Module1_2: module1::<Instance2>::{
|
||||
Module, Call, Storage, Event<T>, Config, Origin<T>, Inherent
|
||||
},
|
||||
Module2: module2::{Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent},
|
||||
Module2_1: module2::<Instance1>::{Module, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>, Inherent},
|
||||
Module2_2: module2::<Instance2>::{Module, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>, Inherent},
|
||||
Module2_3: module2::<Instance3>::{Module, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>, Inherent},
|
||||
Module2_1: module2::<Instance1>::{
|
||||
Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent
|
||||
},
|
||||
Module2_2: module2::<Instance2>::{
|
||||
Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent
|
||||
},
|
||||
Module2_3: module2::<Instance3>::{
|
||||
Module, Call, Storage, Event<T>, Config<T>, Origin<T>, Inherent
|
||||
},
|
||||
Module3: module3::{Module, Call},
|
||||
}
|
||||
);
|
||||
@@ -300,11 +246,9 @@ fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
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,
|
||||
@@ -326,48 +270,48 @@ fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
#[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::<Runtime>::key().to_vec(),
|
||||
module2::Value::<Runtime, module2::Instance1>::key().to_vec(),
|
||||
module2::Value::<Runtime, module2::Instance2>::key().to_vec(),
|
||||
module2::Value::<Runtime, module2::Instance3>::key().to_vec(),
|
||||
module2::Map::<Runtime>::prefix().to_vec(),
|
||||
module2::Map::<Runtime, module2::Instance1>::prefix().to_vec(),
|
||||
module2::Map::<Runtime, module2::Instance2>::prefix().to_vec(),
|
||||
module2::Map::<Runtime, module2::Instance3>::prefix().to_vec(),
|
||||
module2::LinkedMap::<Runtime>::prefix().to_vec(),
|
||||
module2::LinkedMap::<Runtime, module2::Instance1>::prefix().to_vec(),
|
||||
module2::LinkedMap::<Runtime, module2::Instance2>::prefix().to_vec(),
|
||||
module2::LinkedMap::<Runtime, module2::Instance3>::prefix().to_vec(),
|
||||
module2::DoubleMap::<Runtime>::prefix().to_vec(),
|
||||
module2::DoubleMap::<Runtime, module2::Instance1>::prefix().to_vec(),
|
||||
module2::DoubleMap::<Runtime, module2::Instance2>::prefix().to_vec(),
|
||||
module2::DoubleMap::<Runtime, module2::Instance3>::prefix().to_vec(),
|
||||
module2::Map::<Runtime>::key_for(0),
|
||||
module2::Map::<Runtime, module2::Instance1>::key_for(0).to_vec(),
|
||||
module2::Map::<Runtime, module2::Instance2>::key_for(0).to_vec(),
|
||||
module2::Map::<Runtime, module2::Instance3>::key_for(0).to_vec(),
|
||||
module2::LinkedMap::<Runtime>::key_for(0),
|
||||
module2::LinkedMap::<Runtime, module2::Instance1>::key_for(0).to_vec(),
|
||||
module2::LinkedMap::<Runtime, module2::Instance2>::key_for(0).to_vec(),
|
||||
module2::LinkedMap::<Runtime, module2::Instance3>::key_for(0).to_vec(),
|
||||
module2::Map::<Runtime>::key_for(1),
|
||||
module2::Map::<Runtime, module2::Instance1>::key_for(1).to_vec(),
|
||||
module2::Map::<Runtime, module2::Instance2>::key_for(1).to_vec(),
|
||||
module2::Map::<Runtime, module2::Instance3>::key_for(1).to_vec(),
|
||||
module2::LinkedMap::<Runtime>::key_for(1),
|
||||
module2::LinkedMap::<Runtime, module2::Instance1>::key_for(1).to_vec(),
|
||||
module2::LinkedMap::<Runtime, module2::Instance2>::key_for(1).to_vec(),
|
||||
module2::LinkedMap::<Runtime, module2::Instance3>::key_for(1).to_vec(),
|
||||
module2::DoubleMap::<Runtime>::prefix_for(1),
|
||||
module2::DoubleMap::<Runtime, module2::Instance1>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<Runtime, module2::Instance2>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<Runtime, module2::Instance3>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<Runtime>::key_for(1, 1),
|
||||
module2::DoubleMap::<Runtime, module2::Instance1>::key_for(1, 1).to_vec(),
|
||||
module2::DoubleMap::<Runtime, module2::Instance2>::key_for(1, 1).to_vec(),
|
||||
module2::DoubleMap::<Runtime, module2::Instance3>::key_for(1, 1).to_vec(),
|
||||
module2::Map::<module2::DefaultInstance>::prefix().to_vec(),
|
||||
module2::Map::<module2::Instance1>::prefix().to_vec(),
|
||||
module2::Map::<module2::Instance2>::prefix().to_vec(),
|
||||
module2::Map::<module2::Instance3>::prefix().to_vec(),
|
||||
module2::LinkedMap::<module2::DefaultInstance>::prefix().to_vec(),
|
||||
module2::LinkedMap::<module2::Instance1>::prefix().to_vec(),
|
||||
module2::LinkedMap::<module2::Instance2>::prefix().to_vec(),
|
||||
module2::LinkedMap::<module2::Instance3>::prefix().to_vec(),
|
||||
module2::DoubleMap::<module2::DefaultInstance>::prefix().to_vec(),
|
||||
module2::DoubleMap::<module2::Instance1>::prefix().to_vec(),
|
||||
module2::DoubleMap::<module2::Instance2>::prefix().to_vec(),
|
||||
module2::DoubleMap::<module2::Instance3>::prefix().to_vec(),
|
||||
module2::Map::<module2::DefaultInstance>::key_for(0),
|
||||
module2::Map::<module2::Instance1>::key_for(0).to_vec(),
|
||||
module2::Map::<module2::Instance2>::key_for(0).to_vec(),
|
||||
module2::Map::<module2::Instance3>::key_for(0).to_vec(),
|
||||
module2::LinkedMap::<module2::DefaultInstance>::key_for(0),
|
||||
module2::LinkedMap::<module2::Instance1>::key_for(0).to_vec(),
|
||||
module2::LinkedMap::<module2::Instance2>::key_for(0).to_vec(),
|
||||
module2::LinkedMap::<module2::Instance3>::key_for(0).to_vec(),
|
||||
module2::Map::<module2::DefaultInstance>::key_for(1),
|
||||
module2::Map::<module2::Instance1>::key_for(1).to_vec(),
|
||||
module2::Map::<module2::Instance2>::key_for(1).to_vec(),
|
||||
module2::Map::<module2::Instance3>::key_for(1).to_vec(),
|
||||
module2::LinkedMap::<module2::DefaultInstance>::key_for(1),
|
||||
module2::LinkedMap::<module2::Instance1>::key_for(1).to_vec(),
|
||||
module2::LinkedMap::<module2::Instance2>::key_for(1).to_vec(),
|
||||
module2::LinkedMap::<module2::Instance3>::key_for(1).to_vec(),
|
||||
module2::DoubleMap::<module2::DefaultInstance>::prefix_for(1),
|
||||
module2::DoubleMap::<module2::Instance1>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance2>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance3>::prefix_for(1).to_vec(),
|
||||
module2::DoubleMap::<module2::DefaultInstance>::key_for(1, 1),
|
||||
module2::DoubleMap::<module2::Instance1>::key_for(1, 1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance2>::key_for(1, 1).to_vec(),
|
||||
module2::DoubleMap::<module2::Instance3>::key_for(1, 1).to_vec(),
|
||||
].iter() {
|
||||
assert!(map.insert(key, ()).is_none())
|
||||
}
|
||||
@@ -378,9 +322,9 @@ fn storage_instance_independance() {
|
||||
fn storage_with_instance_basic_operation() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
type Value = module2::Value<Runtime, module2::Instance1>;
|
||||
type Map = module2::Map<Runtime, module2::Instance1>;
|
||||
type LinkedMap = module2::LinkedMap<Runtime, module2::Instance1>;
|
||||
type DoubleMap = module2::DoubleMap<Runtime, module2::Instance1>;
|
||||
type Map = module2::Map<module2::Instance1>;
|
||||
type LinkedMap = module2::LinkedMap<module2::Instance1>;
|
||||
type DoubleMap = module2::DoubleMap<module2::Instance1>;
|
||||
|
||||
assert_eq!(Value::exists(), true);
|
||||
assert_eq!(Value::get(), 4);
|
||||
@@ -432,4 +376,4 @@ fn storage_with_instance_basic_operation() {
|
||||
DoubleMap::remove(key1, key2);
|
||||
assert_eq!(DoubleMap::get(key1, key2), 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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::{Serialize, Deserialize};
|
||||
|
||||
mod system;
|
||||
|
||||
mod module {
|
||||
use super::*;
|
||||
|
||||
pub type Request<T> = (
|
||||
<T as system::Trait>::AccountId,
|
||||
Role,
|
||||
<T as system::Trait>::BlockNumber,
|
||||
);
|
||||
pub type Requests<T> = Vec<Request<T>>;
|
||||
|
||||
#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub enum Role {
|
||||
Storage,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub struct RoleParameters<T: Trait> {
|
||||
// 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<T: Trait> Default for RoleParameters<T> {
|
||||
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<T: Trait> for enum Call where origin: T::Origin {}
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Copy, Clone, Serialize, Deserialize)]
|
||||
pub struct Data<T: Trait> {
|
||||
pub data: T::BlockNumber,
|
||||
}
|
||||
|
||||
impl<T: Trait> Default for Data<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
data: T::BlockNumber::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srml_support::decl_storage! {
|
||||
trait Store for Module<T: Trait> 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<T> = Default::default();
|
||||
vec![(Role::Storage, storage_params)]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}): map Role => Option<RoleParameters<T>>;
|
||||
|
||||
/// 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<Role>;
|
||||
|
||||
/// Actors list
|
||||
pub ActorAccountIds get(actor_account_ids) : Vec<T::AccountId>;
|
||||
|
||||
/// actor accounts associated with a role
|
||||
pub AccountIdsByRole get(account_ids_by_role) : map Role => Vec<T::AccountId>;
|
||||
|
||||
/// 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<T>;
|
||||
|
||||
/// 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 = <Signature as Verify>::Signer;
|
||||
pub type BlockNumber = u64;
|
||||
pub type Index = u64;
|
||||
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<u32, Index, Call, Signature>;
|
||||
|
||||
impl system::Trait for Runtime {
|
||||
type Hash = H256;
|
||||
type Origin = Origin;
|
||||
type BlockNumber = BlockNumber;
|
||||
type AccountId = AccountId;
|
||||
type Event = Event;
|
||||
}
|
||||
|
||||
impl module::Trait for Runtime {}
|
||||
|
||||
srml_support::construct_runtime!(
|
||||
pub enum Runtime where
|
||||
Block = Block,
|
||||
NodeBlock = Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic
|
||||
{
|
||||
System: system::{Module, Call, Event},
|
||||
Module: module::{Module, Call, Storage, Config},
|
||||
}
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn create_genesis_config() {
|
||||
GenesisConfig {
|
||||
module: Some(module::GenesisConfig {
|
||||
request_life_time: 0,
|
||||
enable_storage_role: true,
|
||||
})
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
use srml_support::codec::{Encode, Decode};
|
||||
|
||||
pub trait Trait: 'static + Eq + Clone {
|
||||
type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
|
||||
+ From<RawOrigin<Self::AccountId>>;
|
||||
|
||||
type BlockNumber: Decode + Encode + Clone + Default;
|
||||
type Hash;
|
||||
type AccountId: Encode + Decode;
|
||||
type Event: From<Event>;
|
||||
}
|
||||
|
||||
srml_support::decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
|
||||
pub fn deposit_event(_event: T::Event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<AccountId> {
|
||||
Root,
|
||||
Signed(AccountId),
|
||||
None,
|
||||
}
|
||||
|
||||
impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
|
||||
fn from(s: Option<AccountId>) -> RawOrigin<AccountId> {
|
||||
match s {
|
||||
Some(who) => RawOrigin::Signed(who),
|
||||
None => RawOrigin::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Origin<T> = RawOrigin<<T as Trait>::AccountId>;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), &'static str>
|
||||
where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
|
||||
{
|
||||
o.into().map(|_| ()).map_err(|_| "bad origin: expected to be a root origin")
|
||||
}
|
||||
@@ -357,7 +357,7 @@ decl_storage! {
|
||||
#[serde(with = "substrate_primitives::bytes")]
|
||||
config(code): Vec<u8>;
|
||||
|
||||
build(|storage: &mut primitives::StorageOverlay, _: &mut primitives::ChildrenStorageOverlay, config: &GenesisConfig<T>| {
|
||||
build(|storage: &mut primitives::StorageOverlay, _: &mut primitives::ChildrenStorageOverlay, config: &GenesisConfig| {
|
||||
use parity_codec::Encode;
|
||||
|
||||
storage.insert(well_known_keys::CODE.to_vec(), config.code.clone());
|
||||
@@ -485,14 +485,14 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
// Index of the to be added event.
|
||||
let event_idx = {
|
||||
let old_event_count = <EventCount<T>>::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,
|
||||
};
|
||||
<EventCount<T>>::put(new_event_count);
|
||||
EventCount::put(new_event_count);
|
||||
old_event_count
|
||||
};
|
||||
|
||||
@@ -524,12 +524,12 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
/// Gets extrinsics count.
|
||||
pub fn extrinsic_count() -> u32 {
|
||||
<ExtrinsicCount<T>>::get().unwrap_or_default()
|
||||
ExtrinsicCount::get().unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Gets a total weight of all executed extrinsics.
|
||||
pub fn all_extrinsics_weight() -> u32 {
|
||||
<AllExtrinsicsWeight<T>>::get().unwrap_or_default()
|
||||
AllExtrinsicsWeight::get().unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Start the execution of a particular block.
|
||||
@@ -553,14 +553,14 @@ impl<T: Trait> Module<T> {
|
||||
*index = (*index + 1) % 81;
|
||||
});
|
||||
<Events<T>>::kill();
|
||||
<EventCount<T>>::kill();
|
||||
EventCount::kill();
|
||||
<EventTopics<T>>::remove_prefix(&());
|
||||
}
|
||||
|
||||
/// Remove temporary "environment" entries in storage.
|
||||
pub fn finalize() -> T::Header {
|
||||
<ExtrinsicCount<T>>::kill();
|
||||
<AllExtrinsicsWeight<T>>::kill();
|
||||
ExtrinsicCount::kill();
|
||||
AllExtrinsicsWeight::kill();
|
||||
|
||||
let number = <Number<T>>::take();
|
||||
let parent_hash = <ParentHash<T>>::take();
|
||||
@@ -699,7 +699,7 @@ impl<T: Trait> Module<T> {
|
||||
/// 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<u8>) {
|
||||
<ExtrinsicData<T>>::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.
|
||||
@@ -713,19 +713,19 @@ impl<T: Trait> Module<T> {
|
||||
let total_length = encoded_len.saturating_add(Self::all_extrinsics_weight());
|
||||
|
||||
storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index);
|
||||
<AllExtrinsicsWeight<T>>::put(&total_length);
|
||||
AllExtrinsicsWeight::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();
|
||||
<ExtrinsicCount<T>>::put(extrinsic_index);
|
||||
ExtrinsicCount::put(extrinsic_index);
|
||||
}
|
||||
|
||||
/// Remove all extrinsic data and save the extrinsics trie root.
|
||||
pub fn derive_extrinsics() {
|
||||
let extrinsics = (0..<ExtrinsicCount<T>>::get().unwrap_or_default()).map(<ExtrinsicData<T>>::take).collect();
|
||||
let extrinsics = (0..ExtrinsicCount::get().unwrap_or_default()).map(ExtrinsicData::take).collect();
|
||||
let xts_root = extrinsics_data_root::<T::Hashing>(extrinsics);
|
||||
<ExtrinsicsRoot<T>>::put(xts_root);
|
||||
}
|
||||
@@ -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<Test>;
|
||||
|
||||
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
GenesisConfig::<Test>::default().build_storage().unwrap().0.into()
|
||||
GenesisConfig::default().build_storage::<Test>().unwrap().0.into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -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::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
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::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
minimum_period: 5,
|
||||
}.build_storage().unwrap().0);
|
||||
@@ -392,7 +390,7 @@ mod tests {
|
||||
#[test]
|
||||
#[should_panic(expected = "Timestamp must increment by at least <MinimumPeriod> between sequential blocks")]
|
||||
fn block_period_minimum_enforced() {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
minimum_period: 5,
|
||||
}.build_storage().unwrap().0);
|
||||
|
||||
@@ -129,7 +129,7 @@ decl_module! {
|
||||
.map_err(|_| "Proposer's balance too low")?;
|
||||
|
||||
let c = Self::proposal_count();
|
||||
<ProposalCount<T>>::put(c + 1);
|
||||
ProposalCount::put(c + 1);
|
||||
<Proposals<T>>::insert(c, Proposal { proposer, value, beneficiary, bond });
|
||||
|
||||
Self::deposit_event(RawEvent::Proposed(c));
|
||||
@@ -148,10 +148,10 @@ decl_module! {
|
||||
#[compact] spend_period: T::BlockNumber,
|
||||
#[compact] burn: Permill
|
||||
) {
|
||||
<ProposalBond<T>>::put(proposal_bond);
|
||||
ProposalBond::put(proposal_bond);
|
||||
<ProposalBondMinimum<T>>::put(proposal_bond_minimum);
|
||||
<SpendPeriod<T>>::put(spend_period);
|
||||
<Burn<T>>::put(burn);
|
||||
Burn::put(burn);
|
||||
}
|
||||
|
||||
/// Reject a proposed spend. The original deposit will be slashed.
|
||||
@@ -183,7 +183,7 @@ decl_module! {
|
||||
|
||||
ensure!(<Proposals<T>>::exists(proposal_id), "No proposal at that index");
|
||||
|
||||
<Approvals<T>>::mutate(|v| v.push(proposal_id));
|
||||
Approvals::mutate(|v| v.push(proposal_id));
|
||||
}
|
||||
|
||||
fn on_finalize(n: T::BlockNumber) {
|
||||
@@ -272,7 +272,7 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
let mut missed_any = false;
|
||||
let mut imbalance = <PositiveImbalanceOf<T>>::zero();
|
||||
<Approvals<T>>::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) {
|
||||
@@ -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<Test>;
|
||||
|
||||
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap().0;
|
||||
t.extend(balances::GenesisConfig::<Test>{
|
||||
balances: vec![(0, 100), (1, 99), (2, 1)],
|
||||
transaction_base_fee: 0,
|
||||
|
||||
Reference in New Issue
Block a user