This repository has been archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
grandpa: Use storage proofs for Grandpa authorities #3734
Merged
Merged
Changes from 6 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
2bfe548
grandpa: Introduce named AuthorityList type.
jimpo ab4d253
grandpa: Write Grandpa authorities to well known key.
jimpo dcc5675
grandpa: Storage migration for srml-grandpa module.
jimpo c896032
Remove no-longer-used GrandpaApi runtime API.
jimpo a3ba235
grandpa: Write AuthorityList to storage with encoding version.
jimpo 0b52b64
Bump node runtime spec version.
jimpo fadd8ca
Merge branch 'master' into grandpa-authority-storage
jimpo f893059
Update srml/grandpa/src/lib.rs
jimpo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,9 +23,9 @@ extern crate alloc; | |
|
||
#[cfg(feature = "std")] | ||
use serde::Serialize; | ||
use codec::{Encode, Decode, Codec}; | ||
use codec::{Encode, Decode, Input, Codec}; | ||
use sr_primitives::{ConsensusEngineId, RuntimeDebug}; | ||
use client::decl_runtime_apis; | ||
use rstd::borrow::Cow; | ||
use rstd::vec::Vec; | ||
|
||
mod app { | ||
|
@@ -46,6 +46,10 @@ pub type AuthoritySignature = app::Signature; | |
/// The `ConsensusEngineId` of GRANDPA. | ||
pub const GRANDPA_ENGINE_ID: ConsensusEngineId = *b"FRNK"; | ||
|
||
/// The storage key for the current set of weighted Grandpa authorities. | ||
/// The value stored is an encoded VersionedAuthorityList. | ||
pub const GRANDPA_AUTHORITIES_KEY: &'static [u8] = b":grandpa_authorities"; | ||
|
||
/// The weight of an authority. | ||
pub type AuthorityWeight = u64; | ||
|
||
|
@@ -58,12 +62,15 @@ pub type SetId = u64; | |
/// The round indicator. | ||
pub type RoundNumber = u64; | ||
|
||
/// A list of Grandpa authorities with associated weights. | ||
pub type AuthorityList = Vec<(AuthorityId, AuthorityWeight)>; | ||
|
||
/// A scheduled change of authority set. | ||
#[cfg_attr(feature = "std", derive(Serialize))] | ||
#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] | ||
pub struct ScheduledChange<N> { | ||
/// The new authorities after the change, along with their respective weights. | ||
pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>, | ||
pub next_authorities: AuthorityList, | ||
/// The number of blocks to delay. | ||
pub delay: N, | ||
} | ||
|
@@ -154,24 +161,51 @@ pub const PENDING_CHANGE_CALL: &str = "grandpa_pending_change"; | |
/// WASM function call to get current GRANDPA authorities. | ||
pub const AUTHORITIES_CALL: &str = "grandpa_authorities"; | ||
|
||
decl_runtime_apis! { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We will need to re-add the runtime API, it's required for exposing equivocation reporting functionality (#3868). But I can re-add it in my PR after this is merged. |
||
/// APIs for integrating the GRANDPA finality gadget into runtimes. | ||
/// This should be implemented on the runtime side. | ||
/// | ||
/// This is primarily used for negotiating authority-set changes for the | ||
/// gadget. GRANDPA uses a signaling model of changing authority sets: | ||
/// changes should be signaled with a delay of N blocks, and then automatically | ||
/// applied in the runtime after those N blocks have passed. | ||
/// | ||
/// The consensus protocol will coordinate the handoff externally. | ||
#[api_version(2)] | ||
pub trait GrandpaApi { | ||
/// Get the current GRANDPA authorities and weights. This should not change except | ||
/// for when changes are scheduled and the corresponding delay has passed. | ||
/// | ||
/// When called at block B, it will return the set of authorities that should be | ||
/// used to finalize descendants of this block (B+1, B+2, ...). The block B itself | ||
/// is finalized by the authorities from block B-1. | ||
fn grandpa_authorities() -> Vec<(AuthorityId, AuthorityWeight)>; | ||
/// The current version of the stored AuthorityList type. The encoding version MUST be updated any | ||
/// time the AuthorityList type changes. | ||
const AUTHORITIES_VERISON: u8 = 1; | ||
|
||
/// An AuthorityList that is encoded with a version specifier. The encoding version is updated any | ||
/// time the AuthorityList type changes. This ensures that encodings of different versions of an | ||
/// AuthorityList are differentiable. Attempting to decode an authority list with an unknown | ||
/// version will fail. | ||
#[derive(Default)] | ||
pub struct VersionedAuthorityList<'a>(Cow<'a, AuthorityList>); | ||
|
||
impl<'a> From<AuthorityList> for VersionedAuthorityList<'a> { | ||
fn from(authorities: AuthorityList) -> Self { | ||
VersionedAuthorityList(Cow::Owned(authorities)) | ||
} | ||
} | ||
|
||
impl<'a> From<&'a AuthorityList> for VersionedAuthorityList<'a> { | ||
fn from(authorities: &'a AuthorityList) -> Self { | ||
VersionedAuthorityList(Cow::Borrowed(authorities)) | ||
} | ||
} | ||
|
||
impl<'a> Into<AuthorityList> for VersionedAuthorityList<'a> { | ||
fn into(self) -> AuthorityList { | ||
self.0.into_owned() | ||
} | ||
} | ||
|
||
impl<'a> Encode for VersionedAuthorityList<'a> { | ||
fn size_hint(&self) -> usize { | ||
(AUTHORITIES_VERISON, self.0.as_ref()).size_hint() | ||
} | ||
|
||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R { | ||
(AUTHORITIES_VERISON, self.0.as_ref()).using_encoded(f) | ||
} | ||
} | ||
|
||
impl<'a> Decode for VersionedAuthorityList<'a> { | ||
fn decode<I: Input>(value: &mut I) -> Result<Self, codec::Error> { | ||
let (version, authorities): (u8, AuthorityList) = Decode::decode(value)?; | ||
if version != AUTHORITIES_VERISON { | ||
return Err("unknown Grandpa authorities version".into()); | ||
} | ||
Ok(authorities.into()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I'd keep an eye out for (that the runtime API approach made handling-of easier) is upgradeability.
We want to upgrade GRANDPA to use BLS keys at some point
We could also have a storage item
:grandpa_protocol_version
which holds the protocol version key. We'd need 2 merkle branches, but it would allow us to change the key type later on without issues.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how the runtime API would make this sort of upgrade any easier? Are keys already encoded with the key type? If so, there's no difference, I'd think, and if not, then the
GrandpaApi_grandpa_authorities
return type would have to change anyway?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the runtime API has an implicit version, that's why
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or we could store the "authorities version" alongside the authorities in the same key. So the value is an encoded
(u8, AuthorityList)
. That way it's still just one merkle proof.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. that will require a more adaptive
Decode
implementation later on, but it should be fine.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like 0349a8b?