mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 07:31:02 +00:00
Rewrite client handling (#1531)
* Rewrite client handling We are supporting muliple polkadot-like chains and all have different client types. This pr reworks the client handling by having all of them in one enum combined. Besides that, there is added a special trait `ExecuteWithClient` to use the internal client. * Apply suggestions from code review Co-authored-by: Robert Habermeier <rphmeier@gmail.com> * Up the versions * Fix Cargo.lock * Fix merge conflict * ...................... * ....v2 * yep * I'm dumb... * Browser lol Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
+111
-14
@@ -14,40 +14,137 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Polkadot Client meta trait
|
||||
//! Polkadot Client abstractions.
|
||||
|
||||
use sp_api::{ProvideRuntimeApi, ConstructRuntimeApi, CallApiAt};
|
||||
use std::sync::Arc;
|
||||
use sp_api::{ProvideRuntimeApi, CallApiAt};
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use sp_runtime::traits::{Block as BlockT, BlakeTwo256};
|
||||
use sc_client_api::{Backend as BackendT, BlockchainEvents};
|
||||
use polkadot_primitives::v0::{Block, ParachainHost, AccountId, Nonce, Balance};
|
||||
|
||||
/// Polkadot client abstraction, this super trait only pulls in functionality required for
|
||||
/// polkadot internal crates like polkadot-collator.
|
||||
pub trait PolkadotClient<Block, Backend, Runtime>:
|
||||
/// A set of APIs that polkadot-like runtimes must implement.
|
||||
pub trait RuntimeApiCollection:
|
||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
|
||||
+ babe_primitives::BabeApi<Block>
|
||||
+ grandpa_primitives::GrandpaApi<Block>
|
||||
+ ParachainHost<Block>
|
||||
+ sp_block_builder::BlockBuilder<Block>
|
||||
+ system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
|
||||
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
|
||||
+ sp_api::Metadata<Block>
|
||||
+ sp_offchain::OffchainWorkerApi<Block>
|
||||
+ sp_session::SessionKeys<Block>
|
||||
+ authority_discovery_primitives::AuthorityDiscoveryApi<Block>
|
||||
where
|
||||
<Self as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
||||
{}
|
||||
|
||||
impl<Api> RuntimeApiCollection for Api
|
||||
where
|
||||
Api:
|
||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
|
||||
+ babe_primitives::BabeApi<Block>
|
||||
+ grandpa_primitives::GrandpaApi<Block>
|
||||
+ ParachainHost<Block>
|
||||
+ sp_block_builder::BlockBuilder<Block>
|
||||
+ system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
|
||||
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
|
||||
+ sp_api::Metadata<Block>
|
||||
+ sp_offchain::OffchainWorkerApi<Block>
|
||||
+ sp_session::SessionKeys<Block>
|
||||
+ authority_discovery_primitives::AuthorityDiscoveryApi<Block>,
|
||||
<Self as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
||||
{}
|
||||
|
||||
/// Trait that abstracts over all available client implementations.
|
||||
///
|
||||
/// For a concrete type there exists [`Client`].
|
||||
pub trait AbstractClient<Block, Backend>:
|
||||
BlockchainEvents<Block> + Sized + Send + Sync
|
||||
+ ProvideRuntimeApi<Block, Api = Runtime::RuntimeApi>
|
||||
+ ProvideRuntimeApi<Block>
|
||||
+ HeaderBackend<Block>
|
||||
+ CallApiAt<
|
||||
Block,
|
||||
Error = sp_blockchain::Error,
|
||||
StateBackend = Backend ::State
|
||||
StateBackend = Backend::State
|
||||
>
|
||||
where
|
||||
Block: BlockT,
|
||||
Backend: BackendT<Block>,
|
||||
Runtime: ConstructRuntimeApi<Block, Self>
|
||||
Backend::State: sp_api::StateBackend<BlakeTwo256>,
|
||||
Self::Api: RuntimeApiCollection<StateBackend = Backend::State>,
|
||||
{}
|
||||
|
||||
impl<Block, Backend, Runtime, Client> PolkadotClient<Block, Backend, Runtime> for Client
|
||||
impl<Block, Backend, Client> AbstractClient<Block, Backend> for Client
|
||||
where
|
||||
Block: BlockT,
|
||||
Runtime: ConstructRuntimeApi<Block, Self>,
|
||||
Backend: BackendT<Block>,
|
||||
Client: BlockchainEvents<Block> + ProvideRuntimeApi<Block, Api = Runtime::RuntimeApi> + HeaderBackend<Block>
|
||||
Backend::State: sp_api::StateBackend<BlakeTwo256>,
|
||||
Client: BlockchainEvents<Block> + ProvideRuntimeApi<Block> + HeaderBackend<Block>
|
||||
+ Sized + Send + Sync
|
||||
+ CallApiAt<
|
||||
Block,
|
||||
Error = sp_blockchain::Error,
|
||||
StateBackend = Backend ::State
|
||||
>
|
||||
StateBackend = Backend::State
|
||||
>,
|
||||
Client::Api: RuntimeApiCollection<StateBackend = Backend::State>,
|
||||
{}
|
||||
|
||||
/// Execute something with the client instance.
|
||||
///
|
||||
/// As there exist multiple chains inside Polkadot, like Polkadot itself, Kusama, Westend etc,
|
||||
/// there can exist different kinds of client types. As these client types differ in the generics
|
||||
/// that are being used, we can not easily return them from a function. For returning them from a
|
||||
/// function there exists [`Client`]. However, the problem on how to use this client instance still
|
||||
/// exists. This trait "solves" it in a dirty way. It requires a type to implement this trait and
|
||||
/// than the [`execute_with_client`](ExecuteWithClient::execute_with_client) function can be called
|
||||
/// with any possible client instance.
|
||||
///
|
||||
/// In a perfect world, we could make a closure work in this way.
|
||||
pub trait ExecuteWithClient {
|
||||
/// The return type when calling this instance.
|
||||
type Output;
|
||||
|
||||
/// Execute whatever should be executed with the given client instance.
|
||||
fn execute_with_client<Client, Api, Backend>(self, client: Arc<Client>) -> Self::Output
|
||||
where
|
||||
<Api as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
||||
Backend: sc_client_api::Backend<Block>,
|
||||
Backend::State: sp_api::StateBackend<BlakeTwo256>,
|
||||
Api: crate::RuntimeApiCollection<StateBackend = Backend::State>,
|
||||
Client: AbstractClient<Block, Backend, Api = Api> + 'static;
|
||||
}
|
||||
|
||||
/// A client instance of Polkadot.
|
||||
///
|
||||
/// See [`ExecuteWithClient`] for more information.
|
||||
#[derive(Clone)]
|
||||
pub enum Client {
|
||||
Polkadot(Arc<crate::FullClient<polkadot_runtime::RuntimeApi, crate::PolkadotExecutor>>),
|
||||
Westend(Arc<crate::FullClient<westend_runtime::RuntimeApi, crate::WestendExecutor>>),
|
||||
Kusama(Arc<crate::FullClient<kusama_runtime::RuntimeApi, crate::KusamaExecutor>>),
|
||||
Rococo(Arc<crate::FullClient<rococo_runtime::RuntimeApi, crate::RococoExecutor>>),
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Execute the given something with the client.
|
||||
pub fn execute_with<T: ExecuteWithClient>(&self, t: T) -> T::Output {
|
||||
match self {
|
||||
Self::Polkadot(client) => {
|
||||
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
|
||||
},
|
||||
Self::Westend(client) => {
|
||||
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
|
||||
},
|
||||
Self::Kusama(client) => {
|
||||
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
|
||||
},
|
||||
Self::Rococo(client) => {
|
||||
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+67
-142
@@ -22,7 +22,7 @@ mod client;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use polkadot_primitives::v0::{self as parachain, Hash, BlockId, AccountId, Nonce, Balance};
|
||||
use polkadot_primitives::v0::{self as parachain, Hash, BlockId};
|
||||
#[cfg(feature = "full-node")]
|
||||
use polkadot_network::{legacy::gossip::Known, protocol as network_protocol};
|
||||
use service::{error::Error as ServiceError};
|
||||
@@ -52,7 +52,7 @@ pub use polkadot_runtime;
|
||||
pub use kusama_runtime;
|
||||
pub use westend_runtime;
|
||||
use prometheus_endpoint::Registry;
|
||||
pub use self::client::PolkadotClient;
|
||||
pub use self::client::*;
|
||||
|
||||
native_executor_instance!(
|
||||
pub PolkadotExecutor,
|
||||
@@ -82,42 +82,6 @@ native_executor_instance!(
|
||||
frame_benchmarking::benchmarking::HostFunctions,
|
||||
);
|
||||
|
||||
/// A set of APIs that polkadot-like runtimes must implement.
|
||||
pub trait RuntimeApiCollection:
|
||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
|
||||
+ babe_primitives::BabeApi<Block>
|
||||
+ grandpa_primitives::GrandpaApi<Block>
|
||||
+ ParachainHost<Block>
|
||||
+ sp_block_builder::BlockBuilder<Block>
|
||||
+ system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
|
||||
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
|
||||
+ sp_api::Metadata<Block>
|
||||
+ sp_offchain::OffchainWorkerApi<Block>
|
||||
+ sp_session::SessionKeys<Block>
|
||||
+ authority_discovery_primitives::AuthorityDiscoveryApi<Block>
|
||||
where
|
||||
<Self as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
||||
{}
|
||||
|
||||
impl<Api> RuntimeApiCollection for Api
|
||||
where
|
||||
Api:
|
||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
|
||||
+ babe_primitives::BabeApi<Block>
|
||||
+ grandpa_primitives::GrandpaApi<Block>
|
||||
+ ParachainHost<Block>
|
||||
+ sp_block_builder::BlockBuilder<Block>
|
||||
+ system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
|
||||
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
|
||||
+ sp_api::Metadata<Block>
|
||||
+ sp_offchain::OffchainWorkerApi<Block>
|
||||
+ sp_session::SessionKeys<Block>
|
||||
+ authority_discovery_primitives::AuthorityDiscoveryApi<Block>,
|
||||
<Self as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
||||
{}
|
||||
|
||||
/// Can be called for a `Configuration` to check if it is a configuration for the `Kusama` network.
|
||||
pub trait IdentifyVariant {
|
||||
/// Returns if this is a configuration for the `Kusama` network.
|
||||
@@ -732,11 +696,7 @@ pub fn polkadot_new_full(
|
||||
)
|
||||
-> Result<(
|
||||
TaskManager,
|
||||
Arc<impl PolkadotClient<
|
||||
Block,
|
||||
FullBackend,
|
||||
polkadot_runtime::RuntimeApi
|
||||
>>,
|
||||
Arc<impl AbstractClient<Block, FullBackend>>,
|
||||
FullNodeHandles,
|
||||
), ServiceError>
|
||||
{
|
||||
@@ -764,12 +724,7 @@ pub fn kusama_new_full(
|
||||
grandpa_pause: Option<(u32, u32)>,
|
||||
) -> Result<(
|
||||
TaskManager,
|
||||
Arc<impl PolkadotClient<
|
||||
Block,
|
||||
FullBackend,
|
||||
kusama_runtime::RuntimeApi
|
||||
>
|
||||
>,
|
||||
Arc<impl AbstractClient<Block, FullBackend>>,
|
||||
FullNodeHandles
|
||||
), ServiceError>
|
||||
{
|
||||
@@ -798,11 +753,7 @@ pub fn westend_new_full(
|
||||
)
|
||||
-> Result<(
|
||||
TaskManager,
|
||||
Arc<impl PolkadotClient<
|
||||
Block,
|
||||
FullBackend,
|
||||
westend_runtime::RuntimeApi
|
||||
>>,
|
||||
Arc<impl AbstractClient<Block, FullBackend>>,
|
||||
FullNodeHandles,
|
||||
), ServiceError>
|
||||
{
|
||||
@@ -831,11 +782,7 @@ pub fn rococo_new_full(
|
||||
)
|
||||
-> Result<(
|
||||
TaskManager,
|
||||
Arc<impl PolkadotClient<
|
||||
Block,
|
||||
TFullBackend<Block>,
|
||||
rococo_runtime::RuntimeApi
|
||||
>>,
|
||||
Arc<impl AbstractClient<Block, TFullBackend<Block>>>,
|
||||
FullNodeHandles,
|
||||
), ServiceError>
|
||||
{
|
||||
@@ -863,90 +810,68 @@ pub struct FullNodeHandles {
|
||||
pub validation_service_handle: Option<consensus::ServiceHandle>,
|
||||
}
|
||||
|
||||
/// A builder for a node.
|
||||
pub struct NodeBuilder {
|
||||
/// Build a new light node.
|
||||
pub fn build_light(config: Configuration) -> Result<(TaskManager, Arc<RpcHandlers>), ServiceError> {
|
||||
if config.chain_spec.is_kusama() {
|
||||
new_light::<kusama_runtime::RuntimeApi, KusamaExecutor>(config)
|
||||
} else if config.chain_spec.is_westend() {
|
||||
new_light::<westend_runtime::RuntimeApi, WestendExecutor>(config)
|
||||
} else if config.chain_spec.is_rococo() {
|
||||
new_light::<rococo_runtime::RuntimeApi, RococoExecutor>(config)
|
||||
} else {
|
||||
new_light::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(config)
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a new full node.
|
||||
#[cfg(feature = "full-node")]
|
||||
pub fn build_full(
|
||||
config: Configuration,
|
||||
}
|
||||
|
||||
impl NodeBuilder {
|
||||
/// Create a new node builder.
|
||||
pub fn new(config: Configuration) -> Self {
|
||||
Self {
|
||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||
max_block_data_size: Option<u64>,
|
||||
authority_discovery_disabled: bool,
|
||||
slot_duration: u64,
|
||||
grandpa_pause: Option<(u32, u32)>,
|
||||
) -> Result<(TaskManager, Client, FullNodeHandles), ServiceError> {
|
||||
if config.chain_spec.is_kusama() {
|
||||
new_full::<kusama_runtime::RuntimeApi, KusamaExecutor>(
|
||||
config,
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a new light node.
|
||||
pub fn build_light(self) -> Result<(TaskManager, Arc<RpcHandlers>), ServiceError> {
|
||||
if self.config.chain_spec.is_kusama() {
|
||||
new_light::<kusama_runtime::RuntimeApi, KusamaExecutor>(
|
||||
self.config,
|
||||
)
|
||||
} else if self.config.chain_spec.is_westend() {
|
||||
new_light::<westend_runtime::RuntimeApi, WestendExecutor>(
|
||||
self.config,
|
||||
)
|
||||
} else if self.config.chain_spec.is_rococo() {
|
||||
new_light::<rococo_runtime::RuntimeApi, RococoExecutor>(
|
||||
self.config,
|
||||
)
|
||||
} else {
|
||||
new_light::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(
|
||||
self.config,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a new full node.
|
||||
#[cfg(feature = "full-node")]
|
||||
pub fn build_full(
|
||||
self,
|
||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||
max_block_data_size: Option<u64>,
|
||||
authority_discovery_disabled: bool,
|
||||
slot_duration: u64,
|
||||
grandpa_pause: Option<(u32, u32)>,
|
||||
) -> Result<TaskManager, ServiceError> {
|
||||
if self.config.chain_spec.is_kusama() {
|
||||
new_full::<kusama_runtime::RuntimeApi, KusamaExecutor>(
|
||||
self.config,
|
||||
collating_for,
|
||||
max_block_data_size,
|
||||
authority_discovery_disabled,
|
||||
slot_duration,
|
||||
grandpa_pause,
|
||||
false,
|
||||
).map(|(task_manager, _, _, _, _)| task_manager)
|
||||
} else if self.config.chain_spec.is_westend() {
|
||||
new_full::<westend_runtime::RuntimeApi, WestendExecutor>(
|
||||
self.config,
|
||||
collating_for,
|
||||
max_block_data_size,
|
||||
authority_discovery_disabled,
|
||||
slot_duration,
|
||||
grandpa_pause,
|
||||
false,
|
||||
).map(|(task_manager, _, _, _, _)| task_manager)
|
||||
} else if self.config.chain_spec.is_rococo() {
|
||||
new_full::<rococo_runtime::RuntimeApi, RococoExecutor>(
|
||||
self.config,
|
||||
collating_for,
|
||||
max_block_data_size,
|
||||
authority_discovery_disabled,
|
||||
slot_duration,
|
||||
grandpa_pause,
|
||||
false,
|
||||
).map(|(task_manager, _, _, _, _)| task_manager)
|
||||
} else {
|
||||
new_full::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(
|
||||
self.config,
|
||||
collating_for,
|
||||
max_block_data_size,
|
||||
authority_discovery_disabled,
|
||||
slot_duration,
|
||||
grandpa_pause,
|
||||
false,
|
||||
).map(|(task_manager, _, _, _, _)| task_manager)
|
||||
}
|
||||
collating_for,
|
||||
max_block_data_size,
|
||||
authority_discovery_disabled,
|
||||
slot_duration,
|
||||
grandpa_pause,
|
||||
false,
|
||||
).map(|(task_manager, client, handles, _, _)| (task_manager, Client::Kusama(client), handles))
|
||||
} else if config.chain_spec.is_westend() {
|
||||
new_full::<westend_runtime::RuntimeApi, WestendExecutor>(
|
||||
config,
|
||||
collating_for,
|
||||
max_block_data_size,
|
||||
authority_discovery_disabled,
|
||||
slot_duration,
|
||||
grandpa_pause,
|
||||
false,
|
||||
).map(|(task_manager, client, handles, _, _)| (task_manager, Client::Westend(client), handles))
|
||||
} else if config.chain_spec.is_rococo() {
|
||||
new_full::<rococo_runtime::RuntimeApi, RococoExecutor>(
|
||||
config,
|
||||
collating_for,
|
||||
max_block_data_size,
|
||||
authority_discovery_disabled,
|
||||
slot_duration,
|
||||
grandpa_pause,
|
||||
false,
|
||||
).map(|(task_manager, client, handles, _, _)| (task_manager, Client::Rococo(client), handles))
|
||||
} else {
|
||||
new_full::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(
|
||||
config,
|
||||
collating_for,
|
||||
max_block_data_size,
|
||||
authority_discovery_disabled,
|
||||
slot_duration,
|
||||
grandpa_pause,
|
||||
false,
|
||||
).map(|(task_manager, client, handles, _, _)| (task_manager, Client::Polkadot(client), handles))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user