From 57038b2e469a221d005bfe83c4bbfcf77344ca13 Mon Sep 17 00:00:00 2001
From: Robert Habermeier <rphmeier@gmail.com>
Date: Thu, 8 Apr 2021 20:24:06 +0200
Subject: [PATCH] =?UTF-8?q?Remove=20real-overseer=20=F0=9F=8E=89=20(#2834)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* remove real-overseer

* overseer: only activate leaves which support parachains

* integrate HeadSupportsParachains into service

* remove unneeded line
---
 polkadot/.gitlab-ci.yml                       |   2 -
 polkadot/Cargo.lock                           |   1 +
 polkadot/Cargo.toml                           |   1 -
 polkadot/cli/Cargo.toml                       |   1 -
 polkadot/node/overseer/Cargo.toml             |   1 +
 .../node/overseer/examples/minimal-example.rs |   9 +-
 polkadot/node/overseer/src/lib.rs             |  97 ++++++++++++----
 polkadot/node/service/Cargo.toml              |  34 +++---
 polkadot/node/service/src/grandpa_support.rs  |   8 +-
 polkadot/node/service/src/lib.rs              | 106 ++----------------
 .../node/service/src/parachains_db/mod.rs     |   7 +-
 .../node/service/src/parachains_db/upgrade.rs |   2 +-
 .../node/subsystem-test-helpers/src/lib.rs    |   9 +-
 .../test-parachains/adder/collator/Cargo.toml |   3 -
 .../test-parachains/adder/collator/README.md  |   6 +-
 .../adder/collator/tests/integration.rs       |   2 -
 polkadot/scripts/adder-collator.sh            |   4 +-
 polkadot/scripts/gitlab/test_linux_stable.sh  |   5 +-
 polkadot/scripts/two-node-local-net.sh        |   2 +-
 19 files changed, 135 insertions(+), 165 deletions(-)

diff --git a/polkadot/.gitlab-ci.yml b/polkadot/.gitlab-ci.yml
index 23d086308f6..5dbda40e521 100644
--- a/polkadot/.gitlab-ci.yml
+++ b/polkadot/.gitlab-ci.yml
@@ -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:
diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock
index b5f9f3c923d..ea0e92648c1 100644
--- a/polkadot/Cargo.lock
+++ b/polkadot/Cargo.lock
@@ -6059,6 +6059,7 @@ dependencies = [
  "polkadot-node-subsystem-util",
  "polkadot-primitives",
  "sc-client-api",
+ "sp-api",
  "sp-core",
  "tracing",
 ]
diff --git a/polkadot/Cargo.toml b/polkadot/Cargo.toml
index 0f02019ca2d..17ba7ebea45 100644
--- a/polkadot/Cargo.toml
+++ b/polkadot/Cargo.toml
@@ -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`
diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml
index 3bc15e0bdc9..544e71d591a 100644
--- a/polkadot/cli/Cargo.toml
+++ b/polkadot/cli/Cargo.toml
@@ -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" ]
diff --git a/polkadot/node/overseer/Cargo.toml b/polkadot/node/overseer/Cargo.toml
index 1c0401a5361..674c22eb806 100644
--- a/polkadot/node/overseer/Cargo.toml
+++ b/polkadot/node/overseer/Cargo.toml
@@ -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" }
diff --git a/polkadot/node/overseer/examples/minimal-example.rs b/polkadot/node/overseer/examples/minimal-example.rs
index 2ebf2a07daa..830c65e89d5 100644
--- a/polkadot/node/overseer/examples/minimal-example.rs
+++ b/polkadot/node/overseer/examples/minimal-example.rs
@@ -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();
diff --git a/polkadot/node/overseer/src/lib.rs b/polkadot/node/overseer/src/lib.rs
index fe372c775de..57af4fb6768 100644
--- a/polkadot/node/overseer/src/lib.rs
+++ b/polkadot/node/overseer/src/lib.rs
@@ -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();
diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml
index 0fd65c23f3a..085ad84c287 100644
--- a/polkadot/node/service/Cargo.toml
+++ b/polkadot/node/service/Cargo.toml
@@ -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",
 ]
diff --git a/polkadot/node/service/src/grandpa_support.rs b/polkadot/node/service/src/grandpa_support.rs
index 27157236880..b6a734b08ec 100644
--- a/polkadot/node/service/src/grandpa_support.rs
+++ b/polkadot/node/service/src/grandpa_support.rs
@@ -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>
 {
diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs
index ac3c53b744d..f12f9a77bf5 100644
--- a/polkadot/node/service/src/lib.rs
+++ b/polkadot/node/service/src/lib.rs
@@ -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(),
diff --git a/polkadot/node/service/src/parachains_db/mod.rs b/polkadot/node/service/src/parachains_db/mod.rs
index dbaae5c825d..8853a6aebad 100644
--- a/polkadot/node/service/src/parachains_db/mod.rs
+++ b/polkadot/node/service/src/parachains_db/mod.rs
@@ -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 {
 	}
 }
 
-#[cfg(feature = "real-overseer")]
+#[cfg(feature = "full-node")]
 fn other_io_error(err: String) -> io::Error {
 	io::Error::new(io::ErrorKind::Other, err)
 }
 
 /// Open the database on disk, creating it if it doesn't exist.
-#[cfg(feature = "real-overseer")]
+#[cfg(feature = "full-node")]
 pub fn open_creating(
 	root: PathBuf,
 	cache_sizes: CacheSizes,
diff --git a/polkadot/node/service/src/parachains_db/upgrade.rs b/polkadot/node/service/src/parachains_db/upgrade.rs
index dbfa0213d3b..6cf47b80cea 100644
--- a/polkadot/node/service/src/parachains_db/upgrade.rs
+++ b/polkadot/node/service/src/parachains_db/upgrade.rs
@@ -14,7 +14,7 @@
 //! Migration code for the parachain's DB.
 
 
-#![cfg(feature = "real-overseer")]
+#![cfg(feature = "full-node")]
 
 use std::fs;
 use std::io;
diff --git a/polkadot/node/subsystem-test-helpers/src/lib.rs b/polkadot/node/subsystem-test-helpers/src/lib.rs
index 955bc22ccc6..44d2d922888 100644
--- a/polkadot/node/subsystem-test-helpers/src/lib.rs
+++ b/polkadot/node/subsystem-test-helpers/src/lib.rs
@@ -360,9 +360,15 @@ impl<C: SubsystemContext<Message = Msg>, Msg: Send + 'static> Subsystem<C> for F
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use polkadot_overseer::{Overseer, AllSubsystems};
+	use polkadot_overseer::{Overseer, HeadSupportsParachains, AllSubsystems};
 	use futures::executor::block_on;
 	use polkadot_node_subsystem::messages::CandidateSelectionMessage;
+	use polkadot_primitives::v1::Hash;
+
+	struct AlwaysSupportsParachains;
+	impl HeadSupportsParachains for AlwaysSupportsParachains {
+		fn head_supports_parachains(&self, _head: &Hash) -> bool { true }
+	}
 
 	#[test]
 	fn forward_subsystem_works() {
@@ -373,6 +379,7 @@ mod tests {
 			Vec::new(),
 			all_subsystems,
 			None,
+			AlwaysSupportsParachains,
 			spawner.clone(),
 		).unwrap();
 
diff --git a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml
index 445d175af54..dfe303f2dcb 100644
--- a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml
+++ b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml
@@ -37,6 +37,3 @@ sc-service = { git = "https://github.com/paritytech/substrate", branch = "master
 sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
 
 tokio = { version = "0.2", features = ["macros"] }
-
-[features]
-real-overseer = [ "polkadot-service/real-overseer" ]
diff --git a/polkadot/parachain/test-parachains/adder/collator/README.md b/polkadot/parachain/test-parachains/adder/collator/README.md
index e3181a84dd5..be5922b9f95 100644
--- a/polkadot/parachain/test-parachains/adder/collator/README.md
+++ b/polkadot/parachain/test-parachains/adder/collator/README.md
@@ -2,13 +2,13 @@
 
 First start two validators that will run for the relay chain:
 ```sh
-cargo run --features=real-overseer --release -- -d alice --chain rococo-local --validator --alice --port 50551
-cargo run --features=real-overseer --release -- -d bob --chain rococo-local --validator --bob --port 50552
+cargo run --release -- -d alice --chain rococo-local --validator --alice --port 50551
+cargo run --release -- -d bob --chain rococo-local --validator --bob --port 50552
 ```
 
 Next start the collator that will collate for the adder parachain:
 ```sh
-cargo run --features=real-overseer --release -p test-parachain-adder-collator -- --tmp --chain rococo-local --port 50553
+cargo run --release -p test-parachain-adder-collator -- --tmp --chain rococo-local --port 50553
 ```
 
 The last step is to register the parachain using polkadot-js. The parachain id is
diff --git a/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs b/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs
index 00513027776..e0f6d2d28ad 100644
--- a/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs
+++ b/polkadot/parachain/test-parachains/adder/collator/tests/integration.rs
@@ -17,9 +17,7 @@
 //! Integration test that ensures that we can build and include parachain
 //! blocks of the adder parachain.
 
-// If this test is failing, make sure to run all tests with the `real-overseer` feature being enabled.
 #[substrate_test_utils::test]
-#[cfg(feature = "real-overseer")]
 async fn collating_using_adder_collator(task_executor: sc_service::TaskExecutor) {
 	use sp_keyring::AccountKeyring::*;
 	use futures::join;
diff --git a/polkadot/scripts/adder-collator.sh b/polkadot/scripts/adder-collator.sh
index ca493eb0a46..8f98aba24c6 100755
--- a/polkadot/scripts/adder-collator.sh
+++ b/polkadot/scripts/adder-collator.sh
@@ -31,11 +31,11 @@ adder_collator="target/release/adder-collator"
 
 # ensure the polkadot binary exists and is up to date
 if [ ! -x "$polkadot" ] || [ "$polkadot" -ot "$last_modified_rust_file" ]; then
-  cargo build --release --features real-overseer
+  cargo build --release
 fi
 # likewise for the adder collator
 if [ ! -x "$adder_collator" ] || [ "$adder_collator" -ot "$last_modified_rust_file" ]; then
-  cargo build --release --features real-overseer -p test-parachain-adder-collator
+  cargo build --release -p test-parachain-adder-collator
 fi
 
 genesis="$(mktemp --directory)"
diff --git a/polkadot/scripts/gitlab/test_linux_stable.sh b/polkadot/scripts/gitlab/test_linux_stable.sh
index 05e20226765..82467e28739 100755
--- a/polkadot/scripts/gitlab/test_linux_stable.sh
+++ b/polkadot/scripts/gitlab/test_linux_stable.sh
@@ -4,7 +4,4 @@ set -e
 #shellcheck source=../common/lib.sh
 source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/../common/lib.sh"
 
-time cargo test --all --release --verbose --locked --features=runtime-benchmarks --features=real-overseer
-
-cd parachain/test-parachains/adder/collator/
-time cargo test --release --verbose --locked --features=real-overseer
+time cargo test --all --release --verbose --locked --features=runtime-benchmarks
diff --git a/polkadot/scripts/two-node-local-net.sh b/polkadot/scripts/two-node-local-net.sh
index 16db4304f15..4e3291b015a 100755
--- a/polkadot/scripts/two-node-local-net.sh
+++ b/polkadot/scripts/two-node-local-net.sh
@@ -27,7 +27,7 @@ polkadot="target/release/polkadot"
 
 # ensure the polkadot binary exists and is up to date
 if [ ! -x "$polkadot" ] || [ "$polkadot" -ot "$last_modified_rust_file" ]; then
-  cargo build --release --features real-overseer
+  cargo build --release
 fi
 
 # setup variables
-- 
GitLab