mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 09:17:58 +00:00
Allow modules to validate transaction, second attempt (#2463)
* first impl * rename origin::inherent to none * fix * fix * Apply suggestions from code review Co-Authored-By: thiolliere <gui.thiolliere@gmail.com> * comment * better error * doc * (add unsigned module 🤦) * doc * fix * implement for node-template as well * add validated unsigned to executor * fix * fix * bump version * testing xt * remove extraneous logic * licence * impl test
This commit is contained in:
@@ -29,7 +29,7 @@ pub use inherents::{InherentData, ProvideInherent, CheckInherentsResult, IsFatal
|
||||
///
|
||||
/// ```nocompile
|
||||
/// impl_outer_inherent! {
|
||||
/// pub struct InherentData where Block = Block, UncheckedExtrinsic = UncheckedExtrinsic {
|
||||
/// impl Inherents where Block = Block, UncheckedExtrinsic = UncheckedExtrinsic {
|
||||
/// timestamp: Timestamp,
|
||||
/// consensus: Consensus,
|
||||
/// /// Aura module using the `Timestamp` call.
|
||||
|
||||
@@ -52,6 +52,8 @@ pub mod metadata;
|
||||
mod runtime;
|
||||
#[macro_use]
|
||||
pub mod inherent;
|
||||
#[macro_use]
|
||||
pub mod unsigned;
|
||||
mod double_map;
|
||||
pub mod traits;
|
||||
|
||||
|
||||
@@ -265,14 +265,14 @@ mod tests {
|
||||
pub enum RawOrigin<AccountId> {
|
||||
Root,
|
||||
Signed(AccountId),
|
||||
Inherent,
|
||||
None,
|
||||
}
|
||||
|
||||
impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
|
||||
fn from(s: Option<AccountId>) -> RawOrigin<AccountId> {
|
||||
match s {
|
||||
Some(who) => RawOrigin::Signed(who),
|
||||
None => RawOrigin::Inherent,
|
||||
None => RawOrigin::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ macro_rules! impl_outer_origin {
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
impl $name {
|
||||
pub const INHERENT: Self = $name::system($system::RawOrigin::Inherent);
|
||||
pub const NONE: Self = $name::system($system::RawOrigin::None);
|
||||
pub const ROOT: Self = $name::system($system::RawOrigin::Root);
|
||||
pub fn signed(by: <$runtime as $system::Trait>::AccountId) -> Self {
|
||||
$name::system($system::RawOrigin::Signed(by))
|
||||
@@ -156,14 +156,14 @@ mod tests {
|
||||
pub enum RawOrigin<AccountId> {
|
||||
Root,
|
||||
Signed(AccountId),
|
||||
Inherent,
|
||||
None,
|
||||
}
|
||||
|
||||
impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
|
||||
fn from(s: Option<AccountId>) -> RawOrigin<AccountId> {
|
||||
match s {
|
||||
Some(who) => RawOrigin::Signed(who),
|
||||
None => RawOrigin::Inherent,
|
||||
None => RawOrigin::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
/// - `Inherent $( (CALL) )*` - If the module provides/can check inherents. The optional parameter
|
||||
/// is for modules that use a `Call` from a different module as
|
||||
/// inherent.
|
||||
/// - `ValidateUnsigned` - If the module validates unsigned extrinsics.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
@@ -286,6 +287,13 @@ macro_rules! construct_runtime {
|
||||
$name: $module::{ $( $modules $( ( $( $modules_args ),* ) )* ),* }
|
||||
),*;
|
||||
);
|
||||
$crate::__impl_outer_validate_unsigned!(
|
||||
$runtime;
|
||||
{};
|
||||
$(
|
||||
$name: $module::{ $( $modules $( ( $( $modules_args )* ) )* )* }
|
||||
)*
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -947,3 +955,65 @@ macro_rules! __decl_instance_import {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// A private macro that calls impl_outer_validate_unsigned for Call.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __impl_outer_validate_unsigned {
|
||||
(
|
||||
$runtime:ident;
|
||||
{ $( $parsed:tt )* };
|
||||
$name:ident: $module:ident:: $(<$module_instance:ident>::)? {
|
||||
ValidateUnsigned $( $modules:ident $( ( $( $modules_args:ident )* ) )* )*
|
||||
}
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
$crate::__impl_outer_validate_unsigned!(
|
||||
$runtime;
|
||||
{ $( $parsed )* $name };
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
(
|
||||
$runtime:ident;
|
||||
{ $( $parsed:tt )* };
|
||||
$name:ident: $module:ident:: $(<$module_instance:ident>::)? {
|
||||
$ignore:ident $( ( $( $args_ignore:ident )* ) )*
|
||||
$( $modules:ident $( ( $( $modules_args:ident )* ) )* )*
|
||||
}
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
$crate::__impl_outer_validate_unsigned!(
|
||||
$runtime;
|
||||
{ $( $parsed )* };
|
||||
$name: $module:: $(<$module_instance>::)? {
|
||||
$( $modules $( ( $( $modules_args )* ) )* )*
|
||||
}
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
(
|
||||
$runtime:ident;
|
||||
{ $( $parsed:tt )* };
|
||||
$name:ident: $module:ident:: $(<$module_instance:ident>::)? {}
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
$crate::__impl_outer_validate_unsigned!(
|
||||
$runtime;
|
||||
{ $( $parsed )* };
|
||||
$( $rest )*
|
||||
);
|
||||
};
|
||||
(
|
||||
$runtime:ident;
|
||||
{ $(
|
||||
$parsed_modules:ident
|
||||
)* };
|
||||
) => {
|
||||
$crate::impl_outer_validate_unsigned!(
|
||||
impl ValidateUnsigned for $runtime {
|
||||
$( $parsed_modules )*
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
// Copyright 2019 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 crate::runtime_primitives::traits::ValidateUnsigned;
|
||||
#[doc(hidden)]
|
||||
pub use crate::runtime_primitives::transaction_validity::TransactionValidity;
|
||||
#[doc(hidden)]
|
||||
pub use crate::runtime_primitives::ApplyError;
|
||||
|
||||
|
||||
/// Implement `ValidateUnsigned` for `Runtime`.
|
||||
/// All given modules need to implement `ValidateUnsigned`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # mod timestamp {
|
||||
/// # pub struct Module;
|
||||
/// #
|
||||
/// # impl srml_support::unsigned::ValidateUnsigned for Module {
|
||||
/// # type Call = Call;
|
||||
/// #
|
||||
/// # fn validate_unsigned(call: &Self::Call) -> srml_support::unsigned::TransactionValidity {
|
||||
/// # unimplemented!();
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # pub enum Call {
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # pub type Timestamp = timestamp::Module;
|
||||
/// #
|
||||
/// #
|
||||
/// # pub enum Call {
|
||||
/// # Timestamp(timestamp::Call),
|
||||
/// # }
|
||||
/// # #[allow(unused)]
|
||||
/// pub struct Runtime;
|
||||
///
|
||||
/// srml_support::impl_outer_validate_unsigned! {
|
||||
/// impl ValidateUnsigned for Runtime {
|
||||
/// Timestamp
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! impl_outer_validate_unsigned {
|
||||
(
|
||||
impl ValidateUnsigned for $runtime:ident {
|
||||
$( $module:ident )*
|
||||
}
|
||||
) => {
|
||||
impl $crate::unsigned::ValidateUnsigned for $runtime {
|
||||
type Call = Call;
|
||||
|
||||
fn validate_unsigned(call: &Self::Call) -> $crate::unsigned::TransactionValidity {
|
||||
#[allow(unreachable_patterns)]
|
||||
match call {
|
||||
$( Call::$module(inner_call) => $module::validate_unsigned(inner_call), )*
|
||||
_ => $crate::unsigned::TransactionValidity::Invalid($crate::unsigned::ApplyError::BadSignature as i8),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_empty_call {
|
||||
pub enum Call {
|
||||
}
|
||||
|
||||
pub struct Runtime;
|
||||
|
||||
impl_outer_validate_unsigned! {
|
||||
impl ValidateUnsigned for Runtime {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_partial_and_full_call {
|
||||
pub mod timestamp {
|
||||
pub struct Module;
|
||||
|
||||
impl super::super::ValidateUnsigned for Module {
|
||||
type Call = Call;
|
||||
|
||||
fn validate_unsigned(_call: &Self::Call) -> super::super::TransactionValidity {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Call {
|
||||
Foo,
|
||||
}
|
||||
}
|
||||
|
||||
mod test_full_unsigned {
|
||||
pub type Timestamp = super::timestamp::Module;
|
||||
|
||||
pub enum Call {
|
||||
Timestamp(super::timestamp::Call),
|
||||
}
|
||||
|
||||
pub struct Runtime;
|
||||
|
||||
impl_outer_validate_unsigned! {
|
||||
impl ValidateUnsigned for Runtime {
|
||||
Timestamp
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn used() {
|
||||
let _ = Call::Timestamp(super::timestamp::Call::Foo);
|
||||
let _ = Runtime;
|
||||
}
|
||||
}
|
||||
|
||||
mod test_not_full_unsigned {
|
||||
pub enum Call {
|
||||
Timestamp(super::timestamp::Call),
|
||||
}
|
||||
|
||||
pub struct Runtime;
|
||||
|
||||
impl_outer_validate_unsigned! {
|
||||
impl ValidateUnsigned for Runtime {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn used() {
|
||||
let _ = Call::Timestamp(super::timestamp::Call::Foo);
|
||||
let _ = Runtime;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user