referrerpolicy=no-referrer-when-downgrade

sp_state_machine/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Substrate state machine implementation.
19
20#![warn(missing_docs)]
21#![cfg_attr(not(feature = "std"), no_std)]
22
23extern crate alloc;
24
25pub mod backend;
26#[cfg(not(substrate_runtime))]
27mod basic;
28mod error;
29mod ext;
30#[cfg(feature = "fuzzing")]
31pub mod fuzzing;
32#[cfg(not(substrate_runtime))]
33mod in_memory_backend;
34pub(crate) mod overlayed_changes;
35#[cfg(not(substrate_runtime))]
36mod read_only;
37mod stats;
38#[cfg(feature = "std")]
39mod testing;
40mod trie_backend;
41mod trie_backend_essence;
42
43pub use trie_backend::TrieCacheProvider;
44
45#[cfg(feature = "std")]
46pub use std_reexport::*;
47
48#[cfg(feature = "std")]
49pub use execution::*;
50#[cfg(feature = "std")]
51pub use log::{debug, error as log_error, warn};
52#[cfg(feature = "std")]
53pub use tracing::trace;
54
55/// In no_std we skip logs for state_machine, this macro
56/// is a noops.
57#[cfg(not(feature = "std"))]
58#[macro_export]
59macro_rules! warn {
60	(target: $target:expr, $message:expr $( , $arg:ident )* $( , )?) => {
61		{
62			$(
63				let _ = &$arg;
64			)*
65		}
66	};
67	($message:expr, $( $arg:expr, )*) => {
68		{
69			$(
70				let _ = &$arg;
71			)*
72		}
73	};
74}
75
76/// In no_std we skip logs for state_machine, this macro
77/// is a noops.
78#[cfg(not(feature = "std"))]
79#[macro_export]
80macro_rules! debug {
81	(target: $target:expr, $message:expr $( , $arg:ident )* $( , )?) => {
82		{
83			$(
84				let _ = &$arg;
85			)*
86		}
87	};
88}
89
90/// In no_std we skip logs for state_machine, this macro
91/// is a noops.
92#[cfg(not(feature = "std"))]
93#[macro_export]
94macro_rules! trace {
95	(target: $target:expr, $($arg:tt)+) => {
96		()
97	};
98	($($arg:tt)+) => {
99		()
100	};
101}
102
103/// In no_std we skip logs for state_machine, this macro
104/// is a noops.
105#[cfg(not(feature = "std"))]
106#[macro_export]
107macro_rules! log_error {
108	(target: $target:expr, $($arg:tt)+) => {
109		()
110	};
111	($($arg:tt)+) => {
112		()
113	};
114}
115
116/// Default error type to use with state machine trie backend.
117#[cfg(feature = "std")]
118pub type DefaultError = String;
119/// Error type to use with state machine trie backend.
120#[cfg(not(feature = "std"))]
121#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
122pub struct DefaultError;
123
124#[cfg(not(feature = "std"))]
125impl core::fmt::Display for DefaultError {
126	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
127		write!(f, "DefaultError")
128	}
129}
130
131pub use crate::{
132	backend::{Backend, BackendTransaction, IterArgs, KeysIter, PairsIter, StorageIterator},
133	error::{Error, ExecutionError},
134	ext::Ext,
135	overlayed_changes::{
136		ChildStorageCollection, IndexOperation, OffchainChangesCollection,
137		OffchainOverlayedChanges, OverlayedChanges, StorageChanges, StorageCollection, StorageKey,
138		StorageValue,
139	},
140	stats::{StateMachineStats, UsageInfo, UsageUnit},
141	trie_backend::{TrieBackend, TrieBackendBuilder},
142	trie_backend_essence::{Storage, TrieBackendStorage},
143};
144
145#[cfg(not(substrate_runtime))]
146pub use crate::{
147	basic::BasicExternalities,
148	in_memory_backend::new_in_mem,
149	read_only::{InspectState, ReadOnlyExternalities},
150};
151
152#[cfg(feature = "std")]
153mod std_reexport {
154	pub use crate::{testing::TestExternalities, trie_backend::create_proof_check_backend};
155	pub use sp_trie::{
156		trie_types::{TrieDBMutV0, TrieDBMutV1},
157		CompactProof, DBValue, LayoutV0, LayoutV1, MemoryDB, StorageProof, TrieMut,
158	};
159}
160
161#[cfg(feature = "std")]
162mod execution {
163	use crate::backend::AsTrieBackend;
164
165	use super::*;
166	use codec::Codec;
167	use hash_db::Hasher;
168	use smallvec::SmallVec;
169	use sp_core::{
170		hexdisplay::HexDisplay,
171		storage::{ChildInfo, ChildType, PrefixedStorageKey, StateVersion},
172		traits::{CallContext, CodeExecutor, RuntimeCode},
173	};
174	use sp_externalities::Extensions;
175	use sp_trie::PrefixedMemoryDB;
176	use std::{
177		collections::{HashMap, HashSet},
178		time::Duration,
179	};
180
181	pub(crate) type CallResult<E> = Result<Vec<u8>, E>;
182
183	/// Default handler of the execution manager.
184	pub type DefaultHandler<E> = fn(CallResult<E>, CallResult<E>) -> CallResult<E>;
185
186	/// Trie backend with in-memory storage.
187	pub type InMemoryBackend<H> = TrieBackend<PrefixedMemoryDB<H>, H>;
188
189	/// Storage backend trust level.
190	#[derive(Debug, Clone)]
191	pub enum BackendTrustLevel {
192		/// Panics from trusted backends are considered justified, and never caught.
193		Trusted,
194		/// Panics from untrusted backend are caught and interpreted as runtime error.
195		/// Untrusted backend may be missing some parts of the trie, so panics are not considered
196		/// fatal.
197		Untrusted,
198	}
199
200	/// The substrate state machine.
201	pub struct StateMachine<'a, B, H, Exec>
202	where
203		H: Hasher,
204		B: Backend<H>,
205	{
206		backend: &'a B,
207		exec: &'a Exec,
208		method: &'a str,
209		call_data: &'a [u8],
210		overlay: &'a mut OverlayedChanges<H>,
211		extensions: &'a mut Extensions,
212		runtime_code: &'a RuntimeCode<'a>,
213		stats: StateMachineStats,
214		/// The hash of the block the state machine will be executed on.
215		///
216		/// Used for logging.
217		parent_hash: Option<H::Out>,
218		context: CallContext,
219		state_version: StateVersion,
220		/// Wall-clock limit for the runtime call, see [`Self::with_timeout`].
221		timeout: Option<Duration>,
222	}
223
224	impl<'a, B, H, Exec> Drop for StateMachine<'a, B, H, Exec>
225	where
226		H: Hasher,
227		B: Backend<H>,
228	{
229		fn drop(&mut self) {
230			self.backend.register_overlay_stats(&self.stats);
231		}
232	}
233
234	impl<'a, B, H, Exec> StateMachine<'a, B, H, Exec>
235	where
236		H: Hasher,
237		H::Out: Ord + 'static + codec::Codec,
238		Exec: CodeExecutor + Clone + 'static,
239		B: Backend<H>,
240	{
241		/// Creates new substrate state machine.
242		pub fn new(
243			backend: &'a B,
244			overlay: &'a mut OverlayedChanges<H>,
245			exec: &'a Exec,
246			method: &'a str,
247			call_data: &'a [u8],
248			extensions: &'a mut Extensions,
249			runtime_code: &'a RuntimeCode,
250			context: CallContext,
251			state_version: StateVersion,
252		) -> Self {
253			Self {
254				backend,
255				exec,
256				method,
257				call_data,
258				extensions,
259				overlay,
260				runtime_code,
261				stats: StateMachineStats::default(),
262				parent_hash: None,
263				context,
264				state_version,
265				timeout: None,
266			}
267		}
268
269		/// Set the given `parent_hash` as the hash of the parent block.
270		///
271		/// This will be used for improved logging.
272		pub fn set_parent_hash(mut self, parent_hash: H::Out) -> Self {
273			self.parent_hash = Some(parent_hash);
274			self
275		}
276
277		/// Interrupt the runtime call once `timeout` has elapsed, if `Some`.
278		///
279		/// See [`CodeExecutor::call_with_execution_timeout`].
280		pub fn with_timeout(mut self, timeout: Option<Duration>) -> Self {
281			self.timeout = timeout;
282			self
283		}
284
285		/// Execute a call using the given state backend, overlayed changes, and call executor.
286		///
287		/// On an error, no prospective changes are written to the overlay. If a timeout was set
288		/// via [`Self::with_timeout`], the call is interrupted once it elapses.
289		///
290		/// Note: changes to code will be in place if this call is made again. For running partial
291		/// blocks (e.g. a transaction at a time), ensure a different method is used.
292		///
293		/// Returns the SCALE encoded result of the executed function.
294		pub fn execute(&mut self) -> Result<Vec<u8>, Box<dyn Error>> {
295			self.overlay
296				.enter_runtime()
297				.expect("StateMachine is never called from the runtime; qed");
298
299			let mut ext =
300				Ext::new(self.overlay, self.backend, Some(self.extensions), self.state_version);
301
302			let ext_id = ext.id;
303
304			trace!(
305				target: "state",
306				ext_id = %HexDisplay::from(&ext_id.to_le_bytes()),
307				method = %self.method,
308				parent_hash = %self.parent_hash.map(|h| format!("{:?}", h)).unwrap_or_else(|| String::from("None")),
309				input = ?HexDisplay::from(&self.call_data),
310				timeout = ?self.timeout,
311				"Call",
312			);
313
314			let result = match self.timeout {
315				Some(timeout) => self.exec.call_with_execution_timeout(
316					&mut ext,
317					self.runtime_code,
318					self.method,
319					self.call_data,
320					self.context,
321					timeout,
322				),
323				None => {
324					self.exec
325						.call(
326							&mut ext,
327							self.runtime_code,
328							self.method,
329							self.call_data,
330							self.context,
331						)
332						.0
333				},
334			};
335
336			self.overlay
337				.exit_runtime()
338				.expect("Runtime is not able to call this function in the overlay; qed");
339
340			trace!(
341				target: "state",
342				ext_id = %HexDisplay::from(&ext_id.to_le_bytes()),
343				?result,
344				"Return",
345			);
346
347			result.map_err(|e| Box::new(e) as Box<_>)
348		}
349	}
350
351	/// Prove execution using the given state backend, overlayed changes, and call executor.
352	///
353	/// `timeout` bounds the wall-clock execution time of the runtime call if `Some`.
354	pub fn prove_execution<B, H, Exec>(
355		backend: &mut B,
356		overlay: &mut OverlayedChanges<H>,
357		exec: &Exec,
358		method: &str,
359		call_data: &[u8],
360		runtime_code: &RuntimeCode,
361		state_version: StateVersion,
362		timeout: Option<Duration>,
363	) -> Result<(Vec<u8>, StorageProof), Box<dyn Error>>
364	where
365		B: AsTrieBackend<H>,
366		H: Hasher,
367		H::Out: Ord + 'static + codec::Codec,
368		Exec: CodeExecutor + Clone + 'static,
369	{
370		let trie_backend = backend.as_trie_backend();
371		prove_execution_on_trie_backend::<_, _, _>(
372			trie_backend,
373			overlay,
374			exec,
375			method,
376			call_data,
377			runtime_code,
378			&mut Default::default(),
379			state_version,
380			timeout,
381		)
382	}
383
384	/// Prove execution using the given trie backend, overlayed changes, and call executor.
385	/// Produces a state-backend-specific "transaction" which can be used to apply the changes
386	/// to the backing store, such as the disk.
387	/// Execution proof is the set of all 'touched' storage DBValues from the backend.
388	///
389	/// `timeout` bounds the wall-clock execution time of the runtime call if `Some`.
390	///
391	/// On an error, no prospective changes are written to the overlay.
392	///
393	/// Note: changes to code will be in place if this call is made again. For running partial
394	/// blocks (e.g. a transaction at a time), ensure a different method is used.
395	pub fn prove_execution_on_trie_backend<S, H, Exec>(
396		trie_backend: &TrieBackend<S, H>,
397		overlay: &mut OverlayedChanges<H>,
398		exec: &Exec,
399		method: &str,
400		call_data: &[u8],
401		runtime_code: &RuntimeCode,
402		extensions: &mut Extensions,
403		state_version: StateVersion,
404		timeout: Option<Duration>,
405	) -> Result<(Vec<u8>, StorageProof), Box<dyn Error>>
406	where
407		S: trie_backend_essence::TrieBackendStorage<H>,
408		H: Hasher,
409		H::Out: Ord + 'static + codec::Codec,
410		Exec: CodeExecutor + 'static + Clone,
411	{
412		let proving_backend =
413			TrieBackendBuilder::wrap(trie_backend).with_recorder(Default::default()).build();
414
415		let result = StateMachine::<_, H, Exec>::new(
416			&proving_backend,
417			overlay,
418			exec,
419			method,
420			call_data,
421			extensions,
422			runtime_code,
423			CallContext::Offchain,
424			state_version,
425		)
426		.with_timeout(timeout)
427		.execute()?;
428
429		let proof = proving_backend
430			.extract_proof()
431			.expect("A recorder was set and thus, a storage proof can be extracted; qed");
432
433		Ok((result, proof))
434	}
435
436	/// Check execution proof, generated by `prove_execution` call.
437	pub fn execution_proof_check<H, Exec>(
438		root: H::Out,
439		proof: StorageProof,
440		overlay: &mut OverlayedChanges<H>,
441		exec: &Exec,
442		method: &str,
443		call_data: &[u8],
444		runtime_code: &RuntimeCode,
445		state_version: StateVersion,
446	) -> Result<Vec<u8>, Box<dyn Error>>
447	where
448		H: Hasher + 'static,
449		Exec: CodeExecutor + Clone + 'static,
450		H::Out: Ord + 'static + codec::Codec,
451	{
452		let trie_backend = create_proof_check_backend::<H>(root, proof)?;
453		execution_proof_check_on_trie_backend::<_, _>(
454			&trie_backend,
455			overlay,
456			exec,
457			method,
458			call_data,
459			runtime_code,
460			state_version,
461		)
462	}
463
464	/// Check execution proof on proving backend, generated by `prove_execution` call.
465	pub fn execution_proof_check_on_trie_backend<H, Exec>(
466		trie_backend: &TrieBackend<MemoryDB<H>, H>,
467		overlay: &mut OverlayedChanges<H>,
468		exec: &Exec,
469		method: &str,
470		call_data: &[u8],
471		runtime_code: &RuntimeCode,
472		state_version: StateVersion,
473	) -> Result<Vec<u8>, Box<dyn Error>>
474	where
475		H: Hasher,
476		H::Out: Ord + 'static + codec::Codec,
477		Exec: CodeExecutor + Clone + 'static,
478	{
479		StateMachine::<_, H, Exec>::new(
480			trie_backend,
481			overlay,
482			exec,
483			method,
484			call_data,
485			&mut Extensions::default(),
486			runtime_code,
487			CallContext::Offchain,
488			state_version,
489		)
490		.execute()
491	}
492
493	/// Generate storage read proof.
494	pub fn prove_read<B, H, I>(backend: B, keys: I) -> Result<StorageProof, Box<dyn Error>>
495	where
496		B: AsTrieBackend<H>,
497		H: Hasher,
498		H::Out: Ord + Codec,
499		I: IntoIterator,
500		I::Item: AsRef<[u8]>,
501	{
502		let trie_backend = backend.as_trie_backend();
503		prove_read_on_trie_backend(trie_backend, keys)
504	}
505
506	/// State machine only allows a single level
507	/// of child trie.
508	pub const MAX_NESTED_TRIE_DEPTH: usize = 2;
509
510	/// Multiple key value state.
511	/// States are ordered by root storage key.
512	#[derive(PartialEq, Eq, Clone)]
513	pub struct KeyValueStates(pub Vec<KeyValueStorageLevel>);
514
515	/// A key value state at any storage level.
516	#[derive(PartialEq, Eq, Clone)]
517	pub struct KeyValueStorageLevel {
518		/// State root of the level, for
519		/// top trie it is as an empty byte array.
520		pub state_root: Vec<u8>,
521		/// Storage of parents, empty for top root or
522		/// when exporting (building proof).
523		pub parent_storage_keys: Vec<Vec<u8>>,
524		/// Pair of key and values from this state.
525		pub key_values: Vec<(Vec<u8>, Vec<u8>)>,
526	}
527
528	impl<I> From<I> for KeyValueStates
529	where
530		I: IntoIterator<Item = (Vec<u8>, (Vec<(Vec<u8>, Vec<u8>)>, Vec<Vec<u8>>))>,
531	{
532		fn from(b: I) -> Self {
533			let mut result = Vec::new();
534			for (state_root, (key_values, storage_paths)) in b.into_iter() {
535				result.push(KeyValueStorageLevel {
536					state_root,
537					key_values,
538					parent_storage_keys: storage_paths,
539				})
540			}
541			KeyValueStates(result)
542		}
543	}
544
545	impl KeyValueStates {
546		/// Return total number of key values in states.
547		pub fn len(&self) -> usize {
548			self.0.iter().fold(0, |nb, state| nb + state.key_values.len())
549		}
550
551		/// Update last keys accessed from this state.
552		pub fn update_last_key(
553			&self,
554			stopped_at: usize,
555			last: &mut SmallVec<[Vec<u8>; 2]>,
556		) -> bool {
557			if stopped_at == 0 || stopped_at > MAX_NESTED_TRIE_DEPTH {
558				return false;
559			}
560			match stopped_at {
561				1 => {
562					let top_last =
563						self.0.get(0).and_then(|s| s.key_values.last().map(|kv| kv.0.clone()));
564					if let Some(top_last) = top_last {
565						match last.len() {
566							0 => {
567								last.push(top_last);
568								return true;
569							},
570							2 => {
571								last.pop();
572							},
573							_ => (),
574						}
575						// update top trie access.
576						last[0] = top_last;
577						return true;
578					} else {
579						// No change in top trie accesses.
580						// Indicates end of reading of a child trie.
581						last.truncate(1);
582						return true;
583					}
584				},
585				2 => {
586					let top_last =
587						self.0.get(0).and_then(|s| s.key_values.last().map(|kv| kv.0.clone()));
588					let child_last =
589						self.0.last().and_then(|s| s.key_values.last().map(|kv| kv.0.clone()));
590
591					if let Some(child_last) = child_last {
592						if last.is_empty() {
593							if let Some(top_last) = top_last {
594								last.push(top_last)
595							} else {
596								return false;
597							}
598						} else if let Some(top_last) = top_last {
599							last[0] = top_last;
600						}
601						if last.len() == 2 {
602							last.pop();
603						}
604						last.push(child_last);
605						return true;
606					} else {
607						// stopped at level 2 so child last is define.
608						return false;
609					}
610				},
611				_ => (),
612			}
613			false
614		}
615	}
616
617	/// Generate range storage read proof, with child tries
618	/// content.
619	/// A size limit is applied to the proof with the
620	/// exception that `start_at` and its following element
621	/// are always part of the proof.
622	/// If a key different than `start_at` is a child trie root,
623	/// the child trie content will be included in the proof.
624	pub fn prove_range_read_with_child_with_size<B, H>(
625		backend: B,
626		size_limit: usize,
627		start_at: &[Vec<u8>],
628	) -> Result<(StorageProof, u32), Box<dyn Error>>
629	where
630		B: AsTrieBackend<H>,
631		H: Hasher,
632		H::Out: Ord + Codec,
633	{
634		let trie_backend = backend.as_trie_backend();
635		prove_range_read_with_child_with_size_on_trie_backend(trie_backend, size_limit, start_at)
636	}
637
638	/// Generate range storage read proof, with child tries
639	/// content.
640	/// See `prove_range_read_with_child_with_size`.
641	pub fn prove_range_read_with_child_with_size_on_trie_backend<S, H>(
642		trie_backend: &TrieBackend<S, H>,
643		size_limit: usize,
644		start_at: &[Vec<u8>],
645	) -> Result<(StorageProof, u32), Box<dyn Error>>
646	where
647		S: trie_backend_essence::TrieBackendStorage<H>,
648		H: Hasher,
649		H::Out: Ord + Codec,
650	{
651		if start_at.len() > MAX_NESTED_TRIE_DEPTH {
652			return Err(Box::new("Invalid start of range."));
653		}
654
655		let recorder = sp_trie::recorder::Recorder::default();
656		let proving_backend =
657			TrieBackendBuilder::wrap(trie_backend).with_recorder(recorder.clone()).build();
658		let mut count = 0;
659
660		let mut child_roots = HashSet::new();
661		let (mut child_key, mut start_at) = if start_at.len() == 2 {
662			let storage_key = start_at.get(0).expect("Checked length.").clone();
663			if let Some(state_root) = proving_backend
664				.storage(&storage_key)
665				.map_err(|e| Box::new(e) as Box<dyn Error>)?
666			{
667				child_roots.insert(state_root);
668			} else {
669				return Err(Box::new("Invalid range start child trie key."));
670			}
671
672			(Some(storage_key), start_at.get(1).cloned())
673		} else {
674			(None, start_at.get(0).cloned())
675		};
676
677		loop {
678			let (child_info, depth) = if let Some(storage_key) = child_key.as_ref() {
679				let storage_key = PrefixedStorageKey::new_ref(storage_key);
680				(
681					Some(match ChildType::from_prefixed_key(storage_key) {
682						Some((ChildType::ParentKeyId, storage_key)) => {
683							ChildInfo::new_default(storage_key)
684						},
685						None => return Err(Box::new("Invalid range start child trie key.")),
686					}),
687					2,
688				)
689			} else {
690				(None, 1)
691			};
692
693			let start_at_ref = start_at.as_ref().map(AsRef::as_ref);
694			let mut switch_child_key = None;
695			let mut iter = proving_backend
696				.pairs(IterArgs {
697					child_info,
698					start_at: start_at_ref,
699					start_at_exclusive: true,
700					..IterArgs::default()
701				})
702				.map_err(|e| Box::new(e) as Box<dyn Error>)?;
703
704			while let Some(item) = iter.next() {
705				let (key, value) = item.map_err(|e| Box::new(e) as Box<dyn Error>)?;
706
707				if depth < MAX_NESTED_TRIE_DEPTH &&
708					sp_core::storage::well_known_keys::is_child_storage_key(key.as_slice())
709				{
710					count += 1;
711					// do not add two child trie with same root
712					if !child_roots.contains(value.as_slice()) {
713						child_roots.insert(value);
714						switch_child_key = Some(key);
715						break;
716					}
717				} else if recorder.estimate_encoded_size() <= size_limit {
718					count += 1;
719				} else {
720					break;
721				}
722			}
723
724			let completed = iter.was_complete();
725
726			if switch_child_key.is_none() {
727				if depth == 1 {
728					break;
729				} else if completed {
730					start_at = child_key.take();
731				} else {
732					break;
733				}
734			} else {
735				child_key = switch_child_key;
736				start_at = None;
737			}
738		}
739
740		let proof = proving_backend
741			.extract_proof()
742			.expect("A recorder was set and thus, a storage proof can be extracted; qed");
743		Ok((proof, count))
744	}
745
746	/// Generate range storage read proof.
747	pub fn prove_range_read_with_size<B, H>(
748		backend: B,
749		child_info: Option<&ChildInfo>,
750		prefix: Option<&[u8]>,
751		size_limit: usize,
752		start_at: Option<&[u8]>,
753	) -> Result<(StorageProof, u32), Box<dyn Error>>
754	where
755		B: AsTrieBackend<H>,
756		H: Hasher,
757		H::Out: Ord + Codec,
758	{
759		let trie_backend = backend.as_trie_backend();
760		prove_range_read_with_size_on_trie_backend(
761			trie_backend,
762			child_info,
763			prefix,
764			size_limit,
765			start_at,
766		)
767	}
768
769	/// Generate range storage read proof on an existing trie backend.
770	pub fn prove_range_read_with_size_on_trie_backend<S, H>(
771		trie_backend: &TrieBackend<S, H>,
772		child_info: Option<&ChildInfo>,
773		prefix: Option<&[u8]>,
774		size_limit: usize,
775		start_at: Option<&[u8]>,
776	) -> Result<(StorageProof, u32), Box<dyn Error>>
777	where
778		S: trie_backend_essence::TrieBackendStorage<H>,
779		H: Hasher,
780		H::Out: Ord + Codec,
781	{
782		let recorder = sp_trie::recorder::Recorder::default();
783		let proving_backend =
784			TrieBackendBuilder::wrap(trie_backend).with_recorder(recorder.clone()).build();
785		let mut count = 0;
786		let iter = proving_backend
787			// NOTE: Even though the loop below doesn't use these values
788			//       this *must* fetch both the keys and the values so that
789			//       the proof is correct.
790			.pairs(IterArgs {
791				child_info: child_info.cloned(),
792				prefix,
793				start_at,
794				..IterArgs::default()
795			})
796			.map_err(|e| Box::new(e) as Box<dyn Error>)?;
797
798		for item in iter {
799			item.map_err(|e| Box::new(e) as Box<dyn Error>)?;
800			if count == 0 || recorder.estimate_encoded_size() <= size_limit {
801				count += 1;
802			} else {
803				break;
804			}
805		}
806
807		let proof = proving_backend
808			.extract_proof()
809			.expect("A recorder was set and thus, a storage proof can be extracted; qed");
810		Ok((proof, count))
811	}
812
813	/// Generate child storage read proof.
814	pub fn prove_child_read<B, H, I>(
815		backend: B,
816		child_info: &ChildInfo,
817		keys: I,
818	) -> Result<StorageProof, Box<dyn Error>>
819	where
820		B: AsTrieBackend<H>,
821		H: Hasher,
822		H::Out: Ord + Codec,
823		I: IntoIterator,
824		I::Item: AsRef<[u8]>,
825	{
826		let trie_backend = backend.as_trie_backend();
827		prove_child_read_on_trie_backend(trie_backend, child_info, keys)
828	}
829
830	/// Generate storage read proof on pre-created trie backend.
831	pub fn prove_read_on_trie_backend<S, H, I>(
832		trie_backend: &TrieBackend<S, H>,
833		keys: I,
834	) -> Result<StorageProof, Box<dyn Error>>
835	where
836		S: trie_backend_essence::TrieBackendStorage<H>,
837		H: Hasher,
838		H::Out: Ord + Codec,
839		I: IntoIterator,
840		I::Item: AsRef<[u8]>,
841	{
842		let proving_backend =
843			TrieBackendBuilder::wrap(trie_backend).with_recorder(Default::default()).build();
844		for key in keys.into_iter() {
845			proving_backend
846				.storage(key.as_ref())
847				.map_err(|e| Box::new(e) as Box<dyn Error>)?;
848		}
849
850		Ok(proving_backend
851			.extract_proof()
852			.expect("A recorder was set and thus, a storage proof can be extracted; qed"))
853	}
854
855	/// Generate storage read proof on pre-created trie backend.
856	pub fn prove_child_read_on_trie_backend<S, H, I>(
857		trie_backend: &TrieBackend<S, H>,
858		child_info: &ChildInfo,
859		keys: I,
860	) -> Result<StorageProof, Box<dyn Error>>
861	where
862		S: trie_backend_essence::TrieBackendStorage<H>,
863		H: Hasher,
864		H::Out: Ord + Codec,
865		I: IntoIterator,
866		I::Item: AsRef<[u8]>,
867	{
868		let proving_backend =
869			TrieBackendBuilder::wrap(trie_backend).with_recorder(Default::default()).build();
870		for key in keys.into_iter() {
871			proving_backend
872				.child_storage(child_info, key.as_ref())
873				.map_err(|e| Box::new(e) as Box<dyn Error>)?;
874		}
875
876		Ok(proving_backend
877			.extract_proof()
878			.expect("A recorder was set and thus, a storage proof can be extracted; qed"))
879	}
880
881	/// Check storage read proof, generated by `prove_read` call.
882	pub fn read_proof_check<H, I>(
883		root: H::Out,
884		proof: StorageProof,
885		keys: I,
886	) -> Result<HashMap<Vec<u8>, Option<Vec<u8>>>, Box<dyn Error>>
887	where
888		H: Hasher + 'static,
889		H::Out: Ord + Codec,
890		I: IntoIterator,
891		I::Item: AsRef<[u8]>,
892	{
893		let proving_backend = create_proof_check_backend::<H>(root, proof)?;
894		let mut result = HashMap::new();
895		for key in keys.into_iter() {
896			let value = read_proof_check_on_proving_backend(&proving_backend, key.as_ref())?;
897			result.insert(key.as_ref().to_vec(), value);
898		}
899		Ok(result)
900	}
901
902	/// Check storage range proof with child trie included, generated by
903	/// `prove_range_read_with_child_with_size` call.
904	///
905	/// Returns key values contents and the depth of the pending state iteration
906	/// (0 if completed).
907	pub fn read_range_proof_check_with_child<H>(
908		root: H::Out,
909		proof: StorageProof,
910		start_at: &[Vec<u8>],
911	) -> Result<(KeyValueStates, usize), Box<dyn Error>>
912	where
913		H: Hasher + 'static,
914		H::Out: Ord + Codec,
915	{
916		let proving_backend = create_proof_check_backend::<H>(root, proof)?;
917		read_range_proof_check_with_child_on_proving_backend(&proving_backend, start_at)
918	}
919
920	/// Check child storage range proof, generated by `prove_range_read_with_size` call.
921	pub fn read_range_proof_check<H>(
922		root: H::Out,
923		proof: StorageProof,
924		child_info: Option<&ChildInfo>,
925		prefix: Option<&[u8]>,
926		count: Option<u32>,
927		start_at: Option<&[u8]>,
928	) -> Result<(Vec<(Vec<u8>, Vec<u8>)>, bool), Box<dyn Error>>
929	where
930		H: Hasher + 'static,
931		H::Out: Ord + Codec,
932	{
933		let proving_backend = create_proof_check_backend::<H>(root, proof)?;
934		read_range_proof_check_on_proving_backend(
935			&proving_backend,
936			child_info,
937			prefix,
938			count,
939			start_at,
940		)
941	}
942
943	/// Check child storage read proof, generated by `prove_child_read` call.
944	pub fn read_child_proof_check<H, I>(
945		root: H::Out,
946		proof: StorageProof,
947		child_info: &ChildInfo,
948		keys: I,
949	) -> Result<HashMap<Vec<u8>, Option<Vec<u8>>>, Box<dyn Error>>
950	where
951		H: Hasher + 'static,
952		H::Out: Ord + Codec,
953		I: IntoIterator,
954		I::Item: AsRef<[u8]>,
955	{
956		let proving_backend = create_proof_check_backend::<H>(root, proof)?;
957		let mut result = HashMap::new();
958		for key in keys.into_iter() {
959			let value = read_child_proof_check_on_proving_backend(
960				&proving_backend,
961				child_info,
962				key.as_ref(),
963			)?;
964			result.insert(key.as_ref().to_vec(), value);
965		}
966		Ok(result)
967	}
968
969	/// Check storage read proof on pre-created proving backend.
970	pub fn read_proof_check_on_proving_backend<H>(
971		proving_backend: &TrieBackend<MemoryDB<H>, H>,
972		key: &[u8],
973	) -> Result<Option<Vec<u8>>, Box<dyn Error>>
974	where
975		H: Hasher,
976		H::Out: Ord + Codec,
977	{
978		proving_backend.storage(key).map_err(|e| Box::new(e) as Box<dyn Error>)
979	}
980
981	/// Check child storage read proof on pre-created proving backend.
982	pub fn read_child_proof_check_on_proving_backend<H>(
983		proving_backend: &TrieBackend<MemoryDB<H>, H>,
984		child_info: &ChildInfo,
985		key: &[u8],
986	) -> Result<Option<Vec<u8>>, Box<dyn Error>>
987	where
988		H: Hasher,
989		H::Out: Ord + Codec,
990	{
991		proving_backend
992			.child_storage(child_info, key)
993			.map_err(|e| Box::new(e) as Box<dyn Error>)
994	}
995
996	/// Check storage range proof on pre-created proving backend.
997	///
998	/// Returns a vector with the read `key => value` pairs and a `bool` that is set to `true` when
999	/// all `key => value` pairs could be read and no more are left.
1000	pub fn read_range_proof_check_on_proving_backend<H>(
1001		proving_backend: &TrieBackend<MemoryDB<H>, H>,
1002		child_info: Option<&ChildInfo>,
1003		prefix: Option<&[u8]>,
1004		count: Option<u32>,
1005		start_at: Option<&[u8]>,
1006	) -> Result<(Vec<(Vec<u8>, Vec<u8>)>, bool), Box<dyn Error>>
1007	where
1008		H: Hasher,
1009		H::Out: Ord + Codec,
1010	{
1011		let mut values = Vec::new();
1012		let mut iter = proving_backend
1013			.pairs(IterArgs {
1014				child_info: child_info.cloned(),
1015				prefix,
1016				start_at,
1017				stop_on_incomplete_database: true,
1018				..IterArgs::default()
1019			})
1020			.map_err(|e| Box::new(e) as Box<dyn Error>)?;
1021
1022		while let Some(item) = iter.next() {
1023			let (key, value) = item.map_err(|e| Box::new(e) as Box<dyn Error>)?;
1024			values.push((key, value));
1025			if !count.as_ref().map_or(true, |c| (values.len() as u32) < *c) {
1026				break;
1027			}
1028		}
1029
1030		Ok((values, iter.was_complete()))
1031	}
1032
1033	/// Check storage range proof on pre-created proving backend.
1034	///
1035	/// See `read_range_proof_check_with_child`.
1036	pub fn read_range_proof_check_with_child_on_proving_backend<H>(
1037		proving_backend: &TrieBackend<MemoryDB<H>, H>,
1038		start_at: &[Vec<u8>],
1039	) -> Result<(KeyValueStates, usize), Box<dyn Error>>
1040	where
1041		H: Hasher,
1042		H::Out: Ord + Codec,
1043	{
1044		let mut result = vec![KeyValueStorageLevel {
1045			state_root: Default::default(),
1046			key_values: Default::default(),
1047			parent_storage_keys: Default::default(),
1048		}];
1049		if start_at.len() > MAX_NESTED_TRIE_DEPTH {
1050			return Err(Box::new("Invalid start of range."));
1051		}
1052
1053		let mut child_roots = HashSet::new();
1054		let (mut child_key, mut start_at) = if start_at.len() == 2 {
1055			let storage_key = start_at.get(0).expect("Checked length.").clone();
1056			let child_key = if let Some(state_root) = proving_backend
1057				.storage(&storage_key)
1058				.map_err(|e| Box::new(e) as Box<dyn Error>)?
1059			{
1060				child_roots.insert(state_root.clone());
1061				Some((storage_key, state_root))
1062			} else {
1063				return Err(Box::new("Invalid range start child trie key."));
1064			};
1065
1066			(child_key, start_at.get(1).cloned())
1067		} else {
1068			(None, start_at.get(0).cloned())
1069		};
1070
1071		let completed = loop {
1072			let (child_info, depth) = if let Some((storage_key, state_root)) = child_key.as_ref() {
1073				result.push(KeyValueStorageLevel {
1074					state_root: state_root.clone(),
1075					key_values: Default::default(),
1076					parent_storage_keys: Default::default(),
1077				});
1078
1079				let storage_key = PrefixedStorageKey::new_ref(storage_key);
1080				(
1081					Some(match ChildType::from_prefixed_key(storage_key) {
1082						Some((ChildType::ParentKeyId, storage_key)) => {
1083							ChildInfo::new_default(storage_key)
1084						},
1085						None => return Err(Box::new("Invalid range start child trie key.")),
1086					}),
1087					2,
1088				)
1089			} else {
1090				(None, 1)
1091			};
1092
1093			let values = if child_info.is_some() {
1094				&mut result.last_mut().expect("Added above").key_values
1095			} else {
1096				&mut result[0].key_values
1097			};
1098			let start_at_ref = start_at.as_ref().map(AsRef::as_ref);
1099			let mut switch_child_key = None;
1100
1101			let mut iter = proving_backend
1102				.pairs(IterArgs {
1103					child_info,
1104					start_at: start_at_ref,
1105					start_at_exclusive: true,
1106					stop_on_incomplete_database: true,
1107					..IterArgs::default()
1108				})
1109				.map_err(|e| Box::new(e) as Box<dyn Error>)?;
1110
1111			while let Some(item) = iter.next() {
1112				let (key, value) = item.map_err(|e| Box::new(e) as Box<dyn Error>)?;
1113				values.push((key.to_vec(), value.to_vec()));
1114
1115				if depth < MAX_NESTED_TRIE_DEPTH &&
1116					sp_core::storage::well_known_keys::is_child_storage_key(key.as_slice())
1117				{
1118					// Do not add two chid trie with same root.
1119					if !child_roots.contains(value.as_slice()) {
1120						child_roots.insert(value.clone());
1121						switch_child_key = Some((key, value));
1122						break;
1123					}
1124				}
1125			}
1126
1127			let completed = iter.was_complete();
1128
1129			if switch_child_key.is_none() {
1130				if !completed {
1131					break depth;
1132				}
1133				if depth == 1 {
1134					break 0;
1135				} else {
1136					start_at = child_key.take().map(|entry| entry.0);
1137				}
1138			} else {
1139				child_key = switch_child_key;
1140				start_at = None;
1141			}
1142		};
1143		Ok((KeyValueStates(result), completed))
1144	}
1145}
1146
1147#[cfg(test)]
1148mod tests {
1149	use super::{backend::AsTrieBackend, ext::Ext, *};
1150	use crate::{execution::CallResult, in_memory_backend::new_in_mem};
1151	use assert_matches::assert_matches;
1152	use codec::Encode;
1153	use sp_core::{
1154		map,
1155		storage::{ChildInfo, StateVersion},
1156		traits::{CallContext, CodeExecutor, Externalities, RuntimeCode},
1157		H256,
1158	};
1159	use sp_runtime::traits::BlakeTwo256;
1160	use sp_trie::{
1161		trie_types::{TrieDBMutBuilderV0, TrieDBMutBuilderV1},
1162		KeySpacedDBMut, PrefixedMemoryDB,
1163	};
1164	use std::collections::{BTreeMap, HashMap};
1165
1166	#[derive(Clone)]
1167	struct DummyCodeExecutor {
1168		native_available: bool,
1169		native_succeeds: bool,
1170		fallback_succeeds: bool,
1171	}
1172
1173	impl CodeExecutor for DummyCodeExecutor {
1174		type Error = u8;
1175
1176		fn call(
1177			&self,
1178			ext: &mut dyn Externalities,
1179			_: &RuntimeCode,
1180			_method: &str,
1181			_data: &[u8],
1182			_: CallContext,
1183		) -> (CallResult<Self::Error>, bool) {
1184			let using_native = self.native_available;
1185			match (using_native, self.native_succeeds, self.fallback_succeeds) {
1186				(true, true, _) | (false, _, true) => (
1187					Ok(vec![
1188						ext.storage(b"value1").unwrap()[0] + ext.storage(b"value2").unwrap()[0],
1189					]),
1190					using_native,
1191				),
1192				_ => (Err(0), using_native),
1193			}
1194		}
1195
1196		fn call_with_execution_timeout(
1197			&self,
1198			ext: &mut dyn Externalities,
1199			runtime_code: &RuntimeCode,
1200			method: &str,
1201			data: &[u8],
1202			context: CallContext,
1203			_timeout: std::time::Duration,
1204		) -> CallResult<Self::Error> {
1205			self.call(ext, runtime_code, method, data, context).0
1206		}
1207	}
1208
1209	impl sp_core::traits::ReadRuntimeVersion for DummyCodeExecutor {
1210		fn read_runtime_version(
1211			&self,
1212			_: &[u8],
1213			_: &mut dyn Externalities,
1214		) -> std::result::Result<Vec<u8>, String> {
1215			unimplemented!("Not required in tests.")
1216		}
1217	}
1218
1219	#[test]
1220	fn execute_works() {
1221		execute_works_inner(StateVersion::V0);
1222		execute_works_inner(StateVersion::V1);
1223	}
1224	fn execute_works_inner(state_version: StateVersion) {
1225		let backend = trie_backend::tests::test_trie(state_version, None, None);
1226		let mut overlayed_changes = Default::default();
1227		let wasm_code = RuntimeCode::empty();
1228		let mut execution_extensions = &mut Default::default();
1229
1230		let mut state_machine = StateMachine::new(
1231			&backend,
1232			&mut overlayed_changes,
1233			&DummyCodeExecutor {
1234				native_available: true,
1235				native_succeeds: true,
1236				fallback_succeeds: true,
1237			},
1238			"test",
1239			&[],
1240			&mut execution_extensions,
1241			&wasm_code,
1242			CallContext::Offchain,
1243			state_version,
1244		);
1245
1246		assert_eq!(state_machine.execute().unwrap(), vec![66]);
1247	}
1248
1249	#[test]
1250	fn execute_works_with_native_else_wasm() {
1251		execute_works_with_native_else_wasm_inner(StateVersion::V0);
1252		execute_works_with_native_else_wasm_inner(StateVersion::V1);
1253	}
1254	fn execute_works_with_native_else_wasm_inner(state_version: StateVersion) {
1255		let backend = trie_backend::tests::test_trie(state_version, None, None);
1256		let mut overlayed_changes = Default::default();
1257		let wasm_code = RuntimeCode::empty();
1258		let mut execution_extensions = &mut Default::default();
1259
1260		let mut state_machine = StateMachine::new(
1261			&backend,
1262			&mut overlayed_changes,
1263			&DummyCodeExecutor {
1264				native_available: true,
1265				native_succeeds: true,
1266				fallback_succeeds: true,
1267			},
1268			"test",
1269			&[],
1270			&mut execution_extensions,
1271			&wasm_code,
1272			CallContext::Offchain,
1273			state_version,
1274		);
1275
1276		assert_eq!(state_machine.execute().unwrap(), vec![66]);
1277	}
1278
1279	#[test]
1280	fn prove_execution_and_proof_check_works() {
1281		for state_version in [StateVersion::V0, StateVersion::V1] {
1282			for timeout in [None, Some(std::time::Duration::from_secs(1))] {
1283				prove_execution_and_proof_check_works_inner(state_version, timeout);
1284			}
1285		}
1286	}
1287	fn prove_execution_and_proof_check_works_inner(
1288		state_version: StateVersion,
1289		timeout: Option<std::time::Duration>,
1290	) {
1291		let executor = DummyCodeExecutor {
1292			native_available: true,
1293			native_succeeds: true,
1294			fallback_succeeds: true,
1295		};
1296
1297		// fetch execution proof from 'remote' full node
1298		let mut remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1299		let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1300		let (remote_result, remote_proof) = prove_execution(
1301			&mut remote_backend,
1302			&mut Default::default(),
1303			&executor,
1304			"test",
1305			&[],
1306			&RuntimeCode::empty(),
1307			state_version,
1308			timeout,
1309		)
1310		.unwrap();
1311
1312		// check proof locally
1313		let local_result = execution_proof_check::<BlakeTwo256, _>(
1314			remote_root,
1315			remote_proof,
1316			&mut Default::default(),
1317			&executor,
1318			"test",
1319			&[],
1320			&RuntimeCode::empty(),
1321			state_version,
1322		)
1323		.unwrap();
1324
1325		// check that both results are correct
1326		assert_eq!(remote_result, vec![66]);
1327		assert_eq!(remote_result, local_result);
1328	}
1329
1330	#[test]
1331	fn clear_prefix_in_ext_works() {
1332		let initial: BTreeMap<_, _> = map![
1333			b"aaa".to_vec() => b"0".to_vec(),
1334			b"abb".to_vec() => b"1".to_vec(),
1335			b"abc".to_vec() => b"2".to_vec(),
1336			b"bbb".to_vec() => b"3".to_vec()
1337		];
1338		let state = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
1339		let backend = state.as_trie_backend();
1340
1341		let mut overlay = OverlayedChanges::default();
1342		overlay.set_storage(b"aba".to_vec(), Some(b"1312".to_vec()));
1343		overlay.set_storage(b"bab".to_vec(), Some(b"228".to_vec()));
1344		overlay.start_transaction();
1345		overlay.set_storage(b"abd".to_vec(), Some(b"69".to_vec()));
1346		overlay.set_storage(b"bbd".to_vec(), Some(b"42".to_vec()));
1347
1348		let overlay_limit = overlay.clone();
1349		{
1350			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1351			let _ = ext.clear_prefix(b"ab", None, None);
1352		}
1353		overlay.commit_transaction().unwrap();
1354
1355		assert_eq!(
1356			overlay
1357				.changes_mut()
1358				.map(|(k, v)| (k.clone(), v.value().cloned()))
1359				.collect::<HashMap<_, _>>(),
1360			map![
1361				b"abc".to_vec() => None,
1362				b"abb".to_vec() => None,
1363				b"aba".to_vec() => None,
1364				b"abd".to_vec() => None,
1365
1366				b"bab".to_vec() => Some(b"228".to_vec()),
1367				b"bbd".to_vec() => Some(b"42".to_vec())
1368			],
1369		);
1370
1371		let mut overlay = overlay_limit;
1372		{
1373			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1374			assert_matches!(
1375				ext.clear_prefix(b"ab", Some(1), None).deconstruct(),
1376				(Some(_), 1, 3, 1)
1377			);
1378		}
1379		overlay.commit_transaction().unwrap();
1380
1381		assert_eq!(
1382			overlay
1383				.changes_mut()
1384				.map(|(k, v)| (k.clone(), v.value().cloned()))
1385				.collect::<HashMap<_, _>>(),
1386			map![
1387				b"abb".to_vec() => None,
1388				b"aba".to_vec() => None,
1389				b"abd".to_vec() => None,
1390
1391				b"bab".to_vec() => Some(b"228".to_vec()),
1392				b"bbd".to_vec() => Some(b"42".to_vec())
1393			],
1394		);
1395	}
1396
1397	#[test]
1398	fn limited_child_kill_works() {
1399		let child_info = ChildInfo::new_default(b"sub1");
1400		let initial: HashMap<_, BTreeMap<_, _>> = map![
1401			Some(child_info.clone()) => map![
1402				b"a".to_vec() => b"0".to_vec(),
1403				b"b".to_vec() => b"1".to_vec(),
1404				b"c".to_vec() => b"2".to_vec(),
1405				b"d".to_vec() => b"3".to_vec()
1406			],
1407		];
1408		let backend = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
1409
1410		let mut overlay = OverlayedChanges::default();
1411		overlay.set_child_storage(&child_info, b"1".to_vec(), Some(b"1312".to_vec()));
1412		overlay.set_child_storage(&child_info, b"2".to_vec(), Some(b"1312".to_vec()));
1413		overlay.set_child_storage(&child_info, b"3".to_vec(), Some(b"1312".to_vec()));
1414		overlay.set_child_storage(&child_info, b"4".to_vec(), Some(b"1312".to_vec()));
1415
1416		{
1417			let mut ext = Ext::new(&mut overlay, &backend, None, StateVersion::default());
1418			let r = ext.kill_child_storage(&child_info, Some(2), None);
1419			assert_matches!(r.deconstruct(), (Some(_), 2, 6, 2));
1420		}
1421
1422		assert_eq!(
1423			overlay
1424				.children_mut()
1425				.flat_map(|(iter, _child_info)| iter)
1426				.map(|(k, v)| (k.clone(), v.value()))
1427				.collect::<BTreeMap<_, _>>(),
1428			map![
1429				b"1".to_vec() => None,
1430				b"2".to_vec() => None,
1431				b"3".to_vec() => None,
1432				b"4".to_vec() => None,
1433				b"a".to_vec() => None,
1434				b"b".to_vec() => None,
1435			],
1436		);
1437	}
1438
1439	#[test]
1440	fn limited_child_kill_off_by_one_works() {
1441		let child_info = ChildInfo::new_default(b"sub1");
1442		let initial: HashMap<_, BTreeMap<_, _>> = map![
1443			Some(child_info.clone()) => map![
1444				b"a".to_vec() => b"0".to_vec(),
1445				b"b".to_vec() => b"1".to_vec(),
1446				b"c".to_vec() => b"2".to_vec(),
1447				b"d".to_vec() => b"3".to_vec()
1448			],
1449		];
1450		let backend = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
1451		let mut overlay = OverlayedChanges::default();
1452		let mut ext = Ext::new(&mut overlay, &backend, None, StateVersion::default());
1453		let r = ext.kill_child_storage(&child_info, Some(0), None).deconstruct();
1454		assert_matches!(r, (Some(_), 0, 0, 0));
1455		let r = ext
1456			.kill_child_storage(&child_info, Some(1), r.0.as_ref().map(|x| &x[..]))
1457			.deconstruct();
1458		assert_matches!(r, (Some(_), 1, 1, 1));
1459		let r = ext
1460			.kill_child_storage(&child_info, Some(4), r.0.as_ref().map(|x| &x[..]))
1461			.deconstruct();
1462		// Only 3 items remaining to remove
1463		assert_matches!(r, (None, 3, 3, 3));
1464		let r = ext.kill_child_storage(&child_info, Some(1), None).deconstruct();
1465		assert_matches!(r, (Some(_), 0, 0, 1));
1466	}
1467
1468	#[test]
1469	fn limited_child_kill_off_by_one_works_without_limit() {
1470		let child_info = ChildInfo::new_default(b"sub1");
1471		let initial: HashMap<_, BTreeMap<_, _>> = map![
1472			Some(child_info.clone()) => map![
1473				b"a".to_vec() => b"0".to_vec(),
1474				b"b".to_vec() => b"1".to_vec(),
1475				b"c".to_vec() => b"2".to_vec(),
1476				b"d".to_vec() => b"3".to_vec()
1477			],
1478		];
1479		let backend = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
1480		let mut overlay = OverlayedChanges::default();
1481		let mut ext = Ext::new(&mut overlay, &backend, None, StateVersion::default());
1482		assert_eq!(ext.kill_child_storage(&child_info, None, None).deconstruct(), (None, 4, 4, 4));
1483	}
1484
1485	#[test]
1486	fn set_child_storage_works() {
1487		let child_info = ChildInfo::new_default(b"sub1");
1488		let child_info = &child_info;
1489		let state = new_in_mem::<BlakeTwo256>();
1490		let backend = state.as_trie_backend();
1491		let mut overlay = OverlayedChanges::default();
1492		let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1493
1494		ext.set_child_storage(child_info, b"abc".to_vec(), b"def".to_vec());
1495		assert_eq!(ext.child_storage(child_info, b"abc"), Some(b"def".to_vec()));
1496		let _ = ext.kill_child_storage(child_info, None, None);
1497		assert_eq!(ext.child_storage(child_info, b"abc"), None);
1498	}
1499
1500	#[test]
1501	fn append_storage_works() {
1502		let reference_data = vec![b"data1".to_vec(), b"2".to_vec(), b"D3".to_vec(), b"d4".to_vec()];
1503		let key = b"key".to_vec();
1504		let state = new_in_mem::<BlakeTwo256>();
1505		let backend = state.as_trie_backend();
1506		let mut overlay = OverlayedChanges::default();
1507		{
1508			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1509
1510			ext.storage_append(key.clone(), reference_data[0].encode());
1511			assert_eq!(ext.storage(key.as_slice()), Some(vec![reference_data[0].clone()].encode()));
1512		}
1513		overlay.start_transaction();
1514		{
1515			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1516
1517			for i in reference_data.iter().skip(1) {
1518				ext.storage_append(key.clone(), i.encode());
1519			}
1520			assert_eq!(ext.storage(key.as_slice()), Some(reference_data.encode()));
1521		}
1522		overlay.rollback_transaction().unwrap();
1523		{
1524			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1525			assert_eq!(ext.storage(key.as_slice()), Some(vec![reference_data[0].clone()].encode()));
1526		}
1527	}
1528
1529	// Test that we can append twice to a key, then perform a remove operation.
1530	// The test checks specifically that the append is merged with its parent transaction
1531	// on commit.
1532	#[test]
1533	fn commit_merges_append_with_parent() {
1534		#[derive(codec::Encode, codec::Decode)]
1535		enum Item {
1536			Item1,
1537			Item2,
1538		}
1539
1540		let key = b"events".to_vec();
1541		let state = new_in_mem::<BlakeTwo256>();
1542		let backend = state.as_trie_backend();
1543		let mut overlay = OverlayedChanges::default();
1544
1545		// Append first item
1546		overlay.start_transaction();
1547		{
1548			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1549			ext.clear_storage(key.as_slice());
1550			ext.storage_append(key.clone(), Item::Item1.encode());
1551		}
1552
1553		// Append second item
1554		overlay.start_transaction();
1555		{
1556			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1557
1558			assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::Item1].encode()));
1559
1560			ext.storage_append(key.clone(), Item::Item2.encode());
1561
1562			assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::Item1, Item::Item2].encode()),);
1563		}
1564
1565		// Remove item
1566		overlay.start_transaction();
1567		{
1568			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1569
1570			ext.place_storage(key.clone(), None);
1571
1572			assert_eq!(ext.storage(key.as_slice()), None);
1573		}
1574
1575		// Remove gets commited and merged into previous transaction
1576		overlay.commit_transaction().unwrap();
1577		{
1578			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1579			assert_eq!(ext.storage(key.as_slice()), None,);
1580		}
1581
1582		// Remove gets rolled back, we should see the initial append again.
1583		overlay.rollback_transaction().unwrap();
1584		{
1585			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1586			assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::Item1].encode()));
1587		}
1588
1589		overlay.commit_transaction().unwrap();
1590		{
1591			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1592			assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::Item1].encode()));
1593		}
1594	}
1595
1596	#[test]
1597	fn remove_with_append_then_rollback_appended_then_append_again() {
1598		#[derive(codec::Encode, codec::Decode)]
1599		enum Item {
1600			InitializationItem,
1601			DiscardedItem,
1602			CommittedItem,
1603		}
1604
1605		let key = b"events".to_vec();
1606		let state = new_in_mem::<BlakeTwo256>();
1607		let backend = state.as_trie_backend();
1608		let mut overlay = OverlayedChanges::default();
1609
1610		// For example, block initialization with event.
1611		{
1612			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1613			ext.clear_storage(key.as_slice());
1614			ext.storage_append(key.clone(), Item::InitializationItem.encode());
1615		}
1616		overlay.start_transaction();
1617
1618		// For example, first transaction resulted in panic during block building
1619		{
1620			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1621
1622			assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::InitializationItem].encode()));
1623
1624			ext.storage_append(key.clone(), Item::DiscardedItem.encode());
1625
1626			assert_eq!(
1627				ext.storage(key.as_slice()),
1628				Some(vec![Item::InitializationItem, Item::DiscardedItem].encode()),
1629			);
1630		}
1631		overlay.rollback_transaction().unwrap();
1632
1633		// Then we apply next transaction which is valid this time.
1634		{
1635			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1636
1637			assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::InitializationItem].encode()));
1638
1639			ext.storage_append(key.clone(), Item::CommittedItem.encode());
1640
1641			assert_eq!(
1642				ext.storage(key.as_slice()),
1643				Some(vec![Item::InitializationItem, Item::CommittedItem].encode()),
1644			);
1645		}
1646		overlay.start_transaction();
1647
1648		// Then only initialization item and second (committed) item should persist.
1649		{
1650			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
1651			assert_eq!(
1652				ext.storage(key.as_slice()),
1653				Some(vec![Item::InitializationItem, Item::CommittedItem].encode()),
1654			);
1655		}
1656	}
1657
1658	fn test_compact(remote_proof: StorageProof, remote_root: &sp_core::H256) -> StorageProof {
1659		let compact_remote_proof =
1660			remote_proof.into_compact_proof::<BlakeTwo256>(*remote_root).unwrap();
1661		compact_remote_proof.to_storage_proof::<BlakeTwo256>(remote_root).unwrap().0
1662	}
1663
1664	#[test]
1665	fn prove_read_and_proof_check_works() {
1666		prove_read_and_proof_check_works_inner(StateVersion::V0);
1667		prove_read_and_proof_check_works_inner(StateVersion::V1);
1668	}
1669	fn prove_read_and_proof_check_works_inner(state_version: StateVersion) {
1670		let child_info = ChildInfo::new_default(b"sub1");
1671		let missing_child_info = ChildInfo::new_default(b"sub1sub2"); // key will include other child root to proof.
1672		let child_info = &child_info;
1673		let missing_child_info = &missing_child_info;
1674		// fetch read proof from 'remote' full node
1675		let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1676		let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1677		let remote_proof = prove_read(remote_backend, &[b"value2"]).unwrap();
1678		let remote_proof = test_compact(remote_proof, &remote_root);
1679		// check proof locally
1680		let local_result1 =
1681			read_proof_check::<BlakeTwo256, _>(remote_root, remote_proof.clone(), &[b"value2"])
1682				.unwrap();
1683		let local_result2 =
1684			read_proof_check::<BlakeTwo256, _>(remote_root, remote_proof, &[&[0xff]]).is_ok();
1685		// check that results are correct
1686		assert_eq!(
1687			local_result1.into_iter().collect::<Vec<_>>(),
1688			vec![(b"value2".to_vec(), Some(vec![24]))],
1689		);
1690		assert_eq!(local_result2, false);
1691		// on child trie
1692		let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1693		let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1694		let remote_proof = prove_child_read(remote_backend, child_info, &[b"value3"]).unwrap();
1695		let remote_proof = test_compact(remote_proof, &remote_root);
1696		let local_result1 = read_child_proof_check::<BlakeTwo256, _>(
1697			remote_root,
1698			remote_proof.clone(),
1699			child_info,
1700			&[b"value3"],
1701		)
1702		.unwrap();
1703		let local_result2 = read_child_proof_check::<BlakeTwo256, _>(
1704			remote_root,
1705			remote_proof.clone(),
1706			child_info,
1707			&[b"value2"],
1708		)
1709		.unwrap();
1710		let local_result3 = read_child_proof_check::<BlakeTwo256, _>(
1711			remote_root,
1712			remote_proof,
1713			missing_child_info,
1714			&[b"dummy"],
1715		)
1716		.unwrap();
1717
1718		assert_eq!(
1719			local_result1.into_iter().collect::<Vec<_>>(),
1720			vec![(b"value3".to_vec(), Some(vec![142; 33]))],
1721		);
1722		assert_eq!(local_result2.into_iter().collect::<Vec<_>>(), vec![(b"value2".to_vec(), None)]);
1723		assert_eq!(local_result3.into_iter().collect::<Vec<_>>(), vec![(b"dummy".to_vec(), None)]);
1724	}
1725
1726	#[test]
1727	fn child_read_compact_stress_test() {
1728		use rand::{rngs::SmallRng, RngCore, SeedableRng};
1729		let mut storage: HashMap<Option<ChildInfo>, BTreeMap<StorageKey, StorageValue>> =
1730			Default::default();
1731		let mut seed = [0; 32];
1732		for i in 0..50u32 {
1733			let mut child_infos = Vec::new();
1734			let seed_partial = &mut seed[0..4];
1735			seed_partial.copy_from_slice(&i.to_be_bytes()[..]);
1736			let mut rand = SmallRng::from_seed(seed);
1737
1738			let nb_child_trie = rand.next_u32() as usize % 25;
1739			for _ in 0..nb_child_trie {
1740				let key_len = 1 + (rand.next_u32() % 10);
1741				let mut key = vec![0; key_len as usize];
1742				rand.fill_bytes(&mut key[..]);
1743				let child_info = ChildInfo::new_default(key.as_slice());
1744				let nb_item = 1 + rand.next_u32() % 25;
1745				let mut items = BTreeMap::new();
1746				for item in 0..nb_item {
1747					let key_len = 1 + (rand.next_u32() % 10);
1748					let mut key = vec![0; key_len as usize];
1749					rand.fill_bytes(&mut key[..]);
1750					let value = vec![item as u8; item as usize + 28];
1751					items.insert(key, value);
1752				}
1753				child_infos.push(child_info.clone());
1754				storage.insert(Some(child_info), items);
1755			}
1756
1757			let trie: InMemoryBackend<BlakeTwo256> =
1758				(storage.clone(), StateVersion::default()).into();
1759			let trie_root = *trie.root();
1760			let backend = TrieBackendBuilder::wrap(&trie).with_recorder(Default::default()).build();
1761			let mut queries = Vec::new();
1762			for c in 0..(5 + nb_child_trie / 2) {
1763				// random existing query
1764				let child_info = if c < 5 {
1765					// 4 missing child trie
1766					let key_len = 1 + (rand.next_u32() % 10);
1767					let mut key = vec![0; key_len as usize];
1768					rand.fill_bytes(&mut key[..]);
1769					ChildInfo::new_default(key.as_slice())
1770				} else {
1771					child_infos[rand.next_u32() as usize % nb_child_trie].clone()
1772				};
1773
1774				if let Some(values) = storage.get(&Some(child_info.clone())) {
1775					for _ in 0..(1 + values.len() / 2) {
1776						let ix = rand.next_u32() as usize % values.len();
1777						for (i, (key, value)) in values.iter().enumerate() {
1778							if i == ix {
1779								assert_eq!(
1780									&backend
1781										.child_storage(&child_info, key.as_slice())
1782										.unwrap()
1783										.unwrap(),
1784									value
1785								);
1786								queries.push((
1787									child_info.clone(),
1788									key.clone(),
1789									Some(value.clone()),
1790								));
1791								break;
1792							}
1793						}
1794					}
1795				}
1796				for _ in 0..4 {
1797					let key_len = 1 + (rand.next_u32() % 10);
1798					let mut key = vec![0; key_len as usize];
1799					rand.fill_bytes(&mut key[..]);
1800					let result = backend.child_storage(&child_info, key.as_slice()).unwrap();
1801					queries.push((child_info.clone(), key, result));
1802				}
1803			}
1804
1805			let storage_proof = backend.extract_proof().expect("Failed to extract proof");
1806			let remote_proof = test_compact(storage_proof, &trie_root);
1807			let proof_check =
1808				create_proof_check_backend::<BlakeTwo256>(trie_root, remote_proof).unwrap();
1809
1810			for (child_info, key, expected) in queries {
1811				assert_eq!(
1812					proof_check.child_storage(&child_info, key.as_slice()).unwrap(),
1813					expected,
1814				);
1815			}
1816		}
1817	}
1818
1819	#[test]
1820	fn prove_read_with_size_limit_works() {
1821		let state_version = StateVersion::V0;
1822		let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1823		let remote_root = remote_backend.storage_root(::std::iter::empty(), state_version).0;
1824		let (proof, count) =
1825			prove_range_read_with_size(remote_backend, None, None, 0, None).unwrap();
1826		// Always contains at least some nodes.
1827		assert_eq!(proof.to_memory_db::<BlakeTwo256>().drain().len(), 3);
1828		assert_eq!(count, 1);
1829		assert_eq!(proof.encoded_size(), 443);
1830
1831		let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1832		let (proof, count) =
1833			prove_range_read_with_size(remote_backend, None, None, 800, Some(&[])).unwrap();
1834		assert_eq!(proof.to_memory_db::<BlakeTwo256>().drain().len(), 9);
1835		assert_eq!(count, 85);
1836		assert_eq!(proof.encoded_size(), 857);
1837		let (results, completed) = read_range_proof_check::<BlakeTwo256>(
1838			remote_root,
1839			proof.clone(),
1840			None,
1841			None,
1842			Some(count),
1843			None,
1844		)
1845		.unwrap();
1846		assert_eq!(results.len() as u32, count);
1847		assert_eq!(completed, false);
1848		// When checking without count limit, proof may actually contain extra values.
1849		let (results, completed) =
1850			read_range_proof_check::<BlakeTwo256>(remote_root, proof, None, None, None, None)
1851				.unwrap();
1852		assert_eq!(results.len() as u32, 101);
1853		assert_eq!(completed, false);
1854
1855		let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1856		let (proof, count) =
1857			prove_range_read_with_size(remote_backend, None, None, 50000, Some(&[])).unwrap();
1858		assert_eq!(proof.to_memory_db::<BlakeTwo256>().drain().len(), 11);
1859		assert_eq!(count, 132);
1860		assert_eq!(proof.encoded_size(), 990);
1861
1862		let (results, completed) =
1863			read_range_proof_check::<BlakeTwo256>(remote_root, proof, None, None, None, None)
1864				.unwrap();
1865		assert_eq!(results.len() as u32, count);
1866		assert_eq!(completed, true);
1867	}
1868
1869	#[test]
1870	fn prove_read_with_size_limit_proof_size() {
1871		let mut root = H256::default();
1872		let mut mdb = PrefixedMemoryDB::<BlakeTwo256>::default();
1873		{
1874			let mut mdb = KeySpacedDBMut::new(&mut mdb, b"");
1875			let mut trie = TrieDBMutBuilderV1::new(&mut mdb, &mut root).build();
1876			trie.insert(b"value1", &[123; 1]).unwrap();
1877			trie.insert(b"value2", &[123; 10]).unwrap();
1878			trie.insert(b"value3", &[123; 100]).unwrap();
1879			trie.insert(b"value4", &[123; 1000]).unwrap();
1880		}
1881
1882		let remote_backend: TrieBackend<PrefixedMemoryDB<BlakeTwo256>, BlakeTwo256> =
1883			TrieBackendBuilder::new(mdb, root)
1884				.with_optional_cache(None)
1885				.with_optional_recorder(None)
1886				.build();
1887
1888		let (proof, count) =
1889			prove_range_read_with_size(remote_backend, None, None, 1000, None).unwrap();
1890
1891		assert_eq!(proof.encoded_size(), 1267);
1892		assert_eq!(count, 3);
1893	}
1894
1895	#[test]
1896	fn inner_state_versioning_switch_proofs() {
1897		let mut state_version = StateVersion::V0;
1898		let (mut mdb, mut root) = trie_backend::tests::test_db(state_version);
1899		{
1900			let mut trie = TrieDBMutBuilderV0::from_existing(&mut mdb, &mut root).build();
1901			trie.insert(b"foo", vec![1u8; 1_000].as_slice()) // big inner hash
1902				.expect("insert failed");
1903			trie.insert(b"foo2", vec![3u8; 16].as_slice()) // no inner hash
1904				.expect("insert failed");
1905			trie.insert(b"foo222", vec![5u8; 100].as_slice()) // inner hash
1906				.expect("insert failed");
1907		}
1908
1909		let check_proof = |mdb, root, state_version| -> StorageProof {
1910			let remote_backend = TrieBackendBuilder::new(mdb, root).build();
1911			let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1912			let remote_proof = prove_read(remote_backend, &[b"foo222"]).unwrap();
1913			// check proof locally
1914			let local_result1 =
1915				read_proof_check::<BlakeTwo256, _>(remote_root, remote_proof.clone(), &[b"foo222"])
1916					.unwrap();
1917			// check that results are correct
1918			assert_eq!(
1919				local_result1.into_iter().collect::<Vec<_>>(),
1920				vec![(b"foo222".to_vec(), Some(vec![5u8; 100]))],
1921			);
1922			remote_proof
1923		};
1924
1925		let remote_proof = check_proof(mdb.clone(), root, state_version);
1926		// check full values in proof
1927		assert!(remote_proof.encode().len() > 1_100);
1928		assert!(remote_proof.encoded_size() > 1_100);
1929		let root1 = root;
1930
1931		// do switch
1932		state_version = StateVersion::V1;
1933		{
1934			let mut trie = TrieDBMutBuilderV1::from_existing(&mut mdb, &mut root).build();
1935			trie.insert(b"foo222", vec![5u8; 100].as_slice()) // inner hash
1936				.expect("insert failed");
1937			// update with same value do change
1938			trie.insert(b"foo", vec![1u8; 1000].as_slice()) // inner hash
1939				.expect("insert failed");
1940		}
1941		let root3 = root;
1942		assert!(root1 != root3);
1943		let remote_proof = check_proof(mdb.clone(), root, state_version);
1944		// nodes foo is replaced by its hashed value form.
1945		assert!(remote_proof.encode().len() < 1000);
1946		assert!(remote_proof.encoded_size() < 1000);
1947		assert_eq!(remote_proof.encode().len(), remote_proof.encoded_size());
1948	}
1949
1950	#[test]
1951	fn prove_range_with_child_works() {
1952		let state_version = StateVersion::V0;
1953		let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1954		let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1955		let mut start_at = smallvec::SmallVec::<[Vec<u8>; 2]>::new();
1956		let trie_backend = remote_backend.as_trie_backend();
1957		let max_iter = 1000;
1958		let mut nb_loop = 0;
1959		loop {
1960			nb_loop += 1;
1961			if max_iter == nb_loop {
1962				panic!("Too many loop in prove range");
1963			}
1964			let (proof, count) = prove_range_read_with_child_with_size_on_trie_backend(
1965				trie_backend,
1966				1,
1967				start_at.as_slice(),
1968			)
1969			.unwrap();
1970			// Always contains at least some nodes.
1971			assert!(proof.to_memory_db::<BlakeTwo256>().drain().len() > 0);
1972			assert!(count < 3); // when doing child we include parent and first child key.
1973
1974			let (result, completed_depth) = read_range_proof_check_with_child::<BlakeTwo256>(
1975				remote_root,
1976				proof.clone(),
1977				start_at.as_slice(),
1978			)
1979			.unwrap();
1980
1981			if completed_depth == 0 {
1982				break;
1983			}
1984			assert!(result.update_last_key(completed_depth, &mut start_at));
1985		}
1986
1987		assert_eq!(nb_loop, 10);
1988	}
1989
1990	#[test]
1991	fn compact_multiple_child_trie() {
1992		let size_no_inner_hash = compact_multiple_child_trie_inner(StateVersion::V0);
1993		let size_inner_hash = compact_multiple_child_trie_inner(StateVersion::V1);
1994		assert!(size_inner_hash < size_no_inner_hash);
1995	}
1996	fn compact_multiple_child_trie_inner(state_version: StateVersion) -> usize {
1997		// this root will be queried
1998		let child_info1 = ChildInfo::new_default(b"sub1");
1999		// this root will not be include in proof
2000		let child_info2 = ChildInfo::new_default(b"sub2");
2001		// this root will be include in proof
2002		let child_info3 = ChildInfo::new_default(b"sub");
2003		let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
2004		let long_vec: Vec<u8> = (0..1024usize).map(|_| 8u8).collect();
2005		let (remote_root, transaction) = remote_backend.full_storage_root(
2006			std::iter::empty(),
2007			vec![
2008				(
2009					&child_info1,
2010					vec![
2011						// a inner hashable node
2012						(&b"k"[..], Some(&long_vec[..])),
2013						// need to ensure this is not an inline node
2014						// otherwise we do not know what is accessed when
2015						// storing proof.
2016						(&b"key1"[..], Some(&vec![5u8; 32][..])),
2017						(&b"key2"[..], Some(&b"val3"[..])),
2018					]
2019					.into_iter(),
2020				),
2021				(
2022					&child_info2,
2023					vec![(&b"key3"[..], Some(&b"val4"[..])), (&b"key4"[..], Some(&b"val5"[..]))]
2024						.into_iter(),
2025				),
2026				(
2027					&child_info3,
2028					vec![(&b"key5"[..], Some(&b"val6"[..])), (&b"key6"[..], Some(&b"val7"[..]))]
2029						.into_iter(),
2030				),
2031			]
2032			.into_iter(),
2033			state_version,
2034		);
2035		let mut remote_storage = remote_backend.backend_storage().clone();
2036		remote_storage.consolidate(transaction);
2037		let remote_backend = TrieBackendBuilder::new(remote_storage, remote_root).build();
2038		let remote_proof = prove_child_read(remote_backend, &child_info1, &[b"key1"]).unwrap();
2039		let size = remote_proof.encoded_size();
2040		let remote_proof = test_compact(remote_proof, &remote_root);
2041		let local_result1 = read_child_proof_check::<BlakeTwo256, _>(
2042			remote_root,
2043			remote_proof,
2044			&child_info1,
2045			&[b"key1"],
2046		)
2047		.unwrap();
2048		assert_eq!(local_result1.len(), 1);
2049		assert_eq!(local_result1.get(&b"key1"[..]), Some(&Some(vec![5u8; 32])));
2050		size
2051	}
2052
2053	#[test]
2054	fn child_storage_uuid() {
2055		let state_version = StateVersion::V0;
2056		let child_info_1 = ChildInfo::new_default(b"sub_test1");
2057		let child_info_2 = ChildInfo::new_default(b"sub_test2");
2058
2059		use crate::trie_backend::tests::test_trie;
2060		let mut overlay = OverlayedChanges::default();
2061
2062		let mut transaction = {
2063			let backend = test_trie(state_version, None, None);
2064			let mut ext = Ext::new(&mut overlay, &backend, None, state_version);
2065			ext.set_child_storage(&child_info_1, b"abc".to_vec(), b"def".to_vec());
2066			ext.set_child_storage(&child_info_2, b"abc".to_vec(), b"def".to_vec());
2067			ext.storage_root();
2068			overlay.drain_storage_changes(&backend, state_version).unwrap().transaction
2069		};
2070		let mut duplicate = false;
2071		for (k, (value, rc)) in transaction.drain().iter() {
2072			// look for a key inserted twice: transaction rc is 2
2073			if *rc == 2 {
2074				duplicate = true;
2075				println!("test duplicate for {:?} {:?}", k, value);
2076			}
2077		}
2078		assert!(!duplicate);
2079	}
2080
2081	#[test]
2082	fn set_storage_empty_allowed() {
2083		let initial: BTreeMap<_, _> = map![
2084			b"aaa".to_vec() => b"0".to_vec(),
2085			b"bbb".to_vec() => b"".to_vec()
2086		];
2087		let state = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
2088		let backend = state.as_trie_backend();
2089
2090		let mut overlay = OverlayedChanges::default();
2091		overlay.start_transaction();
2092		overlay.set_storage(b"ccc".to_vec(), Some(b"".to_vec()));
2093		assert_eq!(overlay.storage(b"ccc"), Some(Some(&[][..])));
2094		overlay.commit_transaction().unwrap();
2095		overlay.start_transaction();
2096		assert_eq!(overlay.storage(b"ccc"), Some(Some(&[][..])));
2097		assert_eq!(overlay.storage(b"bbb"), None);
2098
2099		{
2100			let mut ext = Ext::new(&mut overlay, backend, None, StateVersion::default());
2101			assert_eq!(ext.storage(b"bbb"), Some(vec![]));
2102			assert_eq!(ext.storage(b"ccc"), Some(vec![]));
2103			ext.clear_storage(b"ccc");
2104			assert_eq!(ext.storage(b"ccc"), None);
2105		}
2106		overlay.commit_transaction().unwrap();
2107		assert_eq!(overlay.storage(b"ccc"), Some(None));
2108	}
2109}