Use GrandpaJustification instead of Vec<u8> in Pallet API (#847)

* Stop passing raw encoded justifications to pallet API

By having the API accept a struct-ified justification we are able to
better utilize the justifications fields for weight calculations.

* Update relayer code to use decoded justifications

* Add justification to `expect()` statement

* Fix some imports

* Make justification wrapper contain decoded justification

* Rename some fields

* Get rid of warnings

* Appease Clippy

* Only decode justification once at init time

* Remove unnecessary method

* Remove justification wrapper

This became kinda unnecessary since we could implement the FinalityProof
trait on GrandpaJustification directly.
This commit is contained in:
Hernando Castano
2021-04-01 07:08:28 -04:00
committed by Bastian Köcher
parent 904b9f4da5
commit 67cdca8aa4
14 changed files with 92 additions and 117 deletions
@@ -25,7 +25,7 @@ use frame_support::RuntimeDebug;
use sp_finality_grandpa::{AuthorityId, AuthoritySignature, SetId};
use sp_runtime::traits::Header as HeaderT;
use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
use sp_std::prelude::Vec;
use sp_std::prelude::*;
/// Justification verification error.
#[derive(RuntimeDebug, PartialEq)]
@@ -58,15 +58,11 @@ pub fn verify_justification<Header: HeaderT>(
finalized_target: (Header::Hash, Header::Number),
authorities_set_id: SetId,
authorities_set: &VoterSet<AuthorityId>,
raw_justification: &[u8],
justification: &GrandpaJustification<Header>,
) -> Result<(), Error>
where
Header::Number: finality_grandpa::BlockNumberOps,
{
// Decode justification first
let justification =
GrandpaJustification::<Header>::decode(&mut &*raw_justification).map_err(|_| Error::JustificationDecode)?;
// Ensure that it is justification for the expected header
if (justification.commit.target_hash, justification.commit.target_number) != finalized_target {
return Err(Error::InvalidJustificationTarget);
@@ -130,7 +126,7 @@ where
///
/// This particular proof is used to prove that headers on a bridged chain
/// (so not our chain) have been finalized correctly.
#[derive(Encode, Decode, RuntimeDebug)]
#[derive(Encode, Decode, RuntimeDebug, Clone, PartialEq, Eq)]
pub struct GrandpaJustification<Header: HeaderT> {
/// The round (voting period) this justification is valid for.
pub round: u64,
@@ -140,6 +136,12 @@ pub struct GrandpaJustification<Header: HeaderT> {
pub votes_ancestries: Vec<Header>,
}
impl<H: HeaderT> crate::FinalityProof<H::Number> for GrandpaJustification<H> {
fn target_header_number(&self) -> H::Number {
self.commit.target_number
}
}
/// A utility trait implementing `finality_grandpa::Chain` using a given set of headers.
#[derive(RuntimeDebug)]
struct AncestryChain<Header: HeaderT> {
@@ -94,6 +94,12 @@ impl<H: Default, E> HeaderChain<H, E> for () {
}
}
/// Abstract finality proof that is justifying block finality.
pub trait FinalityProof<Number>: Clone + Send + Sync + Debug {
/// Return number of header that this proof is generated for.
fn target_header_number(&self) -> Number;
}
/// Find header digest that schedules next GRANDPA authorities set.
pub fn find_grandpa_authorities_scheduled_change<H: HeaderT>(
header: &H,
@@ -18,7 +18,6 @@
use bp_header_chain::justification::{verify_justification, Error};
use bp_test_utils::*;
use codec::Encode;
type TestHeader = sp_runtime::testing::Header;
@@ -38,7 +37,7 @@ fn valid_justification_accepted() {
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
&voter_set(),
&make_justification_for_header::<TestHeader>(params).encode()
&make_justification_for_header::<TestHeader>(params)
),
Ok(()),
);
@@ -60,7 +59,7 @@ fn valid_justification_accepted_with_single_fork() {
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
&voter_set(),
&make_justification_for_header::<TestHeader>(params).encode()
&make_justification_for_header::<TestHeader>(params)
),
Ok(()),
);
@@ -94,20 +93,12 @@ fn valid_justification_accepted_with_arbitrary_number_of_authorities() {
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
&voter_set,
&make_justification_for_header::<TestHeader>(params).encode()
&make_justification_for_header::<TestHeader>(params)
),
Ok(()),
);
}
#[test]
fn justification_with_invalid_encoding_rejected() {
assert_eq!(
verify_justification::<TestHeader>(header_id::<TestHeader>(1), TEST_GRANDPA_SET_ID, &voter_set(), &[],),
Err(Error::JustificationDecode),
);
}
#[test]
fn justification_with_invalid_target_rejected() {
assert_eq!(
@@ -115,7 +106,7 @@ fn justification_with_invalid_target_rejected() {
header_id::<TestHeader>(2),
TEST_GRANDPA_SET_ID,
&voter_set(),
&make_default_justification::<TestHeader>(&test_header(1)).encode(),
&make_default_justification::<TestHeader>(&test_header(1)),
),
Err(Error::InvalidJustificationTarget),
);
@@ -131,7 +122,7 @@ fn justification_with_invalid_commit_rejected() {
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
&voter_set(),
&justification.encode(),
&justification,
),
Err(Error::InvalidJustificationCommit),
);
@@ -147,7 +138,7 @@ fn justification_with_invalid_authority_signature_rejected() {
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
&voter_set(),
&justification.encode(),
&justification,
),
Err(Error::InvalidAuthoritySignature),
);
@@ -163,7 +154,7 @@ fn justification_with_invalid_precommit_ancestry() {
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
&voter_set(),
&justification.encode(),
&justification,
),
Err(Error::InvalidPrecommitAncestries),
);
@@ -186,7 +177,7 @@ fn justification_is_invalid_if_we_dont_meet_threshold() {
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
&voter_set(),
&make_justification_for_header::<TestHeader>(params).encode()
&make_justification_for_header::<TestHeader>(params)
),
Err(Error::InvalidJustificationCommit),
);