Add support for modules to require inherent to be present (#5792)

* Add support for modules to require inherent to be present

* Bump node impl version

* Allow is_inherent_required itself to return error

This handles the case if runtime fails to check the inherent data (if the
inherent data is invalid, etc).

* typo: &module -> $module

* fix: iter
This commit is contained in:
Wei Tang
2020-04-29 12:05:35 +02:00
committed by GitHub
parent ba50664fea
commit 521f8ff427
3 changed files with 43 additions and 3 deletions
+1 -1
View File
@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 244,
impl_version: 2,
impl_version: 3,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
};
+37 -2
View File
@@ -77,7 +77,7 @@ macro_rules! impl_outer_inherent {
let mut result = $crate::inherent::CheckInherentsResult::new();
for xt in block.extrinsics() {
if $crate::inherent::Extrinsic::is_signed(xt).unwrap_or(false) {
break;
break
}
$(
@@ -88,7 +88,7 @@ macro_rules! impl_outer_inherent {
$module::INHERENT_IDENTIFIER, &e
).expect("There is only one fatal error; qed");
if e.is_fatal_error() {
return result;
return result
}
}
}
@@ -97,6 +97,41 @@ macro_rules! impl_outer_inherent {
)*
}
$(
match $module::is_inherent_required(self) {
Ok(Some(e)) => {
let found = block.extrinsics().iter().any(|xt| {
if $crate::inherent::Extrinsic::is_signed(xt).unwrap_or(false) {
return false
}
match xt.function {
Call::$call(_) => true,
_ => false,
}
});
if !found {
result.put_error(
$module::INHERENT_IDENTIFIER, &e
).expect("There is only one fatal error; qed");
if e.is_fatal_error() {
return result
}
}
},
Ok(None) => (),
Err(e) => {
result.put_error(
$module::INHERENT_IDENTIFIER, &e
).expect("There is only one fatal error; qed");
if e.is_fatal_error() {
return result
}
},
}
)*
result
}
}
@@ -408,6 +408,11 @@ pub trait ProvideInherent {
/// Create an inherent out of the given `InherentData`.
fn create_inherent(data: &InherentData) -> Option<Self::Call>;
/// If `Some`, indicates that an inherent is required. Check will return the inner error if no
/// inherent is found. If `Err`, indicates that the check failed and further operations should
/// be aborted.
fn is_inherent_required(_: &InherentData) -> Result<Option<Self::Error>, Self::Error> { Ok(None) }
/// Check the given inherent if it is valid.
/// Checking the inherent is optional and can be omitted.
fn check_inherent(_: &Self::Call, _: &InherentData) -> Result<(), Self::Error> {