frame_decode/methods/
storage_decoder.rs

1// Copyright (C) 2022-2025 Parity Technologies (UK) Ltd. (admin@parity.io)
2// This file is a part of the frame-decode crate.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//         http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::storage_encoder::encode_storage_key_prefix;
17use super::storage_type_info::{StorageHasher, StorageInfo, StorageTypeInfo};
18use crate::methods::storage_type_info::StorageInfoError;
19use crate::utils::{
20    DecodableValues, DecodeErrorTrace, IntoDecodableValues, decode_with_error_tracing,
21};
22use alloc::vec;
23use alloc::vec::Vec;
24use core::ops::Range;
25use scale_type_resolver::TypeResolver;
26
27/// An error returned trying to decode storage bytes.
28#[non_exhaustive]
29#[allow(missing_docs)]
30#[derive(Clone, Debug, thiserror::Error)]
31pub enum StorageKeyDecodeError<TypeId> {
32    #[error("Cannot get storage info: {0}")]
33    CannotGetInfo(StorageInfoError<'static>),
34    #[error(
35        "The hashed storage prefix given does not match the pallet and storage name asked to decode."
36    )]
37    PrefixMismatch,
38    #[error("Not enough bytes left: we need at least {needed} bytes but have {have} bytes")]
39    NotEnoughBytes { needed: usize, have: usize },
40    #[error(
41        "Cannot decode storage key '{ty:?}':\n\n{reason}\n\nDecoded so far:\n\n{decoded_so_far}"
42    )]
43    CannotDecodeKey {
44        ty: TypeId,
45        reason: DecodeErrorTrace,
46        decoded_so_far: StorageKey<TypeId>,
47    },
48}
49
50impl<TypeId> StorageKeyDecodeError<TypeId> {
51    /// Map the storage key error type IDs to something else.
52    pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKeyDecodeError<NewTypeId>
53    where
54        F: FnMut(TypeId) -> NewTypeId,
55    {
56        match self {
57            StorageKeyDecodeError::CannotGetInfo(e) => StorageKeyDecodeError::CannotGetInfo(e),
58            StorageKeyDecodeError::PrefixMismatch => StorageKeyDecodeError::PrefixMismatch,
59            StorageKeyDecodeError::NotEnoughBytes { needed, have } => {
60                StorageKeyDecodeError::NotEnoughBytes { needed, have }
61            }
62            StorageKeyDecodeError::CannotDecodeKey {
63                ty,
64                reason,
65                decoded_so_far,
66            } => StorageKeyDecodeError::CannotDecodeKey {
67                ty: f(ty),
68                reason,
69                decoded_so_far: decoded_so_far.map_type_id(f),
70            },
71        }
72    }
73}
74
75/// An error returned trying to decode the values in storage keys
76#[non_exhaustive]
77#[allow(missing_docs)]
78#[derive(Debug, thiserror::Error)]
79pub enum StorageKeyValueDecodeError {
80    #[error("Cannot decode storage value at index {index}: {error}")]
81    DecodeError {
82        index: usize,
83        error: scale_decode::Error,
84    },
85    #[error("Cannot decode storage key values; need {need} values but have {have}")]
86    WrongNumberOfValues { have: usize, need: usize },
87    #[error(
88        "There were leftover bytes after decoding a value, indicating that decoding was not successful"
89    )]
90    LeftoverBytes { bytes: Vec<u8> },
91    #[error(
92        "An invalid byte range was asked for from the key bytes, implying that the key bytes are not those that the information is about"
93    )]
94    InvalidRange,
95}
96
97/// An error returned trying to decode storage bytes.
98#[non_exhaustive]
99#[allow(missing_docs)]
100#[derive(Clone, Debug)]
101pub enum StorageValueDecodeError<TypeId> {
102    CannotGetInfo(StorageInfoError<'static>),
103    CannotDecodeValue {
104        ty: TypeId,
105        reason: DecodeErrorTrace,
106    },
107}
108
109impl<TypeId: core::fmt::Debug> core::error::Error for StorageValueDecodeError<TypeId> {}
110
111impl<TypeId: core::fmt::Debug> core::fmt::Display for StorageValueDecodeError<TypeId> {
112    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
113        match self {
114            StorageValueDecodeError::CannotGetInfo(storage_info_error) => {
115                write!(f, "Cannot get storage info:\n\n{storage_info_error}")
116            }
117            StorageValueDecodeError::CannotDecodeValue { ty, reason } => {
118                write!(f, "Cannot decode value with type ID {ty:?}:\n\n{reason}")
119            }
120        }
121    }
122}
123
124impl<TypeId> StorageValueDecodeError<TypeId> {
125    /// Map the storage value error type IDs to something else.
126    pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageValueDecodeError<NewTypeId>
127    where
128        F: FnMut(TypeId) -> NewTypeId,
129    {
130        match self {
131            StorageValueDecodeError::CannotGetInfo(e) => StorageValueDecodeError::CannotGetInfo(e),
132            StorageValueDecodeError::CannotDecodeValue { ty, reason } => {
133                StorageValueDecodeError::CannotDecodeValue { ty: f(ty), reason }
134            }
135        }
136    }
137}
138
139/// Details about a storage key.
140#[derive(Clone, Debug)]
141pub struct StorageKey<TypeId> {
142    parts: Vec<StorageKeyPart<TypeId>>,
143}
144
145impl<TypeId: core::fmt::Debug> core::fmt::Display for StorageKey<TypeId> {
146    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
147        // Plain entries have no keys:
148        if self.parts.is_empty() {
149            write!(f, "No storage parts")?;
150            return Ok(());
151        }
152
153        // hash type: blake2,
154        // hash range: 0..13,
155        // value range: 13..23,
156        // value type: AccountId
157        //
158        // ...
159        for key in self.parts.iter() {
160            writeln!(f, "Hash type: {:?}", key.hasher)?;
161            writeln!(
162                f,
163                "Hash range: {}..{}",
164                key.hash_range.start, key.hash_range.end
165            )?;
166            if let Some(v) = &key.value {
167                writeln!(f, "Value type: {:?}", v.ty)?;
168                writeln!(f, "Value range: {}..{}", v.range.start, v.range.end)?;
169            }
170
171            writeln!(f)?;
172        }
173
174        Ok(())
175    }
176}
177
178impl<TypeId> core::ops::Index<usize> for StorageKey<TypeId> {
179    type Output = StorageKeyPart<TypeId>;
180    fn index(&self, index: usize) -> &Self::Output {
181        &self.parts[index]
182    }
183}
184
185impl<TypeId> StorageKey<TypeId> {
186    /// Iterate over the parts of this storage key.
187    pub fn parts(&self) -> impl ExactSizeIterator<Item = &StorageKeyPart<TypeId>> {
188        self.parts.iter()
189    }
190
191    /// Map the storage key type IDs to something else.
192    pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKey<NewTypeId>
193    where
194        F: FnMut(TypeId) -> NewTypeId,
195    {
196        StorageKey {
197            parts: self
198                .parts
199                .into_iter()
200                .map(|p| p.map_type_id(&mut f))
201                .collect(),
202        }
203    }
204}
205
206/// The decoded representation of a storage key.
207#[derive(Clone, Debug)]
208pub struct StorageKeyPart<TypeId> {
209    hash_range: Range<u32>,
210    value: Option<StorageKeyPartValue<TypeId>>,
211    hasher: StorageHasher,
212}
213
214impl<TypeId> StorageKeyPart<TypeId> {
215    /// The byte range of the hash for this storage key part.
216    pub fn hash_range(&self) -> Range<usize> {
217        Range {
218            start: self.hash_range.start as usize,
219            end: self.hash_range.end as usize,
220        }
221    }
222
223    /// The hasher used for this storage key part.
224    pub fn hasher(&self) -> StorageHasher {
225        self.hasher
226    }
227
228    /// If applicable (ie this part uses a concat or ident hasher), return information
229    /// about the value encoded into this hash.
230    pub fn value(&self) -> Option<&StorageKeyPartValue<TypeId>> {
231        self.value.as_ref()
232    }
233
234    /// Map the storage part type ID to something else.
235    pub fn map_type_id<NewTypeId, F>(self, f: F) -> StorageKeyPart<NewTypeId>
236    where
237        F: FnMut(TypeId) -> NewTypeId,
238    {
239        StorageKeyPart {
240            hash_range: self.hash_range,
241            value: self.value.map(|v| v.map_type_id(f)),
242            hasher: self.hasher,
243        }
244    }
245}
246
247/// Information about the value contained within a storage key part hash.
248#[derive(Clone, Debug)]
249pub struct StorageKeyPartValue<TypeId> {
250    range: Range<u32>,
251    ty: TypeId,
252}
253
254impl<TypeId> StorageKeyPartValue<TypeId> {
255    /// The byte range for this value in the storage key.
256    pub fn range(&self) -> Range<usize> {
257        Range {
258            start: self.range.start as usize,
259            end: self.range.end as usize,
260        }
261    }
262
263    /// The type ID for this value.
264    pub fn ty(&self) -> &TypeId {
265        &self.ty
266    }
267
268    /// Map the storage part type ID to something else.
269    pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKeyPartValue<NewTypeId>
270    where
271        F: FnMut(TypeId) -> NewTypeId,
272    {
273        StorageKeyPartValue {
274            range: self.range,
275            ty: f(self.ty),
276        }
277    }
278}
279
280/// Decode a storage key, returning information about it.
281///
282/// This information can be used to identify and, where possible, decode the parts of the storage key.
283///
284/// # Example
285///
286/// Here, we decode some storage keys from a block.
287///
288/// ```rust
289/// use frame_decode::storage::decode_storage_key;
290/// use frame_decode::helpers::decode_with_visitor;
291/// use frame_metadata::RuntimeMetadata;
292/// use parity_scale_codec::Decode;
293/// use scale_value::scale::ValueVisitor;
294///
295/// let metadata_bytes = std::fs::read("artifacts/metadata_10000000_9180.scale").unwrap();
296/// let RuntimeMetadata::V14(metadata) = RuntimeMetadata::decode(&mut &*metadata_bytes).unwrap() else { return };
297///
298/// let storage_keyval_bytes = std::fs::read("artifacts/storage_10000000_9180_system_account.json").unwrap();
299/// let storage_keyval_hex: Vec<(String, String)> = serde_json::from_slice(&storage_keyval_bytes).unwrap();
300///
301/// for (key, _val) in storage_keyval_hex {
302///     let key_bytes = hex::decode(key.trim_start_matches("0x")).unwrap();
303///
304///     // Decode the storage key, returning information about it:
305///     let storage_info = decode_storage_key(
306///         "System",
307///         "Account",
308///         &mut &*key_bytes,
309///         &metadata,
310///         &metadata.types
311///     ).unwrap();
312///
313///     for part in storage_info.parts() {
314///         // Access information about the hasher for this part of the key:
315///         let hash_bytes = &key_bytes[part.hash_range()];
316///         let hasher = part.hasher();
317///
318///         // If the value is encoded as part of the hasher, we can find and
319///         // decode the value too:
320///         if let Some(value_info) = part.value() {
321///             let value_bytes = &key_bytes[value_info.range()];
322///             let value = decode_with_visitor(
323///                 &mut &*value_bytes,
324///                 *value_info.ty(),
325///                 &metadata.types,
326///                 ValueVisitor::new()
327///             ).unwrap();
328///         }
329///     }
330/// }
331/// ```
332pub fn decode_storage_key<Info, Resolver>(
333    pallet_name: &str,
334    storage_entry: &str,
335    cursor: &mut &[u8],
336    info: &Info,
337    type_resolver: &Resolver,
338) -> Result<StorageKey<Info::TypeId>, StorageKeyDecodeError<Info::TypeId>>
339where
340    Info: StorageTypeInfo,
341    Info::TypeId: Clone + core::fmt::Debug,
342    Resolver: TypeResolver<TypeId = Info::TypeId>,
343{
344    let storage_info = info
345        .storage_info(pallet_name, storage_entry)
346        .map_err(|e| StorageKeyDecodeError::CannotGetInfo(e.into_owned()))?;
347
348    // Sanity check that the storage key prefix is what we expect:
349    let expected_prefix = encode_storage_key_prefix(pallet_name, storage_entry);
350    if cursor[..32] != expected_prefix {
351        return Err(StorageKeyDecodeError::PrefixMismatch);
352    }
353
354    decode_storage_key_with_info(cursor, &storage_info, type_resolver)
355}
356
357/// Decode a storage key, returning information about it.
358///
359/// Unlike [`decode_storage_key`], which obtains the storage info internally given the pallet and storage entry names,
360/// this function takes the storage info as an argument. This is useful if you already have the storage info available,
361/// for example if you are decoding multiple keys for the same storage entry.
362///
363/// # Warning
364///
365/// Unlike [`decode_storage_key`], this does not check that the bytes start with the expected prefix; ensuring that the
366/// storage information lines up with the bytes is the caller's responsibility.
367pub fn decode_storage_key_with_info<Resolver>(
368    cursor: &mut &[u8],
369    storage_info: &StorageInfo<<Resolver as TypeResolver>::TypeId>,
370    type_resolver: &Resolver,
371) -> Result<
372    StorageKey<<Resolver as TypeResolver>::TypeId>,
373    StorageKeyDecodeError<<Resolver as TypeResolver>::TypeId>,
374>
375where
376    Resolver: TypeResolver,
377    <Resolver as TypeResolver>::TypeId: Clone + core::fmt::Debug,
378{
379    let bytes = *cursor;
380    let curr_idx = |cursor: &mut &[u8]| (bytes.len() - cursor.len()) as u32;
381
382    let _prefix = strip_bytes(cursor, 32)?;
383
384    let mut parts = vec![];
385    for key in &*storage_info.keys {
386        let hasher = key.hasher;
387        let start_idx = curr_idx(cursor);
388        let part = match &hasher {
389            StorageHasher::Blake2_128 | StorageHasher::Twox128 => {
390                strip_bytes(cursor, 16)?;
391                StorageKeyPart {
392                    hash_range: Range {
393                        start: start_idx,
394                        end: curr_idx(cursor),
395                    },
396                    value: None,
397                    hasher,
398                }
399            }
400            StorageHasher::Blake2_256 | StorageHasher::Twox256 => {
401                strip_bytes(cursor, 32)?;
402                StorageKeyPart {
403                    hash_range: Range {
404                        start: start_idx,
405                        end: curr_idx(cursor),
406                    },
407                    value: None,
408                    hasher,
409                }
410            }
411            StorageHasher::Blake2_128Concat => {
412                strip_bytes(cursor, 16)?;
413                let hash_end_idx = curr_idx(cursor);
414                decode_with_error_tracing(
415                    cursor,
416                    key.key_id.clone(),
417                    type_resolver,
418                    scale_decode::visitor::IgnoreVisitor::new(),
419                )
420                .map_err(|e| StorageKeyDecodeError::CannotDecodeKey {
421                    ty: key.key_id.clone(),
422                    reason: e,
423                    decoded_so_far: StorageKey {
424                        parts: parts.clone(),
425                    },
426                })?;
427                StorageKeyPart {
428                    hash_range: Range {
429                        start: start_idx,
430                        end: hash_end_idx,
431                    },
432                    value: Some(StorageKeyPartValue {
433                        range: Range {
434                            start: hash_end_idx,
435                            end: curr_idx(cursor),
436                        },
437                        ty: key.key_id.clone(),
438                    }),
439                    hasher,
440                }
441            }
442            StorageHasher::Twox64Concat => {
443                strip_bytes(cursor, 8)?;
444                let hash_end_idx = curr_idx(cursor);
445                decode_with_error_tracing(
446                    cursor,
447                    key.key_id.clone(),
448                    type_resolver,
449                    scale_decode::visitor::IgnoreVisitor::new(),
450                )
451                .map_err(|e| StorageKeyDecodeError::CannotDecodeKey {
452                    ty: key.key_id.clone(),
453                    reason: e,
454                    decoded_so_far: StorageKey {
455                        parts: parts.clone(),
456                    },
457                })?;
458                StorageKeyPart {
459                    hash_range: Range {
460                        start: start_idx,
461                        end: hash_end_idx,
462                    },
463                    value: Some(StorageKeyPartValue {
464                        range: Range {
465                            start: hash_end_idx,
466                            end: curr_idx(cursor),
467                        },
468                        ty: key.key_id.clone(),
469                    }),
470                    hasher,
471                }
472            }
473            StorageHasher::Identity => {
474                decode_with_error_tracing(
475                    cursor,
476                    key.key_id.clone(),
477                    type_resolver,
478                    scale_decode::visitor::IgnoreVisitor::new(),
479                )
480                .map_err(|e| StorageKeyDecodeError::CannotDecodeKey {
481                    ty: key.key_id.clone(),
482                    reason: e,
483                    decoded_so_far: StorageKey {
484                        parts: parts.clone(),
485                    },
486                })?;
487                StorageKeyPart {
488                    hash_range: Range {
489                        start: start_idx,
490                        end: start_idx,
491                    },
492                    value: Some(StorageKeyPartValue {
493                        range: Range {
494                            start: start_idx,
495                            end: curr_idx(cursor),
496                        },
497                        ty: key.key_id.clone(),
498                    }),
499                    hasher,
500                }
501            }
502        };
503        parts.push(part)
504    }
505
506    Ok(StorageKey { parts })
507}
508
509/// Attempt to decode the values attached to parts of a storage key into the provided output type.
510/// [`decode_storage_key`] and related functions take a storage key and return information (in the
511/// form of [`StorageKey`]) which describes each of the parts of the key.
512///
513/// This function takes that information and returns a user-defined generic type which implements
514/// [`IntoDecodableValues`], and attempts to decode some or all of the values from it (in order).
515///
516/// # Example
517///
518/// Here, we decode some storage keys from a block.
519///
520/// ```rust
521/// use frame_decode::storage::{ decode_storage_key, decode_storage_key_values };
522/// use frame_decode::helpers::decode_with_visitor;
523/// use frame_metadata::RuntimeMetadata;
524/// use parity_scale_codec::Decode;
525/// use scale_value::scale::ValueVisitor;
526///
527/// let metadata_bytes = std::fs::read("artifacts/metadata_10000000_9180.scale").unwrap();
528/// let RuntimeMetadata::V14(metadata) = RuntimeMetadata::decode(&mut &*metadata_bytes).unwrap() else { return };
529///
530/// let storage_keyval_bytes = std::fs::read("artifacts/storage_10000000_9180_system_account.json").unwrap();
531/// let storage_keyval_hex: Vec<(String, String)> = serde_json::from_slice(&storage_keyval_bytes).unwrap();
532///
533/// for (key, _val) in storage_keyval_hex {
534///     let key_bytes = hex::decode(key.trim_start_matches("0x")).unwrap();
535///
536///     // First decode the storage key, returning information about it:
537///     let storage_info = decode_storage_key(
538///         "System",
539///         "Account",
540///         &mut &*key_bytes,
541///         &metadata,
542///         &metadata.types
543///     ).unwrap();
544///
545///     // Use this information to decode any values within the key. Here
546///     // we ask for the first (and here only) value present, which we know to
547///     // be decodable into a [u8; 32] because it's an AccountId32.
548///     let values: ([u8;32],) = decode_storage_key_values(
549///         &key_bytes,
550///         &storage_info,
551///         &metadata.types
552///     ).unwrap();
553///
554///     println!("Account ID Hex: {}", hex::encode(&values.0));
555///
556///     // If we don't know what we are decoding, we can target a Vec<scale_value::Value>
557///     // which allows arbitrary items to be decoded into it.
558///     let values: Vec<scale_value::Value> = decode_storage_key_values(
559///         &key_bytes,
560///         &storage_info,
561///         &metadata.types
562///     ).unwrap();
563///
564///     println!("All values extracted from key:");
565///     for value in values {
566///         println!("  {value}");
567///     }
568/// }
569/// ```
570pub fn decode_storage_key_values<Values, Resolver>(
571    key_bytes: &[u8],
572    decoded_key: &StorageKey<Resolver::TypeId>,
573    types: &Resolver,
574) -> Result<Values, StorageKeyValueDecodeError>
575where
576    Values: IntoDecodableValues,
577    Resolver: TypeResolver,
578{
579    let num_values = decoded_key
580        .parts()
581        .filter(|part| part.value.is_some())
582        .count();
583
584    let needed_values = Values::num_decodable_values();
585
586    // If a specific number of values are needed, ensure that we have enough available.
587    if let Some(needed_values) = needed_values
588        && num_values < needed_values
589    {
590        return Err(StorageKeyValueDecodeError::WrongNumberOfValues {
591            have: num_values,
592            need: needed_values,
593        });
594    }
595
596    let mut decode_target = Values::into_decodable_values();
597
598    // Iterate over **at most** needed_values, or all of the available values if no limit.
599    let value_info_iter =
600        (0..needed_values.unwrap_or(usize::MAX)).zip(decoded_key.parts().filter_map(|p| p.value()));
601
602    for (idx, value_info) in value_info_iter {
603        // This will panic if the key bytes provided don't line up with the information.
604        let value_bytes = &mut key_bytes
605            .get(value_info.range())
606            .ok_or(StorageKeyValueDecodeError::InvalidRange)?;
607        let value_ty = value_info.ty().clone();
608
609        decode_target
610            .decode_next_value(value_bytes, value_ty, types)
611            .map_err(|e| StorageKeyValueDecodeError::DecodeError {
612                index: idx,
613                error: e,
614            })?;
615
616        if !value_bytes.is_empty() {
617            return Err(StorageKeyValueDecodeError::LeftoverBytes {
618                bytes: value_bytes.to_vec(),
619            });
620        }
621    }
622
623    Ok(decode_target.decoded_target())
624}
625
626/// Decode a storage value.
627///
628/// # Example
629///
630/// Here, we decode some storage values from a block.
631///
632/// ```rust
633/// use frame_decode::storage::decode_storage_value;
634/// use frame_decode::helpers::decode_with_visitor;
635/// use frame_metadata::RuntimeMetadata;
636/// use parity_scale_codec::Decode;
637/// use scale_value::scale::ValueVisitor;
638///
639/// let metadata_bytes = std::fs::read("artifacts/metadata_10000000_9180.scale").unwrap();
640/// let RuntimeMetadata::V14(metadata) = RuntimeMetadata::decode(&mut &*metadata_bytes).unwrap() else { return };
641///
642/// let storage_keyval_bytes = std::fs::read("artifacts/storage_10000000_9180_system_account.json").unwrap();
643/// let storage_keyval_hex: Vec<(String, String)> = serde_json::from_slice(&storage_keyval_bytes).unwrap();
644///
645/// for (_key, val) in storage_keyval_hex {
646///     let value_bytes = hex::decode(val.trim_start_matches("0x")).unwrap();
647///
648///     // Decode the storage value, here into a scale_value::Value:
649///     let account_value = decode_storage_value(
650///         "System",
651///         "Account",
652///         &mut &*value_bytes,
653///         &metadata,
654///         &metadata.types,
655///         ValueVisitor::new()
656///     ).unwrap();
657/// }
658/// ```
659pub fn decode_storage_value<'scale, 'resolver, Info, Resolver, V>(
660    pallet_name: &str,
661    storage_entry: &str,
662    cursor: &mut &'scale [u8],
663    info: &Info,
664    type_resolver: &'resolver Resolver,
665    visitor: V,
666) -> Result<V::Value<'scale, 'resolver>, StorageValueDecodeError<Info::TypeId>>
667where
668    Info: StorageTypeInfo,
669    Info::TypeId: Clone + core::fmt::Debug,
670    Resolver: TypeResolver<TypeId = Info::TypeId>,
671    V: scale_decode::Visitor<TypeResolver = Resolver>,
672    V::Error: core::fmt::Debug,
673{
674    let storage_info = info
675        .storage_info(pallet_name, storage_entry)
676        .map_err(|e| StorageValueDecodeError::CannotGetInfo(e.into_owned()))?;
677
678    decode_storage_value_with_info(cursor, &storage_info, type_resolver, visitor)
679}
680
681/// Decode a storage value.
682///
683/// Unlike [`decode_storage_value`], which obtains the storage info internally given the pallet and storage entry names,
684/// this function takes the storage info as an argument. This is useful if you already have the storage info available,
685/// for example if you are decoding multiple keys for the same storage entry.
686pub fn decode_storage_value_with_info<'scale, 'resolver, V>(
687    cursor: &mut &'scale [u8],
688    storage_info: &StorageInfo<<V::TypeResolver as TypeResolver>::TypeId>,
689    type_resolver: &'resolver V::TypeResolver,
690    visitor: V,
691) -> Result<
692    V::Value<'scale, 'resolver>,
693    StorageValueDecodeError<<V::TypeResolver as TypeResolver>::TypeId>,
694>
695where
696    V: scale_decode::Visitor,
697    V::Error: core::fmt::Debug,
698{
699    let value_id = storage_info.value_id.clone();
700
701    decode_with_error_tracing(cursor, value_id.clone(), type_resolver, visitor).map_err(|e| {
702        StorageValueDecodeError::CannotDecodeValue {
703            ty: value_id,
704            reason: e,
705        }
706    })
707}
708
709/// Decode the default storage value given some [`StorageInfo`].
710///
711/// The resulting value may be tied to the lifetime of the [`StorageInfo`] being provided if the implementation decides to borrow
712/// from it. This is also why no `decode_default_storage_value` function exists; the [`StorageInfo`] must outlive this call.
713pub fn decode_default_storage_value_with_info<'info, 'resolver, V>(
714    storage_info: &'info StorageInfo<<V::TypeResolver as TypeResolver>::TypeId>,
715    type_resolver: &'resolver V::TypeResolver,
716    visitor: V,
717) -> Result<
718    Option<V::Value<'info, 'resolver>>,
719    StorageValueDecodeError<<V::TypeResolver as TypeResolver>::TypeId>,
720>
721where
722    V: scale_decode::Visitor,
723    V::Error: core::fmt::Debug,
724{
725    let value_id = storage_info.value_id.clone();
726
727    let Some(default_bytes) = &storage_info.default_value else {
728        return Ok(None);
729    };
730    let value = decode_with_error_tracing(
731        &mut &**default_bytes,
732        value_id.clone(),
733        type_resolver,
734        visitor,
735    )
736    .map_err(|e| StorageValueDecodeError::CannotDecodeValue {
737        ty: value_id,
738        reason: e,
739    })?;
740
741    Ok(Some(value))
742}
743
744fn strip_bytes<'a, T>(
745    cursor: &mut &'a [u8],
746    num: usize,
747) -> Result<&'a [u8], StorageKeyDecodeError<T>> {
748    let bytes = cursor
749        .get(..num)
750        .ok_or_else(|| StorageKeyDecodeError::NotEnoughBytes {
751            needed: num,
752            have: cursor.len(),
753        })?;
754
755    *cursor = &cursor[num..];
756    Ok(bytes)
757}
758
759#[cfg(test)]
760mod test {
761    use super::*;
762
763    #[test]
764    fn test_strip_bytes() {
765        let v = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
766        let cursor = &mut &*v;
767        let stripped = strip_bytes::<()>(cursor, 4).unwrap();
768        assert_eq!(stripped, &[0, 1, 2, 3]);
769        assert_eq!(cursor, &[4, 5, 6, 7, 8]);
770    }
771}