From d2fce8963af0cd4dda43756f5314813962e5297e Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Fri, 27 Feb 2026 09:34:25 +0000 Subject: [PATCH 1/2] Remove duplicate error The error types for `hidden` v30 were exact copies of the v29 types. Remove the `Error` module from v30 and reuse the v29 types instead. --- types/src/v30/hidden/error.rs | 73 ----------------------------------- types/src/v30/hidden/mod.rs | 6 +-- types/src/v30/mod.rs | 6 +-- 3 files changed, 6 insertions(+), 79 deletions(-) delete mode 100644 types/src/v30/hidden/error.rs diff --git a/types/src/v30/hidden/error.rs b/types/src/v30/hidden/error.rs deleted file mode 100644 index 93a62dd30..000000000 --- a/types/src/v30/hidden/error.rs +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -use core::fmt; - -use bitcoin::consensus::encode; -use bitcoin::hex; - -use crate::error::write_err; - -/// Error when converting a `GetOrphanTxsVerboseOneEntry` type into the model type. -#[derive(Debug)] -pub enum GetOrphanTxsVerboseOneEntryError { - /// Conversion of the transaction `txid` field failed. - Txid(hex::HexToArrayError), - /// Conversion of the transaction `wtxid` field failed. - Wtxid(hex::HexToArrayError), -} - -impl fmt::Display for GetOrphanTxsVerboseOneEntryError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Self::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), - Self::Wtxid(ref e) => write_err!(f, "conversion of the `wtxid` field failed"; e), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for GetOrphanTxsVerboseOneEntryError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match *self { - Self::Txid(ref e) => Some(e), - Self::Wtxid(ref e) => Some(e), - } - } -} - -/// Error when converting a `GetOrphanTxsVerboseTwoEntry` type into the model type. -#[derive(Debug)] -pub enum GetOrphanTxsVerboseTwoEntryError { - /// Conversion of the transaction `txid` field failed. - Txid(hex::HexToArrayError), - /// Conversion of the transaction `wtxid` field failed. - Wtxid(hex::HexToArrayError), - /// Conversion of hex data to bytes failed. - Hex(hex::HexToBytesError), - /// Consensus decoding of `hex` to transaction failed. - Consensus(encode::Error), -} - -impl fmt::Display for GetOrphanTxsVerboseTwoEntryError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Self::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), - Self::Wtxid(ref e) => write_err!(f, "conversion of the `wtxid` field failed"; e), - Self::Hex(ref e) => write_err!(f, "conversion of hex data to bytes failed"; e), - Self::Consensus(ref e) => - write_err!(f, "consensus decoding of `hex` to transaction failed"; e), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for GetOrphanTxsVerboseTwoEntryError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match *self { - Self::Txid(ref e) => Some(e), - Self::Wtxid(ref e) => Some(e), - Self::Hex(ref e) => Some(e), - Self::Consensus(ref e) => Some(e), - } - } -} diff --git a/types/src/v30/hidden/mod.rs b/types/src/v30/hidden/mod.rs index e6632d6d5..51702260d 100644 --- a/types/src/v30/hidden/mod.rs +++ b/types/src/v30/hidden/mod.rs @@ -4,13 +4,13 @@ //! //! Types for methods that are excluded from the API docs by default. -mod error; mod into; use serde::{Deserialize, Serialize}; -pub use self::error::{GetOrphanTxsVerboseOneEntryError, GetOrphanTxsVerboseTwoEntryError}; -pub use super::GetOrphanTxsError; +pub use super::{ + GetOrphanTxsError, GetOrphanTxsVerboseOneEntryError, GetOrphanTxsVerboseTwoEntryError, +}; /// Result of JSON-RPC method `getorphantxs` verbosity 0. /// diff --git a/types/src/v30/mod.rs b/types/src/v30/mod.rs index e685211eb..55ee01a1e 100644 --- a/types/src/v30/mod.rs +++ b/types/src/v30/mod.rs @@ -252,9 +252,8 @@ mod wallet; pub use self::{ blockchain::GetMempoolInfo, hidden::{ - GetOrphanTxs, GetOrphanTxsVerboseOne, GetOrphanTxsVerboseOneEntry, - GetOrphanTxsVerboseOneEntryError, GetOrphanTxsVerboseTwo, GetOrphanTxsVerboseTwoEntry, - GetOrphanTxsVerboseTwoEntryError, + GetOrphanTxs, GetOrphanTxsVerboseOne, GetOrphanTxsVerboseOneEntry, GetOrphanTxsVerboseTwo, + GetOrphanTxsVerboseTwoEntry, }, mining::{GetMiningInfo, GetMiningInfoError}, raw_transactions::{ @@ -365,6 +364,7 @@ pub use crate::{ GetBlockVerboseTwoError, GetBlockVerboseTwoTransaction, GetBlockchainInfo, GetBlockchainInfoError, GetChainStates, GetChainStatesError, GetDescriptorActivity, GetDescriptorActivityError, GetDescriptorInfo, GetOrphanTxsError, + GetOrphanTxsVerboseOneEntryError, GetOrphanTxsVerboseTwoEntryError, GetRawTransactionVerboseWithPrevout, MempoolAcceptance, MempoolAcceptanceFees, NextBlockInfo, NextBlockInfoError, RawTransactionInputWithPrevout, ReceiveActivity, SpendActivity, TestMempoolAccept, From 9ca8e04aa685c0ec5f0ff3b55e8b2db2baf98091 Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Thu, 26 Feb 2026 11:16:51 +0000 Subject: [PATCH 2/2] Fix types conversion error variants Each error variant should be for an individual field. Add new variants where one variant was used for more than one field. Rename existing variants and update error messages to match the field names. --- types/src/v17/blockchain/error.rs | 7 +++--- types/src/v17/blockchain/into.rs | 2 +- types/src/v17/mining/error.rs | 5 ++-- types/src/v17/raw_transactions/error.rs | 5 ++-- types/src/v23/raw_transactions/error.rs | 5 ++-- types/src/v24/raw_transactions/error.rs | 5 ++-- types/src/v29/blockchain/error.rs | 32 ++++++++++++++++++------- types/src/v29/blockchain/into.rs | 13 +++++----- types/src/v29/hidden/error.rs | 14 +++++------ types/src/v29/hidden/into.rs | 2 +- types/src/v30/hidden/into.rs | 2 +- types/src/v30/raw_transactions/error.rs | 5 ++-- 12 files changed, 58 insertions(+), 39 deletions(-) diff --git a/types/src/v17/blockchain/error.rs b/types/src/v17/blockchain/error.rs index 5e4835669..fa1156408 100644 --- a/types/src/v17/blockchain/error.rs +++ b/types/src/v17/blockchain/error.rs @@ -113,15 +113,14 @@ pub enum GetBlockHeaderError { /// Conversion of hex data to bytes failed. Hex(hex::HexToBytesError), /// Consensus decoding of bytes to header failed. - Consensus(encode::Error), + Header(encode::Error), } impl fmt::Display for GetBlockHeaderError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Self::Hex(ref e) => write_err!(f, "conversion of hex data to bytes failed"; e), - Self::Consensus(ref e) => - write_err!(f, "consensus decoding of bytes to header failed"; e), + Self::Header(ref e) => write_err!(f, "consensus decoding of bytes to header failed"; e), } } } @@ -131,7 +130,7 @@ impl std::error::Error for GetBlockHeaderError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match *self { Self::Hex(ref e) => Some(e), - Self::Consensus(ref e) => Some(e), + Self::Header(ref e) => Some(e), } } } diff --git a/types/src/v17/blockchain/into.rs b/types/src/v17/blockchain/into.rs index 27ef92fb5..be5267ec5 100644 --- a/types/src/v17/blockchain/into.rs +++ b/types/src/v17/blockchain/into.rs @@ -162,7 +162,7 @@ impl GetBlockHeader { use GetBlockHeaderError as E; let v = Vec::from_hex(&self.0).map_err(E::Hex)?; - let header = encode::deserialize::(&v).map_err(E::Consensus)?; + let header = encode::deserialize::(&v).map_err(E::Header)?; Ok(model::GetBlockHeader(header)) } diff --git a/types/src/v17/mining/error.rs b/types/src/v17/mining/error.rs index 6c9295190..651fbb172 100644 --- a/types/src/v17/mining/error.rs +++ b/types/src/v17/mining/error.rs @@ -65,7 +65,7 @@ pub enum BlockTemplateTransactionError { Data(consensus::encode::FromHexError), /// Conversion of the `txid` field failed. Txid(hex::HexToArrayError), - /// Conversion of the `hash` field failed. + /// Conversion of the `hash` field to `wtxid` failed. Hash(hex::HexToArrayError), /// Conversion of the `fee` field failed. Fee(ParseAmountError), @@ -77,7 +77,8 @@ impl fmt::Display for BlockTemplateTransactionError { Self::Numeric(ref e) => write_err!(f, "numeric"; e), Self::Data(ref e) => write_err!(f, "conversion of the `data` field failed"; e), Self::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), - Self::Hash(ref e) => write_err!(f, "conversion of the `hash` field failed"; e), + Self::Hash(ref e) => + write_err!(f, "conversion of the `hash` field to `wtxid` failed"; e), Self::Fee(ref e) => write_err!(f, "conversion of the `fee` field failed"; e), } } diff --git a/types/src/v17/raw_transactions/error.rs b/types/src/v17/raw_transactions/error.rs index defe45143..fc40154c6 100644 --- a/types/src/v17/raw_transactions/error.rs +++ b/types/src/v17/raw_transactions/error.rs @@ -16,7 +16,7 @@ use crate::psbt::{ /// Error when converting a `DecodePsbt` type into the model type. #[derive(Debug)] pub enum DecodePsbtError { - /// Conversion of the `tx` field failed. + /// Conversion of the `tx` field to `unsigned_tx` failed. Tx(RawTransactionError), /// Conversion of one the map items in the `unknown` field failed. Unknown(hex::HexToBytesError), @@ -31,7 +31,8 @@ pub enum DecodePsbtError { impl fmt::Display for DecodePsbtError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Self::Tx(ref e) => write_err!(f, "conversion of raw transaction data field failed"; e), + Self::Tx(ref e) => + write_err!(f, "conversion of the `tx` field to `unsigned_tx` failed"; e), Self::Unknown(ref e) => write_err!(f, "conversion of one the map items in the `unknown` field failed"; e), Self::Inputs(ref e) => write_err!(f, "conversion of one of the PSBT inputs failed"; e), diff --git a/types/src/v23/raw_transactions/error.rs b/types/src/v23/raw_transactions/error.rs index 6acd34c35..3ca2d2d1b 100644 --- a/types/src/v23/raw_transactions/error.rs +++ b/types/src/v23/raw_transactions/error.rs @@ -11,7 +11,7 @@ use crate::error::write_err; /// Error when converting a `DecodePsbt` type into the model type. #[derive(Debug)] pub enum DecodePsbtError { - /// Conversion of the `tx` field failed. + /// Conversion of the `tx` field to `unsigned_tx` failed. Tx(RawTransactionError), /// Conversion of the `global_xpubs` field failed. GlobalXpubs(GlobalXpubError), @@ -30,7 +30,8 @@ pub enum DecodePsbtError { impl fmt::Display for DecodePsbtError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Self::Tx(ref e) => write_err!(f, "conversion of raw transaction data field failed"; e), + Self::Tx(ref e) => + write_err!(f, "conversion of the `tx` field to `unsigned_tx` failed"; e), Self::GlobalXpubs(ref e) => write_err!(f, "conversion of one the map items in the `global_xbubs` field failed"; e), Self::Proprietary(ref e) => diff --git a/types/src/v24/raw_transactions/error.rs b/types/src/v24/raw_transactions/error.rs index 05f92931f..2256eac32 100644 --- a/types/src/v24/raw_transactions/error.rs +++ b/types/src/v24/raw_transactions/error.rs @@ -12,7 +12,7 @@ use crate::error::write_err; /// Error when converting a `DecodePsbt` type into the model type. #[derive(Debug)] pub enum DecodePsbtError { - /// Conversion of the `tx` field failed. + /// Conversion of the `tx` field to `unsigned_tx` failed. Tx(RawTransactionError), /// Conversion of the `global_xpubs` field failed. GlobalXpubs(GlobalXpubError), @@ -31,7 +31,8 @@ pub enum DecodePsbtError { impl fmt::Display for DecodePsbtError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Self::Tx(ref e) => write_err!(f, "conversion of raw transaction data field failed"; e), + Self::Tx(ref e) => + write_err!(f, "conversion of the `tx` field to `unsigned_tx` failed"; e), Self::GlobalXpubs(ref e) => write_err!(f, "conversion of one the map items in the `global_xbubs` field failed"; e), Self::Proprietary(ref e) => diff --git a/types/src/v29/blockchain/error.rs b/types/src/v29/blockchain/error.rs index 41c4fb3ae..6bb5887b1 100644 --- a/types/src/v29/blockchain/error.rs +++ b/types/src/v29/blockchain/error.rs @@ -289,15 +289,14 @@ pub enum GetBlockHeaderError { /// Conversion of hex data to bytes failed. Hex(hex::HexToBytesError), /// Consensus decoding of bytes to header failed. - Consensus(encode::Error), + Header(encode::Error), } impl fmt::Display for GetBlockHeaderError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Self::Hex(ref e) => write_err!(f, "conversion of hex data to bytes failed"; e), - Self::Consensus(ref e) => - write_err!(f, "consensus decoding of bytes to header failed"; e), + Self::Header(ref e) => write_err!(f, "consensus decoding of bytes to header failed"; e), } } } @@ -307,7 +306,7 @@ impl std::error::Error for GetBlockHeaderError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match *self { Self::Hex(ref e) => Some(e), - Self::Consensus(ref e) => Some(e), + Self::Header(ref e) => Some(e), } } } @@ -427,8 +426,14 @@ impl From for GetChainStatesError { pub enum GetDescriptorActivityError { /// Conversion of numeric type (e.g., height) to expected type failed. Numeric(NumericError), - /// Conversion of a hash string (BlockHash, Txid) failed. - Hash(hex::HexToArrayError), + /// Conversion of the `spend_txid` field failed. + SpendTxid(hex::HexToArrayError), + /// Conversion of the `prevout_txid` field failed. + PrevoutTxid(hex::HexToArrayError), + /// Conversion of the `txid` field failed. + Txid(hex::HexToArrayError), + /// Conversion of the `block_hash` field failed. + BlockHash(hex::HexToArrayError), /// Conversion of the `amount` field (f64 BTC) failed. Amount(amount::ParseAmountError), /// Conversion of script hex to ScriptBuf failed. @@ -449,7 +454,13 @@ impl fmt::Display for GetDescriptorActivityError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Self::Numeric(ref e) => write_err!(f, "numeric conversion failed"; e), - Self::Hash(ref e) => write_err!(f, "conversion of a hash string failed"; e), + Self::SpendTxid(ref e) => + write_err!(f, "conversion of the `spend_txid` field failed"; e), + Self::PrevoutTxid(ref e) => + write_err!(f, "conversion of the `prevout_txid` field failed"; e), + Self::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), + Self::BlockHash(ref e) => + write_err!(f, "conversion of the `block_hash` field failed"; e), Self::Amount(ref e) => write_err!(f, "conversion of the `amount` field failed"; e), Self::Script(ref e) => write_err!(f, "conversion of the script `hex` field failed"; e), Self::Address(ref e) => write_err!(f, "conversion of the `address` field failed"; e), @@ -470,7 +481,10 @@ impl std::error::Error for GetDescriptorActivityError { match *self { Numeric(ref e) => Some(e), - Hash(ref e) => Some(e), + SpendTxid(ref e) => Some(e), + PrevoutTxid(ref e) => Some(e), + Txid(ref e) => Some(e), + BlockHash(ref e) => Some(e), Amount(ref e) => Some(e), Script(ref e) => Some(e), Address(ref e) => Some(e), @@ -487,7 +501,7 @@ impl From for GetDescriptorActivityError { } impl From for GetDescriptorActivityError { - fn from(e: hex::HexToArrayError) -> Self { Self::Hash(e) } + fn from(e: hex::HexToArrayError) -> Self { Self::BlockHash(e) } } impl From for GetDescriptorActivityError { diff --git a/types/src/v29/blockchain/into.rs b/types/src/v29/blockchain/into.rs index 63e5b3a3f..b42c8631d 100644 --- a/types/src/v29/blockchain/into.rs +++ b/types/src/v29/blockchain/into.rs @@ -300,7 +300,7 @@ impl GetBlockHeader { use GetBlockHeaderError as E; let v = Vec::from_hex(&self.0).map_err(E::Hex)?; - let header = encode::deserialize::(&v).map_err(E::Consensus)?; + let header = encode::deserialize::(&v).map_err(E::Header)?; Ok(model::GetBlockHeader(header)) } @@ -404,11 +404,12 @@ impl GetDescriptorActivity { .block_hash .map(|s| BlockHash::from_str(&s)) .transpose() - .map_err(E::Hash)?; + .map_err(E::BlockHash)?; let height = spend.height.map(|h| crate::to_u32(h, "height")).transpose()?; - let spend_txid = Txid::from_str(&spend.spend_txid).map_err(E::Hash)?; - let prevout_txid = Txid::from_str(&spend.prevout_txid).map_err(E::Hash)?; + let spend_txid = Txid::from_str(&spend.spend_txid).map_err(E::SpendTxid)?; + let prevout_txid = + Txid::from_str(&spend.prevout_txid).map_err(E::PrevoutTxid)?; let prevout_spk = spend.prevout_spk.into_model().map_err(E::PrevoutSpk)?; Ok(model::ActivityEntry::Spend(model::SpendActivity { @@ -428,10 +429,10 @@ impl GetDescriptorActivity { .block_hash .map(|s| BlockHash::from_str(&s)) .transpose() - .map_err(E::Hash)?; + .map_err(E::BlockHash)?; let height = receive.height.map(|h| crate::to_u32(h, "height")).transpose()?; // Uses From - let txid = Txid::from_str(&receive.txid).map_err(E::Hash)?; + let txid = Txid::from_str(&receive.txid).map_err(E::Txid)?; let output_spk = receive.output_spk.into_model().map_err(E::OutputSpk)?; Ok(model::ActivityEntry::Receive(model::ReceiveActivity { diff --git a/types/src/v29/hidden/error.rs b/types/src/v29/hidden/error.rs index c7bd896c3..14069ddd3 100644 --- a/types/src/v29/hidden/error.rs +++ b/types/src/v29/hidden/error.rs @@ -66,10 +66,10 @@ pub enum GetOrphanTxsVerboseTwoEntryError { Txid(hex::HexToArrayError), /// Conversion of the transaction `wtxid` field failed. Wtxid(hex::HexToArrayError), - /// Conversion of hex data to bytes failed. + /// Conversion of the `hex` field to bytes failed. Hex(hex::HexToBytesError), - /// Consensus decoding of `hex` to transaction failed. - Consensus(encode::Error), + /// Consensus decoding of the `hex` bytes to `transaction` failed. + Transaction(encode::Error), } impl fmt::Display for GetOrphanTxsVerboseTwoEntryError { @@ -77,9 +77,9 @@ impl fmt::Display for GetOrphanTxsVerboseTwoEntryError { match *self { Self::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), Self::Wtxid(ref e) => write_err!(f, "conversion of the `wtxid` field failed"; e), - Self::Hex(ref e) => write_err!(f, "conversion of hex data to bytes failed"; e), - Self::Consensus(ref e) => - write_err!(f, "consensus decoding of `hex` to transaction failed"; e), + Self::Hex(ref e) => write_err!(f, "conversion of the `hex` field to bytes failed"; e), + Self::Transaction(ref e) => + write_err!(f, "consensus decoding of the `hex` bytes to `transaction` failed"; e), } } } @@ -91,7 +91,7 @@ impl std::error::Error for GetOrphanTxsVerboseTwoEntryError { Self::Txid(ref e) => Some(e), Self::Wtxid(ref e) => Some(e), Self::Hex(ref e) => Some(e), - Self::Consensus(ref e) => Some(e), + Self::Transaction(ref e) => Some(e), } } } diff --git a/types/src/v29/hidden/into.rs b/types/src/v29/hidden/into.rs index 833108163..c3d2f1723 100644 --- a/types/src/v29/hidden/into.rs +++ b/types/src/v29/hidden/into.rs @@ -59,7 +59,7 @@ impl GetOrphanTxsVerboseTwoEntry { let txid = self.txid.parse::().map_err(E::Txid)?; let wtxid = self.wtxid.parse::().map_err(E::Wtxid)?; let v = Vec::from_hex(&self.hex).map_err(E::Hex)?; - let transaction = encode::deserialize::(&v).map_err(E::Consensus)?; + let transaction = encode::deserialize::(&v).map_err(E::Transaction)?; Ok(model::GetOrphanTxsVerboseTwoEntry { txid, diff --git a/types/src/v30/hidden/into.rs b/types/src/v30/hidden/into.rs index 5c773652a..a4580f761 100644 --- a/types/src/v30/hidden/into.rs +++ b/types/src/v30/hidden/into.rs @@ -59,7 +59,7 @@ impl GetOrphanTxsVerboseTwoEntry { let txid = self.txid.parse::().map_err(E::Txid)?; let wtxid = self.wtxid.parse::().map_err(E::Wtxid)?; let v = Vec::from_hex(&self.hex).map_err(E::Hex)?; - let transaction = encode::deserialize::(&v).map_err(E::Consensus)?; + let transaction = encode::deserialize::(&v).map_err(E::Transaction)?; Ok(model::GetOrphanTxsVerboseTwoEntry { txid, diff --git a/types/src/v30/raw_transactions/error.rs b/types/src/v30/raw_transactions/error.rs index 05f92931f..2256eac32 100644 --- a/types/src/v30/raw_transactions/error.rs +++ b/types/src/v30/raw_transactions/error.rs @@ -12,7 +12,7 @@ use crate::error::write_err; /// Error when converting a `DecodePsbt` type into the model type. #[derive(Debug)] pub enum DecodePsbtError { - /// Conversion of the `tx` field failed. + /// Conversion of the `tx` field to `unsigned_tx` failed. Tx(RawTransactionError), /// Conversion of the `global_xpubs` field failed. GlobalXpubs(GlobalXpubError), @@ -31,7 +31,8 @@ pub enum DecodePsbtError { impl fmt::Display for DecodePsbtError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Self::Tx(ref e) => write_err!(f, "conversion of raw transaction data field failed"; e), + Self::Tx(ref e) => + write_err!(f, "conversion of the `tx` field to `unsigned_tx` failed"; e), Self::GlobalXpubs(ref e) => write_err!(f, "conversion of one the map items in the `global_xbubs` field failed"; e), Self::Proprietary(ref e) =>