Move inherent implementation into the modules (#924)

* Adds new `ProvideInherent` trait

Also implements the new trait for `srml/consensus` and `srml/timestamp`.

* Adds `impl_outer_inherent!` macro

* Reexport macros from `alloc`

* Introduce `RuntimeString` and fix `ProvideInherent` on `no_std`

* Replace `VersionString` with `RuntimeString`

* Improvements for `impl_outer_inherent!`

* Make `construct_runtime!` support `impl_outer_inherent!`

* Fixes after rebase

* Whitespace
This commit is contained in:
Bastian Köcher
2018-10-18 10:55:52 +02:00
committed by Gav Wood
parent 36625faa9f
commit 4132a49fbb
31 changed files with 498 additions and 166 deletions
+128
View File
@@ -0,0 +1,128 @@
// Copyright 2018 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/>.
#[doc(hidden)]
pub use rstd::{result::Result, vec::Vec};
#[doc(hidden)]
pub use runtime_primitives::traits::ProvideInherent;
/// Implement the outer inherent.
/// All given modules need to implement `ProvideInherent`.
///
/// # Example
///
/// ```nocompile
/// impl_outer_inherent! {
/// pub struct InherentData where Block = Block, UncheckedExtrinsic = UncheckedExtrinsic {
/// timestamp: Timestamp export Error as TimestampInherentError,
/// consensus: Consensus,
/// }
/// }
/// ```
///
/// Additional parameters after `UncheckedExtrinsic` are `Error` and `Call`.
#[macro_export]
macro_rules! impl_outer_inherent {
(
$(#[$attr:meta])*
pub struct $name:ident where Block = $block:ident, UncheckedExtrinsic = $unchecked:ident {
$( $module:ident: $module_ty:ident $(export Error as $error_name:ident)*, )*
}
) => {
impl_outer_inherent!(
$( #[$attr] )*
pub struct $name where Block = $block, UncheckedExtrinsic = $unchecked, Error = InherentError, Call = Call {
$( $module: $module_ty $(export Error as $error_name)*, )*
}
);
};
(
$(#[$attr:meta])*
pub struct $name:ident where Block = $block:ident, UncheckedExtrinsic = $unchecked:ident, Error = $error:ident {
$( $module:ident: $module_ty:ident $(export Error as $error_name:ident)*, )*
}
) => {
impl_outer_inherent!(
$( #[$attr] )*
pub struct $name where Block = $block, UncheckedExtrinsic = $unchecked, Error = $error, Call = Call {
$( $module: $module_ty $(export Error as $error_name)*, )*
}
);
};
(
$(#[$attr:meta])*
pub struct $name:ident where Block = $block:ident, UncheckedExtrinsic = $unchecked:ident, Error = $error:ident, Call = $call:ident {
$( $module:ident: $module_ty:ident $(export Error as $error_name:ident)*, )*
}
) => {
$( #[$attr] )*
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Encode, Decode)]
/// Inherent data to include in a block.
pub struct $name {
$( $module: <$module_ty as $crate::inherent::ProvideInherent>::Inherent, )*
}
$(
$(
pub type $error_name =<$module_ty as $crate::inherent::ProvideInherent>::Error;
)*
)*
impl $name {
/// Create a new instance.
pub fn new( $( $module: <$module_ty as $crate::inherent::ProvideInherent>::Inherent ),* ) -> Self {
Self {
$( $module, )*
}
}
fn create_inherent_extrinsics(self) -> Vec<$unchecked> {
let mut inherent = $crate::inherent::Vec::new();
$(
inherent.extend(
<$module_ty as $crate::inherent::ProvideInherent>::create_inherent_extrinsics(self.$module)
.into_iter()
.map(|v| (v.0, $unchecked::new_unsigned($call::$module_ty(v.1))))
);
)*
inherent.as_mut_slice().sort_unstable_by_key(|v| v.0);
inherent.into_iter().map(|v| v.1).collect()
}
fn check_inherents(self, block: $block) -> $crate::inherent::Result<(), $error> {
$(
<$module_ty as $crate::inherent::ProvideInherent>::check_inherent(
&block, self.$module, &|xt| match xt.function {
Call::$module_ty(ref data) => Some(data),
_ => None,
}).map_err($error::$module_ty)?;
)*
Ok(())
}
}
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Encode)]
#[cfg_attr(feature = "std", derive(Decode))]
pub enum $error {
$( $module_ty(<$module_ty as $crate::inherent::ProvideInherent>::Error), )*
}
};
}
+3 -10
View File
@@ -21,15 +21,12 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(feature = "std")]
extern crate serde;
extern crate sr_std as rstd;
extern crate sr_io as runtime_io;
#[cfg(feature = "std")]
#[doc(hidden)]
pub extern crate sr_primitives as runtime_primitives;
extern crate substrate_metadata;
@@ -49,12 +46,6 @@ extern crate parity_codec_derive;
pub extern crate parity_codec as codec;
pub use self::storage::generator::Storage as GenericStorage;
#[cfg(feature = "std")]
pub mod alloc {
pub use std::boxed;
pub use std::vec;
}
#[macro_use]
pub mod dispatch;
#[macro_use]
@@ -68,6 +59,8 @@ mod origin;
pub mod metadata;
#[macro_use]
mod runtime;
#[macro_use]
pub mod inherent;
pub use self::storage::{StorageVec, StorageList, StorageValue, StorageMap};
pub use self::hashable::Hashable;
+130 -9
View File
@@ -47,12 +47,16 @@
#[macro_export]
macro_rules! construct_runtime {
(
pub enum $runtime:ident with Log ($log_internal:ident: DigestItem<$( $log_genarg:ty ),+>) {
pub enum $runtime:ident with Log ($log_internal:ident: DigestItem<$( $log_genarg:ty ),+>)
where Block = $block:ident, UncheckedExtrinsic = $unchecked:ident
{
$( $rest:tt )*
}
) => {
construct_runtime!(
$runtime;
$block;
$unchecked;
$log_internal < $( $log_genarg ),* >;
;
$( $rest )*
@@ -60,6 +64,8 @@ macro_rules! construct_runtime {
};
(
$runtime:ident;
$block:ident;
$unchecked:ident;
$log_internal:ident <$( $log_genarg:ty ),+>;
$(
$expanded_name:ident: $expanded_module:ident::{
@@ -85,6 +91,8 @@ macro_rules! construct_runtime {
) => {
construct_runtime!(
$runtime;
$block;
$unchecked;
$log_internal < $( $log_genarg ),* >;
$(
$expanded_name: $expanded_module::{
@@ -110,6 +118,8 @@ macro_rules! construct_runtime {
};
(
$runtime:ident;
$block:ident;
$unchecked:ident;
$log_internal:ident <$( $log_genarg:ty ),+>;
$(
$expanded_name:ident: $expanded_module:ident::{
@@ -142,6 +152,8 @@ macro_rules! construct_runtime {
) => {
construct_runtime!(
$runtime;
$block;
$unchecked;
$log_internal < $( $log_genarg ),* >;
$(
$expanded_name: $expanded_module::{
@@ -173,6 +185,8 @@ macro_rules! construct_runtime {
};
(
$runtime:ident;
$block:ident;
$unchecked:ident;
$log_internal:ident <$( $log_genarg:ty ),+>;
$(
$expanded_name:ident: $expanded_module:ident::{
@@ -204,6 +218,8 @@ macro_rules! construct_runtime {
) => {
construct_runtime!(
$runtime;
$block;
$unchecked;
$log_internal < $( $log_genarg ),* >;
$(
$expanded_name: $expanded_module::{
@@ -234,6 +250,8 @@ macro_rules! construct_runtime {
};
(
$runtime:ident;
$block:ident;
$unchecked:ident;
$log_internal:ident <$( $log_genarg:ty ),+>;
$(
$name:ident: $module:ident::{
@@ -245,6 +263,13 @@ macro_rules! construct_runtime {
}
),*;
) => {
mashup! {
$(
substrate_generate_ident_name["config-ident" $name] = $name Config;
substrate_generate_ident_name["inherent-error-ident" $name] = $name InherentError;
)*
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct $runtime;
@@ -298,6 +323,15 @@ macro_rules! construct_runtime {
$name: $module::{ $( $modules $( <$modules_generic> )* ),* }
),*;
);
__decl_outer_inherent!(
$runtime;
$block;
$unchecked;
;
$(
$name: $module::{ $( $modules $( <$modules_generic> )* ),* }
),*;
);
}
}
@@ -980,17 +1014,104 @@ macro_rules! __decl_outer_config {
$( $parsed_modules:ident :: $parsed_name:ident ),*;
;
) => {
mashup! {
$(
substrate_generate_config_name["config-name" $parsed_name] = $parsed_name Config;
)*
}
substrate_generate_config_name! {
substrate_generate_ident_name! {
impl_outer_config!(
pub struct GenesisConfig for $runtime {
$(
"config-name" $parsed_name => $parsed_modules,
"config-ident" $parsed_name => $parsed_modules,
)*
}
);
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __decl_outer_inherent {
(
$runtime:ident;
$block:ident;
$unchecked:ident;
$( $parsed_modules:ident :: $parsed_name:ident ),*;
$name:ident: $module:ident::{
Inherent $(, $modules:ident $( <$modules_generic:ident> )* )*
}
$(, $rest_name:ident : $rest_module:ident::{
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
})*;
) => {
__decl_outer_inherent!(
$runtime;
$block;
$unchecked;
$( $parsed_modules :: $parsed_name, )* $module::$name;
$(
$rest_name: $rest_module::{
$( $rest_modules $( <$rest_modules_generic> )* ),*
}
),*;
);
};
(
$runtime:ident;
$block:ident;
$unchecked:ident;
$( $parsed_modules:ident :: $parsed_name:ident ),*;
$name:ident: $module:ident::{
$ingore:ident $( <$ignor:ident> )* $(, $modules:ident $( <$modules_generic:ident> )* )*
}
$(, $rest_name:ident : $rest_module:ident::{
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
})*;
) => {
__decl_outer_inherent!(
$runtime;
$block;
$unchecked;
$( $parsed_modules :: $parsed_name ),*;
$name: $module::{ $( $modules $( <$modules_generic> )* ),* }
$(
, $rest_name: $rest_module::{
$( $rest_modules $( <$rest_modules_generic> )* ),*
}
)*;
);
};
(
$runtime:ident;
$block:ident;
$unchecked:ident;
$( $parsed_modules:ident :: $parsed_name:ident ),*;
$name:ident: $module:ident::{}
$(, $rest_name:ident : $rest_module:ident::{
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
})*;
) => {
__decl_outer_inherent!(
$runtime;
$block;
$unchecked;
$( $parsed_modules :: $parsed_name ),*;
$(
$rest_name: $rest_module::{
$( $rest_modules $( <$rest_modules_generic> )* ),*
}
),*;
);
};
(
$runtime:ident;
$block:ident;
$unchecked:ident;
$( $parsed_modules:ident :: $parsed_name:ident ),*;
;
) => {
substrate_generate_ident_name! {
impl_outer_inherent!(
pub struct InherentData where Block = $block, UncheckedExtrinsic = $unchecked {
$(
$parsed_modules: $parsed_name export Error as "inherent-error-ident" $parsed_name,
)*
}
);