sc_rpc_spec_v2/common/
events.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Common events for RPC-V2 spec.
20
21use serde::{Deserialize, Serialize};
22
23/// The storage item to query.
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25#[serde(rename_all = "camelCase")]
26pub struct StorageQuery<Key> {
27	/// The provided key.
28	pub key: Key,
29	/// The type of the storage query.
30	#[serde(rename = "type")]
31	pub query_type: StorageQueryType,
32}
33
34/// The storage item to query with pagination.
35#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
36#[serde(rename_all = "camelCase")]
37pub struct PaginatedStorageQuery<Key> {
38	/// The provided key.
39	pub key: Key,
40	/// The type of the storage query.
41	#[serde(rename = "type")]
42	pub query_type: StorageQueryType,
43	/// The pagination key from which the iteration should resume.
44	#[serde(skip_serializing_if = "Option::is_none")]
45	#[serde(default)]
46	pub pagination_start_key: Option<Key>,
47}
48
49/// The type of the storage query.
50#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
51#[serde(rename_all = "camelCase")]
52pub enum StorageQueryType {
53	/// Fetch the value of the provided key.
54	Value,
55	/// Fetch the hash of the value of the provided key.
56	Hash,
57	/// Fetch the closest descendant merkle value.
58	ClosestDescendantMerkleValue,
59	/// Fetch the values of all descendants of they provided key.
60	DescendantsValues,
61	/// Fetch the hashes of the values of all descendants of they provided key.
62	DescendantsHashes,
63}
64
65impl StorageQueryType {
66	/// Returns `true` if the query is a descendant query.
67	pub fn is_descendant_query(&self) -> bool {
68		matches!(self, Self::DescendantsValues | Self::DescendantsHashes)
69	}
70}
71
72/// The storage result.
73#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74#[serde(rename_all = "camelCase")]
75pub struct StorageResult {
76	/// The hex-encoded key of the result.
77	pub key: String,
78	/// The result of the query.
79	#[serde(flatten)]
80	pub result: StorageResultType,
81}
82
83/// The type of the storage query.
84#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85#[serde(rename_all = "camelCase")]
86pub enum StorageResultType {
87	/// Fetch the value of the provided key.
88	Value(String),
89	/// Fetch the hash of the value of the provided key.
90	Hash(String),
91	/// Fetch the closest descendant merkle value.
92	ClosestDescendantMerkleValue(String),
93}
94
95/// The error of a storage call.
96#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97#[serde(rename_all = "camelCase")]
98pub struct StorageResultErr {
99	/// The hex-encoded key of the result.
100	pub key: String,
101	/// The result of the query.
102	#[serde(flatten)]
103	pub error: StorageResultType,
104}
105
106/// The result of a storage call.
107#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
108#[serde(untagged)]
109pub enum ArchiveStorageResult {
110	/// Query generated a result.
111	Ok(ArchiveStorageMethodOk),
112	/// Query encountered an error.
113	Err(ArchiveStorageMethodErr),
114}
115
116impl ArchiveStorageResult {
117	/// Create a new `ArchiveStorageResult::Ok` result.
118	pub fn ok(result: Vec<StorageResult>, discarded_items: usize) -> Self {
119		Self::Ok(ArchiveStorageMethodOk { result, discarded_items })
120	}
121
122	/// Create a new `ArchiveStorageResult::Err` result.
123	pub fn err(error: String) -> Self {
124		Self::Err(ArchiveStorageMethodErr { error })
125	}
126}
127
128/// The result of a storage call.
129#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
130#[serde(rename_all = "camelCase")]
131pub struct ArchiveStorageMethodOk {
132	/// Reported results.
133	pub result: Vec<StorageResult>,
134	/// Number of discarded items.
135	pub discarded_items: usize,
136}
137
138/// The error of a storage call.
139#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
140#[serde(rename_all = "camelCase")]
141pub struct ArchiveStorageMethodErr {
142	/// Reported error.
143	pub error: String,
144}
145
146#[cfg(test)]
147mod tests {
148	use super::*;
149
150	#[test]
151	fn storage_result() {
152		// Item with Value.
153		let item =
154			StorageResult { key: "0x1".into(), result: StorageResultType::Value("res".into()) };
155		// Encode
156		let ser = serde_json::to_string(&item).unwrap();
157		let exp = r#"{"key":"0x1","value":"res"}"#;
158		assert_eq!(ser, exp);
159		// Decode
160		let dec: StorageResult = serde_json::from_str(exp).unwrap();
161		assert_eq!(dec, item);
162
163		// Item with Hash.
164		let item =
165			StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res".into()) };
166		// Encode
167		let ser = serde_json::to_string(&item).unwrap();
168		let exp = r#"{"key":"0x1","hash":"res"}"#;
169		assert_eq!(ser, exp);
170		// Decode
171		let dec: StorageResult = serde_json::from_str(exp).unwrap();
172		assert_eq!(dec, item);
173
174		// Item with DescendantsValues.
175		let item = StorageResult {
176			key: "0x1".into(),
177			result: StorageResultType::ClosestDescendantMerkleValue("res".into()),
178		};
179		// Encode
180		let ser = serde_json::to_string(&item).unwrap();
181		let exp = r#"{"key":"0x1","closestDescendantMerkleValue":"res"}"#;
182		assert_eq!(ser, exp);
183		// Decode
184		let dec: StorageResult = serde_json::from_str(exp).unwrap();
185		assert_eq!(dec, item);
186	}
187
188	#[test]
189	fn storage_query() {
190		// Item with Value.
191		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Value };
192		// Encode
193		let ser = serde_json::to_string(&item).unwrap();
194		let exp = r#"{"key":"0x1","type":"value"}"#;
195		assert_eq!(ser, exp);
196		// Decode
197		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
198		assert_eq!(dec, item);
199
200		// Item with Hash.
201		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Hash };
202		// Encode
203		let ser = serde_json::to_string(&item).unwrap();
204		let exp = r#"{"key":"0x1","type":"hash"}"#;
205		assert_eq!(ser, exp);
206		// Decode
207		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
208		assert_eq!(dec, item);
209
210		// Item with DescendantsValues.
211		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsValues };
212		// Encode
213		let ser = serde_json::to_string(&item).unwrap();
214		let exp = r#"{"key":"0x1","type":"descendantsValues"}"#;
215		assert_eq!(ser, exp);
216		// Decode
217		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
218		assert_eq!(dec, item);
219
220		// Item with DescendantsHashes.
221		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsHashes };
222		// Encode
223		let ser = serde_json::to_string(&item).unwrap();
224		let exp = r#"{"key":"0x1","type":"descendantsHashes"}"#;
225		assert_eq!(ser, exp);
226		// Decode
227		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
228		assert_eq!(dec, item);
229
230		// Item with Merkle.
231		let item =
232			StorageQuery { key: "0x1", query_type: StorageQueryType::ClosestDescendantMerkleValue };
233		// Encode
234		let ser = serde_json::to_string(&item).unwrap();
235		let exp = r#"{"key":"0x1","type":"closestDescendantMerkleValue"}"#;
236		assert_eq!(ser, exp);
237		// Decode
238		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
239		assert_eq!(dec, item);
240	}
241
242	#[test]
243	fn storage_query_paginated() {
244		let item = PaginatedStorageQuery {
245			key: "0x1",
246			query_type: StorageQueryType::Value,
247			pagination_start_key: None,
248		};
249		// Encode
250		let ser = serde_json::to_string(&item).unwrap();
251		let exp = r#"{"key":"0x1","type":"value"}"#;
252		assert_eq!(ser, exp);
253		// Decode
254		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
255		assert_eq!(dec.key, item.key);
256		assert_eq!(dec.query_type, item.query_type);
257		let dec: PaginatedStorageQuery<&str> = serde_json::from_str(exp).unwrap();
258		assert_eq!(dec, item);
259
260		let item = PaginatedStorageQuery {
261			key: "0x1",
262			query_type: StorageQueryType::Value,
263			pagination_start_key: Some("0x2"),
264		};
265		// Encode
266		let ser = serde_json::to_string(&item).unwrap();
267		let exp = r#"{"key":"0x1","type":"value","paginationStartKey":"0x2"}"#;
268		assert_eq!(ser, exp);
269		// Decode
270		let dec: PaginatedStorageQuery<&str> = serde_json::from_str(exp).unwrap();
271		assert_eq!(dec, item);
272	}
273}