From 56f471063e87505b0d73b5c68b9e9964fe44d008 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 28 Mar 2022 18:23:42 +0300 Subject: [PATCH 01/14] codegen: Handle new errors of type [u8; 4] with backwards compatibility Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 56 +++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index 625e94d40b..7a14bbacfe 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -42,7 +42,9 @@ pub fn generate_has_module_error_impl( // variant. Newer versions have something like a `DispatchError::Module (Details)` variant. // We check to see which type of variant we're dealing with based on the metadata, and // generate the correct code to handle either older or newer substrate versions. - let module_variant_is_struct = if let TypeDef::Variant(details) = dispatch_error_def { + let (module_variant_is_struct, module_legacy_err) = if let TypeDef::Variant(details) = + dispatch_error_def + { let module_variant = details .variants() .iter() @@ -50,19 +52,39 @@ pub fn generate_has_module_error_impl( .unwrap_or_else(|| { abort_call_site!("DispatchError::Module variant expected in metadata") }); - let are_fields_named = module_variant - .fields() - .get(0) - .unwrap_or_else(|| { - abort_call_site!( - "DispatchError::Module expected to contain 1 or more fields" - ) - }) - .name() - .is_some(); - are_fields_named + + let module_field = module_variant.fields().get(0).unwrap_or_else(|| { + abort_call_site!("DispatchError::Module expected to contain 1 or more fields") + }); + if module_field.name().is_none() { + let module_err = metadata + .types + .resolve(module_field.ty().id()) + .unwrap_or_else(|| { + abort_call_site!("sp_runtime::ModuleError type expected in metadata") + }); + + if let TypeDef::Composite(composite) = module_err.type_def() { + let error_field = composite + .fields() + .iter() + .find(|field| field.name() == Some(&"error".to_string())) + .unwrap_or_else(|| { + abort_call_site!( + "sp_runtime::ModuleError expected to contain error field" + ) + }); + // Avoid further metadata inspection by relying on type name information + // (the name of the type of the field as it appears in the source code) + (false, error_field.type_name() == Some(&"[u8]".to_string())) + } else { + (false, false) + } + } else { + (true, false) + } } else { - false + (false, false) }; let trait_fn_body = if module_variant_is_struct { @@ -74,9 +96,15 @@ pub fn generate_has_module_error_impl( } } } else { + let error_conversion = if module_legacy_err { + quote! { module_error.error } + } else { + quote! { module_error.error[0] } + }; + quote! { if let Self::Module (module_error) = self { - Some((module_error.index, module_error.error)) + Some((module_error.index, #error_conversion)) } else { None } From c3da1938a437eaa2a689d64e448fa37852996852 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 28 Mar 2022 18:35:40 +0300 Subject: [PATCH 02/14] codegen: Add comments about the compatibility of `DispatchError::Module` Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index 7a14bbacfe..6483a9bc18 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -38,10 +38,20 @@ pub fn generate_has_module_error_impl( .ty() .type_def(); - // Slightly older versions of substrate have a `DispatchError::Module { index, error }` - // variant. Newer versions have something like a `DispatchError::Module (Details)` variant. - // We check to see which type of variant we're dealing with based on the metadata, and - // generate the correct code to handle either older or newer substrate versions. + // Different substrate versions will have a `DispatchError::Module` of the following form, + // ordered by versions: + // + // Case 1. DispatchError::Module { index: u8, error: u8 } + // Case 2. DispatchError::Module ( sp_runtime::ModuleError { index: u8, error: u8 } ) + // Case 3. DispatchError::Module ( sp_runtime::ModuleError { index: u8, error: [u8; 4] } ) + // + // To handle all cases and maintain backward compatibility, the type of the variant is inspected + // based on the metadata. + // If the variant has a named field (i.e, Case 1) the variable `module_variant_is_struct` is + // true. If the error is of form `u8`, then `module_legacy_err` is True. + // + // Note: Legacy errors are present in Case 1 and Case 2. Therefore, newer errors are possibly + // encountered in Case 3s, the unnamed field case. let (module_variant_is_struct, module_legacy_err) = if let TypeDef::Variant(details) = dispatch_error_def { @@ -99,6 +109,7 @@ pub fn generate_has_module_error_impl( let error_conversion = if module_legacy_err { quote! { module_error.error } } else { + // Convert [u8; 4] errors to legacy format. quote! { module_error.error[0] } }; From 6e84862834bf1e2ce76b01d4b2c87f6cfae712d8 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 28 Mar 2022 18:50:19 +0300 Subject: [PATCH 03/14] codegen: Handle legacy cases appropriately Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index 6483a9bc18..b2dd97fc4d 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -86,15 +86,15 @@ pub fn generate_has_module_error_impl( }); // Avoid further metadata inspection by relying on type name information // (the name of the type of the field as it appears in the source code) - (false, error_field.type_name() == Some(&"[u8]".to_string())) + (false, error_field.type_name() == Some(&"u8".to_string())) } else { - (false, false) + (false, true) } } else { - (true, false) + (true, true) } } else { - (false, false) + (false, true) }; let trait_fn_body = if module_variant_is_struct { From 20b23eb6cf7982a1fc28bf68d3236385f6b6de3e Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 29 Mar 2022 13:15:55 +0300 Subject: [PATCH 04/14] codegen: Introduce `ModuleErrorType` for compatibility versioning Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index b2dd97fc4d..9d086f375f 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -20,6 +20,23 @@ use proc_macro_error::abort_call_site; use quote::quote; use scale_info::TypeDef; +/// Different substrate versions will have a different `DispatchError::Module`. +/// The following cases are ordered by versions. +enum ModuleErrorType { + /// Case 1: `DispatchError::Module { index: u8, error: u8 }` + /// + /// This is the first supported `DispatchError::Module` format. + NamedField, + /// Case 2: `DispatchError::Module ( sp_runtime::ModuleError { index: u8, error: u8 } )` + /// + /// Substrate introduced `sp_runtime::ModuleError`, while keeping the error `u8`. + LegacyError, + /// Case 3: `DispatchError::Module ( sp_runtime::ModuleError { index: u8, error: [u8; 4] } )` + /// + /// The substrate error evolved into `[u8; 4]`. + ErrorArray, +} + /// The aim of this is to implement the `::subxt::HasModuleError` trait for /// the generated `DispatchError`, so that we can obtain the module error details, /// if applicable, from it. From 3ce61f462c89c7318faa3d14485d874ec967d550 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 29 Mar 2022 14:48:44 +0300 Subject: [PATCH 05/14] codegen: Implement `module_error_type` helper Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 162 ++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 76 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index 9d086f375f..b337960730 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -18,7 +18,11 @@ use frame_metadata::v14::RuntimeMetadataV14; use proc_macro2::TokenStream as TokenStream2; use proc_macro_error::abort_call_site; use quote::quote; -use scale_info::TypeDef; +use scale_info::{ + form::PortableForm, + Field, + TypeDef, +}; /// Different substrate versions will have a different `DispatchError::Module`. /// The following cases are ordered by versions. @@ -37,6 +41,46 @@ enum ModuleErrorType { ErrorArray, } +/// Determine the `ModuleError` type for the `ModuleErrorType::LegacyError` and +/// `ModuleErrorType::ErrorArray` cases. +fn module_error_type( + module_field: &Field, + metadata: &RuntimeMetadataV14, +) -> ModuleErrorType { + // Fields are named. + if module_field.name().is_some() { + return ModuleErrorType::NamedField + } + + // Get the `sp_runtime::ModuleError` structure. + let module_err = metadata + .types + .resolve(module_field.ty().id()) + .unwrap_or_else(|| { + abort_call_site!("sp_runtime::ModuleError type expected in metadata") + }); + + let error_type_def = match module_err.type_def() { + TypeDef::Composite(composite) => composite, + _ => abort_call_site!("sp_runtime::ModuleError type should be a composite type"), + }; + + // Get the error field from the `sp_runtime::ModuleError` structure. + let error_field = error_type_def + .fields() + .iter() + .find(|field| field.name() == Some(&"error".to_string())) + .unwrap_or_else(|| { + abort_call_site!("sp_runtime::ModuleError expected to contain error field") + }); + + if error_field.type_name() == Some(&"u8".to_string()) { + ModuleErrorType::LegacyError + } else { + ModuleErrorType::ErrorArray + } +} + /// The aim of this is to implement the `::subxt::HasModuleError` trait for /// the generated `DispatchError`, so that we can obtain the module error details, /// if applicable, from it. @@ -44,7 +88,7 @@ pub fn generate_has_module_error_impl( metadata: &RuntimeMetadataV14, types_mod_ident: &syn::Ident, ) -> TokenStream2 { - let dispatch_error_def = metadata + let dispatch_error = metadata .types .types() .iter() @@ -55,86 +99,52 @@ pub fn generate_has_module_error_impl( .ty() .type_def(); - // Different substrate versions will have a `DispatchError::Module` of the following form, - // ordered by versions: - // - // Case 1. DispatchError::Module { index: u8, error: u8 } - // Case 2. DispatchError::Module ( sp_runtime::ModuleError { index: u8, error: u8 } ) - // Case 3. DispatchError::Module ( sp_runtime::ModuleError { index: u8, error: [u8; 4] } ) - // - // To handle all cases and maintain backward compatibility, the type of the variant is inspected - // based on the metadata. - // If the variant has a named field (i.e, Case 1) the variable `module_variant_is_struct` is - // true. If the error is of form `u8`, then `module_legacy_err` is True. - // - // Note: Legacy errors are present in Case 1 and Case 2. Therefore, newer errors are possibly - // encountered in Case 3s, the unnamed field case. - let (module_variant_is_struct, module_legacy_err) = if let TypeDef::Variant(details) = - dispatch_error_def - { - let module_variant = details - .variants() - .iter() - .find(|variant| variant.name() == "Module") - .unwrap_or_else(|| { - abort_call_site!("DispatchError::Module variant expected in metadata") - }); - - let module_field = module_variant.fields().get(0).unwrap_or_else(|| { - abort_call_site!("DispatchError::Module expected to contain 1 or more fields") - }); - if module_field.name().is_none() { - let module_err = metadata - .types - .resolve(module_field.ty().id()) + // Get the `DispatchError::Module` variant (either struct or named fields). + let module_variant = match dispatch_error { + TypeDef::Variant(variant) => { + variant + .variants() + .iter() + .find(|variant| variant.name() == "Module") .unwrap_or_else(|| { - abort_call_site!("sp_runtime::ModuleError type expected in metadata") - }); - - if let TypeDef::Composite(composite) = module_err.type_def() { - let error_field = composite - .fields() - .iter() - .find(|field| field.name() == Some(&"error".to_string())) - .unwrap_or_else(|| { - abort_call_site!( - "sp_runtime::ModuleError expected to contain error field" - ) - }); - // Avoid further metadata inspection by relying on type name information - // (the name of the type of the field as it appears in the source code) - (false, error_field.type_name() == Some(&"u8".to_string())) - } else { - (false, true) - } - } else { - (true, true) + abort_call_site!("DispatchError::Module variant expected in metadata") + }) } - } else { - (false, true) + _ => abort_call_site!("DispatchError expected to contain variant in metadata"), }; - let trait_fn_body = if module_variant_is_struct { - quote! { - if let &Self::Module { index, error } = self { - Some((index, error)) - } else { - None + let module_field = module_variant.fields().get(0).unwrap_or_else(|| { + abort_call_site!("DispatchError::Module expected to contain 1 or more fields") + }); + + let error_type = module_error_type(module_field, metadata); + + let trait_fn_body = match error_type { + ModuleErrorType::NamedField => { + quote! { + if let &Self::Module { index, error } = self { + Some((index, error)) + } else { + None + } } } - } else { - let error_conversion = if module_legacy_err { - quote! { module_error.error } - } else { - // Convert [u8; 4] errors to legacy format. - quote! { module_error.error[0] } - }; - - quote! { - if let Self::Module (module_error) = self { - Some((module_error.index, #error_conversion)) - } else { - None + ModuleErrorType::LegacyError => { + quote! { + if let Self::Module (module_error) = self { + Some((module_error.index, module_error.error)) + } else { + None + } + } + } + ModuleErrorType::ErrorArray => { + quote! { + if let Self::Module (module_error) = self { + Some((module_error.index, module_error.error[0])) + } else { + None + } } } }; From 2f19bca6e79997729eef09fed5bba313e4454215 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 29 Mar 2022 14:58:19 +0300 Subject: [PATCH 06/14] codegen: Implement `quote::ToTokens` for `ModuleErrorType` Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 68 +++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index b337960730..a6573907a2 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -41,6 +41,42 @@ enum ModuleErrorType { ErrorArray, } +impl quote::ToTokens for ModuleErrorType { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let trait_fn_body = match self { + ModuleErrorType::NamedField => { + quote! { + if let &Self::Module { index, error } = self { + Some((index, error)) + } else { + None + } + } + } + ModuleErrorType::LegacyError => { + quote! { + if let Self::Module (module_error) = self { + Some((module_error.index, module_error.error)) + } else { + None + } + } + } + ModuleErrorType::ErrorArray => { + quote! { + if let Self::Module (module_error) = self { + Some((module_error.index, module_error.error[0])) + } else { + None + } + } + } + }; + + tokens.extend(trait_fn_body); + } +} + /// Determine the `ModuleError` type for the `ModuleErrorType::LegacyError` and /// `ModuleErrorType::ErrorArray` cases. fn module_error_type( @@ -119,40 +155,10 @@ pub fn generate_has_module_error_impl( let error_type = module_error_type(module_field, metadata); - let trait_fn_body = match error_type { - ModuleErrorType::NamedField => { - quote! { - if let &Self::Module { index, error } = self { - Some((index, error)) - } else { - None - } - } - } - ModuleErrorType::LegacyError => { - quote! { - if let Self::Module (module_error) = self { - Some((module_error.index, module_error.error)) - } else { - None - } - } - } - ModuleErrorType::ErrorArray => { - quote! { - if let Self::Module (module_error) = self { - Some((module_error.index, module_error.error[0])) - } else { - None - } - } - } - }; - quote! { impl ::subxt::HasModuleError for #types_mod_ident::sp_runtime::DispatchError { fn module_error_indices(&self) -> Option<(u8,u8)> { - #trait_fn_body + #error_type } } } From e949546dd93d695556b71881db4cd67ed49ba5e2 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 29 Mar 2022 14:59:13 +0300 Subject: [PATCH 07/14] codegen: Rename new error to ArrayError Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index a6573907a2..a144051e6e 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -38,7 +38,7 @@ enum ModuleErrorType { /// Case 3: `DispatchError::Module ( sp_runtime::ModuleError { index: u8, error: [u8; 4] } )` /// /// The substrate error evolved into `[u8; 4]`. - ErrorArray, + ArrayError, } impl quote::ToTokens for ModuleErrorType { @@ -62,7 +62,7 @@ impl quote::ToTokens for ModuleErrorType { } } } - ModuleErrorType::ErrorArray => { + ModuleErrorType::ArrayError => { quote! { if let Self::Module (module_error) = self { Some((module_error.index, module_error.error[0])) @@ -113,7 +113,7 @@ fn module_error_type( if error_field.type_name() == Some(&"u8".to_string()) { ModuleErrorType::LegacyError } else { - ModuleErrorType::ErrorArray + ModuleErrorType::ArrayError } } From f02146fb3cc9f51c7d5d4ad57f697ccb9b2af961 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Wed, 30 Mar 2022 12:43:31 +0300 Subject: [PATCH 08/14] codegen: Add strict checks for ModuleError Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 46 +++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index a144051e6e..5bac2ce434 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -22,6 +22,7 @@ use scale_info::{ form::PortableForm, Field, TypeDef, + TypeDefPrimitive, }; /// Different substrate versions will have a different `DispatchError::Module`. @@ -110,10 +111,47 @@ fn module_error_type( abort_call_site!("sp_runtime::ModuleError expected to contain error field") }); - if error_field.type_name() == Some(&"u8".to_string()) { - ModuleErrorType::LegacyError - } else { - ModuleErrorType::ArrayError + // Resolve the error type from the metadata. + let error_field_ty = metadata + .types + .resolve(error_field.ty().id()) + .unwrap_or_else(|| { + abort_call_site!("sp_runtime::ModuleError::error type expected in metadata") + }); + + match error_field_ty.type_def() { + // Check for legacy error type. + TypeDef::Primitive(TypeDefPrimitive::U8) => ModuleErrorType::LegacyError, + TypeDef::Array(array) => { + // Check new error type of len 4 and type u8. + if array.len() != 4 { + abort_call_site!( + "sp_runtime::ModuleError::error array length is not 4" + ); + } + + let array_ty = metadata + .types + .resolve(array.type_param().id()) + .unwrap_or_else(|| { + abort_call_site!( + "sp_runtime::ModuleError::error array type expected in metadata" + ) + }); + + if let TypeDef::Primitive(TypeDefPrimitive::U8) = array_ty.type_def() { + ModuleErrorType::ArrayError + } else { + abort_call_site!( + "sp_runtime::ModuleError::error array type expected to be u8" + ) + } + } + _ => { + abort_call_site!( + "sp_runtime::ModuleError::error array type or primitive expected" + ) + } } } From 0edb276ddbd18490eb18ad7e0098846b9ca80fc4 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Wed, 30 Mar 2022 12:47:52 +0300 Subject: [PATCH 09/14] codegen: Fix cargo fmt Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index 5bac2ce434..1315fcc32a 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -125,9 +125,7 @@ fn module_error_type( TypeDef::Array(array) => { // Check new error type of len 4 and type u8. if array.len() != 4 { - abort_call_site!( - "sp_runtime::ModuleError::error array length is not 4" - ); + abort_call_site!("sp_runtime::ModuleError::error array length is not 4"); } let array_ty = metadata From 948b94be153640db9162dcdd8cf65144dbb436f5 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Wed, 30 Mar 2022 14:47:56 +0300 Subject: [PATCH 10/14] codegen, subxt: Expose the error's raw bytes to user Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 8 ++++---- subxt/src/error.rs | 16 +++++++++++++++- subxt/src/lib.rs | 1 + subxt/src/transaction.rs | 11 +++++++---- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index 1315fcc32a..78b312808a 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -48,7 +48,7 @@ impl quote::ToTokens for ModuleErrorType { ModuleErrorType::NamedField => { quote! { if let &Self::Module { index, error } = self { - Some((index, error)) + Some(::subxt::ModuleErrorRaw { pallet_index: index, error: [error, 0, 0, 0] }) } else { None } @@ -57,7 +57,7 @@ impl quote::ToTokens for ModuleErrorType { ModuleErrorType::LegacyError => { quote! { if let Self::Module (module_error) = self { - Some((module_error.index, module_error.error)) + Some(::subxt::ModuleErrorRaw { pallet_index: module_error.index, error: [module_error.error, 0, 0, 0] }) } else { None } @@ -66,7 +66,7 @@ impl quote::ToTokens for ModuleErrorType { ModuleErrorType::ArrayError => { quote! { if let Self::Module (module_error) = self { - Some((module_error.index, module_error.error[0])) + Some(::subxt::ModuleErrorRaw { pallet_index: module_error.index, error: module_error.error }) } else { None } @@ -193,7 +193,7 @@ pub fn generate_has_module_error_impl( quote! { impl ::subxt::HasModuleError for #types_mod_ident::sp_runtime::DispatchError { - fn module_error_indices(&self) -> Option<(u8,u8)> { + fn module_error_indices(&self) -> Option<::subxt::ModuleErrorRaw> { #error_type } } diff --git a/subxt/src/error.rs b/subxt/src/error.rs index 4d2bebeacd..b62ab9d2ab 100644 --- a/subxt/src/error.rs +++ b/subxt/src/error.rs @@ -182,6 +182,20 @@ pub struct ModuleError { pub error: String, /// A description of the error. pub description: Vec, + /// A raw byte representation of the error. + pub raw: ModuleErrorRaw, +} + +/// The raw error details about a module error that has occurred. +/// +/// **Note**: Structure used to obtain the underlying bytes of a ModuleError. +#[derive(Clone, Debug, thiserror::Error)] +#[error("Pallet index {pallet_index}: raw error: {error:?}")] +pub struct ModuleErrorRaw { + /// Index of the pallet that the error came from. + pub pallet_index: u8, + /// Raw error bytes. + pub error: [u8; 4], } /// This trait is automatically implemented for the generated `DispatchError`, @@ -190,5 +204,5 @@ pub struct ModuleError { pub trait HasModuleError { /// If the error has a `Module` variant, return a tuple of the /// pallet index and error index. Else, return `None`. - fn module_error_indices(&self) -> Option<(u8, u8)>; + fn module_error_indices(&self) -> Option; } diff --git a/subxt/src/lib.rs b/subxt/src/lib.rs index dc4e1e2723..b8a3c59af2 100644 --- a/subxt/src/lib.rs +++ b/subxt/src/lib.rs @@ -81,6 +81,7 @@ pub use crate::{ Error, GenericError, HasModuleError, + ModuleErrorRaw, RuntimeError, TransactionError, }, diff --git a/subxt/src/transaction.rs b/subxt/src/transaction.rs index e0a781287d..50add125d7 100644 --- a/subxt/src/transaction.rs +++ b/subxt/src/transaction.rs @@ -389,14 +389,17 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode> let ev = ev?; if &ev.pallet == "System" && &ev.variant == "ExtrinsicFailed" { let dispatch_error = E::decode(&mut &*ev.data)?; - if let Some((pallet_idx, error_idx)) = - dispatch_error.module_error_indices() - { - let details = self.client.metadata().error(pallet_idx, error_idx)?; + if let Some(raw_error) = dispatch_error.module_error_indices() { + // Error index is utilized as the first byte from the error array. + let details = self + .client + .metadata() + .error(raw_error.pallet_index, raw_error.error[0])?; return Err(Error::Module(ModuleError { pallet: details.pallet().to_string(), error: details.error().to_string(), description: details.description().to_vec(), + raw: raw_error, })) } else { return Err(Error::Runtime(RuntimeError(dispatch_error))) From 445a1e958454ca0490b40f8bd9c6e414b659312b Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Wed, 30 Mar 2022 14:58:51 +0300 Subject: [PATCH 11/14] subxt: Update polkadot with ModuleErrorRaw Signed-off-by: Alexandru Vasile --- subxt/tests/integration/codegen/polkadot.rs | 554 +++++++++++++------- 1 file changed, 369 insertions(+), 185 deletions(-) diff --git a/subxt/tests/integration/codegen/polkadot.rs b/subxt/tests/integration/codegen/polkadot.rs index eca60c0583..7b0b4af0f7 100644 --- a/subxt/tests/integration/codegen/polkadot.rs +++ b/subxt/tests/integration/codegen/polkadot.rs @@ -1,4 +1,3 @@ -// Note [jsdw]: generated from polkadot 0.9.13-82616422d0-aarch64-macos #[allow(dead_code, unused_imports, non_camel_case_types)] pub mod api { use super::api as root_mod; @@ -76,11 +75,15 @@ pub mod api { XcmPallet(xcm_pallet::Event), } pub mod system { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct FillBlock { @@ -843,11 +846,15 @@ pub mod api { } } pub mod scheduler { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Schedule { @@ -1274,11 +1281,15 @@ pub mod api { } } pub mod preimage { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct NotePreimage { @@ -1505,11 +1516,15 @@ pub mod api { } } pub mod babe { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct ReportEquivocation { @@ -1975,11 +1990,15 @@ pub mod api { } } pub mod timestamp { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Set { @@ -2082,11 +2101,15 @@ pub mod api { } } pub mod indices { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive( :: subxt :: codec :: Encode, @@ -2341,11 +2364,15 @@ pub mod api { } } pub mod balances { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Transfer { @@ -2848,8 +2875,10 @@ pub mod api { } } pub mod transaction_payment { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod storage { use super::runtime_types; pub struct NextFeeMultiplier; @@ -2941,11 +2970,15 @@ pub mod api { } } pub mod authorship { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct SetUncles { @@ -3090,11 +3123,15 @@ pub mod api { } } pub mod staking { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Bond { @@ -4976,8 +5013,10 @@ pub mod api { } } pub mod offences { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub type Event = runtime_types::pallet_offences::pallet::Event; pub mod events { use super::runtime_types; @@ -5130,15 +5169,21 @@ pub mod api { } } pub mod historical { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; } pub mod session { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct SetKeys { @@ -5395,11 +5440,15 @@ pub mod api { } } pub mod grandpa { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct ReportEquivocation { @@ -5698,11 +5747,15 @@ pub mod api { } } pub mod im_online { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Heartbeat { @@ -5929,15 +5982,21 @@ pub mod api { } } pub mod authority_discovery { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; } pub mod democracy { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Propose { @@ -7276,11 +7335,15 @@ pub mod api { } } pub mod council { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct SetMembers { @@ -7715,11 +7778,15 @@ pub mod api { } } pub mod technical_committee { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct SetMembers { @@ -8154,11 +8221,15 @@ pub mod api { } } pub mod phragmen_election { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Vote { @@ -8611,11 +8682,15 @@ pub mod api { } } pub mod technical_membership { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct AddMember { @@ -8878,11 +8953,15 @@ pub mod api { } } pub mod treasury { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct ProposeSpend { @@ -9236,11 +9315,15 @@ pub mod api { } } pub mod claims { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Claim { @@ -9631,11 +9714,15 @@ pub mod api { } } pub mod vesting { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Vest; @@ -9935,11 +10022,15 @@ pub mod api { } } pub mod utility { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Batch { @@ -10107,11 +10198,15 @@ pub mod api { } } pub mod identity { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct AddRegistrar { @@ -10862,11 +10957,15 @@ pub mod api { } } pub mod proxy { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Proxy { @@ -11400,11 +11499,15 @@ pub mod api { } } pub mod multisig { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct AsMultiThreshold1 { @@ -11775,11 +11878,15 @@ pub mod api { } } pub mod bounties { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct ProposeBounty { @@ -12315,11 +12422,15 @@ pub mod api { } } pub mod tips { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct ReportAwesome { @@ -12673,11 +12784,15 @@ pub mod api { } } pub mod election_provider_multi_phase { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct SubmitUnsigned { pub raw_solution : :: std :: boxed :: Box < runtime_types :: pallet_election_provider_multi_phase :: RawSolution < runtime_types :: polkadot_runtime :: NposCompactSolution16 > > , pub witness : runtime_types :: pallet_election_provider_multi_phase :: SolutionOrSnapshotSize , } @@ -13195,11 +13310,15 @@ pub mod api { } } pub mod bags_list { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Rebag { @@ -13555,15 +13674,21 @@ pub mod api { } } pub mod parachains_origin { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; } pub mod configuration { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive( :: subxt :: codec :: Encode, @@ -14858,11 +14983,15 @@ pub mod api { } } pub mod paras_shared { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; pub struct TransactionApi<'a, T: ::subxt::Config, X> { client: &'a ::subxt::Client, @@ -14957,11 +15086,15 @@ pub mod api { } } pub mod para_inclusion { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; pub struct TransactionApi<'a, T: ::subxt::Config, X> { client: &'a ::subxt::Client, @@ -15128,11 +15261,15 @@ pub mod api { } } pub mod para_inherent { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Enter { @@ -15238,8 +15375,10 @@ pub mod api { } } pub mod para_scheduler { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod storage { use super::runtime_types; pub struct ValidatorGroups; @@ -15370,11 +15509,15 @@ pub mod api { } } pub mod paras { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct ForceSetCurrentCode { @@ -16295,11 +16438,15 @@ pub mod api { } } pub mod initializer { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive( :: subxt :: codec :: Encode, @@ -16387,11 +16534,15 @@ pub mod api { } } pub mod dmp { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; pub struct TransactionApi<'a, T: ::subxt::Config, X> { client: &'a ::subxt::Client, @@ -16497,11 +16648,15 @@ pub mod api { } } pub mod ump { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct ServiceOverweight { @@ -16789,11 +16944,15 @@ pub mod api { } } pub mod hrmp { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct HrmpInitOpenChannel { @@ -17418,8 +17577,10 @@ pub mod api { } } pub mod para_session_info { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod storage { use super::runtime_types; pub struct AssignmentKeysUnsafe; @@ -17507,11 +17668,15 @@ pub mod api { } } pub mod registrar { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Register { @@ -17855,11 +18020,15 @@ pub mod api { } } pub mod slots { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct ForceLease { @@ -18065,11 +18234,15 @@ pub mod api { } } pub mod auctions { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct NewAuction { @@ -18420,11 +18593,15 @@ pub mod api { } } pub mod crowdloan { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Create { @@ -18948,11 +19125,15 @@ pub mod api { } } pub mod xcm_pallet { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{ + root_mod, + runtime_types, + }; type DispatchError = runtime_types::sp_runtime::DispatchError; #[derive(:: subxt :: codec :: Encode, :: subxt :: codec :: Decode, Debug)] pub struct Send { @@ -27255,9 +27436,12 @@ pub mod api { #[doc = r" The default error type returned when there is a runtime issue."] pub type DispatchError = runtime_types::sp_runtime::DispatchError; impl ::subxt::HasModuleError for runtime_types::sp_runtime::DispatchError { - fn module_error_indices(&self) -> Option<(u8, u8)> { + fn module_error_indices(&self) -> Option<::subxt::ModuleErrorRaw> { if let &Self::Module { index, error } = self { - Some((index, error)) + Some(::subxt::ModuleErrorRaw { + pallet_index: index, + error: [error, 0, 0, 0], + }) } else { None } From f9bfec7daa8c2ceab4b5430f01136bc55ec30fa7 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 31 Mar 2022 11:35:38 +0300 Subject: [PATCH 12/14] subxt: Rename `ModuleErrorRaw` to `ModuleErrorData` Signed-off-by: Alexandru Vasile --- subxt/src/error.rs | 10 +++++----- subxt/src/lib.rs | 2 +- subxt/src/transaction.rs | 4 ++-- subxt/tests/integration/codegen/polkadot.rs | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/subxt/src/error.rs b/subxt/src/error.rs index b62ab9d2ab..57b6ccc168 100644 --- a/subxt/src/error.rs +++ b/subxt/src/error.rs @@ -182,16 +182,16 @@ pub struct ModuleError { pub error: String, /// A description of the error. pub description: Vec, - /// A raw byte representation of the error. - pub raw: ModuleErrorRaw, + /// A byte representation of the error. + pub error_data: ModuleErrorData, } -/// The raw error details about a module error that has occurred. +/// The error details about a module error that has occurred. /// /// **Note**: Structure used to obtain the underlying bytes of a ModuleError. #[derive(Clone, Debug, thiserror::Error)] #[error("Pallet index {pallet_index}: raw error: {error:?}")] -pub struct ModuleErrorRaw { +pub struct ModuleErrorData { /// Index of the pallet that the error came from. pub pallet_index: u8, /// Raw error bytes. @@ -204,5 +204,5 @@ pub struct ModuleErrorRaw { pub trait HasModuleError { /// If the error has a `Module` variant, return a tuple of the /// pallet index and error index. Else, return `None`. - fn module_error_indices(&self) -> Option; + fn module_error_data(&self) -> Option; } diff --git a/subxt/src/lib.rs b/subxt/src/lib.rs index b8a3c59af2..4882927514 100644 --- a/subxt/src/lib.rs +++ b/subxt/src/lib.rs @@ -81,7 +81,7 @@ pub use crate::{ Error, GenericError, HasModuleError, - ModuleErrorRaw, + ModuleErrorData, RuntimeError, TransactionError, }, diff --git a/subxt/src/transaction.rs b/subxt/src/transaction.rs index 50add125d7..73cd36c679 100644 --- a/subxt/src/transaction.rs +++ b/subxt/src/transaction.rs @@ -389,7 +389,7 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode> let ev = ev?; if &ev.pallet == "System" && &ev.variant == "ExtrinsicFailed" { let dispatch_error = E::decode(&mut &*ev.data)?; - if let Some(raw_error) = dispatch_error.module_error_indices() { + if let Some(raw_error) = dispatch_error.module_error_data() { // Error index is utilized as the first byte from the error array. let details = self .client @@ -399,7 +399,7 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode> pallet: details.pallet().to_string(), error: details.error().to_string(), description: details.description().to_vec(), - raw: raw_error, + error_data: raw_error, })) } else { return Err(Error::Runtime(RuntimeError(dispatch_error))) diff --git a/subxt/tests/integration/codegen/polkadot.rs b/subxt/tests/integration/codegen/polkadot.rs index 7b0b4af0f7..d27bba228a 100644 --- a/subxt/tests/integration/codegen/polkadot.rs +++ b/subxt/tests/integration/codegen/polkadot.rs @@ -27436,9 +27436,9 @@ pub mod api { #[doc = r" The default error type returned when there is a runtime issue."] pub type DispatchError = runtime_types::sp_runtime::DispatchError; impl ::subxt::HasModuleError for runtime_types::sp_runtime::DispatchError { - fn module_error_indices(&self) -> Option<::subxt::ModuleErrorRaw> { + fn module_error_data(&self) -> Option<::subxt::ModuleErrorData> { if let &Self::Module { index, error } = self { - Some(::subxt::ModuleErrorRaw { + Some(::subxt::ModuleErrorData { pallet_index: index, error: [error, 0, 0, 0], }) From fa0816b1e137bdbb817d7669a777841858bfb2aa Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 31 Mar 2022 11:39:41 +0300 Subject: [PATCH 13/14] subxt: Expose method to obtain error index Signed-off-by: Alexandru Vasile --- subxt/src/error.rs | 8 ++++++++ subxt/src/transaction.rs | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/subxt/src/error.rs b/subxt/src/error.rs index 57b6ccc168..50d1c1cbca 100644 --- a/subxt/src/error.rs +++ b/subxt/src/error.rs @@ -198,6 +198,14 @@ pub struct ModuleErrorData { pub error: [u8; 4], } +impl ModuleErrorData { + /// Obtain the error index from the underlying byte data. + pub fn error_index(&self) -> u8 { + // Error index is utilized as the first byte from the error array. + self.error[0] + } +} + /// This trait is automatically implemented for the generated `DispatchError`, /// so that we can pluck out information about the `Module` error variant, if` /// it exists. diff --git a/subxt/src/transaction.rs b/subxt/src/transaction.rs index 73cd36c679..1b1bedd15a 100644 --- a/subxt/src/transaction.rs +++ b/subxt/src/transaction.rs @@ -389,17 +389,17 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode> let ev = ev?; if &ev.pallet == "System" && &ev.variant == "ExtrinsicFailed" { let dispatch_error = E::decode(&mut &*ev.data)?; - if let Some(raw_error) = dispatch_error.module_error_data() { + if let Some(error_data) = dispatch_error.module_error_data() { // Error index is utilized as the first byte from the error array. let details = self .client .metadata() - .error(raw_error.pallet_index, raw_error.error[0])?; + .error(error_data.pallet_index, error_data.error_index())?; return Err(Error::Module(ModuleError { pallet: details.pallet().to_string(), error: details.error().to_string(), description: details.description().to_vec(), - error_data: raw_error, + error_data, })) } else { return Err(Error::Runtime(RuntimeError(dispatch_error))) From 2d2e475435c81793cfd91b921340e1fea13d1da8 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 31 Mar 2022 11:41:12 +0300 Subject: [PATCH 14/14] codegen: Rename `ModuleErrorRaw` to `ModuleErrorData` Signed-off-by: Alexandru Vasile --- codegen/src/api/errors.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/codegen/src/api/errors.rs b/codegen/src/api/errors.rs index 78b312808a..f9f860f42a 100644 --- a/codegen/src/api/errors.rs +++ b/codegen/src/api/errors.rs @@ -48,7 +48,7 @@ impl quote::ToTokens for ModuleErrorType { ModuleErrorType::NamedField => { quote! { if let &Self::Module { index, error } = self { - Some(::subxt::ModuleErrorRaw { pallet_index: index, error: [error, 0, 0, 0] }) + Some(::subxt::ModuleErrorData { pallet_index: index, error: [error, 0, 0, 0] }) } else { None } @@ -57,7 +57,7 @@ impl quote::ToTokens for ModuleErrorType { ModuleErrorType::LegacyError => { quote! { if let Self::Module (module_error) = self { - Some(::subxt::ModuleErrorRaw { pallet_index: module_error.index, error: [module_error.error, 0, 0, 0] }) + Some(::subxt::ModuleErrorData { pallet_index: module_error.index, error: [module_error.error, 0, 0, 0] }) } else { None } @@ -66,7 +66,7 @@ impl quote::ToTokens for ModuleErrorType { ModuleErrorType::ArrayError => { quote! { if let Self::Module (module_error) = self { - Some(::subxt::ModuleErrorRaw { pallet_index: module_error.index, error: module_error.error }) + Some(::subxt::ModuleErrorData { pallet_index: module_error.index, error: module_error.error }) } else { None } @@ -193,7 +193,7 @@ pub fn generate_has_module_error_impl( quote! { impl ::subxt::HasModuleError for #types_mod_ident::sp_runtime::DispatchError { - fn module_error_indices(&self) -> Option<::subxt::ModuleErrorRaw> { + fn module_error_data(&self) -> Option<::subxt::ModuleErrorData> { #error_type } }