b6d35f6faf
Updated 4763 files with dual copyright: - Parity Technologies (UK) Ltd. - Dijital Kurdistan Tech Institute
151 lines
5.0 KiB
Rust
151 lines
5.0 KiB
Rust
// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
|
|
// This file is part of Pezcumulus.
|
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
|
|
// Pezcumulus is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// Pezcumulus is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Pezcumulus. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
use futures::{select, StreamExt};
|
|
use std::sync::Arc;
|
|
|
|
use pezkuwi_overseer::{
|
|
BlockInfo, Handle, Overseer, OverseerConnector, OverseerHandle, SpawnGlue, UnpinHandle,
|
|
};
|
|
use pezkuwi_service::overseer::{collator_overseer_builder, OverseerGenArgs};
|
|
|
|
use pezsc_network::{request_responses::IncomingRequest, service::traits::NetworkService};
|
|
use pezsc_service::TaskManager;
|
|
use pezsc_utils::mpsc::tracing_unbounded;
|
|
|
|
use pezcumulus_relay_chain_interface::RelayChainError;
|
|
|
|
use crate::BlockChainRpcClient;
|
|
|
|
fn build_overseer(
|
|
connector: OverseerConnector,
|
|
args: OverseerGenArgs<pezsc_service::SpawnTaskHandle, BlockChainRpcClient>,
|
|
) -> Result<
|
|
(Overseer<SpawnGlue<pezsc_service::SpawnTaskHandle>, Arc<BlockChainRpcClient>>, OverseerHandle),
|
|
RelayChainError,
|
|
> {
|
|
let builder =
|
|
collator_overseer_builder(args).map_err(|e| RelayChainError::Application(e.into()))?;
|
|
|
|
builder
|
|
.build_with_connector(connector)
|
|
.map_err(|e| RelayChainError::Application(e.into()))
|
|
}
|
|
|
|
pub(crate) fn spawn_overseer(
|
|
overseer_args: OverseerGenArgs<pezsc_service::SpawnTaskHandle, BlockChainRpcClient>,
|
|
task_manager: &TaskManager,
|
|
relay_chain_rpc_client: Arc<BlockChainRpcClient>,
|
|
) -> Result<pezkuwi_overseer::Handle, RelayChainError> {
|
|
let (overseer, overseer_handle) = build_overseer(OverseerConnector::default(), overseer_args)
|
|
.map_err(|e| {
|
|
tracing::error!("Failed to initialize overseer: {}", e);
|
|
e
|
|
})?;
|
|
|
|
let overseer_handle = Handle::new(overseer_handle);
|
|
{
|
|
let handle = overseer_handle.clone();
|
|
task_manager.spawn_essential_handle().spawn_blocking(
|
|
"overseer",
|
|
None,
|
|
Box::pin(async move {
|
|
use futures::{pin_mut, FutureExt};
|
|
|
|
let forward = forward_collator_events(relay_chain_rpc_client, handle).fuse();
|
|
|
|
let overseer_fut = overseer.run().fuse();
|
|
|
|
pin_mut!(overseer_fut);
|
|
pin_mut!(forward);
|
|
|
|
select! {
|
|
_ = forward => (),
|
|
_ = overseer_fut => (),
|
|
}
|
|
}),
|
|
);
|
|
}
|
|
Ok(overseer_handle)
|
|
}
|
|
|
|
/// Minimal relay chain node representation
|
|
pub struct NewMinimalNode {
|
|
/// Task manager running all tasks for the minimal node
|
|
pub task_manager: TaskManager,
|
|
/// Overseer handle to interact with subsystems
|
|
pub overseer_handle: Handle,
|
|
/// Network service
|
|
pub network_service: Arc<dyn NetworkService>,
|
|
/// Teyrchain bootnode request-response protocol receiver
|
|
pub paranode_rx: async_channel::Receiver<IncomingRequest>,
|
|
}
|
|
|
|
/// Glues together the [`Overseer`] and `BlockchainEvents` by forwarding
|
|
/// import and finality notifications into the [`OverseerHandle`].
|
|
async fn forward_collator_events(
|
|
client: Arc<BlockChainRpcClient>,
|
|
mut handle: Handle,
|
|
) -> Result<(), RelayChainError> {
|
|
let mut finality = client.finality_notification_stream().await?.fuse();
|
|
let mut imports = client.import_notification_stream().await?.fuse();
|
|
// Collators do no need to pin any specific blocks
|
|
let (dummy_sink, _) = tracing_unbounded("does-not-matter", 42);
|
|
let dummy_unpin_handle = UnpinHandle::new(Default::default(), dummy_sink);
|
|
|
|
loop {
|
|
select! {
|
|
f = finality.next() => {
|
|
match f {
|
|
Some(header) => {
|
|
let hash = header.hash();
|
|
tracing::info!(
|
|
target: "minimal-pezkuwi-node",
|
|
"Received finalized block via RPC: #{} ({} -> {})",
|
|
header.number,
|
|
header.parent_hash,
|
|
hash,
|
|
);
|
|
let unpin_handle = dummy_unpin_handle.clone();
|
|
let block_info = BlockInfo { hash, parent_hash: header.parent_hash, number: header.number, unpin_handle };
|
|
handle.block_finalized(block_info).await;
|
|
}
|
|
None => return Err(RelayChainError::GenericError("Relay chain finality stream ended.".to_string())),
|
|
}
|
|
},
|
|
i = imports.next() => {
|
|
match i {
|
|
Some(header) => {
|
|
let hash = header.hash();
|
|
tracing::info!(
|
|
target: "minimal-pezkuwi-node",
|
|
"Received imported block via RPC: #{} ({} -> {})",
|
|
header.number,
|
|
header.parent_hash,
|
|
hash,
|
|
);
|
|
let unpin_handle = dummy_unpin_handle.clone();
|
|
let block_info = BlockInfo { hash, parent_hash: header.parent_hash, number: header.number, unpin_handle };
|
|
handle.block_imported(block_info).await;
|
|
}
|
|
None => return Err(RelayChainError::GenericError("Relay chain import stream ended.".to_string())),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|