From b255f8f98711c398eb532041bf4394ead2e2739b Mon Sep 17 00:00:00 2001
From: Robert Habermeier <rphmeier@gmail.com>
Date: Thu, 4 Oct 2018 17:54:56 -0400
Subject: [PATCH] grandpa-compatible digest items

---
 substrate/core/finality-grandpa/src/lib.rs | 19 ++++++++++++++++++-
 substrate/core/sr-primitives/src/traits.rs |  4 ++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/substrate/core/finality-grandpa/src/lib.rs b/substrate/core/finality-grandpa/src/lib.rs
index 969ebc197a4..3321e9edad8 100644
--- a/substrate/core/finality-grandpa/src/lib.rs
+++ b/substrate/core/finality-grandpa/src/lib.rs
@@ -43,7 +43,9 @@ use futures::stream::Fuse;
 use futures::sync::mpsc;
 use client::{Client, ImportNotifications, backend::Backend, CallExecutor};
 use codec::{Encode, Decode};
-use runtime_primitives::traits::{As, NumberFor, Block as BlockT, Header as HeaderT};
+use runtime_primitives::traits::{
+	As, NumberFor, Block as BlockT, Header as HeaderT, DigestItemFor,
+};
 use runtime_primitives::generic::BlockId;
 use substrate_primitives::{ed25519, AuthorityId, Blake2Hasher};
 use tokio::timer::Interval;
@@ -390,6 +392,7 @@ impl<Block: BlockT, B, E, N> grandpa::Chain<Block::Hash> for Environment<B, E, B
 	N: Network + 'static,
 	N::In: 'static,
 	NumberFor<Block>: As<u32>,
+	DigestItemFor<Block>: CompatibleDigestItem<NumberFor<Block>>,
 {
 	fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result<Vec<Block::Hash>, GrandpaError> {
 		let tree_route_res = ::client::blockchain::tree_route(
@@ -434,6 +437,16 @@ impl<Block: BlockT, B, E, N> grandpa::Chain<Block::Hash> for Environment<B, E, B
 	}
 }
 
+/// A GRANDPA-compatible DigestItem. This can describe when GRANDPA set changes
+/// are scheduled.
+// TODO: with specialization, do a blanket implementation so this trait
+// doesn't have to be implemented by users.
+pub trait CompatibleDigestItem<N> {
+	/// If this digest item notes a GRANDPA set change, return the number of
+	/// blocks the change should occur after.
+	fn scheduled_change_in(&self) -> Option<N> { None }
+}
+
 impl<B, E, Block: BlockT, N> voter::Environment<Block::Hash> for Environment<B, E, Block, N> where
 	Block: 'static,
 	B: Backend<Block, Blake2Hasher> + 'static,
@@ -441,6 +454,7 @@ impl<B, E, Block: BlockT, N> voter::Environment<Block::Hash> for Environment<B,
 	N: Network + 'static,
 	N::In: 'static,
 	NumberFor<Block>: As<u32>,
+	DigestItemFor<Block>: CompatibleDigestItem<NumberFor<Block>>,
 {
 	type Timer = Box<Future<Item = (), Error = Self::Error>>;
 	type Id = AuthorityId;
@@ -555,6 +569,7 @@ pub fn run_grandpa<B, E, Block: BlockT, N>(
 	N: Network + 'static,
 	N::In: 'static,
 	NumberFor<Block>: As<u32>,
+	DigestItemFor<Block>: CompatibleDigestItem<NumberFor<Block>>,
 {
 	let chain_info = client.info()?;
 	let genesis_hash = chain_info.chain.genesis_hash;
@@ -597,6 +612,8 @@ mod tests {
 	use keyring::Keyring;
 	use client::BlockchainEvents;
 
+	impl CompatibleDigestItem<NumberFor<Block>> for DigestItemFor<Block> { }
+
 	#[derive(Clone)]
 	struct TestGrandpaNetwork {
 		inner: Arc<Mutex<TestNet>>,
diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs
index 24dda09345a..072dffe3f3e 100644
--- a/substrate/core/sr-primitives/src/traits.rs
+++ b/substrate/core/sr-primitives/src/traits.rs
@@ -447,6 +447,10 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'stati
 pub type HashFor<B> = <<B as Block>::Header as Header>::Hashing;
 /// Extract the number type for a block.
 pub type NumberFor<B> = <<B as Block>::Header as Header>::Number;
+/// Extract the digest type for a block.
+pub type DigestFor<B> = <<B as Block>::Header as Header>::Digest;
+/// Extract the digest item type for a block.
+pub type DigestItemFor<B> = <DigestFor<B> as Digest>::Item;
 
 /// A "checkable" piece of information, used by the standard Substrate Executive in order to
 /// check the validity of a piece of extrinsic information, usually by verifying the signature.
-- 
GitLab