1use super::storage_type_info::{StorageHasher, StorageTypeInfo};
17use crate::decoding::storage_type_info::StorageInfoError;
18use crate::utils::{decode_with_error_tracing, DecodeErrorTrace};
19use alloc::vec;
20use alloc::vec::Vec;
21use core::ops::Range;
22use scale_type_resolver::TypeResolver;
23
24#[non_exhaustive]
26#[allow(missing_docs)]
27#[derive(Clone, Debug)]
28pub enum StorageKeyDecodeError<TypeId> {
29 CannotGetInfo(StorageInfoError<'static>),
30 PrefixMismatch,
31 NotEnoughBytes {
32 needed: usize,
33 have: usize,
34 },
35 CannotDecodeKey {
36 ty: TypeId,
37 reason: DecodeErrorTrace,
38 decoded_so_far: StorageKey<TypeId>,
39 },
40}
41
42impl<TypeId: core::fmt::Debug> core::error::Error for StorageKeyDecodeError<TypeId> {}
43
44impl<TypeId: core::fmt::Debug> core::fmt::Display for StorageKeyDecodeError<TypeId> {
45 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
46 match self {
47 StorageKeyDecodeError::CannotGetInfo(storage_info_error) => {
48 write!(f, "Cannot get storage info:\n\n{storage_info_error}")
49 }
50 StorageKeyDecodeError::PrefixMismatch => {
51 write!(f, "The hashed storage prefix given does not match the pallet and storage name asked to decode.")
52 }
53 StorageKeyDecodeError::NotEnoughBytes { needed, have } => {
54 write!(
55 f,
56 "Not enough bytes left: we need at least {needed} bytes but have {have} bytes"
57 )
58 }
59 StorageKeyDecodeError::CannotDecodeKey {
60 ty,
61 reason,
62 decoded_so_far,
63 } => {
64 write!(f, "Cannot decode storage key '{ty:?}':\n\n{reason}\n\nDecoded so far:\n\n{decoded_so_far}")
65 }
66 }
67 }
68}
69
70impl<TypeId> StorageKeyDecodeError<TypeId> {
71 pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKeyDecodeError<NewTypeId>
73 where
74 F: FnMut(TypeId) -> NewTypeId,
75 {
76 match self {
77 StorageKeyDecodeError::CannotGetInfo(e) => StorageKeyDecodeError::CannotGetInfo(e),
78 StorageKeyDecodeError::PrefixMismatch => StorageKeyDecodeError::PrefixMismatch,
79 StorageKeyDecodeError::NotEnoughBytes { needed, have } => {
80 StorageKeyDecodeError::NotEnoughBytes { needed, have }
81 }
82 StorageKeyDecodeError::CannotDecodeKey {
83 ty,
84 reason,
85 decoded_so_far,
86 } => StorageKeyDecodeError::CannotDecodeKey {
87 ty: f(ty),
88 reason,
89 decoded_so_far: decoded_so_far.map_type_id(f),
90 },
91 }
92 }
93}
94
95#[non_exhaustive]
97#[allow(missing_docs)]
98#[derive(Clone, Debug)]
99pub enum StorageValueDecodeError<TypeId> {
100 CannotGetInfo(StorageInfoError<'static>),
101 CannotDecodeValue {
102 ty: TypeId,
103 reason: DecodeErrorTrace,
104 },
105}
106
107impl<TypeId: core::fmt::Debug> core::error::Error for StorageValueDecodeError<TypeId> {}
108
109impl<TypeId: core::fmt::Debug> core::fmt::Display for StorageValueDecodeError<TypeId> {
110 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
111 match self {
112 StorageValueDecodeError::CannotGetInfo(storage_info_error) => {
113 write!(f, "Cannot get storage info:\n\n{storage_info_error}")
114 }
115 StorageValueDecodeError::CannotDecodeValue { ty, reason } => {
116 write!(f, "Cannot decode value with type ID {ty:?}:\n\n{reason}")
117 }
118 }
119 }
120}
121
122impl<TypeId> StorageValueDecodeError<TypeId> {
123 pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageValueDecodeError<NewTypeId>
125 where
126 F: FnMut(TypeId) -> NewTypeId,
127 {
128 match self {
129 StorageValueDecodeError::CannotGetInfo(e) => StorageValueDecodeError::CannotGetInfo(e),
130 StorageValueDecodeError::CannotDecodeValue { ty, reason } => {
131 StorageValueDecodeError::CannotDecodeValue { ty: f(ty), reason }
132 }
133 }
134 }
135}
136
137#[derive(Clone, Debug)]
139pub struct StorageKey<TypeId> {
140 parts: Vec<StorageKeyPart<TypeId>>,
141}
142
143impl<TypeId: core::fmt::Debug> core::fmt::Display for StorageKey<TypeId> {
144 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
145 if self.parts.is_empty() {
147 write!(f, "No storage parts")?;
148 return Ok(());
149 }
150
151 for key in self.parts.iter() {
158 writeln!(f, "Hash type: {:?}", key.hasher)?;
159 writeln!(
160 f,
161 "Hash range: {}..{}",
162 key.hash_range.start, key.hash_range.end
163 )?;
164 if let Some(v) = &key.value {
165 writeln!(f, "Value type: {:?}", v.ty)?;
166 writeln!(f, "Value range: {}..{}", v.range.start, v.range.end)?;
167 }
168
169 writeln!(f)?;
170 }
171
172 Ok(())
173 }
174}
175
176impl<TypeId> StorageKey<TypeId> {
177 pub fn parts(&self) -> impl ExactSizeIterator<Item = &StorageKeyPart<TypeId>> {
179 self.parts.iter()
180 }
181
182 pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKey<NewTypeId>
184 where
185 F: FnMut(TypeId) -> NewTypeId,
186 {
187 StorageKey {
188 parts: self
189 .parts
190 .into_iter()
191 .map(|p| p.map_type_id(&mut f))
192 .collect(),
193 }
194 }
195}
196
197#[derive(Clone, Debug)]
199pub struct StorageKeyPart<TypeId> {
200 hash_range: Range<u32>,
201 value: Option<StorageKeyPartValue<TypeId>>,
202 hasher: StorageHasher,
203}
204
205impl<TypeId> StorageKeyPart<TypeId> {
206 pub fn hash_range(&self) -> Range<usize> {
208 Range {
209 start: self.hash_range.start as usize,
210 end: self.hash_range.end as usize,
211 }
212 }
213
214 pub fn hasher(&self) -> StorageHasher {
216 self.hasher
217 }
218
219 pub fn value(&self) -> Option<&StorageKeyPartValue<TypeId>> {
222 self.value.as_ref()
223 }
224
225 pub fn map_type_id<NewTypeId, F>(self, f: F) -> StorageKeyPart<NewTypeId>
227 where
228 F: FnMut(TypeId) -> NewTypeId,
229 {
230 StorageKeyPart {
231 hash_range: self.hash_range,
232 value: self.value.map(|v| v.map_type_id(f)),
233 hasher: self.hasher,
234 }
235 }
236}
237
238#[derive(Clone, Debug)]
240pub struct StorageKeyPartValue<TypeId> {
241 range: Range<u32>,
242 ty: TypeId,
243}
244
245impl<TypeId> StorageKeyPartValue<TypeId> {
246 pub fn range(&self) -> Range<usize> {
248 Range {
249 start: self.range.start as usize,
250 end: self.range.end as usize,
251 }
252 }
253
254 pub fn ty(&self) -> &TypeId {
256 &self.ty
257 }
258
259 pub fn map_type_id<NewTypeId, F>(self, mut f: F) -> StorageKeyPartValue<NewTypeId>
261 where
262 F: FnMut(TypeId) -> NewTypeId,
263 {
264 StorageKeyPartValue {
265 range: self.range,
266 ty: f(self.ty),
267 }
268 }
269}
270
271pub fn decode_storage_key<Info, Resolver>(
324 pallet_name: &str,
325 storage_entry: &str,
326 cursor: &mut &[u8],
327 info: &Info,
328 type_resolver: &Resolver,
329) -> Result<StorageKey<Info::TypeId>, StorageKeyDecodeError<Info::TypeId>>
330where
331 Info: StorageTypeInfo,
332 Info::TypeId: Clone + core::fmt::Debug,
333 Resolver: TypeResolver<TypeId = Info::TypeId>,
334{
335 let storage_info = info
336 .get_storage_info(pallet_name, storage_entry)
337 .map_err(|e| StorageKeyDecodeError::CannotGetInfo(e.into_owned()))?;
338
339 let bytes = *cursor;
340 let curr_idx = |cursor: &mut &[u8]| (bytes.len() - cursor.len()) as u32;
341
342 let prefix = strip_bytes(cursor, 32)?;
343
344 let expected_prefix = {
346 let mut v = Vec::<u8>::with_capacity(16);
347 v.extend(&sp_crypto_hashing::twox_128(pallet_name.as_bytes()));
348 v.extend(&sp_crypto_hashing::twox_128(storage_entry.as_bytes()));
349 v
350 };
351 if prefix != expected_prefix {
352 return Err(StorageKeyDecodeError::PrefixMismatch);
353 }
354
355 let mut parts = vec![];
356 for key in storage_info.keys {
357 let hasher = key.hasher;
358 let start_idx = curr_idx(cursor);
359 let part = match &hasher {
360 StorageHasher::Blake2_128 | StorageHasher::Twox128 => {
361 strip_bytes(cursor, 16)?;
362 StorageKeyPart {
363 hash_range: Range {
364 start: start_idx,
365 end: curr_idx(cursor),
366 },
367 value: None,
368 hasher,
369 }
370 }
371 StorageHasher::Blake2_256 | StorageHasher::Twox256 => {
372 strip_bytes(cursor, 32)?;
373 StorageKeyPart {
374 hash_range: Range {
375 start: start_idx,
376 end: curr_idx(cursor),
377 },
378 value: None,
379 hasher,
380 }
381 }
382 StorageHasher::Blake2_128Concat => {
383 strip_bytes(cursor, 16)?;
384 let hash_end_idx = curr_idx(cursor);
385 decode_with_error_tracing(
386 cursor,
387 key.key_id.clone(),
388 type_resolver,
389 scale_decode::visitor::IgnoreVisitor::new(),
390 )
391 .map_err(|e| StorageKeyDecodeError::CannotDecodeKey {
392 ty: key.key_id.clone(),
393 reason: e,
394 decoded_so_far: StorageKey {
395 parts: parts.clone(),
396 },
397 })?;
398 StorageKeyPart {
399 hash_range: Range {
400 start: start_idx,
401 end: hash_end_idx,
402 },
403 value: Some(StorageKeyPartValue {
404 range: Range {
405 start: hash_end_idx,
406 end: curr_idx(cursor),
407 },
408 ty: key.key_id,
409 }),
410 hasher,
411 }
412 }
413 StorageHasher::Twox64Concat => {
414 strip_bytes(cursor, 8)?;
415 let hash_end_idx = curr_idx(cursor);
416 decode_with_error_tracing(
417 cursor,
418 key.key_id.clone(),
419 type_resolver,
420 scale_decode::visitor::IgnoreVisitor::new(),
421 )
422 .map_err(|e| StorageKeyDecodeError::CannotDecodeKey {
423 ty: key.key_id.clone(),
424 reason: e,
425 decoded_so_far: StorageKey {
426 parts: parts.clone(),
427 },
428 })?;
429 StorageKeyPart {
430 hash_range: Range {
431 start: start_idx,
432 end: hash_end_idx,
433 },
434 value: Some(StorageKeyPartValue {
435 range: Range {
436 start: hash_end_idx,
437 end: curr_idx(cursor),
438 },
439 ty: key.key_id,
440 }),
441 hasher,
442 }
443 }
444 StorageHasher::Identity => {
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: start_idx,
462 },
463 value: Some(StorageKeyPartValue {
464 range: Range {
465 start: start_idx,
466 end: curr_idx(cursor),
467 },
468 ty: key.key_id,
469 }),
470 hasher,
471 }
472 }
473 };
474 parts.push(part)
475 }
476
477 Ok(StorageKey { parts })
478}
479
480pub fn decode_storage_value<'scale, 'resolver, Info, Resolver, V>(
514 pallet_name: &str,
515 storage_entry: &str,
516 cursor: &mut &'scale [u8],
517 info: &Info,
518 type_resolver: &'resolver Resolver,
519 visitor: V,
520) -> Result<V::Value<'scale, 'resolver>, StorageValueDecodeError<Info::TypeId>>
521where
522 Info: StorageTypeInfo,
523 Info::TypeId: Clone + core::fmt::Debug,
524 Resolver: TypeResolver<TypeId = Info::TypeId>,
525 V: scale_decode::Visitor<TypeResolver = Resolver>,
526 V::Error: core::fmt::Debug,
527{
528 let storage_info = info
529 .get_storage_info(pallet_name, storage_entry)
530 .map_err(|e| StorageValueDecodeError::CannotGetInfo(e.into_owned()))?;
531
532 let value_id = storage_info.value_id;
533
534 let decoded = decode_with_error_tracing(cursor, value_id.clone(), type_resolver, visitor)
535 .map_err(|e| StorageValueDecodeError::CannotDecodeValue {
536 ty: value_id,
537 reason: e,
538 })?;
539
540 Ok(decoded)
541}
542
543fn strip_bytes<'a, T>(
544 cursor: &mut &'a [u8],
545 num: usize,
546) -> Result<&'a [u8], StorageKeyDecodeError<T>> {
547 let bytes = cursor
548 .get(..num)
549 .ok_or_else(|| StorageKeyDecodeError::NotEnoughBytes {
550 needed: num,
551 have: cursor.len(),
552 })?;
553
554 *cursor = &cursor[num..];
555 Ok(bytes)
556}
557
558#[cfg(test)]
559mod test {
560 use super::*;
561
562 #[test]
563 fn test_strip_bytes() {
564 let v = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
565 let cursor = &mut &*v;
566 let stripped = strip_bytes::<()>(cursor, 4).unwrap();
567 assert_eq!(stripped, &[0, 1, 2, 3]);
568 assert_eq!(cursor, &[4, 5, 6, 7, 8]);
569 }
570}