referrerpolicy=no-referrer-when-downgrade

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	/// The child trie key if provided.
82	#[serde(skip_serializing_if = "Option::is_none")]
83	#[serde(default)]
84	pub child_trie_key: Option<String>,
85}
86
87/// The type of the storage query.
88#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
89#[serde(rename_all = "camelCase")]
90pub enum StorageResultType {
91	/// Fetch the value of the provided key.
92	Value(String),
93	/// Fetch the hash of the value of the provided key.
94	Hash(String),
95	/// Fetch the closest descendant merkle value.
96	ClosestDescendantMerkleValue(String),
97}
98
99/// The error of a storage call.
100#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
101#[serde(rename_all = "camelCase")]
102pub struct StorageResultErr {
103	/// The hex-encoded key of the result.
104	pub key: String,
105	/// The result of the query.
106	#[serde(flatten)]
107	pub error: StorageResultType,
108}
109
110/// The result of a storage call.
111#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
112#[serde(rename_all = "camelCase")]
113#[serde(tag = "event")]
114pub enum ArchiveStorageEvent {
115	/// Query generated a result.
116	Storage(StorageResult),
117	/// Query encountered an error.
118	StorageError(ArchiveStorageMethodErr),
119	/// Operation storage is done.
120	StorageDone,
121}
122
123impl ArchiveStorageEvent {
124	/// Create a new `ArchiveStorageEvent::StorageErr` event.
125	pub fn err(error: String) -> Self {
126		Self::StorageError(ArchiveStorageMethodErr { error })
127	}
128
129	/// Create a new `ArchiveStorageEvent::StorageResult` event.
130	pub fn result(result: StorageResult) -> Self {
131		Self::Storage(result)
132	}
133
134	/// Checks if the event is a `StorageDone` event.
135	pub fn is_done(&self) -> bool {
136		matches!(self, Self::StorageDone)
137	}
138
139	/// Checks if the event is a `StorageErr` event.
140	pub fn is_err(&self) -> bool {
141		matches!(self, Self::StorageError(_))
142	}
143
144	/// Checks if the event is a `StorageResult` event.
145	pub fn is_result(&self) -> bool {
146		matches!(self, Self::Storage(_))
147	}
148}
149
150/// The result of a storage call.
151#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
152#[serde(rename_all = "camelCase")]
153pub struct ArchiveStorageMethodOk {
154	/// Reported results.
155	pub result: Vec<StorageResult>,
156	/// Number of discarded items.
157	pub discarded_items: usize,
158}
159
160/// The error of a storage call.
161#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
162#[serde(rename_all = "camelCase")]
163pub struct ArchiveStorageMethodErr {
164	/// Reported error.
165	pub error: String,
166}
167
168/// The type of theĀ archive storage difference query.
169#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
170#[serde(rename_all = "camelCase")]
171pub enum ArchiveStorageDiffType {
172	/// The result is provided as value of the key.
173	Value,
174	/// The result the hash of the value of the key.
175	Hash,
176}
177
178/// The storage item to query.
179#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
180#[serde(rename_all = "camelCase")]
181pub struct ArchiveStorageDiffItem<Key> {
182	/// The provided key.
183	pub key: Key,
184	/// The type of the storage query.
185	pub return_type: ArchiveStorageDiffType,
186	/// The child trie key if provided.
187	#[serde(skip_serializing_if = "Option::is_none")]
188	#[serde(default)]
189	pub child_trie_key: Option<Key>,
190}
191
192/// The result of a storage difference call.
193#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
194#[serde(rename_all = "camelCase")]
195pub struct ArchiveStorageDiffMethodResult {
196	/// Reported results.
197	pub result: Vec<ArchiveStorageDiffResult>,
198}
199
200/// The result of a storage difference call operation type.
201#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
202#[serde(rename_all = "camelCase")]
203pub enum ArchiveStorageDiffOperationType {
204	/// The key is added.
205	Added,
206	/// The key is modified.
207	Modified,
208	/// The key is removed.
209	Deleted,
210}
211
212/// The result of an individual storage difference key.
213#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
214#[serde(rename_all = "camelCase")]
215pub struct ArchiveStorageDiffResult {
216	/// The hex-encoded key of the result.
217	pub key: String,
218	/// The result of the query.
219	#[serde(flatten)]
220	pub result: StorageResultType,
221	/// The operation type.
222	#[serde(rename = "type")]
223	pub operation_type: ArchiveStorageDiffOperationType,
224	/// The child trie key if provided.
225	#[serde(skip_serializing_if = "Option::is_none")]
226	#[serde(default)]
227	pub child_trie_key: Option<String>,
228}
229
230/// The event generated by the `archive_storageDiff` method.
231///
232/// The `archive_storageDiff` can generate the following events:
233///  - `storageDiff` event - generated when a `ArchiveStorageDiffResult` is produced.
234///  - `storageDiffError` event - generated when an error is produced.
235///  - `storageDiffDone` event - generated when the `archive_storageDiff` method completed.
236#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
237#[serde(rename_all = "camelCase")]
238#[serde(tag = "event")]
239pub enum ArchiveStorageDiffEvent {
240	/// The `storageDiff` event.
241	StorageDiff(ArchiveStorageDiffResult),
242	/// The `storageDiffError` event.
243	StorageDiffError(ArchiveStorageMethodErr),
244	/// The `storageDiffDone` event.
245	StorageDiffDone,
246}
247
248impl ArchiveStorageDiffEvent {
249	/// Create a new `ArchiveStorageDiffEvent::StorageDiffError` event.
250	pub fn err(error: String) -> Self {
251		Self::StorageDiffError(ArchiveStorageMethodErr { error })
252	}
253
254	/// Checks if the event is a `StorageDiffDone` event.
255	pub fn is_done(&self) -> bool {
256		matches!(self, Self::StorageDiffDone)
257	}
258
259	/// Checks if the event is a `StorageDiffError` event.
260	pub fn is_err(&self) -> bool {
261		matches!(self, Self::StorageDiffError(_))
262	}
263}
264
265#[cfg(test)]
266mod tests {
267	use super::*;
268
269	#[test]
270	fn archive_diff_input() {
271		// Item with Value.
272		let item = ArchiveStorageDiffItem {
273			key: "0x1",
274			return_type: ArchiveStorageDiffType::Value,
275			child_trie_key: None,
276		};
277		// Encode
278		let ser = serde_json::to_string(&item).unwrap();
279		let exp = r#"{"key":"0x1","returnType":"value"}"#;
280		assert_eq!(ser, exp);
281		// Decode
282		let dec: ArchiveStorageDiffItem<&str> = serde_json::from_str(exp).unwrap();
283		assert_eq!(dec, item);
284
285		// Item with Hash.
286		let item = ArchiveStorageDiffItem {
287			key: "0x1",
288			return_type: ArchiveStorageDiffType::Hash,
289			child_trie_key: None,
290		};
291		// Encode
292		let ser = serde_json::to_string(&item).unwrap();
293		let exp = r#"{"key":"0x1","returnType":"hash"}"#;
294		assert_eq!(ser, exp);
295		// Decode
296		let dec: ArchiveStorageDiffItem<&str> = serde_json::from_str(exp).unwrap();
297		assert_eq!(dec, item);
298
299		// Item with Value and child trie key.
300		let item = ArchiveStorageDiffItem {
301			key: "0x1",
302			return_type: ArchiveStorageDiffType::Value,
303			child_trie_key: Some("0x2"),
304		};
305		// Encode
306		let ser = serde_json::to_string(&item).unwrap();
307		let exp = r#"{"key":"0x1","returnType":"value","childTrieKey":"0x2"}"#;
308		assert_eq!(ser, exp);
309		// Decode
310		let dec: ArchiveStorageDiffItem<&str> = serde_json::from_str(exp).unwrap();
311		assert_eq!(dec, item);
312
313		// Item with Hash and child trie key.
314		let item = ArchiveStorageDiffItem {
315			key: "0x1",
316			return_type: ArchiveStorageDiffType::Hash,
317			child_trie_key: Some("0x2"),
318		};
319		// Encode
320		let ser = serde_json::to_string(&item).unwrap();
321		let exp = r#"{"key":"0x1","returnType":"hash","childTrieKey":"0x2"}"#;
322		assert_eq!(ser, exp);
323		// Decode
324		let dec: ArchiveStorageDiffItem<&str> = serde_json::from_str(exp).unwrap();
325		assert_eq!(dec, item);
326	}
327
328	#[test]
329	fn archive_diff_output() {
330		// Item with Value.
331		let item = ArchiveStorageDiffResult {
332			key: "0x1".into(),
333			result: StorageResultType::Value("res".into()),
334			operation_type: ArchiveStorageDiffOperationType::Added,
335			child_trie_key: None,
336		};
337		// Encode
338		let ser = serde_json::to_string(&item).unwrap();
339		let exp = r#"{"key":"0x1","value":"res","type":"added"}"#;
340		assert_eq!(ser, exp);
341		// Decode
342		let dec: ArchiveStorageDiffResult = serde_json::from_str(exp).unwrap();
343		assert_eq!(dec, item);
344
345		// Item with Hash.
346		let item = ArchiveStorageDiffResult {
347			key: "0x1".into(),
348			result: StorageResultType::Hash("res".into()),
349			operation_type: ArchiveStorageDiffOperationType::Modified,
350			child_trie_key: None,
351		};
352		// Encode
353		let ser = serde_json::to_string(&item).unwrap();
354		let exp = r#"{"key":"0x1","hash":"res","type":"modified"}"#;
355		assert_eq!(ser, exp);
356		// Decode
357		let dec: ArchiveStorageDiffResult = serde_json::from_str(exp).unwrap();
358		assert_eq!(dec, item);
359
360		// Item with Hash, child trie key and removed.
361		let item = ArchiveStorageDiffResult {
362			key: "0x1".into(),
363			result: StorageResultType::Hash("res".into()),
364			operation_type: ArchiveStorageDiffOperationType::Deleted,
365			child_trie_key: Some("0x2".into()),
366		};
367		// Encode
368		let ser = serde_json::to_string(&item).unwrap();
369		let exp = r#"{"key":"0x1","hash":"res","type":"deleted","childTrieKey":"0x2"}"#;
370		assert_eq!(ser, exp);
371		// Decode
372		let dec: ArchiveStorageDiffResult = serde_json::from_str(exp).unwrap();
373		assert_eq!(dec, item);
374	}
375
376	#[test]
377	fn storage_result() {
378		// Item with Value.
379		let item = StorageResult {
380			key: "0x1".into(),
381			result: StorageResultType::Value("res".into()),
382			child_trie_key: None,
383		};
384		// Encode
385		let ser = serde_json::to_string(&item).unwrap();
386		let exp = r#"{"key":"0x1","value":"res"}"#;
387		assert_eq!(ser, exp);
388		// Decode
389		let dec: StorageResult = serde_json::from_str(exp).unwrap();
390		assert_eq!(dec, item);
391
392		// Item with Hash.
393		let item = StorageResult {
394			key: "0x1".into(),
395			result: StorageResultType::Hash("res".into()),
396			child_trie_key: None,
397		};
398		// Encode
399		let ser = serde_json::to_string(&item).unwrap();
400		let exp = r#"{"key":"0x1","hash":"res"}"#;
401		assert_eq!(ser, exp);
402		// Decode
403		let dec: StorageResult = serde_json::from_str(exp).unwrap();
404		assert_eq!(dec, item);
405
406		// Item with DescendantsValues.
407		let item = StorageResult {
408			key: "0x1".into(),
409			result: StorageResultType::ClosestDescendantMerkleValue("res".into()),
410			child_trie_key: None,
411		};
412		// Encode
413		let ser = serde_json::to_string(&item).unwrap();
414		let exp = r#"{"key":"0x1","closestDescendantMerkleValue":"res"}"#;
415		assert_eq!(ser, exp);
416		// Decode
417		let dec: StorageResult = serde_json::from_str(exp).unwrap();
418		assert_eq!(dec, item);
419	}
420
421	#[test]
422	fn storage_query() {
423		// Item with Value.
424		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Value };
425		// Encode
426		let ser = serde_json::to_string(&item).unwrap();
427		let exp = r#"{"key":"0x1","type":"value"}"#;
428		assert_eq!(ser, exp);
429		// Decode
430		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
431		assert_eq!(dec, item);
432
433		// Item with Hash.
434		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Hash };
435		// Encode
436		let ser = serde_json::to_string(&item).unwrap();
437		let exp = r#"{"key":"0x1","type":"hash"}"#;
438		assert_eq!(ser, exp);
439		// Decode
440		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
441		assert_eq!(dec, item);
442
443		// Item with DescendantsValues.
444		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsValues };
445		// Encode
446		let ser = serde_json::to_string(&item).unwrap();
447		let exp = r#"{"key":"0x1","type":"descendantsValues"}"#;
448		assert_eq!(ser, exp);
449		// Decode
450		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
451		assert_eq!(dec, item);
452
453		// Item with DescendantsHashes.
454		let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsHashes };
455		// Encode
456		let ser = serde_json::to_string(&item).unwrap();
457		let exp = r#"{"key":"0x1","type":"descendantsHashes"}"#;
458		assert_eq!(ser, exp);
459		// Decode
460		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
461		assert_eq!(dec, item);
462
463		// Item with Merkle.
464		let item =
465			StorageQuery { key: "0x1", query_type: StorageQueryType::ClosestDescendantMerkleValue };
466		// Encode
467		let ser = serde_json::to_string(&item).unwrap();
468		let exp = r#"{"key":"0x1","type":"closestDescendantMerkleValue"}"#;
469		assert_eq!(ser, exp);
470		// Decode
471		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
472		assert_eq!(dec, item);
473	}
474
475	#[test]
476	fn storage_query_paginated() {
477		let item = PaginatedStorageQuery {
478			key: "0x1",
479			query_type: StorageQueryType::Value,
480			pagination_start_key: None,
481		};
482		// Encode
483		let ser = serde_json::to_string(&item).unwrap();
484		let exp = r#"{"key":"0x1","type":"value"}"#;
485		assert_eq!(ser, exp);
486		// Decode
487		let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
488		assert_eq!(dec.key, item.key);
489		assert_eq!(dec.query_type, item.query_type);
490		let dec: PaginatedStorageQuery<&str> = serde_json::from_str(exp).unwrap();
491		assert_eq!(dec, item);
492
493		let item = PaginatedStorageQuery {
494			key: "0x1",
495			query_type: StorageQueryType::Value,
496			pagination_start_key: Some("0x2"),
497		};
498		// Encode
499		let ser = serde_json::to_string(&item).unwrap();
500		let exp = r#"{"key":"0x1","type":"value","paginationStartKey":"0x2"}"#;
501		assert_eq!(ser, exp);
502		// Decode
503		let dec: PaginatedStorageQuery<&str> = serde_json::from_str(exp).unwrap();
504		assert_eq!(dec, item);
505	}
506}