Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
@@ -19,26 +19,30 @@
//! Extensions for manual seal to produce blocks valid for any runtime.
use super::Error;
use sp_runtime::traits::{Block as BlockT, DigestFor};
use sp_inherents::InherentData;
use sp_consensus::BlockImportParams;
use sp_inherents::InherentData;
use sp_runtime::traits::{Block as BlockT, DigestFor};
pub mod babe;
/// Consensus data provider, manual seal uses this trait object for authoring blocks valid
/// Consensus data provider, manual seal uses this trait object for authoring blocks valid
/// for any runtime.
pub trait ConsensusDataProvider<B: BlockT>: Send + Sync {
/// Block import transaction type
type Transaction;
/// Attempt to create a consensus digest.
fn create_digest(&self, parent: &B::Header, inherents: &InherentData) -> Result<DigestFor<B>, Error>;
fn create_digest(
&self,
parent: &B::Header,
inherents: &InherentData,
) -> Result<DigestFor<B>, Error>;
/// set up the neccessary import params.
fn append_block_import(
&self,
parent: &B::Header,
params: &mut BlockImportParams<B, Self::Transaction>,
inherents: &InherentData
inherents: &InherentData,
) -> Result<(), Error>;
}
@@ -21,30 +21,40 @@
use super::ConsensusDataProvider;
use crate::Error;
use codec::Encode;
use std::{borrow::Cow, sync::{Arc, atomic}, time::SystemTime};
use sc_client_api::{AuxStore, UsageProvider};
use sc_consensus_babe::{
Config, Epoch, authorship, CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY,
find_pre_digest,
authorship, find_pre_digest, BabeIntermediate, CompatibleDigestItem, Config, Epoch,
INTERMEDIATE_KEY,
};
use sc_consensus_epochs::{
descendent_query, EpochHeader, SharedEpochChanges, ViableEpochDescriptor,
};
use sc_consensus_epochs::{SharedEpochChanges, descendent_query, ViableEpochDescriptor, EpochHeader};
use sp_keystore::SyncCryptoStorePtr;
use std::{
borrow::Cow,
sync::{atomic, Arc},
time::SystemTime,
};
use sp_api::{ProvideRuntimeApi, TransactionFor};
use sp_blockchain::{HeaderBackend, HeaderMetadata};
use sp_consensus::{BlockImportParams, BlockOrigin, ForkChoiceStrategy};
use sp_consensus_slots::Slot;
use sp_consensus_babe::{
BabeApi, inherents::BabeInherentData, ConsensusLog, BABE_ENGINE_ID, AuthorityId,
digests::{PreDigest, SecondaryPlainPreDigest, NextEpochDescriptor}, BabeAuthorityWeight,
use sp_consensus::{
import_queue::{CacheKeyId, Verifier},
BlockImportParams, BlockOrigin, ForkChoiceStrategy,
};
use sp_consensus_babe::{
digests::{NextEpochDescriptor, PreDigest, SecondaryPlainPreDigest},
inherents::BabeInherentData,
AuthorityId, BabeApi, BabeAuthorityWeight, ConsensusLog, BABE_ENGINE_ID,
};
use sp_consensus_slots::Slot;
use sp_inherents::{InherentData, InherentDataProvider, InherentIdentifier};
use sp_runtime::{
traits::{DigestItemFor, DigestFor, Block as BlockT, Zero, Header},
generic::{Digest, BlockId}, Justifications,
generic::{BlockId, Digest},
traits::{Block as BlockT, DigestFor, DigestItemFor, Header, Zero},
Justifications,
};
use sp_timestamp::{InherentType, INHERENT_IDENTIFIER, TimestampInherentData};
use sp_consensus::import_queue::{Verifier, CacheKeyId};
use sp_timestamp::{InherentType, TimestampInherentData, INHERENT_IDENTIFIER};
/// Provides BABE-compatible predigests and BlockImportParams.
/// Intended for use with BABE runtimes.
@@ -77,19 +87,16 @@ pub struct BabeVerifier<B: BlockT, C> {
impl<B: BlockT, C> BabeVerifier<B, C> {
/// create a nrew verifier
pub fn new(epoch_changes: SharedEpochChanges<B, Epoch>, client: Arc<C>) -> BabeVerifier<B, C> {
BabeVerifier {
epoch_changes,
client,
}
BabeVerifier { epoch_changes, client }
}
}
/// The verifier for the manual seal engine; instantly finalizes.
#[async_trait::async_trait]
impl<B, C> Verifier<B> for BabeVerifier<B, C>
where
B: BlockT,
C: HeaderBackend<B> + HeaderMetadata<B, Error = sp_blockchain::Error>
where
B: BlockT,
C: HeaderBackend<B> + HeaderMetadata<B, Error = sp_blockchain::Error>,
{
async fn verify(
&mut self,
@@ -107,7 +114,9 @@ impl<B, C> Verifier<B> for BabeVerifier<B, C>
let pre_digest = find_pre_digest::<B>(&header)?;
let parent_hash = header.parent_hash();
let parent = self.client.header(BlockId::Hash(*parent_hash))
let parent = self
.client
.header(BlockId::Hash(*parent_hash))
.ok()
.flatten()
.ok_or_else(|| format!("header for block {} not found", parent_hash))?;
@@ -134,14 +143,14 @@ impl<B, C> Verifier<B> for BabeVerifier<B, C>
}
impl<B, C> BabeConsensusDataProvider<B, C>
where
B: BlockT,
C: AuxStore
+ HeaderBackend<B>
+ ProvideRuntimeApi<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ UsageProvider<B>,
C::Api: BabeApi<B>,
where
B: BlockT,
C: AuxStore
+ HeaderBackend<B>
+ ProvideRuntimeApi<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ UsageProvider<B>,
C::Api: BabeApi<B>,
{
pub fn new(
client: Arc<C>,
@@ -155,13 +164,7 @@ impl<B, C> BabeConsensusDataProvider<B, C>
let config = Config::get_or_compute(&*client)?;
Ok(Self {
config,
client,
keystore,
epoch_changes,
authorities,
})
Ok(Self { config, client, keystore, epoch_changes, authorities })
}
fn epoch(&self, parent: &B::Header, slot: Slot) -> Result<Epoch, Error> {
@@ -177,10 +180,7 @@ impl<B, C> BabeConsensusDataProvider<B, C>
.ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet)?;
let epoch = epoch_changes
.viable_epoch(
&epoch_descriptor,
|slot| Epoch::genesis(&self.config, slot),
)
.viable_epoch(&epoch_descriptor, |slot| Epoch::genesis(&self.config, slot))
.ok_or_else(|| {
log::info!(target: "babe", "create_digest: no viable_epoch :(");
sp_consensus::Error::InvalidAuthoritiesSet
@@ -191,38 +191,37 @@ impl<B, C> BabeConsensusDataProvider<B, C>
}
impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
where
B: BlockT,
C: AuxStore
+ HeaderBackend<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ UsageProvider<B>
+ ProvideRuntimeApi<B>,
C::Api: BabeApi<B>,
where
B: BlockT,
C: AuxStore
+ HeaderBackend<B>
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ UsageProvider<B>
+ ProvideRuntimeApi<B>,
C::Api: BabeApi<B>,
{
type Transaction = TransactionFor<C, B>;
fn create_digest(&self, parent: &B::Header, inherents: &InherentData) -> Result<DigestFor<B>, Error> {
let slot = inherents.babe_inherent_data()?
fn create_digest(
&self,
parent: &B::Header,
inherents: &InherentData,
) -> Result<DigestFor<B>, Error> {
let slot = inherents
.babe_inherent_data()?
.ok_or_else(|| Error::StringError("No babe inherent data".into()))?;
let epoch = self.epoch(parent, slot)?;
// this is a dev node environment, we should always be able to claim a slot.
let logs = if let Some((predigest, _)) = authorship::claim_slot(
slot,
&epoch,
&self.keystore,
) {
vec![
<DigestItemFor<B> as CompatibleDigestItem>::babe_pre_digest(predigest),
]
let logs = if let Some((predigest, _)) =
authorship::claim_slot(slot, &epoch, &self.keystore)
{
vec![<DigestItemFor<B> as CompatibleDigestItem>::babe_pre_digest(predigest)]
} else {
// well we couldn't claim a slot because this is an existing chain and we're not in the authorities.
// we need to tell BabeBlockImport that the epoch has changed, and we put ourselves in the authorities.
let predigest = PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
slot,
authority_index: 0_u32,
});
let predigest =
PreDigest::SecondaryPlain(SecondaryPlainPreDigest { slot, authority_index: 0_u32 });
let mut epoch_changes = self.epoch_changes.shared_data();
let epoch_descriptor = epoch_changes
@@ -232,12 +231,15 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
parent.number().clone(),
slot,
)
.map_err(|e| Error::StringError(format!("failed to fetch epoch_descriptor: {}", e)))?
.map_err(|e| {
Error::StringError(format!("failed to fetch epoch_descriptor: {}", e))
})?
.ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet)?;
match epoch_descriptor {
ViableEpochDescriptor::Signaled(identifier, _epoch_header) => {
let epoch_mut = epoch_changes.epoch_mut(&identifier)
let epoch_mut = epoch_changes
.epoch_mut(&identifier)
.ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet)?;
// mutate the current epoch
@@ -251,15 +253,13 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
vec![
DigestItemFor::<B>::PreRuntime(BABE_ENGINE_ID, predigest.encode()),
DigestItemFor::<B>::Consensus(BABE_ENGINE_ID, next_epoch.encode())
DigestItemFor::<B>::Consensus(BABE_ENGINE_ID, next_epoch.encode()),
]
},
ViableEpochDescriptor::UnimportedGenesis(_) => {
// since this is the genesis, secondary predigest works for now.
vec![
DigestItemFor::<B>::PreRuntime(BABE_ENGINE_ID, predigest.encode()),
]
}
vec![DigestItemFor::<B>::PreRuntime(BABE_ENGINE_ID, predigest.encode())]
},
}
};
@@ -270,9 +270,10 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
&self,
parent: &B::Header,
params: &mut BlockImportParams<B, Self::Transaction>,
inherents: &InherentData
inherents: &InherentData,
) -> Result<(), Error> {
let slot = inherents.babe_inherent_data()?
let slot = inherents
.babe_inherent_data()?
.ok_or_else(|| Error::StringError("No babe inherent data".into()))?;
let epoch_changes = self.epoch_changes.shared_data();
let mut epoch_descriptor = epoch_changes
@@ -289,27 +290,27 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
// a quick check to see if we're in the authorities
let epoch = self.epoch(parent, slot)?;
let (authority, _) = self.authorities.first().expect("authorities is non-emptyp; qed");
let has_authority = epoch.authorities.iter()
.find(|(id, _)| *id == *authority)
.is_some();
let has_authority = epoch.authorities.iter().find(|(id, _)| *id == *authority).is_some();
if !has_authority {
log::info!(target: "manual-seal", "authority not found");
let timestamp = inherents.timestamp_inherent_data()?
let timestamp = inherents
.timestamp_inherent_data()?
.ok_or_else(|| Error::StringError("No timestamp inherent data".into()))?;
let slot = *timestamp / self.config.slot_duration;
// manually hard code epoch descriptor
epoch_descriptor = match epoch_descriptor {
ViableEpochDescriptor::Signaled(identifier, _header) => {
ViableEpochDescriptor::Signaled(identifier, _header) =>
ViableEpochDescriptor::Signaled(
identifier,
EpochHeader {
start_slot: slot.into(),
end_slot: (slot * self.config.epoch_length).into(),
},
)
},
_ => unreachable!("we're not in the authorities, so this isn't the genesis epoch; qed")
),
_ => unreachable!(
"we're not in the authorities, so this isn't the genesis epoch; qed"
),
};
}
@@ -326,16 +327,16 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
/// Mocks the timestamp inherent to always produce the timestamp for the next babe slot.
pub struct SlotTimestampProvider {
time: atomic::AtomicU64,
slot_duration: u64
slot_duration: u64,
}
impl SlotTimestampProvider {
/// Create a new mocked time stamp provider.
pub fn new<B, C>(client: Arc<C>) -> Result<Self, Error>
where
B: BlockT,
C: AuxStore + HeaderBackend<B> + ProvideRuntimeApi<B> + UsageProvider<B>,
C::Api: BabeApi<B>,
where
B: BlockT,
C: AuxStore + HeaderBackend<B> + ProvideRuntimeApi<B> + UsageProvider<B>,
C::Api: BabeApi<B>,
{
let slot_duration = Config::get_or_compute(&*client)?.slot_duration;
let info = client.info();
@@ -355,10 +356,7 @@ impl SlotTimestampProvider {
.as_millis() as u64
};
Ok(Self {
time: atomic::AtomicU64::new(time),
slot_duration,
})
Ok(Self { time: atomic::AtomicU64::new(time), slot_duration })
}
/// Get the current slot number
@@ -369,12 +367,13 @@ impl SlotTimestampProvider {
#[async_trait::async_trait]
impl InherentDataProvider for SlotTimestampProvider {
fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), sp_inherents::Error> {
fn provide_inherent_data(
&self,
inherent_data: &mut InherentData,
) -> Result<(), sp_inherents::Error> {
// we update the time here.
let duration: InherentType = self.time.fetch_add(
self.slot_duration,
atomic::Ordering::SeqCst,
).into();
let duration: InherentType =
self.time.fetch_add(self.slot_duration, atomic::Ordering::SeqCst).into();
inherent_data.put_data(INHERENT_IDENTIFIER, &duration)?;
Ok(())
}
@@ -19,10 +19,10 @@
//! A manual sealing engine: the engine listens for rpc calls to seal blocks and create forks.
//! This is suitable for a testing environment.
use sp_consensus::{Error as ConsensusError, ImportResult};
use futures::channel::{mpsc::SendError, oneshot};
use sp_blockchain::Error as BlockchainError;
use sp_consensus::{Error as ConsensusError, ImportResult};
use sp_inherents::Error as InherentsError;
use futures::channel::{oneshot, mpsc::SendError};
/// Error code for rpc
mod codes {
@@ -63,14 +63,14 @@ pub enum Error {
#[display(fmt = "{}", _0)]
#[from(ignore)]
StringError(String),
///send error
/// send error
#[display(fmt = "Consensus process is terminating")]
Canceled(oneshot::Canceled),
///send error
/// send error
#[display(fmt = "Consensus process is terminating")]
SendError(SendError),
/// Some other error.
#[display(fmt="Other error: {}", _0)]
#[display(fmt = "Other error: {}", _0)]
Other(Box<dyn std::error::Error + Send>),
}
@@ -85,7 +85,7 @@ impl Error {
InherentError(_) => codes::INHERENTS_ERROR,
BlockchainError(_) => codes::BLOCKCHAIN_ERROR,
SendError(_) | Canceled(_) => codes::SERVER_SHUTTING_DOWN,
_ => codes::UNKNOWN_ERROR
_ => codes::UNKNOWN_ERROR,
}
}
}
@@ -95,7 +95,7 @@ impl std::convert::From<Error> for jsonrpc_core::Error {
jsonrpc_core::Error {
code: jsonrpc_core::ErrorCode::ServerError(error.to_code()),
message: format!("{}", error),
data: None
data: None,
}
}
}
@@ -19,14 +19,9 @@
//! Block finalization utilities
use crate::rpc;
use sp_runtime::{
Justification,
traits::Block as BlockT,
generic::BlockId,
};
use std::sync::Arc;
use sc_client_api::backend::{Backend as ClientBackend, Finalizer};
use std::marker::PhantomData;
use sp_runtime::{generic::BlockId, traits::Block as BlockT, Justification};
use std::{marker::PhantomData, sync::Arc};
/// params for block finalization.
pub struct FinalizeBlockParams<B: BlockT, F, CB> {
@@ -42,30 +37,23 @@ pub struct FinalizeBlockParams<B: BlockT, F, CB> {
pub _phantom: PhantomData<CB>,
}
/// finalizes a block in the backend with the given params.
pub async fn finalize_block<B, F, CB>(params: FinalizeBlockParams<B, F, CB>)
where
B: BlockT,
F: Finalizer<B, CB>,
CB: ClientBackend<B>,
where
B: BlockT,
F: Finalizer<B, CB>,
CB: ClientBackend<B>,
{
let FinalizeBlockParams {
hash,
mut sender,
justification,
finalizer,
..
} = params;
let FinalizeBlockParams { hash, mut sender, justification, finalizer, .. } = params;
match finalizer.finalize_block(BlockId::Hash(hash), justification, true) {
Err(e) => {
log::warn!("Failed to finalize block {:?}", e);
rpc::send_result(&mut sender, Err(e.into()))
}
},
Ok(()) => {
log::info!("✅ Successfully finalized block: {}", hash);
rpc::send_result(&mut sender, Ok(()))
}
},
}
}
+171 -201
View File
@@ -20,17 +20,17 @@
//! This is suitable for a testing environment.
use futures::prelude::*;
use sp_consensus::{
Environment, Proposer, SelectChain, BlockImport,
ForkChoiceStrategy, BlockImportParams, BlockOrigin,
import_queue::{Verifier, BasicQueue, CacheKeyId, BoxBlockImport},
};
use sp_blockchain::HeaderBackend;
use sp_inherents::CreateInherentDataProviders;
use sp_runtime::{traits::Block as BlockT, Justifications, ConsensusEngineId};
use sc_client_api::backend::{Backend as ClientBackend, Finalizer};
use std::{sync::Arc, marker::PhantomData};
use prometheus_endpoint::Registry;
use sc_client_api::backend::{Backend as ClientBackend, Finalizer};
use sp_blockchain::HeaderBackend;
use sp_consensus::{
import_queue::{BasicQueue, BoxBlockImport, CacheKeyId, Verifier},
BlockImport, BlockImportParams, BlockOrigin, Environment, ForkChoiceStrategy, Proposer,
SelectChain,
};
use sp_inherents::CreateInherentDataProviders;
use sp_runtime::{traits::Block as BlockT, ConsensusEngineId, Justifications};
use std::{marker::PhantomData, sync::Arc};
mod error;
mod finalize_block;
@@ -40,14 +40,14 @@ pub mod consensus;
pub mod rpc;
pub use self::{
error::Error,
consensus::ConsensusDataProvider,
error::Error,
finalize_block::{finalize_block, FinalizeBlockParams},
seal_block::{SealBlockParams, seal_block, MAX_PROPOSAL_DURATION},
rpc::{EngineCommand, CreatedBlock},
rpc::{CreatedBlock, EngineCommand},
seal_block::{seal_block, SealBlockParams, MAX_PROPOSAL_DURATION},
};
use sp_api::{ProvideRuntimeApi, TransactionFor};
use sc_transaction_pool_api::TransactionPool;
use sp_api::{ProvideRuntimeApi, TransactionFor};
/// The `ConsensusEngineId` of Manual Seal.
pub const MANUAL_SEAL_ENGINE_ID: ConsensusEngineId = [b'm', b'a', b'n', b'l'];
@@ -80,17 +80,11 @@ pub fn import_queue<Block, Transaction>(
spawner: &impl sp_core::traits::SpawnEssentialNamed,
registry: Option<&Registry>,
) -> BasicQueue<Block, Transaction>
where
Block: BlockT,
Transaction: Send + Sync + 'static,
where
Block: BlockT,
Transaction: Send + Sync + 'static,
{
BasicQueue::new(
ManualSealVerifier,
block_import,
None,
spawner,
registry,
)
BasicQueue::new(ManualSealVerifier, block_import, None, spawner, registry)
}
/// Params required to start the instant sealing authorship task.
@@ -115,7 +109,8 @@ pub struct ManualSealParams<B: BlockT, BI, E, C: ProvideRuntimeApi<B>, TP, SC, C
pub select_chain: SC,
/// Digest provider for inclusion in blocks.
pub consensus_data_provider: Option<Box<dyn ConsensusDataProvider<B, Transaction = TransactionFor<C, B>>>>,
pub consensus_data_provider:
Option<Box<dyn ConsensusDataProvider<B, Transaction = TransactionFor<C, B>>>>,
/// Something that can create the inherent data providers.
pub create_inherent_data_providers: CIDP,
@@ -139,7 +134,8 @@ pub struct InstantSealParams<B: BlockT, BI, E, C: ProvideRuntimeApi<B>, TP, SC,
pub select_chain: SC,
/// Digest provider for inclusion in blocks.
pub consensus_data_provider: Option<Box<dyn ConsensusDataProvider<B, Transaction = TransactionFor<C, B>>>>,
pub consensus_data_provider:
Option<Box<dyn ConsensusDataProvider<B, Transaction = TransactionFor<C, B>>>>,
/// Something that can create the inherent data providers.
pub create_inherent_data_providers: CIDP,
@@ -156,58 +152,52 @@ pub async fn run_manual_seal<B, BI, CB, E, C, TP, SC, CS, CIDP>(
select_chain,
consensus_data_provider,
create_inherent_data_providers,
}: ManualSealParams<B, BI, E, C, TP, SC, CS, CIDP>
)
where
B: BlockT + 'static,
BI: BlockImport<B, Error = sp_consensus::Error, Transaction = sp_api::TransactionFor<C, B>>
+ Send + Sync + 'static,
C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + 'static,
CB: ClientBackend<B> + 'static,
E: Environment<B> + 'static,
E::Proposer: Proposer<B, Transaction = TransactionFor<C, B>>,
CS: Stream<Item=EngineCommand<<B as BlockT>::Hash>> + Unpin + 'static,
SC: SelectChain<B> + 'static,
TransactionFor<C, B>: 'static,
TP: TransactionPool<Block = B>,
CIDP: CreateInherentDataProviders<B, ()>,
}: ManualSealParams<B, BI, E, C, TP, SC, CS, CIDP>,
) where
B: BlockT + 'static,
BI: BlockImport<B, Error = sp_consensus::Error, Transaction = sp_api::TransactionFor<C, B>>
+ Send
+ Sync
+ 'static,
C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + 'static,
CB: ClientBackend<B> + 'static,
E: Environment<B> + 'static,
E::Proposer: Proposer<B, Transaction = TransactionFor<C, B>>,
CS: Stream<Item = EngineCommand<<B as BlockT>::Hash>> + Unpin + 'static,
SC: SelectChain<B> + 'static,
TransactionFor<C, B>: 'static,
TP: TransactionPool<Block = B>,
CIDP: CreateInherentDataProviders<B, ()>,
{
while let Some(command) = commands_stream.next().await {
match command {
EngineCommand::SealNewBlock {
create_empty,
finalize,
parent_hash,
sender,
} => {
seal_block(
SealBlockParams {
sender,
parent_hash,
finalize,
create_empty,
env: &mut env,
select_chain: &select_chain,
block_import: &mut block_import,
consensus_data_provider: consensus_data_provider.as_ref().map(|p| &**p),
pool: pool.clone(),
client: client.clone(),
create_inherent_data_providers: &create_inherent_data_providers,
}
).await;
}
EngineCommand::SealNewBlock { create_empty, finalize, parent_hash, sender } => {
seal_block(SealBlockParams {
sender,
parent_hash,
finalize,
create_empty,
env: &mut env,
select_chain: &select_chain,
block_import: &mut block_import,
consensus_data_provider: consensus_data_provider.as_ref().map(|p| &**p),
pool: pool.clone(),
client: client.clone(),
create_inherent_data_providers: &create_inherent_data_providers,
})
.await;
},
EngineCommand::FinalizeBlock { hash, sender, justification } => {
let justification = justification.map(|j| (MANUAL_SEAL_ENGINE_ID, j));
finalize_block(
FinalizeBlockParams {
hash,
sender,
justification,
finalizer: client.clone(),
_phantom: PhantomData,
}
).await
}
finalize_block(FinalizeBlockParams {
hash,
sender,
justification,
finalizer: client.clone(),
_phantom: PhantomData,
})
.await
},
}
}
}
@@ -224,63 +214,57 @@ pub async fn run_instant_seal<B, BI, CB, E, C, TP, SC, CIDP>(
select_chain,
consensus_data_provider,
create_inherent_data_providers,
}: InstantSealParams<B, BI, E, C, TP, SC, CIDP>
)
where
B: BlockT + 'static,
BI: BlockImport<B, Error = sp_consensus::Error, Transaction = sp_api::TransactionFor<C, B>>
+ Send + Sync + 'static,
C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + 'static,
CB: ClientBackend<B> + 'static,
E: Environment<B> + 'static,
E::Proposer: Proposer<B, Transaction = TransactionFor<C, B>>,
SC: SelectChain<B> + 'static,
TransactionFor<C, B>: 'static,
TP: TransactionPool<Block = B>,
CIDP: CreateInherentDataProviders<B, ()>,
}: InstantSealParams<B, BI, E, C, TP, SC, CIDP>,
) where
B: BlockT + 'static,
BI: BlockImport<B, Error = sp_consensus::Error, Transaction = sp_api::TransactionFor<C, B>>
+ Send
+ Sync
+ 'static,
C: HeaderBackend<B> + Finalizer<B, CB> + ProvideRuntimeApi<B> + 'static,
CB: ClientBackend<B> + 'static,
E: Environment<B> + 'static,
E::Proposer: Proposer<B, Transaction = TransactionFor<C, B>>,
SC: SelectChain<B> + 'static,
TransactionFor<C, B>: 'static,
TP: TransactionPool<Block = B>,
CIDP: CreateInherentDataProviders<B, ()>,
{
// instant-seal creates blocks as soon as transactions are imported
// into the transaction pool.
let commands_stream = pool.import_notification_stream()
.map(|_| {
EngineCommand::SealNewBlock {
create_empty: false,
finalize: false,
parent_hash: None,
sender: None,
}
});
let commands_stream = pool.import_notification_stream().map(|_| EngineCommand::SealNewBlock {
create_empty: false,
finalize: false,
parent_hash: None,
sender: None,
});
run_manual_seal(
ManualSealParams {
block_import,
env,
client,
pool,
commands_stream,
select_chain,
consensus_data_provider,
create_inherent_data_providers,
}
).await
run_manual_seal(ManualSealParams {
block_import,
env,
client,
pool,
commands_stream,
select_chain,
consensus_data_provider,
create_inherent_data_providers,
})
.await
}
#[cfg(test)]
mod tests {
use super::*;
use substrate_test_runtime_client::{
DefaultTestClientBuilderExt,
TestClientBuilderExt,
AccountKeyring::*,
TestClientBuilder,
};
use sc_transaction_pool::{BasicPool, RevalidationType, Options};
use substrate_test_runtime_transaction_pool::{TestApi, uxt};
use sc_transaction_pool_api::{TransactionPool, MaintainedTransactionPool, TransactionSource};
use sp_runtime::generic::BlockId;
use sp_consensus::ImportedAux;
use sc_basic_authorship::ProposerFactory;
use sc_client_api::BlockBackend;
use sc_transaction_pool::{BasicPool, Options, RevalidationType};
use sc_transaction_pool_api::{MaintainedTransactionPool, TransactionPool, TransactionSource};
use sp_consensus::ImportedAux;
use sp_runtime::generic::BlockId;
use substrate_test_runtime_client::{
AccountKeyring::*, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt,
};
use substrate_test_runtime_transaction_pool::{uxt, TestApi};
fn api() -> Arc<TestApi> {
Arc::new(TestApi::empty())
@@ -303,40 +287,32 @@ mod tests {
spawner.clone(),
0,
));
let env = ProposerFactory::new(
spawner.clone(),
client.clone(),
pool.clone(),
None,
None,
);
let env = ProposerFactory::new(spawner.clone(), client.clone(), pool.clone(), None, None);
// this test checks that blocks are created as soon as transactions are imported into the pool.
let (sender, receiver) = futures::channel::oneshot::channel();
let mut sender = Arc::new(Some(sender));
let commands_stream = pool.pool().validated_pool().import_notification_stream()
.map(move |_| {
let commands_stream =
pool.pool().validated_pool().import_notification_stream().map(move |_| {
// we're only going to submit one tx so this fn will only be called once.
let mut_sender = Arc::get_mut(&mut sender).unwrap();
let mut_sender = Arc::get_mut(&mut sender).unwrap();
let sender = std::mem::take(mut_sender);
EngineCommand::SealNewBlock {
create_empty: false,
finalize: true,
parent_hash: None,
sender
sender,
}
});
let future = run_manual_seal(
ManualSealParams {
block_import: client.clone(),
env,
client: client.clone(),
pool: pool.clone(),
commands_stream,
select_chain,
create_inherent_data_providers: |_, _| async { Ok(()) },
consensus_data_provider: None,
}
);
let future = run_manual_seal(ManualSealParams {
block_import: client.clone(),
env,
client: client.clone(),
pool: pool.clone(),
commands_stream,
select_chain,
create_inherent_data_providers: |_, _| async { Ok(()) },
consensus_data_provider: None,
});
std::thread::spawn(|| {
let mut rt = tokio::runtime::Runtime::new().unwrap();
// spawn the background authorship task
@@ -380,27 +356,19 @@ mod tests {
spawner.clone(),
0,
));
let env = ProposerFactory::new(
spawner.clone(),
client.clone(),
pool.clone(),
None,
None,
);
let env = ProposerFactory::new(spawner.clone(), client.clone(), pool.clone(), None, None);
// this test checks that blocks are created as soon as an engine command is sent over the stream.
let (mut sink, commands_stream) = futures::channel::mpsc::channel(1024);
let future = run_manual_seal(
ManualSealParams {
block_import: client.clone(),
env,
client: client.clone(),
pool: pool.clone(),
commands_stream,
select_chain,
consensus_data_provider: None,
create_inherent_data_providers: |_, _| async { Ok(()) },
}
);
let future = run_manual_seal(ManualSealParams {
block_import: client.clone(),
env,
client: client.clone(),
pool: pool.clone(),
commands_stream,
select_chain,
consensus_data_provider: None,
create_inherent_data_providers: |_, _| async { Ok(()) },
});
std::thread::spawn(|| {
let mut rt = tokio::runtime::Runtime::new().unwrap();
// spawn the background authorship task
@@ -416,7 +384,9 @@ mod tests {
sender: Some(tx),
create_empty: false,
finalize: false,
}).await.unwrap();
})
.await
.unwrap();
let created_block = rx.await.unwrap().unwrap();
// assert that the background task returns ok
@@ -439,8 +409,10 @@ mod tests {
sink.send(EngineCommand::FinalizeBlock {
sender: Some(tx),
hash: header.hash(),
justification: None
}).await.unwrap();
justification: None,
})
.await
.unwrap();
// assert that the background task returns ok
assert_eq!(rx.await.unwrap().unwrap(), ());
}
@@ -461,27 +433,19 @@ mod tests {
spawner.clone(),
0,
));
let env = ProposerFactory::new(
spawner.clone(),
client.clone(),
pool.clone(),
None,
None,
);
let env = ProposerFactory::new(spawner.clone(), client.clone(), pool.clone(), None, None);
// this test checks that blocks are created as soon as an engine command is sent over the stream.
let (mut sink, commands_stream) = futures::channel::mpsc::channel(1024);
let future = run_manual_seal(
ManualSealParams {
block_import: client.clone(),
env,
client: client.clone(),
pool: pool.clone(),
commands_stream,
select_chain,
consensus_data_provider: None,
create_inherent_data_providers: |_, _| async { Ok(()) },
}
);
let future = run_manual_seal(ManualSealParams {
block_import: client.clone(),
env,
client: client.clone(),
pool: pool.clone(),
commands_stream,
select_chain,
consensus_data_provider: None,
create_inherent_data_providers: |_, _| async { Ok(()) },
});
std::thread::spawn(|| {
let mut rt = tokio::runtime::Runtime::new().unwrap();
// spawn the background authorship task
@@ -498,7 +462,9 @@ mod tests {
sender: Some(tx),
create_empty: false,
finalize: false,
}).await.unwrap();
})
.await
.unwrap();
let created_block = rx.await.unwrap().unwrap();
pool_api.increment_nonce(Alice.into());
@@ -524,31 +490,35 @@ mod tests {
pool.maintain(sc_transaction_pool_api::ChainEvent::NewBestBlock {
hash: header.hash(),
tree_route: None,
}).await;
})
.await;
let (tx1, rx1) = futures::channel::oneshot::channel();
assert!(sink.send(EngineCommand::SealNewBlock {
parent_hash: Some(created_block.hash),
sender: Some(tx1),
create_empty: false,
finalize: false,
}).await.is_ok());
assert_matches::assert_matches!(
rx1.await.expect("should be no error receiving"),
Ok(_)
);
assert!(sink
.send(EngineCommand::SealNewBlock {
parent_hash: Some(created_block.hash),
sender: Some(tx1),
create_empty: false,
finalize: false,
})
.await
.is_ok());
assert_matches::assert_matches!(rx1.await.expect("should be no error receiving"), Ok(_));
let block = client.block(&BlockId::Number(2)).unwrap().unwrap().block;
pool_api.add_block(block, true);
pool_api.increment_nonce(Alice.into());
assert!(pool.submit_one(&BlockId::Number(1), SOURCE, uxt(Bob, 0)).await.is_ok());
let (tx2, rx2) = futures::channel::oneshot::channel();
assert!(sink.send(EngineCommand::SealNewBlock {
parent_hash: Some(created_block.hash),
sender: Some(tx2),
create_empty: false,
finalize: false,
}).await.is_ok());
assert!(sink
.send(EngineCommand::SealNewBlock {
parent_hash: Some(created_block.hash),
sender: Some(tx2),
create_empty: false,
finalize: false,
})
.await
.is_ok());
let imported = rx2.await.unwrap().unwrap();
// assert that fork block is in the db
assert!(client.header(&BlockId::Hash(imported.hash)).unwrap().is_some())
@@ -18,18 +18,16 @@
//! RPC interface for the `ManualSeal` Engine.
use sp_consensus::ImportedAux;
use jsonrpc_core::Error;
use jsonrpc_derive::rpc;
pub use self::gen_client::Client as ManualSealClient;
use futures::{
channel::{mpsc, oneshot},
TryFutureExt,
FutureExt,
SinkExt
FutureExt, SinkExt, TryFutureExt,
};
use jsonrpc_core::Error;
use jsonrpc_derive::rpc;
use serde::{Deserialize, Serialize};
use sp_consensus::ImportedAux;
use sp_runtime::EncodedJustification;
pub use self::gen_client::Client as ManualSealClient;
/// Future's type for jsonrpc
type FutureResult<T> = Box<dyn jsonrpc_core::futures::Future<Item = T, Error = Error> + Send>;
@@ -63,7 +61,7 @@ pub enum EngineCommand<Hash> {
sender: Sender<()>,
/// finalization justification
justification: Option<EncodedJustification>,
}
},
}
/// RPC trait that provides methods for interacting with the manual-seal authorship task over rpc.
@@ -75,7 +73,7 @@ pub trait ManualSealApi<Hash> {
&self,
create_empty: bool,
finalize: bool,
parent_hash: Option<Hash>
parent_hash: Option<Hash>,
) -> FutureResult<CreatedBlock<Hash>>;
/// Instructs the manual-seal authorship task to finalize a block
@@ -83,7 +81,7 @@ pub trait ManualSealApi<Hash> {
fn finalize_block(
&self,
hash: Hash,
justification: Option<EncodedJustification>
justification: Option<EncodedJustification>,
) -> FutureResult<bool>;
}
@@ -98,7 +96,7 @@ pub struct CreatedBlock<Hash> {
/// hash of the created block.
pub hash: Hash,
/// some extra details about the import operation
pub aux: ImportedAux
pub aux: ImportedAux,
}
impl<Hash> ManualSeal<Hash> {
@@ -113,7 +111,7 @@ impl<Hash: Send + 'static> ManualSealApi<Hash> for ManualSeal<Hash> {
&self,
create_empty: bool,
finalize: bool,
parent_hash: Option<Hash>
parent_hash: Option<Hash>,
) -> FutureResult<CreatedBlock<Hash>> {
let mut sink = self.import_block_channel.clone();
let future = async move {
@@ -126,18 +124,22 @@ impl<Hash: Send + 'static> ManualSealApi<Hash> for ManualSeal<Hash> {
};
sink.send(command).await?;
receiver.await?
}.boxed();
}
.boxed();
Box::new(future.map_err(Error::from).compat())
}
fn finalize_block(&self, hash: Hash, justification: Option<EncodedJustification>) -> FutureResult<bool> {
fn finalize_block(
&self,
hash: Hash,
justification: Option<EncodedJustification>,
) -> FutureResult<bool> {
let mut sink = self.import_block_channel.clone();
let future = async move {
let (sender, receiver) = oneshot::channel();
sink.send(
EngineCommand::FinalizeBlock { hash, sender: Some(sender), justification }
).await?;
sink.send(EngineCommand::FinalizeBlock { hash, sender: Some(sender), justification })
.await?;
receiver.await?.map(|_| true)
};
@@ -150,7 +152,7 @@ impl<Hash: Send + 'static> ManualSealApi<Hash> for ManualSeal<Hash> {
/// to the rpc
pub fn send_result<T: std::fmt::Debug>(
sender: &mut Sender<T>,
result: std::result::Result<T, crate::Error>
result: std::result::Result<T, crate::Error>,
) {
if let Some(sender) = sender.take() {
if let Err(err) = sender.send(result) {
@@ -160,7 +162,7 @@ pub fn send_result<T: std::fmt::Debug>(
// instant seal doesn't report errors over rpc, simply log them.
match result {
Ok(r) => log::info!("Instant Seal success: {:?}", r),
Err(e) => log::error!("Instant Seal encountered an error: {}", e)
Err(e) => log::error!("Instant Seal encountered an error: {}", e),
}
}
}
@@ -18,23 +18,21 @@
//! Block sealing utilities
use crate::{Error, rpc, CreatedBlock, ConsensusDataProvider};
use std::sync::Arc;
use sp_runtime::{
traits::{Block as BlockT, Header as HeaderT},
generic::BlockId,
};
use crate::{rpc, ConsensusDataProvider, CreatedBlock, Error};
use futures::prelude::*;
use sp_consensus::{
self, BlockImport, Environment, Proposer, ForkChoiceStrategy,
BlockImportParams, BlockOrigin, ImportResult, SelectChain, StateAction,
};
use sp_blockchain::HeaderBackend;
use std::collections::HashMap;
use std::time::Duration;
use sp_inherents::{CreateInherentDataProviders, InherentDataProvider};
use sp_api::{ProvideRuntimeApi, TransactionFor};
use sc_transaction_pool_api::TransactionPool;
use sp_api::{ProvideRuntimeApi, TransactionFor};
use sp_blockchain::HeaderBackend;
use sp_consensus::{
self, BlockImport, BlockImportParams, BlockOrigin, Environment, ForkChoiceStrategy,
ImportResult, Proposer, SelectChain, StateAction,
};
use sp_inherents::{CreateInherentDataProviders, InherentDataProvider};
use sp_runtime::{
generic::BlockId,
traits::{Block as BlockT, Header as HeaderT},
};
use std::{collections::HashMap, sync::Arc, time::Duration};
/// max duration for creating a proposal in secs
pub const MAX_PROPOSAL_DURATION: u64 = 10;
@@ -59,7 +57,8 @@ pub struct SealBlockParams<'a, B: BlockT, BI, SC, C: ProvideRuntimeApi<B>, E, TP
/// SelectChain object
pub select_chain: &'a SC,
/// Digest provider for inclusion in blocks.
pub consensus_data_provider: Option<&'a dyn ConsensusDataProvider<B, Transaction = TransactionFor<C, B>>>,
pub consensus_data_provider:
Option<&'a dyn ConsensusDataProvider<B, Transaction = TransactionFor<C, B>>>,
/// block import object
pub block_import: &'a mut BI,
/// Something that can create the inherent data providers.
@@ -97,7 +96,7 @@ pub async fn seal_block<B, BI, SC, C, E, TP, CIDP>(
{
let future = async {
if pool.status().ready == 0 && !create_empty {
return Err(Error::EmptyTransactionPool);
return Err(Error::EmptyTransactionPool)
}
// get the header to build this new block on.
@@ -129,12 +128,15 @@ pub async fn seal_block<B, BI, SC, C, E, TP, CIDP>(
Default::default()
};
let proposal = proposer.propose(
inherent_data.clone(),
digest,
Duration::from_secs(MAX_PROPOSAL_DURATION),
None,
).map_err(|err| Error::StringError(format!("{:?}", err))).await?;
let proposal = proposer
.propose(
inherent_data.clone(),
digest,
Duration::from_secs(MAX_PROPOSAL_DURATION),
None,
)
.map_err(|err| Error::StringError(format!("{:?}", err)))
.await?;
if proposal.block.extrinsics().len() == inherents_len && !create_empty {
return Err(Error::EmptyTransactionPool)
@@ -145,18 +147,17 @@ pub async fn seal_block<B, BI, SC, C, E, TP, CIDP>(
params.body = Some(body);
params.finalized = finalize;
params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
params.state_action = StateAction::ApplyChanges(
sp_consensus::StorageChanges::Changes(proposal.storage_changes)
);
params.state_action = StateAction::ApplyChanges(sp_consensus::StorageChanges::Changes(
proposal.storage_changes,
));
if let Some(digest_provider) = digest_provider {
digest_provider.append_block_import(&parent, &mut params, &inherent_data)?;
}
match block_import.import_block(params, HashMap::new()).await? {
ImportResult::Imported(aux) => {
Ok(CreatedBlock { hash: <B as BlockT>::Header::hash(&header), aux })
},
ImportResult::Imported(aux) =>
Ok(CreatedBlock { hash: <B as BlockT>::Header::hash(&header), aux }),
other => Err(other.into()),
}
};