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, 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 pub type DefaultHandler<E> = fn(CallResult<E>, CallResult<E>) -> CallResult<E>;
185
186 pub type InMemoryBackend<H> = TrieBackend<PrefixedMemoryDB<H>, H>;
188
189 #[derive(Debug, Clone)]
191 pub enum BackendTrustLevel {
192 Trusted,
194 Untrusted,
198 }
199
200 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 parent_hash: Option<H::Out>,
218 context: CallContext,
219 state_version: StateVersion,
220 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 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 pub fn set_parent_hash(mut self, parent_hash: H::Out) -> Self {
273 self.parent_hash = Some(parent_hash);
274 self
275 }
276
277 pub fn with_timeout(mut self, timeout: Option<Duration>) -> Self {
281 self.timeout = timeout;
282 self
283 }
284
285 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 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 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 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 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 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 pub const MAX_NESTED_TRIE_DEPTH: usize = 2;
509
510 #[derive(PartialEq, Eq, Clone)]
513 pub struct KeyValueStates(pub Vec<KeyValueStorageLevel>);
514
515 #[derive(PartialEq, Eq, Clone)]
517 pub struct KeyValueStorageLevel {
518 pub state_root: Vec<u8>,
521 pub parent_storage_keys: Vec<Vec<u8>>,
524 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 pub fn len(&self) -> usize {
548 self.0.iter().fold(0, |nb, state| nb + state.key_values.len())
549 }
550
551 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 last[0] = top_last;
577 return true;
578 } else {
579 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 return false;
609 }
610 },
611 _ => (),
612 }
613 false
614 }
615 }
616
617 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 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 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 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 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 .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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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]
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 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 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 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 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 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 {
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 {
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 {
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 {
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"); let child_info = &child_info;
1673 let missing_child_info = &missing_child_info;
1674 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 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 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 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 let child_info = if c < 5 {
1765 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 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 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()) .expect("insert failed");
1903 trie.insert(b"foo2", vec![3u8; 16].as_slice()) .expect("insert failed");
1905 trie.insert(b"foo222", vec![5u8; 100].as_slice()) .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 let local_result1 =
1915 read_proof_check::<BlakeTwo256, _>(remote_root, remote_proof.clone(), &[b"foo222"])
1916 .unwrap();
1917 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 assert!(remote_proof.encode().len() > 1_100);
1928 assert!(remote_proof.encoded_size() > 1_100);
1929 let root1 = root;
1930
1931 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()) .expect("insert failed");
1937 trie.insert(b"foo", vec![1u8; 1000].as_slice()) .expect("insert failed");
1940 }
1941 let root3 = root;
1942 assert!(root1 != root3);
1943 let remote_proof = check_proof(mdb.clone(), root, state_version);
1944 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 assert!(proof.to_memory_db::<BlakeTwo256>().drain().len() > 0);
1972 assert!(count < 3); 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 let child_info1 = ChildInfo::new_default(b"sub1");
1999 let child_info2 = ChildInfo::new_default(b"sub2");
2001 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 (&b"k"[..], Some(&long_vec[..])),
2013 (&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 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}