diff --git a/primitives/src/inclusion_inherent.rs b/primitives/src/inclusion_inherent.rs
new file mode 100644
index 000000000000..ca3f5ec23a16
--- /dev/null
+++ b/primitives/src/inclusion_inherent.rs
@@ -0,0 +1,23 @@
+// Copyright 2017-2020 Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot 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.
+
+// Polkadot 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 Polkadot. If not, see .
+
+//! Inclusion Inherent primitives define types and constants which can be imported
+//! without needing to import the entire inherent module.
+
+use inherents::InherentIdentifier;
+
+/// Unique identifier for the Inclusion Inherent
+pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"inclusn0";
diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs
index 9167d9910e37..24ed6e1eb37f 100644
--- a/primitives/src/lib.rs
+++ b/primitives/src/lib.rs
@@ -23,6 +23,7 @@
use runtime_primitives::{generic, MultiSignature};
pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify, IdentifyAccount};
+pub mod inclusion_inherent;
pub mod parachain;
pub use parity_scale_codec::Compact;
diff --git a/primitives/src/parachain.rs b/primitives/src/parachain.rs
index a24cb5b612de..52306174be5d 100644
--- a/primitives/src/parachain.rs
+++ b/primitives/src/parachain.rs
@@ -722,6 +722,12 @@ pub type SignedAvailabilityBitfield = Signed;
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
pub struct SignedAvailabilityBitfields(pub Vec);
+impl From> for SignedAvailabilityBitfields {
+ fn from(fields: Vec) -> SignedAvailabilityBitfields {
+ SignedAvailabilityBitfields(fields)
+ }
+}
+
/// A backed (or backable, depending on context) candidate.
// TODO: yes, this is roughly the same as AttestedCandidate.
// After https://github.com/paritytech/polkadot/issues/1250
diff --git a/runtime/parachains/src/inclusion_inherent.rs b/runtime/parachains/src/inclusion_inherent.rs
index 46fe1fee469e..ac092f6b4837 100644
--- a/runtime/parachains/src/inclusion_inherent.rs
+++ b/runtime/parachains/src/inclusion_inherent.rs
@@ -23,18 +23,23 @@
use sp_std::prelude::*;
use primitives::{
+ inclusion_inherent,
parachain::{BackedCandidate, SignedAvailabilityBitfields},
};
use frame_support::{
- decl_storage, decl_module, decl_error, ensure,
+ decl_error, decl_module, decl_storage, ensure,
dispatch::DispatchResult,
weights::{DispatchClass, Weight},
traits::Get,
};
use system::ensure_none;
-use crate::{inclusion, scheduler::{self, FreedReason}};
+use crate::{
+ inclusion,
+ scheduler::{self, FreedReason},
+};
+use inherents::{InherentIdentifier, InherentData, MakeFatalError, ProvideInherent};
-pub trait Trait: inclusion::Trait + scheduler::Trait { }
+pub trait Trait: inclusion::Trait + scheduler::Trait {}
decl_storage! {
trait Store for Module as ParaInclusionInherent {
@@ -118,3 +123,23 @@ decl_module! {
}
}
}
+
+impl ProvideInherent for Module {
+ type Call = Call;
+ type Error = MakeFatalError<()>;
+ const INHERENT_IDENTIFIER: InherentIdentifier = inclusion_inherent::INHERENT_IDENTIFIER;
+
+ fn create_inherent(data: &InherentData) -> Option {
+ data.get_data(&Self::INHERENT_IDENTIFIER)
+ .expect("inclusion inherent data failed to decode")
+ .map(|(signed_bitfields, backed_candidates): (SignedAvailabilityBitfields, Vec>)| {
+ // Sanity check: session changes can invalidate an inherent, and we _really_ don't want that to happen.
+ // See github.com/paritytech/polkadot/issues/1327
+ if Self::inclusion(system::RawOrigin::None.into(), signed_bitfields.clone(), backed_candidates.clone()).is_ok() {
+ Call::inclusion(signed_bitfields, backed_candidates)
+ } else {
+ Call::inclusion(Vec::new().into(), Vec::new())
+ }
+ })
+ }
+}