From e2ee6a2b90a80e9197bdf4283075c2ab5be85d87 Mon Sep 17 00:00:00 2001 From: Robert Habermeier <rphmeier@gmail.com> Date: Mon, 29 Oct 2018 02:31:51 +0100 Subject: [PATCH] read authority set from DB on startup --- .../finality-grandpa/primitives/src/lib.rs | 6 ++-- .../core/finality-grandpa/src/authorities.rs | 10 ------- substrate/core/finality-grandpa/src/lib.rs | 28 +++++++++++++++---- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/substrate/core/finality-grandpa/primitives/src/lib.rs b/substrate/core/finality-grandpa/primitives/src/lib.rs index 047c37632a8..ddf924cc2e0 100644 --- a/substrate/core/finality-grandpa/primitives/src/lib.rs +++ b/substrate/core/finality-grandpa/primitives/src/lib.rs @@ -44,7 +44,7 @@ pub struct ScheduledChange<N> { /// WASM function call to check for pending changes. pub const PENDING_CHANGE_CALL: &str = "grandpa_pending_change"; /// WASM function call to get current GRANDPA authorities. -pub const AUTHORITIES_CALL: &str = "grandpa_pending_change"; +pub const AUTHORITIES_CALL: &str = "grandpa_authorities"; decl_apis! { /// APIs for integrating the GRANDPA finality gadget into runtimes. @@ -66,8 +66,8 @@ decl_apis! { /// passed completely. fn grandpa_pending_change(digest: DigestFor<B>) -> Option<ScheduledChange<NumberFor<B>>>; - /// Get the current GRANDPA authorities. This should not change except + /// Get the current GRANDPA authorities and weights. This should not change except /// for when changes are scheduled and the corresponding delay has passed. - fn grandpa_authorities() -> Vec<AuthorityId>; + fn grandpa_authorities() -> Vec<(AuthorityId, u64)>; } } diff --git a/substrate/core/finality-grandpa/src/authorities.rs b/substrate/core/finality-grandpa/src/authorities.rs index 7896c084950..6a32e3ddb7c 100644 --- a/substrate/core/finality-grandpa/src/authorities.rs +++ b/substrate/core/finality-grandpa/src/authorities.rs @@ -56,11 +56,6 @@ impl<H, N> SharedAuthoritySet<H, N> { impl<H: Eq, N> SharedAuthoritySet<H, N> where N: Add<Output=N> + Ord + Clone + Debug { - /// Note an upcoming pending transition. - pub(crate) fn add_pending_change(&self, pending: PendingChange<H, N>) { - self.inner.write().add_pending_change(pending) - } - /// Get the earliest limit-block number, if any. pub(crate) fn current_limit(&self) -> Option<N> { self.inner.read().current_limit() @@ -96,11 +91,6 @@ pub(crate) struct AuthoritySet<H, N> { } impl<H, N> AuthoritySet<H, N> { - /// Get the set identifier. - pub(crate) fn set_id(&self) -> u64 { - self.set_id - } - /// Get the current set id and a reference to the current authority set. pub(crate) fn current(&self) -> (u64, &[(AuthorityId, u64)]) { (self.set_id, &self.current_authorities[..]) diff --git a/substrate/core/finality-grandpa/src/lib.rs b/substrate/core/finality-grandpa/src/lib.rs index 58de2553b3f..2291c0c8237 100644 --- a/substrate/core/finality-grandpa/src/lib.rs +++ b/substrate/core/finality-grandpa/src/lib.rs @@ -712,7 +712,6 @@ impl<B, E, Block: BlockT> BlockImport<Block> for GrandpaBlockImport<B, E, Block> fn import_block(&self, mut block: ImportBlock<Block>, new_authorities: Option<Vec<AuthorityId>>) -> Result<ImportResult, Self::Error> { - use runtime_primitives::traits::Digest; use authorities::PendingChange; let maybe_change: Option<ScheduledChange<NumberFor<Block>>> = self.inner.call_api_at( @@ -779,10 +778,29 @@ pub fn run_grandpa<B, E, Block: BlockT, N>( let chain_info = client.info()?; let genesis_hash = chain_info.chain.genesis_hash; - // TODO [now]: attempt to load from disk. - let authority_set = SharedAuthoritySet::genesis( - voters.iter().map(|(&id, &weight)| (id, weight)).collect(), - ); + let authority_set = match client.backend().get_aux(AUTHORITY_SET_KEY)? { + None => { + info!(target: "afg", "Loading GRANDPA authorities \ + from genesis on what appears to be first startup."); + + // no authority set on disk: fetch authorities from genesis state. + // if genesis state is not available, we may be a light client, but these + // are unsupported for following GRANDPA directly. + let genesis_authorities: Vec<(AuthorityId, u64)> = client + .call_api_at(&BlockId::Number(NumberFor::<Block>::zero()), fg_primitives::AUTHORITIES_CALL, &())?; + + let authority_set = SharedAuthoritySet::genesis(genesis_authorities); + let encoded = authority_set.inner().read().encode(); + client.backend().insert_aux(&[(AUTHORITY_SET_KEY, &encoded[..])], &[])?; + + authority_set + } + Some(raw) => ::authorities::AuthoritySet::decode(&mut &raw[..]) + .ok_or_else(|| ::client::error::ErrorKind::Backend( + format!("GRANDPA authority set kept in invalid format") + ))? + .into(), + }; let block_import = GrandpaBlockImport { inner: client.clone(), -- GitLab