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}
248
249impl<H: Hasher> StorageTransactionCache<H> {
250 fn into_inner(self) -> (BackendTransaction<H>, H::Out) {
251 (self.transaction, self.transaction_storage_root)
252 }
253}
254
255impl<H: Hasher> Clone for StorageTransactionCache<H> {
256 fn clone(&self) -> Self {
257 Self {
258 transaction: self.transaction.clone(),
259 transaction_storage_root: self.transaction_storage_root,
260 }
261 }
262}
263
264impl<H: Hasher> core::fmt::Debug for StorageTransactionCache<H> {
265 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
266 let mut debug = f.debug_struct("StorageTransactionCache");
267
268 #[cfg(feature = "std")]
269 debug.field("transaction_storage_root", &self.transaction_storage_root);
270
271 #[cfg(not(feature = "std"))]
272 debug.field("transaction_storage_root", &self.transaction_storage_root.as_ref());
273
274 debug.finish()
275 }
276}
277
278impl<H: Hasher> OverlayedChanges<H> {
279 pub fn is_empty(&self) -> bool {
281 self.top.is_empty() && self.children.is_empty()
282 }
283
284 pub fn set_collect_extrinsics(&mut self, collect_extrinsics: bool) {
286 self.collect_extrinsics = collect_extrinsics;
287 }
288
289 pub fn storage(&mut self, key: &[u8]) -> Option<Option<&[u8]>> {
293 self.top.get(key).map(|x| {
294 let value = x.value();
295 let size_read = value.map(|x| x.len() as u64).unwrap_or(0);
296 self.stats.tally_read_modified(size_read);
297 value.map(AsRef::as_ref)
298 })
299 }
300
301 fn mark_dirty(&mut self) {
304 self.storage_transaction_cache = None;
305 }
306
307 pub fn child_storage(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<Option<&[u8]>> {
311 let map = self.children.get_mut(child_info.storage_key())?;
312 let value = map.0.get(key)?.value();
313 let size_read = value.map(|x| x.len() as u64).unwrap_or(0);
314 self.stats.tally_read_modified(size_read);
315 Some(value.map(AsRef::as_ref))
316 }
317
318 pub fn set_storage(&mut self, key: StorageKey, val: Option<StorageValue>) {
322 self.mark_dirty();
323
324 let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0);
325 self.stats.tally_write_overlay(size_write);
326 let extrinsic_index = self.extrinsic_index();
327 self.top.set(key, val, extrinsic_index);
328 }
329
330 pub fn append_storage(
332 &mut self,
333 key: StorageKey,
334 element: StorageValue,
335 init: impl Fn() -> StorageValue,
336 ) {
337 let extrinsic_index = self.extrinsic_index();
338 let size_write = element.len() as u64;
339 self.stats.tally_write_overlay(size_write);
340 self.top.append_storage(key, element, init, extrinsic_index);
341 }
342
343 pub fn set_child_storage(
349 &mut self,
350 child_info: &ChildInfo,
351 key: StorageKey,
352 val: Option<StorageValue>,
353 ) {
354 self.mark_dirty();
355
356 let extrinsic_index = self.extrinsic_index();
357 let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0);
358 self.stats.tally_write_overlay(size_write);
359 let storage_key = child_info.storage_key().to_vec();
360 let top = &self.top;
361 let (changeset, info) = self
362 .children
363 .entry(storage_key)
364 .or_insert_with(|| (top.spawn_child(), child_info.clone()));
365 let updatable = info.try_update(child_info);
366 debug_assert!(updatable);
367 changeset.set(key, val, extrinsic_index);
368 }
369
370 pub fn clear_child_storage(&mut self, child_info: &ChildInfo) -> u32 {
374 self.mark_dirty();
375
376 let extrinsic_index = self.extrinsic_index();
377 let storage_key = child_info.storage_key().to_vec();
378 let top = &self.top;
379 let (changeset, info) = self
380 .children
381 .entry(storage_key)
382 .or_insert_with(|| (top.spawn_child(), child_info.clone()));
383 let updatable = info.try_update(child_info);
384 debug_assert!(updatable);
385 changeset.clear_where(|_, _| true, extrinsic_index)
386 }
387
388 pub fn clear_prefix(&mut self, prefix: &[u8]) -> u32 {
392 self.mark_dirty();
393
394 let extrinsic_index = self.extrinsic_index();
395 self.top.clear_where(|key, _| key.starts_with(prefix), extrinsic_index)
396 }
397
398 pub fn clear_child_prefix(&mut self, child_info: &ChildInfo, prefix: &[u8]) -> u32 {
402 self.mark_dirty();
403
404 let extrinsic_index = self.extrinsic_index();
405 let storage_key = child_info.storage_key().to_vec();
406 let top = &self.top;
407 let (changeset, info) = self
408 .children
409 .entry(storage_key)
410 .or_insert_with(|| (top.spawn_child(), child_info.clone()));
411 let updatable = info.try_update(child_info);
412 debug_assert!(updatable);
413 changeset.clear_where(|key, _| key.starts_with(prefix), extrinsic_index)
414 }
415
416 pub fn transaction_depth(&self) -> usize {
420 self.top.transaction_depth()
423 }
424
425 pub fn start_transaction(&mut self) {
433 self.top.start_transaction();
434 for (_, (changeset, _)) in self.children.iter_mut() {
435 changeset.start_transaction();
436 }
437 self.offchain.overlay_mut().start_transaction();
438 }
439
440 pub fn rollback_transaction(&mut self) -> Result<(), NoOpenTransaction> {
445 self.mark_dirty();
446
447 self.top.rollback_transaction()?;
448 retain_map(&mut self.children, |_, (changeset, _)| {
449 changeset
450 .rollback_transaction()
451 .expect("Top and children changesets are started in lockstep; qed");
452 !changeset.is_empty()
453 });
454 self.offchain
455 .overlay_mut()
456 .rollback_transaction_offchain()
457 .expect("Top and offchain changesets are started in lockstep; qed");
458 Ok(())
459 }
460
461 pub fn commit_transaction(&mut self) -> Result<(), NoOpenTransaction> {
466 self.top.commit_transaction()?;
467 for (_, (changeset, _)) in self.children.iter_mut() {
468 changeset
469 .commit_transaction()
470 .expect("Top and children changesets are started in lockstep; qed");
471 }
472 self.offchain
473 .overlay_mut()
474 .commit_transaction_offchain()
475 .expect("Top and offchain changesets are started in lockstep; qed");
476 Ok(())
477 }
478
479 pub fn enter_runtime(&mut self) -> Result<(), AlreadyInRuntime> {
484 self.top.enter_runtime()?;
485 for (_, (changeset, _)) in self.children.iter_mut() {
486 changeset
487 .enter_runtime()
488 .expect("Top and children changesets are entering runtime in lockstep; qed")
489 }
490 self.offchain
491 .overlay_mut()
492 .enter_runtime()
493 .expect("Top and offchain changesets are started in lockstep; qed");
494 Ok(())
495 }
496
497 pub fn exit_runtime(&mut self) -> Result<(), NotInRuntime> {
502 self.top.exit_runtime()?;
503 for (_, (changeset, _)) in self.children.iter_mut() {
504 changeset
505 .exit_runtime()
506 .expect("Top and children changesets are entering runtime in lockstep; qed");
507 }
508 self.offchain
509 .overlay_mut()
510 .exit_runtime_offchain()
511 .expect("Top and offchain changesets are started in lockstep; qed");
512 Ok(())
513 }
514
515 pub fn offchain_drain_committed(
522 &mut self,
523 ) -> impl Iterator<Item = ((StorageKey, StorageKey), OffchainOverlayedChange)> {
524 self.offchain.drain()
525 }
526
527 pub fn children(
529 &self,
530 ) -> impl Iterator<Item = (impl Iterator<Item = (&StorageKey, &OverlayedValue)>, &ChildInfo)> {
531 self.children.values().map(|v| (v.0.changes(), &v.1))
532 }
533
534 pub fn children_mut(
536 &mut self,
537 ) -> impl Iterator<Item = (impl Iterator<Item = (&StorageKey, &mut OverlayedValue)>, &ChildInfo)>
538 {
539 self.children.values_mut().map(|v| (v.0.changes_mut(), &v.1))
540 }
541
542 pub fn changes(&self) -> impl Iterator<Item = (&StorageKey, &OverlayedValue)> {
544 self.top.changes()
545 }
546
547 pub fn changes_mut(&mut self) -> impl Iterator<Item = (&StorageKey, &mut OverlayedValue)> {
549 self.top.changes_mut()
550 }
551
552 pub fn child_changes(
554 &self,
555 key: &[u8],
556 ) -> Option<(impl Iterator<Item = (&StorageKey, &OverlayedValue)>, &ChildInfo)> {
557 self.children.get(key).map(|(overlay, info)| (overlay.changes(), info))
558 }
559
560 pub fn child_changes_mut(
562 &mut self,
563 key: &[u8],
564 ) -> Option<(impl Iterator<Item = (&StorageKey, &mut OverlayedValue)>, &ChildInfo)> {
565 self.children
566 .get_mut(key)
567 .map(|(overlay, info)| (overlay.changes_mut(), &*info))
568 }
569
570 pub fn transaction_index_ops(&self) -> &[IndexOperation] {
572 &self.transaction_index_ops
573 }
574
575 pub fn drain_storage_changes<B: Backend<H>>(
577 &mut self,
578 backend: &B,
579 state_version: StateVersion,
580 ) -> Result<StorageChanges<H>, DefaultError>
581 where
582 H::Out: Ord + Encode + 'static,
583 {
584 let (transaction, transaction_storage_root) = match self.storage_transaction_cache.take() {
585 Some(cache) => cache.into_inner(),
586 None => {
588 self.storage_root(backend, state_version);
589 self.storage_transaction_cache
590 .take()
591 .expect("`storage_transaction_cache` was just initialized; qed")
592 .into_inner()
593 },
594 };
595
596 use core::mem::take;
597 let main_storage_changes =
598 take(&mut self.top).drain_committed().map(|(k, v)| (k, v.to_option()));
599 let child_storage_changes =
600 take(&mut self.children).into_iter().map(|(key, (val, info))| {
601 (key, (val.drain_committed().map(|(k, v)| (k, v.to_option())), info))
602 });
603 let offchain_storage_changes = self.offchain_drain_committed().collect();
604
605 #[cfg(feature = "std")]
606 let transaction_index_changes = std::mem::take(&mut self.transaction_index_ops);
607
608 Ok(StorageChanges {
609 main_storage_changes: main_storage_changes.collect(),
610 child_storage_changes: child_storage_changes
611 .map(|(sk, it)| (sk, it.0.collect()))
612 .collect(),
613 offchain_storage_changes,
614 transaction,
615 transaction_storage_root,
616 #[cfg(feature = "std")]
617 transaction_index_changes,
618 })
619 }
620
621 #[cfg(test)]
623 pub(crate) fn set_extrinsic_index(&mut self, extrinsic_index: u32) {
624 self.top.set(EXTRINSIC_INDEX.to_vec(), Some(extrinsic_index.encode()), None);
625 }
626
627 fn extrinsic_index(&mut self) -> Option<u32> {
634 self.collect_extrinsics.then(|| {
635 self.storage(EXTRINSIC_INDEX)
636 .and_then(|idx| idx.and_then(|idx| Decode::decode(&mut &*idx).ok()))
637 .unwrap_or(NO_EXTRINSIC_INDEX)
638 })
639 }
640
641 pub fn storage_root<B: Backend<H>>(
646 &mut self,
647 backend: &B,
648 state_version: StateVersion,
649 ) -> (H::Out, bool)
650 where
651 H::Out: Ord + Encode,
652 {
653 if let Some(cache) = &self.storage_transaction_cache {
654 return (cache.transaction_storage_root, true)
655 }
656
657 let delta = self.top.changes_mut().map(|(k, v)| (&k[..], v.value().map(|v| &v[..])));
658
659 let child_delta = self
660 .children
661 .values_mut()
662 .map(|v| (&v.1, v.0.changes_mut().map(|(k, v)| (&k[..], v.value().map(|v| &v[..])))));
663
664 let (root, transaction) = backend.full_storage_root(delta, child_delta, state_version);
665
666 self.storage_transaction_cache =
667 Some(StorageTransactionCache { transaction, transaction_storage_root: root });
668
669 (root, false)
670 }
671
672 pub fn child_storage_root<B: Backend<H>>(
677 &mut self,
678 child_info: &ChildInfo,
679 backend: &B,
680 state_version: StateVersion,
681 ) -> Result<(H::Out, bool), B::Error>
682 where
683 H::Out: Ord + Encode + Decode,
684 {
685 let storage_key = child_info.storage_key();
686 let prefixed_storage_key = child_info.prefixed_storage_key();
687
688 if self.storage_transaction_cache.is_some() {
689 let root = self
690 .storage(prefixed_storage_key.as_slice())
691 .map(|v| Ok(v.map(|v| v.to_vec())))
692 .or_else(|| backend.storage(prefixed_storage_key.as_slice()).map(Some).transpose())
693 .transpose()?
694 .flatten()
695 .and_then(|k| Decode::decode(&mut &k[..]).ok())
696 .unwrap_or_else(empty_child_trie_root::<LayoutV1<H>>);
698
699 return Ok((root, true))
700 }
701
702 let root = if let Some((changes, info)) = self.child_changes_mut(storage_key) {
703 let delta = changes.map(|(k, v)| (k.as_ref(), v.value().map(AsRef::as_ref)));
704 Some(backend.child_storage_root(info, delta, state_version))
705 } else {
706 None
707 };
708
709 let root = if let Some((root, is_empty, _)) = root {
710 self.set_storage(prefixed_storage_key.into_inner(), (!is_empty).then(|| root.encode()));
716
717 self.mark_dirty();
718
719 root
720 } else {
721 let root = backend
723 .storage(prefixed_storage_key.as_slice())?
724 .and_then(|k| Decode::decode(&mut &k[..]).ok())
725 .unwrap_or_else(empty_child_trie_root::<LayoutV1<H>>);
727
728 root
729 };
730
731 Ok((root, false))
732 }
733
734 pub fn iter_after(&mut self, key: &[u8]) -> impl Iterator<Item = (&[u8], &mut OverlayedValue)> {
737 self.top.changes_after(key)
738 }
739
740 pub fn child_iter_after(
743 &mut self,
744 storage_key: &[u8],
745 key: &[u8],
746 ) -> impl Iterator<Item = (&[u8], &mut OverlayedValue)> {
747 self.children
748 .get_mut(storage_key)
749 .map(|(overlay, _)| overlay.changes_after(key))
750 .into_iter()
751 .flatten()
752 }
753
754 pub fn offchain(&self) -> &OffchainOverlayedChanges {
756 &self.offchain
757 }
758
759 pub fn set_offchain_storage(&mut self, key: &[u8], value: Option<&[u8]>) {
761 use sp_core::offchain::STORAGE_PREFIX;
762 match value {
763 Some(value) => self.offchain.set(STORAGE_PREFIX, key, value),
764 None => self.offchain.remove(STORAGE_PREFIX, key),
765 }
766 }
767
768 pub fn add_transaction_index(&mut self, op: IndexOperation) {
770 self.transaction_index_ops.push(op)
771 }
772}
773
774#[cfg(not(substrate_runtime))]
775impl<H: Hasher> From<sp_core::storage::Storage> for OverlayedChanges<H> {
776 fn from(storage: sp_core::storage::Storage) -> Self {
777 Self {
778 top: storage.top.into(),
779 children: storage
780 .children_default
781 .into_iter()
782 .map(|(k, v)| (k, (v.data.into(), v.child_info)))
783 .collect(),
784 ..Default::default()
785 }
786 }
787}
788
789#[cfg(feature = "std")]
790fn retain_map<K, V, F>(map: &mut Map<K, V>, f: F)
791where
792 K: std::cmp::Eq + std::hash::Hash,
793 F: FnMut(&K, &mut V) -> bool,
794{
795 map.retain(f);
796}
797
798#[cfg(not(feature = "std"))]
799fn retain_map<K, V, F>(map: &mut Map<K, V>, mut f: F)
800where
801 K: Ord,
802 F: FnMut(&K, &mut V) -> bool,
803{
804 let old = core::mem::replace(map, Map::default());
805 for (k, mut v) in old.into_iter() {
806 if f(&k, &mut v) {
807 map.insert(k, v);
808 }
809 }
810}
811
812#[cfg(feature = "std")]
815pub enum OverlayedExtension<'a> {
816 MutRef(&'a mut Box<dyn Extension>),
817 Owned(Box<dyn Extension>),
818}
819
820#[cfg(feature = "std")]
821impl OverlayedExtension<'_> {
822 fn extension(&mut self) -> &mut dyn Extension {
823 match self {
824 Self::MutRef(ext) => *ext,
825 Self::Owned(ext) => &mut *ext,
826 }
827 }
828}
829
830#[cfg(feature = "std")]
838pub struct OverlayedExtensions<'a> {
839 extensions: Map<TypeId, OverlayedExtension<'a>>,
840}
841
842#[cfg(feature = "std")]
843impl<'a> OverlayedExtensions<'a> {
844 pub fn new(extensions: &'a mut Extensions) -> Self {
846 Self {
847 extensions: extensions
848 .iter_mut()
849 .map(|(k, v)| (*k, OverlayedExtension::MutRef(v)))
850 .collect(),
851 }
852 }
853
854 pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> {
856 self.extensions.get_mut(&ext_type_id).map(|ext| match ext {
857 OverlayedExtension::MutRef(ext) => ext.as_mut_any(),
858 OverlayedExtension::Owned(ext) => ext.as_mut_any(),
859 })
860 }
861
862 pub fn register(
864 &mut self,
865 type_id: TypeId,
866 extension: Box<dyn Extension>,
867 ) -> Result<(), sp_externalities::Error> {
868 match self.extensions.entry(type_id) {
869 MapEntry::Vacant(vacant) => {
870 vacant.insert(OverlayedExtension::Owned(extension));
871 Ok(())
872 },
873 MapEntry::Occupied(_) => Err(sp_externalities::Error::ExtensionAlreadyRegistered),
874 }
875 }
876
877 pub fn deregister(&mut self, type_id: TypeId) -> bool {
881 self.extensions.remove(&type_id).is_some()
882 }
883
884 pub fn start_transaction(&mut self, ty: TransactionType) {
888 self.extensions.values_mut().for_each(|e| e.extension().start_transaction(ty));
889 }
890
891 pub fn commit_transaction(&mut self, ty: TransactionType) {
895 self.extensions.values_mut().for_each(|e| e.extension().commit_transaction(ty));
896 }
897
898 pub fn rollback_transaction(&mut self, ty: TransactionType) {
902 self.extensions
903 .values_mut()
904 .for_each(|e| e.extension().rollback_transaction(ty));
905 }
906}
907
908#[cfg(test)]
909mod tests {
910 use super::*;
911 use crate::{ext::Ext, new_in_mem, InMemoryBackend};
912 use array_bytes::bytes2hex;
913 use sp_core::{traits::Externalities, Blake2Hasher};
914 use std::collections::BTreeMap;
915
916 fn assert_extrinsics(
917 overlay: &mut OverlayedChangeSet,
918 key: impl AsRef<[u8]>,
919 expected: Vec<u32>,
920 ) {
921 assert_eq!(
922 overlay.get(key.as_ref()).unwrap().extrinsics().into_iter().collect::<Vec<_>>(),
923 expected
924 )
925 }
926
927 #[test]
928 fn overlayed_storage_works() {
929 let mut overlayed = OverlayedChanges::<Blake2Hasher>::default();
930
931 let key = vec![42, 69, 169, 142];
932
933 assert!(overlayed.storage(&key).is_none());
934
935 overlayed.start_transaction();
936
937 overlayed.set_storage(key.clone(), Some(vec![1, 2, 3]));
938 assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
939
940 overlayed.commit_transaction().unwrap();
941
942 assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
943
944 overlayed.start_transaction();
945
946 overlayed.set_storage(key.clone(), Some(vec![]));
947 assert_eq!(overlayed.storage(&key).unwrap(), Some(&[][..]));
948
949 overlayed.set_storage(key.clone(), None);
950 assert!(overlayed.storage(&key).unwrap().is_none());
951
952 overlayed.rollback_transaction().unwrap();
953
954 assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
955
956 overlayed.set_storage(key.clone(), None);
957 assert!(overlayed.storage(&key).unwrap().is_none());
958 }
959
960 #[test]
961 fn offchain_overlayed_storage_transactions_works() {
962 use sp_core::offchain::STORAGE_PREFIX;
963 fn check_offchain_content(
964 state: &OverlayedChanges<Blake2Hasher>,
965 nb_commit: usize,
966 expected: Vec<(Vec<u8>, Option<Vec<u8>>)>,
967 ) {
968 let mut state = state.clone();
969 for _ in 0..nb_commit {
970 state.commit_transaction().unwrap();
971 }
972 let offchain_data: Vec<_> = state.offchain_drain_committed().collect();
973 let expected: Vec<_> = expected
974 .into_iter()
975 .map(|(key, value)| {
976 let change = match value {
977 Some(value) => OffchainOverlayedChange::SetValue(value),
978 None => OffchainOverlayedChange::Remove,
979 };
980 ((STORAGE_PREFIX.to_vec(), key), change)
981 })
982 .collect();
983 assert_eq!(offchain_data, expected);
984 }
985
986 let mut overlayed = OverlayedChanges::default();
987
988 let key = vec![42, 69, 169, 142];
989
990 check_offchain_content(&overlayed, 0, vec![]);
991
992 overlayed.start_transaction();
993
994 overlayed.set_offchain_storage(key.as_slice(), Some(&[1, 2, 3][..]));
995 check_offchain_content(&overlayed, 1, vec![(key.clone(), Some(vec![1, 2, 3]))]);
996
997 overlayed.commit_transaction().unwrap();
998
999 check_offchain_content(&overlayed, 0, vec![(key.clone(), Some(vec![1, 2, 3]))]);
1000
1001 overlayed.start_transaction();
1002
1003 overlayed.set_offchain_storage(key.as_slice(), Some(&[][..]));
1004 check_offchain_content(&overlayed, 1, vec![(key.clone(), Some(vec![]))]);
1005
1006 overlayed.set_offchain_storage(key.as_slice(), None);
1007 check_offchain_content(&overlayed, 1, vec![(key.clone(), None)]);
1008
1009 overlayed.rollback_transaction().unwrap();
1010
1011 check_offchain_content(&overlayed, 0, vec![(key.clone(), Some(vec![1, 2, 3]))]);
1012
1013 overlayed.set_offchain_storage(key.as_slice(), None);
1014 check_offchain_content(&overlayed, 0, vec![(key.clone(), None)]);
1015 }
1016
1017 #[test]
1018 fn overlayed_storage_root_works() {
1019 let state_version = StateVersion::default();
1020 let initial: BTreeMap<_, _> = vec![
1021 (b"doe".to_vec(), b"reindeer".to_vec()),
1022 (b"dog".to_vec(), b"puppyXXX".to_vec()),
1023 (b"dogglesworth".to_vec(), b"catXXX".to_vec()),
1024 (b"doug".to_vec(), b"notadog".to_vec()),
1025 ]
1026 .into_iter()
1027 .collect();
1028 let backend = InMemoryBackend::<Blake2Hasher>::from((initial, state_version));
1029 let mut overlay = OverlayedChanges::default();
1030
1031 overlay.start_transaction();
1032 overlay.set_storage(b"dog".to_vec(), Some(b"puppy".to_vec()));
1033 overlay.set_storage(b"dogglesworth".to_vec(), Some(b"catYYY".to_vec()));
1034 overlay.set_storage(b"doug".to_vec(), Some(vec![]));
1035 overlay.commit_transaction().unwrap();
1036
1037 overlay.start_transaction();
1038 overlay.set_storage(b"dogglesworth".to_vec(), Some(b"cat".to_vec()));
1039 overlay.set_storage(b"doug".to_vec(), None);
1040
1041 {
1042 let mut ext = Ext::new(&mut overlay, &backend, None);
1043 let root = "39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa";
1044
1045 assert_eq!(bytes2hex("", &ext.storage_root(state_version)), root);
1046 assert_eq!(bytes2hex("", &ext.storage_root(state_version)), root);
1048 }
1049
1050 overlay.set_storage(b"doug2".to_vec(), Some(b"yes".to_vec()));
1052
1053 let mut ext = Ext::new(&mut overlay, &backend, None);
1054 let root = "5c0a4e35cb967de785e1cb8743e6f24b6ff6d45155317f2078f6eb3fc4ff3e3d";
1055 assert_eq!(bytes2hex("", &ext.storage_root(state_version)), root);
1056 }
1057
1058 #[test]
1059 fn overlayed_child_storage_root_works() {
1060 let state_version = StateVersion::default();
1061 let child_info = ChildInfo::new_default(b"Child1");
1062 let child_info = &child_info;
1063 let backend = new_in_mem::<Blake2Hasher>();
1064 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1065 overlay.start_transaction();
1066 overlay.set_child_storage(child_info, vec![20], Some(vec![20]));
1067 overlay.set_child_storage(child_info, vec![30], Some(vec![30]));
1068 overlay.set_child_storage(child_info, vec![40], Some(vec![40]));
1069 overlay.commit_transaction().unwrap();
1070 overlay.set_child_storage(child_info, vec![10], Some(vec![10]));
1071 overlay.set_child_storage(child_info, vec![30], None);
1072
1073 {
1074 let mut ext = Ext::new(&mut overlay, &backend, None);
1075 let child_root = "c02965e1df4dc5baf6977390ce67dab1d7a9b27a87c1afe27b50d29cc990e0f5";
1076 let root = "eafb765909c3ed5afd92a0c564acf4620d0234b31702e8e8e9b48da72a748838";
1077
1078 assert_eq!(
1079 bytes2hex("", &ext.child_storage_root(child_info, state_version)),
1080 child_root,
1081 );
1082
1083 assert_eq!(bytes2hex("", &ext.storage_root(state_version)), root);
1084
1085 assert_eq!(
1087 bytes2hex("", &ext.child_storage_root(child_info, state_version)),
1088 child_root,
1089 );
1090 }
1091 }
1092
1093 #[test]
1094 fn extrinsic_changes_are_collected() {
1095 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1096 overlay.set_collect_extrinsics(true);
1097
1098 overlay.start_transaction();
1099
1100 overlay.set_storage(vec![100], Some(vec![101]));
1101
1102 overlay.set_extrinsic_index(0);
1103 overlay.set_storage(vec![1], Some(vec![2]));
1104
1105 overlay.set_extrinsic_index(1);
1106 overlay.set_storage(vec![3], Some(vec![4]));
1107
1108 overlay.set_extrinsic_index(2);
1109 overlay.set_storage(vec![1], Some(vec![6]));
1110
1111 assert_extrinsics(&mut overlay.top, vec![1], vec![0, 2]);
1112 assert_extrinsics(&mut overlay.top, vec![3], vec![1]);
1113 assert_extrinsics(&mut overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
1114
1115 overlay.start_transaction();
1116
1117 overlay.set_extrinsic_index(3);
1118 overlay.set_storage(vec![3], Some(vec![7]));
1119
1120 overlay.set_extrinsic_index(4);
1121 overlay.set_storage(vec![1], Some(vec![8]));
1122
1123 assert_extrinsics(&mut overlay.top, vec![1], vec![0, 2, 4]);
1124 assert_extrinsics(&mut overlay.top, vec![3], vec![1, 3]);
1125 assert_extrinsics(&mut overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
1126
1127 overlay.rollback_transaction().unwrap();
1128
1129 assert_extrinsics(&mut overlay.top, vec![1], vec![0, 2]);
1130 assert_extrinsics(&mut overlay.top, vec![3], vec![1]);
1131 assert_extrinsics(&mut overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
1132 }
1133
1134 #[test]
1135 fn next_storage_key_change_works() {
1136 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1137 overlay.start_transaction();
1138 overlay.set_storage(vec![20], Some(vec![20]));
1139 overlay.set_storage(vec![30], Some(vec![30]));
1140 overlay.set_storage(vec![40], Some(vec![40]));
1141 overlay.commit_transaction().unwrap();
1142 overlay.set_storage(vec![10], Some(vec![10]));
1143 overlay.set_storage(vec![30], None);
1144
1145 let next_to_5 = overlay.iter_after(&[5]).next().unwrap();
1147 assert_eq!(next_to_5.0.to_vec(), vec![10]);
1148 assert_eq!(next_to_5.1.value(), Some(&vec![10]));
1149
1150 let next_to_10 = overlay.iter_after(&[10]).next().unwrap();
1152 assert_eq!(next_to_10.0.to_vec(), vec![20]);
1153 assert_eq!(next_to_10.1.value(), Some(&vec![20]));
1154
1155 let next_to_20 = overlay.iter_after(&[20]).next().unwrap();
1157 assert_eq!(next_to_20.0.to_vec(), vec![30]);
1158 assert_eq!(next_to_20.1.value(), None);
1159
1160 let next_to_30 = overlay.iter_after(&[30]).next().unwrap();
1162 assert_eq!(next_to_30.0.to_vec(), vec![40]);
1163 assert_eq!(next_to_30.1.value(), Some(&vec![40]));
1164
1165 overlay.set_storage(vec![50], Some(vec![50]));
1166 let next_to_40 = overlay.iter_after(&[40]).next().unwrap();
1168 assert_eq!(next_to_40.0.to_vec(), vec![50]);
1169 assert_eq!(next_to_40.1.value(), Some(&vec![50]));
1170 }
1171
1172 #[test]
1173 fn next_child_storage_key_change_works() {
1174 let child_info = ChildInfo::new_default(b"Child1");
1175 let child_info = &child_info;
1176 let child = child_info.storage_key();
1177 let mut overlay = OverlayedChanges::<Blake2Hasher>::default();
1178 overlay.start_transaction();
1179 overlay.set_child_storage(child_info, vec![20], Some(vec![20]));
1180 overlay.set_child_storage(child_info, vec![30], Some(vec![30]));
1181 overlay.set_child_storage(child_info, vec![40], Some(vec![40]));
1182 overlay.commit_transaction().unwrap();
1183 overlay.set_child_storage(child_info, vec![10], Some(vec![10]));
1184 overlay.set_child_storage(child_info, vec![30], None);
1185
1186 let next_to_5 = overlay.child_iter_after(child, &[5]).next().unwrap();
1188 assert_eq!(next_to_5.0.to_vec(), vec![10]);
1189 assert_eq!(next_to_5.1.value(), Some(&vec![10]));
1190
1191 let next_to_10 = overlay.child_iter_after(child, &[10]).next().unwrap();
1193 assert_eq!(next_to_10.0.to_vec(), vec![20]);
1194 assert_eq!(next_to_10.1.value(), Some(&vec![20]));
1195
1196 let next_to_20 = overlay.child_iter_after(child, &[20]).next().unwrap();
1198 assert_eq!(next_to_20.0.to_vec(), vec![30]);
1199 assert_eq!(next_to_20.1.value(), None);
1200
1201 let next_to_30 = overlay.child_iter_after(child, &[30]).next().unwrap();
1203 assert_eq!(next_to_30.0.to_vec(), vec![40]);
1204 assert_eq!(next_to_30.1.value(), Some(&vec![40]));
1205
1206 overlay.set_child_storage(child_info, vec![50], Some(vec![50]));
1207 let next_to_40 = overlay.child_iter_after(child, &[40]).next().unwrap();
1209 assert_eq!(next_to_40.0.to_vec(), vec![50]);
1210 assert_eq!(next_to_40.1.value(), Some(&vec![50]));
1211 }
1212}