1use crate::{Backend, StorageKey, StorageValue};
21use alloc::{boxed::Box, vec::Vec};
22use codec::Encode;
23use core::{
24 any::{Any, TypeId},
25 marker::PhantomData,
26};
27use hash_db::Hasher;
28use sp_core::{
29 storage::{ChildInfo, StateVersion, TrackedStorageKey},
30 traits::Externalities,
31};
32use sp_externalities::MultiRemovalResults;
33
34pub trait InspectState<H: Hasher, B: Backend<H>> {
38 fn inspect_state<F: FnOnce() -> R, R>(&self, f: F) -> R;
45}
46
47impl<H: Hasher, B: Backend<H>> InspectState<H, B> for B
48where
49 H::Out: Encode,
50{
51 fn inspect_state<F: FnOnce() -> R, R>(&self, f: F) -> R {
52 ReadOnlyExternalities::from(self).execute_with(f)
53 }
54}
55
56#[derive(Debug)]
61pub struct ReadOnlyExternalities<'a, H: Hasher, B: 'a + Backend<H>> {
62 backend: &'a B,
63 _phantom: PhantomData<H>,
64}
65
66impl<'a, H: Hasher, B: 'a + Backend<H>> From<&'a B> for ReadOnlyExternalities<'a, H, B> {
67 fn from(backend: &'a B) -> Self {
68 ReadOnlyExternalities { backend, _phantom: PhantomData }
69 }
70}
71
72impl<'a, H: Hasher, B: 'a + Backend<H>> ReadOnlyExternalities<'a, H, B>
73where
74 H::Out: Encode,
75{
76 pub fn execute_with<R>(&mut self, f: impl FnOnce() -> R) -> R {
80 sp_externalities::set_and_run_with_externalities(self, f)
81 }
82}
83
84impl<'a, H: Hasher, B: 'a + Backend<H>> Externalities for ReadOnlyExternalities<'a, H, B>
85where
86 H::Out: Encode,
87{
88 fn set_offchain_storage(&mut self, _key: &[u8], _value: Option<&[u8]>) {
89 panic!("Should not be used in read-only externalities!")
90 }
91
92 fn storage(&mut self, key: &[u8]) -> Option<StorageValue> {
93 self.backend
94 .storage(key)
95 .expect("Backed failed for storage in ReadOnlyExternalities")
96 }
97
98 fn storage_hash(&mut self, key: &[u8]) -> Option<Vec<u8>> {
99 self.backend
100 .storage_hash(key)
101 .expect("Backed failed for storage_hash in ReadOnlyExternalities")
102 .map(|h| h.encode())
103 }
104
105 fn child_storage(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<StorageValue> {
106 self.backend
107 .child_storage(child_info, key)
108 .expect("Backed failed for child_storage in ReadOnlyExternalities")
109 }
110
111 fn child_storage_hash(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<Vec<u8>> {
112 self.backend
113 .child_storage_hash(child_info, key)
114 .expect("Backed failed for child_storage_hash in ReadOnlyExternalities")
115 .map(|h| h.encode())
116 }
117
118 fn next_storage_key(&mut self, key: &[u8]) -> Option<StorageKey> {
119 self.backend
120 .next_storage_key(key)
121 .expect("Backed failed for next_storage_key in ReadOnlyExternalities")
122 }
123
124 fn next_child_storage_key(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<StorageKey> {
125 self.backend
126 .next_child_storage_key(child_info, key)
127 .expect("Backed failed for next_child_storage_key in ReadOnlyExternalities")
128 }
129
130 fn place_storage(&mut self, _key: StorageKey, _maybe_value: Option<StorageValue>) {
131 unimplemented!("place_storage not supported in ReadOnlyExternalities")
132 }
133
134 fn place_child_storage(
135 &mut self,
136 _child_info: &ChildInfo,
137 _key: StorageKey,
138 _value: Option<StorageValue>,
139 ) {
140 unimplemented!("place_child_storage not supported in ReadOnlyExternalities")
141 }
142
143 fn kill_child_storage(
144 &mut self,
145 _child_info: &ChildInfo,
146 _maybe_limit: Option<u32>,
147 _maybe_cursor: Option<&[u8]>,
148 ) -> MultiRemovalResults {
149 unimplemented!("kill_child_storage is not supported in ReadOnlyExternalities")
150 }
151
152 fn clear_prefix(
153 &mut self,
154 _prefix: &[u8],
155 _maybe_limit: Option<u32>,
156 _maybe_cursor: Option<&[u8]>,
157 ) -> MultiRemovalResults {
158 unimplemented!("clear_prefix is not supported in ReadOnlyExternalities")
159 }
160
161 fn clear_child_prefix(
162 &mut self,
163 _child_info: &ChildInfo,
164 _prefix: &[u8],
165 _maybe_limit: Option<u32>,
166 _maybe_cursor: Option<&[u8]>,
167 ) -> MultiRemovalResults {
168 unimplemented!("clear_child_prefix is not supported in ReadOnlyExternalities")
169 }
170
171 fn storage_append(&mut self, _key: Vec<u8>, _value: Vec<u8>) {
172 unimplemented!("storage_append is not supported in ReadOnlyExternalities")
173 }
174
175 fn storage_root(&mut self, _state_version: StateVersion) -> Vec<u8> {
176 unimplemented!("storage_root is not supported in ReadOnlyExternalities")
177 }
178
179 fn child_storage_root(
180 &mut self,
181 _child_info: &ChildInfo,
182 _state_version: StateVersion,
183 ) -> Vec<u8> {
184 unimplemented!("child_storage_root is not supported in ReadOnlyExternalities")
185 }
186
187 fn storage_start_transaction(&mut self) {
188 unimplemented!("Transactions are not supported by ReadOnlyExternalities");
189 }
190
191 fn storage_rollback_transaction(&mut self) -> Result<(), ()> {
192 unimplemented!("Transactions are not supported by ReadOnlyExternalities");
193 }
194
195 fn storage_commit_transaction(&mut self) -> Result<(), ()> {
196 unimplemented!("Transactions are not supported by ReadOnlyExternalities");
197 }
198
199 fn wipe(&mut self) {}
200
201 fn commit(&mut self) {}
202
203 fn read_write_count(&self) -> (u32, u32, u32, u32) {
204 unimplemented!("read_write_count is not supported in ReadOnlyExternalities")
205 }
206
207 fn reset_read_write_count(&mut self) {
208 unimplemented!("reset_read_write_count is not supported in ReadOnlyExternalities")
209 }
210
211 fn get_whitelist(&self) -> Vec<TrackedStorageKey> {
212 unimplemented!("get_whitelist is not supported in ReadOnlyExternalities")
213 }
214
215 fn set_whitelist(&mut self, _: Vec<TrackedStorageKey>) {
216 unimplemented!("set_whitelist is not supported in ReadOnlyExternalities")
217 }
218
219 fn get_read_and_written_keys(&self) -> Vec<(Vec<u8>, u32, u32, bool)> {
220 unimplemented!("get_read_and_written_keys is not supported in ReadOnlyExternalities")
221 }
222}
223
224impl<'a, H: Hasher, B: 'a + Backend<H>> sp_externalities::ExtensionStore
225 for ReadOnlyExternalities<'a, H, B>
226{
227 fn extension_by_type_id(&mut self, _type_id: TypeId) -> Option<&mut dyn Any> {
228 unimplemented!("extension_by_type_id is not supported in ReadOnlyExternalities")
229 }
230
231 fn register_extension_with_type_id(
232 &mut self,
233 _type_id: TypeId,
234 _extension: Box<dyn sp_externalities::Extension>,
235 ) -> Result<(), sp_externalities::Error> {
236 unimplemented!("register_extension_with_type_id is not supported in ReadOnlyExternalities")
237 }
238
239 fn deregister_extension_by_type_id(
240 &mut self,
241 _type_id: TypeId,
242 ) -> Result<(), sp_externalities::Error> {
243 unimplemented!("deregister_extension_by_type_id is not supported in ReadOnlyExternalities")
244 }
245}