mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 04:11:09 +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:
@@ -54,15 +54,20 @@ use sp_blockchain::{
|
||||
};
|
||||
use sp_block_builder::BlockBuilder as BlockBuilderApi;
|
||||
use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, Justification};
|
||||
use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, Member};
|
||||
use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor, Zero, Member};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
|
||||
use sp_core::crypto::Pair;
|
||||
use sp_inherents::{InherentDataProviders, InherentData};
|
||||
use sp_timestamp::{
|
||||
TimestampInherentData, InherentType as TimestampInherent, InherentError as TIError
|
||||
};
|
||||
use sc_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, CONSENSUS_INFO};
|
||||
use sc_consensus_slots::{CheckedHeader, SlotWorker, SlotInfo, SlotCompatible};
|
||||
use sc_consensus_slots::check_equivocation;
|
||||
|
||||
use sc_consensus_slots::{
|
||||
CheckedHeader, SlotWorker, SlotInfo, SlotCompatible, StorageChanges, check_equivocation,
|
||||
};
|
||||
|
||||
use sc_keystore::KeyStorePtr;
|
||||
use sp_api::ApiExt;
|
||||
|
||||
@@ -91,7 +96,7 @@ impl SlotDuration {
|
||||
where
|
||||
A: Codec,
|
||||
B: BlockT,
|
||||
C: AuxStore + ProvideRuntimeApi,
|
||||
C: AuxStore + ProvideRuntimeApi<B>,
|
||||
C::Api: AuraApi<B, A, Error = sp_blockchain::Error>,
|
||||
{
|
||||
sc_consensus_slots::SlotDuration::get_or_compute(client, |a, b| a.slot_duration(b)).map(Self)
|
||||
@@ -137,7 +142,7 @@ impl SlotCompatible for AuraSlotCompatible {
|
||||
}
|
||||
|
||||
/// Start the aura worker. The returned future should be run in a futures executor.
|
||||
pub fn start_aura<B, C, SC, E, I, P, SO, CAW, Error, H>(
|
||||
pub fn start_aura<B, C, SC, E, I, P, SO, CAW, Error>(
|
||||
slot_duration: SlotDuration,
|
||||
client: Arc<C>,
|
||||
select_chain: SC,
|
||||
@@ -149,19 +154,17 @@ pub fn start_aura<B, C, SC, E, I, P, SO, CAW, Error, H>(
|
||||
keystore: KeyStorePtr,
|
||||
can_author_with: CAW,
|
||||
) -> Result<impl futures01::Future<Item = (), Error = ()>, sp_consensus::Error> where
|
||||
B: BlockT<Header=H>,
|
||||
C: ProvideRuntimeApi + BlockOf + ProvideCache<B> + AuxStore + Send + Sync,
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> + BlockOf + ProvideCache<B> + AuxStore + Send + Sync,
|
||||
C::Api: AuraApi<B, AuthorityId<P>>,
|
||||
SC: SelectChain<B>,
|
||||
E: Environment<B, Error=Error> + Send + Sync + 'static,
|
||||
E::Proposer: Proposer<B, Error=Error>,
|
||||
<E::Proposer as Proposer<B>>::Create: Unpin + Send,
|
||||
E: Environment<B, Error = Error> + Send + Sync + 'static,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
P: Pair + Send + Sync,
|
||||
P::Public: Hash + Member + Encode + Decode,
|
||||
P::Signature: Hash + Member + Encode + Decode,
|
||||
H: Header<Hash=B::Hash>,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
Error: ::std::error::Error + Send + From<::sp_consensus::Error> + From<I::Error> + 'static,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
Error: std::error::Error + Send + From<sp_consensus::Error> + 'static,
|
||||
SO: SyncOracle + Send + Sync + Clone,
|
||||
CAW: CanAuthorWith<B> + Send,
|
||||
{
|
||||
@@ -199,20 +202,18 @@ struct AuraWorker<C, E, I, P, SO> {
|
||||
_key_type: PhantomData<P>,
|
||||
}
|
||||
|
||||
impl<H, B, C, E, I, P, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for AuraWorker<C, E, I, P, SO> where
|
||||
B: BlockT<Header=H>,
|
||||
C: ProvideRuntimeApi + BlockOf + ProvideCache<B> + Sync,
|
||||
impl<B, C, E, I, P, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for AuraWorker<C, E, I, P, SO> where
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> + BlockOf + ProvideCache<B> + Sync,
|
||||
C::Api: AuraApi<B, AuthorityId<P>>,
|
||||
E: Environment<B, Error=Error>,
|
||||
E::Proposer: Proposer<B, Error=Error>,
|
||||
<E::Proposer as Proposer<B>>::Create: Unpin + Send,
|
||||
H: Header<Hash=B::Hash>,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
E: Environment<B, Error = Error>,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
P: Pair + Send + Sync,
|
||||
P::Public: Member + Encode + Decode + Hash,
|
||||
P::Signature: Member + Encode + Decode + Hash + Debug,
|
||||
SO: SyncOracle + Send + Clone,
|
||||
Error: ::std::error::Error + Send + From<::sp_consensus::Error> + From<I::Error> + 'static,
|
||||
Error: std::error::Error + Send + From<sp_consensus::Error> + 'static,
|
||||
{
|
||||
type BlockImport = I;
|
||||
type SyncOracle = SO;
|
||||
@@ -228,7 +229,11 @@ impl<H, B, C, E, I, P, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for Au
|
||||
self.block_import.clone()
|
||||
}
|
||||
|
||||
fn epoch_data(&self, header: &B::Header, _slot_number: u64) -> Result<Self::EpochData, sp_consensus::Error> {
|
||||
fn epoch_data(
|
||||
&self,
|
||||
header: &B::Header,
|
||||
_slot_number: u64,
|
||||
) -> Result<Self::EpochData, sp_consensus::Error> {
|
||||
authorities(self.client.as_ref(), &BlockId::Hash(header.hash()))
|
||||
}
|
||||
|
||||
@@ -250,7 +255,11 @@ impl<H, B, C, E, I, P, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for Au
|
||||
})
|
||||
}
|
||||
|
||||
fn pre_digest_data(&self, slot_number: u64, _claim: &Self::Claim) -> Vec<sp_runtime::DigestItem<B::Hash>> {
|
||||
fn pre_digest_data(
|
||||
&self,
|
||||
slot_number: u64,
|
||||
_claim: &Self::Claim,
|
||||
) -> Vec<sp_runtime::DigestItem<B::Hash>> {
|
||||
vec![
|
||||
<DigestItemFor<B> as CompatibleDigestItem<P>>::aura_pre_digest(slot_number),
|
||||
]
|
||||
@@ -260,9 +269,10 @@ impl<H, B, C, E, I, P, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for Au
|
||||
B::Header,
|
||||
&B::Hash,
|
||||
Vec<B::Extrinsic>,
|
||||
StorageChanges<sp_api::TransactionFor<C, B>, B>,
|
||||
Self::Claim,
|
||||
) -> sp_consensus::BlockImportParams<B> + Send> {
|
||||
Box::new(|header, header_hash, body, pair| {
|
||||
) -> sp_consensus::BlockImportParams<B, sp_api::TransactionFor<C, B>> + Send> {
|
||||
Box::new(|header, header_hash, body, storage_changes, pair| {
|
||||
// sign the pre-sealed hash of the block and then
|
||||
// add it to a digest item.
|
||||
let signature = pair.sign(header_hash.as_ref());
|
||||
@@ -274,6 +284,7 @@ impl<H, B, C, E, I, P, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for Au
|
||||
justification: None,
|
||||
post_digests: vec![signature_digest_item],
|
||||
body: Some(body),
|
||||
storage_changes: Some(storage_changes),
|
||||
finalized: false,
|
||||
auxiliary: Vec::new(),
|
||||
fork_choice: ForkChoiceStrategy::LongestChain,
|
||||
@@ -324,20 +335,18 @@ impl<H, B, C, E, I, P, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for Au
|
||||
}
|
||||
}
|
||||
|
||||
impl<H, B: BlockT, C, E, I, P, Error, SO> SlotWorker<B> for AuraWorker<C, E, I, P, SO> where
|
||||
B: BlockT<Header=H>,
|
||||
C: ProvideRuntimeApi + BlockOf + ProvideCache<B> + Sync + Send,
|
||||
impl<B: BlockT, C, E, I, P, Error, SO> SlotWorker<B> for AuraWorker<C, E, I, P, SO> where
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> + BlockOf + ProvideCache<B> + Sync + Send,
|
||||
C::Api: AuraApi<B, AuthorityId<P>>,
|
||||
E: Environment<B, Error=Error> + Send + Sync,
|
||||
E::Proposer: Proposer<B, Error=Error>,
|
||||
<E::Proposer as Proposer<B>>::Create: Unpin + Send + 'static,
|
||||
H: Header<Hash=B::Hash>,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
E: Environment<B, Error = Error> + Send + Sync,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
P: Pair + Send + Sync,
|
||||
P::Public: Member + Encode + Decode + Hash,
|
||||
P::Signature: Member + Encode + Decode + Hash + Debug,
|
||||
SO: SyncOracle + Send + Sync + Clone,
|
||||
Error: ::std::error::Error + Send + From<::sp_consensus::Error> + From<I::Error> + 'static,
|
||||
Error: std::error::Error + Send + From<sp_consensus::Error> + 'static,
|
||||
{
|
||||
type OnSlot = Pin<Box<dyn Future<Output = Result<(), sp_consensus::Error>> + Send>>;
|
||||
|
||||
@@ -489,7 +498,7 @@ impl<C, P, T> AuraVerifier<C, P, T>
|
||||
inherent_data: InherentData,
|
||||
timestamp_now: u64,
|
||||
) -> Result<(), Error<B>>
|
||||
where C: ProvideRuntimeApi, C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>
|
||||
where C: ProvideRuntimeApi<B>, C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>
|
||||
{
|
||||
const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60;
|
||||
|
||||
@@ -535,7 +544,12 @@ impl<C, P, T> AuraVerifier<C, P, T>
|
||||
|
||||
#[forbid(deprecated)]
|
||||
impl<B: BlockT, C, P, T> Verifier<B> for AuraVerifier<C, P, T> where
|
||||
C: ProvideRuntimeApi + Send + Sync + sc_client_api::backend::AuxStore + ProvideCache<B> + BlockOf,
|
||||
C: ProvideRuntimeApi<B> +
|
||||
Send +
|
||||
Sync +
|
||||
sc_client_api::backend::AuxStore +
|
||||
ProvideCache<B> +
|
||||
BlockOf,
|
||||
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B, Error = sp_blockchain::Error>,
|
||||
DigestItemFor<B>: CompatibleDigestItem<P>,
|
||||
P: Pair + Send + Sync + 'static,
|
||||
@@ -549,7 +563,7 @@ impl<B: BlockT, C, P, T> Verifier<B> for AuraVerifier<C, P, T> where
|
||||
header: B::Header,
|
||||
justification: Option<Justification>,
|
||||
mut body: Option<Vec<B::Extrinsic>>,
|
||||
) -> Result<(BlockImportParams<B>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
) -> Result<(BlockImportParams<B, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
let mut inherent_data = self.inherent_data_providers
|
||||
.create_inherent_data()
|
||||
.map_err(|e| e.into_string())?;
|
||||
@@ -623,6 +637,7 @@ impl<B: BlockT, C, P, T> Verifier<B> for AuraVerifier<C, P, T> where
|
||||
header: pre_header,
|
||||
post_digests: vec![seal],
|
||||
body,
|
||||
storage_changes: None,
|
||||
finalized: false,
|
||||
justification,
|
||||
auxiliary: Vec::new(),
|
||||
@@ -647,7 +662,7 @@ impl<B: BlockT, C, P, T> Verifier<B> for AuraVerifier<C, P, T> where
|
||||
fn initialize_authorities_cache<A, B, C>(client: &C) -> Result<(), ConsensusError> where
|
||||
A: Codec,
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi + BlockOf + ProvideCache<B>,
|
||||
C: ProvideRuntimeApi<B> + BlockOf + ProvideCache<B>,
|
||||
C::Api: AuraApi<B, A>,
|
||||
{
|
||||
// no cache => no initialization
|
||||
@@ -681,7 +696,7 @@ fn initialize_authorities_cache<A, B, C>(client: &C) -> Result<(), ConsensusErro
|
||||
fn authorities<A, B, C>(client: &C, at: &BlockId<B>) -> Result<Vec<A>, ConsensusError> where
|
||||
A: Codec,
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi + BlockOf + ProvideCache<B>,
|
||||
C: ProvideRuntimeApi<B> + BlockOf + ProvideCache<B>,
|
||||
C::Api: AuraApi<B, A>,
|
||||
{
|
||||
client
|
||||
@@ -695,7 +710,7 @@ fn authorities<A, B, C>(client: &C, at: &BlockId<B>) -> Result<Vec<A>, Consensus
|
||||
}
|
||||
|
||||
/// The Aura import queue type.
|
||||
pub type AuraImportQueue<B> = BasicQueue<B>;
|
||||
pub type AuraImportQueue<B, Transaction> = BasicQueue<B, Transaction>;
|
||||
|
||||
/// Register the aura inherent data provider, if not registered already.
|
||||
fn register_aura_inherent_data_provider(
|
||||
@@ -744,14 +759,15 @@ impl<Block: BlockT, C, I: BlockImport<Block>, P> AuraBlockImport<Block, C, I, P>
|
||||
}
|
||||
|
||||
impl<Block: BlockT, C, I, P> BlockImport<Block> for AuraBlockImport<Block, C, I, P> where
|
||||
I: BlockImport<Block> + Send + Sync,
|
||||
I: BlockImport<Block, Transaction = sp_api::TransactionFor<C, Block>> + Send + Sync,
|
||||
I::Error: Into<ConsensusError>,
|
||||
C: HeaderBackend<Block>,
|
||||
C: HeaderBackend<Block> + ProvideRuntimeApi<Block>,
|
||||
P: Pair + Send + Sync + 'static,
|
||||
P::Public: Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode,
|
||||
P::Signature: Encode + Decode,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = sp_api::TransactionFor<C, Block>;
|
||||
|
||||
fn check_block(
|
||||
&mut self,
|
||||
@@ -762,7 +778,7 @@ impl<Block: BlockT, C, I, P> BlockImport<Block> for AuraBlockImport<Block, C, I,
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<Block>,
|
||||
block: BlockImportParams<Block, Self::Transaction>,
|
||||
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
let hash = block.post_header().hash();
|
||||
@@ -790,8 +806,7 @@ impl<Block: BlockT, C, I, P> BlockImport<Block> for AuraBlockImport<Block, C, I,
|
||||
);
|
||||
}
|
||||
|
||||
self.inner.import_block(block, new_cache)
|
||||
.map_err(Into::into)
|
||||
self.inner.import_block(block, new_cache).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -804,11 +819,11 @@ pub fn import_queue<B, I, C, P, T>(
|
||||
client: Arc<C>,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
transaction_pool: Option<Arc<T>>,
|
||||
) -> Result<AuraImportQueue<B>, sp_consensus::Error> where
|
||||
) -> Result<AuraImportQueue<B, sp_api::TransactionFor<C, B>>, sp_consensus::Error> where
|
||||
B: BlockT,
|
||||
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B, Error = sp_blockchain::Error>,
|
||||
C: 'static + ProvideRuntimeApi + BlockOf + ProvideCache<B> + Send + Sync + AuxStore + HeaderBackend<B>,
|
||||
I: BlockImport<B,Error=ConsensusError> + Send + Sync + 'static,
|
||||
C: 'static + ProvideRuntimeApi<B> + BlockOf + ProvideCache<B> + Send + Sync + AuxStore + HeaderBackend<B>,
|
||||
I: BlockImport<B, Error=ConsensusError, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
DigestItemFor<B>: CompatibleDigestItem<P>,
|
||||
P: Pair + Send + Sync + 'static,
|
||||
P::Public: Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode,
|
||||
@@ -835,7 +850,7 @@ pub fn import_queue<B, I, C, P, T>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sp_consensus::NoNetwork as DummyOracle;
|
||||
use sp_consensus::{NoNetwork as DummyOracle, Proposal, RecordProof};
|
||||
use sc_network_test::{Block as TestBlock, *};
|
||||
use sp_runtime::traits::{Block as BlockT, DigestFor};
|
||||
use sc_network::config::ProtocolConfig;
|
||||
@@ -870,16 +885,26 @@ mod tests {
|
||||
|
||||
impl Proposer<TestBlock> for DummyProposer {
|
||||
type Error = Error;
|
||||
type Create = future::Ready<Result<TestBlock, Error>>;
|
||||
type Transaction = sc_client_api::TransactionFor<
|
||||
substrate_test_runtime_client::Backend,
|
||||
TestBlock
|
||||
>;
|
||||
type Proposal = future::Ready<Result<Proposal<TestBlock, Self::Transaction>, Error>>;
|
||||
|
||||
fn propose(
|
||||
&mut self,
|
||||
_: InherentData,
|
||||
digests: DigestFor<TestBlock>,
|
||||
_: Duration,
|
||||
) -> Self::Create {
|
||||
let r = self.1.new_block(digests).unwrap().bake().map_err(|e| e.into());
|
||||
future::ready(r)
|
||||
_: RecordProof,
|
||||
) -> Self::Proposal {
|
||||
let r = self.1.new_block(digests).unwrap().build().map_err(|e| e.into());
|
||||
|
||||
future::ready(r.map(|b| Proposal {
|
||||
block: b.block,
|
||||
proof: b.proof,
|
||||
storage_changes: b.storage_changes,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,7 +1008,7 @@ mod tests {
|
||||
&inherent_data_providers, slot_duration.get()
|
||||
).expect("Registers aura inherent data provider");
|
||||
|
||||
let aura = start_aura::<_, _, _, _, _, AuthorityPair, _, _, _, _>(
|
||||
let aura = start_aura::<_, _, _, _, _, AuthorityPair, _, _, _>(
|
||||
slot_duration,
|
||||
client.clone(),
|
||||
select_chain,
|
||||
|
||||
@@ -27,7 +27,6 @@ use sp_runtime::traits::{Block as BlockT, NumberFor, One, Zero};
|
||||
use codec::{Encode, Decode};
|
||||
use sc_client_api::utils::is_descendent_of;
|
||||
use sp_blockchain::{HeaderMetadata, HeaderBackend, Error as ClientError};
|
||||
use sp_core::H256;
|
||||
use std::ops::Add;
|
||||
|
||||
/// A builder for `is_descendent_of` functions.
|
||||
@@ -57,17 +56,15 @@ pub(crate) fn descendent_query<H, Block>(client: &H) -> HeaderBackendDescendentB
|
||||
/// `IsDescendentOfBuilder` for header backends.
|
||||
pub(crate) struct HeaderBackendDescendentBuilder<H, Block>(H, std::marker::PhantomData<Block>);
|
||||
|
||||
// TODO: relying on Hash = H256 is awful.
|
||||
// https://github.com/paritytech/substrate/issues/3624
|
||||
impl<'a, H, Block> IsDescendentOfBuilder<H256>
|
||||
impl<'a, H, Block> IsDescendentOfBuilder<Block::Hash>
|
||||
for HeaderBackendDescendentBuilder<&'a H, Block> where
|
||||
H: HeaderBackend<Block> + HeaderMetadata<Block, Error=ClientError>,
|
||||
Block: BlockT<Hash = H256>,
|
||||
Block: BlockT,
|
||||
{
|
||||
type Error = ClientError;
|
||||
type IsDescendentOf = Box<dyn Fn(&H256, &H256) -> Result<bool, ClientError> + 'a>;
|
||||
type IsDescendentOf = Box<dyn Fn(&Block::Hash, &Block::Hash) -> Result<bool, ClientError> + 'a>;
|
||||
|
||||
fn build_is_descendent_of(&self, current: Option<(H256, H256)>)
|
||||
fn build_is_descendent_of(&self, current: Option<(Block::Hash, Block::Hash)>)
|
||||
-> Self::IsDescendentOf
|
||||
{
|
||||
Box::new(is_descendent_of(self.0, current))
|
||||
|
||||
@@ -69,14 +69,14 @@ use sp_consensus::{ImportResult, CanAuthorWith};
|
||||
use sp_consensus::import_queue::{
|
||||
BoxJustificationImport, BoxFinalityProofImport,
|
||||
};
|
||||
use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, Justification};
|
||||
use sp_runtime::traits::{
|
||||
Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi,
|
||||
Zero,
|
||||
use sp_runtime::{
|
||||
generic::{BlockId, OpaqueDigestItemId}, Justification,
|
||||
traits::{Block as BlockT, Header, DigestItemFor, Zero},
|
||||
};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sc_keystore::KeyStorePtr;
|
||||
use parking_lot::Mutex;
|
||||
use sp_core::{Blake2Hasher, H256, Pair};
|
||||
use sp_core::Pair;
|
||||
use sp_inherents::{InherentDataProviders, InherentData};
|
||||
use sc_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG};
|
||||
use sp_consensus::{
|
||||
@@ -96,10 +96,11 @@ use sc_client::Client;
|
||||
|
||||
use sp_block_builder::BlockBuilder as BlockBuilderApi;
|
||||
|
||||
use sc_consensus_slots::{CheckedHeader, check_equivocation};
|
||||
use futures::prelude::*;
|
||||
use log::{warn, debug, info, trace};
|
||||
use sc_consensus_slots::{SlotWorker, SlotInfo, SlotCompatible};
|
||||
use sc_consensus_slots::{
|
||||
SlotWorker, SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation,
|
||||
};
|
||||
use epoch_changes::descendent_query;
|
||||
use sp_blockchain::{
|
||||
Result as ClientResult, Error as ClientError,
|
||||
@@ -207,7 +208,7 @@ impl Config {
|
||||
/// Either fetch the slot duration from disk or compute it from the genesis
|
||||
/// state.
|
||||
pub fn get_or_compute<B: BlockT, C>(client: &C) -> ClientResult<Self> where
|
||||
C: AuxStore + ProvideRuntimeApi, C::Api: BabeApi<B, Error = sp_blockchain::Error>,
|
||||
C: AuxStore + ProvideRuntimeApi<B>, C::Api: BabeApi<B, Error = sp_blockchain::Error>,
|
||||
{
|
||||
trace!(target: "babe", "Getting slot duration");
|
||||
match sc_consensus_slots::SlotDuration::get_or_compute(client, |a, b| a.configuration(b)).map(Self) {
|
||||
@@ -291,16 +292,16 @@ pub fn start_babe<B, C, SC, E, I, SO, CAW, Error>(BabeParams {
|
||||
impl futures01::Future<Item=(), Error=()>,
|
||||
sp_consensus::Error,
|
||||
> where
|
||||
B: BlockT<Hash=H256>,
|
||||
C: ProvideRuntimeApi + ProvideCache<B> + ProvideUncles<B> + BlockchainEvents<B>
|
||||
+ HeaderBackend<B> + HeaderMetadata<B, Error=ClientError> + Send + Sync + 'static,
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> + ProvideCache<B> + ProvideUncles<B> + BlockchainEvents<B>
|
||||
+ HeaderBackend<B> + HeaderMetadata<B, Error = ClientError> + Send + Sync + 'static,
|
||||
C::Api: BabeApi<B>,
|
||||
SC: SelectChain<B> + 'static,
|
||||
E: Environment<B, Error=Error> + Send + Sync,
|
||||
E::Proposer: Proposer<B, Error=Error>,
|
||||
<E::Proposer as Proposer<B>>::Create: Unpin + Send + 'static,
|
||||
I: BlockImport<B,Error=ConsensusError> + Send + Sync + 'static,
|
||||
Error: std::error::Error + Send + From<::sp_consensus::Error> + From<I::Error> + 'static,
|
||||
E: Environment<B, Error = Error> + Send + Sync,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
I: BlockImport<B, Error = ConsensusError, Transaction = sp_api::TransactionFor<C, B>> + Send
|
||||
+ Sync + 'static,
|
||||
Error: std::error::Error + Send + From<ConsensusError> + From<I::Error> + 'static,
|
||||
SO: SyncOracle + Send + Sync + Clone,
|
||||
CAW: CanAuthorWith<B> + Send,
|
||||
{
|
||||
@@ -349,15 +350,17 @@ struct BabeWorker<B: BlockT, C, E, I, SO> {
|
||||
}
|
||||
|
||||
impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWorker<B, C, E, I, SO> where
|
||||
B: BlockT<Hash=H256>,
|
||||
C: ProvideRuntimeApi + ProvideCache<B> + HeaderBackend<B> + HeaderMetadata<B, Error=ClientError>,
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> +
|
||||
ProvideCache<B> +
|
||||
HeaderBackend<B> +
|
||||
HeaderMetadata<B, Error = ClientError>,
|
||||
C::Api: BabeApi<B>,
|
||||
E: Environment<B, Error=Error>,
|
||||
E::Proposer: Proposer<B, Error=Error>,
|
||||
<E::Proposer as Proposer<B>>::Create: Unpin + Send + 'static,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
E: Environment<B, Error = Error>,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
SO: SyncOracle + Send + Clone,
|
||||
Error: std::error::Error + Send + From<::sp_consensus::Error> + From<I::Error> + 'static,
|
||||
Error: std::error::Error + Send + From<ConsensusError> + From<I::Error> + 'static,
|
||||
{
|
||||
type EpochData = Epoch;
|
||||
type Claim = (BabePreDigest, AuthorityPair);
|
||||
@@ -373,7 +376,11 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWork
|
||||
self.block_import.clone()
|
||||
}
|
||||
|
||||
fn epoch_data(&self, parent: &B::Header, slot_number: u64) -> Result<Self::EpochData, sp_consensus::Error> {
|
||||
fn epoch_data(
|
||||
&self,
|
||||
parent: &B::Header,
|
||||
slot_number: u64,
|
||||
) -> Result<Self::EpochData, ConsensusError> {
|
||||
self.epoch_changes.lock().epoch_for_child_of(
|
||||
descendent_query(&*self.client),
|
||||
&parent.hash(),
|
||||
@@ -411,7 +418,11 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWork
|
||||
s
|
||||
}
|
||||
|
||||
fn pre_digest_data(&self, _slot_number: u64, claim: &Self::Claim) -> Vec<sp_runtime::DigestItem<B::Hash>> {
|
||||
fn pre_digest_data(
|
||||
&self,
|
||||
_slot_number: u64,
|
||||
claim: &Self::Claim,
|
||||
) -> Vec<sp_runtime::DigestItem<B::Hash>> {
|
||||
vec![
|
||||
<DigestItemFor<B> as CompatibleDigestItem>::babe_pre_digest(claim.0.clone()),
|
||||
]
|
||||
@@ -421,20 +432,22 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWork
|
||||
B::Header,
|
||||
&B::Hash,
|
||||
Vec<B::Extrinsic>,
|
||||
StorageChanges<I::Transaction, B>,
|
||||
Self::Claim,
|
||||
) -> sp_consensus::BlockImportParams<B> + Send> {
|
||||
Box::new(|header, header_hash, body, (_, pair)| {
|
||||
) -> sp_consensus::BlockImportParams<B, I::Transaction> + Send> {
|
||||
Box::new(|header, header_hash, body, storage_changes, (_, pair)| {
|
||||
// sign the pre-sealed hash of the block and then
|
||||
// add it to a digest item.
|
||||
let signature = pair.sign(header_hash.as_ref());
|
||||
let signature_digest_item = <DigestItemFor<B> as CompatibleDigestItem>::babe_seal(signature);
|
||||
let digest_item = <DigestItemFor<B> as CompatibleDigestItem>::babe_seal(signature);
|
||||
|
||||
BlockImportParams {
|
||||
origin: BlockOrigin::Own,
|
||||
header,
|
||||
justification: None,
|
||||
post_digests: vec![signature_digest_item],
|
||||
post_digests: vec![digest_item],
|
||||
body: Some(body),
|
||||
storage_changes: Some(storage_changes),
|
||||
finalized: false,
|
||||
auxiliary: Vec::new(), // block-weight is written in block import.
|
||||
// TODO: block-import handles fork choice and this shouldn't even have the
|
||||
@@ -500,15 +513,17 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWork
|
||||
}
|
||||
|
||||
impl<B, C, E, I, Error, SO> SlotWorker<B> for BabeWorker<B, C, E, I, SO> where
|
||||
B: BlockT<Hash=H256>,
|
||||
C: ProvideRuntimeApi + ProvideCache<B> + HeaderBackend<B> + HeaderMetadata<B, Error=ClientError> + Send + Sync,
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> +
|
||||
ProvideCache<B> +
|
||||
HeaderBackend<B> +
|
||||
HeaderMetadata<B, Error = ClientError> + Send + Sync,
|
||||
C::Api: BabeApi<B>,
|
||||
E: Environment<B, Error=Error> + Send + Sync,
|
||||
E::Proposer: Proposer<B, Error=Error>,
|
||||
<E::Proposer as Proposer<B>>::Create: Unpin + Send + 'static,
|
||||
I: BlockImport<B> + Send + Sync + 'static,
|
||||
E: Environment<B, Error = Error> + Send + Sync,
|
||||
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
|
||||
SO: SyncOracle + Send + Sync + Clone,
|
||||
Error: std::error::Error + Send + From<::sp_consensus::Error> + From<I::Error> + 'static,
|
||||
Error: std::error::Error + Send + From<sp_consensus::Error> + From<I::Error> + 'static,
|
||||
{
|
||||
type OnSlot = Pin<Box<dyn Future<Output = Result<(), sp_consensus::Error>> + Send>>;
|
||||
|
||||
@@ -603,7 +618,9 @@ impl<B, E, Block: BlockT, RA, PRA> BabeVerifier<B, E, Block, RA, PRA> {
|
||||
block_id: BlockId<Block>,
|
||||
inherent_data: InherentData,
|
||||
) -> Result<(), Error<Block>>
|
||||
where PRA: ProvideRuntimeApi, PRA::Api: BlockBuilderApi<Block, Error = sp_blockchain::Error>
|
||||
where
|
||||
PRA: ProvideRuntimeApi<Block>,
|
||||
PRA::Api: BlockBuilderApi<Block, Error = sp_blockchain::Error>
|
||||
{
|
||||
let inherent_res = self.api.runtime_api().check_inherents(
|
||||
&block_id,
|
||||
@@ -667,11 +684,11 @@ fn median_algorithm(
|
||||
}
|
||||
|
||||
impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA> where
|
||||
Block: BlockT<Hash=H256>,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
Block: BlockT,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
PRA: ProvideRuntimeApi + Send + Sync + AuxStore + ProvideCache<Block>,
|
||||
PRA: ProvideRuntimeApi<Block> + Send + Sync + AuxStore + ProvideCache<Block>,
|
||||
PRA::Api: BlockBuilderApi<Block, Error = sp_blockchain::Error>
|
||||
+ BabeApi<Block, Error = sp_blockchain::Error>,
|
||||
{
|
||||
@@ -681,7 +698,7 @@ impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA
|
||||
header: Block::Header,
|
||||
justification: Option<Justification>,
|
||||
mut body: Option<Vec<Block::Extrinsic>>,
|
||||
) -> Result<(BlockImportParams<Block>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
) -> Result<(BlockImportParams<Block, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
trace!(
|
||||
target: "babe",
|
||||
"Verifying origin: {:?} header: {:?} justification: {:?} body: {:?}",
|
||||
@@ -785,6 +802,7 @@ impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA
|
||||
header: pre_header,
|
||||
post_digests: vec![verified_info.seal],
|
||||
body,
|
||||
storage_changes: None,
|
||||
finalized: false,
|
||||
justification,
|
||||
auxiliary: Vec::new(),
|
||||
@@ -810,7 +828,7 @@ impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA
|
||||
}
|
||||
|
||||
/// The BABE import queue type.
|
||||
pub type BabeImportQueue<B> = BasicQueue<B>;
|
||||
pub type BabeImportQueue<B, Transaction> = BasicQueue<B, Transaction>;
|
||||
|
||||
/// Register the babe inherent data provider, if not registered already.
|
||||
fn register_babe_inherent_data_provider(
|
||||
@@ -875,20 +893,22 @@ impl<B, E, Block: BlockT, I, RA, PRA> BabeBlockImport<B, E, Block, I, RA, PRA> {
|
||||
}
|
||||
|
||||
impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block, I, RA, PRA> where
|
||||
Block: BlockT<Hash=H256>,
|
||||
I: BlockImport<Block> + Send + Sync,
|
||||
Block: BlockT,
|
||||
I: BlockImport<Block, Transaction = sp_api::TransactionFor<PRA, Block>> + Send + Sync,
|
||||
I::Error: Into<ConsensusError>,
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + 'static + Clone + Send + Sync,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
RA: Send + Sync,
|
||||
PRA: ProvideRuntimeApi + ProvideCache<Block>,
|
||||
PRA::Api: BabeApi<Block>,
|
||||
PRA: ProvideRuntimeApi<Block> + ProvideCache<Block>,
|
||||
PRA::Api: BabeApi<Block> + ApiExt<Block, StateBackend = B::State>,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = sp_api::TransactionFor<PRA, Block>;
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<Block>,
|
||||
mut block: BlockImportParams<Block, Self::Transaction>,
|
||||
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
let hash = block.post_header().hash();
|
||||
@@ -1099,9 +1119,9 @@ fn prune_finalized<B, E, Block, RA>(
|
||||
client: &Client<B, E, Block, RA>,
|
||||
epoch_changes: &mut EpochChangesFor<Block>,
|
||||
) -> Result<(), ConsensusError> where
|
||||
Block: BlockT<Hash=H256>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync,
|
||||
B: Backend<Block, Blake2Hasher>,
|
||||
Block: BlockT,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
B: Backend<Block>,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
let info = client.chain_info();
|
||||
@@ -1133,15 +1153,16 @@ fn prune_finalized<B, E, Block, RA>(
|
||||
///
|
||||
/// Also returns a link object used to correctly instantiate the import queue
|
||||
/// and background worker.
|
||||
pub fn block_import<B, E, Block: BlockT<Hash=H256>, I, RA, PRA>(
|
||||
pub fn block_import<B, E, Block: BlockT, I, RA, PRA>(
|
||||
config: Config,
|
||||
wrapped_block_import: I,
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
api: Arc<PRA>,
|
||||
) -> ClientResult<(BabeBlockImport<B, E, Block, I, RA, PRA>, BabeLink<Block>)> where
|
||||
B: Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
{
|
||||
let epoch_changes = aux_schema::load_epoch_changes(&*client)?;
|
||||
let link = BabeLink {
|
||||
@@ -1178,7 +1199,7 @@ pub fn block_import<B, E, Block: BlockT<Hash=H256>, I, RA, PRA>(
|
||||
///
|
||||
/// The block import object provided must be the `BabeBlockImport` or a wrapper
|
||||
/// of it, otherwise crucial import logic will be omitted.
|
||||
pub fn import_queue<B, E, Block: BlockT<Hash=H256>, I, RA, PRA>(
|
||||
pub fn import_queue<B, E, Block: BlockT, I, RA, PRA>(
|
||||
babe_link: BabeLink<Block>,
|
||||
block_import: I,
|
||||
justification_import: Option<BoxJustificationImport<Block>>,
|
||||
@@ -1186,12 +1207,13 @@ pub fn import_queue<B, E, Block: BlockT<Hash=H256>, I, RA, PRA>(
|
||||
client: Arc<Client<B, E, Block, RA>>,
|
||||
api: Arc<PRA>,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
) -> ClientResult<BabeImportQueue<Block>> where
|
||||
B: Backend<Block, Blake2Hasher> + 'static,
|
||||
I: BlockImport<Block,Error=ConsensusError> + Send + Sync + 'static,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Clone + Send + Sync + 'static,
|
||||
) -> ClientResult<BabeImportQueue<Block, sp_api::TransactionFor<PRA, Block>>> where
|
||||
B: Backend<Block> + 'static,
|
||||
I: BlockImport<Block, Error = ConsensusError, Transaction = sp_api::TransactionFor<PRA, Block>>
|
||||
+ Send + Sync + 'static,
|
||||
E: CallExecutor<Block> + Clone + Send + Sync + 'static,
|
||||
RA: Send + Sync + 'static,
|
||||
PRA: ProvideRuntimeApi + ProvideCache<Block> + Send + Sync + AuxStore + 'static,
|
||||
PRA: ProvideRuntimeApi<Block> + ProvideCache<Block> + Send + Sync + AuxStore + 'static,
|
||||
PRA::Api: BlockBuilderApi<Block> + BabeApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>,
|
||||
{
|
||||
register_babe_inherent_data_provider(&inherent_data_providers, babe_link.config.slot_duration)?;
|
||||
@@ -1227,8 +1249,11 @@ pub mod test_helpers {
|
||||
keystore: &KeyStorePtr,
|
||||
link: &BabeLink<B>,
|
||||
) -> Option<BabePreDigest> where
|
||||
B: BlockT<Hash=H256>,
|
||||
C: ProvideRuntimeApi + ProvideCache<B> + HeaderBackend<B> + HeaderMetadata<B, Error=ClientError>,
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> +
|
||||
ProvideCache<B> +
|
||||
HeaderBackend<B> +
|
||||
HeaderMetadata<B, Error = ClientError>,
|
||||
C::Api: BabeApi<B>,
|
||||
{
|
||||
let epoch = link.epoch_changes.lock().epoch_for_child_of(
|
||||
|
||||
@@ -24,16 +24,16 @@ use authorship::claim_slot;
|
||||
|
||||
use sp_consensus_babe::{AuthorityPair, SlotNumber};
|
||||
use sc_block_builder::BlockBuilder;
|
||||
use sp_consensus::NoNetwork as DummyOracle;
|
||||
use sp_consensus::import_queue::{
|
||||
BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport,
|
||||
use sp_consensus::{
|
||||
NoNetwork as DummyOracle, Proposal, RecordProof,
|
||||
import_queue::{BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport},
|
||||
};
|
||||
use sc_network_test::*;
|
||||
use sc_network_test::{Block as TestBlock, PeersClient};
|
||||
use sc_network::config::{BoxFinalityProofRequestBuilder, ProtocolConfig};
|
||||
use sp_runtime::{generic::DigestItem, traits::{Block as BlockT, DigestFor}};
|
||||
use tokio::runtime::current_thread;
|
||||
use sc_client_api::BlockchainEvents;
|
||||
use sc_client_api::{BlockchainEvents, backend::TransactionFor};
|
||||
use log::debug;
|
||||
use std::{time::Duration, cell::RefCell};
|
||||
|
||||
@@ -94,16 +94,25 @@ impl Environment<TestBlock> for DummyFactory {
|
||||
|
||||
impl DummyProposer {
|
||||
fn propose_with(&mut self, pre_digests: DigestFor<TestBlock>)
|
||||
-> future::Ready<Result<TestBlock, Error>>
|
||||
-> future::Ready<
|
||||
Result<
|
||||
Proposal<
|
||||
TestBlock,
|
||||
sc_client_api::TransactionFor<substrate_test_runtime_client::Backend, TestBlock>
|
||||
>,
|
||||
Error
|
||||
>
|
||||
>
|
||||
{
|
||||
use codec::Encode;
|
||||
let block_builder = self.factory.client.new_block_at(
|
||||
&BlockId::Hash(self.parent_hash),
|
||||
pre_digests,
|
||||
false,
|
||||
).unwrap();
|
||||
|
||||
let mut block = match block_builder.bake().map_err(|e| e.into()) {
|
||||
Ok(b) => b,
|
||||
let mut block = match block_builder.build().map_err(|e| e.into()) {
|
||||
Ok(b) => b.block,
|
||||
Err(e) => return future::ready(Err(e)),
|
||||
};
|
||||
|
||||
@@ -142,20 +151,22 @@ impl DummyProposer {
|
||||
// mutate the block header according to the mutator.
|
||||
(self.factory.mutator)(&mut block.header, Stage::PreSeal);
|
||||
|
||||
future::ready(Ok(block))
|
||||
future::ready(Ok(Proposal { block, proof: None, storage_changes: Default::default() }))
|
||||
}
|
||||
}
|
||||
|
||||
impl Proposer<TestBlock> for DummyProposer {
|
||||
type Error = Error;
|
||||
type Create = future::Ready<Result<TestBlock, Error>>;
|
||||
type Transaction = sc_client_api::TransactionFor<substrate_test_runtime_client::Backend, TestBlock>;
|
||||
type Proposal = future::Ready<Result<Proposal<TestBlock, Self::Transaction>, Error>>;
|
||||
|
||||
fn propose(
|
||||
&mut self,
|
||||
_: InherentData,
|
||||
pre_digests: DigestFor<TestBlock>,
|
||||
_: Duration,
|
||||
) -> Self::Create {
|
||||
_: RecordProof,
|
||||
) -> Self::Proposal {
|
||||
self.propose_with(pre_digests)
|
||||
}
|
||||
}
|
||||
@@ -169,10 +180,11 @@ struct PanickingBlockImport<B>(B);
|
||||
|
||||
impl<B: BlockImport<TestBlock>> BlockImport<TestBlock> for PanickingBlockImport<B> {
|
||||
type Error = B::Error;
|
||||
type Transaction = B::Transaction;
|
||||
|
||||
fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<TestBlock>,
|
||||
block: BlockImportParams<TestBlock, Self::Transaction>,
|
||||
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
Ok(self.0.import_block(block, new_cache).expect("importing block failed"))
|
||||
@@ -214,7 +226,7 @@ impl Verifier<TestBlock> for TestVerifier {
|
||||
mut header: TestHeader,
|
||||
justification: Option<Justification>,
|
||||
body: Option<Vec<TestExtrinsic>>,
|
||||
) -> Result<(BlockImportParams<TestBlock>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
) -> Result<(BlockImportParams<TestBlock, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
// apply post-sealing mutations (i.e. stripping seal, if desired).
|
||||
(self.mutator)(&mut header, Stage::PostSeal);
|
||||
Ok(self.inner.verify(origin, header, justification, body).expect("verification failed!"))
|
||||
@@ -224,7 +236,9 @@ impl Verifier<TestBlock> for TestVerifier {
|
||||
pub struct PeerData {
|
||||
link: BabeLink<TestBlock>,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
block_import: Mutex<Option<BoxBlockImport<TestBlock>>>,
|
||||
block_import: Mutex<
|
||||
Option<BoxBlockImport<TestBlock, TransactionFor<substrate_test_runtime_client::Backend, TestBlock>>>
|
||||
>,
|
||||
}
|
||||
|
||||
impl TestNetFactory for BabeTestNet {
|
||||
@@ -240,9 +254,9 @@ impl TestNetFactory for BabeTestNet {
|
||||
}
|
||||
}
|
||||
|
||||
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>>,
|
||||
@@ -262,9 +276,11 @@ impl TestNetFactory for BabeTestNet {
|
||||
|
||||
let block_import = PanickingBlockImport(block_import);
|
||||
|
||||
let data_block_import = Mutex::new(Some(Box::new(block_import.clone()) as BoxBlockImport<_>));
|
||||
let data_block_import = Mutex::new(
|
||||
Some(Box::new(block_import.clone()) as BoxBlockImport<_, _>)
|
||||
);
|
||||
(
|
||||
Box::new(block_import),
|
||||
BlockImportAdapter::new_full(block_import),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
@@ -322,8 +338,8 @@ impl TestNetFactory for BabeTestNet {
|
||||
fn rejects_empty_block() {
|
||||
env_logger::try_init().unwrap();
|
||||
let mut net = BabeTestNet::new(3);
|
||||
let block_builder = |builder: BlockBuilder<_, _>| {
|
||||
builder.bake().unwrap()
|
||||
let block_builder = |builder: BlockBuilder<_, _, _>| {
|
||||
builder.build().unwrap().block
|
||||
};
|
||||
net.mut_peers(|peer| {
|
||||
peer[0].generate_blocks(1, BlockOrigin::NetworkInitialSync, block_builder);
|
||||
@@ -525,12 +541,12 @@ fn can_author_block() {
|
||||
}
|
||||
|
||||
// Propose and import a new BABE block on top of the given parent.
|
||||
fn propose_and_import_block(
|
||||
fn propose_and_import_block<Transaction>(
|
||||
parent: &TestHeader,
|
||||
slot_number: Option<SlotNumber>,
|
||||
proposer_factory: &mut DummyFactory,
|
||||
block_import: &mut BoxBlockImport<TestBlock>,
|
||||
) -> H256 {
|
||||
block_import: &mut BoxBlockImport<TestBlock, Transaction>,
|
||||
) -> sp_core::H256 {
|
||||
let mut proposer = proposer_factory.init(parent).unwrap();
|
||||
|
||||
let slot_number = slot_number.unwrap_or_else(|| {
|
||||
@@ -549,7 +565,7 @@ fn propose_and_import_block(
|
||||
],
|
||||
};
|
||||
|
||||
let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap();
|
||||
let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap().block;
|
||||
|
||||
let seal = {
|
||||
// sign the pre-sealed hash of the block and then
|
||||
@@ -574,6 +590,7 @@ fn propose_and_import_block(
|
||||
justification: None,
|
||||
post_digests: vec![seal],
|
||||
body: Some(block.extrinsics),
|
||||
storage_changes: None,
|
||||
finalized: false,
|
||||
auxiliary: Vec::new(),
|
||||
fork_choice: ForkChoiceStrategy::LongestChain,
|
||||
|
||||
@@ -10,6 +10,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive
|
||||
sp-core = { version = "2.0.0", path = "../../../primitives/core" }
|
||||
sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" }
|
||||
sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" }
|
||||
sp-api = { version = "2.0.0", path = "../../../primitives/api" }
|
||||
sc-client-api = { version = "2.0.0", path = "../../api" }
|
||||
sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" }
|
||||
sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" }
|
||||
|
||||
@@ -37,19 +37,19 @@ use sp_blockchain::{HeaderBackend, ProvideCache, well_known_cache_keys::Id as Ca
|
||||
use sp_block_builder::BlockBuilder as BlockBuilderApi;
|
||||
use sp_runtime::{Justification, RuntimeString};
|
||||
use sp_runtime::generic::{BlockId, Digest, DigestItem};
|
||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi};
|
||||
use sp_timestamp::{TimestampInherentData, InherentError as TIError};
|
||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_consensus_pow::{Seal, TotalDifficulty, POW_ENGINE_ID};
|
||||
use sp_core::H256;
|
||||
use sp_inherents::{InherentDataProviders, InherentData};
|
||||
use sp_consensus::{
|
||||
BlockImportParams, BlockOrigin, ForkChoiceStrategy, SyncOracle, Environment, Proposer,
|
||||
SelectChain, Error as ConsensusError, CanAuthorWith,
|
||||
SelectChain, Error as ConsensusError, CanAuthorWith, RecordProof,
|
||||
};
|
||||
use sp_consensus::import_queue::{BoxBlockImport, BasicQueue, Verifier};
|
||||
use codec::{Encode, Decode};
|
||||
use sc_client_api;
|
||||
use log::*;
|
||||
use sp_timestamp::{InherentError as TIError, TimestampInherentData};
|
||||
|
||||
#[derive(derive_more::Display, Debug)]
|
||||
pub enum Error<B: BlockT> {
|
||||
@@ -93,9 +93,8 @@ impl<B: BlockT> std::convert::From<Error<B>> for String {
|
||||
pub const POW_AUX_PREFIX: [u8; 4] = *b"PoW:";
|
||||
|
||||
/// Get the auxiliary storage key used by engine to store total difficulty.
|
||||
fn aux_key(hash: &H256) -> Vec<u8> {
|
||||
POW_AUX_PREFIX.iter().chain(&hash[..])
|
||||
.cloned().collect::<Vec<_>>()
|
||||
fn aux_key<T: AsRef<[u8]>>(hash: &T) -> Vec<u8> {
|
||||
POW_AUX_PREFIX.iter().chain(hash.as_ref()).copied().collect()
|
||||
}
|
||||
|
||||
/// Auxiliary storage data for PoW.
|
||||
@@ -111,12 +110,11 @@ impl<Difficulty> PowAux<Difficulty> where
|
||||
Difficulty: Decode + Default,
|
||||
{
|
||||
/// Read the auxiliary from client.
|
||||
pub fn read<C: AuxStore, B: BlockT>(client: &C, hash: &H256) -> Result<Self, Error<B>> {
|
||||
let key = aux_key(hash);
|
||||
pub fn read<C: AuxStore, B: BlockT>(client: &C, hash: &B::Hash) -> Result<Self, Error<B>> {
|
||||
let key = aux_key(&hash);
|
||||
|
||||
match client.get_aux(&key).map_err(Error::Client)? {
|
||||
Some(bytes) => Self::decode(&mut &bytes[..])
|
||||
.map_err(Error::Codec),
|
||||
Some(bytes) => Self::decode(&mut &bytes[..]).map_err(Error::Codec),
|
||||
None => Ok(Self::default()),
|
||||
}
|
||||
}
|
||||
@@ -133,7 +131,7 @@ pub trait PowAlgorithm<B: BlockT> {
|
||||
fn verify(
|
||||
&self,
|
||||
parent: &BlockId<B>,
|
||||
pre_hash: &H256,
|
||||
pre_hash: &B::Hash,
|
||||
seal: &Seal,
|
||||
difficulty: Self::Difficulty,
|
||||
) -> Result<bool, Error<B>>;
|
||||
@@ -141,14 +139,14 @@ pub trait PowAlgorithm<B: BlockT> {
|
||||
fn mine(
|
||||
&self,
|
||||
parent: &BlockId<B>,
|
||||
pre_hash: &H256,
|
||||
pre_hash: &B::Hash,
|
||||
difficulty: Self::Difficulty,
|
||||
round: u32,
|
||||
) -> Result<Option<Seal>, Error<B>>;
|
||||
}
|
||||
|
||||
/// A verifier for PoW blocks.
|
||||
pub struct PowVerifier<B: BlockT<Hash=H256>, C, S, Algorithm> {
|
||||
pub struct PowVerifier<B: BlockT, C, S, Algorithm> {
|
||||
client: Arc<C>,
|
||||
algorithm: Algorithm,
|
||||
inherent_data_providers: sp_inherents::InherentDataProviders,
|
||||
@@ -156,7 +154,7 @@ pub struct PowVerifier<B: BlockT<Hash=H256>, C, S, Algorithm> {
|
||||
check_inherents_after: <<B as BlockT>::Header as HeaderT>::Number,
|
||||
}
|
||||
|
||||
impl<B: BlockT<Hash=H256>, C, S, Algorithm> PowVerifier<B, C, S, Algorithm> {
|
||||
impl<B: BlockT, C, S, Algorithm> PowVerifier<B, C, S, Algorithm> {
|
||||
pub fn new(
|
||||
client: Arc<C>,
|
||||
algorithm: Algorithm,
|
||||
@@ -171,7 +169,7 @@ impl<B: BlockT<Hash=H256>, C, S, Algorithm> PowVerifier<B, C, S, Algorithm> {
|
||||
&self,
|
||||
mut header: B::Header,
|
||||
parent_block_id: BlockId<B>,
|
||||
) -> Result<(B::Header, Algorithm::Difficulty, DigestItem<H256>), Error<B>> where
|
||||
) -> Result<(B::Header, Algorithm::Difficulty, DigestItem<B::Hash>), Error<B>> where
|
||||
Algorithm: PowAlgorithm<B>,
|
||||
{
|
||||
let hash = header.hash();
|
||||
@@ -209,7 +207,7 @@ impl<B: BlockT<Hash=H256>, C, S, Algorithm> PowVerifier<B, C, S, Algorithm> {
|
||||
inherent_data: InherentData,
|
||||
timestamp_now: u64,
|
||||
) -> Result<(), Error<B>> where
|
||||
C: ProvideRuntimeApi, C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>
|
||||
C: ProvideRuntimeApi<B>, C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>
|
||||
{
|
||||
const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60;
|
||||
|
||||
@@ -245,8 +243,8 @@ impl<B: BlockT<Hash=H256>, C, S, Algorithm> PowVerifier<B, C, S, Algorithm> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT<Hash=H256>, C, S, Algorithm> Verifier<B> for PowVerifier<B, C, S, Algorithm> where
|
||||
C: ProvideRuntimeApi + Send + Sync + HeaderBackend<B> + AuxStore + ProvideCache<B> + BlockOf,
|
||||
impl<B: BlockT, C, S, Algorithm> Verifier<B> for PowVerifier<B, C, S, Algorithm> where
|
||||
C: ProvideRuntimeApi<B> + Send + Sync + HeaderBackend<B> + AuxStore + ProvideCache<B> + BlockOf,
|
||||
C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>,
|
||||
S: SelectChain<B>,
|
||||
Algorithm: PowAlgorithm<B> + Send + Sync,
|
||||
@@ -257,7 +255,7 @@ impl<B: BlockT<Hash=H256>, C, S, Algorithm> Verifier<B> for PowVerifier<B, C, S,
|
||||
header: B::Header,
|
||||
justification: Option<Justification>,
|
||||
mut body: Option<Vec<B::Extrinsic>>,
|
||||
) -> Result<(BlockImportParams<B>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
) -> Result<(BlockImportParams<B, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
let inherent_data = self.inherent_data_providers
|
||||
.create_inherent_data().map_err(|e| e.into_string())?;
|
||||
let timestamp_now = inherent_data.timestamp_inherent_data().map_err(|e| e.into_string())?;
|
||||
@@ -290,19 +288,22 @@ impl<B: BlockT<Hash=H256>, C, S, Algorithm> Verifier<B> for PowVerifier<B, C, S,
|
||||
timestamp_now
|
||||
)?;
|
||||
|
||||
let (_, inner_body) = block.deconstruct();
|
||||
body = Some(inner_body);
|
||||
body = Some(block.deconstruct().1);
|
||||
}
|
||||
|
||||
let key = aux_key(&hash);
|
||||
let import_block = BlockImportParams {
|
||||
origin,
|
||||
header: checked_header,
|
||||
post_digests: vec![seal],
|
||||
body,
|
||||
storage_changes: None,
|
||||
finalized: false,
|
||||
justification,
|
||||
auxiliary: vec![(key, Some(aux.encode()))],
|
||||
fork_choice: ForkChoiceStrategy::Custom(aux.total_difficulty > best_aux.total_difficulty),
|
||||
fork_choice: ForkChoiceStrategy::Custom(
|
||||
aux.total_difficulty > best_aux.total_difficulty
|
||||
),
|
||||
allow_missing_state: false,
|
||||
import_existing: false,
|
||||
};
|
||||
@@ -326,19 +327,22 @@ pub fn register_pow_inherent_data_provider(
|
||||
}
|
||||
|
||||
/// The PoW import queue type.
|
||||
pub type PowImportQueue<B> = BasicQueue<B>;
|
||||
pub type PowImportQueue<B, Transaction> = BasicQueue<B, Transaction>;
|
||||
|
||||
/// Import queue for PoW engine.
|
||||
pub fn import_queue<B, C, S, Algorithm>(
|
||||
block_import: BoxBlockImport<B>,
|
||||
block_import: BoxBlockImport<B, sp_api::TransactionFor<C, B>>,
|
||||
client: Arc<C>,
|
||||
algorithm: Algorithm,
|
||||
check_inherents_after: <<B as BlockT>::Header as HeaderT>::Number,
|
||||
select_chain: Option<S>,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
) -> Result<PowImportQueue<B>, sp_consensus::Error> where
|
||||
B: BlockT<Hash=H256>,
|
||||
C: ProvideRuntimeApi + HeaderBackend<B> + BlockOf + ProvideCache<B> + AuxStore,
|
||||
) -> Result<
|
||||
PowImportQueue<B, sp_api::TransactionFor<C, B>>,
|
||||
sp_consensus::Error
|
||||
> where
|
||||
B: BlockT,
|
||||
C: ProvideRuntimeApi<B> + HeaderBackend<B> + BlockOf + ProvideCache<B> + AuxStore,
|
||||
C: Send + Sync + AuxStore + 'static,
|
||||
C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>,
|
||||
Algorithm: PowAlgorithm<B> + Send + Sync + 'static,
|
||||
@@ -372,8 +376,8 @@ pub fn import_queue<B, C, S, Algorithm>(
|
||||
/// information, or just be a graffiti. `round` is for number of rounds the
|
||||
/// CPU miner runs each time. This parameter should be tweaked so that each
|
||||
/// mining round is within sub-second time.
|
||||
pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
|
||||
mut block_import: BoxBlockImport<B>,
|
||||
pub fn start_mine<B: BlockT, C, Algorithm, E, SO, S, CAW>(
|
||||
mut block_import: BoxBlockImport<B, sp_api::TransactionFor<C, B>>,
|
||||
client: Arc<C>,
|
||||
algorithm: Algorithm,
|
||||
mut env: E,
|
||||
@@ -385,10 +389,11 @@ pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
|
||||
inherent_data_providers: sp_inherents::InherentDataProviders,
|
||||
can_author_with: CAW,
|
||||
) where
|
||||
C: HeaderBackend<B> + AuxStore + 'static,
|
||||
C: HeaderBackend<B> + AuxStore + ProvideRuntimeApi<B> + 'static,
|
||||
Algorithm: PowAlgorithm<B> + Send + Sync + 'static,
|
||||
E: Environment<B> + Send + Sync + 'static,
|
||||
E::Error: std::fmt::Debug,
|
||||
E::Proposer: Proposer<B, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
SO: SyncOracle + Send + Sync + 'static,
|
||||
S: SelectChain<B> + 'static,
|
||||
CAW: CanAuthorWith<B> + Send + 'static,
|
||||
@@ -423,8 +428,8 @@ pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
|
||||
});
|
||||
}
|
||||
|
||||
fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
|
||||
block_import: &mut BoxBlockImport<B>,
|
||||
fn mine_loop<B: BlockT, C, Algorithm, E, SO, S, CAW>(
|
||||
block_import: &mut BoxBlockImport<B, sp_api::TransactionFor<C, B>>,
|
||||
client: &C,
|
||||
algorithm: &Algorithm,
|
||||
env: &mut E,
|
||||
@@ -436,12 +441,14 @@ fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
|
||||
inherent_data_providers: &sp_inherents::InherentDataProviders,
|
||||
can_author_with: &CAW,
|
||||
) -> Result<(), Error<B>> where
|
||||
C: HeaderBackend<B> + AuxStore,
|
||||
C: HeaderBackend<B> + AuxStore + ProvideRuntimeApi<B>,
|
||||
Algorithm: PowAlgorithm<B>,
|
||||
E: Environment<B>,
|
||||
E::Proposer: Proposer<B, Transaction = sp_api::TransactionFor<C, B>>,
|
||||
E::Error: std::fmt::Debug,
|
||||
SO: SyncOracle,
|
||||
S: SelectChain<B>,
|
||||
sp_api::TransactionFor<C, B>: 'static,
|
||||
CAW: CanAuthorWith<B>,
|
||||
{
|
||||
'outer: loop {
|
||||
@@ -488,13 +495,14 @@ fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
|
||||
if let Some(preruntime) = &preruntime {
|
||||
inherent_digest.push(DigestItem::PreRuntime(POW_ENGINE_ID, preruntime.to_vec()));
|
||||
}
|
||||
let block = futures::executor::block_on(proposer.propose(
|
||||
let proposal = futures::executor::block_on(proposer.propose(
|
||||
inherent_data,
|
||||
inherent_digest,
|
||||
build_time.clone(),
|
||||
RecordProof::No,
|
||||
)).map_err(|e| Error::BlockProposingError(format!("{:?}", e)))?;
|
||||
|
||||
let (header, body) = block.deconstruct();
|
||||
let (header, body) = proposal.block.deconstruct();
|
||||
let (difficulty, seal) = {
|
||||
let difficulty = algorithm.difficulty(
|
||||
&BlockId::Hash(best_hash),
|
||||
@@ -546,6 +554,7 @@ fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
|
||||
justification: None,
|
||||
post_digests: vec![DigestItem::Seal(POW_ENGINE_ID, seal)],
|
||||
body: Some(body),
|
||||
storage_changes: Some(proposal.storage_changes),
|
||||
finalized: false,
|
||||
auxiliary: vec![(key, Some(aux.encode()))],
|
||||
fork_choice: ForkChoiceStrategy::Custom(true),
|
||||
|
||||
@@ -12,6 +12,8 @@ sc-client-api = { version = "2.0.0", path = "../../api" }
|
||||
sp-core = { version = "2.0.0", path = "../../../primitives/core" }
|
||||
sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" }
|
||||
sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" }
|
||||
sp-state-machine = { version = "2.0.0", path = "../../../primitives/state-machine" }
|
||||
sp-api = { version = "2.0.0", path = "../../../primitives/api" }
|
||||
sc-telemetry = { version = "2.0.0", path = "../../telemetry" }
|
||||
sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" }
|
||||
sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" }
|
||||
|
||||
@@ -31,17 +31,23 @@ use slots::Slots;
|
||||
pub use aux_schema::{check_equivocation, MAX_SLOT_CAPACITY, PRUNING_BOUND};
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use sp_consensus::{BlockImport, Proposer, SyncOracle, SelectChain, CanAuthorWith, SlotData};
|
||||
use sp_consensus::{BlockImport, Proposer, SyncOracle, SelectChain, CanAuthorWith, SlotData, RecordProof};
|
||||
use futures::{prelude::*, future::{self, Either}};
|
||||
use futures_timer::Delay;
|
||||
use sp_inherents::{InherentData, InherentDataProviders};
|
||||
use log::{debug, error, info, warn};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_runtime::traits::{ApiRef, Block as BlockT, Header, ProvideRuntimeApi};
|
||||
use sp_runtime::traits::{Block as BlockT, Header, HasherFor, NumberFor};
|
||||
use sp_api::{ProvideRuntimeApi, ApiRef};
|
||||
use std::{fmt::Debug, ops::Deref, pin::Pin, sync::Arc, time::{Instant, Duration}};
|
||||
use sc_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_WARN, CONSENSUS_INFO};
|
||||
use parking_lot::Mutex;
|
||||
use sc_client_api;
|
||||
|
||||
/// The changes that need to applied to the storage to create the state for a block.
|
||||
///
|
||||
/// See [`state_machine::StorageChanges`] for more information.
|
||||
pub type StorageChanges<Transaction, Block> =
|
||||
sp_state_machine::StorageChanges<Transaction, HasherFor<Block>, NumberFor<Block>>;
|
||||
|
||||
/// A worker that should be invoked at every new slot.
|
||||
pub trait SlotWorker<B: BlockT> {
|
||||
@@ -58,7 +64,8 @@ pub trait SlotWorker<B: BlockT> {
|
||||
/// out if block production takes too long.
|
||||
pub trait SimpleSlotWorker<B: BlockT> {
|
||||
/// A handle to a `BlockImport`.
|
||||
type BlockImport: BlockImport<B> + Send + 'static;
|
||||
type BlockImport: BlockImport<B, Transaction = <Self::Proposer as Proposer<B>>::Transaction>
|
||||
+ Send + 'static;
|
||||
|
||||
/// A handle to a `SyncOracle`.
|
||||
type SyncOracle: SyncOracle;
|
||||
@@ -94,15 +101,26 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
) -> Option<Self::Claim>;
|
||||
|
||||
/// Return the pre digest data to include in a block authored with the given claim.
|
||||
fn pre_digest_data(&self, slot_number: u64, claim: &Self::Claim) -> Vec<sp_runtime::DigestItem<B::Hash>>;
|
||||
fn pre_digest_data(
|
||||
&self,
|
||||
slot_number: u64,
|
||||
claim: &Self::Claim,
|
||||
) -> Vec<sp_runtime::DigestItem<B::Hash>>;
|
||||
|
||||
/// Returns a function which produces a `BlockImportParams`.
|
||||
fn block_import_params(&self) -> Box<dyn Fn(
|
||||
B::Header,
|
||||
&B::Hash,
|
||||
Vec<B::Extrinsic>,
|
||||
Self::Claim,
|
||||
) -> sp_consensus::BlockImportParams<B> + Send>;
|
||||
fn block_import_params(&self) -> Box<
|
||||
dyn Fn(
|
||||
B::Header,
|
||||
&B::Hash,
|
||||
Vec<B::Extrinsic>,
|
||||
StorageChanges<<Self::BlockImport as BlockImport<B>>::Transaction, B>,
|
||||
Self::Claim,
|
||||
) -> sp_consensus::BlockImportParams<
|
||||
B,
|
||||
<Self::BlockImport as BlockImport<B>>::Transaction
|
||||
>
|
||||
+ Send
|
||||
>;
|
||||
|
||||
/// Whether to force authoring if offline.
|
||||
fn force_authoring(&self) -> bool;
|
||||
@@ -136,7 +154,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo)
|
||||
-> Pin<Box<dyn Future<Output = Result<(), sp_consensus::Error>> + Send>> where
|
||||
Self: Send + Sync,
|
||||
<Self::Proposer as Proposer<B>>::Create: Unpin + Send + 'static,
|
||||
<Self::Proposer as Proposer<B>>::Proposal: Unpin + Send + 'static,
|
||||
{
|
||||
let (timestamp, slot_number, slot_duration) =
|
||||
(slot_info.timestamp, slot_info.number, slot_info.duration);
|
||||
@@ -222,6 +240,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
logs,
|
||||
},
|
||||
slot_remaining_duration,
|
||||
RecordProof::No,
|
||||
).map_err(|e| sp_consensus::Error::ClientImport(format!("{:?}", e)));
|
||||
let delay: Box<dyn Future<Output=()> + Unpin + Send> = match proposing_remaining_duration {
|
||||
Some(r) => Box::new(Delay::new(r)),
|
||||
@@ -247,8 +266,8 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
let block_import = self.block_import();
|
||||
let logging_target = self.logging_target();
|
||||
|
||||
Box::pin(proposal_work.map_ok(move |(block, claim)| {
|
||||
let (header, body) = block.deconstruct();
|
||||
Box::pin(proposal_work.map_ok(move |(proposal, claim)| {
|
||||
let (header, body) = proposal.block.deconstruct();
|
||||
let header_num = *header.number();
|
||||
let header_hash = header.hash();
|
||||
let parent_hash = *header.parent_hash();
|
||||
@@ -257,13 +276,15 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
header,
|
||||
&header_hash,
|
||||
body,
|
||||
proposal.storage_changes,
|
||||
claim,
|
||||
);
|
||||
|
||||
info!("Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.",
|
||||
header_num,
|
||||
block_import_params.post_header().hash(),
|
||||
header_hash,
|
||||
info!(
|
||||
"Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.",
|
||||
header_num,
|
||||
block_import_params.post_header().hash(),
|
||||
header_hash,
|
||||
);
|
||||
|
||||
telemetry!(CONSENSUS_INFO; "slots.pre_sealed_block";
|
||||
@@ -418,7 +439,7 @@ impl<T: Clone> SlotDuration<T> {
|
||||
/// compile-time constant.
|
||||
pub fn get_or_compute<B: BlockT, C, CB>(client: &C, cb: CB) -> sp_blockchain::Result<Self> where
|
||||
C: sc_client_api::backend::AuxStore,
|
||||
C: ProvideRuntimeApi,
|
||||
C: ProvideRuntimeApi<B>,
|
||||
CB: FnOnce(ApiRef<C::Api>, &BlockId<B>) -> sp_blockchain::Result<T>,
|
||||
T: SlotData + Encode + Decode + Debug,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user