@@ -2,12 +2,21 @@ use std::{
22 fs:: File ,
33 io:: { BufRead , BufReader } ,
44 path:: PathBuf ,
5+ str:: FromStr ,
56} ;
67
78use crate :: error:: Error ;
89use crate :: jsonrpc:: minreq_http:: Builder ;
9- use corepc_types:: bitcoin:: BlockHash ;
10- use jsonrpc:: { serde, serde_json, Transport } ;
10+ use corepc_types:: {
11+ bitcoin:: {
12+ Block , BlockHash , Transaction , Txid , block:: Header , consensus:: deserialize, hex:: FromHex ,
13+ } ,
14+ model:: { GetBlockCount , GetBlockFilter , GetBlockVerboseOne , GetRawMempool } ,
15+ } ;
16+ use jsonrpc:: {
17+ Transport , serde,
18+ serde_json:: { self , json} ,
19+ } ;
1120
1221/// client authentication methods
1322#[ derive( Clone , Debug , Hash , Eq , PartialEq , Ord , PartialOrd ) ]
@@ -101,11 +110,94 @@ impl Client {
101110
102111// `bitcoind` RPC methods
103112impl Client {
104- /// Get best block hash.
113+ /// Get block
114+ pub fn get_block ( & self , block_hash : & BlockHash ) -> Result < Block , Error > {
115+ 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+
122+ Ok ( block)
123+ }
124+
125+ /// Get block verboseone
126+ 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)
129+ }
130+
131+ /// Get best block hash
105132 pub fn get_best_block_hash ( & self ) -> Result < BlockHash , Error > {
106133 let res: String = self . call ( "getbestblockhash" , & [ ] ) ?;
107134 Ok ( res. parse ( ) ?)
108135 }
136+
137+ /// Get block count
138+ pub fn get_block_count ( & self ) -> Result < u64 , Error > {
139+ let res: GetBlockCount = self . call ( "getblockcount" , & [ ] ) ?;
140+ Ok ( res. 0 )
141+ }
142+
143+ /// Get block hash
144+ 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 )
162+ }
163+
164+ /// Get block filter
165+ pub fn get_block_filter ( & self , block_hash : BlockHash ) -> Result < GetBlockFilter , Error > {
166+ let res: GetBlockFilter = self . call ( "getblockfilter" , & [ json ! ( block_hash) ] ) ?;
167+ Ok ( res)
168+ }
169+
170+ /// Get block header
171+ pub fn get_block_header ( & self , block_hash : & BlockHash ) -> Result < Header , Error > {
172+ let hex_string: String = self . call ( "getblockheader" , & [ json ! ( block_hash) , json ! ( false ) ] ) ?;
173+
174+ let bytes = Vec :: < u8 > :: from_hex ( & hex_string) . map_err ( Error :: HexToBytes ) ?;
175+
176+ let header = deserialize ( & bytes) . map_err ( |e| {
177+ Error :: InvalidResponse ( format ! ( "failed to deserialize block header: {e}" ) )
178+ } ) ?;
179+
180+ Ok ( header)
181+ }
182+
183+ /// Get raw mempool
184+ pub fn get_raw_mempool ( & self ) -> Result < Vec < Txid > , Error > {
185+ let res: GetRawMempool = self . call ( "getrawmempool" , & [ ] ) ?;
186+ Ok ( res. 0 )
187+ }
188+
189+ /// Get raw transaction
190+ pub fn get_raw_transaction ( & self , txid : & Txid ) -> Result < Transaction , Error > {
191+ let hex_string: String = self . call ( "getrawtransaction" , & [ json ! ( txid) ] ) ?;
192+
193+ let bytes = Vec :: < u8 > :: from_hex ( & hex_string) . map_err ( Error :: HexToBytes ) ?;
194+
195+ let transaction = deserialize ( & bytes) . map_err ( |e| {
196+ Error :: InvalidResponse ( format ! ( "transaction deserialization failed: {e}" ) )
197+ } ) ?;
198+
199+ Ok ( transaction)
200+ }
109201}
110202
111203#[ cfg( test) ]
0 commit comments