BEEFY: expect_validator_set() fix (#2716)

Fixes #https://github.com/paritytech/polkadot-sdk/issues/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>
This commit is contained in:
Serban Iorga
2023-12-15 08:09:39 +01:00
committed by GitHub
parent b58f0aef2d
commit 99df39194d
+18 -20
View File
@@ -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()))
}
}
}