mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 01:21:07 +00:00
Add OnInitialise handler. (#1690)
* Add OnInitialise handler. Closes #1686 * Fix typo * Fix wasm build * Add tests for initialise and finalise.
This commit is contained in:
@@ -251,6 +251,15 @@ pub trait OnFinalise<BlockNumber> {
|
||||
|
||||
impl<N> OnFinalise<N> for () {}
|
||||
|
||||
/// The block initialisation trait. Implementing this lets you express what should happen
|
||||
/// for your module when the block is beginning (right before the first extrinsic is executed).
|
||||
pub trait OnInitialise<BlockNumber> {
|
||||
/// The block is being initialised. Implement to have something happen.
|
||||
fn on_initialise(_n: BlockNumber) {}
|
||||
}
|
||||
|
||||
impl<N> OnInitialise<N> for () {}
|
||||
|
||||
macro_rules! tuple_impl {
|
||||
($one:ident,) => {
|
||||
impl<Number: Copy, $one: OnFinalise<Number>> OnFinalise<Number> for ($one,) {
|
||||
@@ -258,6 +267,11 @@ macro_rules! tuple_impl {
|
||||
$one::on_finalise(n);
|
||||
}
|
||||
}
|
||||
impl<Number: Copy, $one: OnInitialise<Number>> OnInitialise<Number> for ($one,) {
|
||||
fn on_initialise(n: Number) {
|
||||
$one::on_initialise(n);
|
||||
}
|
||||
}
|
||||
};
|
||||
($first:ident, $($rest:ident,)+) => {
|
||||
impl<
|
||||
@@ -270,6 +284,16 @@ macro_rules! tuple_impl {
|
||||
$($rest::on_finalise(n);)+
|
||||
}
|
||||
}
|
||||
impl<
|
||||
Number: Copy,
|
||||
$first: OnInitialise<Number>,
|
||||
$($rest: OnInitialise<Number>),+
|
||||
> OnInitialise<Number> for ($first, $($rest),+) {
|
||||
fn on_initialise(n: Number) {
|
||||
$first::on_initialise(n);
|
||||
$($rest::on_initialise(n);)+
|
||||
}
|
||||
}
|
||||
tuple_impl!($($rest,)+);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("node"),
|
||||
impl_name: create_runtime_str!("substrate-node"),
|
||||
authoring_version: 10,
|
||||
spec_version: 19,
|
||||
impl_version: 19,
|
||||
spec_version: 20,
|
||||
impl_version: 20,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
|
||||
|
||||
BIN
Binary file not shown.
@@ -31,7 +31,8 @@ extern crate sr_io;
|
||||
#[cfg(test)]
|
||||
extern crate substrate_primitives;
|
||||
|
||||
// Needed for various traits. In our case, `OnFinalise`.
|
||||
// Needed for various traits. In our case, `OnInitialise` and `OnFinalise` in our
|
||||
// tests.
|
||||
extern crate sr_primitives;
|
||||
|
||||
// Needed for deriving `Encode` and `Decode` for `RawEvent`.
|
||||
@@ -63,6 +64,52 @@ pub trait Trait: balances::Trait {
|
||||
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
// A macro for the Storage trait, and its implementation, for this module.
|
||||
// This allows for type-safe usage of the Substrate storage database, so you can
|
||||
// keep things around between blocks.
|
||||
trait Store for Module<T: Trait> as Example {
|
||||
// Any storage declarations of the form:
|
||||
// `pub? Name get(getter_name)? [config()|config(myname)] [build(|_| {...})] : <type> (= <new_default_value>)?;`
|
||||
// where `<type>` is either:
|
||||
// - `Type` (a basic value item); or
|
||||
// - `map KeyType => ValueType` (a map item).
|
||||
//
|
||||
// Note that there are two optional modifiers for the storage type declaration.
|
||||
// - `Foo: Option<u32>`:
|
||||
// - `Foo::put(1); Foo::get()` returns `Some(1)`;
|
||||
// - `Foo::kill(); Foo::get()` returns `None`.
|
||||
// - `Foo: u32`:
|
||||
// - `Foo::put(1); Foo::get()` returns `1`;
|
||||
// - `Foo::kill(); Foo::get()` returns `0` (u32::default()).
|
||||
// e.g. Foo: u32;
|
||||
// e.g. pub Bar get(bar): map T::AccountId => Vec<(T::Balance, u64)>;
|
||||
//
|
||||
// For basic value items, you'll get a type which implements
|
||||
// `support::StorageValue`. For map items, you'll get a type which
|
||||
// implements `support::StorageMap`.
|
||||
//
|
||||
// If they have a getter (`get(getter_name)`), then your module will come
|
||||
// equipped with `fn getter_name() -> Type` for basic value items or
|
||||
// `fn getter_name(key: KeyType) -> ValueType` for map items.
|
||||
Dummy get(dummy) config(): Option<T::Balance>;
|
||||
|
||||
// this one uses the default, we'll demonstrate the usage of 'mutate' API.
|
||||
Foo get(foo) config(): T::Balance;
|
||||
}
|
||||
}
|
||||
|
||||
/// An event in this module. Events are simple means of reporting specific conditions and
|
||||
/// circumstances that have happened that users, Dapps and/or chain explorers would find
|
||||
/// interesting and otherwise difficult to detect.
|
||||
decl_event!(
|
||||
pub enum Event<T> where B = <T as balances::Trait>::Balance {
|
||||
// Just a normal `enum`, here's a dummy event to ensure it compiles.
|
||||
/// Dummy event, just here so there's a generic type that's used.
|
||||
Dummy(B),
|
||||
}
|
||||
);
|
||||
|
||||
// The module declaration. This states the entry points that we handle. The
|
||||
// macro takes care of the marshalling of arguments and dispatch.
|
||||
//
|
||||
@@ -182,6 +229,12 @@ decl_module! {
|
||||
<Dummy<T>>::put(new_value);
|
||||
}
|
||||
|
||||
// The signature could also look like: `fn on_initialise()`
|
||||
fn on_initialise(_n: T::BlockNumber) {
|
||||
// Anything that needs to be done at the start of the block.
|
||||
// We don't do anything here.
|
||||
}
|
||||
|
||||
// The signature could also look like: `fn on_finalise()`
|
||||
fn on_finalise(_n: T::BlockNumber) {
|
||||
// Anything that needs to be done at the end of the block.
|
||||
@@ -191,52 +244,6 @@ decl_module! {
|
||||
}
|
||||
}
|
||||
|
||||
/// An event in this module. Events are simple means of reporting specific conditions and
|
||||
/// circumstances that have happened that users, Dapps and/or chain explorers would find
|
||||
/// interesting and otherwise difficult to detect.
|
||||
decl_event!(
|
||||
pub enum Event<T> where B = <T as balances::Trait>::Balance {
|
||||
// Just a normal `enum`, here's a dummy event to ensure it compiles.
|
||||
/// Dummy event, just here so there's a generic type that's used.
|
||||
Dummy(B),
|
||||
}
|
||||
);
|
||||
|
||||
decl_storage! {
|
||||
// A macro for the Storage trait, and its implementation, for this module.
|
||||
// This allows for type-safe usage of the Substrate storage database, so you can
|
||||
// keep things around between blocks.
|
||||
trait Store for Module<T: Trait> as Example {
|
||||
// Any storage declarations of the form:
|
||||
// `pub? Name get(getter_name)? [config()|config(myname)] [build(|_| {...})] : <type> (= <new_default_value>)?;`
|
||||
// where `<type>` is either:
|
||||
// - `Type` (a basic value item); or
|
||||
// - `map KeyType => ValueType` (a map item).
|
||||
//
|
||||
// Note that there are two optional modifiers for the storage type declaration.
|
||||
// - `Foo: Option<u32>`:
|
||||
// - `Foo::put(1); Foo::get()` returns `Some(1)`;
|
||||
// - `Foo::kill(); Foo::get()` returns `None`.
|
||||
// - `Foo: u32`:
|
||||
// - `Foo::put(1); Foo::get()` returns `1`;
|
||||
// - `Foo::kill(); Foo::get()` returns `0` (u32::default()).
|
||||
// e.g. Foo: u32;
|
||||
// e.g. pub Bar get(bar): map T::AccountId => Vec<(T::Balance, u64)>;
|
||||
//
|
||||
// For basic value items, you'll get a type which implements
|
||||
// `support::StorageValue`. For map items, you'll get a type which
|
||||
// implements `support::StorageMap`.
|
||||
//
|
||||
// If they have a getter (`get(getter_name)`), then your module will come
|
||||
// equipped with `fn getter_name() -> Type` for basic value items or
|
||||
// `fn getter_name(key: KeyType) -> ValueType` for map items.
|
||||
Dummy get(dummy) config(): Option<T::Balance>;
|
||||
|
||||
// this one uses the default, we'll demonstrate the usage of 'mutate' API.
|
||||
Foo get(foo) config(): T::Balance;
|
||||
}
|
||||
}
|
||||
|
||||
// The main implementation block for the module. Functions here fall into three broad
|
||||
// categories:
|
||||
// - Public interface. These are functions that are `pub` and generally fall into inspector
|
||||
@@ -269,7 +276,8 @@ 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, OnFinalise, IdentityLookup}, testing::{Digest, DigestItem, Header}
|
||||
BuildStorage, traits::{BlakeTwo256, OnInitialise, OnFinalise, IdentityLookup},
|
||||
testing::{Digest, DigestItem, Header}
|
||||
};
|
||||
|
||||
impl_outer_origin! {
|
||||
@@ -334,6 +342,7 @@ mod tests {
|
||||
assert_eq!(Example::dummy(), None);
|
||||
|
||||
// Check that accumulate works when we Dummy has None in it.
|
||||
<Example as OnInitialise<u64>>::on_initialise(2);
|
||||
assert_ok!(Example::accumulate_dummy(Origin::signed(1), 42));
|
||||
assert_eq!(Example::dummy(), Some(42));
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ use rstd::prelude::*;
|
||||
use rstd::marker::PhantomData;
|
||||
use rstd::result;
|
||||
use primitives::traits::{self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalise,
|
||||
MakePayment, Hash, As, Digest};
|
||||
OnInitialise, MakePayment, Hash, As, Digest};
|
||||
use runtime_support::Dispatchable;
|
||||
use codec::{Codec, Encode};
|
||||
use system::extrinsics_root;
|
||||
@@ -74,16 +74,16 @@ pub struct Executive<
|
||||
Block,
|
||||
Context,
|
||||
Payment,
|
||||
Finalisation,
|
||||
>(PhantomData<(System, Block, Context, Payment, Finalisation)>);
|
||||
AllModules,
|
||||
>(PhantomData<(System, Block, Context, Payment, AllModules)>);
|
||||
|
||||
impl<
|
||||
Context: Default,
|
||||
System: system::Trait,
|
||||
Block: traits::Block<Header=System::Header, Hash=System::Hash>,
|
||||
Payment: MakePayment<System::AccountId>,
|
||||
Finalisation: OnFinalise<System::BlockNumber>,
|
||||
> Executive<System, Block, Context, Payment, Finalisation> where
|
||||
AllModules: OnInitialise<System::BlockNumber> + OnFinalise<System::BlockNumber>,
|
||||
> Executive<System, Block, Context, Payment, AllModules> where
|
||||
Block::Extrinsic: Checkable<Context> + Codec,
|
||||
<Block::Extrinsic as Checkable<Context>>::Checked: Applyable<Index=System::Index, AccountId=System::AccountId>,
|
||||
<<Block::Extrinsic as Checkable<Context>>::Checked as Applyable>::Call: Dispatchable,
|
||||
@@ -92,6 +92,7 @@ impl<
|
||||
/// Start the execution of a particular block.
|
||||
pub fn initialise_block(header: &System::Header) {
|
||||
<system::Module<System>>::initialise(header.number(), header.parent_hash(), header.extrinsics_root());
|
||||
<AllModules as OnInitialise<System::BlockNumber>>::on_initialise(*header.number());
|
||||
}
|
||||
|
||||
fn initial_checks(block: &Block) {
|
||||
@@ -123,7 +124,7 @@ impl<
|
||||
|
||||
// post-transactional book-keeping.
|
||||
<system::Module<System>>::note_finished_extrinsics();
|
||||
Finalisation::on_finalise(*header.number());
|
||||
<AllModules as OnFinalise<System::BlockNumber>>::on_finalise(*header.number());
|
||||
|
||||
// any final checks
|
||||
Self::final_checks(&header);
|
||||
@@ -133,7 +134,7 @@ impl<
|
||||
/// except state-root.
|
||||
pub fn finalise_block() -> System::Header {
|
||||
<system::Module<System>>::note_finished_extrinsics();
|
||||
Finalisation::on_finalise(<system::Module<System>>::block_number());
|
||||
<AllModules as OnFinalise<System::BlockNumber>>::on_finalise(<system::Module<System>>::block_number());
|
||||
|
||||
// setup extrinsics
|
||||
<system::Module<System>>::derive_extrinsics();
|
||||
|
||||
@@ -86,8 +86,8 @@ impl<T> Parameter for T where T: Codec + Clone + Eq {}
|
||||
/// 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.
|
||||
/// The `on_initialise` and `on_finalise` functions are 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
|
||||
@@ -105,6 +105,7 @@ macro_rules! decl_module {
|
||||
for enum $call_type where origin: $origin_type, system = system
|
||||
{}
|
||||
{}
|
||||
{}
|
||||
[]
|
||||
$($t)*
|
||||
);
|
||||
@@ -122,6 +123,7 @@ macro_rules! decl_module {
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{}
|
||||
{}
|
||||
{}
|
||||
[]
|
||||
$($t)*
|
||||
);
|
||||
@@ -132,6 +134,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{}
|
||||
{ $( $on_initialise:tt )* }
|
||||
{ $( $on_finalise:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
@@ -143,6 +146,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type<$trait_instance: $trait_name>
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{ $vis fn deposit_event $(<$dpeg>)* () = default; }
|
||||
{ $( $on_initialise )* }
|
||||
{ $( $on_finalise )* }
|
||||
[ $($t)* ]
|
||||
$($rest)*
|
||||
@@ -153,6 +157,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{}
|
||||
{ $( $on_initialise:tt )* }
|
||||
{ $( $on_finalise:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
@@ -166,6 +171,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type<$trait_instance: $trait_name>
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{ $vis fn deposit_event $(<$dpeg>)* ($( $param_name: $param ),* ) { $( $impl )* } }
|
||||
{ $( $on_initialise )* }
|
||||
{ $( $on_finalise )* }
|
||||
[ $($t)* ]
|
||||
$($rest)*
|
||||
@@ -175,7 +181,8 @@ macro_rules! decl_module {
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialise:tt )* }
|
||||
{}
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
@@ -187,6 +194,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type<$trait_instance: $trait_name>
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{ $( $deposit_event )* }
|
||||
{ $( $on_initialise )* }
|
||||
{ fn on_finalise( $( $param_name : $param ),* ) { $( $impl )* } }
|
||||
[ $($t)* ]
|
||||
$($rest)*
|
||||
@@ -197,6 +205,30 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{}
|
||||
{ $( $on_finalise:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
fn on_initialise($($param_name:ident : $param:ty),* ) { $( $impl:tt )* }
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
decl_module!(@normalize
|
||||
$(#[$attr])*
|
||||
pub struct $mod_type<$trait_instance: $trait_name>
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{ $( $deposit_event )* }
|
||||
{ fn on_initialise( $( $param_name : $param ),* ) { $( $impl )* } }
|
||||
{ $( $on_finalise )* }
|
||||
[ $($t)* ]
|
||||
$($rest)*
|
||||
);
|
||||
};
|
||||
(@normalize
|
||||
$(#[$attr:meta])*
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialise:tt )* }
|
||||
{ $( $on_finalise:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
@@ -210,6 +242,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type<$trait_instance: $trait_name>
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{ $( $deposit_event )* }
|
||||
{ $( $on_initialise )* }
|
||||
{ $( $on_finalise )* }
|
||||
[
|
||||
$($t)*
|
||||
@@ -226,6 +259,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialise:tt )* }
|
||||
{ $( $on_finalise:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
@@ -245,6 +279,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialise:tt )* }
|
||||
{ $( $on_finalise:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
@@ -264,6 +299,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialise:tt )* }
|
||||
{ $( $on_finalise:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
@@ -277,6 +313,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type<$trait_instance: $trait_name>
|
||||
for enum $call_type where origin: $origin_type, system = $system
|
||||
{ $( $deposit_event )* }
|
||||
{ $( $on_initialise )* }
|
||||
{ $( $on_finalise )* }
|
||||
[
|
||||
$($t)*
|
||||
@@ -293,6 +330,7 @@ macro_rules! decl_module {
|
||||
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident>
|
||||
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialise:tt )* }
|
||||
{ $( $on_finalise:tt )* }
|
||||
[ $($t:tt)* ]
|
||||
) => {
|
||||
@@ -303,6 +341,7 @@ macro_rules! decl_module {
|
||||
$($t)*
|
||||
}
|
||||
{ $( $deposit_event )* }
|
||||
{ $( $on_initialise )* }
|
||||
{ $( $on_finalise )* }
|
||||
);
|
||||
};
|
||||
@@ -374,13 +413,47 @@ macro_rules! decl_module {
|
||||
}
|
||||
};
|
||||
|
||||
(@impl_on_initialise
|
||||
$module:ident<$trait_instance:ident: $trait_name:ident>;
|
||||
fn on_initialise() { $( $impl:tt )* }
|
||||
) => {
|
||||
impl<$trait_instance: $trait_name>
|
||||
$crate::runtime_primitives::traits::OnInitialise<$trait_instance::BlockNumber>
|
||||
for $module<$trait_instance>
|
||||
{
|
||||
fn on_initialise(_block_number_not_used: $trait_instance::BlockNumber) { $( $impl )* }
|
||||
}
|
||||
};
|
||||
|
||||
(@impl_on_initialise
|
||||
$module:ident<$trait_instance:ident: $trait_name:ident>;
|
||||
fn on_initialise($param:ident : $param_ty:ty) { $( $impl:tt )* }
|
||||
) => {
|
||||
impl<$trait_instance: $trait_name>
|
||||
$crate::runtime_primitives::traits::OnInitialise<$trait_instance::BlockNumber>
|
||||
for $module<$trait_instance>
|
||||
{
|
||||
fn on_initialise($param: $param_ty) { $( $impl )* }
|
||||
}
|
||||
};
|
||||
|
||||
(@impl_on_initialise
|
||||
$module:ident<$trait_instance:ident: $trait_name:ident>;
|
||||
) => {
|
||||
impl<$trait_instance: $trait_name>
|
||||
$crate::runtime_primitives::traits::OnInitialise<$trait_instance::BlockNumber>
|
||||
for $module<$trait_instance>
|
||||
{}
|
||||
};
|
||||
|
||||
(@impl_on_finalise
|
||||
$module:ident<$trait_instance:ident: $trait_name:ident>;
|
||||
fn on_finalise() { $( $impl:tt )* }
|
||||
) => {
|
||||
impl<$trait_instance: $trait_name>
|
||||
$crate::runtime_primitives::traits::OnFinalise<$trait_instance::BlockNumber>
|
||||
for $module<$trait_instance> {
|
||||
for $module<$trait_instance>
|
||||
{
|
||||
fn on_finalise(_block_number_not_used: $trait_instance::BlockNumber) { $( $impl )* }
|
||||
}
|
||||
};
|
||||
@@ -391,7 +464,8 @@ macro_rules! decl_module {
|
||||
) => {
|
||||
impl<$trait_instance: $trait_name>
|
||||
$crate::runtime_primitives::traits::OnFinalise<$trait_instance::BlockNumber>
|
||||
for $module<$trait_instance> {
|
||||
for $module<$trait_instance>
|
||||
{
|
||||
fn on_finalise($param: $param_ty) { $( $impl )* }
|
||||
}
|
||||
};
|
||||
@@ -401,7 +475,9 @@ macro_rules! decl_module {
|
||||
) => {
|
||||
impl<$trait_instance: $trait_name>
|
||||
$crate::runtime_primitives::traits::OnFinalise<$trait_instance::BlockNumber>
|
||||
for $module<$trait_instance> {}
|
||||
for $module<$trait_instance>
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
(@impl_function
|
||||
@@ -480,6 +556,7 @@ macro_rules! decl_module {
|
||||
)*
|
||||
}
|
||||
{ $( $deposit_event:tt )* }
|
||||
{ $( $on_initialise:tt )* }
|
||||
{ $( $on_finalise:tt )* }
|
||||
) => {
|
||||
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
|
||||
@@ -497,6 +574,12 @@ macro_rules! decl_module {
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub struct $mod_type<$trait_instance: $trait_name>(::core::marker::PhantomData<$trait_instance>);
|
||||
|
||||
decl_module! {
|
||||
@impl_on_initialise
|
||||
$mod_type<$trait_instance: $trait_name>;
|
||||
$( $on_initialise )*
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
@impl_on_finalise
|
||||
$mod_type<$trait_instance: $trait_name>;
|
||||
@@ -972,10 +1055,11 @@ macro_rules! __function_to_metadata {
|
||||
#[allow(dead_code)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::runtime_primitives::traits::{OnInitialise, OnFinalise};
|
||||
|
||||
pub trait Trait {
|
||||
type Origin;
|
||||
type BlockNumber;
|
||||
type BlockNumber: Into<u32>;
|
||||
}
|
||||
|
||||
pub mod system {
|
||||
@@ -994,6 +1078,9 @@ mod tests {
|
||||
fn aux_2(_origin, _data: i32, _data2: String) -> Result { unreachable!() }
|
||||
fn aux_3() -> Result { unreachable!() }
|
||||
fn aux_4(_data: i32) -> Result { unreachable!() }
|
||||
|
||||
fn on_initialise(n: T::BlockNumber) { if n.into() == 42 { panic!("on_initialise") } }
|
||||
fn on_finalise(n: T::BlockNumber) { if n.into() == 42 { panic!("on_finalise") } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1065,4 +1152,16 @@ mod tests {
|
||||
let encoded = call.encode();
|
||||
assert_eq!(encoded.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "on_initialise")]
|
||||
fn on_initialise_should_work() {
|
||||
<Module<TraitImpl> as OnInitialise<u32>>::on_initialise(42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "on_finalise")]
|
||||
fn on_finalise_should_work() {
|
||||
<Module<TraitImpl> as OnFinalise<u32>>::on_finalise(42);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user