Finality Verifier Pallet (#629)

* Add skeleton for `pallet-finality-verifier`

* Sketch out implementation for importing finality proofs

* Get pallet compiling

* Introduce skeleton for mock runtime

* Start using real Grandpa types in finality pallet

* Redefine types in header chain primitives crate

* Implement HeaderChain for Substrate bridge pallet

* Plug Substrate Bridge Pallet into verifier mock

* Fix compilation of `header-chain` primitives

* Start writing to base pallet storage

* Add first "cross-pallet" test

* Move keyring primitives used in tests to shared crate

* Stop pulling `std` deps into `no_std` builds

* Revert "Stop pulling `std` deps into `no_std` builds"

This reverts commit f74dd660652f98b7336936d1534a4e63cc9169a5.

* Revert "Move keyring primitives used in tests to shared crate"

This reverts commit b774fa730b2cdc40545afff308a66b0840266001.

* Use new SS58Prefix type in mock

* Start using `bp-test-utils` in finality pallet

* Start using real justification code

* Get a test working with real justification verification

* Add basic tests for invalid proofs

* Get rid of AncestryProof config type

* Add error types to transaction outcome

* Bound number of headers allowed in a single ancestry proof

* Disallow invalid authority sets

* Remove unused items

* Add some documentation

* Get rid of Clippy warnings

* Rename BaseHeaderChain to TransactionVerifier

* Remove unused code

* Make dummy trait implementations more generic

* Fix more Clippy complaints

* Update tests to use fix for duplicate headers

* Fix benchmarking compilation

* Rename TransactionVerifier to InclusionProofVerifier
This commit is contained in:
Hernando Castano
2021-01-21 10:09:59 -05:00
committed by Bastian Köcher
parent 5e38b126f2
commit ea5d8662be
14 changed files with 592 additions and 38 deletions
+2 -1
View File
@@ -55,9 +55,10 @@
//! because the header is an old header.
use crate::mock::*;
use crate::storage::{AuthoritySet, ImportedHeader};
use crate::storage::ImportedHeader;
use crate::verifier::*;
use crate::{BestFinalized, BestHeight, BridgeStorage, NextScheduledChange, PalletStorage};
use bp_header_chain::AuthoritySet;
use bp_test_utils::{alice, authority_list, bob, make_justification_for_header};
use codec::Encode;
use frame_support::{IterableStorageMap, StorageValue};
+34 -1
View File
@@ -32,6 +32,7 @@
#![allow(clippy::large_enum_variant)]
use crate::storage::ImportedHeader;
use bp_header_chain::AuthoritySet;
use bp_runtime::{BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf};
use frame_support::{
decl_error, decl_module, decl_storage, dispatch::DispatchResult, ensure, traits::Get, weights::DispatchClass,
@@ -43,7 +44,7 @@ use sp_std::{marker::PhantomData, prelude::*};
use sp_trie::StorageProof;
// Re-export since the node uses these when configuring genesis
pub use storage::{AuthoritySet, InitializationData, ScheduledChange};
pub use storage::{InitializationData, ScheduledChange};
pub use storage_proof::StorageProofChecker;
@@ -361,6 +362,38 @@ impl<T: Config> Module<T> {
}
}
impl<T: Config> bp_header_chain::HeaderChain<BridgedHeader<T>> for Module<T> {
fn best_finalized() -> BridgedHeader<T> {
PalletStorage::<T>::new().best_finalized_header().header
}
fn authority_set() -> AuthoritySet {
PalletStorage::<T>::new().current_authority_set()
}
fn import_header(header: BridgedHeader<T>) -> Result<(), ()> {
let mut verifier = verifier::Verifier {
storage: PalletStorage::<T>::new(),
};
let _ = verifier.import_header(header.hash(), header).map_err(|_| ())?;
Ok(())
}
fn import_finality_proof(header: BridgedHeader<T>, finality_proof: Vec<u8>) -> Result<(), ()> {
let mut verifier = verifier::Verifier {
storage: PalletStorage::<T>::new(),
};
let _ = verifier
.import_finality_proof(header.hash(), finality_proof.into())
.map_err(|_| ())?;
Ok(())
}
}
/// Ensure that the origin is either root, or `ModuleOwner`.
fn ensure_owner_or_root<T: Config>(origin: T::Origin) -> Result<(), BadOrigin> {
match origin.into() {
+1 -17
View File
@@ -16,6 +16,7 @@
//! Storage primitives for the Substrate light client (a.k.a bridge) pallet.
use bp_header_chain::AuthoritySet;
use codec::{Decode, Encode};
use core::default::Default;
#[cfg(feature = "std")]
@@ -42,23 +43,6 @@ pub struct InitializationData<H: HeaderT> {
pub is_halted: bool,
}
/// A GRANDPA Authority List and ID.
#[derive(Default, Encode, Decode, RuntimeDebug, PartialEq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct AuthoritySet {
/// List of GRANDPA authorities for the current round.
pub authorities: AuthorityList,
/// Monotonic identifier of the current GRANDPA authority set.
pub set_id: SetId,
}
impl AuthoritySet {
/// Create a new GRANDPA Authority Set.
pub fn new(authorities: AuthorityList, set_id: SetId) -> Self {
Self { authorities, set_id }
}
}
/// Keeps track of when the next GRANDPA authority set change will occur.
#[derive(Default, Encode, Decode, RuntimeDebug, PartialEq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+2 -2
View File
@@ -22,10 +22,10 @@
//! has been signed off by the correct GRANDPA authorities, and also enact any authority set changes
//! if required.
use crate::storage::{AuthoritySet, ImportedHeader, ScheduledChange};
use crate::storage::{ImportedHeader, ScheduledChange};
use crate::BridgeStorage;
use bp_header_chain::justification::verify_justification;
use bp_header_chain::{justification::verify_justification, AuthoritySet};
use finality_grandpa::voter_set::VoterSet;
use sp_finality_grandpa::{ConsensusLog, GRANDPA_ENGINE_ID};
use sp_runtime::generic::OpaqueDigestItemId;