1#[cfg(feature = "std")]
21use crate::trie_backend::TrieBackend;
22use crate::{
23 trie_backend_essence::TrieBackendStorage, ChildStorageCollection, StorageCollection,
24 StorageKey, StorageValue, UsageInfo,
25};
26use alloc::vec::Vec;
27use codec::Encode;
28use core::marker::PhantomData;
29use hash_db::Hasher;
30use sp_core::storage::{ChildInfo, StateVersion, TrackedStorageKey};
31#[cfg(feature = "std")]
32use sp_core::traits::RuntimeCode;
33use sp_trie::{MerkleValue, PrefixedMemoryDB, RandomState};
34
35#[derive(Default)]
37#[non_exhaustive]
38pub struct IterArgs<'a> {
39 pub prefix: Option<&'a [u8]>,
41
42 pub start_at: Option<&'a [u8]>,
46
47 pub start_at_exclusive: bool,
50
51 pub child_info: Option<ChildInfo>,
53
54 pub stop_on_incomplete_database: bool,
60}
61
62pub trait StorageIterator<H>
64where
65 H: Hasher,
66{
67 type Backend;
69
70 type Error;
72
73 fn next_key(
75 &mut self,
76 backend: &Self::Backend,
77 ) -> Option<core::result::Result<StorageKey, Self::Error>>;
78
79 fn next_pair(
81 &mut self,
82 backend: &Self::Backend,
83 ) -> Option<core::result::Result<(StorageKey, StorageValue), Self::Error>>;
84
85 fn was_complete(&self) -> bool;
87}
88
89pub struct PairsIter<'a, H, I>
91where
92 H: Hasher,
93 I: StorageIterator<H>,
94{
95 backend: Option<&'a I::Backend>,
96 raw_iter: I,
97 _phantom: PhantomData<H>,
98}
99
100impl<'a, H, I> Iterator for PairsIter<'a, H, I>
101where
102 H: Hasher,
103 I: StorageIterator<H>,
104{
105 type Item = Result<(Vec<u8>, Vec<u8>), <I as StorageIterator<H>>::Error>;
106 fn next(&mut self) -> Option<Self::Item> {
107 self.raw_iter.next_pair(self.backend.as_ref()?)
108 }
109}
110
111impl<'a, H, I> Default for PairsIter<'a, H, I>
112where
113 H: Hasher,
114 I: StorageIterator<H> + Default,
115{
116 fn default() -> Self {
117 Self {
118 backend: Default::default(),
119 raw_iter: Default::default(),
120 _phantom: Default::default(),
121 }
122 }
123}
124
125impl<'a, H, I> PairsIter<'a, H, I>
126where
127 H: Hasher,
128 I: StorageIterator<H> + Default,
129{
130 #[cfg(feature = "std")]
131 pub(crate) fn was_complete(&self) -> bool {
132 self.raw_iter.was_complete()
133 }
134}
135
136pub struct KeysIter<'a, H, I>
138where
139 H: Hasher,
140 I: StorageIterator<H>,
141{
142 backend: Option<&'a I::Backend>,
143 raw_iter: I,
144 _phantom: PhantomData<H>,
145}
146
147impl<'a, H, I> Iterator for KeysIter<'a, H, I>
148where
149 H: Hasher,
150 I: StorageIterator<H>,
151{
152 type Item = Result<Vec<u8>, <I as StorageIterator<H>>::Error>;
153 fn next(&mut self) -> Option<Self::Item> {
154 self.raw_iter.next_key(self.backend.as_ref()?)
155 }
156}
157
158impl<'a, H, I> Default for KeysIter<'a, H, I>
159where
160 H: Hasher,
161 I: StorageIterator<H> + Default,
162{
163 fn default() -> Self {
164 Self {
165 backend: Default::default(),
166 raw_iter: Default::default(),
167 _phantom: Default::default(),
168 }
169 }
170}
171
172pub type BackendTransaction<H> = PrefixedMemoryDB<H>;
177
178pub trait Backend<H: Hasher>: core::fmt::Debug {
183 type Error: super::Error;
185
186 type TrieBackendStorage: TrieBackendStorage<H>;
188
189 type RawIter: StorageIterator<H, Backend = Self, Error = Self::Error>;
191
192 fn storage(&self, key: &[u8]) -> Result<Option<StorageValue>, Self::Error>;
194
195 fn storage_hash(&self, key: &[u8]) -> Result<Option<H::Out>, Self::Error>;
197
198 fn closest_merkle_value(&self, key: &[u8]) -> Result<Option<MerkleValue<H::Out>>, Self::Error>;
200
201 fn child_closest_merkle_value(
203 &self,
204 child_info: &ChildInfo,
205 key: &[u8],
206 ) -> Result<Option<MerkleValue<H::Out>>, Self::Error>;
207
208 fn child_storage(
210 &self,
211 child_info: &ChildInfo,
212 key: &[u8],
213 ) -> Result<Option<StorageValue>, Self::Error>;
214
215 fn child_storage_hash(
217 &self,
218 child_info: &ChildInfo,
219 key: &[u8],
220 ) -> Result<Option<H::Out>, Self::Error>;
221
222 fn exists_storage(&self, key: &[u8]) -> Result<bool, Self::Error> {
224 Ok(self.storage_hash(key)?.is_some())
225 }
226
227 fn exists_child_storage(
229 &self,
230 child_info: &ChildInfo,
231 key: &[u8],
232 ) -> Result<bool, Self::Error> {
233 Ok(self.child_storage_hash(child_info, key)?.is_some())
234 }
235
236 fn next_storage_key(&self, key: &[u8]) -> Result<Option<StorageKey>, Self::Error>;
238
239 fn next_child_storage_key(
241 &self,
242 child_info: &ChildInfo,
243 key: &[u8],
244 ) -> Result<Option<StorageKey>, Self::Error>;
245
246 fn storage_root<'a>(
250 &self,
251 delta: impl Iterator<Item = (&'a [u8], Option<&'a [u8]>)>,
252 state_version: StateVersion,
253 ) -> (H::Out, BackendTransaction<H>)
254 where
255 H::Out: Ord;
256
257 fn child_storage_root<'a>(
261 &self,
262 child_info: &ChildInfo,
263 delta: impl Iterator<Item = (&'a [u8], Option<&'a [u8]>)>,
264 state_version: StateVersion,
265 ) -> (H::Out, bool, BackendTransaction<H>)
266 where
267 H::Out: Ord;
268
269 fn raw_iter(&self, args: IterArgs) -> Result<Self::RawIter, Self::Error>;
271
272 fn pairs<'a>(&'a self, args: IterArgs) -> Result<PairsIter<'a, H, Self::RawIter>, Self::Error> {
274 Ok(PairsIter {
275 backend: Some(self),
276 raw_iter: self.raw_iter(args)?,
277 _phantom: Default::default(),
278 })
279 }
280
281 fn keys<'a>(&'a self, args: IterArgs) -> Result<KeysIter<'a, H, Self::RawIter>, Self::Error> {
283 Ok(KeysIter {
284 backend: Some(self),
285 raw_iter: self.raw_iter(args)?,
286 _phantom: Default::default(),
287 })
288 }
289
290 fn full_storage_root<'a>(
294 &self,
295 delta: impl Iterator<Item = (&'a [u8], Option<&'a [u8]>)>,
296 child_deltas: impl Iterator<
297 Item = (&'a ChildInfo, impl Iterator<Item = (&'a [u8], Option<&'a [u8]>)>),
298 >,
299 state_version: StateVersion,
300 ) -> (H::Out, BackendTransaction<H>)
301 where
302 H::Out: Ord + Encode,
303 {
304 let mut txs = BackendTransaction::with_hasher(RandomState::default());
305 let mut child_roots: Vec<_> = Default::default();
306 for (child_info, child_delta) in child_deltas {
308 let (child_root, empty, child_txs) =
309 self.child_storage_root(child_info, child_delta, state_version);
310 let prefixed_storage_key = child_info.prefixed_storage_key();
311 txs.consolidate(child_txs);
312 if empty {
313 child_roots.push((prefixed_storage_key.into_inner(), None));
314 } else {
315 child_roots.push((prefixed_storage_key.into_inner(), Some(child_root.encode())));
316 }
317 }
318 let (root, parent_txs) = self.storage_root(
319 delta
320 .map(|(k, v)| (k, v.as_ref().map(|v| &v[..])))
321 .chain(child_roots.iter().map(|(k, v)| (&k[..], v.as_ref().map(|v| &v[..])))),
322 state_version,
323 );
324 txs.consolidate(parent_txs);
325
326 (root, txs)
327 }
328
329 fn register_overlay_stats(&self, _stats: &crate::stats::StateMachineStats);
333
334 fn usage_info(&self) -> UsageInfo;
339
340 fn wipe(&self) -> Result<(), Self::Error> {
342 unimplemented!()
343 }
344
345 fn commit(
347 &self,
348 _: H::Out,
349 _: BackendTransaction<H>,
350 _: StorageCollection,
351 _: ChildStorageCollection,
352 ) -> Result<(), Self::Error> {
353 unimplemented!()
354 }
355
356 fn read_write_count(&self) -> (u32, u32, u32, u32) {
358 unimplemented!()
359 }
360
361 fn reset_read_write_count(&self) {
363 unimplemented!()
364 }
365
366 fn get_whitelist(&self) -> Vec<TrackedStorageKey> {
368 Default::default()
369 }
370
371 fn set_whitelist(&self, _: Vec<TrackedStorageKey>) {}
373
374 fn proof_size(&self) -> Option<u32> {
376 unimplemented!()
377 }
378
379 fn get_read_and_written_keys(&self) -> Vec<(Vec<u8>, u32, u32, bool)> {
381 unimplemented!()
382 }
383}
384
385#[cfg(feature = "std")]
387pub trait AsTrieBackend<H: Hasher, C = sp_trie::cache::LocalTrieCache<H>> {
388 type TrieBackendStorage: TrieBackendStorage<H>;
390
391 fn as_trie_backend(&self) -> &TrieBackend<Self::TrieBackendStorage, H, C>;
393}
394
395#[cfg(feature = "std")]
397pub struct BackendRuntimeCode<'a, B, H> {
398 backend: &'a B,
399 _marker: PhantomData<H>,
400}
401
402#[cfg(feature = "std")]
403impl<'a, B: Backend<H>, H: Hasher> sp_core::traits::FetchRuntimeCode
404 for BackendRuntimeCode<'a, B, H>
405{
406 fn fetch_runtime_code(&self) -> Option<std::borrow::Cow<[u8]>> {
407 self.backend
408 .storage(sp_core::storage::well_known_keys::CODE)
409 .ok()
410 .flatten()
411 .map(Into::into)
412 }
413}
414
415#[cfg(feature = "std")]
416impl<'a, B: Backend<H>, H: Hasher> BackendRuntimeCode<'a, B, H>
417where
418 H::Out: Encode,
419{
420 pub fn new(backend: &'a B) -> Self {
422 Self { backend, _marker: PhantomData }
423 }
424
425 pub fn runtime_code(&self) -> Result<RuntimeCode, &'static str> {
427 let hash = self
428 .backend
429 .storage_hash(sp_core::storage::well_known_keys::CODE)
430 .ok()
431 .flatten()
432 .ok_or("`:code` hash not found")?
433 .encode();
434 let heap_pages = self
435 .backend
436 .storage(sp_core::storage::well_known_keys::HEAP_PAGES)
437 .ok()
438 .flatten()
439 .and_then(|d| codec::Decode::decode(&mut &d[..]).ok());
440
441 Ok(RuntimeCode { code_fetcher: self, hash, heap_pages })
442 }
443}