bitcoincore_rpc_async/
client.rs

1// To the extent possible under law, the author(s) have dedicated all
2// copyright and related and neighboring rights to this software to
3// the public domain worldwide. This software is distributed without
4// any warranty.
5//
6// You should have received a copy of the CC0 Public Domain Dedication
7// along with this software.
8// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
9//
10
11use serde_json::value::RawValue;
12use std::collections::HashMap;
13use std::fs::File;
14use std::iter::FromIterator;
15use std::path::PathBuf;
16use std::{fmt, result};
17
18use super::bitcoin;
19use bitcoincore_rpc_json as json;
20use jsonrpc_async as jsonrpc;
21use serde::*;
22use serde_json;
23
24use async_trait::async_trait;
25use bitcoin::hashes::hex::{FromHex, ToHex};
26use bitcoin::secp256k1::Signature;
27use bitcoin::{
28    Address, Amount, Block, BlockHeader, OutPoint, PrivateKey, PublicKey, Script, Transaction,
29};
30use log::Level::{Debug, Trace, Warn};
31use log::{debug, log_enabled, trace};
32
33use crate::error::*;
34use crate::queryable;
35
36/// Crate-specific Result type, shorthand for `std::result::Result` with our
37/// crate-specific Error type;
38pub type Result<T> = result::Result<T, Error>;
39
40#[derive(Clone, Debug, Serialize, Deserialize)]
41struct JsonOutPoint {
42    pub txid: bitcoin::Txid,
43    pub vout: u32,
44}
45
46impl From<OutPoint> for JsonOutPoint {
47    fn from(o: OutPoint) -> JsonOutPoint {
48        JsonOutPoint {
49            txid: o.txid,
50            vout: o.vout,
51        }
52    }
53}
54
55impl Into<OutPoint> for JsonOutPoint {
56    fn into(self) -> OutPoint {
57        OutPoint {
58            txid: self.txid,
59            vout: self.vout,
60        }
61    }
62}
63
64/// Shorthand for converting a variable into a serde_json::Value.
65fn into_json<T>(val: T) -> Result<serde_json::Value>
66where
67    T: serde::ser::Serialize,
68{
69    Ok(serde_json::to_value(val)?)
70}
71
72/// Shorthand for converting an Option into an Option<serde_json::Value>.
73fn opt_into_json<T>(opt: Option<T>) -> Result<serde_json::Value>
74where
75    T: serde::ser::Serialize,
76{
77    match opt {
78        Some(val) => Ok(into_json(val)?),
79        None => Ok(serde_json::Value::Null),
80    }
81}
82
83/// Shorthand for `serde_json::Value::Null`.
84fn null() -> serde_json::Value {
85    serde_json::Value::Null
86}
87
88/// Shorthand for an empty serde_json::Value array.
89fn empty_arr() -> serde_json::Value {
90    serde_json::Value::Array(vec![])
91}
92
93/// Shorthand for an empty serde_json object.
94fn empty_obj() -> serde_json::Value {
95    serde_json::Value::Object(Default::default())
96}
97
98/// Handle default values in the argument list
99///
100/// Substitute `Value::Null`s with corresponding values from `defaults` table,
101/// except when they are trailing, in which case just skip them altogether
102/// in returned list.
103///
104/// Note, that `defaults` corresponds to the last elements of `args`.
105///
106/// ```norust
107/// arg1 arg2 arg3 arg4
108///           def1 def2
109/// ```
110///
111/// Elements of `args` without corresponding `defaults` value, won't
112/// be substituted, because they are required.
113fn handle_defaults<'a, 'b>(
114    args: &'a mut [serde_json::Value],
115    defaults: &'b [serde_json::Value],
116) -> &'a [serde_json::Value] {
117    assert!(args.len() >= defaults.len());
118
119    // Pass over the optional arguments in backwards order, filling in defaults after the first
120    // non-null optional argument has been observed.
121    let mut first_non_null_optional_idx = None;
122    for i in 0..defaults.len() {
123        let args_i = args.len() - 1 - i;
124        let defaults_i = defaults.len() - 1 - i;
125        if args[args_i] == serde_json::Value::Null {
126            if first_non_null_optional_idx.is_some() {
127                if defaults[defaults_i] == serde_json::Value::Null {
128                    panic!("Missing `default` for argument idx {}", args_i);
129                }
130                args[args_i] = defaults[defaults_i].clone();
131            }
132        } else if first_non_null_optional_idx.is_none() {
133            first_non_null_optional_idx = Some(args_i);
134        }
135    }
136
137    let required_num = args.len() - defaults.len();
138
139    if let Some(i) = first_non_null_optional_idx {
140        &args[..i + 1]
141    } else {
142        &args[..required_num]
143    }
144}
145
146/// Convert a possible-null result into an Option.
147fn opt_result<T: for<'a> serde::de::Deserialize<'a>>(
148    result: serde_json::Value,
149) -> Result<Option<T>> {
150    if result == serde_json::Value::Null {
151        Ok(None)
152    } else {
153        Ok(serde_json::from_value(result)?)
154    }
155}
156
157/// Used to pass raw txs into the API.
158pub trait RawTx: Sized + Clone {
159    fn raw_hex(self) -> String;
160}
161
162impl<'a> RawTx for &'a Transaction {
163    fn raw_hex(self) -> String {
164        bitcoin::consensus::encode::serialize(self).to_hex()
165    }
166}
167
168impl<'a> RawTx for &'a [u8] {
169    fn raw_hex(self) -> String {
170        self.to_hex()
171    }
172}
173
174impl<'a> RawTx for &'a Vec<u8> {
175    fn raw_hex(self) -> String {
176        self.to_hex()
177    }
178}
179
180impl<'a> RawTx for &'a str {
181    fn raw_hex(self) -> String {
182        self.to_owned()
183    }
184}
185
186impl RawTx for String {
187    fn raw_hex(self) -> String {
188        self
189    }
190}
191
192/// The different authentication methods for the client.
193#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
194pub enum Auth {
195    None,
196    UserPass(String, String),
197    CookieFile(PathBuf),
198}
199
200impl Auth {
201    /// Convert into the arguments that jsonrpc::Client needs.
202    fn get_user_pass(self) -> Result<Option<(String, String)>> {
203        use std::io::Read;
204        match self {
205            Auth::None => Ok(None),
206            Auth::UserPass(u, p) => Ok(Some((u, p))),
207            Auth::CookieFile(path) => {
208                let mut file = File::open(path)?;
209                let mut contents = String::new();
210                file.read_to_string(&mut contents)?;
211                let mut split = contents.splitn(2, ":");
212                let u = split.next().ok_or(Error::InvalidCookieFile)?.into();
213                let p = split.next().ok_or(Error::InvalidCookieFile)?.into();
214                Ok(Some((u, p)))
215            }
216        }
217    }
218}
219
220#[async_trait]
221pub trait RpcApi: Sized {
222    /// Call a `cmd` rpc with given `args` list
223    async fn call<T: for<'a> serde::de::Deserialize<'a>>(
224        &self,
225        cmd: &str,
226        args: &[serde_json::Value],
227    ) -> Result<T>;
228
229    /// Query an object implementing `Querable` type
230    async fn get_by_id<T: queryable::Queryable<Self>>(
231        &self,
232        id: &<T as queryable::Queryable<Self>>::Id,
233    ) -> Result<T>
234    where
235        T: Sync + Send,
236        <T as queryable::Queryable<Self>>::Id: Sync + Send,
237    {
238        T::query(&self, &id).await
239    }
240
241    async fn get_network_info(&self) -> Result<json::GetNetworkInfoResult> {
242        self.call("getnetworkinfo", &[]).await
243    }
244
245    async fn version(&self) -> Result<usize> {
246        #[derive(Deserialize)]
247        struct Response {
248            pub version: usize,
249        }
250        let res: Response = self.call("getnetworkinfo", &[]).await?;
251        Ok(res.version)
252    }
253
254    async fn add_multisig_address(
255        &self,
256        nrequired: usize,
257        keys: &[json::PubKeyOrAddress<'_>],
258        label: Option<&str>,
259        address_type: Option<json::AddressType>,
260    ) -> Result<json::AddMultiSigAddressResult> {
261        let mut args = [
262            into_json(nrequired)?,
263            into_json(keys)?,
264            opt_into_json(label)?,
265            opt_into_json(address_type)?,
266        ];
267        self.call("addmultisigaddress", handle_defaults(&mut args, &[into_json("")?, null()])).await
268    }
269
270    async fn load_wallet(&self, wallet: &str) -> Result<json::LoadWalletResult> {
271        self.call("loadwallet", &[wallet.into()]).await
272    }
273
274    async fn unload_wallet(&self, wallet: Option<&str>) -> Result<()> {
275        let mut args = [opt_into_json(wallet)?];
276        self.call("unloadwallet", handle_defaults(&mut args, &[null()])).await
277    }
278
279    async fn create_wallet(
280        &self,
281        wallet: &str,
282        disable_private_keys: Option<bool>,
283        blank: Option<bool>,
284        passphrase: Option<&str>,
285        avoid_reuse: Option<bool>,
286    ) -> Result<json::LoadWalletResult> {
287        let mut args = [
288            wallet.into(),
289            opt_into_json(disable_private_keys)?,
290            opt_into_json(blank)?,
291            opt_into_json(passphrase)?,
292            opt_into_json(avoid_reuse)?,
293        ];
294        self.call(
295            "createwallet",
296            handle_defaults(&mut args, &[false.into(), false.into(), into_json("")?, false.into()]),
297        )
298        .await
299    }
300
301    async fn list_wallets(&self) -> Result<Vec<String>> {
302        self.call("listwallets", &[]).await
303    }
304
305    async fn get_wallet_info(&self) -> Result<json::GetWalletInfoResult> {
306        self.call("getwalletinfo", &[]).await
307    }
308
309    async fn backup_wallet(&self, destination: Option<&str>) -> Result<()> {
310        let mut args = [opt_into_json(destination)?];
311        self.call("backupwallet", handle_defaults(&mut args, &[null()])).await
312    }
313
314    async fn dump_private_key(&self, address: &Address) -> Result<PrivateKey> {
315        self.call("dumpprivkey", &[address.to_string().into()]).await
316    }
317
318    async fn encrypt_wallet(&self, passphrase: &str) -> Result<()> {
319        self.call("encryptwallet", &[into_json(passphrase)?]).await
320    }
321
322    async fn get_difficulty(&self) -> Result<f64> {
323        self.call("getdifficulty", &[]).await
324    }
325
326    async fn get_connection_count(&self) -> Result<usize> {
327        self.call("getconnectioncount", &[]).await
328    }
329
330    async fn get_block(&self, hash: &bitcoin::BlockHash) -> Result<Block> {
331        let hex: String = self.call("getblock", &[into_json(hash)?, 0.into()]).await?;
332        let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
333        Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
334    }
335
336    async fn get_block_hex(&self, hash: &bitcoin::BlockHash) -> Result<String> {
337        self.call("getblock", &[into_json(hash)?, 0.into()]).await
338    }
339
340    async fn get_block_info(&self, hash: &bitcoin::BlockHash) -> Result<json::GetBlockResult> {
341        self.call("getblock", &[into_json(hash)?, 1.into()]).await
342    }
343    //TODO(stevenroose) add getblock_txs
344
345    async fn get_block_header(&self, hash: &bitcoin::BlockHash) -> Result<BlockHeader> {
346        let hex: String = self.call("getblockheader", &[into_json(hash)?, false.into()]).await?;
347        let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
348        Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
349    }
350
351    async fn get_block_header_info(
352        &self,
353        hash: &bitcoin::BlockHash,
354    ) -> Result<json::GetBlockHeaderResult> {
355        self.call("getblockheader", &[into_json(hash)?, true.into()]).await
356    }
357
358    async fn get_mining_info(&self) -> Result<json::GetMiningInfoResult> {
359        self.call("getmininginfo", &[]).await
360    }
361
362    /// Returns a data structure containing various state info regarding
363    /// blockchain processing.
364    async fn get_blockchain_info(&self) -> Result<json::GetBlockchainInfoResult> {
365        let mut raw: serde_json::Value = self.call("getblockchaininfo", &[]).await?;
366        // The softfork fields are not backwards compatible:
367        // - 0.18.x returns a "softforks" array and a "bip9_softforks" map.
368        // - 0.19.x returns a "softforks" map.
369        Ok(if self.version().await? < 190000 {
370            use Error::UnexpectedStructure as err;
371
372            // First, remove both incompatible softfork fields.
373            // We need to scope the mutable ref here for v1.29 borrowck.
374            let (bip9_softforks, old_softforks) = {
375                let map = raw.as_object_mut().ok_or(err)?;
376                let bip9_softforks = map.remove("bip9_softforks").ok_or(err)?;
377                let old_softforks = map.remove("softforks").ok_or(err)?;
378                // Put back an empty "softforks" field.
379                map.insert("softforks".into(), serde_json::Map::new().into());
380                (bip9_softforks, old_softforks)
381            };
382            let mut ret: json::GetBlockchainInfoResult = serde_json::from_value(raw)?;
383
384            // Then convert both softfork types and add them.
385            for sf in old_softforks.as_array().ok_or(err)?.iter() {
386                let json = sf.as_object().ok_or(err)?;
387                let id = json.get("id").ok_or(err)?.as_str().ok_or(err)?;
388                let reject = json.get("reject").ok_or(err)?.as_object().ok_or(err)?;
389                let active = reject.get("status").ok_or(err)?.as_bool().ok_or(err)?;
390                ret.softforks.insert(
391                    id.into(),
392                    json::Softfork {
393                        type_: json::SoftforkType::Buried,
394                        bip9: None,
395                        height: None,
396                        active: active,
397                    },
398                );
399            }
400            for (id, sf) in bip9_softforks.as_object().ok_or(err)?.iter() {
401                #[derive(Deserialize)]
402                struct OldBip9SoftFork {
403                    pub status: json::Bip9SoftforkStatus,
404                    pub bit: Option<u8>,
405                    #[serde(rename = "startTime")]
406                    pub start_time: i64,
407                    pub timeout: u64,
408                    pub since: u32,
409                    pub statistics: Option<json::Bip9SoftforkStatistics>,
410                }
411                let sf: OldBip9SoftFork = serde_json::from_value(sf.clone())?;
412                ret.softforks.insert(
413                    id.clone(),
414                    json::Softfork {
415                        type_: json::SoftforkType::Bip9,
416                        bip9: Some(json::Bip9SoftforkInfo {
417                            status: sf.status,
418                            bit: sf.bit,
419                            start_time: sf.start_time,
420                            timeout: sf.timeout,
421                            since: sf.since,
422                            statistics: sf.statistics,
423                        }),
424                        height: None,
425                        active: sf.status == json::Bip9SoftforkStatus::Active,
426                    },
427                );
428            }
429            ret
430        } else {
431            serde_json::from_value(raw)?
432        })
433    }
434
435    /// Returns the numbers of block in the longest chain.
436    async fn get_block_count(&self) -> Result<u64> {
437        self.call("getblockcount", &[]).await
438    }
439
440    /// Returns the hash of the best (tip) block in the longest blockchain.
441    async fn get_best_block_hash(&self) -> Result<bitcoin::BlockHash> {
442        self.call("getbestblockhash", &[]).await
443    }
444
445    /// Get block hash at a given height
446    async fn get_block_hash(&self, height: u64) -> Result<bitcoin::BlockHash> {
447        self.call("getblockhash", &[height.into()]).await
448    }
449
450    async fn get_raw_transaction(
451        &self,
452        txid: &bitcoin::Txid,
453        block_hash: Option<&bitcoin::BlockHash>,
454    ) -> Result<Transaction> {
455        let mut args = [into_json(txid)?, into_json(false)?, opt_into_json(block_hash)?];
456        let hex: String =
457            self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await?;
458        let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
459        Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
460    }
461
462    async fn get_raw_transaction_hex(
463        &self,
464        txid: &bitcoin::Txid,
465        block_hash: Option<&bitcoin::BlockHash>,
466    ) -> Result<String> {
467        let mut args = [into_json(txid)?, into_json(false)?, opt_into_json(block_hash)?];
468        self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await
469    }
470
471    async fn get_raw_transaction_info(
472        &self,
473        txid: &bitcoin::Txid,
474        block_hash: Option<&bitcoin::BlockHash>,
475    ) -> Result<json::GetRawTransactionResult> {
476        let mut args = [into_json(txid)?, into_json(true)?, opt_into_json(block_hash)?];
477        self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await
478    }
479
480    async fn get_block_filter(
481        &self,
482        block_hash: &bitcoin::BlockHash,
483    ) -> Result<json::GetBlockFilterResult> {
484        self.call("getblockfilter", &[into_json(block_hash)?]).await
485    }
486
487    async fn get_balance(
488        &self,
489        minconf: Option<usize>,
490        include_watchonly: Option<bool>,
491    ) -> Result<Amount> {
492        let mut args = ["*".into(), opt_into_json(minconf)?, opt_into_json(include_watchonly)?];
493        Ok(Amount::from_btc(
494            self.call("getbalance", handle_defaults(&mut args, &[0.into(), null()])).await?,
495        )?)
496    }
497
498    async fn get_balances(&self) -> Result<json::GetBalancesResult> {
499        Ok(self.call("getbalances", &[]).await?)
500    }
501
502    async fn get_received_by_address(
503        &self,
504        address: &Address,
505        minconf: Option<u32>,
506    ) -> Result<Amount> {
507        let mut args = [address.to_string().into(), opt_into_json(minconf)?];
508        Ok(Amount::from_btc(
509            self.call("getreceivedbyaddress", handle_defaults(&mut args, &[null()])).await?,
510        )?)
511    }
512
513    async fn get_transaction(
514        &self,
515        txid: &bitcoin::Txid,
516        include_watchonly: Option<bool>,
517    ) -> Result<json::GetTransactionResult> {
518        let mut args = [into_json(txid)?, opt_into_json(include_watchonly)?];
519        self.call("gettransaction", handle_defaults(&mut args, &[null()])).await
520    }
521
522    async fn list_transactions(
523        &self,
524        label: Option<&str>,
525        count: Option<usize>,
526        skip: Option<usize>,
527        include_watchonly: Option<bool>,
528    ) -> Result<Vec<json::ListTransactionResult>> {
529        let mut args = [
530            label.unwrap_or("*").into(),
531            opt_into_json(count)?,
532            opt_into_json(skip)?,
533            opt_into_json(include_watchonly)?,
534        ];
535        self.call("listtransactions", handle_defaults(&mut args, &[10.into(), 0.into(), null()]))
536            .await
537    }
538
539    async fn list_since_block(
540        &self,
541        blockhash: Option<&bitcoin::BlockHash>,
542        target_confirmations: Option<usize>,
543        include_watchonly: Option<bool>,
544        include_removed: Option<bool>,
545    ) -> Result<json::ListSinceBlockResult> {
546        let mut args = [
547            opt_into_json(blockhash)?,
548            opt_into_json(target_confirmations)?,
549            opt_into_json(include_watchonly)?,
550            opt_into_json(include_removed)?,
551        ];
552        self.call("listsinceblock", handle_defaults(&mut args, &[null()])).await
553    }
554
555    async fn get_tx_out(
556        &self,
557        txid: &bitcoin::Txid,
558        vout: u32,
559        include_mempool: Option<bool>,
560    ) -> Result<Option<json::GetTxOutResult>> {
561        let mut args = [into_json(txid)?, into_json(vout)?, opt_into_json(include_mempool)?];
562        opt_result(self.call("gettxout", handle_defaults(&mut args, &[null()])).await?)
563    }
564
565    async fn get_tx_out_proof(
566        &self,
567        txids: &[bitcoin::Txid],
568        block_hash: Option<&bitcoin::BlockHash>,
569    ) -> Result<Vec<u8>> {
570        let mut args = [into_json(txids)?, opt_into_json(block_hash)?];
571        let hex: String = self.call("gettxoutproof", handle_defaults(&mut args, &[null()])).await?;
572        Ok(FromHex::from_hex(&hex)?)
573    }
574
575    async fn import_public_key(
576        &self,
577        pubkey: &PublicKey,
578        label: Option<&str>,
579        rescan: Option<bool>,
580    ) -> Result<()> {
581        let mut args = [pubkey.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
582        self.call("importpubkey", handle_defaults(&mut args, &[into_json("")?, null()])).await
583    }
584
585    async fn import_private_key(
586        &self,
587        privkey: &PrivateKey,
588        label: Option<&str>,
589        rescan: Option<bool>,
590    ) -> Result<()> {
591        let mut args = [privkey.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
592        self.call("importprivkey", handle_defaults(&mut args, &[into_json("")?, null()])).await
593    }
594
595    async fn import_address(
596        &self,
597        address: &Address,
598        label: Option<&str>,
599        rescan: Option<bool>,
600    ) -> Result<()> {
601        let mut args = [address.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
602        self.call("importaddress", handle_defaults(&mut args, &[into_json("")?, null()])).await
603    }
604
605    async fn import_address_script(
606        &self,
607        script: &Script,
608        label: Option<&str>,
609        rescan: Option<bool>,
610        p2sh: Option<bool>,
611    ) -> Result<()> {
612        let mut args = [
613            script.to_hex().into(),
614            opt_into_json(label)?,
615            opt_into_json(rescan)?,
616            opt_into_json(p2sh)?,
617        ];
618        self.call(
619            "importaddress",
620            handle_defaults(&mut args, &[into_json("")?, true.into(), null()]),
621        )
622        .await
623    }
624
625    async fn import_multi(
626        &self,
627        requests: &[json::ImportMultiRequest<'_>],
628        options: Option<&json::ImportMultiOptions>,
629    ) -> Result<Vec<json::ImportMultiResult>> {
630        let mut json_requests = Vec::with_capacity(requests.len());
631        for req in requests {
632            json_requests.push(serde_json::to_value(req)?);
633        }
634        let mut args = [json_requests.into(), opt_into_json(options)?];
635        self.call("importmulti", handle_defaults(&mut args, &[null()])).await
636    }
637
638    async fn set_label(&self, address: &Address, label: &str) -> Result<()> {
639        self.call("setlabel", &[address.to_string().into(), label.into()]).await
640    }
641
642    async fn key_pool_refill(&self, new_size: Option<usize>) -> Result<()> {
643        let mut args = [opt_into_json(new_size)?];
644        self.call("keypoolrefill", handle_defaults(&mut args, &[null()])).await
645    }
646
647    async fn list_unspent(
648        &self,
649        minconf: Option<usize>,
650        maxconf: Option<usize>,
651        addresses: Option<&[&Address]>,
652        include_unsafe: Option<bool>,
653        query_options: Option<json::ListUnspentQueryOptions>,
654    ) -> Result<Vec<json::ListUnspentResultEntry>> {
655        let mut args = [
656            opt_into_json(minconf)?,
657            opt_into_json(maxconf)?,
658            opt_into_json(addresses)?,
659            opt_into_json(include_unsafe)?,
660            opt_into_json(query_options)?,
661        ];
662        let defaults = [into_json(0)?, into_json(9999999)?, empty_arr(), into_json(true)?, null()];
663        self.call("listunspent", handle_defaults(&mut args, &defaults)).await
664    }
665
666    /// To unlock, use [unlock_unspent].
667    async fn lock_unspent(&self, outputs: &[OutPoint]) -> Result<bool> {
668        let outputs: Vec<_> = outputs
669            .into_iter()
670            .map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap())
671            .collect();
672        self.call("lockunspent", &[false.into(), outputs.into()]).await
673    }
674
675    async fn unlock_unspent(&self, outputs: &[OutPoint]) -> Result<bool> {
676        let outputs: Vec<_> = outputs
677            .into_iter()
678            .map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap())
679            .collect();
680        self.call("lockunspent", &[true.into(), outputs.into()]).await
681    }
682
683    async fn list_received_by_address(
684        &self,
685        address_filter: Option<&Address>,
686        minconf: Option<u32>,
687        include_empty: Option<bool>,
688        include_watchonly: Option<bool>,
689    ) -> Result<Vec<json::ListReceivedByAddressResult>> {
690        let mut args = [
691            opt_into_json(minconf)?,
692            opt_into_json(include_empty)?,
693            opt_into_json(include_watchonly)?,
694            opt_into_json(address_filter)?,
695        ];
696        let defaults = [1.into(), false.into(), false.into(), null()];
697        self.call("listreceivedbyaddress", handle_defaults(&mut args, &defaults)).await
698    }
699
700    async fn create_raw_transaction_hex(
701        &self,
702        utxos: &[json::CreateRawTransactionInput],
703        outs: &HashMap<String, Amount>,
704        locktime: Option<i64>,
705        replaceable: Option<bool>,
706    ) -> Result<String> {
707        let outs_converted = serde_json::Map::from_iter(
708            outs.iter().map(|(k, v)| (k.clone(), serde_json::Value::from(v.as_btc()))),
709        );
710        let mut args = [
711            into_json(utxos)?,
712            into_json(outs_converted)?,
713            opt_into_json(locktime)?,
714            opt_into_json(replaceable)?,
715        ];
716        let defaults = [into_json(0i64)?, null()];
717        self.call("createrawtransaction", handle_defaults(&mut args, &defaults)).await
718    }
719
720    async fn create_raw_transaction(
721        &self,
722        utxos: &[json::CreateRawTransactionInput],
723        outs: &HashMap<String, Amount>,
724        locktime: Option<i64>,
725        replaceable: Option<bool>,
726    ) -> Result<Transaction> {
727        let hex: String =
728            self.create_raw_transaction_hex(utxos, outs, locktime, replaceable).await?;
729        let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
730        Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
731    }
732
733    async fn fund_raw_transaction<R: RawTx>(
734        &self,
735        tx: R,
736        options: Option<&json::FundRawTransactionOptions>,
737        is_witness: Option<bool>,
738    ) -> Result<json::FundRawTransactionResult>
739    where
740        R: Sync + Send,
741    {
742        let mut args = [tx.raw_hex().into(), opt_into_json(options)?, opt_into_json(is_witness)?];
743        let defaults = [empty_obj(), null()];
744        self.call("fundrawtransaction", handle_defaults(&mut args, &defaults)).await
745    }
746
747    #[deprecated]
748    async fn sign_raw_transaction<R: RawTx>(
749        &self,
750        tx: R,
751        utxos: Option<&[json::SignRawTransactionInput]>,
752        private_keys: Option<&[PrivateKey]>,
753        sighash_type: Option<json::SigHashType>,
754    ) -> Result<json::SignRawTransactionResult>
755    where
756        R: Sync + Send,
757    {
758        let mut args = [
759            tx.raw_hex().into(),
760            opt_into_json(utxos)?,
761            opt_into_json(private_keys)?,
762            opt_into_json(sighash_type)?,
763        ];
764        let defaults = [empty_arr(), empty_arr(), null()];
765        self.call("signrawtransaction", handle_defaults(&mut args, &defaults)).await
766    }
767
768    async fn sign_raw_transaction_with_wallet<R: RawTx>(
769        &self,
770        tx: R,
771        utxos: Option<&[json::SignRawTransactionInput]>,
772        sighash_type: Option<json::SigHashType>,
773    ) -> Result<json::SignRawTransactionResult>
774    where
775        R: Sync + Send,
776    {
777        let mut args = [tx.raw_hex().into(), opt_into_json(utxos)?, opt_into_json(sighash_type)?];
778        let defaults = [empty_arr(), null()];
779        self.call("signrawtransactionwithwallet", handle_defaults(&mut args, &defaults)).await
780    }
781
782    async fn sign_raw_transaction_with_key<R: RawTx>(
783        &self,
784        tx: R,
785        privkeys: &[PrivateKey],
786        prevtxs: Option<&[json::SignRawTransactionInput]>,
787        sighash_type: Option<json::SigHashType>,
788    ) -> Result<json::SignRawTransactionResult>
789    where
790        R: Sync + Send,
791    {
792        let mut args = [
793            tx.raw_hex().into(),
794            into_json(privkeys)?,
795            opt_into_json(prevtxs)?,
796            opt_into_json(sighash_type)?,
797        ];
798        let defaults = [empty_arr(), null()];
799        self.call("signrawtransactionwithkey", handle_defaults(&mut args, &defaults)).await
800    }
801
802    async fn test_mempool_accept<R: RawTx>(
803        &self,
804        rawtxs: &[R],
805    ) -> Result<Vec<json::TestMempoolAcceptResult>>
806    where
807        R: Sync + Send,
808    {
809        let hexes: Vec<serde_json::Value> =
810            rawtxs.to_vec().into_iter().map(|r| r.raw_hex().into()).collect();
811        self.call("testmempoolaccept", &[hexes.into()]).await
812    }
813
814    async fn stop(&self) -> Result<String> {
815        self.call("stop", &[]).await
816    }
817
818    async fn verify_message(
819        &self,
820        address: &Address,
821        signature: &Signature,
822        message: &str,
823    ) -> Result<bool> {
824        let args = [address.to_string().into(), signature.to_string().into(), into_json(message)?];
825        self.call("verifymessage", &args).await
826    }
827
828    /// Generate new address under own control
829    async fn get_new_address(
830        &self,
831        label: Option<&str>,
832        address_type: Option<json::AddressType>,
833    ) -> Result<Address> {
834        self.call("getnewaddress", &[opt_into_json(label)?, opt_into_json(address_type)?]).await
835    }
836
837    async fn get_address_info(&self, address: &Address) -> Result<json::GetAddressInfoResult> {
838        self.call("getaddressinfo", &[address.to_string().into()]).await
839    }
840
841    /// Mine `block_num` blocks and pay coinbase to `address`
842    ///
843    /// Returns hashes of the generated blocks
844    async fn generate_to_address(
845        &self,
846        block_num: u64,
847        address: &Address,
848    ) -> Result<Vec<bitcoin::BlockHash>> {
849        self.call("generatetoaddress", &[block_num.into(), address.to_string().into()]).await
850    }
851
852    /// Mine up to block_num blocks immediately (before the RPC call returns)
853    /// to an address in the wallet.
854    async fn generate(
855        &self,
856        block_num: u64,
857        maxtries: Option<u64>,
858    ) -> Result<Vec<bitcoin::BlockHash>> {
859        self.call("generate", &[block_num.into(), opt_into_json(maxtries)?]).await
860    }
861
862    /// Mark a block as invalid by `block_hash`
863    async fn invalidate_block(&self, block_hash: &bitcoin::BlockHash) -> Result<()> {
864        self.call("invalidateblock", &[into_json(block_hash)?]).await
865    }
866
867    /// Mark a block as valid by `block_hash`
868    async fn reconsider_block(&self, block_hash: &bitcoin::BlockHash) -> Result<()> {
869        self.call("reconsiderblock", &[into_json(block_hash)?]).await
870    }
871
872    /// Get txids of all transactions in a memory pool
873    async fn get_raw_mempool(&self) -> Result<Vec<bitcoin::Txid>> {
874        self.call("getrawmempool", &[]).await
875    }
876
877    /// Get mempool data for given transaction
878    async fn get_mempool_entry(&self, txid: &bitcoin::Txid) -> Result<json::GetMempoolEntryResult> {
879        self.call("getmempoolentry", &[into_json(txid)?]).await
880    }
881
882    async fn send_to_address(
883        &self,
884        address: &Address,
885        amount: Amount,
886        comment: Option<&str>,
887        comment_to: Option<&str>,
888        subtract_fee: Option<bool>,
889        replaceable: Option<bool>,
890        confirmation_target: Option<u32>,
891        estimate_mode: Option<json::EstimateMode>,
892    ) -> Result<bitcoin::Txid> {
893        let mut args = [
894            address.to_string().into(),
895            into_json(amount.as_btc())?,
896            opt_into_json(comment)?,
897            opt_into_json(comment_to)?,
898            opt_into_json(subtract_fee)?,
899            opt_into_json(replaceable)?,
900            opt_into_json(confirmation_target)?,
901            opt_into_json(estimate_mode)?,
902        ];
903        self.call(
904            "sendtoaddress",
905            handle_defaults(
906                &mut args,
907                &["".into(), "".into(), false.into(), false.into(), 6.into(), null()],
908            ),
909        )
910        .await
911    }
912
913    /// Returns data about each connected network node as an array of
914    /// [`PeerInfo`][]
915    ///
916    /// [`PeerInfo`]: net/struct.PeerInfo.html
917    async fn get_peer_info(&self) -> Result<Vec<json::GetPeerInfoResult>> {
918        self.call("getpeerinfo", &[]).await
919    }
920
921    /// Requests that a ping be sent to all other nodes, to measure ping
922    /// time.
923    ///
924    /// Results provided in `getpeerinfo`, `pingtime` and `pingwait` fields
925    /// are decimal seconds.
926    ///
927    /// Ping command is handled in queue with all other commands, so it
928    /// measures processing backlog, not just network ping.
929    async fn ping(&self) -> Result<()> {
930        self.call("ping", &[]).await
931    }
932
933    async fn send_raw_transaction<R: RawTx>(&self, tx: R) -> Result<bitcoin::Txid>
934    where
935        R: Sync + Send,
936    {
937        self.call("sendrawtransaction", &[tx.raw_hex().into()]).await
938    }
939
940    async fn estimate_smart_fee(
941        &self,
942        conf_target: u16,
943        estimate_mode: Option<json::EstimateMode>,
944    ) -> Result<json::EstimateSmartFeeResult> {
945        let mut args = [into_json(conf_target)?, opt_into_json(estimate_mode)?];
946        self.call("estimatesmartfee", handle_defaults(&mut args, &[null()])).await
947    }
948
949    /// Waits for a specific new block and returns useful info about it.
950    /// Returns the current block on timeout or exit.
951    ///
952    /// # Arguments
953    ///
954    /// 1. `timeout`: Time in milliseconds to wait for a response. 0
955    /// indicates no timeout.
956    async fn wait_for_new_block(&self, timeout: u64) -> Result<json::BlockRef> {
957        self.call("waitfornewblock", &[into_json(timeout)?]).await
958    }
959
960    /// Waits for a specific new block and returns useful info about it.
961    /// Returns the current block on timeout or exit.
962    ///
963    /// # Arguments
964    ///
965    /// 1. `blockhash`: Block hash to wait for.
966    /// 2. `timeout`: Time in milliseconds to wait for a response. 0
967    /// indicates no timeout.
968    async fn wait_for_block(
969        &self,
970        blockhash: &bitcoin::BlockHash,
971        timeout: u64,
972    ) -> Result<json::BlockRef> {
973        let args = [into_json(blockhash)?, into_json(timeout)?];
974        self.call("waitforblock", &args).await
975    }
976
977    async fn wallet_create_funded_psbt(
978        &self,
979        inputs: &[json::CreateRawTransactionInput],
980        outputs: &HashMap<String, Amount>,
981        locktime: Option<i64>,
982        options: Option<json::WalletCreateFundedPsbtOptions>,
983        bip32derivs: Option<bool>,
984    ) -> Result<json::WalletCreateFundedPsbtResult> {
985        let outputs_converted = serde_json::Map::from_iter(
986            outputs.iter().map(|(k, v)| (k.clone(), serde_json::Value::from(v.as_btc()))),
987        );
988        let mut args = [
989            into_json(inputs)?,
990            into_json(outputs_converted)?,
991            opt_into_json(locktime)?,
992            opt_into_json(options)?,
993            opt_into_json(bip32derivs)?,
994        ];
995        self.call(
996            "walletcreatefundedpsbt",
997            handle_defaults(&mut args, &[0.into(), serde_json::Map::new().into(), false.into()]),
998        )
999        .await
1000    }
1001
1002    async fn get_descriptor_info(&self, desc: &str) -> Result<json::GetDescriptorInfoResult> {
1003        self.call("getdescriptorinfo", &[desc.to_string().into()]).await
1004    }
1005
1006    async fn combine_psbt(&self, psbts: &[String]) -> Result<String> {
1007        self.call("combinepsbt", &[into_json(psbts)?]).await
1008    }
1009
1010    async fn finalize_psbt(
1011        &self,
1012        psbt: &str,
1013        extract: Option<bool>,
1014    ) -> Result<json::FinalizePsbtResult> {
1015        let mut args = [into_json(psbt)?, opt_into_json(extract)?];
1016        self.call("finalizepsbt", handle_defaults(&mut args, &[true.into()])).await
1017    }
1018
1019    async fn derive_addresses(
1020        &self,
1021        descriptor: &str,
1022        range: Option<[u32; 2]>,
1023    ) -> Result<Vec<Address>> {
1024        let mut args = [into_json(descriptor)?, opt_into_json(range)?];
1025        self.call("deriveaddresses", handle_defaults(&mut args, &[null()])).await
1026    }
1027
1028    async fn rescan_blockchain(
1029        &self,
1030        start_from: Option<usize>,
1031        stop_height: Option<usize>,
1032    ) -> Result<(usize, Option<usize>)> {
1033        let mut args = [opt_into_json(start_from)?, opt_into_json(stop_height)?];
1034
1035        #[derive(Deserialize)]
1036        struct Response {
1037            pub start_height: usize,
1038            pub stop_height: Option<usize>,
1039        }
1040        let res: Response =
1041            self.call("rescanblockchain", handle_defaults(&mut args, &[0.into(), null()])).await?;
1042        Ok((res.start_height, res.stop_height))
1043    }
1044
1045    /// Returns statistics about the unspent transaction output set.
1046    /// This call may take some time.
1047    async fn get_tx_out_set_info(&self) -> Result<json::GetTxOutSetInfoResult> {
1048        self.call("gettxoutsetinfo", &[]).await
1049    }
1050
1051    /// Returns information about network traffic, including bytes in, bytes out,
1052    /// and current time.
1053    async fn get_net_totals(&self) -> Result<json::GetNetTotalsResult> {
1054        self.call("getnettotals", &[]).await
1055    }
1056
1057    /// Returns the estimated network hashes per second based on the last n blocks.
1058    async fn get_network_hash_ps(&self, nblocks: Option<u64>, height: Option<u64>) -> Result<f64> {
1059        let mut args = [opt_into_json(nblocks)?, opt_into_json(height)?];
1060        self.call("getnetworkhashps", handle_defaults(&mut args, &[null(), null()])).await
1061    }
1062
1063    /// Returns the total uptime of the server in seconds
1064    async fn uptime(&self) -> Result<u64> {
1065        self.call("uptime", &[]).await
1066    }
1067
1068    async fn scan_tx_out_set_blocking(
1069        &self,
1070        descriptors: &[json::ScanTxOutRequest],
1071    ) -> Result<json::ScanTxOutResult> {
1072        self.call("scantxoutset", &["start".into(), into_json(descriptors)?]).await
1073    }
1074}
1075
1076/// Client implements a JSON-RPC client for the Bitcoin Core daemon or compatible APIs.
1077pub struct Client {
1078    client: jsonrpc::client::Client,
1079}
1080
1081impl fmt::Debug for Client {
1082    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1083        write!(f, "bitcoincore_rpc::Client(jsonrpc::client::Client(last_nonce=?))",)
1084    }
1085}
1086
1087impl Client {
1088    /// Creates a client to a bitcoind JSON-RPC server.
1089    ///
1090    /// Can only return [Err] when using cookie authentication.
1091    pub async fn new(url: String, auth: Auth) -> Result<Self> {
1092        let mut client = jsonrpc::simple_http::SimpleHttpTransport::builder()
1093            .url(&url)
1094            .await
1095            .map_err(|e| Error::JsonRpc(e.into()))?;
1096        if let Some((user, pass)) = auth.get_user_pass()? {
1097            client = client.auth(user, Some(pass));
1098        }
1099
1100        Ok(Client {
1101            client: jsonrpc::client::Client::with_transport(client.build()),
1102        })
1103    }
1104
1105    /// Create a new Client.
1106    pub fn from_jsonrpc(client: jsonrpc::client::Client) -> Client {
1107        Client {
1108            client: client,
1109        }
1110    }
1111
1112    /// Get the underlying JSONRPC client.
1113    pub fn get_jsonrpc_client(&self) -> &jsonrpc::client::Client {
1114        &self.client
1115    }
1116}
1117
1118#[async_trait]
1119impl RpcApi for Client {
1120    /// Call an `cmd` rpc with given `args` list
1121    async fn call<T: for<'a> serde::de::Deserialize<'a>>(
1122        &self,
1123        cmd: &str,
1124        args: &[serde_json::Value],
1125    ) -> Result<T> {
1126        let v_args: Vec<_> = args
1127            .iter()
1128            .map(serde_json::value::to_raw_value)
1129            .collect::<std::result::Result<_, serde_json::Error>>()?;
1130        let req = self.client.build_request(cmd, &v_args[..]);
1131        if log_enabled!(Debug) {
1132            debug!(target: "bitcoincore_rpc", "JSON-RPC request: {} {}", cmd, serde_json::Value::from(args));
1133        }
1134
1135        let resp = self.client.send_request(req).await.map_err(Error::from);
1136        log_response(cmd, &resp);
1137        Ok(resp?.result()?)
1138    }
1139}
1140
1141fn log_response(cmd: &str, resp: &Result<jsonrpc::Response>) {
1142    if log_enabled!(Warn) || log_enabled!(Debug) || log_enabled!(Trace) {
1143        match resp {
1144            Err(ref e) => {
1145                if log_enabled!(Debug) {
1146                    debug!(target: "bitcoincore_rpc", "JSON-RPC failed parsing reply of {}: {:?}", cmd, e);
1147                }
1148            }
1149            Ok(ref resp) => {
1150                if let Some(ref e) = resp.error {
1151                    if log_enabled!(Debug) {
1152                        debug!(target: "bitcoincore_rpc", "JSON-RPC error for {}: {:?}", cmd, e);
1153                    }
1154                } else if log_enabled!(Trace) {
1155                    let rawnull =
1156                        serde_json::value::to_raw_value(&serde_json::Value::Null).unwrap();
1157                    let result = resp.result.as_ref().unwrap_or(&rawnull);
1158                    trace!(target: "bitcoincore_rpc", "JSON-RPC response for {}: {}", cmd, result);
1159                }
1160            }
1161        }
1162    }
1163}
1164
1165#[cfg(test)]
1166mod tests {
1167    use super::*;
1168    use bitcoin;
1169    use serde_json;
1170    use tokio;
1171
1172    #[tokio::test]
1173    async fn test_raw_tx() {
1174        use bitcoin::consensus::encode;
1175        let client = Client::new("http://localhost/".into(), Auth::None).await.unwrap();
1176        let tx: bitcoin::Transaction = encode::deserialize(&Vec::<u8>::from_hex("0200000001586bd02815cf5faabfec986a4e50d25dbee089bd2758621e61c5fab06c334af0000000006b483045022100e85425f6d7c589972ee061413bcf08dc8c8e589ce37b217535a42af924f0e4d602205c9ba9cb14ef15513c9d946fa1c4b797883e748e8c32171bdf6166583946e35c012103dae30a4d7870cd87b45dd53e6012f71318fdd059c1c2623b8cc73f8af287bb2dfeffffff021dc4260c010000001976a914f602e88b2b5901d8aab15ebe4a97cf92ec6e03b388ac00e1f505000000001976a914687ffeffe8cf4e4c038da46a9b1d37db385a472d88acfd211500").unwrap()).unwrap();
1177
1178        assert!(client.send_raw_transaction(&tx).await.is_err());
1179        assert!(client.send_raw_transaction(&encode::serialize(&tx)).await.is_err());
1180        assert!(client.send_raw_transaction("deadbeef").await.is_err());
1181        assert!(client.send_raw_transaction("deadbeef".to_owned()).await.is_err());
1182    }
1183
1184    fn test_handle_defaults_inner() -> Result<()> {
1185        {
1186            let mut args = [into_json(0)?, null(), null()];
1187            let defaults = [into_json(1)?, into_json(2)?];
1188            let res = [into_json(0)?];
1189            assert_eq!(handle_defaults(&mut args, &defaults), &res);
1190        }
1191        {
1192            let mut args = [into_json(0)?, into_json(1)?, null()];
1193            let defaults = [into_json(2)?];
1194            let res = [into_json(0)?, into_json(1)?];
1195            assert_eq!(handle_defaults(&mut args, &defaults), &res);
1196        }
1197        {
1198            let mut args = [into_json(0)?, null(), into_json(5)?];
1199            let defaults = [into_json(2)?, into_json(3)?];
1200            let res = [into_json(0)?, into_json(2)?, into_json(5)?];
1201            assert_eq!(handle_defaults(&mut args, &defaults), &res);
1202        }
1203        {
1204            let mut args = [into_json(0)?, null(), into_json(5)?, null()];
1205            let defaults = [into_json(2)?, into_json(3)?, into_json(4)?];
1206            let res = [into_json(0)?, into_json(2)?, into_json(5)?];
1207            assert_eq!(handle_defaults(&mut args, &defaults), &res);
1208        }
1209        {
1210            let mut args = [null(), null()];
1211            let defaults = [into_json(2)?, into_json(3)?];
1212            let res: [serde_json::Value; 0] = [];
1213            assert_eq!(handle_defaults(&mut args, &defaults), &res);
1214        }
1215        {
1216            let mut args = [null(), into_json(1)?];
1217            let defaults = [];
1218            let res = [null(), into_json(1)?];
1219            assert_eq!(handle_defaults(&mut args, &defaults), &res);
1220        }
1221        {
1222            let mut args = [];
1223            let defaults = [];
1224            let res: [serde_json::Value; 0] = [];
1225            assert_eq!(handle_defaults(&mut args, &defaults), &res);
1226        }
1227        {
1228            let mut args = [into_json(0)?];
1229            let defaults = [into_json(2)?];
1230            let res = [into_json(0)?];
1231            assert_eq!(handle_defaults(&mut args, &defaults), &res);
1232        }
1233        Ok(())
1234    }
1235
1236    #[test]
1237    fn test_handle_defaults() {
1238        test_handle_defaults_inner().unwrap();
1239    }
1240}