1#![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#[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#[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#[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#[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#[cfg(feature = "std")]
118pub type DefaultError = String;
119#[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},
172 traits::{CallContext, CodeExecutor, RuntimeCode},
173 };
174 use sp_externalities::Extensions;
175 use sp_trie::PrefixedMemoryDB;
176 use std::collections::{HashMap, HashSet};
177
178 pub(crate) type CallResult<E> = Result<Vec<u8>, E>;
179
180 pub type DefaultHandler<E> = fn(CallResult<E>, CallResult<E>) -> CallResult<E>;
182
183 pub type InMemoryBackend<H> = TrieBackend<PrefixedMemoryDB<H>, H>;
185
186 #[derive(Debug, Clone)]
188 pub enum BackendTrustLevel {
189 Trusted,
191 Untrusted,
195 }
196
197 pub struct StateMachine<'a, B, H, Exec>
199 where
200 H: Hasher,
201 B: Backend<H>,
202 {
203 backend: &'a B,
204 exec: &'a Exec,
205 method: &'a str,
206 call_data: &'a [u8],
207 overlay: &'a mut OverlayedChanges<H>,
208 extensions: &'a mut Extensions,
209 runtime_code: &'a RuntimeCode<'a>,
210 stats: StateMachineStats,
211 parent_hash: Option<H::Out>,
215 context: CallContext,
216 }
217
218 impl<'a, B, H, Exec> Drop for StateMachine<'a, B, H, Exec>
219 where
220 H: Hasher,
221 B: Backend<H>,
222 {
223 fn drop(&mut self) {
224 self.backend.register_overlay_stats(&self.stats);
225 }
226 }
227
228 impl<'a, B, H, Exec> StateMachine<'a, B, H, Exec>
229 where
230 H: Hasher,
231 H::Out: Ord + 'static + codec::Codec,
232 Exec: CodeExecutor + Clone + 'static,
233 B: Backend<H>,
234 {
235 pub fn new(
237 backend: &'a B,
238 overlay: &'a mut OverlayedChanges<H>,
239 exec: &'a Exec,
240 method: &'a str,
241 call_data: &'a [u8],
242 extensions: &'a mut Extensions,
243 runtime_code: &'a RuntimeCode,
244 context: CallContext,
245 ) -> Self {
246 Self {
247 backend,
248 exec,
249 method,
250 call_data,
251 extensions,
252 overlay,
253 runtime_code,
254 stats: StateMachineStats::default(),
255 parent_hash: None,
256 context,
257 }
258 }
259
260 pub fn set_parent_hash(mut self, parent_hash: H::Out) -> Self {
264 self.parent_hash = Some(parent_hash);
265 self
266 }
267
268 pub fn execute(&mut self) -> Result<Vec<u8>, Box<dyn Error>> {
277 self.overlay
278 .enter_runtime()
279 .expect("StateMachine is never called from the runtime; qed");
280
281 let mut ext = Ext::new(self.overlay, self.backend, Some(self.extensions));
282
283 let ext_id = ext.id;
284
285 trace!(
286 target: "state",
287 ext_id = %HexDisplay::from(&ext_id.to_le_bytes()),
288 method = %self.method,
289 parent_hash = %self.parent_hash.map(|h| format!("{:?}", h)).unwrap_or_else(|| String::from("None")),
290 input = ?HexDisplay::from(&self.call_data),
291 "Call",
292 );
293
294 let result = self
295 .exec
296 .call(&mut ext, self.runtime_code, self.method, self.call_data, self.context)
297 .0;
298
299 self.overlay
300 .exit_runtime()
301 .expect("Runtime is not able to call this function in the overlay; qed");
302
303 trace!(
304 target: "state",
305 ext_id = %HexDisplay::from(&ext_id.to_le_bytes()),
306 ?result,
307 "Return",
308 );
309
310 result.map_err(|e| Box::new(e) as Box<_>)
311 }
312 }
313
314 pub fn prove_execution<B, H, Exec>(
316 backend: &mut B,
317 overlay: &mut OverlayedChanges<H>,
318 exec: &Exec,
319 method: &str,
320 call_data: &[u8],
321 runtime_code: &RuntimeCode,
322 ) -> Result<(Vec<u8>, StorageProof), Box<dyn Error>>
323 where
324 B: AsTrieBackend<H>,
325 H: Hasher,
326 H::Out: Ord + 'static + codec::Codec,
327 Exec: CodeExecutor + Clone + 'static,
328 {
329 let trie_backend = backend.as_trie_backend();
330 prove_execution_on_trie_backend::<_, _, _>(
331 trie_backend,
332 overlay,
333 exec,
334 method,
335 call_data,
336 runtime_code,
337 &mut Default::default(),
338 )
339 }
340
341 pub fn prove_execution_on_trie_backend<S, H, Exec>(
351 trie_backend: &TrieBackend<S, H>,
352 overlay: &mut OverlayedChanges<H>,
353 exec: &Exec,
354 method: &str,
355 call_data: &[u8],
356 runtime_code: &RuntimeCode,
357 extensions: &mut Extensions,
358 ) -> Result<(Vec<u8>, StorageProof), Box<dyn Error>>
359 where
360 S: trie_backend_essence::TrieBackendStorage<H>,
361 H: Hasher,
362 H::Out: Ord + 'static + codec::Codec,
363 Exec: CodeExecutor + 'static + Clone,
364 {
365 let proving_backend =
366 TrieBackendBuilder::wrap(trie_backend).with_recorder(Default::default()).build();
367
368 let result = StateMachine::<_, H, Exec>::new(
369 &proving_backend,
370 overlay,
371 exec,
372 method,
373 call_data,
374 extensions,
375 runtime_code,
376 CallContext::Offchain,
377 )
378 .execute()?;
379
380 let proof = proving_backend
381 .extract_proof()
382 .expect("A recorder was set and thus, a storage proof can be extracted; qed");
383
384 Ok((result, proof))
385 }
386
387 pub fn execution_proof_check<H, Exec>(
389 root: H::Out,
390 proof: StorageProof,
391 overlay: &mut OverlayedChanges<H>,
392 exec: &Exec,
393 method: &str,
394 call_data: &[u8],
395 runtime_code: &RuntimeCode,
396 ) -> Result<Vec<u8>, Box<dyn Error>>
397 where
398 H: Hasher + 'static,
399 Exec: CodeExecutor + Clone + 'static,
400 H::Out: Ord + 'static + codec::Codec,
401 {
402 let trie_backend = create_proof_check_backend::<H>(root, proof)?;
403 execution_proof_check_on_trie_backend::<_, _>(
404 &trie_backend,
405 overlay,
406 exec,
407 method,
408 call_data,
409 runtime_code,
410 )
411 }
412
413 pub fn execution_proof_check_on_trie_backend<H, Exec>(
415 trie_backend: &TrieBackend<MemoryDB<H>, H>,
416 overlay: &mut OverlayedChanges<H>,
417 exec: &Exec,
418 method: &str,
419 call_data: &[u8],
420 runtime_code: &RuntimeCode,
421 ) -> Result<Vec<u8>, Box<dyn Error>>
422 where
423 H: Hasher,
424 H::Out: Ord + 'static + codec::Codec,
425 Exec: CodeExecutor + Clone + 'static,
426 {
427 StateMachine::<_, H, Exec>::new(
428 trie_backend,
429 overlay,
430 exec,
431 method,
432 call_data,
433 &mut Extensions::default(),
434 runtime_code,
435 CallContext::Offchain,
436 )
437 .execute()
438 }
439
440 pub fn prove_read<B, H, I>(backend: B, keys: I) -> Result<StorageProof, Box<dyn Error>>
442 where
443 B: AsTrieBackend<H>,
444 H: Hasher,
445 H::Out: Ord + Codec,
446 I: IntoIterator,
447 I::Item: AsRef<[u8]>,
448 {
449 let trie_backend = backend.as_trie_backend();
450 prove_read_on_trie_backend(trie_backend, keys)
451 }
452
453 pub const MAX_NESTED_TRIE_DEPTH: usize = 2;
456
457 #[derive(PartialEq, Eq, Clone)]
460 pub struct KeyValueStates(pub Vec<KeyValueStorageLevel>);
461
462 #[derive(PartialEq, Eq, Clone)]
464 pub struct KeyValueStorageLevel {
465 pub state_root: Vec<u8>,
468 pub parent_storage_keys: Vec<Vec<u8>>,
471 pub key_values: Vec<(Vec<u8>, Vec<u8>)>,
473 }
474
475 impl<I> From<I> for KeyValueStates
476 where
477 I: IntoIterator<Item = (Vec<u8>, (Vec<(Vec<u8>, Vec<u8>)>, Vec<Vec<u8>>))>,
478 {
479 fn from(b: I) -> Self {
480 let mut result = Vec::new();
481 for (state_root, (key_values, storage_paths)) in b.into_iter() {
482 result.push(KeyValueStorageLevel {
483 state_root,
484 key_values,
485 parent_storage_keys: storage_paths,
486 })
487 }
488 KeyValueStates(result)
489 }
490 }
491
492 impl KeyValueStates {
493 pub fn len(&self) -> usize {
495 self.0.iter().fold(0, |nb, state| nb + state.key_values.len())
496 }
497
498 pub fn update_last_key(
500 &self,
501 stopped_at: usize,
502 last: &mut SmallVec<[Vec<u8>; 2]>,
503 ) -> bool {
504 if stopped_at == 0 || stopped_at > MAX_NESTED_TRIE_DEPTH {
505 return false
506 }
507 match stopped_at {
508 1 => {
509 let top_last =
510 self.0.get(0).and_then(|s| s.key_values.last().map(|kv| kv.0.clone()));
511 if let Some(top_last) = top_last {
512 match last.len() {
513 0 => {
514 last.push(top_last);
515 return true
516 },
517 2 => {
518 last.pop();
519 },
520 _ => (),
521 }
522 last[0] = top_last;
524 return true
525 } else {
526 last.truncate(1);
529 return true
530 }
531 },
532 2 => {
533 let top_last =
534 self.0.get(0).and_then(|s| s.key_values.last().map(|kv| kv.0.clone()));
535 let child_last =
536 self.0.last().and_then(|s| s.key_values.last().map(|kv| kv.0.clone()));
537
538 if let Some(child_last) = child_last {
539 if last.is_empty() {
540 if let Some(top_last) = top_last {
541 last.push(top_last)
542 } else {
543 return false
544 }
545 } else if let Some(top_last) = top_last {
546 last[0] = top_last;
547 }
548 if last.len() == 2 {
549 last.pop();
550 }
551 last.push(child_last);
552 return true
553 } else {
554 return false
556 }
557 },
558 _ => (),
559 }
560 false
561 }
562 }
563
564 pub fn prove_range_read_with_child_with_size<B, H>(
572 backend: B,
573 size_limit: usize,
574 start_at: &[Vec<u8>],
575 ) -> Result<(StorageProof, u32), Box<dyn Error>>
576 where
577 B: AsTrieBackend<H>,
578 H: Hasher,
579 H::Out: Ord + Codec,
580 {
581 let trie_backend = backend.as_trie_backend();
582 prove_range_read_with_child_with_size_on_trie_backend(trie_backend, size_limit, start_at)
583 }
584
585 pub fn prove_range_read_with_child_with_size_on_trie_backend<S, H>(
589 trie_backend: &TrieBackend<S, H>,
590 size_limit: usize,
591 start_at: &[Vec<u8>],
592 ) -> Result<(StorageProof, u32), Box<dyn Error>>
593 where
594 S: trie_backend_essence::TrieBackendStorage<H>,
595 H: Hasher,
596 H::Out: Ord + Codec,
597 {
598 if start_at.len() > MAX_NESTED_TRIE_DEPTH {
599 return Err(Box::new("Invalid start of range."))
600 }
601
602 let recorder = sp_trie::recorder::Recorder::default();
603 let proving_backend =
604 TrieBackendBuilder::wrap(trie_backend).with_recorder(recorder.clone()).build();
605 let mut count = 0;
606
607 let mut child_roots = HashSet::new();
608 let (mut child_key, mut start_at) = if start_at.len() == 2 {
609 let storage_key = start_at.get(0).expect("Checked length.").clone();
610 if let Some(state_root) = proving_backend
611 .storage(&storage_key)
612 .map_err(|e| Box::new(e) as Box<dyn Error>)?
613 {
614 child_roots.insert(state_root);
615 } else {
616 return Err(Box::new("Invalid range start child trie key."))
617 }
618
619 (Some(storage_key), start_at.get(1).cloned())
620 } else {
621 (None, start_at.get(0).cloned())
622 };
623
624 loop {
625 let (child_info, depth) = if let Some(storage_key) = child_key.as_ref() {
626 let storage_key = PrefixedStorageKey::new_ref(storage_key);
627 (
628 Some(match ChildType::from_prefixed_key(storage_key) {
629 Some((ChildType::ParentKeyId, storage_key)) =>
630 ChildInfo::new_default(storage_key),
631 None => return Err(Box::new("Invalid range start child trie key.")),
632 }),
633 2,
634 )
635 } else {
636 (None, 1)
637 };
638
639 let start_at_ref = start_at.as_ref().map(AsRef::as_ref);
640 let mut switch_child_key = None;
641 let mut iter = proving_backend
642 .pairs(IterArgs {
643 child_info,
644 start_at: start_at_ref,
645 start_at_exclusive: true,
646 ..IterArgs::default()
647 })
648 .map_err(|e| Box::new(e) as Box<dyn Error>)?;
649
650 while let Some(item) = iter.next() {
651 let (key, value) = item.map_err(|e| Box::new(e) as Box<dyn Error>)?;
652
653 if depth < MAX_NESTED_TRIE_DEPTH &&
654 sp_core::storage::well_known_keys::is_child_storage_key(key.as_slice())
655 {
656 count += 1;
657 if !child_roots.contains(value.as_slice()) {
659 child_roots.insert(value);
660 switch_child_key = Some(key);
661 break
662 }
663 } else if recorder.estimate_encoded_size() <= size_limit {
664 count += 1;
665 } else {
666 break
667 }
668 }
669
670 let completed = iter.was_complete();
671
672 if switch_child_key.is_none() {
673 if depth == 1 {
674 break
675 } else if completed {
676 start_at = child_key.take();
677 } else {
678 break
679 }
680 } else {
681 child_key = switch_child_key;
682 start_at = None;
683 }
684 }
685
686 let proof = proving_backend
687 .extract_proof()
688 .expect("A recorder was set and thus, a storage proof can be extracted; qed");
689 Ok((proof, count))
690 }
691
692 pub fn prove_range_read_with_size<B, H>(
694 backend: B,
695 child_info: Option<&ChildInfo>,
696 prefix: Option<&[u8]>,
697 size_limit: usize,
698 start_at: Option<&[u8]>,
699 ) -> Result<(StorageProof, u32), Box<dyn Error>>
700 where
701 B: AsTrieBackend<H>,
702 H: Hasher,
703 H::Out: Ord + Codec,
704 {
705 let trie_backend = backend.as_trie_backend();
706 prove_range_read_with_size_on_trie_backend(
707 trie_backend,
708 child_info,
709 prefix,
710 size_limit,
711 start_at,
712 )
713 }
714
715 pub fn prove_range_read_with_size_on_trie_backend<S, H>(
717 trie_backend: &TrieBackend<S, H>,
718 child_info: Option<&ChildInfo>,
719 prefix: Option<&[u8]>,
720 size_limit: usize,
721 start_at: Option<&[u8]>,
722 ) -> Result<(StorageProof, u32), Box<dyn Error>>
723 where
724 S: trie_backend_essence::TrieBackendStorage<H>,
725 H: Hasher,
726 H::Out: Ord + Codec,
727 {
728 let recorder = sp_trie::recorder::Recorder::default();
729 let proving_backend =
730 TrieBackendBuilder::wrap(trie_backend).with_recorder(recorder.clone()).build();
731 let mut count = 0;
732 let iter = proving_backend
733 .pairs(IterArgs {
737 child_info: child_info.cloned(),
738 prefix,
739 start_at,
740 ..IterArgs::default()
741 })
742 .map_err(|e| Box::new(e) as Box<dyn Error>)?;
743
744 for item in iter {
745 item.map_err(|e| Box::new(e) as Box<dyn Error>)?;
746 if count == 0 || recorder.estimate_encoded_size() <= size_limit {
747 count += 1;
748 } else {
749 break
750 }
751 }
752
753 let proof = proving_backend
754 .extract_proof()
755 .expect("A recorder was set and thus, a storage proof can be extracted; qed");
756 Ok((proof, count))
757 }
758
759 pub fn prove_child_read<B, H, I>(
761 backend: B,
762 child_info: &ChildInfo,
763 keys: I,
764 ) -> Result<StorageProof, Box<dyn Error>>
765 where
766 B: AsTrieBackend<H>,
767 H: Hasher,
768 H::Out: Ord + Codec,
769 I: IntoIterator,
770 I::Item: AsRef<[u8]>,
771 {
772 let trie_backend = backend.as_trie_backend();
773 prove_child_read_on_trie_backend(trie_backend, child_info, keys)
774 }
775
776 pub fn prove_read_on_trie_backend<S, H, I>(
778 trie_backend: &TrieBackend<S, H>,
779 keys: I,
780 ) -> Result<StorageProof, Box<dyn Error>>
781 where
782 S: trie_backend_essence::TrieBackendStorage<H>,
783 H: Hasher,
784 H::Out: Ord + Codec,
785 I: IntoIterator,
786 I::Item: AsRef<[u8]>,
787 {
788 let proving_backend =
789 TrieBackendBuilder::wrap(trie_backend).with_recorder(Default::default()).build();
790 for key in keys.into_iter() {
791 proving_backend
792 .storage(key.as_ref())
793 .map_err(|e| Box::new(e) as Box<dyn Error>)?;
794 }
795
796 Ok(proving_backend
797 .extract_proof()
798 .expect("A recorder was set and thus, a storage proof can be extracted; qed"))
799 }
800
801 pub fn prove_child_read_on_trie_backend<S, H, I>(
803 trie_backend: &TrieBackend<S, H>,
804 child_info: &ChildInfo,
805 keys: I,
806 ) -> Result<StorageProof, Box<dyn Error>>
807 where
808 S: trie_backend_essence::TrieBackendStorage<H>,
809 H: Hasher,
810 H::Out: Ord + Codec,
811 I: IntoIterator,
812 I::Item: AsRef<[u8]>,
813 {
814 let proving_backend =
815 TrieBackendBuilder::wrap(trie_backend).with_recorder(Default::default()).build();
816 for key in keys.into_iter() {
817 proving_backend
818 .child_storage(child_info, key.as_ref())
819 .map_err(|e| Box::new(e) as Box<dyn Error>)?;
820 }
821
822 Ok(proving_backend
823 .extract_proof()
824 .expect("A recorder was set and thus, a storage proof can be extracted; qed"))
825 }
826
827 pub fn read_proof_check<H, I>(
829 root: H::Out,
830 proof: StorageProof,
831 keys: I,
832 ) -> Result<HashMap<Vec<u8>, Option<Vec<u8>>>, Box<dyn Error>>
833 where
834 H: Hasher + 'static,
835 H::Out: Ord + Codec,
836 I: IntoIterator,
837 I::Item: AsRef<[u8]>,
838 {
839 let proving_backend = create_proof_check_backend::<H>(root, proof)?;
840 let mut result = HashMap::new();
841 for key in keys.into_iter() {
842 let value = read_proof_check_on_proving_backend(&proving_backend, key.as_ref())?;
843 result.insert(key.as_ref().to_vec(), value);
844 }
845 Ok(result)
846 }
847
848 pub fn read_range_proof_check_with_child<H>(
854 root: H::Out,
855 proof: StorageProof,
856 start_at: &[Vec<u8>],
857 ) -> Result<(KeyValueStates, usize), Box<dyn Error>>
858 where
859 H: Hasher + 'static,
860 H::Out: Ord + Codec,
861 {
862 let proving_backend = create_proof_check_backend::<H>(root, proof)?;
863 read_range_proof_check_with_child_on_proving_backend(&proving_backend, start_at)
864 }
865
866 pub fn read_range_proof_check<H>(
868 root: H::Out,
869 proof: StorageProof,
870 child_info: Option<&ChildInfo>,
871 prefix: Option<&[u8]>,
872 count: Option<u32>,
873 start_at: Option<&[u8]>,
874 ) -> Result<(Vec<(Vec<u8>, Vec<u8>)>, bool), Box<dyn Error>>
875 where
876 H: Hasher + 'static,
877 H::Out: Ord + Codec,
878 {
879 let proving_backend = create_proof_check_backend::<H>(root, proof)?;
880 read_range_proof_check_on_proving_backend(
881 &proving_backend,
882 child_info,
883 prefix,
884 count,
885 start_at,
886 )
887 }
888
889 pub fn read_child_proof_check<H, I>(
891 root: H::Out,
892 proof: StorageProof,
893 child_info: &ChildInfo,
894 keys: I,
895 ) -> Result<HashMap<Vec<u8>, Option<Vec<u8>>>, Box<dyn Error>>
896 where
897 H: Hasher + 'static,
898 H::Out: Ord + Codec,
899 I: IntoIterator,
900 I::Item: AsRef<[u8]>,
901 {
902 let proving_backend = create_proof_check_backend::<H>(root, proof)?;
903 let mut result = HashMap::new();
904 for key in keys.into_iter() {
905 let value = read_child_proof_check_on_proving_backend(
906 &proving_backend,
907 child_info,
908 key.as_ref(),
909 )?;
910 result.insert(key.as_ref().to_vec(), value);
911 }
912 Ok(result)
913 }
914
915 pub fn read_proof_check_on_proving_backend<H>(
917 proving_backend: &TrieBackend<MemoryDB<H>, H>,
918 key: &[u8],
919 ) -> Result<Option<Vec<u8>>, Box<dyn Error>>
920 where
921 H: Hasher,
922 H::Out: Ord + Codec,
923 {
924 proving_backend.storage(key).map_err(|e| Box::new(e) as Box<dyn Error>)
925 }
926
927 pub fn read_child_proof_check_on_proving_backend<H>(
929 proving_backend: &TrieBackend<MemoryDB<H>, H>,
930 child_info: &ChildInfo,
931 key: &[u8],
932 ) -> Result<Option<Vec<u8>>, Box<dyn Error>>
933 where
934 H: Hasher,
935 H::Out: Ord + Codec,
936 {
937 proving_backend
938 .child_storage(child_info, key)
939 .map_err(|e| Box::new(e) as Box<dyn Error>)
940 }
941
942 pub fn read_range_proof_check_on_proving_backend<H>(
947 proving_backend: &TrieBackend<MemoryDB<H>, H>,
948 child_info: Option<&ChildInfo>,
949 prefix: Option<&[u8]>,
950 count: Option<u32>,
951 start_at: Option<&[u8]>,
952 ) -> Result<(Vec<(Vec<u8>, Vec<u8>)>, bool), Box<dyn Error>>
953 where
954 H: Hasher,
955 H::Out: Ord + Codec,
956 {
957 let mut values = Vec::new();
958 let mut iter = proving_backend
959 .pairs(IterArgs {
960 child_info: child_info.cloned(),
961 prefix,
962 start_at,
963 stop_on_incomplete_database: true,
964 ..IterArgs::default()
965 })
966 .map_err(|e| Box::new(e) as Box<dyn Error>)?;
967
968 while let Some(item) = iter.next() {
969 let (key, value) = item.map_err(|e| Box::new(e) as Box<dyn Error>)?;
970 values.push((key, value));
971 if !count.as_ref().map_or(true, |c| (values.len() as u32) < *c) {
972 break
973 }
974 }
975
976 Ok((values, iter.was_complete()))
977 }
978
979 pub fn read_range_proof_check_with_child_on_proving_backend<H>(
983 proving_backend: &TrieBackend<MemoryDB<H>, H>,
984 start_at: &[Vec<u8>],
985 ) -> Result<(KeyValueStates, usize), Box<dyn Error>>
986 where
987 H: Hasher,
988 H::Out: Ord + Codec,
989 {
990 let mut result = vec![KeyValueStorageLevel {
991 state_root: Default::default(),
992 key_values: Default::default(),
993 parent_storage_keys: Default::default(),
994 }];
995 if start_at.len() > MAX_NESTED_TRIE_DEPTH {
996 return Err(Box::new("Invalid start of range."))
997 }
998
999 let mut child_roots = HashSet::new();
1000 let (mut child_key, mut start_at) = if start_at.len() == 2 {
1001 let storage_key = start_at.get(0).expect("Checked length.").clone();
1002 let child_key = if let Some(state_root) = proving_backend
1003 .storage(&storage_key)
1004 .map_err(|e| Box::new(e) as Box<dyn Error>)?
1005 {
1006 child_roots.insert(state_root.clone());
1007 Some((storage_key, state_root))
1008 } else {
1009 return Err(Box::new("Invalid range start child trie key."))
1010 };
1011
1012 (child_key, start_at.get(1).cloned())
1013 } else {
1014 (None, start_at.get(0).cloned())
1015 };
1016
1017 let completed = loop {
1018 let (child_info, depth) = if let Some((storage_key, state_root)) = child_key.as_ref() {
1019 result.push(KeyValueStorageLevel {
1020 state_root: state_root.clone(),
1021 key_values: Default::default(),
1022 parent_storage_keys: Default::default(),
1023 });
1024
1025 let storage_key = PrefixedStorageKey::new_ref(storage_key);
1026 (
1027 Some(match ChildType::from_prefixed_key(storage_key) {
1028 Some((ChildType::ParentKeyId, storage_key)) =>
1029 ChildInfo::new_default(storage_key),
1030 None => return Err(Box::new("Invalid range start child trie key.")),
1031 }),
1032 2,
1033 )
1034 } else {
1035 (None, 1)
1036 };
1037
1038 let values = if child_info.is_some() {
1039 &mut result.last_mut().expect("Added above").key_values
1040 } else {
1041 &mut result[0].key_values
1042 };
1043 let start_at_ref = start_at.as_ref().map(AsRef::as_ref);
1044 let mut switch_child_key = None;
1045
1046 let mut iter = proving_backend
1047 .pairs(IterArgs {
1048 child_info,
1049 start_at: start_at_ref,
1050 start_at_exclusive: true,
1051 stop_on_incomplete_database: true,
1052 ..IterArgs::default()
1053 })
1054 .map_err(|e| Box::new(e) as Box<dyn Error>)?;
1055
1056 while let Some(item) = iter.next() {
1057 let (key, value) = item.map_err(|e| Box::new(e) as Box<dyn Error>)?;
1058 values.push((key.to_vec(), value.to_vec()));
1059
1060 if depth < MAX_NESTED_TRIE_DEPTH &&
1061 sp_core::storage::well_known_keys::is_child_storage_key(key.as_slice())
1062 {
1063 if !child_roots.contains(value.as_slice()) {
1065 child_roots.insert(value.clone());
1066 switch_child_key = Some((key, value));
1067 break
1068 }
1069 }
1070 }
1071
1072 let completed = iter.was_complete();
1073
1074 if switch_child_key.is_none() {
1075 if !completed {
1076 break depth
1077 }
1078 if depth == 1 {
1079 break 0
1080 } else {
1081 start_at = child_key.take().map(|entry| entry.0);
1082 }
1083 } else {
1084 child_key = switch_child_key;
1085 start_at = None;
1086 }
1087 };
1088 Ok((KeyValueStates(result), completed))
1089 }
1090}
1091
1092#[cfg(test)]
1093mod tests {
1094 use super::{backend::AsTrieBackend, ext::Ext, *};
1095 use crate::{execution::CallResult, in_memory_backend::new_in_mem};
1096 use assert_matches::assert_matches;
1097 use codec::Encode;
1098 use sp_core::{
1099 map,
1100 storage::{ChildInfo, StateVersion},
1101 traits::{CallContext, CodeExecutor, Externalities, RuntimeCode},
1102 H256,
1103 };
1104 use sp_runtime::traits::BlakeTwo256;
1105 use sp_trie::{
1106 trie_types::{TrieDBMutBuilderV0, TrieDBMutBuilderV1},
1107 KeySpacedDBMut, PrefixedMemoryDB,
1108 };
1109 use std::collections::{BTreeMap, HashMap};
1110
1111 #[derive(Clone)]
1112 struct DummyCodeExecutor {
1113 native_available: bool,
1114 native_succeeds: bool,
1115 fallback_succeeds: bool,
1116 }
1117
1118 impl CodeExecutor for DummyCodeExecutor {
1119 type Error = u8;
1120
1121 fn call(
1122 &self,
1123 ext: &mut dyn Externalities,
1124 _: &RuntimeCode,
1125 _method: &str,
1126 _data: &[u8],
1127 _: CallContext,
1128 ) -> (CallResult<Self::Error>, bool) {
1129 let using_native = self.native_available;
1130 match (using_native, self.native_succeeds, self.fallback_succeeds) {
1131 (true, true, _) | (false, _, true) => (
1132 Ok(vec![
1133 ext.storage(b"value1").unwrap()[0] + ext.storage(b"value2").unwrap()[0],
1134 ]),
1135 using_native,
1136 ),
1137 _ => (Err(0), using_native),
1138 }
1139 }
1140 }
1141
1142 impl sp_core::traits::ReadRuntimeVersion for DummyCodeExecutor {
1143 fn read_runtime_version(
1144 &self,
1145 _: &[u8],
1146 _: &mut dyn Externalities,
1147 ) -> std::result::Result<Vec<u8>, String> {
1148 unimplemented!("Not required in tests.")
1149 }
1150 }
1151
1152 #[test]
1153 fn execute_works() {
1154 execute_works_inner(StateVersion::V0);
1155 execute_works_inner(StateVersion::V1);
1156 }
1157 fn execute_works_inner(state_version: StateVersion) {
1158 let backend = trie_backend::tests::test_trie(state_version, None, None);
1159 let mut overlayed_changes = Default::default();
1160 let wasm_code = RuntimeCode::empty();
1161 let mut execution_extensions = &mut Default::default();
1162
1163 let mut state_machine = StateMachine::new(
1164 &backend,
1165 &mut overlayed_changes,
1166 &DummyCodeExecutor {
1167 native_available: true,
1168 native_succeeds: true,
1169 fallback_succeeds: true,
1170 },
1171 "test",
1172 &[],
1173 &mut execution_extensions,
1174 &wasm_code,
1175 CallContext::Offchain,
1176 );
1177
1178 assert_eq!(state_machine.execute().unwrap(), vec![66]);
1179 }
1180
1181 #[test]
1182 fn execute_works_with_native_else_wasm() {
1183 execute_works_with_native_else_wasm_inner(StateVersion::V0);
1184 execute_works_with_native_else_wasm_inner(StateVersion::V1);
1185 }
1186 fn execute_works_with_native_else_wasm_inner(state_version: StateVersion) {
1187 let backend = trie_backend::tests::test_trie(state_version, None, None);
1188 let mut overlayed_changes = Default::default();
1189 let wasm_code = RuntimeCode::empty();
1190 let mut execution_extensions = &mut Default::default();
1191
1192 let mut state_machine = StateMachine::new(
1193 &backend,
1194 &mut overlayed_changes,
1195 &DummyCodeExecutor {
1196 native_available: true,
1197 native_succeeds: true,
1198 fallback_succeeds: true,
1199 },
1200 "test",
1201 &[],
1202 &mut execution_extensions,
1203 &wasm_code,
1204 CallContext::Offchain,
1205 );
1206
1207 assert_eq!(state_machine.execute().unwrap(), vec![66]);
1208 }
1209
1210 #[test]
1211 fn prove_execution_and_proof_check_works() {
1212 prove_execution_and_proof_check_works_inner(StateVersion::V0);
1213 prove_execution_and_proof_check_works_inner(StateVersion::V1);
1214 }
1215 fn prove_execution_and_proof_check_works_inner(state_version: StateVersion) {
1216 let executor = DummyCodeExecutor {
1217 native_available: true,
1218 native_succeeds: true,
1219 fallback_succeeds: true,
1220 };
1221
1222 let mut remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1224 let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1225 let (remote_result, remote_proof) = prove_execution(
1226 &mut remote_backend,
1227 &mut Default::default(),
1228 &executor,
1229 "test",
1230 &[],
1231 &RuntimeCode::empty(),
1232 )
1233 .unwrap();
1234
1235 let local_result = execution_proof_check::<BlakeTwo256, _>(
1237 remote_root,
1238 remote_proof,
1239 &mut Default::default(),
1240 &executor,
1241 "test",
1242 &[],
1243 &RuntimeCode::empty(),
1244 )
1245 .unwrap();
1246
1247 assert_eq!(remote_result, vec![66]);
1249 assert_eq!(remote_result, local_result);
1250 }
1251
1252 #[test]
1253 fn clear_prefix_in_ext_works() {
1254 let initial: BTreeMap<_, _> = map![
1255 b"aaa".to_vec() => b"0".to_vec(),
1256 b"abb".to_vec() => b"1".to_vec(),
1257 b"abc".to_vec() => b"2".to_vec(),
1258 b"bbb".to_vec() => b"3".to_vec()
1259 ];
1260 let state = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
1261 let backend = state.as_trie_backend();
1262
1263 let mut overlay = OverlayedChanges::default();
1264 overlay.set_storage(b"aba".to_vec(), Some(b"1312".to_vec()));
1265 overlay.set_storage(b"bab".to_vec(), Some(b"228".to_vec()));
1266 overlay.start_transaction();
1267 overlay.set_storage(b"abd".to_vec(), Some(b"69".to_vec()));
1268 overlay.set_storage(b"bbd".to_vec(), Some(b"42".to_vec()));
1269
1270 let overlay_limit = overlay.clone();
1271 {
1272 let mut ext = Ext::new(&mut overlay, backend, None);
1273 let _ = ext.clear_prefix(b"ab", None, None);
1274 }
1275 overlay.commit_transaction().unwrap();
1276
1277 assert_eq!(
1278 overlay
1279 .changes_mut()
1280 .map(|(k, v)| (k.clone(), v.value().cloned()))
1281 .collect::<HashMap<_, _>>(),
1282 map![
1283 b"abc".to_vec() => None,
1284 b"abb".to_vec() => None,
1285 b"aba".to_vec() => None,
1286 b"abd".to_vec() => None,
1287
1288 b"bab".to_vec() => Some(b"228".to_vec()),
1289 b"bbd".to_vec() => Some(b"42".to_vec())
1290 ],
1291 );
1292
1293 let mut overlay = overlay_limit;
1294 {
1295 let mut ext = Ext::new(&mut overlay, backend, None);
1296 assert_matches!(
1297 ext.clear_prefix(b"ab", Some(1), None).deconstruct(),
1298 (Some(_), 1, 3, 1)
1299 );
1300 }
1301 overlay.commit_transaction().unwrap();
1302
1303 assert_eq!(
1304 overlay
1305 .changes_mut()
1306 .map(|(k, v)| (k.clone(), v.value().cloned()))
1307 .collect::<HashMap<_, _>>(),
1308 map![
1309 b"abb".to_vec() => None,
1310 b"aba".to_vec() => None,
1311 b"abd".to_vec() => None,
1312
1313 b"bab".to_vec() => Some(b"228".to_vec()),
1314 b"bbd".to_vec() => Some(b"42".to_vec())
1315 ],
1316 );
1317 }
1318
1319 #[test]
1320 fn limited_child_kill_works() {
1321 let child_info = ChildInfo::new_default(b"sub1");
1322 let initial: HashMap<_, BTreeMap<_, _>> = map![
1323 Some(child_info.clone()) => map![
1324 b"a".to_vec() => b"0".to_vec(),
1325 b"b".to_vec() => b"1".to_vec(),
1326 b"c".to_vec() => b"2".to_vec(),
1327 b"d".to_vec() => b"3".to_vec()
1328 ],
1329 ];
1330 let backend = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
1331
1332 let mut overlay = OverlayedChanges::default();
1333 overlay.set_child_storage(&child_info, b"1".to_vec(), Some(b"1312".to_vec()));
1334 overlay.set_child_storage(&child_info, b"2".to_vec(), Some(b"1312".to_vec()));
1335 overlay.set_child_storage(&child_info, b"3".to_vec(), Some(b"1312".to_vec()));
1336 overlay.set_child_storage(&child_info, b"4".to_vec(), Some(b"1312".to_vec()));
1337
1338 {
1339 let mut ext = Ext::new(&mut overlay, &backend, None);
1340 let r = ext.kill_child_storage(&child_info, Some(2), None);
1341 assert_matches!(r.deconstruct(), (Some(_), 2, 6, 2));
1342 }
1343
1344 assert_eq!(
1345 overlay
1346 .children_mut()
1347 .flat_map(|(iter, _child_info)| iter)
1348 .map(|(k, v)| (k.clone(), v.value()))
1349 .collect::<BTreeMap<_, _>>(),
1350 map![
1351 b"1".to_vec() => None,
1352 b"2".to_vec() => None,
1353 b"3".to_vec() => None,
1354 b"4".to_vec() => None,
1355 b"a".to_vec() => None,
1356 b"b".to_vec() => None,
1357 ],
1358 );
1359 }
1360
1361 #[test]
1362 fn limited_child_kill_off_by_one_works() {
1363 let child_info = ChildInfo::new_default(b"sub1");
1364 let initial: HashMap<_, BTreeMap<_, _>> = map![
1365 Some(child_info.clone()) => map![
1366 b"a".to_vec() => b"0".to_vec(),
1367 b"b".to_vec() => b"1".to_vec(),
1368 b"c".to_vec() => b"2".to_vec(),
1369 b"d".to_vec() => b"3".to_vec()
1370 ],
1371 ];
1372 let backend = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
1373 let mut overlay = OverlayedChanges::default();
1374 let mut ext = Ext::new(&mut overlay, &backend, None);
1375 let r = ext.kill_child_storage(&child_info, Some(0), None).deconstruct();
1376 assert_matches!(r, (Some(_), 0, 0, 0));
1377 let r = ext
1378 .kill_child_storage(&child_info, Some(1), r.0.as_ref().map(|x| &x[..]))
1379 .deconstruct();
1380 assert_matches!(r, (Some(_), 1, 1, 1));
1381 let r = ext
1382 .kill_child_storage(&child_info, Some(4), r.0.as_ref().map(|x| &x[..]))
1383 .deconstruct();
1384 assert_matches!(r, (None, 3, 3, 3));
1386 let r = ext.kill_child_storage(&child_info, Some(1), None).deconstruct();
1387 assert_matches!(r, (Some(_), 0, 0, 1));
1388 }
1389
1390 #[test]
1391 fn limited_child_kill_off_by_one_works_without_limit() {
1392 let child_info = ChildInfo::new_default(b"sub1");
1393 let initial: HashMap<_, BTreeMap<_, _>> = map![
1394 Some(child_info.clone()) => map![
1395 b"a".to_vec() => b"0".to_vec(),
1396 b"b".to_vec() => b"1".to_vec(),
1397 b"c".to_vec() => b"2".to_vec(),
1398 b"d".to_vec() => b"3".to_vec()
1399 ],
1400 ];
1401 let backend = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
1402 let mut overlay = OverlayedChanges::default();
1403 let mut ext = Ext::new(&mut overlay, &backend, None);
1404 assert_eq!(ext.kill_child_storage(&child_info, None, None).deconstruct(), (None, 4, 4, 4));
1405 }
1406
1407 #[test]
1408 fn set_child_storage_works() {
1409 let child_info = ChildInfo::new_default(b"sub1");
1410 let child_info = &child_info;
1411 let state = new_in_mem::<BlakeTwo256>();
1412 let backend = state.as_trie_backend();
1413 let mut overlay = OverlayedChanges::default();
1414 let mut ext = Ext::new(&mut overlay, backend, None);
1415
1416 ext.set_child_storage(child_info, b"abc".to_vec(), b"def".to_vec());
1417 assert_eq!(ext.child_storage(child_info, b"abc"), Some(b"def".to_vec()));
1418 let _ = ext.kill_child_storage(child_info, None, None);
1419 assert_eq!(ext.child_storage(child_info, b"abc"), None);
1420 }
1421
1422 #[test]
1423 fn append_storage_works() {
1424 let reference_data = vec![b"data1".to_vec(), b"2".to_vec(), b"D3".to_vec(), b"d4".to_vec()];
1425 let key = b"key".to_vec();
1426 let state = new_in_mem::<BlakeTwo256>();
1427 let backend = state.as_trie_backend();
1428 let mut overlay = OverlayedChanges::default();
1429 {
1430 let mut ext = Ext::new(&mut overlay, backend, None);
1431
1432 ext.storage_append(key.clone(), reference_data[0].encode());
1433 assert_eq!(ext.storage(key.as_slice()), Some(vec![reference_data[0].clone()].encode()));
1434 }
1435 overlay.start_transaction();
1436 {
1437 let mut ext = Ext::new(&mut overlay, backend, None);
1438
1439 for i in reference_data.iter().skip(1) {
1440 ext.storage_append(key.clone(), i.encode());
1441 }
1442 assert_eq!(ext.storage(key.as_slice()), Some(reference_data.encode()));
1443 }
1444 overlay.rollback_transaction().unwrap();
1445 {
1446 let mut ext = Ext::new(&mut overlay, backend, None);
1447 assert_eq!(ext.storage(key.as_slice()), Some(vec![reference_data[0].clone()].encode()));
1448 }
1449 }
1450
1451 #[test]
1455 fn commit_merges_append_with_parent() {
1456 #[derive(codec::Encode, codec::Decode)]
1457 enum Item {
1458 Item1,
1459 Item2,
1460 }
1461
1462 let key = b"events".to_vec();
1463 let state = new_in_mem::<BlakeTwo256>();
1464 let backend = state.as_trie_backend();
1465 let mut overlay = OverlayedChanges::default();
1466
1467 overlay.start_transaction();
1469 {
1470 let mut ext = Ext::new(&mut overlay, backend, None);
1471 ext.clear_storage(key.as_slice());
1472 ext.storage_append(key.clone(), Item::Item1.encode());
1473 }
1474
1475 overlay.start_transaction();
1477 {
1478 let mut ext = Ext::new(&mut overlay, backend, None);
1479
1480 assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::Item1].encode()));
1481
1482 ext.storage_append(key.clone(), Item::Item2.encode());
1483
1484 assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::Item1, Item::Item2].encode()),);
1485 }
1486
1487 overlay.start_transaction();
1489 {
1490 let mut ext = Ext::new(&mut overlay, backend, None);
1491
1492 ext.place_storage(key.clone(), None);
1493
1494 assert_eq!(ext.storage(key.as_slice()), None);
1495 }
1496
1497 overlay.commit_transaction().unwrap();
1499 {
1500 let mut ext = Ext::new(&mut overlay, backend, None);
1501 assert_eq!(ext.storage(key.as_slice()), None,);
1502 }
1503
1504 overlay.rollback_transaction().unwrap();
1506 {
1507 let mut ext = Ext::new(&mut overlay, backend, None);
1508 assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::Item1].encode()));
1509 }
1510
1511 overlay.commit_transaction().unwrap();
1512 {
1513 let mut ext = Ext::new(&mut overlay, backend, None);
1514 assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::Item1].encode()));
1515 }
1516 }
1517
1518 #[test]
1519 fn remove_with_append_then_rollback_appended_then_append_again() {
1520 #[derive(codec::Encode, codec::Decode)]
1521 enum Item {
1522 InitializationItem,
1523 DiscardedItem,
1524 CommittedItem,
1525 }
1526
1527 let key = b"events".to_vec();
1528 let state = new_in_mem::<BlakeTwo256>();
1529 let backend = state.as_trie_backend();
1530 let mut overlay = OverlayedChanges::default();
1531
1532 {
1534 let mut ext = Ext::new(&mut overlay, backend, None);
1535 ext.clear_storage(key.as_slice());
1536 ext.storage_append(key.clone(), Item::InitializationItem.encode());
1537 }
1538 overlay.start_transaction();
1539
1540 {
1542 let mut ext = Ext::new(&mut overlay, backend, None);
1543
1544 assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::InitializationItem].encode()));
1545
1546 ext.storage_append(key.clone(), Item::DiscardedItem.encode());
1547
1548 assert_eq!(
1549 ext.storage(key.as_slice()),
1550 Some(vec![Item::InitializationItem, Item::DiscardedItem].encode()),
1551 );
1552 }
1553 overlay.rollback_transaction().unwrap();
1554
1555 {
1557 let mut ext = Ext::new(&mut overlay, backend, None);
1558
1559 assert_eq!(ext.storage(key.as_slice()), Some(vec![Item::InitializationItem].encode()));
1560
1561 ext.storage_append(key.clone(), Item::CommittedItem.encode());
1562
1563 assert_eq!(
1564 ext.storage(key.as_slice()),
1565 Some(vec![Item::InitializationItem, Item::CommittedItem].encode()),
1566 );
1567 }
1568 overlay.start_transaction();
1569
1570 {
1572 let mut ext = Ext::new(&mut overlay, backend, None);
1573 assert_eq!(
1574 ext.storage(key.as_slice()),
1575 Some(vec![Item::InitializationItem, Item::CommittedItem].encode()),
1576 );
1577 }
1578 }
1579
1580 fn test_compact(remote_proof: StorageProof, remote_root: &sp_core::H256) -> StorageProof {
1581 let compact_remote_proof =
1582 remote_proof.into_compact_proof::<BlakeTwo256>(*remote_root).unwrap();
1583 compact_remote_proof
1584 .to_storage_proof::<BlakeTwo256>(Some(remote_root))
1585 .unwrap()
1586 .0
1587 }
1588
1589 #[test]
1590 fn prove_read_and_proof_check_works() {
1591 prove_read_and_proof_check_works_inner(StateVersion::V0);
1592 prove_read_and_proof_check_works_inner(StateVersion::V1);
1593 }
1594 fn prove_read_and_proof_check_works_inner(state_version: StateVersion) {
1595 let child_info = ChildInfo::new_default(b"sub1");
1596 let missing_child_info = ChildInfo::new_default(b"sub1sub2"); let child_info = &child_info;
1598 let missing_child_info = &missing_child_info;
1599 let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1601 let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1602 let remote_proof = prove_read(remote_backend, &[b"value2"]).unwrap();
1603 let remote_proof = test_compact(remote_proof, &remote_root);
1604 let local_result1 =
1606 read_proof_check::<BlakeTwo256, _>(remote_root, remote_proof.clone(), &[b"value2"])
1607 .unwrap();
1608 let local_result2 =
1609 read_proof_check::<BlakeTwo256, _>(remote_root, remote_proof, &[&[0xff]]).is_ok();
1610 assert_eq!(
1612 local_result1.into_iter().collect::<Vec<_>>(),
1613 vec![(b"value2".to_vec(), Some(vec![24]))],
1614 );
1615 assert_eq!(local_result2, false);
1616 let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1618 let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1619 let remote_proof = prove_child_read(remote_backend, child_info, &[b"value3"]).unwrap();
1620 let remote_proof = test_compact(remote_proof, &remote_root);
1621 let local_result1 = read_child_proof_check::<BlakeTwo256, _>(
1622 remote_root,
1623 remote_proof.clone(),
1624 child_info,
1625 &[b"value3"],
1626 )
1627 .unwrap();
1628 let local_result2 = read_child_proof_check::<BlakeTwo256, _>(
1629 remote_root,
1630 remote_proof.clone(),
1631 child_info,
1632 &[b"value2"],
1633 )
1634 .unwrap();
1635 let local_result3 = read_child_proof_check::<BlakeTwo256, _>(
1636 remote_root,
1637 remote_proof,
1638 missing_child_info,
1639 &[b"dummy"],
1640 )
1641 .unwrap();
1642
1643 assert_eq!(
1644 local_result1.into_iter().collect::<Vec<_>>(),
1645 vec![(b"value3".to_vec(), Some(vec![142; 33]))],
1646 );
1647 assert_eq!(local_result2.into_iter().collect::<Vec<_>>(), vec![(b"value2".to_vec(), None)]);
1648 assert_eq!(local_result3.into_iter().collect::<Vec<_>>(), vec![(b"dummy".to_vec(), None)]);
1649 }
1650
1651 #[test]
1652 fn child_read_compact_stress_test() {
1653 use rand::{rngs::SmallRng, RngCore, SeedableRng};
1654 let mut storage: HashMap<Option<ChildInfo>, BTreeMap<StorageKey, StorageValue>> =
1655 Default::default();
1656 let mut seed = [0; 32];
1657 for i in 0..50u32 {
1658 let mut child_infos = Vec::new();
1659 let seed_partial = &mut seed[0..4];
1660 seed_partial.copy_from_slice(&i.to_be_bytes()[..]);
1661 let mut rand = SmallRng::from_seed(seed);
1662
1663 let nb_child_trie = rand.next_u32() as usize % 25;
1664 for _ in 0..nb_child_trie {
1665 let key_len = 1 + (rand.next_u32() % 10);
1666 let mut key = vec![0; key_len as usize];
1667 rand.fill_bytes(&mut key[..]);
1668 let child_info = ChildInfo::new_default(key.as_slice());
1669 let nb_item = 1 + rand.next_u32() % 25;
1670 let mut items = BTreeMap::new();
1671 for item in 0..nb_item {
1672 let key_len = 1 + (rand.next_u32() % 10);
1673 let mut key = vec![0; key_len as usize];
1674 rand.fill_bytes(&mut key[..]);
1675 let value = vec![item as u8; item as usize + 28];
1676 items.insert(key, value);
1677 }
1678 child_infos.push(child_info.clone());
1679 storage.insert(Some(child_info), items);
1680 }
1681
1682 let trie: InMemoryBackend<BlakeTwo256> =
1683 (storage.clone(), StateVersion::default()).into();
1684 let trie_root = *trie.root();
1685 let backend = TrieBackendBuilder::wrap(&trie).with_recorder(Default::default()).build();
1686 let mut queries = Vec::new();
1687 for c in 0..(5 + nb_child_trie / 2) {
1688 let child_info = if c < 5 {
1690 let key_len = 1 + (rand.next_u32() % 10);
1692 let mut key = vec![0; key_len as usize];
1693 rand.fill_bytes(&mut key[..]);
1694 ChildInfo::new_default(key.as_slice())
1695 } else {
1696 child_infos[rand.next_u32() as usize % nb_child_trie].clone()
1697 };
1698
1699 if let Some(values) = storage.get(&Some(child_info.clone())) {
1700 for _ in 0..(1 + values.len() / 2) {
1701 let ix = rand.next_u32() as usize % values.len();
1702 for (i, (key, value)) in values.iter().enumerate() {
1703 if i == ix {
1704 assert_eq!(
1705 &backend
1706 .child_storage(&child_info, key.as_slice())
1707 .unwrap()
1708 .unwrap(),
1709 value
1710 );
1711 queries.push((
1712 child_info.clone(),
1713 key.clone(),
1714 Some(value.clone()),
1715 ));
1716 break
1717 }
1718 }
1719 }
1720 }
1721 for _ in 0..4 {
1722 let key_len = 1 + (rand.next_u32() % 10);
1723 let mut key = vec![0; key_len as usize];
1724 rand.fill_bytes(&mut key[..]);
1725 let result = backend.child_storage(&child_info, key.as_slice()).unwrap();
1726 queries.push((child_info.clone(), key, result));
1727 }
1728 }
1729
1730 let storage_proof = backend.extract_proof().expect("Failed to extract proof");
1731 let remote_proof = test_compact(storage_proof, &trie_root);
1732 let proof_check =
1733 create_proof_check_backend::<BlakeTwo256>(trie_root, remote_proof).unwrap();
1734
1735 for (child_info, key, expected) in queries {
1736 assert_eq!(
1737 proof_check.child_storage(&child_info, key.as_slice()).unwrap(),
1738 expected,
1739 );
1740 }
1741 }
1742 }
1743
1744 #[test]
1745 fn prove_read_with_size_limit_works() {
1746 let state_version = StateVersion::V0;
1747 let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1748 let remote_root = remote_backend.storage_root(::std::iter::empty(), state_version).0;
1749 let (proof, count) =
1750 prove_range_read_with_size(remote_backend, None, None, 0, None).unwrap();
1751 assert_eq!(proof.to_memory_db::<BlakeTwo256>().drain().len(), 3);
1753 assert_eq!(count, 1);
1754 assert_eq!(proof.encoded_size(), 443);
1755
1756 let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1757 let (proof, count) =
1758 prove_range_read_with_size(remote_backend, None, None, 800, Some(&[])).unwrap();
1759 assert_eq!(proof.to_memory_db::<BlakeTwo256>().drain().len(), 9);
1760 assert_eq!(count, 85);
1761 assert_eq!(proof.encoded_size(), 857);
1762 let (results, completed) = read_range_proof_check::<BlakeTwo256>(
1763 remote_root,
1764 proof.clone(),
1765 None,
1766 None,
1767 Some(count),
1768 None,
1769 )
1770 .unwrap();
1771 assert_eq!(results.len() as u32, count);
1772 assert_eq!(completed, false);
1773 let (results, completed) =
1775 read_range_proof_check::<BlakeTwo256>(remote_root, proof, None, None, None, None)
1776 .unwrap();
1777 assert_eq!(results.len() as u32, 101);
1778 assert_eq!(completed, false);
1779
1780 let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1781 let (proof, count) =
1782 prove_range_read_with_size(remote_backend, None, None, 50000, Some(&[])).unwrap();
1783 assert_eq!(proof.to_memory_db::<BlakeTwo256>().drain().len(), 11);
1784 assert_eq!(count, 132);
1785 assert_eq!(proof.encoded_size(), 990);
1786
1787 let (results, completed) =
1788 read_range_proof_check::<BlakeTwo256>(remote_root, proof, None, None, None, None)
1789 .unwrap();
1790 assert_eq!(results.len() as u32, count);
1791 assert_eq!(completed, true);
1792 }
1793
1794 #[test]
1795 fn prove_read_with_size_limit_proof_size() {
1796 let mut root = H256::default();
1797 let mut mdb = PrefixedMemoryDB::<BlakeTwo256>::default();
1798 {
1799 let mut mdb = KeySpacedDBMut::new(&mut mdb, b"");
1800 let mut trie = TrieDBMutBuilderV1::new(&mut mdb, &mut root).build();
1801 trie.insert(b"value1", &[123; 1]).unwrap();
1802 trie.insert(b"value2", &[123; 10]).unwrap();
1803 trie.insert(b"value3", &[123; 100]).unwrap();
1804 trie.insert(b"value4", &[123; 1000]).unwrap();
1805 }
1806
1807 let remote_backend: TrieBackend<PrefixedMemoryDB<BlakeTwo256>, BlakeTwo256> =
1808 TrieBackendBuilder::new(mdb, root)
1809 .with_optional_cache(None)
1810 .with_optional_recorder(None)
1811 .build();
1812
1813 let (proof, count) =
1814 prove_range_read_with_size(remote_backend, None, None, 1000, None).unwrap();
1815
1816 assert_eq!(proof.encoded_size(), 1267);
1817 assert_eq!(count, 3);
1818 }
1819
1820 #[test]
1821 fn inner_state_versioning_switch_proofs() {
1822 let mut state_version = StateVersion::V0;
1823 let (mut mdb, mut root) = trie_backend::tests::test_db(state_version);
1824 {
1825 let mut trie = TrieDBMutBuilderV0::from_existing(&mut mdb, &mut root).build();
1826 trie.insert(b"foo", vec![1u8; 1_000].as_slice()) .expect("insert failed");
1828 trie.insert(b"foo2", vec![3u8; 16].as_slice()) .expect("insert failed");
1830 trie.insert(b"foo222", vec![5u8; 100].as_slice()) .expect("insert failed");
1832 }
1833
1834 let check_proof = |mdb, root, state_version| -> StorageProof {
1835 let remote_backend = TrieBackendBuilder::new(mdb, root).build();
1836 let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1837 let remote_proof = prove_read(remote_backend, &[b"foo222"]).unwrap();
1838 let local_result1 =
1840 read_proof_check::<BlakeTwo256, _>(remote_root, remote_proof.clone(), &[b"foo222"])
1841 .unwrap();
1842 assert_eq!(
1844 local_result1.into_iter().collect::<Vec<_>>(),
1845 vec![(b"foo222".to_vec(), Some(vec![5u8; 100]))],
1846 );
1847 remote_proof
1848 };
1849
1850 let remote_proof = check_proof(mdb.clone(), root, state_version);
1851 assert!(remote_proof.encode().len() > 1_100);
1853 assert!(remote_proof.encoded_size() > 1_100);
1854 let root1 = root;
1855
1856 state_version = StateVersion::V1;
1858 {
1859 let mut trie = TrieDBMutBuilderV1::from_existing(&mut mdb, &mut root).build();
1860 trie.insert(b"foo222", vec![5u8; 100].as_slice()) .expect("insert failed");
1862 trie.insert(b"foo", vec![1u8; 1000].as_slice()) .expect("insert failed");
1865 }
1866 let root3 = root;
1867 assert!(root1 != root3);
1868 let remote_proof = check_proof(mdb.clone(), root, state_version);
1869 assert!(remote_proof.encode().len() < 1000);
1871 assert!(remote_proof.encoded_size() < 1000);
1872 assert_eq!(remote_proof.encode().len(), remote_proof.encoded_size());
1873 }
1874
1875 #[test]
1876 fn prove_range_with_child_works() {
1877 let state_version = StateVersion::V0;
1878 let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1879 let remote_root = remote_backend.storage_root(std::iter::empty(), state_version).0;
1880 let mut start_at = smallvec::SmallVec::<[Vec<u8>; 2]>::new();
1881 let trie_backend = remote_backend.as_trie_backend();
1882 let max_iter = 1000;
1883 let mut nb_loop = 0;
1884 loop {
1885 nb_loop += 1;
1886 if max_iter == nb_loop {
1887 panic!("Too many loop in prove range");
1888 }
1889 let (proof, count) = prove_range_read_with_child_with_size_on_trie_backend(
1890 trie_backend,
1891 1,
1892 start_at.as_slice(),
1893 )
1894 .unwrap();
1895 assert!(proof.to_memory_db::<BlakeTwo256>().drain().len() > 0);
1897 assert!(count < 3); let (result, completed_depth) = read_range_proof_check_with_child::<BlakeTwo256>(
1900 remote_root,
1901 proof.clone(),
1902 start_at.as_slice(),
1903 )
1904 .unwrap();
1905
1906 if completed_depth == 0 {
1907 break
1908 }
1909 assert!(result.update_last_key(completed_depth, &mut start_at));
1910 }
1911
1912 assert_eq!(nb_loop, 10);
1913 }
1914
1915 #[test]
1916 fn compact_multiple_child_trie() {
1917 let size_no_inner_hash = compact_multiple_child_trie_inner(StateVersion::V0);
1918 let size_inner_hash = compact_multiple_child_trie_inner(StateVersion::V1);
1919 assert!(size_inner_hash < size_no_inner_hash);
1920 }
1921 fn compact_multiple_child_trie_inner(state_version: StateVersion) -> usize {
1922 let child_info1 = ChildInfo::new_default(b"sub1");
1924 let child_info2 = ChildInfo::new_default(b"sub2");
1926 let child_info3 = ChildInfo::new_default(b"sub");
1928 let remote_backend = trie_backend::tests::test_trie(state_version, None, None);
1929 let long_vec: Vec<u8> = (0..1024usize).map(|_| 8u8).collect();
1930 let (remote_root, transaction) = remote_backend.full_storage_root(
1931 std::iter::empty(),
1932 vec![
1933 (
1934 &child_info1,
1935 vec![
1936 (&b"k"[..], Some(&long_vec[..])),
1938 (&b"key1"[..], Some(&vec![5u8; 32][..])),
1942 (&b"key2"[..], Some(&b"val3"[..])),
1943 ]
1944 .into_iter(),
1945 ),
1946 (
1947 &child_info2,
1948 vec![(&b"key3"[..], Some(&b"val4"[..])), (&b"key4"[..], Some(&b"val5"[..]))]
1949 .into_iter(),
1950 ),
1951 (
1952 &child_info3,
1953 vec![(&b"key5"[..], Some(&b"val6"[..])), (&b"key6"[..], Some(&b"val7"[..]))]
1954 .into_iter(),
1955 ),
1956 ]
1957 .into_iter(),
1958 state_version,
1959 );
1960 let mut remote_storage = remote_backend.backend_storage().clone();
1961 remote_storage.consolidate(transaction);
1962 let remote_backend = TrieBackendBuilder::new(remote_storage, remote_root).build();
1963 let remote_proof = prove_child_read(remote_backend, &child_info1, &[b"key1"]).unwrap();
1964 let size = remote_proof.encoded_size();
1965 let remote_proof = test_compact(remote_proof, &remote_root);
1966 let local_result1 = read_child_proof_check::<BlakeTwo256, _>(
1967 remote_root,
1968 remote_proof,
1969 &child_info1,
1970 &[b"key1"],
1971 )
1972 .unwrap();
1973 assert_eq!(local_result1.len(), 1);
1974 assert_eq!(local_result1.get(&b"key1"[..]), Some(&Some(vec![5u8; 32])));
1975 size
1976 }
1977
1978 #[test]
1979 fn child_storage_uuid() {
1980 let state_version = StateVersion::V0;
1981 let child_info_1 = ChildInfo::new_default(b"sub_test1");
1982 let child_info_2 = ChildInfo::new_default(b"sub_test2");
1983
1984 use crate::trie_backend::tests::test_trie;
1985 let mut overlay = OverlayedChanges::default();
1986
1987 let mut transaction = {
1988 let backend = test_trie(state_version, None, None);
1989 let mut ext = Ext::new(&mut overlay, &backend, None);
1990 ext.set_child_storage(&child_info_1, b"abc".to_vec(), b"def".to_vec());
1991 ext.set_child_storage(&child_info_2, b"abc".to_vec(), b"def".to_vec());
1992 ext.storage_root(state_version);
1993 overlay.drain_storage_changes(&backend, state_version).unwrap().transaction
1994 };
1995 let mut duplicate = false;
1996 for (k, (value, rc)) in transaction.drain().iter() {
1997 if *rc == 2 {
1999 duplicate = true;
2000 println!("test duplicate for {:?} {:?}", k, value);
2001 }
2002 }
2003 assert!(!duplicate);
2004 }
2005
2006 #[test]
2007 fn set_storage_empty_allowed() {
2008 let initial: BTreeMap<_, _> = map![
2009 b"aaa".to_vec() => b"0".to_vec(),
2010 b"bbb".to_vec() => b"".to_vec()
2011 ];
2012 let state = InMemoryBackend::<BlakeTwo256>::from((initial, StateVersion::default()));
2013 let backend = state.as_trie_backend();
2014
2015 let mut overlay = OverlayedChanges::default();
2016 overlay.start_transaction();
2017 overlay.set_storage(b"ccc".to_vec(), Some(b"".to_vec()));
2018 assert_eq!(overlay.storage(b"ccc"), Some(Some(&[][..])));
2019 overlay.commit_transaction().unwrap();
2020 overlay.start_transaction();
2021 assert_eq!(overlay.storage(b"ccc"), Some(Some(&[][..])));
2022 assert_eq!(overlay.storage(b"bbb"), None);
2023
2024 {
2025 let mut ext = Ext::new(&mut overlay, backend, None);
2026 assert_eq!(ext.storage(b"bbb"), Some(vec![]));
2027 assert_eq!(ext.storage(b"ccc"), Some(vec![]));
2028 ext.clear_storage(b"ccc");
2029 assert_eq!(ext.storage(b"ccc"), None);
2030 }
2031 overlay.commit_transaction().unwrap();
2032 assert_eq!(overlay.storage(b"ccc"), Some(None));
2033 }
2034}