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

Commit

Permalink
pallet-beefy-mmr: add new authority_set() API
Browse files Browse the repository at this point in the history
Expose current and next BEEFY authority sets through runtime API.
These can be directly used by light clients to avoid having them
compute them themselves based on BEEFY validator sets.

Signed-off-by: acatangiu <adrian@parity.io>
  • Loading branch information
acatangiu committed Jun 4, 2022
1 parent 968616b commit f4bb6f5
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion frame/beefy-mmr/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ hex = { version = "0.4", default-features = false, optional = true }
log = { version = "0.4", default-features = false, optional = true }
tiny-keccak = { version = "2.0.2", features = ["keccak"], optional = true }

beefy-primitives = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/beefy" }
sp-api = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/api" }

[dev-dependencies]
env_logger = "0.9"
hex = "0.4"
Expand All @@ -22,4 +25,7 @@ hex-literal = "0.3"
debug = ["hex", "hex/std", "log"]
default = ["debug", "keccak", "std"]
keccak = ["tiny-keccak"]
std = []
std = [
"beefy-primitives/std",
"sp-api/std"
]
17 changes: 17 additions & 0 deletions frame/beefy-mmr/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;

use beefy_primitives::mmr::{BeefyAuthoritySet, BeefyNextAuthoritySet};

/// Supported hashing output size.
///
/// The size is restricted to 32 bytes to allow for a more optimised implementation.
Expand Down Expand Up @@ -375,6 +377,21 @@ where
}
}

sp_api::decl_runtime_apis! {
/// API useful for BEEFY light clients.
pub trait BeefyMmrApi<H>
where
H: From<Hash> + Into<Hash>,
BeefyAuthoritySet<H>: sp_api::Decode,
{
/// Return the currently active BEEFY authority set.
fn authority_set() -> BeefyAuthoritySet<H>;

/// Return the next/queued BEEFY authority set.
fn next_authority_set() -> BeefyNextAuthoritySet<H>;
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
10 changes: 10 additions & 0 deletions frame/beefy-mmr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,16 @@ impl<T: Config> Pallet<T>
where
MerkleRootOf<T>: From<beefy_merkle_tree::Hash> + Into<beefy_merkle_tree::Hash>,
{
/// Return the currently active BEEFY authority set.
pub fn authority_set() -> BeefyAuthoritySet<MerkleRootOf<T>> {
Pallet::<T>::beefy_authorities()
}

/// Return the next/queued BEEFY authority set.
pub fn next_authority_set() -> BeefyNextAuthoritySet<MerkleRootOf<T>> {
Pallet::<T>::beefy_next_authorities()
}

/// Returns details of a BEEFY authority set.
///
/// Details contain authority set id, authority set length and a merkle root,
Expand Down
50 changes: 50 additions & 0 deletions frame/beefy-mmr/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,53 @@ fn should_contain_valid_leaf_data() {
}
);
}

#[test]
fn should_update_authorities() {
new_test_ext(vec![1, 2, 3, 4]).execute_with(|| {
let auth_set = BeefyMmr::authority_set();
let next_auth_set = BeefyMmr::next_authority_set();

// check current authority set
assert_eq!(0, auth_set.id);
assert_eq!(2, auth_set.len);
let want: H256 =
hex!("176e73f1bf656478b728e28dd1a7733c98621b8acf830bff585949763dca7a96").into();
assert_eq!(want, auth_set.root);

// next authority set should have same validators but different id
assert_eq!(1, next_auth_set.id);
assert_eq!(auth_set.len, next_auth_set.len);
assert_eq!(auth_set.root, next_auth_set.root);

let announced_set = next_auth_set;
init_block(1);
let auth_set = BeefyMmr::authority_set();
let next_auth_set = BeefyMmr::next_authority_set();

// check new auth are expected ones
assert_eq!(announced_set, auth_set);
assert_eq!(1, auth_set.id);
// check next auth set
assert_eq!(2, next_auth_set.id);
let want: H256 =
hex!("9c6b2c1b0d0b25a008e6c882cc7b415f309965c72ad2b944ac0931048ca31cd5").into();
assert_eq!(2, next_auth_set.len);
assert_eq!(want, next_auth_set.root);

let announced_set = next_auth_set;
init_block(2);
let auth_set = BeefyMmr::authority_set();
let next_auth_set = BeefyMmr::next_authority_set();

// check new auth are expected ones
assert_eq!(announced_set, auth_set);
assert_eq!(2, auth_set.id);
// check next auth set
assert_eq!(3, next_auth_set.id);
let want: H256 =
hex!("9c6b2c1b0d0b25a008e6c882cc7b415f309965c72ad2b944ac0931048ca31cd5").into();
assert_eq!(2, next_auth_set.len);
assert_eq!(want, next_auth_set.root);
});
}
1 change: 1 addition & 0 deletions frame/beefy/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ impl frame_system::Config for Test {

impl pallet_beefy::Config for Test {
type BeefyId = BeefyId;
type OnNewValidatorSet = ();
}

parameter_types! {
Expand Down
2 changes: 1 addition & 1 deletion primitives/beefy/src/mmr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub struct BeefyAuthoritySet<MerkleRoot> {
pub id: crate::ValidatorSetId,
/// Number of validators in the set.
///
/// Some BEEFY Light Clients may use an interactive protocol to verify only subset
/// Some BEEFY Light Clients may use an interactive protocol to verify only a subset
/// of signatures. We put set length here, so that these clients can verify the minimal
/// number of required signatures.
pub len: u32,
Expand Down
2 changes: 2 additions & 0 deletions test-utils/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
beefy-primitives = { version = "4.0.0-dev", default-features = false, path = "../../primitives/beefy" }
beefy-merkle-tree = { version = "4.0.0-dev", default-features = false, path = "../../frame/beefy-mmr/primitives" }
sp-application-crypto = { version = "6.0.0", default-features = false, path = "../../primitives/application-crypto" }
sp-consensus-aura = { version = "0.10.0-dev", default-features = false, path = "../../primitives/consensus/aura" }
sp-consensus-babe = { version = "0.10.0-dev", default-features = false, path = "../../primitives/consensus/babe" }
Expand Down Expand Up @@ -67,6 +68,7 @@ default = [
]
std = [
"beefy-primitives/std",
"beefy-merkle-tree/std",
"sp-application-crypto/std",
"sp-consensus-aura/std",
"sp-consensus-babe/std",
Expand Down
10 changes: 10 additions & 0 deletions test-utils/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,16 @@ cfg_if! {
}
}

impl beefy_merkle_tree::BeefyMmrApi<Block, beefy_primitives::MmrRootHash> for RuntimeApi {
fn authority_set() -> beefy_primitives::mmr::BeefyAuthoritySet<beefy_primitives::MmrRootHash> {
Default::default()
}

fn next_authority_set() -> beefy_primitives::mmr::BeefyNextAuthoritySet<beefy_primitives::MmrRootHash> {
Default::default()
}
}

impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
fn account_nonce(_account: AccountId) -> Index {
0
Expand Down

0 comments on commit f4bb6f5

Please sign in to comment.