mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +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:
Generated
+2
-2
@@ -5997,7 +5997,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rococo-runtime"
|
||||
version = "0.8.14"
|
||||
version = "0.8.22"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"frame-benchmarking",
|
||||
@@ -6073,7 +6073,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rococo-v1-runtime"
|
||||
version = "0.8.19"
|
||||
version = "0.8.22"
|
||||
dependencies = [
|
||||
"frame-executive",
|
||||
"frame-support",
|
||||
|
||||
@@ -46,8 +46,7 @@ async fn start_inner(chain_spec: String, log_level: String) -> Result<Client, Bo
|
||||
info!("👤 Role: {}", config.display_role());
|
||||
|
||||
// Create the service. This is the most heavy initialization step.
|
||||
let builder = service::NodeBuilder::new(config);
|
||||
let (task_manager, rpc_handlers) = builder.build_light().map_err(|e| format!("{:?}", e))?;
|
||||
let (task_manager, rpc_handlers) = service::build_light(config).map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
Ok(browser_utils::start_client(task_manager, rpc_handlers))
|
||||
}
|
||||
|
||||
@@ -131,17 +131,17 @@ pub fn run() -> Result<()> {
|
||||
|
||||
runner.run_node_until_exit(|config| {
|
||||
let role = config.role.clone();
|
||||
let builder = service::NodeBuilder::new(config);
|
||||
|
||||
match role {
|
||||
Role::Light => builder.build_light().map(|(task_manager, _)| task_manager),
|
||||
_ => builder.build_full(
|
||||
Role::Light => service::build_light(config).map(|(task_manager, _)| task_manager),
|
||||
_ => service::build_full(
|
||||
config,
|
||||
None,
|
||||
None,
|
||||
authority_discovery_disabled,
|
||||
6000,
|
||||
grandpa_pause,
|
||||
),
|
||||
).map(|r| r.0),
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
+168
-207
@@ -51,8 +51,6 @@ use std::time::Duration;
|
||||
use std::pin::Pin;
|
||||
|
||||
use futures::{future, Future, Stream, FutureExt, StreamExt};
|
||||
use sc_client_api::{StateBackend, BlockchainEvents};
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_core::Pair;
|
||||
use polkadot_primitives::v0::{
|
||||
BlockId, Hash, Block, DownwardMessage,
|
||||
@@ -60,27 +58,24 @@ use polkadot_primitives::v0::{
|
||||
PoVBlock, ValidatorId, CollatorPair, LocalValidationData, GlobalValidationData,
|
||||
Collation, CollationInfo, collator_signature_payload,
|
||||
};
|
||||
use polkadot_cli::{
|
||||
ProvideRuntimeApi, ParachainHost, IdentifyVariant,
|
||||
service::{self, Role}
|
||||
};
|
||||
use polkadot_cli::service::{self, Role};
|
||||
pub use polkadot_cli::service::Configuration;
|
||||
pub use polkadot_cli::Cli;
|
||||
pub use polkadot_validation::SignedStatement;
|
||||
pub use polkadot_primitives::v0::CollatorId;
|
||||
pub use sc_network::PeerId;
|
||||
pub use service::RuntimeApiCollection;
|
||||
pub use service::{RuntimeApiCollection, Client};
|
||||
pub use sc_cli::SubstrateCli;
|
||||
use sp_api::{ConstructRuntimeApi, ApiExt, HashFor};
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
use polkadot_service::{FullNodeHandles, PolkadotClient};
|
||||
use polkadot_service::{FullNodeHandles, AbstractClient};
|
||||
#[cfg(feature = "service-rewr")]
|
||||
use polkadot_service_new::{
|
||||
self as polkadot_service,
|
||||
Error as ServiceError, FullNodeHandles, PolkadotClient,
|
||||
Error as ServiceError, FullNodeHandles, AbstractClient,
|
||||
};
|
||||
use sc_service::SpawnTaskHandle;
|
||||
use sp_core::traits::SpawnNamed;
|
||||
use sp_runtime::traits::BlakeTwo256;
|
||||
|
||||
const COLLATION_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
@@ -121,16 +116,13 @@ pub trait BuildParachainContext {
|
||||
type ParachainContext: self::ParachainContext;
|
||||
|
||||
/// Build the `ParachainContext`.
|
||||
fn build<Client, SP>(
|
||||
fn build<SP>(
|
||||
self,
|
||||
client: Arc<Client>,
|
||||
client: polkadot_service::Client,
|
||||
spawner: SP,
|
||||
network: impl Network + Clone + 'static,
|
||||
) -> Result<Self::ParachainContext, ()>
|
||||
where
|
||||
Client: ProvideRuntimeApi<Block> + HeaderBackend<Block> + BlockchainEvents<Block> + Send + Sync + 'static,
|
||||
Client::Api: RuntimeApiCollection,
|
||||
<Client::Api as ApiExt<Block>>::StateBackend: StateBackend<HashFor<Block>>,
|
||||
SP: SpawnNamed + Clone + Send + Sync + 'static;
|
||||
}
|
||||
|
||||
@@ -202,171 +194,179 @@ pub async fn collate<P>(
|
||||
}
|
||||
|
||||
#[cfg(feature = "service-rewr")]
|
||||
fn build_collator_service<SP, P, C, R>(
|
||||
_spawner: SP,
|
||||
_handles: FullNodeHandles,
|
||||
_client: Arc<C>,
|
||||
_para_id: ParaId,
|
||||
_key: Arc<CollatorPair>,
|
||||
_build_parachain_context: P,
|
||||
) -> Result<future::Ready<()>, polkadot_service::Error>
|
||||
fn build_collator_service<P>(
|
||||
spawner: SpawnTaskHandle,
|
||||
handles: FullNodeHandles,
|
||||
client: polkadot_service::Client,
|
||||
para_id: ParaId,
|
||||
key: Arc<CollatorPair>,
|
||||
build_parachain_context: P,
|
||||
) -> Result<Pin<Box<dyn Future<Output = ()> + Send + 'static>>, polkadot_service::Error>
|
||||
where
|
||||
C: PolkadotClient<
|
||||
service::Block,
|
||||
service::TFullBackend<service::Block>,
|
||||
R
|
||||
> + 'static,
|
||||
R: ConstructRuntimeApi<service::Block, C> + Sync + Send,
|
||||
<R as ConstructRuntimeApi<service::Block, C>>::RuntimeApi:
|
||||
sp_api::ApiExt<
|
||||
service::Block,
|
||||
StateBackend = <service::TFullBackend<service::Block> as service::Backend<service::Block>>::State,
|
||||
>
|
||||
+ RuntimeApiCollection<
|
||||
StateBackend = <service::TFullBackend<service::Block> as service::Backend<service::Block>>::State,
|
||||
>
|
||||
+ Sync + Send,
|
||||
P: BuildParachainContext,
|
||||
P::ParachainContext: Send + 'static,
|
||||
<P::ParachainContext as ParachainContext>::ProduceCandidate: Send,
|
||||
SP: SpawnNamed + Clone + Send + Sync + 'static,
|
||||
{
|
||||
Err("Collator is not functional with the new service yet".into())
|
||||
}
|
||||
|
||||
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
fn build_collator_service<P, C, R>(
|
||||
spawner: SpawnTaskHandle,
|
||||
handles: FullNodeHandles,
|
||||
client: Arc<C>,
|
||||
struct BuildCollationWork<P> {
|
||||
handles: polkadot_service::FullNodeHandles,
|
||||
para_id: ParaId,
|
||||
key: Arc<CollatorPair>,
|
||||
build_parachain_context: P,
|
||||
) -> Result<impl Future<Output = ()> + Send + 'static, polkadot_service::Error>
|
||||
spawner: SpawnTaskHandle,
|
||||
client: polkadot_service::Client,
|
||||
}
|
||||
|
||||
impl<P> polkadot_service::ExecuteWithClient for BuildCollationWork<P>
|
||||
where
|
||||
C: PolkadotClient<
|
||||
service::Block,
|
||||
service::TFullBackend<service::Block>,
|
||||
R
|
||||
> + 'static,
|
||||
R: ConstructRuntimeApi<service::Block, C> + Sync + Send,
|
||||
<R as ConstructRuntimeApi<service::Block, C>>::RuntimeApi:
|
||||
sp_api::ApiExt<
|
||||
service::Block,
|
||||
StateBackend = <service::TFullBackend<service::Block> as service::Backend<service::Block>>::State,
|
||||
>
|
||||
+ RuntimeApiCollection<
|
||||
StateBackend = <service::TFullBackend<service::Block> as service::Backend<service::Block>>::State,
|
||||
>
|
||||
+ Sync + Send,
|
||||
P: BuildParachainContext,
|
||||
P::ParachainContext: Send + 'static,
|
||||
<P::ParachainContext as ParachainContext>::ProduceCandidate: Send,
|
||||
{
|
||||
let polkadot_network = handles.polkadot_network
|
||||
.ok_or_else(|| "Collator cannot run when Polkadot-specific networking has not been started")?;
|
||||
type Output = Result<Pin<Box<dyn Future<Output = ()> + Send + 'static>>, polkadot_service::Error>;
|
||||
|
||||
// We don't require this here, but we need to make sure that the validation service is started.
|
||||
// This service makes sure the collator is joining the correct gossip topics and receives the appropiate
|
||||
// messages.
|
||||
handles.validation_service_handle
|
||||
.ok_or_else(|| "Collator cannot run when validation networking has not been started")?;
|
||||
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: RuntimeApiCollection<StateBackend = Backend::State>,
|
||||
Client: AbstractClient<Block, Backend, Api = Api> + 'static
|
||||
{
|
||||
let polkadot_network = self.handles
|
||||
.polkadot_network
|
||||
.ok_or_else(|| "Collator cannot run when Polkadot-specific networking has not been started")?;
|
||||
|
||||
let parachain_context = match build_parachain_context.build(
|
||||
client.clone(),
|
||||
spawner.clone(),
|
||||
polkadot_network.clone(),
|
||||
) {
|
||||
Ok(ctx) => ctx,
|
||||
Err(()) => {
|
||||
return Err("Could not build the parachain context!".into())
|
||||
}
|
||||
};
|
||||
// We don't require this here, but we need to make sure that the validation service is started.
|
||||
// This service makes sure the collator is joining the correct gossip topics and receives the appropiate
|
||||
// messages.
|
||||
self.handles.validation_service_handle
|
||||
.ok_or_else(|| "Collator cannot run when validation networking has not been started")?;
|
||||
|
||||
let work = async move {
|
||||
let mut notification_stream = client.import_notification_stream();
|
||||
let parachain_context = match self.build_parachain_context.build(
|
||||
self.client,
|
||||
self.spawner.clone(),
|
||||
polkadot_network.clone(),
|
||||
) {
|
||||
Ok(ctx) => ctx,
|
||||
Err(()) => {
|
||||
return Err("Could not build the parachain context!".into())
|
||||
}
|
||||
};
|
||||
|
||||
while let Some(notification) = notification_stream.next().await {
|
||||
macro_rules! try_fr {
|
||||
($e:expr) => {
|
||||
match $e {
|
||||
Ok(x) => x,
|
||||
Err(e) => return future::Either::Left(future::err(Error::Polkadot(
|
||||
format!("{:?}", e)
|
||||
))),
|
||||
let key = self.key;
|
||||
let para_id = self.para_id;
|
||||
let spawner = self.spawner;
|
||||
|
||||
let res = async move {
|
||||
let mut notification_stream = client.import_notification_stream();
|
||||
|
||||
while let Some(notification) = notification_stream.next().await {
|
||||
macro_rules! try_fr {
|
||||
($e:expr) => {
|
||||
match $e {
|
||||
Ok(x) => x,
|
||||
Err(e) => return future::Either::Left(future::err(Error::Polkadot(
|
||||
format!("{:?}", e)
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let relay_parent = notification.hash;
|
||||
let id = BlockId::hash(relay_parent);
|
||||
let relay_parent = notification.hash;
|
||||
let id = BlockId::hash(relay_parent);
|
||||
|
||||
let network = polkadot_network.clone();
|
||||
let client = client.clone();
|
||||
let key = key.clone();
|
||||
let parachain_context = parachain_context.clone();
|
||||
let network = polkadot_network.clone();
|
||||
let client = client.clone();
|
||||
let key = key.clone();
|
||||
let parachain_context = parachain_context.clone();
|
||||
|
||||
let work = future::lazy(move |_| {
|
||||
let api = client.runtime_api();
|
||||
let global_validation = try_fr!(api.global_validation_data(&id));
|
||||
let local_validation = match try_fr!(api.local_validation_data(&id, para_id)) {
|
||||
Some(local_validation) => local_validation,
|
||||
None => return future::Either::Left(future::ok(())),
|
||||
};
|
||||
let downward_messages = try_fr!(api.downward_messages(&id, para_id));
|
||||
let work = future::lazy(move |_| {
|
||||
let api = client.runtime_api();
|
||||
let global_validation = try_fr!(api.global_validation_data(&id));
|
||||
let local_validation = match try_fr!(api.local_validation_data(&id, para_id)) {
|
||||
Some(local_validation) => local_validation,
|
||||
None => return future::Either::Left(future::ok(())),
|
||||
};
|
||||
let downward_messages = try_fr!(api.downward_messages(&id, para_id));
|
||||
|
||||
let validators = try_fr!(api.validators(&id));
|
||||
let validators = try_fr!(api.validators(&id));
|
||||
|
||||
let targets = compute_targets(
|
||||
para_id,
|
||||
validators.as_slice(),
|
||||
try_fr!(api.duty_roster(&id)),
|
||||
let targets = compute_targets(
|
||||
para_id,
|
||||
validators.as_slice(),
|
||||
try_fr!(api.duty_roster(&id)),
|
||||
);
|
||||
|
||||
let collation_work = collate(
|
||||
relay_parent,
|
||||
para_id,
|
||||
global_validation,
|
||||
local_validation,
|
||||
downward_messages,
|
||||
parachain_context,
|
||||
key,
|
||||
).map(move |collation| {
|
||||
match collation {
|
||||
Some(collation) => network.distribute_collation(targets, collation),
|
||||
None => log::trace!("Skipping collation as `collate` returned `None`"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
future::Either::Right(collation_work)
|
||||
});
|
||||
|
||||
let deadlined = future::select(
|
||||
work.then(|f| f).boxed(),
|
||||
futures_timer::Delay::new(COLLATION_TIMEOUT)
|
||||
);
|
||||
|
||||
let collation_work = collate(
|
||||
relay_parent,
|
||||
para_id,
|
||||
global_validation,
|
||||
local_validation,
|
||||
downward_messages,
|
||||
parachain_context,
|
||||
key,
|
||||
).map(move |collation| {
|
||||
match collation {
|
||||
Some(collation) => network.distribute_collation(targets, collation),
|
||||
None => log::trace!("Skipping collation as `collate` returned `None`"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
future::Either::Right(collation_work)
|
||||
});
|
||||
|
||||
let deadlined = future::select(
|
||||
work.then(|f| f).boxed(),
|
||||
futures_timer::Delay::new(COLLATION_TIMEOUT)
|
||||
);
|
||||
|
||||
let silenced = deadlined
|
||||
.map(|either| {
|
||||
match either {
|
||||
future::Either::Right(_) => log::warn!("Collation failure: timeout"),
|
||||
future::Either::Left((Err(e), _)) => {
|
||||
log::error!("Collation failed: {:?}", e)
|
||||
let silenced = deadlined
|
||||
.map(|either| {
|
||||
match either {
|
||||
future::Either::Right(_) => log::warn!("Collation failure: timeout"),
|
||||
future::Either::Left((Err(e), _)) => {
|
||||
log::error!("Collation failed: {:?}", e)
|
||||
}
|
||||
future::Either::Left((Ok(()), _)) => {},
|
||||
}
|
||||
future::Either::Left((Ok(()), _)) => {},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let future = silenced.map(drop);
|
||||
let future = silenced.map(drop);
|
||||
|
||||
spawner.spawn("collation-work", future);
|
||||
}
|
||||
}.boxed();
|
||||
spawner.spawn("collation-work", future);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(work)
|
||||
Ok(res.boxed())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
fn build_collator_service<P>(
|
||||
spawner: SpawnTaskHandle,
|
||||
handles: FullNodeHandles,
|
||||
client: polkadot_service::Client,
|
||||
para_id: ParaId,
|
||||
key: Arc<CollatorPair>,
|
||||
build_parachain_context: P,
|
||||
) -> Result<Pin<Box<dyn Future<Output = ()> + Send + 'static>>, polkadot_service::Error>
|
||||
where
|
||||
P: BuildParachainContext,
|
||||
P::ParachainContext: Send + 'static,
|
||||
<P::ParachainContext as ParachainContext>::ProduceCandidate: Send,
|
||||
{
|
||||
client.execute_with(BuildCollationWork {
|
||||
handles,
|
||||
para_id,
|
||||
key,
|
||||
build_parachain_context,
|
||||
spawner,
|
||||
client: client.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Async function that will run the collator node with the given `RelayChainContext` and `ParachainContext`
|
||||
@@ -391,64 +391,25 @@ where
|
||||
.into());
|
||||
}
|
||||
|
||||
if config.chain_spec.is_kusama() {
|
||||
let (task_manager, client, handlers) = service::kusama_new_full(
|
||||
config,
|
||||
Some((key.public(), para_id)),
|
||||
None,
|
||||
false,
|
||||
6000,
|
||||
None,
|
||||
)?;
|
||||
let spawn_handle = task_manager.spawn_handle();
|
||||
let future = build_collator_service(
|
||||
spawn_handle,
|
||||
handlers,
|
||||
client,
|
||||
para_id,
|
||||
key,
|
||||
build_parachain_context
|
||||
)?;
|
||||
Ok((future.boxed(), task_manager))
|
||||
} else if config.chain_spec.is_westend() {
|
||||
let (task_manager, client, handlers) = service::westend_new_full(
|
||||
config,
|
||||
Some((key.public(), para_id)),
|
||||
None,
|
||||
false,
|
||||
6000,
|
||||
None,
|
||||
)?;
|
||||
let spawn_handle = task_manager.spawn_handle();
|
||||
let future = build_collator_service(
|
||||
spawn_handle,
|
||||
handlers,
|
||||
client,
|
||||
para_id,
|
||||
key,
|
||||
build_parachain_context
|
||||
)?;
|
||||
Ok((future.boxed(), task_manager))
|
||||
} else {
|
||||
let (task_manager, client, handles) = service::polkadot_new_full(
|
||||
config,
|
||||
Some((key.public(), para_id)),
|
||||
None,
|
||||
false,
|
||||
6000,
|
||||
None,
|
||||
)?;
|
||||
let spawn_handle = task_manager.spawn_handle();
|
||||
let future = build_collator_service(
|
||||
spawn_handle,
|
||||
handles,
|
||||
client,
|
||||
para_id,
|
||||
key,
|
||||
build_parachain_context
|
||||
)?;
|
||||
Ok((future.boxed(), task_manager))
|
||||
}
|
||||
let (task_manager, client, handlers) = polkadot_service::build_full(
|
||||
config,
|
||||
Some((key.public(), para_id)),
|
||||
None,
|
||||
false,
|
||||
6000,
|
||||
None,
|
||||
)?;
|
||||
|
||||
let future = build_collator_service(
|
||||
task_manager.spawn_handle(),
|
||||
handlers,
|
||||
client,
|
||||
para_id,
|
||||
key,
|
||||
build_parachain_context
|
||||
)?;
|
||||
|
||||
Ok((future, task_manager))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
@@ -492,9 +453,9 @@ mod tests {
|
||||
impl BuildParachainContext for BuildDummyParachainContext {
|
||||
type ParachainContext = DummyParachainContext;
|
||||
|
||||
fn build<C, SP>(
|
||||
fn build<SP>(
|
||||
self,
|
||||
_: Arc<C>,
|
||||
_: polkadot_service::Client,
|
||||
_: SP,
|
||||
_: impl Network + Clone + 'static,
|
||||
) -> Result<Self::ParachainContext, ()> {
|
||||
|
||||
@@ -26,9 +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, PolkadotClient,
|
||||
};
|
||||
use polkadot_service::{new_full, FullNodeHandles, AbstractClient};
|
||||
use polkadot_test_runtime::{RestrictFunctionality, Runtime, SignedExtra, SignedPayload, VERSION};
|
||||
use sc_chain_spec::ChainSpec;
|
||||
use sc_client_api::{execution_extensions::ExecutionStrategies, BlockchainEvents};
|
||||
@@ -69,7 +67,7 @@ pub fn polkadot_test_new_full(
|
||||
) -> Result<
|
||||
(
|
||||
TaskManager,
|
||||
Arc<impl PolkadotClient<Block, TFullBackend<Block>, polkadot_test_runtime::RuntimeApi>>,
|
||||
Arc<impl AbstractClient<Block, TFullBackend<Block>>>,
|
||||
FullNodeHandles,
|
||||
Arc<NetworkService<Block, Hash>>,
|
||||
Arc<RpcHandlers>,
|
||||
@@ -196,7 +194,7 @@ pub fn run_test_node(
|
||||
boot_nodes: Vec<MultiaddrWithPeerId>,
|
||||
) -> PolkadotTestNode<
|
||||
TaskManager,
|
||||
impl PolkadotClient<Block, TFullBackend<Block>, polkadot_test_runtime::RuntimeApi>,
|
||||
impl AbstractClient<Block, TFullBackend<Block>>,
|
||||
> {
|
||||
let config = node_config(storage_update_func, task_executor, key, boot_nodes);
|
||||
let multiaddr = config.network.listen_addresses[0].clone();
|
||||
|
||||
@@ -89,8 +89,11 @@ impl ParachainContext for AdderContext {
|
||||
let encoded_head = HeadData(next_head.encode());
|
||||
let encoded_body = BlockData(next_body.encode());
|
||||
|
||||
println!("Created collation for #{}, post-state={}",
|
||||
next_head.number, next_body.state.overflowing_add(next_body.add).0);
|
||||
println!(
|
||||
"Created collation for #{}, post-state={}",
|
||||
next_head.number,
|
||||
next_body.state.overflowing_add(next_body.add).0,
|
||||
);
|
||||
|
||||
db.insert(next_head.clone(), next_body);
|
||||
ready(Some((encoded_body, encoded_head)))
|
||||
@@ -100,9 +103,9 @@ impl ParachainContext for AdderContext {
|
||||
impl BuildParachainContext for AdderContext {
|
||||
type ParachainContext = Self;
|
||||
|
||||
fn build<Client, SP>(
|
||||
fn build<SP>(
|
||||
self,
|
||||
_: Arc<Client>,
|
||||
_: collator::Client,
|
||||
_: SP,
|
||||
network: impl Network + Clone + 'static,
|
||||
) -> Result<Self::ParachainContext, ()> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rococo-v1-runtime"
|
||||
version = "0.8.19"
|
||||
version = "0.8.22"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rococo-runtime"
|
||||
version = "0.8.14"
|
||||
version = "0.8.22"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
+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