mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 08:11:03 +00:00
Allow for customisation of chain selection systems (#2240)
* move SelectChain trait out of client * Extend SelectChain, move longest chain implementation into it * Bring SelectChain into service * implement LongestChain SelectChain * implement longest chain for node * update Cargo.lock's * in between erroring tests * deprecate ::backend and ::import_lock * Remove unneded space Co-Authored-By: gnunicorn <ben.kampmann@googlemail.com> * Remove unneded space Co-Authored-By: gnunicorn <ben.kampmann@googlemail.com> * Fixes test compilation * remove todo * re-enable client test * add doc * fixing tests * Clarify SelectChain Interface, intended implementation and usage * minor components cleanups * minor cleanups * Update lock files * Implement cleaner interface for SelectChain * addressing comments * Updating tests * bump node runtime impl version * address grumbles
This commit is contained in:
committed by
Gavin Wood
parent
32fdeed21c
commit
18ca0170c3
@@ -16,14 +16,14 @@
|
||||
|
||||
//! Substrate service components.
|
||||
|
||||
use std::{sync::Arc, net::SocketAddr, marker::PhantomData, ops::Deref, ops::DerefMut};
|
||||
use std::{sync::Arc, net::SocketAddr, ops::Deref, ops::DerefMut};
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
use tokio::runtime::TaskExecutor;
|
||||
use crate::chain_spec::ChainSpec;
|
||||
use client_db;
|
||||
use client::{self, Client, runtime_api};
|
||||
use crate::{error, Service, maybe_start_server};
|
||||
use consensus_common::import_queue::ImportQueue;
|
||||
use consensus_common::{import_queue::ImportQueue, SelectChain};
|
||||
use network::{self, OnDemand};
|
||||
use substrate_executor::{NativeExecutor, NativeExecutionDispatch};
|
||||
use transaction_pool::txpool::{self, Options as TransactionPoolOptions, Pool as TransactionPool};
|
||||
@@ -304,9 +304,11 @@ pub trait ServiceFactory: 'static + Sized {
|
||||
/// Extended light service type.
|
||||
type LightService: ServiceTrait<LightComponents<Self>>;
|
||||
/// ImportQueue for full client
|
||||
type FullImportQueue: consensus_common::import_queue::ImportQueue<Self::Block> + 'static;
|
||||
type FullImportQueue: ImportQueue<Self::Block> + 'static;
|
||||
/// ImportQueue for light clients
|
||||
type LightImportQueue: consensus_common::import_queue::ImportQueue<Self::Block> + 'static;
|
||||
type LightImportQueue: ImportQueue<Self::Block> + 'static;
|
||||
/// The Fork Choice Strategy for the chain
|
||||
type SelectChain: SelectChain<Self::Block> + 'static;
|
||||
|
||||
//TODO: replace these with a constructor trait. that TransactionPool implements. (#1242)
|
||||
/// Extrinsic pool constructor for the full client.
|
||||
@@ -320,6 +322,12 @@ pub trait ServiceFactory: 'static + Sized {
|
||||
fn build_network_protocol(config: &FactoryFullConfiguration<Self>)
|
||||
-> Result<Self::NetworkProtocol, error::Error>;
|
||||
|
||||
/// Build the Fork Choice algorithm for full client
|
||||
fn build_select_chain(
|
||||
config: &mut FactoryFullConfiguration<Self>,
|
||||
client: Arc<FullClient<Self>>,
|
||||
) -> Result<Self::SelectChain, error::Error>;
|
||||
|
||||
/// Build full service.
|
||||
fn new_full(config: FactoryFullConfiguration<Self>, executor: TaskExecutor)
|
||||
-> Result<Self::FullService, error::Error>;
|
||||
@@ -330,7 +338,8 @@ pub trait ServiceFactory: 'static + Sized {
|
||||
/// ImportQueue for a full client
|
||||
fn build_full_import_queue(
|
||||
config: &mut FactoryFullConfiguration<Self>,
|
||||
_client: Arc<FullClient<Self>>
|
||||
_client: Arc<FullClient<Self>>,
|
||||
_select_chain: Self::SelectChain
|
||||
) -> Result<Self::FullImportQueue, error::Error> {
|
||||
if let Some(name) = config.chain_spec.consensus_engine() {
|
||||
match name {
|
||||
@@ -378,6 +387,8 @@ pub trait Components: Sized + 'static {
|
||||
>;
|
||||
/// Our Import Queue
|
||||
type ImportQueue: ImportQueue<FactoryBlock<Self::Factory>> + 'static;
|
||||
/// The Fork Choice Strategy for the chain
|
||||
type SelectChain: SelectChain<FactoryBlock<Self::Factory>>;
|
||||
|
||||
/// Create client.
|
||||
fn build_client(
|
||||
@@ -398,13 +409,20 @@ pub trait Components: Sized + 'static {
|
||||
/// instance of import queue for clients
|
||||
fn build_import_queue(
|
||||
config: &mut FactoryFullConfiguration<Self::Factory>,
|
||||
client: Arc<ComponentClient<Self>>
|
||||
client: Arc<ComponentClient<Self>>,
|
||||
select_chain: Self::SelectChain,
|
||||
) -> Result<Self::ImportQueue, error::Error>;
|
||||
|
||||
/// Build fork choice selector
|
||||
fn build_select_chain(
|
||||
config: &mut FactoryFullConfiguration<Self::Factory>,
|
||||
client: Arc<ComponentClient<Self>>
|
||||
) -> Result<Self::SelectChain, error::Error>;
|
||||
|
||||
}
|
||||
|
||||
/// A struct that implement `Components` for the full client.
|
||||
pub struct FullComponents<Factory: ServiceFactory> {
|
||||
_factory: PhantomData<Factory>,
|
||||
service: Service<FullComponents<Factory>>,
|
||||
}
|
||||
|
||||
@@ -416,7 +434,6 @@ impl<Factory: ServiceFactory> FullComponents<Factory> {
|
||||
) -> Result<Self, error::Error> {
|
||||
Ok(
|
||||
Self {
|
||||
_factory: Default::default(),
|
||||
service: Service::new(config, task_executor)?,
|
||||
}
|
||||
)
|
||||
@@ -445,6 +462,7 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
|
||||
type ImportQueue = Factory::FullImportQueue;
|
||||
type RuntimeApi = Factory::RuntimeApi;
|
||||
type RuntimeServices = Factory::FullService;
|
||||
type SelectChain = Factory::SelectChain;
|
||||
|
||||
fn build_client(
|
||||
config: &FactoryFullConfiguration<Factory>,
|
||||
@@ -469,23 +487,32 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
|
||||
)?), None))
|
||||
}
|
||||
|
||||
fn build_transaction_pool(config: TransactionPoolOptions, client: Arc<ComponentClient<Self>>)
|
||||
-> Result<TransactionPool<Self::TransactionPoolApi>, error::Error>
|
||||
{
|
||||
fn build_transaction_pool(
|
||||
config: TransactionPoolOptions,
|
||||
client: Arc<ComponentClient<Self>>
|
||||
) -> Result<TransactionPool<Self::TransactionPoolApi>, error::Error> {
|
||||
Factory::build_full_transaction_pool(config, client)
|
||||
}
|
||||
|
||||
fn build_import_queue(
|
||||
config: &mut FactoryFullConfiguration<Self::Factory>,
|
||||
client: Arc<ComponentClient<Self>>
|
||||
client: Arc<ComponentClient<Self>>,
|
||||
select_chain: Self::SelectChain,
|
||||
) -> Result<Self::ImportQueue, error::Error> {
|
||||
Factory::build_full_import_queue(config, client)
|
||||
Factory::build_full_import_queue(config, client, select_chain)
|
||||
}
|
||||
|
||||
fn build_select_chain(
|
||||
config: &mut FactoryFullConfiguration<Self::Factory>,
|
||||
client: Arc<ComponentClient<Self>>
|
||||
) -> Result<Self::SelectChain, error::Error> {
|
||||
Self::Factory::build_select_chain(config, client)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// A struct that implement `Components` for the light client.
|
||||
pub struct LightComponents<Factory: ServiceFactory> {
|
||||
_factory: PhantomData<Factory>,
|
||||
service: Service<LightComponents<Factory>>,
|
||||
}
|
||||
|
||||
@@ -497,7 +524,6 @@ impl<Factory: ServiceFactory> LightComponents<Factory> {
|
||||
) -> Result<Self, error::Error> {
|
||||
Ok(
|
||||
Self {
|
||||
_factory: Default::default(),
|
||||
service: Service::new(config, task_executor)?,
|
||||
}
|
||||
)
|
||||
@@ -520,6 +546,7 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
|
||||
type ImportQueue = <Factory as ServiceFactory>::LightImportQueue;
|
||||
type RuntimeApi = Factory::RuntimeApi;
|
||||
type RuntimeServices = Factory::LightService;
|
||||
type SelectChain = Factory::SelectChain;
|
||||
|
||||
fn build_client(
|
||||
config: &FactoryFullConfiguration<Factory>,
|
||||
@@ -554,16 +581,27 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
|
||||
|
||||
fn build_import_queue(
|
||||
config: &mut FactoryFullConfiguration<Self::Factory>,
|
||||
client: Arc<ComponentClient<Self>>
|
||||
client: Arc<ComponentClient<Self>>,
|
||||
_select_chain: Self::SelectChain,
|
||||
) -> Result<Self::ImportQueue, error::Error> {
|
||||
Factory::build_light_import_queue(config, client)
|
||||
}
|
||||
|
||||
/// Build fork choice selector
|
||||
fn build_select_chain(
|
||||
_config: &mut FactoryFullConfiguration<Self::Factory>,
|
||||
_client: Arc<ComponentClient<Self>>
|
||||
) -> Result<Self::SelectChain, error::Error> {
|
||||
Err("Fork choice doesn't happen on light clients.".into())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use consensus_common::BlockOrigin;
|
||||
use client::LongestChain;
|
||||
use substrate_test_client::{self, TestClient, AccountKeyring, runtime::Transfer};
|
||||
|
||||
#[test]
|
||||
@@ -576,8 +614,11 @@ mod tests {
|
||||
from: AccountKeyring::Alice.into(),
|
||||
to: Default::default(),
|
||||
}.into_signed_tx();
|
||||
let best = LongestChain::new(client.backend().clone(), client.import_lock())
|
||||
.best_chain().unwrap();
|
||||
|
||||
// store the transaction in the pool
|
||||
pool.submit_one(&BlockId::hash(client.best_block_header().unwrap().hash()), transaction.clone()).unwrap();
|
||||
pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap();
|
||||
|
||||
// import the block
|
||||
let mut builder = client.new_block().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user