sc_rpc_spec_v2/archive/
archive_storage.rs1use std::sync::Arc;
22
23use sc_client_api::{Backend, ChildInfo, StorageKey, StorageProvider};
24use sp_runtime::traits::Block as BlockT;
25
26use crate::common::{
27 events::{ArchiveStorageResult, PaginatedStorageQuery, StorageQueryType},
28 storage::{IterQueryType, QueryIter, Storage},
29};
30
31pub struct ArchiveStorage<Client, Block, BE> {
33 client: Storage<Client, Block, BE>,
35 storage_max_descendant_responses: usize,
37 storage_max_queried_items: usize,
39}
40
41impl<Client, Block, BE> ArchiveStorage<Client, Block, BE> {
42 pub fn new(
44 client: Arc<Client>,
45 storage_max_descendant_responses: usize,
46 storage_max_queried_items: usize,
47 ) -> Self {
48 Self {
49 client: Storage::new(client),
50 storage_max_descendant_responses,
51 storage_max_queried_items,
52 }
53 }
54}
55
56impl<Client, Block, BE> ArchiveStorage<Client, Block, BE>
57where
58 Block: BlockT + 'static,
59 BE: Backend<Block> + 'static,
60 Client: StorageProvider<Block, BE> + 'static,
61{
62 pub fn handle_query(
64 &self,
65 hash: Block::Hash,
66 mut items: Vec<PaginatedStorageQuery<StorageKey>>,
67 child_key: Option<ChildInfo>,
68 ) -> ArchiveStorageResult {
69 let discarded_items = items.len().saturating_sub(self.storage_max_queried_items);
70 items.truncate(self.storage_max_queried_items);
71
72 let mut storage_results = Vec::with_capacity(items.len());
73 for item in items {
74 match item.query_type {
75 StorageQueryType::Value => {
76 match self.client.query_value(hash, &item.key, child_key.as_ref()) {
77 Ok(Some(value)) => storage_results.push(value),
78 Ok(None) => continue,
79 Err(error) => return ArchiveStorageResult::err(error),
80 }
81 },
82 StorageQueryType::Hash =>
83 match self.client.query_hash(hash, &item.key, child_key.as_ref()) {
84 Ok(Some(value)) => storage_results.push(value),
85 Ok(None) => continue,
86 Err(error) => return ArchiveStorageResult::err(error),
87 },
88 StorageQueryType::ClosestDescendantMerkleValue =>
89 match self.client.query_merkle_value(hash, &item.key, child_key.as_ref()) {
90 Ok(Some(value)) => storage_results.push(value),
91 Ok(None) => continue,
92 Err(error) => return ArchiveStorageResult::err(error),
93 },
94 StorageQueryType::DescendantsValues => {
95 match self.client.query_iter_pagination(
96 QueryIter {
97 query_key: item.key,
98 ty: IterQueryType::Value,
99 pagination_start_key: item.pagination_start_key,
100 },
101 hash,
102 child_key.as_ref(),
103 self.storage_max_descendant_responses,
104 ) {
105 Ok((results, _)) => storage_results.extend(results),
106 Err(error) => return ArchiveStorageResult::err(error),
107 }
108 },
109 StorageQueryType::DescendantsHashes => {
110 match self.client.query_iter_pagination(
111 QueryIter {
112 query_key: item.key,
113 ty: IterQueryType::Hash,
114 pagination_start_key: item.pagination_start_key,
115 },
116 hash,
117 child_key.as_ref(),
118 self.storage_max_descendant_responses,
119 ) {
120 Ok((results, _)) => storage_results.extend(results),
121 Err(error) => return ArchiveStorageResult::err(error),
122 }
123 },
124 };
125 }
126
127 ArchiveStorageResult::ok(storage_results, discarded_items)
128 }
129}