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}