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

Commit

Permalink
BEEFY: define on-chain beefy-genesis and use it to coordinate voter i…
Browse files Browse the repository at this point in the history
…nitialization (#13215)

* beefy: add support to configure BEEFY genesis

* client/beefy: more flexible test runtime api

* client/beefy: add tests for custom BEEFY genesis

* client/beefy: ignore old state that didn't account for pallet genesis

* client/beefy: fix clippy

* frame/beefy: default BEEFY-genesis is block One::one()

* frame/beefy: add extra doc comments

---------

Co-authored-by: parity-processbot <>
  • Loading branch information
acatangiu authored and Ank4n committed Feb 5, 2023
1 parent c6c490d commit 6453a4a
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 114 deletions.
5 changes: 3 additions & 2 deletions client/beefy/src/aux_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use sp_runtime::traits::Block as BlockT;
const VERSION_KEY: &[u8] = b"beefy_auxschema_version";
const WORKER_STATE: &[u8] = b"beefy_voter_state";

const CURRENT_VERSION: u32 = 1;
const CURRENT_VERSION: u32 = 2;

pub(crate) fn write_current_version<B: AuxStore>(backend: &B) -> ClientResult<()> {
info!(target: LOG_TARGET, "🥩 write aux schema version {:?}", CURRENT_VERSION);
Expand Down Expand Up @@ -63,7 +63,8 @@ where

match version {
None => (),
Some(1) => return load_decode::<_, PersistedState<B>>(backend, WORKER_STATE),
Some(1) => (), // version 1 is totally obsolete and should be simply ignored
Some(2) => return load_decode::<_, PersistedState<B>>(backend, WORKER_STATE),
other =>
return Err(ClientError::Backend(format!("Unsupported BEEFY DB version: {:?}", other))),
}
Expand Down
34 changes: 21 additions & 13 deletions client/beefy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use sp_keystore::SyncCryptoStorePtr;
use sp_mmr_primitives::MmrApi;
use sp_runtime::{
generic::BlockId,
traits::{Block, One, Zero},
traits::{Block, Zero},
};
use std::{collections::VecDeque, marker::PhantomData, sync::Arc};

Expand Down Expand Up @@ -346,6 +346,12 @@ where
R: ProvideRuntimeApi<B>,
R::Api: BeefyApi<B>,
{
let beefy_genesis = runtime
.runtime_api()
.beefy_genesis(&BlockId::hash(best_grandpa.hash()))
.ok()
.flatten()
.ok_or_else(|| ClientError::Backend("BEEFY pallet expected to be active.".into()))?;
// Walk back the imported blocks and initialize voter either, at the last block with
// a BEEFY justification, or at pallet genesis block; voter will resume from there.
let blockchain = backend.blockchain();
Expand Down Expand Up @@ -378,20 +384,19 @@ where
break state
}

if *header.number() == One::one() {
// We've reached chain genesis, initialize voter here.
let genesis_num = *header.number();
if *header.number() == beefy_genesis {
// We've reached BEEFY genesis, initialize voter here.
let genesis_set = expect_validator_set(runtime, BlockId::hash(header.hash()))
.and_then(genesis_set_sanity_check)?;
info!(
target: LOG_TARGET,
"🥩 Loading BEEFY voter state from genesis on what appears to be first startup. \
Starting voting rounds at block {:?}, genesis validator set {:?}.",
genesis_num,
beefy_genesis,
genesis_set,
);

sessions.push_front(Rounds::new(genesis_num, genesis_set));
sessions.push_front(Rounds::new(beefy_genesis, genesis_set));
break PersistedState::checked_new(best_grandpa, Zero::zero(), sessions, min_block_delta)
.ok_or_else(|| ClientError::Backend("Invalid BEEFY chain".into()))?
}
Expand Down Expand Up @@ -448,13 +453,16 @@ where
None => break
};
let at = BlockId::hash(notif.header.hash());
if let Some(active) = runtime.runtime_api().validator_set(&at).ok().flatten() {
// Beefy pallet available, return best grandpa at the time.
info!(
target: LOG_TARGET, "🥩 BEEFY pallet available: block {:?} validator set {:?}",
notif.header.number(), active
);
return Ok(notif.header)
if let Some(start) = runtime.runtime_api().beefy_genesis(&at).ok().flatten() {
if *notif.header.number() >= start {
// Beefy pallet available, return header for best grandpa at the time.
info!(
target: LOG_TARGET,
"🥩 BEEFY pallet available: block {:?} beefy genesis {:?}",
notif.header.number(), start
);
return Ok(notif.header)
}
}
},
_ = gossip_engine => {
Expand Down
Loading

0 comments on commit 6453a4a

Please sign in to comment.