Unverified Commit e4f5ade5 authored by asynchronous rob's avatar asynchronous rob Committed by GitHub
Browse files

Remove real-overseer 馃帀 (#2834)

* remove real-overseer

* overseer: only activate leaves which support parachains

* integrate HeadSupportsParachains into service

* remove unneeded line
parent c44fdd2f
Pipeline #133413 failed with stages
in 20 minutes and 29 seconds
......@@ -176,11 +176,9 @@ build-linux-release:
# extra features when building on `rococo-v1` branch and manual build on PRs
- if: $CI_COMMIT_REF_NAME == "rococo-v1"
variables:
EXTRA_FLAGS: "--features=real-overseer"
RUSTFLAGS: "-Cdebug-assertions=y"
- if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs
variables:
EXTRA_FLAGS: "--features=real-overseer"
RUSTFLAGS: "-Cdebug-assertions=y"
- when: always
script:
......
......@@ -6059,6 +6059,7 @@ dependencies = [
"polkadot-node-subsystem-util",
"polkadot-primitives",
"sc-client-api",
"sp-api",
"sp-core",
"tracing",
]
......
......@@ -95,7 +95,6 @@ panic = "unwind"
[features]
runtime-benchmarks=["cli/runtime-benchmarks"]
real-overseer=["cli/real-overseer"]
try-runtime = ["cli/try-runtime"]
# Configuration for building a .deb package - for use with `cargo-deb`
......
......@@ -58,5 +58,4 @@ browser = [
runtime-benchmarks = [ "service/runtime-benchmarks" ]
trie-memory-tracker = [ "sp-trie/memory-tracker" ]
full-node = [ "service/full-node" ]
real-overseer = [ "service/real-overseer" ]
try-runtime = [ "service/try-runtime" ]
......@@ -7,6 +7,7 @@ edition = "2018"
[dependencies]
async-trait = "0.1.42"
client = { package = "sc-client-api", git = "https://github.com/paritytech/substrate", branch = "master" }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
futures = "0.3.12"
futures-timer = "3.0.2"
polkadot-node-primitives = { package = "polkadot-node-primitives", path = "../primitives" }
......
......@@ -27,13 +27,19 @@ use futures::{
use futures_timer::Delay;
use polkadot_node_primitives::{PoV, BlockData};
use polkadot_overseer::{Overseer, AllSubsystems};
use polkadot_primitives::v1::Hash;
use polkadot_overseer::{Overseer, HeadSupportsParachains, AllSubsystems};
use polkadot_subsystem::{Subsystem, SubsystemContext, SpawnedSubsystem, FromOverseer};
use polkadot_subsystem::messages::{
CandidateValidationMessage, CandidateBackingMessage, AllMessages,
};
struct AlwaysSupportsParachains;
impl HeadSupportsParachains for AlwaysSupportsParachains {
fn head_supports_parachains(&self, _head: &Hash) -> bool { true }
}
struct Subsystem1;
impl Subsystem1 {
......@@ -146,6 +152,7 @@ fn main() {
vec![],
all_subsystems,
None,
AlwaysSupportsParachains,
spawner,
).unwrap();
let overseer_fut = overseer.run().fuse();
......
......@@ -75,8 +75,9 @@ use futures::{
};
use futures_timer::Delay;
use polkadot_primitives::v1::{Block, BlockNumber, Hash};
use polkadot_primitives::v1::{Block, BlockId,BlockNumber, Hash, ParachainHost};
use client::{BlockImportNotification, BlockchainEvents, FinalityNotification};
use sp_api::{ApiExt, ProvideRuntimeApi};
use polkadot_subsystem::messages::{
CandidateValidationMessage, CandidateBackingMessage,
......@@ -118,6 +119,22 @@ impl<F, T, U> MapSubsystem<T> for F where F: Fn(T) -> U {
}
}
/// Whether a header supports parachain consensus or not.
pub trait HeadSupportsParachains {
/// Return true if the given header supports parachain consensus. Otherwise, false.
fn head_supports_parachains(&self, head: &Hash) -> bool;
}
impl<Client> HeadSupportsParachains for Arc<Client> where
Client: ProvideRuntimeApi<Block>,
Client::Api: ParachainHost<Block>,
{
fn head_supports_parachains(&self, head: &Hash) -> bool {
let id = BlockId::Hash(*head);
self.runtime_api().has_api::<dyn ParachainHost<Block>>(&id).unwrap_or(false)
}
}
/// This struct is passed as an argument to create a new instance of an [`Overseer`].
///
/// As any entity that satisfies the interface may act as a [`Subsystem`] this allows
......@@ -1515,7 +1532,7 @@ struct SubsystemMeterReadouts {
}
/// The `Overseer` itself.
pub struct Overseer<S> {
pub struct Overseer<S, SupportsParachains> {
/// Handles to all subsystems.
subsystems: AllSubsystems<
OverseenSubsystem<CandidateValidationMessage>,
......@@ -1564,6 +1581,9 @@ pub struct Overseer<S> {
/// The set of the "active leaves".
active_leaves: HashMap<Hash, BlockNumber>,
/// An implementation for checking whether a header supports parachain consensus.
supports_parachains: SupportsParachains,
/// Various Prometheus metrics.
metrics: Metrics,
}
......@@ -1740,9 +1760,10 @@ impl fmt::Debug for Metrics {
}
}
impl<S> Overseer<S>
impl<S, SupportsParachains> Overseer<S, SupportsParachains>
where
S: SpawnNamed,
SupportsParachains: HeadSupportsParachains,
{
/// Create a new instance of the `Overseer` with a fixed set of [`Subsystem`]s.
///
......@@ -1778,7 +1799,8 @@ where
/// # use std::time::Duration;
/// # use futures::{executor, pin_mut, select, FutureExt};
/// # use futures_timer::Delay;
/// # use polkadot_overseer::{Overseer, AllSubsystems};
/// # use polkadot_overseer::{Overseer, HeadSupportsParachains, AllSubsystems};
/// # use polkadot_primitives::v1::Hash;
/// # use polkadot_subsystem::{
/// # Subsystem, DummySubsystem, SpawnedSubsystem, SubsystemContext,
/// # messages::CandidateValidationMessage,
......@@ -1805,12 +1827,18 @@ where
/// }
///
/// # fn main() { executor::block_on(async move {
///
/// struct AlwaysSupportsParachains;
/// impl HeadSupportsParachains for AlwaysSupportsParachains {
/// fn head_supports_parachains(&self, _head: &Hash) -> bool { true }
/// }
/// let spawner = sp_core::testing::TaskExecutor::new();
/// let all_subsystems = AllSubsystems::<()>::dummy().replace_candidate_validation(ValidationSubsystem);
/// let (overseer, _handler) = Overseer::new(
/// vec![],
/// all_subsystems,
/// None,
/// AlwaysSupportsParachains,
/// spawner,
/// ).unwrap();
///
......@@ -1831,6 +1859,7 @@ where
leaves: impl IntoIterator<Item = BlockInfo>,
all_subsystems: AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS>,
prometheus_registry: Option<&prometheus::Registry>,
supports_parachains: SupportsParachains,
mut s: S,
) -> SubsystemResult<(Self, OverseerHandler)>
where
......@@ -2289,6 +2318,7 @@ where
active_leaves,
metrics,
span_per_active_leaf: Default::default(),
supports_parachains,
};
Ok((this, handler))
......@@ -2337,12 +2367,13 @@ where
for (hash, number) in std::mem::take(&mut self.leaves) {
let _ = self.active_leaves.insert(hash, number);
let span = self.on_head_activated(&hash, None);
update.activated.push(ActivatedLeaf {
hash,
number,
span,
});
if let Some(span) = self.on_head_activated(&hash, None) {
update.activated.push(ActivatedLeaf {
hash,
number,
span,
});
}
}
if !update.is_empty() {
......@@ -2421,12 +2452,14 @@ where
}
};
let span = self.on_head_activated(&block.hash, Some(block.parent_hash));
let mut update = ActiveLeavesUpdate::start_work(ActivatedLeaf {
hash: block.hash,
number: block.number,
span
});
let mut update = match self.on_head_activated(&block.hash, Some(block.parent_hash)) {
Some(span) => ActiveLeavesUpdate::start_work(ActivatedLeaf {
hash: block.hash,
number: block.number,
span
}),
None => ActiveLeavesUpdate::default(),
};
if let Some(number) = self.active_leaves.remove(&block.parent_hash) {
debug_assert_eq!(block.number.saturating_sub(1), number);
......@@ -2436,7 +2469,11 @@ where
self.clean_up_external_listeners();
self.broadcast_signal(OverseerSignal::ActiveLeaves(update)).await
if !update.is_empty() {
self.broadcast_signal(OverseerSignal::ActiveLeaves(update)).await
} else {
Ok(())
}
}
#[tracing::instrument(level = "trace", skip(self), fields(subsystem = LOG_TARGET))]
......@@ -2555,8 +2592,16 @@ where
Ok(())
}
/// Handles a header activation. If the header's state doesn't support the parachains API,
/// this returns `None`.
#[tracing::instrument(level = "trace", skip(self), fields(subsystem = LOG_TARGET))]
fn on_head_activated(&mut self, hash: &Hash, parent_hash: Option<Hash>) -> Arc<jaeger::Span> {
fn on_head_activated(&mut self, hash: &Hash, parent_hash: Option<Hash>)
-> Option<Arc<jaeger::Span>>
{
if !self.supports_parachains.head_supports_parachains(hash) {
return None;
}
self.metrics.on_head_activated();
if let Some(listeners) = self.activation_external_listeners.remove(hash) {
for listener in listeners {
......@@ -2573,7 +2618,7 @@ where
let span = Arc::new(span);
self.span_per_active_leaf.insert(*hash, span.clone());
span
Some(span)
}
#[tracing::instrument(level = "trace", skip(self), fields(subsystem = LOG_TARGET))]
......@@ -2786,6 +2831,13 @@ mod tests {
}
}
struct MockSupportsParachains;
impl HeadSupportsParachains for MockSupportsParachains {
fn head_supports_parachains(&self, _head: &Hash) -> bool {
true
}
}
// Checks that a minimal configuration of two jobs can run and exchange messages.
#[test]
......@@ -2807,6 +2859,7 @@ mod tests {
vec![],
all_subsystems,
None,
MockSupportsParachains,
spawner,
).unwrap();
let overseer_fut = overseer.run().fuse();
......@@ -2876,6 +2929,7 @@ mod tests {
vec![first_block],
all_subsystems,
Some(&registry),
MockSupportsParachains,
spawner,
).unwrap();
let overseer_fut = overseer.run().fuse();
......@@ -2929,6 +2983,7 @@ mod tests {
vec![],
all_subsystems,
None,
MockSupportsParachains,
spawner,
).unwrap();
......@@ -3034,6 +3089,7 @@ mod tests {
vec![first_block],
all_subsystems,
None,
MockSupportsParachains,
spawner,
).unwrap();
......@@ -3139,6 +3195,7 @@ mod tests {
vec![first_block, second_block],
all_subsystems,
None,
MockSupportsParachains,
spawner,
).unwrap();
......@@ -3236,6 +3293,7 @@ mod tests {
Vec::new(),
all_subsystems,
None,
MockSupportsParachains,
spawner,
).unwrap();
......@@ -3479,6 +3537,7 @@ mod tests {
vec![],
all_subsystems,
None,
MockSupportsParachains,
spawner,
).unwrap();
let overseer_fut = overseer.run().fuse();
......
......@@ -113,25 +113,6 @@ db = ["service/db"]
full-node = [
"polkadot-node-core-av-store",
"polkadot-node-core-approval-voting",
"sc-finality-grandpa-warp-sync",
"kvdb-rocksdb"
]
runtime-benchmarks = [
"polkadot-runtime/runtime-benchmarks",
"kusama-runtime/runtime-benchmarks",
"westend-runtime/runtime-benchmarks",
"rococo-runtime/runtime-benchmarks"
]
try-runtime = [
"polkadot-runtime/try-runtime",
"kusama-runtime/try-runtime",
"westend-runtime/try-runtime",
"rococo-runtime/try-runtime",
]
real-overseer = [
"full-node",
"polkadot-availability-bitfield-distribution",
"polkadot-availability-distribution",
"polkadot-availability-recovery",
......@@ -148,4 +129,19 @@ real-overseer = [
"polkadot-node-core-runtime-api",
"polkadot-statement-distribution",
"polkadot-approval-distribution",
"sc-finality-grandpa-warp-sync",
"kvdb-rocksdb"
]
runtime-benchmarks = [
"polkadot-runtime/runtime-benchmarks",
"kusama-runtime/runtime-benchmarks",
"westend-runtime/runtime-benchmarks",
"rococo-runtime/runtime-benchmarks"
]
try-runtime = [
"polkadot-runtime/try-runtime",
"kusama-runtime/try-runtime",
"westend-runtime/try-runtime",
"rococo-runtime/try-runtime",
]
......@@ -24,7 +24,7 @@ use sp_runtime::traits::{Block as BlockT, NumberFor};
use sp_runtime::generic::BlockId;
use sp_runtime::traits::Header as _;
#[cfg(feature = "real-overseer")]
#[cfg(feature = "full-node")]
use {
polkadot_primitives::v1::{Block as PolkadotBlock, Header as PolkadotHeader},
polkadot_subsystem::messages::ApprovalVotingMessage,
......@@ -39,14 +39,14 @@ use {
/// The practical effect of this voting rule is to implement a fixed delay of
/// blocks and to issue a prometheus metric on the lag behind the head that
/// approval checking would indicate.
#[cfg(feature = "real-overseer")]
#[cfg(feature = "full-node")]
#[derive(Clone)]
pub(crate) struct ApprovalCheckingVotingRule {
checking_lag: Option<prometheus_endpoint::Gauge<prometheus_endpoint::U64>>,
overseer: OverseerHandler,
}
#[cfg(feature = "real-overseer")]
#[cfg(feature = "full-node")]
impl ApprovalCheckingVotingRule {
/// Create a new approval checking diagnostic voting rule.
pub fn new(overseer: OverseerHandler, registry: Option<&Registry>)
......@@ -71,7 +71,7 @@ impl ApprovalCheckingVotingRule {
}
}
#[cfg(feature = "real-overseer")]
#[cfg(feature = "full-node")]
impl<B> grandpa::VotingRule<PolkadotBlock, B> for ApprovalCheckingVotingRule
where B: sp_blockchain::HeaderBackend<PolkadotBlock>
{
......
......@@ -27,6 +27,7 @@ mod parachains_db;
use {
std::time::Duration,
tracing::info,
polkadot_network_bridge::RequestMultiplexer,
polkadot_node_core_av_store::Config as AvailabilityConfig,
polkadot_node_core_av_store::Error as AvailabilityError,
polkadot_node_core_approval_voting::Config as ApprovalVotingConfig,
......@@ -44,8 +45,6 @@ use {
beefy_primitives::ecdsa::AuthoritySignature as BeefySignature,
sp_runtime::traits::Header as HeaderT,
};
#[cfg(feature = "real-overseer")]
use polkadot_network_bridge::RequestMultiplexer;
use sp_core::traits::SpawnNamed;
......@@ -413,36 +412,7 @@ fn new_partial<RuntimeApi, Executor>(
})
}
#[cfg(all(feature="full-node", not(feature = "real-overseer")))]
fn real_overseer<Spawner, RuntimeClient>(
leaves: impl IntoIterator<Item = BlockInfo>,
_: Arc<LocalKeystore>,
_: Arc<RuntimeClient>,
_parachains_db: (),
_: AvailabilityConfig,
_: ApprovalVotingConfig,
_: Arc<sc_network::NetworkService<Block, Hash>>,
_: AuthorityDiscoveryService,
_request_multiplexer: (),
registry: Option<&Registry>,
spawner: Spawner,
_: IsCollator,
_: IsolationStrategy,
) -> Result<(Overseer<Spawner>, OverseerHandler), Error>
where
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
Spawner: 'static + SpawnNamed + Clone + Unpin,
{
Overseer::new(
leaves,
AllSubsystems::<()>::dummy(),
registry,
spawner,
).map_err(|e| e.into())
}
#[cfg(all(feature = "full-node", feature = "real-overseer"))]
#[cfg(feature = "full-node")]
fn real_overseer<Spawner, RuntimeClient>(
leaves: impl IntoIterator<Item = BlockInfo>,
keystore: Arc<LocalKeystore>,
......@@ -457,7 +427,7 @@ fn real_overseer<Spawner, RuntimeClient>(
spawner: Spawner,
is_collator: IsCollator,
isolation_strategy: IsolationStrategy,
) -> Result<(Overseer<Spawner>, OverseerHandler), Error>
) -> Result<(Overseer<Spawner, Arc<RuntimeClient>>, OverseerHandler), Error>
where
RuntimeClient: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block> + AuxStore,
RuntimeClient::Api: ParachainHost<Block> + BabeApi<Block> + AuthorityDiscoveryApi<Block>,
......@@ -582,6 +552,7 @@ where
leaves,
all_subsystems,
registry,
runtime_client.clone(),
spawner,
).map_err(|e| e.into())
}
......@@ -711,17 +682,10 @@ pub fn new_full<RuntimeApi, Executor>(
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
Executor: NativeExecutionDispatch + 'static,
{
#[cfg(feature = "real-overseer")]
info!("real-overseer feature is ENABLED");
let role = config.role.clone();
let force_authoring = config.force_authoring;
let backoff_authoring_blocks = {
let mut backoff = sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging {
#[cfg(feature = "real-overseer")]
unfinalized_slack: 100,
..Default::default()
};
let mut backoff = sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default();
if config.chain_spec.is_rococo() {
// it's a testnet that's in flux, finality has stalled sometimes due
......@@ -761,7 +725,6 @@ pub fn new_full<RuntimeApi, Executor>(
config.network.extra_sets.push(beefy_gadget::beefy_peers_set_config());
}
#[cfg(feature = "real-overseer")]
{
use polkadot_network_bridge::{peer_sets_info, IsAuthority};
let is_authority = if role.is_authority() {
......@@ -772,20 +735,6 @@ pub fn new_full<RuntimeApi, Executor>(
config.network.extra_sets.extend(peer_sets_info(is_authority));
}
// Add a dummy collation set with the intent of printing an error if one tries to connect a
// collator to a node that isn't compiled with `--features real-overseer`.
#[cfg(not(feature = "real-overseer"))]
config.network.extra_sets.push(sc_network::config::NonDefaultSetConfig {
notifications_protocol: "/polkadot/collation/1".into(),
max_notification_size: 16,
set_config: sc_network::config::SetConfig {
in_peers: 25,
out_peers: 0,
reserved_nodes: Vec::new(),
non_reserved_mode: sc_network::config::NonReservedPeerMode::Accept,
},
});
// TODO: At the moment, the collator protocol uses notifications protocols to download
// collations. Because of DoS-protection measures, notifications protocols have a very limited
// bandwidth capacity, resulting in the collation download taking a long time.
......@@ -793,26 +742,16 @@ pub fn new_full<RuntimeApi, Executor>(
// this problem. This configuraiton change should preferably not reach any live network, and
// should be removed once the collation protocol is finished.
// Tracking issue: https://github.com/paritytech/polkadot/issues/2283
#[cfg(feature = "real-overseer")]
fn adjust_yamux(cfg: &mut sc_network::config::NetworkConfiguration) {
cfg.yamux_window_size = Some(5 * 1024 * 1024);
}
#[cfg(not(feature = "real-overseer"))]
fn adjust_yamux(_: &mut sc_network::config::NetworkConfiguration) {}
adjust_yamux(&mut config.network);
config.network.yamux_window_size = Some(5 * 1024 * 1024);
config.network.request_response_protocols.push(sc_finality_grandpa_warp_sync::request_response_config_for_chain(
&config, task_manager.spawn_handle(), backend.clone(), import_setup.1.shared_authority_set().clone(),
));
#[cfg(feature = "real-overseer")]
fn register_request_response(config: &mut sc_network::config::NetworkConfiguration) -> RequestMultiplexer {
let request_multiplexer = {
let (multiplexer, configs) = RequestMultiplexer::new();
config.request_response_protocols.extend(configs);
config.network.request_response_protocols.extend(configs);
multiplexer
}
#[cfg(not(feature = "real-overseer"))]
fn register_request_response(_: &mut sc_network::config::NetworkConfiguration) {}
let request_multiplexer = register_request_response(&mut config.network);
};
let (network, network_status_sinks, system_rpc_tx, network_starter) =
service::build_network(service::BuildNetworkParams {
......@@ -825,43 +764,17 @@ pub fn new_full<RuntimeApi, Executor>(
block_announce_validator_builder: None,
})?;
// See above. We have added a dummy collation set with the intent of printing an error if one
// tries to connect a collator to a node that isn't compiled with `--features real-overseer`.
#[cfg(not(feature = "real-overseer"))]
task_manager.spawn_handle().spawn("dummy-collation-handler", {
let mut network_events = network.event_stream("dummy-collation-handler");
async move {
use futures::prelude::*;
while let Some(ev) = network_events.next().await {
if let sc_network::Event::NotificationStreamOpened { protocol, .. } = ev {
if protocol == "/polkadot/collation/1" {
tracing::warn!(
"Incoming collator on a node with parachains disabled. This warning \
is harmless and is here to warn developers that they might have \
accidentally compiled their node without the `real-overseer` feature \
enabled."
);
}
}
}
}
});
if config.offchain_worker.enabled {
let _ = service::build_offchain_workers(
&config, task_manager.spawn_handle(), client.clone(), network.clone(),
);
}
#[cfg(feature = "real-overseer")]
let parachains_db = crate::parachains_db::open_creating(
config.database.path().ok_or(Error::DatabasePathRequired)?.into(),
crate::parachains_db::CacheSizes::default(),
)?;
#[cfg(not(feature = "real-overseer"))]
let parachains_db = ();
let availability_config = AvailabilityConfig {
col_data: crate::parachains_db::REAL_COLUMNS.col_availability_data,
col_meta: crate::parachains_db::REAL_COLUMNS.col_availability_meta,
......@@ -1064,7 +977,6 @@ pub fn new_full<RuntimeApi, Executor>(
// given delay.
let builder = grandpa::VotingRulesBuilder::default();
#[cfg(feature = "real-overseer")]
let builder = if let Some(ref overseer) = overseer_handler {
builder.add(grandpa_support::ApprovalCheckingVotingRule::new(
overseer.clone(),
......
......@@ -13,7 +13,7 @@
//! A RocksDB instance for storing parachain data; availability data, and approvals.
#[cfg(feature = "real-overseer")]
#[cfg(feature = "full-node")]
use {
std::io,
std::path::PathBuf,
......@@ -25,7 +25,6 @@ use {
mod upgrade;
mod columns {
#[cfg(feature = "real-overseer")]
pub const NUM_COLUMNS: u32 = 3;
......@@ -73,13 +72,13 @@ impl Default for CacheSizes {