frame-executive: Reject invalid inherents in the executive (#12365)

* frame-executive: Reject invalid inherents in the executive

We already had support for making a block fail if an inherent returned, but it was part of the
signed extension `CheckWeight`. Rejecting blocks with invalid inherents should happen on the
`frame-executive` level without requiring any special signed extension. This is crucial to prevent
any kind of spamming of the network that could may happen with blocks that include failing inherents.

* FMT

* Update frame/executive/src/lib.rs

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>

* Update primitives/runtime/src/transaction_validity.rs

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>

Co-authored-by: parity-processbot <>
Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
This commit is contained in:
Bastian Köcher
2022-12-04 20:40:38 +01:00
committed by GitHub
parent 1520623b90
commit 1943e25cb9
4 changed files with 61 additions and 26 deletions
@@ -18,7 +18,7 @@
use crate::{limits::BlockWeights, Config, Pallet};
use codec::{Decode, Encode};
use frame_support::{
dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo},
dispatch::{DispatchInfo, PostDispatchInfo},
traits::Get,
};
use scale_info::TypeInfo;
@@ -190,9 +190,6 @@ where
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<(), TransactionValidityError> {
if info.class == DispatchClass::Mandatory {
return Err(InvalidTransaction::MandatoryDispatch.into())
}
Self::do_pre_dispatch(info, len)
}
@@ -203,9 +200,6 @@ where
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> TransactionValidity {
if info.class == DispatchClass::Mandatory {
return Err(InvalidTransaction::MandatoryDispatch.into())
}
Self::do_validate(info, len)
}
@@ -230,16 +224,8 @@ where
info: &DispatchInfoOf<Self::Call>,
post_info: &PostDispatchInfoOf<Self::Call>,
_len: usize,
result: &DispatchResult,
_result: &DispatchResult,
) -> Result<(), TransactionValidityError> {
// Since mandatory dispatched do not get validated for being overweight, we are sensitive
// to them actually being useful. Block producers are thus not allowed to include mandatory
// extrinsics that result in error.
if let (DispatchClass::Mandatory, Err(e)) = (info.class, result) {
log::error!(target: "runtime::system", "Bad mandatory: {:?}", e);
return Err(InvalidTransaction::BadMandatory.into())
}
let unspent = post_info.calc_unspent(info);
if unspent.any_gt(Weight::zero()) {
crate::BlockWeight::<T>::mutate(|current_weight| {
@@ -268,7 +254,7 @@ mod tests {
use super::*;
use crate::{
mock::{new_test_ext, System, Test, CALL},
AllExtrinsicsLen, BlockWeight,
AllExtrinsicsLen, BlockWeight, DispatchClass,
};
use frame_support::{assert_err, assert_ok, dispatch::Pays, weights::Weight};
use sp_std::marker::PhantomData;