remove connected disconnected state only (#3868)

* remove connected disconnected state from overseer

* foo

* split new partial

* fix

* refactor init code to not require a `OverseerHandle` when we don't have an overseer

* intermediate

* fixins

* X

* fixup

* foo

* fixup

* docs

* conditional

* Update node/service/src/lib.rs

* review by ladi
This commit is contained in:
Bernhard Schuster
2021-09-17 21:39:33 +02:00
committed by GitHub
parent 63a520b056
commit 5f637c510e
17 changed files with 552 additions and 307 deletions
+170 -112
View File
@@ -54,7 +54,7 @@ use {
pub use sp_core::traits::SpawnNamed;
#[cfg(feature = "full-node")]
pub use {
polkadot_overseer::{Handle, Overseer, OverseerHandle},
polkadot_overseer::{Handle, Overseer, OverseerConnector, OverseerHandle},
polkadot_primitives::v1::ParachainHost,
sc_client_api::AuxStore,
sp_authority_discovery::AuthorityDiscoveryApi,
@@ -68,6 +68,8 @@ use polkadot_subsystem::jaeger;
use std::{sync::Arc, time::Duration};
use prometheus_endpoint::Registry;
#[cfg(feature = "full-node")]
use service::KeystoreContainer;
use service::RpcHandlers;
use telemetry::TelemetryWorker;
#[cfg(feature = "full-node")]
@@ -302,14 +304,15 @@ fn jaeger_launch_collector_with_agent(
}
#[cfg(feature = "full-node")]
type FullSelectChain = relay_chain_selection::SelectRelayChainWithFallback<FullBackend>;
type FullSelectChain = relay_chain_selection::SelectRelayChain<FullBackend>;
#[cfg(feature = "full-node")]
type FullGrandpaBlockImport<RuntimeApi, ExecutorDispatch> = grandpa::GrandpaBlockImport<
FullBackend,
Block,
FullClient<RuntimeApi, ExecutorDispatch>,
FullSelectChain,
>;
type FullGrandpaBlockImport<RuntimeApi, ExecutorDispatch, ChainSelection = FullSelectChain> =
grandpa::GrandpaBlockImport<
FullBackend,
Block,
FullClient<RuntimeApi, ExecutorDispatch>,
ChainSelection,
>;
#[cfg(feature = "light-node")]
type LightBackend = service::TLightBackendWithHash<Block, sp_runtime::traits::BlakeTwo256>;
@@ -319,36 +322,29 @@ type LightClient<RuntimeApi, ExecutorDispatch> =
service::TLightClientWithBackend<Block, RuntimeApi, ExecutorDispatch, LightBackend>;
#[cfg(feature = "full-node")]
fn new_partial<RuntimeApi, ExecutorDispatch>(
struct Basics<RuntimeApi, ExecutorDispatch>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ Send
+ Sync
+ 'static,
RuntimeApi::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
{
task_manager: TaskManager,
client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
backend: Arc<FullBackend>,
keystore_container: KeystoreContainer,
telemetry: Option<Telemetry>,
}
#[cfg(feature = "full-node")]
fn new_partial_basics<RuntimeApi, ExecutorDispatch>(
config: &mut Configuration,
jaeger_agent: Option<std::net::SocketAddr>,
telemetry_worker_handle: Option<TelemetryWorkerHandle>,
) -> Result<
service::PartialComponents<
FullClient<RuntimeApi, ExecutorDispatch>,
FullBackend,
FullSelectChain,
sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
(
impl service::RpcExtensionBuilder,
(
babe::BabeBlockImport<
Block,
FullClient<RuntimeApi, ExecutorDispatch>,
FullGrandpaBlockImport<RuntimeApi, ExecutorDispatch>,
>,
grandpa::LinkHalf<Block, FullClient<RuntimeApi, ExecutorDispatch>, FullSelectChain>,
babe::BabeLink<Block>,
beefy_gadget::notification::BeefySignedCommitmentSender<Block>,
),
grandpa::SharedVoterState,
std::time::Duration, // slot-duration
Option<Telemetry>,
),
>,
Error,
>
) -> Result<Basics<RuntimeApi, ExecutorDispatch>, Error>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ Send
@@ -391,21 +387,62 @@ where
)?;
let client = Arc::new(client);
let telemetry = telemetry.map(|(worker, telemetry)| {
jaeger_launch_collector_with_agent(task_manager.spawn_handle(), &*config, jaeger_agent)?;
let telemetry: Option<_> = telemetry.map(|(worker, telemetry)| {
if let Some(worker) = worker {
task_manager.spawn_handle().spawn("telemetry", worker.run());
}
telemetry
});
jaeger_launch_collector_with_agent(task_manager.spawn_handle(), &*config, jaeger_agent)?;
let select_chain = relay_chain_selection::SelectRelayChainWithFallback::new(
backend.clone(),
Handle::new_disconnected(),
polkadot_node_subsystem_util::metrics::Metrics::register(config.prometheus_registry())?,
);
Ok(Basics { task_manager, client, backend, keystore_container, telemetry })
}
#[cfg(feature = "full-node")]
fn new_partial<RuntimeApi, ExecutorDispatch, ChainSelection>(
config: &mut Configuration,
Basics { task_manager, backend, client, keystore_container, telemetry }: Basics<
RuntimeApi,
ExecutorDispatch,
>,
select_chain: ChainSelection,
) -> Result<
service::PartialComponents<
FullClient<RuntimeApi, ExecutorDispatch>,
FullBackend,
ChainSelection,
sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
(
impl service::RpcExtensionBuilder,
(
babe::BabeBlockImport<
Block,
FullClient<RuntimeApi, ExecutorDispatch>,
FullGrandpaBlockImport<RuntimeApi, ExecutorDispatch, ChainSelection>,
>,
grandpa::LinkHalf<Block, FullClient<RuntimeApi, ExecutorDispatch>, ChainSelection>,
babe::BabeLink<Block>,
beefy_gadget::notification::BeefySignedCommitmentSender<Block>,
),
grandpa::SharedVoterState,
std::time::Duration, // slot-duration
Option<Telemetry>,
),
>,
Error,
>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
+ Send
+ Sync
+ 'static,
RuntimeApi::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
ChainSelection: 'static + SelectChain<Block>,
{
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
config.transaction_pool.clone(),
config.role.is_authority().into(),
@@ -674,23 +711,50 @@ where
let disable_grandpa = config.disable_grandpa;
let name = config.network.node_name.clone();
let service::PartialComponents {
client,
backend,
mut task_manager,
keystore_container,
mut select_chain,
import_queue,
transaction_pool,
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry),
} = new_partial::<RuntimeApi, ExecutorDispatch>(
let overseer_connector = OverseerConnector::default();
let handle = Handle(overseer_connector.as_handle().clone());
let basics = new_partial_basics::<RuntimeApi, ExecutorDispatch>(
&mut config,
jaeger_agent,
telemetry_worker_handle,
)?;
// we should remove this check before we deploy parachains on polkadot
// TODO: https://github.com/paritytech/polkadot/issues/3326
let chain_spec = &config.chain_spec as &dyn IdentifyVariant;
let is_relay_chain = chain_spec.is_kusama() ||
chain_spec.is_westend() ||
chain_spec.is_rococo() ||
chain_spec.is_wococo();
let prometheus_registry = config.prometheus_registry().cloned();
use relay_chain_selection::SelectRelayChain;
let select_chain = SelectRelayChain::new(
basics.backend.clone(),
is_relay_chain,
handle.clone(),
polkadot_node_subsystem_util::metrics::Metrics::register(prometheus_registry.as_ref())?,
);
let service::PartialComponents::<_, _, SelectRelayChain<_>, _, _, _> {
client,
backend,
mut task_manager,
keystore_container,
select_chain,
import_queue,
transaction_pool,
other: (rpc_extensions_builder, import_setup, rpc_setup, slot_duration, mut telemetry),
} = new_partial::<RuntimeApi, ExecutorDispatch, SelectRelayChain<_>>(
&mut config,
basics,
select_chain,
)?;
let shared_voter_state = rpc_setup;
let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht;
@@ -850,8 +914,10 @@ where
local_keystore.and_then(move |k| authority_discovery_service.map(|a| (a, k)));
let overseer_handle = if let Some((authority_discovery_service, keystore)) = maybe_params {
let (overseer, overseer_handle) = overseer_gen
// already have access to the handle
let (overseer, _handle) = overseer_gen
.generate::<service::SpawnTaskHandle, FullClient<RuntimeApi, ExecutorDispatch>>(
overseer_connector,
OverseerGenArgs {
leaves: active_leaves,
keystore,
@@ -875,40 +941,29 @@ where
dispute_coordinator_config,
},
)?;
let handle = Handle::Connected(overseer_handle.clone());
let handle_clone = handle.clone();
task_manager.spawn_essential_handle().spawn_blocking(
"overseer",
Box::pin(async move {
use futures::{pin_mut, select, FutureExt};
{
let handle = handle.clone();
task_manager.spawn_essential_handle().spawn_blocking(
"overseer",
Box::pin(async move {
use futures::{pin_mut, select, FutureExt};
let forward = polkadot_overseer::forward_events(overseer_client, handle_clone);
let forward = polkadot_overseer::forward_events(overseer_client, handle);
let forward = forward.fuse();
let overseer_fut = overseer.run().fuse();
let forward = forward.fuse();
let overseer_fut = overseer.run().fuse();
pin_mut!(overseer_fut);
pin_mut!(forward);
pin_mut!(overseer_fut);
pin_mut!(forward);
select! {
_ = forward => (),
_ = overseer_fut => (),
complete => (),
}
}),
);
// we should remove this check before we deploy parachains on polkadot
// TODO: https://github.com/paritytech/polkadot/issues/3326
let should_connect_overseer = chain_spec.is_kusama() ||
chain_spec.is_westend() ||
chain_spec.is_rococo() ||
chain_spec.is_wococo();
if should_connect_overseer {
select_chain.connect_to_overseer(overseer_handle.clone());
} else {
tracing::info!("Overseer is running in the disconnected state");
select! {
_ = forward => (),
_ = overseer_fut => (),
complete => (),
}
}),
);
}
Some(handle)
} else {
@@ -1228,6 +1283,31 @@ where
Ok((task_manager, rpc_handlers))
}
macro_rules! chain_ops {
($config:expr, $jaeger_agent:expr, $telemetry_worker_handle:expr; $scope:ident, $executor:ident, $variant:ident) => {{
let telemetry_worker_handle = $telemetry_worker_handle;
let jaeger_agent = $jaeger_agent;
let mut config = $config;
let basics = new_partial_basics::<$scope::RuntimeApi, $executor>(
config,
jaeger_agent,
telemetry_worker_handle,
)?;
use ::sc_consensus::LongestChain;
// use the longest chain selection, since there is no overseer available
let chain_selection = LongestChain::new(basics.backend.clone());
let service::PartialComponents { client, backend, import_queue, task_manager, .. } =
new_partial::<$scope::RuntimeApi, $executor, LongestChain<_, Block>>(
&mut config,
basics,
chain_selection,
)?;
Ok((Arc::new(Client::$variant(client)), backend, import_queue, task_manager))
}};
}
/// Builds a new object suitable for chain operations.
#[cfg(feature = "full-node")]
pub fn new_chain_ops(
@@ -1244,50 +1324,28 @@ pub fn new_chain_ops(
> {
config.keystore = service::config::KeystoreConfig::InMemory;
let telemetry_worker_handle = None;
#[cfg(feature = "rococo-native")]
if config.chain_spec.is_rococo() || config.chain_spec.is_wococo() {
let service::PartialComponents { client, backend, import_queue, task_manager, .. } =
new_partial::<rococo_runtime::RuntimeApi, RococoExecutorDispatch>(
config,
jaeger_agent,
None,
)?;
return Ok((Arc::new(Client::Rococo(client)), backend, import_queue, task_manager))
return chain_ops!(config, jaeger_agent, telemetry_worker_handle; rococo_runtime, RococoExecutorDispatch, Rococo)
}
#[cfg(feature = "kusama-native")]
if config.chain_spec.is_kusama() {
let service::PartialComponents { client, backend, import_queue, task_manager, .. } =
new_partial::<kusama_runtime::RuntimeApi, KusamaExecutorDispatch>(
config,
jaeger_agent,
None,
)?;
return Ok((Arc::new(Client::Kusama(client)), backend, import_queue, task_manager))
return chain_ops!(config, jaeger_agent, telemetry_worker_handle; kusama_runtime, KusamaExecutorDispatch, Kusama)
}
#[cfg(feature = "westend-native")]
if config.chain_spec.is_westend() {
let service::PartialComponents { client, backend, import_queue, task_manager, .. } =
new_partial::<westend_runtime::RuntimeApi, WestendExecutorDispatch>(
config,
jaeger_agent,
None,
)?;
return Ok((Arc::new(Client::Westend(client)), backend, import_queue, task_manager))
return chain_ops!(config, jaeger_agent, telemetry_worker_handle; westend_runtime, WestendExecutorDispatch, Westend)
}
#[cfg(feature = "polkadot-native")]
{
let service::PartialComponents { client, backend, import_queue, task_manager, .. } =
new_partial::<polkadot_runtime::RuntimeApi, PolkadotExecutorDispatch>(
config,
jaeger_agent,
None,
)?;
return Ok((Arc::new(Client::Polkadot(client)), backend, import_queue, task_manager))
chain_ops!(config, jaeger_agent, telemetry_worker_handle; polkadot_runtime, PolkadotExecutorDispatch, Polkadot)
}
#[cfg(not(feature = "polkadot-native"))]
Err(Error::NoRuntime)
}
+186 -10
View File
@@ -15,6 +15,7 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use super::{AuthorityDiscoveryApi, Block, Error, Hash, IsCollator, Registry, SpawnNamed};
use lru::LruCache;
use polkadot_availability_distribution::IncomingRequestReceivers;
use polkadot_node_core_approval_voting::Config as ApprovalVotingConfig;
use polkadot_node_core_av_store::Config as AvailabilityConfig;
@@ -22,7 +23,14 @@ use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig
use polkadot_node_core_chain_selection::Config as ChainSelectionConfig;
use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig;
use polkadot_node_network_protocol::request_response::{v1 as request_v1, IncomingRequestReceiver};
use polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandle};
#[cfg(any(feature = "malus", test))]
pub use polkadot_overseer::dummy::DummySubsystem;
pub use polkadot_overseer::{
metrics::{Metrics, MetricsTrait},
AllSubsystems, BlockInfo, HeadSupportsParachains, Overseer, OverseerBuilder, OverseerConnector,
OverseerHandle,
};
use polkadot_primitives::v1::ParachainHost;
use sc_authority_discovery::Service as AuthorityDiscoveryService;
use sc_client_api::AuxStore;
@@ -255,6 +263,176 @@ where
Ok(all_subsystems)
}
/// Obtain a prepared `OverseerBuilder`, that is initialized
/// with all default values.
pub fn prepared_overseer_builder<'a, Spawner, RuntimeClient>(
OverseerGenArgs {
leaves,
keystore,
runtime_client,
parachains_db,
network_service,
authority_discovery_service,
pov_req_receiver,
chunk_req_receiver,
collation_req_receiver,
available_data_req_receiver,
statement_req_receiver,
dispute_req_receiver,
registry,
spawner,
is_collator,
approval_voting_config,
availability_config,
candidate_validation_config,
chain_selection_config,
dispute_coordinator_config,
}: OverseerGenArgs<'a, Spawner, RuntimeClient>,
) -> Result<
OverseerBuilder<
Spawner,
Arc<RuntimeClient>,
CandidateValidationSubsystem,
CandidateBackingSubsystem<Spawner>,
StatementDistributionSubsystem,
AvailabilityDistributionSubsystem,
AvailabilityRecoverySubsystem,
BitfieldSigningSubsystem<Spawner>,
BitfieldDistributionSubsystem,
ProvisionerSubsystem<Spawner>,
RuntimeApiSubsystem<RuntimeClient>,
AvailabilityStoreSubsystem,
NetworkBridgeSubsystem<
Arc<sc_network::NetworkService<Block, Hash>>,
AuthorityDiscoveryService,
>,
ChainApiSubsystem<RuntimeClient>,
CollationGenerationSubsystem,
CollatorProtocolSubsystem,
ApprovalDistributionSubsystem,
ApprovalVotingSubsystem,
GossipSupportSubsystem,
DisputeCoordinatorSubsystem,
DisputeParticipationSubsystem,
DisputeDistributionSubsystem<AuthorityDiscoveryService>,
ChainSelectionSubsystem,
>,
Error,
>
where
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Spawner: 'static + SpawnNamed + Clone + Unpin,
{
use polkadot_node_subsystem_util::metrics::Metrics;
use std::iter::FromIterator;
let metrics = <polkadot_overseer::metrics::Metrics as MetricsTrait>::register(registry)?;
let builder = Overseer::builder()
.availability_distribution(AvailabilityDistributionSubsystem::new(
keystore.clone(),
IncomingRequestReceivers { pov_req_receiver, chunk_req_receiver },
Metrics::register(registry)?,
))
.availability_recovery(AvailabilityRecoverySubsystem::with_chunks_only(
available_data_req_receiver,
Metrics::register(registry)?,
))
.availability_store(AvailabilityStoreSubsystem::new(
parachains_db.clone(),
availability_config,
Metrics::register(registry)?,
))
.bitfield_distribution(BitfieldDistributionSubsystem::new(Metrics::register(registry)?))
.bitfield_signing(BitfieldSigningSubsystem::new(
spawner.clone(),
keystore.clone(),
Metrics::register(registry)?,
))
.candidate_backing(CandidateBackingSubsystem::new(
spawner.clone(),
keystore.clone(),
Metrics::register(registry)?,
))
.candidate_validation(CandidateValidationSubsystem::with_config(
candidate_validation_config,
Metrics::register(registry)?, // candidate-validation metrics
Metrics::register(registry)?, // validation host metrics
))
.chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?))
.collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?))
.collator_protocol({
let side = match is_collator {
IsCollator::Yes(collator_pair) => ProtocolSide::Collator(
network_service.local_peer_id().clone(),
collator_pair,
collation_req_receiver,
Metrics::register(registry)?,
),
IsCollator::No => ProtocolSide::Validator {
keystore: keystore.clone(),
eviction_policy: Default::default(),
metrics: Metrics::register(registry)?,
},
};
CollatorProtocolSubsystem::new(side)
})
.network_bridge(NetworkBridgeSubsystem::new(
network_service.clone(),
authority_discovery_service.clone(),
Box::new(network_service.clone()),
Metrics::register(registry)?,
))
.provisioner(ProvisionerSubsystem::new(spawner.clone(), (), Metrics::register(registry)?))
.runtime_api(RuntimeApiSubsystem::new(
runtime_client.clone(),
Metrics::register(registry)?,
spawner.clone(),
))
.statement_distribution(StatementDistributionSubsystem::new(
keystore.clone(),
statement_req_receiver,
Metrics::register(registry)?,
))
.approval_distribution(ApprovalDistributionSubsystem::new(Metrics::register(registry)?))
.approval_voting(ApprovalVotingSubsystem::with_config(
approval_voting_config,
parachains_db.clone(),
keystore.clone(),
Box::new(network_service.clone()),
Metrics::register(registry)?,
))
.gossip_support(GossipSupportSubsystem::new(keystore.clone()))
.dispute_coordinator(DisputeCoordinatorSubsystem::new(
parachains_db.clone(),
dispute_coordinator_config,
keystore.clone(),
Metrics::register(registry)?,
))
.dispute_participation(DisputeParticipationSubsystem::new())
.dispute_distribution(DisputeDistributionSubsystem::new(
keystore.clone(),
dispute_req_receiver,
authority_discovery_service.clone(),
Metrics::register(registry)?,
))
.chain_selection(ChainSelectionSubsystem::new(chain_selection_config, parachains_db))
.leaves(Vec::from_iter(
leaves
.into_iter()
.map(|BlockInfo { hash, parent_hash: _, number }| (hash, number)),
))
.activation_external_listeners(Default::default())
.span_per_active_leaf(Default::default())
.active_leaves(Default::default())
.supports_parachains(runtime_client)
.known_leaves(LruCache::new(KNOWN_LEAVES_CACHE_SIZE))
.metrics(metrics)
.spawner(spawner);
Ok(builder)
}
/// Trait for the `fn` generating the overseer.
///
/// Default behavior is to create an unmodified overseer, as `RealOverseerGen`
@@ -263,6 +441,7 @@ pub trait OverseerGen {
/// Overwrite the full generation of the overseer, including the subsystems.
fn generate<'a, Spawner, RuntimeClient>(
&self,
connector: OverseerConnector,
args: OverseerGenArgs<'a, Spawner, RuntimeClient>,
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandle), Error>
where
@@ -271,19 +450,22 @@ pub trait OverseerGen {
Spawner: 'static + SpawnNamed + Clone + Unpin,
{
let gen = RealOverseerGen;
RealOverseerGen::generate::<Spawner, RuntimeClient>(&gen, args)
RealOverseerGen::generate::<Spawner, RuntimeClient>(&gen, connector, args)
}
// It would be nice to make `create_subsystems` part of this trait,
// but the amount of generic arguments that would be required as
// as consequence make this rather annoying to implement and use.
}
use polkadot_overseer::KNOWN_LEAVES_CACHE_SIZE;
/// The regular set of subsystems.
pub struct RealOverseerGen;
impl OverseerGen for RealOverseerGen {
fn generate<'a, Spawner, RuntimeClient>(
&self,
connector: OverseerConnector,
args: OverseerGenArgs<'a, Spawner, RuntimeClient>,
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandle), Error>
where
@@ -291,14 +473,8 @@ impl OverseerGen for RealOverseerGen {
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Spawner: 'static + SpawnNamed + Clone + Unpin,
{
let spawner = args.spawner.clone();
let leaves = args.leaves.clone();
let runtime_client = args.runtime_client.clone();
let registry = args.registry.clone();
let all_subsystems = create_default_subsystems::<Spawner, RuntimeClient>(args)?;
Overseer::new(leaves, all_subsystems, registry, runtime_client, spawner)
prepared_overseer_builder(args)?
.build_with_connector(connector)
.map_err(|e| e.into())
}
}
@@ -39,7 +39,7 @@ use super::{HeaderProvider, HeaderProviderProvider};
use consensus_common::{Error as ConsensusError, SelectChain};
use futures::channel::oneshot;
use polkadot_node_subsystem_util::metrics::{self, prometheus};
use polkadot_overseer::{AllMessages, Handle, OverseerHandle};
use polkadot_overseer::{AllMessages, Handle};
use polkadot_primitives::v1::{
Block as PolkadotBlock, BlockNumber, Hash, Header as PolkadotHeader,
};
@@ -109,66 +109,57 @@ impl Metrics {
}
/// A chain-selection implementation which provides safety for relay chains.
pub struct SelectRelayChainWithFallback<B: sc_client_api::Backend<PolkadotBlock>> {
// A fallback to use in case the overseer is disconnected.
//
// This is used on relay chains which have not yet enabled
// parachains as well as situations where the node is offline.
fallback: sc_consensus::LongestChain<B, PolkadotBlock>,
selection: SelectRelayChain<B, Handle>,
pub struct SelectRelayChain<B: sc_client_api::Backend<PolkadotBlock>> {
is_relay_chain: bool,
longest_chain: sc_consensus::LongestChain<B, PolkadotBlock>,
selection: SelectRelayChainInner<B, Handle>,
}
impl<B> Clone for SelectRelayChainWithFallback<B>
impl<B> Clone for SelectRelayChain<B>
where
B: sc_client_api::Backend<PolkadotBlock>,
SelectRelayChain<B, Handle>: Clone,
SelectRelayChainInner<B, Handle>: Clone,
{
fn clone(&self) -> Self {
Self { fallback: self.fallback.clone(), selection: self.selection.clone() }
}
}
impl<B> SelectRelayChainWithFallback<B>
where
B: sc_client_api::Backend<PolkadotBlock> + 'static,
{
/// Create a new [`SelectRelayChainWithFallback`] wrapping the given chain backend
/// and a handle to the overseer.
pub fn new(backend: Arc<B>, overseer: Handle, metrics: Metrics) -> Self {
SelectRelayChainWithFallback {
fallback: sc_consensus::LongestChain::new(backend.clone()),
selection: SelectRelayChain::new(backend, overseer, metrics),
Self {
is_relay_chain: self.is_relay_chain,
longest_chain: self.longest_chain.clone(),
selection: self.selection.clone(),
}
}
}
impl<B> SelectRelayChainWithFallback<B>
impl<B> SelectRelayChain<B>
where
B: sc_client_api::Backend<PolkadotBlock> + 'static,
{
/// Given an overseer handle, this connects the [`SelectRelayChainWithFallback`]'s
/// internal handle and its clones to the same overseer.
pub fn connect_to_overseer(&mut self, handle: OverseerHandle) {
self.selection.overseer.connect_to_overseer(handle);
/// Create a new [`SelectRelayChain`] wrapping the given chain backend
/// and a handle to the overseer.
pub fn new(backend: Arc<B>, is_relay_chain: bool, overseer: Handle, metrics: Metrics) -> Self {
SelectRelayChain {
is_relay_chain,
longest_chain: sc_consensus::LongestChain::new(backend.clone()),
selection: SelectRelayChainInner::new(backend, overseer, metrics),
}
}
}
#[async_trait::async_trait]
impl<B> SelectChain<PolkadotBlock> for SelectRelayChainWithFallback<B>
impl<B> SelectChain<PolkadotBlock> for SelectRelayChain<B>
where
B: sc_client_api::Backend<PolkadotBlock> + 'static,
{
async fn leaves(&self) -> Result<Vec<Hash>, ConsensusError> {
if self.selection.overseer.is_disconnected() {
return self.fallback.leaves().await
if !self.is_relay_chain {
return self.longest_chain.leaves().await
}
self.selection.leaves().await
}
async fn best_chain(&self) -> Result<PolkadotHeader, ConsensusError> {
if self.selection.overseer.is_disconnected() {
return self.fallback.best_chain().await
if !self.is_relay_chain {
return self.longest_chain.best_chain().await
}
self.selection.best_chain().await
}
@@ -179,34 +170,34 @@ where
maybe_max_number: Option<BlockNumber>,
) -> Result<Option<Hash>, ConsensusError> {
let longest_chain_best =
self.fallback.finality_target(target_hash, maybe_max_number).await?;
self.longest_chain.finality_target(target_hash, maybe_max_number).await?;
if self.selection.overseer.is_disconnected() {
if !self.is_relay_chain {
return Ok(longest_chain_best)
}
self.selection
.finality_target_with_fallback(target_hash, longest_chain_best, maybe_max_number)
.finality_target_with_longest_chain(target_hash, longest_chain_best, maybe_max_number)
.await
}
}
/// A chain-selection implementation which provides safety for relay chains
/// but does not handle situations where the overseer is not yet connected.
pub struct SelectRelayChain<B, OH> {
pub struct SelectRelayChainInner<B, OH> {
backend: Arc<B>,
overseer: OH,
metrics: Metrics,
}
impl<B, OH> SelectRelayChain<B, OH>
impl<B, OH> SelectRelayChainInner<B, OH>
where
B: HeaderProviderProvider<PolkadotBlock>,
OH: OverseerHandleT,
{
/// Create a new [`SelectRelayChain`] wrapping the given chain backend
/// Create a new [`SelectRelayChainInner`] wrapping the given chain backend
/// and a handle to the overseer.
pub fn new(backend: Arc<B>, overseer: OH, metrics: Metrics) -> Self {
SelectRelayChain { backend, overseer, metrics }
SelectRelayChainInner { backend, overseer, metrics }
}
fn block_header(&self, hash: Hash) -> Result<PolkadotHeader, ConsensusError> {
@@ -234,13 +225,13 @@ where
}
}
impl<B, OH> Clone for SelectRelayChain<B, OH>
impl<B, OH> Clone for SelectRelayChainInner<B, OH>
where
B: HeaderProviderProvider<PolkadotBlock> + Send + Sync,
OH: OverseerHandleT,
{
fn clone(&self) -> Self {
SelectRelayChain {
SelectRelayChainInner {
backend: self.backend.clone(),
overseer: self.overseer.clone(),
metrics: self.metrics.clone(),
@@ -273,7 +264,7 @@ impl OverseerHandleT for Handle {
}
}
impl<B, OH> SelectRelayChain<B, OH>
impl<B, OH> SelectRelayChainInner<B, OH>
where
B: HeaderProviderProvider<PolkadotBlock>,
OH: OverseerHandleT,
@@ -317,7 +308,7 @@ where
///
/// It will also constrain the chain to only chains which are fully
/// approved, and chains which contain no disputes.
pub(crate) async fn finality_target_with_fallback(
pub(crate) async fn finality_target_with_longest_chain(
&self,
target_hash: Hash,
best_leaf: Option<Hash>,
+1 -1
View File
@@ -79,7 +79,7 @@ fn test_harness<T: Future<Output = VirtualOverseer>>(
let (finality_target_tx, finality_target_rx) = oneshot::channel::<Option<Hash>>();
let select_relay_chain = SelectRelayChain::<TestChainStorage, TestSubsystemSender>::new(
let select_relay_chain = SelectRelayChainInner::<TestChainStorage, TestSubsystemSender>::new(
Arc::new(case_vars.chain.clone()),
context.sender().clone(),
Default::default(),