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:
Bastian Köcher
2020-01-10 10:48:32 +01:00
committed by GitHub
parent 74d6e660c6
commit fd6b29dd2c
140 changed files with 4860 additions and 3339 deletions
+36 -26
View File
@@ -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,
{