From de05bec4d63c46f0d85672f5f4dd93999f046e24 Mon Sep 17 00:00:00 2001
From: Andronik Ordian <write@reusable.software>
Date: Tue, 29 Sep 2020 13:42:20 +0200
Subject: [PATCH] move Metrics to utils (#1765)

---
 polkadot/Cargo.lock                           |  7 ++-
 polkadot/node/collation-generation/src/lib.rs |  4 +-
 polkadot/node/core/av-store/Cargo.toml        | 15 +++---
 polkadot/node/core/av-store/src/lib.rs        |  4 +-
 polkadot/node/core/backing/src/lib.rs         |  2 +-
 .../node/core/bitfield-signing/src/lib.rs     |  4 +-
 .../node/core/candidate-selection/src/lib.rs  |  4 +-
 .../node/core/candidate-validation/Cargo.toml |  6 ++-
 .../node/core/candidate-validation/src/lib.rs |  4 +-
 polkadot/node/core/chain-api/Cargo.toml       |  1 +
 polkadot/node/core/chain-api/src/lib.rs       |  4 +-
 polkadot/node/core/provisioner/src/lib.rs     |  2 +-
 polkadot/node/core/runtime-api/Cargo.toml     |  1 +
 polkadot/node/core/runtime-api/src/lib.rs     | 12 ++---
 .../availability-distribution/src/lib.rs      |  2 -
 .../network/bitfield-distribution/src/lib.rs  |  2 -
 polkadot/node/network/bridge/src/lib.rs       |  2 -
 .../collator-protocol/src/collator_side.rs    |  2 +-
 .../node/network/collator-protocol/src/lib.rs |  9 ++--
 .../collator-protocol/src/validator_side.rs   |  6 ++-
 .../node/network/pov-distribution/src/lib.rs  |  2 -
 .../network/statement-distribution/src/lib.rs |  2 -
 polkadot/node/overseer/Cargo.toml             |  1 +
 .../node/overseer/examples/minimal-example.rs |  4 --
 polkadot/node/overseer/src/lib.rs             | 16 +------
 polkadot/node/subsystem-util/Cargo.toml       |  9 ++--
 polkadot/node/subsystem-util/src/lib.rs       | 47 ++++++++++++++++---
 polkadot/node/subsystem/Cargo.toml            |  1 -
 polkadot/node/subsystem/src/lib.rs            | 44 -----------------
 29 files changed, 99 insertions(+), 120 deletions(-)

diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock
index 24d70ac96ba..d79c9e2ec6d 100644
--- a/polkadot/Cargo.lock
+++ b/polkadot/Cargo.lock
@@ -4843,6 +4843,7 @@ dependencies = [
  "polkadot-erasure-coding",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-test-helpers",
+ "polkadot-node-subsystem-util",
  "polkadot-overseer",
  "polkadot-primitives",
  "sp-core",
@@ -4913,6 +4914,7 @@ dependencies = [
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-test-helpers",
+ "polkadot-node-subsystem-util",
  "polkadot-parachain",
  "polkadot-primitives",
  "sp-blockchain",
@@ -4928,6 +4930,7 @@ dependencies = [
  "maplit",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-test-helpers",
+ "polkadot-node-subsystem-util",
  "polkadot-primitives",
  "sp-blockchain",
  "sp-core",
@@ -4983,6 +4986,7 @@ dependencies = [
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
  "polkadot-node-subsystem-test-helpers",
+ "polkadot-node-subsystem-util",
  "polkadot-primitives",
  "sp-api",
  "sp-blockchain",
@@ -5034,7 +5038,6 @@ dependencies = [
  "sc-network",
  "smallvec 1.4.2",
  "sp-core",
- "substrate-prometheus-endpoint",
 ]
 
 [[package]]
@@ -5083,6 +5086,7 @@ dependencies = [
  "smallvec 1.4.2",
  "sp-core",
  "streamunordered",
+ "substrate-prometheus-endpoint",
 ]
 
 [[package]]
@@ -5098,6 +5102,7 @@ dependencies = [
  "polkadot-node-network-protocol",
  "polkadot-node-primitives",
  "polkadot-node-subsystem",
+ "polkadot-node-subsystem-util",
  "polkadot-primitives",
  "sc-client-api",
  "sp-core",
diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs
index ce671324f1d..a5ee4bc56d9 100644
--- a/polkadot/node/collation-generation/src/lib.rs
+++ b/polkadot/node/collation-generation/src/lib.rs
@@ -30,11 +30,11 @@ use polkadot_node_primitives::CollationGenerationConfig;
 use polkadot_node_subsystem::{
 	messages::{AllMessages, CollationGenerationMessage, CollatorProtocolMessage},
 	FromOverseer, SpawnedSubsystem, Subsystem, SubsystemContext, SubsystemResult,
-	metrics::{self, prometheus},
 };
 use polkadot_node_subsystem_util::{
 	request_availability_cores_ctx, request_full_validation_data_ctx,
 	request_validators_ctx,
+	metrics::{self, prometheus},
 };
 use polkadot_primitives::v1::{
 	collator_signature_payload, AvailableData, CandidateCommitments,
@@ -164,8 +164,6 @@ impl<Context> Subsystem<Context> for CollationGenerationSubsystem
 where
 	Context: SubsystemContext<Message = CollationGenerationMessage>,
 {
-	type Metrics = Metrics;
-
 	fn start(self, ctx: Context) -> SpawnedSubsystem {
 		let future = Box::pin(self.run(ctx));
 
diff --git a/polkadot/node/core/av-store/Cargo.toml b/polkadot/node/core/av-store/Cargo.toml
index f457b7edaaa..f1a2c5ade2e 100644
--- a/polkadot/node/core/av-store/Cargo.toml
+++ b/polkadot/node/core/av-store/Cargo.toml
@@ -5,16 +5,19 @@ authors = ["Parity Technologies <admin@parity.io>"]
 edition = "2018"
 
 [dependencies]
+derive_more = "0.99.9"
 futures = "0.3.5"
-polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../../subsystem" }
-polkadot-overseer = { path = "../../overseer" }
-polkadot-primitives = { path = "../../../primitives" }
-erasure = { package = "polkadot-erasure-coding", path = "../../../erasure-coding" }
+log = "0.4.8"
+
 kvdb = "0.7.0"
 kvdb-rocksdb = "0.9.1"
 codec = { package = "parity-scale-codec", version = "1.3.1", features = ["derive"] }
-log = "0.4.8"
-derive_more = "0.99.9"
+
+erasure = { package = "polkadot-erasure-coding", path = "../../../erasure-coding" }
+polkadot-overseer = { path = "../../overseer" }
+polkadot-primitives = { path = "../../../primitives" }
+polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../../subsystem" }
+polkadot-node-subsystem-util = { path = "../../subsystem-util" }
 
 [dev-dependencies]
 sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
diff --git a/polkadot/node/core/av-store/src/lib.rs b/polkadot/node/core/av-store/src/lib.rs
index 5837377dd5f..e4eb7358418 100644
--- a/polkadot/node/core/av-store/src/lib.rs
+++ b/polkadot/node/core/av-store/src/lib.rs
@@ -34,6 +34,8 @@ use polkadot_primitives::v1::{
 };
 use polkadot_subsystem::{
 	FromOverseer, SubsystemError, Subsystem, SubsystemContext, SpawnedSubsystem,
+};
+use polkadot_node_subsystem_util::{
 	metrics::{self, prometheus},
 };
 use polkadot_subsystem::messages::AvailabilityStoreMessage;
@@ -276,8 +278,6 @@ impl<Context> Subsystem<Context> for AvailabilityStoreSubsystem
 	where
 		Context: SubsystemContext<Message=AvailabilityStoreMessage>,
 {
-	type Metrics = Metrics;
-
 	fn start(self, ctx: Context) -> SpawnedSubsystem {
 		let future = Box::pin(async move {
 			if let Err(e) = run(self, ctx).await {
diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs
index 7e6e64ee47d..2397f5245a2 100644
--- a/polkadot/node/core/backing/src/lib.rs
+++ b/polkadot/node/core/backing/src/lib.rs
@@ -45,7 +45,6 @@ use polkadot_subsystem::{
 		ProvisionerMessage, RuntimeApiMessage, StatementDistributionMessage, ValidationFailed,
 		RuntimeApiRequest,
 	},
-	metrics::{self, prometheus},
 };
 use polkadot_node_subsystem_util::{
 	self as util,
@@ -55,6 +54,7 @@ use polkadot_node_subsystem_util::{
 	request_from_runtime,
 	Validator,
 	delegated_subsystem,
+	metrics::{self, prometheus},
 };
 use statement_table::{
 	generic::AttestedCandidate as TableAttestedCandidate,
diff --git a/polkadot/node/core/bitfield-signing/src/lib.rs b/polkadot/node/core/bitfield-signing/src/lib.rs
index 66badf3d18c..224432a7b64 100644
--- a/polkadot/node/core/bitfield-signing/src/lib.rs
+++ b/polkadot/node/core/bitfield-signing/src/lib.rs
@@ -29,10 +29,10 @@ use polkadot_node_subsystem::{
 		BitfieldSigningMessage, CandidateBackingMessage, RuntimeApiMessage,
 	},
 	errors::RuntimeApiError,
-	metrics::{self, prometheus},
 };
 use polkadot_node_subsystem_util::{
-	self as util, JobManager, JobTrait, ToJobTrait, Validator
+	self as util, JobManager, JobTrait, ToJobTrait, Validator,
+	metrics::{self, prometheus},
 };
 use polkadot_primitives::v1::{AvailabilityBitfield, CoreState, Hash, ValidatorIndex};
 use std::{convert::TryFrom, pin::Pin, time::Duration};
diff --git a/polkadot/node/core/candidate-selection/src/lib.rs b/polkadot/node/core/candidate-selection/src/lib.rs
index 7d31c0318e2..004df663916 100644
--- a/polkadot/node/core/candidate-selection/src/lib.rs
+++ b/polkadot/node/core/candidate-selection/src/lib.rs
@@ -30,9 +30,11 @@ use polkadot_node_subsystem::{
 		AllMessages, CandidateBackingMessage, CandidateSelectionMessage,
 		CandidateValidationMessage, CollatorProtocolMessage,
 	},
+};
+use polkadot_node_subsystem_util::{
+	self as util, delegated_subsystem, JobTrait, ToJobTrait,
 	metrics::{self, prometheus},
 };
-use polkadot_node_subsystem_util::{self as util, delegated_subsystem, JobTrait, ToJobTrait};
 use polkadot_primitives::v1::{
 	CandidateDescriptor, CandidateReceipt, CollatorId, Hash, Id as ParaId, PoV,
 };
diff --git a/polkadot/node/core/candidate-validation/Cargo.toml b/polkadot/node/core/candidate-validation/Cargo.toml
index 8f1b7a0fa0f..77f9712cb8c 100644
--- a/polkadot/node/core/candidate-validation/Cargo.toml
+++ b/polkadot/node/core/candidate-validation/Cargo.toml
@@ -5,7 +5,10 @@ authors = ["Parity Technologies <admin@parity.io>"]
 edition = "2018"
 
 [dependencies]
+derive_more = "0.99.9"
 futures = "0.3.5"
+log = "0.4.8"
+
 sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
 sp-core = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "master" }
 parity-scale-codec = { version = "1.3.0", default-features = false, features = ["bit-vec", "derive"] }
@@ -14,8 +17,7 @@ polkadot-primitives = { path = "../../../primitives" }
 polkadot-parachain = { path = "../../../parachain" }
 polkadot-node-primitives = { path = "../../primitives" }
 polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../../subsystem" }
-derive_more = "0.99.9"
-log = "0.4.8"
+polkadot-node-subsystem-util = { path = "../../subsystem-util" }
 
 [dev-dependencies]
 sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs
index fa61325b9c4..273df04c4dd 100644
--- a/polkadot/node/core/candidate-validation/src/lib.rs
+++ b/polkadot/node/core/candidate-validation/src/lib.rs
@@ -27,6 +27,8 @@ use polkadot_subsystem::{
 		AllMessages, CandidateValidationMessage, RuntimeApiMessage,
 		ValidationFailed, RuntimeApiRequest,
 	},
+};
+use polkadot_node_subsystem_util::{
 	metrics::{self, prometheus},
 };
 use polkadot_subsystem::errors::RuntimeApiError;
@@ -113,8 +115,6 @@ impl<S, C> Subsystem<C> for CandidateValidationSubsystem<S> where
 	C: SubsystemContext<Message = CandidateValidationMessage>,
 	S: SpawnNamed + Clone + 'static,
 {
-	type Metrics = Metrics;
-
 	fn start(self, ctx: C) -> SpawnedSubsystem {
 		SpawnedSubsystem {
 			name: "candidate-validation-subsystem",
diff --git a/polkadot/node/core/chain-api/Cargo.toml b/polkadot/node/core/chain-api/Cargo.toml
index d626a0d9329..23f6ed4dede 100644
--- a/polkadot/node/core/chain-api/Cargo.toml
+++ b/polkadot/node/core/chain-api/Cargo.toml
@@ -9,6 +9,7 @@ futures = { version = "0.3.5" }
 sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
 polkadot-primitives = { path = "../../../primitives" }
 polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../../subsystem" }
+polkadot-node-subsystem-util = { path = "../../subsystem-util" }
 
 [dev-dependencies]
 futures = { version = "0.3.5", features = ["thread-pool"] }
diff --git a/polkadot/node/core/chain-api/src/lib.rs b/polkadot/node/core/chain-api/src/lib.rs
index d3be1c4bf48..9a272e7d1d8 100644
--- a/polkadot/node/core/chain-api/src/lib.rs
+++ b/polkadot/node/core/chain-api/src/lib.rs
@@ -30,6 +30,8 @@ use polkadot_subsystem::{
 	FromOverseer, OverseerSignal,
 	SpawnedSubsystem, Subsystem, SubsystemResult, SubsystemContext,
 	messages::ChainApiMessage,
+};
+use polkadot_node_subsystem_util::{
 	metrics::{self, prometheus},
 };
 use polkadot_primitives::v1::{Block, BlockId};
@@ -57,8 +59,6 @@ impl<Client, Context> Subsystem<Context> for ChainApiSubsystem<Client> where
 	Client: HeaderBackend<Block> + 'static,
 	Context: SubsystemContext<Message = ChainApiMessage>
 {
-	type Metrics = Metrics;
-
 	fn start(self, ctx: Context) -> SpawnedSubsystem {
 		SpawnedSubsystem {
 			future: run(ctx, self).map(|_| ()).boxed(),
diff --git a/polkadot/node/core/provisioner/src/lib.rs b/polkadot/node/core/provisioner/src/lib.rs
index 9449c99dadc..6579b95d912 100644
--- a/polkadot/node/core/provisioner/src/lib.rs
+++ b/polkadot/node/core/provisioner/src/lib.rs
@@ -30,12 +30,12 @@ use polkadot_node_subsystem::{
 		AllMessages, ChainApiMessage, ProvisionableData, ProvisionerInherentData,
 		ProvisionerMessage, RuntimeApiMessage,
 	},
-	metrics::{self, prometheus},
 };
 use polkadot_node_subsystem_util::{
 	self as util,
 	delegated_subsystem,
 	request_availability_cores, request_persisted_validation_data, JobTrait, ToJobTrait,
+	metrics::{self, prometheus},
 };
 use polkadot_primitives::v1::{
 	BackedCandidate, BlockNumber, CoreState, Hash, OccupiedCoreAssumption,
diff --git a/polkadot/node/core/runtime-api/Cargo.toml b/polkadot/node/core/runtime-api/Cargo.toml
index 229366627a3..0a3a5015a4b 100644
--- a/polkadot/node/core/runtime-api/Cargo.toml
+++ b/polkadot/node/core/runtime-api/Cargo.toml
@@ -12,6 +12,7 @@ sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "mas
 polkadot-primitives = { path = "../../../primitives" }
 polkadot-node-primitives = { path = "../../primitives" }
 polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../../subsystem" }
+polkadot-node-subsystem-util = { path = "../../subsystem-util" }
 
 [dev-dependencies]
 sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
diff --git a/polkadot/node/core/runtime-api/src/lib.rs b/polkadot/node/core/runtime-api/src/lib.rs
index 3c05b71dd70..59a6684ab9f 100644
--- a/polkadot/node/core/runtime-api/src/lib.rs
+++ b/polkadot/node/core/runtime-api/src/lib.rs
@@ -22,12 +22,14 @@
 use polkadot_subsystem::{
 	Subsystem, SpawnedSubsystem, SubsystemResult, SubsystemContext,
 	FromOverseer, OverseerSignal,
-	metrics::{self, prometheus},
+	messages::{
+		RuntimeApiMessage, RuntimeApiRequest as Request,
+	},
+	errors::RuntimeApiError,
 };
-use polkadot_subsystem::messages::{
-	RuntimeApiMessage, RuntimeApiRequest as Request,
+use polkadot_node_subsystem_util::{
+	metrics::{self, prometheus},
 };
-use polkadot_subsystem::errors::RuntimeApiError;
 use polkadot_primitives::v1::{Block, BlockId, Hash, ParachainHost};
 
 use sp_api::{ProvideRuntimeApi};
@@ -52,8 +54,6 @@ impl<Client, Context> Subsystem<Context> for RuntimeApiSubsystem<Client> where
 	Client::Api: ParachainHost<Block>,
 	Context: SubsystemContext<Message = RuntimeApiMessage>
 {
-	type Metrics = Metrics;
-
 	fn start(self, ctx: Context) -> SpawnedSubsystem {
 		SpawnedSubsystem {
 			future: run(ctx, self).map(|_| ()).boxed(),
diff --git a/polkadot/node/network/availability-distribution/src/lib.rs b/polkadot/node/network/availability-distribution/src/lib.rs
index 32b61f5817f..2a5a0860657 100644
--- a/polkadot/node/network/availability-distribution/src/lib.rs
+++ b/polkadot/node/network/availability-distribution/src/lib.rs
@@ -756,8 +756,6 @@ impl<Context> Subsystem<Context> for AvailabilityDistributionSubsystem
 where
 	Context: SubsystemContext<Message = AvailabilityDistributionMessage> + Sync + Send,
 {
-	type Metrics = ();
-
 	fn start(self, ctx: Context) -> SpawnedSubsystem {
 		SpawnedSubsystem {
 			name: "availability-distribution-subsystem",
diff --git a/polkadot/node/network/bitfield-distribution/src/lib.rs b/polkadot/node/network/bitfield-distribution/src/lib.rs
index 9b0e5c747de..7b05b88b178 100644
--- a/polkadot/node/network/bitfield-distribution/src/lib.rs
+++ b/polkadot/node/network/bitfield-distribution/src/lib.rs
@@ -561,8 +561,6 @@ impl<C> Subsystem<C> for BitfieldDistribution
 where
 	C: SubsystemContext<Message = BitfieldDistributionMessage> + Sync + Send,
 {
-	type Metrics = ();
-
 	fn start(self, ctx: C) -> SpawnedSubsystem {
 		SpawnedSubsystem {
 			name: "bitfield-distribution-subsystem",
diff --git a/polkadot/node/network/bridge/src/lib.rs b/polkadot/node/network/bridge/src/lib.rs
index b531d597743..0ed6e11ce3b 100644
--- a/polkadot/node/network/bridge/src/lib.rs
+++ b/polkadot/node/network/bridge/src/lib.rs
@@ -205,8 +205,6 @@ impl<Net, Context> Subsystem<Context> for NetworkBridge<Net>
 		Net: Network,
 		Context: SubsystemContext<Message=NetworkBridgeMessage>,
 {
-	type Metrics = ();
-
 	fn start(self, ctx: Context) -> SpawnedSubsystem {
 		// Swallow error because failure is fatal to the node and we log with more precision
 		// within `run_network`.
diff --git a/polkadot/node/network/collator-protocol/src/collator_side.rs b/polkadot/node/network/collator-protocol/src/collator_side.rs
index ba00796742b..aefca693b4d 100644
--- a/polkadot/node/network/collator-protocol/src/collator_side.rs
+++ b/polkadot/node/network/collator-protocol/src/collator_side.rs
@@ -29,7 +29,6 @@ use polkadot_subsystem::{
 		AllMessages, CollatorProtocolMessage, RuntimeApiMessage, RuntimeApiRequest,
 		NetworkBridgeMessage,
 	},
-	metrics::{self, prometheus},
 };
 use polkadot_node_network_protocol::{
 	v1 as protocol_v1, View, PeerId, PeerSet, NetworkBridgeEvent, RequestId,
@@ -37,6 +36,7 @@ use polkadot_node_network_protocol::{
 use polkadot_node_subsystem_util::{
 	request_validators_ctx,
 	request_validator_groups_ctx,
+	metrics::{self, prometheus},
 };
 
 #[derive(Clone, Default)]
diff --git a/polkadot/node/network/collator-protocol/src/lib.rs b/polkadot/node/network/collator-protocol/src/lib.rs
index aa261fedf15..647eb1ea46b 100644
--- a/polkadot/node/network/collator-protocol/src/lib.rs
+++ b/polkadot/node/network/collator-protocol/src/lib.rs
@@ -26,7 +26,6 @@ use log::trace;
 use polkadot_subsystem::{
 	Subsystem, SubsystemContext, SubsystemError, SpawnedSubsystem,
 	errors::RuntimeApiError,
-	metrics::{self, prometheus},
 	messages::{
 		AllMessages, CollatorProtocolMessage, NetworkBridgeMessage,
 	},
@@ -35,7 +34,10 @@ use polkadot_node_network_protocol::{
 	PeerId, ReputationChange as Rep,
 };
 use polkadot_primitives::v1::CollatorId;
-use polkadot_node_subsystem_util as util;
+use polkadot_node_subsystem_util::{
+	self as util,
+	metrics::{self, prometheus},
+};
 
 mod collator_side;
 mod validator_side;
@@ -109,9 +111,6 @@ impl<Context> Subsystem<Context> for CollatorProtocolSubsystem
 where
 	Context: SubsystemContext<Message = CollatorProtocolMessage> + Sync + Send,
 {
-	// The actual `Metrics` type depends on whether we're on the collator or validator side.
-	type Metrics = ();
-
 	fn start(self, ctx: Context) -> SpawnedSubsystem {
 		SpawnedSubsystem {
 			name: "collator-protocol-subsystem",
diff --git a/polkadot/node/network/collator-protocol/src/validator_side.rs b/polkadot/node/network/collator-protocol/src/validator_side.rs
index 39466ad66ac..70ea30331ee 100644
--- a/polkadot/node/network/collator-protocol/src/validator_side.rs
+++ b/polkadot/node/network/collator-protocol/src/validator_side.rs
@@ -34,13 +34,15 @@ use polkadot_subsystem::{
 	messages::{
 		AllMessages, CandidateSelectionMessage, CollatorProtocolMessage, NetworkBridgeMessage,
 	},
-	metrics::{self, prometheus},
 };
 use polkadot_node_network_protocol::{
 	v1 as protocol_v1, View, PeerId, ReputationChange as Rep, RequestId,
 	NetworkBridgeEvent,
 };
-use polkadot_node_subsystem_util::TimeoutExt;
+use polkadot_node_subsystem_util::{
+	TimeoutExt as _,
+	metrics::{self, prometheus},
+};
 
 use super::{modify_reputation, TARGET, Result};
 
diff --git a/polkadot/node/network/pov-distribution/src/lib.rs b/polkadot/node/network/pov-distribution/src/lib.rs
index 552981244d2..994090c0d58 100644
--- a/polkadot/node/network/pov-distribution/src/lib.rs
+++ b/polkadot/node/network/pov-distribution/src/lib.rs
@@ -51,8 +51,6 @@ pub struct PoVDistribution;
 impl<C> Subsystem<C> for PoVDistribution
 	where C: SubsystemContext<Message = PoVDistributionMessage>
 {
-	type Metrics = ();
-
 	fn start(self, ctx: C) -> SpawnedSubsystem {
 		// Swallow error because failure is fatal to the node and we log with more precision
 		// within `run`.
diff --git a/polkadot/node/network/statement-distribution/src/lib.rs b/polkadot/node/network/statement-distribution/src/lib.rs
index d997f5a9005..d16a58d08b7 100644
--- a/polkadot/node/network/statement-distribution/src/lib.rs
+++ b/polkadot/node/network/statement-distribution/src/lib.rs
@@ -65,8 +65,6 @@ pub struct StatementDistribution;
 impl<C> Subsystem<C> for StatementDistribution
 	where C: SubsystemContext<Message=StatementDistributionMessage>
 {
-	type Metrics = ();
-
 	fn start(self, ctx: C) -> SpawnedSubsystem {
 		// Swallow error because failure is fatal to the node and we log with more precision
 		// within `run`.
diff --git a/polkadot/node/overseer/Cargo.toml b/polkadot/node/overseer/Cargo.toml
index e21cb936314..bf0fd778583 100644
--- a/polkadot/node/overseer/Cargo.toml
+++ b/polkadot/node/overseer/Cargo.toml
@@ -12,6 +12,7 @@ streamunordered = "0.5.1"
 polkadot-primitives = { path = "../../primitives" }
 client = { package = "sc-client-api", git = "https://github.com/paritytech/substrate", branch = "master" }
 polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../subsystem" }
+polkadot-node-subsystem-util = { path = "../subsystem-util" }
 polkadot-node-primitives = { package = "polkadot-node-primitives", path = "../primitives" }
 async-trait = "0.1"
 
diff --git a/polkadot/node/overseer/examples/minimal-example.rs b/polkadot/node/overseer/examples/minimal-example.rs
index 4087429e6dc..2b55fa2634c 100644
--- a/polkadot/node/overseer/examples/minimal-example.rs
+++ b/polkadot/node/overseer/examples/minimal-example.rs
@@ -76,8 +76,6 @@ impl Subsystem1 {
 impl<C> Subsystem<C> for Subsystem1
 	where C: SubsystemContext<Message=CandidateBackingMessage>
 {
-	type Metrics = (); // no Prometheus metrics
-
 	fn start(self, ctx: C) -> SpawnedSubsystem {
 		let future = Box::pin(async move {
 			Self::run(ctx).await;
@@ -123,8 +121,6 @@ impl Subsystem2 {
 impl<C> Subsystem<C> for Subsystem2
 	where C: SubsystemContext<Message=CandidateValidationMessage>
 {
-	type Metrics = (); // no Prometheus metrics
-
 	fn start(self, ctx: C) -> SpawnedSubsystem {
 		let future = Box::pin(async move {
 			Self::run(ctx).await;
diff --git a/polkadot/node/overseer/src/lib.rs b/polkadot/node/overseer/src/lib.rs
index 8228682fcdf..4589ee553c9 100644
--- a/polkadot/node/overseer/src/lib.rs
+++ b/polkadot/node/overseer/src/lib.rs
@@ -84,8 +84,8 @@ use polkadot_subsystem::messages::{
 pub use polkadot_subsystem::{
 	Subsystem, SubsystemContext, OverseerSignal, FromOverseer, SubsystemError, SubsystemResult,
 	SpawnedSubsystem, ActiveLeavesUpdate,
-	metrics::{self, prometheus},
 };
+use polkadot_node_subsystem_util::metrics::{self, prometheus};
 use polkadot_node_primitives::SpawnNamed;
 
 
@@ -560,8 +560,6 @@ where
 	/// impl<C> Subsystem<C> for ValidationSubsystem
 	///     where C: SubsystemContext<Message=CandidateValidationMessage>
 	/// {
-	///     type Metrics = ();
-	///
 	///     fn start(
 	///         self,
 	///         mut ctx: C,
@@ -1229,8 +1227,6 @@ mod tests {
 	impl<C> Subsystem<C> for TestSubsystem1
 		where C: SubsystemContext<Message=CandidateValidationMessage>
 	{
-		type Metrics = ();
-
 		fn start(self, mut ctx: C) -> SpawnedSubsystem {
 			let mut sender = self.0;
 			SpawnedSubsystem {
@@ -1259,8 +1255,6 @@ mod tests {
 	impl<C> Subsystem<C> for TestSubsystem2
 		where C: SubsystemContext<Message=CandidateBackingMessage>
 	{
-		type Metrics = ();
-
 		fn start(self, mut ctx: C) -> SpawnedSubsystem {
 			let sender = self.0.clone();
 			SpawnedSubsystem {
@@ -1307,8 +1301,6 @@ mod tests {
 	impl<C> Subsystem<C> for TestSubsystem4
 		where C: SubsystemContext<Message=CandidateBackingMessage>
 	{
-		type Metrics = ();
-
 		fn start(self, mut _ctx: C) -> SpawnedSubsystem {
 			SpawnedSubsystem {
 				name: "test-subsystem-4",
@@ -1513,8 +1505,6 @@ mod tests {
 	impl<C> Subsystem<C> for TestSubsystem5
 		where C: SubsystemContext<Message=CandidateValidationMessage>
 	{
-		type Metrics = ();
-
 		fn start(self, mut ctx: C) -> SpawnedSubsystem {
 			let mut sender = self.0.clone();
 
@@ -1544,8 +1534,6 @@ mod tests {
 	impl<C> Subsystem<C> for TestSubsystem6
 		where C: SubsystemContext<Message=CandidateBackingMessage>
 	{
-		type Metrics = ();
-
 		fn start(self, mut ctx: C) -> SpawnedSubsystem {
 			let mut sender = self.0.clone();
 
@@ -1813,8 +1801,6 @@ mod tests {
 			C: SubsystemContext<Message=M>,
 			M: Send,
 	{
-		type Metrics = ();
-
 		fn start(self, mut ctx: C) -> SpawnedSubsystem {
 			SpawnedSubsystem {
 				name: "counter-subsystem",
diff --git a/polkadot/node/subsystem-util/Cargo.toml b/polkadot/node/subsystem-util/Cargo.toml
index 2c189419cc1..bc8ac375ff2 100644
--- a/polkadot/node/subsystem-util/Cargo.toml
+++ b/polkadot/node/subsystem-util/Cargo.toml
@@ -10,19 +10,22 @@ async-trait = "0.1"
 derive_more = "0.99.9"
 futures = "0.3.5"
 futures-timer = "3.0.2"
-keystore = { package = "sc-keystore", git = "https://github.com/paritytech/substrate", branch = "master" }
 log = "0.4.8"
 parity-scale-codec = "1.3.4"
 parking_lot = { version = "0.10.0", optional = true }
 pin-project = "0.4.22"
+smallvec = "1.4.1"
+streamunordered = "0.5.1"
+
 polkadot-node-primitives = { path = "../primitives" }
 polkadot-node-subsystem = { path = "../subsystem" }
 polkadot-primitives = { path = "../../primitives" }
 polkadot-statement-table = { path = "../../statement-table" }
+
+sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
 sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
-smallvec = "1.4.1"
 sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
-streamunordered = "0.5.1"
+substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" }
 
 [dev-dependencies]
 assert_matches = "1.3.0"
diff --git a/polkadot/node/subsystem-util/src/lib.rs b/polkadot/node/subsystem-util/src/lib.rs
index 0a44a327d61..f796c6bc33d 100644
--- a/polkadot/node/subsystem-util/src/lib.rs
+++ b/polkadot/node/subsystem-util/src/lib.rs
@@ -19,12 +19,14 @@
 //! Many subsystems have common interests such as canceling a bunch of spawned jobs,
 //! or determining what their validator ID is. These common interests are factored into
 //! this module.
+//!
+//! This crate also reexports Prometheus metric types which are expected to be implemented by subsystems.
+
 
 use polkadot_node_subsystem::{
 	errors::{ChainApiError, RuntimeApiError},
 	messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest, RuntimeApiSender},
 	FromOverseer, SpawnedSubsystem, Subsystem, SubsystemContext, SubsystemError, SubsystemResult,
-	metrics,
 };
 use futures::{
 	channel::{mpsc, oneshot},
@@ -35,7 +37,7 @@ use futures::{
 	task,
 };
 use futures_timer::Delay;
-use keystore::KeyStorePtr;
+use sc_keystore::KeyStorePtr;
 use parity_scale_codec::Encode;
 use pin_project::{pin_project, pinned_drop};
 use polkadot_primitives::v1::{
@@ -434,6 +436,43 @@ impl<ToJob: ToJobTrait> JobHandle<ToJob> {
 	}
 }
 
+/// This module reexports Prometheus types and defines the [`Metrics`] trait.
+pub mod metrics {
+	/// Reexport Prometheus types.
+	pub use substrate_prometheus_endpoint as prometheus;
+
+	/// Subsystem- or job-specific Prometheus metrics.
+	///
+	/// Usually implemented as a wrapper for `Option<ActualMetrics>`
+	/// to ensure `Default` bounds or as a dummy type ().
+	/// Prometheus metrics internally hold an `Arc` reference, so cloning them is fine.
+	pub trait Metrics: Default + Clone {
+		/// Try to register metrics in the Prometheus registry.
+		fn try_register(registry: &prometheus::Registry) -> Result<Self, prometheus::PrometheusError>;
+
+		/// Convience method to register metrics in the optional Prometheus registry.
+		/// If the registration fails, prints a warning and returns `Default::default()`.
+		fn register(registry: Option<&prometheus::Registry>) -> Self {
+			registry.map(|r| {
+				match Self::try_register(r) {
+					Err(e) => {
+						log::warn!("Failed to register metrics: {:?}", e);
+						Default::default()
+					},
+					Ok(metrics) => metrics,
+				}
+			}).unwrap_or_default()
+		}
+	}
+
+	// dummy impl
+	impl Metrics for () {
+		fn try_register(_registry: &prometheus::Registry) -> Result<(), prometheus::PrometheusError> {
+			Ok(())
+		}
+	}
+}
+
 /// This trait governs jobs.
 ///
 /// Jobs are instantiated and killed automatically on appropriate overseer messages.
@@ -870,8 +909,6 @@ where
 	Job::ToJob: TryFrom<AllMessages> + Sync,
 	Job::Metrics: Sync,
 {
-	type Metrics = Job::Metrics;
-
 	fn start(self, ctx: Context) -> SpawnedSubsystem {
 		let spawner = self.spawner.clone();
 		let run_args = self.run_args.clone();
@@ -965,8 +1002,6 @@ macro_rules! delegated_subsystem {
 			Context: $crate::reexports::SubsystemContext,
 			<Context as $crate::reexports::SubsystemContext>::Message: Into<$to_job>,
 		{
-			type Metrics = $metrics;
-
 			fn start(self, ctx: Context) -> $crate::reexports::SpawnedSubsystem {
 				self.manager.start(ctx)
 			}
diff --git a/polkadot/node/subsystem/Cargo.toml b/polkadot/node/subsystem/Cargo.toml
index f7283d40aad..6ad013c177f 100644
--- a/polkadot/node/subsystem/Cargo.toml
+++ b/polkadot/node/subsystem/Cargo.toml
@@ -21,7 +21,6 @@ polkadot-statement-table = { path = "../../statement-table" }
 sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
 smallvec = "1.4.1"
 sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
-substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" }
 
 [dev-dependencies]
 assert_matches = "1.3.0"
diff --git a/polkadot/node/subsystem/src/lib.rs b/polkadot/node/subsystem/src/lib.rs
index 77ad27a2c1d..843791b7206 100644
--- a/polkadot/node/subsystem/src/lib.rs
+++ b/polkadot/node/subsystem/src/lib.rs
@@ -19,8 +19,6 @@
 //! Node-side logic for Polkadot is mostly comprised of Subsystems, which are discrete components
 //! that communicate via message-passing. They are coordinated by an overseer, provided by a
 //! separate crate.
-//!
-//! This crate also reexports Prometheus metric types which are expected to be implemented by subsystems.
 
 #![warn(missing_docs)]
 
@@ -204,9 +202,6 @@ pub trait SubsystemContext: Send + 'static {
 /// [`Overseer`]: struct.Overseer.html
 /// [`Subsystem`]: trait.Subsystem.html
 pub trait Subsystem<C: SubsystemContext> {
-	/// Subsystem-specific Prometheus metrics.
-	type Metrics: metrics::Metrics;
-
 	/// Start this `Subsystem` and return `SpawnedSubsystem`.
 	fn start(self, ctx: C) -> SpawnedSubsystem;
 }
@@ -216,8 +211,6 @@ pub trait Subsystem<C: SubsystemContext> {
 pub struct DummySubsystem;
 
 impl<C: SubsystemContext> Subsystem<C> for DummySubsystem {
-	type Metrics = ();
-
 	fn start(self, mut ctx: C) -> SpawnedSubsystem {
 		let future = Box::pin(async move {
 			loop {
@@ -235,40 +228,3 @@ impl<C: SubsystemContext> Subsystem<C> for DummySubsystem {
 		}
 	}
 }
-
-/// This module reexports Prometheus types and defines the [`Metrics`] trait.
-pub mod metrics {
-	/// Reexport Prometheus types.
-	pub use substrate_prometheus_endpoint as prometheus;
-
-	/// Subsystem- or job-specific Prometheus metrics.
-	///
-	/// Usually implemented as a wrapper for `Option<ActualMetrics>`
-	/// to ensure `Default` bounds or as a dummy type ().
-	/// Prometheus metrics internally hold an `Arc` reference, so cloning them is fine.
-	pub trait Metrics: Default + Clone {
-		/// Try to register metrics in the Prometheus registry.
-		fn try_register(registry: &prometheus::Registry) -> Result<Self, prometheus::PrometheusError>;
-
-		/// Convience method to register metrics in the optional Prometheus registry.
-		/// If the registration fails, prints a warning and returns `Default::default()`.
-		fn register(registry: Option<&prometheus::Registry>) -> Self {
-			registry.map(|r| {
-				match Self::try_register(r) {
-					Err(e) => {
-						log::warn!("Failed to register metrics: {:?}", e);
-						Default::default()
-					},
-					Ok(metrics) => metrics,
-				}
-			}).unwrap_or_default()
-		}
-	}
-
-	// dummy impl
-	impl Metrics for () {
-		fn try_register(_registry: &prometheus::Registry) -> Result<(), prometheus::PrometheusError> {
-			Ok(())
-		}
-	}
-}
-- 
GitLab