From e956c2e1c70a1cc0457844f74331f0d144e03ab2 Mon Sep 17 00:00:00 2001
From: Qinxuan Chen <koushiro.cqx@gmail.com>
Date: Wed, 26 Jan 2022 03:48:46 +0800
Subject: [PATCH] use `thiserror` instead of `derive_more` for error handling
 (#10696)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* use thiserror instead of derive_more for error handling

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Update utils/prometheus/src/lib.rs

* Update utils/prometheus/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
---
 substrate/Cargo.lock                          | 30 ++++----
 substrate/bin/node/inspect/Cargo.toml         |  2 +-
 substrate/bin/node/inspect/src/lib.rs         | 19 ++----
 .../client/authority-discovery/Cargo.toml     |  2 +-
 .../client/authority-discovery/src/error.rs   | 68 ++++++++++++-------
 substrate/client/beefy/rpc/Cargo.toml         |  1 -
 substrate/client/beefy/rpc/src/lib.rs         |  8 +--
 substrate/client/consensus/aura/Cargo.toml    |  2 +-
 substrate/client/consensus/aura/src/lib.rs    | 19 +++---
 substrate/client/consensus/babe/Cargo.toml    |  2 +-
 .../client/consensus/babe/rpc/Cargo.toml      |  4 +-
 .../client/consensus/babe/rpc/src/lib.rs      |  6 +-
 substrate/client/consensus/babe/src/lib.rs    | 61 ++++++++---------
 .../client/consensus/manual-seal/Cargo.toml   |  2 +-
 .../client/consensus/manual-seal/src/error.rs | 50 ++++++++------
 substrate/client/consensus/pow/Cargo.toml     |  2 +-
 substrate/client/consensus/pow/src/lib.rs     | 41 ++++++-----
 substrate/client/executor/common/Cargo.toml   |  1 -
 substrate/client/executor/common/src/error.rs | 28 +++++---
 substrate/client/finality-grandpa/Cargo.toml  |  3 +-
 .../client/finality-grandpa/rpc/Cargo.toml    |  2 +-
 .../client/finality-grandpa/rpc/src/error.rs  | 12 ++--
 .../finality-grandpa/src/authorities.rs       | 19 +++---
 .../finality-grandpa/src/finality_proof.rs    |  9 +--
 .../client/finality-grandpa/src/warp_proof.rs | 17 +++--
 substrate/client/keystore/Cargo.toml          |  2 +-
 substrate/client/keystore/src/lib.rs          | 30 +++-----
 substrate/client/network/Cargo.toml           |  3 +-
 substrate/client/network/src/bitswap.rs       | 26 ++++---
 .../network/src/block_request_handler.rs      | 23 ++++---
 substrate/client/network/src/error.rs         | 39 ++++-------
 .../src/light_client_requests/handler.rs      | 18 ++---
 .../src/protocol/notifications/handler.rs     |  4 +-
 .../notifications/upgrade/notifications.rs    | 15 ++--
 .../client/network/src/request_responses.rs   | 23 ++++---
 substrate/client/network/src/service.rs       |  4 +-
 .../network/src/state_request_handler.rs      | 23 ++++---
 .../network/src/warp_request_handler.rs       | 29 ++++----
 .../client/transaction-pool/api/Cargo.toml    |  9 ++-
 .../client/transaction-pool/api/src/error.rs  |  3 +-
 substrate/client/transaction-pool/src/lib.rs  |  8 +--
 substrate/primitives/keystore/Cargo.toml      | 10 +--
 substrate/primitives/keystore/src/lib.rs      | 10 +--
 .../runtime/transaction-pool/Cargo.toml       |  2 +-
 .../runtime/transaction-pool/src/lib.rs       | 11 +--
 substrate/utils/prometheus/Cargo.toml         |  2 +-
 substrate/utils/prometheus/src/lib.rs         | 27 +++-----
 47 files changed, 376 insertions(+), 355 deletions(-)

diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index 39cb42be7a8..a8092fffa7c 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -520,7 +520,6 @@ version = "4.0.0-dev"
 dependencies = [
  "beefy-gadget",
  "beefy-primitives",
- "derive_more",
  "futures 0.3.16",
  "jsonrpc-core",
  "jsonrpc-core-client",
@@ -4710,7 +4709,6 @@ name = "node-inspect"
 version = "0.9.0-dev"
 dependencies = [
  "clap 3.0.7",
- "derive_more",
  "parity-scale-codec",
  "sc-cli",
  "sc-client-api",
@@ -4719,6 +4717,7 @@ dependencies = [
  "sp-blockchain",
  "sp-core",
  "sp-runtime",
+ "thiserror",
 ]
 
 [[package]]
@@ -7647,7 +7646,6 @@ name = "sc-authority-discovery"
 version = "0.10.0-dev"
 dependencies = [
  "async-trait",
- "derive_more",
  "futures 0.3.16",
  "futures-timer",
  "ip_network",
@@ -7669,6 +7667,7 @@ dependencies = [
  "sp-tracing",
  "substrate-prometheus-endpoint",
  "substrate-test-runtime-client",
+ "thiserror",
 ]
 
 [[package]]
@@ -7863,7 +7862,6 @@ name = "sc-consensus-aura"
 version = "0.10.0-dev"
 dependencies = [
  "async-trait",
- "derive_more",
  "futures 0.3.16",
  "getrandom 0.2.3",
  "log 0.4.14",
@@ -7894,6 +7892,7 @@ dependencies = [
  "substrate-prometheus-endpoint",
  "substrate-test-runtime-client",
  "tempfile",
+ "thiserror",
 ]
 
 [[package]]
@@ -7901,7 +7900,6 @@ name = "sc-consensus-babe"
 version = "0.10.0-dev"
 dependencies = [
  "async-trait",
- "derive_more",
  "fork-tree",
  "futures 0.3.16",
  "log 0.4.14",
@@ -7944,13 +7942,13 @@ dependencies = [
  "substrate-prometheus-endpoint",
  "substrate-test-runtime-client",
  "tempfile",
+ "thiserror",
 ]
 
 [[package]]
 name = "sc-consensus-babe-rpc"
 version = "0.10.0-dev"
 dependencies = [
- "derive_more",
  "futures 0.3.16",
  "jsonrpc-core",
  "jsonrpc-core-client",
@@ -7973,6 +7971,7 @@ dependencies = [
  "sp-runtime",
  "substrate-test-runtime-client",
  "tempfile",
+ "thiserror",
 ]
 
 [[package]]
@@ -7993,7 +7992,6 @@ version = "0.10.0-dev"
 dependencies = [
  "assert_matches",
  "async-trait",
- "derive_more",
  "futures 0.3.16",
  "jsonrpc-core",
  "jsonrpc-core-client",
@@ -8023,6 +8021,7 @@ dependencies = [
  "substrate-prometheus-endpoint",
  "substrate-test-runtime-client",
  "substrate-test-runtime-transaction-pool",
+ "thiserror",
  "tokio",
 ]
 
@@ -8031,7 +8030,6 @@ name = "sc-consensus-pow"
 version = "0.10.0-dev"
 dependencies = [
  "async-trait",
- "derive_more",
  "futures 0.3.16",
  "futures-timer",
  "log 0.4.14",
@@ -8048,6 +8046,7 @@ dependencies = [
  "sp-inherents",
  "sp-runtime",
  "substrate-prometheus-endpoint",
+ "thiserror",
 ]
 
 [[package]]
@@ -8128,7 +8127,6 @@ dependencies = [
 name = "sc-executor-common"
 version = "0.10.0-dev"
 dependencies = [
- "derive_more",
  "environmental",
  "parity-scale-codec",
  "sc-allocator",
@@ -8184,7 +8182,6 @@ version = "0.10.0-dev"
 dependencies = [
  "assert_matches",
  "async-trait",
- "derive_more",
  "dyn-clone",
  "finality-grandpa",
  "fork-tree",
@@ -8219,6 +8216,7 @@ dependencies = [
  "substrate-prometheus-endpoint",
  "substrate-test-runtime-client",
  "tempfile",
+ "thiserror",
  "tokio",
 ]
 
@@ -8226,7 +8224,6 @@ dependencies = [
 name = "sc-finality-grandpa-rpc"
 version = "0.10.0-dev"
 dependencies = [
- "derive_more",
  "finality-grandpa",
  "futures 0.3.16",
  "jsonrpc-core",
@@ -8247,6 +8244,7 @@ dependencies = [
  "sp-keyring",
  "sp-runtime",
  "substrate-test-runtime-client",
+ "thiserror",
 ]
 
 [[package]]
@@ -8270,7 +8268,6 @@ name = "sc-keystore"
 version = "4.0.0-dev"
 dependencies = [
  "async-trait",
- "derive_more",
  "hex",
  "parking_lot 0.11.2",
  "serde_json",
@@ -8278,6 +8275,7 @@ dependencies = [
  "sp-core",
  "sp-keystore",
  "tempfile",
+ "thiserror",
 ]
 
 [[package]]
@@ -8291,7 +8289,6 @@ dependencies = [
  "bitflags",
  "bytes 1.1.0",
  "cid",
- "derive_more",
  "either",
  "fnv",
  "fork-tree",
@@ -8762,7 +8759,6 @@ dependencies = [
 name = "sc-transaction-pool-api"
 version = "4.0.0-dev"
 dependencies = [
- "derive_more",
  "futures 0.3.16",
  "log 0.4.14",
  "serde",
@@ -9632,7 +9628,6 @@ name = "sp-keystore"
 version = "0.10.0"
 dependencies = [
  "async-trait",
- "derive_more",
  "futures 0.3.16",
  "merlin",
  "parity-scale-codec",
@@ -9643,6 +9638,7 @@ dependencies = [
  "serde",
  "sp-core",
  "sp-externalities",
+ "thiserror",
 ]
 
 [[package]]
@@ -10211,11 +10207,11 @@ name = "substrate-prometheus-endpoint"
 version = "0.10.0-dev"
 dependencies = [
  "async-std",
- "derive_more",
  "futures-util",
  "hyper 0.14.16",
  "log 0.4.14",
  "prometheus",
+ "thiserror",
  "tokio",
 ]
 
@@ -10312,7 +10308,6 @@ dependencies = [
 name = "substrate-test-runtime-transaction-pool"
 version = "2.0.0"
 dependencies = [
- "derive_more",
  "futures 0.3.16",
  "parity-scale-codec",
  "parking_lot 0.11.2",
@@ -10321,6 +10316,7 @@ dependencies = [
  "sp-blockchain",
  "sp-runtime",
  "substrate-test-runtime-client",
+ "thiserror",
 ]
 
 [[package]]
diff --git a/substrate/bin/node/inspect/Cargo.toml b/substrate/bin/node/inspect/Cargo.toml
index 49470a7e7b0..bb9af8c6698 100644
--- a/substrate/bin/node/inspect/Cargo.toml
+++ b/substrate/bin/node/inspect/Cargo.toml
@@ -13,7 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 [dependencies]
 clap = { version = "3.0", features = ["derive"] }
 codec = { package = "parity-scale-codec", version = "2.0.0" }
-derive_more = "0.99"
+thiserror = "1.0"
 sc-cli = { version = "0.10.0-dev", path = "../../../client/cli" }
 sc-client-api = { version = "4.0.0-dev", path = "../../../client/api" }
 sc-executor = { version = "0.10.0-dev", path = "../../../client/executor" }
diff --git a/substrate/bin/node/inspect/src/lib.rs b/substrate/bin/node/inspect/src/lib.rs
index ff1eecd219a..b37c5aa7ca2 100644
--- a/substrate/bin/node/inspect/src/lib.rs
+++ b/substrate/bin/node/inspect/src/lib.rs
@@ -78,26 +78,19 @@ impl<TBlock: Block> PrettyPrinter<TBlock> for DebugPrinter {
 }
 
 /// Aggregated error for `Inspector` operations.
-#[derive(Debug, derive_more::From, derive_more::Display)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error {
 	/// Could not decode Block or Extrinsic.
-	Codec(codec::Error),
+	#[error(transparent)]
+	Codec(#[from] codec::Error),
 	/// Error accessing blockchain DB.
-	Blockchain(sp_blockchain::Error),
+	#[error(transparent)]
+	Blockchain(#[from] sp_blockchain::Error),
 	/// Given block has not been found.
+	#[error("{0}")]
 	NotFound(String),
 }
 
-impl std::error::Error for Error {
-	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-		match *self {
-			Self::Codec(ref e) => Some(e),
-			Self::Blockchain(ref e) => Some(e),
-			Self::NotFound(_) => None,
-		}
-	}
-}
-
 /// A helper trait to access block headers and bodies.
 pub trait ChainAccess<TBlock: Block>: HeaderBackend<TBlock> + BlockBackend<TBlock> {}
 
diff --git a/substrate/client/authority-discovery/Cargo.toml b/substrate/client/authority-discovery/Cargo.toml
index c6c523fa5ee..ec43112a714 100644
--- a/substrate/client/authority-discovery/Cargo.toml
+++ b/substrate/client/authority-discovery/Cargo.toml
@@ -19,7 +19,7 @@ prost-build = "0.9"
 [dependencies]
 async-trait = "0.1"
 codec = { package = "parity-scale-codec", default-features = false, version = "2.0.0" }
-derive_more = "0.99.16"
+thiserror = "1.0"
 futures = "0.3.9"
 futures-timer = "3.0.1"
 ip_network = "0.4.1"
diff --git a/substrate/client/authority-discovery/src/error.rs b/substrate/client/authority-discovery/src/error.rs
index 26ee02ef853..bad53e905cb 100644
--- a/substrate/client/authority-discovery/src/error.rs
+++ b/substrate/client/authority-discovery/src/error.rs
@@ -24,40 +24,56 @@ use sp_core::crypto::CryptoTypePublicPair;
 pub type Result<T> = std::result::Result<T, Error>;
 
 /// Error type for the authority discovery module.
-#[derive(Debug, derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error {
-	/// Received dht value found event with records with different keys.
+	#[error("Received dht value found event with records with different keys.")]
 	ReceivingDhtValueFoundEventWithDifferentKeys,
-	/// Received dht value found event with no records.
+
+	#[error("Received dht value found event with no records.")]
 	ReceivingDhtValueFoundEventWithNoRecords,
-	/// Failed to verify a dht payload with the given signature.
+
+	#[error("Failed to verify a dht payload with the given signature.")]
 	VerifyingDhtPayload,
-	/// Failed to hash the authority id to be used as a dht key.
-	HashingAuthorityId(libp2p::core::multiaddr::multihash::Error),
-	/// Failed calling into the Substrate runtime.
-	CallingRuntime(sp_blockchain::Error),
-	/// Received a dht record with a key that does not match any in-flight awaited keys.
+
+	#[error("Failed to hash the authority id to be used as a dht key.")]
+	HashingAuthorityId(#[from] libp2p::core::multiaddr::multihash::Error),
+
+	#[error("Failed calling into the Substrate runtime.")]
+	CallingRuntime(#[from] sp_blockchain::Error),
+
+	#[error("Received a dht record with a key that does not match any in-flight awaited keys.")]
 	ReceivingUnexpectedRecord,
-	/// Failed to encode a protobuf payload.
-	EncodingProto(prost::EncodeError),
-	/// Failed to decode a protobuf payload.
-	DecodingProto(prost::DecodeError),
-	/// Failed to encode or decode scale payload.
-	EncodingDecodingScale(codec::Error),
-	/// Failed to parse a libp2p multi address.
-	ParsingMultiaddress(libp2p::core::multiaddr::Error),
-	/// Failed to parse a libp2p key.
-	ParsingLibp2pIdentity(sc_network::DecodingError),
-	/// Failed to sign using a specific public key.
+
+	#[error("Failed to encode a protobuf payload.")]
+	EncodingProto(#[from] prost::EncodeError),
+
+	#[error("Failed to decode a protobuf payload.")]
+	DecodingProto(#[from] prost::DecodeError),
+
+	#[error("Failed to encode or decode scale payload.")]
+	EncodingDecodingScale(#[from] codec::Error),
+
+	#[error("Failed to parse a libp2p multi address.")]
+	ParsingMultiaddress(#[from] libp2p::core::multiaddr::Error),
+
+	#[error("Failed to parse a libp2p key.")]
+	ParsingLibp2pIdentity(#[from] sc_network::DecodingError),
+
+	#[error("Failed to sign using a specific public key.")]
 	MissingSignature(CryptoTypePublicPair),
-	/// Failed to sign using all public keys.
+
+	#[error("Failed to sign using all public keys.")]
 	Signing,
-	/// Failed to register Prometheus metric.
-	Prometheus(prometheus_endpoint::PrometheusError),
-	/// Received authority record that contains addresses with multiple peer ids
+
+	#[error("Failed to register Prometheus metric.")]
+	Prometheus(#[from] prometheus_endpoint::PrometheusError),
+
+	#[error("Received authority record that contains addresses with multiple peer ids")]
 	ReceivingDhtValueFoundEventWithDifferentPeerIds,
-	/// Received authority record without any addresses having a peer id
+
+	#[error("Received authority record without any addresses having a peer id")]
 	ReceivingDhtValueFoundEventWithNoPeerIds,
-	/// Received authority record without a valid signature for the remote peer id.
+
+	#[error("Received authority record without a valid signature for the remote peer id.")]
 	MissingPeerIdSignature,
 }
diff --git a/substrate/client/beefy/rpc/Cargo.toml b/substrate/client/beefy/rpc/Cargo.toml
index a72af62fdee..444f1ff4aaf 100644
--- a/substrate/client/beefy/rpc/Cargo.toml
+++ b/substrate/client/beefy/rpc/Cargo.toml
@@ -8,7 +8,6 @@ repository = "https://github.com/paritytech/substrate"
 description = "RPC for the BEEFY Client gadget for substrate"
 
 [dependencies]
-derive_more = "0.99"
 futures = "0.3.16"
 log = "0.4"
 parking_lot = "0.11"
diff --git a/substrate/client/beefy/rpc/src/lib.rs b/substrate/client/beefy/rpc/src/lib.rs
index dc9ee8b9470..4c1bc03e222 100644
--- a/substrate/client/beefy/rpc/src/lib.rs
+++ b/substrate/client/beefy/rpc/src/lib.rs
@@ -36,15 +36,15 @@ mod notification;
 
 type FutureResult<T> = jsonrpc_core::BoxFuture<Result<T, jsonrpc_core::Error>>;
 
-#[derive(Debug, derive_more::Display, derive_more::From, thiserror::Error)]
+#[derive(Debug, thiserror::Error)]
 /// Top-level error type for the RPC handler
 pub enum Error {
 	/// The BEEFY RPC endpoint is not ready.
-	#[display(fmt = "BEEFY RPC endpoint not ready")]
+	#[error("BEEFY RPC endpoint not ready")]
 	EndpointNotReady,
 	/// The BEEFY RPC background task failed to spawn.
-	#[display(fmt = "BEEFY RPC background task failed to spawn")]
-	RpcTaskFailure(SpawnError),
+	#[error("BEEFY RPC background task failed to spawn")]
+	RpcTaskFailure(#[from] SpawnError),
 }
 
 /// The error codes returned by jsonrpc.
diff --git a/substrate/client/consensus/aura/Cargo.toml b/substrate/client/consensus/aura/Cargo.toml
index 97409c5944d..bcae7648ce2 100644
--- a/substrate/client/consensus/aura/Cargo.toml
+++ b/substrate/client/consensus/aura/Cargo.toml
@@ -22,7 +22,7 @@ codec = { package = "parity-scale-codec", version = "2.0.0" }
 sp-consensus = { version = "0.10.0-dev", path = "../../../primitives/consensus/common" }
 sc-consensus = { version = "0.10.0-dev", path = "../../../client/consensus/common" }
 sp-consensus-slots = { version = "0.10.0-dev", path = "../../../primitives/consensus/slots" }
-derive_more = "0.99.16"
+thiserror = "1.0"
 futures = "0.3.9"
 sp-inherents = { version = "4.0.0-dev", path = "../../../primitives/inherents" }
 log = "0.4.8"
diff --git a/substrate/client/consensus/aura/src/lib.rs b/substrate/client/consensus/aura/src/lib.rs
index d7fe6131393..61c56108831 100644
--- a/substrate/client/consensus/aura/src/lib.rs
+++ b/substrate/client/consensus/aura/src/lib.rs
@@ -491,33 +491,34 @@ fn aura_err<B: BlockT>(error: Error<B>) -> Error<B> {
 }
 
 /// Aura Errors
-#[derive(derive_more::Display, Debug)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error<B: BlockT> {
 	/// Multiple Aura pre-runtime headers
-	#[display(fmt = "Multiple Aura pre-runtime headers")]
+	#[error("Multiple Aura pre-runtime headers")]
 	MultipleHeaders,
 	/// No Aura pre-runtime digest found
-	#[display(fmt = "No Aura pre-runtime digest found")]
+	#[error("No Aura pre-runtime digest found")]
 	NoDigestFound,
 	/// Header is unsealed
-	#[display(fmt = "Header {:?} is unsealed", _0)]
+	#[error("Header {0:?} is unsealed")]
 	HeaderUnsealed(B::Hash),
 	/// Header has a bad seal
-	#[display(fmt = "Header {:?} has a bad seal", _0)]
+	#[error("Header {0:?} has a bad seal")]
 	HeaderBadSeal(B::Hash),
 	/// Slot Author not found
-	#[display(fmt = "Slot Author not found")]
+	#[error("Slot Author not found")]
 	SlotAuthorNotFound,
 	/// Bad signature
-	#[display(fmt = "Bad signature on {:?}", _0)]
+	#[error("Bad signature on {0:?}")]
 	BadSignature(B::Hash),
 	/// Client Error
+	#[error(transparent)]
 	Client(sp_blockchain::Error),
 	/// Unknown inherent error for identifier
-	#[display(fmt = "Unknown inherent error for identifier: {}", "String::from_utf8_lossy(_0)")]
+	#[error("Unknown inherent error for identifier: {}", String::from_utf8_lossy(.0))]
 	UnknownInherentError(sp_inherents::InherentIdentifier),
-	#[display(fmt = "Inherent error: {}", _0)]
 	/// Inherents Error
+	#[error("Inherent error: {0}")]
 	Inherent(sp_inherents::Error),
 }
 
diff --git a/substrate/client/consensus/babe/Cargo.toml b/substrate/client/consensus/babe/Cargo.toml
index e4d66fcad87..5dd029f0ad4 100644
--- a/substrate/client/consensus/babe/Cargo.toml
+++ b/substrate/client/consensus/babe/Cargo.toml
@@ -49,7 +49,7 @@ log = "0.4.8"
 schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"] }
 rand = "0.7.2"
 merlin = "2.0"
-derive_more = "0.99.16"
+thiserror = "1.0"
 retain_mut = "0.1.4"
 async-trait = "0.1.50"
 
diff --git a/substrate/client/consensus/babe/rpc/Cargo.toml b/substrate/client/consensus/babe/rpc/Cargo.toml
index 93be56b9d36..4997cfdd1ee 100644
--- a/substrate/client/consensus/babe/rpc/Cargo.toml
+++ b/substrate/client/consensus/babe/rpc/Cargo.toml
@@ -19,12 +19,12 @@ jsonrpc-core = "18.0.0"
 jsonrpc-core-client = "18.0.0"
 jsonrpc-derive = "18.0.0"
 sp-consensus-babe = { version = "0.10.0-dev", path = "../../../../primitives/consensus/babe" }
-serde = { version = "1.0.132", features=["derive"] }
+serde = { version = "1.0.132", features = ["derive"] }
 sp-blockchain = { version = "4.0.0-dev", path = "../../../../primitives/blockchain" }
 sp-runtime = { version = "4.1.0-dev", path = "../../../../primitives/runtime" }
 sc-consensus-epochs = { version = "0.10.0-dev", path = "../../epochs" }
 futures = "0.3.16"
-derive_more = "0.99.16"
+thiserror = "1.0"
 sp-api = { version = "4.0.0-dev", path = "../../../../primitives/api" }
 sp-consensus = { version = "0.10.0-dev", path = "../../../../primitives/consensus/common" }
 sp-core = { version = "4.1.0-dev", path = "../../../../primitives/core" }
diff --git a/substrate/client/consensus/babe/rpc/src/lib.rs b/substrate/client/consensus/babe/rpc/src/lib.rs
index c9d2f9b76c2..462620f26e5 100644
--- a/substrate/client/consensus/babe/rpc/src/lib.rs
+++ b/substrate/client/consensus/babe/rpc/src/lib.rs
@@ -166,11 +166,13 @@ pub struct EpochAuthorship {
 }
 
 /// Errors encountered by the RPC
-#[derive(Debug, derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error {
 	/// Consensus error
-	Consensus(ConsensusError),
+	#[error(transparent)]
+	Consensus(#[from] ConsensusError),
 	/// Errors that can be formatted as a String
+	#[error("{0}")]
 	StringError(String),
 }
 
diff --git a/substrate/client/consensus/babe/src/lib.rs b/substrate/client/consensus/babe/src/lib.rs
index a86eac35a10..3e9cf5aab64 100644
--- a/substrate/client/consensus/babe/src/lib.rs
+++ b/substrate/client/consensus/babe/src/lib.rs
@@ -217,95 +217,94 @@ impl Epoch {
 }
 
 /// Errors encountered by the babe authorship task.
-#[derive(derive_more::Display, Debug)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error<B: BlockT> {
 	/// Multiple BABE pre-runtime digests
-	#[display(fmt = "Multiple BABE pre-runtime digests, rejecting!")]
+	#[error("Multiple BABE pre-runtime digests, rejecting!")]
 	MultiplePreRuntimeDigests,
 	/// No BABE pre-runtime digest found
-	#[display(fmt = "No BABE pre-runtime digest found")]
+	#[error("No BABE pre-runtime digest found")]
 	NoPreRuntimeDigest,
 	/// Multiple BABE epoch change digests
-	#[display(fmt = "Multiple BABE epoch change digests, rejecting!")]
+	#[error("Multiple BABE epoch change digests, rejecting!")]
 	MultipleEpochChangeDigests,
 	/// Multiple BABE config change digests
-	#[display(fmt = "Multiple BABE config change digests, rejecting!")]
+	#[error("Multiple BABE config change digests, rejecting!")]
 	MultipleConfigChangeDigests,
 	/// Could not extract timestamp and slot
-	#[display(fmt = "Could not extract timestamp and slot: {:?}", _0)]
+	#[error("Could not extract timestamp and slot: {0:?}")]
 	Extraction(sp_consensus::Error),
 	/// Could not fetch epoch
-	#[display(fmt = "Could not fetch epoch at {:?}", _0)]
+	#[error("Could not fetch epoch at {0:?}")]
 	FetchEpoch(B::Hash),
 	/// Header rejected: too far in the future
-	#[display(fmt = "Header {:?} rejected: too far in the future", _0)]
+	#[error("Header {0:?} rejected: too far in the future")]
 	TooFarInFuture(B::Hash),
 	/// Parent unavailable. Cannot import
-	#[display(fmt = "Parent ({}) of {} unavailable. Cannot import", _0, _1)]
+	#[error("Parent ({0}) of {1} unavailable. Cannot import")]
 	ParentUnavailable(B::Hash, B::Hash),
 	/// Slot number must increase
-	#[display(fmt = "Slot number must increase: parent slot: {}, this slot: {}", _0, _1)]
+	#[error("Slot number must increase: parent slot: {0}, this slot: {1}")]
 	SlotMustIncrease(Slot, Slot),
 	/// Header has a bad seal
-	#[display(fmt = "Header {:?} has a bad seal", _0)]
+	#[error("Header {0:?} has a bad seal")]
 	HeaderBadSeal(B::Hash),
 	/// Header is unsealed
-	#[display(fmt = "Header {:?} is unsealed", _0)]
+	#[error("Header {0:?} is unsealed")]
 	HeaderUnsealed(B::Hash),
 	/// Slot author not found
-	#[display(fmt = "Slot author not found")]
+	#[error("Slot author not found")]
 	SlotAuthorNotFound,
 	/// Secondary slot assignments are disabled for the current epoch.
-	#[display(fmt = "Secondary slot assignments are disabled for the current epoch.")]
+	#[error("Secondary slot assignments are disabled for the current epoch.")]
 	SecondarySlotAssignmentsDisabled,
 	/// Bad signature
-	#[display(fmt = "Bad signature on {:?}", _0)]
+	#[error("Bad signature on {0:?}")]
 	BadSignature(B::Hash),
 	/// Invalid author: Expected secondary author
-	#[display(fmt = "Invalid author: Expected secondary author: {:?}, got: {:?}.", _0, _1)]
+	#[error("Invalid author: Expected secondary author: {0:?}, got: {1:?}.")]
 	InvalidAuthor(AuthorityId, AuthorityId),
 	/// No secondary author expected.
-	#[display(fmt = "No secondary author expected.")]
+	#[error("No secondary author expected.")]
 	NoSecondaryAuthorExpected,
 	/// VRF verification of block by author failed
-	#[display(
-		fmt = "VRF verification of block by author {:?} failed: threshold {} exceeded",
-		_0,
-		_1
-	)]
+	#[error("VRF verification of block by author {0:?} failed: threshold {1} exceeded")]
 	VRFVerificationOfBlockFailed(AuthorityId, u128),
 	/// VRF verification failed
-	#[display(fmt = "VRF verification failed: {:?}", _0)]
+	#[error("VRF verification failed: {0:?}")]
 	VRFVerificationFailed(SignatureError),
 	/// Could not fetch parent header
-	#[display(fmt = "Could not fetch parent header: {:?}", _0)]
+	#[error("Could not fetch parent header: {0:?}")]
 	FetchParentHeader(sp_blockchain::Error),
 	/// Expected epoch change to happen.
-	#[display(fmt = "Expected epoch change to happen at {:?}, s{}", _0, _1)]
+	#[error("Expected epoch change to happen at {0:?}, s{1}")]
 	ExpectedEpochChange(B::Hash, Slot),
 	/// Unexpected config change.
-	#[display(fmt = "Unexpected config change")]
+	#[error("Unexpected config change")]
 	UnexpectedConfigChange,
 	/// Unexpected epoch change
-	#[display(fmt = "Unexpected epoch change")]
+	#[error("Unexpected epoch change")]
 	UnexpectedEpochChange,
 	/// Parent block has no associated weight
-	#[display(fmt = "Parent block of {} has no associated weight", _0)]
+	#[error("Parent block of {0} has no associated weight")]
 	ParentBlockNoAssociatedWeight(B::Hash),
 	/// Check inherents error
-	#[display(fmt = "Checking inherents failed: {}", _0)]
+	#[error("Checking inherents failed: {0}")]
 	CheckInherents(sp_inherents::Error),
 	/// Unhandled check inherents error
-	#[display(fmt = "Checking inherents unhandled error: {}", "String::from_utf8_lossy(_0)")]
+	#[error("Checking inherents unhandled error: {}", String::from_utf8_lossy(.0))]
 	CheckInherentsUnhandled(sp_inherents::InherentIdentifier),
 	/// Create inherents error.
-	#[display(fmt = "Creating inherents failed: {}", _0)]
+	#[error("Creating inherents failed: {0}")]
 	CreateInherents(sp_inherents::Error),
 	/// Client error
+	#[error(transparent)]
 	Client(sp_blockchain::Error),
 	/// Runtime Api error.
+	#[error(transparent)]
 	RuntimeApi(sp_api::ApiError),
 	/// Fork tree error
+	#[error(transparent)]
 	ForkTree(Box<fork_tree::Error<sp_blockchain::Error>>),
 }
 
diff --git a/substrate/client/consensus/manual-seal/Cargo.toml b/substrate/client/consensus/manual-seal/Cargo.toml
index 89f3335899f..ff2264e6417 100644
--- a/substrate/client/consensus/manual-seal/Cargo.toml
+++ b/substrate/client/consensus/manual-seal/Cargo.toml
@@ -13,7 +13,7 @@ readme = "README.md"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
-derive_more = "0.99.16"
+thiserror = "1.0"
 futures = "0.3.9"
 jsonrpc-core = "18.0.0"
 jsonrpc-core-client = "18.0.0"
diff --git a/substrate/client/consensus/manual-seal/src/error.rs b/substrate/client/consensus/manual-seal/src/error.rs
index 3a67b36bc62..2f946f3de3c 100644
--- a/substrate/client/consensus/manual-seal/src/error.rs
+++ b/substrate/client/consensus/manual-seal/src/error.rs
@@ -38,40 +38,52 @@ mod codes {
 }
 
 /// errors encountered by background block authorship task
-#[derive(Debug, derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error {
 	/// An error occurred while importing the block
-	#[display(fmt = "Block import failed: {:?}", _0)]
+	#[error("Block import failed: {0:?}")]
 	BlockImportError(ImportResult),
 	/// Transaction pool is empty, cannot create a block
-	#[display(fmt = "Transaction pool is empty, set create_empty to true,\
-	if you want to create empty blocks")]
+	#[error(
+		"Transaction pool is empty, set create_empty to true, if you want to create empty blocks"
+	)]
 	EmptyTransactionPool,
 	/// encountered during creation of Proposer.
-	#[display(fmt = "Consensus Error: {}", _0)]
-	ConsensusError(ConsensusError),
+	#[error("Consensus Error: {0}")]
+	ConsensusError(#[from] ConsensusError),
 	/// Failed to create Inherents data
-	#[display(fmt = "Inherents Error: {}", _0)]
-	InherentError(InherentsError),
+	#[error("Inherents Error: {0}")]
+	InherentError(#[from] InherentsError),
 	/// error encountered during finalization
-	#[display(fmt = "Finalization Error: {}", _0)]
-	BlockchainError(BlockchainError),
+	#[error("Finalization Error: {0}")]
+	BlockchainError(#[from] BlockchainError),
 	/// Supplied parent_hash doesn't exist in chain
-	#[display(fmt = "Supplied parent_hash: {} doesn't exist in chain", _0)]
-	#[from(ignore)]
+	#[error("Supplied parent_hash: {0} doesn't exist in chain")]
 	BlockNotFound(String),
 	/// Some string error
-	#[display(fmt = "{}", _0)]
+	#[error("{0}")]
 	StringError(String),
 	/// send error
-	#[display(fmt = "Consensus process is terminating")]
-	Canceled(oneshot::Canceled),
+	#[error("Consensus process is terminating")]
+	Canceled(#[from] oneshot::Canceled),
 	/// send error
-	#[display(fmt = "Consensus process is terminating")]
-	SendError(SendError),
+	#[error("Consensus process is terminating")]
+	SendError(#[from] SendError),
 	/// Some other error.
-	#[display(fmt = "Other error: {}", _0)]
-	Other(Box<dyn std::error::Error + Send>),
+	#[error("Other error: {0}")]
+	Other(#[from] Box<dyn std::error::Error + Send>),
+}
+
+impl From<ImportResult> for Error {
+	fn from(err: ImportResult) -> Self {
+		Error::BlockImportError(err)
+	}
+}
+
+impl From<String> for Error {
+	fn from(s: String) -> Self {
+		Error::StringError(s)
+	}
 }
 
 impl Error {
diff --git a/substrate/client/consensus/pow/Cargo.toml b/substrate/client/consensus/pow/Cargo.toml
index db9e4e164e4..e5bf87487c7 100644
--- a/substrate/client/consensus/pow/Cargo.toml
+++ b/substrate/client/consensus/pow/Cargo.toml
@@ -28,6 +28,6 @@ log = "0.4.8"
 futures = "0.3.16"
 futures-timer = "3.0.1"
 parking_lot = "0.11.2"
-derive_more = "0.99.16"
+thiserror = "1.0"
 prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../../utils/prometheus", version = "0.10.0-dev"}
 async-trait = "0.1.50"
diff --git a/substrate/client/consensus/pow/src/lib.rs b/substrate/client/consensus/pow/src/lib.rs
index 0bcb9f3d00a..ef81faff46a 100644
--- a/substrate/client/consensus/pow/src/lib.rs
+++ b/substrate/client/consensus/pow/src/lib.rs
@@ -72,45 +72,50 @@ use std::{
 	time::Duration,
 };
 
-#[derive(derive_more::Display, Debug)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error<B: BlockT> {
-	#[display(fmt = "Header uses the wrong engine {:?}", _0)]
+	#[error("Header uses the wrong engine {0:?}")]
 	WrongEngine([u8; 4]),
-	#[display(fmt = "Header {:?} is unsealed", _0)]
+	#[error("Header {0:?} is unsealed")]
 	HeaderUnsealed(B::Hash),
-	#[display(fmt = "PoW validation error: invalid seal")]
+	#[error("PoW validation error: invalid seal")]
 	InvalidSeal,
-	#[display(fmt = "PoW validation error: preliminary verification failed")]
+	#[error("PoW validation error: preliminary verification failed")]
 	FailedPreliminaryVerify,
-	#[display(fmt = "Rejecting block too far in future")]
+	#[error("Rejecting block too far in future")]
 	TooFarInFuture,
-	#[display(fmt = "Fetching best header failed using select chain: {:?}", _0)]
+	#[error("Fetching best header failed using select chain: {0:?}")]
 	BestHeaderSelectChain(ConsensusError),
-	#[display(fmt = "Fetching best header failed: {:?}", _0)]
+	#[error("Fetching best header failed: {0:?}")]
 	BestHeader(sp_blockchain::Error),
-	#[display(fmt = "Best header does not exist")]
+	#[error("Best header does not exist")]
 	NoBestHeader,
-	#[display(fmt = "Block proposing error: {:?}", _0)]
+	#[error("Block proposing error: {0:?}")]
 	BlockProposingError(String),
-	#[display(fmt = "Fetch best hash failed via select chain: {:?}", _0)]
+	#[error("Fetch best hash failed via select chain: {0:?}")]
 	BestHashSelectChain(ConsensusError),
-	#[display(fmt = "Error with block built on {:?}: {:?}", _0, _1)]
+	#[error("Error with block built on {0:?}: {1:?}")]
 	BlockBuiltError(B::Hash, ConsensusError),
-	#[display(fmt = "Creating inherents failed: {}", _0)]
+	#[error("Creating inherents failed: {0}")]
 	CreateInherents(sp_inherents::Error),
-	#[display(fmt = "Checking inherents failed: {}", _0)]
+	#[error("Checking inherents failed: {0}")]
 	CheckInherents(sp_inherents::Error),
-	#[display(
-		fmt = "Checking inherents unknown error for identifier: {:?}",
-		"String::from_utf8_lossy(_0)"
+	#[error(
+		"Checking inherents unknown error for identifier: {:?}",
+		String::from_utf8_lossy(.0)
 	)]
 	CheckInherentsUnknownError(sp_inherents::InherentIdentifier),
-	#[display(fmt = "Multiple pre-runtime digests")]
+	#[error("Multiple pre-runtime digests")]
 	MultiplePreRuntimeDigests,
+	#[error(transparent)]
 	Client(sp_blockchain::Error),
+	#[error(transparent)]
 	Codec(codec::Error),
+	#[error("{0}")]
 	Environment(String),
+	#[error("{0}")]
 	Runtime(RuntimeString),
+	#[error("{0}")]
 	Other(String),
 }
 
diff --git a/substrate/client/executor/common/Cargo.toml b/substrate/client/executor/common/Cargo.toml
index 8e4b11f8f8f..104d24876d9 100644
--- a/substrate/client/executor/common/Cargo.toml
+++ b/substrate/client/executor/common/Cargo.toml
@@ -14,7 +14,6 @@ readme = "README.md"
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
-derive_more = "0.99.16"
 wasm-instrument = "0.1"
 codec = { package = "parity-scale-codec", version = "2.0.0" }
 wasmi = "0.9.1"
diff --git a/substrate/client/executor/common/src/error.rs b/substrate/client/executor/common/src/error.rs
index 90e658a8962..606f97317b9 100644
--- a/substrate/client/executor/common/src/error.rs
+++ b/substrate/client/executor/common/src/error.rs
@@ -125,28 +125,38 @@ impl From<String> for Error {
 }
 
 /// Type for errors occurring during Wasm runtime construction.
-#[derive(Debug, derive_more::Display)]
+#[derive(Debug, thiserror::Error)]
+#[allow(missing_docs)]
 pub enum WasmError {
-	/// Code could not be read from the state.
+	#[error("Code could not be read from the state.")]
 	CodeNotFound,
-	/// Failure to reinitialize runtime instance from snapshot.
+
+	#[error("Failure to reinitialize runtime instance from snapshot.")]
 	ApplySnapshotFailed,
+
 	/// Failure to erase the wasm memory.
 	///
 	/// Depending on the implementation might mean failure of allocating memory.
+	#[error("Failure to erase the wasm memory: {0}")]
 	ErasingFailed(String),
-	/// Wasm code failed validation.
+
+	#[error("Wasm code failed validation.")]
 	InvalidModule,
-	/// Wasm code could not be deserialized.
+
+	#[error("Wasm code could not be deserialized.")]
 	CantDeserializeWasm,
-	/// The module does not export a linear memory named `memory`.
+
+	#[error("The module does not export a linear memory named `memory`.")]
 	InvalidMemory,
-	/// The number of heap pages requested is disallowed by the module.
+
+	#[error("The number of heap pages requested is disallowed by the module.")]
 	InvalidHeapPages,
+
 	/// Instantiation error.
+	#[error("{0}")]
 	Instantiation(String),
+
 	/// Other error happenend.
+	#[error("{0}")]
 	Other(String),
 }
-
-impl std::error::Error for WasmError {}
diff --git a/substrate/client/finality-grandpa/Cargo.toml b/substrate/client/finality-grandpa/Cargo.toml
index 3f9261c0c17..2e6d3407a19 100644
--- a/substrate/client/finality-grandpa/Cargo.toml
+++ b/substrate/client/finality-grandpa/Cargo.toml
@@ -13,9 +13,8 @@ readme = "README.md"
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
 
-
 [dependencies]
-derive_more = "0.99.16"
+thiserror = "1.0"
 dyn-clone = "1.0"
 fork-tree = { version = "3.0.0", path = "../../utils/fork-tree" }
 futures = "0.3.9"
diff --git a/substrate/client/finality-grandpa/rpc/Cargo.toml b/substrate/client/finality-grandpa/rpc/Cargo.toml
index be6dfc371e4..39bf398fe31 100644
--- a/substrate/client/finality-grandpa/rpc/Cargo.toml
+++ b/substrate/client/finality-grandpa/rpc/Cargo.toml
@@ -23,7 +23,7 @@ futures = "0.3.16"
 serde = { version = "1.0.105", features = ["derive"] }
 serde_json = "1.0.50"
 log = "0.4.8"
-derive_more = "0.99.2"
+thiserror = "1.0"
 parity-scale-codec = { version = "2.0.0", features = ["derive"] }
 sc-client-api = { version = "4.0.0-dev", path = "../../api" }
 
diff --git a/substrate/client/finality-grandpa/rpc/src/error.rs b/substrate/client/finality-grandpa/rpc/src/error.rs
index 1c1361bcaed..845b4d99dcc 100644
--- a/substrate/client/finality-grandpa/rpc/src/error.rs
+++ b/substrate/client/finality-grandpa/rpc/src/error.rs
@@ -16,21 +16,21 @@
 // You should have received a copy of the GNU General Public License
 // along with this program. If not, see <https://www.gnu.org/licenses/>.
 
-#[derive(derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 /// Top-level error type for the RPC handler
 pub enum Error {
 	/// The GRANDPA RPC endpoint is not ready.
-	#[display(fmt = "GRANDPA RPC endpoint not ready")]
+	#[error("GRANDPA RPC endpoint not ready")]
 	EndpointNotReady,
 	/// GRANDPA reports the authority set id to be larger than 32-bits.
-	#[display(fmt = "GRANDPA reports authority set id unreasonably large")]
+	#[error("GRANDPA reports authority set id unreasonably large")]
 	AuthoritySetIdReportedAsUnreasonablyLarge,
 	/// GRANDPA reports voter state with round id or weights larger than 32-bits.
-	#[display(fmt = "GRANDPA reports voter state as unreasonably large")]
+	#[error("GRANDPA reports voter state as unreasonably large")]
 	VoterStateReportsUnreasonablyLargeNumbers,
 	/// GRANDPA prove finality failed.
-	#[display(fmt = "GRANDPA prove finality rpc failed: {}", _0)]
-	ProveFinalityFailed(sc_finality_grandpa::FinalityProofError),
+	#[error("GRANDPA prove finality rpc failed: {0}")]
+	ProveFinalityFailed(#[from] sc_finality_grandpa::FinalityProofError),
 }
 
 /// The error codes returned by jsonrpc.
diff --git a/substrate/client/finality-grandpa/src/authorities.rs b/substrate/client/finality-grandpa/src/authorities.rs
index aa8be83b952..033a1c4bbb2 100644
--- a/substrate/client/finality-grandpa/src/authorities.rs
+++ b/substrate/client/finality-grandpa/src/authorities.rs
@@ -32,23 +32,22 @@ use sp_finality_grandpa::{AuthorityId, AuthorityList};
 use crate::SetId;
 
 /// Error type returned on operations on the `AuthoritySet`.
-#[derive(Debug, derive_more::Display)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error<N, E> {
-	#[display(fmt = "Invalid authority set, either empty or with an authority weight set to 0.")]
+	#[error("Invalid authority set, either empty or with an authority weight set to 0.")]
 	InvalidAuthoritySet,
-	#[display(fmt = "Client error during ancestry lookup: {}", _0)]
+	#[error("Client error during ancestry lookup: {0}")]
 	Client(E),
-	#[display(fmt = "Duplicate authority set change.")]
+	#[error("Duplicate authority set change.")]
 	DuplicateAuthoritySetChange,
-	#[display(fmt = "Multiple pending forced authority set changes are not allowed.")]
+	#[error("Multiple pending forced authority set changes are not allowed.")]
 	MultiplePendingForcedAuthoritySetChanges,
-	#[display(
-		fmt = "A pending forced authority set change could not be applied since it must be applied \
-		after the pending standard change at #{}",
-		_0
+	#[error(
+		"A pending forced authority set change could not be applied since it must be applied \
+		after the pending standard change at #{0}"
 	)]
 	ForcedAuthoritySetChangeDependencyUnsatisfied(N),
-	#[display(fmt = "Invalid operation in the pending changes tree: {}", _0)]
+	#[error("Invalid operation in the pending changes tree: {0}")]
 	ForkTree(fork_tree::Error<E>),
 }
 
diff --git a/substrate/client/finality-grandpa/src/finality_proof.rs b/substrate/client/finality-grandpa/src/finality_proof.rs
index cc6853bee3b..03a4f2ff450 100644
--- a/substrate/client/finality-grandpa/src/finality_proof.rs
+++ b/substrate/client/finality-grandpa/src/finality_proof.rs
@@ -132,17 +132,18 @@ pub struct FinalityProof<Header: HeaderT> {
 }
 
 /// Errors occurring when trying to prove finality
-#[derive(Debug, derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 pub enum FinalityProofError {
 	/// The requested block has not yet been finalized.
-	#[display(fmt = "Block not yet finalized")]
+	#[error("Block not yet finalized")]
 	BlockNotYetFinalized,
 	/// The requested block is not covered by authority set changes. Likely this means the block is
 	/// in the latest authority set, and the subscription API is more appropriate.
-	#[display(fmt = "Block not covered by authority set changes")]
+	#[error("Block not covered by authority set changes")]
 	BlockNotInAuthoritySetChanges,
 	/// Errors originating from the client.
-	Client(sp_blockchain::Error),
+	#[error(transparent)]
+	Client(#[from] sp_blockchain::Error),
 }
 
 fn prove_finality<Block, B>(
diff --git a/substrate/client/finality-grandpa/src/warp_proof.rs b/substrate/client/finality-grandpa/src/warp_proof.rs
index 39d570d22bd..bdb8e36373d 100644
--- a/substrate/client/finality-grandpa/src/warp_proof.rs
+++ b/substrate/client/finality-grandpa/src/warp_proof.rs
@@ -34,26 +34,25 @@ use sp_runtime::{
 use std::{collections::HashMap, sync::Arc};
 
 /// Warp proof processing error.
-#[derive(Debug, derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error {
 	/// Decoding error.
-	#[display(fmt = "Failed to decode block hash: {}.", _0)]
-	DecodeScale(codec::Error),
+	#[error("Failed to decode block hash: {0}.")]
+	DecodeScale(#[from] codec::Error),
 	/// Client backend error.
-	Client(sp_blockchain::Error),
+	#[error("{0}")]
+	Client(#[from] sp_blockchain::Error),
 	/// Invalid request data.
-	#[from(ignore)]
+	#[error("{0}")]
 	InvalidRequest(String),
 	/// Invalid warp proof.
-	#[from(ignore)]
+	#[error("{0}")]
 	InvalidProof(String),
 	/// Missing header or authority set change data.
-	#[display(fmt = "Missing required data to be able to answer request.")]
+	#[error("Missing required data to be able to answer request.")]
 	MissingData,
 }
 
-impl std::error::Error for Error {}
-
 /// The maximum size in bytes of the `WarpSyncProof`.
 pub(super) const MAX_WARP_SYNC_PROOF_SIZE: usize = 8 * 1024 * 1024;
 
diff --git a/substrate/client/keystore/Cargo.toml b/substrate/client/keystore/Cargo.toml
index 7fe9e182efb..56d4ee0d556 100644
--- a/substrate/client/keystore/Cargo.toml
+++ b/substrate/client/keystore/Cargo.toml
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 async-trait = "0.1.50"
-derive_more = "0.99.16"
+thiserror = "1.0"
 sp-application-crypto = { version = "4.0.0", path = "../../primitives/application-crypto" }
 sp-core = { version = "4.1.0-dev", path = "../../primitives/core" }
 sp-keystore = { version = "0.10.0", path = "../../primitives/keystore" }
diff --git a/substrate/client/keystore/src/lib.rs b/substrate/client/keystore/src/lib.rs
index 359326bb4ca..cf94a16f08d 100644
--- a/substrate/client/keystore/src/lib.rs
+++ b/substrate/client/keystore/src/lib.rs
@@ -28,29 +28,31 @@ mod local;
 pub use local::LocalKeystore;
 
 /// Keystore error.
-#[derive(Debug, derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error {
 	/// IO error.
-	Io(io::Error),
+	#[error(transparent)]
+	Io(#[from] io::Error),
 	/// JSON error.
-	Json(serde_json::Error),
+	#[error(transparent)]
+	Json(#[from] serde_json::Error),
 	/// Invalid password.
-	#[display(
-		fmt = "Requested public key and public key of the loaded private key do not match. \n
+	#[error(
+		"Requested public key and public key of the loaded private key do not match. \n
 			This means either that the keystore password is incorrect or that the private key was stored under a wrong public key."
 	)]
 	PublicKeyMismatch,
 	/// Invalid BIP39 phrase
-	#[display(fmt = "Invalid recovery phrase (BIP39) data")]
+	#[error("Invalid recovery phrase (BIP39) data")]
 	InvalidPhrase,
 	/// Invalid seed
-	#[display(fmt = "Invalid seed")]
+	#[error("Invalid seed")]
 	InvalidSeed,
 	/// Public key type is not supported
-	#[display(fmt = "Key crypto type is not supported")]
+	#[error("Key crypto type is not supported")]
 	KeyNotSupported(KeyTypeId),
 	/// Keystore unavailable
-	#[display(fmt = "Keystore unavailable")]
+	#[error("Keystore unavailable")]
 	Unavailable,
 }
 
@@ -69,13 +71,3 @@ impl From<Error> for TraitError {
 		}
 	}
 }
-
-impl std::error::Error for Error {
-	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-		match self {
-			Error::Io(ref err) => Some(err),
-			Error::Json(ref err) => Some(err),
-			_ => None,
-		}
-	}
-}
diff --git a/substrate/client/network/Cargo.toml b/substrate/client/network/Cargo.toml
index f378b75990c..354991b32ba 100644
--- a/substrate/client/network/Cargo.toml
+++ b/substrate/client/network/Cargo.toml
@@ -25,7 +25,6 @@ bytes = "1"
 codec = { package = "parity-scale-codec", version = "2.0.0", features = [
     "derive",
 ] }
-derive_more = "0.99.16"
 either = "1.5.3"
 fnv = "1.0.6"
 fork-tree = { version = "3.0.0", path = "../../utils/fork-tree" }
@@ -57,7 +56,7 @@ sp-core = { version = "4.1.0-dev", path = "../../primitives/core" }
 sp-runtime = { version = "4.1.0-dev", path = "../../primitives/runtime" }
 sc-utils = { version = "4.0.0-dev", path = "../utils" }
 sp-finality-grandpa = { version = "4.0.0-dev", path = "../../primitives/finality-grandpa" }
-thiserror = "1"
+thiserror = "1.0"
 unsigned-varint = { version = "0.6.0", features = [
     "futures",
     "asynchronous_codec",
diff --git a/substrate/client/network/src/bitswap.rs b/substrate/client/network/src/bitswap.rs
index e6cb1d9d79e..e7c37968b5f 100644
--- a/substrate/client/network/src/bitswap.rs
+++ b/substrate/client/network/src/bitswap.rs
@@ -313,21 +313,29 @@ impl<B: BlockT> NetworkBehaviour for Bitswap<B> {
 }
 
 /// Bitswap protocol error.
-#[derive(derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 pub enum BitswapError {
 	/// Protobuf decoding error.
-	#[display(fmt = "Failed to decode request: {}.", _0)]
-	DecodeProto(prost::DecodeError),
+	#[error("Failed to decode request: {0}.")]
+	DecodeProto(#[from] prost::DecodeError),
+
 	/// Protobuf encoding error.
-	#[display(fmt = "Failed to encode response: {}.", _0)]
-	EncodeProto(prost::EncodeError),
+	#[error("Failed to encode response: {0}.")]
+	EncodeProto(#[from] prost::EncodeError),
+
 	/// Client backend error.
-	Client(sp_blockchain::Error),
+	#[error(transparent)]
+	Client(#[from] sp_blockchain::Error),
+
 	/// Error parsing CID
-	BadCid(cid::Error),
+	#[error(transparent)]
+	BadCid(#[from] cid::Error),
+
 	/// Packet read error.
-	Read(io::Error),
+	#[error(transparent)]
+	Read(#[from] io::Error),
+
 	/// Error sending response.
-	#[display(fmt = "Failed to send response.")]
+	#[error("Failed to send response.")]
 	SendResponse,
 }
diff --git a/substrate/client/network/src/block_request_handler.rs b/substrate/client/network/src/block_request_handler.rs
index 9d963480a7e..2f17cdac074 100644
--- a/substrate/client/network/src/block_request_handler.rs
+++ b/substrate/client/network/src/block_request_handler.rs
@@ -379,19 +379,20 @@ impl<B: BlockT> BlockRequestHandler<B> {
 	}
 }
 
-#[derive(derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 enum HandleRequestError {
-	#[display(fmt = "Failed to decode request: {}.", _0)]
-	DecodeProto(prost::DecodeError),
-	#[display(fmt = "Failed to encode response: {}.", _0)]
-	EncodeProto(prost::EncodeError),
-	#[display(fmt = "Failed to decode block hash: {}.", _0)]
-	DecodeScale(codec::Error),
-	#[display(fmt = "Missing `BlockRequest::from_block` field.")]
+	#[error("Failed to decode request: {0}.")]
+	DecodeProto(#[from] prost::DecodeError),
+	#[error("Failed to encode response: {0}.")]
+	EncodeProto(#[from] prost::EncodeError),
+	#[error("Failed to decode block hash: {0}.")]
+	DecodeScale(#[from] codec::Error),
+	#[error("Missing `BlockRequest::from_block` field.")]
 	MissingFromField,
-	#[display(fmt = "Failed to parse BlockRequest::direction.")]
+	#[error("Failed to parse BlockRequest::direction.")]
 	ParseDirection,
-	Client(sp_blockchain::Error),
-	#[display(fmt = "Failed to send response.")]
+	#[error(transparent)]
+	Client(#[from] sp_blockchain::Error),
+	#[error("Failed to send response.")]
 	SendResponse,
 }
diff --git a/substrate/client/network/src/error.rs b/substrate/client/network/src/error.rs
index 1dafddd7bcc..716235193a8 100644
--- a/substrate/client/network/src/error.rs
+++ b/substrate/client/network/src/error.rs
@@ -27,18 +27,18 @@ use std::{borrow::Cow, fmt};
 pub type Result<T> = std::result::Result<T, Error>;
 
 /// Error type for the network.
-#[derive(derive_more::Display, derive_more::From)]
+#[derive(thiserror::Error)]
 pub enum Error {
 	/// Io error
-	Io(std::io::Error),
+	#[error(transparent)]
+	Io(#[from] std::io::Error),
+
 	/// Client error
-	Client(Box<sp_blockchain::Error>),
+	#[error(transparent)]
+	Client(#[from] Box<sp_blockchain::Error>),
 	/// The same bootnode (based on address) is registered with two different peer ids.
-	#[display(
-		fmt = "The same bootnode (`{}`) is registered with two different peer ids: `{}` and `{}`",
-		address,
-		first_id,
-		second_id
+	#[error(
+		"The same bootnode (`{address}`) is registered with two different peer ids: `{first_id}` and `{second_id}`"
 	)]
 	DuplicateBootnode {
 		/// The address of the bootnode.
@@ -49,11 +49,11 @@ pub enum Error {
 		second_id: PeerId,
 	},
 	/// Prometheus metrics error.
-	Prometheus(prometheus_endpoint::PrometheusError),
+	#[error(transparent)]
+	Prometheus(#[from] prometheus_endpoint::PrometheusError),
 	/// The network addresses are invalid because they don't match the transport.
-	#[display(
-		fmt = "The following addresses are invalid because they don't match the transport: {:?}",
-		addresses
+	#[error(
+		"The following addresses are invalid because they don't match the transport: {addresses:?}"
 	)]
 	AddressesForAnotherTransport {
 		/// Transport used.
@@ -62,7 +62,7 @@ pub enum Error {
 		addresses: Vec<Multiaddr>,
 	},
 	/// The same request-response protocol has been registered multiple times.
-	#[display(fmt = "Request-response protocol registered multiple times: {}", protocol)]
+	#[error("Request-response protocol registered multiple times: {protocol}")]
 	DuplicateRequestResponseProtocol {
 		/// Name of the protocol registered multiple times.
 		protocol: Cow<'static, str>,
@@ -75,16 +75,3 @@ impl fmt::Debug for Error {
 		fmt::Display::fmt(self, f)
 	}
 }
-
-impl std::error::Error for Error {
-	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-		match self {
-			Self::Io(ref err) => Some(err),
-			Self::Client(ref err) => Some(err),
-			Self::Prometheus(ref err) => Some(err),
-			Self::DuplicateBootnode { .. } |
-			Self::AddressesForAnotherTransport { .. } |
-			Self::DuplicateRequestResponseProtocol { .. } => None,
-		}
-	}
-}
diff --git a/substrate/client/network/src/light_client_requests/handler.rs b/substrate/client/network/src/light_client_requests/handler.rs
index b5c6ccb196d..fb258304f2e 100644
--- a/substrate/client/network/src/light_client_requests/handler.rs
+++ b/substrate/client/network/src/light_client_requests/handler.rs
@@ -284,20 +284,20 @@ impl<B: Block> LightClientRequestHandler<B> {
 	}
 }
 
-#[derive(derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 enum HandleRequestError {
-	#[display(fmt = "Failed to decode request: {}.", _0)]
-	DecodeProto(prost::DecodeError),
-	#[display(fmt = "Failed to encode response: {}.", _0)]
-	EncodeProto(prost::EncodeError),
-	#[display(fmt = "Failed to send response.")]
+	#[error("Failed to decode request: {0}.")]
+	DecodeProto(#[from] prost::DecodeError),
+	#[error("Failed to encode response: {0}.")]
+	EncodeProto(#[from] prost::EncodeError),
+	#[error("Failed to send response.")]
 	SendResponse,
 	/// A bad request has been received.
-	#[display(fmt = "bad request: {}", _0)]
+	#[error("bad request: {0}")]
 	BadRequest(&'static str),
 	/// Encoding or decoding of some data failed.
-	#[display(fmt = "codec error: {}", _0)]
-	Codec(codec::Error),
+	#[error("codec error: {0}")]
+	Codec(#[from] codec::Error),
 }
 
 fn fmt_keys(first: Option<&Vec<u8>>, last: Option<&Vec<u8>>) -> String {
diff --git a/substrate/client/network/src/protocol/notifications/handler.rs b/substrate/client/network/src/protocol/notifications/handler.rs
index 158ab2ae379..91225f54203 100644
--- a/substrate/client/network/src/protocol/notifications/handler.rs
+++ b/substrate/client/network/src/protocol/notifications/handler.rs
@@ -457,9 +457,9 @@ impl<'a> Ready<'a> {
 }
 
 /// Error specific to the collection of protocols.
-#[derive(Debug, derive_more::Display, derive_more::Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum NotifsHandlerError {
-	/// Channel of synchronous notifications is full.
+	#[error("Channel of synchronous notifications is full.")]
 	SyncNotificationsClogged,
 }
 
diff --git a/substrate/client/network/src/protocol/notifications/upgrade/notifications.rs b/substrate/client/network/src/protocol/notifications/upgrade/notifications.rs
index 5171d459fa4..53270975a5b 100644
--- a/substrate/client/network/src/protocol/notifications/upgrade/notifications.rs
+++ b/substrate/client/network/src/protocol/notifications/upgrade/notifications.rs
@@ -457,13 +457,14 @@ where
 }
 
 /// Error generated by sending on a notifications out substream.
-#[derive(Debug, derive_more::From, derive_more::Display)]
+#[derive(Debug, thiserror::Error)]
 pub enum NotificationsHandshakeError {
 	/// I/O error on the substream.
-	Io(io::Error),
+	#[error(transparent)]
+	Io(#[from] io::Error),
 
 	/// Initial message or handshake was too large.
-	#[display(fmt = "Initial message or handshake was too large: {}", requested)]
+	#[error("Initial message or handshake was too large: {requested}")]
 	TooLarge {
 		/// Size requested by the remote.
 		requested: usize,
@@ -472,7 +473,8 @@ pub enum NotificationsHandshakeError {
 	},
 
 	/// Error while decoding the variable-length integer.
-	VarintDecode(unsigned_varint::decode::Error),
+	#[error(transparent)]
+	VarintDecode(#[from] unsigned_varint::decode::Error),
 }
 
 impl From<unsigned_varint::io::ReadError> for NotificationsHandshakeError {
@@ -489,10 +491,11 @@ impl From<unsigned_varint::io::ReadError> for NotificationsHandshakeError {
 }
 
 /// Error generated by sending on a notifications out substream.
-#[derive(Debug, derive_more::From, derive_more::Display)]
+#[derive(Debug, thiserror::Error)]
 pub enum NotificationsOutError {
 	/// I/O error on the substream.
-	Io(io::Error),
+	#[error(transparent)]
+	Io(#[from] io::Error),
 }
 
 #[cfg(test)]
diff --git a/substrate/client/network/src/request_responses.rs b/substrate/client/network/src/request_responses.rs
index 24b3d3df00b..58007c7bc5c 100644
--- a/substrate/client/network/src/request_responses.rs
+++ b/substrate/client/network/src/request_responses.rs
@@ -884,34 +884,35 @@ impl NetworkBehaviour for RequestResponsesBehaviour {
 }
 
 /// Error when registering a protocol.
-#[derive(Debug, derive_more::Display, derive_more::Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum RegisterError {
 	/// A protocol has been specified multiple times.
-	DuplicateProtocol(#[error(ignore)] Cow<'static, str>),
+	#[error("{0}")]
+	DuplicateProtocol(Cow<'static, str>),
 }
 
 /// Error in a request.
-#[derive(Debug, derive_more::Display, derive_more::Error)]
+#[derive(Debug, thiserror::Error)]
+#[allow(missing_docs)]
 pub enum RequestFailure {
-	/// We are not currently connected to the requested peer.
+	#[error("We are not currently connected to the requested peer.")]
 	NotConnected,
-	/// Given protocol hasn't been registered.
+	#[error("Given protocol hasn't been registered.")]
 	UnknownProtocol,
-	/// Remote has closed the substream before answering, thereby signaling that it considers the
-	/// request as valid, but refused to answer it.
+	#[error("Remote has closed the substream before answering, thereby signaling that it considers the request as valid, but refused to answer it.")]
 	Refused,
-	/// The remote replied, but the local node is no longer interested in the response.
+	#[error("The remote replied, but the local node is no longer interested in the response.")]
 	Obsolete,
 	/// Problem on the network.
-	#[display(fmt = "Problem on the network: {}", _0)]
+	#[error("Problem on the network: {0}")]
 	Network(OutboundFailure),
 }
 
 /// Error when processing a request sent by a remote.
-#[derive(Debug, derive_more::Display, derive_more::Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum ResponseFailure {
 	/// Problem on the network.
-	#[display(fmt = "Problem on the network: {}", _0)]
+	#[error("Problem on the network: {0}")]
 	Network(InboundFailure),
 }
 
diff --git a/substrate/client/network/src/service.rs b/substrate/client/network/src/service.rs
index 9c8c58ef49e..b6a1d3c88e7 100644
--- a/substrate/client/network/src/service.rs
+++ b/substrate/client/network/src/service.rs
@@ -1391,7 +1391,7 @@ impl<'a> NotificationSenderReady<'a> {
 }
 
 /// Error returned by [`NetworkService::send_notification`].
-#[derive(Debug, derive_more::Display, derive_more::Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum NotificationSenderError {
 	/// The notification receiver has been closed, usually because the underlying connection
 	/// closed.
@@ -1399,8 +1399,10 @@ pub enum NotificationSenderError {
 	/// Some of the notifications most recently sent may not have been received. However,
 	/// the peer may still be connected and a new `NotificationSender` for the same
 	/// protocol obtained from [`NetworkService::notification_sender`].
+	#[error("The notification receiver has been closed")]
 	Closed,
 	/// Protocol name hasn't been registered.
+	#[error("Protocol name hasn't been registered")]
 	BadProtocol,
 }
 
diff --git a/substrate/client/network/src/state_request_handler.rs b/substrate/client/network/src/state_request_handler.rs
index 89f1f2b363c..10a77061a03 100644
--- a/substrate/client/network/src/state_request_handler.rs
+++ b/substrate/client/network/src/state_request_handler.rs
@@ -241,15 +241,20 @@ impl<B: BlockT> StateRequestHandler<B> {
 	}
 }
 
-#[derive(derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 enum HandleRequestError {
-	#[display(fmt = "Failed to decode request: {}.", _0)]
-	DecodeProto(prost::DecodeError),
-	#[display(fmt = "Failed to encode response: {}.", _0)]
-	EncodeProto(prost::EncodeError),
-	#[display(fmt = "Failed to decode block hash: {}.", _0)]
-	InvalidHash(codec::Error),
-	Client(sp_blockchain::Error),
-	#[display(fmt = "Failed to send response.")]
+	#[error("Failed to decode request: {0}.")]
+	DecodeProto(#[from] prost::DecodeError),
+
+	#[error("Failed to encode response: {0}.")]
+	EncodeProto(#[from] prost::EncodeError),
+
+	#[error("Failed to decode block hash: {0}.")]
+	InvalidHash(#[from] codec::Error),
+
+	#[error(transparent)]
+	Client(#[from] sp_blockchain::Error),
+
+	#[error("Failed to send response.")]
 	SendResponse,
 }
diff --git a/substrate/client/network/src/warp_request_handler.rs b/substrate/client/network/src/warp_request_handler.rs
index ca5a93b752b..4c839825ff5 100644
--- a/substrate/client/network/src/warp_request_handler.rs
+++ b/substrate/client/network/src/warp_request_handler.rs
@@ -149,18 +149,23 @@ impl<TBlock: BlockT> RequestHandler<TBlock> {
 	}
 }
 
-#[derive(Debug, derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 enum HandleRequestError {
-	#[display(fmt = "Failed to decode request: {}.", _0)]
-	DecodeProto(prost::DecodeError),
-	#[display(fmt = "Failed to encode response: {}.", _0)]
-	EncodeProto(prost::EncodeError),
-	#[display(fmt = "Failed to decode block hash: {}.", _0)]
-	DecodeScale(codec::Error),
-	Client(sp_blockchain::Error),
-	#[from(ignore)]
-	#[display(fmt = "Invalid request {}.", _0)]
-	InvalidRequest(Box<dyn std::error::Error + Send + Sync>),
-	#[display(fmt = "Failed to send response.")]
+	#[error("Failed to decode request: {0}.")]
+	DecodeProto(#[from] prost::DecodeError),
+
+	#[error("Failed to encode response: {0}.")]
+	EncodeProto(#[from] prost::EncodeError),
+
+	#[error("Failed to decode block hash: {0}.")]
+	DecodeScale(#[from] codec::Error),
+
+	#[error(transparent)]
+	Client(#[from] sp_blockchain::Error),
+
+	#[error("Invalid request {0}.")]
+	InvalidRequest(#[from] Box<dyn std::error::Error + Send + Sync>),
+
+	#[error("Failed to send response.")]
 	SendResponse,
 }
diff --git a/substrate/client/transaction-pool/api/Cargo.toml b/substrate/client/transaction-pool/api/Cargo.toml
index 95b82e26fc5..a544248a4f2 100644
--- a/substrate/client/transaction-pool/api/Cargo.toml
+++ b/substrate/client/transaction-pool/api/Cargo.toml
@@ -9,11 +9,10 @@ repository = "https://github.com/paritytech/substrate/"
 description = "Transaction pool client facing API."
 
 [dependencies]
-futures = { version = "0.3.1"  }
-log = { version = "0.4.8" }
+futures = "0.3.1"
+log = "0.4.8"
 serde = { version = "1.0.132", features = ["derive"] }
-thiserror = { version = "1.0.30" }
-sp-runtime = { version = "4.1.0-dev", default-features = false, path = "../../../primitives/runtime" }
+thiserror = "1.0.30"
 
-derive_more = { version = "0.99.16" }
+sp-runtime = { version = "4.1.0-dev", default-features = false, path = "../../../primitives/runtime" }
 sp-blockchain = { version = "4.0.0-dev", path = "../../../primitives/blockchain" }
diff --git a/substrate/client/transaction-pool/api/src/error.rs b/substrate/client/transaction-pool/api/src/error.rs
index f1ac2798e62..b093657f739 100644
--- a/substrate/client/transaction-pool/api/src/error.rs
+++ b/substrate/client/transaction-pool/api/src/error.rs
@@ -26,7 +26,7 @@ use sp_runtime::transaction_validity::{
 pub type Result<T> = std::result::Result<T, Error>;
 
 /// Transaction pool error type.
-#[derive(Debug, thiserror::Error, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 #[allow(missing_docs)]
 pub enum Error {
 	#[error("Unknown transaction validity: {0:?}")]
@@ -64,7 +64,6 @@ pub enum Error {
 	#[error("Transaction cannot be propagated and the local node does not author blocks")]
 	Unactionable,
 
-	#[from(ignore)]
 	#[error("{0}")]
 	InvalidBlockId(String),
 
diff --git a/substrate/client/transaction-pool/src/lib.rs b/substrate/client/transaction-pool/src/lib.rs
index 2d07815e4ba..b5af2d12d65 100644
--- a/substrate/client/transaction-pool/src/lib.rs
+++ b/substrate/client/transaction-pool/src/lib.rs
@@ -47,8 +47,8 @@ use std::{
 
 use graph::{ExtrinsicHash, IsValidator};
 use sc_transaction_pool_api::{
-	ChainEvent, ImportNotificationStream, MaintainedTransactionPool, PoolFuture, PoolStatus,
-	ReadyTransactions, TransactionFor, TransactionPool, TransactionSource,
+	error::Error as TxPoolError, ChainEvent, ImportNotificationStream, MaintainedTransactionPool,
+	PoolFuture, PoolStatus, ReadyTransactions, TransactionFor, TransactionPool, TransactionSource,
 	TransactionStatusStreamFor, TxHash,
 };
 use sp_core::traits::SpawnEssentialNamed;
@@ -418,8 +418,8 @@ where
 			.validate_transaction_blocking(at, TransactionSource::Local, xt.clone())?
 			.map_err(|e| {
 				Self::Error::Pool(match e {
-					TransactionValidityError::Invalid(i) => i.into(),
-					TransactionValidityError::Unknown(u) => u.into(),
+					TransactionValidityError::Invalid(i) => TxPoolError::InvalidTransaction(i),
+					TransactionValidityError::Unknown(u) => TxPoolError::UnknownTransaction(u),
 				})
 			})?;
 
diff --git a/substrate/primitives/keystore/Cargo.toml b/substrate/primitives/keystore/Cargo.toml
index e918f5d2c6d..28802cbec35 100644
--- a/substrate/primitives/keystore/Cargo.toml
+++ b/substrate/primitives/keystore/Cargo.toml
@@ -14,13 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
 async-trait = "0.1.50"
-derive_more = "0.99.16"
+futures = "0.3.1"
+parking_lot = { version = "0.11.2", default-features = false }
+serde = { version = "1.0", optional = true }
+thiserror = "1.0"
+
 codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
-futures = { version = "0.3.1" }
 schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false }
 merlin = { version = "2.0", default-features = false }
-parking_lot = { version = "0.11.2", default-features = false }
-serde = { version = "1.0", optional = true}
 sp-core = { version = "4.1.0-dev", path = "../core" }
 sp-externalities = { version = "0.10.0", path = "../externalities", default-features = false }
 
@@ -28,7 +29,6 @@ sp-externalities = { version = "0.10.0", path = "../externalities", default-feat
 rand = "0.7.2"
 rand_chacha = "0.2.2"
 
-
 [features]
 default = ["std"]
 std = [
diff --git a/substrate/primitives/keystore/src/lib.rs b/substrate/primitives/keystore/src/lib.rs
index 6c27e3df7ce..6540e71bc3f 100644
--- a/substrate/primitives/keystore/src/lib.rs
+++ b/substrate/primitives/keystore/src/lib.rs
@@ -29,19 +29,19 @@ use sp_core::{
 use std::sync::Arc;
 
 /// CryptoStore error
-#[derive(Debug, derive_more::Display)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error {
 	/// Public key type is not supported
-	#[display(fmt = "Key not supported: {:?}", _0)]
+	#[error("Key not supported: {0:?}")]
 	KeyNotSupported(KeyTypeId),
 	/// Validation error
-	#[display(fmt = "Validation error: {}", _0)]
+	#[error("Validation error: {0}")]
 	ValidationError(String),
 	/// Keystore unavailable
-	#[display(fmt = "Keystore unavailable")]
+	#[error("Keystore unavailable")]
 	Unavailable,
 	/// Programming errors
-	#[display(fmt = "An unknown keystore error occurred: {}", _0)]
+	#[error("An unknown keystore error occurred: {0}")]
 	Other(String),
 }
 
diff --git a/substrate/test-utils/runtime/transaction-pool/Cargo.toml b/substrate/test-utils/runtime/transaction-pool/Cargo.toml
index 39221a2d157..2a94f248458 100644
--- a/substrate/test-utils/runtime/transaction-pool/Cargo.toml
+++ b/substrate/test-utils/runtime/transaction-pool/Cargo.toml
@@ -20,4 +20,4 @@ sp-runtime = { version = "4.1.0-dev", path = "../../../primitives/runtime" }
 sc-transaction-pool = { version = "4.0.0-dev", path = "../../../client/transaction-pool" }
 sc-transaction-pool-api = { version = "4.0.0-dev", path = "../../../client/transaction-pool/api" }
 futures = "0.3.16"
-derive_more = "0.99.16"
+thiserror = "1.0"
diff --git a/substrate/test-utils/runtime/transaction-pool/src/lib.rs b/substrate/test-utils/runtime/transaction-pool/src/lib.rs
index ba317f57f53..40084276234 100644
--- a/substrate/test-utils/runtime/transaction-pool/src/lib.rs
+++ b/substrate/test-utils/runtime/transaction-pool/src/lib.rs
@@ -40,8 +40,9 @@ use substrate_test_runtime_client::{
 };
 
 /// Error type used by [`TestApi`].
-#[derive(Debug, derive_more::From, derive_more::Display)]
-pub struct Error(sc_transaction_pool_api::error::Error);
+#[derive(Debug, thiserror::Error)]
+#[error(transparent)]
+pub struct Error(#[from] sc_transaction_pool_api::error::Error);
 
 impl sc_transaction_pool_api::error::IntoPoolError for Error {
 	fn into_pool_error(self) -> Result<sc_transaction_pool_api::error::Error, Self> {
@@ -49,12 +50,6 @@ impl sc_transaction_pool_api::error::IntoPoolError for Error {
 	}
 }
 
-impl std::error::Error for Error {
-	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-		Some(&self.0)
-	}
-}
-
 pub enum IsBestBlock {
 	Yes,
 	No,
diff --git a/substrate/utils/prometheus/Cargo.toml b/substrate/utils/prometheus/Cargo.toml
index 4ae38f64553..27b5f94305f 100644
--- a/substrate/utils/prometheus/Cargo.toml
+++ b/substrate/utils/prometheus/Cargo.toml
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 log = "0.4.8"
 prometheus = { version = "0.13.0", default-features = false }
 futures-util = { version = "0.3.19", default-features = false, features = ["io"] }
-derive_more = "0.99"
+thiserror = "1.0"
 async-std = { version = "1.10.0", features = ["unstable"] }
 tokio = "1.15"
 hyper = { version = "0.14.16", default-features = false, features = ["http1", "server", "tcp"] }
diff --git a/substrate/utils/prometheus/src/lib.rs b/substrate/utils/prometheus/src/lib.rs
index f1d87ac9f72..3d28d9cd6f1 100644
--- a/substrate/utils/prometheus/src/lib.rs
+++ b/substrate/utils/prometheus/src/lib.rs
@@ -47,27 +47,22 @@ pub fn register<T: Clone + Collector + 'static>(
 	Ok(metric)
 }
 
-#[derive(Debug, derive_more::Display, derive_more::From)]
+#[derive(Debug, thiserror::Error)]
 pub enum Error {
 	/// Hyper internal error.
-	Hyper(hyper::Error),
+	#[error(transparent)]
+	Hyper(#[from] hyper::Error),
+
 	/// Http request error.
-	Http(hyper::http::Error),
+	#[error(transparent)]
+	Http(#[from] hyper::http::Error),
+
 	/// i/o error.
-	Io(std::io::Error),
-	#[display(fmt = "Prometheus port {} already in use.", _0)]
-	PortInUse(SocketAddr),
-}
+	#[error(transparent)]
+	Io(#[from] std::io::Error),
 
-impl std::error::Error for Error {
-	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-		match self {
-			Error::Hyper(error) => Some(error),
-			Error::Http(error) => Some(error),
-			Error::Io(error) => Some(error),
-			Error::PortInUse(_) => None,
-		}
-	}
+	#[error("Prometheus port {0} already in use.")]
+	PortInUse(SocketAddr),
 }
 
 async fn request_metrics(req: Request<Body>, registry: Registry) -> Result<Response<Body>, Error> {
-- 
GitLab