diff --git a/substrate/srml/support/src/dispatch.rs b/substrate/srml/support/src/dispatch.rs index f751a5293eedfa6bb6ae06d4dc07f0e5cda6b2ee..900af554b4e29440e7be4aab1085309ed28f4ea3 100644 --- a/substrate/srml/support/src/dispatch.rs +++ b/substrate/srml/support/src/dispatch.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see <http://www.gnu.org/licenses/>. -//! Dispatch system. Just dispatches calls. +//! Dispatch system. Contains a macro for defining runtime modules and +//! generating values representing lazy module function calls. pub use rstd::prelude::{Vec, Clone, Eq, PartialEq}; #[cfg(feature = "std")] @@ -26,14 +27,23 @@ pub use srml_metadata::{ CallMetadata, FunctionArgumentMetadata, OuterDispatchMetadata, OuterDispatchCall }; +/// Result of a module function call; either nothing (functions are only called for "side efeects") +/// or an error message. pub type Result = result::Result<(), &'static str>; +/// A lazy call (module function and argument values) that can be executed via its dispatch() +/// method. pub trait Dispatchable { + /// Every function call to your runtime has an origin which specifies where the extrinsic was + /// generated from. In the case of a signed extrinsic (transaction), the origin contains an + /// identifier for the caller. The origin can be empty in the case of an inherent extrinsic. type Origin; type Trait; fn dispatch(self, origin: Self::Origin) -> Result; } +/// Serializable version of Dispatchable. +/// This value can be used as a "function" in an extrinsic. pub trait Callable { type Call: Dispatchable + Codec + Clone + PartialEq + Eq; } @@ -54,13 +64,34 @@ pub trait Parameter: Codec + Clone + Eq {} #[cfg(not(feature = "std"))] impl<T> Parameter for T where T: Codec + Clone + Eq {} -/// Declare a struct for this module, then implement dispatch logic to create a pairing of several -/// dispatch traits and enums. +/// Declare a module struct and implement the dispatch logic. +/// +/// Usually used as follows: +/// +/// decl_module! { +/// pub struct Module<T: Trait> for enum Call where origin: T::Origin +///{} +/// } +/// +/// where "Trait" is a trait describing this module's requirements for the Runtime type. +/// T::Origin is declared using a impl_outer_origin! per-module macro (which is generated by the +/// construct_runtime! macro) and automatically includes all the modules that are used by the +/// runtime (alongside with a variant called "system"). +/// +/// A runtime module is a collection of functions unified by a common problem domain and certain +/// shared types. The "functions" do not actually return values (see Dispatchable) and are only +/// used for side effects. +/// +/// For every module an associated enum (usually "Call") is generated with every variant +/// corresponding to a function of the module. This enum implements Callable and thus its values +/// can be used as an extrinsic's payload. /// /// The `on_finalise` function is special, since it can either take no parameters, /// or one parameter, which has the runtime's block number type. #[macro_export] macro_rules! decl_module { + // Macro transformations (to convert invocations with incomplete parameters to the canonical + // form) ( $(#[$attr:meta])* pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident> @@ -276,6 +307,9 @@ macro_rules! decl_module { ); }; + // Implementation of Call enum's .dispatch() method. + // TODO: this probably should be a different macro? + (@call root $mod_type:ident $trait_instance:ident $fn_name:ident $origin:ident $system:ident [ $( $param_name:ident),* ] @@ -432,6 +466,8 @@ macro_rules! decl_module { } }; + // The main macro expansion that actually renders the module code. + (@imp $(#[$attr:meta])* pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>