Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
grandpa-rpc: allow proving finality of blocks from latest authority s…
Browse files Browse the repository at this point in the history
…et (#8585)

* grandpa: use new latest stored justification in prove_finality

* grandpa: include end in range in FinalityProof::unknown_headers

* grandpa: typo in comment

* grandpa: remove ProvableJustification

* grandpa: revert unnecessary changes

* grandpa: extend AuthoritySetChangeId and cleanup get_set_id

* grandpa: move check_finality_proof to the test module

* grandpa: warn on missing authority set changes data

* grandpa: add missing use statement

* grandpa: simplify finality_proof tests

* grandpa: additional tests for finality_proof

Co-authored-by: André Silva <[email protected]>
  • Loading branch information
octol and andresilva authored Apr 28, 2021
1 parent 6181e37 commit 37e97cf
Show file tree
Hide file tree
Showing 2 changed files with 344 additions and 231 deletions.
60 changes: 42 additions & 18 deletions client/finality-grandpa/src/authorities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

//! Utilities for dealing with authorities, authority sets, and handoffs.
use std::cmp::Ord;
use std::fmt::Debug;
use std::ops::Add;

use fork_tree::ForkTree;
use parking_lot::MappedMutexGuard;
use finality_grandpa::voter_set::VoterSet;
Expand All @@ -27,9 +31,7 @@ use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_INFO};
use sp_finality_grandpa::{AuthorityId, AuthorityList};
use sc_consensus::shared_data::{SharedData, SharedDataLocked};

use std::cmp::Ord;
use std::fmt::Debug;
use std::ops::Add;
use crate::SetId;

/// Error type returned on operations on the `AuthoritySet`.
#[derive(Debug, derive_more::Display)]
Expand Down Expand Up @@ -684,6 +686,20 @@ impl<H, N: Add<Output=N> + Clone> PendingChange<H, N> {
#[derive(Debug, Encode, Decode, Clone, PartialEq)]
pub struct AuthoritySetChanges<N>(Vec<(u64, N)>);

/// The response when querying for a set id for a specific block. Either we get a set id
/// together with a block number for the last block in the set, or that the requested block is in the
/// latest set, or that we don't know what set id the given block belongs to.
#[derive(Debug, PartialEq)]
pub enum AuthoritySetChangeId<N> {
/// The requested block is in the latest set.
Latest,
/// Tuple containing the set id and the last block number of that set.
Set(SetId, N),
/// We don't know which set id the request block belongs to (this can only happen due to missing
/// data).
Unknown,
}

impl<N> From<Vec<(u64, N)>> for AuthoritySetChanges<N> {
fn from(changes: Vec<(u64, N)>) -> AuthoritySetChanges<N> {
AuthoritySetChanges(changes)
Expand All @@ -699,7 +715,15 @@ impl<N: Ord + Clone> AuthoritySetChanges<N> {
self.0.push((set_id, block_number));
}

pub(crate) fn get_set_id(&self, block_number: N) -> Option<(u64, N)> {
pub(crate) fn get_set_id(&self, block_number: N) -> AuthoritySetChangeId<N> {
if self.0
.last()
.map(|last_auth_change| last_auth_change.1 < block_number)
.unwrap_or(false)
{
return AuthoritySetChangeId::Latest;
}

let idx = self.0
.binary_search_by_key(&block_number, |(_, n)| n.clone())
.unwrap_or_else(|b| b);
Expand All @@ -711,16 +735,16 @@ impl<N: Ord + Clone> AuthoritySetChanges<N> {
let (prev_set_id, _) = self.0[idx - 1usize];
if set_id != prev_set_id + 1u64 {
// Without the preceding set_id we don't have a well-defined start.
return None;
return AuthoritySetChangeId::Unknown;
}
} else if set_id != 0 {
// If this is the first index, yet not the first set id then it's not well-defined
// that we are in the right set id.
return None;
return AuthoritySetChangeId::Unknown;
}
Some((set_id, block_number))
AuthoritySetChangeId::Set(set_id, block_number)
} else {
None
AuthoritySetChangeId::Unknown
}
}

Expand Down Expand Up @@ -1660,11 +1684,11 @@ mod tests {
authority_set_changes.append(1, 81);
authority_set_changes.append(2, 121);

assert_eq!(authority_set_changes.get_set_id(20), Some((0, 41)));
assert_eq!(authority_set_changes.get_set_id(40), Some((0, 41)));
assert_eq!(authority_set_changes.get_set_id(41), Some((0, 41)));
assert_eq!(authority_set_changes.get_set_id(42), Some((1, 81)));
assert_eq!(authority_set_changes.get_set_id(141), None);
assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Set(0, 41));
assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Set(0, 41));
assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Set(0, 41));
assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(1, 81));
assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
}

#[test]
Expand All @@ -1674,11 +1698,11 @@ mod tests {
authority_set_changes.append(3, 81);
authority_set_changes.append(4, 121);

assert_eq!(authority_set_changes.get_set_id(20), None);
assert_eq!(authority_set_changes.get_set_id(40), None);
assert_eq!(authority_set_changes.get_set_id(41), None);
assert_eq!(authority_set_changes.get_set_id(42), Some((3, 81)));
assert_eq!(authority_set_changes.get_set_id(141), None);
assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Unknown);
assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Unknown);
assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Unknown);
assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(3, 81));
assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
}

#[test]
Expand Down
Loading

0 comments on commit 37e97cf

Please sign in to comment.