referrerpolicy=no-referrer-when-downgrade

sp_storage/
lib.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//! Primitive types for storage related stuff.
19
20#![cfg_attr(not(feature = "std"), no_std)]
21
22extern crate alloc;
23
24#[cfg(feature = "serde")]
25use serde::{Deserialize, Serialize};
26
27use alloc::vec::Vec;
28use codec::{Decode, Encode};
29use core::{
30	fmt::Display,
31	ops::{Deref, DerefMut},
32};
33use ref_cast::RefCast;
34
35/// Storage key.
36#[derive(PartialEq, Eq, Debug, Hash, PartialOrd, Ord, Clone, Encode, Decode)]
37#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
38pub struct StorageKey(
39	#[cfg_attr(feature = "serde", serde(with = "impl_serde::serialize"))] pub Vec<u8>,
40);
41
42impl AsRef<[u8]> for StorageKey {
43	fn as_ref(&self) -> &[u8] {
44		self.0.as_ref()
45	}
46}
47
48/// Storage key with read/write tracking information.
49#[derive(PartialEq, Eq, Ord, PartialOrd, core::hash::Hash, Debug, Clone, Encode, Decode)]
50pub struct TrackedStorageKey {
51	pub key: Vec<u8>,
52	pub reads: u32,
53	pub writes: u32,
54	pub whitelisted: bool,
55	/// If set, this key belongs to a child trie identified by this storage key.
56	pub child_trie_key: Option<Vec<u8>>,
57}
58
59impl TrackedStorageKey {
60	/// Create a default `TrackedStorageKey` for main storage.
61	pub fn new(key: Vec<u8>) -> Self {
62		Self { key, reads: 0, writes: 0, whitelisted: false, child_trie_key: None }
63	}
64
65	/// Create a `TrackedStorageKey` for a child trie.
66	pub fn new_child(child_trie_key: Vec<u8>, key: Vec<u8>) -> Self {
67		Self { key, reads: 0, writes: 0, whitelisted: false, child_trie_key: Some(child_trie_key) }
68	}
69	/// Check if this key has been "read", i.e. it exists in the memory overlay.
70	///
71	/// Can be true if the key has been read, has been written to, or has been
72	/// whitelisted.
73	pub fn has_been_read(&self) -> bool {
74		self.whitelisted || self.reads > 0u32 || self.has_been_written()
75	}
76	/// Check if this key has been "written", i.e. a new value will be committed to the database.
77	///
78	/// Can be true if the key has been written to, or has been whitelisted.
79	pub fn has_been_written(&self) -> bool {
80		self.whitelisted || self.writes > 0u32
81	}
82	/// Add a storage read to this key.
83	pub fn add_read(&mut self) {
84		self.reads += 1;
85	}
86	/// Add a storage write to this key.
87	pub fn add_write(&mut self) {
88		self.writes += 1;
89	}
90	/// Whitelist this key.
91	pub fn whitelist(&mut self) {
92		self.whitelisted = true;
93	}
94}
95
96// Easily convert a key to a `TrackedStorageKey` that has been whitelisted.
97impl From<Vec<u8>> for TrackedStorageKey {
98	fn from(key: Vec<u8>) -> Self {
99		Self { key, reads: 0, writes: 0, whitelisted: true, child_trie_key: None }
100	}
101}
102
103/// Storage key of a child trie, it contains the prefix to the key.
104#[derive(PartialEq, Eq, Debug, Hash, PartialOrd, Ord, Clone)]
105#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
106#[repr(transparent)]
107#[derive(RefCast)]
108pub struct PrefixedStorageKey(
109	#[cfg_attr(feature = "serde", serde(with = "impl_serde::serialize"))] Vec<u8>,
110);
111
112impl Deref for PrefixedStorageKey {
113	type Target = Vec<u8>;
114
115	fn deref(&self) -> &Vec<u8> {
116		&self.0
117	}
118}
119
120impl DerefMut for PrefixedStorageKey {
121	fn deref_mut(&mut self) -> &mut Vec<u8> {
122		&mut self.0
123	}
124}
125
126impl PrefixedStorageKey {
127	/// Create a prefixed storage key from its byte array representation.
128	pub fn new(inner: Vec<u8>) -> Self {
129		PrefixedStorageKey(inner)
130	}
131
132	/// Create a prefixed storage key reference.
133	pub fn new_ref(inner: &Vec<u8>) -> &Self {
134		PrefixedStorageKey::ref_cast(inner)
135	}
136
137	/// Get inner key, this should only be needed when writing into parent trie to avoid an
138	/// allocation.
139	pub fn into_inner(self) -> Vec<u8> {
140		self.0
141	}
142}
143
144/// Storage data associated to a [`StorageKey`].
145#[derive(PartialEq, Eq, Debug, Hash, PartialOrd, Ord, Clone, Encode, Decode, Default)]
146#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
147pub struct StorageData(
148	#[cfg_attr(feature = "serde", serde(with = "impl_serde::serialize"))] pub Vec<u8>,
149);
150
151/// Map of data to use in a storage, it is a collection of
152/// byte key and values.
153pub type StorageMap = alloc::collections::BTreeMap<Vec<u8>, Vec<u8>>;
154
155/// Map of storage children.
156#[cfg(feature = "std")]
157pub type ChildrenMap = std::collections::HashMap<Vec<u8>, StorageChild>;
158
159#[cfg(not(feature = "std"))]
160pub type ChildrenMap = alloc::collections::BTreeMap<Vec<u8>, StorageChild>;
161
162/// Child trie storage data.
163#[derive(Debug, PartialEq, Eq, Clone)]
164pub struct StorageChild {
165	/// Child data for storage.
166	pub data: StorageMap,
167	/// Associated child info for a child
168	/// trie.
169	pub child_info: ChildInfo,
170}
171
172/// Struct containing data needed for a storage.
173#[derive(Default, Debug, Clone)]
174pub struct Storage {
175	/// Top trie storage data.
176	pub top: StorageMap,
177	/// Children trie storage data. Key does not include prefix, only for the `default` trie kind,
178	/// of `ChildType::ParentKeyId` type.
179	pub children_default: ChildrenMap,
180}
181
182/// Storage change set
183#[derive(Debug, PartialEq, Eq, Clone)]
184#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
185#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
186pub struct StorageChangeSet<Hash> {
187	/// Block hash
188	pub block: Hash,
189	/// A list of changes
190	pub changes: Vec<(StorageKey, Option<StorageData>)>,
191}
192
193/// List of all well known keys and prefixes in storage.
194pub mod well_known_keys {
195	/// Wasm code of the runtime.
196	///
197	/// Stored as a raw byte vector. Required by substrate.
198	///
199	/// Encodes to `0x3A636F6465`.
200	pub const CODE: &[u8] = b":code";
201
202	/// New wasm code of the runtime.
203	///
204	/// To be applied in the next block.
205	///
206	/// Stored as a raw byte vector. Required by substrate.
207	pub const PENDING_CODE: &[u8] = b":pending_code";
208
209	/// Number of wasm linear memory pages required for execution of the runtime.
210	///
211	/// The type of this value is encoded `u64`.
212	///
213	/// Encodes to `0x307833413633364636343635`
214	pub const HEAP_PAGES: &[u8] = b":heappages";
215
216	/// Current extrinsic index (u32) is stored under this key.
217	///
218	/// Encodes to `0x3a65787472696e7369635f696e646578`.
219	pub const EXTRINSIC_INDEX: &[u8] = b":extrinsic_index";
220
221	/// Current intra-block entropy (a universally unique `[u8; 32]` value) is stored here.
222	///
223	/// Encodes to `0x3a696e747261626c6f636b5f656e74726f7079`.
224	pub const INTRABLOCK_ENTROPY: &[u8] = b":intrablock_entropy";
225
226	/// Prefix of child storage keys.
227	pub const CHILD_STORAGE_KEY_PREFIX: &[u8] = b":child_storage:";
228
229	/// Prefix of the default child storage keys in the top trie.
230	pub const DEFAULT_CHILD_STORAGE_KEY_PREFIX: &[u8] = b":child_storage:default:";
231
232	/// Whether a key is a default child storage key.
233	///
234	/// This is convenience function which basically checks if the given `key` starts
235	/// with `DEFAULT_CHILD_STORAGE_KEY_PREFIX` and doesn't do anything apart from that.
236	pub fn is_default_child_storage_key(key: &[u8]) -> bool {
237		key.starts_with(DEFAULT_CHILD_STORAGE_KEY_PREFIX)
238	}
239
240	/// Whether a key is a child storage key.
241	///
242	/// This is convenience function which basically checks if the given `key` starts
243	/// with `CHILD_STORAGE_KEY_PREFIX` and doesn't do anything apart from that.
244	pub fn is_child_storage_key(key: &[u8]) -> bool {
245		// Other code might depend on this, so be careful changing this.
246		key.starts_with(CHILD_STORAGE_KEY_PREFIX)
247	}
248
249	/// Returns if the given `key` starts with [`CHILD_STORAGE_KEY_PREFIX`] or collides with it.
250	pub fn starts_with_child_storage_key(key: &[u8]) -> bool {
251		if key.len() > CHILD_STORAGE_KEY_PREFIX.len() {
252			key.starts_with(CHILD_STORAGE_KEY_PREFIX)
253		} else {
254			CHILD_STORAGE_KEY_PREFIX.starts_with(key)
255		}
256	}
257}
258
259/// Threshold size to start using trie value nodes in state.
260pub const TRIE_VALUE_NODE_THRESHOLD: u32 = 33;
261
262/// Information related to a child state.
263#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Encode, Decode, Debug, Clone)]
264pub enum ChildInfo {
265	/// This is the one used by default.
266	ParentKeyId(ChildTrieParentKeyId),
267}
268
269impl ChildInfo {
270	/// Instantiates child information for a default child trie
271	/// of kind `ChildType::ParentKeyId`, using an unprefixed parent
272	/// storage key.
273	pub fn new_default(storage_key: &[u8]) -> Self {
274		let data = storage_key.to_vec();
275		ChildInfo::ParentKeyId(ChildTrieParentKeyId { data })
276	}
277
278	/// Same as `new_default` but with `Vec<u8>` as input.
279	pub fn new_default_from_vec(storage_key: Vec<u8>) -> Self {
280		ChildInfo::ParentKeyId(ChildTrieParentKeyId { data: storage_key })
281	}
282
283	/// Try to update with another instance, return false if both instance
284	/// are not compatible.
285	pub fn try_update(&mut self, other: &ChildInfo) -> bool {
286		match self {
287			ChildInfo::ParentKeyId(child_trie) => child_trie.try_update(other),
288		}
289	}
290
291	/// Returns byte sequence (keyspace) that can be use by underlying db to isolate keys.
292	/// This is a unique id of the child trie. The collision resistance of this value
293	/// depends on the type of child info use. For `ChildInfo::Default` it is and need to be.
294	#[inline]
295	pub fn keyspace(&self) -> &[u8] {
296		match self {
297			ChildInfo::ParentKeyId(..) => self.storage_key(),
298		}
299	}
300
301	/// Returns a reference to the location in the direct parent of
302	/// this trie but without the common prefix for this kind of
303	/// child trie.
304	pub fn storage_key(&self) -> &[u8] {
305		match self {
306			ChildInfo::ParentKeyId(ChildTrieParentKeyId { data }) => &data[..],
307		}
308	}
309
310	/// Return the full location in the direct parent of
311	/// this trie.
312	pub fn prefixed_storage_key(&self) -> PrefixedStorageKey {
313		match self {
314			ChildInfo::ParentKeyId(ChildTrieParentKeyId { data }) => {
315				ChildType::ParentKeyId.new_prefixed_key(data.as_slice())
316			},
317		}
318	}
319
320	/// Returns the full location in the direct parent of
321	/// this trie.
322	pub fn into_prefixed_storage_key(self) -> PrefixedStorageKey {
323		match self {
324			ChildInfo::ParentKeyId(ChildTrieParentKeyId { mut data }) => {
325				ChildType::ParentKeyId.do_prefix_key(&mut data);
326				PrefixedStorageKey(data)
327			},
328		}
329	}
330
331	/// Returns the type for this child info.
332	pub fn child_type(&self) -> ChildType {
333		match self {
334			ChildInfo::ParentKeyId(..) => ChildType::ParentKeyId,
335		}
336	}
337}
338
339/// Type of child.
340/// It does not strictly define different child type, it can also
341/// be related to technical consideration or api variant.
342#[repr(u32)]
343#[derive(Clone, Copy, PartialEq)]
344#[cfg_attr(feature = "std", derive(Debug))]
345pub enum ChildType {
346	/// If runtime module ensures that the child key is a unique id that will
347	/// only be used once, its parent key is used as a child trie unique id.
348	ParentKeyId = 1,
349}
350
351impl ChildType {
352	/// Try to get a child type from its `u32` representation.
353	pub fn new(repr: u32) -> Option<ChildType> {
354		Some(match repr {
355			r if r == ChildType::ParentKeyId as u32 => ChildType::ParentKeyId,
356			_ => return None,
357		})
358	}
359
360	/// Transform a prefixed key into a tuple of the child type
361	/// and the unprefixed representation of the key.
362	pub fn from_prefixed_key<'a>(storage_key: &'a PrefixedStorageKey) -> Option<(Self, &'a [u8])> {
363		let match_type = |storage_key: &'a [u8], child_type: ChildType| {
364			let prefix = child_type.parent_prefix();
365			if storage_key.starts_with(prefix) {
366				Some((child_type, &storage_key[prefix.len()..]))
367			} else {
368				None
369			}
370		};
371		match_type(storage_key, ChildType::ParentKeyId)
372	}
373
374	/// Produce a prefixed key for a given child type.
375	fn new_prefixed_key(&self, key: &[u8]) -> PrefixedStorageKey {
376		let parent_prefix = self.parent_prefix();
377		let mut result = Vec::with_capacity(parent_prefix.len() + key.len());
378		result.extend_from_slice(parent_prefix);
379		result.extend_from_slice(key);
380		PrefixedStorageKey(result)
381	}
382
383	/// Prefixes a vec with the prefix for this child type.
384	fn do_prefix_key(&self, key: &mut Vec<u8>) {
385		let parent_prefix = self.parent_prefix();
386		let key_len = key.len();
387		if !parent_prefix.is_empty() {
388			key.resize(key_len + parent_prefix.len(), 0);
389			key.copy_within(..key_len, parent_prefix.len());
390			key[..parent_prefix.len()].copy_from_slice(parent_prefix);
391		}
392	}
393
394	/// Returns the location reserved for this child trie in their parent trie if there
395	/// is one.
396	pub fn parent_prefix(&self) -> &'static [u8] {
397		match self {
398			&ChildType::ParentKeyId => well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX,
399		}
400	}
401}
402
403/// A child trie of default type.
404///
405/// It uses the same default implementation as the top trie, top trie being a child trie with no
406/// keyspace and no storage key. Its keyspace is the variable (unprefixed) part of its storage key.
407/// It shares its trie nodes backend storage with every other child trie, so its storage key needs
408/// to be a unique id that will be use only once. Those unique id also required to be long enough to
409/// avoid any unique id to be prefixed by an other unique id.
410#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Encode, Decode, Debug, Clone)]
411pub struct ChildTrieParentKeyId {
412	/// Data is the storage key without prefix.
413	data: Vec<u8>,
414}
415
416impl ChildTrieParentKeyId {
417	/// Try to update with another instance, return false if both instance
418	/// are not compatible.
419	fn try_update(&mut self, other: &ChildInfo) -> bool {
420		match other {
421			ChildInfo::ParentKeyId(other) => self.data[..] == other.data[..],
422		}
423	}
424}
425
426/// Different possible state version.
427///
428/// V0 and V1 uses a same trie implementation, but V1 will write external value node in the trie for
429/// value with size at least `TRIE_VALUE_NODE_THRESHOLD`.
430#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
431#[cfg_attr(feature = "std", derive(Encode, Decode))]
432pub enum StateVersion {
433	/// Old state version, no value nodes.
434	V0 = 0,
435	/// New state version can use value nodes.
436	#[default]
437	V1 = 1,
438}
439
440impl Display for StateVersion {
441	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
442		match self {
443			StateVersion::V0 => f.write_str("0"),
444			StateVersion::V1 => f.write_str("1"),
445		}
446	}
447}
448
449impl From<StateVersion> for u8 {
450	fn from(version: StateVersion) -> u8 {
451		version as u8
452	}
453}
454
455impl TryFrom<u8> for StateVersion {
456	type Error = ();
457	fn try_from(val: u8) -> core::result::Result<StateVersion, ()> {
458		match val {
459			0 => Ok(StateVersion::V0),
460			1 => Ok(StateVersion::V1),
461			2 => Ok(StateVersion::V1),
462			_ => Err(()),
463		}
464	}
465}
466
467impl StateVersion {
468	/// If defined, values in state of size bigger or equal
469	/// to this threshold will use a separate trie node.
470	/// Otherwise, value will be inlined in branch or leaf
471	/// node.
472	pub fn state_value_threshold(&self) -> Option<u32> {
473		match self {
474			StateVersion::V0 => None,
475			StateVersion::V1 => Some(TRIE_VALUE_NODE_THRESHOLD),
476		}
477	}
478}
479
480#[cfg(test)]
481mod tests {
482	use super::*;
483
484	#[test]
485	fn test_prefix_default_child_info() {
486		let child_info = ChildInfo::new_default(b"any key");
487		let prefix = child_info.child_type().parent_prefix();
488		assert!(prefix.starts_with(well_known_keys::CHILD_STORAGE_KEY_PREFIX));
489		assert!(prefix.starts_with(well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX));
490	}
491}