frame_decode/methods/
storage_decoder.rs

1// Copyright (C) 2022-2023 Parity Technologies (UK) Ltd. (admin@parity.io)
2// This file is a part of the scale-value 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_prefix;
17use super::storage_type_info::{StorageHasher, StorageTypeInfo};
18use crate::methods::storage_type_info::StorageInfoError;
19use crate::utils::{decode_with_error_tracing, DecodeErrorTrace};
20use alloc::vec;
21use alloc::vec::Vec;
22use core::ops::Range;
23use scale_type_resolver::TypeResolver;
24
25/// An error returned trying to decode storage bytes.
26#[non_exhaustive]
27#[allow(missing_docs)]
28#[derive(Clone, Debug, thiserror::Error)]
29pub enum StorageKeyDecodeError<TypeId> {
30    #[error("Cannot get storage info: {0}")]
31    CannotGetInfo(StorageInfoError<'static>),
32    #[error("The hashed storage prefix given does not match the pallet and storage name asked to decode.")]
33    PrefixMismatch,
34    #[error("Not enough bytes left: we need at least {needed} bytes but have {have} bytes")]
35    NotEnoughBytes { needed: usize, have: usize },
36    #[error(
37        "Cannot decode storage key '{ty:?}':\n\n{reason}\n\nDecoded so far:\n\n{decoded_so_far}"
38    )]
39    CannotDecodeKey {
40        ty: TypeId,
41        reason: DecodeErrorTrace,
42        decoded_so_far: StorageKey<TypeId>,
43    },
44}
45
46impl<TypeId> StorageKeyDecodeError<TypeId> {
47    /// Map the storage key error type IDs to something else.
48    pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKeyDecodeError<NewTypeId>
49    where
50        F: FnMut(TypeId) -> NewTypeId,
51    {
52        match self {
53            StorageKeyDecodeError::CannotGetInfo(e) => StorageKeyDecodeError::CannotGetInfo(e),
54            StorageKeyDecodeError::PrefixMismatch => StorageKeyDecodeError::PrefixMismatch,
55            StorageKeyDecodeError::NotEnoughBytes { needed, have } => {
56                StorageKeyDecodeError::NotEnoughBytes { needed, have }
57            }
58            StorageKeyDecodeError::CannotDecodeKey {
59                ty,
60                reason,
61                decoded_so_far,
62            } => StorageKeyDecodeError::CannotDecodeKey {
63                ty: f(ty),
64                reason,
65                decoded_so_far: decoded_so_far.map_type_id(f),
66            },
67        }
68    }
69}
70
71/// An error returned trying to decode storage bytes.
72#[non_exhaustive]
73#[allow(missing_docs)]
74#[derive(Clone, Debug)]
75pub enum StorageValueDecodeError<TypeId> {
76    CannotGetInfo(StorageInfoError<'static>),
77    CannotDecodeValue {
78        ty: TypeId,
79        reason: DecodeErrorTrace,
80    },
81}
82
83impl<TypeId: core::fmt::Debug> core::error::Error for StorageValueDecodeError<TypeId> {}
84
85impl<TypeId: core::fmt::Debug> core::fmt::Display for StorageValueDecodeError<TypeId> {
86    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
87        match self {
88            StorageValueDecodeError::CannotGetInfo(storage_info_error) => {
89                write!(f, "Cannot get storage info:\n\n{storage_info_error}")
90            }
91            StorageValueDecodeError::CannotDecodeValue { ty, reason } => {
92                write!(f, "Cannot decode value with type ID {ty:?}:\n\n{reason}")
93            }
94        }
95    }
96}
97
98impl<TypeId> StorageValueDecodeError<TypeId> {
99    /// Map the storage value error type IDs to something else.
100    pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageValueDecodeError<NewTypeId>
101    where
102        F: FnMut(TypeId) -> NewTypeId,
103    {
104        match self {
105            StorageValueDecodeError::CannotGetInfo(e) => StorageValueDecodeError::CannotGetInfo(e),
106            StorageValueDecodeError::CannotDecodeValue { ty, reason } => {
107                StorageValueDecodeError::CannotDecodeValue { ty: f(ty), reason }
108            }
109        }
110    }
111}
112
113/// Details about a storage key.
114#[derive(Clone, Debug)]
115pub struct StorageKey<TypeId> {
116    parts: Vec<StorageKeyPart<TypeId>>,
117}
118
119impl<TypeId: core::fmt::Debug> core::fmt::Display for StorageKey<TypeId> {
120    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
121        // Plain entries have no keys:
122        if self.parts.is_empty() {
123            write!(f, "No storage parts")?;
124            return Ok(());
125        }
126
127        // hash type: blake2,
128        // hash range: 0..13,
129        // value range: 13..23,
130        // value type: AccountId
131        //
132        // ...
133        for key in self.parts.iter() {
134            writeln!(f, "Hash type: {:?}", key.hasher)?;
135            writeln!(
136                f,
137                "Hash range: {}..{}",
138                key.hash_range.start, key.hash_range.end
139            )?;
140            if let Some(v) = &key.value {
141                writeln!(f, "Value type: {:?}", v.ty)?;
142                writeln!(f, "Value range: {}..{}", v.range.start, v.range.end)?;
143            }
144
145            writeln!(f)?;
146        }
147
148        Ok(())
149    }
150}
151
152impl<TypeId> core::ops::Index<usize> for StorageKey<TypeId> {
153    type Output = StorageKeyPart<TypeId>;
154    fn index(&self, index: usize) -> &Self::Output {
155        &self.parts[index]
156    }
157}
158
159impl<TypeId> StorageKey<TypeId> {
160    /// Iterate over the parts of this storage key.
161    pub fn parts(&self) -> impl ExactSizeIterator<Item = &StorageKeyPart<TypeId>> {
162        self.parts.iter()
163    }
164
165    /// Map the storage key type IDs to something else.
166    pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKey<NewTypeId>
167    where
168        F: FnMut(TypeId) -> NewTypeId,
169    {
170        StorageKey {
171            parts: self
172                .parts
173                .into_iter()
174                .map(|p| p.map_type_id(&mut f))
175                .collect(),
176        }
177    }
178}
179
180/// The decoded representation of a storage key.
181#[derive(Clone, Debug)]
182pub struct StorageKeyPart<TypeId> {
183    hash_range: Range<u32>,
184    value: Option<StorageKeyPartValue<TypeId>>,
185    hasher: StorageHasher,
186}
187
188impl<TypeId> StorageKeyPart<TypeId> {
189    /// The byte range of the hash for this storage key part.
190    pub fn hash_range(&self) -> Range<usize> {
191        Range {
192            start: self.hash_range.start as usize,
193            end: self.hash_range.end as usize,
194        }
195    }
196
197    /// The hasher used for this storage key part.
198    pub fn hasher(&self) -> StorageHasher {
199        self.hasher
200    }
201
202    /// If applicable (ie this part uses a concat or ident hasher), return information
203    /// about the value encoded into this hash.
204    pub fn value(&self) -> Option<&StorageKeyPartValue<TypeId>> {
205        self.value.as_ref()
206    }
207
208    /// Map the storage part type ID to something else.
209    pub fn map_type_id<NewTypeId, F>(self, f: F) -> StorageKeyPart<NewTypeId>
210    where
211        F: FnMut(TypeId) -> NewTypeId,
212    {
213        StorageKeyPart {
214            hash_range: self.hash_range,
215            value: self.value.map(|v| v.map_type_id(f)),
216            hasher: self.hasher,
217        }
218    }
219}
220
221/// Information about the value contained within a storage key part hash.
222#[derive(Clone, Debug)]
223pub struct StorageKeyPartValue<TypeId> {
224    range: Range<u32>,
225    ty: TypeId,
226}
227
228impl<TypeId> StorageKeyPartValue<TypeId> {
229    /// The byte range for this value in the storage key.
230    pub fn range(&self) -> Range<usize> {
231        Range {
232            start: self.range.start as usize,
233            end: self.range.end as usize,
234        }
235    }
236
237    /// The type ID for this value.
238    pub fn ty(&self) -> &TypeId {
239        &self.ty
240    }
241
242    /// Map the storage part type ID to something else.
243    pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKeyPartValue<NewTypeId>
244    where
245        F: FnMut(TypeId) -> NewTypeId,
246    {
247        StorageKeyPartValue {
248            range: self.range,
249            ty: f(self.ty),
250        }
251    }
252}
253
254/// Decode a storage key, returning information about it.
255///
256/// This information can be used to identify and, where possible, decode the parts of the storage key.
257///
258/// # Example
259///
260/// Here, we decode some storage keys from a block.
261///
262/// ```rust
263/// use frame_decode::storage::decode_storage_key;
264/// use frame_decode::helpers::decode_with_visitor;
265/// use frame_metadata::RuntimeMetadata;
266/// use parity_scale_codec::Decode;
267/// use scale_value::scale::ValueVisitor;
268///
269/// let metadata_bytes = std::fs::read("artifacts/metadata_10000000_9180.scale").unwrap();
270/// let RuntimeMetadata::V14(metadata) = RuntimeMetadata::decode(&mut &*metadata_bytes).unwrap() else { return };
271///
272/// let storage_keyval_bytes = std::fs::read("artifacts/storage_10000000_9180_system_account.json").unwrap();
273/// let storage_keyval_hex: Vec<(String, String)> = serde_json::from_slice(&storage_keyval_bytes).unwrap();
274///
275/// for (key, _val) in storage_keyval_hex {
276///     let key_bytes = hex::decode(key.trim_start_matches("0x")).unwrap();
277///
278///     // Decode the storage key, returning information about it:
279///     let storage_info = decode_storage_key(
280///         "System",
281///         "Account",
282///         &mut &*key_bytes,
283///         &metadata,
284///         &metadata.types
285///     ).unwrap();
286///
287///     for part in storage_info.parts() {
288///         // Access information about the hasher for this part of the key:
289///         let hash_bytes = &key_bytes[part.hash_range()];
290///         let hasher = part.hasher();
291///
292///         // If the value is encoded as part of the hasher, we can find and
293///         // decode the value too:
294///         if let Some(value_info) = part.value() {
295///             let value_bytes = &key_bytes[value_info.range()];
296///             let value = decode_with_visitor(
297///                 &mut &*value_bytes,
298///                 *value_info.ty(),
299///                 &metadata.types,
300///                 ValueVisitor::new()
301///             ).unwrap();
302///         }
303///     }
304/// }
305/// ```
306pub fn decode_storage_key<Info, Resolver>(
307    pallet_name: &str,
308    storage_entry: &str,
309    cursor: &mut &[u8],
310    info: &Info,
311    type_resolver: &Resolver,
312) -> Result<StorageKey<Info::TypeId>, StorageKeyDecodeError<Info::TypeId>>
313where
314    Info: StorageTypeInfo,
315    Info::TypeId: Clone + core::fmt::Debug,
316    Resolver: TypeResolver<TypeId = Info::TypeId>,
317{
318    let storage_info = info
319        .get_storage_info(pallet_name, storage_entry)
320        .map_err(|e| StorageKeyDecodeError::CannotGetInfo(e.into_owned()))?;
321
322    // Sanity check that the storage key prefix is what we expect:
323    let expected_prefix = encode_prefix(pallet_name, storage_entry);
324    if cursor[..32] != expected_prefix {
325        return Err(StorageKeyDecodeError::PrefixMismatch);
326    }
327
328    decode_storage_key_with_info(cursor, &storage_info, type_resolver)
329}
330
331/// Decode a storage key, returning information about it.
332///
333/// Unlike [`decode_storage_key`], which obtains the storage info internally given the pallet and storage entry names,
334/// this function takes the storage info as an argument. This is useful if you already have the storage info available,
335/// for example if you are decoding multiple keys for the same storage entry.
336///
337/// # Warning
338///
339/// Unlike [`decode_storage_key`], this does not check that the bytes start with the expected prefix; ensuring that the
340/// storage information lines up with the bytes is the caller's responsibility.
341pub fn decode_storage_key_with_info<Resolver>(
342    cursor: &mut &[u8],
343    storage_info: &crate::storage::StorageInfo<<Resolver as TypeResolver>::TypeId>,
344    type_resolver: &Resolver,
345) -> Result<
346    StorageKey<<Resolver as TypeResolver>::TypeId>,
347    StorageKeyDecodeError<<Resolver as TypeResolver>::TypeId>,
348>
349where
350    Resolver: TypeResolver,
351    <Resolver as TypeResolver>::TypeId: Clone + core::fmt::Debug,
352{
353    let bytes = *cursor;
354    let curr_idx = |cursor: &mut &[u8]| (bytes.len() - cursor.len()) as u32;
355
356    let _prefix = strip_bytes(cursor, 32)?;
357
358    let mut parts = vec![];
359    for key in &storage_info.keys {
360        let hasher = key.hasher;
361        let start_idx = curr_idx(cursor);
362        let part = match &hasher {
363            StorageHasher::Blake2_128 | StorageHasher::Twox128 => {
364                strip_bytes(cursor, 16)?;
365                StorageKeyPart {
366                    hash_range: Range {
367                        start: start_idx,
368                        end: curr_idx(cursor),
369                    },
370                    value: None,
371                    hasher,
372                }
373            }
374            StorageHasher::Blake2_256 | StorageHasher::Twox256 => {
375                strip_bytes(cursor, 32)?;
376                StorageKeyPart {
377                    hash_range: Range {
378                        start: start_idx,
379                        end: curr_idx(cursor),
380                    },
381                    value: None,
382                    hasher,
383                }
384            }
385            StorageHasher::Blake2_128Concat => {
386                strip_bytes(cursor, 16)?;
387                let hash_end_idx = curr_idx(cursor);
388                decode_with_error_tracing(
389                    cursor,
390                    key.key_id.clone(),
391                    type_resolver,
392                    scale_decode::visitor::IgnoreVisitor::new(),
393                )
394                .map_err(|e| StorageKeyDecodeError::CannotDecodeKey {
395                    ty: key.key_id.clone(),
396                    reason: e,
397                    decoded_so_far: StorageKey {
398                        parts: parts.clone(),
399                    },
400                })?;
401                StorageKeyPart {
402                    hash_range: Range {
403                        start: start_idx,
404                        end: hash_end_idx,
405                    },
406                    value: Some(StorageKeyPartValue {
407                        range: Range {
408                            start: hash_end_idx,
409                            end: curr_idx(cursor),
410                        },
411                        ty: key.key_id.clone(),
412                    }),
413                    hasher,
414                }
415            }
416            StorageHasher::Twox64Concat => {
417                strip_bytes(cursor, 8)?;
418                let hash_end_idx = curr_idx(cursor);
419                decode_with_error_tracing(
420                    cursor,
421                    key.key_id.clone(),
422                    type_resolver,
423                    scale_decode::visitor::IgnoreVisitor::new(),
424                )
425                .map_err(|e| StorageKeyDecodeError::CannotDecodeKey {
426                    ty: key.key_id.clone(),
427                    reason: e,
428                    decoded_so_far: StorageKey {
429                        parts: parts.clone(),
430                    },
431                })?;
432                StorageKeyPart {
433                    hash_range: Range {
434                        start: start_idx,
435                        end: hash_end_idx,
436                    },
437                    value: Some(StorageKeyPartValue {
438                        range: Range {
439                            start: hash_end_idx,
440                            end: curr_idx(cursor),
441                        },
442                        ty: key.key_id.clone(),
443                    }),
444                    hasher,
445                }
446            }
447            StorageHasher::Identity => {
448                decode_with_error_tracing(
449                    cursor,
450                    key.key_id.clone(),
451                    type_resolver,
452                    scale_decode::visitor::IgnoreVisitor::new(),
453                )
454                .map_err(|e| StorageKeyDecodeError::CannotDecodeKey {
455                    ty: key.key_id.clone(),
456                    reason: e,
457                    decoded_so_far: StorageKey {
458                        parts: parts.clone(),
459                    },
460                })?;
461                StorageKeyPart {
462                    hash_range: Range {
463                        start: start_idx,
464                        end: start_idx,
465                    },
466                    value: Some(StorageKeyPartValue {
467                        range: Range {
468                            start: start_idx,
469                            end: curr_idx(cursor),
470                        },
471                        ty: key.key_id.clone(),
472                    }),
473                    hasher,
474                }
475            }
476        };
477        parts.push(part)
478    }
479
480    Ok(StorageKey { parts })
481}
482
483/// Decode a storage value.
484///
485/// # Example
486///
487/// Here, we decode some storage values from a block.
488///
489/// ```rust
490/// use frame_decode::storage::decode_storage_value;
491/// use frame_decode::helpers::decode_with_visitor;
492/// use frame_metadata::RuntimeMetadata;
493/// use parity_scale_codec::Decode;
494/// use scale_value::scale::ValueVisitor;
495///
496/// let metadata_bytes = std::fs::read("artifacts/metadata_10000000_9180.scale").unwrap();
497/// let RuntimeMetadata::V14(metadata) = RuntimeMetadata::decode(&mut &*metadata_bytes).unwrap() else { return };
498///
499/// let storage_keyval_bytes = std::fs::read("artifacts/storage_10000000_9180_system_account.json").unwrap();
500/// let storage_keyval_hex: Vec<(String, String)> = serde_json::from_slice(&storage_keyval_bytes).unwrap();
501///
502/// for (_key, val) in storage_keyval_hex {
503///     let value_bytes = hex::decode(val.trim_start_matches("0x")).unwrap();
504///
505///     // Decode the storage value, here into a scale_value::Value:
506///     let account_value = decode_storage_value(
507///         "System",
508///         "Account",
509///         &mut &*value_bytes,
510///         &metadata,
511///         &metadata.types,
512///         ValueVisitor::new()
513///     ).unwrap();
514/// }
515/// ```
516pub fn decode_storage_value<'scale, 'resolver, Info, Resolver, V>(
517    pallet_name: &str,
518    storage_entry: &str,
519    cursor: &mut &'scale [u8],
520    info: &Info,
521    type_resolver: &'resolver Resolver,
522    visitor: V,
523) -> Result<V::Value<'scale, 'resolver>, StorageValueDecodeError<Info::TypeId>>
524where
525    Info: StorageTypeInfo,
526    Info::TypeId: Clone + core::fmt::Debug,
527    Resolver: TypeResolver<TypeId = Info::TypeId>,
528    V: scale_decode::Visitor<TypeResolver = Resolver>,
529    V::Error: core::fmt::Debug,
530{
531    let storage_info = info
532        .get_storage_info(pallet_name, storage_entry)
533        .map_err(|e| StorageValueDecodeError::CannotGetInfo(e.into_owned()))?;
534
535    decode_storage_value_with_info(cursor, &storage_info, type_resolver, visitor)
536}
537
538/// Decode a storage value.
539///
540/// Unlike [`decode_storage_value`], which obtains the storage info internally given the pallet and storage entry names,
541/// this function takes the storage info as an argument. This is useful if you already have the storage info available,
542/// for example if you are decoding multiple keys for the same storage entry.
543pub fn decode_storage_value_with_info<'scale, 'resolver, V>(
544    cursor: &mut &'scale [u8],
545    storage_info: &crate::storage::StorageInfo<<V::TypeResolver as TypeResolver>::TypeId>,
546    type_resolver: &'resolver V::TypeResolver,
547    visitor: V,
548) -> Result<
549    V::Value<'scale, 'resolver>,
550    StorageValueDecodeError<<V::TypeResolver as TypeResolver>::TypeId>,
551>
552where
553    V: scale_decode::Visitor,
554    V::Error: core::fmt::Debug,
555{
556    let value_id = storage_info.value_id.clone();
557
558    decode_with_error_tracing(cursor, value_id.clone(), type_resolver, visitor).map_err(|e| {
559        StorageValueDecodeError::CannotDecodeValue {
560            ty: value_id,
561            reason: e,
562        }
563    })
564}
565
566fn strip_bytes<'a, T>(
567    cursor: &mut &'a [u8],
568    num: usize,
569) -> Result<&'a [u8], StorageKeyDecodeError<T>> {
570    let bytes = cursor
571        .get(..num)
572        .ok_or_else(|| StorageKeyDecodeError::NotEnoughBytes {
573            needed: num,
574            have: cursor.len(),
575        })?;
576
577    *cursor = &cursor[num..];
578    Ok(bytes)
579}
580
581#[cfg(test)]
582mod test {
583    use super::*;
584
585    #[test]
586    fn test_strip_bytes() {
587        let v = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
588        let cursor = &mut &*v;
589        let stripped = strip_bytes::<()>(cursor, 4).unwrap();
590        assert_eq!(stripped, &[0, 1, 2, 3]);
591        assert_eq!(cursor, &[4, 5, 6, 7, 8]);
592    }
593}