mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 10:31:04 +00:00
Light GRANDPA import handler (#1669)
* GrandpaLightBlockImport * extract authorities in AuraVerifier * post-merge fix * restore authorities cache * license * new finality proof draft * generalized PendingJustifications * finality proof messages * fixed compilation * pass verifier to import_finality_proof * do not fetch remote proof from light import directly * FinalityProofProvider * fixed authorities cache test * restored finality proof tests * finality_proof docs * use DB backend in test client * justification_is_fetched_by_light_client_when_consensus_data_changes * restore justification_is_fetched_by_light_client_when_consensus_data_changes * some more tests * added authorities-related TODO * removed unneeded clear_finality_proof_requests field * truncated some long lines * more granular light import tests * only provide finality proof if it is generated by the requested set * post-merge fix * finality_proof_is_none_if_first_justification_is_generated_by_unknown_set * make light+grandpa test rely on finality proofs (instead of simple justifications) * empty_finality_proof_is_returned_to_light_client_when_authority_set_is_different * missing trait method impl * fixed proof-of-finality docs * one more doc fix * fix docs * initialize authorities cache (post-merge fix) * fixed cache initialization (post-merge fix) * post-fix merge: fix light + GRANDPA tests (bad way) * proper fix of empty_finality_proof_is_returned_to_light_client_when_authority_set_is_different * fixed easy grumbles * import finality proofs in BlockImportWorker thread * allow import of finality proofs for non-requested blocks * limit number of fragments in finality proof * GRANDPA post-merge fix * BABE: pos-merge fix
This commit is contained in:
committed by
Gavin Wood
parent
258f0835e4
commit
22586113ea
@@ -33,7 +33,10 @@ use consensus_common::{self, Authorities, BlockImport, Environment, Proposer,
|
||||
ForkChoiceStrategy, ImportBlock, BlockOrigin, Error as ConsensusError,
|
||||
SelectChain, well_known_cache_keys
|
||||
};
|
||||
use consensus_common::import_queue::{Verifier, BasicQueue, SharedBlockImport, SharedJustificationImport};
|
||||
use consensus_common::import_queue::{
|
||||
Verifier, BasicQueue, SharedBlockImport, SharedJustificationImport, SharedFinalityProofImport,
|
||||
SharedFinalityProofRequestBuilder,
|
||||
};
|
||||
use client::{
|
||||
block_builder::api::BlockBuilder as BlockBuilderApi,
|
||||
blockchain::ProvideCache,
|
||||
@@ -44,7 +47,7 @@ use client::{
|
||||
use aura_primitives::AURA_ENGINE_ID;
|
||||
use runtime_primitives::{generic, generic::BlockId, Justification};
|
||||
use runtime_primitives::traits::{
|
||||
Block, Header, Digest, DigestItemFor, DigestItem, ProvideRuntimeApi, AuthorityIdFor,
|
||||
Block, Header, Digest, DigestItemFor, DigestItem, ProvideRuntimeApi, AuthorityIdFor, Zero,
|
||||
};
|
||||
use primitives::Pair;
|
||||
use inherents::{InherentDataProviders, InherentData, RuntimeString};
|
||||
@@ -653,6 +656,10 @@ impl<B: Block, C, E, P> Verifier<B> for AuraVerifier<C, E, P> where
|
||||
|
||||
extra_verification.into_future().wait()?;
|
||||
|
||||
let new_authorities = pre_header.digest()
|
||||
.log(DigestItem::as_authorities_change)
|
||||
.map(|digest| digest.to_vec());
|
||||
|
||||
let import_block = ImportBlock {
|
||||
origin,
|
||||
header: pre_header,
|
||||
@@ -664,8 +671,7 @@ impl<B: Block, C, E, P> Verifier<B> for AuraVerifier<C, E, P> where
|
||||
fork_choice: ForkChoiceStrategy::LongestChain,
|
||||
};
|
||||
|
||||
// FIXME #1019 extract authorities
|
||||
Ok((import_block, None))
|
||||
Ok((import_block, new_authorities))
|
||||
}
|
||||
CheckedHeader::Deferred(a, b) => {
|
||||
debug!(target: "aura", "Checking {:?} failed; {:?}, {:?}.", hash, a, b);
|
||||
@@ -690,6 +696,38 @@ impl<B, C, E, P> Authorities<B> for AuraVerifier<C, E, P> where
|
||||
}
|
||||
}
|
||||
|
||||
fn initialize_authorities_cache<B, C>(client: &C) -> Result<(), ConsensusError> where
|
||||
B: Block,
|
||||
C: ProvideRuntimeApi + ProvideCache<B>,
|
||||
C::Api: AuthoritiesApi<B>,
|
||||
{
|
||||
// no cache => no initialization
|
||||
let cache = match client.cache() {
|
||||
Some(cache) => cache,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
// check if we already have initialized the cache
|
||||
let genesis_id = BlockId::Number(Zero::zero());
|
||||
let genesis_authorities: Option<Vec<AuthorityIdFor<B>>> = cache
|
||||
.get_at(&well_known_cache_keys::AUTHORITIES, &genesis_id)
|
||||
.and_then(|v| Decode::decode(&mut &v[..]));
|
||||
if genesis_authorities.is_some() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let map_err = |error| consensus_common::Error::from(consensus_common::ErrorKind::ClientImport(
|
||||
format!(
|
||||
"Error initializing authorities cache: {}",
|
||||
error,
|
||||
)));
|
||||
let genesis_authorities = authorities(client, &genesis_id)?;
|
||||
cache.initialize(&well_known_cache_keys::AUTHORITIES, genesis_authorities.encode())
|
||||
.map_err(map_err)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn authorities<B, C>(client: &C, at: &BlockId<B>) -> Result<Vec<AuthorityIdFor<B>>, ConsensusError> where
|
||||
B: Block,
|
||||
@@ -731,6 +769,8 @@ pub fn import_queue<B, C, E, P>(
|
||||
slot_duration: SlotDuration,
|
||||
block_import: SharedBlockImport<B>,
|
||||
justification_import: Option<SharedJustificationImport<B>>,
|
||||
finality_proof_import: Option<SharedFinalityProofImport<B>>,
|
||||
finality_proof_request_builder: Option<SharedFinalityProofRequestBuilder<B>>,
|
||||
client: Arc<C>,
|
||||
extra: E,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
@@ -745,6 +785,7 @@ pub fn import_queue<B, C, E, P>(
|
||||
P::Signature: Encode + Decode,
|
||||
{
|
||||
register_aura_inherent_data_provider(&inherent_data_providers, slot_duration.get())?;
|
||||
initialize_authorities_cache(&*client)?;
|
||||
|
||||
let verifier = Arc::new(
|
||||
AuraVerifier {
|
||||
@@ -755,7 +796,13 @@ pub fn import_queue<B, C, E, P>(
|
||||
allow_old_seals: false,
|
||||
}
|
||||
);
|
||||
Ok(BasicQueue::new(verifier, block_import, justification_import))
|
||||
Ok(BasicQueue::new(
|
||||
verifier,
|
||||
block_import,
|
||||
justification_import,
|
||||
finality_proof_import,
|
||||
finality_proof_request_builder,
|
||||
))
|
||||
}
|
||||
|
||||
/// Start an import queue for the Aura consensus algorithm with backwards compatibility.
|
||||
@@ -767,6 +814,8 @@ pub fn import_queue_accept_old_seals<B, C, E, P>(
|
||||
slot_duration: SlotDuration,
|
||||
block_import: SharedBlockImport<B>,
|
||||
justification_import: Option<SharedJustificationImport<B>>,
|
||||
finality_proof_import: Option<SharedFinalityProofImport<B>>,
|
||||
finality_proof_request_builder: Option<SharedFinalityProofRequestBuilder<B>>,
|
||||
client: Arc<C>,
|
||||
extra: E,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
@@ -781,6 +830,7 @@ pub fn import_queue_accept_old_seals<B, C, E, P>(
|
||||
P::Signature: Encode + Decode,
|
||||
{
|
||||
register_aura_inherent_data_provider(&inherent_data_providers, slot_duration.get())?;
|
||||
initialize_authorities_cache(&*client)?;
|
||||
|
||||
let verifier = Arc::new(
|
||||
AuraVerifier {
|
||||
@@ -791,7 +841,13 @@ pub fn import_queue_accept_old_seals<B, C, E, P>(
|
||||
allow_old_seals: true,
|
||||
}
|
||||
);
|
||||
Ok(BasicQueue::new(verifier, block_import, justification_import))
|
||||
Ok(BasicQueue::new(
|
||||
verifier,
|
||||
block_import,
|
||||
justification_import,
|
||||
finality_proof_import,
|
||||
finality_proof_request_builder,
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -799,7 +855,7 @@ mod tests {
|
||||
use super::*;
|
||||
use consensus_common::NoNetwork as DummyOracle;
|
||||
use network::test::*;
|
||||
use network::test::{Block as TestBlock, PeersClient};
|
||||
use network::test::{Block as TestBlock, PeersClient, PeersFullClient};
|
||||
use runtime_primitives::traits::Block as BlockT;
|
||||
use network::config::ProtocolConfig;
|
||||
use parking_lot::Mutex;
|
||||
@@ -846,7 +902,7 @@ mod tests {
|
||||
|
||||
impl TestNetFactory for AuraTestNet {
|
||||
type Specialization = DummySpecialization;
|
||||
type Verifier = AuraVerifier<PeersClient, NothingExtra, sr25519::Pair>;
|
||||
type Verifier = AuraVerifier<PeersFullClient, NothingExtra, sr25519::Pair>;
|
||||
type PeerData = ();
|
||||
|
||||
/// Create new test network with peers and given config.
|
||||
@@ -857,25 +913,30 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_verifier(&self, client: Arc<PeersClient>, _cfg: &ProtocolConfig)
|
||||
fn make_verifier(&self, client: PeersClient, _cfg: &ProtocolConfig)
|
||||
-> Arc<Self::Verifier>
|
||||
{
|
||||
let slot_duration = SlotDuration::get_or_compute(&*client)
|
||||
.expect("slot duration available");
|
||||
let inherent_data_providers = InherentDataProviders::new();
|
||||
register_aura_inherent_data_provider(
|
||||
&inherent_data_providers,
|
||||
slot_duration.get()
|
||||
).expect("Registers aura inherent data provider");
|
||||
match client {
|
||||
PeersClient::Full(client) => {
|
||||
let slot_duration = SlotDuration::get_or_compute(&*client)
|
||||
.expect("slot duration available");
|
||||
let inherent_data_providers = InherentDataProviders::new();
|
||||
register_aura_inherent_data_provider(
|
||||
&inherent_data_providers,
|
||||
slot_duration.get()
|
||||
).expect("Registers aura inherent data provider");
|
||||
|
||||
assert_eq!(slot_duration.get(), SLOT_DURATION);
|
||||
Arc::new(AuraVerifier {
|
||||
client,
|
||||
extra: NothingExtra,
|
||||
inherent_data_providers,
|
||||
phantom: Default::default(),
|
||||
allow_old_seals: false,
|
||||
})
|
||||
assert_eq!(slot_duration.get(), SLOT_DURATION);
|
||||
Arc::new(AuraVerifier {
|
||||
client,
|
||||
extra: NothingExtra,
|
||||
inherent_data_providers,
|
||||
phantom: Default::default(),
|
||||
allow_old_seals: false,
|
||||
})
|
||||
},
|
||||
PeersClient::Light(_) => unreachable!("No (yet) tests for light client + Aura"),
|
||||
}
|
||||
}
|
||||
|
||||
fn peer(&self, i: usize) -> &Peer<Self::PeerData, DummySpecialization> {
|
||||
@@ -917,7 +978,7 @@ mod tests {
|
||||
|
||||
let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
for (peer_id, key) in peers {
|
||||
let client = net.lock().peer(*peer_id).client().clone();
|
||||
let client = net.lock().peer(*peer_id).client().as_full().expect("full clients are created").clone();
|
||||
let select_chain = LongestChain::new(
|
||||
client.backend().clone(),
|
||||
client.import_lock().clone(),
|
||||
|
||||
Reference in New Issue
Block a user