mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Remove the Future triggering the machine for an async fn
Enables passing data in, such as the network.
This commit is contained in:
@@ -1,7 +1,4 @@
|
|||||||
use std::{
|
use std::sync::{Arc, RwLock};
|
||||||
sync::{Arc, RwLock},
|
|
||||||
future::Future,
|
|
||||||
};
|
|
||||||
|
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
|
|
||||||
@@ -11,7 +8,9 @@ use sc_network::{NetworkService, NetworkBlock};
|
|||||||
use sc_telemetry::{Telemetry, TelemetryWorker};
|
use sc_telemetry::{Telemetry, TelemetryWorker};
|
||||||
|
|
||||||
use serai_runtime::{self, opaque::Block, RuntimeApi};
|
use serai_runtime::{self, opaque::Block, RuntimeApi};
|
||||||
pub(crate) use serai_consensus::{ExecutorDispatch, Announce, FullClient};
|
pub(crate) use serai_consensus::{
|
||||||
|
TendermintAuthority, ExecutorDispatch, Announce, FullClient, TendermintValidatorFirm,
|
||||||
|
};
|
||||||
|
|
||||||
type FullBackend = sc_service::TFullBackend<Block>;
|
type FullBackend = sc_service::TFullBackend<Block>;
|
||||||
type FullSelectChain = serai_consensus::TendermintSelectChain<Block, FullBackend>;
|
type FullSelectChain = serai_consensus::TendermintSelectChain<Block, FullBackend>;
|
||||||
@@ -42,7 +41,13 @@ impl Announce<Block> for NetworkAnnounce {
|
|||||||
|
|
||||||
pub fn new_partial(
|
pub fn new_partial(
|
||||||
config: &Configuration,
|
config: &Configuration,
|
||||||
) -> Result<((NetworkAnnounce, impl Future<Output = ()>), PartialComponents), ServiceError> {
|
) -> Result<
|
||||||
|
(
|
||||||
|
(NetworkAnnounce, TendermintAuthority<TendermintValidatorFirm<NetworkAnnounce>>),
|
||||||
|
PartialComponents,
|
||||||
|
),
|
||||||
|
ServiceError,
|
||||||
|
> {
|
||||||
if config.keystore_remote.is_some() {
|
if config.keystore_remote.is_some() {
|
||||||
return Err(ServiceError::Other("Remote Keystores are not supported".to_string()));
|
return Err(ServiceError::Other("Remote Keystores are not supported".to_string()));
|
||||||
}
|
}
|
||||||
@@ -179,7 +184,7 @@ pub async fn new_full(config: Configuration) -> Result<TaskManager, ServiceError
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
if is_authority {
|
if is_authority {
|
||||||
authority.await;
|
authority.validate().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
network_starter.start_network();
|
network_starter.start_network();
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ use async_trait::async_trait;
|
|||||||
use sp_consensus::{Error, CacheKeyId};
|
use sp_consensus::{Error, CacheKeyId};
|
||||||
use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImport};
|
use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImport};
|
||||||
|
|
||||||
use crate::{types::TendermintAuthor, tendermint::TendermintImport};
|
use crate::{types::TendermintValidator, tendermint::TendermintImport};
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: TendermintAuthor> BlockImport<T::Block> for TendermintImport<T>
|
impl<T: TendermintValidator> BlockImport<T::Block> for TendermintImport<T>
|
||||||
where
|
where
|
||||||
Arc<T::Client>: BlockImport<T::Block, Transaction = T::BackendTransaction>,
|
Arc<T::Client>: BlockImport<T::Block, Transaction = T::BackendTransaction>,
|
||||||
<Arc<T::Client> as BlockImport<T::Block>>::Error: Into<Error>,
|
<Arc<T::Client> as BlockImport<T::Block>>::Error: Into<Error>,
|
||||||
|
|||||||
@@ -1,32 +1,22 @@
|
|||||||
use std::{
|
use std::{
|
||||||
convert::TryInto,
|
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
task::{Poll, Context},
|
task::{Poll, Context},
|
||||||
future::Future,
|
future::Future,
|
||||||
time::{UNIX_EPOCH, SystemTime},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use sp_core::Decode;
|
|
||||||
use sp_runtime::traits::{Header, Block};
|
use sp_runtime::traits::{Header, Block};
|
||||||
use sp_api::BlockId;
|
|
||||||
|
|
||||||
use sp_consensus::Error;
|
use sp_consensus::Error;
|
||||||
use sc_consensus::{BlockImportStatus, BlockImportError, BlockImport, Link, BasicQueue};
|
use sc_consensus::{BlockImportStatus, BlockImportError, BlockImport, Link, BasicQueue};
|
||||||
|
|
||||||
use sc_service::ImportQueue;
|
use sc_service::ImportQueue;
|
||||||
use sc_client_api::{HeaderBackend, BlockBackend};
|
|
||||||
|
|
||||||
use substrate_prometheus_endpoint::Registry;
|
use substrate_prometheus_endpoint::Registry;
|
||||||
|
|
||||||
use tendermint_machine::{
|
|
||||||
ext::{BlockNumber, Commit},
|
|
||||||
TendermintMachine,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CONSENSUS_ID, types::TendermintAuthor, validators::TendermintValidators,
|
types::TendermintValidator,
|
||||||
tendermint::TendermintImport,
|
tendermint::{TendermintImport, TendermintAuthority},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type TendermintImportQueue<Block, Transaction> = BasicQueue<Block, Transaction>;
|
pub type TendermintImportQueue<Block, Transaction> = BasicQueue<Block, Transaction>;
|
||||||
@@ -77,54 +67,20 @@ impl<'a, B: Block, T: Send> Future for ImportFuture<'a, B, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import_queue<T: TendermintAuthor>(
|
pub fn import_queue<T: TendermintValidator>(
|
||||||
client: Arc<T::Client>,
|
client: Arc<T::Client>,
|
||||||
announce: T::Announce,
|
announce: T::Announce,
|
||||||
providers: Arc<T::CIDP>,
|
providers: Arc<T::CIDP>,
|
||||||
env: T::Environment,
|
env: T::Environment,
|
||||||
spawner: &impl sp_core::traits::SpawnEssentialNamed,
|
spawner: &impl sp_core::traits::SpawnEssentialNamed,
|
||||||
registry: Option<&Registry>,
|
registry: Option<&Registry>,
|
||||||
) -> (impl Future<Output = ()>, TendermintImportQueue<T::Block, T::BackendTransaction>)
|
) -> (TendermintAuthority<T>, TendermintImportQueue<T::Block, T::BackendTransaction>)
|
||||||
where
|
where
|
||||||
Arc<T::Client>: BlockImport<T::Block, Transaction = T::BackendTransaction>,
|
Arc<T::Client>: BlockImport<T::Block, Transaction = T::BackendTransaction>,
|
||||||
<Arc<T::Client> as BlockImport<T::Block>>::Error: Into<Error>,
|
<Arc<T::Client> as BlockImport<T::Block>>::Error: Into<Error>,
|
||||||
{
|
{
|
||||||
let import = TendermintImport::<T>::new(client, announce, providers, env);
|
let import = TendermintImport::<T>::new(client, announce, providers, env);
|
||||||
|
let authority = TendermintAuthority(import.clone());
|
||||||
let authority = {
|
|
||||||
let machine_clone = import.machine.clone();
|
|
||||||
let mut import_clone = import.clone();
|
|
||||||
let best = import.client.info().best_number;
|
|
||||||
async move {
|
|
||||||
*machine_clone.write().unwrap() = Some(TendermintMachine::new(
|
|
||||||
import_clone.clone(),
|
|
||||||
// TODO
|
|
||||||
0,
|
|
||||||
(
|
|
||||||
// Header::Number: TryInto<u64> doesn't implement Debug and can't be unwrapped
|
|
||||||
match TryInto::<u64>::try_into(best) {
|
|
||||||
Ok(best) => BlockNumber(best + 1),
|
|
||||||
Err(_) => panic!("BlockNumber exceeded u64"),
|
|
||||||
},
|
|
||||||
Commit::<TendermintValidators<T>>::decode(
|
|
||||||
&mut import_clone
|
|
||||||
.client
|
|
||||||
.justifications(&BlockId::Number(best))
|
|
||||||
.unwrap()
|
|
||||||
.map(|justifications| justifications.get(CONSENSUS_ID).cloned().unwrap())
|
|
||||||
.unwrap_or_default()
|
|
||||||
.as_ref(),
|
|
||||||
)
|
|
||||||
.map(|commit| commit.end_time)
|
|
||||||
// TODO: Genesis start time
|
|
||||||
.unwrap_or_else(|_| SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()),
|
|
||||||
),
|
|
||||||
import_clone
|
|
||||||
.get_proposal(&import_clone.client.header(BlockId::Number(0u8.into())).unwrap().unwrap())
|
|
||||||
.await,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let boxed = Box::new(import.clone());
|
let boxed = Box::new(import.clone());
|
||||||
// Use None for the justification importer since justifications always come with blocks
|
// Use None for the justification importer since justifications always come with blocks
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::{marker::PhantomData, boxed::Box, sync::Arc, future::Future, error::Error};
|
use std::{marker::PhantomData, boxed::Box, sync::Arc, error::Error};
|
||||||
|
|
||||||
use sp_runtime::traits::Block as BlockTrait;
|
use sp_runtime::traits::Block as BlockTrait;
|
||||||
use sp_inherents::CreateInherentDataProviders;
|
use sp_inherents::CreateInherentDataProviders;
|
||||||
@@ -14,11 +14,12 @@ use substrate_prometheus_endpoint::Registry;
|
|||||||
use serai_runtime::{self, opaque::Block, RuntimeApi};
|
use serai_runtime::{self, opaque::Block, RuntimeApi};
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
use types::{TendermintClientMinimal, TendermintAuthor};
|
use types::{TendermintClientMinimal, TendermintValidator};
|
||||||
|
|
||||||
mod validators;
|
mod validators;
|
||||||
|
|
||||||
mod tendermint;
|
mod tendermint;
|
||||||
|
pub use tendermint::TendermintAuthority;
|
||||||
mod block_import;
|
mod block_import;
|
||||||
mod verifier;
|
mod verifier;
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ pub trait Announce<B: BlockTrait>: Send + Sync + Clone + 'static {
|
|||||||
fn announce(&self, hash: B::Hash);
|
fn announce(&self, hash: B::Hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Cidp;
|
pub struct Cidp;
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl CreateInherentDataProviders<Block, ()> for Cidp {
|
impl CreateInherentDataProviders<Block, ()> for Cidp {
|
||||||
type InherentDataProviders = (sp_timestamp::InherentDataProvider,);
|
type InherentDataProviders = (sp_timestamp::InherentDataProvider,);
|
||||||
@@ -67,15 +68,15 @@ impl CreateInherentDataProviders<Block, ()> for Cidp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TendermintAuthorFirm<A: Announce<Block>>(PhantomData<A>);
|
pub struct TendermintValidatorFirm<A: Announce<Block>>(PhantomData<A>);
|
||||||
impl<A: Announce<Block>> TendermintClientMinimal for TendermintAuthorFirm<A> {
|
impl<A: Announce<Block>> TendermintClientMinimal for TendermintValidatorFirm<A> {
|
||||||
type Block = Block;
|
type Block = Block;
|
||||||
type Backend = sc_client_db::Backend<Block>;
|
type Backend = sc_client_db::Backend<Block>;
|
||||||
type Api = <FullClient as ProvideRuntimeApi<Block>>::Api;
|
type Api = <FullClient as ProvideRuntimeApi<Block>>::Api;
|
||||||
type Client = FullClient;
|
type Client = FullClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: Announce<Block>> TendermintAuthor for TendermintAuthorFirm<A> {
|
impl<A: Announce<Block>> TendermintValidator for TendermintValidatorFirm<A> {
|
||||||
type CIDP = Cidp;
|
type CIDP = Cidp;
|
||||||
type Environment = sc_basic_authorship::ProposerFactory<
|
type Environment = sc_basic_authorship::ProposerFactory<
|
||||||
FullPool<Block, FullClient>,
|
FullPool<Block, FullClient>,
|
||||||
@@ -93,8 +94,11 @@ pub fn import_queue<A: Announce<Block>>(
|
|||||||
announce: A,
|
announce: A,
|
||||||
pool: Arc<FullPool<Block, FullClient>>,
|
pool: Arc<FullPool<Block, FullClient>>,
|
||||||
registry: Option<&Registry>,
|
registry: Option<&Registry>,
|
||||||
) -> (impl Future<Output = ()>, TendermintImportQueue<Block, TransactionFor<FullClient, Block>>) {
|
) -> (
|
||||||
import_queue::import_queue::<TendermintAuthorFirm<A>>(
|
TendermintAuthority<TendermintValidatorFirm<A>>,
|
||||||
|
TendermintImportQueue<Block, TransactionFor<FullClient, Block>>,
|
||||||
|
) {
|
||||||
|
import_queue::import_queue::<TendermintValidatorFirm<A>>(
|
||||||
client.clone(),
|
client.clone(),
|
||||||
announce,
|
announce,
|
||||||
Arc::new(Cidp),
|
Arc::new(Cidp),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
time::Duration,
|
time::{UNIX_EPOCH, SystemTime, Duration},
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
@@ -23,22 +23,22 @@ use sp_consensus::{Error, BlockOrigin, Proposer, Environment};
|
|||||||
use sc_consensus::{ForkChoiceStrategy, BlockImportParams, import_queue::IncomingBlock};
|
use sc_consensus::{ForkChoiceStrategy, BlockImportParams, import_queue::IncomingBlock};
|
||||||
|
|
||||||
use sc_service::ImportQueue;
|
use sc_service::ImportQueue;
|
||||||
use sc_client_api::Finalizer;
|
use sc_client_api::{BlockBackend, Finalizer};
|
||||||
|
|
||||||
use tendermint_machine::{
|
use tendermint_machine::{
|
||||||
ext::{BlockError, Commit, Network},
|
ext::{BlockError, BlockNumber, Commit, Network},
|
||||||
SignedMessage, TendermintHandle,
|
SignedMessage, TendermintMachine, TendermintHandle,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CONSENSUS_ID,
|
CONSENSUS_ID,
|
||||||
types::TendermintAuthor,
|
types::TendermintValidator,
|
||||||
validators::TendermintValidators,
|
validators::TendermintValidators,
|
||||||
import_queue::{ImportFuture, TendermintImportQueue},
|
import_queue::{ImportFuture, TendermintImportQueue},
|
||||||
Announce,
|
Announce,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct TendermintImport<T: TendermintAuthor> {
|
pub(crate) struct TendermintImport<T: TendermintValidator> {
|
||||||
_ta: PhantomData<T>,
|
_ta: PhantomData<T>,
|
||||||
|
|
||||||
validators: Arc<TendermintValidators<T>>,
|
validators: Arc<TendermintValidators<T>>,
|
||||||
@@ -55,7 +55,46 @@ pub(crate) struct TendermintImport<T: TendermintAuthor> {
|
|||||||
Arc<AsyncRwLock<Option<TendermintImportQueue<T::Block, T::BackendTransaction>>>>,
|
Arc<AsyncRwLock<Option<TendermintImportQueue<T::Block, T::BackendTransaction>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TendermintAuthor> Clone for TendermintImport<T> {
|
pub struct TendermintAuthority<T: TendermintValidator>(pub(crate) TendermintImport<T>);
|
||||||
|
impl<T: TendermintValidator> TendermintAuthority<T> {
|
||||||
|
pub async fn validate(mut self) {
|
||||||
|
let info = self.0.client.info();
|
||||||
|
|
||||||
|
// Header::Number: TryInto<u64> doesn't implement Debug and can't be unwrapped
|
||||||
|
let start_number = match TryInto::<u64>::try_into(info.best_number) {
|
||||||
|
Ok(best) => BlockNumber(best + 1),
|
||||||
|
Err(_) => panic!("BlockNumber exceeded u64"),
|
||||||
|
};
|
||||||
|
let start_time = Commit::<TendermintValidators<T>>::decode(
|
||||||
|
&mut self
|
||||||
|
.0
|
||||||
|
.client
|
||||||
|
.justifications(&BlockId::Hash(info.best_hash))
|
||||||
|
.unwrap()
|
||||||
|
.map(|justifications| justifications.get(CONSENSUS_ID).cloned().unwrap())
|
||||||
|
.unwrap_or_default()
|
||||||
|
.as_ref(),
|
||||||
|
)
|
||||||
|
.map(|commit| commit.end_time)
|
||||||
|
// TODO: Genesis start time
|
||||||
|
.unwrap_or_else(|_| SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs());
|
||||||
|
|
||||||
|
let proposal = self
|
||||||
|
.0
|
||||||
|
.get_proposal(&self.0.client.header(BlockId::Hash(info.best_hash)).unwrap().unwrap())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
*self.0.machine.write().unwrap() = Some(TendermintMachine::new(
|
||||||
|
self.0.clone(),
|
||||||
|
// TODO
|
||||||
|
0, // ValidatorId
|
||||||
|
(start_number, start_time),
|
||||||
|
proposal,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: TendermintValidator> Clone for TendermintImport<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
TendermintImport {
|
TendermintImport {
|
||||||
_ta: PhantomData,
|
_ta: PhantomData,
|
||||||
@@ -75,7 +114,7 @@ impl<T: TendermintAuthor> Clone for TendermintImport<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TendermintAuthor> TendermintImport<T> {
|
impl<T: TendermintValidator> TendermintImport<T> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
client: Arc<T::Client>,
|
client: Arc<T::Client>,
|
||||||
announce: T::Announce,
|
announce: T::Announce,
|
||||||
@@ -254,7 +293,7 @@ impl<T: TendermintAuthor> TendermintImport<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: TendermintAuthor> Network for TendermintImport<T> {
|
impl<T: TendermintValidator> Network for TendermintImport<T> {
|
||||||
type ValidatorId = u16;
|
type ValidatorId = u16;
|
||||||
type SignatureScheme = TendermintValidators<T>;
|
type SignatureScheme = TendermintValidators<T>;
|
||||||
type Weights = TendermintValidators<T>;
|
type Weights = TendermintValidators<T>;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Trait consolidating additional generics required by sc_tendermint for authoring.
|
/// Trait consolidating additional generics required by sc_tendermint for authoring.
|
||||||
pub trait TendermintAuthor: TendermintClient {
|
pub trait TendermintValidator: TendermintClient {
|
||||||
type CIDP: CreateInherentDataProviders<Self::Block, ()> + 'static;
|
type CIDP: CreateInherentDataProviders<Self::Block, ()> + 'static;
|
||||||
type Environment: Send + Sync + Environment<Self::Block> + 'static;
|
type Environment: Send + Sync + Environment<Self::Block> + 'static;
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ use async_trait::async_trait;
|
|||||||
use sp_consensus::{Error, CacheKeyId};
|
use sp_consensus::{Error, CacheKeyId};
|
||||||
use sc_consensus::{BlockImportParams, BlockImport, Verifier};
|
use sc_consensus::{BlockImportParams, BlockImport, Verifier};
|
||||||
|
|
||||||
use crate::{types::TendermintAuthor, tendermint::TendermintImport};
|
use crate::{types::TendermintValidator, tendermint::TendermintImport};
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: TendermintAuthor> Verifier<T::Block> for TendermintImport<T>
|
impl<T: TendermintValidator> Verifier<T::Block> for TendermintImport<T>
|
||||||
where
|
where
|
||||||
Arc<T::Client>: BlockImport<T::Block, Transaction = T::BackendTransaction>,
|
Arc<T::Client>: BlockImport<T::Block, Transaction = T::BackendTransaction>,
|
||||||
<Arc<T::Client> as BlockImport<T::Block>>::Error: Into<Error>,
|
<Arc<T::Client> as BlockImport<T::Block>>::Error: Into<Error>,
|
||||||
|
|||||||
Reference in New Issue
Block a user