Refactor SignedExtension (#5540)

* Refactor SignedExtension

* Move DispatchInfo Associated type to Dispatchable
* Bound Call: Dispatchable
* Pass PostDispatchInfo to post_dispatch
* Pass DispatchInfo by reference to avoid clones

* Whitespace fix

Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Style changes from code review

Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Only decalre in test mod to remove warning

* Deduplicate Call definition

* Bound frame_system::trait::Call by Dispatchable

* Introduce DispatchInfoOf type alias

* Whitespace fix from review

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Alexander Theißen
2020-04-08 11:12:09 +02:00
committed by GitHub
parent f8c8355ac7
commit 30ae26074c
18 changed files with 235 additions and 167 deletions
+18 -5
View File
@@ -18,6 +18,19 @@
#![cfg(test)]
#[derive(Debug)]
pub struct CallWithDispatchInfo;
impl sp_runtime::traits::Dispatchable for CallWithDispatchInfo {
type Origin = ();
type Trait = ();
type Info = frame_support::weights::DispatchInfo;
type PostInfo = frame_support::weights::PostDispatchInfo;
fn dispatch(self, _origin: Self::Origin)
-> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
panic!("Do not use dummy implementation for dispatch.");
}
}
#[macro_export]
macro_rules! decl_tests {
($test:ty, $ext_builder:ty, $existential_deposit:expr) => {
@@ -40,7 +53,7 @@ macro_rules! decl_tests {
pub type System = frame_system::Module<$test>;
pub type Balances = Module<$test>;
pub const CALL: &<$test as frame_system::Trait>::Call = &();
pub const CALL: &<$test as frame_system::Trait>::Call = &$crate::tests::CallWithDispatchInfo;
/// create a transaction info struct from weight. Handy to avoid building the whole struct.
pub fn info_from_weight(w: Weight) -> DispatchInfo {
@@ -154,14 +167,14 @@ macro_rules! decl_tests {
ChargeTransactionPayment::from(1),
&1,
CALL,
info_from_weight(1),
&info_from_weight(1),
1,
).is_err());
assert!(<ChargeTransactionPayment<$test> as SignedExtension>::pre_dispatch(
ChargeTransactionPayment::from(0),
&1,
CALL,
info_from_weight(1),
&info_from_weight(1),
1,
).is_ok());
@@ -172,14 +185,14 @@ macro_rules! decl_tests {
ChargeTransactionPayment::from(1),
&1,
CALL,
info_from_weight(1),
&info_from_weight(1),
1,
).is_err());
assert!(<ChargeTransactionPayment<$test> as SignedExtension>::pre_dispatch(
ChargeTransactionPayment::from(0),
&1,
CALL,
info_from_weight(1),
&info_from_weight(1),
1,
).is_err());
});
@@ -18,14 +18,18 @@
#![cfg(test)]
use sp_runtime::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header};
use sp_runtime::{
Perbill,
traits::{ConvertInto, IdentityLookup},
testing::Header,
};
use sp_core::H256;
use sp_io;
use frame_support::{impl_outer_origin, parameter_types};
use frame_support::traits::Get;
use frame_support::weights::{Weight, DispatchInfo};
use std::cell::RefCell;
use crate::{GenesisConfig, Module, Trait, decl_tests};
use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo};
use frame_system as system;
impl_outer_origin!{
@@ -54,7 +58,7 @@ impl frame_system::Trait for Test {
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Call = ();
type Call = CallWithDispatchInfo;
type Hash = H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = u64;
+7 -3
View File
@@ -18,14 +18,18 @@
#![cfg(test)]
use sp_runtime::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header};
use sp_runtime::{
Perbill,
traits::{ConvertInto, IdentityLookup},
testing::Header,
};
use sp_core::H256;
use sp_io;
use frame_support::{impl_outer_origin, parameter_types};
use frame_support::traits::{Get, StorageMapShim};
use frame_support::weights::{Weight, DispatchInfo};
use std::cell::RefCell;
use crate::{GenesisConfig, Module, Trait, decl_tests};
use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo};
use frame_system as system;
impl_outer_origin!{
@@ -54,7 +58,7 @@ impl frame_system::Trait for Test {
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Call = ();
type Call = CallWithDispatchInfo;
type Hash = H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = u64;
+5 -4
View File
@@ -113,7 +113,10 @@ use sp_std::{prelude::*, marker::PhantomData, fmt::Debug};
use codec::{Codec, Encode, Decode};
use sp_io::hashing::blake2_256;
use sp_runtime::{
traits::{Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, SignedExtension},
traits::{
Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, SignedExtension,
DispatchInfoOf,
},
transaction_validity::{
ValidTransaction, InvalidTransaction, TransactionValidity, TransactionValidityError,
},
@@ -123,7 +126,6 @@ use frame_support::dispatch::{DispatchResult, Dispatchable};
use frame_support::{
Parameter, decl_module, decl_event, decl_storage, decl_error, storage::child,
parameter_types, IsSubType,
weights::DispatchInfo,
};
use frame_support::traits::{OnUnbalanced, Currency, Get, Time, Randomness};
use frame_system::{self as system, ensure_signed, RawOrigin, ensure_root};
@@ -1091,7 +1093,6 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckBlockGasLimit<T> {
type AccountId = T::AccountId;
type Call = <T as Trait>::Call;
type AdditionalSigned = ();
type DispatchInfo = DispatchInfo;
type Pre = ();
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
@@ -1100,7 +1101,7 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckBlockGasLimit<T> {
&self,
_: &Self::AccountId,
call: &Self::Call,
_: Self::DispatchInfo,
_: &DispatchInfoOf<Self::Call>,
_: usize,
) -> TransactionValidity {
let call = match call.is_sub_type() {
+2 -2
View File
@@ -2633,11 +2633,11 @@ fn check_block_gas_limit_works() {
let call: Call = crate::Call::put_code(1000, vec![]).into();
assert_eq!(
check.validate(&0, &call, info, 0), InvalidTransaction::ExhaustsResources.into(),
check.validate(&0, &call, &info, 0), InvalidTransaction::ExhaustsResources.into(),
);
let call: Call = crate::Call::update_schedule(Default::default()).into();
assert_eq!(check.validate(&0, &call, info, 0), Ok(Default::default()));
assert_eq!(check.validate(&0, &call, &info, 0), Ok(Default::default()));
});
}
+8 -8
View File
@@ -257,15 +257,16 @@ use sp_std::marker::PhantomData;
use frame_support::{
dispatch::DispatchResult, decl_module, decl_storage, decl_event,
weights::{
SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight,
PaysFee,
SimpleDispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee,
},
};
use sp_std::prelude::*;
use frame_system::{self as system, ensure_signed, ensure_root};
use codec::{Encode, Decode};
use sp_runtime::{
traits::{SignedExtension, Bounded, SaturatedConversion},
traits::{
SignedExtension, Bounded, SaturatedConversion, DispatchInfoOf,
},
transaction_validity::{
ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity,
},
@@ -619,7 +620,6 @@ impl<T: Trait + Send + Sync> SignedExtension for WatchDummy<T> {
// other pallets.
type Call = Call<T>;
type AdditionalSigned = ();
type DispatchInfo = DispatchInfo;
type Pre = ();
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
@@ -628,7 +628,7 @@ impl<T: Trait + Send + Sync> SignedExtension for WatchDummy<T> {
&self,
_who: &Self::AccountId,
call: &Self::Call,
_info: Self::DispatchInfo,
_info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity {
// if the transaction is too big, just drop it.
@@ -713,7 +713,7 @@ mod tests {
use super::*;
use frame_support::{
assert_ok, impl_outer_origin, parameter_types, weights::GetDispatchInfo,
assert_ok, impl_outer_origin, parameter_types, weights::{DispatchInfo, GetDispatchInfo},
traits::{OnInitialize, OnFinalize}
};
use sp_core::H256;
@@ -829,13 +829,13 @@ mod tests {
let info = DispatchInfo::default();
assert_eq!(
WatchDummy::<Test>(PhantomData).validate(&1, &call, info, 150)
WatchDummy::<Test>(PhantomData).validate(&1, &call, &info, 150)
.unwrap()
.priority,
Bounded::max_value(),
);
assert_eq!(
WatchDummy::<Test>(PhantomData).validate(&1, &call, info, 250),
WatchDummy::<Test>(PhantomData).validate(&1, &call, &info, 250),
InvalidTransaction::ExhaustsResources.into(),
);
})
+6 -6
View File
@@ -120,9 +120,9 @@ impl<
where
Block::Extrinsic: Checkable<Context> + Codec,
CheckedOf<Block::Extrinsic, Context>:
Applyable<DispatchInfo=DispatchInfo> +
Applyable +
GetDispatchInfo,
CallOf<Block::Extrinsic, Context>: Dispatchable,
CallOf<Block::Extrinsic, Context>: Dispatchable<Info=DispatchInfo>,
OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
UnsignedValidator: ValidateUnsigned<Call=CallOf<Block::Extrinsic, Context>>,
{
@@ -145,9 +145,9 @@ impl<
where
Block::Extrinsic: Checkable<Context> + Codec,
CheckedOf<Block::Extrinsic, Context>:
Applyable<DispatchInfo=DispatchInfo> +
Applyable +
GetDispatchInfo,
CallOf<Block::Extrinsic, Context>: Dispatchable,
CallOf<Block::Extrinsic, Context>: Dispatchable<Info=DispatchInfo>,
OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
UnsignedValidator: ValidateUnsigned<Call=CallOf<Block::Extrinsic, Context>>,
{
@@ -307,7 +307,7 @@ where
// Decode parameters and dispatch
let dispatch_info = xt.get_dispatch_info();
let r = Applyable::apply::<UnsignedValidator>(xt, dispatch_info, encoded_len)?;
let r = Applyable::apply::<UnsignedValidator>(xt, &dispatch_info, encoded_len)?;
<frame_system::Module<System>>::note_applied_extrinsic(&r, encoded_len as u32, dispatch_info);
@@ -348,7 +348,7 @@ where
let xt = uxt.check(&Default::default())?;
let dispatch_info = xt.get_dispatch_info();
xt.validate::<UnsignedValidator>(source, dispatch_info, encoded_len)
xt.validate::<UnsignedValidator>(source, &dispatch_info, encoded_len)
}
/// Start an offchain worker and generate extrinsics.
+3 -4
View File
@@ -288,7 +288,7 @@ use sp_runtime::{
curve::PiecewiseLinear,
traits::{
Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion, AtLeast32Bit,
SignedExtension,
SignedExtension, Dispatchable, DispatchInfoOf,
},
transaction_validity::{
TransactionValidityError, TransactionValidity, ValidTransaction, InvalidTransaction,
@@ -772,7 +772,7 @@ pub trait Trait: frame_system::Trait {
type ElectionLookahead: Get<Self::BlockNumber>;
/// The overarching call type.
type Call: From<Call<Self>> + IsSubType<Module<Self>, Self> + Clone;
type Call: Dispatchable + From<Call<Self>> + IsSubType<Module<Self>, Self> + Clone;
/// A transaction submitter.
type SubmitTransaction: SubmitUnsignedTransaction<Self, <Self as Trait>::Call>;
@@ -3135,7 +3135,6 @@ impl<T: Trait + Send + Sync> SignedExtension for LockStakingStatus<T> {
type AccountId = T::AccountId;
type Call = <T as Trait>::Call;
type AdditionalSigned = ();
type DispatchInfo = frame_support::weights::DispatchInfo;
type Pre = ();
fn additional_signed(&self) -> Result<(), TransactionValidityError> { Ok(()) }
@@ -3144,7 +3143,7 @@ impl<T: Trait + Send + Sync> SignedExtension for LockStakingStatus<T> {
&self,
_who: &Self::AccountId,
call: &Self::Call,
_info: Self::DispatchInfo,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
if let Some(inner_call) = call.is_sub_type() {
+1 -1
View File
@@ -2939,7 +2939,7 @@ mod offchain_phragmen {
let lock_staking: LockStakingStatus<Test> = Default::default();
assert_eq!(
lock_staking.validate(&10, &outer, Default::default(), Default::default(),),
lock_staking.validate(&10, &outer, &Default::default(), Default::default(),),
TransactionValidity::Err(InvalidTransaction::Stale.into()),
)
})
+3 -1
View File
@@ -53,7 +53,7 @@ pub enum Never {}
/// Serializable version of Dispatchable.
/// This value can be used as a "function" in an extrinsic.
pub trait Callable<T> {
type Call: Dispatchable<PostInfo=PostDispatchInfo> + Codec + Clone + PartialEq + Eq;
type Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo> + Codec + Clone + PartialEq + Eq;
}
// dirty hack to work around serde_derive issue
@@ -1593,6 +1593,7 @@ macro_rules! decl_module {
{
type Trait = $trait_instance;
type Origin = $origin_type;
type Info = $crate::weights::DispatchInfo;
type PostInfo = $crate::weights::PostDispatchInfo;
fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResultWithPostInfo {
match self {
@@ -1720,6 +1721,7 @@ macro_rules! impl_outer_dispatch {
impl $crate::dispatch::Dispatchable for $call_type {
type Origin = $origin;
type Trait = $call_type;
type Info = $crate::weights::DispatchInfo;
type PostInfo = $crate::weights::PostDispatchInfo;
fn dispatch(
self,
+2 -4
View File
@@ -256,9 +256,8 @@ mod tests {
struct TestExtension;
impl sp_runtime::traits::SignedExtension for TestExtension {
type AccountId = u32;
type Call = u32;
type Call = ();
type AdditionalSigned = u32;
type DispatchInfo = ();
type Pre = ();
const IDENTIFIER: &'static str = "testextension";
fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
@@ -270,9 +269,8 @@ mod tests {
struct TestExtension2;
impl sp_runtime::traits::SignedExtension for TestExtension2 {
type AccountId = u32;
type Call = u32;
type Call = ();
type AdditionalSigned = u32;
type DispatchInfo = ();
type Pre = ();
const IDENTIFIER: &'static str = "testextension2";
fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
+65 -49
View File
@@ -109,6 +109,7 @@ use sp_runtime::{
self, CheckEqual, AtLeast32Bit, Zero, SignedExtension, Lookup, LookupError,
SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin, SaturatedConversion,
MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded,
Dispatchable, DispatchInfoOf, PostDispatchInfoOf,
},
};
@@ -146,7 +147,7 @@ pub trait Trait: 'static + Eq + Clone {
+ Clone;
/// The aggregated `Call` type.
type Call: Debug;
type Call: Dispatchable + Debug;
/// Account index (aka nonce) type. This stores the number of previous transactions associated
/// with a sender account.
@@ -1167,7 +1168,9 @@ pub fn split_inner<T, R, S>(option: Option<T>, splitter: impl FnOnce(T) -> (R, S
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
pub struct CheckWeight<T: Trait + Send + Sync>(PhantomData<T>);
impl<T: Trait + Send + Sync> CheckWeight<T> {
impl<T: Trait + Send + Sync> CheckWeight<T> where
T::Call: Dispatchable<Info=DispatchInfo>
{
/// Get the quota ratio of each dispatch class type. This indicates that all operational
/// dispatches can use the full capacity of any resource, while user-triggered ones can consume
/// a portion.
@@ -1183,7 +1186,7 @@ impl<T: Trait + Send + Sync> CheckWeight<T> {
///
/// Upon successes, it returns the new block weight as a `Result`.
fn check_weight(
info: <Self as SignedExtension>::DispatchInfo,
info: &DispatchInfoOf<T::Call>,
) -> Result<Weight, TransactionValidityError> {
let current_weight = Module::<T>::all_extrinsics_weight();
let maximum_weight = T::MaximumBlockWeight::get();
@@ -1201,7 +1204,7 @@ impl<T: Trait + Send + Sync> CheckWeight<T> {
///
/// Upon successes, it returns the new block length as a `Result`.
fn check_block_length(
info: <Self as SignedExtension>::DispatchInfo,
info: &DispatchInfoOf<T::Call>,
len: usize,
) -> Result<u32, TransactionValidityError> {
let current_len = Module::<T>::all_extrinsics_len();
@@ -1217,7 +1220,7 @@ impl<T: Trait + Send + Sync> CheckWeight<T> {
}
/// get the priority of an extrinsic denoted by `info`.
fn get_priority(info: <Self as SignedExtension>::DispatchInfo) -> TransactionPriority {
fn get_priority(info: &DispatchInfoOf<T::Call>) -> TransactionPriority {
match info.class {
DispatchClass::Normal => info.weight.into(),
DispatchClass::Operational => Bounded::max_value(),
@@ -1235,7 +1238,7 @@ impl<T: Trait + Send + Sync> CheckWeight<T> {
///
/// It checks and notes the new weight and length.
fn do_pre_dispatch(
info: <Self as SignedExtension>::DispatchInfo,
info: &DispatchInfoOf<T::Call>,
len: usize,
) -> Result<(), TransactionValidityError> {
let next_len = Self::check_block_length(info, len)?;
@@ -1249,7 +1252,7 @@ impl<T: Trait + Send + Sync> CheckWeight<T> {
///
/// It only checks that the block weight and length limit will not exceed.
fn do_validate(
info: <Self as SignedExtension>::DispatchInfo,
info: &DispatchInfoOf<T::Call>,
len: usize,
) -> TransactionValidity {
// ignore the next weight and length. If they return `Ok`, then it is below the limit.
@@ -1260,11 +1263,12 @@ impl<T: Trait + Send + Sync> CheckWeight<T> {
}
}
impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> {
impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> where
T::Call: Dispatchable<Info=DispatchInfo>
{
type AccountId = T::AccountId;
type Call = T::Call;
type AdditionalSigned = ();
type DispatchInfo = DispatchInfo;
type Pre = ();
const IDENTIFIER: &'static str = "CheckWeight";
@@ -1274,7 +1278,7 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> {
self,
_who: &Self::AccountId,
_call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<(), TransactionValidityError> {
if info.class == DispatchClass::Mandatory {
@@ -1287,7 +1291,7 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> {
&self,
_who: &Self::AccountId,
_call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity {
if info.class == DispatchClass::Mandatory {
@@ -1298,7 +1302,7 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> {
fn pre_dispatch_unsigned(
_call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<(), TransactionValidityError> {
Self::do_pre_dispatch(info, len)
@@ -1306,7 +1310,7 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> {
fn validate_unsigned(
_call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity {
Self::do_validate(info, len)
@@ -1314,7 +1318,8 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckWeight<T> {
fn post_dispatch(
_pre: Self::Pre,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
_post_info: &PostDispatchInfoOf<Self::Call>,
_len: usize,
result: &DispatchResult,
) -> Result<(), TransactionValidityError> {
@@ -1363,11 +1368,12 @@ impl<T: Trait> Debug for CheckNonce<T> {
}
}
impl<T: Trait> SignedExtension for CheckNonce<T> {
impl<T: Trait> SignedExtension for CheckNonce<T> where
T::Call: Dispatchable<Info=DispatchInfo>
{
type AccountId = T::AccountId;
type Call = T::Call;
type AdditionalSigned = ();
type DispatchInfo = DispatchInfo;
type Pre = ();
const IDENTIFIER: &'static str = "CheckNonce";
@@ -1377,7 +1383,7 @@ impl<T: Trait> SignedExtension for CheckNonce<T> {
self,
who: &Self::AccountId,
_call: &Self::Call,
_info: Self::DispatchInfo,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> Result<(), TransactionValidityError> {
let mut account = Account::<T>::get(who);
@@ -1399,7 +1405,7 @@ impl<T: Trait> SignedExtension for CheckNonce<T> {
&self,
who: &Self::AccountId,
_call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
// check index
@@ -1458,7 +1464,6 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckEra<T> {
type AccountId = T::AccountId;
type Call = T::Call;
type AdditionalSigned = T::Hash;
type DispatchInfo = DispatchInfo;
type Pre = ();
const IDENTIFIER: &'static str = "CheckEra";
@@ -1466,7 +1471,7 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckEra<T> {
&self,
_who: &Self::AccountId,
_call: &Self::Call,
_info: Self::DispatchInfo,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
let current_u64 = <Module<T>>::block_number().saturated_into::<u64>();
@@ -1515,7 +1520,6 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckGenesis<T> {
type AccountId = T::AccountId;
type Call = <T as Trait>::Call;
type AdditionalSigned = T::Hash;
type DispatchInfo = DispatchInfo;
type Pre = ();
const IDENTIFIER: &'static str = "CheckGenesis";
@@ -1551,7 +1555,6 @@ impl<T: Trait + Send + Sync> SignedExtension for CheckVersion<T> {
type AccountId = T::AccountId;
type Call = <T as Trait>::Call;
type AdditionalSigned = u32;
type DispatchInfo = DispatchInfo;
type Pre = ();
const IDENTIFIER: &'static str = "CheckVersion";
@@ -1615,9 +1618,22 @@ mod tests {
fn on_killed_account(who: &u64) { KILLED.with(|r| r.borrow_mut().push(*who)) }
}
#[derive(Debug)]
pub struct Call {}
impl Dispatchable for Call {
type Origin = ();
type Trait = ();
type Info = DispatchInfo;
type PostInfo = ();
fn dispatch(self, _origin: Self::Origin)
-> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
panic!("Do not use dummy implementation for dispatch.");
}
}
impl Trait for Test {
type Origin = Origin;
type Call = ();
type Call = Call;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
@@ -1650,7 +1666,7 @@ mod tests {
type System = Module<Test>;
const CALL: &<Test as Trait>::Call = &();
const CALL: &<Test as Trait>::Call = &Call {};
fn new_test_ext() -> sp_io::TestExternalities {
GenesisConfig::default().build_storage::<Test>().unwrap().into()
@@ -1851,14 +1867,14 @@ mod tests {
let info = DispatchInfo::default();
let len = 0_usize;
// stale
assert!(CheckNonce::<Test>(0).validate(&1, CALL, info, len).is_err());
assert!(CheckNonce::<Test>(0).pre_dispatch(&1, CALL, info, len).is_err());
assert!(CheckNonce::<Test>(0).validate(&1, CALL, &info, len).is_err());
assert!(CheckNonce::<Test>(0).pre_dispatch(&1, CALL, &info, len).is_err());
// correct
assert!(CheckNonce::<Test>(1).validate(&1, CALL, info, len).is_ok());
assert!(CheckNonce::<Test>(1).pre_dispatch(&1, CALL, info, len).is_ok());
assert!(CheckNonce::<Test>(1).validate(&1, CALL, &info, len).is_ok());
assert!(CheckNonce::<Test>(1).pre_dispatch(&1, CALL, &info, len).is_ok());
// future
assert!(CheckNonce::<Test>(5).validate(&1, CALL, info, len).is_ok());
assert!(CheckNonce::<Test>(5).pre_dispatch(&1, CALL, info, len).is_err());
assert!(CheckNonce::<Test>(5).validate(&1, CALL, &info, len).is_ok());
assert!(CheckNonce::<Test>(5).pre_dispatch(&1, CALL, &info, len).is_err());
})
}
@@ -1883,9 +1899,9 @@ mod tests {
if f { assert!(r.is_err()) } else { assert!(r.is_ok()) }
};
reset_check_weight(small, false, 0);
reset_check_weight(medium, false, 0);
reset_check_weight(big, true, 1);
reset_check_weight(&small, false, 0);
reset_check_weight(&medium, false, 0);
reset_check_weight(&big, true, 1);
})
}
@@ -1896,7 +1912,7 @@ mod tests {
let len = 0_usize;
assert_eq!(System::all_extrinsics_weight(), 0);
let r = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, free, len);
let r = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &free, len);
assert!(r.is_ok());
assert_eq!(System::all_extrinsics_weight(), 0);
})
@@ -1910,7 +1926,7 @@ mod tests {
let normal_limit = normal_weight_limit();
assert_eq!(System::all_extrinsics_weight(), 0);
let r = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, max, len);
let r = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &max, len);
assert!(r.is_ok());
assert_eq!(System::all_extrinsics_weight(), normal_limit);
})
@@ -1927,15 +1943,15 @@ mod tests {
// given almost full block
AllExtrinsicsWeight::put(normal_limit);
// will not fit.
assert!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, normal, len).is_err());
assert!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err());
// will fit.
assert!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, op, len).is_ok());
assert!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok());
// likewise for length limit.
let len = 100_usize;
AllExtrinsicsLen::put(normal_length_limit());
assert!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, normal, len).is_err());
assert!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, op, len).is_ok());
assert!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err());
assert!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok());
})
}
@@ -1947,13 +1963,13 @@ mod tests {
let len = 0_usize;
let priority = CheckWeight::<Test>(PhantomData)
.validate(&1, CALL, normal, len)
.validate(&1, CALL, &normal, len)
.unwrap()
.priority;
assert_eq!(priority, 100);
let priority = CheckWeight::<Test>(PhantomData)
.validate(&1, CALL, op, len)
.validate(&1, CALL, &op, len)
.unwrap()
.priority;
assert_eq!(priority, u64::max_value());
@@ -1971,16 +1987,16 @@ mod tests {
if f { assert!(r.is_err()) } else { assert!(r.is_ok()) }
};
reset_check_weight(normal, normal_limit - 1, false);
reset_check_weight(normal, normal_limit, false);
reset_check_weight(normal, normal_limit + 1, true);
reset_check_weight(&normal, normal_limit - 1, false);
reset_check_weight(&normal, normal_limit, false);
reset_check_weight(&normal, normal_limit + 1, true);
// Operational ones don't have this limit.
let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: true };
reset_check_weight(op, normal_limit, false);
reset_check_weight(op, normal_limit + 100, false);
reset_check_weight(op, 1024, false);
reset_check_weight(op, 1025, true);
reset_check_weight(&op, normal_limit, false);
reset_check_weight(&op, normal_limit + 100, false);
reset_check_weight(&op, 1024, false);
reset_check_weight(&op, 1025, true);
})
}
@@ -2012,7 +2028,7 @@ mod tests {
System::set_block_number(17);
<BlockHash<Test>>::insert(16, H256::repeat_byte(1));
assert_eq!(ext.validate(&1, CALL, normal, len).unwrap().longevity, 15);
assert_eq!(ext.validate(&1, CALL, &normal, len).unwrap().longevity, 15);
})
}
+30 -23
View File
@@ -44,7 +44,10 @@ use sp_runtime::{
TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError,
TransactionValidity,
},
traits::{Zero, Saturating, SignedExtension, SaturatedConversion, Convert},
traits::{
Zero, Saturating, SignedExtension, SaturatedConversion, Convert, Dispatchable,
DispatchInfoOf,
},
};
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
@@ -98,7 +101,9 @@ decl_module! {
}
}
impl<T: Trait> Module<T> {
impl<T: Trait> Module<T> where
T::Call: Dispatchable<Info=DispatchInfo>,
{
/// Query the data that we know about the fee of a given `call`.
///
/// As this module is not and cannot be aware of the internals of a signed extension, it only
@@ -122,7 +127,7 @@ impl<T: Trait> Module<T> {
let dispatch_info = <Extrinsic as GetDispatchInfo>::get_dispatch_info(&unchecked_extrinsic);
let partial_fee =
<ChargeTransactionPayment<T>>::compute_fee(len, dispatch_info, 0u32.into());
<ChargeTransactionPayment<T>>::compute_fee(len, &dispatch_info, 0u32.into());
let DispatchInfo { weight, class, .. } = dispatch_info;
RuntimeDispatchInfo { weight, class, partial_fee }
@@ -134,7 +139,9 @@ impl<T: Trait> Module<T> {
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
pub struct ChargeTransactionPayment<T: Trait + Send + Sync>(#[codec(compact)] BalanceOf<T>);
impl<T: Trait + Send + Sync> ChargeTransactionPayment<T> {
impl<T: Trait + Send + Sync> ChargeTransactionPayment<T> where
T::Call: Dispatchable<Info=DispatchInfo>,
{
/// utility constructor. Used only in client/factory code.
pub fn from(fee: BalanceOf<T>) -> Self {
Self(fee)
@@ -156,7 +163,7 @@ impl<T: Trait + Send + Sync> ChargeTransactionPayment<T> {
/// final_fee = base_fee + targeted_fee_adjustment(len_fee + weight_fee) + tip;
pub fn compute_fee(
len: u32,
info: <Self as SignedExtension>::DispatchInfo,
info: &DispatchInfoOf<T::Call>,
tip: BalanceOf<T>,
) -> BalanceOf<T>
where
@@ -200,14 +207,14 @@ impl<T: Trait + Send + Sync> sp_std::fmt::Debug for ChargeTransactionPayment<T>
}
}
impl<T: Trait + Send + Sync> SignedExtension for ChargeTransactionPayment<T>
where BalanceOf<T>: Send + Sync
impl<T: Trait + Send + Sync> SignedExtension for ChargeTransactionPayment<T> where
BalanceOf<T>: Send + Sync,
T::Call: Dispatchable<Info=DispatchInfo>,
{
const IDENTIFIER: &'static str = "ChargeTransactionPayment";
type AccountId = T::AccountId;
type Call = T::Call;
type AdditionalSigned = ();
type DispatchInfo = DispatchInfo;
type Pre = ();
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
@@ -215,7 +222,7 @@ impl<T: Trait + Send + Sync> SignedExtension for ChargeTransactionPayment<T>
&self,
who: &Self::AccountId,
_call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity {
// pay any fees.
@@ -438,14 +445,14 @@ mod tests {
let len = 10;
assert!(
ChargeTransactionPayment::<Runtime>::from(0)
.pre_dispatch(&1, CALL, info_from_weight(5), len)
.pre_dispatch(&1, CALL, &info_from_weight(5), len)
.is_ok()
);
assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10);
assert!(
ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
.pre_dispatch(&2, CALL, info_from_weight(3), len)
.pre_dispatch(&2, CALL, &info_from_weight(3), len)
.is_ok()
);
assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 3 - 5);
@@ -463,7 +470,7 @@ mod tests {
// maximum weight possible
assert!(
ChargeTransactionPayment::<Runtime>::from(0)
.pre_dispatch(&1, CALL, info_from_weight(Weight::max_value()), 10)
.pre_dispatch(&1, CALL, &info_from_weight(Weight::max_value()), 10)
.is_ok()
);
// fee will be proportional to what is the actual maximum weight in the runtime.
@@ -495,7 +502,7 @@ mod tests {
};
assert!(
ChargeTransactionPayment::<Runtime>::from(0)
.validate(&1, CALL, operational_transaction , len)
.validate(&1, CALL, &operational_transaction , len)
.is_ok()
);
@@ -507,7 +514,7 @@ mod tests {
};
assert!(
ChargeTransactionPayment::<Runtime>::from(0)
.validate(&1, CALL, free_transaction , len)
.validate(&1, CALL, &free_transaction , len)
.is_err()
);
});
@@ -527,7 +534,7 @@ mod tests {
assert!(
ChargeTransactionPayment::<Runtime>::from(10) // tipped
.pre_dispatch(&1, CALL, info_from_weight(3), len)
.pre_dispatch(&1, CALL, &info_from_weight(3), len)
.is_ok()
);
assert_eq!(Balances::free_balance(1), 100 - 10 - 5 - (10 + 3) * 3 / 2);
@@ -587,25 +594,25 @@ mod tests {
class: DispatchClass::Operational,
pays_fee: false,
};
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, dispatch_info, 10), 10);
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, &dispatch_info, 10), 10);
// No tip, only base fee works
let dispatch_info = DispatchInfo {
weight: 0,
class: DispatchClass::Operational,
pays_fee: true,
};
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, dispatch_info, 0), 100);
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
// Tip + base fee works
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, dispatch_info, 69), 169);
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, &dispatch_info, 69), 169);
// Len (byte fee) + base fee works
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(42, dispatch_info, 0), 520);
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(42, &dispatch_info, 0), 520);
// Weight fee + base fee works
let dispatch_info = DispatchInfo {
weight: 1000,
class: DispatchClass::Operational,
pays_fee: true,
};
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, dispatch_info, 0), 1100);
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, &dispatch_info, 0), 1100);
});
}
@@ -626,7 +633,7 @@ mod tests {
class: DispatchClass::Operational,
pays_fee: true,
};
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, dispatch_info, 0), 100);
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
// Everything works together :)
let dispatch_info = DispatchInfo {
@@ -638,7 +645,7 @@ mod tests {
// adjustable fee = (123 * 1) + (456 * 10) = 4683
// adjusted fee = (4683 * .5) + 4683 = 7024.5 -> 7024
// final fee = 100 + 7024 + 789 tip = 7913
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(456, dispatch_info, 789), 7913);
assert_eq!(ChargeTransactionPayment::<Runtime>::compute_fee(456, &dispatch_info, 789), 7913);
});
}
@@ -660,7 +667,7 @@ mod tests {
assert_eq!(
ChargeTransactionPayment::<Runtime>::compute_fee(
<u32>::max_value(),
dispatch_info,
&dispatch_info,
<u64>::max_value()
),
<u64>::max_value()
@@ -18,9 +18,8 @@
//! stage.
use crate::traits::{
self, Member, MaybeDisplay, SignedExtension, Dispatchable,
self, Member, MaybeDisplay, SignedExtension, Dispatchable, DispatchInfoOf, ValidateUnsigned,
};
use crate::traits::ValidateUnsigned;
use crate::transaction_validity::{TransactionValidity, TransactionSource};
/// Definition of something that the external world might want to say; its
@@ -36,28 +35,26 @@ pub struct CheckedExtrinsic<AccountId, Call, Extra> {
pub function: Call,
}
impl<AccountId, Call, Extra, Origin, Info> traits::Applyable for
impl<AccountId, Call, Extra, Origin> traits::Applyable for
CheckedExtrinsic<AccountId, Call, Extra>
where
AccountId: Member + MaybeDisplay,
Call: Member + Dispatchable<Origin=Origin>,
Extra: SignedExtension<AccountId=AccountId, Call=Call, DispatchInfo=Info>,
Extra: SignedExtension<AccountId=AccountId, Call=Call>,
Origin: From<Option<AccountId>>,
Info: Clone,
{
type Call = Call;
type DispatchInfo = Info;
fn validate<U: ValidateUnsigned<Call = Self::Call>>(
&self,
// TODO [#5006;ToDr] should source be passed to `SignedExtension`s?
// Perhaps a change for 2.0 to avoid breaking too much APIs?
source: TransactionSource,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity {
if let Some((ref id, ref extra)) = self.signed {
Extra::validate(extra, id, &self.function, info.clone(), len)
Extra::validate(extra, id, &self.function, info, len)
} else {
let valid = Extra::validate_unsigned(&self.function, info, len)?;
let unsigned_validation = U::validate_unsigned(source, &self.function)?;
@@ -67,21 +64,24 @@ where
fn apply<U: ValidateUnsigned<Call=Self::Call>>(
self,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> crate::ApplyExtrinsicResult {
let (maybe_who, pre) = if let Some((id, extra)) = self.signed {
let pre = Extra::pre_dispatch(extra, &id, &self.function, info.clone(), len)?;
let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?;
(Some(id), pre)
} else {
let pre = Extra::pre_dispatch_unsigned(&self.function, info.clone(), len)?;
let pre = Extra::pre_dispatch_unsigned(&self.function, info, len)?;
U::pre_dispatch(&self.function)?;
(None, pre)
};
let res = self.function.dispatch(Origin::from(maybe_who))
.map(|_| ())
.map_err(|e| e.error);
Extra::post_dispatch(pre, info.clone(), len, &res)?;
let res = self.function.dispatch(Origin::from(maybe_who));
let post_info = match res {
Ok(info) => info,
Err(err) => err.post_info,
};
let res = res.map(|_| ()).map_err(|e| e.error);
Extra::post_dispatch(pre, info, &post_info, len, &res)?;
Ok(res)
}
}
@@ -357,7 +357,6 @@ mod tests {
type AccountId = u64;
type Call = ();
type AdditionalSigned = ();
type DispatchInfo = ();
type Pre = ();
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
+5 -7
View File
@@ -21,7 +21,7 @@ use std::{fmt::Debug, ops::Deref, fmt, cell::RefCell};
use crate::codec::{Codec, Encode, Decode};
use crate::traits::{
self, Checkable, Applyable, BlakeTwo256, OpaqueKeys,
SignedExtension, Dispatchable,
SignedExtension, Dispatchable, DispatchInfoOf,
};
use crate::traits::ValidateUnsigned;
use crate::{generic, KeyTypeId, ApplyExtrinsicResult};
@@ -345,20 +345,18 @@ impl<Call: Codec + Sync + Send, Extra> traits::Extrinsic for TestXt<Call, Extra>
}
}
impl<Origin, Call, Extra, Info> Applyable for TestXt<Call, Extra> where
impl<Origin, Call, Extra> Applyable for TestXt<Call, Extra> where
Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Dispatchable<Origin=Origin>,
Extra: SignedExtension<AccountId=u64, Call=Call, DispatchInfo=Info>,
Extra: SignedExtension<AccountId=u64, Call=Call>,
Origin: From<Option<u64>>,
Info: Clone,
{
type Call = Call;
type DispatchInfo = Info;
/// Checks to see if this is a valid *transaction*. It returns information on it if so.
fn validate<U: ValidateUnsigned<Call=Self::Call>>(
&self,
_source: TransactionSource,
_info: Self::DispatchInfo,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
Ok(Default::default())
@@ -368,7 +366,7 @@ impl<Origin, Call, Extra, Info> Applyable for TestXt<Call, Extra> where
/// index and sender.
fn apply<U: ValidateUnsigned<Call=Self::Call>>(
self,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> ApplyExtrinsicResult {
let maybe_who = if let Some((who, extra)) = self.signature {
+48 -31
View File
@@ -625,6 +625,10 @@ pub trait Dispatchable {
type Origin;
/// ...
type Trait;
/// An opaque set of information attached to the transaction. This could be constructed anywhere
/// down the line in a runtime. The current Substrate runtime uses a struct with the same name
/// to represent the dispatch class and weight.
type Info;
/// Additional information that is returned by `dispatch`. Can be used to supply the caller
/// with information about a `Dispatchable` that is ownly known post dispatch.
type PostInfo: Eq + PartialEq + Clone + Copy + Encode + Decode + Printable;
@@ -632,6 +636,21 @@ pub trait Dispatchable {
fn dispatch(self, origin: Self::Origin) -> crate::DispatchResultWithInfo<Self::PostInfo>;
}
/// Shortcut to reference the `Info` type of a `Dispatchable`.
pub type DispatchInfoOf<T> = <T as Dispatchable>::Info;
/// Shortcut to reference the `PostInfo` type of a `Dispatchable`.
pub type PostDispatchInfoOf<T> = <T as Dispatchable>::PostInfo;
impl Dispatchable for () {
type Origin = ();
type Trait = ();
type Info = ();
type PostInfo = ();
fn dispatch(self, _origin: Self::Origin) -> crate::DispatchResultWithInfo<Self::PostInfo> {
panic!("This implemention should not be used for actual dispatch.");
}
}
/// Means by which a transaction may be extended. This type embodies both the data and the logic
/// that should be additionally associated with the transaction. It should be plain old data.
pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq {
@@ -645,7 +664,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
type AccountId;
/// The type which encodes the call to be dispatched.
type Call;
type Call: Dispatchable;
/// Any additional data that will go into the signed payload. This may be created dynamically
/// from the transaction using the `additional_signed` function.
@@ -654,11 +673,6 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
/// The type that encodes information that can be passed from pre_dispatch to post-dispatch.
type Pre: Default;
/// An opaque set of information attached to the transaction. This could be constructed anywhere
/// down the line in a runtime. The current Substrate runtime uses a struct with the same name
/// to represent the dispatch class and weight.
type DispatchInfo: Clone;
/// Construct any additional data that should be in the signed payload of the transaction. Can
/// also perform any pre-signature-verification checks and return an error if needed.
fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError>;
@@ -676,7 +690,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
&self,
_who: &Self::AccountId,
_call: &Self::Call,
_info: Self::DispatchInfo,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
Ok(ValidTransaction::default())
@@ -694,7 +708,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
self,
who: &Self::AccountId,
call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
self.validate(who, call, info.clone(), len)
@@ -712,7 +726,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
/// Make sure to perform the same checks in `pre_dispatch_unsigned` function.
fn validate_unsigned(
_call: &Self::Call,
_info: Self::DispatchInfo,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
Ok(ValidTransaction::default())
@@ -728,7 +742,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
/// perform the same validation as in `validate_unsigned`.
fn pre_dispatch_unsigned(
call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
Self::validate_unsigned(call, info.clone(), len)
@@ -751,7 +765,8 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
/// will come from either an offchain-worker or via `InherentData`.
fn post_dispatch(
_pre: Self::Pre,
_info: Self::DispatchInfo,
_info: &DispatchInfoOf<Self::Call>,
_post_info: &PostDispatchInfoOf<Self::Call>,
_len: usize,
_result: &DispatchResult,
) -> Result<(), TransactionValidityError> {
@@ -771,11 +786,10 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
}
#[impl_for_tuples(1, 12)]
impl<AccountId, Call, Info: Clone> SignedExtension for Tuple {
for_tuples!( where #( Tuple: SignedExtension<AccountId=AccountId, Call=Call, DispatchInfo=Info> )* );
impl<AccountId, Call: Dispatchable> SignedExtension for Tuple {
for_tuples!( where #( Tuple: SignedExtension<AccountId=AccountId, Call=Call,> )* );
type AccountId = AccountId;
type Call = Call;
type DispatchInfo = Info;
const IDENTIFIER: &'static str = "You should call `identifier()`!";
for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); );
for_tuples!( type Pre = ( #( Tuple::Pre ),* ); );
@@ -788,45 +802,46 @@ impl<AccountId, Call, Info: Clone> SignedExtension for Tuple {
&self,
who: &Self::AccountId,
call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity {
let valid = ValidTransaction::default();
for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info.clone(), len)?); )* );
for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info, len)?); )* );
Ok(valid)
}
fn pre_dispatch(self, who: &Self::AccountId, call: &Self::Call, info: Self::DispatchInfo, len: usize)
fn pre_dispatch(self, who: &Self::AccountId, call: &Self::Call, info: &DispatchInfoOf<Self::Call>, len: usize)
-> Result<Self::Pre, TransactionValidityError>
{
Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info.clone(), len)? ),* ) ))
Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) ))
}
fn validate_unsigned(
call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity {
let valid = ValidTransaction::default();
for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info.clone(), len)?); )* );
for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info, len)?); )* );
Ok(valid)
}
fn pre_dispatch_unsigned(
call: &Self::Call,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
Ok(for_tuples!( ( #( Tuple::pre_dispatch_unsigned(call, info.clone(), len)? ),* ) ))
Ok(for_tuples!( ( #( Tuple::pre_dispatch_unsigned(call, info, len)? ),* ) ))
}
fn post_dispatch(
pre: Self::Pre,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
post_info: &PostDispatchInfoOf<Self::Call>,
len: usize,
result: &DispatchResult,
) -> Result<(), TransactionValidityError> {
for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info.clone(), len, result)?; )* );
for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, post_info, len, result)?; )* );
Ok(())
}
@@ -844,7 +859,6 @@ impl SignedExtension for () {
type AdditionalSigned = ();
type Call = ();
type Pre = ();
type DispatchInfo = ();
const IDENTIFIER: &'static str = "UnitSignedExtension";
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
}
@@ -857,16 +871,13 @@ impl SignedExtension for () {
/// each piece of attributable information to be disambiguated.
pub trait Applyable: Sized + Send + Sync {
/// Type by which we can dispatch. Restricts the `UnsignedValidator` type.
type Call;
/// An opaque set of information attached to the transaction.
type DispatchInfo: Clone;
type Call: Dispatchable;
/// Checks to see if this is a valid *transaction*. It returns information on it if so.
fn validate<V: ValidateUnsigned<Call=Self::Call>>(
&self,
source: TransactionSource,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity;
@@ -874,7 +885,7 @@ pub trait Applyable: Sized + Send + Sync {
/// index and sender.
fn apply<V: ValidateUnsigned<Call=Self::Call>>(
self,
info: Self::DispatchInfo,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> crate::ApplyExtrinsicResult;
}
@@ -1273,6 +1284,12 @@ impl Printable for bool {
}
}
impl Printable for () {
fn print(&self) {
"()".print()
}
}
#[impl_for_tuples(1, 12)]
impl Printable for Tuple {
fn print(&self) {
+10
View File
@@ -181,6 +181,16 @@ impl ExtrinsicT for Extrinsic {
}
}
impl sp_runtime::traits::Dispatchable for Extrinsic {
type Origin = ();
type Trait = ();
type Info = ();
type PostInfo = ();
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
panic!("This implemention should not be used for actual dispatch.");
}
}
impl Extrinsic {
pub fn transfer(&self) -> &Transfer {
match self {