grandpa: Use storage proofs for Grandpa authorities (#3985)

This commit is contained in:
Jim Posen
2019-11-07 14:31:17 +01:00
committed by GitHub
parent bb6b3db57e
commit 021f3a3f06
16 changed files with 289 additions and 149 deletions
+1
View File
@@ -35,3 +35,4 @@ std = [
"session/std",
"finality-tracker/std",
]
migrate-authorities = []
+45 -18
View File
@@ -32,9 +32,7 @@ pub use substrate_finality_grandpa_primitives as fg_primitives;
use rstd::prelude::*;
use codec::{self as codec, Encode, Decode, Error};
use support::{
decl_event, decl_storage, decl_module, dispatch::Result,
};
use support::{decl_event, decl_storage, decl_module, dispatch::Result, storage};
use sr_primitives::{
generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill,
};
@@ -42,8 +40,10 @@ use sr_staking_primitives::{
SessionIndex,
offence::{Offence, Kind},
};
use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog, SetId, RoundNumber};
pub use fg_primitives::{AuthorityId, AuthorityWeight};
use fg_primitives::{
GRANDPA_AUTHORITIES_KEY, GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog, SetId, RoundNumber,
};
pub use fg_primitives::{AuthorityId, AuthorityList, AuthorityWeight, VersionedAuthorityList};
use system::{ensure_signed, DigestOf};
mod mock;
@@ -64,7 +64,7 @@ pub struct OldStoredPendingChange<N> {
/// The delay in blocks until it will be applied.
pub delay: N,
/// The next authority set.
pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>,
pub next_authorities: AuthorityList,
}
/// A stored pending change.
@@ -75,7 +75,7 @@ pub struct StoredPendingChange<N> {
/// The delay in blocks until it will be applied.
pub delay: N,
/// The next authority set.
pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>,
pub next_authorities: AuthorityList,
/// If defined it means the change was forced and the given block number
/// indicates the median last finalized block when the change was signaled.
pub forced: Option<N>,
@@ -126,7 +126,7 @@ pub enum StoredState<N> {
decl_event!(
pub enum Event {
/// New authority set has been applied.
NewAuthorities(Vec<(AuthorityId, AuthorityWeight)>),
NewAuthorities(AuthorityList),
/// Current authority set has been paused.
Paused,
/// Current authority set has been resumed.
@@ -136,8 +136,12 @@ decl_event!(
decl_storage! {
trait Store for Module<T: Trait> as GrandpaFinality {
/// The current authority set.
Authorities get(fn authorities): Vec<(AuthorityId, AuthorityWeight)>;
/// DEPRECATED
///
/// This used to store the current authority set, which has been migrated to the well-known
/// GRANDPA_AUTHORITES_KEY unhashed key.
#[cfg(feature = "migrate-authorities")]
pub(crate) Authorities get(fn authorities): AuthorityList;
/// State of the current authority set.
State get(fn state): StoredState<T::BlockNumber> = StoredState::Live;
@@ -159,7 +163,7 @@ decl_storage! {
SetIdSession get(fn session_for_set): map SetId => Option<SessionIndex>;
}
add_extra_genesis {
config(authorities): Vec<(AuthorityId, AuthorityWeight)>;
config(authorities): AuthorityList;
build(|config| Module::<T>::initialize_authorities(&config.authorities))
}
}
@@ -174,6 +178,11 @@ decl_module! {
// FIXME: https://github.com/paritytech/substrate/issues/1112
}
fn on_initialize() {
#[cfg(feature = "migrate-authorities")]
Self::migrate_authorities();
}
fn on_finalize(block_number: T::BlockNumber) {
// check for scheduled pending authority set changes
if let Some(pending_change) = <PendingChange<T>>::get() {
@@ -199,7 +208,7 @@ decl_module! {
// enact the change if we've reached the enacting block
if block_number == pending_change.scheduled_at + pending_change.delay {
Authorities::put(&pending_change.next_authorities);
Self::set_grandpa_authorities(&pending_change.next_authorities);
Self::deposit_event(
Event::NewAuthorities(pending_change.next_authorities)
);
@@ -241,8 +250,16 @@ decl_module! {
impl<T: Trait> Module<T> {
/// Get the current set of authorities, along with their respective weights.
pub fn grandpa_authorities() -> Vec<(AuthorityId, AuthorityWeight)> {
Authorities::get()
pub fn grandpa_authorities() -> AuthorityList {
storage::unhashed::get_or_default::<VersionedAuthorityList>(GRANDPA_AUTHORITIES_KEY).into()
}
/// Set the current set of authorities, along with their respective weights.
fn set_grandpa_authorities(authorities: &AuthorityList) {
storage::unhashed::put(
GRANDPA_AUTHORITIES_KEY,
&VersionedAuthorityList::from(authorities),
);
}
/// Schedule GRANDPA to pause starting in the given number of blocks.
@@ -293,7 +310,7 @@ impl<T: Trait> Module<T> {
/// No change should be signaled while any change is pending. Returns
/// an error if a change is already pending.
pub fn schedule_change(
next_authorities: Vec<(AuthorityId, AuthorityWeight)>,
next_authorities: AuthorityList,
in_blocks: T::BlockNumber,
forced: Option<T::BlockNumber>,
) -> Result {
@@ -329,10 +346,20 @@ impl<T: Trait> Module<T> {
<system::Module<T>>::deposit_log(log.into());
}
fn initialize_authorities(authorities: &[(AuthorityId, AuthorityWeight)]) {
fn initialize_authorities(authorities: &AuthorityList) {
if !authorities.is_empty() {
assert!(Authorities::get().is_empty(), "Authorities are already initialized!");
Authorities::put(authorities);
assert!(
Self::grandpa_authorities().is_empty(),
"Authorities are already initialized!"
);
Self::set_grandpa_authorities(authorities);
}
}
#[cfg(feature = "migrate-authorities")]
fn migrate_authorities() {
if Authorities::exists() {
Self::set_grandpa_authorities(&Authorities::take());
}
}
}
+2 -2
View File
@@ -23,7 +23,7 @@ use runtime_io;
use support::{impl_outer_origin, impl_outer_event, parameter_types};
use primitives::H256;
use codec::{Encode, Decode};
use crate::{AuthorityId, GenesisConfig, Trait, Module, ConsensusLog};
use crate::{AuthorityId, AuthorityList, GenesisConfig, Trait, Module, ConsensusLog};
use substrate_finality_grandpa_primitives::GRANDPA_ENGINE_ID;
impl_outer_origin!{
@@ -75,7 +75,7 @@ impl_outer_event!{
}
}
pub fn to_authorities(vec: Vec<(u64, u64)>) -> Vec<(AuthorityId, u64)> {
pub fn to_authorities(vec: Vec<(u64, u64)>) -> AuthorityList {
vec.into_iter()
.map(|(id, weight)| (UintAuthorityId(id).to_public_key::<AuthorityId>(), weight))
.collect()
+18
View File
@@ -308,3 +308,21 @@ fn time_slot_have_sane_ord() {
];
assert!(FIXTURE.windows(2).all(|f| f[0] < f[1]));
}
#[test]
#[cfg(feature = "migrate-authorities")]
fn authorities_migration() {
use sr_primitives::traits::OnInitialize;
with_externalities(&mut new_test_ext(vec![]), || {
let authorities = to_authorities(vec![(1, 1), (2, 1), (3, 1)]);
Authorities::put(authorities.clone());
assert!(Grandpa::grandpa_authorities().is_empty());
Grandpa::on_initialize(1);
assert!(!Authorities::exists());
assert_eq!(Grandpa::grandpa_authorities(), authorities);
});
}