mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
removes use of sc_client::Client from sc_finality_grandpa (#5030)
* removes use of sc_client::Client from sc_finality_grandpa * code formatting * code formatting * removes use of sc_client::Client from sc_finality_grandpa
This commit is contained in:
@@ -21,8 +21,9 @@ assert_matches = "1.3.0"
|
||||
parity-scale-codec = { version = "1.0.0", features = ["derive"] }
|
||||
sp-arithmetic = { version = "2.0.0-alpha.2", path = "../../primitives/arithmetic" }
|
||||
sp-runtime = { version = "2.0.0-alpha.2", path = "../../primitives/runtime" }
|
||||
sp-consensus = { version = "0.8.0-alpha.2", path = "../../primitives/consensus/common" }
|
||||
sp-consensus = { version = "0.8.0-alpha.1", path = "../../primitives/consensus/common" }
|
||||
sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" }
|
||||
sp-api = { version = "2.0.0-alpha.2", path = "../../primitives/api" }
|
||||
sc-telemetry = { version = "2.0.0-alpha.2", path = "../telemetry" }
|
||||
sc-keystore = { version = "2.0.0-alpha.2", path = "../keystore" }
|
||||
serde_json = "1.0.41"
|
||||
|
||||
@@ -25,18 +25,14 @@ use parity_scale_codec::{Decode, Encode};
|
||||
use futures::prelude::*;
|
||||
use futures_timer::Delay;
|
||||
use parking_lot::RwLock;
|
||||
use sp_blockchain::{HeaderBackend, Error as ClientError};
|
||||
use sp_blockchain::{HeaderBackend, Error as ClientError, HeaderMetadata};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use sc_client_api::{
|
||||
BlockchainEvents,
|
||||
backend::{AuxStore, Backend},
|
||||
Finalizer,
|
||||
call_executor::CallExecutor,
|
||||
backend::Backend,
|
||||
utils::is_descendent_of,
|
||||
};
|
||||
use sc_client::{
|
||||
apply_aux, Client,
|
||||
};
|
||||
use sc_client::apply_aux;
|
||||
use finality_grandpa::{
|
||||
BlockNumberOps, Equivocation, Error as GrandpaError, round::State as RoundState,
|
||||
voter, voter_set::VoterSet,
|
||||
@@ -377,8 +373,8 @@ impl<Block: BlockT> SharedVoterSetState<Block> {
|
||||
}
|
||||
|
||||
/// The environment we run GRANDPA in.
|
||||
pub(crate) struct Environment<B, E, Block: BlockT, N: NetworkT<Block>, RA, SC, VR> {
|
||||
pub(crate) client: Arc<Client<B, E, Block, RA>>,
|
||||
pub(crate) struct Environment<Backend, Block: BlockT, C, N: NetworkT<Block>, SC, VR> {
|
||||
pub(crate) client: Arc<C>,
|
||||
pub(crate) select_chain: SC,
|
||||
pub(crate) voters: Arc<VoterSet<AuthorityId>>,
|
||||
pub(crate) config: Config,
|
||||
@@ -388,9 +384,10 @@ pub(crate) struct Environment<B, E, Block: BlockT, N: NetworkT<Block>, RA, SC, V
|
||||
pub(crate) set_id: SetId,
|
||||
pub(crate) voter_set_state: SharedVoterSetState<Block>,
|
||||
pub(crate) voting_rule: VR,
|
||||
pub(crate) _phantom: PhantomData<Backend>,
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, N: NetworkT<Block>, RA, SC, VR> Environment<B, E, Block, N, RA, SC, VR> {
|
||||
impl<Backend, Block: BlockT, C, N: NetworkT<Block>, SC, VR> Environment<Backend, Block, C, N, SC, VR> {
|
||||
/// Updates the voter set state using the given closure. The write lock is
|
||||
/// held during evaluation of the closure and the environment's voter set
|
||||
/// state is set to its result if successful.
|
||||
@@ -406,17 +403,16 @@ impl<B, E, Block: BlockT, N: NetworkT<Block>, RA, SC, VR> Environment<B, E, Bloc
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT, B, E, N, RA, SC, VR>
|
||||
impl<BE, Block: BlockT, C, N, SC, VR>
|
||||
finality_grandpa::Chain<Block::Hash, NumberFor<Block>>
|
||||
for Environment<B, E, Block, N, RA, SC, VR>
|
||||
for Environment<BE, Block, C, N, SC, VR>
|
||||
where
|
||||
Block: 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
BE: Backend<Block>,
|
||||
C: crate::ClientForGrandpa<Block, BE>,
|
||||
N: NetworkT<Block> + 'static + Send,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>>,
|
||||
RA: Send + Sync,
|
||||
VR: VotingRule<Block, C>,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
{
|
||||
fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result<Vec<Block::Hash>, GrandpaError> {
|
||||
@@ -432,7 +428,7 @@ where
|
||||
return None;
|
||||
}
|
||||
|
||||
let base_header = match self.client.header(&BlockId::Hash(block)).ok()? {
|
||||
let base_header = match self.client.header(BlockId::Hash(block)).ok()? {
|
||||
Some(h) => h,
|
||||
None => {
|
||||
debug!(target: "afg", "Encountered error finding best chain containing {:?}: couldn't find base block", block);
|
||||
@@ -450,7 +446,7 @@ where
|
||||
|
||||
match self.select_chain.finality_target(block, None) {
|
||||
Ok(Some(best_hash)) => {
|
||||
let best_header = self.client.header(&BlockId::Hash(best_hash)).ok()?
|
||||
let best_header = self.client.header(BlockId::Hash(best_hash)).ok()?
|
||||
.expect("Header known to exist after `finality_target` call; qed");
|
||||
|
||||
// check if our vote is currently being limited due to a pending change
|
||||
@@ -474,7 +470,7 @@ where
|
||||
break;
|
||||
}
|
||||
|
||||
target_header = self.client.header(&BlockId::Hash(*target_header.parent_hash())).ok()?
|
||||
target_header = self.client.header(BlockId::Hash(*target_header.parent_hash())).ok()?
|
||||
.expect("Header known to exist after `finality_target` call; qed");
|
||||
}
|
||||
|
||||
@@ -519,17 +515,16 @@ where
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn ancestry<B, Block: BlockT, E, RA>(
|
||||
client: &Client<B, E, Block, RA>,
|
||||
pub(crate) fn ancestry<Block: BlockT, Client>(
|
||||
client: &Arc<Client>,
|
||||
base: Block::Hash,
|
||||
block: Block::Hash,
|
||||
) -> Result<Vec<Block::Hash>, GrandpaError> where
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block>,
|
||||
Client: HeaderMetadata<Block, Error = sp_blockchain::Error>,
|
||||
{
|
||||
if base == block { return Err(GrandpaError::NotDescendent) }
|
||||
|
||||
let tree_route_res = sp_blockchain::tree_route(client, block, base);
|
||||
let tree_route_res = sp_blockchain::tree_route(&**client, block, base);
|
||||
|
||||
let tree_route = match tree_route_res {
|
||||
Ok(tree_route) => tree_route,
|
||||
@@ -550,19 +545,17 @@ pub(crate) fn ancestry<B, Block: BlockT, E, RA>(
|
||||
Ok(tree_route.retracted().iter().skip(1).map(|e| e.hash).collect())
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, N, RA, SC, VR>
|
||||
impl<B, Block: BlockT, C, N, SC, VR>
|
||||
voter::Environment<Block::Hash, NumberFor<Block>>
|
||||
for Environment<B, E, Block, N, RA, SC, VR>
|
||||
for Environment<B, Block, C, N, SC, VR>
|
||||
where
|
||||
Block: 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Send + Sync,
|
||||
B: Backend<Block>,
|
||||
C: crate::ClientForGrandpa<Block, B> + 'static,
|
||||
N: NetworkT<Block> + 'static + Send,
|
||||
RA: 'static + Send + Sync,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>>,
|
||||
VR: VotingRule<Block, C>,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
{
|
||||
type Timer = Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send>>;
|
||||
type Id = AuthorityId;
|
||||
@@ -882,7 +875,7 @@ where
|
||||
commit: Commit<Block>,
|
||||
) -> Result<(), Self::Error> {
|
||||
finalize_block(
|
||||
&*self.client,
|
||||
self.client.clone(),
|
||||
&self.authority_set,
|
||||
&self.consensus_changes,
|
||||
Some(self.config.justification_period.into()),
|
||||
@@ -940,8 +933,8 @@ impl<Block: BlockT> From<GrandpaJustification<Block>> for JustificationOrCommit<
|
||||
/// authority set change is enacted then a justification is created (if not
|
||||
/// given) and stored with the block when finalizing it.
|
||||
/// This method assumes that the block being finalized has already been imported.
|
||||
pub(crate) fn finalize_block<B, Block: BlockT, E, RA>(
|
||||
client: &Client<B, E, Block, RA>,
|
||||
pub(crate) fn finalize_block<BE, Block, Client>(
|
||||
client: Arc<Client>,
|
||||
authority_set: &SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
consensus_changes: &SharedConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
justification_period: Option<NumberFor<Block>>,
|
||||
@@ -949,16 +942,16 @@ pub(crate) fn finalize_block<B, Block: BlockT, E, RA>(
|
||||
number: NumberFor<Block>,
|
||||
justification_or_commit: JustificationOrCommit<Block>,
|
||||
) -> Result<(), CommandOrError<Block::Hash, NumberFor<Block>>> where
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
Block: BlockT,
|
||||
BE: Backend<Block>,
|
||||
Client: crate::ClientForGrandpa<Block, BE>,
|
||||
{
|
||||
// NOTE: lock must be held through writing to DB to avoid race. this lock
|
||||
// also implicitly synchronizes the check for last finalized number
|
||||
// below.
|
||||
let mut authority_set = authority_set.inner().write();
|
||||
|
||||
let status = client.chain_info();
|
||||
let status = client.info();
|
||||
if number <= status.finalized_number && client.hash(number)? == Some(hash) {
|
||||
// This can happen after a forced change (triggered by the finality tracker when finality is stalled), since
|
||||
// the voter will be restarted at the median last finalized block, which can be lower than the local best
|
||||
@@ -981,14 +974,14 @@ pub(crate) fn finalize_block<B, Block: BlockT, E, RA>(
|
||||
let mut consensus_changes = consensus_changes.lock();
|
||||
let canon_at_height = |canon_number| {
|
||||
// "true" because the block is finalized
|
||||
canonical_at_height(client, (hash, number), true, canon_number)
|
||||
canonical_at_height(&*client, (hash, number), true, canon_number)
|
||||
};
|
||||
|
||||
let update_res: Result<_, Error> = client.lock_import_and_run(|import_op| {
|
||||
let status = authority_set.apply_standard_changes(
|
||||
hash,
|
||||
number,
|
||||
&is_descendent_of::<Block, _>(client, None),
|
||||
&is_descendent_of::<Block, _>(&*client, None),
|
||||
).map_err(|e| Error::Safety(e.to_string()))?;
|
||||
|
||||
// check if this is this is the first finalization of some consensus changes
|
||||
@@ -1031,7 +1024,7 @@ pub(crate) fn finalize_block<B, Block: BlockT, E, RA>(
|
||||
// finalization to remote nodes
|
||||
if !justification_required {
|
||||
if let Some(justification_period) = justification_period {
|
||||
let last_finalized_number = client.chain_info().finalized_number;
|
||||
let last_finalized_number = client.info().finalized_number;
|
||||
justification_required =
|
||||
(!last_finalized_number.is_zero() || number - last_finalized_number == justification_period) &&
|
||||
(last_finalized_number / justification_period != number / justification_period);
|
||||
@@ -1040,7 +1033,7 @@ pub(crate) fn finalize_block<B, Block: BlockT, E, RA>(
|
||||
|
||||
if justification_required {
|
||||
let justification = GrandpaJustification::from_commit(
|
||||
client,
|
||||
&client,
|
||||
round_number,
|
||||
commit,
|
||||
)?;
|
||||
|
||||
@@ -21,9 +21,10 @@ use parity_scale_codec::Encode;
|
||||
use futures::channel::mpsc;
|
||||
use parking_lot::RwLockWriteGuard;
|
||||
|
||||
use sp_blockchain::{HeaderBackend, BlockStatus, well_known_cache_keys};
|
||||
use sc_client_api::{backend::{TransactionFor, Backend}, CallExecutor, utils::is_descendent_of};
|
||||
use sc_client::Client;
|
||||
use sp_blockchain::{BlockStatus, well_known_cache_keys};
|
||||
use sc_client_api::{backend::Backend, utils::is_descendent_of};
|
||||
use sp_api::{TransactionFor};
|
||||
|
||||
use sp_consensus::{
|
||||
BlockImport, Error as ConsensusError,
|
||||
BlockCheckParams, BlockImportParams, ImportResult, JustificationImport,
|
||||
@@ -41,6 +42,7 @@ use crate::authorities::{AuthoritySet, SharedAuthoritySet, DelayKind, PendingCha
|
||||
use crate::consensus_changes::SharedConsensusChanges;
|
||||
use crate::environment::finalize_block;
|
||||
use crate::justification::GrandpaJustification;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// A block-import handler for GRANDPA.
|
||||
///
|
||||
@@ -51,16 +53,17 @@ use crate::justification::GrandpaJustification;
|
||||
///
|
||||
/// When using GRANDPA, the block import worker should be using this block import
|
||||
/// object.
|
||||
pub struct GrandpaBlockImport<B, E, Block: BlockT, RA, SC> {
|
||||
inner: Arc<Client<B, E, Block, RA>>,
|
||||
pub struct GrandpaBlockImport<Backend, Block: BlockT, Client, SC> {
|
||||
inner: Arc<Client>,
|
||||
select_chain: SC,
|
||||
authority_set: SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
send_voter_commands: mpsc::UnboundedSender<VoterCommand<Block::Hash, NumberFor<Block>>>,
|
||||
consensus_changes: SharedConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
_phantom: PhantomData<Backend>,
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA, SC: Clone> Clone for
|
||||
GrandpaBlockImport<B, E, Block, RA, SC>
|
||||
impl<Backend, Block: BlockT, Client, SC: Clone> Clone for
|
||||
GrandpaBlockImport<Backend, Block, Client, SC>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
GrandpaBlockImport {
|
||||
@@ -69,24 +72,24 @@ impl<B, E, Block: BlockT, RA, SC: Clone> Clone for
|
||||
authority_set: self.authority_set.clone(),
|
||||
send_voter_commands: self.send_voter_commands.clone(),
|
||||
consensus_changes: self.consensus_changes.clone(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA, SC> JustificationImport<Block>
|
||||
for GrandpaBlockImport<B, E, Block, RA, SC> where
|
||||
impl<BE, Block: BlockT, Client, SC> JustificationImport<Block>
|
||||
for GrandpaBlockImport<BE, Block, Client, SC> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
BE: Backend<Block>,
|
||||
Client: crate::ClientForGrandpa<Block, BE>,
|
||||
SC: SelectChain<Block>,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
|
||||
fn on_start(&mut self) -> Vec<(Block::Hash, NumberFor<Block>)> {
|
||||
let mut out = Vec::new();
|
||||
let chain_info = self.inner.chain_info();
|
||||
let chain_info = self.inner.info();
|
||||
|
||||
// request justifications for all pending changes for which change blocks have already been imported
|
||||
let authorities = self.authority_set.inner().read();
|
||||
@@ -105,7 +108,7 @@ impl<B, E, Block: BlockT, RA, SC> JustificationImport<Block>
|
||||
};
|
||||
|
||||
if let Ok(Some(hash)) = effective_block_hash {
|
||||
if let Ok(Some(header)) = self.inner.header(&BlockId::Hash(hash)) {
|
||||
if let Ok(Some(header)) = self.inner.header(BlockId::Hash(hash)) {
|
||||
if *header.number() == pending_change.effective_number() {
|
||||
out.push((header.hash(), *header.number()));
|
||||
}
|
||||
@@ -123,7 +126,7 @@ impl<B, E, Block: BlockT, RA, SC> JustificationImport<Block>
|
||||
number: NumberFor<Block>,
|
||||
justification: Justification,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.import_justification(hash, number, justification, false)
|
||||
GrandpaBlockImport::import_justification(self, hash, number, justification, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,14 +203,13 @@ fn find_forced_change<B: BlockT>(header: &B::Header)
|
||||
header.digest().convert_first(|l| l.try_to(id).and_then(filter_log))
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA, SC>
|
||||
GrandpaBlockImport<B, E, Block, RA, SC>
|
||||
impl<BE, Block: BlockT, Client, SC>
|
||||
GrandpaBlockImport<BE, Block, Client, SC>
|
||||
where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
BE: Backend<Block>,
|
||||
Client: crate::ClientForGrandpa<Block, BE>,
|
||||
{
|
||||
// check for a new authority set change.
|
||||
fn check_new_change(&self, header: &Block::Header, hash: Block::Hash)
|
||||
@@ -235,11 +237,11 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn make_authorities_changes<'a>(
|
||||
&'a self,
|
||||
block: &mut BlockImportParams<Block, TransactionFor<B, Block>>,
|
||||
fn make_authorities_changes(
|
||||
&self,
|
||||
block: &mut BlockImportParams<Block, TransactionFor<Client, Block>>,
|
||||
hash: Block::Hash,
|
||||
) -> Result<PendingSetChanges<'a, Block>, ConsensusError> {
|
||||
) -> Result<PendingSetChanges<Block>, ConsensusError> {
|
||||
// when we update the authorities, we need to hold the lock
|
||||
// until the block is written to prevent a race if we need to restore
|
||||
// the old authority set on error or panic.
|
||||
@@ -325,10 +327,10 @@ where
|
||||
// for the canon block the new authority set should start
|
||||
// with. we use the minimum between the median and the local
|
||||
// best finalized block.
|
||||
let best_finalized_number = self.inner.chain_info().finalized_number;
|
||||
let best_finalized_number = self.inner.info().finalized_number;
|
||||
let canon_number = best_finalized_number.min(median_last_finalized_number);
|
||||
let canon_hash =
|
||||
self.inner.header(&BlockId::Number(canon_number))
|
||||
self.inner.header(BlockId::Number(canon_number))
|
||||
.map_err(|e| ConsensusError::ClientImport(e.to_string()))?
|
||||
.expect("the given block number is less or equal than the current best finalized number; \
|
||||
current best finalized number must exist in chain; qed.")
|
||||
@@ -380,18 +382,17 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA, SC> BlockImport<Block>
|
||||
for GrandpaBlockImport<B, E, Block, RA, SC> where
|
||||
impl<BE, Block: BlockT, Client, SC> BlockImport<Block>
|
||||
for GrandpaBlockImport<BE, Block, Client, SC> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
for<'a> &'a Client<B, E, Block, RA>:
|
||||
BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<B, Block>>,
|
||||
BE: Backend<Block>,
|
||||
Client: crate::ClientForGrandpa<Block, BE>,
|
||||
for<'a> &'a Client:
|
||||
BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<Client, Block>>,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = TransactionFor<B, Block>;
|
||||
type Transaction = TransactionFor<Client, Block>;
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
@@ -521,31 +522,31 @@ impl<B, E, Block: BlockT, RA, SC> BlockImport<Block>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA, SC> GrandpaBlockImport<B, E, Block, RA, SC> {
|
||||
impl<Backend, Block: BlockT, Client, SC> GrandpaBlockImport<Backend, Block, Client, SC> {
|
||||
pub(crate) fn new(
|
||||
inner: Arc<Client<B, E, Block, RA>>,
|
||||
inner: Arc<Client>,
|
||||
select_chain: SC,
|
||||
authority_set: SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
send_voter_commands: mpsc::UnboundedSender<VoterCommand<Block::Hash, NumberFor<Block>>>,
|
||||
consensus_changes: SharedConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
) -> GrandpaBlockImport<B, E, Block, RA, SC> {
|
||||
) -> GrandpaBlockImport<Backend, Block, Client, SC> {
|
||||
GrandpaBlockImport {
|
||||
inner,
|
||||
select_chain,
|
||||
authority_set,
|
||||
send_voter_commands,
|
||||
consensus_changes,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA, SC>
|
||||
GrandpaBlockImport<B, E, Block, RA, SC>
|
||||
impl<BE, Block: BlockT, Client, SC>
|
||||
GrandpaBlockImport<BE, Block, Client, SC>
|
||||
where
|
||||
BE: Backend<Block>,
|
||||
Client: crate::ClientForGrandpa<Block, BE>,
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
|
||||
/// Import a block justification and finalize the block.
|
||||
@@ -572,7 +573,7 @@ where
|
||||
};
|
||||
|
||||
let result = finalize_block(
|
||||
&*self.inner,
|
||||
self.inner.clone(),
|
||||
&self.authority_set,
|
||||
&self.consensus_changes,
|
||||
None,
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
|
||||
use sc_client::Client;
|
||||
use sc_client_api::{CallExecutor, backend::Backend};
|
||||
use sp_blockchain::Error as ClientError;
|
||||
use sp_blockchain::{Error as ClientError, HeaderBackend};
|
||||
use parity_scale_codec::{Encode, Decode};
|
||||
use finality_grandpa::voter_set::VoterSet;
|
||||
use finality_grandpa::{Error as GrandpaError};
|
||||
@@ -47,14 +46,12 @@ pub struct GrandpaJustification<Block: BlockT> {
|
||||
impl<Block: BlockT> GrandpaJustification<Block> {
|
||||
/// Create a GRANDPA justification from the given commit. This method
|
||||
/// assumes the commit is valid and well-formed.
|
||||
pub(crate) fn from_commit<B, E, RA>(
|
||||
client: &Client<B, E, Block, RA>,
|
||||
pub(crate) fn from_commit<C>(
|
||||
client: &Arc<C>,
|
||||
round: u64,
|
||||
commit: Commit<Block>,
|
||||
) -> Result<GrandpaJustification<Block>, Error> where
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
C: HeaderBackend<Block>,
|
||||
{
|
||||
let mut votes_ancestries_hashes = HashSet::new();
|
||||
let mut votes_ancestries = Vec::new();
|
||||
@@ -69,7 +66,7 @@ impl<Block: BlockT> GrandpaJustification<Block> {
|
||||
loop {
|
||||
if current_hash == commit.target_hash { break; }
|
||||
|
||||
match client.header(&BlockId::Hash(current_hash))? {
|
||||
match client.header(BlockId::Hash(current_hash))? {
|
||||
Some(current_header) => {
|
||||
if *current_header.number() <= commit.target_number {
|
||||
return error();
|
||||
|
||||
@@ -56,15 +56,18 @@ use futures::prelude::*;
|
||||
use futures::StreamExt;
|
||||
use log::{debug, info};
|
||||
use futures::channel::mpsc;
|
||||
use sc_client_api::{BlockchainEvents, CallExecutor, backend::{AuxStore, Backend}, ExecutionStrategy};
|
||||
use sp_blockchain::{HeaderBackend, Error as ClientError};
|
||||
use sc_client_api::{
|
||||
LockImportRun, BlockchainEvents, CallExecutor,
|
||||
backend::{AuxStore, Backend}, ExecutionStrategy, Finalizer, TransactionFor,
|
||||
};
|
||||
use sp_blockchain::{HeaderBackend, Error as ClientError, HeaderMetadata};
|
||||
use sc_client::Client;
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_runtime::traits::{NumberFor, Block as BlockT, DigestFor, Zero};
|
||||
use sc_keystore::KeyStorePtr;
|
||||
use sp_inherents::InherentDataProviders;
|
||||
use sp_consensus::SelectChain;
|
||||
use sp_consensus::{SelectChain, BlockImport};
|
||||
use sp_core::Pair;
|
||||
use sc_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG};
|
||||
use serde_json;
|
||||
@@ -109,6 +112,8 @@ use sp_finality_grandpa::{AuthorityList, AuthorityPair, AuthoritySignature, SetI
|
||||
|
||||
// Re-export these two because it's just so damn convenient.
|
||||
pub use sp_finality_grandpa::{AuthorityId, ScheduledChange};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@@ -245,10 +250,8 @@ pub(crate) trait BlockStatus<Block: BlockT> {
|
||||
fn block_number(&self, hash: Block::Hash) -> Result<Option<NumberFor<Block>>, Error>;
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA> BlockStatus<Block> for Arc<Client<B, E, Block, RA>> where
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
impl<Block: BlockT, Client> BlockStatus<Block> for Arc<Client> where
|
||||
Client: HeaderBackend<Block>,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
{
|
||||
fn block_number(&self, hash: Block::Hash) -> Result<Option<NumberFor<Block>>, Error> {
|
||||
@@ -257,6 +260,29 @@ impl<B, E, Block: BlockT, RA> BlockStatus<Block> for Arc<Client<B, E, Block, RA>
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait that includes all the client functionalities grandpa requires.
|
||||
/// Ideally this would be a trait alias, we're not there yet.
|
||||
/// tracking issue https://github.com/rust-lang/rust/issues/41517
|
||||
pub trait ClientForGrandpa<Block, BE>:
|
||||
LockImportRun<Block, BE> + Finalizer<Block, BE> + AuxStore
|
||||
+ HeaderMetadata<Block, Error = sp_blockchain::Error> + HeaderBackend<Block>
|
||||
+ BlockchainEvents<Block> + ProvideRuntimeApi<Block>
|
||||
+ BlockImport<Block, Transaction = TransactionFor<BE, Block>, Error = sp_consensus::Error>
|
||||
where
|
||||
BE: Backend<Block>,
|
||||
Block: BlockT,
|
||||
{}
|
||||
|
||||
impl<Block, BE, T> ClientForGrandpa<Block, BE> for T
|
||||
where
|
||||
BE: Backend<Block>,
|
||||
Block: BlockT,
|
||||
T: LockImportRun<Block, BE> + Finalizer<Block, BE> + AuxStore
|
||||
+ HeaderMetadata<Block, Error = sp_blockchain::Error> + HeaderBackend<Block>
|
||||
+ BlockchainEvents<Block> + ProvideRuntimeApi<Block>
|
||||
+ BlockImport<Block, Transaction = TransactionFor<BE, Block>, Error = sp_consensus::Error>,
|
||||
{}
|
||||
|
||||
/// Something that one can ask to do a block sync request.
|
||||
pub(crate) trait BlockSyncRequester<Block: BlockT> {
|
||||
/// Notifies the sync service to try and sync the given block from the given
|
||||
@@ -348,8 +374,8 @@ impl<H, N> fmt::Display for CommandOrError<H, N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LinkHalf<B, E, Block: BlockT, RA, SC> {
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
pub struct LinkHalf<Block: BlockT, C, SC> {
|
||||
client: Arc<C>,
|
||||
select_chain: SC,
|
||||
persistent_data: PersistentData<Block>,
|
||||
voter_commands_rx: mpsc::UnboundedReceiver<VoterCommand<Block::Hash, NumberFor<Block>>>,
|
||||
@@ -390,22 +416,20 @@ impl<B, E, Block: BlockT, RA> GenesisAuthoritySetProvider<Block> for Client<B, E
|
||||
|
||||
/// Make block importer and link half necessary to tie the background voter
|
||||
/// to it.
|
||||
pub fn block_import<B, E, Block: BlockT, RA, SC>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
pub fn block_import<BE, Block: BlockT, Client, SC>(
|
||||
client: Arc<Client>,
|
||||
genesis_authorities_provider: &dyn GenesisAuthoritySetProvider<Block>,
|
||||
select_chain: SC,
|
||||
) -> Result<(
|
||||
GrandpaBlockImport<B, E, Block, RA, SC>,
|
||||
LinkHalf<B, E, Block, RA, SC>
|
||||
GrandpaBlockImport<BE, Block, Client, SC>,
|
||||
LinkHalf<Block, Client, SC>,
|
||||
), ClientError>
|
||||
where
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
SC: SelectChain<Block>,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
BE: Backend<Block> + 'static,
|
||||
Client: ClientForGrandpa<Block, BE> + 'static,
|
||||
{
|
||||
let chain_info = client.chain_info();
|
||||
let chain_info = client.info();
|
||||
let genesis_hash = chain_info.genesis_hash;
|
||||
|
||||
let persistent_data = aux_schema::load_persistent(
|
||||
@@ -440,10 +464,10 @@ where
|
||||
))
|
||||
}
|
||||
|
||||
fn global_communication<Block: BlockT, B, E, N, RA>(
|
||||
fn global_communication<BE, Block: BlockT, C, N>(
|
||||
set_id: SetId,
|
||||
voters: &Arc<VoterSet<AuthorityId>>,
|
||||
client: &Arc<Client<B, E, Block, RA>>,
|
||||
client: Arc<C>,
|
||||
network: &NetworkBridge<Block, N>,
|
||||
keystore: &Option<KeyStorePtr>,
|
||||
) -> (
|
||||
@@ -455,10 +479,9 @@ fn global_communication<Block: BlockT, B, E, N, RA>(
|
||||
Error = CommandOrError<Block::Hash, NumberFor<Block>>,
|
||||
> + Unpin,
|
||||
) where
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
BE: Backend<Block> + 'static,
|
||||
C: ClientForGrandpa<Block, BE> + 'static,
|
||||
N: NetworkT<Block>,
|
||||
RA: Send + Sync,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
{
|
||||
let is_voter = is_voter(voters, keystore).is_some();
|
||||
@@ -487,20 +510,18 @@ fn global_communication<Block: BlockT, B, E, N, RA>(
|
||||
|
||||
/// Register the finality tracker inherent data provider (which is used by
|
||||
/// GRANDPA), if not registered already.
|
||||
fn register_finality_tracker_inherent_data_provider<B, E, Block: BlockT, RA>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
fn register_finality_tracker_inherent_data_provider<Block: BlockT, Client>(
|
||||
client: Arc<Client>,
|
||||
inherent_data_providers: &InherentDataProviders,
|
||||
) -> Result<(), sp_consensus::Error> where
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
RA: Send + Sync + 'static,
|
||||
Client: HeaderBackend<Block> + 'static,
|
||||
{
|
||||
if !inherent_data_providers.has_provider(&sp_finality_tracker::INHERENT_IDENTIFIER) {
|
||||
inherent_data_providers
|
||||
.register_provider(sp_finality_tracker::InherentDataProvider::new(move || {
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
let info = client.chain_info();
|
||||
let info = client.info();
|
||||
telemetry!(CONSENSUS_INFO; "afg.finalized";
|
||||
"finalized_number" => ?info.finalized_number,
|
||||
"finalized_hash" => ?info.finalized_hash,
|
||||
@@ -515,11 +536,11 @@ fn register_finality_tracker_inherent_data_provider<B, E, Block: BlockT, RA>(
|
||||
}
|
||||
|
||||
/// Parameters used to run Grandpa.
|
||||
pub struct GrandpaParams<B, E, Block: BlockT, N, RA, SC, VR, X> {
|
||||
pub struct GrandpaParams<Block: BlockT, C, N, SC, VR, X> {
|
||||
/// Configuration for the GRANDPA service.
|
||||
pub config: Config,
|
||||
/// A link to the block import worker.
|
||||
pub link: LinkHalf<B, E, Block, RA, SC>,
|
||||
pub link: LinkHalf<Block, C, SC>,
|
||||
/// The Network instance.
|
||||
pub network: N,
|
||||
/// The inherent data providers.
|
||||
@@ -534,20 +555,18 @@ pub struct GrandpaParams<B, E, Block: BlockT, N, RA, SC, VR, X> {
|
||||
|
||||
/// Run a GRANDPA voter as a task. Provide configuration and a link to a
|
||||
/// block import worker that has already been instantiated with `block_import`.
|
||||
pub fn run_grandpa_voter<B, E, Block: BlockT, N, RA, SC, VR, X>(
|
||||
grandpa_params: GrandpaParams<B, E, Block, N, RA, SC, VR, X>,
|
||||
pub fn run_grandpa_voter<Block: BlockT, BE: 'static, C, N, SC, VR, X>(
|
||||
grandpa_params: GrandpaParams<Block, C, N, SC, VR, X>,
|
||||
) -> sp_blockchain::Result<impl Future<Output = ()> + Unpin + Send + 'static> where
|
||||
Block::Hash: Ord,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
BE: Backend<Block> + 'static,
|
||||
N: NetworkT<Block> + Send + Sync + Clone + 'static,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>> + Clone + 'static,
|
||||
VR: VotingRule<Block, C> + Clone + 'static,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync + 'static,
|
||||
X: futures::Future<Output=()> + Clone + Send + Unpin + 'static,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
C: ClientForGrandpa<Block, BE> + 'static,
|
||||
{
|
||||
let GrandpaParams {
|
||||
mut config,
|
||||
@@ -629,27 +648,25 @@ pub fn run_grandpa_voter<B, E, Block: BlockT, N, RA, SC, VR, X>(
|
||||
|
||||
/// Future that powers the voter.
|
||||
#[must_use]
|
||||
struct VoterWork<B, E, Block: BlockT, N: NetworkT<Block>, RA, SC, VR> {
|
||||
struct VoterWork<B, Block: BlockT, C, N: NetworkT<Block>, SC, VR> {
|
||||
voter: Pin<Box<dyn Future<Output = Result<(), CommandOrError<Block::Hash, NumberFor<Block>>>> + Send>>,
|
||||
env: Arc<Environment<B, E, Block, N, RA, SC, VR>>,
|
||||
env: Arc<Environment<B, Block, C, N, SC, VR>>,
|
||||
voter_commands_rx: mpsc::UnboundedReceiver<VoterCommand<Block::Hash, NumberFor<Block>>>,
|
||||
network: NetworkBridge<Block, N>,
|
||||
}
|
||||
|
||||
impl<B, E, Block, N, RA, SC, VR> VoterWork<B, E, Block, N, RA, SC, VR>
|
||||
impl<B, Block, C, N, SC, VR> VoterWork<B, Block, C, N, SC, VR>
|
||||
where
|
||||
Block: BlockT,
|
||||
B: Backend<Block> + 'static,
|
||||
C: ClientForGrandpa<Block, B> + 'static,
|
||||
N: NetworkT<Block> + Sync,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
RA: 'static + Send + Sync,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>> + Clone + 'static,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
VR: VotingRule<Block, C> + Clone + 'static,
|
||||
{
|
||||
fn new(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
client: Arc<C>,
|
||||
config: Config,
|
||||
network: NetworkBridge<Block, N>,
|
||||
select_chain: SC,
|
||||
@@ -670,6 +687,7 @@ where
|
||||
authority_set: persistent_data.authority_set.clone(),
|
||||
consensus_changes: persistent_data.consensus_changes.clone(),
|
||||
voter_set_state: persistent_data.set_state.clone(),
|
||||
_phantom: PhantomData,
|
||||
});
|
||||
|
||||
let mut work = VoterWork {
|
||||
@@ -700,7 +718,7 @@ where
|
||||
"authority_id" => authority_id.to_string(),
|
||||
);
|
||||
|
||||
let chain_info = self.env.client.chain_info();
|
||||
let chain_info = self.env.client.info();
|
||||
telemetry!(CONSENSUS_INFO; "afg.authority_set";
|
||||
"number" => ?chain_info.finalized_number,
|
||||
"hash" => ?chain_info.finalized_hash,
|
||||
@@ -724,7 +742,7 @@ where
|
||||
let global_comms = global_communication(
|
||||
self.env.set_id,
|
||||
&self.env.voters,
|
||||
&self.env.client,
|
||||
self.env.client.clone(),
|
||||
&self.env.network,
|
||||
&self.env.config.keystore,
|
||||
);
|
||||
@@ -789,6 +807,7 @@ where
|
||||
consensus_changes: self.env.consensus_changes.clone(),
|
||||
network: self.env.network.clone(),
|
||||
voting_rule: self.env.voting_rule.clone(),
|
||||
_phantom: PhantomData,
|
||||
});
|
||||
|
||||
self.rebuild_voter();
|
||||
@@ -813,17 +832,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block, N, RA, SC, VR> Future for VoterWork<B, E, Block, N, RA, SC, VR>
|
||||
impl<B, Block, C, N, SC, VR> Future for VoterWork<B, Block, C, N, SC, VR>
|
||||
where
|
||||
Block: BlockT,
|
||||
B: Backend<Block> + 'static,
|
||||
N: NetworkT<Block> + Sync,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
RA: 'static + Send + Sync,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>> + Clone + 'static,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
C: ClientForGrandpa<Block, B> + 'static,
|
||||
VR: VotingRule<Block, C> + Clone + 'static,
|
||||
{
|
||||
type Output = Result<(), Error>;
|
||||
|
||||
@@ -868,15 +885,13 @@ where
|
||||
/// discards all GRANDPA messages (otherwise, we end up banning nodes that send
|
||||
/// us a `Neighbor` message, since there is no registered gossip validator for
|
||||
/// the engine id defined in the message.)
|
||||
pub fn setup_disabled_grandpa<B, E, Block: BlockT, RA, N>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
pub fn setup_disabled_grandpa<Block: BlockT, Client, N>(
|
||||
client: Arc<Client>,
|
||||
inherent_data_providers: &InherentDataProviders,
|
||||
network: N,
|
||||
) -> Result<(), sp_consensus::Error> where
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
RA: Send + Sync + 'static,
|
||||
N: NetworkT<Block> + Send + Clone + 'static,
|
||||
Client: HeaderBackend<Block> + 'static,
|
||||
{
|
||||
register_finality_tracker_inherent_data_provider(
|
||||
client,
|
||||
|
||||
@@ -18,8 +18,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use log::{info, trace, warn};
|
||||
use parking_lot::RwLock;
|
||||
use sc_client::Client;
|
||||
use sc_client_api::{CallExecutor, backend::{AuxStore, Backend, Finalizer, TransactionFor}};
|
||||
use sc_client_api::backend::{AuxStore, Backend, Finalizer, TransactionFor};
|
||||
use sp_blockchain::{HeaderBackend, Error as ClientError, well_known_cache_keys};
|
||||
use parity_scale_codec::{Encode, Decode};
|
||||
use sp_consensus::{
|
||||
@@ -48,17 +47,15 @@ const LIGHT_AUTHORITY_SET_KEY: &[u8] = b"grandpa_voters";
|
||||
const LIGHT_CONSENSUS_CHANGES_KEY: &[u8] = b"grandpa_consensus_changes";
|
||||
|
||||
/// Create light block importer.
|
||||
pub fn light_block_import<B, E, Block: BlockT, RA>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
backend: Arc<B>,
|
||||
pub fn light_block_import<BE, Block: BlockT, Client>(
|
||||
client: Arc<Client>,
|
||||
backend: Arc<BE>,
|
||||
genesis_authorities_provider: &dyn GenesisAuthoritySetProvider<Block>,
|
||||
authority_set_provider: Arc<dyn AuthoritySetForFinalityChecker<Block>>,
|
||||
) -> Result<GrandpaLightBlockImport<B, E, Block, RA>, ClientError>
|
||||
) -> Result<GrandpaLightBlockImport<BE, Block, Client>, ClientError>
|
||||
where
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
BE: Backend<Block>,
|
||||
Client: crate::ClientForGrandpa<Block, BE>,
|
||||
{
|
||||
let info = client.info();
|
||||
let import_data = load_aux_import_data(
|
||||
@@ -79,14 +76,14 @@ pub fn light_block_import<B, E, Block: BlockT, RA>(
|
||||
/// It is responsible for:
|
||||
/// - checking GRANDPA justifications;
|
||||
/// - fetching finality proofs for blocks that are enacting consensus changes.
|
||||
pub struct GrandpaLightBlockImport<B, E, Block: BlockT, RA> {
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
backend: Arc<B>,
|
||||
pub struct GrandpaLightBlockImport<BE, Block: BlockT, Client> {
|
||||
client: Arc<Client>,
|
||||
backend: Arc<BE>,
|
||||
authority_set_provider: Arc<dyn AuthoritySetForFinalityChecker<Block>>,
|
||||
data: Arc<RwLock<LightImportData<Block>>>,
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA> Clone for GrandpaLightBlockImport<B, E, Block, RA> {
|
||||
impl<BE, Block: BlockT, Client> Clone for GrandpaLightBlockImport<BE, Block, Client> {
|
||||
fn clone(&self) -> Self {
|
||||
GrandpaLightBlockImport {
|
||||
client: self.client.clone(),
|
||||
@@ -111,27 +108,26 @@ struct LightAuthoritySet {
|
||||
authorities: AuthorityList,
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA> GrandpaLightBlockImport<B, E, Block, RA> {
|
||||
impl<BE, Block: BlockT, Client> GrandpaLightBlockImport<BE, Block, Client> {
|
||||
/// Create finality proof request builder.
|
||||
pub fn create_finality_proof_request_builder(&self) -> BoxFinalityProofRequestBuilder<Block> {
|
||||
Box::new(GrandpaFinalityProofRequestBuilder(self.data.clone())) as _
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA> BlockImport<Block>
|
||||
for GrandpaLightBlockImport<B, E, Block, RA> where
|
||||
impl<BE, Block: BlockT, Client> BlockImport<Block>
|
||||
for GrandpaLightBlockImport<BE, Block, Client> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
for<'a> &'a Client<B, E, Block, RA>:
|
||||
BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<B, Block>>
|
||||
+ Finalizer<Block, B>
|
||||
BE: Backend<Block> + 'static,
|
||||
for<'a> &'a Client:
|
||||
HeaderBackend<Block>
|
||||
+ BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<BE, Block>>
|
||||
+ Finalizer<Block, BE>
|
||||
+ AuxStore,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = TransactionFor<B, Block>;
|
||||
type Transaction = TransactionFor<BE, Block>;
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
@@ -151,23 +147,22 @@ impl<B, E, Block: BlockT, RA> BlockImport<Block>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA> FinalityProofImport<Block>
|
||||
for GrandpaLightBlockImport<B, E, Block, RA> where
|
||||
impl<BE, Block: BlockT, Client> FinalityProofImport<Block>
|
||||
for GrandpaLightBlockImport<BE, Block, Client> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
for<'a> &'a Client<B, E, Block, RA>:
|
||||
BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<B, Block>>
|
||||
+ Finalizer<Block, B>
|
||||
BE: Backend<Block> + 'static,
|
||||
for<'a> &'a Client:
|
||||
HeaderBackend<Block>
|
||||
+ BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<BE, Block>>
|
||||
+ Finalizer<Block, BE>
|
||||
+ AuxStore,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
|
||||
fn on_start(&mut self) -> Vec<(Block::Hash, NumberFor<Block>)> {
|
||||
let mut out = Vec::new();
|
||||
let chain_info = self.client.chain_info();
|
||||
let chain_info = (&*self.client).info();
|
||||
|
||||
let data = self.data.read();
|
||||
for (pending_number, pending_hash) in data.consensus_changes.pending_changes() {
|
||||
@@ -567,7 +562,7 @@ fn on_post_finalization_error(error: ClientError, value_type: &str) -> Consensus
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
use sp_consensus::ForkChoiceStrategy;
|
||||
use sp_consensus::{ForkChoiceStrategy, BlockImport};
|
||||
use sp_finality_grandpa::AuthorityId;
|
||||
use sp_core::{H256, crypto::Public};
|
||||
use substrate_test_runtime_client::sc_client::in_mem::Blockchain as InMemoryAuxStore;
|
||||
@@ -575,37 +570,36 @@ pub mod tests {
|
||||
use crate::tests::TestApi;
|
||||
use crate::finality_proof::tests::TestJustification;
|
||||
|
||||
pub struct NoJustificationsImport<B, E, Block: BlockT, RA>(
|
||||
pub GrandpaLightBlockImport<B, E, Block, RA>
|
||||
pub struct NoJustificationsImport<BE, Block: BlockT, Client>(
|
||||
pub GrandpaLightBlockImport<BE, Block, Client>
|
||||
);
|
||||
|
||||
impl<B, E, Block: BlockT, RA> Clone
|
||||
for NoJustificationsImport<B, E, Block, RA> where
|
||||
impl<BE, Block: BlockT, Client> Clone
|
||||
for NoJustificationsImport<BE, Block, Client> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
BE: Backend<Block> + 'static,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
NoJustificationsImport(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA> BlockImport<Block>
|
||||
for NoJustificationsImport<B, E, Block, RA> where
|
||||
impl<BE, Block: BlockT, Client> BlockImport<Block>
|
||||
for NoJustificationsImport<BE, Block, Client> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
for<'a> &'a Client<B, E, Block, RA>:
|
||||
BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<B, Block>>
|
||||
+ Finalizer<Block, B>
|
||||
BE: Backend<Block> + 'static,
|
||||
for <'a > &'a Client:
|
||||
HeaderBackend<Block>
|
||||
+ BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<BE, Block>>
|
||||
+ Finalizer<Block, BE>
|
||||
+ AuxStore,
|
||||
GrandpaLightBlockImport<BE, Block, Client>:
|
||||
BlockImport<Block, Transaction = TransactionFor<BE, Block>, Error = ConsensusError>
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = TransactionFor<B, Block>;
|
||||
type Transaction = TransactionFor<BE, Block>;
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
@@ -624,16 +618,15 @@ pub mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT, RA> FinalityProofImport<Block>
|
||||
for NoJustificationsImport<B, E, Block, RA> where
|
||||
impl<BE, Block: BlockT, Client> FinalityProofImport<Block>
|
||||
for NoJustificationsImport<BE, Block, Client> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
BE: Backend<Block> + 'static,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
for<'a> &'a Client<B, E, Block, RA>:
|
||||
BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<B, Block>>
|
||||
+ Finalizer<Block, B>
|
||||
for <'a > &'a Client:
|
||||
HeaderBackend<Block>
|
||||
+ BlockImport<Block, Error = ConsensusError, Transaction = TransactionFor<BE, Block>>
|
||||
+ Finalizer<Block, BE>
|
||||
+ AuxStore,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
@@ -654,19 +647,15 @@ pub mod tests {
|
||||
}
|
||||
|
||||
/// Creates light block import that ignores justifications that came outside of finality proofs.
|
||||
pub fn light_block_import_without_justifications<B, E, Block: BlockT, RA>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
backend: Arc<B>,
|
||||
pub fn light_block_import_without_justifications<BE, Block: BlockT, Client>(
|
||||
client: Arc<Client>,
|
||||
backend: Arc<BE>,
|
||||
genesis_authorities_provider: &dyn GenesisAuthoritySetProvider<Block>,
|
||||
authority_set_provider: Arc<dyn AuthoritySetForFinalityChecker<Block>>,
|
||||
) -> Result<NoJustificationsImport<B, E, Block, RA>, ClientError>
|
||||
) -> Result<NoJustificationsImport<BE, Block, Client>, ClientError>
|
||||
where
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
Client<B, E, Block, RA>: BlockImport<Block, Error = ConsensusError>
|
||||
+ Finalizer<Block, B>
|
||||
+ AuxStore,
|
||||
BE: Backend<Block> + 'static,
|
||||
Client: crate::ClientForGrandpa<Block, BE>,
|
||||
{
|
||||
light_block_import(client, backend, genesis_authorities_provider, authority_set_provider)
|
||||
.map(NoJustificationsImport)
|
||||
@@ -677,6 +666,7 @@ pub mod tests {
|
||||
justification: Option<Justification>,
|
||||
) -> ImportResult {
|
||||
let (client, _backend) = substrate_test_runtime_client::new_light();
|
||||
let client = Arc::new(client);
|
||||
let mut import_data = LightImportData {
|
||||
last_finalized: Default::default(),
|
||||
authority_set: LightAuthoritySet::genesis(vec![(AuthorityId::from_slice(&[1; 32]), 1)]),
|
||||
@@ -696,7 +686,7 @@ pub mod tests {
|
||||
block.fork_choice = Some(ForkChoiceStrategy::LongestChain);
|
||||
|
||||
do_import_block::<_, _, _, TestJustification>(
|
||||
&client,
|
||||
&*client,
|
||||
&mut import_data,
|
||||
block,
|
||||
new_cache,
|
||||
|
||||
@@ -26,10 +26,9 @@ use finality_grandpa::{
|
||||
use log::{debug, info, warn};
|
||||
|
||||
use sp_consensus::SelectChain;
|
||||
use sc_client_api::{CallExecutor, backend::{Backend, AuxStore}};
|
||||
use sc_client::Client;
|
||||
use sc_client_api::backend::Backend;
|
||||
use sp_runtime::traits::{NumberFor, Block as BlockT};
|
||||
|
||||
use sp_blockchain::HeaderMetadata;
|
||||
use crate::{
|
||||
global_communication, CommandOrError, CommunicationIn, Config, environment,
|
||||
LinkHalf, Error, aux_schema::PersistentData, VoterCommand, VoterSetState,
|
||||
@@ -38,17 +37,21 @@ use crate::authorities::SharedAuthoritySet;
|
||||
use crate::communication::{Network as NetworkT, NetworkBridge};
|
||||
use crate::consensus_changes::SharedConsensusChanges;
|
||||
use sp_finality_grandpa::AuthorityId;
|
||||
use std::marker::{PhantomData, Unpin};
|
||||
|
||||
struct ObserverChain<'a, Block: BlockT, B, E, RA>(&'a Client<B, E, Block, RA>);
|
||||
struct ObserverChain<'a, Block: BlockT, Client> {
|
||||
client: &'a Arc<Client>,
|
||||
_phantom: PhantomData<Block>,
|
||||
}
|
||||
|
||||
impl<'a, Block: BlockT, B, E, RA> finality_grandpa::Chain<Block::Hash, NumberFor<Block>>
|
||||
for ObserverChain<'a, Block, B, E, RA> where
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block>,
|
||||
impl<'a, Block, Client> finality_grandpa::Chain<Block::Hash, NumberFor<Block>>
|
||||
for ObserverChain<'a, Block, Client> where
|
||||
Block: BlockT,
|
||||
Client: HeaderMetadata<Block, Error = sp_blockchain::Error>,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
{
|
||||
fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result<Vec<Block::Hash>, GrandpaError> {
|
||||
environment::ancestry(&self.0, base, block)
|
||||
environment::ancestry(&self.client, base, block)
|
||||
}
|
||||
|
||||
fn best_chain_containing(&self, _block: Block::Hash) -> Option<(Block::Hash, NumberFor<Block>)> {
|
||||
@@ -57,8 +60,8 @@ impl<'a, Block: BlockT, B, E, RA> finality_grandpa::Chain<Block::Hash, NumberFor
|
||||
}
|
||||
}
|
||||
|
||||
fn grandpa_observer<B, E, Block: BlockT, RA, S, F>(
|
||||
client: &Arc<Client<B, E, Block, RA>>,
|
||||
fn grandpa_observer<BE, Block: BlockT, Client, S, F>(
|
||||
client: &Arc<Client>,
|
||||
authority_set: &SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
consensus_changes: &SharedConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
voters: &Arc<VoterSet<AuthorityId>>,
|
||||
@@ -67,13 +70,12 @@ fn grandpa_observer<B, E, Block: BlockT, RA, S, F>(
|
||||
note_round: F,
|
||||
) -> impl Future<Output=Result<(), CommandOrError<Block::Hash, NumberFor<Block>>>> where
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
RA: Send + Sync,
|
||||
S: Stream<
|
||||
Item = Result<CommunicationIn<Block>, CommandOrError<Block::Hash, NumberFor<Block>>>,
|
||||
>,
|
||||
F: Fn(u64),
|
||||
BE: Backend<Block>,
|
||||
Client: crate::ClientForGrandpa<Block, BE>,
|
||||
{
|
||||
let authority_set = authority_set.clone();
|
||||
let consensus_changes = consensus_changes.clone();
|
||||
@@ -101,7 +103,7 @@ fn grandpa_observer<B, E, Block: BlockT, RA, S, F>(
|
||||
let validation_result = match finality_grandpa::validate_commit(
|
||||
&commit,
|
||||
&voters,
|
||||
&ObserverChain(&*client),
|
||||
&ObserverChain { client: &client, _phantom: PhantomData },
|
||||
) {
|
||||
Ok(r) => r,
|
||||
Err(e) => return future::err(e.into()),
|
||||
@@ -113,7 +115,7 @@ fn grandpa_observer<B, E, Block: BlockT, RA, S, F>(
|
||||
|
||||
// commit is valid, finalize the block it targets
|
||||
match environment::finalize_block(
|
||||
&client,
|
||||
client.clone(),
|
||||
&authority_set,
|
||||
&consensus_changes,
|
||||
None,
|
||||
@@ -153,19 +155,17 @@ fn grandpa_observer<B, E, Block: BlockT, RA, S, F>(
|
||||
/// NOTE: this is currently not part of the crate's public API since we don't consider
|
||||
/// it stable enough to use on a live network.
|
||||
#[allow(unused)]
|
||||
pub fn run_grandpa_observer<B, E, Block: BlockT, N, RA, SC>(
|
||||
pub fn run_grandpa_observer<BE, Block: BlockT, Client, N, SC>(
|
||||
config: Config,
|
||||
link: LinkHalf<B, E, Block, RA, SC>,
|
||||
link: LinkHalf<Block, Client, SC>,
|
||||
network: N,
|
||||
on_exit: impl futures::Future<Output=()> + Clone + Send + Unpin + 'static,
|
||||
) -> sp_blockchain::Result<impl Future<Output = ()> + Unpin + Send + 'static> where
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
BE: Backend<Block> + Unpin + 'static,
|
||||
N: NetworkT<Block> + Send + Clone + 'static,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
RA: Send + Sync + 'static,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
Client: crate::ClientForGrandpa<Block, BE> + 'static,
|
||||
{
|
||||
let LinkHalf {
|
||||
client,
|
||||
@@ -199,28 +199,27 @@ pub fn run_grandpa_observer<B, E, Block: BlockT, N, RA, SC>(
|
||||
|
||||
/// Future that powers the observer.
|
||||
#[must_use]
|
||||
struct ObserverWork<B: BlockT, N: NetworkT<B>, E, Backend, RA> {
|
||||
struct ObserverWork<B: BlockT, BE, Client, N: NetworkT<B>> {
|
||||
observer: Pin<Box<dyn Future<Output = Result<(), CommandOrError<B::Hash, NumberFor<B>>>> + Send>>,
|
||||
client: Arc<Client<Backend, E, B, RA>>,
|
||||
client: Arc<Client>,
|
||||
network: NetworkBridge<B, N>,
|
||||
persistent_data: PersistentData<B>,
|
||||
keystore: Option<sc_keystore::KeyStorePtr>,
|
||||
voter_commands_rx: mpsc::UnboundedReceiver<VoterCommand<B::Hash, NumberFor<B>>>,
|
||||
_phantom: PhantomData<BE>,
|
||||
}
|
||||
|
||||
impl<B, N, E, Bk, RA> ObserverWork<B, N, E, Bk, RA>
|
||||
impl<B, BE, Client, Network> ObserverWork<B, BE, Client, Network>
|
||||
where
|
||||
B: BlockT,
|
||||
N: NetworkT<B>,
|
||||
BE: Backend<B> + 'static,
|
||||
Client: crate::ClientForGrandpa<B, BE> + 'static,
|
||||
Network: NetworkT<B>,
|
||||
NumberFor<B>: BlockNumberOps,
|
||||
RA: 'static + Send + Sync,
|
||||
E: CallExecutor<B> + Send + Sync + 'static,
|
||||
Bk: Backend<B> + 'static,
|
||||
Client<Bk, E, B, RA>: AuxStore,
|
||||
{
|
||||
fn new(
|
||||
client: Arc<Client<Bk, E, B, RA>>,
|
||||
network: NetworkBridge<B, N>,
|
||||
client: Arc<Client>,
|
||||
network: NetworkBridge<B, Network>,
|
||||
persistent_data: PersistentData<B>,
|
||||
keystore: Option<sc_keystore::KeyStorePtr>,
|
||||
voter_commands_rx: mpsc::UnboundedReceiver<VoterCommand<B::Hash, NumberFor<B>>>,
|
||||
@@ -235,6 +234,7 @@ where
|
||||
persistent_data,
|
||||
keystore,
|
||||
voter_commands_rx,
|
||||
_phantom: PhantomData,
|
||||
};
|
||||
work.rebuild_observer();
|
||||
work
|
||||
@@ -251,12 +251,12 @@ where
|
||||
let (global_in, _) = global_communication(
|
||||
set_id,
|
||||
&voters,
|
||||
&self.client,
|
||||
self.client.clone(),
|
||||
&self.network,
|
||||
&self.keystore,
|
||||
);
|
||||
|
||||
let last_finalized_number = self.client.chain_info().finalized_number;
|
||||
let last_finalized_number = self.client.info().finalized_number;
|
||||
|
||||
// NOTE: since we are not using `round_communication` we have to
|
||||
// manually note the round with the gossip validator, otherwise we won't
|
||||
@@ -324,15 +324,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, N, E, Bk, RA> Future for ObserverWork<B, N, E, Bk, RA>
|
||||
impl<B, BE, C, N> Future for ObserverWork<B, BE, C, N>
|
||||
where
|
||||
B: BlockT,
|
||||
BE: Backend<B> + Unpin + 'static,
|
||||
C: crate::ClientForGrandpa<B, BE>+ 'static,
|
||||
N: NetworkT<B>,
|
||||
NumberFor<B>: BlockNumberOps,
|
||||
RA: 'static + Send + Sync,
|
||||
E: CallExecutor<B> + Send + Sync + 'static,
|
||||
Bk: Backend<B> + 'static,
|
||||
Client<Bk, E, B, RA>: AuxStore,
|
||||
{
|
||||
type Output = Result<(), Error>;
|
||||
|
||||
@@ -379,6 +377,7 @@ mod tests {
|
||||
use crate::{aux_schema, communication::tests::{Event, make_test_network}};
|
||||
use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt};
|
||||
use sc_network::PeerId;
|
||||
use sp_blockchain::HeaderBackend as _;
|
||||
|
||||
use futures::executor;
|
||||
|
||||
@@ -406,7 +405,7 @@ mod tests {
|
||||
|
||||
let persistent_data = aux_schema::load_persistent(
|
||||
&*backend,
|
||||
client.chain_info().genesis_hash,
|
||||
client.info().genesis_hash,
|
||||
0,
|
||||
|| Ok(vec![]),
|
||||
).unwrap();
|
||||
|
||||
@@ -20,7 +20,7 @@ use super::*;
|
||||
use environment::HasVoted;
|
||||
use sc_network_test::{
|
||||
Block, Hash, TestNetFactory, BlockImportAdapter, Peer,
|
||||
PeersClient, PassThroughVerifier,
|
||||
PeersClient, PassThroughVerifier, PeersFullClient,
|
||||
};
|
||||
use sc_network::config::{ProtocolConfig, Roles, BoxFinalityProofRequestBuilder};
|
||||
use parking_lot::Mutex;
|
||||
@@ -60,10 +60,8 @@ type PeerData =
|
||||
Mutex<
|
||||
Option<
|
||||
LinkHalf<
|
||||
substrate_test_runtime_client::Backend,
|
||||
substrate_test_runtime_client::Executor,
|
||||
Block,
|
||||
substrate_test_runtime_client::runtime::RuntimeApi,
|
||||
PeersFullClient,
|
||||
LongestChain<substrate_test_runtime_client::Backend, Block>
|
||||
>
|
||||
>
|
||||
@@ -1654,6 +1652,7 @@ fn grandpa_environment_respects_voting_rules() {
|
||||
voters: Arc::new(authority_set.current_authorities()),
|
||||
network,
|
||||
voting_rule,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user