mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 22:41:02 +00:00
Remove requirement on Hash = H256, make Proposer return StorageChanges and Proof (#3860)
* Extend `Proposer` to optionally generate a proof of the proposal * Something * Refactor sr-api to not depend on client anymore * Fix benches * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Apply suggestions from code review * Introduce new `into_storage_changes` function * Switch to runtime api for `execute_block` and don't require `H256` anywhere in the code * Put the `StorageChanges` into the `Proposal` * Move the runtime api error to its own trait * Adds `StorageTransactionCache` to the runtime api This requires that we add `type NodeBlock = ` to the `impl_runtime_apis!` macro to work around some bugs in rustc :( * Remove `type NodeBlock` and switch to a "better" hack * Start using the transaction cache from the runtime api * Make it compile * Move `InMemory` to its own file * Make all tests work again * Return block, storage_changes and proof from Blockbuilder::bake() * Make sure that we use/set `storage_changes` when possible * Add test * Fix deadlock * Remove accidentally added folders * Introduce `RecordProof` as argument type to be more explicit * Update client/src/client.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update primitives/state-machine/src/ext.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Integrates review feedback * Remove `unsafe` usage * Update client/block-builder/src/lib.rs Co-Authored-By: Benjamin Kampmann <ben@gnunicorn.org> * Update client/src/call_executor.rs * Bump versions Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Benjamin Kampmann <ben.kampmann@googlemail.com>
This commit is contained in:
@@ -29,7 +29,7 @@ use sp_blockchain::{HeaderBackend, Error as ClientError};
|
||||
|
||||
use sc_client_api::{
|
||||
BlockchainEvents,
|
||||
backend::{Backend},
|
||||
backend::{AuxStore, Backend},
|
||||
Finalizer,
|
||||
call_executor::CallExecutor,
|
||||
utils::is_descendent_of,
|
||||
@@ -41,7 +41,7 @@ use finality_grandpa::{
|
||||
BlockNumberOps, Equivocation, Error as GrandpaError, round::State as RoundState,
|
||||
voter, voter_set::VoterSet,
|
||||
};
|
||||
use sp_core::{Blake2Hasher, H256, Pair};
|
||||
use sp_core::Pair;
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_runtime::traits::{
|
||||
Block as BlockT, Header as HeaderT, NumberFor, One, Zero,
|
||||
@@ -406,13 +406,13 @@ impl<B, E, Block: BlockT, N: NetworkT<Block>, RA, SC, VR> Environment<B, E, Bloc
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT<Hash=H256>, B, E, N, RA, SC, VR>
|
||||
impl<Block: BlockT, B, E, N, RA, SC, VR>
|
||||
finality_grandpa::Chain<Block::Hash, NumberFor<Block>>
|
||||
for Environment<B, E, Block, N, RA, SC, VR>
|
||||
where
|
||||
Block: 'static,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
N: NetworkT<Block> + 'static + Send,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>>,
|
||||
@@ -519,13 +519,13 @@ where
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn ancestry<B, Block: BlockT<Hash=H256>, E, RA>(
|
||||
pub(crate) fn ancestry<B, Block: BlockT, E, RA>(
|
||||
client: &Client<B, E, Block, RA>,
|
||||
base: Block::Hash,
|
||||
block: Block::Hash,
|
||||
) -> Result<Vec<Block::Hash>, GrandpaError> where
|
||||
B: Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher>,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block>,
|
||||
{
|
||||
if base == block { return Err(GrandpaError::NotDescendent) }
|
||||
|
||||
@@ -550,18 +550,19 @@ pub(crate) fn ancestry<B, Block: BlockT<Hash=H256>, E, RA>(
|
||||
Ok(tree_route.retracted().iter().skip(1).map(|e| e.hash).collect())
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, N, RA, SC, VR>
|
||||
impl<B, E, Block: BlockT, N, RA, SC, VR>
|
||||
voter::Environment<Block::Hash, NumberFor<Block>>
|
||||
for Environment<B, E, Block, N, RA, SC, VR>
|
||||
where
|
||||
Block: 'static,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Send + Sync,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Send + Sync,
|
||||
N: NetworkT<Block> + 'static + Send,
|
||||
RA: 'static + Send + Sync,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>>,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
{
|
||||
type Timer = Box<dyn Future<Item = (), Error = Self::Error> + Send>;
|
||||
type Id = AuthorityId;
|
||||
@@ -940,7 +941,7 @@ 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<Hash=H256>, E, RA>(
|
||||
pub(crate) fn finalize_block<B, Block: BlockT, E, RA>(
|
||||
client: &Client<B, E, Block, RA>,
|
||||
authority_set: &SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
consensus_changes: &SharedConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
@@ -949,8 +950,8 @@ pub(crate) fn finalize_block<B, Block: BlockT<Hash=H256>, E, RA>(
|
||||
number: NumberFor<Block>,
|
||||
justification_or_commit: JustificationOrCommit<Block>,
|
||||
) -> Result<(), CommandOrError<Block::Hash, NumberFor<Block>>> where
|
||||
B: Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
// NOTE: lock must be held through writing to DB to avoid race. this lock
|
||||
@@ -988,7 +989,7 @@ pub(crate) fn finalize_block<B, Block: BlockT<Hash=H256>, E, RA>(
|
||||
let status = authority_set.apply_standard_changes(
|
||||
hash,
|
||||
number,
|
||||
&is_descendent_of::<_, _, Block::Hash>(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
|
||||
@@ -1124,8 +1125,8 @@ pub(crate) fn finalize_block<B, Block: BlockT<Hash=H256>, E, RA>(
|
||||
|
||||
/// Using the given base get the block at the given height on this chain. The
|
||||
/// target block must be an ancestor of base, therefore `height <= base.height`.
|
||||
pub(crate) fn canonical_at_height<Block: BlockT<Hash=H256>, C: HeaderBackend<Block>>(
|
||||
provider: C,
|
||||
pub(crate) fn canonical_at_height<Block: BlockT, C: HeaderBackend<Block>>(
|
||||
provider: &C,
|
||||
base: (Block::Hash, NumberFor<Block>),
|
||||
base_is_canonical: bool,
|
||||
height: NumberFor<Block>,
|
||||
|
||||
@@ -50,7 +50,7 @@ use sp_runtime::{
|
||||
Justification, generic::BlockId,
|
||||
traits::{NumberFor, Block as BlockT, Header as HeaderT, One},
|
||||
};
|
||||
use sp_core::{H256, Blake2Hasher, storage::StorageKey};
|
||||
use sp_core::storage::StorageKey;
|
||||
use sc_telemetry::{telemetry, CONSENSUS_INFO};
|
||||
use sp_finality_grandpa::{AuthorityId, AuthorityList, VersionedAuthorityList, GRANDPA_AUTHORITIES_KEY};
|
||||
|
||||
@@ -68,10 +68,10 @@ pub trait AuthoritySetForFinalityProver<Block: BlockT>: Send + Sync {
|
||||
}
|
||||
|
||||
/// Client-based implementation of AuthoritySetForFinalityProver.
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> AuthoritySetForFinalityProver<Block> for Client<B, E, Block, RA>
|
||||
impl<B, E, Block: BlockT, RA> AuthoritySetForFinalityProver<Block> for Client<B, E, Block, RA>
|
||||
where
|
||||
B: Backend<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + Send + Sync + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
fn authorities(&self, block: &BlockId<Block>) -> ClientResult<AuthorityList> {
|
||||
@@ -134,13 +134,13 @@ impl<Block: BlockT> AuthoritySetForFinalityChecker<Block> for Arc<dyn FetchCheck
|
||||
}
|
||||
|
||||
/// Finality proof provider for serving network requests.
|
||||
pub struct FinalityProofProvider<B, Block: BlockT<Hash=H256>> {
|
||||
pub struct FinalityProofProvider<B, Block: BlockT> {
|
||||
backend: Arc<B>,
|
||||
authority_provider: Arc<dyn AuthoritySetForFinalityProver<Block>>,
|
||||
}
|
||||
|
||||
impl<B, Block: BlockT<Hash=H256>> FinalityProofProvider<B, Block>
|
||||
where B: Backend<Block, Blake2Hasher> + Send + Sync + 'static
|
||||
impl<B, Block: BlockT> FinalityProofProvider<B, Block>
|
||||
where B: Backend<Block> + Send + Sync + 'static
|
||||
{
|
||||
/// Create new finality proof provider using:
|
||||
///
|
||||
@@ -156,9 +156,9 @@ impl<B, Block: BlockT<Hash=H256>> FinalityProofProvider<B, Block>
|
||||
|
||||
impl<B, Block> sc_network::FinalityProofProvider<Block> for FinalityProofProvider<B, Block>
|
||||
where
|
||||
Block: BlockT<Hash=H256>,
|
||||
Block: BlockT,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
B: Backend<Block> + Send + Sync + 'static,
|
||||
{
|
||||
fn prove_finality(
|
||||
&self,
|
||||
@@ -252,7 +252,7 @@ pub(crate) fn make_finality_proof_request<H: Encode + Decode>(last_finalized: H,
|
||||
/// It is assumed that the caller already knows all blocks in the range (begin; end].
|
||||
///
|
||||
/// Returns None if there are no finalized blocks unknown to the caller.
|
||||
pub(crate) fn prove_finality<Block: BlockT<Hash=H256>, B: BlockchainBackend<Block>, J>(
|
||||
pub(crate) fn prove_finality<Block: BlockT, B: BlockchainBackend<Block>, J>(
|
||||
blockchain: &B,
|
||||
authorities_provider: &dyn AuthoritySetForFinalityProver<Block>,
|
||||
authorities_set_id: u64,
|
||||
@@ -410,7 +410,7 @@ pub(crate) fn prove_finality<Block: BlockT<Hash=H256>, B: BlockchainBackend<Bloc
|
||||
///
|
||||
/// Returns the vector of headers that MUST be validated + imported
|
||||
/// AND if at least one of those headers is invalid, all other MUST be considered invalid.
|
||||
pub(crate) fn check_finality_proof<Block: BlockT<Hash=H256>, B>(
|
||||
pub(crate) fn check_finality_proof<Block: BlockT, B>(
|
||||
blockchain: &B,
|
||||
current_set_id: u64,
|
||||
current_authorities: AuthorityList,
|
||||
@@ -429,7 +429,7 @@ pub(crate) fn check_finality_proof<Block: BlockT<Hash=H256>, B>(
|
||||
remote_proof)
|
||||
}
|
||||
|
||||
fn do_check_finality_proof<Block: BlockT<Hash=H256>, B, J>(
|
||||
fn do_check_finality_proof<Block: BlockT, B, J>(
|
||||
blockchain: &B,
|
||||
current_set_id: u64,
|
||||
current_authorities: AuthorityList,
|
||||
@@ -484,7 +484,7 @@ fn do_check_finality_proof<Block: BlockT<Hash=H256>, B, J>(
|
||||
}
|
||||
|
||||
/// Check finality proof for the single block.
|
||||
fn check_finality_proof_fragment<Block: BlockT<Hash=H256>, B, J>(
|
||||
fn check_finality_proof_fragment<Block: BlockT, B, J>(
|
||||
blockchain: &B,
|
||||
authority_set: AuthoritiesOrEffects<Block::Header>,
|
||||
authorities_provider: &dyn AuthoritySetForFinalityChecker<Block>,
|
||||
@@ -569,7 +569,7 @@ pub(crate) trait ProvableJustification<Header: HeaderT>: Encode + Decode {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT<Hash=H256>> ProvableJustification<Block::Header> for GrandpaJustification<Block>
|
||||
impl<Block: BlockT> ProvableJustification<Block::Header> for GrandpaJustification<Block>
|
||||
where
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ use futures::sync::mpsc;
|
||||
use parking_lot::RwLockWriteGuard;
|
||||
|
||||
use sp_blockchain::{HeaderBackend, BlockStatus, well_known_cache_keys};
|
||||
use sc_client_api::{backend::Backend, CallExecutor, utils::is_descendent_of};
|
||||
use sc_client_api::{backend::{TransactionFor, Backend}, CallExecutor, utils::is_descendent_of};
|
||||
use sc_client::Client;
|
||||
use sp_consensus::{
|
||||
BlockImport, Error as ConsensusError,
|
||||
@@ -35,7 +35,6 @@ use sp_runtime::generic::{BlockId, OpaqueDigestItemId};
|
||||
use sp_runtime::traits::{
|
||||
Block as BlockT, DigestFor, Header as HeaderT, NumberFor, Zero,
|
||||
};
|
||||
use sp_core::{H256, Blake2Hasher};
|
||||
|
||||
use crate::{Error, CommandOrError, NewAuthoritySet, VoterCommand};
|
||||
use crate::authorities::{AuthoritySet, SharedAuthoritySet, DelayKind, PendingChange};
|
||||
@@ -52,7 +51,7 @@ 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<Hash=H256>, RA, SC> {
|
||||
pub struct GrandpaBlockImport<B, E, Block: BlockT, RA, SC> {
|
||||
inner: Arc<Client<B, E, Block, RA>>,
|
||||
select_chain: SC,
|
||||
authority_set: SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
@@ -60,7 +59,7 @@ pub struct GrandpaBlockImport<B, E, Block: BlockT<Hash=H256>, RA, SC> {
|
||||
consensus_changes: SharedConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA, SC: Clone> Clone for
|
||||
impl<B, E, Block: BlockT, RA, SC: Clone> Clone for
|
||||
GrandpaBlockImport<B, E, Block, RA, SC>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
@@ -74,11 +73,11 @@ impl<B, E, Block: BlockT<Hash=H256>, RA, SC: Clone> Clone for
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA, SC> JustificationImport<Block>
|
||||
impl<B, E, Block: BlockT, RA, SC> JustificationImport<Block>
|
||||
for GrandpaBlockImport<B, E, Block, RA, SC> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
SC: SelectChain<Block>,
|
||||
@@ -201,12 +200,12 @@ 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<Hash=H256>, RA, SC>
|
||||
impl<B, E, Block: BlockT, RA, SC>
|
||||
GrandpaBlockImport<B, E, Block, RA, SC>
|
||||
where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
@@ -236,9 +235,11 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn make_authorities_changes<'a>(&'a self, block: &mut BlockImportParams<Block>, hash: Block::Hash)
|
||||
-> Result<PendingSetChanges<'a, Block>, ConsensusError>
|
||||
{
|
||||
fn make_authorities_changes<'a>(
|
||||
&'a self,
|
||||
block: &mut BlockImportParams<Block, TransactionFor<B, Block>>,
|
||||
hash: Block::Hash,
|
||||
) -> Result<PendingSetChanges<'a, 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.
|
||||
@@ -285,7 +286,7 @@ where
|
||||
// returns a function for checking whether a block is a descendent of another
|
||||
// consistent with querying client directly after importing the block.
|
||||
let parent_hash = *block.header.parent_hash();
|
||||
let is_descendent_of = is_descendent_of(&*self.inner, Some((&hash, &parent_hash)));
|
||||
let is_descendent_of = is_descendent_of(&*self.inner, Some((hash, parent_hash)));
|
||||
|
||||
let mut guard = InnerGuard {
|
||||
guard: Some(self.authority_set.inner().write()),
|
||||
@@ -379,19 +380,22 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA, SC> BlockImport<Block>
|
||||
impl<B, E, Block: BlockT, RA, SC> BlockImport<Block>
|
||||
for GrandpaBlockImport<B, E, Block, RA, SC> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
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>>,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = TransactionFor<B, Block>;
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block>,
|
||||
mut block: BlockImportParams<Block, Self::Transaction>,
|
||||
new_cache: HashMap<well_known_cache_keys::Id, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
let hash = block.post_header().hash();
|
||||
@@ -416,12 +420,20 @@ impl<B, E, Block: BlockT<Hash=H256>, RA, SC> BlockImport<Block>
|
||||
match import_result {
|
||||
Ok(ImportResult::Imported(aux)) => aux,
|
||||
Ok(r) => {
|
||||
debug!(target: "afg", "Restoring old authority set after block import result: {:?}", r);
|
||||
debug!(
|
||||
target: "afg",
|
||||
"Restoring old authority set after block import result: {:?}",
|
||||
r,
|
||||
);
|
||||
pending_changes.revert();
|
||||
return Ok(r);
|
||||
},
|
||||
Err(e) => {
|
||||
debug!(target: "afg", "Restoring old authority set after block import error: {:?}", e);
|
||||
debug!(
|
||||
target: "afg",
|
||||
"Restoring old authority set after block import error: {:?}",
|
||||
e,
|
||||
);
|
||||
pending_changes.revert();
|
||||
return Err(ConsensusError::ClientImport(e.to_string()).into());
|
||||
},
|
||||
@@ -509,9 +521,7 @@ impl<B, E, Block: BlockT<Hash=H256>, RA, SC> BlockImport<Block>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA, SC>
|
||||
GrandpaBlockImport<B, E, Block, RA, SC>
|
||||
{
|
||||
impl<B, E, Block: BlockT, RA, SC> GrandpaBlockImport<B, E, Block, RA, SC> {
|
||||
pub(crate) fn new(
|
||||
inner: Arc<Client<B, E, Block, RA>>,
|
||||
select_chain: SC,
|
||||
@@ -529,12 +539,12 @@ impl<B, E, Block: BlockT<Hash=H256>, RA, SC>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA, SC>
|
||||
impl<B, E, Block: BlockT, RA, SC>
|
||||
GrandpaBlockImport<B, E, Block, RA, SC>
|
||||
where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ use finality_grandpa::voter_set::VoterSet;
|
||||
use finality_grandpa::{Error as GrandpaError};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_runtime::traits::{NumberFor, Block as BlockT, Header as HeaderT};
|
||||
use sp_core::{H256, Blake2Hasher};
|
||||
use sp_finality_grandpa::AuthorityId;
|
||||
|
||||
use crate::{Commit, Error};
|
||||
@@ -45,7 +44,7 @@ pub struct GrandpaJustification<Block: BlockT> {
|
||||
votes_ancestries: Vec<Block::Header>,
|
||||
}
|
||||
|
||||
impl<Block: BlockT<Hash=H256>> GrandpaJustification<Block> {
|
||||
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>(
|
||||
@@ -53,8 +52,8 @@ impl<Block: BlockT<Hash=H256>> GrandpaJustification<Block> {
|
||||
round: u64,
|
||||
commit: Commit<Block>,
|
||||
) -> Result<GrandpaJustification<Block>, Error> where
|
||||
B: Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
let mut votes_ancestries_hashes = HashSet::new();
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
use futures::prelude::*;
|
||||
use log::{debug, error, info};
|
||||
use futures::sync::mpsc;
|
||||
use sc_client_api::{BlockchainEvents, CallExecutor, backend::Backend, ExecutionStrategy};
|
||||
use sc_client_api::{BlockchainEvents, CallExecutor, backend::{AuxStore, Backend}, ExecutionStrategy};
|
||||
use sp_blockchain::{HeaderBackend, Error as ClientError};
|
||||
use sc_client::Client;
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
@@ -64,7 +64,7 @@ use sp_runtime::traits::{NumberFor, Block as BlockT, DigestFor, Zero};
|
||||
use sc_keystore::KeyStorePtr;
|
||||
use sp_inherents::InherentDataProviders;
|
||||
use sp_consensus::SelectChain;
|
||||
use sp_core::{H256, Blake2Hasher, Pair};
|
||||
use sp_core::Pair;
|
||||
use sc_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG, CONSENSUS_WARN};
|
||||
use serde_json;
|
||||
|
||||
@@ -252,9 +252,9 @@ pub(crate) trait BlockStatus<Block: BlockT> {
|
||||
fn block_number(&self, hash: Block::Hash) -> Result<Option<NumberFor<Block>>, Error>;
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> BlockStatus<Block> for Arc<Client<B, E, Block, RA>> where
|
||||
B: Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync,
|
||||
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,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
{
|
||||
@@ -355,7 +355,7 @@ impl<H, N> fmt::Display for CommandOrError<H, N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LinkHalf<B, E, Block: BlockT<Hash=H256>, RA, SC> {
|
||||
pub struct LinkHalf<B, E, Block: BlockT, RA, SC> {
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
select_chain: SC,
|
||||
persistent_data: PersistentData<Block>,
|
||||
@@ -368,10 +368,10 @@ pub trait GenesisAuthoritySetProvider<Block: BlockT> {
|
||||
fn get(&self) -> Result<AuthorityList, ClientError>;
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> GenesisAuthoritySetProvider<Block> for Client<B, E, Block, RA>
|
||||
impl<B, E, Block: BlockT, RA> GenesisAuthoritySetProvider<Block> for Client<B, E, Block, RA>
|
||||
where
|
||||
B: Backend<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + Send + Sync + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
fn get(&self) -> Result<AuthorityList, ClientError> {
|
||||
@@ -397,7 +397,7 @@ impl<B, E, Block: BlockT<Hash=H256>, RA> GenesisAuthoritySetProvider<Block> for
|
||||
|
||||
/// Make block importer and link half necessary to tie the background voter
|
||||
/// to it.
|
||||
pub fn block_import<B, E, Block: BlockT<Hash=H256>, RA, SC>(
|
||||
pub fn block_import<B, E, Block: BlockT, RA, SC>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
genesis_authorities_provider: &dyn GenesisAuthoritySetProvider<Block>,
|
||||
select_chain: SC,
|
||||
@@ -406,10 +406,11 @@ pub fn block_import<B, E, Block: BlockT<Hash=H256>, RA, SC>(
|
||||
LinkHalf<B, E, Block, RA, SC>
|
||||
), ClientError>
|
||||
where
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
SC: SelectChain<Block>,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
{
|
||||
let chain_info = client.chain_info();
|
||||
let genesis_hash = chain_info.genesis_hash;
|
||||
@@ -446,7 +447,7 @@ where
|
||||
))
|
||||
}
|
||||
|
||||
fn global_communication<Block: BlockT<Hash=H256>, B, E, N, RA>(
|
||||
fn global_communication<Block: BlockT, B, E, N, RA>(
|
||||
set_id: SetId,
|
||||
voters: &Arc<VoterSet<AuthorityId>>,
|
||||
client: &Arc<Client<B, E, Block, RA>>,
|
||||
@@ -454,16 +455,16 @@ fn global_communication<Block: BlockT<Hash=H256>, B, E, N, RA>(
|
||||
keystore: &Option<KeyStorePtr>,
|
||||
) -> (
|
||||
impl Stream<
|
||||
Item = CommunicationInH<Block, H256>,
|
||||
Error = CommandOrError<H256, NumberFor<Block>>,
|
||||
Item = CommunicationInH<Block, Block::Hash>,
|
||||
Error = CommandOrError<Block::Hash, NumberFor<Block>>,
|
||||
>,
|
||||
impl Sink<
|
||||
SinkItem = CommunicationOutH<Block, H256>,
|
||||
SinkError = CommandOrError<H256, NumberFor<Block>>,
|
||||
SinkItem = CommunicationOutH<Block, Block::Hash>,
|
||||
SinkError = CommandOrError<Block::Hash, NumberFor<Block>>,
|
||||
>,
|
||||
) where
|
||||
B: Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
N: NetworkT<Block>,
|
||||
RA: Send + Sync,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
@@ -494,12 +495,12 @@ fn global_communication<Block: BlockT<Hash=H256>, 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<Hash=H256>, RA>(
|
||||
fn register_finality_tracker_inherent_data_provider<B, E, Block: BlockT, RA>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
inherent_data_providers: &InherentDataProviders,
|
||||
) -> Result<(), sp_consensus::Error> where
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
RA: Send + Sync + 'static,
|
||||
{
|
||||
if !inherent_data_providers.has_provider(&sp_finality_tracker::INHERENT_IDENTIFIER) {
|
||||
@@ -522,7 +523,7 @@ fn register_finality_tracker_inherent_data_provider<B, E, Block: BlockT<Hash=H25
|
||||
}
|
||||
|
||||
/// Parameters used to run Grandpa.
|
||||
pub struct GrandpaParams<B, E, Block: BlockT<Hash=H256>, N, RA, SC, VR, X, Sp> {
|
||||
pub struct GrandpaParams<B, E, Block: BlockT, N, RA, SC, VR, X, Sp> {
|
||||
/// Configuration for the GRANDPA service.
|
||||
pub config: Config,
|
||||
/// A link to the block import worker.
|
||||
@@ -543,12 +544,12 @@ pub struct GrandpaParams<B, E, Block: BlockT<Hash=H256>, N, RA, SC, VR, X, Sp> {
|
||||
|
||||
/// 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<Hash=H256>, N, RA, SC, VR, X, Sp>(
|
||||
pub fn run_grandpa_voter<B, E, Block: BlockT, N, RA, SC, VR, X, Sp>(
|
||||
grandpa_params: GrandpaParams<B, E, Block, N, RA, SC, VR, X, Sp>,
|
||||
) -> sp_blockchain::Result<impl Future<Item=(),Error=()> + Send + 'static> where
|
||||
Block::Hash: Ord,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
N: NetworkT<Block> + Send + Sync + Clone + 'static,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>> + Clone + 'static,
|
||||
@@ -556,6 +557,7 @@ pub fn run_grandpa_voter<B, E, Block: BlockT<Hash=H256>, N, RA, SC, VR, X, Sp>(
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync + 'static,
|
||||
X: futures03::Future<Output=()> + Clone + Send + Unpin + 'static,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
Sp: futures03::task::Spawn + 'static,
|
||||
{
|
||||
let GrandpaParams {
|
||||
@@ -650,14 +652,15 @@ struct VoterWork<B, E, Block: BlockT, N: NetworkT<Block>, RA, SC, VR> {
|
||||
|
||||
impl<B, E, Block, N, RA, SC, VR> VoterWork<B, E, Block, N, RA, SC, VR>
|
||||
where
|
||||
Block: BlockT<Hash=H256>,
|
||||
Block: BlockT,
|
||||
N: NetworkT<Block> + Sync,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
RA: 'static + Send + Sync,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
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,
|
||||
{
|
||||
fn new(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
@@ -825,14 +828,15 @@ where
|
||||
|
||||
impl<B, E, Block, N, RA, SC, VR> Future for VoterWork<B, E, Block, N, RA, SC, VR>
|
||||
where
|
||||
Block: BlockT<Hash=H256>,
|
||||
Block: BlockT,
|
||||
N: NetworkT<Block> + Sync,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
RA: 'static + Send + Sync,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
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,
|
||||
{
|
||||
type Item = ();
|
||||
type Error = Error;
|
||||
@@ -877,12 +881,12 @@ where
|
||||
}
|
||||
|
||||
#[deprecated(since = "1.1.0", note = "Please switch to run_grandpa_voter.")]
|
||||
pub fn run_grandpa<B, E, Block: BlockT<Hash=H256>, N, RA, SC, VR, X, Sp>(
|
||||
pub fn run_grandpa<B, E, Block: BlockT, N, RA, SC, VR, X, Sp>(
|
||||
grandpa_params: GrandpaParams<B, E, Block, N, RA, SC, VR, X, Sp>,
|
||||
) -> ::sp_blockchain::Result<impl Future<Item=(),Error=()> + Send + 'static> where
|
||||
) -> sp_blockchain::Result<impl Future<Item=(),Error=()> + Send + 'static> where
|
||||
Block::Hash: Ord,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
N: NetworkT<Block> + Send + Sync + Clone + 'static,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
@@ -890,6 +894,7 @@ pub fn run_grandpa<B, E, Block: BlockT<Hash=H256>, N, RA, SC, VR, X, Sp>(
|
||||
RA: Send + Sync + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>> + Clone + 'static,
|
||||
X: futures03::Future<Output=()> + Clone + Send + Unpin + 'static,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
Sp: futures03::task::Spawn + 'static,
|
||||
{
|
||||
run_grandpa_voter(grandpa_params)
|
||||
@@ -901,13 +906,13 @@ pub fn run_grandpa<B, E, Block: BlockT<Hash=H256>, N, RA, SC, VR, X, Sp>(
|
||||
/// 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<Hash=H256>, RA, N>(
|
||||
pub fn setup_disabled_grandpa<B, E, Block: BlockT, RA, N>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
inherent_data_providers: &InherentDataProviders,
|
||||
network: N,
|
||||
) -> Result<(), sp_consensus::Error> where
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
RA: Send + Sync + 'static,
|
||||
N: NetworkT<Block> + Send + Clone + 'static,
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ 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}};
|
||||
use sc_client_api::{CallExecutor, 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::{
|
||||
@@ -32,7 +32,6 @@ use sp_runtime::Justification;
|
||||
use sp_runtime::traits::{NumberFor, Block as BlockT, Header as HeaderT, DigestFor};
|
||||
use sp_finality_grandpa::{self, AuthorityList};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_core::{H256, Blake2Hasher};
|
||||
|
||||
use crate::GenesisAuthoritySetProvider;
|
||||
use crate::aux_schema::load_decode;
|
||||
@@ -49,16 +48,17 @@ 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<Hash=H256>, RA>(
|
||||
pub fn light_block_import<B, E, Block: BlockT, RA>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
backend: Arc<B>,
|
||||
genesis_authorities_provider: &dyn GenesisAuthoritySetProvider<Block>,
|
||||
authority_set_provider: Arc<dyn AuthoritySetForFinalityChecker<Block>>,
|
||||
) -> Result<GrandpaLightBlockImport<B, E, Block, RA>, ClientError>
|
||||
where
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
{
|
||||
let info = client.info();
|
||||
let import_data = load_aux_import_data(
|
||||
@@ -79,14 +79,14 @@ pub fn light_block_import<B, E, Block: BlockT<Hash=H256>, 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<Hash=H256>, RA> {
|
||||
pub struct GrandpaLightBlockImport<B, E, Block: BlockT, RA> {
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
backend: Arc<B>,
|
||||
authority_set_provider: Arc<dyn AuthoritySetForFinalityChecker<Block>>,
|
||||
data: Arc<RwLock<LightImportData<Block>>>,
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> Clone for GrandpaLightBlockImport<B, E, Block, RA> {
|
||||
impl<B, E, Block: BlockT, RA> Clone for GrandpaLightBlockImport<B, E, Block, RA> {
|
||||
fn clone(&self) -> Self {
|
||||
GrandpaLightBlockImport {
|
||||
client: self.client.clone(),
|
||||
@@ -98,7 +98,7 @@ impl<B, E, Block: BlockT<Hash=H256>, RA> Clone for GrandpaLightBlockImport<B, E,
|
||||
}
|
||||
|
||||
/// Mutable data of light block importer.
|
||||
struct LightImportData<Block: BlockT<Hash=H256>> {
|
||||
struct LightImportData<Block: BlockT> {
|
||||
last_finalized: Block::Hash,
|
||||
authority_set: LightAuthoritySet,
|
||||
consensus_changes: ConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
@@ -111,26 +111,31 @@ struct LightAuthoritySet {
|
||||
authorities: AuthorityList,
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> GrandpaLightBlockImport<B, E, Block, RA> {
|
||||
impl<B, E, Block: BlockT, RA> GrandpaLightBlockImport<B, E, Block, RA> {
|
||||
/// 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<Hash=H256>, RA> BlockImport<Block>
|
||||
impl<B, E, Block: BlockT, RA> BlockImport<Block>
|
||||
for GrandpaLightBlockImport<B, E, Block, RA> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
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>
|
||||
+ AuxStore,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = TransactionFor<B, Block>;
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<Block>,
|
||||
block: BlockImportParams<Block, Self::Transaction>,
|
||||
new_cache: HashMap<well_known_cache_keys::Id, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
do_import_block::<_, _, _, GrandpaJustification<Block>>(
|
||||
@@ -146,13 +151,17 @@ impl<B, E, Block: BlockT<Hash=H256>, RA> BlockImport<Block>
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> FinalityProofImport<Block>
|
||||
impl<B, E, Block: BlockT, RA> FinalityProofImport<Block>
|
||||
for GrandpaLightBlockImport<B, E, Block, RA> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
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>
|
||||
+ AuxStore,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
|
||||
@@ -162,7 +171,9 @@ impl<B, E, Block: BlockT<Hash=H256>, RA> FinalityProofImport<Block>
|
||||
|
||||
let data = self.data.read();
|
||||
for (pending_number, pending_hash) in data.consensus_changes.pending_changes() {
|
||||
if *pending_number > chain_info.finalized_number && *pending_number <= chain_info.best_number {
|
||||
if *pending_number > chain_info.finalized_number
|
||||
&& *pending_number <= chain_info.best_number
|
||||
{
|
||||
out.push((pending_hash.clone(), *pending_number));
|
||||
}
|
||||
}
|
||||
@@ -216,9 +227,9 @@ impl LightAuthoritySet {
|
||||
}
|
||||
}
|
||||
|
||||
struct GrandpaFinalityProofRequestBuilder<B: BlockT<Hash=H256>>(Arc<RwLock<LightImportData<B>>>);
|
||||
struct GrandpaFinalityProofRequestBuilder<B: BlockT>(Arc<RwLock<LightImportData<B>>>);
|
||||
|
||||
impl<B: BlockT<Hash=H256>> FinalityProofRequestBuilder<B> for GrandpaFinalityProofRequestBuilder<B> {
|
||||
impl<B: BlockT> FinalityProofRequestBuilder<B> for GrandpaFinalityProofRequestBuilder<B> {
|
||||
fn build_request_data(&mut self, _hash: &B::Hash) -> Vec<u8> {
|
||||
let data = self.0.read();
|
||||
make_finality_proof_request(
|
||||
@@ -229,19 +240,19 @@ impl<B: BlockT<Hash=H256>> FinalityProofRequestBuilder<B> for GrandpaFinalityPro
|
||||
}
|
||||
|
||||
/// Try to import new block.
|
||||
fn do_import_block<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
fn do_import_block<B, C, Block: BlockT, J>(
|
||||
mut client: C,
|
||||
data: &mut LightImportData<Block>,
|
||||
mut block: BlockImportParams<Block>,
|
||||
mut block: BlockImportParams<Block, TransactionFor<B, Block>>,
|
||||
new_cache: HashMap<well_known_cache_keys::Id, Vec<u8>>,
|
||||
) -> Result<ImportResult, ConsensusError>
|
||||
where
|
||||
C: HeaderBackend<Block>
|
||||
+ AuxStore
|
||||
+ Finalizer<Block, Blake2Hasher, B>
|
||||
+ BlockImport<Block>
|
||||
+ Finalizer<Block, B>
|
||||
+ BlockImport<Block, Transaction = TransactionFor<B, Block>>
|
||||
+ Clone,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
DigestFor<Block>: Encode,
|
||||
J: ProvableJustification<Block::Header>,
|
||||
@@ -288,7 +299,7 @@ fn do_import_block<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
}
|
||||
|
||||
/// Try to import finality proof.
|
||||
fn do_import_finality_proof<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
fn do_import_finality_proof<B, C, Block: BlockT, J>(
|
||||
client: C,
|
||||
backend: Arc<B>,
|
||||
authority_set_provider: &dyn AuthoritySetForFinalityChecker<Block>,
|
||||
@@ -301,10 +312,10 @@ fn do_import_finality_proof<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
where
|
||||
C: HeaderBackend<Block>
|
||||
+ AuxStore
|
||||
+ Finalizer<Block, Blake2Hasher, B>
|
||||
+ BlockImport<Block>
|
||||
+ Finalizer<Block, B>
|
||||
+ BlockImport<Block, Transaction = TransactionFor<B, Block>>
|
||||
+ Clone,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
DigestFor<Block>: Encode,
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
J: ProvableJustification<Block::Header>,
|
||||
@@ -322,15 +333,27 @@ fn do_import_finality_proof<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
// try to import all new headers
|
||||
let block_origin = BlockOrigin::NetworkBroadcast;
|
||||
for header_to_import in finality_effects.headers_to_import {
|
||||
let (block_to_import, new_authorities) = verifier.verify(block_origin, header_to_import, None, None)
|
||||
.map_err(|e| ConsensusError::ClientImport(e))?;
|
||||
assert!(block_to_import.justification.is_none(), "We have passed None as justification to verifier.verify");
|
||||
let (block_to_import, new_authorities) = verifier.verify(
|
||||
block_origin,
|
||||
header_to_import,
|
||||
None,
|
||||
None,
|
||||
).map_err(|e| ConsensusError::ClientImport(e))?;
|
||||
assert!(
|
||||
block_to_import.justification.is_none(),
|
||||
"We have passed None as justification to verifier.verify",
|
||||
);
|
||||
|
||||
let mut cache = HashMap::new();
|
||||
if let Some(authorities) = new_authorities {
|
||||
cache.insert(well_known_cache_keys::AUTHORITIES, authorities.encode());
|
||||
}
|
||||
do_import_block::<_, _, _, J>(client.clone(), data, block_to_import, cache)?;
|
||||
do_import_block::<_, _, _, J>(
|
||||
client.clone(),
|
||||
data,
|
||||
block_to_import.convert_transaction(),
|
||||
cache,
|
||||
)?;
|
||||
}
|
||||
|
||||
// try to import latest justification
|
||||
@@ -356,7 +379,7 @@ fn do_import_finality_proof<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
}
|
||||
|
||||
/// Try to import justification.
|
||||
fn do_import_justification<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
fn do_import_justification<B, C, Block: BlockT, J>(
|
||||
client: C,
|
||||
data: &mut LightImportData<Block>,
|
||||
hash: Block::Hash,
|
||||
@@ -366,9 +389,9 @@ fn do_import_justification<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
where
|
||||
C: HeaderBackend<Block>
|
||||
+ AuxStore
|
||||
+ Finalizer<Block, Blake2Hasher, B>
|
||||
+ Finalizer<Block, B>
|
||||
+ Clone,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
J: ProvableJustification<Block::Header>,
|
||||
{
|
||||
@@ -427,7 +450,7 @@ fn do_import_justification<B, C, Block: BlockT<Hash=H256>, J>(
|
||||
}
|
||||
|
||||
/// Finalize the block.
|
||||
fn do_finalize_block<B, C, Block: BlockT<Hash=H256>>(
|
||||
fn do_finalize_block<B, C, Block: BlockT>(
|
||||
client: C,
|
||||
data: &mut LightImportData<Block>,
|
||||
hash: Block::Hash,
|
||||
@@ -437,9 +460,9 @@ fn do_finalize_block<B, C, Block: BlockT<Hash=H256>>(
|
||||
where
|
||||
C: HeaderBackend<Block>
|
||||
+ AuxStore
|
||||
+ Finalizer<Block, Blake2Hasher, B>
|
||||
+ Finalizer<Block, B>
|
||||
+ Clone,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
{
|
||||
// finalize the block
|
||||
@@ -450,7 +473,10 @@ fn do_finalize_block<B, C, Block: BlockT<Hash=H256>>(
|
||||
|
||||
// forget obsoleted consensus changes
|
||||
let consensus_finalization_res = data.consensus_changes
|
||||
.finalize((number, hash), |at_height| canonical_at_height(client.clone(), (hash, number), true, at_height));
|
||||
.finalize(
|
||||
(number, hash),
|
||||
|at_height| canonical_at_height(&client, (hash, number), true, at_height)
|
||||
);
|
||||
match consensus_finalization_res {
|
||||
Ok((true, _)) => require_insert_aux(
|
||||
&client,
|
||||
@@ -470,13 +496,14 @@ fn do_finalize_block<B, C, Block: BlockT<Hash=H256>>(
|
||||
}
|
||||
|
||||
/// Load light import aux data from the store.
|
||||
fn load_aux_import_data<B, Block: BlockT<Hash=H256>>(
|
||||
fn load_aux_import_data<B, Block>(
|
||||
last_finalized: Block::Hash,
|
||||
aux_store: &B,
|
||||
genesis_authorities_provider: &dyn GenesisAuthoritySetProvider<Block>,
|
||||
) -> Result<LightImportData<Block>, ClientError>
|
||||
where
|
||||
B: AuxStore,
|
||||
Block: BlockT,
|
||||
{
|
||||
let authority_set = match load_decode(aux_store, LIGHT_AUTHORITY_SET_KEY)? {
|
||||
Some(authority_set) => authority_set,
|
||||
@@ -548,15 +575,15 @@ pub mod tests {
|
||||
use crate::tests::TestApi;
|
||||
use crate::finality_proof::tests::TestJustification;
|
||||
|
||||
pub struct NoJustificationsImport<B, E, Block: BlockT<Hash=H256>, RA>(
|
||||
pub struct NoJustificationsImport<B, E, Block: BlockT, RA>(
|
||||
pub GrandpaLightBlockImport<B, E, Block, RA>
|
||||
);
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> Clone
|
||||
impl<B, E, Block: BlockT, RA> Clone
|
||||
for NoJustificationsImport<B, E, Block, RA> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
DigestFor<Block>: Encode,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
@@ -565,19 +592,24 @@ pub mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> BlockImport<Block>
|
||||
impl<B, E, Block: BlockT, RA> BlockImport<Block>
|
||||
for NoJustificationsImport<B, E, Block, RA> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
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>
|
||||
+ AuxStore,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = TransactionFor<B, Block>;
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block>,
|
||||
mut block: BlockImportParams<Block, Self::Transaction>,
|
||||
new_cache: HashMap<well_known_cache_keys::Id, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
block.justification.take();
|
||||
@@ -592,13 +624,17 @@ pub mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block: BlockT<Hash=H256>, RA> FinalityProofImport<Block>
|
||||
impl<B, E, Block: BlockT, RA> FinalityProofImport<Block>
|
||||
for NoJustificationsImport<B, E, Block, RA> where
|
||||
NumberFor<Block>: finality_grandpa::BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
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>
|
||||
+ AuxStore,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
|
||||
@@ -618,16 +654,19 @@ 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<Hash=H256>, RA>(
|
||||
pub fn light_block_import_without_justifications<B, E, Block: BlockT, RA>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
backend: Arc<B>,
|
||||
genesis_authorities_provider: &dyn GenesisAuthoritySetProvider<Block>,
|
||||
authority_set_provider: Arc<dyn AuthoritySetForFinalityChecker<Block>>,
|
||||
) -> Result<NoJustificationsImport<B, E, Block, RA>, ClientError>
|
||||
where
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
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,
|
||||
{
|
||||
light_block_import(client, backend, genesis_authorities_provider, authority_set_provider)
|
||||
.map(NoJustificationsImport)
|
||||
@@ -655,6 +694,7 @@ pub mod tests {
|
||||
justification,
|
||||
post_digests: Vec::new(),
|
||||
body: None,
|
||||
storage_changes: None,
|
||||
finalized: false,
|
||||
auxiliary: Vec::new(),
|
||||
fork_choice: ForkChoiceStrategy::LongestChain,
|
||||
|
||||
@@ -25,10 +25,9 @@ use finality_grandpa::{
|
||||
use log::{debug, info, warn};
|
||||
|
||||
use sp_consensus::SelectChain;
|
||||
use sc_client_api::{CallExecutor, backend::Backend};
|
||||
use sc_client_api::{CallExecutor, backend::{Backend, AuxStore}};
|
||||
use sc_client::Client;
|
||||
use sp_runtime::traits::{NumberFor, Block as BlockT};
|
||||
use sp_core::{H256, Blake2Hasher};
|
||||
|
||||
use crate::{
|
||||
global_communication, CommandOrError, CommunicationIn, Config, environment,
|
||||
@@ -41,10 +40,10 @@ use sp_finality_grandpa::AuthorityId;
|
||||
|
||||
struct ObserverChain<'a, Block: BlockT, B, E, RA>(&'a Client<B, E, Block, RA>);
|
||||
|
||||
impl<'a, Block: BlockT<Hash=H256>, B, E, RA> finality_grandpa::Chain<Block::Hash, NumberFor<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, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher>,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block>,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
{
|
||||
fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result<Vec<Block::Hash>, GrandpaError> {
|
||||
@@ -57,7 +56,7 @@ impl<'a, Block: BlockT<Hash=H256>, B, E, RA> finality_grandpa::Chain<Block::Hash
|
||||
}
|
||||
}
|
||||
|
||||
fn grandpa_observer<B, E, Block: BlockT<Hash=H256>, RA, S, F>(
|
||||
fn grandpa_observer<B, E, Block: BlockT, RA, S, F>(
|
||||
client: &Arc<Client<B, E, Block, RA>>,
|
||||
authority_set: &SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
consensus_changes: &SharedConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
@@ -65,10 +64,10 @@ fn grandpa_observer<B, E, Block: BlockT<Hash=H256>, RA, S, F>(
|
||||
last_finalized_number: NumberFor<Block>,
|
||||
commits: S,
|
||||
note_round: F,
|
||||
) -> impl Future<Item=(), Error=CommandOrError<H256, NumberFor<Block>>> where
|
||||
) -> impl Future<Item=(), Error=CommandOrError<Block::Hash, NumberFor<Block>>> where
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
B: Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
S: Stream<
|
||||
Item = CommunicationIn<Block>,
|
||||
@@ -151,20 +150,21 @@ fn grandpa_observer<B, E, Block: BlockT<Hash=H256>, RA, S, F>(
|
||||
/// listening for and validating GRANDPA commits instead of following the full
|
||||
/// protocol. Provide configuration and a link to a block import worker that has
|
||||
/// already been instantiated with `block_import`.
|
||||
pub fn run_grandpa_observer<B, E, Block: BlockT<Hash=H256>, N, RA, SC, Sp>(
|
||||
pub fn run_grandpa_observer<B, E, Block: BlockT, N, RA, SC, Sp>(
|
||||
config: Config,
|
||||
link: LinkHalf<B, E, Block, RA, SC>,
|
||||
network: N,
|
||||
on_exit: impl futures03::Future<Output=()> + Clone + Send + Unpin + 'static,
|
||||
executor: Sp,
|
||||
) -> ::sp_blockchain::Result<impl Future<Item=(),Error=()> + Send + 'static> where
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + 'static,
|
||||
) -> sp_blockchain::Result<impl Future<Item=(), Error=()> + Send + 'static> where
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
N: NetworkT<Block> + Send + Clone + 'static,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
RA: Send + Sync + 'static,
|
||||
Sp: futures03::task::Spawn + 'static,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
{
|
||||
let LinkHalf {
|
||||
client,
|
||||
@@ -202,7 +202,7 @@ pub fn run_grandpa_observer<B, E, Block: BlockT<Hash=H256>, N, RA, SC, Sp>(
|
||||
|
||||
/// Future that powers the observer.
|
||||
#[must_use]
|
||||
struct ObserverWork<B: BlockT<Hash=H256>, N: NetworkT<B>, E, Backend, RA> {
|
||||
struct ObserverWork<B: BlockT, N: NetworkT<B>, E, Backend, RA> {
|
||||
observer: Box<dyn Future<Item = (), Error = CommandOrError<B::Hash, NumberFor<B>>> + Send>,
|
||||
client: Arc<Client<Backend, E, B, RA>>,
|
||||
network: NetworkBridge<B, N>,
|
||||
@@ -213,12 +213,13 @@ struct ObserverWork<B: BlockT<Hash=H256>, N: NetworkT<B>, E, Backend, RA> {
|
||||
|
||||
impl<B, N, E, Bk, RA> ObserverWork<B, N, E, Bk, RA>
|
||||
where
|
||||
B: BlockT<Hash=H256>,
|
||||
B: BlockT,
|
||||
N: NetworkT<B>,
|
||||
NumberFor<B>: BlockNumberOps,
|
||||
RA: 'static + Send + Sync,
|
||||
E: CallExecutor<B, Blake2Hasher> + Send + Sync + 'static,
|
||||
Bk: Backend<B, Blake2Hasher> + 'static,
|
||||
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>>,
|
||||
@@ -328,12 +329,13 @@ where
|
||||
|
||||
impl<B, N, E, Bk, RA> Future for ObserverWork<B, N, E, Bk, RA>
|
||||
where
|
||||
B: BlockT<Hash=H256>,
|
||||
B: BlockT,
|
||||
N: NetworkT<B>,
|
||||
NumberFor<B>: BlockNumberOps,
|
||||
RA: 'static + Send + Sync,
|
||||
E: CallExecutor<B, Blake2Hasher> + Send + Sync + 'static,
|
||||
Bk: Backend<B, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<B> + Send + Sync + 'static,
|
||||
Bk: Backend<B> + 'static,
|
||||
Client<Bk, E, B, RA>: AuxStore,
|
||||
{
|
||||
type Item = ();
|
||||
type Error = Error;
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
|
||||
use super::*;
|
||||
use environment::HasVoted;
|
||||
use sc_network_test::{Block, DummySpecialization, Hash, TestNetFactory, Peer, PeersClient};
|
||||
use sc_network_test::{PassThroughVerifier};
|
||||
use sc_network_test::{
|
||||
Block, DummySpecialization, Hash, TestNetFactory, BlockImportAdapter, Peer,
|
||||
PeersClient, PassThroughVerifier,
|
||||
};
|
||||
use sc_network::config::{ProtocolConfig, Roles, BoxFinalityProofRequestBuilder};
|
||||
use parking_lot::Mutex;
|
||||
use futures_timer::Delay;
|
||||
@@ -27,23 +29,28 @@ use futures03::{StreamExt as _, TryStreamExt as _};
|
||||
use tokio::runtime::current_thread;
|
||||
use sp_keyring::Ed25519Keyring;
|
||||
use sc_client::LongestChain;
|
||||
use sc_client_api::backend::TransactionFor;
|
||||
use sp_blockchain::Result;
|
||||
use sp_api::{Core, RuntimeVersion, ApiExt, StorageProof};
|
||||
use substrate_test_runtime_client::{self, runtime::BlockNumber};
|
||||
use sp_consensus::{BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult};
|
||||
use sp_consensus::import_queue::{BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport};
|
||||
use sp_api::{ApiRef, ApiErrorExt, Core, RuntimeVersion, ApiExt, StorageProof, ProvideRuntimeApi};
|
||||
use substrate_test_runtime_client::runtime::BlockNumber;
|
||||
use sp_consensus::{
|
||||
BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult, BlockImport,
|
||||
import_queue::{BoxJustificationImport, BoxFinalityProofImport},
|
||||
};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::result;
|
||||
use parity_scale_codec::Decode;
|
||||
use sp_runtime::traits::{ApiRef, ProvideRuntimeApi, Header as HeaderT};
|
||||
use sp_runtime::traits::{Header as HeaderT, HasherFor};
|
||||
use sp_runtime::generic::{BlockId, DigestItem};
|
||||
use sp_core::{NativeOrEncoded, ExecutionContext, crypto::Public};
|
||||
use sp_core::{H256, NativeOrEncoded, ExecutionContext, crypto::Public};
|
||||
use sp_finality_grandpa::{GRANDPA_ENGINE_ID, AuthorityList, GrandpaApi};
|
||||
use sp_state_machine::{backend::InMemory, prove_read, read_proof_check};
|
||||
use sp_state_machine::{InMemoryBackend, prove_read, read_proof_check};
|
||||
use std::{pin::Pin, task};
|
||||
|
||||
use authorities::AuthoritySet;
|
||||
use finality_proof::{FinalityProofProvider, AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker};
|
||||
use finality_proof::{
|
||||
FinalityProofProvider, AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker,
|
||||
};
|
||||
use consensus_changes::ConsensusChanges;
|
||||
|
||||
type PeerData =
|
||||
@@ -108,9 +115,9 @@ impl TestNetFactory for GrandpaTestNet {
|
||||
PassThroughVerifier(false) // use non-instant finality.
|
||||
}
|
||||
|
||||
fn make_block_import(&self, client: PeersClient)
|
||||
fn make_block_import<Transaction>(&self, client: PeersClient)
|
||||
-> (
|
||||
BoxBlockImport<Block>,
|
||||
BlockImportAdapter<Transaction>,
|
||||
Option<BoxJustificationImport<Block>>,
|
||||
Option<BoxFinalityProofImport<Block>>,
|
||||
Option<BoxFinalityProofRequestBuilder<Block>>,
|
||||
@@ -125,8 +132,13 @@ impl TestNetFactory for GrandpaTestNet {
|
||||
LongestChain::new(backend.clone()),
|
||||
).expect("Could not create block import for fresh peer.");
|
||||
let justification_import = Box::new(import.clone());
|
||||
let block_import = Box::new(import);
|
||||
(block_import, Some(justification_import), None, None, Mutex::new(Some(link)))
|
||||
(
|
||||
BlockImportAdapter::new_full(import),
|
||||
Some(justification_import),
|
||||
None,
|
||||
None,
|
||||
Mutex::new(Some(link)),
|
||||
)
|
||||
},
|
||||
PeersClient::Light(ref client, ref backend) => {
|
||||
use crate::light_import::tests::light_block_import_without_justifications;
|
||||
@@ -142,8 +154,13 @@ impl TestNetFactory for GrandpaTestNet {
|
||||
).expect("Could not create block import for fresh peer.");
|
||||
let finality_proof_req_builder = import.0.create_finality_proof_request_builder();
|
||||
let proof_import = Box::new(import.clone());
|
||||
let block_import = Box::new(import);
|
||||
(block_import, None, Some(proof_import), Some(finality_proof_req_builder), Mutex::new(None))
|
||||
(
|
||||
BlockImportAdapter::new_light(import),
|
||||
None,
|
||||
Some(proof_import),
|
||||
Some(finality_proof_req_builder),
|
||||
Mutex::new(None),
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -202,7 +219,7 @@ pub(crate) struct RuntimeApi {
|
||||
inner: TestApi,
|
||||
}
|
||||
|
||||
impl ProvideRuntimeApi for TestApi {
|
||||
impl ProvideRuntimeApi<Block> for TestApi {
|
||||
type Api = RuntimeApi;
|
||||
|
||||
fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> {
|
||||
@@ -242,8 +259,14 @@ impl Core<Block> for RuntimeApi {
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiExt<Block> for RuntimeApi {
|
||||
impl ApiErrorExt for RuntimeApi {
|
||||
type Error = sp_blockchain::Error;
|
||||
}
|
||||
|
||||
impl ApiExt<Block> for RuntimeApi {
|
||||
type StateBackend = <
|
||||
substrate_test_runtime_client::Backend as sc_client_api::backend::Backend<Block>
|
||||
>::State;
|
||||
|
||||
fn map_api_result<F: FnOnce(&Self) -> result::Result<R, E>, R, E>(
|
||||
&self,
|
||||
@@ -263,6 +286,19 @@ impl ApiExt<Block> for RuntimeApi {
|
||||
fn extract_proof(&mut self) -> Option<StorageProof> {
|
||||
unimplemented!("Not required for testing!")
|
||||
}
|
||||
|
||||
fn into_storage_changes<
|
||||
T: sp_api::ChangesTrieStorage<sp_api::HasherFor<Block>, sp_api::NumberFor<Block>>
|
||||
>(
|
||||
&self,
|
||||
_: &Self::StateBackend,
|
||||
_: Option<&T>,
|
||||
_: <Block as sp_api::BlockT>::Hash,
|
||||
) -> std::result::Result<sp_api::StorageChanges<Self::StateBackend, Block>, String>
|
||||
where Self: Sized
|
||||
{
|
||||
unimplemented!("Not required for testing!")
|
||||
}
|
||||
}
|
||||
|
||||
impl GrandpaApi<Block> for RuntimeApi {
|
||||
@@ -290,7 +326,7 @@ impl AuthoritySetForFinalityProver<Block> for TestApi {
|
||||
|
||||
fn prove_authorities(&self, block: &BlockId<Block>) -> Result<StorageProof> {
|
||||
let authorities = self.authorities(block)?;
|
||||
let backend = <InMemory<Blake2Hasher>>::from(vec![
|
||||
let backend = <InMemoryBackend<HasherFor<Block>>>::from(vec![
|
||||
(None, vec![(b"authorities".to_vec(), Some(authorities.encode()))])
|
||||
]);
|
||||
let proof = prove_read(backend, vec![b"authorities"])
|
||||
@@ -306,7 +342,7 @@ impl AuthoritySetForFinalityChecker<Block> for TestApi {
|
||||
header: <Block as BlockT>::Header,
|
||||
proof: StorageProof,
|
||||
) -> Result<AuthorityList> {
|
||||
let results = read_proof_check::<Blake2Hasher, _>(
|
||||
let results = read_proof_check::<HasherFor<Block>, _>(
|
||||
*header.state_root(), proof, vec![b"authorities"]
|
||||
)
|
||||
.expect("failure checking read proof for authorities");
|
||||
@@ -629,7 +665,7 @@ fn transition_3_voters_twice_1_full_observer() {
|
||||
14 => {
|
||||
// generate transition at block 15, applied at 20.
|
||||
net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
let mut block = builder.bake().unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
add_scheduled_change(&mut block, ScheduledChange {
|
||||
next_authorities: make_ids(peers_b),
|
||||
delay: 4,
|
||||
@@ -643,7 +679,7 @@ fn transition_3_voters_twice_1_full_observer() {
|
||||
// at block 21 we do another transition, but this time instant.
|
||||
// add more until we have 30.
|
||||
net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
let mut block = builder.bake().unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
add_scheduled_change(&mut block, ScheduledChange {
|
||||
next_authorities: make_ids(&peers_c),
|
||||
delay: 0,
|
||||
@@ -808,7 +844,7 @@ fn sync_justifications_on_change_blocks() {
|
||||
|
||||
// at block 21 we do add a transition which is instant
|
||||
net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
let mut block = builder.bake().unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
add_scheduled_change(&mut block, ScheduledChange {
|
||||
next_authorities: make_ids(peers_b),
|
||||
delay: 0,
|
||||
@@ -870,7 +906,7 @@ fn finalizes_multiple_pending_changes_in_order() {
|
||||
|
||||
// at block 21 we do add a transition which is instant
|
||||
net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
let mut block = builder.bake().unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
add_scheduled_change(&mut block, ScheduledChange {
|
||||
next_authorities: make_ids(peers_b),
|
||||
delay: 0,
|
||||
@@ -883,7 +919,7 @@ fn finalizes_multiple_pending_changes_in_order() {
|
||||
|
||||
// at block 26 we add another which is enacted at block 30
|
||||
net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
let mut block = builder.bake().unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
add_scheduled_change(&mut block, ScheduledChange {
|
||||
next_authorities: make_ids(peers_c),
|
||||
delay: 4,
|
||||
@@ -927,7 +963,7 @@ fn force_change_to_new_set() {
|
||||
let net = Arc::new(Mutex::new(net));
|
||||
|
||||
net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
let mut block = builder.bake().unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
|
||||
// add a forced transition at block 12.
|
||||
add_forced_change(&mut block, 0, ScheduledChange {
|
||||
@@ -973,11 +1009,15 @@ fn allows_reimporting_change_blocks() {
|
||||
let mut net = GrandpaTestNet::new(api.clone(), 3);
|
||||
|
||||
let client = net.peer(0).client().clone();
|
||||
let (mut block_import, ..) = net.make_block_import(client.clone());
|
||||
let (mut block_import, ..) = net.make_block_import::<
|
||||
TransactionFor<substrate_test_runtime_client::Backend, Block>
|
||||
>(
|
||||
client.clone(),
|
||||
);
|
||||
|
||||
let full_client = client.as_full().unwrap();
|
||||
let builder = full_client.new_block_at(&BlockId::Number(0), Default::default()).unwrap();
|
||||
let mut block = builder.bake().unwrap();
|
||||
let builder = full_client.new_block_at(&BlockId::Number(0), Default::default(), false).unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
add_scheduled_change(&mut block, ScheduledChange {
|
||||
next_authorities: make_ids(peers_b),
|
||||
delay: 0,
|
||||
@@ -991,6 +1031,7 @@ fn allows_reimporting_change_blocks() {
|
||||
justification: None,
|
||||
post_digests: Vec::new(),
|
||||
body: Some(block.extrinsics),
|
||||
storage_changes: None,
|
||||
finalized: false,
|
||||
auxiliary: Vec::new(),
|
||||
fork_choice: ForkChoiceStrategy::LongestChain,
|
||||
@@ -1026,11 +1067,15 @@ fn test_bad_justification() {
|
||||
let mut net = GrandpaTestNet::new(api.clone(), 3);
|
||||
|
||||
let client = net.peer(0).client().clone();
|
||||
let (mut block_import, ..) = net.make_block_import(client.clone());
|
||||
let (mut block_import, ..) = net.make_block_import::<
|
||||
TransactionFor<substrate_test_runtime_client::Backend, Block>
|
||||
>(
|
||||
client.clone(),
|
||||
);
|
||||
|
||||
let full_client = client.as_full().expect("only full clients are used in test");
|
||||
let builder = full_client.new_block_at(&BlockId::Number(0), Default::default()).unwrap();
|
||||
let mut block = builder.bake().unwrap();
|
||||
let builder = full_client.new_block_at(&BlockId::Number(0), Default::default(), false).unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
|
||||
add_scheduled_change(&mut block, ScheduledChange {
|
||||
next_authorities: make_ids(peers_b),
|
||||
@@ -1045,6 +1090,7 @@ fn test_bad_justification() {
|
||||
justification: Some(Vec::new()),
|
||||
post_digests: Vec::new(),
|
||||
body: Some(block.extrinsics),
|
||||
storage_changes: None,
|
||||
finalized: false,
|
||||
auxiliary: Vec::new(),
|
||||
fork_choice: ForkChoiceStrategy::LongestChain,
|
||||
@@ -1136,7 +1182,10 @@ fn voter_persists_its_votes() {
|
||||
Ok(Async::NotReady) => {}
|
||||
Ok(Async::Ready(Some(()))) => {
|
||||
let (_block_import, _, _, _, link) =
|
||||
self.net.lock().make_block_import(self.client.clone());
|
||||
self.net.lock()
|
||||
.make_block_import::<
|
||||
TransactionFor<substrate_test_runtime_client::Backend, Block>
|
||||
>(self.client.clone());
|
||||
let link = link.lock().take().unwrap();
|
||||
|
||||
let grandpa_params = GrandpaParams {
|
||||
@@ -1209,7 +1258,10 @@ fn voter_persists_its_votes() {
|
||||
};
|
||||
|
||||
let set_state = {
|
||||
let (_, _, _, _, link) = net.lock().make_block_import(client);
|
||||
let (_, _, _, _, link) = net.lock()
|
||||
.make_block_import::<
|
||||
TransactionFor<substrate_test_runtime_client::Backend, Block>
|
||||
>(client);
|
||||
let LinkHalf { persistent_data, .. } = link.lock().take().unwrap();
|
||||
let PersistentData { set_state, .. } = persistent_data;
|
||||
set_state
|
||||
@@ -1439,7 +1491,7 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ
|
||||
// best is #1
|
||||
net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
// add a forced transition at block 5.
|
||||
let mut block = builder.bake().unwrap();
|
||||
let mut block = builder.build().unwrap().block;
|
||||
if FORCE_CHANGE {
|
||||
add_forced_change(&mut block, 0, ScheduledChange {
|
||||
next_authorities: voters.clone(),
|
||||
@@ -1728,11 +1780,13 @@ fn imports_justification_for_regular_blocks_on_import() {
|
||||
let mut net = GrandpaTestNet::new(api.clone(), 1);
|
||||
|
||||
let client = net.peer(0).client().clone();
|
||||
let (mut block_import, ..) = net.make_block_import(client.clone());
|
||||
let (mut block_import, ..) = net.make_block_import::<
|
||||
TransactionFor<substrate_test_runtime_client::Backend, Block>
|
||||
>(client.clone());
|
||||
|
||||
let full_client = client.as_full().expect("only full clients are used in test");
|
||||
let builder = full_client.new_block_at(&BlockId::Number(0), Default::default()).unwrap();
|
||||
let block = builder.bake().unwrap();
|
||||
let builder = full_client.new_block_at(&BlockId::Number(0), Default::default(), false).unwrap();
|
||||
let block = builder.build().unwrap().block;
|
||||
|
||||
let block_hash = block.hash();
|
||||
|
||||
@@ -1776,6 +1830,7 @@ fn imports_justification_for_regular_blocks_on_import() {
|
||||
justification: Some(justification.encode()),
|
||||
post_digests: Vec::new(),
|
||||
body: Some(block.extrinsics),
|
||||
storage_changes: None,
|
||||
finalized: false,
|
||||
auxiliary: Vec::new(),
|
||||
fork_choice: ForkChoiceStrategy::LongestChain,
|
||||
|
||||
Reference in New Issue
Block a user