From 6d5f0a1f1df62eff30bc67ce1cd111cf0c8c1f41 Mon Sep 17 00:00:00 2001
From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
Date: Mon, 31 Jul 2023 10:26:13 +0300
Subject: [PATCH] chainHead: Sync events with spec (#14654)

* chainHead/events: Remove network config

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/events: Add events for operations

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/tests: Test chainHead events serialize/deserialize

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/events: Remove generics from the storage event

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/events: Rename kebab-case to camelCase

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/events: Add methodResponse object

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
---
 .../client/rpc-spec-v2/src/chain_head/api.rs  |  11 +-
 .../rpc-spec-v2/src/chain_head/chain_head.rs  |  12 +-
 .../src/chain_head/chain_head_storage.rs      |  20 +-
 .../rpc-spec-v2/src/chain_head/event.rs       | 351 ++++++++++++++----
 .../client/rpc-spec-v2/src/chain_head/mod.rs  |   2 +-
 .../rpc-spec-v2/src/chain_head/tests.rs       |  56 +--
 6 files changed, 328 insertions(+), 124 deletions(-)

diff --git a/substrate/client/rpc-spec-v2/src/chain_head/api.rs b/substrate/client/rpc-spec-v2/src/chain_head/api.rs
index 8347617279c..8905e036877 100644
--- a/substrate/client/rpc-spec-v2/src/chain_head/api.rs
+++ b/substrate/client/rpc-spec-v2/src/chain_head/api.rs
@@ -19,7 +19,7 @@
 #![allow(non_snake_case)]
 
 //! API trait of the chain head.
-use crate::chain_head::event::{ChainHeadEvent, FollowEvent, NetworkConfig, StorageQuery};
+use crate::chain_head::event::{ChainHeadEvent, FollowEvent, StorageQuery};
 use jsonrpsee::{core::RpcResult, proc_macros::rpc};
 
 #[rpc(client, server)]
@@ -52,12 +52,7 @@ pub trait ChainHeadApi<Hash> {
 		unsubscribe = "chainHead_unstable_stopBody",
 		item = ChainHeadEvent<String>,
 	)]
-	fn chain_head_unstable_body(
-		&self,
-		follow_subscription: String,
-		hash: Hash,
-		network_config: Option<NetworkConfig>,
-	);
+	fn chain_head_unstable_body(&self, follow_subscription: String, hash: Hash);
 
 	/// Retrieves the header of a pinned block.
 	///
@@ -102,7 +97,6 @@ pub trait ChainHeadApi<Hash> {
 		hash: Hash,
 		items: Vec<StorageQuery<String>>,
 		child_trie: Option<String>,
-		network_config: Option<NetworkConfig>,
 	);
 
 	/// Call into the Runtime API at a specified block's state.
@@ -121,7 +115,6 @@ pub trait ChainHeadApi<Hash> {
 		hash: Hash,
 		function: String,
 		call_parameters: String,
-		network_config: Option<NetworkConfig>,
 	);
 
 	/// Unpin a block reported by the `follow` method.
diff --git a/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs b/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs
index 7f34bde6886..a2c9afc0349 100644
--- a/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs
+++ b/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs
@@ -23,7 +23,7 @@ use crate::{
 		api::ChainHeadApiServer,
 		chain_head_follow::ChainHeadFollower,
 		error::Error as ChainHeadRpcError,
-		event::{ChainHeadEvent, ChainHeadResult, ErrorEvent, FollowEvent, NetworkConfig},
+		event::{ChainHeadEvent, ChainHeadResult, ErrorEvent, FollowEvent},
 		hex_string,
 		subscription::{SubscriptionManagement, SubscriptionManagementError},
 	},
@@ -205,7 +205,6 @@ where
 		mut sink: SubscriptionSink,
 		follow_subscription: String,
 		hash: Block::Hash,
-		_network_config: Option<NetworkConfig>,
 	) -> SubscriptionResult {
 		let client = self.client.clone();
 		let subscriptions = self.subscriptions.clone();
@@ -294,7 +293,6 @@ where
 		hash: Block::Hash,
 		items: Vec<StorageQuery<String>>,
 		child_trie: Option<String>,
-		_network_config: Option<NetworkConfig>,
 	) -> SubscriptionResult {
 		// Gain control over parameter parsing and returned error.
 		let items = items
@@ -327,7 +325,7 @@ where
 			Ok(block) => block,
 			Err(SubscriptionManagementError::SubscriptionAbsent) => {
 				// Invalid invalid subscription ID.
-				let _ = sink.send(&ChainHeadStorageEvent::<String>::Disjoint);
+				let _ = sink.send(&ChainHeadStorageEvent::Disjoint);
 				return Ok(())
 			},
 			Err(SubscriptionManagementError::BlockHashAbsent) => {
@@ -336,9 +334,8 @@ where
 				return Ok(())
 			},
 			Err(error) => {
-				let _ = sink.send(&ChainHeadStorageEvent::<String>::Error(ErrorEvent {
-					error: error.to_string(),
-				}));
+				let _ = sink
+					.send(&ChainHeadStorageEvent::Error(ErrorEvent { error: error.to_string() }));
 				return Ok(())
 			},
 		};
@@ -362,7 +359,6 @@ where
 		hash: Block::Hash,
 		function: String,
 		call_parameters: String,
-		_network_config: Option<NetworkConfig>,
 	) -> SubscriptionResult {
 		let call_parameters = Bytes::from(parse_hex_param(&mut sink, call_parameters)?);
 
diff --git a/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs b/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs
index 310e4890187..df1600628de 100644
--- a/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs
+++ b/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs
@@ -70,10 +70,10 @@ fn is_key_queryable(key: &[u8]) -> bool {
 }
 
 /// The result of making a query call.
-type QueryResult = Result<Option<StorageResult<String>>, ChainHeadStorageEvent<String>>;
+type QueryResult = Result<Option<StorageResult>, ChainHeadStorageEvent>;
 
 /// The result of iterating over keys.
-type QueryIterResult = Result<Vec<StorageResult<String>>, ChainHeadStorageEvent<String>>;
+type QueryIterResult = Result<Vec<StorageResult>, ChainHeadStorageEvent>;
 
 impl<Client, Block, BE> ChainHeadStorage<Client, Block, BE>
 where
@@ -96,13 +96,13 @@ where
 
 		result
 			.map(|opt| {
-				QueryResult::Ok(opt.map(|storage_data| StorageResult::<String> {
+				QueryResult::Ok(opt.map(|storage_data| StorageResult {
 					key: hex_string(&key.0),
 					result: StorageResultType::Value(hex_string(&storage_data.0)),
 				}))
 			})
 			.unwrap_or_else(|err| {
-				QueryResult::Err(ChainHeadStorageEvent::<String>::Error(ErrorEvent {
+				QueryResult::Err(ChainHeadStorageEvent::Error(ErrorEvent {
 					error: err.to_string(),
 				}))
 			})
@@ -123,13 +123,13 @@ where
 
 		result
 			.map(|opt| {
-				QueryResult::Ok(opt.map(|storage_data| StorageResult::<String> {
+				QueryResult::Ok(opt.map(|storage_data| StorageResult {
 					key: hex_string(&key.0),
 					result: StorageResultType::Hash(hex_string(&storage_data.as_ref())),
 				}))
 			})
 			.unwrap_or_else(|err| {
-				QueryResult::Err(ChainHeadStorageEvent::<String>::Error(ErrorEvent {
+				QueryResult::Err(ChainHeadStorageEvent::Error(ErrorEvent {
 					error: err.to_string(),
 				}))
 			})
@@ -148,9 +148,7 @@ where
 		} else {
 			self.client.storage_keys(hash, Some(key), None)
 		}
-		.map_err(|err| {
-			ChainHeadStorageEvent::<String>::Error(ErrorEvent { error: err.to_string() })
-		})?;
+		.map_err(|err| ChainHeadStorageEvent::Error(ErrorEvent { error: err.to_string() }))?;
 
 		let mut ret = Vec::with_capacity(MAX_ITER_ITEMS);
 		let mut keys_iter = keys_iter.take(MAX_ITER_ITEMS);
@@ -178,7 +176,7 @@ where
 	) {
 		if let Some(child_key) = child_key.as_ref() {
 			if !is_key_queryable(child_key.storage_key()) {
-				let _ = sink.send(&ChainHeadStorageEvent::<String>::Done);
+				let _ = sink.send(&ChainHeadStorageEvent::Done);
 				return
 			}
 		}
@@ -242,6 +240,6 @@ where
 			let _ = sink.send(&event);
 		}
 
-		let _ = sink.send(&ChainHeadStorageEvent::<String>::Done);
+		let _ = sink.send(&ChainHeadStorageEvent::Done);
 	}
 }
diff --git a/substrate/client/rpc-spec-v2/src/chain_head/event.rs b/substrate/client/rpc-spec-v2/src/chain_head/event.rs
index 0199edee423..971a0a9f46b 100644
--- a/substrate/client/rpc-spec-v2/src/chain_head/event.rs
+++ b/substrate/client/rpc-spec-v2/src/chain_head/event.rs
@@ -21,27 +21,6 @@
 use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
 use sp_api::ApiError;
 use sp_version::RuntimeVersion;
-use std::num::NonZeroUsize;
-
-/// The network config parameter is used when a function
-/// needs to request the information from its peers.
-///
-/// These values can be tweaked depending on the urgency of the JSON-RPC function call.
-#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct NetworkConfig {
-	/// The total number of peers from which the information is requested.
-	total_attempts: u64,
-	/// The maximum number of requests to perform in parallel.
-	///
-	/// # Note
-	///
-	/// A zero value is illegal.
-	max_parallel: NonZeroUsize,
-	/// The time, in milliseconds, after which a single requests towards one peer
-	/// is considered unsuccessful.
-	timeout_ms: u64,
-}
 
 /// The operation could not be processed due to an error.
 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -189,14 +168,76 @@ pub struct Finalized<Hash> {
 	pub pruned_block_hashes: Vec<Hash>,
 }
 
+/// Indicate the operation id of the event.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct OperationId {
+	/// The operation id of the event.
+	pub operation_id: String,
+}
+
+/// The response of the `chainHead_body` method.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct OperationBodyDone {
+	/// The operation id of the event.
+	pub operation_id: String,
+	/// Array of hexadecimal-encoded scale-encoded extrinsics found in the block.
+	pub value: Vec<String>,
+}
+
+/// The response of the `chainHead_call` method.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct OperationCallDone {
+	/// The operation id of the event.
+	pub operation_id: String,
+	/// Hexadecimal-encoded output of the runtime function call.
+	pub output: String,
+}
+
+/// The response of the `chainHead_call` method.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct OperationStorageItems {
+	/// The operation id of the event.
+	pub operation_id: String,
+	/// The resulting items.
+	pub items: Vec<StorageResult>,
+}
+
+/// Indicate a problem during the operation.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct OperationError {
+	/// The operation id of the event.
+	pub operation_id: String,
+	/// The reason of the error.
+	pub error: String,
+}
+
 /// The event generated by the `follow` method.
 ///
-/// The events are generated in the following order:
+/// The block events are generated in the following order:
 /// 1. Initialized - generated only once to signal the latest finalized block
 /// 2. NewBlock - a new block was added.
 /// 3. BestBlockChanged - indicate that the best block is now the one from this event. The block was
 ///    announced priorly with the `NewBlock` event.
 /// 4. Finalized - State the finalized and pruned blocks.
+///
+/// The following events are related to operations:
+/// - OperationBodyDone: The response of the `chianHead_body`
+/// - OperationCallDone: The response of the `chianHead_call`
+/// - OperationStorageItems: Items produced by the `chianHead_storage`
+/// - OperationWaitingForContinue: Generated after OperationStorageItems and requires the user to
+///   call `chainHead_continue`
+/// - OperationStorageDone: The `chianHead_storage` method has produced all the results
+/// - OperationInaccessible: The server was unable to provide the result, retries might succeed in
+///   the future
+/// - OperationError: The server encountered an error, retries will not succeed
+///
+/// The stop event indicates that the JSON-RPC server was unable to provide a consistent list of
+/// the blocks at the head of the chain.
 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 #[serde(tag = "event")]
@@ -211,6 +252,25 @@ pub enum FollowEvent<Hash> {
 	BestBlockChanged(BestBlockChanged<Hash>),
 	/// A list of finalized and pruned blocks.
 	Finalized(Finalized<Hash>),
+	/// The response of the `chainHead_body` method.
+	OperationBodyDone(OperationBodyDone),
+	/// The response of the `chainHead_call` method.
+	OperationCallDone(OperationCallDone),
+	/// Yield one or more items found in the storage.
+	OperationStorageItems(OperationStorageItems),
+	/// Ask the user to call `chainHead_continue` to produce more events
+	/// regarding the operation id.
+	OperationWaitingForContinue(OperationId),
+	/// The responses of the `chainHead_storage` method have been produced.
+	OperationStorageDone(OperationId),
+	/// The RPC server was unable to provide the response of the following operation id.
+	///
+	/// Repeating the same operation in the future might succeed.
+	OperationInaccessible(OperationId),
+	/// The RPC server encountered an error while processing an operation id.
+	///
+	/// Repeating the same operation in the future will not succeed.
+	OperationError(OperationError),
 	/// The subscription is dropped and no further events
 	/// will be generated.
 	Stop,
@@ -254,7 +314,7 @@ pub struct StorageQuery<Key> {
 
 /// The type of the storage query.
 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-#[serde(rename_all = "kebab-case")]
+#[serde(rename_all = "camelCase")]
 pub enum StorageQueryType {
 	/// Fetch the value of the provided key.
 	Value,
@@ -271,33 +331,33 @@ pub enum StorageQueryType {
 /// The storage result.
 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
-pub struct StorageResult<T> {
+pub struct StorageResult {
 	/// The hex-encoded key of the result.
 	pub key: String,
 	/// The result of the query.
 	#[serde(flatten)]
-	pub result: StorageResultType<T>,
+	pub result: StorageResultType,
 }
 
 /// The type of the storage query.
 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
-#[serde(rename_all = "kebab-case")]
-pub enum StorageResultType<T> {
+#[serde(rename_all = "camelCase")]
+pub enum StorageResultType {
 	/// Fetch the value of the provided key.
-	Value(T),
+	Value(String),
 	/// Fetch the hash of the value of the provided key.
-	Hash(T),
+	Hash(String),
 	/// Fetch the closest descendant merkle value.
-	ClosestDescendantMerkleValue(T),
+	ClosestDescendantMerkleValue(String),
 }
 
 /// The event generated by storage method.
 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 #[serde(rename_all = "kebab-case")]
 #[serde(tag = "event")]
-pub enum ChainHeadStorageEvent<T> {
+pub enum ChainHeadStorageEvent {
 	/// The request produced multiple result items.
-	Items(ItemsEvent<T>),
+	Items(ItemsEvent),
 	/// The request produced multiple result items.
 	WaitForContinue,
 	/// The request completed successfully and all the results were provided.
@@ -315,9 +375,32 @@ pub enum ChainHeadStorageEvent<T> {
 /// The request produced multiple result items.
 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
-pub struct ItemsEvent<T> {
+pub struct ItemsEvent {
 	/// The resulting items.
-	pub items: Vec<StorageResult<T>>,
+	pub items: Vec<StorageResult>,
+}
+
+/// The method respose of `chainHead_body`, `chainHead_call` and `chainHead_storage`.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+#[serde(tag = "result")]
+pub enum MethodResponse {
+	/// The method has started.
+	Started(MethodResponseStarted),
+	/// The RPC server cannot handle the request at the moment.
+	LimitReached,
+}
+
+/// The `started` result of a method.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MethodResponseStarted {
+	/// The operation id of the response.
+	pub operation_id: String,
+	/// The number of items from the back of the `chainHead_storage` that have been discarded.
+	#[serde(skip_serializing_if = "Option::is_none")]
+	#[serde(default)]
+	pub discarded_items: Option<usize>,
 }
 
 #[cfg(test)]
@@ -477,6 +560,109 @@ mod tests {
 		assert_eq!(event_dec, event);
 	}
 
+	#[test]
+	fn follow_op_body_event() {
+		let event: FollowEvent<String> = FollowEvent::OperationBodyDone(OperationBodyDone {
+			operation_id: "123".into(),
+			value: vec!["0x1".into()],
+		});
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"event":"operationBodyDone","operationId":"123","value":["0x1"]}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+	}
+
+	#[test]
+	fn follow_op_call_event() {
+		let event: FollowEvent<String> = FollowEvent::OperationCallDone(OperationCallDone {
+			operation_id: "123".into(),
+			output: "0x1".into(),
+		});
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"event":"operationCallDone","operationId":"123","output":"0x1"}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+	}
+
+	#[test]
+	fn follow_op_storage_items_event() {
+		let event: FollowEvent<String> =
+			FollowEvent::OperationStorageItems(OperationStorageItems {
+				operation_id: "123".into(),
+				items: vec![StorageResult {
+					key: "0x1".into(),
+					result: StorageResultType::Value("0x123".to_string()),
+				}],
+			});
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"event":"operationStorageItems","operationId":"123","items":[{"key":"0x1","value":"0x123"}]}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+	}
+
+	#[test]
+	fn follow_op_wait_event() {
+		let event: FollowEvent<String> =
+			FollowEvent::OperationWaitingForContinue(OperationId { operation_id: "123".into() });
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"event":"operationWaitingForContinue","operationId":"123"}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+	}
+
+	#[test]
+	fn follow_op_storage_done_event() {
+		let event: FollowEvent<String> =
+			FollowEvent::OperationStorageDone(OperationId { operation_id: "123".into() });
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"event":"operationStorageDone","operationId":"123"}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+	}
+
+	#[test]
+	fn follow_op_inaccessible_event() {
+		let event: FollowEvent<String> =
+			FollowEvent::OperationInaccessible(OperationId { operation_id: "123".into() });
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"event":"operationInaccessible","operationId":"123"}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+	}
+
+	#[test]
+	fn follow_op_error_event() {
+		let event: FollowEvent<String> = FollowEvent::OperationError(OperationError {
+			operation_id: "123".into(),
+			error: "reason".into(),
+		});
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"event":"operationError","operationId":"123","error":"reason"}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+	}
+
 	#[test]
 	fn follow_stop_event() {
 		let event: FollowEvent<String> = FollowEvent::Stop;
@@ -489,6 +675,45 @@ mod tests {
 		assert_eq!(event_dec, event);
 	}
 
+	#[test]
+	fn method_response() {
+		// Response of `call` and `body`
+		let event = MethodResponse::Started(MethodResponseStarted {
+			operation_id: "123".into(),
+			discarded_items: None,
+		});
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"result":"started","operationId":"123"}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: MethodResponse = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+
+		// Response of `storage`
+		let event = MethodResponse::Started(MethodResponseStarted {
+			operation_id: "123".into(),
+			discarded_items: Some(1),
+		});
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"result":"started","operationId":"123","discardedItems":1}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: MethodResponse = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+
+		// Limit reached.
+		let event = MethodResponse::LimitReached;
+
+		let ser = serde_json::to_string(&event).unwrap();
+		let exp = r#"{"result":"limitReached"}"#;
+		assert_eq!(ser, exp);
+
+		let event_dec: MethodResponse = serde_json::from_str(exp).unwrap();
+		assert_eq!(event_dec, event);
+	}
+
 	#[test]
 	fn chain_head_done_event() {
 		let event: ChainHeadEvent<String> =
@@ -539,22 +764,6 @@ mod tests {
 		assert_eq!(event_dec, event);
 	}
 
-	#[test]
-	fn chain_head_network_config() {
-		let conf = NetworkConfig {
-			total_attempts: 1,
-			max_parallel: NonZeroUsize::new(2).expect("Non zero number; qed"),
-			timeout_ms: 3,
-		};
-
-		let ser = serde_json::to_string(&conf).unwrap();
-		let exp = r#"{"totalAttempts":1,"maxParallel":2,"timeoutMs":3}"#;
-		assert_eq!(ser, exp);
-
-		let conf_dec: NetworkConfig = serde_json::from_str(exp).unwrap();
-		assert_eq!(conf_dec, conf);
-	}
-
 	#[test]
 	fn chain_head_storage_query() {
 		// Item with Value.
@@ -581,7 +790,7 @@ mod tests {
 		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsValues };
 		// Encode
 		let ser = serde_json::to_string(&item).unwrap();
-		let exp = r#"{"key":"0x1","type":"descendants-values"}"#;
+		let exp = r#"{"key":"0x1","type":"descendantsValues"}"#;
 		assert_eq!(ser, exp);
 		// Decode
 		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
@@ -591,7 +800,7 @@ mod tests {
 		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsHashes };
 		// Encode
 		let ser = serde_json::to_string(&item).unwrap();
-		let exp = r#"{"key":"0x1","type":"descendants-hashes"}"#;
+		let exp = r#"{"key":"0x1","type":"descendantsHashes"}"#;
 		assert_eq!(ser, exp);
 		// Decode
 		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
@@ -602,7 +811,7 @@ mod tests {
 			StorageQuery { key: "0x1", query_type: StorageQueryType::ClosestDescendantMerkleValue };
 		// Encode
 		let ser = serde_json::to_string(&item).unwrap();
-		let exp = r#"{"key":"0x1","type":"closest-descendant-merkle-value"}"#;
+		let exp = r#"{"key":"0x1","type":"closestDescendantMerkleValue"}"#;
 		assert_eq!(ser, exp);
 		// Decode
 		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
@@ -612,36 +821,38 @@ mod tests {
 	#[test]
 	fn chain_head_storage_result() {
 		// Item with Value.
-		let item = StorageResult { key: "0x1".into(), result: StorageResultType::Value("res") };
+		let item =
+			StorageResult { key: "0x1".into(), result: StorageResultType::Value("res".into()) };
 		// Encode
 		let ser = serde_json::to_string(&item).unwrap();
 		let exp = r#"{"key":"0x1","value":"res"}"#;
 		assert_eq!(ser, exp);
 		// Decode
-		let dec: StorageResult<&str> = serde_json::from_str(exp).unwrap();
+		let dec: StorageResult = serde_json::from_str(exp).unwrap();
 		assert_eq!(dec, item);
 
 		// Item with Hash.
-		let item = StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res") };
+		let item =
+			StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res".into()) };
 		// Encode
 		let ser = serde_json::to_string(&item).unwrap();
 		let exp = r#"{"key":"0x1","hash":"res"}"#;
 		assert_eq!(ser, exp);
 		// Decode
-		let dec: StorageResult<&str> = serde_json::from_str(exp).unwrap();
+		let dec: StorageResult = serde_json::from_str(exp).unwrap();
 		assert_eq!(dec, item);
 
 		// Item with DescendantsValues.
 		let item = StorageResult {
 			key: "0x1".into(),
-			result: StorageResultType::ClosestDescendantMerkleValue("res"),
+			result: StorageResultType::ClosestDescendantMerkleValue("res".into()),
 		};
 		// Encode
 		let ser = serde_json::to_string(&item).unwrap();
-		let exp = r#"{"key":"0x1","closest-descendant-merkle-value":"res"}"#;
+		let exp = r#"{"key":"0x1","closestDescendantMerkleValue":"res"}"#;
 		assert_eq!(ser, exp);
 		// Decode
-		let dec: StorageResult<&str> = serde_json::from_str(exp).unwrap();
+		let dec: StorageResult = serde_json::from_str(exp).unwrap();
 		assert_eq!(dec, item);
 	}
 
@@ -650,8 +861,14 @@ mod tests {
 		// Event with Items.
 		let event = ChainHeadStorageEvent::Items(ItemsEvent {
 			items: vec![
-				StorageResult { key: "0x1".into(), result: StorageResultType::Value("first") },
-				StorageResult { key: "0x2".into(), result: StorageResultType::Hash("second") },
+				StorageResult {
+					key: "0x1".into(),
+					result: StorageResultType::Value("first".into()),
+				},
+				StorageResult {
+					key: "0x2".into(),
+					result: StorageResultType::Hash("second".into()),
+				},
 			],
 		});
 		// Encode
@@ -659,7 +876,7 @@ mod tests {
 		let exp = r#"{"event":"items","items":[{"key":"0x1","value":"first"},{"key":"0x2","hash":"second"}]}"#;
 		assert_eq!(ser, exp);
 		// Decode
-		let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
+		let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
 		assert_eq!(dec, event);
 
 		// Event with WaitForContinue.
@@ -669,7 +886,7 @@ mod tests {
 		let exp = r#"{"event":"wait-for-continue"}"#;
 		assert_eq!(ser, exp);
 		// Decode
-		let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
+		let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
 		assert_eq!(dec, event);
 
 		// Event with Done.
@@ -679,7 +896,7 @@ mod tests {
 		let exp = r#"{"event":"done"}"#;
 		assert_eq!(ser, exp);
 		// Decode
-		let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
+		let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
 		assert_eq!(dec, event);
 
 		// Event with Inaccessible.
@@ -689,7 +906,7 @@ mod tests {
 		let exp = r#"{"event":"inaccessible"}"#;
 		assert_eq!(ser, exp);
 		// Decode
-		let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
+		let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
 		assert_eq!(dec, event);
 
 		// Event with Inaccessible.
@@ -699,7 +916,7 @@ mod tests {
 		let exp = r#"{"event":"error","error":"reason"}"#;
 		assert_eq!(ser, exp);
 		// Decode
-		let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
+		let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
 		assert_eq!(dec, event);
 	}
 }
diff --git a/substrate/client/rpc-spec-v2/src/chain_head/mod.rs b/substrate/client/rpc-spec-v2/src/chain_head/mod.rs
index fc138e863e5..604f565ce75 100644
--- a/substrate/client/rpc-spec-v2/src/chain_head/mod.rs
+++ b/substrate/client/rpc-spec-v2/src/chain_head/mod.rs
@@ -40,7 +40,7 @@ pub use api::ChainHeadApiServer;
 pub use chain_head::ChainHead;
 pub use event::{
 	BestBlockChanged, ChainHeadEvent, ChainHeadResult, ErrorEvent, Finalized, FollowEvent,
-	Initialized, NetworkConfig, NewBlock, RuntimeEvent, RuntimeVersionEvent,
+	Initialized, NewBlock, RuntimeEvent, RuntimeVersionEvent,
 };
 
 use sp_core::hexdisplay::{AsBytesRef, HexDisplay};
diff --git a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs
index 5608a474c71..fc2f1e85b42 100644
--- a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs
+++ b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs
@@ -532,8 +532,8 @@ async fn get_storage_hash() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
-	assert_eq!(event, ChainHeadStorageEvent::<String>::Disjoint);
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
+	assert_eq!(event, ChainHeadStorageEvent::Disjoint);
 
 	// Valid subscription ID with invalid block hash will error.
 	let err = api
@@ -563,7 +563,7 @@ async fn get_storage_hash() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	// The `Done` event is generated directly since the key does not have any value associated.
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 
@@ -597,9 +597,9 @@ async fn get_storage_hash() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
-	assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Hash(expected_hash));
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
+	assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Hash(expected_hash));
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 
 	// Child value set in `setup_api`.
@@ -618,9 +618,9 @@ async fn get_storage_hash() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
-	assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Hash(expected_hash));
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
+	assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Hash(expected_hash));
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 }
 
@@ -669,13 +669,13 @@ async fn get_storage_multi_query_iter() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
-	assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 2 &&
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
+	assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 2 &&
 		res.items[0].key == key &&
 		res.items[1].key == key &&
 		res.items[0].result == StorageResultType::Hash(expected_hash) &&
 		res.items[1].result == StorageResultType::Value(expected_value));
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 
 	// Child value set in `setup_api`.
@@ -704,13 +704,13 @@ async fn get_storage_multi_query_iter() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
-	assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 2 &&
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
+	assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 2 &&
 		res.items[0].key == key &&
 		res.items[1].key == key &&
 		res.items[0].result == StorageResultType::Hash(expected_hash) &&
 		res.items[1].result == StorageResultType::Value(expected_value));
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 }
 
@@ -733,8 +733,8 @@ async fn get_storage_value() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
-	assert_eq!(event, ChainHeadStorageEvent::<String>::Disjoint);
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
+	assert_eq!(event, ChainHeadStorageEvent::Disjoint);
 
 	// Valid subscription ID with invalid block hash will error.
 	let err = api
@@ -764,7 +764,7 @@ async fn get_storage_value() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	// The `Done` event is generated directly since the key does not have any value associated.
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 
@@ -798,9 +798,9 @@ async fn get_storage_value() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
-	assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Value(expected_value));
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
+	assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Value(expected_value));
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 
 	// Child value set in `setup_api`.
@@ -819,9 +819,9 @@ async fn get_storage_value() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
-	assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Value(expected_value));
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
+	assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Value(expected_value));
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 }
 
@@ -846,7 +846,7 @@ async fn get_storage_wrong_key() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 
 	// Key is prefixed by DEFAULT_CHILD_STORAGE_KEY_PREFIX.
@@ -864,7 +864,7 @@ async fn get_storage_wrong_key() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 
 	// Child key is prefixed by CHILD_STORAGE_KEY_PREFIX.
@@ -883,7 +883,7 @@ async fn get_storage_wrong_key() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 
 	// Child key is prefixed by DEFAULT_CHILD_STORAGE_KEY_PREFIX.
@@ -902,7 +902,7 @@ async fn get_storage_wrong_key() {
 		)
 		.await
 		.unwrap();
-	let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
+	let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
 	assert_matches!(event, ChainHeadStorageEvent::Done);
 }
 
-- 
GitLab