mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Consolidate file structure in sc_tendermint
This commit is contained in:
@@ -1,22 +1,17 @@
|
|||||||
use std::{
|
use std::{
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::{Arc, RwLock},
|
sync::RwLock,
|
||||||
task::{Poll, Context},
|
task::{Poll, Context},
|
||||||
future::Future,
|
future::Future,
|
||||||
};
|
};
|
||||||
|
|
||||||
use sp_runtime::traits::{Header, Block};
|
use sp_runtime::traits::{Header, Block};
|
||||||
|
|
||||||
use sp_consensus::Error;
|
use sc_consensus::{BlockImportStatus, BlockImportError, Link};
|
||||||
use sc_consensus::{BlockImportStatus, BlockImportError, BlockImport, Link, BasicQueue};
|
|
||||||
|
|
||||||
use sc_service::ImportQueue;
|
use sc_service::ImportQueue;
|
||||||
|
|
||||||
use substrate_prometheus_endpoint::Registry;
|
use crate::TendermintImportQueue;
|
||||||
|
|
||||||
use crate::{types::TendermintValidator, TendermintImport};
|
|
||||||
|
|
||||||
pub type TendermintImportQueue<Block, Transaction> = BasicQueue<Block, Transaction>;
|
|
||||||
|
|
||||||
// Custom helpers for ImportQueue in order to obtain the result of a block's importing
|
// Custom helpers for ImportQueue in order to obtain the result of a block's importing
|
||||||
struct ValidateLink<B: Block>(Option<(B::Hash, bool)>);
|
struct ValidateLink<B: Block>(Option<(B::Hash, bool)>);
|
||||||
@@ -63,23 +58,3 @@ impl<'a, B: Block, T: Send> Future for ImportFuture<'a, B, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import_queue<T: TendermintValidator>(
|
|
||||||
spawner: &impl sp_core::traits::SpawnEssentialNamed,
|
|
||||||
client: Arc<T::Client>,
|
|
||||||
registry: Option<&Registry>,
|
|
||||||
) -> (TendermintImport<T>, TendermintImportQueue<T::Block, T::BackendTransaction>)
|
|
||||||
where
|
|
||||||
Arc<T::Client>: BlockImport<T::Block, Transaction = T::BackendTransaction>,
|
|
||||||
<Arc<T::Client> as BlockImport<T::Block>>::Error: Into<Error>,
|
|
||||||
{
|
|
||||||
let import = TendermintImport::<T>::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())
|
|
||||||
}
|
|
||||||
@@ -34,10 +34,15 @@ use tendermint_machine::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CONSENSUS_ID, types::TendermintValidator, validators::TendermintValidators,
|
CONSENSUS_ID, TendermintValidator, validators::TendermintValidators, tendermint::TendermintImport,
|
||||||
import_queue::ImportFuture, tendermint::TendermintImport, gossip::TendermintGossip,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod gossip;
|
||||||
|
use gossip::TendermintGossip;
|
||||||
|
|
||||||
|
mod import_future;
|
||||||
|
use import_future::ImportFuture;
|
||||||
|
|
||||||
// Data for an active validator
|
// Data for an active validator
|
||||||
// This is distinct as even when we aren't an authority, we still create stubbed Authority objects
|
// This is distinct as even when we aren't an authority, we still create stubbed Authority objects
|
||||||
// as it's only Authority which implements tendermint_machine::ext::Network. Network has
|
// as it's only Authority which implements tendermint_machine::ext::Network. Network has
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
use std::{sync::Arc, collections::HashMap};
|
use std::{marker::PhantomData, sync::Arc, collections::HashMap};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use sp_consensus::{Error, CacheKeyId};
|
use sp_api::BlockId;
|
||||||
|
use sp_runtime::traits::Block;
|
||||||
|
use sp_blockchain::{HeaderBackend, Backend as BlockchainBackend};
|
||||||
|
use sp_consensus::{Error, CacheKeyId, SelectChain};
|
||||||
|
|
||||||
use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImport, Verifier};
|
use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImport, Verifier};
|
||||||
|
|
||||||
use crate::{types::TendermintValidator, tendermint::TendermintImport};
|
use sc_client_api::Backend;
|
||||||
|
|
||||||
|
use crate::{TendermintValidator, tendermint::TendermintImport};
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: TendermintValidator> BlockImport<T::Block> for TendermintImport<T>
|
impl<T: TendermintValidator> BlockImport<T::Block> for TendermintImport<T>
|
||||||
@@ -60,3 +66,52 @@ where
|
|||||||
Ok((block, None))
|
Ok((block, None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SelectChain, while provided by Substrate and part of PartialComponents, isn't used by Substrate
|
||||||
|
// It's common between various block-production/finality crates, yet Substrate as a system doesn't
|
||||||
|
// rely on it, which is good, because its definition is explicitly incompatible with Tendermint
|
||||||
|
//
|
||||||
|
// leaves is supposed to return all leaves of the blockchain. While Tendermint maintains that view,
|
||||||
|
// an honest node will only build on the most recently finalized block, so it is a 'leaf' despite
|
||||||
|
// having descendants
|
||||||
|
//
|
||||||
|
// best_chain will always be this finalized block, yet Substrate explicitly defines it as one of
|
||||||
|
// the above leaves, which this finalized block is explicitly not included in. Accordingly, we
|
||||||
|
// can never provide a compatible decision
|
||||||
|
//
|
||||||
|
// Since PartialComponents expects it, an implementation which does its best is provided. It panics
|
||||||
|
// if leaves is called, yet returns the finalized chain tip for best_chain, as that's intended to
|
||||||
|
// be the header to build upon
|
||||||
|
pub struct TendermintSelectChain<B: Block, Be: Backend<B>>(Arc<Be>, PhantomData<B>);
|
||||||
|
|
||||||
|
impl<B: Block, Be: Backend<B>> Clone for TendermintSelectChain<B, Be> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
TendermintSelectChain(self.0.clone(), PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Block, Be: Backend<B>> TendermintSelectChain<B, Be> {
|
||||||
|
pub fn new(backend: Arc<Be>) -> TendermintSelectChain<B, Be> {
|
||||||
|
TendermintSelectChain(backend, PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<B: Block, Be: Backend<B>> SelectChain<B> for TendermintSelectChain<B, Be> {
|
||||||
|
async fn leaves(&self) -> Result<Vec<B::Hash>, Error> {
|
||||||
|
panic!("Substrate definition of leaves is incompatible with Tendermint")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn best_chain(&self) -> Result<B::Header, Error> {
|
||||||
|
Ok(
|
||||||
|
self
|
||||||
|
.0
|
||||||
|
.blockchain()
|
||||||
|
// There should always be a finalized block
|
||||||
|
.header(BlockId::Hash(self.0.blockchain().last_finalized().unwrap()))
|
||||||
|
// There should not be an error in retrieving it and since it's finalized, it should exist
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
mod types;
|
use std::sync::Arc;
|
||||||
pub use types::{TendermintClientMinimal, TendermintValidator};
|
|
||||||
|
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;
|
mod validators;
|
||||||
|
|
||||||
@@ -7,14 +21,103 @@ pub(crate) mod tendermint;
|
|||||||
pub use tendermint::TendermintImport;
|
pub use tendermint::TendermintImport;
|
||||||
|
|
||||||
mod block_import;
|
mod block_import;
|
||||||
mod import_queue;
|
pub use block_import::TendermintSelectChain;
|
||||||
pub use import_queue::{TendermintImportQueue, import_queue};
|
|
||||||
|
|
||||||
pub(crate) mod gossip;
|
|
||||||
pub(crate) mod authority;
|
pub(crate) mod authority;
|
||||||
pub use authority::TendermintAuthority;
|
pub use authority::TendermintAuthority;
|
||||||
|
|
||||||
mod select_chain;
|
|
||||||
pub use select_chain::TendermintSelectChain;
|
|
||||||
|
|
||||||
const CONSENSUS_ID: [u8; 4] = *b"tend";
|
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<Self::Block> + 'static;
|
||||||
|
|
||||||
|
/// TransactionFor<Client, Block>
|
||||||
|
type BackendTransaction: Send + Sync + 'static;
|
||||||
|
/// StateBackendFor<Client, Block>
|
||||||
|
type StateBackend: StateBackend<
|
||||||
|
<<Self::Block as Block>::Header as Header>::Hashing,
|
||||||
|
Transaction = Self::BackendTransaction,
|
||||||
|
>;
|
||||||
|
// Client::Api
|
||||||
|
type Api: ApiExt<Self::Block, StateBackend = Self::StateBackend> + TendermintApi<Self::Block>;
|
||||||
|
type Client: Send
|
||||||
|
+ Sync
|
||||||
|
+ HeaderBackend<Self::Block>
|
||||||
|
+ BlockBackend<Self::Block>
|
||||||
|
+ BlockImport<Self::Block, Transaction = Self::BackendTransaction>
|
||||||
|
+ Finalizer<Self::Block, Self::Backend>
|
||||||
|
+ ProvideRuntimeApi<Self::Block, Api = Self::Api>
|
||||||
|
+ '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<Self::Block> + 'static;
|
||||||
|
type Api: ApiExt<Self::Block> + TendermintApi<Self::Block>;
|
||||||
|
type Client: Send
|
||||||
|
+ Sync
|
||||||
|
+ HeaderBackend<Self::Block>
|
||||||
|
+ BlockBackend<Self::Block>
|
||||||
|
+ BlockImport<Self::Block, Transaction = TransactionFor<Self::Client, Self::Block>>
|
||||||
|
+ Finalizer<Self::Block, Self::Backend>
|
||||||
|
+ ProvideRuntimeApi<Self::Block, Api = Self::Api>
|
||||||
|
+ 'static;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: TendermintClientMinimal> TendermintClient for T
|
||||||
|
where
|
||||||
|
<T::Client as ProvideRuntimeApi<T::Block>>::Api: TendermintApi<T::Block>,
|
||||||
|
TransactionFor<T::Client, T::Block>: 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<T::Client, T::Block>;
|
||||||
|
type StateBackend = StateBackendFor<T::Client, T::Block>;
|
||||||
|
type Api = <T::Client as ProvideRuntimeApi<T::Block>>::Api;
|
||||||
|
type Client = T::Client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trait consolidating additional generics required by sc_tendermint for authoring.
|
||||||
|
pub trait TendermintValidator: TendermintClient {
|
||||||
|
type CIDP: CreateInherentDataProviders<Self::Block, ()> + 'static;
|
||||||
|
type Environment: Send + Sync + Environment<Self::Block> + 'static;
|
||||||
|
|
||||||
|
type Network: Clone
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ Network<Self::Block>
|
||||||
|
+ NetworkBlock<<Self::Block as Block>::Hash, <<Self::Block as Block>::Header as Header>::Number>
|
||||||
|
+ 'static;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type TendermintImportQueue<Block, Transaction> = BasicQueue<Block, Transaction>;
|
||||||
|
|
||||||
|
pub fn import_queue<T: TendermintValidator>(
|
||||||
|
spawner: &impl sp_core::traits::SpawnEssentialNamed,
|
||||||
|
client: Arc<T::Client>,
|
||||||
|
registry: Option<&Registry>,
|
||||||
|
) -> (TendermintImport<T>, TendermintImportQueue<T::Block, T::BackendTransaction>)
|
||||||
|
where
|
||||||
|
Arc<T::Client>: BlockImport<T::Block, Transaction = T::BackendTransaction>,
|
||||||
|
<Arc<T::Client> as BlockImport<T::Block>>::Error: Into<Error>,
|
||||||
|
{
|
||||||
|
let import = TendermintImport::<T>::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())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
// SelectChain, while provided by Substrate and part of PartialComponents, isn't used by Substrate
|
|
||||||
// It's common between various block-production/finality crates, yet Substrate as a system doesn't
|
|
||||||
// rely on it, which is good, because its definition is explicitly incompatible with Tendermint
|
|
||||||
//
|
|
||||||
// leaves is supposed to return all leaves of the blockchain. While Tendermint maintains that view,
|
|
||||||
// an honest node will only build on the most recently finalized block, so it is a 'leaf' despite
|
|
||||||
// having descendants
|
|
||||||
//
|
|
||||||
// best_chain will always be this finalized block, yet Substrate explicitly defines it as one of
|
|
||||||
// the above leaves, which this finalized block is explicitly not included in. Accordingly, we
|
|
||||||
// can never provide a compatible decision
|
|
||||||
//
|
|
||||||
// Since PartialComponents expects it, an implementation which does its best is provided. It panics
|
|
||||||
// if leaves is called, yet returns the finalized chain tip for best_chain, as that's intended to
|
|
||||||
// be the header to build upon
|
|
||||||
|
|
||||||
use std::{marker::PhantomData, sync::Arc};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
|
|
||||||
use sp_api::BlockId;
|
|
||||||
use sp_runtime::traits::Block;
|
|
||||||
use sp_blockchain::{HeaderBackend, Backend as BlockchainBackend};
|
|
||||||
use sc_client_api::Backend;
|
|
||||||
use sp_consensus::{Error, SelectChain};
|
|
||||||
|
|
||||||
pub struct TendermintSelectChain<B: Block, Be: Backend<B>>(Arc<Be>, PhantomData<B>);
|
|
||||||
|
|
||||||
impl<B: Block, Be: Backend<B>> Clone for TendermintSelectChain<B, Be> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
TendermintSelectChain(self.0.clone(), PhantomData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Block, Be: Backend<B>> TendermintSelectChain<B, Be> {
|
|
||||||
pub fn new(backend: Arc<Be>) -> TendermintSelectChain<B, Be> {
|
|
||||||
TendermintSelectChain(backend, PhantomData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<B: Block, Be: Backend<B>> SelectChain<B> for TendermintSelectChain<B, Be> {
|
|
||||||
async fn leaves(&self) -> Result<Vec<B::Hash>, Error> {
|
|
||||||
panic!("Substrate definition of leaves is incompatible with Tendermint")
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn best_chain(&self) -> Result<B::Header, Error> {
|
|
||||||
Ok(
|
|
||||||
self
|
|
||||||
.0
|
|
||||||
.blockchain()
|
|
||||||
// There should always be a finalized block
|
|
||||||
.header(BlockId::Hash(self.0.blockchain().last_finalized().unwrap()))
|
|
||||||
// There should not be an error in retrieving it and since it's finalized, it should exist
|
|
||||||
.unwrap()
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,8 +18,8 @@ use sc_consensus::{ForkChoiceStrategy, BlockImportParams};
|
|||||||
use tendermint_machine::ext::{Commit, Network};
|
use tendermint_machine::ext::{Commit, Network};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CONSENSUS_ID, types::TendermintValidator, validators::TendermintValidators,
|
CONSENSUS_ID, TendermintValidator, validators::TendermintValidators, TendermintImportQueue,
|
||||||
import_queue::TendermintImportQueue, authority::TendermintAuthority,
|
authority::TendermintAuthority,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TendermintImport<T: TendermintValidator> {
|
pub struct TendermintImport<T: TendermintValidator> {
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
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::Environment;
|
|
||||||
use sc_consensus::BlockImport;
|
|
||||||
|
|
||||||
use sc_client_api::{BlockBackend, Backend, Finalizer};
|
|
||||||
use sc_network::NetworkBlock;
|
|
||||||
use sc_network_gossip::Network;
|
|
||||||
|
|
||||||
use sp_tendermint::TendermintApi;
|
|
||||||
|
|
||||||
/// 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<Self::Block> + 'static;
|
|
||||||
|
|
||||||
/// TransactionFor<Client, Block>
|
|
||||||
type BackendTransaction: Send + Sync + 'static;
|
|
||||||
/// StateBackendFor<Client, Block>
|
|
||||||
type StateBackend: StateBackend<
|
|
||||||
<<Self::Block as Block>::Header as Header>::Hashing,
|
|
||||||
Transaction = Self::BackendTransaction,
|
|
||||||
>;
|
|
||||||
// Client::Api
|
|
||||||
type Api: ApiExt<Self::Block, StateBackend = Self::StateBackend> + TendermintApi<Self::Block>;
|
|
||||||
type Client: Send
|
|
||||||
+ Sync
|
|
||||||
+ HeaderBackend<Self::Block>
|
|
||||||
+ BlockBackend<Self::Block>
|
|
||||||
+ BlockImport<Self::Block, Transaction = Self::BackendTransaction>
|
|
||||||
+ Finalizer<Self::Block, Self::Backend>
|
|
||||||
+ ProvideRuntimeApi<Self::Block, Api = Self::Api>
|
|
||||||
+ '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<Self::Block> + 'static;
|
|
||||||
type Api: ApiExt<Self::Block> + TendermintApi<Self::Block>;
|
|
||||||
type Client: Send
|
|
||||||
+ Sync
|
|
||||||
+ HeaderBackend<Self::Block>
|
|
||||||
+ BlockBackend<Self::Block>
|
|
||||||
+ BlockImport<Self::Block, Transaction = TransactionFor<Self::Client, Self::Block>>
|
|
||||||
+ Finalizer<Self::Block, Self::Backend>
|
|
||||||
+ ProvideRuntimeApi<Self::Block, Api = Self::Api>
|
|
||||||
+ 'static;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: TendermintClientMinimal> TendermintClient for T
|
|
||||||
where
|
|
||||||
<T::Client as ProvideRuntimeApi<T::Block>>::Api: TendermintApi<T::Block>,
|
|
||||||
TransactionFor<T::Client, T::Block>: 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<T::Client, T::Block>;
|
|
||||||
type StateBackend = StateBackendFor<T::Client, T::Block>;
|
|
||||||
type Api = <T::Client as ProvideRuntimeApi<T::Block>>::Api;
|
|
||||||
type Client = T::Client;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait consolidating additional generics required by sc_tendermint for authoring.
|
|
||||||
pub trait TendermintValidator: TendermintClient {
|
|
||||||
type CIDP: CreateInherentDataProviders<Self::Block, ()> + 'static;
|
|
||||||
type Environment: Send + Sync + Environment<Self::Block> + 'static;
|
|
||||||
|
|
||||||
type Network: Clone
|
|
||||||
+ Send
|
|
||||||
+ Sync
|
|
||||||
+ Network<Self::Block>
|
|
||||||
+ NetworkBlock<<Self::Block as Block>::Hash, <<Self::Block as Block>::Header as Header>::Number>
|
|
||||||
+ 'static;
|
|
||||||
}
|
|
||||||
@@ -15,7 +15,7 @@ use tendermint_machine::ext::{BlockNumber, Round, Weights, SignatureScheme};
|
|||||||
|
|
||||||
use sp_tendermint::TendermintApi;
|
use sp_tendermint::TendermintApi;
|
||||||
|
|
||||||
use crate::types::TendermintClient;
|
use crate::TendermintClient;
|
||||||
|
|
||||||
struct TendermintValidatorsStruct {
|
struct TendermintValidatorsStruct {
|
||||||
session: SessionIndex,
|
session: SessionIndex,
|
||||||
|
|||||||
Reference in New Issue
Block a user