bitcoincore_rpc_async/
queryable.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 super::bitcoin;
12use super::json;
13use serde_json;
14
15use crate::client::Result;
16use crate::client::RpcApi;
17use async_trait::async_trait;
18
19/// A type that can be queried from Bitcoin Core.
20#[async_trait]
21pub trait Queryable<C: RpcApi>: Sized + Send + Sync {
22    /// Type of the ID used to query the item.
23    type Id;
24    /// Query the item using `rpc` and convert to `Self`.
25    async fn query(rpc: &C, id: &Self::Id) -> Result<Self>;
26}
27
28#[async_trait]
29impl<C: RpcApi + std::marker::Sync> Queryable<C> for bitcoin::blockdata::block::Block {
30    type Id = bitcoin::BlockHash;
31
32    async fn query(rpc: &C, id: &Self::Id) -> Result<Self> {
33        let rpc_name = "getblock";
34        let hex: String = rpc.call(rpc_name, &[serde_json::to_value(id)?, 0.into()]).await?;
35        let bytes: Vec<u8> = bitcoin::hashes::hex::FromHex::from_hex(&hex)?;
36        Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
37    }
38}
39
40#[async_trait]
41impl<C: RpcApi + std::marker::Sync> Queryable<C> for bitcoin::blockdata::transaction::Transaction {
42    type Id = bitcoin::Txid;
43
44    async fn query(rpc: &C, id: &Self::Id) -> Result<Self> {
45        let rpc_name = "getrawtransaction";
46        let hex: String = rpc.call(rpc_name, &[serde_json::to_value(id)?]).await?;
47        let bytes: Vec<u8> = bitcoin::hashes::hex::FromHex::from_hex(&hex)?;
48        Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
49    }
50}
51
52#[async_trait]
53impl<C: RpcApi + std::marker::Sync> Queryable<C> for Option<json::GetTxOutResult> {
54    type Id = bitcoin::OutPoint;
55
56    async fn query(rpc: &C, id: &Self::Id) -> Result<Self> {
57        rpc.get_tx_out(&id.txid, id.vout, Some(true)).await
58    }
59}