From f5fe7e5b80d73bf355a8d14e9f87118e8e534184 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Thu, 6 Mar 2025 10:33:30 +0100 Subject: [PATCH] Expose blockchain APIs in Client Fix as required and expose in the `Client` all the methods from the `blockchain` section. - Fix `gettxout` for `v22`+ .. since then `ScriptPubkey` dropped the `addresses` and `reqSigs` field (see https://github.com/bitcoin/bitcoin/blob/master/doc/release-notes/release-notes-22.0.md#new-and-updated-rpcs and https://github.com/bitcoin/bitcoin/pull/20286). - Expose `getblockcount` for `v19`+ clients - Expose `getblockhash` for `v19`+ clients - Expose `getblockheader` for `v19`+ clients - Expose `getblockstats` for `v19`+ clients - Expose `getchaintips` for `v19`+ clients - Expose `getchaintxstats` for `v19`+ clients - Expose `getdifficulty` for `v19`+ clients - Expose `get*mempool*` for `v19`+ clients - Expose remaining `get*txout*` for `v19`+ clients .. as they was previously only available in `v17` and `v18`. --- client/src/client_sync/v19/blockchain.rs | 62 ++++ client/src/client_sync/v19/mod.rs | 20 +- client/src/client_sync/v20.rs | 17 +- client/src/client_sync/v21.rs | 18 +- client/src/client_sync/v22/blockchain.rs | 22 ++ client/src/client_sync/v22/mod.rs | 20 +- client/src/client_sync/v23.rs | 19 +- client/src/client_sync/v24.rs | 19 +- client/src/client_sync/v25.rs | 19 +- client/src/client_sync/v26/blockchain.rs | 22 ++ client/src/client_sync/{v26.rs => v26/mod.rs} | 21 +- client/src/client_sync/v27.rs | 19 +- client/src/client_sync/v28/mod.rs | 19 +- integration_test/tests/blockchain.rs | 27 +- types/src/model/blockchain.rs | 13 +- types/src/v17/blockchain/into.rs | 6 +- types/src/v19/blockchain.rs | 327 +++++++++++++++++- types/src/v19/mod.rs | 29 +- types/src/v20/mod.rs | 27 +- types/src/v21/mod.rs | 27 +- types/src/v22/blockchain.rs | 130 +++++++ types/src/v22/mod.rs | 31 +- types/src/v23/mod.rs | 28 +- types/src/v24/mod.rs | 28 +- types/src/v25/mod.rs | 27 +- types/src/v26/blockchain.rs | 107 ++++++ types/src/v26/mod.rs | 25 +- types/src/v27/mod.rs | 22 +- types/src/v28/mod.rs | 22 +- 29 files changed, 1016 insertions(+), 157 deletions(-) create mode 100644 client/src/client_sync/v19/blockchain.rs create mode 100644 client/src/client_sync/v22/blockchain.rs create mode 100644 client/src/client_sync/v26/blockchain.rs rename client/src/client_sync/{v26.rs => v26/mod.rs} (65%) create mode 100644 types/src/v22/blockchain.rs create mode 100644 types/src/v26/blockchain.rs diff --git a/client/src/client_sync/v19/blockchain.rs b/client/src/client_sync/v19/blockchain.rs new file mode 100644 index 0000000..5475f25 --- /dev/null +++ b/client/src/client_sync/v19/blockchain.rs @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! Macros for implementing JSON-RPC methods on a client. +//! +//! Specifically this is methods found under the `== Blockchain ==` section of the +//! API docs of Bitcoin Core `v0.19`. +//! +//! All macros require `Client` to be in scope. +//! +//! See or use the `define_jsonrpc_minreq_client!` macro to define a `Client`. + +/// Implements Bitcoin Core JSON-RPC API method `getmempoolancestors` +#[macro_export] +macro_rules! impl_client_v19__getmempoolancestors { + () => { + impl Client { + pub fn get_mempool_ancestors(&self, txid: Txid) -> Result { + // Equivalent to self.call("getmempoolancestors", &[into_json(txid)?, into_json(false)?]) + self.call("getmempoolancestors", &[into_json(txid)?]) + } + + pub fn get_mempool_ancestors_verbose( + &self, + txid: Txid, + ) -> Result { + self.call("getmempoolancestors", &[into_json(txid)?, into_json(true)?]) + } + } + }; +} + +/// Implements Bitcoin Core JSON-RPC API method `getmempooldescendants` +#[macro_export] +macro_rules! impl_client_v19__getmempooldescendants { + () => { + impl Client { + pub fn get_mempool_descendants(&self, txid: Txid) -> Result { + // Equivalent to self.call("getmempooldescendants", &[into_json(txid)?, into_json(false)?]) + self.call("getmempooldescendants", &[into_json(txid)?]) + } + + pub fn get_mempool_descendants_verbose( + &self, + txid: Txid, + ) -> Result { + self.call("getmempooldescendants", &[into_json(txid)?, into_json(true)?]) + } + } + }; +} + +/// Implements Bitcoin Core JSON-RPC API method `getmempoolentry` +#[macro_export] +macro_rules! impl_client_v19__getmempoolentry { + () => { + impl Client { + pub fn get_mempool_entry(&self, txid: Txid) -> Result { + self.call("getmempoolentry", &[into_json(txid)?]) + } + } + }; +} diff --git a/client/src/client_sync/v19/mod.rs b/client/src/client_sync/v19/mod.rs index 3c2b996..8ec81b6 100644 --- a/client/src/client_sync/v19/mod.rs +++ b/client/src/client_sync/v19/mod.rs @@ -4,7 +4,8 @@ //! //! We ignore option arguments unless they effect the shape of the returned JSON data. -mod wallet; +pub mod blockchain; +pub mod wallet; use bitcoin::address::{Address, NetworkChecked}; use bitcoin::{Amount, Block, BlockHash, Txid}; @@ -15,10 +16,25 @@ use crate::types::v19::*; crate::define_jsonrpc_minreq_client!("v19"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v17__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v20.rs b/client/src/client_sync/v20.rs index aef7ecb..e906088 100644 --- a/client/src/client_sync/v20.rs +++ b/client/src/client_sync/v20.rs @@ -16,10 +16,25 @@ pub use crate::client_sync::v17::AddressType; crate::define_jsonrpc_minreq_client!("v20"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v17__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v21.rs b/client/src/client_sync/v21.rs index a028afe..b7aa4f9 100644 --- a/client/src/client_sync/v21.rs +++ b/client/src/client_sync/v21.rs @@ -16,9 +16,25 @@ pub use crate::client_sync::v17::AddressType; crate::define_jsonrpc_minreq_client!("v21"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); +crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v17__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v22/blockchain.rs b/client/src/client_sync/v22/blockchain.rs new file mode 100644 index 0000000..df90c8a --- /dev/null +++ b/client/src/client_sync/v22/blockchain.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! Macros for implementing JSON-RPC methods on a client. +//! +//! Specifically this is methods found under the `== Blockchain ==` section of the +//! API docs of Bitcoin Core `v22`. +//! +//! All macros require `Client` to be in scope. +//! +//! See or use the `define_jsonrpc_minreq_client!` macro to define a `Client`. + +/// Implements Bitcoin Core JSON-RPC API method `gettxout` +#[macro_export] +macro_rules! impl_client_v22__gettxout { + () => { + impl Client { + pub fn get_tx_out(&self, txid: Txid, vout: u64) -> Result { + self.call("gettxout", &[into_json(txid)?, into_json(vout)?]) + } + } + }; +} diff --git a/client/src/client_sync/v22/mod.rs b/client/src/client_sync/v22/mod.rs index f853d38..d296207 100644 --- a/client/src/client_sync/v22/mod.rs +++ b/client/src/client_sync/v22/mod.rs @@ -4,6 +4,7 @@ //! //! We ignore option arguments unless they effect the shape of the returned JSON data. +mod blockchain; mod wallet; use bitcoin::address::{Address, NetworkChecked}; @@ -15,10 +16,25 @@ use crate::types::v22::*; crate::define_jsonrpc_minreq_client!("v22"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); -crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); +crate::impl_client_v22__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v17__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v23.rs b/client/src/client_sync/v23.rs index 9a66564..a83ecac 100644 --- a/client/src/client_sync/v23.rs +++ b/client/src/client_sync/v23.rs @@ -14,10 +14,25 @@ use crate::types::v23::*; crate::define_jsonrpc_minreq_client!("v23"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); -crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); +crate::impl_client_v22__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v17__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v24.rs b/client/src/client_sync/v24.rs index d6ef1f2..65d29ee 100644 --- a/client/src/client_sync/v24.rs +++ b/client/src/client_sync/v24.rs @@ -16,10 +16,25 @@ pub use crate::client_sync::v23::AddressType; crate::define_jsonrpc_minreq_client!("v24"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); -crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); +crate::impl_client_v22__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v17__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v25.rs b/client/src/client_sync/v25.rs index b072643..c6763a3 100644 --- a/client/src/client_sync/v25.rs +++ b/client/src/client_sync/v25.rs @@ -16,10 +16,25 @@ pub use crate::client_sync::v23::AddressType; crate::define_jsonrpc_minreq_client!("v25"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); -crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); +crate::impl_client_v22__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v17__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v26/blockchain.rs b/client/src/client_sync/v26/blockchain.rs new file mode 100644 index 0000000..bb4aaff --- /dev/null +++ b/client/src/client_sync/v26/blockchain.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! Macros for implementing JSON-RPC methods on a client. +//! +//! Specifically this is methods found under the `== Blockchain ==` section of the +//! API docs of Bitcoin Core `v0.26`. +//! +//! All macros require `Client` to be in scope. +//! +//! See or use the `define_jsonrpc_minreq_client!` macro to define a `Client`. + +/// Implements Bitcoin Core JSON-RPC API method `gettxoutsetinfo` +#[macro_export] +macro_rules! impl_client_v26__gettxoutsetinfo { + () => { + impl Client { + pub fn get_tx_out_set_info(&self) -> Result { + self.call("gettxoutsetinfo", &[]) + } + } + }; +} diff --git a/client/src/client_sync/v26.rs b/client/src/client_sync/v26/mod.rs similarity index 65% rename from client/src/client_sync/v26.rs rename to client/src/client_sync/v26/mod.rs index 5104878..243f131 100644 --- a/client/src/client_sync/v26.rs +++ b/client/src/client_sync/v26/mod.rs @@ -4,6 +4,8 @@ //! //! We ignore option arguments unless they effect the shape of the returned JSON data. +pub mod blockchain; + use bitcoin::address::{Address, NetworkChecked}; use bitcoin::{Amount, Block, BlockHash, Txid}; @@ -16,10 +18,25 @@ pub use crate::client_sync::v23::AddressType; crate::define_jsonrpc_minreq_client!("v26"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); -crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); +crate::impl_client_v22__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v26__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v27.rs b/client/src/client_sync/v27.rs index d172e39..9f848f6 100644 --- a/client/src/client_sync/v27.rs +++ b/client/src/client_sync/v27.rs @@ -16,10 +16,25 @@ pub use crate::client_sync::v23::AddressType; crate::define_jsonrpc_minreq_client!("v27"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); -crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); +crate::impl_client_v22__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v26__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/client/src/client_sync/v28/mod.rs b/client/src/client_sync/v28/mod.rs index 6b364f2..a6a95e6 100644 --- a/client/src/client_sync/v28/mod.rs +++ b/client/src/client_sync/v28/mod.rs @@ -18,10 +18,25 @@ pub use crate::client_sync::v23::AddressType; crate::define_jsonrpc_minreq_client!("v28"); // == Blockchain == -crate::impl_client_v17__getblockchaininfo!(); crate::impl_client_v17__getbestblockhash!(); crate::impl_client_v17__getblock!(); -crate::impl_client_v17__gettxout!(); +crate::impl_client_v17__getblockchaininfo!(); +crate::impl_client_v17__getblockcount!(); +crate::impl_client_v17__getblockhash!(); +crate::impl_client_v17__getblockheader!(); +crate::impl_client_v17__getblockstats!(); +crate::impl_client_v17__getchaintips!(); +crate::impl_client_v17__getchaintxstats!(); +crate::impl_client_v17__getdifficulty!(); +crate::impl_client_v19__getmempoolancestors!(); +crate::impl_client_v19__getmempooldescendants!(); +crate::impl_client_v19__getmempoolentry!(); +crate::impl_client_v17__getmempoolinfo!(); +crate::impl_client_v17__getrawmempool!(); +crate::impl_client_v22__gettxout!(); +crate::impl_client_v17__gettxoutproof!(); +crate::impl_client_v26__gettxoutsetinfo!(); +crate::impl_client_v17__verifytxoutproof!(); // == Control == crate::impl_client_v17__stop!(); diff --git a/integration_test/tests/blockchain.rs b/integration_test/tests/blockchain.rs index 7bf1921..4f05c34 100644 --- a/integration_test/tests/blockchain.rs +++ b/integration_test/tests/blockchain.rs @@ -2,8 +2,6 @@ //! Tests for methods found under the `== Blockchain ==` section of the API docs. -#![cfg(any(feature = "0_17_1", feature = "0_18_1"))] - use integration_test::{Node, NodeExt as _}; // FIXME: Do we need this? @@ -72,23 +70,30 @@ fn get_block_header_verbose() { // verbose = true assert!(json.into_model().is_ok()); } -// FIXME: I don't know why this passes for v17 and not v18. I tried making stats -// optional as suggested in the docs but to no avail. +#[cfg(all(not(feature = "0_18_1"), not(feature = "0_19_1"), not(feature = "0_19_1"), not(feature = "0_20_2"), not(feature = "0_21_2"), not(feature = "22_1"), not(feature = "23_2"), not(feature = "24_2")))] +// `getblockstats` used to not work on the genesis block as it doesn't have undo data saved to disk +// (see https://github.com/bitcoin/bitcoin/pull/19888). We therefore only run tests for versions +// allowing to. #[test] -#[cfg(feature = "0_17_1")] fn get_block_stats() { get_block_stats_by_height(); get_block_stats_by_hash(); } -#[cfg(feature = "0_17_1")] +#[cfg(all(not(feature = "0_18_1"), not(feature = "0_19_1"), not(feature = "0_19_1"), not(feature = "0_20_2"), not(feature = "0_21_2"), not(feature = "22_1"), not(feature = "23_2"), not(feature = "24_2")))] +// `getblockstats` used to not work on the genesis block as it doesn't have undo data saved to disk +// (see https://github.com/bitcoin/bitcoin/pull/19888). We therefore only run tests for versions +// allowing to. fn get_block_stats_by_height() { let node = Node::new_no_wallet(); let json = node.client.get_block_stats_by_height(0).expect("getblockstats"); assert!(json.into_model().is_ok()); } -#[cfg(feature = "0_17_1")] +#[cfg(all(not(feature = "0_18_1"), not(feature = "0_19_1"), not(feature = "0_19_1"), not(feature = "0_20_2"), not(feature = "0_21_2"), not(feature = "22_1"), not(feature = "23_2"), not(feature = "24_2")))] +// `getblockstats` used to not work on the genesis block as it doesn't have undo data saved to disk +// (see https://github.com/bitcoin/bitcoin/pull/19888). We therefore only run tests for versions +// allowing to. fn get_block_stats_by_hash() { // verbose = true let node = Node::new_no_wallet(); let block_hash = best_block_hash(); @@ -96,6 +101,10 @@ fn get_block_stats_by_hash() { // verbose = true assert!(json.into_model().is_ok()); } +#[cfg(all(not(feature = "0_18_1"), not(feature = "0_19_1"), not(feature = "0_19_1"), not(feature = "0_20_2"), not(feature = "0_21_2"), not(feature = "22_1"), not(feature = "23_2"), not(feature = "24_2")))] +// `getblockstats` used to not work on the genesis block as it doesn't have undo data saved to disk +// (see https://github.com/bitcoin/bitcoin/pull/19888). We therefore only run tests for versions +// allowing to. #[test] fn get_block_stats_by_height_txindex() { let node = Node::new_no_wallet_txindex(); @@ -103,6 +112,10 @@ fn get_block_stats_by_height_txindex() { assert!(json.into_model().is_ok()); } +#[cfg(all(not(feature = "0_18_1"), not(feature = "0_19_1"), not(feature = "0_19_1"), not(feature = "0_20_2"), not(feature = "0_21_2"), not(feature = "22_1"), not(feature = "23_2"), not(feature = "24_2")))] +// `getblockstats` used to not work on the genesis block as it doesn't have undo data saved to disk +// (see https://github.com/bitcoin/bitcoin/pull/19888). We therefore only run tests for versions +// allowing to. #[test] fn get_block_stats_by_hash_txindex() { // verbose = true let node = Node::new_no_wallet_txindex(); diff --git a/types/src/model/blockchain.rs b/types/src/model/blockchain.rs index 01d5c7d..3f3ef2c 100644 --- a/types/src/model/blockchain.rs +++ b/types/src/model/blockchain.rs @@ -364,7 +364,14 @@ pub struct MempoolEntry { /// Virtual transaction size as defined in BIP 141. /// /// This is different from actual serialized size for witness transactions as witness data is discounted. - pub size: u32, + /// + /// This was deprecated with Bitcoin Core v0.19 and hence will be `None` for v0.19 and later. + pub size: Option, + /// Transaction weight as defined in BIP 141 + /// + /// This was introduced with Bitcoin Core v0.19 and will hence be `None` for previous + /// versions. + pub weight: Option, /// Local time transaction entered pool in seconds since 1 Jan 1970 GMT. pub time: u32, /// Block height when transaction entered pool. @@ -467,7 +474,9 @@ pub struct GetTxOutSetInfo { /// A meaningless metric for UTXO set size. pub bogo_size: u32, /// The serialized hash. - pub hash_serialized_2: String, // FIXME: What sort of hash is this? + /// + /// This was removed in Bitcoin Core v26, and hence will be `None` for v26 and later. + pub hash_serialized_2: Option, // FIXME: What sort of hash is this? /// The estimated size of the chainstate on disk. pub disk_size: u32, /// The total amount. diff --git a/types/src/v17/blockchain/into.rs b/types/src/v17/blockchain/into.rs index 4e22375..9bdc3d7 100644 --- a/types/src/v17/blockchain/into.rs +++ b/types/src/v17/blockchain/into.rs @@ -377,7 +377,8 @@ impl MempoolEntry { pub fn into_model(self) -> Result { use MempoolEntryError as E; - let size = crate::to_u32(self.size, "size")?; + let size = Some(crate::to_u32(self.size, "size")?); + let weight = None; let time = crate::to_u32(self.time, "time")?; let height = crate::to_u32(self.height, "height")?; let descendant_count = crate::to_u32(self.descendant_count, "descendant_count")?; @@ -401,6 +402,7 @@ impl MempoolEntry { Ok(model::MempoolEntry { size, + weight, time, height, descendant_count, @@ -512,7 +514,7 @@ impl GetTxOutSetInfo { let transactions = crate::to_u32(self.transactions, "transactions")?; let tx_outs = crate::to_u32(self.tx_outs, "tx_outs")?; let bogo_size = crate::to_u32(self.bogo_size, "bogo_size")?; - let hash_serialized_2 = self.hash_serialized_2; // TODO: Convert this to a hash type. + let hash_serialized_2 = Some(self.hash_serialized_2); // TODO: Convert this to a hash type. let disk_size = crate::to_u32(self.disk_size, "disk_size")?; let total_amount = Amount::from_btc(self.total_amount).map_err(E::TotalAmount)?; diff --git a/types/src/v19/blockchain.rs b/types/src/v19/blockchain.rs index bf4dab2..d956ded 100644 --- a/types/src/v19/blockchain.rs +++ b/types/src/v19/blockchain.rs @@ -7,8 +7,9 @@ use alloc::collections::BTreeMap; use core::fmt; +use bitcoin::amount::ParseAmountError; use bitcoin::error::UnprefixedHexError; -use bitcoin::{hex, network, BlockHash, Network, Work}; +use bitcoin::{hex, network, Amount, BlockHash, Network, Txid, Work, Wtxid}; use serde::{Deserialize, Serialize}; use crate::error::write_err; @@ -219,3 +220,327 @@ impl std::error::Error for GetBlockchainInfoError { impl From for GetBlockchainInfoError { fn from(e: NumericError) -> Self { Self::Numeric(e) } } + +/// Result of JSON-RPC method `getmempoolancestors` with verbose set to `false`. +/// +/// > getmempoolancestors txid (verbose) +/// > +/// > If txid is in the mempool, returns all in-mempool ancestors. +/// > +/// > Arguments: +/// > 1. "txid" (string, required) The transaction id (must be in mempool) +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetMempoolAncestors(pub Vec); + +impl GetMempoolAncestors { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + let v = self.0.iter().map(|t| t.parse::()).collect::, _>>()?; + Ok(model::GetMempoolAncestors(v)) + } +} + +/// Result of JSON-RPC method `getmempoolancestors` with verbose set to true. +/// +/// Map of txid to [`MempoolEntry`] i.e., an ancestor. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetMempoolAncestorsVerbose(pub BTreeMap); + +impl GetMempoolAncestorsVerbose { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use MapMempoolEntryError as E; + + let mut map = BTreeMap::new(); + for (k, v) in self.0.into_iter() { + let txid = k.parse::().map_err(E::Txid)?; + let relative = v.into_model().map_err(E::MempoolEntry)?; + map.insert(txid, relative); + } + Ok(model::GetMempoolAncestorsVerbose(map)) + } +} + +/// Result of JSON-RPC method `getmempooldescendants` with verbose set to `false`. +/// +/// > getmempooldescendants txid (verbose) +/// > +/// > If txid is in the mempool, returns all in-mempool descendants. +/// > +/// > Arguments: +/// > 1. "txid" (string, required) The transaction id (must be in mempool) +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetMempoolDescendants(pub Vec); + +impl GetMempoolDescendants { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + let v = self.0.iter().map(|t| t.parse::()).collect::, _>>()?; + Ok(model::GetMempoolDescendants(v)) + } +} + +/// Result of JSON-RPC method `getmempooldescendants` with verbose set to true. +/// +/// Map of txid to [`MempoolEntry`] i.e., a descendant. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetMempoolDescendantsVerbose(pub BTreeMap); + +impl GetMempoolDescendantsVerbose { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use MapMempoolEntryError as E; + + let mut map = BTreeMap::new(); + for (k, v) in self.0.into_iter() { + let txid = k.parse::().map_err(E::Txid)?; + let relative = v.into_model().map_err(E::MempoolEntry)?; + map.insert(txid, relative); + } + Ok(model::GetMempoolDescendantsVerbose(map)) + } +} + +/// Result of JSON-RPC method `getmempoolentry`. +/// +/// > getmempoolentry txid +/// > +/// > Returns mempool data for given transaction +/// > +/// > Arguments: +/// > 1. "txid" (string, required) The transaction id (must be in mempool) +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetMempoolEntry(pub MempoolEntry); + +impl GetMempoolEntry { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + Ok(model::GetMempoolEntry(self.0.into_model()?)) + } +} + +/// A relative (ancestor or descendant) transaction of a transaction in the mempool. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct MempoolEntry { + /// Virtual transaction size as defined in BIP 141. + /// + /// This is different from actual serialized size for witness transactions as witness data is discounted. + pub weight: i64, + /// Local time transaction entered pool in seconds since 1 Jan 1970 GMT. + pub time: i64, + /// Block height when transaction entered pool. + pub height: i64, + /// Number of in-mempool descendant transactions (including this one). + #[serde(rename = "descendantcount")] + pub descendant_count: i64, + /// Virtual transaction size of in-mempool descendants (including this one). + #[serde(rename = "descendantsize")] + pub descendant_size: i64, + /// Number of in-mempool ancestor transactions (including this one). + #[serde(rename = "ancestorcount")] + pub ancestor_count: i64, + /// Virtual transaction size of in-mempool ancestors (including this one). + #[serde(rename = "ancestorsize")] + pub ancestor_size: i64, + /// Hash of serialized transaction, including witness data. + pub wtxid: String, + /// (No docs in Core v17.) + pub fees: MempoolEntryFees, + /// Unconfirmed transactions used as inputs for this transaction (parent transaction id). + pub depends: Vec, + /// Unconfirmed transactions spending outputs from this transaction (child transaction id). + #[serde(rename = "spentby")] + pub spent_by: Vec, +} + +impl MempoolEntry { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use MempoolEntryError as E; + + let size = None; + let weight = Some(crate::to_u32(self.weight, "weight")?); + let time = crate::to_u32(self.time, "time")?; + let height = crate::to_u32(self.height, "height")?; + let descendant_count = crate::to_u32(self.descendant_count, "descendant_count")?; + let descendant_size = crate::to_u32(self.descendant_size, "descendant_size")?; + let ancestor_count = crate::to_u32(self.ancestor_count, "ancestor_count")?; + let ancestor_size = crate::to_u32(self.ancestor_size, "ancestor_size")?; + let wtxid = self.wtxid.parse::().map_err(E::Wtxid)?; + let fees = self.fees.into_model().map_err(E::Fees)?; + let depends = self + .depends + .iter() + .map(|txid| txid.parse::()) + .collect::, _>>() + .map_err(E::Depends)?; + let spent_by = self + .spent_by + .iter() + .map(|txid| txid.parse::()) + .collect::, _>>() + .map_err(E::SpentBy)?; + + Ok(model::MempoolEntry { + size, + weight, + time, + height, + descendant_count, + descendant_size, + ancestor_count, + ancestor_size, + wtxid, + fees, + depends, + spent_by, + }) + } +} + +/// (No docs in Core v17.) +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct MempoolEntryFees { + /// Transaction fee in BTC. + pub base: f64, + /// Transaction fee with fee deltas used for mining priority in BTC. + pub modified: f64, + /// Modified fees (see above) of in-mempool ancestors (including this one) in BTC + pub ancestor: f64, + /// Modified fees (see above) of in-mempool descendants (including this one) in BTC. + pub descendant: f64, +} + +impl MempoolEntryFees { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use MempoolEntryFeesError as E; + + Ok(model::MempoolEntryFees { + base: Amount::from_btc(self.base).map_err(E::Base)?, + modified: Amount::from_btc(self.modified).map_err(E::Modified)?, + ancestor: Amount::from_btc(self.ancestor).map_err(E::MempoolEntry)?, + descendant: Amount::from_btc(self.descendant).map_err(E::Descendant)?, + }) + } +} + +/// Error when converting a `MapMempoolEntry` into the model type. +#[derive(Debug)] +pub enum MapMempoolEntryError { + /// Conversion of a `txid` failed. + Txid(hex::HexToArrayError), + /// Conversion of a [`MempoolEntry`] failed. + MempoolEntry(MempoolEntryError), +} + +impl fmt::Display for MapMempoolEntryError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use MapMempoolEntryError as E; + + match *self { + E::Txid(ref e) => write_err!(f, "conversion of a `txid` failed"; e), + E::MempoolEntry(ref e) => write_err!(f, "conversion of an `MempoolEntry` failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for MapMempoolEntryError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use MapMempoolEntryError as E; + + match *self { + E::Txid(ref e) => Some(e), + E::MempoolEntry(ref e) => Some(e), + } + } +} + +/// Error when converting a `Mem` type into the model type. +#[derive(Debug)] +pub enum MempoolEntryError { + /// Conversion of numeric type to expected type failed. + Numeric(NumericError), + /// Conversion of the `wtxid` field failed. + Wtxid(hex::HexToArrayError), + /// Conversion of the `MempoolEntryFees` type failed. + Fees(MempoolEntryFeesError), + /// Conversion of the `depends` field failed. + Depends(hex::HexToArrayError), + /// Conversion of the `spent_by` field failed. + SpentBy(hex::HexToArrayError), +} + +impl From for MempoolEntryError { + fn from(e: NumericError) -> Self { Self::Numeric(e) } +} + +impl fmt::Display for MempoolEntryError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use MempoolEntryError as E; + + match *self { + E::Numeric(ref e) => write_err!(f, "numeric"; e), + E::Wtxid(ref e) => write_err!(f, "conversion of the `wtxid` field failed"; e), + E::Fees(ref e) => write_err!(f, "conversion of the `fees` field failed"; e), + E::Depends(ref e) => write_err!(f, "conversion of the `depends` field failed"; e), + E::SpentBy(ref e) => write_err!(f, "conversion of the `spent_by` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for MempoolEntryError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use MempoolEntryError as E; + + match *self { + E::Numeric(ref e) => Some(e), + E::Wtxid(ref e) => Some(e), + E::Fees(ref e) => Some(e), + E::Depends(ref e) => Some(e), + E::SpentBy(ref e) => Some(e), + } + } +} + +/// Error when converting a `MempoolEntryFeesError` type into the model type. +#[derive(Debug)] +pub enum MempoolEntryFeesError { + /// Conversion of the `base` field failed. + Base(ParseAmountError), + /// Conversion of the `modified` field failed. + Modified(ParseAmountError), + /// Conversion of the `ancestor` field failed. + MempoolEntry(ParseAmountError), + /// Conversion of the `descendant` field failed. + Descendant(ParseAmountError), +} + +impl fmt::Display for MempoolEntryFeesError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use MempoolEntryFeesError as E; + + match *self { + E::Base(ref e) => write_err!(f, "conversion of the `base` field failed"; e), + E::Modified(ref e) => write_err!(f, "conversion of the `modified` field failed"; e), + E::MempoolEntry(ref e) => write_err!(f, "conversion of the `ancestor` field failed"; e), + E::Descendant(ref e) => write_err!(f, "conversion of the `descendant` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for MempoolEntryFeesError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use MempoolEntryFeesError as E; + + match *self { + E::Base(ref e) => Some(e), + E::Modified(ref e) => Some(e), + E::MempoolEntry(ref e) => Some(e), + E::Descendant(ref e) => Some(e), + } + } +} diff --git a/types/src/v19/mod.rs b/types/src/v19/mod.rs index 713192a..7609aaa 100644 --- a/types/src/v19/mod.rs +++ b/types/src/v19/mod.rs @@ -229,7 +229,9 @@ mod wallet; pub use self::{ blockchain::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBlockchainInfo, - GetBlockchainInfoError, Softfork, SoftforkType, + GetBlockchainInfoError, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, wallet::{GetBalances, GetBalancesMine, GetBalancesWatchOnly}, }; @@ -240,17 +242,16 @@ pub use crate::v17::{ GetAddedNodeInfo, GetAddressInfo, GetAddressInfoEmbedded, GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, - GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, GetMempoolAncestors, - GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, - GetMempoolEntry, GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, - GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, - GetRawMempool, GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, - GetTransactionDetail, GetTxOut, GetTxOutSetInfo, GetUnconfirmedBalance, GetWalletInfo, - GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, - ListLockUnspent, ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, - ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, MempoolEntry, MempoolEntryFees, - PeerInfo, RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, - SignErrorData, SignMessage, SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, - UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, + GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, GetMempoolInfo, GetNetTotals, + GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, + GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, + GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, + GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, + ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, + ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, + ListTransactions, ListTransactionsItem, ListUnspent, ListUnspentItem, ListWallets, LoadWallet, + Locked, Logging, PeerInfo, RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, + SendToAddress, SignErrorData, SignMessage, SignRawTransactionWithWallet, SoftforkReject, + TransactionCategory, UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, + WalletProcessPsbt, }; diff --git a/types/src/v20/mod.rs b/types/src/v20/mod.rs index 0eb5098..2757420 100644 --- a/types/src/v20/mod.rs +++ b/types/src/v20/mod.rs @@ -232,23 +232,22 @@ pub use crate::{ GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, - GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, - ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, + GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, + GetTxOutSetInfo, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, + ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, + ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, MempoolEntry, MempoolEntryFees, - PeerInfo, RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, - SignErrorData, SignMessage, SignRawTransactionWithWallet, SoftforkReject, - TransactionCategory, UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletProcessPsbt, + ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, PeerInfo, RescanBlockchain, + ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfo, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, }; diff --git a/types/src/v21/mod.rs b/types/src/v21/mod.rs index 959bc46..035f3ea 100644 --- a/types/src/v21/mod.rs +++ b/types/src/v21/mod.rs @@ -243,23 +243,22 @@ pub use crate::{ GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, - GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, - ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, + GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, + GetTxOutSetInfo, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, + ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, + ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, MempoolEntry, MempoolEntryFees, - PeerInfo, RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, - SignErrorData, SignMessage, SignRawTransactionWithWallet, SoftforkReject, - TransactionCategory, UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletProcessPsbt, + ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, PeerInfo, RescanBlockchain, + ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfo, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, }; diff --git a/types/src/v22/blockchain.rs b/types/src/v22/blockchain.rs new file mode 100644 index 0000000..6d6c134 --- /dev/null +++ b/types/src/v22/blockchain.rs @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v0.22` - blockchain. +//! +//! Types for methods found under the `== Blockchain ==` section of the API docs. + +use core::fmt; + +use bitcoin::{address, amount, hex, Address, Amount, BlockHash, ScriptBuf, TxOut}; +use serde::{Deserialize, Serialize}; + +use crate::error::write_err; +use crate::{model, NumericError}; + +/// Result of JSON-RPC method `gettxout`. +/// +/// > gettxout "txid" n ( include_mempool ) +/// > +/// > Returns details about an unspent transaction output. +/// > +/// > Arguments: +/// > 1. txid (string, required) The transaction id +/// > 2. n (numeric, required) vout number +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTxOut { + /// The hash of the block at the tip of the chain. + #[serde(rename = "bestblock")] + pub best_block: String, + /// The number of confirmations. + pub confirmations: u32, // TODO: Change this to an i64. + /// The transaction value in BTC. + pub value: f64, + /// The script pubkey. + #[serde(rename = "scriptPubKey")] + pub script_pubkey: ScriptPubkey, + /// Coinbase or not. + pub coinbase: bool, +} + +impl GetTxOut { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTxOutError as E; + + let best_block = self.best_block.parse::().map_err(E::BestBlock)?; + let tx_out = TxOut { + value: Amount::from_btc(self.value).map_err(E::Value)?, + script_pubkey: ScriptBuf::from_hex(&self.script_pubkey.hex).map_err(E::ScriptPubkey)?, + }; + + let addresses = self + .script_pubkey + .address + .into_iter() + .map(|address| address.parse::>()) + .collect::, _>>() + .map_err(E::Addresses)?; + + Ok(model::GetTxOut { + best_block, + confirmations: self.confirmations, + tx_out, + addresses, + coinbase: self.coinbase, + }) + } +} + +/// A script pubkey. +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +pub struct ScriptPubkey { + /// Script assembly. + pub asm: String, + /// Script hex. + pub hex: String, + /// The type, eg pubkeyhash. + #[serde(rename = "type")] + pub type_: String, + /// bitcoin address (only if a well-defined address exists). + pub address: Option, +} + +/// Error when converting a `GetTxOut` type into the model type. +#[derive(Debug)] +pub enum GetTxOutError { + /// Conversion of numeric type to expected type failed. + Numeric(NumericError), + /// Conversion of the transaction `best_block` field failed. + BestBlock(hex::HexToArrayError), + /// Conversion of the transaction `value` field failed. + Value(amount::ParseAmountError), + /// Conversion of the transaction `script_pubkey` field failed. + ScriptPubkey(hex::HexToBytesError), + /// Conversion of the transaction `addresses` field failed. + Addresses(address::ParseError), +} + +impl fmt::Display for GetTxOutError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use GetTxOutError::*; + + match *self { + Numeric(ref e) => write_err!(f, "numeric"; e), + BestBlock(ref e) => write_err!(f, "conversion of the `beast_block` field failed"; e), + Value(ref e) => write_err!(f, "conversion of the `value` field failed"; e), + ScriptPubkey(ref e) => + write_err!(f, "conversion of the `script_pubkey` field failed"; e), + Addresses(ref e) => write_err!(f, "conversion of the `addresses` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for GetTxOutError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use GetTxOutError::*; + + match *self { + Numeric(ref e) => Some(e), + BestBlock(ref e) => Some(e), + Value(ref e) => Some(e), + ScriptPubkey(ref e) => Some(e), + Addresses(ref e) => Some(e), + } + } +} + +impl From for GetTxOutError { + fn from(e: NumericError) -> Self { Self::Numeric(e) } +} diff --git a/types/src/v22/mod.rs b/types/src/v22/mod.rs index 80b6f1d..ed45659 100644 --- a/types/src/v22/mod.rs +++ b/types/src/v22/mod.rs @@ -240,6 +240,10 @@ //! - Method returns a simple type (e.g. bool or integer). //! - Method is deprecated. +mod blockchain; + +#[doc(inline)] +pub use self::blockchain::{GetTxOut, ScriptPubkey}; #[doc(inline)] pub use crate::{ v17::{ @@ -249,24 +253,23 @@ pub use crate::{ GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, - GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, - ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, + GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, + GetTxOutSetInfo, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, + ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, + ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, MempoolEntry, MempoolEntryFees, - PeerInfo, RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, - SignErrorData, SignMessage, SignRawTransactionWithWallet, SoftforkReject, - TransactionCategory, UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletProcessPsbt, + ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, PeerInfo, RescanBlockchain, + SendMany, SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfo, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, v21::UnloadWallet, }; diff --git a/types/src/v23/mod.rs b/types/src/v23/mod.rs index 4926236..e07b1ef 100644 --- a/types/src/v23/mod.rs +++ b/types/src/v23/mod.rs @@ -242,24 +242,24 @@ pub use crate::{ GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, - GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, - ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, + GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, + GetTxOutSetInfo, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, + ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, + ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, MempoolEntry, MempoolEntryFees, - PeerInfo, RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, - SignErrorData, SignMessage, SignRawTransactionWithWallet, SoftforkReject, - TransactionCategory, UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletProcessPsbt, + ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, PeerInfo, RescanBlockchain, + SendMany, SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfo, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, v21::UnloadWallet, + v22::{GetTxOut, ScriptPubkey}, }; diff --git a/types/src/v24/mod.rs b/types/src/v24/mod.rs index 173a2c2..1721fe8 100644 --- a/types/src/v24/mod.rs +++ b/types/src/v24/mod.rs @@ -246,24 +246,24 @@ pub use crate::{ GetAddressInfoLabel, GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, - GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, - ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, + GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, + GetTxOutSetInfo, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, + ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, + ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, MempoolEntry, MempoolEntryFees, - PeerInfo, RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, - SignErrorData, SignMessage, SignRawTransactionWithWallet, SoftforkReject, - TransactionCategory, UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, - WalletProcessPsbt, + ListUnspentItem, ListWallets, LoadWallet, Locked, Logging, PeerInfo, RescanBlockchain, + SendMany, SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfo, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, v21::UnloadWallet, + v22::{GetTxOut, ScriptPubkey}, }; diff --git a/types/src/v25/mod.rs b/types/src/v25/mod.rs index 57b2811..f004311 100644 --- a/types/src/v25/mod.rs +++ b/types/src/v25/mod.rs @@ -251,23 +251,24 @@ pub use crate::{ GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, - GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, - ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, - ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, + GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, + GetTxOutSetInfo, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, + ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, + ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, Locked, Logging, MempoolEntry, MempoolEntryFees, PeerInfo, - RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, SignErrorData, - SignMessage, SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, - UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, + ListUnspentItem, ListWallets, Locked, Logging, PeerInfo, RescanBlockchain, SendMany, + SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfo, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, v21::UnloadWallet, + v22::{GetTxOut, ScriptPubkey}, }; diff --git a/types/src/v26/blockchain.rs b/types/src/v26/blockchain.rs new file mode 100644 index 0000000..66432bf --- /dev/null +++ b/types/src/v26/blockchain.rs @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! The JSON-RPC API for Bitcoin Core `v0.26` - blockchain. +//! +//! Types for methods found under the `== Blockchain ==` section of the API docs. + +use core::fmt; + +use bitcoin::{amount, hex, Amount, BlockHash}; +use serde::{Deserialize, Serialize}; + +use crate::error::write_err; +use crate::{model, NumericError}; + +/// Result of JSON-RPC method `gettxoutsetinfo`. +/// +/// > gettxoutsetinfo +/// > +/// > Returns statistics about the unspent transaction output set. +/// > Note this call may take some time. +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +pub struct GetTxOutSetInfo { + /// The current block height (index). + pub height: i64, + /// The hash of the block at the tip of the chain. + #[serde(rename = "bestblock")] + pub best_block: String, + /// The number of transactions with unspent outputs. + pub transactions: i64, + /// The number of unspent transaction outputs. + #[serde(rename = "txouts")] + pub tx_outs: i64, + /// A meaningless metric for UTXO set size. + #[serde(rename = "bogosize")] + pub bogo_size: i64, + /// The estimated size of the chainstate on disk. + pub disk_size: i64, + /// The total amount. + pub total_amount: f64, +} + +impl GetTxOutSetInfo { + /// Converts version specific type to a version nonspecific, more strongly typed type. + pub fn into_model(self) -> Result { + use GetTxOutSetInfoError as E; + + let height = crate::to_u32(self.height, "height")?; + let best_block = self.best_block.parse::().map_err(E::BestBlock)?; + let transactions = crate::to_u32(self.transactions, "transactions")?; + let tx_outs = crate::to_u32(self.tx_outs, "tx_outs")?; + let bogo_size = crate::to_u32(self.bogo_size, "bogo_size")?; + let hash_serialized_2 = None; // Removed in Core v26 + let disk_size = crate::to_u32(self.disk_size, "disk_size")?; + let total_amount = Amount::from_btc(self.total_amount).map_err(E::TotalAmount)?; + + Ok(model::GetTxOutSetInfo { + height, + best_block, + transactions, + tx_outs, + bogo_size, + hash_serialized_2, + disk_size, + total_amount, + }) + } +} + +/// Error when converting a `GetTxOut` type into the model type. +#[derive(Debug)] +pub enum GetTxOutSetInfoError { + /// Conversion of numeric type to expected type failed. + Numeric(NumericError), + /// Conversion of the transaction `best_block` field failed. + BestBlock(hex::HexToArrayError), + /// Conversion of the transaction `total_amount` field failed. + TotalAmount(amount::ParseAmountError), +} + +impl fmt::Display for GetTxOutSetInfoError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use GetTxOutSetInfoError::*; + + match *self { + Numeric(ref e) => write_err!(f, "numeric"; e), + BestBlock(ref e) => write_err!(f, "conversion of the `beast_block` field failed"; e), + TotalAmount(ref e) => write_err!(f, "conversion of the `total_amount` field failed"; e), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for GetTxOutSetInfoError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + use GetTxOutSetInfoError::*; + + match *self { + Numeric(ref e) => Some(e), + BestBlock(ref e) => Some(e), + TotalAmount(ref e) => Some(e), + } + } +} + +impl From for GetTxOutSetInfoError { + fn from(e: NumericError) -> Self { Self::Numeric(e) } +} diff --git a/types/src/v26/mod.rs b/types/src/v26/mod.rs index 7f3ae52..df8045b 100644 --- a/types/src/v26/mod.rs +++ b/types/src/v26/mod.rs @@ -246,6 +246,10 @@ //! - Method returns a simple type (e.g. bool or integer). //! - Method is deprecated. +mod blockchain; + +#[doc(inline)] +pub use self::blockchain::GetTxOutSetInfo; #[doc(inline)] pub use crate::{ v17::{ @@ -255,24 +259,25 @@ pub use crate::{ GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, + GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, Locked, Logging, MempoolEntry, MempoolEntryFees, PeerInfo, - RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, SignErrorData, - SignMessage, SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, - UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, + ListUnspentItem, ListWallets, Locked, Logging, PeerInfo, RescanBlockchain, SendMany, + SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfo, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, v21::UnloadWallet, + v22::{GetTxOut, ScriptPubkey}, v25::{CreateWallet, LoadWallet}, }; diff --git a/types/src/v27/mod.rs b/types/src/v27/mod.rs index 7f3ae52..8cf6c8b 100644 --- a/types/src/v27/mod.rs +++ b/types/src/v27/mod.rs @@ -255,24 +255,26 @@ pub use crate::{ GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, - GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, + GetMempoolInfo, GetNetTotals, GetNetworkInfo, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, Locked, Logging, MempoolEntry, MempoolEntryFees, PeerInfo, - RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, SignErrorData, - SignMessage, SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, - UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, + ListUnspentItem, ListWallets, Locked, Logging, PeerInfo, RescanBlockchain, SendMany, + SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfo, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfo, GetMempoolAncestors, GetMempoolAncestorsVerbose, + GetMempoolDescendants, GetMempoolDescendantsVerbose, GetMempoolEntry, MempoolEntry, + MempoolEntryFees, Softfork, SoftforkType, }, v21::UnloadWallet, + v22::{GetTxOut, ScriptPubkey}, v25::{CreateWallet, LoadWallet}, + v26::GetTxOutSetInfo, }; diff --git a/types/src/v28/mod.rs b/types/src/v28/mod.rs index 51b98ad..a41538a 100644 --- a/types/src/v28/mod.rs +++ b/types/src/v28/mod.rs @@ -267,24 +267,26 @@ pub use crate::{ GetAddressesByLabel, GetBalance, GetBestBlockHash, GetBlockCount, GetBlockHash, GetBlockHeader, GetBlockHeaderVerbose, GetBlockStats, GetBlockVerbosityOne, GetBlockVerbosityZero, GetChainTips, GetChainTxStats, GetDifficulty, GetMemoryInfoStats, - GetMempoolAncestors, GetMempoolAncestorsVerbose, GetMempoolDescendants, - GetMempoolDescendantsVerbose, GetMempoolEntry, GetMempoolInfo, GetNetTotals, - GetNetworkInfoAddress, GetNetworkInfoError, GetNetworkInfoNetwork, GetNewAddress, - GetPeerInfo, GetRawChangeAddress, GetRawMempool, GetRawMempoolVerbose, - GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetTxOut, GetTxOutSetInfo, + GetMempoolInfo, GetNetTotals, GetNetworkInfoAddress, GetNetworkInfoError, + GetNetworkInfoNetwork, GetNewAddress, GetPeerInfo, GetRawChangeAddress, GetRawMempool, + GetRawMempoolVerbose, GetReceivedByAddress, GetTransaction, GetTransactionDetail, GetUnconfirmedBalance, GetWalletInfo, GetZmqNotifications, ListAddressGroupings, ListAddressGroupingsItem, ListBanned, ListLabels, ListLockUnspent, ListLockUnspentItem, ListReceivedByAddress, ListReceivedByAddressItem, ListSinceBlock, ListSinceBlockTransaction, ListTransactions, ListTransactionsItem, ListUnspent, - ListUnspentItem, ListWallets, Locked, Logging, MempoolEntry, MempoolEntryFees, PeerInfo, - RescanBlockchain, ScriptPubkey, SendMany, SendRawTransaction, SendToAddress, SignErrorData, - SignMessage, SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, - UploadTarget, Uptime, VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, + ListUnspentItem, ListWallets, Locked, Logging, PeerInfo, RescanBlockchain, SendMany, + SendRawTransaction, SendToAddress, SignErrorData, SignMessage, + SignRawTransactionWithWallet, SoftforkReject, TransactionCategory, UploadTarget, Uptime, + VerifyTxOutProof, WalletCreateFundedPsbt, WalletProcessPsbt, }, v19::{ Bip9SoftforkInfo, Bip9SoftforkStatistics, Bip9SoftforkStatus, GetBalances, GetBalancesMine, - GetBalancesWatchOnly, GetBlockchainInfoError, Softfork, SoftforkType, + GetBalancesWatchOnly, GetBlockchainInfoError, GetMempoolAncestors, + GetMempoolAncestorsVerbose, GetMempoolDescendants, GetMempoolDescendantsVerbose, + GetMempoolEntry, MempoolEntry, MempoolEntryFees, Softfork, SoftforkType, }, v21::UnloadWallet, + v22::{GetTxOut, ScriptPubkey}, v25::{CreateWallet, LoadWallet}, + v26::GetTxOutSetInfo, };