use std::sync::Arc; use sp_inherents::CreateInherentDataProviders; use sp_runtime::traits::{Header, Block}; use sp_blockchain::HeaderBackend; use sp_api::{StateBackend, StateBackendFor, TransactionFor, ApiExt, ProvideRuntimeApi}; use sp_consensus::{Error, Environment}; use sc_client_api::{BlockBackend, Backend, Finalizer}; use sc_consensus::{BlockImport, BasicQueue}; use sc_network::NetworkBlock; use sc_network_gossip::Network; use sp_tendermint::TendermintApi; use substrate_prometheus_endpoint::Registry; mod validators; pub(crate) mod tendermint; pub use tendermint::TendermintImport; mod block_import; pub use block_import::TendermintSelectChain; pub(crate) mod authority; pub use authority::TendermintAuthority; const CONSENSUS_ID: [u8; 4] = *b"tend"; /// Trait consolidating all generics required by sc_tendermint for processing. pub trait TendermintClient: Send + Sync + 'static { const BLOCK_TIME_IN_SECONDS: u32; type Block: Block; type Backend: Backend + 'static; /// TransactionFor type BackendTransaction: Send + Sync + 'static; /// StateBackendFor type StateBackend: StateBackend< <::Header as Header>::Hashing, Transaction = Self::BackendTransaction, >; // Client::Api type Api: ApiExt + TendermintApi; type Client: Send + Sync + HeaderBackend + BlockBackend + BlockImport + Finalizer + ProvideRuntimeApi + 'static; } /// Trait implementable on firm types to automatically provide a full TendermintClient impl. pub trait TendermintClientMinimal: Send + Sync + 'static { const BLOCK_TIME_IN_SECONDS: u32; type Block: Block; type Backend: Backend + 'static; type Api: ApiExt + TendermintApi; type Client: Send + Sync + HeaderBackend + BlockBackend + BlockImport> + Finalizer + ProvideRuntimeApi + 'static; } impl TendermintClient for T where >::Api: TendermintApi, TransactionFor: Send + Sync + 'static, { const BLOCK_TIME_IN_SECONDS: u32 = T::BLOCK_TIME_IN_SECONDS; type Block = T::Block; type Backend = T::Backend; type BackendTransaction = TransactionFor; type StateBackend = StateBackendFor; type Api = >::Api; type Client = T::Client; } /// Trait consolidating additional generics required by sc_tendermint for authoring. pub trait TendermintValidator: TendermintClient { type CIDP: CreateInherentDataProviders + 'static; type Environment: Send + Sync + Environment + 'static; type Network: Clone + Send + Sync + Network + NetworkBlock<::Hash, <::Header as Header>::Number> + 'static; } pub type TendermintImportQueue = BasicQueue; pub fn import_queue( spawner: &impl sp_core::traits::SpawnEssentialNamed, client: Arc, registry: Option<&Registry>, ) -> (TendermintImport, TendermintImportQueue) where Arc: BlockImport, as BlockImport>::Error: Into, { let import = TendermintImport::::new(client); let boxed = Box::new(import.clone()); // Use None for the justification importer since justifications always come with blocks // Therefore, they're never imported after the fact, which is what mandates an importer let queue = || BasicQueue::new(import.clone(), boxed.clone(), None, spawner, registry); *futures::executor::block_on(import.queue.write()) = Some(queue()); (import.clone(), queue()) }