Unverified Commit 3b623579 authored by Cecile Tonglet's avatar Cecile Tonglet Committed by GitHub
Browse files

Allow using any polkadot client instead of enum Client (#1575)

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* Apply suggestions from code review

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* WIP

Forked at: e9164236
Parent branch: origin/rococo-branch

* CLEANUP

Forked at: e9164236
Parent branch: origin/rococo-branch

* link in doc

* doc
parent f73f2a86
Pipeline #103773 passed with stages
in 30 minutes and 40 seconds
......@@ -8713,8 +8713,11 @@ dependencies = [
"polkadot-collator",
"polkadot-parachain",
"polkadot-primitives",
"polkadot-service",
"sc-client-api",
"sp-api",
"sp-core",
"sp-runtime",
"test-parachain-adder",
]
......
......@@ -67,7 +67,7 @@ pub use sc_network::PeerId;
pub use service::{RuntimeApiCollection, Client};
pub use sc_cli::SubstrateCli;
#[cfg(not(feature = "service-rewr"))]
use polkadot_service::{FullNodeHandles, AbstractClient};
use polkadot_service::{FullNodeHandles, AbstractClient, ClientHandle};
#[cfg(feature = "service-rewr")]
use polkadot_service_new::{
self as polkadot_service,
......@@ -77,6 +77,7 @@ use sc_service::SpawnTaskHandle;
use sp_core::traits::SpawnNamed;
use sp_runtime::traits::BlakeTwo256;
use consensus_common::SyncOracle;
use sc_client_api::Backend as BackendT;
const COLLATION_TIMEOUT: Duration = Duration::from_secs(30);
......@@ -117,14 +118,19 @@ pub trait BuildParachainContext {
type ParachainContext: self::ParachainContext;
/// Build the `ParachainContext`.
fn build<SP>(
fn build<SP, Client, Backend>(
self,
client: polkadot_service::Client,
client: Arc<Client>,
spawner: SP,
network: impl Network + SyncOracle + Clone + 'static,
) -> Result<Self::ParachainContext, ()>
where
SP: SpawnNamed + Clone + Send + Sync + 'static;
SP: SpawnNamed + Clone + Send + Sync + 'static,
Backend: BackendT<Block>,
Backend::State: sp_api::StateBackend<BlakeTwo256>,
Client: polkadot_service::AbstractClient<Block, Backend> + 'static,
Client::Api: RuntimeApiCollection<StateBackend = Backend::State>,
;
}
/// Parachain context needed for collation.
......@@ -194,11 +200,12 @@ pub async fn collate<P>(
Some(collation)
}
/// Build a collator service based on the `ClientHandle`.
#[cfg(feature = "service-rewr")]
fn build_collator_service<P>(
pub fn build_collator_service<P>(
spawner: SpawnTaskHandle,
handles: FullNodeHandles,
client: polkadot_service::Client,
client: impl ClientHandle,
para_id: ParaId,
key: Arc<CollatorPair>,
build_parachain_context: P,
......@@ -217,7 +224,6 @@ struct BuildCollationWork<P> {
key: Arc<CollatorPair>,
build_parachain_context: P,
spawner: SpawnTaskHandle,
client: polkadot_service::Client,
}
impl<P> polkadot_service::ExecuteWithClient for BuildCollationWork<P>
......@@ -233,7 +239,7 @@ impl<P> polkadot_service::ExecuteWithClient for BuildCollationWork<P>
Backend: sc_client_api::Backend<Block>,
Backend::State: sp_api::StateBackend<BlakeTwo256>,
Api: RuntimeApiCollection<StateBackend = Backend::State>,
Client: AbstractClient<Block, Backend, Api = Api> + 'static
Client: AbstractClient<Block, Backend, Api = Api> + 'static,
{
let polkadot_network = self.handles
.polkadot_network
......@@ -246,7 +252,7 @@ impl<P> polkadot_service::ExecuteWithClient for BuildCollationWork<P>
.ok_or_else(|| "Collator cannot run when validation networking has not been started")?;
let parachain_context = match self.build_parachain_context.build(
self.client,
client.clone(),
self.spawner.clone(),
polkadot_network.clone(),
) {
......@@ -346,11 +352,12 @@ impl<P> polkadot_service::ExecuteWithClient for BuildCollationWork<P>
}
}
/// Build a collator service based on the `ClientHandle`.
#[cfg(not(feature = "service-rewr"))]
fn build_collator_service<P>(
pub fn build_collator_service<P>(
spawner: SpawnTaskHandle,
handles: FullNodeHandles,
client: polkadot_service::Client,
client: impl ClientHandle,
para_id: ParaId,
key: Arc<CollatorPair>,
build_parachain_context: P,
......@@ -366,7 +373,6 @@ fn build_collator_service<P>(
key,
build_parachain_context,
spawner,
client: client.clone(),
})
}
......@@ -454,12 +460,19 @@ mod tests {
impl BuildParachainContext for BuildDummyParachainContext {
type ParachainContext = DummyParachainContext;
fn build<SP>(
fn build<SP, Client, Backend>(
self,
_: polkadot_service::Client,
_: Arc<Client>,
_: SP,
_: impl Network + Clone + 'static,
) -> Result<Self::ParachainContext, ()> {
) -> Result<Self::ParachainContext, ()>
where
SP: SpawnNamed + Clone + Send + Sync + 'static,
Backend: BackendT<Block>,
Backend::State: sp_api::StateBackend<BlakeTwo256>,
Client: polkadot_service::AbstractClient<Block, Backend> + 'static,
Client::Api: RuntimeApiCollection<StateBackend = Backend::State>,
{
Ok(DummyParachainContext)
}
}
......
......@@ -26,7 +26,7 @@ use polkadot_primitives::v0::{
Block, Hash, CollatorId, Id as ParaId,
};
use polkadot_runtime_common::{parachains, registrar, BlockHashCount};
use polkadot_service::{new_full, FullNodeHandles, AbstractClient};
use polkadot_service::{new_full, FullNodeHandles, AbstractClient, ClientHandle, ExecuteWithClient};
use polkadot_test_runtime::{RestrictFunctionality, Runtime, SignedExtra, SignedPayload, VERSION};
use sc_chain_spec::ChainSpec;
use sc_client_api::{execution_extensions::ExecutionStrategies, BlockchainEvents};
......@@ -67,7 +67,7 @@ pub fn polkadot_test_new_full(
) -> Result<
(
TaskManager,
Arc<impl AbstractClient<Block, TFullBackend<Block>>>,
Arc<polkadot_service::FullClient<polkadot_test_runtime::RuntimeApi, PolkadotTestExecutor>>,
FullNodeHandles,
Arc<NetworkService<Block, Hash>>,
Arc<RpcHandlers>,
......@@ -88,6 +88,15 @@ pub fn polkadot_test_new_full(
Ok((task_manager, client, handles, network, rpc_handlers))
}
/// A wrapper for the test client that implements `ClientHandle`.
pub struct TestClient(pub Arc<polkadot_service::FullClient<polkadot_test_runtime::RuntimeApi, PolkadotTestExecutor>>);
impl ClientHandle for TestClient {
fn execute_with<T: ExecuteWithClient>(&self, t: T) -> T::Output {
T::execute_with_client::<_, _, polkadot_service::FullBackend>(t, self.0.clone())
}
}
/// Create a Polkadot `Configuration`. By default an in-memory socket will be used, therefore you need to provide boot
/// nodes if you want the future node to be connected to other nodes. The `storage_update_func` can be used to make
/// adjustements to the runtime before the node starts.
......
......@@ -9,8 +9,11 @@ adder = { package = "test-parachain-adder", path = ".." }
parachain = { package = "polkadot-parachain", path = "../../.." }
collator = { package = "polkadot-collator", path = "../../../../collator" }
primitives = { package = "polkadot-primitives", path = "../../../../primitives" }
service = { package = "polkadot-service", path = "../../../../service" }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
client-api = { package = "sc-client-api", git = "https://github.com/paritytech/substrate", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
parking_lot = "0.10.0"
codec = { package = "parity-scale-codec", version = "1.3.4" }
futures = "0.3.4"
......@@ -20,15 +20,17 @@ use std::collections::HashMap;
use std::sync::Arc;
use adder::{HeadData as AdderHead, BlockData as AdderBody};
use sp_core::Pair;
use sp_core::{traits::SpawnNamed, Pair};
use codec::{Encode, Decode};
use primitives::v0::{
Hash, DownwardMessage,
Block, Hash, DownwardMessage,
HeadData, BlockData, Id as ParaId, LocalValidationData, GlobalValidationData,
};
use collator::{ParachainContext, Network, BuildParachainContext, Cli, SubstrateCli};
use parking_lot::Mutex;
use futures::future::{Ready, ready, FutureExt};
use sp_runtime::traits::BlakeTwo256;
use client_api::Backend as BackendT;
const GENESIS: AdderHead = AdderHead {
number: 0,
......@@ -103,12 +105,19 @@ impl ParachainContext for AdderContext {
impl BuildParachainContext for AdderContext {
type ParachainContext = Self;
fn build<SP>(
fn build<SP, Client, Backend>(
self,
_: collator::Client,
_: Arc<Client>,
_: SP,
network: impl Network + Clone + 'static,
) -> Result<Self::ParachainContext, ()> {
) -> Result<Self::ParachainContext, ()>
where
SP: SpawnNamed + Clone + Send + Sync + 'static,
Backend: BackendT<Block>,
Backend::State: sp_api::StateBackend<BlakeTwo256>,
Client: service::AbstractClient<Block, Backend> + 'static,
Client::Api: service::RuntimeApiCollection<StateBackend = Backend::State>,
{
Ok(Self { _network: Some(Arc::new(network)), ..self })
}
}
......
......@@ -118,6 +118,19 @@ pub trait ExecuteWithClient {
Client: AbstractClient<Block, Backend, Api = Api> + 'static;
}
/// A handle to a Polkadot client instance.
///
/// The Polkadot service supports multiple different runtimes (Westend, Polkadot itself, etc). As each runtime has a
/// specialized client, we need to hide them behind a trait. This is this trait.
///
/// When wanting to work with the inner client, you need to use `execute_with`.
///
/// See [`ExecuteWithClient`](trait.ExecuteWithClient.html) for more information.
pub trait ClientHandle {
/// Execute the given something with the client.
fn execute_with<T: ExecuteWithClient>(&self, t: T) -> T::Output;
}
/// A client instance of Polkadot.
///
/// See [`ExecuteWithClient`] for more information.
......@@ -129,9 +142,8 @@ pub enum Client {
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 {
impl ClientHandle for Client {
fn execute_with<T: ExecuteWithClient>(&self, t: T) -> T::Output {
match self {
Self::Polkadot(client) => {
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
......
......@@ -109,16 +109,25 @@ impl IdentifyVariant for Box<dyn ChainSpec> {
}
}
type FullBackend = service::TFullBackend<Block>;
type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
type FullClient<RuntimeApi, Executor> = service::TFullClient<Block, RuntimeApi, Executor>;
type FullGrandpaBlockImport<RuntimeApi, Executor> = grandpa::GrandpaBlockImport<
/// Polkadot's full backend.
pub type FullBackend = service::TFullBackend<Block>;
/// Polkadot's select chain.
pub type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
/// Polkadot's full client.
pub type FullClient<RuntimeApi, Executor> = service::TFullClient<Block, RuntimeApi, Executor>;
/// Polkadot's full Grandpa block import.
pub type FullGrandpaBlockImport<RuntimeApi, Executor> = grandpa::GrandpaBlockImport<
FullBackend, Block, FullClient<RuntimeApi, Executor>, FullSelectChain
>;
type LightBackend = service::TLightBackendWithHash<Block, sp_runtime::traits::BlakeTwo256>;
/// Polkadot's light backend.
pub type LightBackend = service::TLightBackendWithHash<Block, sp_runtime::traits::BlakeTwo256>;
type LightClient<RuntimeApi, Executor> =
/// Polkadot's light client.
pub type LightClient<RuntimeApi, Executor> =
service::TLightClientWithBackend<Block, RuntimeApi, Executor, LightBackend>;
#[cfg(feature = "full-node")]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment