@@ -2,32 +2,43 @@ use std::{
22 fs:: File ,
33 io:: { BufRead , BufReader } ,
44 path:: PathBuf ,
5- str:: FromStr ,
65} ;
76
87use crate :: error:: Error ;
98use crate :: jsonrpc:: minreq_http:: Builder ;
109use corepc_types:: {
1110 bitcoin:: {
12- Block , BlockHash , Transaction , Txid , block:: Header , consensus:: deserialize, hex:: FromHex ,
11+ block:: Header ,
12+ consensus:: { deserialize, encode:: deserialize_hex} ,
13+ hex:: FromHex ,
14+ Block , BlockHash , Transaction , Txid ,
1315 } ,
14- model:: { GetBlockCount , GetBlockFilter , GetBlockVerboseOne , GetRawMempool } ,
16+ model:: { GetBlockCount , GetBlockFilter , GetRawMempool } ,
17+ v29:: GetBlockVerboseOne ,
1518} ;
1619use jsonrpc:: {
17- Transport , serde,
20+ serde,
1821 serde_json:: { self , json} ,
22+ Transport ,
1923} ;
2024
21- /// client authentication methods
25+ /// Client authentication methods for the Bitcoin Core JSON-RPC server
2226#[ derive( Clone , Debug , Hash , Eq , PartialEq , Ord , PartialOrd ) ]
2327pub enum Auth {
28+ /// No authentication (not recommended)
2429 None ,
30+ /// Username and password authentication (RPC user/pass)
2531 UserPass ( String , String ) ,
32+ /// Authentication via a cookie file
2633 CookieFile ( PathBuf ) ,
2734}
2835
2936impl Auth {
30- /// Convert into the arguments that jsonrpc::Client needs.
37+ /// Converts `Auth` enum into the optional username and password strings
38+ /// required by JSON-RPC client transport.
39+ ///
40+ /// # Errors
41+ /// Returns an error if the `CookieFile` cannot be read or invalid
3142 pub fn get_user_pass ( self ) -> Result < ( Option < String > , Option < String > ) , Error > {
3243 match self {
3344 Auth :: None => Ok ( ( None , None ) ) ,
@@ -44,18 +55,28 @@ impl Auth {
4455 }
4556}
4657
47- // RPC Client.
58+ /// Bitcoin Core JSON-RPC Client.
59+ ///
60+ /// A wrapper for JSON-RPC client for interacting with the `bitcoind` RPC interface.
4861#[ derive( Debug ) ]
4962pub struct Client {
5063 /// The inner JSON-RPC client.
5164 inner : jsonrpc:: Client ,
5265}
5366
5467impl Client {
55- /// Creates a client to a bitcoind JSON-RPC server.
68+ /// Creates a client connection to a bitcoind JSON-RPC server with authentication
5669 ///
5770 /// Requires authentication via username/password or cookie file.
5871 /// For connections without authentication, use `with_transport` instead.
72+ /// # Arguments
73+ /// * `url` - URL of the RPC server
74+ /// * `auth` - authentication method (`UserPass` or `CookieFile`).
75+ ///
76+ /// # Errors
77+ /// * Returns `Error::MissingAuthentication` if `Auth::None` is provided.
78+ /// * Returns `Error::InvalidResponse` if the URL is invalid.
79+ /// * Returns errors related to reading the cookie file.
5980 pub fn with_auth ( url : & str , auth : Auth ) -> Result < Self , Error > {
6081 if matches ! ( auth, Auth :: None ) {
6182 return Err ( Error :: MissingAuthentication ) ;
@@ -95,7 +116,9 @@ impl Client {
95116 }
96117 }
97118
98- /// Calls the RPC `method` with a given `args` list.
119+ /// Calls the underlying RPC `method` with given `args` list
120+ ///
121+ /// This is the generic function used by all specific RPC methods.
99122 pub fn call < T > ( & self , method : & str , args : & [ serde_json:: Value ] ) -> Result < T , Error >
100123 where
101124 T : for < ' de > serde:: Deserialize < ' de > ,
@@ -108,66 +131,82 @@ impl Client {
108131 }
109132}
110133
111- // `bitcoind` RPC methods
134+ // `bitcoind` RPC methods implementation for `Client`
112135impl Client {
113- /// Get block
136+ /// Retrieves the raw block data for a given block hash (verbosity 0)
137+ ///
138+ /// # Arguments
139+ /// * `block_hash`: The hash of the block to retrieve.
140+ ///
141+ /// # Returns
142+ /// The deserialized `Block` struct.
114143 pub fn get_block ( & self , block_hash : & BlockHash ) -> Result < Block , Error > {
115144 let hex_string: String = self . call ( "getblock" , & [ json ! ( block_hash) , json ! ( 0 ) ] ) ?;
116-
117- let bytes: Vec < u8 > = Vec :: < u8 > :: from_hex ( & hex_string) . map_err ( Error :: HexToBytes ) ?;
118-
119- let block: Block = deserialize ( & bytes)
120- . map_err ( |e| Error :: InvalidResponse ( format ! ( "failed to deserialize block: {e}" ) ) ) ?;
121-
145+ let block = deserialize_hex ( & hex_string) . map_err ( Error :: DecodeHex ) ?;
122146 Ok ( block)
123147 }
124148
125- /// Get block verboseone
149+ /// Retrieves the verbose JSON representation of a block (verbosity 1)
150+ /// # Arguments
151+ /// * `block_hash`: The hash of the block to retrieve.
152+ ///
153+ /// # Returns
154+ /// The verbose block data as a `GetBlockVerboseOne` struct.
126155 pub fn get_block_verbose ( & self , block_hash : & BlockHash ) -> Result < GetBlockVerboseOne , Error > {
127- let res: GetBlockVerboseOne = self . call ( "getblock" , & [ json ! ( block_hash) , json ! ( 1 ) ] ) ?;
128- Ok ( res)
156+ let block_verbose_one: GetBlockVerboseOne =
157+ self . call ( "getblock" , & [ json ! ( block_hash) , json ! ( 1 ) ] ) ?;
158+ Ok ( block_verbose_one)
129159 }
130160
131- /// Get best block hash
161+ /// Retrieves the hash of the tip of the best block chain.
162+ ///
163+ /// # Returns
164+ /// The `BlockHash` of the chain tip.
132165 pub fn get_best_block_hash ( & self ) -> Result < BlockHash , Error > {
133166 let res: String = self . call ( "getbestblockhash" , & [ ] ) ?;
134167 Ok ( res. parse ( ) ?)
135168 }
136169
137- /// Get block count
170+ /// Retrieves the number of blocks in the longest chain
171+ ///
172+ /// # Returns
173+ /// The block count as a `u64`
138174 pub fn get_block_count ( & self ) -> Result < u64 , Error > {
139175 let res: GetBlockCount = self . call ( "getblockcount" , & [ ] ) ?;
140176 Ok ( res. 0 )
141177 }
142178
143- /// Get block hash
179+ /// Retrieves the block hash at a given height
180+ ///
181+ /// # Arguments
182+ /// * `height`: The block height
183+ ///
184+ /// # Returns
185+ /// The `BlockHash` for the given height
144186 pub fn get_block_hash ( & self , height : u32 ) -> Result < BlockHash , Error > {
145- let raw: serde_json:: Value = self . call ( "getblockhash" , & [ json ! ( height) ] ) ?;
146-
147- let hash_str = match raw {
148- serde_json:: Value :: String ( s) => s,
149- serde_json:: Value :: Object ( obj) => obj
150- . get ( "hash" )
151- . and_then ( |v| v. as_str ( ) )
152- . ok_or_else ( || Error :: InvalidResponse ( "getblockhash: missing 'hash' field" . into ( ) ) ) ?
153- . to_string ( ) ,
154- _ => {
155- return Err ( Error :: InvalidResponse (
156- "getblockhash: unexpected response type" . into ( ) ,
157- ) ) ;
158- }
159- } ;
160-
161- BlockHash :: from_str ( & hash_str) . map_err ( Error :: HexToArray )
187+ let hex: String = self . call ( "getblockhash" , & [ json ! ( height) ] ) ?;
188+ Ok ( hex. parse ( ) ?)
162189 }
163190
164- /// Get block filter
165- pub fn get_block_filter ( & self , block_hash : BlockHash ) -> Result < GetBlockFilter , Error > {
191+ /// Retrieves the compact block filter for a given block
192+ ///
193+ /// # Arguments
194+ /// * `block_hash`: The hash of the block whose filter is requested
195+ ///
196+ /// # Returns
197+ /// The `GetBlockFilter` structure containing the filter data
198+ pub fn get_block_filter ( & self , block_hash : & BlockHash ) -> Result < GetBlockFilter , Error > {
166199 let res: GetBlockFilter = self . call ( "getblockfilter" , & [ json ! ( block_hash) ] ) ?;
167200 Ok ( res)
168201 }
169202
170- /// Get block header
203+ /// Retrieves the raw block header for a given block hash.
204+ ///
205+ /// # Arguments
206+ /// * `block_hash`: The hash of the block whose header is requested.
207+ ///
208+ /// # Returns
209+ /// The deserialized `Header` struct
171210 pub fn get_block_header ( & self , block_hash : & BlockHash ) -> Result < Header , Error > {
172211 let hex_string: String = self . call ( "getblockheader" , & [ json ! ( block_hash) , json ! ( false ) ] ) ?;
173212
@@ -180,13 +219,22 @@ impl Client {
180219 Ok ( header)
181220 }
182221
183- /// Get raw mempool
222+ /// Retrieves the transaction IDs of all transactions currently in the mempool
223+ ///
224+ /// # Returns
225+ /// A vector of `Txid`s in the raw mempool
184226 pub fn get_raw_mempool ( & self ) -> Result < Vec < Txid > , Error > {
185227 let res: GetRawMempool = self . call ( "getrawmempool" , & [ ] ) ?;
186228 Ok ( res. 0 )
187229 }
188230
189- /// Get raw transaction
231+ /// Retrieves the raw transaction data for a given transaction ID.
232+ ///
233+ /// # Arguments
234+ /// * `txid`: The transaction ID to retrieve.
235+ ///
236+ /// # Returns
237+ /// The deserialized `Transaction` struct
190238 pub fn get_raw_transaction ( & self , txid : & Txid ) -> Result < Transaction , Error > {
191239 let hex_string: String = self . call ( "getrawtransaction" , & [ json ! ( txid) ] ) ?;
192240
0 commit comments