From f83fdf72da8db4a238208f02a439794a925e03d0 Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Wed, 25 Jun 2025 13:58:01 +0100 Subject: [PATCH 1/6] Remove Option from type Returned field `type` from `decodescript` is not optional for v17 to v29. Remove the Option and make it a String. --- types/src/model/raw_transactions.rs | 2 +- types/src/v17/raw_transactions/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/types/src/model/raw_transactions.rs b/types/src/model/raw_transactions.rs index 80efcd21..47c52df6 100644 --- a/types/src/model/raw_transactions.rs +++ b/types/src/model/raw_transactions.rs @@ -94,7 +94,7 @@ pub struct DecodeScript { /// The `scriptPubkey`. pub script_pubkey: Option, /// The output type. - pub type_: Option, + pub type_: String, /// The required signatures. pub required_signatures: Option, /// List of bitcoin addresses. diff --git a/types/src/v17/raw_transactions/mod.rs b/types/src/v17/raw_transactions/mod.rs index ff3fc5a4..99d2f4b1 100644 --- a/types/src/v17/raw_transactions/mod.rs +++ b/types/src/v17/raw_transactions/mod.rs @@ -209,7 +209,7 @@ pub struct DecodeScript { pub hex: Option, /// The output type. #[serde(rename = "type")] - pub type_: Option, + pub type_: String, /// The required signatures. #[serde(rename = "reqSigs")] pub required_signatures: Option, From 6d934567c81f586817cc40fa5c07bfea80ad007b Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Wed, 25 Jun 2025 14:14:34 +0100 Subject: [PATCH 2/6] Add new return fields to decodescript New return fields added in v22 and v23. Add the new fields to the model and v17 type and into function. --- types/src/model/raw_transactions.rs | 4 ++++ types/src/v17/raw_transactions/error.rs | 4 ++++ types/src/v17/raw_transactions/into.rs | 6 ++++++ types/src/v17/raw_transactions/mod.rs | 10 ++++++++++ 4 files changed, 24 insertions(+) diff --git a/types/src/model/raw_transactions.rs b/types/src/model/raw_transactions.rs index 47c52df6..552d1fa5 100644 --- a/types/src/model/raw_transactions.rs +++ b/types/src/model/raw_transactions.rs @@ -93,8 +93,12 @@ pub struct DecodeRawTransaction(pub Transaction); pub struct DecodeScript { /// The `scriptPubkey`. pub script_pubkey: Option, + /// Inferred descriptor for the script. v23 and later only. + pub descriptor: Option, /// The output type. pub type_: String, + /// Bitcoin address (only if a well-defined address exists). v22 and later only. + pub address: Option>, /// The required signatures. pub required_signatures: Option, /// List of bitcoin addresses. diff --git a/types/src/v17/raw_transactions/error.rs b/types/src/v17/raw_transactions/error.rs index 5bb469a9..1b788fb2 100644 --- a/types/src/v17/raw_transactions/error.rs +++ b/types/src/v17/raw_transactions/error.rs @@ -174,6 +174,8 @@ impl std::error::Error for PsbtOutputError { pub enum DecodeScriptError { /// Conversion of the transaction `hex` field failed. Hex(hex::HexToBytesError), + /// Conversion of the transaction `address` field failed. + Address(address::ParseError), /// Conversion of the transaction `addresses` field failed. Addresses(address::ParseError), /// Conversion of the transaction `p2sh` field failed. @@ -186,6 +188,7 @@ impl fmt::Display for DecodeScriptError { match *self { E::Hex(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), + E::Address(ref e) => write_err!(f, "conversion of the `address` field failed"; e), E::Addresses(ref e) => write_err!(f, "conversion of the `addresses` field failed"; e), E::P2sh(ref e) => write_err!(f, "conversion of the `p2sh` field failed"; e), } @@ -199,6 +202,7 @@ impl std::error::Error for DecodeScriptError { match *self { E::Hex(ref e) => Some(e), + E::Address(ref e) => Some(e), E::Addresses(ref e) => Some(e), E::P2sh(ref e) => Some(e), } diff --git a/types/src/v17/raw_transactions/into.rs b/types/src/v17/raw_transactions/into.rs index 6687ed68..5e872cc7 100644 --- a/types/src/v17/raw_transactions/into.rs +++ b/types/src/v17/raw_transactions/into.rs @@ -291,6 +291,10 @@ impl DecodeScript { Some(hex) => Some(ScriptBuf::from_hex(&hex).map_err(E::Hex)?), None => None, }; + let address = match self.address { + Some(addr) => Some(addr.parse::>().map_err(E::Address)?), + None => None, + }; let addresses = match self.addresses { Some(addresses) => addresses .iter() @@ -304,6 +308,8 @@ impl DecodeScript { Ok(model::DecodeScript { script_pubkey, type_: self.type_, + descriptor: self.descriptor, + address, required_signatures: self.required_signatures, addresses, p2sh, diff --git a/types/src/v17/raw_transactions/mod.rs b/types/src/v17/raw_transactions/mod.rs index 99d2f4b1..f7b52525 100644 --- a/types/src/v17/raw_transactions/mod.rs +++ b/types/src/v17/raw_transactions/mod.rs @@ -207,9 +207,14 @@ pub struct DecodeScript { pub asm: String, /// Hex encoded public key. pub hex: Option, + /// Inferred descriptor for the script. v23 and later only. + #[serde(rename = "desc")] + pub descriptor: Option, /// The output type. #[serde(rename = "type")] pub type_: String, + /// Bitcoin address (only if a well-defined address exists). v22 and later only. + pub address: Option, /// The required signatures. #[serde(rename = "reqSigs")] pub required_signatures: Option, @@ -235,11 +240,16 @@ pub struct DecodeScriptSegwit { /// The output type. #[serde(rename = "type")] pub type_: String, + /// Bitcoin address (only if a well-defined address exists). v22 and later only. + pub address: Option, /// The required signatures. #[serde(rename = "reqSigs")] pub required_signatures: Option, /// List of bitcoin addresses. pub addresses: Option>, + /// Inferred descriptor for the script. v23 and later only. + #[serde(rename = "desc")] + pub descriptor: Option, /// Address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH). #[serde(rename = "p2sh-segwit")] pub p2sh_segtwit: Option, From 5e6ee58ea855839336a228c5cc533d45217bc4e4 Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Wed, 25 Jun 2025 14:21:50 +0100 Subject: [PATCH 3/6] Reorder fields in logging alphabetically The core help gives a list in alphabetical order. Change the list here to match and make reading it easier. --- types/src/v17/control.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/types/src/v17/control.rs b/types/src/v17/control.rs index f0610f80..e7e0f71b 100644 --- a/types/src/v17/control.rs +++ b/types/src/v17/control.rs @@ -52,25 +52,25 @@ pub struct Locked { /// > Gets and sets the logging configuration. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct Logging { - pub net: bool, - pub tor: bool, - pub mempool: bool, - pub http: bool, + pub addrman: bool, pub bench: bool, - pub zmq: bool, + pub cmpctblock: bool, + pub coindb: bool, pub db: bool, - pub rpc: bool, pub estimatefee: bool, - pub addrman: bool, - pub selectcoins: bool, - pub reindex: bool, - pub cmpctblock: bool, - pub rand: bool, + pub http: bool, + pub leveldb: bool, + pub libevent: bool, + pub mempool: bool, + pub mempoolrej: bool, + pub net: bool, pub prune: bool, pub proxy: bool, - pub mempoolrej: bool, - pub libevent: bool, - pub coindb: bool, pub qt: bool, - pub leveldb: bool, + pub rand: bool, + pub reindex: bool, + pub rpc: bool, + pub selectcoins: bool, + pub tor: bool, + pub zmq: bool, } From 0cb6283ced2d4e0a79a9203028f7864071569a33 Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Wed, 25 Jun 2025 14:34:23 +0100 Subject: [PATCH 4/6] Add missing fields to logging Fields were added in v22, v23, v25, v26. Remove the redefinitions in version specific folders and add the types as options to the v17 definition. --- types/src/v17/control.rs | 11 ++++++++++- types/src/v20/control.rs | 38 -------------------------------------- types/src/v20/mod.rs | 4 +--- types/src/v21/mod.rs | 4 ++-- types/src/v22/control.rs | 40 ---------------------------------------- types/src/v22/mod.rs | 4 +--- types/src/v23/mod.rs | 4 ++-- types/src/v24/mod.rs | 4 ++-- types/src/v25/mod.rs | 16 ++++++++-------- types/src/v26/mod.rs | 4 ++-- types/src/v27/mod.rs | 4 ++-- types/src/v28/mod.rs | 4 ++-- types/src/v29/mod.rs | 4 ++-- 13 files changed, 34 insertions(+), 107 deletions(-) delete mode 100644 types/src/v20/control.rs delete mode 100644 types/src/v22/control.rs diff --git a/types/src/v17/control.rs b/types/src/v17/control.rs index e7e0f71b..63490318 100644 --- a/types/src/v17/control.rs +++ b/types/src/v17/control.rs @@ -54,11 +54,14 @@ pub struct Locked { pub struct Logging { pub addrman: bool, pub bench: bool, + pub blockstorage: Option, // v23 and later only pub cmpctblock: bool, pub coindb: bool, - pub db: bool, + pub db: Option, // v22 and before only pub estimatefee: bool, pub http: bool, + pub i2p: Option, // v23 and later only + pub ipc: Option, // v23 and later only pub leveldb: bool, pub libevent: bool, pub mempool: bool, @@ -70,7 +73,13 @@ pub struct Logging { pub rand: bool, pub reindex: bool, pub rpc: bool, + pub scan: Option, // v25 and later only pub selectcoins: bool, pub tor: bool, + pub txpackages: Option, // v26 and later only + pub txreconciliation: Option, // v25 and later only + pub util: Option, // v23 and later only + pub validation: Option, // v23 and later only + pub walletdb: Option, // v23 and later only pub zmq: bool, } diff --git a/types/src/v20/control.rs b/types/src/v20/control.rs deleted file mode 100644 index c27e227b..00000000 --- a/types/src/v20/control.rs +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -//! The JSON-RPC API for Bitcoin Core `v0.20` - control. -//! -//! Types for methods found under the `== Control ==` section of the API docs. - -use serde::{Deserialize, Serialize}; - -/// Result of JSON-RPC method `logging`. -/// -/// > logging ( `` `` ) -/// -/// > Gets and sets the logging configuration. -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct Logging { - pub net: bool, - pub tor: bool, - pub mempool: bool, - pub http: bool, - pub bench: bool, - pub zmq: bool, - pub walletdb: bool, - pub rpc: bool, - pub estimatefee: bool, - pub addrman: bool, - pub selectcoins: bool, - pub reindex: bool, - pub cmpctblock: bool, - pub rand: bool, - pub prune: bool, - pub proxy: bool, - pub mempoolrej: bool, - pub libevent: bool, - pub coindb: bool, - pub qt: bool, - pub leveldb: bool, - pub validation: bool, -} diff --git a/types/src/v20/mod.rs b/types/src/v20/mod.rs index 3a0bfdbf..3addc3c8 100644 --- a/types/src/v20/mod.rs +++ b/types/src/v20/mod.rs @@ -226,13 +226,11 @@ //! // JSON-RPC types by API section. -mod control; mod network; mod util; #[doc(inline)] pub use self::{ - control::Logging, network::{Banned, ListBanned}, util::CreateMultisig, }; @@ -263,7 +261,7 @@ pub use crate::{ ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, - LoadWallet, Locked, PruneBlockchain, RawTransactionError, RawTransactionInput, + LoadWallet, Locked, Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, TransactionCategory, diff --git a/types/src/v21/mod.rs b/types/src/v21/mod.rs index 96748025..77a7d37d 100644 --- a/types/src/v21/mod.rs +++ b/types/src/v21/mod.rs @@ -272,7 +272,7 @@ pub use crate::{ ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, - LoadWallet, Locked, PruneBlockchain, RawTransactionError, RawTransactionInput, + LoadWallet, Locked, Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, TransactionCategory, @@ -293,5 +293,5 @@ pub use crate::{ GetMempoolDescendants, GetMempoolDescendantsVerbose, GetRpcInfo, MapMempoolEntryError, MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, }, - v20::{Banned, CreateMultisig, ListBanned, Logging}, + v20::{Banned, CreateMultisig, ListBanned}, }; diff --git a/types/src/v22/control.rs b/types/src/v22/control.rs deleted file mode 100644 index 9e6fbf0e..00000000 --- a/types/src/v22/control.rs +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -//! The JSON-RPC API for Bitcoin Core `v22` - control. -//! -//! Types for methods found under the `== Control ==` section of the API docs. - -use serde::{Deserialize, Serialize}; - -/// Result of JSON-RPC method `logging`. -/// -/// > logging ( `` `` ) -/// -/// > Gets and sets the logging configuration. -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct Logging { - pub net: bool, - pub tor: bool, - pub mempool: bool, - pub http: bool, - pub bench: bool, - pub zmq: bool, - pub walletdb: bool, - pub rpc: bool, - pub estimatefee: bool, - pub addrman: bool, - pub selectcoins: bool, - pub reindex: bool, - pub cmpctblock: bool, - pub rand: bool, - pub prune: bool, - pub proxy: bool, - pub mempoolrej: bool, - pub libevent: bool, - pub coindb: bool, - pub qt: bool, - pub leveldb: bool, - pub validation: bool, - pub i2p: bool, - pub ipc: bool, -} diff --git a/types/src/v22/mod.rs b/types/src/v22/mod.rs index e26bd526..38fe47e0 100644 --- a/types/src/v22/mod.rs +++ b/types/src/v22/mod.rs @@ -244,13 +244,11 @@ // JSON-RPC types by API section. mod blockchain; -mod control; mod network; #[doc(inline)] pub use self::{ blockchain::GetMempoolInfo, - control::Logging, network::{Banned, GetPeerInfo, ListBanned}, }; #[doc(inline)] @@ -280,7 +278,7 @@ pub use crate::{ ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, - LoadWallet, Locked, PruneBlockchain, RawTransactionError, RawTransactionInput, + LoadWallet, Locked, Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, TransactionCategory, diff --git a/types/src/v23/mod.rs b/types/src/v23/mod.rs index 27777f71..2da8ece8 100644 --- a/types/src/v23/mod.rs +++ b/types/src/v23/mod.rs @@ -276,7 +276,7 @@ pub use crate::{ ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, - ListTransactionsItemError, ListUnspentItemError, ListWallets, LoadWallet, Locked, + ListTransactionsItemError, ListUnspentItemError, ListWallets, LoadWallet, Locked, Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, @@ -299,5 +299,5 @@ pub use crate::{ Softfork, SoftforkType, }, v21::{GetNetworkInfo, UnloadWallet}, - v22::{Banned, GetMempoolInfo, ListBanned, Logging, ScriptPubkey}, + v22::{Banned, GetMempoolInfo, ListBanned, ScriptPubkey}, }; diff --git a/types/src/v24/mod.rs b/types/src/v24/mod.rs index fe4c9524..77f42813 100644 --- a/types/src/v24/mod.rs +++ b/types/src/v24/mod.rs @@ -279,7 +279,7 @@ pub use crate::{ ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, - ListTransactionsItemError, ListUnspentItemError, ListWallets, LoadWallet, Locked, + ListTransactionsItemError, ListUnspentItemError, ListWallets, LoadWallet, Locked, Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, @@ -302,6 +302,6 @@ pub use crate::{ Softfork, SoftforkType, }, v21::{GetNetworkInfo, UnloadWallet}, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, + v22::{Banned, ListBanned, ScriptPubkey}, v23::{CreateMultisig, GetBlockchainInfo, SaveMempool}, }; diff --git a/types/src/v25/mod.rs b/types/src/v25/mod.rs index b322fc45..fd21af75 100644 --- a/types/src/v25/mod.rs +++ b/types/src/v25/mod.rs @@ -270,13 +270,13 @@ pub use crate::{ ListLockUnspentItemError, ListReceivedByAddress, ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, - ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, PruneBlockchain, - RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, - SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, - SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, - TransactionCategory, UploadTarget, ValidateAddress, ValidateAddressError, VerifyChain, - VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, WalletCreateFundedPsbtError, - WalletProcessPsbt, WitnessUtxo, + ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, Logging, + PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, + RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, + SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, + SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, + ValidateAddressError, VerifyChain, VerifyMessage, VerifyTxOutProof, WalletCreateFundedPsbt, + WalletCreateFundedPsbtError, WalletProcessPsbt, WitnessUtxo, }, v18::{ ActiveCommand, AnalyzePsbt, AnalyzePsbtError, AnalyzePsbtInput, AnalyzePsbtInputMissing, @@ -293,7 +293,7 @@ pub use crate::{ Softfork, SoftforkType, }, v21::GetNetworkInfo, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, + v22::{Banned, ListBanned, ScriptPubkey}, v23::{CreateMultisig, GetBlockchainInfo, SaveMempool}, v24::{ DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GetPeerInfo, GlobalXpub, diff --git a/types/src/v26/mod.rs b/types/src/v26/mod.rs index 802dff24..2f8ecf20 100644 --- a/types/src/v26/mod.rs +++ b/types/src/v26/mod.rs @@ -292,7 +292,7 @@ pub use crate::{ ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, - PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, + Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, @@ -314,7 +314,7 @@ pub use crate::{ Softfork, SoftforkType, }, v21::GetNetworkInfo, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, + v22::{Banned, ListBanned, ScriptPubkey}, v23::{CreateMultisig, GetBlockchainInfo, SaveMempool}, v24::{ DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GlobalXpub, Proprietary, diff --git a/types/src/v27/mod.rs b/types/src/v27/mod.rs index 6dcf5cb1..7f15ee71 100644 --- a/types/src/v27/mod.rs +++ b/types/src/v27/mod.rs @@ -274,7 +274,7 @@ pub use crate::{ ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, - PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, + Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, @@ -296,7 +296,7 @@ pub use crate::{ Softfork, SoftforkType, }, v21::GetNetworkInfo, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, + v22::{Banned, ListBanned, ScriptPubkey}, v23::{CreateMultisig, GetBlockchainInfo, SaveMempool}, v24::{ DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GlobalXpub, Proprietary, diff --git a/types/src/v28/mod.rs b/types/src/v28/mod.rs index 8a496c93..fb712799 100644 --- a/types/src/v28/mod.rs +++ b/types/src/v28/mod.rs @@ -291,7 +291,7 @@ pub use crate::{ ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, - PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, + Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, SoftforkReject, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, @@ -312,7 +312,7 @@ pub use crate::{ MempoolEntry, MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, Softfork, SoftforkType, }, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, + v22::{Banned, ListBanned, ScriptPubkey}, v23::{CreateMultisig, SaveMempool}, v24::{ DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GlobalXpub, Proprietary, diff --git a/types/src/v29/mod.rs b/types/src/v29/mod.rs index 4e9ee32f..0e6d6ba8 100644 --- a/types/src/v29/mod.rs +++ b/types/src/v29/mod.rs @@ -293,7 +293,7 @@ pub use crate::{ ListReceivedByAddressError, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockError, ListSinceBlockTransaction, ListSinceBlockTransactionError, ListTransactions, ListTransactionsItem, ListTransactionsItemError, ListUnspentItemError, ListWallets, Locked, - PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, + Logging, PruneBlockchain, RawTransactionError, RawTransactionInput, RawTransactionOutput, RescanBlockchain, SendMany, SendRawTransaction, SendToAddress, SetNetworkActive, SignMessage, SignMessageWithPrivKey, SignRawTransaction, SignRawTransactionError, TestMempoolAccept, TransactionCategory, UploadTarget, ValidateAddress, @@ -314,7 +314,7 @@ pub use crate::{ MempoolEntryError, MempoolEntryFees, MempoolEntryFeesError, PeerInfo, Softfork, SoftforkType, }, - v22::{Banned, ListBanned, Logging, ScriptPubkey}, + v22::{Banned, ListBanned, ScriptPubkey}, v23::{CreateMultisig, SaveMempool}, v24::{ DecodePsbt, DecodePsbtError, GetMempoolEntry, GetMempoolInfo, GlobalXpub, Proprietary, From 28609ca760b7094d74c5d82cb68d13c15038016d Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Wed, 25 Jun 2025 14:37:06 +0100 Subject: [PATCH 5/6] Add missing field to ScriptPubKey A return field `desc` was added in v23. Add it as an option to the struct. --- types/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/types/src/lib.rs b/types/src/lib.rs index d07770e6..4e477634 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -183,6 +183,9 @@ pub fn compact_size_decode(slice: &mut &[u8]) -> u64 { pub struct ScriptPubkey { /// Script assembly. pub asm: String, + /// Inferred descriptor for the output. v23 and later only. + #[serde(rename = "desc")] + pub descriptor: Option, /// Script hex. pub hex: String, /// Number of required signatures - deprecated in Core v22. From c00c2571fd661215e239ca74bfb466bb8a78f82e Mon Sep 17 00:00:00 2001 From: "Jamil Lambert, PhD" Date: Wed, 25 Jun 2025 15:37:25 +0100 Subject: [PATCH 6/6] Add missing fields to gettransaction Fields were added in v23, v24, v26, v29. Add the new return fields as options to the v17 definition. Add the new LastProcessedBlock type, model, error and into function. Add GetTransaction error variants, update the model and into function. --- types/src/model/mod.rs | 12 +++---- types/src/model/wallet.rs | 33 +++++++++++++++++++ types/src/v17/wallet/error.rs | 60 +++++++++++++++++++++++++++++++++++ types/src/v17/wallet/into.rs | 45 ++++++++++++++++++++++++-- types/src/v17/wallet/mod.rs | 50 ++++++++++++++++++++++++++--- 5 files changed, 188 insertions(+), 12 deletions(-) diff --git a/types/src/model/mod.rs b/types/src/model/mod.rs index 007d3d69..70c9fe68 100644 --- a/types/src/model/mod.rs +++ b/types/src/model/mod.rs @@ -55,11 +55,11 @@ pub use self::{ GetAddressesByLabel, GetBalance, GetBalances, GetBalancesMine, GetBalancesWatchOnly, GetNewAddress, GetRawChangeAddress, GetReceivedByAddress, GetReceivedByLabel, GetTransaction, GetTransactionDetail, GetUnconfirmedBalance, GetWalletInfo, - ListAddressGroupings, ListAddressGroupingsItem, ListLabels, ListLockUnspent, - ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListReceivedByLabel, - ListReceivedByLabelItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, - ListTransactionsItem, ListUnspent, ListUnspentItem, ListWallets, LoadWallet, - RescanBlockchain, ScriptType, SendMany, SendToAddress, SignMessage, TransactionCategory, - UnloadWallet, WalletCreateFundedPsbt, WalletProcessPsbt, + LastProcessedBlock, ListAddressGroupings, ListAddressGroupingsItem, ListLabels, + ListLockUnspent, ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, + ListReceivedByLabel, ListReceivedByLabelItem, ListSinceBlock, ListSinceBlockTransaction, + ListTransactions, ListTransactionsItem, ListUnspent, ListUnspentItem, ListWallets, + LoadWallet, RescanBlockchain, ScriptType, SendMany, SendToAddress, SignMessage, + TransactionCategory, UnloadWallet, WalletCreateFundedPsbt, WalletProcessPsbt, }, }; diff --git a/types/src/model/wallet.rs b/types/src/model/wallet.rs index a7755692..ce16e4d3 100644 --- a/types/src/model/wallet.rs +++ b/types/src/model/wallet.rs @@ -290,27 +290,51 @@ pub struct GetTransaction { pub fee: Option, /// The number of confirmations. pub confirmations: i64, // Docs do not indicate what negative value means? + /// Only present if the transaction's only input is a coinbase one. v29 and later only. + pub generated: Option, /// Whether we consider the outputs of this unconfirmed transaction safe to spend. pub trusted: Option, /// The block hash. pub block_hash: Option, + /// The block height containing the transaction. v29 and later only. + pub block_height: Option, /// The index of the transaction in the block that includes it. pub block_index: Option, /// The time in seconds since epoch (1 Jan 1970 GMT). pub block_time: Option, /// The transaction id. pub txid: Txid, + /// The hash of serialized transaction, including witness data. v29 and later only. + pub wtxid: Option, /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. pub wallet_conflicts: Vec, + /// Only if 'category' is 'send'. The txid if this tx was replaced. v29 and later only. + pub replaced_by_txid: Option, + /// Only if 'category' is 'send'. The txid if this tx replaces another. v29 and later only. + pub replaces_txid: Option, + /// Transactions in the mempool that directly conflict with either this transaction or an ancestor transaction. v29 and later only. + pub mempool_conflicts: Option>, + /// If a comment to is associated with the transaction. v29 and later only. + pub to: Option, /// The transaction time in seconds since epoch (1 Jan 1970 GMT). pub time: u32, /// The time received in seconds since epoch (1 Jan 1970 GMT). pub time_received: u32, + /// If a comment is associated with the transaction, only present if not empty. v29 and later only. + pub comment: Option, /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); /// may be unknown for unconfirmed transactions not in the mempool pub bip125_replaceable: Bip125Replaceable, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this coin. v29 and later only. + pub parent_descriptors: Option>, /// Transaction details. pub details: Vec, + /// Raw data for transaction. v29 and later only. + pub hex: Option, + /// The decoded transaction (only present when `verbose` is passed). v29 and later only. + pub decoded: Option, + /// Hash and height of the block this information was generated on. v29 and later only. + pub last_processed_block: Option, /// The transaction, parsed from hex string. pub tx: Transaction, } @@ -340,6 +364,15 @@ pub struct GetTransactionDetail { pub abandoned: Option, } +/// Part of the `GetTransaction`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct LastProcessedBlock { + /// Hash of the block this information was generated on. + pub hash: BlockHash, + /// Height of the block this information was generated on. + pub height: u32, +} + /// Models the result of JSON-RPC method `getunconfirmedbalance`. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct GetUnconfirmedBalance(pub Amount); diff --git a/types/src/v17/wallet/error.rs b/types/src/v17/wallet/error.rs index 5cebbff5..82c518a0 100644 --- a/types/src/v17/wallet/error.rs +++ b/types/src/v17/wallet/error.rs @@ -249,12 +249,22 @@ pub enum GetTransactionError { BlockHash(hex::HexToArrayError), /// Conversion of the `txid` field failed. Txid(hex::HexToArrayError), + /// Conversion of the `wtxid` field failed. + Wtxid(hex::HexToArrayError), /// Conversion of the `wallet_conflicts` field failed. WalletConflicts(hex::HexToArrayError), + /// Conversion of the `replaced_by_txid` field failed. + ReplacedByTxid(hex::HexToArrayError), + /// Conversion of the `replaces_txid` field failed. + ReplacesTxid(hex::HexToArrayError), + /// Conversion of the `mempool_conflicts` field failed. + MempoolConflicts(hex::HexToArrayError), /// Conversion of the transaction `hex` field failed. Tx(encode::FromHexError), /// Conversion of the `details` field failed. Details(GetTransactionDetailError), + /// Conversion of the `last_processed_block` field failed. + LastProcessedBlock(LastProcessedBlockError), } impl fmt::Display for GetTransactionError { @@ -267,10 +277,19 @@ impl fmt::Display for GetTransactionError { E::Fee(ref e) => write_err!(f, "conversion of the `fee` field failed"; e), E::BlockHash(ref e) => write_err!(f, "conversion of the `block_hash` field failed"; e), E::Txid(ref e) => write_err!(f, "conversion of the `txid` field failed"; e), + E::Wtxid(ref e) => write_err!(f, "conversion of the `wtxid` field failed"; e), E::WalletConflicts(ref e) => write_err!(f, "conversion of the `wallet_conflicts` field failed"; e), + E::ReplacedByTxid(ref e) => + write_err!(f, "conversion of the `replaced_by_txid` field failed"; e), + E::ReplacesTxid(ref e) => + write_err!(f, "conversion of the `replaces_txid` field failed"; e), + E::MempoolConflicts(ref e) => + write_err!(f, "conversion of the `mempool_conflicts` field failed"; e), E::Tx(ref e) => write_err!(f, "conversion of the `hex` field failed"; e), E::Details(ref e) => write_err!(f, "conversion of the `details` field failed"; e), + E::LastProcessedBlock(ref e) => + write_err!(f, "conversion of the `last_processed_block` field failed"; e), } } } @@ -286,9 +305,14 @@ impl std::error::Error for GetTransactionError { E::Fee(ref e) => Some(e), E::BlockHash(ref e) => Some(e), E::Txid(ref e) => Some(e), + E::Wtxid(ref e) => Some(e), E::WalletConflicts(ref e) => Some(e), + E::ReplacedByTxid(ref e) => Some(e), + E::ReplacesTxid(ref e) => Some(e), + E::MempoolConflicts(ref e) => Some(e), E::Tx(ref e) => Some(e), E::Details(ref e) => Some(e), + E::LastProcessedBlock(ref e) => Some(e), } } } @@ -333,6 +357,42 @@ impl std::error::Error for GetTransactionDetailError { } } +/// Error when converting a `LastProcessedBlock` type into the model type. +#[derive(Debug)] +pub enum LastProcessedBlockError { + /// Conversion of the `hash` field failed. + Hash(hex::HexToArrayError), + /// Conversion of the `height` field failed. + Height(NumericError), +} + +impl fmt::Display for LastProcessedBlockError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use LastProcessedBlockError::*; + + match *self { + Hash(ref e) => write_err!(f, "conversion of the `hash` field failed"; e), + Height(ref e) => write_err!(f, "conversion of the `height` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for LastProcessedBlockError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use LastProcessedBlockError::*; + + match *self { + Hash(ref e) => Some(e), + Height(ref e) => Some(e), + } + } +} + +impl From for LastProcessedBlockError { + fn from(e: NumericError) -> Self { Self::Height(e) } +} + /// Error when converting a `GetWalletInfo` type into the model type. #[derive(Debug)] pub enum GetWalletInfoError { diff --git a/types/src/v17/wallet/into.rs b/types/src/v17/wallet/into.rs index e07f240d..6d47287d 100644 --- a/types/src/v17/wallet/into.rs +++ b/types/src/v17/wallet/into.rs @@ -331,39 +331,71 @@ impl GetTransaction { let amount = SignedAmount::from_btc(self.amount).map_err(E::Amount)?; let fee = self.fee.map(|fee| SignedAmount::from_btc(fee).map_err(E::Fee)).transpose()?; - let block_hash = self.block_hash.map(|s| s.parse::().map_err(E::BlockHash)).transpose()?; let block_index = self.block_index.map(|idx| crate::to_u32(idx, "block_index")).transpose()?; - + let block_height = + self.block_height.map(|h| crate::to_u32(h, "block_height")).transpose()?; let txid = self.txid.parse::().map_err(E::Txid)?; + let wtxid = self.wtxid.map(|s| s.parse::().map_err(E::Wtxid)).transpose()?; let wallet_conflicts = self .wallet_conflicts .into_iter() .map(|s| s.parse::().map_err(E::WalletConflicts)) .collect::, _>>()?; + let replaced_by_txid = self + .replaced_by_txid + .map(|s| s.parse::().map_err(E::ReplacedByTxid)) + .transpose()?; + let replaces_txid = + self.replaces_txid.map(|s| s.parse::().map_err(E::ReplacesTxid)).transpose()?; + let mempool_conflicts = self + .mempool_conflicts + .map(|vec| { + vec.into_iter() + .map(|s| s.parse::().map_err(E::MempoolConflicts)) + .collect::, _>>() + }) + .transpose()?; let tx = encode::deserialize_hex::(&self.hex).map_err(E::Tx)?; let details = self .details .into_iter() .map(|d| d.into_model().map_err(E::Details)) .collect::, _>>()?; + let last_processed_block = self + .last_processed_block + .map(|l| l.into_model()) + .transpose() + .map_err(E::LastProcessedBlock)?; Ok(model::GetTransaction { amount, fee, confirmations: self.confirmations, + generated: self.generated, trusted: self.trusted, block_hash, + block_height, block_index, block_time: self.block_time, txid, + wtxid, wallet_conflicts, + replaced_by_txid, + replaces_txid, + mempool_conflicts, + to: self.to, time: self.time, time_received: self.time_received, + comment: self.comment, bip125_replaceable: self.bip125_replaceable.into_model(), + parent_descriptors: self.parent_descriptors, details, + hex: Some(self.hex), + decoded: self.decoded, + last_processed_block, tx, }) } @@ -390,6 +422,15 @@ impl GetTransactionDetail { } } +impl LastProcessedBlock { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + let hash = self.hash.parse::().map_err(LastProcessedBlockError::Hash)?; + let height = crate::to_u32(self.height, "height")?; + Ok(model::LastProcessedBlock { height, hash }) + } +} + impl GetUnconfirmedBalance { /// Converts version specific type to a version nonspecific, more strongly typed type. pub fn into_model(self) -> Result { diff --git a/types/src/v17/wallet/mod.rs b/types/src/v17/wallet/mod.rs index bda0c483..25702305 100644 --- a/types/src/v17/wallet/mod.rs +++ b/types/src/v17/wallet/mod.rs @@ -11,7 +11,7 @@ use alloc::collections::BTreeMap; use bitcoin::amount::ParseAmountError; use bitcoin::key::{self, PrivateKey}; -use bitcoin::{hex, Amount, Txid}; +use bitcoin::{hex, Amount, Transaction, Txid}; use serde::{Deserialize, Serialize}; // TODO: Remove wildcard, use explicit types. @@ -436,41 +436,70 @@ pub struct GetTransaction { pub fee: Option, /// The number of confirmations. pub confirmations: i64, + /// Only present if the transaction's only input is a coinbase one. v29 and later only. + pub generated: Option, // v29 and later only. /// Whether we consider the outputs of this unconfirmed transaction safe to spend. pub trusted: Option, /// The block hash. #[serde(rename = "blockhash")] - // The docs say this field should exist but integration test fail without `Option`. pub block_hash: Option, + /// The block height containing the transaction. v29 and later only. + #[serde(rename = "blockheight")] + pub block_height: Option, // v29 and later only. /// The index of the transaction in the block that includes it. #[serde(rename = "blockindex")] - // The docs say this field should exist but integration test fail without `Option`. pub block_index: Option, /// The time in seconds since epoch (1 Jan 1970 GMT). #[serde(rename = "blocktime")] - pub block_time: Option, // Docs are wrong, this is not documented as optional. + pub block_time: Option, /// The transaction id. pub txid: String, + /// The hash of serialized transaction, including witness data. v23 and later only. + pub wtxid: Option, /// Confirmed transactions that have been detected by the wallet to conflict with this transaction. #[serde(rename = "walletconflicts")] pub wallet_conflicts: Vec, + /// Only if 'category' is 'send'. The txid if this tx was replaced. v29 and later only. + pub replaced_by_txid: Option, + /// Only if 'category' is 'send'. The txid if this tx replaces another. v29 and later only. + pub replaces_txid: Option, + /// Transactions in the mempool that directly conflict with either this transaction or an ancestor + /// transaction. v29 and later only. + #[serde(rename = "mempoolconflicts")] + pub mempool_conflicts: Option>, + /// If a comment to is associated with the transaction. v29 and later only. + pub to: Option, /// The transaction time in seconds since epoch (1 Jan 1970 GMT). pub time: u32, /// The time received in seconds since epoch (1 Jan 1970 GMT). #[serde(rename = "timereceived")] pub time_received: u32, + /// If a comment is associated with the transaction, only present if not empty. v29 and later only. + pub comment: Option, /// Whether this transaction could be replaced due to BIP125 (replace-by-fee); /// may be unknown for unconfirmed transactions not in the mempool #[serde(rename = "bip125-replaceable")] pub bip125_replaceable: Bip125Replaceable, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this + /// coin. v24 and later only. + #[serde(rename = "parent_descs")] + pub parent_descriptors: Option>, /// Transaction details. pub details: Vec, /// Raw data for transaction. pub hex: String, + /// The decoded transaction (only present when `verbose` is passed). v29 and later only. + pub decoded: Option, + /// Hash and height of the block this information was generated on. v26 and later only. + #[serde(rename = "lastprocessedblock")] + pub last_processed_block: Option, } #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct GetTransactionDetail { + /// Only returns true if imported addresses were involved in transaction. v29 and later only. + #[serde(rename = "involvesWatchonly")] + pub involves_watchonly: Option, /// DEPRECATED. The account name involved in the transaction, can be "" for the default account. pub account: Option, // Docs are wrong, this is not documented as optional. /// The bitcoin address involved in the transaction. @@ -491,6 +520,19 @@ pub struct GetTransactionDetail { /// /// Only available for the 'send' category of transactions. pub abandoned: Option, + /// Only if 'category' is 'received'. List of parent descriptors for the output script of this + /// coin. v24 and later only. + #[serde(rename = "parent_descs")] + pub parent_descriptors: Option>, +} + +/// Item returned as part of of `gettransaction`. v26 and later only. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct LastProcessedBlock { + /// Hash of the block this information was generated on. + pub hash: String, + /// Height of the block this information was generated on. + pub height: i64, } /// Result of the JSON-RPC method `getunconfirmedbalance`.