Skip to content

Commit

Permalink
BEEFY: expect_validator_set() fix (#2716)
Browse files Browse the repository at this point in the history
Fixes ##2699

Modifying `expect_validator_set()` in order to be able to walk back
until block 0. The chain state at block 0 is available even if we use
`--sync fast` or `--sync warp`. This way we can retrieve the initial
authority set even when BEEFY genesis is 1 and there is no authority
change entry in the headers log.

Credits to @acatangiu for the solution

---------

Co-authored-by: Adrian Catangiu <adrian@parity.io>
  • Loading branch information
serban300 and acatangiu committed Dec 15, 2023
1 parent b58f0ae commit 99df391
Showing 1 changed file with 18 additions and 20 deletions.
38 changes: 18 additions & 20 deletions substrate/client/consensus/beefy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,25 +543,23 @@ where
R: ProvideRuntimeApi<B>,
R::Api: BeefyApi<B, AuthorityId>,
{
debug!(target: LOG_TARGET, "🥩 Try to find validator set active at header: {:?}", at_header);
runtime
.runtime_api()
.validator_set(at_header.hash())
.ok()
.flatten()
.or_else(|| {
// if state unavailable, fallback to walking up the chain looking for the header
// Digest emitted when validator set active 'at_header' was enacted.
let blockchain = backend.blockchain();
let mut header = at_header.clone();
loop {
debug!(target: LOG_TARGET, "🥩 look for auth set change digest in header number: {:?}", *header.number());
match worker::find_authorities_change::<B>(&header) {
Some(active) => return Some(active),
// Move up the chain.
None => header = blockchain.expect_header(*header.parent_hash()).ok()?,
}
let blockchain = backend.blockchain();

// Walk up the chain looking for the validator set active at 'at_header'. Process both state and
// header digests.
debug!(target: LOG_TARGET, "🥩 Trying to find validator set active at header: {:?}", at_header);
let mut header = at_header.clone();
loop {
if let Ok(Some(active)) = runtime.runtime_api().validator_set(at_header.hash()) {
return Ok(active)
} else {
debug!(target: LOG_TARGET, "🥩 Looking for auth set change at block number: {:?}", *header.number());
match worker::find_authorities_change::<B>(&header) {
Some(active) => return Ok(active),
// Move up the chain. Ultimately we'll get it from chain genesis state, or error out
// here.
None => header = blockchain.expect_header(*header.parent_hash())?,
}
})
.ok_or_else(|| ClientError::Backend("Could not find initial validator set".into()))
}
}
}

0 comments on commit 99df391

Please sign in to comment.