sp_state_machine/
ext.rs

1// This file is part of Substrate.
2
3// Copyright (C) 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//! Concrete externalities implementation.
19
20#[cfg(feature = "std")]
21use crate::overlayed_changes::OverlayedExtensions;
22use crate::{
23	backend::Backend, IndexOperation, IterArgs, OverlayedChanges, StorageKey, StorageValue,
24};
25use codec::{Compact, CompactLen, Decode, Encode};
26use hash_db::Hasher;
27#[cfg(feature = "std")]
28use sp_core::hexdisplay::HexDisplay;
29use sp_core::storage::{
30	well_known_keys::is_child_storage_key, ChildInfo, StateVersion, TrackedStorageKey,
31};
32#[cfg(feature = "std")]
33use sp_externalities::TransactionType;
34use sp_externalities::{Extension, ExtensionStore, Externalities, MultiRemovalResults};
35
36use crate::{trace, warn};
37use alloc::{boxed::Box, vec::Vec};
38use core::{
39	any::{Any, TypeId},
40	cmp::Ordering,
41};
42
43const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime";
44const BENCHMARKING_FN: &str = "\
45	This is a special fn only for benchmarking where a database commit happens from the runtime.
46	For that reason client started transactions before calling into runtime are not allowed.
47	Without client transactions the loop condition guarantees the success of the tx close.";
48
49#[cfg(feature = "std")]
50fn guard() -> sp_panic_handler::AbortGuard {
51	sp_panic_handler::AbortGuard::force_abort()
52}
53
54#[cfg(not(feature = "std"))]
55fn guard() -> () {
56	()
57}
58
59/// Wraps a read-only backend, call executor, and current overlayed changes.
60pub struct Ext<'a, H, B>
61where
62	H: Hasher,
63	B: 'a + Backend<H>,
64{
65	/// The overlayed changes to write to.
66	overlay: &'a mut OverlayedChanges<H>,
67	/// The storage backend to read from.
68	backend: &'a B,
69	/// Pseudo-unique id used for tracing.
70	pub id: u16,
71	/// Extensions registered with this instance.
72	#[cfg(feature = "std")]
73	extensions: Option<OverlayedExtensions<'a>>,
74}
75
76impl<'a, H, B> Ext<'a, H, B>
77where
78	H: Hasher,
79	B: Backend<H>,
80{
81	/// Create a new `Ext`.
82	#[cfg(not(feature = "std"))]
83	pub fn new(overlay: &'a mut OverlayedChanges<H>, backend: &'a B) -> Self {
84		Ext { overlay, backend, id: 0 }
85	}
86
87	/// Create a new `Ext` from overlayed changes and read-only backend
88	#[cfg(feature = "std")]
89	pub fn new(
90		overlay: &'a mut OverlayedChanges<H>,
91		backend: &'a B,
92		extensions: Option<&'a mut sp_externalities::Extensions>,
93	) -> Self {
94		Self {
95			overlay,
96			backend,
97			id: rand::random(),
98			extensions: extensions.map(OverlayedExtensions::new),
99		}
100	}
101}
102
103#[cfg(test)]
104impl<'a, H, B> Ext<'a, H, B>
105where
106	H: Hasher,
107	H::Out: Ord + 'static,
108	B: 'a + Backend<H>,
109{
110	/// Return all storage pairs from the backend and overlay combined.
111	pub fn storage_pairs(&mut self) -> Vec<(StorageKey, StorageValue)> {
112		use std::collections::HashMap;
113
114		self.backend
115			.pairs(Default::default())
116			.expect("never fails in tests; qed.")
117			.map(|key_value| key_value.expect("never fails in tests; qed."))
118			.map(|(k, v)| (k, Some(v)))
119			.chain(self.overlay.changes_mut().map(|(k, v)| (k.clone(), v.value().cloned())))
120			.collect::<HashMap<_, _>>()
121			.into_iter()
122			.filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val)))
123			.collect()
124	}
125}
126
127impl<'a, H, B> Externalities for Ext<'a, H, B>
128where
129	H: Hasher,
130	H::Out: Ord + 'static + codec::Codec,
131	B: Backend<H>,
132{
133	fn set_offchain_storage(&mut self, key: &[u8], value: Option<&[u8]>) {
134		self.overlay.set_offchain_storage(key, value)
135	}
136
137	fn storage(&mut self, key: &[u8]) -> Option<StorageValue> {
138		let _guard = guard();
139		let result = self
140			.overlay
141			.storage(key)
142			.map(|x| x.map(|x| x.to_vec()))
143			.unwrap_or_else(|| self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL));
144
145		// NOTE: be careful about touching the key names – used outside substrate!
146		trace!(
147			target: "state",
148			method = "Get",
149			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
150			key = %HexDisplay::from(&key),
151			result = ?result.as_ref().map(HexDisplay::from),
152			result_encoded = %HexDisplay::from(
153				&result
154					.as_ref()
155					.map(|v| EncodeOpaqueValue(v.clone()))
156					.encode()
157			),
158		);
159
160		result
161	}
162
163	fn storage_hash(&mut self, key: &[u8]) -> Option<Vec<u8>> {
164		let _guard = guard();
165		let result = self
166			.overlay
167			.storage(key)
168			.map(|x| x.map(|x| H::hash(x)))
169			.unwrap_or_else(|| self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL));
170
171		trace!(
172			target: "state",
173			method = "Hash",
174			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
175			key = %HexDisplay::from(&key),
176			?result,
177		);
178		result.map(|r| r.encode())
179	}
180
181	fn child_storage(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<StorageValue> {
182		let _guard = guard();
183		let result = self
184			.overlay
185			.child_storage(child_info, key)
186			.map(|x| x.map(|x| x.to_vec()))
187			.unwrap_or_else(|| {
188				self.backend.child_storage(child_info, key).expect(EXT_NOT_ALLOWED_TO_FAIL)
189			});
190
191		trace!(
192			target: "state",
193			method = "ChildGet",
194			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
195			child_info = %HexDisplay::from(&child_info.storage_key()),
196			key = %HexDisplay::from(&key),
197			result = ?result.as_ref().map(HexDisplay::from)
198		);
199
200		result
201	}
202
203	fn child_storage_hash(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<Vec<u8>> {
204		let _guard = guard();
205		let result = self
206			.overlay
207			.child_storage(child_info, key)
208			.map(|x| x.map(|x| H::hash(x)))
209			.unwrap_or_else(|| {
210				self.backend.child_storage_hash(child_info, key).expect(EXT_NOT_ALLOWED_TO_FAIL)
211			});
212
213		trace!(
214			target: "state",
215			method = "ChildHash",
216			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
217			child_info = %HexDisplay::from(&child_info.storage_key()),
218			key = %HexDisplay::from(&key),
219			?result,
220		);
221
222		result.map(|r| r.encode())
223	}
224
225	fn exists_storage(&mut self, key: &[u8]) -> bool {
226		let _guard = guard();
227		let result = match self.overlay.storage(key) {
228			Some(x) => x.is_some(),
229			_ => self.backend.exists_storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL),
230		};
231
232		trace!(
233			target: "state",
234			method = "Exists",
235			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
236			key = %HexDisplay::from(&key),
237			%result,
238		);
239
240		result
241	}
242
243	fn exists_child_storage(&mut self, child_info: &ChildInfo, key: &[u8]) -> bool {
244		let _guard = guard();
245
246		let result = match self.overlay.child_storage(child_info, key) {
247			Some(x) => x.is_some(),
248			_ => self
249				.backend
250				.exists_child_storage(child_info, key)
251				.expect(EXT_NOT_ALLOWED_TO_FAIL),
252		};
253
254		trace!(
255			target: "state",
256			method = "ChildExists",
257			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
258			child_info = %HexDisplay::from(&child_info.storage_key()),
259			key = %HexDisplay::from(&key),
260			%result,
261		);
262		result
263	}
264
265	fn next_storage_key(&mut self, key: &[u8]) -> Option<StorageKey> {
266		let mut next_backend_key =
267			self.backend.next_storage_key(key).expect(EXT_NOT_ALLOWED_TO_FAIL);
268		let mut overlay_changes = self.overlay.iter_after(key).peekable();
269
270		match (&next_backend_key, overlay_changes.peek()) {
271			(_, None) => next_backend_key,
272			(Some(_), Some(_)) => {
273				for overlay_key in overlay_changes {
274					let cmp = next_backend_key.as_deref().map(|v| v.cmp(overlay_key.0));
275
276					// If `backend_key` is less than the `overlay_key`, we found out next key.
277					if cmp == Some(Ordering::Less) {
278						return next_backend_key
279					} else if overlay_key.1.value().is_some() {
280						// If there exists a value for the `overlay_key` in the overlay
281						// (aka the key is still valid), it means we have found our next key.
282						return Some(overlay_key.0.to_vec())
283					} else if cmp == Some(Ordering::Equal) {
284						// If the `backend_key` and `overlay_key` are equal, it means that we need
285						// to search for the next backend key, because the overlay has overwritten
286						// this key.
287						next_backend_key = self
288							.backend
289							.next_storage_key(overlay_key.0)
290							.expect(EXT_NOT_ALLOWED_TO_FAIL);
291					}
292				}
293
294				next_backend_key
295			},
296			(None, Some(_)) => {
297				// Find the next overlay key that has a value attached.
298				overlay_changes.find_map(|k| k.1.value().as_ref().map(|_| k.0.to_vec()))
299			},
300		}
301	}
302
303	fn next_child_storage_key(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<StorageKey> {
304		let mut next_backend_key = self
305			.backend
306			.next_child_storage_key(child_info, key)
307			.expect(EXT_NOT_ALLOWED_TO_FAIL);
308		let mut overlay_changes =
309			self.overlay.child_iter_after(child_info.storage_key(), key).peekable();
310
311		match (&next_backend_key, overlay_changes.peek()) {
312			(_, None) => next_backend_key,
313			(Some(_), Some(_)) => {
314				for overlay_key in overlay_changes {
315					let cmp = next_backend_key.as_deref().map(|v| v.cmp(overlay_key.0));
316
317					// If `backend_key` is less than the `overlay_key`, we found out next key.
318					if cmp == Some(Ordering::Less) {
319						return next_backend_key
320					} else if overlay_key.1.value().is_some() {
321						// If there exists a value for the `overlay_key` in the overlay
322						// (aka the key is still valid), it means we have found our next key.
323						return Some(overlay_key.0.to_vec())
324					} else if cmp == Some(Ordering::Equal) {
325						// If the `backend_key` and `overlay_key` are equal, it means that we need
326						// to search for the next backend key, because the overlay has overwritten
327						// this key.
328						next_backend_key = self
329							.backend
330							.next_child_storage_key(child_info, overlay_key.0)
331							.expect(EXT_NOT_ALLOWED_TO_FAIL);
332					}
333				}
334
335				next_backend_key
336			},
337			(None, Some(_)) => {
338				// Find the next overlay key that has a value attached.
339				overlay_changes.find_map(|k| k.1.value().as_ref().map(|_| k.0.to_vec()))
340			},
341		}
342	}
343
344	fn place_storage(&mut self, key: StorageKey, value: Option<StorageValue>) {
345		let _guard = guard();
346		if is_child_storage_key(&key) {
347			warn!(target: "trie", "Refuse to directly set child storage key");
348			return
349		}
350
351		// NOTE: be careful about touching the key names – used outside substrate!
352		trace!(
353			target: "state",
354			method = "Put",
355			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
356			key = %HexDisplay::from(&key),
357			value = ?value.as_ref().map(HexDisplay::from),
358			value_encoded = %HexDisplay::from(
359				&value
360					.as_ref()
361					.map(|v| EncodeOpaqueValue(v.clone()))
362					.encode()
363			),
364		);
365
366		self.overlay.set_storage(key, value);
367	}
368
369	fn place_child_storage(
370		&mut self,
371		child_info: &ChildInfo,
372		key: StorageKey,
373		value: Option<StorageValue>,
374	) {
375		trace!(
376			target: "state",
377			method = "ChildPut",
378			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
379			child_info = %HexDisplay::from(&child_info.storage_key()),
380			key = %HexDisplay::from(&key),
381			value = ?value.as_ref().map(HexDisplay::from),
382		);
383		let _guard = guard();
384
385		self.overlay.set_child_storage(child_info, key, value);
386	}
387
388	fn kill_child_storage(
389		&mut self,
390		child_info: &ChildInfo,
391		maybe_limit: Option<u32>,
392		maybe_cursor: Option<&[u8]>,
393	) -> MultiRemovalResults {
394		trace!(
395			target: "state",
396			method = "ChildKill",
397			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
398			child_info = %HexDisplay::from(&child_info.storage_key()),
399		);
400		let _guard = guard();
401		let overlay = self.overlay.clear_child_storage(child_info);
402		let (maybe_cursor, backend, loops) =
403			self.limit_remove_from_backend(Some(child_info), None, maybe_limit, maybe_cursor);
404		MultiRemovalResults { maybe_cursor, backend, unique: overlay + backend, loops }
405	}
406
407	fn clear_prefix(
408		&mut self,
409		prefix: &[u8],
410		maybe_limit: Option<u32>,
411		maybe_cursor: Option<&[u8]>,
412	) -> MultiRemovalResults {
413		trace!(
414			target: "state",
415			method = "ClearPrefix",
416			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
417			prefix = %HexDisplay::from(&prefix),
418		);
419		let _guard = guard();
420
421		if sp_core::storage::well_known_keys::starts_with_child_storage_key(prefix) {
422			warn!(
423				target: "trie",
424				"Refuse to directly clear prefix that is part or contains of child storage key",
425			);
426			return MultiRemovalResults { maybe_cursor: None, backend: 0, unique: 0, loops: 0 }
427		}
428
429		let overlay = self.overlay.clear_prefix(prefix);
430		let (maybe_cursor, backend, loops) =
431			self.limit_remove_from_backend(None, Some(prefix), maybe_limit, maybe_cursor);
432		MultiRemovalResults { maybe_cursor, backend, unique: overlay + backend, loops }
433	}
434
435	fn clear_child_prefix(
436		&mut self,
437		child_info: &ChildInfo,
438		prefix: &[u8],
439		maybe_limit: Option<u32>,
440		maybe_cursor: Option<&[u8]>,
441	) -> MultiRemovalResults {
442		trace!(
443			target: "state",
444			method = "ChildClearPrefix",
445			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
446			child_info = %HexDisplay::from(&child_info.storage_key()),
447			prefix = %HexDisplay::from(&prefix),
448		);
449		let _guard = guard();
450
451		let overlay = self.overlay.clear_child_prefix(child_info, prefix);
452		let (maybe_cursor, backend, loops) = self.limit_remove_from_backend(
453			Some(child_info),
454			Some(prefix),
455			maybe_limit,
456			maybe_cursor,
457		);
458		MultiRemovalResults { maybe_cursor, backend, unique: overlay + backend, loops }
459	}
460
461	fn storage_append(&mut self, key: Vec<u8>, value: Vec<u8>) {
462		trace!(
463			target: "state",
464			method = "Append",
465			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
466			key = %HexDisplay::from(&key),
467			value = %HexDisplay::from(&value),
468		);
469
470		let _guard = guard();
471
472		let backend = &mut self.backend;
473		self.overlay.append_storage(key.clone(), value, || {
474			backend.storage(&key).expect(EXT_NOT_ALLOWED_TO_FAIL).unwrap_or_default()
475		});
476	}
477
478	fn storage_root(&mut self, state_version: StateVersion) -> Vec<u8> {
479		let _guard = guard();
480
481		let (root, _cached) = self.overlay.storage_root(self.backend, state_version);
482
483		trace!(
484			target: "state",
485			method = "StorageRoot",
486			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
487			storage_root = %HexDisplay::from(&root.as_ref()),
488			cached = %_cached,
489		);
490
491		root.encode()
492	}
493
494	fn child_storage_root(
495		&mut self,
496		child_info: &ChildInfo,
497		state_version: StateVersion,
498	) -> Vec<u8> {
499		let _guard = guard();
500
501		let (root, _cached) = self
502			.overlay
503			.child_storage_root(child_info, self.backend, state_version)
504			.expect(EXT_NOT_ALLOWED_TO_FAIL);
505
506		trace!(
507			target: "state",
508			method = "ChildStorageRoot",
509			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
510			child_info = %HexDisplay::from(&child_info.storage_key()),
511			storage_root = %HexDisplay::from(&root.as_ref()),
512			cached = %_cached,
513		);
514
515		root.encode()
516	}
517
518	fn storage_index_transaction(&mut self, index: u32, hash: &[u8], size: u32) {
519		trace!(
520			target: "state",
521			method = "IndexTransaction",
522			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
523			%index,
524			tx_hash = %HexDisplay::from(&hash),
525			%size,
526		);
527
528		self.overlay.add_transaction_index(IndexOperation::Insert {
529			extrinsic: index,
530			hash: hash.to_vec(),
531			size,
532		});
533	}
534
535	/// Renew existing piece of data storage.
536	fn storage_renew_transaction_index(&mut self, index: u32, hash: &[u8]) {
537		trace!(
538			target: "state",
539			method = "RenewTransactionIndex",
540			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
541			%index,
542			tx_hash = %HexDisplay::from(&hash),
543		);
544
545		self.overlay
546			.add_transaction_index(IndexOperation::Renew { extrinsic: index, hash: hash.to_vec() });
547	}
548
549	fn storage_start_transaction(&mut self) {
550		self.overlay.start_transaction();
551
552		#[cfg(feature = "std")]
553		if let Some(exts) = self.extensions.as_mut() {
554			exts.start_transaction(TransactionType::Runtime);
555		}
556	}
557
558	fn storage_rollback_transaction(&mut self) -> Result<(), ()> {
559		self.overlay.rollback_transaction().map_err(|_| ())?;
560
561		#[cfg(feature = "std")]
562		if let Some(exts) = self.extensions.as_mut() {
563			exts.rollback_transaction(TransactionType::Runtime);
564		}
565
566		Ok(())
567	}
568
569	fn storage_commit_transaction(&mut self) -> Result<(), ()> {
570		self.overlay.commit_transaction().map_err(|_| ())?;
571
572		#[cfg(feature = "std")]
573		if let Some(exts) = self.extensions.as_mut() {
574			exts.commit_transaction(TransactionType::Runtime);
575		}
576
577		Ok(())
578	}
579
580	fn wipe(&mut self) {
581		for _ in 0..self.overlay.transaction_depth() {
582			self.overlay.rollback_transaction().expect(BENCHMARKING_FN);
583		}
584		self.overlay
585			.drain_storage_changes(self.backend, Default::default())
586			.expect(EXT_NOT_ALLOWED_TO_FAIL);
587		self.backend.wipe().expect(EXT_NOT_ALLOWED_TO_FAIL);
588		self.overlay
589			.enter_runtime()
590			.expect("We have reset the overlay above, so we can not be in the runtime; qed");
591	}
592
593	fn commit(&mut self) {
594		// Bench always use latest state.
595		let state_version = StateVersion::default();
596		for _ in 0..self.overlay.transaction_depth() {
597			self.overlay.commit_transaction().expect(BENCHMARKING_FN);
598		}
599		let changes = self
600			.overlay
601			.drain_storage_changes(self.backend, state_version)
602			.expect(EXT_NOT_ALLOWED_TO_FAIL);
603		self.backend
604			.commit(
605				changes.transaction_storage_root,
606				changes.transaction,
607				changes.main_storage_changes,
608				changes.child_storage_changes,
609			)
610			.expect(EXT_NOT_ALLOWED_TO_FAIL);
611		self.overlay
612			.enter_runtime()
613			.expect("We have reset the overlay above, so we can not be in the runtime; qed");
614	}
615
616	fn read_write_count(&self) -> (u32, u32, u32, u32) {
617		self.backend.read_write_count()
618	}
619
620	fn reset_read_write_count(&mut self) {
621		self.backend.reset_read_write_count()
622	}
623
624	fn get_whitelist(&self) -> Vec<TrackedStorageKey> {
625		self.backend.get_whitelist()
626	}
627
628	fn set_whitelist(&mut self, new: Vec<TrackedStorageKey>) {
629		self.backend.set_whitelist(new)
630	}
631
632	fn proof_size(&self) -> Option<u32> {
633		self.backend.proof_size()
634	}
635
636	fn get_read_and_written_keys(&self) -> Vec<(Vec<u8>, u32, u32, bool)> {
637		self.backend.get_read_and_written_keys()
638	}
639}
640
641impl<'a, H, B> Ext<'a, H, B>
642where
643	H: Hasher,
644	H::Out: Ord + 'static + codec::Codec,
645	B: Backend<H>,
646{
647	fn limit_remove_from_backend(
648		&mut self,
649		child_info: Option<&ChildInfo>,
650		prefix: Option<&[u8]>,
651		maybe_limit: Option<u32>,
652		start_at: Option<&[u8]>,
653	) -> (Option<Vec<u8>>, u32, u32) {
654		let iter = match self.backend.keys(IterArgs {
655			child_info: child_info.cloned(),
656			prefix,
657			start_at,
658			..IterArgs::default()
659		}) {
660			Ok(iter) => iter,
661			Err(error) => {
662				log::debug!(target: "trie", "Error while iterating the storage: {}", error);
663				return (None, 0, 0)
664			},
665		};
666
667		let mut delete_count: u32 = 0;
668		let mut loop_count: u32 = 0;
669		let mut maybe_next_key = None;
670		for key in iter {
671			let key = match key {
672				Ok(key) => key,
673				Err(error) => {
674					log::debug!(target: "trie", "Error while iterating the storage: {}", error);
675					break
676				},
677			};
678
679			if maybe_limit.map_or(false, |limit| loop_count == limit) {
680				maybe_next_key = Some(key);
681				break
682			}
683			let overlay = match child_info {
684				Some(child_info) => self.overlay.child_storage(child_info, &key),
685				None => self.overlay.storage(&key),
686			};
687			if !matches!(overlay, Some(None)) {
688				// not pending deletion from the backend - delete it.
689				if let Some(child_info) = child_info {
690					self.overlay.set_child_storage(child_info, key, None);
691				} else {
692					self.overlay.set_storage(key, None);
693				}
694				delete_count = delete_count.saturating_add(1);
695			}
696			loop_count = loop_count.saturating_add(1);
697		}
698
699		(maybe_next_key, delete_count, loop_count)
700	}
701}
702
703/// Implement `Encode` by forwarding the stored raw vec.
704#[allow(dead_code)]
705struct EncodeOpaqueValue(Vec<u8>);
706
707impl Encode for EncodeOpaqueValue {
708	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
709		f(&self.0)
710	}
711}
712
713/// Auxiliary structure for appending a value to a storage item.
714pub(crate) struct StorageAppend<'a>(&'a mut Vec<u8>);
715
716impl<'a> StorageAppend<'a> {
717	/// Create a new instance using the given `storage` reference.
718	pub fn new(storage: &'a mut Vec<u8>) -> Self {
719		Self(storage)
720	}
721
722	/// Extract the length of the list like data structure.
723	pub fn extract_length(&self) -> Option<u32> {
724		Compact::<u32>::decode(&mut &self.0[..]).map(|c| c.0).ok()
725	}
726
727	/// Replace the length in the encoded data.
728	///
729	/// If `old_length` is `None`, the previous length will be assumed to be `0`.
730	pub fn replace_length(&mut self, old_length: Option<u32>, new_length: u32) {
731		let old_len_encoded_len = old_length.map(|l| Compact::<u32>::compact_len(&l)).unwrap_or(0);
732		let new_len_encoded = Compact::<u32>(new_length).encode();
733		self.0.splice(0..old_len_encoded_len, new_len_encoded);
734	}
735
736	/// Append the given `value` to the storage item.
737	///
738	/// If appending fails, `[value]` is stored in the storage item and we return false.
739	#[cfg(any(test, feature = "fuzzing"))]
740	pub fn append(&mut self, value: Vec<u8>) -> bool {
741		use codec::EncodeAppend;
742		let mut result = true;
743		let value = vec![EncodeOpaqueValue(value)];
744
745		let item = core::mem::take(self.0);
746
747		*self.0 = match Vec::<EncodeOpaqueValue>::append_or_new(item, &value) {
748			Ok(item) => item,
749			Err(_) => {
750				result = false;
751				crate::log_error!(
752					target: "runtime",
753					"Failed to append value, resetting storage item to `[value]`.",
754				);
755				value.encode()
756			},
757		};
758		result
759	}
760
761	/// Append to current buffer, do not touch the prefixed length.
762	pub fn append_raw(&mut self, mut value: Vec<u8>) {
763		self.0.append(&mut value)
764	}
765}
766
767#[cfg(not(feature = "std"))]
768impl<'a, H, B> ExtensionStore for Ext<'a, H, B>
769where
770	H: Hasher,
771	H::Out: Ord + 'static + codec::Codec,
772	B: Backend<H>,
773{
774	fn extension_by_type_id(&mut self, _type_id: TypeId) -> Option<&mut dyn Any> {
775		None
776	}
777
778	fn register_extension_with_type_id(
779		&mut self,
780		_type_id: TypeId,
781		_extension: Box<dyn Extension>,
782	) -> Result<(), sp_externalities::Error> {
783		Err(sp_externalities::Error::ExtensionsAreNotSupported)
784	}
785
786	fn deregister_extension_by_type_id(
787		&mut self,
788		_type_id: TypeId,
789	) -> Result<(), sp_externalities::Error> {
790		Err(sp_externalities::Error::ExtensionsAreNotSupported)
791	}
792}
793
794#[cfg(feature = "std")]
795impl<'a, H, B> ExtensionStore for Ext<'a, H, B>
796where
797	H: Hasher,
798	B: 'a + Backend<H>,
799{
800	fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> {
801		self.extensions.as_mut().and_then(|exts| exts.get_mut(type_id))
802	}
803
804	fn register_extension_with_type_id(
805		&mut self,
806		type_id: TypeId,
807		extension: Box<dyn Extension>,
808	) -> Result<(), sp_externalities::Error> {
809		if let Some(ref mut extensions) = self.extensions {
810			extensions.register(type_id, extension)
811		} else {
812			Err(sp_externalities::Error::ExtensionsAreNotSupported)
813		}
814	}
815
816	fn deregister_extension_by_type_id(
817		&mut self,
818		type_id: TypeId,
819	) -> Result<(), sp_externalities::Error> {
820		if let Some(ref mut extensions) = self.extensions {
821			if extensions.deregister(type_id) {
822				Ok(())
823			} else {
824				Err(sp_externalities::Error::ExtensionIsNotRegistered(type_id))
825			}
826		} else {
827			Err(sp_externalities::Error::ExtensionsAreNotSupported)
828		}
829	}
830}
831
832#[cfg(test)]
833mod tests {
834	use super::*;
835	use crate::InMemoryBackend;
836	use codec::{Decode, Encode};
837	use sp_core::{
838		map,
839		storage::{Storage, StorageChild},
840		Blake2Hasher,
841	};
842
843	type TestBackend = InMemoryBackend<Blake2Hasher>;
844	type TestExt<'a> = Ext<'a, Blake2Hasher, TestBackend>;
845
846	#[test]
847	fn next_storage_key_works() {
848		let mut overlay = OverlayedChanges::default();
849		overlay.set_storage(vec![20], None);
850		overlay.set_storage(vec![30], Some(vec![31]));
851		let backend = (
852			Storage {
853				top: map![
854					vec![10] => vec![10],
855					vec![20] => vec![20],
856					vec![40] => vec![40]
857				],
858				children_default: map![],
859			},
860			StateVersion::default(),
861		)
862			.into();
863
864		let mut ext = TestExt::new(&mut overlay, &backend, None);
865
866		// next_backend < next_overlay
867		assert_eq!(ext.next_storage_key(&[5]), Some(vec![10]));
868
869		// next_backend == next_overlay but next_overlay is a delete
870		assert_eq!(ext.next_storage_key(&[10]), Some(vec![30]));
871
872		// next_overlay < next_backend
873		assert_eq!(ext.next_storage_key(&[20]), Some(vec![30]));
874
875		// next_backend exist but next_overlay doesn't exist
876		assert_eq!(ext.next_storage_key(&[30]), Some(vec![40]));
877
878		drop(ext);
879		overlay.set_storage(vec![50], Some(vec![50]));
880		let mut ext = TestExt::new(&mut overlay, &backend, None);
881
882		// next_overlay exist but next_backend doesn't exist
883		assert_eq!(ext.next_storage_key(&[40]), Some(vec![50]));
884	}
885
886	#[test]
887	fn next_storage_key_works_with_a_lot_empty_values_in_overlay() {
888		let mut overlay = OverlayedChanges::default();
889		overlay.set_storage(vec![20], None);
890		overlay.set_storage(vec![21], None);
891		overlay.set_storage(vec![22], None);
892		overlay.set_storage(vec![23], None);
893		overlay.set_storage(vec![24], None);
894		overlay.set_storage(vec![25], None);
895		overlay.set_storage(vec![26], None);
896		overlay.set_storage(vec![27], None);
897		overlay.set_storage(vec![28], None);
898		overlay.set_storage(vec![29], None);
899		let backend = (
900			Storage {
901				top: map![
902					vec![30] => vec![30]
903				],
904				children_default: map![],
905			},
906			StateVersion::default(),
907		)
908			.into();
909
910		let mut ext = TestExt::new(&mut overlay, &backend, None);
911
912		assert_eq!(ext.next_storage_key(&[5]), Some(vec![30]));
913
914		drop(ext);
915	}
916
917	#[test]
918	fn next_child_storage_key_works() {
919		let child_info = ChildInfo::new_default(b"Child1");
920		let child_info = &child_info;
921
922		let mut overlay = OverlayedChanges::default();
923		overlay.set_child_storage(child_info, vec![20], None);
924		overlay.set_child_storage(child_info, vec![30], Some(vec![31]));
925		let backend = (
926			Storage {
927				top: map![],
928				children_default: map![
929					child_info.storage_key().to_vec() => StorageChild {
930						data: map![
931							vec![10] => vec![10],
932							vec![20] => vec![20],
933							vec![40] => vec![40]
934						],
935						child_info: child_info.to_owned(),
936					}
937				],
938			},
939			StateVersion::default(),
940		)
941			.into();
942
943		let mut ext = TestExt::new(&mut overlay, &backend, None);
944
945		// next_backend < next_overlay
946		assert_eq!(ext.next_child_storage_key(child_info, &[5]), Some(vec![10]));
947
948		// next_backend == next_overlay but next_overlay is a delete
949		assert_eq!(ext.next_child_storage_key(child_info, &[10]), Some(vec![30]));
950
951		// next_overlay < next_backend
952		assert_eq!(ext.next_child_storage_key(child_info, &[20]), Some(vec![30]));
953
954		// next_backend exist but next_overlay doesn't exist
955		assert_eq!(ext.next_child_storage_key(child_info, &[30]), Some(vec![40]));
956
957		drop(ext);
958		overlay.set_child_storage(child_info, vec![50], Some(vec![50]));
959		let mut ext = TestExt::new(&mut overlay, &backend, None);
960
961		// next_overlay exist but next_backend doesn't exist
962		assert_eq!(ext.next_child_storage_key(child_info, &[40]), Some(vec![50]));
963	}
964
965	#[test]
966	fn child_storage_works() {
967		let child_info = ChildInfo::new_default(b"Child1");
968		let child_info = &child_info;
969		let mut overlay = OverlayedChanges::default();
970		overlay.set_child_storage(child_info, vec![20], None);
971		overlay.set_child_storage(child_info, vec![30], Some(vec![31]));
972		let backend = (
973			Storage {
974				top: map![],
975				children_default: map![
976					child_info.storage_key().to_vec() => StorageChild {
977						data: map![
978							vec![10] => vec![10],
979							vec![20] => vec![20],
980							vec![30] => vec![40]
981						],
982						child_info: child_info.to_owned(),
983					}
984				],
985			},
986			StateVersion::default(),
987		)
988			.into();
989
990		let mut ext = TestExt::new(&mut overlay, &backend, None);
991
992		assert_eq!(ext.child_storage(child_info, &[10]), Some(vec![10]));
993		assert_eq!(
994			ext.child_storage_hash(child_info, &[10]),
995			Some(Blake2Hasher::hash(&[10]).as_ref().to_vec()),
996		);
997
998		assert_eq!(ext.child_storage(child_info, &[20]), None);
999		assert_eq!(ext.child_storage_hash(child_info, &[20]), None);
1000
1001		assert_eq!(ext.child_storage(child_info, &[30]), Some(vec![31]));
1002		assert_eq!(
1003			ext.child_storage_hash(child_info, &[30]),
1004			Some(Blake2Hasher::hash(&[31]).as_ref().to_vec()),
1005		);
1006	}
1007
1008	#[test]
1009	fn clear_prefix_cannot_delete_a_child_root() {
1010		let child_info = ChildInfo::new_default(b"Child1");
1011		let child_info = &child_info;
1012		let mut overlay = OverlayedChanges::default();
1013		let backend = (
1014			Storage {
1015				top: map![],
1016				children_default: map![
1017					child_info.storage_key().to_vec() => StorageChild {
1018						data: map![
1019							vec![30] => vec![40]
1020						],
1021						child_info: child_info.to_owned(),
1022					}
1023				],
1024			},
1025			StateVersion::default(),
1026		)
1027			.into();
1028
1029		let ext = TestExt::new(&mut overlay, &backend, None);
1030
1031		use sp_core::storage::well_known_keys;
1032		let mut ext = ext;
1033		let mut not_under_prefix = well_known_keys::CHILD_STORAGE_KEY_PREFIX.to_vec();
1034		not_under_prefix[4] = 88;
1035		not_under_prefix.extend(b"path");
1036		ext.set_storage(not_under_prefix.clone(), vec![10]);
1037
1038		let _ = ext.clear_prefix(&[], None, None);
1039		let _ = ext.clear_prefix(&well_known_keys::CHILD_STORAGE_KEY_PREFIX[..4], None, None);
1040		let mut under_prefix = well_known_keys::CHILD_STORAGE_KEY_PREFIX.to_vec();
1041		under_prefix.extend(b"path");
1042		let _ = ext.clear_prefix(&well_known_keys::CHILD_STORAGE_KEY_PREFIX[..4], None, None);
1043		assert_eq!(ext.child_storage(child_info, &[30]), Some(vec![40]));
1044		assert_eq!(ext.storage(not_under_prefix.as_slice()), Some(vec![10]));
1045		let _ = ext.clear_prefix(&not_under_prefix[..5], None, None);
1046		assert_eq!(ext.storage(not_under_prefix.as_slice()), None);
1047	}
1048
1049	#[test]
1050	fn storage_append_works() {
1051		let mut data = Vec::new();
1052		let mut append = StorageAppend::new(&mut data);
1053		append.append(1u32.encode());
1054		append.append(2u32.encode());
1055		drop(append);
1056
1057		assert_eq!(Vec::<u32>::decode(&mut &data[..]).unwrap(), vec![1, 2]);
1058
1059		// Initialize with some invalid data
1060		let mut data = vec![1];
1061		let mut append = StorageAppend::new(&mut data);
1062		append.append(1u32.encode());
1063		append.append(2u32.encode());
1064		drop(append);
1065
1066		assert_eq!(Vec::<u32>::decode(&mut &data[..]).unwrap(), vec![1, 2]);
1067	}
1068}