mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-21 07:25:44 +00:00
Wire Finality Verifier Pallet Into Runtimes (#696)
* Add Finality Verifier pallet to runtimes * Implement simple ancestry checker * Use the new checker in runtimes * Remove unused import warning * Bump max allowed ancestry proof size * Add a few optimization suggestions when verifying ancestry * Use session length as upper bound for ancestry proof size * Remove unused time units
This commit is contained in:
committed by
Bastian Köcher
parent
d73100cb30
commit
8c7d0ca35d
@@ -27,7 +27,9 @@ use core::fmt::Debug;
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sp_finality_grandpa::{AuthorityList, SetId};
|
||||
use sp_runtime::traits::Header as HeaderT;
|
||||
use sp_runtime::RuntimeDebug;
|
||||
use sp_std::vec::Vec;
|
||||
|
||||
pub mod justification;
|
||||
|
||||
@@ -110,3 +112,101 @@ impl<H, P> AncestryChecker<H, P> for () {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple ancestry checker which verifies ancestry by walking every header between `child` and
|
||||
/// `ancestor`.
|
||||
pub struct LinearAncestryChecker;
|
||||
|
||||
impl<H: HeaderT> AncestryChecker<H, Vec<H>> for LinearAncestryChecker {
|
||||
fn are_ancestors(ancestor: &H, child: &H, proof: &Vec<H>) -> bool {
|
||||
// You can't be your own parent
|
||||
if proof.len() < 2 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let's make sure that the given headers are actually in the proof
|
||||
match proof.first() {
|
||||
Some(first) if first == ancestor => {}
|
||||
_ => return false,
|
||||
}
|
||||
|
||||
match proof.last() {
|
||||
Some(last) if last == child => {}
|
||||
_ => return false,
|
||||
}
|
||||
|
||||
// Now we actually check the proof
|
||||
for i in 1..proof.len() {
|
||||
if &proof[i - 1].hash() != proof[i].parent_hash() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use bp_test_utils::test_header;
|
||||
use sp_runtime::testing::Header;
|
||||
|
||||
#[test]
|
||||
fn can_verify_ancestry_correctly() {
|
||||
let ancestor: Header = test_header(1);
|
||||
let header2: Header = test_header(2);
|
||||
let header3: Header = test_header(3);
|
||||
let child: Header = test_header(4);
|
||||
|
||||
let ancestry_proof = vec![ancestor.clone(), header2, header3, child.clone()];
|
||||
|
||||
assert!(LinearAncestryChecker::are_ancestors(&ancestor, &child, &ancestry_proof));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_not_verify_invalid_proof() {
|
||||
let ancestor: Header = test_header(1);
|
||||
let header2: Header = test_header(2);
|
||||
let header3: Header = test_header(3);
|
||||
let child: Header = test_header(4);
|
||||
|
||||
let ancestry_proof = vec![ancestor.clone(), header3, header2, child.clone()];
|
||||
|
||||
let invalid = !LinearAncestryChecker::are_ancestors(&ancestor, &child, &ancestry_proof);
|
||||
assert!(invalid);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn header_is_not_allowed_to_be_its_own_ancestor() {
|
||||
let ancestor: Header = test_header(1);
|
||||
let child: Header = ancestor.clone();
|
||||
let ancestry_proof = vec![ancestor.clone()];
|
||||
|
||||
let invalid = !LinearAncestryChecker::are_ancestors(&ancestor, &child, &ancestry_proof);
|
||||
assert!(invalid);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proof_is_considered_invalid_if_child_and_ancestor_do_not_match() {
|
||||
let ancestor: Header = test_header(1);
|
||||
let header2: Header = test_header(2);
|
||||
let header3: Header = test_header(3);
|
||||
let child: Header = test_header(4);
|
||||
|
||||
let ancestry_proof = vec![ancestor, header3.clone(), header2.clone(), child];
|
||||
|
||||
let invalid = !LinearAncestryChecker::are_ancestors(&header2, &header3, &ancestry_proof);
|
||||
assert!(invalid);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_proof_is_invalid() {
|
||||
let ancestor: Header = test_header(1);
|
||||
let child: Header = ancestor.clone();
|
||||
let ancestry_proof = vec![];
|
||||
|
||||
let invalid = !LinearAncestryChecker::are_ancestors(&ancestor, &child, &ancestry_proof);
|
||||
assert!(invalid);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user