From 1c8f7464697190331147a9e834cc89ee84ad2336 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Sun, 11 May 2025 10:25:55 +1000 Subject: [PATCH] client: Move types to version specific module Currently we have a bit of confusion around types that are defined and used by the various client version modules. - Some currently don't change e.g., `Input` - Some are due to change in v29 e.g., `TemplateRequest` - Some change already e.g. `AddressVersion` And to make matters worse, I did 'custom' re-exports in `node` which is very confusing when one is reading code in `client`. Put all `client` defined types in the version module they first appear in and re-export them as we do for types from `types`. Then use the type naked (without qualifying the path). --- client/src/client_sync/mod.rs | 39 ------------------ client/src/client_sync/v17/mod.rs | 40 +++++++++++++++++-- .../src/client_sync/v17/raw_transactions.rs | 10 ++--- client/src/client_sync/v17/wallet.rs | 2 +- client/src/client_sync/v18/mod.rs | 4 +- client/src/client_sync/v19/mod.rs | 3 +- client/src/client_sync/v20.rs | 3 +- client/src/client_sync/v21/mod.rs | 3 +- client/src/client_sync/v22/mod.rs | 3 +- client/src/client_sync/v23/mod.rs | 3 +- client/src/client_sync/v24.rs | 4 +- client/src/client_sync/v25.rs | 4 +- client/src/client_sync/v26/mod.rs | 3 +- client/src/client_sync/v27.rs | 4 +- client/src/client_sync/v28/mod.rs | 3 +- integration_test/tests/mining.rs | 3 +- integration_test/tests/raw_transactions.rs | 3 +- integration_test/tests/wallet.rs | 3 +- node/src/client_versions.rs | 34 ++++++++-------- node/src/lib.rs | 4 +- 20 files changed, 77 insertions(+), 98 deletions(-) diff --git a/client/src/client_sync/mod.rs b/client/src/client_sync/mod.rs index f26cbaac..3e6c56c8 100644 --- a/client/src/client_sync/mod.rs +++ b/client/src/client_sync/mod.rs @@ -16,14 +16,10 @@ pub mod v26; pub mod v27; pub mod v28; -use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::PathBuf; -use bitcoin::{Address, Amount, Txid}; -use serde::{Deserialize, Serialize}; - pub use crate::client_sync::error::Error; /// Crate-specific Result type. @@ -224,38 +220,3 @@ fn log_response(method: &str, resp: &Result) { } } } - -/// Input used as parameter to `create_raw_transaction`. -#[derive(Debug, Serialize)] -pub struct Input { - /// The txid of the transaction that contains the UTXO. - pub txid: bitcoin::Txid, - /// The vout for the UTXO. - pub vout: u64, - /// Sequence number if needed. - pub sequence: Option, -} - -/// Output used as parameter to `create_raw_transaction`. -// Abuse `HashMap` so we can derive serialize to get the correct JSON object. -#[derive(Debug, Serialize)] -pub struct Output( - /// Map of address to value. Always only has a single item in it. - HashMap, -); - -impl Output { - /// Creates a single output that serializes as Core expects. - pub fn new(addr: Address, value: Amount) -> Self { - let mut map = HashMap::new(); - map.insert(addr.to_string(), value.to_btc()); - Output(map) - } -} - -/// An element in the `inputs` argument of method `walletcreatefundedpsbt`. -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct WalletCreateFundedPsbtInput { - txid: Txid, - vout: u32, -} diff --git a/client/src/client_sync/v17/mod.rs b/client/src/client_sync/v17/mod.rs index a00b5c72..880b727e 100644 --- a/client/src/client_sync/v17/mod.rs +++ b/client/src/client_sync/v17/mod.rs @@ -12,7 +12,7 @@ pub mod network; pub mod raw_transactions; pub mod wallet; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; use std::path::Path; use bitcoin::address::{Address, NetworkChecked}; @@ -22,9 +22,6 @@ use serde::{Deserialize, Serialize}; use crate::client_sync::into_json; use crate::types::v17::*; -#[rustfmt::skip] // Keep public re-exports separate. -pub use crate::client_sync::WalletCreateFundedPsbtInput; - crate::define_jsonrpc_minreq_client!("v17"); crate::impl_client_check_expected_server_version!({ [170200] }); @@ -174,3 +171,38 @@ pub enum TemplateRules { /// Taproot supported. Taproot, } + +/// Input used as parameter to `create_raw_transaction`. +#[derive(Debug, Serialize)] +pub struct Input { + /// The txid of the transaction that contains the UTXO. + pub txid: bitcoin::Txid, + /// The vout for the UTXO. + pub vout: u64, + /// Sequence number if needed. + pub sequence: Option, +} + +/// Output used as parameter to `create_raw_transaction`. +// Abuse `HashMap` so we can derive serialize to get the correct JSON object. +#[derive(Debug, Serialize)] +pub struct Output( + /// Map of address to value. Always only has a single item in it. + HashMap, +); + +impl Output { + /// Creates a single output that serializes as Core expects. + pub fn new(addr: Address, value: Amount) -> Self { + let mut map = HashMap::new(); + map.insert(addr.to_string(), value.to_btc()); + Output(map) + } +} + +/// An element in the `inputs` argument of method `walletcreatefundedpsbt`. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct WalletCreateFundedPsbtInput { + txid: Txid, + vout: u32, +} diff --git a/client/src/client_sync/v17/raw_transactions.rs b/client/src/client_sync/v17/raw_transactions.rs index 2016f730..4cd8e489 100644 --- a/client/src/client_sync/v17/raw_transactions.rs +++ b/client/src/client_sync/v17/raw_transactions.rs @@ -59,11 +59,7 @@ macro_rules! impl_client_v17__converttopsbt { macro_rules! impl_client_v17__createpsbt { () => { impl Client { - pub fn create_psbt( - &self, - inputs: &[$crate::client_sync::Input], - outputs: &[$crate::client_sync::Output], - ) -> Result { + pub fn create_psbt(&self, inputs: &[Input], outputs: &[Output]) -> Result { self.call("createpsbt", &[into_json(inputs)?, into_json(outputs)?]) } } @@ -77,8 +73,8 @@ macro_rules! impl_client_v17__createrawtransaction { impl Client { pub fn create_raw_transaction( &self, - inputs: &[$crate::client_sync::Input], - outputs: &[$crate::client_sync::Output], + inputs: &[Input], + outputs: &[Output], ) -> Result { self.call("createrawtransaction", &[into_json(inputs)?, into_json(outputs)?]) } diff --git a/client/src/client_sync/v17/wallet.rs b/client/src/client_sync/v17/wallet.rs index 21100037..138ac1df 100644 --- a/client/src/client_sync/v17/wallet.rs +++ b/client/src/client_sync/v17/wallet.rs @@ -446,7 +446,7 @@ macro_rules! impl_client_v17__walletcreatefundedpsbt { impl Client { pub fn wallet_create_funded_psbt( &self, - inputs: Vec<$crate::client_sync::WalletCreateFundedPsbtInput>, + inputs: Vec, outputs: Vec>, ) -> Result { self.call("walletcreatefundedpsbt", &[into_json(inputs)?, into_json(outputs)?]) diff --git a/client/src/client_sync/v18/mod.rs b/client/src/client_sync/v18/mod.rs index c5e58f51..32e2d414 100644 --- a/client/src/client_sync/v18/mod.rs +++ b/client/src/client_sync/v18/mod.rs @@ -18,10 +18,10 @@ use crate::types::v18::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{AddressType, TemplateRequest, TemplateRules}, - WalletCreateFundedPsbtInput + v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, }; +// This publicly re-exports `Client`. crate::define_jsonrpc_minreq_client!("v18"); crate::impl_client_check_expected_server_version!({ [180100] }); diff --git a/client/src/client_sync/v19/mod.rs b/client/src/client_sync/v19/mod.rs index 712beb4c..e3c39b6f 100644 --- a/client/src/client_sync/v19/mod.rs +++ b/client/src/client_sync/v19/mod.rs @@ -18,8 +18,7 @@ use crate::types::v19::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{AddressType, TemplateRequest, TemplateRules}, - WalletCreateFundedPsbtInput + v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, }; crate::define_jsonrpc_minreq_client!("v19"); diff --git a/client/src/client_sync/v20.rs b/client/src/client_sync/v20.rs index 72f0aa24..35b69389 100644 --- a/client/src/client_sync/v20.rs +++ b/client/src/client_sync/v20.rs @@ -15,8 +15,7 @@ use crate::types::v20::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{AddressType, TemplateRequest, TemplateRules}, - WalletCreateFundedPsbtInput + v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, }; crate::define_jsonrpc_minreq_client!("v20"); diff --git a/client/src/client_sync/v21/mod.rs b/client/src/client_sync/v21/mod.rs index 803d8e05..c4cb3c36 100644 --- a/client/src/client_sync/v21/mod.rs +++ b/client/src/client_sync/v21/mod.rs @@ -17,8 +17,7 @@ use crate::types::v21::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{AddressType, TemplateRequest, TemplateRules}, - WalletCreateFundedPsbtInput + v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, }; crate::define_jsonrpc_minreq_client!("v21"); diff --git a/client/src/client_sync/v22/mod.rs b/client/src/client_sync/v22/mod.rs index a3a3fee0..9828ceeb 100644 --- a/client/src/client_sync/v22/mod.rs +++ b/client/src/client_sync/v22/mod.rs @@ -18,8 +18,7 @@ use crate::types::v22::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{AddressType, TemplateRequest, TemplateRules}, - WalletCreateFundedPsbtInput + v17::{AddressType, Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, }; crate::define_jsonrpc_minreq_client!("v22"); diff --git a/client/src/client_sync/v23/mod.rs b/client/src/client_sync/v23/mod.rs index 0cbced31..fb307fb7 100644 --- a/client/src/client_sync/v23/mod.rs +++ b/client/src/client_sync/v23/mod.rs @@ -19,8 +19,7 @@ use crate::types::v23::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{TemplateRequest, TemplateRules}, - WalletCreateFundedPsbtInput + v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, }; crate::define_jsonrpc_minreq_client!("v23"); diff --git a/client/src/client_sync/v24.rs b/client/src/client_sync/v24.rs index 6719790f..5f87e616 100644 --- a/client/src/client_sync/v24.rs +++ b/client/src/client_sync/v24.rs @@ -15,8 +15,8 @@ use crate::types::v24::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{TemplateRequest, TemplateRules}, - v23::AddressType, WalletCreateFundedPsbtInput + v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, + v23::AddressType, }; crate::define_jsonrpc_minreq_client!("v24"); diff --git a/client/src/client_sync/v25.rs b/client/src/client_sync/v25.rs index e35b6a94..0e9c39bf 100644 --- a/client/src/client_sync/v25.rs +++ b/client/src/client_sync/v25.rs @@ -15,8 +15,8 @@ use crate::types::v25::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{TemplateRequest, TemplateRules}, - v23::AddressType, WalletCreateFundedPsbtInput + v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, + v23::AddressType, }; crate::define_jsonrpc_minreq_client!("v25"); diff --git a/client/src/client_sync/v26/mod.rs b/client/src/client_sync/v26/mod.rs index a5dabb1a..6b917337 100644 --- a/client/src/client_sync/v26/mod.rs +++ b/client/src/client_sync/v26/mod.rs @@ -19,9 +19,8 @@ use crate::types::v26::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{TemplateRequest, TemplateRules}, + v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, v23::AddressType, - WalletCreateFundedPsbtInput }; crate::define_jsonrpc_minreq_client!("v26"); diff --git a/client/src/client_sync/v27.rs b/client/src/client_sync/v27.rs index dff657fa..fa6df521 100644 --- a/client/src/client_sync/v27.rs +++ b/client/src/client_sync/v27.rs @@ -15,8 +15,8 @@ use crate::types::v27::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{TemplateRequest, TemplateRules}, - v23::AddressType, WalletCreateFundedPsbtInput + v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, + v23::AddressType, }; crate::define_jsonrpc_minreq_client!("v27"); diff --git a/client/src/client_sync/v28/mod.rs b/client/src/client_sync/v28/mod.rs index 8fb1d30e..2ac27bb5 100644 --- a/client/src/client_sync/v28/mod.rs +++ b/client/src/client_sync/v28/mod.rs @@ -17,9 +17,8 @@ use crate::types::v28::*; #[rustfmt::skip] // Keep public re-exports separate. pub use crate::client_sync::{ - v17::{TemplateRequest, TemplateRules}, + v17::{Input, Output, TemplateRequest, TemplateRules, WalletCreateFundedPsbtInput}, v23::AddressType, - WalletCreateFundedPsbtInput }; crate::define_jsonrpc_minreq_client!("v28"); diff --git a/integration_test/tests/mining.rs b/integration_test/tests/mining.rs index e9fd0e10..5a52e03a 100644 --- a/integration_test/tests/mining.rs +++ b/integration_test/tests/mining.rs @@ -6,9 +6,8 @@ use bitcoin::SignedAmount; use integration_test::{Node, NodeExt as _, Wallet}; -use node::{TemplateRequest, TemplateRules}; +use node::{mtype, TemplateRequest, TemplateRules}; use node::vtype::*; // All the version specific types. -use node::mtype; #[test] fn mining__get_block_template__modelled() { diff --git a/integration_test/tests/raw_transactions.rs b/integration_test/tests/raw_transactions.rs index 04a5dbac..bdb942b8 100644 --- a/integration_test/tests/raw_transactions.rs +++ b/integration_test/tests/raw_transactions.rs @@ -9,9 +9,8 @@ use bitcoin::hex::FromHex as _; use bitcoin::opcodes::all::*; use bitcoin::{absolute, transaction, consensus, script, Amount, TxOut, Transaction, ScriptBuf}; use integration_test::{Node, NodeExt as _, Wallet}; -use node::client::client_sync::{Input, Output}; +use node::{mtype, Input, Output}; use node::vtype::*; // All the version specific types. -use node::mtype; #[test] #[cfg(not(feature = "v17"))] // analyzepsbt was added in v18. diff --git a/integration_test/tests/wallet.rs b/integration_test/tests/wallet.rs index 0c913ee9..f5ced3e1 100644 --- a/integration_test/tests/wallet.rs +++ b/integration_test/tests/wallet.rs @@ -8,9 +8,8 @@ use bitcoin::address::{Address, NetworkChecked}; use bitcoin::Amount; use integration_test::{Node, NodeExt as _, Wallet}; -use node::AddressType; +use node::{mtype,AddressType}; use node::vtype::*; // All the version specific types. -use node::mtype; #[test] #[cfg(feature = "TODO")] diff --git a/node/src/client_versions.rs b/node/src/client_versions.rs index c12634cb..302f6783 100644 --- a/node/src/client_versions.rs +++ b/node/src/client_versions.rs @@ -7,52 +7,52 @@ #![allow(unused_imports)] // Not all users need the json types. #[cfg(feature = "28_0")] -pub use corepc_client::{client_sync::v28::{Client, AddressType, TemplateRequest, TemplateRules}, types::v28 as vtype}; +pub use corepc_client::{client_sync::v28::*, types::v28 as vtype}; #[cfg(all(feature = "27_2", not(feature = "28_0")))] -pub use corepc_client::{client_sync::v27::{Client, AddressType, TemplateRequest, TemplateRules}, types::v27 as vtype}; +pub use corepc_client::{client_sync::v27::*, types::v27 as vtype}; #[cfg(all(feature = "27_1", not(feature = "27_2")))] -pub use corepc_client::{client_sync::v27::{Client, AddressType, TemplateRequest, TemplateRules}, types::v27 as vtype}; +pub use corepc_client::{client_sync::v27::*, types::v27 as vtype}; #[cfg(all(feature = "27_0", not(feature = "27_1")))] -pub use corepc_client::{client_sync::v27::{Client, AddressType, TemplateRequest, TemplateRules}, types::v27 as vtype}; +pub use corepc_client::{client_sync::v27::*, types::v27 as vtype}; #[cfg(all(feature = "26_2", not(feature = "27_0")))] -pub use corepc_client::{client_sync::v26::{Client, AddressType, TemplateRequest, TemplateRules}, types::v26 as vtype}; +pub use corepc_client::{client_sync::v26::*, types::v26 as vtype}; #[cfg(all(feature = "26_1", not(feature = "26_2")))] -pub use corepc_client::{client_sync::v26::{Client, AddressType, TemplateRequest, TemplateRules}, types::v26 as vtype}; +pub use corepc_client::{client_sync::v26::*, types::v26 as vtype}; #[cfg(all(feature = "26_0", not(feature = "26_1")))] -pub use corepc_client::{client_sync::v26::{Client, AddressType, TemplateRequest, TemplateRules}, types::v26 as vtype}; +pub use corepc_client::{client_sync::v26::*, types::v26 as vtype}; #[cfg(all(feature = "25_2", not(feature = "26_0")))] -pub use corepc_client::{client_sync::v25::{Client, AddressType, TemplateRequest, TemplateRules}, types::v25 as vtype}; +pub use corepc_client::{client_sync::v25::*, types::v25 as vtype}; #[cfg(all(feature = "24_2", not(feature = "25_2")))] -pub use corepc_client::{client_sync::v24::{Client, AddressType, TemplateRequest, TemplateRules}, types::v24 as vtype}; +pub use corepc_client::{client_sync::v24::*, types::v24 as vtype}; #[cfg(all(feature = "23_2", not(feature = "24_2")))] -pub use corepc_client::{client_sync::v23::{Client, AddressType, TemplateRequest, TemplateRules}, types::v23 as vtype}; +pub use corepc_client::{client_sync::v23::*, types::v23 as vtype}; #[cfg(all(feature = "22_1", not(feature = "23_2")))] -pub use corepc_client::{client_sync::v22::{Client, AddressType, TemplateRequest, TemplateRules}, types::v22 as vtype}; +pub use corepc_client::{client_sync::v22::*, types::v22 as vtype}; #[cfg(all(feature = "0_21_2", not(feature = "22_1")))] -pub use corepc_client::{client_sync::v21::{Client, AddressType, TemplateRequest, TemplateRules}, types::v21 as vtype}; +pub use corepc_client::{client_sync::v21::*, types::v21 as vtype}; #[cfg(all(feature = "0_20_2", not(feature = "0_21_2")))] -pub use corepc_client::{client_sync::v20::{Client, AddressType, TemplateRequest, TemplateRules}, types::v20 as vtype}; +pub use corepc_client::{client_sync::v20::*, types::v20 as vtype}; #[cfg(all(feature = "0_19_1", not(feature = "0_20_2")))] -pub use corepc_client::{client_sync::v19::{Client, AddressType, TemplateRequest, TemplateRules}, types::v19 as vtype}; +pub use corepc_client::{client_sync::v19::*, types::v19 as vtype}; #[cfg(all(feature = "0_18_1", not(feature = "0_19_1")))] -pub use corepc_client::{client_sync::v18::{Client, AddressType, TemplateRequest, TemplateRules}, types::v18 as vtype}; +pub use corepc_client::{client_sync::v18::*, types::v18 as vtype}; #[cfg(all(feature = "0_17_2", not(feature = "0_18_1")))] -pub use corepc_client::{client_sync::v17::{Client, AddressType, TemplateRequest, TemplateRules}, types::v17 as vtype}; +pub use corepc_client::{client_sync::v17::*, types::v17 as vtype}; /// This is meaningless but we need it otherwise we can't get far enough into /// the build process to trigger the `compile_error!` in `./versions.rs`. @@ -74,4 +74,4 @@ pub use corepc_client::{client_sync::v17::{Client, AddressType, TemplateRequest, not(feature = "0_18_1"), not(feature = "0_17_2"), ))] -pub use corepc_client::{client_sync::v28::{Client, AddressType, TemplateRequest, TemplateRules}, types::v28 as vtype}; +pub use corepc_client::{client_sync::v28::*, types::v28 as vtype}; diff --git a/node/src/lib.rs b/node/src/lib.rs index 874ae6fc..5dbaa4fa 100644 --- a/node/src/lib.rs +++ b/node/src/lib.rs @@ -23,8 +23,8 @@ pub use {anyhow, serde_json, tempfile, which}; #[rustfmt::skip] // Keep pubic re-exports separate. #[doc(inline)] pub use self::{ - // Re-export `vtype` - the version specific types. - client_versions::{vtype, Client, AddressType, TemplateRequest, TemplateRules}, + // Re-export `vtype` (the version specific types) and client defined types. + client_versions::*, // Re-export the version string e.g., "28.0". versions::VERSION, // Re-export the model types as `mtype` to differentiate it from `vtype`.