mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 12:48:00 +00:00
Mandatory dispatch class (#5515)
* Mandatory dispatch class * Tweaks * Docs * Fix test * Update frame/support/src/weights.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Introduce logic that was stated in PR. * Use * Docs. * Fix test * Fix merge * Update frame/support/src/weights.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Fix. * Fix Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
@@ -78,8 +78,10 @@ where
|
||||
U::pre_dispatch(&self.function)?;
|
||||
(None, pre)
|
||||
};
|
||||
let res = self.function.dispatch(Origin::from(maybe_who));
|
||||
Extra::post_dispatch(pre, info, len);
|
||||
Ok(res.map(|_| ()).map_err(|e| e.error))
|
||||
let res = self.function.dispatch(Origin::from(maybe_who))
|
||||
.map(|_| ())
|
||||
.map_err(|e| e.error);
|
||||
Extra::post_dispatch(pre, info.clone(), len, &res)?;
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ pub use sp_arithmetic::traits::{
|
||||
};
|
||||
use sp_application_crypto::AppKey;
|
||||
use impl_trait_for_tuples::impl_for_tuples;
|
||||
use crate::DispatchResult;
|
||||
|
||||
/// A lazy value.
|
||||
pub trait Lazy<T: ?Sized> {
|
||||
@@ -627,7 +628,7 @@ pub trait Dispatchable {
|
||||
/// 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;
|
||||
/// Actually dispatch this call and result the result of it.
|
||||
/// Actually dispatch this call and return the result of it.
|
||||
fn dispatch(self, origin: Self::Origin) -> crate::DispatchResultWithInfo<Self::PostInfo>;
|
||||
}
|
||||
|
||||
@@ -735,8 +736,27 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Do any post-flight stuff for a transaction.
|
||||
fn post_dispatch(_pre: Self::Pre, _info: Self::DispatchInfo, _len: usize) { }
|
||||
/// Do any post-flight stuff for an extrinsic.
|
||||
///
|
||||
/// This gets given the `DispatchResult` `_result` from the extrinsic and can, if desired,
|
||||
/// introduce a `TransactionValidityError`, causing the block to become invalid for including
|
||||
/// it.
|
||||
///
|
||||
/// WARNING: It is dangerous to return an error here. To do so will fundamentally invalidate the
|
||||
/// transaction and any block that it is included in, causing the block author to not be
|
||||
/// compensated for their work in validating the transaction or producing the block so far.
|
||||
///
|
||||
/// It can only be used safely when you *know* that the extrinsic is one that can only be
|
||||
/// introduced by the current block author; generally this implies that it is an inherent and
|
||||
/// will come from either an offchain-worker or via `InherentData`.
|
||||
fn post_dispatch(
|
||||
_pre: Self::Pre,
|
||||
_info: Self::DispatchInfo,
|
||||
_len: usize,
|
||||
_result: &DispatchResult,
|
||||
) -> Result<(), TransactionValidityError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the list of unique identifier for this signed extension.
|
||||
///
|
||||
@@ -804,8 +824,10 @@ impl<AccountId, Call, Info: Clone> SignedExtension for Tuple {
|
||||
pre: Self::Pre,
|
||||
info: Self::DispatchInfo,
|
||||
len: usize,
|
||||
) {
|
||||
for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info.clone(), len); )* )
|
||||
result: &DispatchResult,
|
||||
) -> Result<(), TransactionValidityError> {
|
||||
for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info.clone(), len, result)?; )* );
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn identifier() -> Vec<&'static str> {
|
||||
|
||||
@@ -52,6 +52,13 @@ pub enum InvalidTransaction {
|
||||
ExhaustsResources,
|
||||
/// Any other custom invalid validity that is not covered by this enum.
|
||||
Custom(u8),
|
||||
/// An extrinsic with a Mandatory dispatch resulted in Error. This is indicative of either a
|
||||
/// malicious validator or a buggy `provide_inherent`. In any case, it can result in dangerously
|
||||
/// overweight blocks and therefore if found, invalidates the block.
|
||||
BadMandatory,
|
||||
/// A transaction with a mandatory dispatch. This is invalid; only inherent extrinsics are
|
||||
/// allowed to have mandatory dispatches.
|
||||
MandatoryDispatch,
|
||||
}
|
||||
|
||||
impl InvalidTransaction {
|
||||
@@ -62,6 +69,14 @@ impl InvalidTransaction {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns if the reason for the invalidity was a mandatory call failing.
|
||||
pub fn was_mandatory(&self) -> bool {
|
||||
match self {
|
||||
Self::BadMandatory => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InvalidTransaction> for &'static str {
|
||||
@@ -76,6 +91,10 @@ impl From<InvalidTransaction> for &'static str {
|
||||
"Transaction would exhausts the block limits",
|
||||
InvalidTransaction::Payment =>
|
||||
"Inability to pay some fees (e.g. account balance too low)",
|
||||
InvalidTransaction::BadMandatory =>
|
||||
"A call was labelled as mandatory, but resulted in an Error.",
|
||||
InvalidTransaction::MandatoryDispatch =>
|
||||
"Tranaction dispatch is mandatory; transactions may not have mandatory dispatches.",
|
||||
InvalidTransaction::Custom(_) => "InvalidTransaction custom error",
|
||||
}
|
||||
}
|
||||
@@ -123,6 +142,15 @@ impl TransactionValidityError {
|
||||
Self::Unknown(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the reason for the error was it being a mandatory dispatch that could not
|
||||
/// be completed successfully.
|
||||
pub fn was_mandatory(&self) -> bool {
|
||||
match self {
|
||||
Self::Invalid(e) => e.was_mandatory(),
|
||||
Self::Unknown(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionValidityError> for &'static str {
|
||||
|
||||
Reference in New Issue
Block a user