mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 18:07:58 +00:00
Don't require module name in inherents (#6576)
* Start * Cleanup `construct_runtime!` * Add tests * Fix after merge * Update the docs
This commit is contained in:
@@ -31,19 +31,20 @@ pub use sp_inherents::{InherentData, ProvideInherent, CheckInherentsResult, IsFa
|
||||
/// ```nocompile
|
||||
/// impl_outer_inherent! {
|
||||
/// impl Inherents where Block = Block, UncheckedExtrinsic = UncheckedExtrinsic {
|
||||
/// timestamp: Timestamp,
|
||||
/// consensus: Consensus,
|
||||
/// /// Aura module using the `Timestamp` call.
|
||||
/// aura: Timestamp,
|
||||
/// timestamp,
|
||||
/// consensus,
|
||||
/// aura,
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! impl_outer_inherent {
|
||||
(
|
||||
impl Inherents where Block = $block:ident, UncheckedExtrinsic = $uncheckedextrinsic:ident
|
||||
impl Inherents where
|
||||
Block = $block:ident,
|
||||
UncheckedExtrinsic = $uncheckedextrinsic:ident
|
||||
{
|
||||
$( $module:ident: $call:ident, )*
|
||||
$( $module:ident, )*
|
||||
}
|
||||
) => {
|
||||
trait InherentDataExt {
|
||||
@@ -55,15 +56,14 @@ macro_rules! impl_outer_inherent {
|
||||
impl InherentDataExt for $crate::inherent::InherentData {
|
||||
fn create_extrinsics(&self) ->
|
||||
$crate::inherent::Vec<<$block as $crate::inherent::BlockT>::Extrinsic> {
|
||||
use $crate::inherent::ProvideInherent;
|
||||
use $crate::inherent::Extrinsic;
|
||||
use $crate::inherent::{ProvideInherent, Extrinsic};
|
||||
|
||||
let mut inherents = Vec::new();
|
||||
|
||||
$(
|
||||
if let Some(inherent) = $module::create_inherent(self) {
|
||||
inherents.push($uncheckedextrinsic::new(
|
||||
Call::$call(inherent),
|
||||
inherent.into(),
|
||||
None,
|
||||
).expect("Runtime UncheckedExtrinsic is not Opaque, so it has to return `Some`; qed"));
|
||||
}
|
||||
@@ -74,6 +74,7 @@ macro_rules! impl_outer_inherent {
|
||||
|
||||
fn check_extrinsics(&self, block: &$block) -> $crate::inherent::CheckInherentsResult {
|
||||
use $crate::inherent::{ProvideInherent, IsFatalError};
|
||||
use $crate::dispatch::IsSubType;
|
||||
|
||||
let mut result = $crate::inherent::CheckInherentsResult::new();
|
||||
for xt in block.extrinsics() {
|
||||
@@ -81,21 +82,18 @@ macro_rules! impl_outer_inherent {
|
||||
break
|
||||
}
|
||||
|
||||
$(
|
||||
match xt.function {
|
||||
Call::$call(ref call) => {
|
||||
if let Err(e) = $module::check_inherent(call, self) {
|
||||
result.put_error(
|
||||
$module::INHERENT_IDENTIFIER, &e
|
||||
).expect("There is only one fatal error; qed");
|
||||
if e.is_fatal_error() {
|
||||
return result
|
||||
}
|
||||
$({
|
||||
if let Some(call) = IsSubType::<_>::is_sub_type(&xt.function) {
|
||||
if let Err(e) = $module::check_inherent(call, self) {
|
||||
result.put_error(
|
||||
$module::INHERENT_IDENTIFIER, &e
|
||||
).expect("There is only one fatal error; qed");
|
||||
if e.is_fatal_error() {
|
||||
return result
|
||||
}
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
)*
|
||||
})*
|
||||
}
|
||||
|
||||
$(
|
||||
@@ -106,10 +104,10 @@ macro_rules! impl_outer_inherent {
|
||||
return false
|
||||
}
|
||||
|
||||
match xt.function {
|
||||
Call::$call(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
let call: Option<&<$module as ProvideInherent>::Call> =
|
||||
xt.function.is_sub_type();
|
||||
|
||||
call.is_some()
|
||||
});
|
||||
|
||||
if !found {
|
||||
@@ -138,3 +136,139 @@ macro_rules! impl_outer_inherent {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sp_runtime::{traits, testing::{Header, self}};
|
||||
use crate::dispatch::IsSubType;
|
||||
|
||||
#[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)]
|
||||
enum Call {
|
||||
Test(CallTest),
|
||||
Test2(CallTest2),
|
||||
}
|
||||
|
||||
impl From<CallTest> for Call {
|
||||
fn from(call: CallTest) -> Self {
|
||||
Self::Test(call)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CallTest2> for Call {
|
||||
fn from(call: CallTest2) -> Self {
|
||||
Self::Test2(call)
|
||||
}
|
||||
}
|
||||
|
||||
impl IsSubType<CallTest> for Call {
|
||||
fn is_sub_type(&self) -> Option<&CallTest> {
|
||||
match self {
|
||||
Self::Test(test) => Some(test),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IsSubType<CallTest2> for Call {
|
||||
fn is_sub_type(&self) -> Option<&CallTest2> {
|
||||
match self {
|
||||
Self::Test2(test) => Some(test),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)]
|
||||
enum CallTest {
|
||||
Something,
|
||||
SomethingElse,
|
||||
}
|
||||
|
||||
#[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)]
|
||||
enum CallTest2 {
|
||||
Something,
|
||||
}
|
||||
|
||||
struct ModuleTest;
|
||||
impl ProvideInherent for ModuleTest {
|
||||
type Call = CallTest;
|
||||
type Error = sp_inherents::MakeFatalError<()>;
|
||||
const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"test1235";
|
||||
|
||||
fn create_inherent(_: &InherentData) -> Option<Self::Call> {
|
||||
Some(CallTest::Something)
|
||||
}
|
||||
|
||||
fn check_inherent(call: &Self::Call, _: &InherentData) -> Result<(), Self::Error> {
|
||||
match call {
|
||||
CallTest::Something => Ok(()),
|
||||
CallTest::SomethingElse => Err(().into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ModuleTest2;
|
||||
impl ProvideInherent for ModuleTest2 {
|
||||
type Call = CallTest2;
|
||||
type Error = sp_inherents::MakeFatalError<()>;
|
||||
const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"test1234";
|
||||
|
||||
fn create_inherent(_: &InherentData) -> Option<Self::Call> {
|
||||
Some(CallTest2::Something)
|
||||
}
|
||||
}
|
||||
|
||||
type Block = testing::Block<Extrinsic>;
|
||||
|
||||
#[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)]
|
||||
struct Extrinsic {
|
||||
function: Call,
|
||||
}
|
||||
|
||||
impl traits::Extrinsic for Extrinsic {
|
||||
type Call = Call;
|
||||
type SignaturePayload = ();
|
||||
|
||||
fn new(function: Call, _: Option<()>) -> Option<Self> {
|
||||
Some(Self { function })
|
||||
}
|
||||
}
|
||||
|
||||
parity_util_mem::malloc_size_of_is_0!(Extrinsic);
|
||||
|
||||
impl_outer_inherent! {
|
||||
impl Inherents where Block = Block, UncheckedExtrinsic = Extrinsic {
|
||||
ModuleTest,
|
||||
ModuleTest2,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_inherents_works() {
|
||||
let inherents = InherentData::new().create_extrinsics();
|
||||
|
||||
let expected = vec![
|
||||
Extrinsic { function: Call::Test(CallTest::Something) },
|
||||
Extrinsic { function: Call::Test2(CallTest2::Something) },
|
||||
];
|
||||
assert_eq!(expected, inherents);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_inherents_works() {
|
||||
let block = Block::new(
|
||||
Header::new_from_number(1),
|
||||
vec![Extrinsic { function: Call::Test(CallTest::Something) }],
|
||||
);
|
||||
|
||||
assert!(InherentData::new().check_extrinsics(&block).ok());
|
||||
|
||||
let block = Block::new(
|
||||
Header::new_from_number(1),
|
||||
vec![Extrinsic { function: Call::Test(CallTest::SomethingElse) }],
|
||||
);
|
||||
|
||||
assert!(InherentData::new().check_extrinsics(&block).fatal_error());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user