From a21b2bfbb8089d465e3de4abc7019f64dd7af446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 1 Oct 2018 18:50:30 +0200 Subject: [PATCH] Some metadata cleanup and improvements (#857) * Do not encode the `origin` parameter in the metadata * Remove obsolete macro * Encode outer dispatch in metadata --- substrate/srml/council/src/lib.rs | 6 +- substrate/srml/democracy/src/lib.rs | 6 +- substrate/srml/metadata/src/lib.rs | 18 ++++ substrate/srml/support/src/dispatch.rs | 141 ++++++++++--------------- substrate/srml/support/src/lib.rs | 5 +- substrate/srml/support/src/metadata.rs | 79 +++++++++++--- substrate/srml/support/src/runtime.rs | 4 +- 7 files changed, 144 insertions(+), 115 deletions(-) diff --git a/substrate/srml/council/src/lib.rs b/substrate/srml/council/src/lib.rs index 8793186827..7bc1a4f08f 100644 --- a/substrate/srml/council/src/lib.rs +++ b/substrate/srml/council/src/lib.rs @@ -145,9 +145,9 @@ mod tests { } impl_outer_dispatch! { - pub enum Call where origin: Origin { - Balances, - Democracy, + pub enum Call for Test where origin: Origin { + balances::Balances, + democracy::Democracy, } } diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs index 634fb02251..7d6f43ca47 100644 --- a/substrate/srml/democracy/src/lib.rs +++ b/substrate/srml/democracy/src/lib.rs @@ -374,9 +374,9 @@ mod tests { } impl_outer_dispatch! { - pub enum Call where origin: Origin { - Balances, - Democracy, + pub enum Call for Test where origin: Origin { + balances::Balances, + democracy::Democracy, } } diff --git a/substrate/srml/metadata/src/lib.rs b/substrate/srml/metadata/src/lib.rs index 02219bcff1..7437f408af 100644 --- a/substrate/srml/metadata/src/lib.rs +++ b/substrate/srml/metadata/src/lib.rs @@ -261,6 +261,23 @@ pub enum StorageFunctionModifier { Required, } +/// All metadata about the outer dispatch. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct OuterDispatchMetadata { + pub name: DecodeDifferentStr, + pub calls: DecodeDifferentArray, +} + +/// A Call from the outer dispatch. +#[derive(Clone, PartialEq, Eq, Encode)] +#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] +pub struct OuterDispatchCall { + pub name: DecodeDifferentStr, + pub prefix: DecodeDifferentStr, + pub index: u16, +} + /// All metadata about an runtime module. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] @@ -276,4 +293,5 @@ pub struct RuntimeModuleMetadata { pub struct RuntimeMetadata { pub outer_event: OuterEventMetadata, pub modules: DecodeDifferentArray, + pub outer_dispatch: OuterDispatchMetadata, } diff --git a/substrate/srml/support/src/dispatch.rs b/substrate/srml/support/src/dispatch.rs index d579e5cc12..af7ae2a9df 100644 --- a/substrate/srml/support/src/dispatch.rs +++ b/substrate/srml/support/src/dispatch.rs @@ -25,7 +25,7 @@ use serde; pub use codec::{Codec, Decode, Encode, Input, Output}; pub use substrate_metadata::{ ModuleMetadata, FunctionMetadata, DecodeDifferent, - CallMetadata, FunctionArgumentMetadata + CallMetadata, FunctionArgumentMetadata, OuterDispatchMetadata, OuterDispatchCall }; pub type Result = result::Result<(), &'static str>; @@ -394,15 +394,13 @@ pub trait IsSubType { /// Implement a meta-dispatch module to dispatch to other dispatchers. #[macro_export] macro_rules! impl_outer_dispatch { - () => (); ( $(#[$attr:meta])* - pub enum $call_type:ident where origin: $origin:ty { + pub enum $call_type:ident for $runtime:ident where origin: $origin:ty { $( - $camelcase:ident, + $module:ident::$camelcase:ident, )* } - $( $rest:tt )* ) => { $(#[$attr])* #[derive(Clone, PartialEq, Eq)] @@ -435,7 +433,7 @@ macro_rules! impl_outer_dispatch { } } )* - impl_outer_dispatch!{ $($rest)* } + __impl_outer_dispatch_metadata!($runtime; $call_type; $( $module::$camelcase, )*); } } @@ -458,11 +456,54 @@ macro_rules! __impl_outer_dispatch_common { __impl_encode!(dest; *self; 0; $call_type; $( fn $camelcase( outer_dispatch_param ); )*) } } - } } -/// Implement the `json_metadata` function. +/// Implement metadata for outer dispatch. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_outer_dispatch_metadata { + ( + $runtime:ident; + $outer_name:ident; + $( $module:ident::$call:ident, )* + ) => { + impl $runtime { + pub fn outer_dispatch_metadata() -> $crate::dispatch::OuterDispatchMetadata { + $crate::dispatch::OuterDispatchMetadata { + name: $crate::dispatch::DecodeDifferent::Encode(stringify!($outer_name)), + calls: __impl_outer_dispatch_metadata!(@encode_calls 0; ; $( $module::$call, )*), + } + } + } + }; + (@encode_calls + $index:expr; + $( $encoded_call:expr ),*; + $module:ident::$call:ident, + $( $rest_module:ident::$rest:ident, )* + ) => { + __impl_outer_dispatch_metadata!( + @encode_calls + $index + 1; + $( $encoded_call, )* + $crate::dispatch::OuterDispatchCall { + name: $crate::dispatch::DecodeDifferent::Encode(stringify!($call)), + prefix: $crate::dispatch::DecodeDifferent::Encode(stringify!($module)), + index: $index, + }; + $( $rest_module::$rest, )* + ) + }; + (@encode_calls + $index:expr; + $( $encoded_call:expr ),*; + ) => { + $crate::dispatch::DecodeDifferent::Encode(&[ $( $encoded_call ),* ]) + }; +} + +/// Implement metadata for dispatch. #[macro_export] #[doc(hidden)] macro_rules! __dispatch_impl_metadata { @@ -499,7 +540,7 @@ macro_rules! __call_to_metadata { $crate::dispatch::CallMetadata { name: $crate::dispatch::DecodeDifferent::Encode(stringify!($call_type)), functions: __functions_to_metadata!(0; $origin_type;; $( - fn $fn_name($from $(, $param_name: $param )* ) -> $result; + fn $fn_name( $( $param_name: $param ),* ) -> $result; $( $doc_attr ),*; )*), } @@ -510,15 +551,14 @@ macro_rules! __call_to_metadata { #[macro_export] #[doc(hidden)] macro_rules! __functions_to_metadata{ - // ROOT ( $fn_id:expr; $origin_type:ty; $( $function_metadata:expr ),*; - fn $fn_name:ident(root + fn $fn_name:ident( $( - , $param_name:ident : $param:ty - )* + $param_name:ident : $param:ty + ),* ) -> $result:ty; $( $fn_doc:expr ),*; $( $rest:tt )* @@ -531,31 +571,6 @@ macro_rules! __functions_to_metadata{ $($rest)* ) }; - // NON ROOT - ( - $fn_id:expr; - $origin_type:ty; - $( $function_metadata:expr ),*; - fn $fn_name:ident(origin - $( - , $param_name:ident : $param:ty - )* - ) -> $result:ty; - $( $fn_doc:expr ),*; - $($rest:tt)* - ) => { - __functions_to_metadata!( - $fn_id + 1; $origin_type; - $( $function_metadata, )* __function_to_metadata!( - fn $fn_name( - origin: $origin_type - $( ,$param_name : $param )* - ) -> $result; $( $fn_doc ),*; $fn_id; - ); - $($rest)* - ) - }; - // BASE CASE ( $fn_id:expr; $origin_type:ty; @@ -590,41 +605,6 @@ macro_rules! __function_to_metadata { documentation: $crate::dispatch::DecodeDifferent::Encode(&[ $( $fn_doc ),* ]), } }; - ( - fn $fn_name:ident() -> $result:ty; - $( $fn_doc:expr ),*; - $fn_id:expr; - ) => { - $crate::dispatch::FunctionMetadata { - id: $fn_id, - name: $crate::dispatch::DecodeDifferent::Encode(stringify!($fn_name)), - arguments: $crate::dispatch::DecodeDifferent::Encode(&[]), - documentation: $crate::dispatch::DecodeDifferent::Encode(&[ $( $fn_doc ),* ]), - } - }; -} - -/// Convert a function documentation attribute into its JSON representation. -#[macro_export] -#[doc(hidden)] -macro_rules! __function_doc_to_json { - ( - $prefix_str:tt; - $doc_attr:tt - $($rest:tt)* - ) => { - concat!( - $prefix_str, r#" ""#, - $doc_attr, - r#"""#, - __function_doc_to_json!(","; $($rest)*) - ) - }; - ( - $prefix_str:tt; - ) => { - "" - } } #[cfg(test)] @@ -664,12 +644,7 @@ mod tests { FunctionMetadata { id: 0, name: DecodeDifferent::Encode("aux_0"), - arguments: DecodeDifferent::Encode(&[ - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("origin"), - ty: DecodeDifferent::Encode("T::Origin"), - } - ]), + arguments: DecodeDifferent::Encode(&[]), documentation: DecodeDifferent::Encode(&[ " Hi, this is a comment." ]) @@ -678,10 +653,6 @@ mod tests { id: 1, name: DecodeDifferent::Encode("aux_1"), arguments: DecodeDifferent::Encode(&[ - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("origin"), - ty: DecodeDifferent::Encode("T::Origin"), - }, FunctionArgumentMetadata { name: DecodeDifferent::Encode("data"), ty: DecodeDifferent::Encode("i32"), @@ -693,10 +664,6 @@ mod tests { id: 2, name: DecodeDifferent::Encode("aux_2"), arguments: DecodeDifferent::Encode(&[ - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("origin"), - ty: DecodeDifferent::Encode("T::Origin"), - }, FunctionArgumentMetadata { name: DecodeDifferent::Encode("data"), ty: DecodeDifferent::Encode("i32"), diff --git a/substrate/srml/support/src/lib.rs b/substrate/srml/support/src/lib.rs index 16a6ba7344..e69a8a8d0b 100644 --- a/substrate/srml/support/src/lib.rs +++ b/substrate/srml/support/src/lib.rs @@ -61,10 +61,10 @@ mod hashable; #[macro_use] pub mod event; #[macro_use] -pub mod metadata; -#[macro_use] mod origin; #[macro_use] +pub mod metadata; +#[macro_use] mod runtime; pub use self::storage::{StorageVec, StorageList, StorageValue, StorageMap}; @@ -72,7 +72,6 @@ pub use self::hashable::Hashable; pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType}; pub use runtime_io::print; - #[macro_export] macro_rules! fail { ( $y:expr ) => {{ diff --git a/substrate/srml/support/src/metadata.rs b/substrate/srml/support/src/metadata.rs index 93e59f5343..fc9ae3693e 100644 --- a/substrate/srml/support/src/metadata.rs +++ b/substrate/srml/support/src/metadata.rs @@ -37,6 +37,7 @@ macro_rules! impl_runtime_metadata { $crate::metadata::RuntimeMetadata { outer_event: Self::outer_event_metadata(), modules: __runtime_modules_to_metadata!($runtime;; $( $rest )*), + outer_dispatch: Self::outer_dispatch_metadata(), } } } @@ -99,14 +100,15 @@ mod tests { use super::*; use substrate_metadata::{ EventMetadata, OuterEventMetadata, RuntimeModuleMetadata, CallMetadata, ModuleMetadata, - StorageFunctionModifier, StorageFunctionType, FunctionMetadata, FunctionArgumentMetadata, - StorageMetadata, StorageFunctionMetadata, + StorageFunctionModifier, StorageFunctionType, FunctionMetadata, + StorageMetadata, StorageFunctionMetadata, OuterDispatchMetadata, OuterDispatchCall }; use codec::{Decode, Encode}; mod system { pub trait Trait { - type Origin; + type Origin: Into>> + From>; + type AccountId; } decl_module! { @@ -118,6 +120,24 @@ mod tests { SystemEvent, } ); + + #[derive(Clone, PartialEq, Eq, Debug)] + pub enum RawOrigin { + Root, + Signed(AccountId), + Inherent, + } + + impl From> for RawOrigin { + fn from(s: Option) -> RawOrigin { + match s { + Some(who) => RawOrigin::Signed(who), + None => RawOrigin::Inherent, + } + } + } + + pub type Origin = RawOrigin<::AccountId>; } mod event_module { @@ -163,16 +183,19 @@ mod tests { ); decl_module! { - pub struct ModuleWithStorage for enum Call where origin: T::Origin {} + pub struct Module for enum Call where origin: T::Origin {} } decl_storage! { - trait Store for ModuleWithStorage as TestStorage { + trait Store for Module as TestStorage { StorageMethod : u32; } } } + type EventModule = event_module::Module; + type EventModule2 = event_module2::Module; + #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] pub struct TestRuntime; @@ -183,24 +206,36 @@ mod tests { } } + impl_outer_origin! { + pub enum Origin for TestRuntime {} + } + + impl_outer_dispatch! { + pub enum Call for TestRuntime where origin: Origin { + event_module::EventModule, + event_module2::EventModule2, + } + } + impl event_module::Trait for TestRuntime { - type Origin = u32; + type Origin = Origin; type Balance = u32; } impl event_module2::Trait for TestRuntime { - type Origin = u32; + type Origin = Origin; type Balance = u32; } impl system::Trait for TestRuntime { - type Origin = u32; + type Origin = Origin; + type AccountId = u32; } impl_runtime_metadata!( for TestRuntime with modules event_module::Module, - event_module2::ModuleWithStorage with Storage, + event_module2::Module with Storage, ); const EXPECTED_METADATA: RuntimeMetadata = RuntimeMetadata { @@ -251,12 +286,7 @@ mod tests { FunctionMetadata { id: 0, name: DecodeDifferent::Encode("aux_0"), - arguments: DecodeDifferent::Encode(&[ - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("origin"), - ty: DecodeDifferent::Encode("T::Origin"), - } - ]), + arguments: DecodeDifferent::Encode(&[]), documentation: DecodeDifferent::Encode(&[]), } ]) @@ -269,7 +299,7 @@ mod tests { prefix: DecodeDifferent::Encode("event_module2"), module: DecodeDifferent::Encode(FnEncode(|| ModuleMetadata { - name: DecodeDifferent::Encode("ModuleWithStorage"), + name: DecodeDifferent::Encode("Module"), call: CallMetadata { name: DecodeDifferent::Encode("Call"), functions: DecodeDifferent::Encode(&[]) @@ -290,7 +320,22 @@ mod tests { } ))), } - ]) + ]), + outer_dispatch: OuterDispatchMetadata { + name: DecodeDifferent::Encode("Call"), + calls: DecodeDifferent::Encode(&[ + OuterDispatchCall { + name: DecodeDifferent::Encode("EventModule"), + prefix: DecodeDifferent::Encode("event_module"), + index: 0, + }, + OuterDispatchCall { + name: DecodeDifferent::Encode("EventModule2"), + prefix: DecodeDifferent::Encode("event_module2"), + index: 1, + } + ]) + } }; #[test] diff --git a/substrate/srml/support/src/runtime.rs b/substrate/srml/support/src/runtime.rs index a34b942664..df8fa4c4d4 100644 --- a/substrate/srml/support/src/runtime.rs +++ b/substrate/srml/support/src/runtime.rs @@ -655,8 +655,8 @@ macro_rules! __decl_outer_dispatch { ; ) => { impl_outer_dispatch!( - pub enum Call where origin: Origin { - $( $parsed_name, )* + pub enum Call for $runtime where origin: Origin { + $( $parsed_modules::$parsed_name, )* } ); };