1mod changeset;
21mod offchain;
22
23use self::changeset::OverlayedChangeSet;
24use crate::{backend::Backend, stats::StateMachineStats, BackendTransaction, DefaultError};
25use alloc::{collections::btree_set::BTreeSet, vec::Vec};
26use codec::{Decode, Encode};
27use hash_db::Hasher;
28pub use offchain::OffchainOverlayedChanges;
29use sp_core::{
30 offchain::OffchainOverlayedChange,
31 storage::{well_known_keys::EXTRINSIC_INDEX, ChildInfo, StateVersion},
32};
33#[cfg(feature = "std")]
34use sp_externalities::{Extension, Extensions, TransactionType};
35use sp_trie::{empty_child_trie_root, LayoutV1};
36
37#[cfg(not(feature = "std"))]
38use alloc::collections::btree_map::BTreeMap as Map;
39#[cfg(feature = "std")]
40use std::collections::{hash_map::Entry as MapEntry, HashMap as Map};
41
42#[cfg(feature = "std")]
43use std::{
44 any::{Any, TypeId},
45 boxed::Box,
46};
47
48pub use self::changeset::{AlreadyInRuntime, NoOpenTransaction, NotInRuntime, OverlayedValue};
49
50pub const NO_EXTRINSIC_INDEX: u32 = 0xffffffff;
52
53pub type StorageKey = Vec<u8>;
55
56pub type StorageValue = Vec<u8>;
58
59pub type StorageCollection = Vec<(StorageKey, Option<StorageValue>)>;
61
62pub type ChildStorageCollection = Vec<(StorageKey, StorageCollection)>;
64
65pub type OffchainChangesCollection = Vec<((Vec<u8>, Vec<u8>), OffchainOverlayedChange)>;
67
68#[derive(Debug, Default, Eq, PartialEq, Clone)]
70pub struct Extrinsics(Vec<u32>);
71
72impl Extrinsics {
73 fn copy_extrinsics_into(&self, dest: &mut BTreeSet<u32>) {
75 dest.extend(self.0.iter())
76 }
77
78 fn insert(&mut self, ext: u32) {
80 if Some(&ext) != self.0.last() {
81 self.0.push(ext);
82 }
83 }
84
85 fn extend(&mut self, other: Self) {
87 self.0.extend(other.0.into_iter());
88 }
89}
90
91pub struct OverlayedChanges<H: Hasher> {
95 top: OverlayedChangeSet,
97 children: Map<StorageKey, (OverlayedChangeSet, ChildInfo)>,
99 offchain: OffchainOverlayedChanges,
101 transaction_index_ops: Vec<IndexOperation>,
103 collect_extrinsics: bool,
105 stats: StateMachineStats,
107 storage_transaction_cache: Option<StorageTransactionCache<H>>,
111}
112
113impl<H: Hasher> Default for OverlayedChanges<H> {
114 fn default() -> Self {
115 Self {
116 top: Default::default(),
117 children: Default::default(),
118 offchain: Default::default(),
119 transaction_index_ops: Default::default(),
120 collect_extrinsics: Default::default(),
121 stats: Default::default(),
122 storage_transaction_cache: None,
123 }
124 }
125}
126
127impl<H: Hasher> Clone for OverlayedChanges<H> {
128 fn clone(&self) -> Self {
129 Self {
130 top: self.top.clone(),
131 children: self.children.clone(),
132 offchain: self.offchain.clone(),
133 transaction_index_ops: self.transaction_index_ops.clone(),
134 collect_extrinsics: self.collect_extrinsics,
135 stats: self.stats.clone(),
136 storage_transaction_cache: self.storage_transaction_cache.clone(),
137 }
138 }
139}
140
141impl<H: Hasher> core::fmt::Debug for OverlayedChanges<H> {
142 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
143 f.debug_struct("OverlayedChanges")
144 .field("top", &self.top)
145 .field("children", &self.children)
146 .field("offchain", &self.offchain)
147 .field("transaction_index_ops", &self.transaction_index_ops)
148 .field("collect_extrinsics", &self.collect_extrinsics)
149 .field("stats", &self.stats)
150 .field("storage_transaction_cache", &self.storage_transaction_cache)
151 .finish()
152 }
153}
154
155#[derive(Debug, Clone)]
157pub enum IndexOperation {
158 Insert {
160 extrinsic: u32,
162 hash: Vec<u8>,
164 size: u32,
166 },
167 Renew {
169 extrinsic: u32,
171 hash: Vec<u8>,
173 },
174}
175
176pub struct StorageChanges<H: Hasher> {
181 pub main_storage_changes: StorageCollection,
185 pub child_storage_changes: ChildStorageCollection,
187 pub offchain_storage_changes: OffchainChangesCollection,
189 pub transaction: BackendTransaction<H>,
194 pub transaction_storage_root: H::Out,
196 #[cfg(feature = "std")]
198 pub transaction_index_changes: Vec<IndexOperation>,
199}
200
201#[cfg(feature = "std")]
202impl<H: Hasher> StorageChanges<H> {
203 pub fn into_inner(
205 self,
206 ) -> (
207 StorageCollection,
208 ChildStorageCollection,
209 OffchainChangesCollection,
210 BackendTransaction<H>,
211 H::Out,
212 Vec<IndexOperation>,
213 ) {
214 (
215 self.main_storage_changes,
216 self.child_storage_changes,
217 self.offchain_storage_changes,
218 self.transaction,
219 self.transaction_storage_root,
220 self.transaction_index_changes,
221 )
222 }
223}
224
225impl<H: Hasher> Default for StorageChanges<H> {
226 fn default() -> Self {
227 Self {
228 main_storage_changes: Default::default(),
229 child_storage_changes: Default::default(),
230 offchain_storage_changes: Default::default(),
231 transaction: BackendTransaction::with_hasher(Default::default()),
232 transaction_storage_root: Default::default(),
233 #[cfg(feature = "std")]
234 transaction_index_changes: Default::default(),
235 }
236 }
237}
238
239struct StorageTransactionCache<H: Hasher> {
243 transaction: BackendTransaction<H>,
245 transaction_storage_root: H::Out,
247 state_version: StateVersion,
249}
250
251impl<H: Hasher> StorageTransactionCache<H> {
252 fn into_inner(self) -> (BackendTransaction<H>, H::Out) {
253 (self.transaction, self.transaction_storage_root)
254 }
255}
256
257impl<H: Hasher> Clone for StorageTransactionCache<H> {
258 fn clone(&self) -> Self {
259 Self {
260 transaction: self.transaction.clone(),
261 transaction_storage_root: self.transaction_storage_root,
262 state_version: self.state_version,
263 }
264 }
265}
266
267impl<H: Hasher> core::fmt::Debug for StorageTransactionCache<H> {
268 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
269 let mut debug = f.debug_struct("StorageTransactionCache");
270
271 #[cfg(feature = "std")]
272 debug.field("transaction_storage_root", &self.transaction_storage_root);
273
274 #[cfg(not(feature = "std"))]
275 debug.field("transaction_storage_root", &self.transaction_storage_root.as_ref());
276
277 debug.finish()
278 }
279}
280
281impl<H: Hasher> OverlayedChanges<H> {
282 pub fn is_empty(&self) -> bool {
284 self.top.is_empty() && self.children.is_empty()
285 }
286
287 pub fn set_collect_extrinsics(&mut self, collect_extrinsics: bool) {
289 self.collect_extrinsics = collect_extrinsics;
290 }
291
292 pub fn storage(&mut self, key: &[u8]) -> Option<Option<&[u8]>> {
296 self.top.get(key).map(|x| {
297 let value = x.value();
298 let size_read = value.map(|x| x.len() as u64).unwrap_or(0);
299 self.stats.tally_read_modified(size_read);
300 value.map(AsRef::as_ref)
301 })
302 }
303
304 fn mark_dirty(&mut self) {
307 self.storage_transaction_cache = None;
308 }
309
310 pub fn child_storage(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<Option<&[u8]>> {
314 let map = self.children.get_mut(child_info.storage_key())?;
315 let value = map.0.get(key)?.value();
316 let size_read = value.map(|x| x.len() as u64).unwrap_or(0);
317 self.stats.tally_read_modified(size_read);
318 Some(value.map(AsRef::as_ref))
319 }
320
321 pub fn set_storage(&mut self, key: StorageKey, val: Option<StorageValue>) {
325 self.mark_dirty();
326
327 let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0);
328 self.stats.tally_write_overlay(size_write);
329 let extrinsic_index = self.extrinsic_index();
330 self.top.set(key, val, extrinsic_index);
331 }
332
333 pub fn append_storage(
335 &mut self,
336 key: StorageKey,
337 element: StorageValue,
338 init: impl Fn() -> StorageValue,
339 ) {
340 let extrinsic_index = self.extrinsic_index();
341 let size_write = element.len() as u64;
342 self.stats.tally_write_overlay(size_write);
343 self.top.append_storage(key, element, init, extrinsic_index);
344 }
345
346 pub fn set_child_storage(
352 &mut self,
353 child_info: &ChildInfo,
354 key: StorageKey,
355 val: Option<StorageValue>,
356 ) {
357 self.mark_dirty();
358
359 let extrinsic_index = self.extrinsic_index();
360 let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0);
361 self.stats.tally_write_overlay(size_write);
362 let storage_key = child_info.storage_key().to_vec();
363 let top = &self.top;
364 let (changeset, info) = self
365 .children
366 .entry(storage_key)
367 .or_insert_with(|| (top.spawn_child(), child_info.clone()));
368 let updatable = info.try_update(child_info);
369 debug_assert!(updatable);
370 changeset.set(key, val, extrinsic_index);
371 }
372
373 pub fn clear_child_storage(&mut self, child_info: &ChildInfo) -> u32 {
377 self.mark_dirty();
378
379 let extrinsic_index = self.extrinsic_index();
380 let storage_key = child_info.storage_key().to_vec();
381 let top = &self.top;
382 let (changeset, info) = self
383 .children
384 .entry(storage_key)
385 .or_insert_with(|| (top.spawn_child(), child_info.clone()));
386 let updatable = info.try_update(child_info);
387 debug_assert!(updatable);
388 changeset.clear_where(|_, _| true, extrinsic_index)
389 }
390
391 pub fn clear_prefix(&mut self, prefix: &[u8]) -> u32 {
395 self.mark_dirty();
396
397 let extrinsic_index = self.extrinsic_index();
398 self.top.clear_where(|key, _| key.starts_with(prefix), extrinsic_index)
399 }
400
401 pub fn clear_child_prefix(&mut self, child_info: &ChildInfo, prefix: &[u8]) -> u32 {
405 self.mark_dirty();
406
407 let extrinsic_index = self.extrinsic_index();
408 let storage_key = child_info.storage_key().to_vec();
409 let top = &self.top;
410 let (changeset, info) = self
411 .children
412 .entry(storage_key)
413 .or_insert_with(|| (top.spawn_child(), child_info.clone()));
414 let updatable = info.try_update(child_info);
415 debug_assert!(updatable);
416 changeset.clear_where(|key, _| key.starts_with(prefix), extrinsic_index)
417 }
418
419 pub fn transaction_depth(&self) -> usize {
423 self.top.transaction_depth()
426 }
427
428 pub fn start_transaction(&mut self) {
436 self.top.start_transaction();
437 for (_, (changeset, _)) in self.children.iter_mut() {
438 changeset.start_transaction();
439 }
440 self.offchain.overlay_mut().start_transaction();
441 }
442
443 pub fn rollback_transaction(&mut self) -> Result<(), NoOpenTransaction> {
448 self.mark_dirty();
449
450 self.top.rollback_transaction()?;
451 retain_map(&mut self.children, |_, (changeset, _)| {
452 changeset
453 .rollback_transaction()
454 .expect("Top and children changesets are started in lockstep; qed");
455 !changeset.is_empty()
456 });
457 self.offchain
458 .overlay_mut()
459 .rollback_transaction_offchain()
460 .expect("Top and offchain changesets are started in lockstep; qed");
461 Ok(())
462 }
463
464 pub fn commit_transaction(&mut self) -> Result<(), NoOpenTransaction> {
469 self.top.commit_transaction()?;
470 for (_, (changeset, _)) in self.children.iter_mut() {
471 changeset
472 .commit_transaction()
473 .expect("Top and children changesets are started in lockstep; qed");
474 }
475 self.offchain
476 .overlay_mut()
477 .commit_transaction_offchain()
478 .expect("Top and offchain changesets are started in lockstep; qed");
479 Ok(())
480 }
481
482 pub fn enter_runtime(&mut self) -> Result<(), AlreadyInRuntime> {
487 self.top.enter_runtime()?;
488 for (_, (changeset, _)) in self.children.iter_mut() {
489 changeset
490 .enter_runtime()
491 .expect("Top and children changesets are entering runtime in lockstep; qed")
492 }
493 self.offchain
494 .overlay_mut()
495 .enter_runtime()
496 .expect("Top and offchain changesets are started in lockstep; qed");
497 Ok(())
498 }
499
500 pub fn exit_runtime(&mut self) -> Result<(), NotInRuntime> {
505 self.top.exit_runtime()?;
506 for (_, (changeset, _)) in self.children.iter_mut() {
507 changeset
508 .exit_runtime()
509 .expect("Top and children changesets are entering runtime in lockstep; qed");
510 }
511 self.offchain
512 .overlay_mut()
513 .exit_runtime_offchain()
514 .expect("Top and offchain changesets are started in lockstep; qed");
515 Ok(())
516 }
517
518 pub fn offchain_drain_committed(
525 &mut self,
526 ) -> impl Iterator<Item = ((StorageKey, StorageKey), OffchainOverlayedChange)> {
527 self.offchain.drain()
528 }
529
530 pub fn children(
532 &self,
533 ) -> impl Iterator<Item = (impl Iterator<Item = (&StorageKey, &OverlayedValue)>, &ChildInfo)> {
534 self.children.values().map(|v| (v.0.changes(), &v.1))
535 }
536
537 pub fn children_mut(
539 &mut self,
540 ) -> impl Iterator<Item = (impl Iterator<Item = (&StorageKey, &mut OverlayedValue)>, &ChildInfo)>
541 {
542 self.children.values_mut().map(|v| (v.0.changes_mut(), &v.1))
543 }
544
545 pub fn changes(&self) -> impl Iterator<Item = (&StorageKey, &OverlayedValue)> {
547 self.top.changes()
548 }
549
550 pub fn changes_mut(&mut self) -> impl Iterator<Item = (&StorageKey, &mut OverlayedValue)> {
552 self.top.changes_mut()
553 }
554
555 pub fn child_changes(
557 &self,
558 key: &[u8],
559 ) -> Option<(impl Iterator<Item = (&StorageKey, &OverlayedValue)>, &ChildInfo)> {
560 self.children.get(key).map(|(overlay, info)| (overlay.changes(), info))
561 }
562
563 pub fn child_changes_mut(
565 &mut self,
566 key: &[u8],
567 ) -> Option<(impl Iterator<Item = (&StorageKey, &mut OverlayedValue)>, &ChildInfo)> {
568 self.children
569 .get_mut(key)
570 .map(|(overlay, info)| (overlay.changes_mut(), &*info))
571 }
572
573 pub fn transaction_index_ops(&self) -> &[IndexOperation] {
575 &self.transaction_index_ops
576 }
577
578 pub fn drain_storage_changes<B: Backend<H>>(
580 &mut self,
581 backend: &B,
582 state_version: StateVersion,
583 ) -> Result<StorageChanges<H>, DefaultError>
584 where
585 H::Out: Ord + Encode + 'static,
586 {
587 let (transaction, transaction_storage_root) = match self.storage_transaction_cache.take() {
588 Some(cache) => cache.into_inner(),
589 None => {
591 self.storage_root(backend, state_version);
592 self.storage_transaction_cache
593 .take()
594 .expect("`storage_transaction_cache` was just initialized; qed")
595 .into_inner()
596 },
597 };
598
599 use core::mem::take;
600 let main_storage_changes =
601 take(&mut self.top).drain_committed().map(|(k, v)| (k, v.to_option()));
602 let child_storage_changes =
603 take(&mut self.children).into_iter().map(|(key, (val, info))| {
604 (key, (val.drain_committed().map(|(k, v)| (k, v.to_option())), info))
605 });
606 let offchain_storage_changes = self.offchain_drain_committed().collect();
607
608 #[cfg(feature = "std")]
609 let transaction_index_changes = std::mem::take(&mut self.transaction_index_ops);
610
611 Ok(StorageChanges {
612 main_storage_changes: main_storage_changes.collect(),
613 child_storage_changes: child_storage_changes
614 .map(|(sk, it)| (sk, it.0.collect()))
615 .collect(),
616 offchain_storage_changes,
617 transaction,
618 transaction_storage_root,
619 #[cfg(feature = "std")]
620 transaction_index_changes,
621 })
622 }
623
624 #[cfg(test)]
626 pub(crate) fn set_extrinsic_index(&mut self, extrinsic_index: u32) {
627 self.top.set(EXTRINSIC_INDEX.to_vec(), Some(extrinsic_index.encode()), None);
628 }
629
630 fn extrinsic_index(&mut self) -> Option<u32> {
637 self.collect_extrinsics.then(|| {
638 self.storage(EXTRINSIC_INDEX)
639 .and_then(|idx| idx.and_then(|idx| Decode::decode(&mut &*idx).ok()))
640 .unwrap_or(NO_EXTRINSIC_INDEX)
641 })
642 }
643
644 pub fn storage_root<B: Backend<H>>(
649 &mut self,
650 backend: &B,
651 state_version: StateVersion,
652 ) -> (H::Out, bool)
653 where
654 H::Out: Ord + Encode,
655 {
656 if let Some(cache) = &self.storage_transaction_cache {
657 if cache.state_version == state_version {
658 return (cache.transaction_storage_root, true);
659 }
660 }
661
662 let delta = self.top.changes_mut().map(|(k, v)| (&k[..], v.value().map(|v| &v[..])));
663
664 let child_delta = self
665 .children
666 .values_mut()
667 .map(|v| (&v.1, v.0.changes_mut().map(|(k, v)| (&k[..], v.value().map(|v| &v[..])))));
668
669 let (root, transaction) = backend.full_storage_root(delta, child_delta, state_version);
670
671 self.storage_transaction_cache = Some(StorageTransactionCache {
672 transaction,
673 transaction_storage_root: root,
674 state_version,
675 });
676
677 (root, false)
678 }
679
680 pub fn child_storage_root<B: Backend<H>>(
685 &mut self,
686 child_info: &ChildInfo,
687 backend: &B,
688 state_version: StateVersion,
689 ) -> Result<(H::Out, bool), B::Error>
690 where
691 H::Out: Ord + Encode + Decode,
692 {
693 let storage_key = child_info.storage_key();
694 let prefixed_storage_key = child_info.prefixed_storage_key();
695
696 if self.storage_transaction_cache.is_some() {
697 let root = self
698 .storage(prefixed_storage_key.as_slice())
699 .map(|v| Ok(v.map(|v| v.to_vec())))
700 .or_else(|| backend.storage(prefixed_storage_key.as_slice()).map(Some).transpose())
701 .transpose()?
702 .flatten()
703 .and_then(|k| Decode::decode(&mut &k[..]).ok())
704 .unwrap_or_else(empty_child_trie_root::<LayoutV1<H>>);
706
707 return Ok((root, true));
708 }
709
710 let root = if let Some((changes, info)) = self.child_changes_mut(storage_key) {
711 let delta = changes.map(|(k, v)| (k.as_ref(), v.value().map(AsRef::as_ref)));
712 Some(backend.child_storage_root(info, delta, state_version))
713 } else {
714 None
715 };
716
717 let root = if let Some((root, is_empty, _)) = root {
718 self.set_storage(prefixed_storage_key.into_inner(), (!is_empty).then(|| root.encode()));
724
725 self.mark_dirty();
726
727 root
728 } else {
729 let root = backend
731 .storage(prefixed_storage_key.as_slice())?
732 .and_then(|k| Decode::decode(&mut &k[..]).ok())
733 .unwrap_or_else(empty_child_trie_root::<LayoutV1<H>>);
735
736 root
737 };
738
739 Ok((root, false))
740 }
741
742 pub fn iter_after(&mut self, key: &[u8]) -> impl Iterator<Item = (&[u8], &mut OverlayedValue)> {
745 self.top.changes_after(key)
746 }
747
748 pub fn child_iter_after(
751 &mut self,
752 storage_key: &[u8],
753 key: &[u8],
754 ) -> impl Iterator<Item = (&[u8], &mut OverlayedValue)> {
755 self.children
756 .get_mut(storage_key)
757 .map(|(overlay, _)| overlay.changes_after(key))
758 .into_iter()
759 .flatten()
760 }
761
762 pub fn offchain(&self) -> &OffchainOverlayedChanges {
764 &self.offchain
765 }
766
767 pub fn set_offchain_storage(&mut self, key: &[u8], value: Option<&[u8]>) {
769 use sp_core::offchain::STORAGE_PREFIX;
770 match value {
771 Some(value) => self.offchain.set(STORAGE_PREFIX, key, value),
772 None => self.offchain.remove(STORAGE_PREFIX, key),
773 }
774 }
775
776 pub fn add_transaction_index(&mut self, op: IndexOperation) {
778 self.transaction_index_ops.push(op)
779 }
780}
781
782#[cfg(not(substrate_runtime))]
783impl<H: Hasher> From<sp_core::storage::Storage> for OverlayedChanges<H> {
784 fn from(storage: sp_core::storage::Storage) -> Self {
785 Self {
786 top: storage.top.into(),
787 children: storage
788 .children_default
789 .into_iter()
790 .map(|(k, v)| (k, (v.data.into(), v.child_info)))
791 .collect(),
792 ..Default::default()
793 }
794 }
795}
796
797#[cfg(feature = "std")]
798fn retain_map<K, V, F>(map: &mut Map<K, V>, f: F)
799where
800 K: std::cmp::Eq + std::hash::Hash,
801 F: FnMut(&K, &mut V) -> bool,
802{
803 map.retain(f);
804}
805
806#[cfg(not(feature = "std"))]
807fn retain_map<K, V, F>(map: &mut Map<K, V>, mut f: F)
808where
809 K: Ord,
810 F: FnMut(&K, &mut V) -> bool,
811{
812 let old = core::mem::replace(map, Map::default());
813 for (k, mut v) in old.into_iter() {
814 if f(&k, &mut v) {
815 map.insert(k, v);
816 }
817 }
818}
819
820#[cfg(feature = "std")]
823pub enum OverlayedExtension<'a> {
824 MutRef(&'a mut Box<dyn Extension>),
825 Owned(Box<dyn Extension>),
826}
827
828#[cfg(feature = "std")]
829impl OverlayedExtension<'_> {
830 fn extension(&mut self) -> &mut dyn Extension {
831 match self {
832 Self::MutRef(ext) => *ext,
833 Self::Owned(ext) => &mut *ext,
834 }
835 }
836}
837
838#[cfg(feature = "std")]
846pub struct OverlayedExtensions<'a> {
847 extensions: Map<TypeId, OverlayedExtension<'a>>,
848}
849
850#[cfg(feature = "std")]
851impl<'a> OverlayedExtensions<'a> {
852 pub fn new(extensions: &'a mut Extensions) -> Self {
854 Self {
855 extensions: extensions
856 .iter_mut()
857 .map(|(k, v)| (*k, OverlayedExtension::MutRef(v)))
858 .collect(),
859 }
860 }
861
862 pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> {
864 self.extensions.get_mut(&ext_type_id).map(|ext| match ext {
865 OverlayedExtension::MutRef(ext) => ext.as_mut_any(),
866 OverlayedExtension::Owned(ext) => ext.as_mut_any(),
867 })
868 }
869
870 pub fn register(
872 &mut self,
873 type_id: TypeId,
874 extension: Box<dyn Extension>,
875 ) -> Result<(), sp_externalities::Error> {
876 match self.extensions.entry(type_id) {
877 MapEntry::Vacant(vacant) => {
878 vacant.insert(OverlayedExtension::Owned(extension));
879 Ok(())
880 },
881 MapEntry::Occupied(_) => Err(sp_externalities::Error::ExtensionAlreadyRegistered),
882 }
883 }
884
885 pub fn deregister(&mut self, type_id: TypeId) -> bool {
889 self.extensions.remove(&type_id).is_some()
890 }
891
892 pub fn start_transaction(&mut self, ty: TransactionType) {
896 self.extensions.values_mut().for_each(|e| e.extension().start_transaction(ty));
897 }
898
899 pub fn commit_transaction(&mut self, ty: TransactionType) {
903 self.extensions.values_mut().for_each(|e| e.extension().commit_transaction(ty));
904 }
905
906 pub fn rollback_transaction(&mut self, ty: TransactionType) {
910 self.extensions
911 .values_mut()
912 .for_each(|e| e.extension().rollback_transaction(ty));
913 }
914}
915
916#[cfg(test)]
917mod tests {
918 use super::*;
919 use crate::{ext::Ext, new_in_mem, InMemoryBackend};
920 use array_bytes::bytes2hex;
921 use sp_core::{traits::Externalities, Blake2Hasher};
922 use std::collections::BTreeMap;
923
924 fn assert_extrinsics(
925 overlay: &mut OverlayedChangeSet,
926 key: impl AsRef<[u8]>,
927 expected: Vec<u32>,
928 ) {
929 assert_eq!(
930 overlay.get(key.as_ref()).unwrap().extrinsics().into_iter().collect::<Vec<_>>(),
931 expected
932 )
933 }
934
935 #[test]
936 fn overlayed_storage_works() {
937 let mut overlayed = OverlayedChanges::<Blake2Hasher>::default();
938
939 let key = vec![42, 69, 169, 142];
940
941 assert!(overlayed.storage(&key).is_none());
942
943 overlayed.start_transaction();
944
945 overlayed.set_storage(key.clone(), Some(vec![1, 2, 3]));
946 assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
947
948 overlayed.commit_transaction().unwrap();
949
950 assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
951
952 overlayed.start_transaction();
953
954 overlayed.set_storage(key.clone(), Some(vec![]));
955 assert_eq!(overlayed.storage(&key).unwrap(), Some(&[][..]));
956
957 overlayed.set_storage(key.clone(), None);
958 assert!(overlayed.storage(&key).unwrap().is_none());
959
960 overlayed.rollback_transaction().unwrap();
961
962 assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
963
964 overlayed.set_storage(key.clone(), None);
965 assert!(overlayed.storage(&key).unwrap().is_none());
966 }
967
968 #[test]
969 fn offchain_overlayed_storage_transactions_works() {
970 use sp_core::offchain::STORAGE_PREFIX;
971 fn check_offchain_content(
972 state: &OverlayedChanges<Blake2Hasher>,
973 nb_commit: usize,
974 expected: Vec<(Vec<u8>, Option<Vec<u8>>)>,
975 ) {
976 let mut state = state.clone();
977 for _ in 0..nb_commit {
978 state.commit_transaction().unwrap();
979 }
980 let offchain_data: Vec<_> = state.offchain_drain_committed().collect();
981 let expected: Vec<_> = expected
982 .into_iter()
983 .map(|(key, value)| {
984 let change = match value {
985 Some(value) => OffchainOverlayedChange::SetValue(value),
986 None => OffchainOverlayedChange::Remove,
987 };
988 ((STORAGE_PREFIX.to_vec(), key), change)
989 })
990 .collect();
991 assert_eq!(offchain_data, expected);
992 }
993
994 let mut overlayed = OverlayedChanges::default();
995
996 let key = vec![42, 69, 169, 142];
997
998 check_offchain_content(&overlayed, 0, vec![]);
999
1000 overlayed.start_transaction();
1001
1002 overlayed.set_offchain_storage(key.as_slice(), Some(&[1, 2, 3][..]));
1003 check_offchain_content(&overlayed, 1, vec![(key.clone(), Some(vec![1, 2, 3]))]);
1004
1005 overlayed.commit_transaction().unwrap();
1006
1007 check_offchain_content(&overlayed, 0, vec![(key.clone(), Some(vec![1, 2, 3]))]);
1008
1009 overlayed.start_transaction();
1010
1011 overlayed.set_offchain_storage(key.as_slice(), Some(&[][..]));
1012 check_offchain_content(&overlayed, 1, vec![(key.clone(), Some(vec![]))]);
1013
1014 overlayed.set_offchain_storage(key.as_slice(), None);
1015 check_offchain_content(&overlayed, 1, vec![(key.clone(), None)]);
1016
1017 overlayed.rollback_transaction().unwrap();
1018
1019 check_offchain_content(&overlayed, 0, vec![(key.clone(), Some(vec![1, 2, 3]))]);
1020
1021 overlayed.set_offchain_storage(key.as_slice(), None);
1022 check_offchain_content(&overlayed, 0, vec![(key.clone(), None)]);
1023 }
1024
1025 #[test]
1026 fn overlayed_storage_root_works() {
1027 let state_version = StateVersion::default();
1028 let initial: BTreeMap<_, _> = vec![
1029 (b"doe".to_vec(), b"reindeer".to_vec()),
1030 (b"dog".to_vec(), b"puppyXXX".to_vec()),
1031 (b"dogglesworth".to_vec(), b"catXXX".to_vec()),
1032 (b"doug".to_vec(), b"notadog".to_vec()),
1033 ]
1034 .into_iter()
1035 .collect();
1036 let backend = InMemoryBackend::<Blake2Hasher>::from((initial, state_version));
1037 let mut overlay = OverlayedChanges::default();
1038
1039 overlay.start_transaction();
1040 overlay.set_storage(b"dog".to_vec(), Some(b"puppy".to_vec()));
1041 overlay.set_storage(b"dogglesworth".to_vec(), Some(b"catYYY".to_vec()));
1042 overlay.set_storage(b"doug".to_vec(), Some(vec![]));
1043 overlay.commit_transaction().unwrap();
1044
1045 overlay.start_transaction();
1046 overlay.set_storage(b"dogglesworth".to_vec(), Some(b"cat".to_vec()));
1047 overlay.set_storage(b"doug".to_vec(), None);
1048
1049 {
1050 let mut ext = Ext::new(&mut overlay, &backend, None);
1051 let root = "39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa";
1052
1053 assert_eq!(bytes2hex("", &ext.storage_root(state_version)), root);
1054 assert_eq!(bytes2hex("", &ext.storage_root(state_version)), root);
1056 }
1057
1058 overlay.set_storage(b"doug2".to_vec(), Some(b"yes".to_vec()));
1060
1061 let mut ext = Ext::new(&mut overlay, &backend, None);
1062 let root = "5c0a4e35cb967de785e1cb8743e6f24b6ff6d45155317f2078f6eb3fc4ff3e3d";
1063 assert_eq!(bytes2hex("", &ext.storage_root(state_version)), root);
1064 }
1065
1066 #[test]
1067 fn storage_root_cache_invalidates_on_state_version_change() {
1068 let backend = InMemoryBackend::<Blake2Hasher>::default();
1071 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1072 overlay.start_transaction();
1073 overlay.set_storage(b"key".to_vec(), Some(vec![0x42; 64]));
1074 overlay.commit_transaction().unwrap();
1075
1076 let (root_v0_first, cached) = overlay.storage_root(&backend, StateVersion::V0);
1077 assert!(!cached);
1078 let (root_v0_second, cached) = overlay.storage_root(&backend, StateVersion::V0);
1079 assert!(cached);
1080 assert_eq!(root_v0_first, root_v0_second);
1081
1082 let (root_v1, cached) = overlay.storage_root(&backend, StateVersion::V1);
1084 assert!(!cached, "cache must be invalidated when state version changes");
1085 assert_ne!(
1086 root_v0_first, root_v1,
1087 "V0 and V1 roots must differ for values exceeding the inline threshold",
1088 );
1089
1090 let (root_v0_third, cached) = overlay.storage_root(&backend, StateVersion::V0);
1092 assert!(!cached);
1093 assert_eq!(root_v0_first, root_v0_third);
1094 }
1095
1096 #[test]
1097 fn overlayed_child_storage_root_works() {
1098 let state_version = StateVersion::default();
1099 let child_info = ChildInfo::new_default(b"Child1");
1100 let child_info = &child_info;
1101 let backend = new_in_mem::<Blake2Hasher>();
1102 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1103 overlay.start_transaction();
1104 overlay.set_child_storage(child_info, vec![20], Some(vec![20]));
1105 overlay.set_child_storage(child_info, vec![30], Some(vec![30]));
1106 overlay.set_child_storage(child_info, vec![40], Some(vec![40]));
1107 overlay.commit_transaction().unwrap();
1108 overlay.set_child_storage(child_info, vec![10], Some(vec![10]));
1109 overlay.set_child_storage(child_info, vec![30], None);
1110
1111 {
1112 let mut ext = Ext::new(&mut overlay, &backend, None);
1113 let child_root = "c02965e1df4dc5baf6977390ce67dab1d7a9b27a87c1afe27b50d29cc990e0f5";
1114 let root = "eafb765909c3ed5afd92a0c564acf4620d0234b31702e8e8e9b48da72a748838";
1115
1116 assert_eq!(
1117 bytes2hex("", &ext.child_storage_root(child_info, state_version)),
1118 child_root,
1119 );
1120
1121 assert_eq!(bytes2hex("", &ext.storage_root(state_version)), root);
1122
1123 assert_eq!(
1125 bytes2hex("", &ext.child_storage_root(child_info, state_version)),
1126 child_root,
1127 );
1128 }
1129 }
1130
1131 #[test]
1132 fn extrinsic_changes_are_collected() {
1133 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1134 overlay.set_collect_extrinsics(true);
1135
1136 overlay.start_transaction();
1137
1138 overlay.set_storage(vec![100], Some(vec![101]));
1139
1140 overlay.set_extrinsic_index(0);
1141 overlay.set_storage(vec![1], Some(vec![2]));
1142
1143 overlay.set_extrinsic_index(1);
1144 overlay.set_storage(vec![3], Some(vec![4]));
1145
1146 overlay.set_extrinsic_index(2);
1147 overlay.set_storage(vec![1], Some(vec![6]));
1148
1149 assert_extrinsics(&mut overlay.top, vec![1], vec![0, 2]);
1150 assert_extrinsics(&mut overlay.top, vec![3], vec![1]);
1151 assert_extrinsics(&mut overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
1152
1153 overlay.start_transaction();
1154
1155 overlay.set_extrinsic_index(3);
1156 overlay.set_storage(vec![3], Some(vec![7]));
1157
1158 overlay.set_extrinsic_index(4);
1159 overlay.set_storage(vec![1], Some(vec![8]));
1160
1161 assert_extrinsics(&mut overlay.top, vec![1], vec![0, 2, 4]);
1162 assert_extrinsics(&mut overlay.top, vec![3], vec![1, 3]);
1163 assert_extrinsics(&mut overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
1164
1165 overlay.rollback_transaction().unwrap();
1166
1167 assert_extrinsics(&mut overlay.top, vec![1], vec![0, 2]);
1168 assert_extrinsics(&mut overlay.top, vec![3], vec![1]);
1169 assert_extrinsics(&mut overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
1170 }
1171
1172 #[test]
1173 fn next_storage_key_change_works() {
1174 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1175 overlay.start_transaction();
1176 overlay.set_storage(vec![20], Some(vec![20]));
1177 overlay.set_storage(vec![30], Some(vec![30]));
1178 overlay.set_storage(vec![40], Some(vec![40]));
1179 overlay.commit_transaction().unwrap();
1180 overlay.set_storage(vec![10], Some(vec![10]));
1181 overlay.set_storage(vec![30], None);
1182
1183 let next_to_5 = overlay.iter_after(&[5]).next().unwrap();
1185 assert_eq!(next_to_5.0.to_vec(), vec![10]);
1186 assert_eq!(next_to_5.1.value(), Some(&vec![10]));
1187
1188 let next_to_10 = overlay.iter_after(&[10]).next().unwrap();
1190 assert_eq!(next_to_10.0.to_vec(), vec![20]);
1191 assert_eq!(next_to_10.1.value(), Some(&vec![20]));
1192
1193 let next_to_20 = overlay.iter_after(&[20]).next().unwrap();
1195 assert_eq!(next_to_20.0.to_vec(), vec![30]);
1196 assert_eq!(next_to_20.1.value(), None);
1197
1198 let next_to_30 = overlay.iter_after(&[30]).next().unwrap();
1200 assert_eq!(next_to_30.0.to_vec(), vec![40]);
1201 assert_eq!(next_to_30.1.value(), Some(&vec![40]));
1202
1203 overlay.set_storage(vec![50], Some(vec![50]));
1204 let next_to_40 = overlay.iter_after(&[40]).next().unwrap();
1206 assert_eq!(next_to_40.0.to_vec(), vec![50]);
1207 assert_eq!(next_to_40.1.value(), Some(&vec![50]));
1208 }
1209
1210 #[test]
1211 fn next_child_storage_key_change_works() {
1212 let child_info = ChildInfo::new_default(b"Child1");
1213 let child_info = &child_info;
1214 let child = child_info.storage_key();
1215 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1216 overlay.start_transaction();
1217 overlay.set_child_storage(child_info, vec![20], Some(vec![20]));
1218 overlay.set_child_storage(child_info, vec![30], Some(vec![30]));
1219 overlay.set_child_storage(child_info, vec![40], Some(vec![40]));
1220 overlay.commit_transaction().unwrap();
1221 overlay.set_child_storage(child_info, vec![10], Some(vec![10]));
1222 overlay.set_child_storage(child_info, vec![30], None);
1223
1224 let next_to_5 = overlay.child_iter_after(child, &[5]).next().unwrap();
1226 assert_eq!(next_to_5.0.to_vec(), vec![10]);
1227 assert_eq!(next_to_5.1.value(), Some(&vec![10]));
1228
1229 let next_to_10 = overlay.child_iter_after(child, &[10]).next().unwrap();
1231 assert_eq!(next_to_10.0.to_vec(), vec![20]);
1232 assert_eq!(next_to_10.1.value(), Some(&vec![20]));
1233
1234 let next_to_20 = overlay.child_iter_after(child, &[20]).next().unwrap();
1236 assert_eq!(next_to_20.0.to_vec(), vec![30]);
1237 assert_eq!(next_to_20.1.value(), None);
1238
1239 let next_to_30 = overlay.child_iter_after(child, &[30]).next().unwrap();
1241 assert_eq!(next_to_30.0.to_vec(), vec![40]);
1242 assert_eq!(next_to_30.1.value(), Some(&vec![40]));
1243
1244 overlay.set_child_storage(child_info, vec![50], Some(vec![50]));
1245 let next_to_40 = overlay.child_iter_after(child, &[40]).next().unwrap();
1247 assert_eq!(next_to_40.0.to_vec(), vec![50]);
1248 assert_eq!(next_to_40.1.value(), Some(&vec![50]));
1249 }
1250}