pallet_stateful_storage_rpc/
lib.rs

1// Strong Documentation Lints
2#![deny(
3	rustdoc::broken_intra_doc_links,
4	rustdoc::missing_crate_level_docs,
5	rustdoc::invalid_codeblock_attributes,
6	missing_docs
7)]
8
9//! Custom APIs for [Stateful-Storage](../pallet_stateful_storage/index.html)
10
11use common_primitives::{
12	msa::MessageSourceId,
13	schema::*,
14	stateful_storage::{ItemizedStoragePageResponse, PaginatedStorageResponse},
15};
16use jsonrpsee::{
17	core::{async_trait, RpcResult},
18	proc_macros::rpc,
19	types::error::{ErrorCode, ErrorObject},
20};
21use pallet_stateful_storage_runtime_api::StatefulStorageRuntimeApi;
22use sp_api::{ApiError, ProvideRuntimeApi};
23use sp_blockchain::HeaderBackend;
24use sp_runtime::{traits::Block as BlockT, DispatchError};
25extern crate alloc;
26use alloc::{sync::Arc, vec::Vec};
27
28#[cfg(test)]
29mod tests;
30
31/// Frequency Stateful Storage Custom RPC API
32#[rpc(client, server)]
33pub trait StatefulStorageApi<BlockHash> {
34	/// retrieving pages of stateful storage
35	#[method(name = "statefulStorage_getPaginatedStorage")]
36	fn get_paginated_storage(
37		&self,
38		msa_id: MessageSourceId,
39		schema_id: SchemaId,
40	) -> RpcResult<Vec<PaginatedStorageResponse>>;
41
42	/// retrieving itemized storage of stateful storage
43	#[method(name = "statefulStorage_getItemizedStorage")]
44	fn get_itemized_storage(
45		&self,
46		msa_id: MessageSourceId,
47		schema_id: SchemaId,
48	) -> RpcResult<ItemizedStoragePageResponse>;
49}
50
51/// The client handler for the API used by Frequency Service RPC with `jsonrpsee`
52pub struct StatefulStorageHandler<C, M> {
53	client: Arc<C>,
54	_marker: std::marker::PhantomData<M>,
55}
56
57impl<C, M> StatefulStorageHandler<C, M> {
58	/// Create new instance with the given reference to the client.
59	pub fn new(client: Arc<C>) -> Self {
60		Self { client, _marker: Default::default() }
61	}
62}
63
64#[async_trait]
65impl<C, Block> StatefulStorageApiServer<<Block as BlockT>::Hash>
66	for StatefulStorageHandler<C, Block>
67where
68	Block: BlockT,
69	C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
70	C::Api: StatefulStorageRuntimeApi<Block>,
71{
72	fn get_paginated_storage(
73		&self,
74		msa_id: MessageSourceId,
75		schema_id: SchemaId,
76	) -> RpcResult<Vec<PaginatedStorageResponse>> {
77		let api = self.client.runtime_api();
78		let at = self.client.info().best_hash;
79		let api_result = api.get_paginated_storage(at, msa_id, schema_id);
80		map_result(api_result)
81	}
82
83	fn get_itemized_storage(
84		&self,
85		msa_id: MessageSourceId,
86		schema_id: SchemaId,
87	) -> RpcResult<ItemizedStoragePageResponse> {
88		let api = self.client.runtime_api();
89		let at = self.client.info().best_hash;
90		let api_result = api.get_itemized_storage(at, msa_id, schema_id);
91		map_result(api_result)
92	}
93}
94
95fn map_result<T>(api_result: Result<Result<T, DispatchError>, ApiError>) -> RpcResult<T> {
96	match api_result {
97		Ok(Ok(result)) => Ok(result),
98		Ok(Err(e)) => Err(ErrorObject::owned(
99			ErrorCode::ServerError(300).code(), // No real reason for this value
100			"Runtime Error",
101			Some(format!("{e:?}")),
102		)),
103		Err(e) => Err(ErrorObject::owned(
104			ErrorCode::ServerError(301).code(), // No real reason for this value
105			"Api Error",
106			Some(format!("{e:?}")),
107		)),
108	}
109}