Skip to content

Commit e24663b

Browse files
Merge #25: Add get raw block endpoint
199c6ec Add get raw block endpoint (benthecarman) Pull request description: This will be needed for implementing LDKs `BlockSource` trait Top commit has no ACKs. Tree-SHA512: b59f4933f6ba03dc36805b9728e57f480fe33a1e1908d2affa1028c27548fd4426c66261a087f5414bf790380c4f68f8ed8d8012f84deaa039f96a746d3f3ad2
2 parents 8ff0a18 + 199c6ec commit e24663b

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

src/async.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::str::FromStr;
1717
use bitcoin::consensus::{deserialize, serialize};
1818
use bitcoin::hashes::hex::{FromHex, ToHex};
1919
use bitcoin::hashes::{sha256, Hash};
20-
use bitcoin::{BlockHash, BlockHeader, Script, Transaction, Txid};
20+
use bitcoin::{Block, BlockHash, BlockHeader, Script, Transaction, Txid};
2121

2222
#[allow(unused_imports)]
2323
use log::{debug, error, info, trace};
@@ -147,6 +147,20 @@ impl AsyncClient {
147147
Ok(resp.error_for_status()?.json().await?)
148148
}
149149

150+
/// Get a [`Block`] given a particular [`BlockHash`].
151+
pub async fn get_block_by_hash(&self, block_hash: &BlockHash) -> Result<Option<Block>, Error> {
152+
let resp = self
153+
.client
154+
.get(&format!("{}/block/{}/raw", self.url, block_hash))
155+
.send()
156+
.await?;
157+
158+
if let StatusCode::NOT_FOUND = resp.status() {
159+
return Ok(None);
160+
}
161+
Ok(Some(deserialize(&resp.error_for_status()?.bytes().await?)?))
162+
}
163+
150164
/// Get a merkle inclusion proof for a [`Transaction`] with the given [`Txid`].
151165
pub async fn get_merkle_proof(&self, tx_hash: &Txid) -> Result<Option<MerkleProof>, Error> {
152166
let resp = self

src/blocking.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use ureq::{Agent, Proxy, Response};
2525
use bitcoin::consensus::{deserialize, serialize};
2626
use bitcoin::hashes::hex::{FromHex, ToHex};
2727
use bitcoin::hashes::{sha256, Hash};
28-
use bitcoin::{BlockHash, BlockHeader, Script, Transaction, Txid};
28+
use bitcoin::{Block, BlockHash, BlockHeader, Script, Transaction, Txid};
2929

3030
use crate::{BlockStatus, Builder, Error, MerkleProof, OutputStatus, Tx, TxStatus};
3131

@@ -164,6 +164,25 @@ impl BlockingClient {
164164
}
165165
}
166166

167+
/// Get a [`Block`] given a particular [`BlockHash`].
168+
pub fn get_block_by_hash(&self, block_hash: &BlockHash) -> Result<Option<Block>, Error> {
169+
let resp = self
170+
.agent
171+
.get(&format!("{}/block/{}/raw", self.url, block_hash))
172+
.call();
173+
174+
match resp {
175+
Ok(resp) => Ok(Some(deserialize(&into_bytes(resp)?)?)),
176+
Err(ureq::Error::Status(code, _)) => {
177+
if is_status_not_found(code) {
178+
return Ok(None);
179+
}
180+
Err(Error::HttpResponse(code))
181+
}
182+
Err(e) => Err(Error::Ureq(e)),
183+
}
184+
}
185+
167186
/// Get a merkle inclusion proof for a [`Transaction`] with the given [`Txid`].
168187
pub fn get_merkle_proof(&self, txid: &Txid) -> Result<Option<MerkleProof>, Error> {
169188
let resp = self

src/lib.rs

+31
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,37 @@ mod test {
506506
assert_eq!(expected, block_status_async);
507507
}
508508

509+
#[cfg(all(feature = "blocking", any(feature = "async", feature = "async-https")))]
510+
#[tokio::test]
511+
async fn test_get_block_by_hash() {
512+
let (blocking_client, async_client) = setup_clients().await;
513+
514+
let block_hash = BITCOIND.client.get_block_hash(21).unwrap();
515+
516+
let expected = Some(BITCOIND.client.get_block(&block_hash).unwrap());
517+
518+
let block = blocking_client.get_block_by_hash(&block_hash).unwrap();
519+
let block_async = async_client.get_block_by_hash(&block_hash).await.unwrap();
520+
assert_eq!(expected, block);
521+
assert_eq!(expected, block_async);
522+
}
523+
524+
#[cfg(all(feature = "blocking", any(feature = "async", feature = "async-https")))]
525+
#[tokio::test]
526+
async fn test_get_block_by_hash_not_existing() {
527+
let (blocking_client, async_client) = setup_clients().await;
528+
529+
let block = blocking_client
530+
.get_block_by_hash(&BlockHash::all_zeros())
531+
.unwrap();
532+
let block_async = async_client
533+
.get_block_by_hash(&BlockHash::all_zeros())
534+
.await
535+
.unwrap();
536+
assert!(block.is_none());
537+
assert!(block_async.is_none());
538+
}
539+
509540
#[cfg(all(feature = "blocking", any(feature = "async", feature = "async-https")))]
510541
#[tokio::test]
511542
async fn test_get_merkle_proof() {

0 commit comments

Comments
 (0)