tp_state_machine/overlayed_changes/
mod.rs

1// This file is part of Tetcore.
2
3// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! The overlayed changes to state.
19
20mod changeset;
21mod offchain;
22
23pub use offchain::OffchainOverlayedChanges;
24use crate::{
25	backend::Backend,
26	stats::StateMachineStats,
27};
28use tetcore_std::{vec::Vec, any::{TypeId, Any}, boxed::Box};
29use self::changeset::OverlayedChangeSet;
30
31#[cfg(feature = "std")]
32use crate::{
33	ChangesTrieTransaction,
34	changes_trie::{
35		build_changes_trie,
36		State as ChangesTrieState,
37	},
38};
39use crate::changes_trie::BlockNumber;
40#[cfg(feature = "std")]
41use std::collections::{HashMap as Map, hash_map::Entry as MapEntry};
42#[cfg(not(feature = "std"))]
43use tetcore_std::collections::btree_map::{BTreeMap as Map, Entry as MapEntry};
44use tetcore_std::collections::btree_set::BTreeSet;
45use codec::{Decode, Encode};
46use tet_core::storage::{well_known_keys::EXTRINSIC_INDEX, ChildInfo};
47use tet_core::offchain::OffchainOverlayedChange;
48use tetsy_hash_db::Hasher;
49use crate::DefaultError;
50use externalities::{Extensions, Extension};
51
52pub use self::changeset::{OverlayedValue, NoOpenTransaction, AlreadyInRuntime, NotInRuntime};
53
54/// Changes that are made outside of extrinsics are marked with this index;
55pub const NO_EXTRINSIC_INDEX: u32 = 0xffffffff;
56
57/// Storage key.
58pub type StorageKey = Vec<u8>;
59
60/// Storage value.
61pub type StorageValue = Vec<u8>;
62
63/// In memory array of storage values.
64pub type StorageCollection = Vec<(StorageKey, Option<StorageValue>)>;
65
66/// In memory arrays of storage values for multiple child tries.
67pub type ChildStorageCollection = Vec<(StorageKey, StorageCollection)>;
68
69/// In memory array of storage values.
70pub type OffchainChangesCollection = Vec<((Vec<u8>, Vec<u8>), OffchainOverlayedChange)>;
71
72/// Keep trace of extrinsics index for a modified value.
73#[derive(Debug, Default, Eq, PartialEq, Clone)]
74pub struct Extrinsics(Vec<u32>);
75
76impl Extrinsics {
77	/// Extracts extrinsics into a `BTreeSets`.
78	fn copy_extrinsics_into(&self, dest: &mut BTreeSet<u32>) {
79		dest.extend(self.0.iter())
80	}
81
82	/// Add an extrinsics.
83	fn insert(&mut self, ext: u32) {
84		if Some(&ext) != self.0.last() {
85			self.0.push(ext);
86		}
87	}
88
89	/// Extend `self` with `other`.
90	fn extend(&mut self, other: Self) {
91		self.0.extend(other.0.into_iter());
92	}
93}
94
95/// The set of changes that are overlaid onto the backend.
96///
97/// It allows changes to be modified using nestable transactions.
98#[derive(Debug, Default, Clone)]
99pub struct OverlayedChanges {
100	/// Top level storage changes.
101	top: OverlayedChangeSet,
102	/// Child storage changes. The map key is the child storage key without the common prefix.
103	children: Map<StorageKey, (OverlayedChangeSet, ChildInfo)>,
104	/// Offchain related changes.
105	offchain: OffchainOverlayedChanges,
106	/// True if extrinsics stats must be collected.
107	collect_extrinsics: bool,
108	/// Collect statistic on this execution.
109	stats: StateMachineStats,
110}
111
112/// A storage changes structure that can be generated by the data collected in [`OverlayedChanges`].
113///
114/// This contains all the changes to the storage and transactions to apply theses changes to the
115/// backend.
116pub struct StorageChanges<Transaction, H: Hasher, N: BlockNumber> {
117	/// All changes to the main storage.
118	///
119	/// A value of `None` means that it was deleted.
120	pub main_storage_changes: StorageCollection,
121	/// All changes to the child storages.
122	pub child_storage_changes: ChildStorageCollection,
123	/// Offchain state changes to write to the offchain database.
124	pub offchain_storage_changes: OffchainChangesCollection,
125	/// A transaction for the backend that contains all changes from
126	/// [`main_storage_changes`](StorageChanges::main_storage_changes) and from
127	/// [`child_storage_changes`](StorageChanges::child_storage_changes).
128	/// [`offchain_storage_changes`](StorageChanges::offchain_storage_changes).
129	pub transaction: Transaction,
130	/// The storage root after applying the transaction.
131	pub transaction_storage_root: H::Out,
132	/// Contains the transaction for the backend for the changes trie.
133	///
134	/// If changes trie is disabled the value is set to `None`.
135	#[cfg(feature = "std")]
136	pub changes_trie_transaction: Option<ChangesTrieTransaction<H, N>>,
137	/// Phantom data for block number until change trie support no_std.
138	#[cfg(not(feature = "std"))]
139	pub _ph: tetcore_std::marker::PhantomData<N>,
140}
141
142#[cfg(feature = "std")]
143impl<Transaction, H: Hasher, N: BlockNumber> StorageChanges<Transaction, H, N> {
144	/// Deconstruct into the inner values
145	pub fn into_inner(self) -> (
146		StorageCollection,
147		ChildStorageCollection,
148		OffchainChangesCollection,
149		Transaction,
150		H::Out,
151		Option<ChangesTrieTransaction<H, N>>,
152	) {
153		(
154			self.main_storage_changes,
155			self.child_storage_changes,
156			self.offchain_storage_changes,
157			self.transaction,
158			self.transaction_storage_root,
159			self.changes_trie_transaction,
160		)
161	}
162}
163
164/// The storage transaction are calculated as part of the `storage_root` and
165/// `changes_trie_storage_root`. These transactions can be reused for importing the block into the
166/// storage. So, we cache them to not require a recomputation of those transactions.
167pub struct StorageTransactionCache<Transaction, H: Hasher, N: BlockNumber> {
168	/// Contains the changes for the main and the child storages as one transaction.
169	pub(crate) transaction: Option<Transaction>,
170	/// The storage root after applying the transaction.
171	pub(crate) transaction_storage_root: Option<H::Out>,
172	/// Contains the changes trie transaction.
173	#[cfg(feature = "std")]
174	pub(crate) changes_trie_transaction: Option<Option<ChangesTrieTransaction<H, N>>>,
175	/// The storage root after applying the changes trie transaction.
176	#[cfg(feature = "std")]
177	pub(crate) changes_trie_transaction_storage_root: Option<Option<H::Out>>,
178	/// Phantom data for block number until change trie support no_std.
179	#[cfg(not(feature = "std"))]
180	pub(crate) _ph: tetcore_std::marker::PhantomData<N>,
181}
182
183impl<Transaction, H: Hasher, N: BlockNumber> StorageTransactionCache<Transaction, H, N> {
184	/// Reset the cached transactions.
185	pub fn reset(&mut self) {
186		*self = Self::default();
187	}
188}
189
190impl<Transaction, H: Hasher, N: BlockNumber> Default for StorageTransactionCache<Transaction, H, N> {
191	fn default() -> Self {
192		Self {
193			transaction: None,
194			transaction_storage_root: None,
195			#[cfg(feature = "std")]
196			changes_trie_transaction: None,
197			#[cfg(feature = "std")]
198			changes_trie_transaction_storage_root: None,
199			#[cfg(not(feature = "std"))]
200			_ph: Default::default(),
201		}
202	}
203}
204
205impl<Transaction: Default, H: Hasher, N: BlockNumber> Default for StorageChanges<Transaction, H, N> {
206	fn default() -> Self {
207		Self {
208			main_storage_changes: Default::default(),
209			child_storage_changes: Default::default(),
210			offchain_storage_changes: Default::default(),
211			transaction: Default::default(),
212			transaction_storage_root: Default::default(),
213			#[cfg(feature = "std")]
214			changes_trie_transaction: None,
215			#[cfg(not(feature = "std"))]
216			_ph: Default::default(),
217		}
218	}
219}
220
221impl OverlayedChanges {
222	/// Whether no changes are contained in the top nor in any of the child changes.
223	pub fn is_empty(&self) -> bool {
224		self.top.is_empty() && self.children.is_empty()
225	}
226
227	/// Ask to collect/not to collect extrinsics indices where key(s) has been changed.
228	pub fn set_collect_extrinsics(&mut self, collect_extrinsics: bool) {
229		self.collect_extrinsics = collect_extrinsics;
230	}
231
232	/// Returns a double-Option: None if the key is unknown (i.e. and the query should be referred
233	/// to the backend); Some(None) if the key has been deleted. Some(Some(...)) for a key whose
234	/// value has been set.
235	pub fn storage(&self, key: &[u8]) -> Option<Option<&[u8]>> {
236		self.top.get(key).map(|x| {
237			let value = x.value();
238			let size_read = value.map(|x| x.len() as u64).unwrap_or(0);
239			self.stats.tally_read_modified(size_read);
240			value.map(AsRef::as_ref)
241		})
242	}
243
244	/// Returns mutable reference to current value.
245	/// If there is no value in the overlay, the given callback is used to initiate the value.
246	/// Warning this function registers a change, so the mutable reference MUST be modified.
247	///
248	/// Can be rolled back or committed when called inside a transaction.
249	#[must_use = "A change was registered, so this value MUST be modified."]
250	pub fn value_mut_or_insert_with(
251		&mut self,
252		key: &[u8],
253		init: impl Fn() -> StorageValue,
254	) -> &mut StorageValue {
255		let value = self.top.modify(key.to_vec(), init, self.extrinsic_index());
256
257		// if the value was deleted initialise it back with an empty vec
258		value.get_or_insert_with(StorageValue::default)
259	}
260
261	/// Returns a double-Option: None if the key is unknown (i.e. and the query should be referred
262	/// to the backend); Some(None) if the key has been deleted. Some(Some(...)) for a key whose
263	/// value has been set.
264	pub fn child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> Option<Option<&[u8]>> {
265		let map = self.children.get(child_info.storage_key())?;
266		let value = map.0.get(key)?.value();
267		let size_read = value.map(|x| x.len() as u64).unwrap_or(0);
268		self.stats.tally_read_modified(size_read);
269		Some(value.map(AsRef::as_ref))
270	}
271
272	/// Set a new value for the specified key.
273	///
274	/// Can be rolled back or committed when called inside a transaction.
275	pub(crate) fn set_storage(&mut self, key: StorageKey, val: Option<StorageValue>) {
276		let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0);
277		self.stats.tally_write_overlay(size_write);
278		self.top.set(key, val, self.extrinsic_index());
279	}
280
281	/// Set a new value for the specified key and child.
282	///
283	/// `None` can be used to delete a value specified by the given key.
284	///
285	/// Can be rolled back or committed when called inside a transaction.
286	pub(crate) fn set_child_storage(
287		&mut self,
288		child_info: &ChildInfo,
289		key: StorageKey,
290		val: Option<StorageValue>,
291	) {
292		let extrinsic_index = self.extrinsic_index();
293		let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0);
294		self.stats.tally_write_overlay(size_write);
295		let storage_key = child_info.storage_key().to_vec();
296		let top = &self.top;
297		let (changeset, info) = self.children.entry(storage_key).or_insert_with(||
298			(
299				top.spawn_child(),
300				child_info.clone()
301			)
302		);
303		let updatable = info.try_update(child_info);
304		debug_assert!(updatable);
305		changeset.set(key, val, extrinsic_index);
306	}
307
308	/// Clear child storage of given storage key.
309	///
310	/// Can be rolled back or committed when called inside a transaction.
311	pub(crate) fn clear_child_storage(
312		&mut self,
313		child_info: &ChildInfo,
314	) {
315		let extrinsic_index = self.extrinsic_index();
316		let storage_key = child_info.storage_key().to_vec();
317		let top = &self.top;
318		let (changeset, info) = self.children.entry(storage_key).or_insert_with(||
319			(
320				top.spawn_child(),
321				child_info.clone()
322			)
323		);
324		let updatable = info.try_update(child_info);
325		debug_assert!(updatable);
326		changeset.clear_where(|_, _| true, extrinsic_index);
327	}
328
329	/// Removes all key-value pairs which keys share the given prefix.
330	///
331	/// Can be rolled back or committed when called inside a transaction.
332	pub(crate) fn clear_prefix(&mut self, prefix: &[u8]) {
333		self.top.clear_where(|key, _| key.starts_with(prefix), self.extrinsic_index());
334	}
335
336	/// Removes all key-value pairs which keys share the given prefix.
337	///
338	/// Can be rolled back or committed when called inside a transaction
339	pub(crate) fn clear_child_prefix(
340		&mut self,
341		child_info: &ChildInfo,
342		prefix: &[u8],
343	) {
344		let extrinsic_index = self.extrinsic_index();
345		let storage_key = child_info.storage_key().to_vec();
346		let top = &self.top;
347		let (changeset, info) = self.children.entry(storage_key).or_insert_with(||
348			(
349				top.spawn_child(),
350				child_info.clone()
351			)
352		);
353		let updatable = info.try_update(child_info);
354		debug_assert!(updatable);
355		changeset.clear_where(|key, _| key.starts_with(prefix), extrinsic_index);
356	}
357
358	/// Returns the current nesting depth of the transaction stack.
359	///
360	/// A value of zero means that no transaction is open and changes are committed on write.
361	pub fn transaction_depth(&self) -> usize {
362		// The top changeset and all child changesets transact in lockstep and are
363		// therefore always at the same transaction depth.
364		self.top.transaction_depth()
365	}
366
367	/// Start a new nested transaction.
368	///
369	/// This allows to either commit or roll back all changes that where made while this
370	/// transaction was open. Any transaction must be closed by either `rollback_transaction` or
371	/// `commit_transaction` before this overlay can be converted into storage changes.
372	///
373	/// Changes made without any open transaction are committed immediatly.
374	pub fn start_transaction(&mut self) {
375		self.top.start_transaction();
376		for (_, (changeset, _)) in self.children.iter_mut() {
377			changeset.start_transaction();
378		}
379		self.offchain.overlay_mut().start_transaction();
380	}
381
382	/// Rollback the last transaction started by `start_transaction`.
383	///
384	/// Any changes made during that transaction are discarded. Returns an error if
385	/// there is no open transaction that can be rolled back.
386	pub fn rollback_transaction(&mut self) -> Result<(), NoOpenTransaction> {
387		self.top.rollback_transaction()?;
388		retain_map(&mut self.children, |_, (changeset, _)| {
389			changeset.rollback_transaction()
390				.expect("Top and children changesets are started in lockstep; qed");
391			!changeset.is_empty()
392		});
393		self.offchain.overlay_mut().rollback_transaction()
394			.expect("Top and offchain changesets are started in lockstep; qed");
395		Ok(())
396	}
397
398	/// Commit the last transaction started by `start_transaction`.
399	///
400	/// Any changes made during that transaction are committed. Returns an error if there
401	/// is no open transaction that can be committed.
402	pub fn commit_transaction(&mut self) -> Result<(), NoOpenTransaction> {
403		self.top.commit_transaction()?;
404		for (_, (changeset, _)) in self.children.iter_mut() {
405			changeset.commit_transaction()
406				.expect("Top and children changesets are started in lockstep; qed");
407		}
408		self.offchain.overlay_mut().commit_transaction()
409			.expect("Top and offchain changesets are started in lockstep; qed");
410		Ok(())
411	}
412
413	/// Call this before transfering control to the runtime.
414	///
415	/// This protects all existing transactions from being removed by the runtime.
416	/// Calling this while already inside the runtime will return an error.
417	pub fn enter_runtime(&mut self) -> Result<(), AlreadyInRuntime> {
418		self.top.enter_runtime()?;
419		for (_, (changeset, _)) in self.children.iter_mut() {
420			changeset.enter_runtime()
421				.expect("Top and children changesets are entering runtime in lockstep; qed")
422		}
423		self.offchain.overlay_mut().enter_runtime()
424			.expect("Top and offchain changesets are started in lockstep; qed");
425		Ok(())
426	}
427
428	/// Call this when control returns from the runtime.
429	///
430	/// This commits all dangling transaction left open by the runtime.
431	/// Calling this while outside the runtime will return an error.
432	pub fn exit_runtime(&mut self) -> Result<(), NotInRuntime> {
433		self.top.exit_runtime()?;
434		for (_, (changeset, _)) in self.children.iter_mut() {
435			changeset.exit_runtime()
436				.expect("Top and children changesets are entering runtime in lockstep; qed");
437		}
438		self.offchain.overlay_mut().exit_runtime()
439			.expect("Top and offchain changesets are started in lockstep; qed");
440		Ok(())
441	}
442
443	/// Consume all changes (top + children) and return them.
444	///
445	/// After calling this function no more changes are contained in this changeset.
446	///
447	/// Panics:
448	/// Panics if `transaction_depth() > 0`
449	fn drain_committed(&mut self) -> (
450		impl Iterator<Item=(StorageKey, Option<StorageValue>)>,
451		impl Iterator<Item=(StorageKey, (impl Iterator<Item=(StorageKey, Option<StorageValue>)>, ChildInfo))>,
452	) {
453		use tetcore_std::mem::take;
454		(
455			take(&mut self.top).drain_commited(),
456			take(&mut self.children).into_iter()
457				.map(|(key, (val, info))| (
458						key,
459						(val.drain_commited(), info)
460					)
461				),
462		)
463	}
464
465	/// Consume all changes (top + children) and return them.
466	///
467	/// After calling this function no more changes are contained in this changeset.
468	///
469	/// Panics:
470	/// Panics if `transaction_depth() > 0`
471	pub fn offchain_drain_committed(&mut self) -> impl Iterator<Item=((StorageKey, StorageKey), OffchainOverlayedChange)> {
472		self.offchain.drain()
473	}
474
475	/// Get an iterator over all child changes as seen by the current transaction.
476	pub fn children(&self)
477		-> impl Iterator<Item=(impl Iterator<Item=(&StorageKey, &OverlayedValue)>, &ChildInfo)> {
478		self.children.iter().map(|(_, v)| (v.0.changes(), &v.1))
479	}
480
481	/// Get an iterator over all top changes as been by the current transaction.
482	pub fn changes(&self) -> impl Iterator<Item=(&StorageKey, &OverlayedValue)> {
483		self.top.changes()
484	}
485
486	/// Get an optional iterator over all child changes stored under the supplied key.
487	pub fn child_changes(&self, key: &[u8])
488		-> Option<(impl Iterator<Item=(&StorageKey, &OverlayedValue)>, &ChildInfo)> {
489		self.children.get(key).map(|(overlay, info)| (overlay.changes(), info))
490	}
491
492	/// Convert this instance with all changes into a [`StorageChanges`] instance.
493	#[cfg(feature = "std")]
494	pub fn into_storage_changes<
495		B: Backend<H>, H: Hasher, N: BlockNumber
496	>(
497		mut self,
498		backend: &B,
499		changes_trie_state: Option<&ChangesTrieState<H, N>>,
500		parent_hash: H::Out,
501		mut cache: StorageTransactionCache<B::Transaction, H, N>,
502	) -> Result<StorageChanges<B::Transaction, H, N>, DefaultError>
503		where H::Out: Ord + Encode + 'static {
504		self.drain_storage_changes(backend, changes_trie_state, parent_hash, &mut cache)
505	}
506
507	/// Drain all changes into a [`StorageChanges`] instance. Leave empty overlay in place.
508	pub fn drain_storage_changes<B: Backend<H>, H: Hasher, N: BlockNumber>(
509		&mut self,
510		backend: &B,
511		#[cfg(feature = "std")]
512		changes_trie_state: Option<&ChangesTrieState<H, N>>,
513		parent_hash: H::Out,
514		mut cache: &mut StorageTransactionCache<B::Transaction, H, N>,
515	) -> Result<StorageChanges<B::Transaction, H, N>, DefaultError>
516		where H::Out: Ord + Encode + 'static {
517		// If the transaction does not exist, we generate it.
518		if cache.transaction.is_none() {
519			self.storage_root(backend, &mut cache);
520		}
521
522		let (transaction, transaction_storage_root) = cache.transaction.take()
523			.and_then(|t| cache.transaction_storage_root.take().map(|tr| (t, tr)))
524			.expect("Transaction was be generated as part of `storage_root`; qed");
525
526		// If the transaction does not exist, we generate it.
527		#[cfg(feature = "std")]
528		if cache.changes_trie_transaction.is_none() {
529			self.changes_trie_root(
530				backend,
531				changes_trie_state,
532				parent_hash,
533				false,
534				&mut cache,
535			).map_err(|_| "Failed to generate changes trie transaction")?;
536		}
537
538		#[cfg(feature = "std")]
539		let changes_trie_transaction = cache.changes_trie_transaction
540			.take()
541			.expect("Changes trie transaction was generated by `changes_trie_root`; qed");
542
543		let (main_storage_changes, child_storage_changes) = self.drain_committed();
544		let offchain_storage_changes = self.offchain_drain_committed().collect();
545
546		Ok(StorageChanges {
547			main_storage_changes: main_storage_changes.collect(),
548			child_storage_changes: child_storage_changes.map(|(sk, it)| (sk, it.0.collect())).collect(),
549			offchain_storage_changes,
550			transaction,
551			transaction_storage_root,
552			#[cfg(feature = "std")]
553			changes_trie_transaction,
554			#[cfg(not(feature = "std"))]
555			_ph: Default::default(),
556		})
557	}
558
559	/// Inserts storage entry responsible for current extrinsic index.
560	#[cfg(test)]
561	pub(crate) fn set_extrinsic_index(&mut self, extrinsic_index: u32) {
562		self.top.set(EXTRINSIC_INDEX.to_vec(), Some(extrinsic_index.encode()), None);
563	}
564
565	/// Returns current extrinsic index to use in changes trie construction.
566	/// None is returned if it is not set or changes trie config is not set.
567	/// Persistent value (from the backend) can be ignored because runtime must
568	/// set this index before first and unset after last extrinsic is executed.
569	/// Changes that are made outside of extrinsics, are marked with
570	/// `NO_EXTRINSIC_INDEX` index.
571	fn extrinsic_index(&self) -> Option<u32> {
572		match self.collect_extrinsics {
573			true => Some(
574				self.storage(EXTRINSIC_INDEX)
575					.and_then(|idx| idx.and_then(|idx| Decode::decode(&mut &*idx).ok()))
576					.unwrap_or(NO_EXTRINSIC_INDEX)),
577			false => None,
578		}
579	}
580
581	/// Generate the storage root using `backend` and all changes
582	/// as seen by the current transaction.
583	///
584	/// Returns the storage root and caches storage transaction in the given `cache`.
585	pub fn storage_root<H: Hasher, N: BlockNumber, B: Backend<H>>(
586		&self,
587		backend: &B,
588		cache: &mut StorageTransactionCache<B::Transaction, H, N>,
589	) -> H::Out
590		where H::Out: Ord + Encode,
591	{
592		let delta = self.changes().map(|(k, v)| (&k[..], v.value().map(|v| &v[..])));
593		let child_delta = self.children()
594			.map(|(changes, info)| (info, changes.map(
595				|(k, v)| (&k[..], v.value().map(|v| &v[..]))
596			)));
597
598		let (root, transaction) = backend.full_storage_root(delta, child_delta);
599
600		cache.transaction = Some(transaction);
601		cache.transaction_storage_root = Some(root);
602
603		root
604	}
605
606	/// Generate the changes trie root.
607	///
608	/// Returns the changes trie root and caches the storage transaction into the given `cache`.
609	///
610	/// # Panics
611	///
612	/// Panics on storage error, when `panic_on_storage_error` is set.
613	#[cfg(feature = "std")]
614	pub fn changes_trie_root<'a, H: Hasher, N: BlockNumber, B: Backend<H>>(
615		&self,
616		backend: &B,
617		changes_trie_state: Option<&'a ChangesTrieState<'a, H, N>>,
618		parent_hash: H::Out,
619		panic_on_storage_error: bool,
620		cache: &mut StorageTransactionCache<B::Transaction, H, N>,
621	) -> Result<Option<H::Out>, ()> where H::Out: Ord + Encode + 'static {
622		build_changes_trie::<_, H, N>(
623			backend,
624			changes_trie_state,
625			self,
626			parent_hash,
627			panic_on_storage_error,
628		).map(|r| {
629			let root = r.as_ref().map(|r| r.1).clone();
630			cache.changes_trie_transaction = Some(r.map(|(db, _, cache)| (db, cache)));
631			cache.changes_trie_transaction_storage_root = Some(root);
632			root
633		})
634	}
635
636	/// Returns the next (in lexicographic order) storage key in the overlayed alongside its value.
637	/// If no value is next then `None` is returned.
638	pub fn next_storage_key_change(&self, key: &[u8]) -> Option<(&[u8], &OverlayedValue)> {
639		self.top.next_change(key)
640	}
641
642	/// Returns the next (in lexicographic order) child storage key in the overlayed alongside its
643	/// value.  If no value is next then `None` is returned.
644	pub fn next_child_storage_key_change(
645		&self,
646		storage_key: &[u8],
647		key: &[u8]
648	) -> Option<(&[u8], &OverlayedValue)> {
649		self.children
650			.get(storage_key)
651			.and_then(|(overlay, _)|
652				overlay.next_change(key)
653			)
654	}
655
656	/// Read only access ot offchain overlay.
657	pub fn offchain(&self) -> &OffchainOverlayedChanges {
658		&self.offchain
659	}
660
661	/// Write a key value pair to the offchain storage overlay.
662	pub fn set_offchain_storage(&mut self, key: &[u8], value: Option<&[u8]>) {
663		use tet_core::offchain::STORAGE_PREFIX;
664		match value {
665			Some(value) => self.offchain.set(STORAGE_PREFIX, key, value),
666			None => self.offchain.remove(STORAGE_PREFIX, key),
667		}
668	}
669}
670
671#[cfg(feature = "std")]
672fn retain_map<K, V, F>(map: &mut Map<K, V>, f: F)
673	where
674		K: std::cmp::Eq + std::hash::Hash,
675		F: FnMut(&K, &mut V) -> bool,
676{
677	map.retain(f);
678}
679
680#[cfg(not(feature = "std"))]
681fn retain_map<K, V, F>(map: &mut Map<K, V>, mut f: F)
682	where
683		K: Ord,
684		F: FnMut(&K, &mut V) -> bool,
685{
686	let old = tetcore_std::mem::replace(map, Map::default());
687	for (k, mut v) in old.into_iter() {
688		if f(&k, &mut v) {
689			map.insert(k, v);
690		}
691	}
692}
693
694/// An overlayed extension is either a mutable reference
695/// or an owned extension.
696pub enum OverlayedExtension<'a> {
697	MutRef(&'a mut Box<dyn Extension>),
698	Owned(Box<dyn Extension>),
699}
700
701/// Overlayed extensions which are sourced from [`Extensions`].
702///
703/// The sourced extensions will be stored as mutable references,
704/// while extensions that are registered while execution are stored
705/// as owned references. After the execution of a runtime function, we
706/// can safely drop this object while not having modified the original
707/// list.
708pub struct OverlayedExtensions<'a> {
709	extensions: Map<TypeId, OverlayedExtension<'a>>,
710}
711
712impl<'a> OverlayedExtensions<'a> {
713	/// Create a new instance of overalyed extensions from the given extensions.
714	pub fn new(extensions: &'a mut Extensions) -> Self {
715		Self {
716			extensions: extensions
717				.iter_mut()
718				.map(|(k, v)| (*k, OverlayedExtension::MutRef(v)))
719				.collect(),
720		}
721	}
722
723	/// Return a mutable reference to the requested extension.
724	pub fn get_mut(&mut self, ext_type_id: TypeId) -> Option<&mut dyn Any> {
725		self.extensions.get_mut(&ext_type_id).map(|ext| match ext {
726			OverlayedExtension::MutRef(ext) => ext.as_mut_any(),
727			OverlayedExtension::Owned(ext) => ext.as_mut_any(),
728		})
729	}
730
731	/// Register extension `extension` with the given `type_id`.
732	pub fn register(
733		&mut self,
734		type_id: TypeId,
735		extension: Box<dyn Extension>,
736	) -> Result<(), externalities::Error> {
737		match self.extensions.entry(type_id) {
738			MapEntry::Vacant(vacant) => {
739				vacant.insert(OverlayedExtension::Owned(extension));
740				Ok(())
741			},
742			MapEntry::Occupied(_) => Err(externalities::Error::ExtensionAlreadyRegistered),
743		}
744	}
745
746	/// Deregister extension with the given `type_id`.
747	///
748	/// Returns `true` when there was an extension registered for the given `type_id`.
749	pub fn deregister(&mut self, type_id: TypeId) -> bool {
750		self.extensions.remove(&type_id).is_some()
751	}
752}
753
754#[cfg(test)]
755mod tests {
756	use hex_literal::hex;
757	use tet_core::{Blake2Hasher, traits::Externalities};
758	use crate::InMemoryBackend;
759	use crate::ext::Ext;
760	use super::*;
761	use std::collections::BTreeMap;
762
763	fn assert_extrinsics(
764		overlay: &OverlayedChangeSet,
765		key: impl AsRef<[u8]>,
766		expected: Vec<u32>,
767	) {
768		assert_eq!(
769			overlay.get(key.as_ref()).unwrap().extrinsics().into_iter().collect::<Vec<_>>(),
770			expected
771		)
772	}
773
774	#[test]
775	fn overlayed_storage_works() {
776		let mut overlayed = OverlayedChanges::default();
777
778		let key = vec![42, 69, 169, 142];
779
780		assert!(overlayed.storage(&key).is_none());
781
782		overlayed.start_transaction();
783
784		overlayed.set_storage(key.clone(), Some(vec![1, 2, 3]));
785		assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
786
787		overlayed.commit_transaction().unwrap();
788
789		assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
790
791		overlayed.start_transaction();
792
793		overlayed.set_storage(key.clone(), Some(vec![]));
794		assert_eq!(overlayed.storage(&key).unwrap(), Some(&[][..]));
795
796		overlayed.set_storage(key.clone(), None);
797		assert!(overlayed.storage(&key).unwrap().is_none());
798
799		overlayed.rollback_transaction().unwrap();
800
801		assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..]));
802
803		overlayed.set_storage(key.clone(), None);
804		assert!(overlayed.storage(&key).unwrap().is_none());
805	}
806
807	#[test]
808	fn offchain_overlayed_storage_transactions_works() {
809		use tet_core::offchain::STORAGE_PREFIX;
810		fn check_offchain_content(
811			state: &OverlayedChanges,
812			nb_commit: usize,
813			expected: Vec<(Vec<u8>, Option<Vec<u8>>)>,
814		) {
815			let mut state = state.clone();
816			for _ in 0..nb_commit {
817				state.commit_transaction().unwrap();
818			}
819			let offchain_data: Vec<_> = state.offchain_drain_committed().collect();
820			let expected: Vec<_> = expected.into_iter().map(|(key, value)| {
821				let change = match value {
822					Some(value) => OffchainOverlayedChange::SetValue(value),
823					None => OffchainOverlayedChange::Remove,
824				};
825				((STORAGE_PREFIX.to_vec(), key), change)
826			}).collect();
827			assert_eq!(offchain_data, expected);
828		}
829
830		let mut overlayed = OverlayedChanges::default();
831
832		let key = vec![42, 69, 169, 142];
833
834		check_offchain_content(&overlayed, 0, vec![]);
835
836		overlayed.start_transaction();
837
838		overlayed.set_offchain_storage(key.as_slice(), Some(&[1, 2, 3][..]));
839		check_offchain_content(&overlayed, 1, vec![(key.clone(), Some(vec![1, 2, 3]))]);
840
841		overlayed.commit_transaction().unwrap();
842
843		check_offchain_content(&overlayed, 0, vec![(key.clone(), Some(vec![1, 2, 3]))]);
844
845		overlayed.start_transaction();
846
847		overlayed.set_offchain_storage(key.as_slice(), Some(&[][..]));
848		check_offchain_content(&overlayed, 1, vec![(key.clone(), Some(vec![]))]);
849
850		overlayed.set_offchain_storage(key.as_slice(), None);
851		check_offchain_content(&overlayed, 1, vec![(key.clone(), None)]);
852
853		overlayed.rollback_transaction().unwrap();
854
855		check_offchain_content(&overlayed, 0, vec![(key.clone(), Some(vec![1, 2, 3]))]);
856
857		overlayed.set_offchain_storage(key.as_slice(), None);
858		check_offchain_content(&overlayed, 0, vec![(key.clone(), None)]);
859	}
860
861
862	#[test]
863	fn overlayed_storage_root_works() {
864		let initial: BTreeMap<_, _> = vec![
865			(b"doe".to_vec(), b"reindeer".to_vec()),
866			(b"dog".to_vec(), b"puppyXXX".to_vec()),
867			(b"dogglesworth".to_vec(), b"catXXX".to_vec()),
868			(b"doug".to_vec(), b"notadog".to_vec()),
869		].into_iter().collect();
870		let backend = InMemoryBackend::<Blake2Hasher>::from(initial);
871		let mut overlay = OverlayedChanges::default();
872		overlay.set_collect_extrinsics(false);
873
874		overlay.start_transaction();
875		overlay.set_storage(b"dog".to_vec(), Some(b"puppy".to_vec()));
876		overlay.set_storage(b"dogglesworth".to_vec(), Some(b"catYYY".to_vec()));
877		overlay.set_storage(b"doug".to_vec(), Some(vec![]));
878		overlay.commit_transaction().unwrap();
879
880		overlay.start_transaction();
881		overlay.set_storage(b"dogglesworth".to_vec(), Some(b"cat".to_vec()));
882		overlay.set_storage(b"doug".to_vec(), None);
883
884		let mut cache = StorageTransactionCache::default();
885		let mut ext = Ext::new(
886			&mut overlay,
887			&mut cache,
888			&backend,
889			crate::changes_trie::disabled_state::<_, u64>(),
890			None,
891		);
892		const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa");
893
894		assert_eq!(&ext.storage_root()[..], &ROOT);
895	}
896
897	#[test]
898	fn extrinsic_changes_are_collected() {
899		let mut overlay = OverlayedChanges::default();
900		overlay.set_collect_extrinsics(true);
901
902		overlay.start_transaction();
903
904		overlay.set_storage(vec![100], Some(vec![101]));
905
906		overlay.set_extrinsic_index(0);
907		overlay.set_storage(vec![1], Some(vec![2]));
908
909		overlay.set_extrinsic_index(1);
910		overlay.set_storage(vec![3], Some(vec![4]));
911
912		overlay.set_extrinsic_index(2);
913		overlay.set_storage(vec![1], Some(vec![6]));
914
915		assert_extrinsics(&overlay.top, vec![1], vec![0, 2]);
916		assert_extrinsics(&overlay.top, vec![3], vec![1]);
917		assert_extrinsics(&overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
918
919		overlay.start_transaction();
920
921		overlay.set_extrinsic_index(3);
922		overlay.set_storage(vec![3], Some(vec![7]));
923
924		overlay.set_extrinsic_index(4);
925		overlay.set_storage(vec![1], Some(vec![8]));
926
927		assert_extrinsics(&overlay.top, vec![1], vec![0, 2, 4]);
928		assert_extrinsics(&overlay.top, vec![3], vec![1, 3]);
929		assert_extrinsics(&overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
930
931		overlay.rollback_transaction().unwrap();
932
933		assert_extrinsics(&overlay.top, vec![1], vec![0, 2]);
934		assert_extrinsics(&overlay.top, vec![3], vec![1]);
935		assert_extrinsics(&overlay.top, vec![100], vec![NO_EXTRINSIC_INDEX]);
936	}
937
938	#[test]
939	fn next_storage_key_change_works() {
940		let mut overlay = OverlayedChanges::default();
941		overlay.start_transaction();
942		overlay.set_storage(vec![20], Some(vec![20]));
943		overlay.set_storage(vec![30], Some(vec![30]));
944		overlay.set_storage(vec![40], Some(vec![40]));
945		overlay.commit_transaction().unwrap();
946		overlay.set_storage(vec![10], Some(vec![10]));
947		overlay.set_storage(vec![30], None);
948
949		// next_prospective < next_committed
950		let next_to_5 = overlay.next_storage_key_change(&[5]).unwrap();
951		assert_eq!(next_to_5.0.to_vec(), vec![10]);
952		assert_eq!(next_to_5.1.value(), Some(&vec![10]));
953
954		// next_committed < next_prospective
955		let next_to_10 = overlay.next_storage_key_change(&[10]).unwrap();
956		assert_eq!(next_to_10.0.to_vec(), vec![20]);
957		assert_eq!(next_to_10.1.value(), Some(&vec![20]));
958
959		// next_committed == next_prospective
960		let next_to_20 = overlay.next_storage_key_change(&[20]).unwrap();
961		assert_eq!(next_to_20.0.to_vec(), vec![30]);
962		assert_eq!(next_to_20.1.value(), None);
963
964		// next_committed, no next_prospective
965		let next_to_30 = overlay.next_storage_key_change(&[30]).unwrap();
966		assert_eq!(next_to_30.0.to_vec(), vec![40]);
967		assert_eq!(next_to_30.1.value(), Some(&vec![40]));
968
969		overlay.set_storage(vec![50], Some(vec![50]));
970		// next_prospective, no next_committed
971		let next_to_40 = overlay.next_storage_key_change(&[40]).unwrap();
972		assert_eq!(next_to_40.0.to_vec(), vec![50]);
973		assert_eq!(next_to_40.1.value(), Some(&vec![50]));
974	}
975
976	#[test]
977	fn next_child_storage_key_change_works() {
978		let child_info = ChildInfo::new_default(b"Child1");
979		let child_info = &child_info;
980		let child = child_info.storage_key();
981		let mut overlay = OverlayedChanges::default();
982		overlay.start_transaction();
983		overlay.set_child_storage(child_info, vec![20], Some(vec![20]));
984		overlay.set_child_storage(child_info, vec![30], Some(vec![30]));
985		overlay.set_child_storage(child_info, vec![40], Some(vec![40]));
986		overlay.commit_transaction().unwrap();
987		overlay.set_child_storage(child_info, vec![10], Some(vec![10]));
988		overlay.set_child_storage(child_info, vec![30], None);
989
990		// next_prospective < next_committed
991		let next_to_5 = overlay.next_child_storage_key_change(child, &[5]).unwrap();
992		assert_eq!(next_to_5.0.to_vec(), vec![10]);
993		assert_eq!(next_to_5.1.value(), Some(&vec![10]));
994
995		// next_committed < next_prospective
996		let next_to_10 = overlay.next_child_storage_key_change(child, &[10]).unwrap();
997		assert_eq!(next_to_10.0.to_vec(), vec![20]);
998		assert_eq!(next_to_10.1.value(), Some(&vec![20]));
999
1000		// next_committed == next_prospective
1001		let next_to_20 = overlay.next_child_storage_key_change(child, &[20]).unwrap();
1002		assert_eq!(next_to_20.0.to_vec(), vec![30]);
1003		assert_eq!(next_to_20.1.value(), None);
1004
1005		// next_committed, no next_prospective
1006		let next_to_30 = overlay.next_child_storage_key_change(child, &[30]).unwrap();
1007		assert_eq!(next_to_30.0.to_vec(), vec![40]);
1008		assert_eq!(next_to_30.1.value(), Some(&vec![40]));
1009
1010		overlay.set_child_storage(child_info, vec![50], Some(vec![50]));
1011		// next_prospective, no next_committed
1012		let next_to_40 = overlay.next_child_storage_key_change(child, &[40]).unwrap();
1013		assert_eq!(next_to_40.0.to_vec(), vec![50]);
1014		assert_eq!(next_to_40.1.value(), Some(&vec![50]));
1015	}
1016}