From 9a2c44e88e320206617551c5a2a36e1e66b70c9f Mon Sep 17 00:00:00 2001 From: James Wilson Date: Tue, 22 Oct 2024 17:46:29 +0100 Subject: [PATCH 1/2] Add an extrinsic index to decode errors so that we know which extrinsic failed --- core/src/blocks/extrinsics.rs | 26 +++++++++++++++++++------- core/src/error.rs | 31 +++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/core/src/blocks/extrinsics.rs b/core/src/blocks/extrinsics.rs index 2b82d2eb1b..ac58ab87f4 100644 --- a/core/src/blocks/extrinsics.rs +++ b/core/src/blocks/extrinsics.rs @@ -32,7 +32,8 @@ impl Extrinsics { pub fn decode_from(extrinsics: Vec>, metadata: Metadata) -> Result { let extrinsics = extrinsics .into_iter() - .map(|bytes| { + .enumerate() + .map(|(extrinsic_index, bytes)| { let cursor = &mut &*bytes; // Try to decode the extrinsic. @@ -41,12 +42,19 @@ impl Extrinsics { metadata.deref(), metadata.types(), ) - .map_err(BlockError::ExtrinsicDecodeError)? + .map_err(|error| BlockError::ExtrinsicDecodeError { + extrinsic_index, + error, + })? .into_owned(); // We didn't consume all bytes, so decoding probably failed. if !cursor.is_empty() { - return Err(BlockError::LeftoverBytes(cursor.len()).into()); + return Err(BlockError::LeftoverBytes { + extrinsic_index, + num_leftover_bytes: cursor.len(), + } + .into()); } Ok(Arc::new((decoded_info, bytes))) @@ -493,7 +501,10 @@ mod tests { assert_matches!( result.err(), Some(crate::Error::Block( - crate::error::BlockError::ExtrinsicDecodeError(_) + crate::error::BlockError::ExtrinsicDecodeError { + extrinsic_index: 0, + error: _ + } )) ); } @@ -510,9 +521,10 @@ mod tests { assert_matches!( result.err(), Some(crate::Error::Block( - crate::error::BlockError::ExtrinsicDecodeError( - ExtrinsicDecodeError::VersionNotSupported(3) - ) + crate::error::BlockError::ExtrinsicDecodeError { + extrinsic_index: 0, + error: ExtrinsicDecodeError::VersionNotSupported(3), + } )) ); } diff --git a/core/src/error.rs b/core/src/error.rs index 8b9b8a83d5..000a3019cc 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -59,21 +59,40 @@ impl_from!(codec::Error => Error::Codec); #[derive(Debug)] pub enum BlockError { /// Leftover bytes found after decoding the extrinsic. - LeftoverBytes(usize), + LeftoverBytes { + /// Index of the extrinsic that failed to decode. + extrinsic_index: usize, + /// Number of bytes leftover after decoding the extrinsic. + num_leftover_bytes: usize, + }, /// Something went wrong decoding the extrinsic. - ExtrinsicDecodeError(ExtrinsicDecodeError), + ExtrinsicDecodeError { + /// Index of the extrinsic that failed to decode. + extrinsic_index: usize, + /// The decode error. + error: ExtrinsicDecodeError, + }, } impl Display for BlockError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - BlockError::LeftoverBytes(n) => { + BlockError::LeftoverBytes { + extrinsic_index, + num_leftover_bytes, + } => { write!( f, - "After decoding, {n} bytes were left, suggesting that decoding may have failed" + "After decoding the extrinsic at index {extrinsic_index}, {num_leftover_bytes} bytes were left, suggesting that decoding may have failed" ) } - BlockError::ExtrinsicDecodeError(e) => { - write!(f, "{e}") + BlockError::ExtrinsicDecodeError { + extrinsic_index, + error, + } => { + write!( + f, + "Failed to decode extrinsic at index {extrinsic_index}: {error}" + ) } } } From 7d967c80f16d12abfadc3f2b5e1d5705642b383e Mon Sep 17 00:00:00 2001 From: James Wilson Date: Wed, 23 Oct 2024 09:39:37 +0100 Subject: [PATCH 2/2] Fix subxt::BlockError to align with subxt_core::BlockError --- subxt/src/error/mod.rs | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/subxt/src/error/mod.rs b/subxt/src/error/mod.rs index 44a4283c09..21e20735c1 100644 --- a/subxt/src/error/mod.rs +++ b/subxt/src/error/mod.rs @@ -172,18 +172,40 @@ pub enum BlockError { #[error("Could not find a block with hash {0} (perhaps it was on a non-finalized fork?)")] NotFound(String), /// Leftover bytes found after decoding the extrinsic. - #[error("After decoding, {0} bytes were left, suggesting that decoding may have failed")] - LeftoverBytes(usize), + #[error("After decoding the exntrinsic at index {extrinsic_index}, {num_leftover_bytes} bytes were left, suggesting that decoding may have failed")] + LeftoverBytes { + /// Index of the extrinsic that failed to decode. + extrinsic_index: usize, + /// Number of bytes leftover after decoding the extrinsic. + num_leftover_bytes: usize, + }, /// Decoding error. - #[error("Cannot decode extrinsic: {0}")] - ExtrinsicDecodeError(subxt_core::error::ExtrinsicDecodeError), + #[error("Cannot decode extrinsic at index {extrinsic_index}: {error}")] + ExtrinsicDecodeError { + /// Index of the extrinsic that failed to decode. + extrinsic_index: usize, + /// The decode error. + error: subxt_core::error::ExtrinsicDecodeError, + }, } impl From for BlockError { fn from(value: CoreBlockError) -> Self { match value { - CoreBlockError::LeftoverBytes(n) => BlockError::LeftoverBytes(n), - CoreBlockError::ExtrinsicDecodeError(e) => BlockError::ExtrinsicDecodeError(e), + CoreBlockError::LeftoverBytes { + extrinsic_index, + num_leftover_bytes, + } => BlockError::LeftoverBytes { + extrinsic_index, + num_leftover_bytes, + }, + CoreBlockError::ExtrinsicDecodeError { + extrinsic_index, + error, + } => BlockError::ExtrinsicDecodeError { + extrinsic_index, + error, + }, } } }