diff --git a/Cargo.toml b/Cargo.toml index e7320b8..0301e7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ exclude = ["/for_tests", "/.github"] base58 = {version = "0.2.0", optional = true} bitvec = {version = "1.0.1", default-features = false, features = ["alloc"]} blake2 = {version = "0.10.6", default-features = false, optional = true} +external-memory-tools = {git = "https://github.com/Alzymologist/external-memory-tools", default-features = false} frame-metadata = {version = "16.0.0", default-features = false, features = ["current", "decode"]} hex = {version = "0.4.3", default-features = false, features = ["alloc"]} num-bigint = {version = "0.4.3", default-features = false} @@ -29,7 +30,7 @@ sp-runtime = {version = "27.0.0", optional = true} [features] default = ["std"] -std = ["plot_icon", "sp-core/std", "sp-runtime/std"] +std = ["external-memory-tools/std", "frame-metadata/std", "plot_icon", "sp-core/std", "sp-runtime/std"] embed-display = ["base58", "blake2"] [lib] diff --git a/src/compacts.rs b/src/compacts.rs index 9ffa996..13634e0 100644 --- a/src/compacts.rs +++ b/src/compacts.rs @@ -1,8 +1,8 @@ //! [`Compact`] search and processing. +use external_memory_tools::{AddressableBuffer, BufferError, ExternalMemory}; use parity_scale_codec::{Compact, Decode, HasCompact}; use crate::error::ParserError; -use crate::traits::{AddressableBuffer, ExternalMemory}; /// Compact found in data. pub struct FoundCompact { @@ -34,10 +34,10 @@ where Compact: Decode, { if data.total_len() < position { - return Err(ParserError::OutOfRange { + return Err(ParserError::Buffer(BufferError::OutOfRange { position, total_length: data.total_len(), - }); + })); } let mut out = None; for i in 0..(data.total_len() - position) { diff --git a/src/decoding_sci.rs b/src/decoding_sci.rs index f1e0ff8..c8bfbf0 100644 --- a/src/decoding_sci.rs +++ b/src/decoding_sci.rs @@ -2,6 +2,9 @@ #[cfg(any(target_pointer_width = "32", test))] use bitvec::prelude::BitOrder; use bitvec::prelude::{BitVec, Lsb0, Msb0}; +#[cfg(any(target_pointer_width = "32", test))] +use external_memory_tools::BufferError; +use external_memory_tools::{AddressableBuffer, ExternalMemory}; use num_bigint::{BigInt, BigUint}; use parity_scale_codec::DecodeAll; use primitive_types::{H160, H512}; @@ -44,7 +47,7 @@ use crate::special_indicators::{ use crate::special_types::{ special_case_era, special_case_h256, wrap_sequence, CheckCompact, UnsignedInteger, }; -use crate::traits::{AddressableBuffer, AsMetadata, ExternalMemory, ResolveType}; +use crate::traits::{AsMetadata, ResolveType}; use crate::MarkedData; /// Finalize parsing of primitives (variants of [`TypeDefPrimitive`]). @@ -208,8 +211,7 @@ where let extrinsic_ty = extrinsic.ty; let types = meta_v14.types(); - let extrinsic_type_params = extrinsic_type_params::(ext_memory, &types, &extrinsic_ty) - .map_err(SignableError::Parsing)?; + let extrinsic_type_params = extrinsic_type_params::(ext_memory, &types, &extrinsic_ty)?; let mut found_all_calls_ty = None; @@ -229,8 +231,7 @@ where position, &types, Propagated::new(), - ) - .map_err(SignableError::Parsing)?; + )?; if let ParsedData::Call(call) = call_extended_data.data { Ok(call) } else { @@ -1097,10 +1098,11 @@ macro_rules! impl_patched { .expect("constant size slice, always fits"), ), Err(_) => { - return Err(ParserError::DataTooShort { + return Err(ParserError::Buffer( + BufferError::DataTooShort { position: bitvec_positions.bitvec_start, minimal_length: bitvec_positions.minimal_length, - }) + })) } } } diff --git a/src/decoding_sci_ext.rs b/src/decoding_sci_ext.rs index 89659ab..bbd0626 100644 --- a/src/decoding_sci_ext.rs +++ b/src/decoding_sci_ext.rs @@ -1,4 +1,5 @@ //! Decode signable transaction extensions using `RuntimeMetadataV14`. +use external_memory_tools::{AddressableBuffer, ExternalMemory}; use primitive_types::H256; #[cfg(not(feature = "std"))] @@ -18,7 +19,7 @@ use crate::error::{ExtensionsError, SignableError}; use crate::propagated::Propagated; use crate::special_indicators::SpecialtyUnsignedInteger; use crate::special_types::UnsignedInteger; -use crate::traits::{AddressableBuffer, AsMetadata, ExternalMemory}; +use crate::traits::AsMetadata; use crate::MarkedData; /// Parse extensions part of the signable transaction [`MarkedData`] using @@ -85,30 +86,24 @@ where let meta_v14_types = meta_v14.types(); let extrinsic = meta_v14.extrinsic().map_err(SignableError::MetaStructure)?; for signed_extensions_metadata in extrinsic.signed_extensions.iter() { - extensions.push( - decode_with_type::( - &Ty::Symbol(&signed_extensions_metadata.ty), - data, - ext_memory, - position, - &meta_v14_types, - Propagated::from_ext_meta(signed_extensions_metadata), - ) - .map_err(SignableError::Parsing)?, - ) + extensions.push(decode_with_type::( + &Ty::Symbol(&signed_extensions_metadata.ty), + data, + ext_memory, + position, + &meta_v14_types, + Propagated::from_ext_meta(signed_extensions_metadata), + )?) } for signed_extensions_metadata in extrinsic.signed_extensions.iter() { - extensions.push( - decode_with_type::( - &Ty::Symbol(&signed_extensions_metadata.additional_signed), - data, - ext_memory, - position, - &meta_v14_types, - Propagated::from_ext_meta(signed_extensions_metadata), - ) - .map_err(SignableError::Parsing)?, - ) + extensions.push(decode_with_type::( + &Ty::Symbol(&signed_extensions_metadata.additional_signed), + data, + ext_memory, + position, + &meta_v14_types, + Propagated::from_ext_meta(signed_extensions_metadata), + )?) } // `position > data.total_len()` is ruled out elsewhere if *position != data.total_len() { diff --git a/src/error.rs b/src/error.rs index 09cae87..edfa1aa 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ //! Errors. +use external_memory_tools::BufferError; use primitive_types::H256; use crate::std::string::String; @@ -12,7 +13,9 @@ use std::{ #[cfg(not(feature = "std"))] use core::fmt::{Display, Formatter, Result as FmtResult}; -use crate::traits::{AsMetadata, ExternalMemory}; +use external_memory_tools::ExternalMemory; + +use crate::traits::AsMetadata; /// Errors in signable transactions parsing. #[derive(Debug, Eq, PartialEq)] @@ -112,66 +115,31 @@ impl StorageError { /// Errors in data parsing. #[derive(Debug, Eq, PartialEq)] pub enum ParserError { - DataTooShort { - position: usize, - minimal_length: usize, - }, - CyclicMetadata { - id: u32, - }, - External(E::ExternalMemoryError), + Buffer(BufferError), + CyclicMetadata { id: u32 }, ExtrinsicNoCallParam, - NoCompact { - position: usize, - }, - NotBitOrderType { - id: u32, - }, - NotBitStoreType { - id: u32, - }, - OutOfRange { - position: usize, - total_length: usize, - }, - SomeDataNotUsedBlob { - from: usize, - }, - TypeFailure { - position: usize, - ty: &'static str, - }, - UnexpectedCompactInsides { - id: u32, - }, - UnexpectedEnumVariant { - position: usize, - }, - UnexpectedExtrinsicType { - extrinsic_ty_id: u32, - }, - V14ShortTypesIncomplete { - old_id: u32, - }, - V14TypeNotResolved { - id: u32, - }, - V14TypeNotResolvedShortened { - id: u32, - }, + NoCompact { position: usize }, + NotBitOrderType { id: u32 }, + NotBitStoreType { id: u32 }, + SomeDataNotUsedBlob { from: usize }, + TypeFailure { position: usize, ty: &'static str }, + UnexpectedCompactInsides { id: u32 }, + UnexpectedEnumVariant { position: usize }, + UnexpectedExtrinsicType { extrinsic_ty_id: u32 }, + V14ShortTypesIncomplete { old_id: u32 }, + V14TypeNotResolved { id: u32 }, + V14TypeNotResolvedShortened { id: u32 }, } impl ParserError { fn error_text(&self) -> String { match &self { - ParserError::DataTooShort { position, minimal_length } => format!("Data is too short for expected content. Expected at least {minimal_length} element(s) after position {position}."), + ParserError::Buffer(buffer_error) => format!("{buffer_error}"), ParserError::CyclicMetadata { id } => format!("Resolving type id {id} in metadata type registry results in cycling."), - ParserError::External(e) => format!("Error accessing external memory. {e}"), ParserError::ExtrinsicNoCallParam => String::from("Extrinsic type in provided metadata has no specified call parameter."), ParserError::NoCompact { position } => format!("Expected compact starting at position {position}, not found one."), ParserError::NotBitOrderType { id } => format!("BitVec type {id} in metadata type registry has unexpected BitOrder type."), ParserError::NotBitStoreType { id } => format!("BitVec type {id} in metadata type registry has unexpected BitStore type."), - ParserError::OutOfRange { position, total_length } => format!("Position {position} is out of range for data length {total_length}."), ParserError::SomeDataNotUsedBlob { from } => format!("Some data (input positions [{from}..]) remained unused after decoding."), ParserError::TypeFailure { position, ty } => format!("Unable to decode data starting at position {position} as {ty}."), ParserError::UnexpectedCompactInsides { id } => format!("Compact type {id} in metadata type registry has unexpected type inside compact."), @@ -276,7 +244,7 @@ pub enum UncheckedExtrinsicError> { NoCallParam, NoExtraParam, NoSignatureParam, - Parser(ParserError), + Parsing(ParserError), VersionMismatch { version_byte: u8, version: u8 }, UnexpectedCallTy { call_ty_id: u32 }, } @@ -294,7 +262,7 @@ where UncheckedExtrinsicError::NoCallParam => String::from("Unchecked extrinsic type in provided metadata has no specified call parameter."), UncheckedExtrinsicError::NoExtraParam => String::from("Unchecked extrinsic type in provided metadata has no specified extra parameter."), UncheckedExtrinsicError::NoSignatureParam => String::from("Unchecked extrinsic type in provided metadata has no specified signature parameter."), - UncheckedExtrinsicError::Parser(parser_error) => format!("Error parsing unchecked extrinsic data. {parser_error}"), + UncheckedExtrinsicError::Parsing(parser_error) => format!("Error parsing unchecked extrinsic data. {parser_error}"), UncheckedExtrinsicError::VersionMismatch { version_byte, version } => format!("Version byte in unchecked extrinsic {version_byte} does not match with version {version} from provided metadata. Last 7 bits were expected to be identical."), UncheckedExtrinsicError::UnexpectedCallTy { call_ty_id } => format!("Parameter type for call {call_ty_id} in metadata type registry is not a call type, and does not match known call type descriptors."), } @@ -326,7 +294,7 @@ impl_display_and_error!(ExtensionsError, MetaVersionErrorPallets); /// Implement [`Display`] for errors in both `std` and `no_std` cases. /// Implement `Error` for `std` case. -macro_rules! impl_display_and_error_traited { +macro_rules! impl_display_and_error_gen { ($($ty: ty), *) => { $( impl Display for $ty { @@ -345,46 +313,52 @@ macro_rules! impl_display_and_error_traited { } } -impl_display_and_error_traited!(ParserError, StorageError); +impl_display_and_error_gen!(ParserError, StorageError); -impl Display for SignableError -where - E: ExternalMemory, - M: AsMetadata, -{ - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "{}", self.error_text()) +impl From> for ParserError { + fn from(buffer_error: BufferError) -> Self { + ParserError::Buffer(buffer_error) } } -#[cfg(feature = "std")] -impl Error for SignableError -where - E: ExternalMemory, - M: AsMetadata, -{ - fn source(&self) -> Option<&(dyn Error + 'static)> { - None - } -} +/// Implement [`Display`] for errors in both `std` and `no_std` cases. +/// Implement `Error` for `std` case. +/// Implement `From>` for simplified error conversion. +macro_rules! impl_display_error_from_2gen { + ($($ty: ty), *) => { + $( + impl Display for $ty + where + E: ExternalMemory, + M: AsMetadata, + { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "{}", self.error_text()) + } + } -impl Display for UncheckedExtrinsicError -where - E: ExternalMemory, - M: AsMetadata, -{ - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "{}", self.error_text()) - } -} + #[cfg(feature = "std")] + impl Error for $ty + where + E: ExternalMemory, + M: AsMetadata, + { + fn source(&self) -> Option<&(dyn Error + 'static)> { + None + } + } -#[cfg(feature = "std")] -impl Error for UncheckedExtrinsicError -where - E: ExternalMemory, - M: AsMetadata, -{ - fn source(&self) -> Option<&(dyn Error + 'static)> { - None + impl From> for $ty + where + E: ExternalMemory, + M: AsMetadata, + { + fn from(parser_error: ParserError) -> Self { + <$ty>::Parsing(parser_error) + } + } + )* } } + +impl_display_error_from_2gen!(SignableError, UncheckedExtrinsicError); diff --git a/src/lib.rs b/src/lib.rs index a91c4a7..67e12fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -455,6 +455,7 @@ #![no_std] #![deny(unused_crate_dependencies)] +pub use external_memory_tools::{AddressableBuffer, ExternalMemory}; use parity_scale_codec::{Decode, Encode}; use primitive_types::H256; use scale_info::interner::UntrackedSymbol; @@ -496,7 +497,7 @@ use core::{any::TypeId, marker::PhantomData}; pub use decoding_sci::{decode_as_call, decode_as_call_unmarked, ResolvedTy}; pub use decoding_sci_ext::{decode_extensions, decode_extensions_unmarked}; -pub use traits::{AddressableBuffer, AsMetadata, ExternalMemory, ResolveType}; +pub use traits::{AsMetadata, ResolveType}; use cards::{Call, ExtendedCard, ExtendedData}; use compacts::get_compact; diff --git a/src/propagated.rs b/src/propagated.rs index c3660e7..a03659c 100644 --- a/src/propagated.rs +++ b/src/propagated.rs @@ -1,4 +1,5 @@ //! Data that can propagate hierarchically during parsing. +use external_memory_tools::ExternalMemory; use frame_metadata::v14::SignedExtensionMetadata; use scale_info::{form::PortableForm, Field, Path, Type}; @@ -7,7 +8,6 @@ use crate::std::vec::Vec; use crate::cards::Info; use crate::error::ParserError; use crate::special_indicators::{Hint, SpecialtyH256, SpecialtyUnsignedInteger}; -use crate::traits::ExternalMemory; /// Type specialty data (type specialty [`Hint`] and compact info) that /// hierarchically propagates during the decoding. diff --git a/src/special_indicators.rs b/src/special_indicators.rs index c7e5ba6..dacb316 100644 --- a/src/special_indicators.rs +++ b/src/special_indicators.rs @@ -7,6 +7,7 @@ //! Additionally, some data should better be decoded directly as the custom type //! mentioned in metadata descriptors, rather than decoded as more generalized //! type and cast into custom type later on. +use external_memory_tools::{AddressableBuffer, ExternalMemory}; use frame_metadata::v14::SignedExtensionMetadata; use scale_info::{form::PortableForm, Field, Path, Type, TypeDef, Variant}; @@ -14,7 +15,7 @@ use crate::std::{borrow::ToOwned, string::String, vec::Vec}; use crate::cards::Info; use crate::decoding_sci::pick_variant; -use crate::traits::{AddressableBuffer, AsMetadata, ExternalMemory, ResolveType}; +use crate::traits::{AsMetadata, ResolveType}; /// [`Field`] `type_name` set indicating that the value *may* be /// currency-related. diff --git a/src/special_types.rs b/src/special_types.rs index e265ba0..cdb5b96 100644 --- a/src/special_types.rs +++ b/src/special_types.rs @@ -1,4 +1,5 @@ //! Decoders for special types: primitives, `PerThing` items, well-known arrays. +use external_memory_tools::{AddressableBuffer, ExternalMemory}; use num_bigint::{BigInt, BigUint}; use parity_scale_codec::{DecodeAll, HasCompact}; use primitive_types::{H160, H256, H512}; @@ -35,7 +36,6 @@ use crate::error::ParserError; use crate::printing_balance::AsBalance; use crate::propagated::SpecialtySet; use crate::special_indicators::{SpecialtyH256, SpecialtyUnsignedInteger}; -use crate::traits::{AddressableBuffer, ExternalMemory}; /// Stable length trait. /// diff --git a/src/storage_data.rs b/src/storage_data.rs index f0bcab1..280a454 100644 --- a/src/storage_data.rs +++ b/src/storage_data.rs @@ -23,6 +23,7 @@ //! //! [`Storage`] contains parsed storage entry data (key, value, and general //! documentation associated with every key with the same prefix). +use external_memory_tools::{AddressableBuffer, ExternalMemory}; use frame_metadata::v14::{StorageEntryMetadata, StorageEntryType, StorageHasher}; use scale_info::{form::PortableForm, interner::UntrackedSymbol, TypeDef}; use sp_core_hashing::{blake2_128, twox_64}; @@ -38,9 +39,9 @@ use core::any::TypeId; use crate::cards::{Documented, ExtendedData, Info}; use crate::decode_all_as_type; use crate::decoding_sci::{decode_with_type, Ty}; -use crate::error::StorageError; +use crate::error::{ParserError, StorageError}; use crate::propagated::Propagated; -use crate::traits::{AddressableBuffer, AsMetadata, ExternalMemory, ResolveType}; +use crate::traits::{AsMetadata, ResolveType}; /// Parsed storage entry data: key, value, general docs. #[derive(Debug, Eq, PartialEq)] @@ -204,7 +205,7 @@ macro_rules! cut_hash { { let slice = key_input .read_slice(ext_memory, *position, $hash_len) - .map_err(StorageError::ParsingKey)?; + .map_err(|e| StorageError::ParsingKey(ParserError::Buffer(e)))?; let hash_part: [u8; $hash_len] = slice .as_ref() .try_into() @@ -245,7 +246,7 @@ macro_rules! check_hash { { let slice = key_input .read_slice(ext_memory, *position, $hash_len) - .map_err(StorageError::ParsingKey)?; + .map_err(|e| StorageError::ParsingKey(ParserError::Buffer(e)))?; let hash_part: [u8; $hash_len] = slice .as_ref() .try_into() diff --git a/src/tests.rs b/src/tests.rs index ded6bc0..d4e8a5e 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -3,6 +3,7 @@ use crate::std::{ string::{String, ToString}, vec::Vec, }; +use external_memory_tools::BufferError; use frame_metadata::v14::{RuntimeMetadataV14, StorageEntryMetadata}; use parity_scale_codec::Decode; use primitive_types::H256; @@ -915,10 +916,10 @@ fn parser_error_6() { // i.e. `88157155` `u8` elements are expected to be found). When all call // data is exhausted, i.e. after element `42` of the data, no new `u8` // element could be found, therefore the error. - let call_error_known = SignableError::Parsing(ParserError::DataTooShort { + let call_error_known = SignableError::Parsing(ParserError::Buffer(BufferError::DataTooShort { position: 42, minimal_length: 1, - }); + })); assert_eq!(call_error_known, call_error); } diff --git a/src/traits.rs b/src/traits.rs index 6503160..64cf4f3 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,12 +1,12 @@ #[cfg(not(feature = "std"))] use core::{ any::TypeId, - fmt::{Debug, Display, Formatter, Result as FmtResult}, + fmt::{Debug, Display}, }; #[cfg(feature = "std")] use std::{ any::TypeId, - fmt::{Debug, Display, Formatter, Result as FmtResult}, + fmt::{Debug, Display}, }; use crate::std::{ @@ -15,6 +15,7 @@ use crate::std::{ vec::Vec, }; +use external_memory_tools::ExternalMemory; use frame_metadata::v14::{ExtrinsicMetadata, PalletMetadata, RuntimeMetadataV14}; use parity_scale_codec::{Decode, Encode}; use scale_info::{form::PortableForm, interner::UntrackedSymbol, PortableRegistry, Type}; @@ -24,75 +25,6 @@ use crate::decode_all_as_type; use crate::error::{MetaVersionErrorPallets, ParserError}; use crate::special_indicators::{SpecialtyStr, SpecialtyUnsignedInteger}; -pub trait ExternalMemory: Debug { - type ExternalMemoryError: Debug + Display + Eq + PartialEq; -} - -impl ExternalMemory for () { - type ExternalMemoryError = NoEntries; -} - -#[derive(Debug, Eq, PartialEq)] -pub enum NoEntries {} - -impl Display for NoEntries { - fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - write!(f, "") - } -} - -pub trait AddressableBuffer { - type ReadBuffer: AsRef<[u8]>; - fn total_len(&self) -> usize; - fn read_slice( - &self, - ext_memory: &mut E, - position: usize, - slice_len: usize, - ) -> Result>; - fn read_byte(&self, ext_memory: &mut E, position: usize) -> Result> { - let byte_slice = self.read_slice(ext_memory, position, 1)?; - Ok(byte_slice.as_ref()[0]) - } - /// Limits the available buffer length to shorter `new_len` provided. - /// - /// If `new_len` exceeds initial `total_len`, panics. This should be - /// used only with pre-checked `new_len`. - /// - /// Mostly for call decoding, so that the input stops when the call ends. - fn limit_length(&self, new_len: usize) -> Self; -} - -impl<'a, E: ExternalMemory> AddressableBuffer for &'a [u8] { - type ReadBuffer = &'a [u8]; - fn total_len(&self) -> usize { - self.len() - } - fn read_slice( - &self, - _ext_memory: &mut E, - position: usize, - slice_len: usize, - ) -> Result> { - if self.len() < position { - return Err(ParserError::OutOfRange { - position, - total_length: self.len(), - }); - } - match self.get(position..position + slice_len) { - Some(a) => Ok(a), - None => Err(ParserError::DataTooShort { - position, - minimal_length: slice_len, - }), - } - } - fn limit_length(&self, new_len: usize) -> Self { - &self[..new_len] - } -} - pub trait AsMetadata: Debug + Sized { type TypeRegistry: ResolveType; type MetaStructureError: Debug + Display + Eq; diff --git a/src/unchecked_extrinsic.rs b/src/unchecked_extrinsic.rs index 8e37f0a..e8f617a 100644 --- a/src/unchecked_extrinsic.rs +++ b/src/unchecked_extrinsic.rs @@ -48,12 +48,14 @@ use std::cmp::Ordering; #[cfg(not(feature = "std"))] use core::cmp::Ordering; +use external_memory_tools::{AddressableBuffer, BufferError, ExternalMemory}; + use crate::cards::{Call, ExtendedData, ParsedData}; use crate::compacts::get_compact; use crate::decode_as_type_at_position; use crate::decoding_sci::{extrinsic_type_params, CALL_INDICATOR}; use crate::error::{ParserError, UncheckedExtrinsicError}; -use crate::traits::{AddressableBuffer, AsMetadata, ExternalMemory}; +use crate::traits::AsMetadata; /// Length of version indicator, 1 byte. const VERSION_LENGTH: usize = 1; @@ -91,8 +93,7 @@ where let meta_v14_types = meta_v14.types(); let extrinsic_type_params = - extrinsic_type_params::(ext_memory, &meta_v14_types, &extrinsic_ty) - .map_err(UncheckedExtrinsicError::Parser)?; + extrinsic_type_params::(ext_memory, &meta_v14_types, &extrinsic_ty)?; // This could have been just a single decode line. // Written this way to: (1) trace position from the start, (2) have descriptive errors @@ -102,13 +103,15 @@ where let len = input.total_len(); match (extrinsic_start + extrinsic_length).cmp(&len) { Ordering::Greater => { - return Err(UncheckedExtrinsicError::Parser(ParserError::DataTooShort { - position: len, - minimal_length: extrinsic_start + extrinsic_length - len, - })) + return Err(UncheckedExtrinsicError::Parsing(ParserError::Buffer( + BufferError::DataTooShort { + position: len, + minimal_length: extrinsic_start + extrinsic_length - len, + }, + ))) } Ordering::Less => { - return Err(UncheckedExtrinsicError::Parser( + return Err(UncheckedExtrinsicError::Parsing( ParserError::SomeDataNotUsedBlob { from: extrinsic_start + extrinsic_length, }, @@ -122,7 +125,7 @@ where // version byte from extrinsic, to diffirentiate signed and unsigned extrinsics let version_byte = input .read_byte(ext_memory, position) - .map_err(UncheckedExtrinsicError::Parser)?; + .map_err(|e| UncheckedExtrinsicError::Parsing(ParserError::Buffer(e)))?; position += VERSION_LENGTH; let version = extrinsic.version; @@ -144,7 +147,7 @@ where } } - let call_ty = found_call.ok_or(UncheckedExtrinsicError::Parser( + let call_ty = found_call.ok_or(UncheckedExtrinsicError::Parsing( ParserError::ExtrinsicNoCallParam, ))?; let call_extended_data = decode_as_type_at_position::( @@ -153,8 +156,7 @@ where ext_memory, &meta_v14_types, &mut position, - ) - .map_err(UncheckedExtrinsicError::Parser)?; + )?; if let ParsedData::Call(call) = call_extended_data.data { Ok(UncheckedExtrinsic::Unsigned { call }) } else { @@ -187,8 +189,7 @@ where ext_memory, &meta_v14_types, &mut position, - ) - .map_err(UncheckedExtrinsicError::Parser)?; + )?; let signature_ty = found_signature.ok_or(UncheckedExtrinsicError::NoSignatureParam)?; let signature = decode_as_type_at_position::( @@ -197,8 +198,7 @@ where ext_memory, &meta_v14_types, &mut position, - ) - .map_err(UncheckedExtrinsicError::Parser)?; + )?; let extra_ty = found_extra.ok_or(UncheckedExtrinsicError::NoExtraParam)?; let extra = decode_as_type_at_position::( @@ -207,8 +207,7 @@ where ext_memory, &meta_v14_types, &mut position, - ) - .map_err(UncheckedExtrinsicError::Parser)?; + )?; let call_ty = found_call.ok_or(UncheckedExtrinsicError::NoCallParam)?; let call_extended_data = decode_as_type_at_position::( @@ -217,8 +216,7 @@ where ext_memory, &meta_v14_types, &mut position, - ) - .map_err(UncheckedExtrinsicError::Parser)?; + )?; if let ParsedData::Call(call) = call_extended_data.data { Ok(UncheckedExtrinsic::Signed { address,