1#![cfg_attr(not(feature = "std"), no_std)]
21
22extern crate alloc;
23
24#[cfg(feature = "serde")]
25use serde::{Deserialize, Serialize};
26use sp_debug_derive::RuntimeDebug;
27
28use alloc::vec::Vec;
29use codec::{Decode, Encode};
30use core::{
31 fmt::Display,
32 ops::{Deref, DerefMut},
33};
34use ref_cast::RefCast;
35
36#[derive(PartialEq, Eq, RuntimeDebug)]
38#[cfg_attr(
39 feature = "serde",
40 derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone, Encode, Decode)
41)]
42pub struct StorageKey(
43 #[cfg_attr(feature = "serde", serde(with = "impl_serde::serialize"))] pub Vec<u8>,
44);
45
46impl AsRef<[u8]> for StorageKey {
47 fn as_ref(&self) -> &[u8] {
48 self.0.as_ref()
49 }
50}
51
52#[derive(PartialEq, Eq, Ord, PartialOrd, core::hash::Hash, RuntimeDebug, Clone, Encode, Decode)]
54pub struct TrackedStorageKey {
55 pub key: Vec<u8>,
56 pub reads: u32,
57 pub writes: u32,
58 pub whitelisted: bool,
59}
60
61impl TrackedStorageKey {
62 pub fn new(key: Vec<u8>) -> Self {
64 Self { key, reads: 0, writes: 0, whitelisted: false }
65 }
66 pub fn has_been_read(&self) -> bool {
71 self.whitelisted || self.reads > 0u32 || self.has_been_written()
72 }
73 pub fn has_been_written(&self) -> bool {
77 self.whitelisted || self.writes > 0u32
78 }
79 pub fn add_read(&mut self) {
81 self.reads += 1;
82 }
83 pub fn add_write(&mut self) {
85 self.writes += 1;
86 }
87 pub fn whitelist(&mut self) {
89 self.whitelisted = true;
90 }
91}
92
93impl From<Vec<u8>> for TrackedStorageKey {
95 fn from(key: Vec<u8>) -> Self {
96 Self { key, reads: 0, writes: 0, whitelisted: true }
97 }
98}
99
100#[derive(PartialEq, Eq, RuntimeDebug)]
102#[cfg_attr(feature = "serde", derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone))]
103#[repr(transparent)]
104#[derive(RefCast)]
105pub struct PrefixedStorageKey(
106 #[cfg_attr(feature = "serde", serde(with = "impl_serde::serialize"))] Vec<u8>,
107);
108
109impl Deref for PrefixedStorageKey {
110 type Target = Vec<u8>;
111
112 fn deref(&self) -> &Vec<u8> {
113 &self.0
114 }
115}
116
117impl DerefMut for PrefixedStorageKey {
118 fn deref_mut(&mut self) -> &mut Vec<u8> {
119 &mut self.0
120 }
121}
122
123impl PrefixedStorageKey {
124 pub fn new(inner: Vec<u8>) -> Self {
126 PrefixedStorageKey(inner)
127 }
128
129 pub fn new_ref(inner: &Vec<u8>) -> &Self {
131 PrefixedStorageKey::ref_cast(inner)
132 }
133
134 pub fn into_inner(self) -> Vec<u8> {
137 self.0
138 }
139}
140
141#[derive(PartialEq, Eq, RuntimeDebug)]
143#[cfg_attr(
144 feature = "serde",
145 derive(Serialize, Deserialize, Hash, PartialOrd, Ord, Clone, Encode, Decode, Default)
146)]
147pub struct StorageData(
148 #[cfg_attr(feature = "serde", serde(with = "impl_serde::serialize"))] pub Vec<u8>,
149);
150
151#[cfg(feature = "std")]
154pub type StorageMap = std::collections::BTreeMap<Vec<u8>, Vec<u8>>;
155
156#[cfg(feature = "std")]
158#[derive(Debug, PartialEq, Eq, Clone)]
159pub struct StorageChild {
160 pub data: StorageMap,
162 pub child_info: ChildInfo,
165}
166
167#[cfg(feature = "std")]
169#[derive(Default, Debug, Clone)]
170pub struct Storage {
171 pub top: StorageMap,
173 pub children_default: std::collections::HashMap<Vec<u8>, StorageChild>,
176}
177
178#[derive(RuntimeDebug)]
180#[cfg_attr(feature = "serde", derive(Serialize, Deserialize, PartialEq, Eq, Clone))]
181#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
182pub struct StorageChangeSet<Hash> {
183 pub block: Hash,
185 pub changes: Vec<(StorageKey, Option<StorageData>)>,
187}
188
189pub mod well_known_keys {
191 pub const CODE: &[u8] = b":code";
195
196 pub const HEAP_PAGES: &[u8] = b":heappages";
200
201 pub const EXTRINSIC_INDEX: &[u8] = b":extrinsic_index";
205
206 pub const INTRABLOCK_ENTROPY: &[u8] = b":intrablock_entropy";
210
211 pub const CHILD_STORAGE_KEY_PREFIX: &[u8] = b":child_storage:";
213
214 pub const DEFAULT_CHILD_STORAGE_KEY_PREFIX: &[u8] = b":child_storage:default:";
216
217 pub fn is_default_child_storage_key(key: &[u8]) -> bool {
222 key.starts_with(DEFAULT_CHILD_STORAGE_KEY_PREFIX)
223 }
224
225 pub fn is_child_storage_key(key: &[u8]) -> bool {
230 key.starts_with(CHILD_STORAGE_KEY_PREFIX)
232 }
233
234 pub fn starts_with_child_storage_key(key: &[u8]) -> bool {
236 if key.len() > CHILD_STORAGE_KEY_PREFIX.len() {
237 key.starts_with(CHILD_STORAGE_KEY_PREFIX)
238 } else {
239 CHILD_STORAGE_KEY_PREFIX.starts_with(key)
240 }
241 }
242}
243
244pub const TRIE_VALUE_NODE_THRESHOLD: u32 = 33;
246
247#[derive(Debug, Clone)]
249#[cfg_attr(feature = "serde", derive(PartialEq, Eq, Hash, PartialOrd, Ord, Encode, Decode))]
250pub enum ChildInfo {
251 ParentKeyId(ChildTrieParentKeyId),
253}
254
255impl ChildInfo {
256 pub fn new_default(storage_key: &[u8]) -> Self {
260 let data = storage_key.to_vec();
261 ChildInfo::ParentKeyId(ChildTrieParentKeyId { data })
262 }
263
264 pub fn new_default_from_vec(storage_key: Vec<u8>) -> Self {
266 ChildInfo::ParentKeyId(ChildTrieParentKeyId { data: storage_key })
267 }
268
269 pub fn try_update(&mut self, other: &ChildInfo) -> bool {
272 match self {
273 ChildInfo::ParentKeyId(child_trie) => child_trie.try_update(other),
274 }
275 }
276
277 #[inline]
281 pub fn keyspace(&self) -> &[u8] {
282 match self {
283 ChildInfo::ParentKeyId(..) => self.storage_key(),
284 }
285 }
286
287 pub fn storage_key(&self) -> &[u8] {
291 match self {
292 ChildInfo::ParentKeyId(ChildTrieParentKeyId { data }) => &data[..],
293 }
294 }
295
296 pub fn prefixed_storage_key(&self) -> PrefixedStorageKey {
299 match self {
300 ChildInfo::ParentKeyId(ChildTrieParentKeyId { data }) =>
301 ChildType::ParentKeyId.new_prefixed_key(data.as_slice()),
302 }
303 }
304
305 pub fn into_prefixed_storage_key(self) -> PrefixedStorageKey {
308 match self {
309 ChildInfo::ParentKeyId(ChildTrieParentKeyId { mut data }) => {
310 ChildType::ParentKeyId.do_prefix_key(&mut data);
311 PrefixedStorageKey(data)
312 },
313 }
314 }
315
316 pub fn child_type(&self) -> ChildType {
318 match self {
319 ChildInfo::ParentKeyId(..) => ChildType::ParentKeyId,
320 }
321 }
322}
323
324#[repr(u32)]
328#[derive(Clone, Copy, PartialEq)]
329#[cfg_attr(feature = "std", derive(Debug))]
330pub enum ChildType {
331 ParentKeyId = 1,
334}
335
336impl ChildType {
337 pub fn new(repr: u32) -> Option<ChildType> {
339 Some(match repr {
340 r if r == ChildType::ParentKeyId as u32 => ChildType::ParentKeyId,
341 _ => return None,
342 })
343 }
344
345 pub fn from_prefixed_key<'a>(storage_key: &'a PrefixedStorageKey) -> Option<(Self, &'a [u8])> {
348 let match_type = |storage_key: &'a [u8], child_type: ChildType| {
349 let prefix = child_type.parent_prefix();
350 if storage_key.starts_with(prefix) {
351 Some((child_type, &storage_key[prefix.len()..]))
352 } else {
353 None
354 }
355 };
356 match_type(storage_key, ChildType::ParentKeyId)
357 }
358
359 fn new_prefixed_key(&self, key: &[u8]) -> PrefixedStorageKey {
361 let parent_prefix = self.parent_prefix();
362 let mut result = Vec::with_capacity(parent_prefix.len() + key.len());
363 result.extend_from_slice(parent_prefix);
364 result.extend_from_slice(key);
365 PrefixedStorageKey(result)
366 }
367
368 fn do_prefix_key(&self, key: &mut Vec<u8>) {
370 let parent_prefix = self.parent_prefix();
371 let key_len = key.len();
372 if !parent_prefix.is_empty() {
373 key.resize(key_len + parent_prefix.len(), 0);
374 key.copy_within(..key_len, parent_prefix.len());
375 key[..parent_prefix.len()].copy_from_slice(parent_prefix);
376 }
377 }
378
379 pub fn parent_prefix(&self) -> &'static [u8] {
382 match self {
383 &ChildType::ParentKeyId => well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX,
384 }
385 }
386}
387
388#[derive(Debug, Clone)]
396#[cfg_attr(feature = "serde", derive(PartialEq, Eq, Hash, PartialOrd, Ord, Encode, Decode))]
397pub struct ChildTrieParentKeyId {
398 data: Vec<u8>,
400}
401
402impl ChildTrieParentKeyId {
403 fn try_update(&mut self, other: &ChildInfo) -> bool {
406 match other {
407 ChildInfo::ParentKeyId(other) => self.data[..] == other.data[..],
408 }
409 }
410}
411
412#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
417#[cfg_attr(feature = "std", derive(Encode, Decode))]
418pub enum StateVersion {
419 V0 = 0,
421 #[default]
423 V1 = 1,
424}
425
426impl Display for StateVersion {
427 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
428 match self {
429 StateVersion::V0 => f.write_str("0"),
430 StateVersion::V1 => f.write_str("1"),
431 }
432 }
433}
434
435impl From<StateVersion> for u8 {
436 fn from(version: StateVersion) -> u8 {
437 version as u8
438 }
439}
440
441impl TryFrom<u8> for StateVersion {
442 type Error = ();
443 fn try_from(val: u8) -> core::result::Result<StateVersion, ()> {
444 match val {
445 0 => Ok(StateVersion::V0),
446 1 => Ok(StateVersion::V1),
447 2 => Ok(StateVersion::V1),
448 _ => Err(()),
449 }
450 }
451}
452
453impl StateVersion {
454 pub fn state_value_threshold(&self) -> Option<u32> {
459 match self {
460 StateVersion::V0 => None,
461 StateVersion::V1 => Some(TRIE_VALUE_NODE_THRESHOLD),
462 }
463 }
464}
465
466#[cfg(test)]
467mod tests {
468 use super::*;
469
470 #[test]
471 fn test_prefix_default_child_info() {
472 let child_info = ChildInfo::new_default(b"any key");
473 let prefix = child_info.child_type().parent_prefix();
474 assert!(prefix.starts_with(well_known_keys::CHILD_STORAGE_KEY_PREFIX));
475 assert!(prefix.starts_with(well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX));
476 }
477}