1use 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#[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 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#[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 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#[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 if self.parts.is_empty() {
123 write!(f, "No storage parts")?;
124 return Ok(());
125 }
126
127 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 pub fn parts(&self) -> impl ExactSizeIterator<Item = &StorageKeyPart<TypeId>> {
162 self.parts.iter()
163 }
164
165 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#[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 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 pub fn hasher(&self) -> StorageHasher {
199 self.hasher
200 }
201
202 pub fn value(&self) -> Option<&StorageKeyPartValue<TypeId>> {
205 self.value.as_ref()
206 }
207
208 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#[derive(Clone, Debug)]
223pub struct StorageKeyPartValue<TypeId> {
224 range: Range<u32>,
225 ty: TypeId,
226}
227
228impl<TypeId> StorageKeyPartValue<TypeId> {
229 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 pub fn ty(&self) -> &TypeId {
239 &self.ty
240 }
241
242 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
254pub 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 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
331pub 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
483pub 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
538pub 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}