+//! Simple RPC client implementation which implements [`BlockSource`] against a Bitcoin Core RPC
+//! endpoint.
+
+use crate::{BlockHeaderData, BlockSource, AsyncBlockSourceResult};
use crate::http::{HttpClient, HttpEndpoint, JsonResponse};
+use bitcoin::blockdata::block::Block;
+use bitcoin::hash_types::BlockHash;
+use bitcoin::hashes::hex::ToHex;
+
use serde_json;
use std::convert::TryFrom;
}
/// Calls a method with the response encoded in JSON format and interpreted as type `T`.
- async fn call_method<T>(&mut self, method: &str, params: &[serde_json::Value]) -> std::io::Result<T>
+ pub async fn call_method<T>(&mut self, method: &str, params: &[serde_json::Value]) -> std::io::Result<T>
where JsonResponse: TryFrom<Vec<u8>, Error = std::io::Error> + TryInto<T, Error = std::io::Error> {
let host = format!("{}:{}", self.endpoint.host(), self.endpoint.port());
let uri = self.endpoint.path();
}
}
+impl BlockSource for RpcClient {
+ fn get_header<'a>(&'a mut self, header_hash: &'a BlockHash, _height: Option<u32>) -> AsyncBlockSourceResult<'a, BlockHeaderData> {
+ Box::pin(async move {
+ let header_hash = serde_json::json!(header_hash.to_hex());
+ Ok(self.call_method("getblockheader", &[header_hash]).await?)
+ })
+ }
+
+ fn get_block<'a>(&'a mut self, header_hash: &'a BlockHash) -> AsyncBlockSourceResult<'a, Block> {
+ Box::pin(async move {
+ let header_hash = serde_json::json!(header_hash.to_hex());
+ let verbosity = serde_json::json!(0);
+ Ok(self.call_method("getblock", &[header_hash, verbosity]).await?)
+ })
+ }
+
+ fn get_best_block<'a>(&'a mut self) -> AsyncBlockSourceResult<'a, (BlockHash, Option<u32>)> {
+ Box::pin(async move {
+ Ok(self.call_method("getblockchaininfo", &[]).await?)
+ })
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;