Skip to content

Commit 8364d05

Browse files
Merge #13: Query block hash by by block height
7c66cf1 Add integration test for get_block_hash() (Gabriel Comte) a0f1aca Query block hash by by block height (Gabriel Comte) Pull request description: Give the possibility to query a block hash by providing its corresponding block height Top commit has no ACKs. Tree-SHA512: e6ae7a1804f6e08079e05db665ab7f32c48af338ed3c6b257102f5721af0e8cd312abbe1f0bdb2429cc3c0969dab3e5ab5ac97f228f47d89b8eedb9ddebc3378
2 parents 7d382f2 + 7c66cf1 commit 8364d05

File tree

3 files changed

+55
-28
lines changed

3 files changed

+55
-28
lines changed

src/async.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -115,22 +115,11 @@ impl AsyncClient {
115115

116116
/// Get a [`BlockHeader`] given a particular block height.
117117
pub async fn get_header(&self, block_height: u32) -> Result<BlockHeader, Error> {
118-
let resp = self
119-
.client
120-
.get(&format!("{}/block-height/{}", self.url, block_height))
121-
.send()
122-
.await?;
123-
124-
if let StatusCode::NOT_FOUND = resp.status() {
125-
return Err(Error::HeaderHeightNotFound(block_height));
126-
}
127-
let bytes = resp.bytes().await?;
128-
let hash =
129-
std::str::from_utf8(&bytes).map_err(|_| Error::HeaderHeightNotFound(block_height))?;
118+
let block_hash = self.get_block_hash(block_height).await?;
130119

131120
let resp = self
132121
.client
133-
.get(&format!("{}/block/{}/header", self.url, hash))
122+
.get(&format!("{}/block/{}/header", self.url, block_hash))
134123
.send()
135124
.await?;
136125

@@ -209,6 +198,23 @@ impl AsyncClient {
209198
)?)
210199
}
211200

201+
/// Get the [`BlockHash`] of a specific block height
202+
pub async fn get_block_hash(&self, block_height: u32) -> Result<BlockHash, Error> {
203+
let resp = self
204+
.client
205+
.get(&format!("{}/block-height/{}", self.url, block_height))
206+
.send()
207+
.await?;
208+
209+
if let StatusCode::NOT_FOUND = resp.status() {
210+
return Err(Error::HeaderHeightNotFound(block_height));
211+
}
212+
213+
Ok(BlockHash::from_str(
214+
&resp.error_for_status()?.text().await?,
215+
)?)
216+
}
217+
212218
/// Get confirmed transaction history for the specified address/scripthash,
213219
/// sorted with newest first. Returns 25 transactions per page.
214220
/// More can be requested by specifying the last txid seen by the previous query.

src/blocking.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,23 +128,11 @@ impl BlockingClient {
128128

129129
/// Get a [`BlockHeader`] given a particular block height.
130130
pub fn get_header(&self, block_height: u32) -> Result<BlockHeader, Error> {
131-
let resp = self
132-
.agent
133-
.get(&format!("{}/block-height/{}", self.url, block_height))
134-
.call();
135-
136-
let bytes = match resp {
137-
Ok(resp) => Ok(into_bytes(resp)?),
138-
Err(ureq::Error::Status(code, _)) => Err(Error::HttpResponse(code)),
139-
Err(e) => Err(Error::Ureq(e)),
140-
}?;
141-
142-
let hash =
143-
std::str::from_utf8(&bytes).map_err(|_| Error::HeaderHeightNotFound(block_height))?;
131+
let block_hash = self.get_block_hash(block_height)?;
144132

145133
let resp = self
146134
.agent
147-
.get(&format!("{}/block/{}/header", self.url, hash))
135+
.get(&format!("{}/block/{}/header", self.url, block_hash))
148136
.call();
149137

150138
match resp {
@@ -231,7 +219,27 @@ impl BlockingClient {
231219
.get(&format!("{}/blocks/tip/hash", self.url))
232220
.call();
233221

234-
match resp {
222+
Self::process_block_result(resp)
223+
}
224+
225+
/// Get the [`BlockHash`] of a specific block height
226+
pub fn get_block_hash(&self, block_height: u32) -> Result<BlockHash, Error> {
227+
let resp = self
228+
.agent
229+
.get(&format!("{}/block-height/{}", self.url, block_height))
230+
.call();
231+
232+
if let Err(ureq::Error::Status(code, _)) = resp {
233+
if is_status_not_found(code) {
234+
return Err(Error::HeaderHeightNotFound(block_height));
235+
}
236+
}
237+
238+
Self::process_block_result(resp)
239+
}
240+
241+
fn process_block_result(response: Result<Response, ureq::Error>) -> Result<BlockHash, Error> {
242+
match response {
235243
Ok(resp) => Ok(BlockHash::from_str(&resp.into_string()?)?),
236244
Err(ureq::Error::Status(code, _)) => Err(Error::HttpResponse(code)),
237245
Err(e) => Err(Error::Ureq(e)),

src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,19 @@ mod test {
545545
assert_eq!(tip_hash, tip_hash_async);
546546
}
547547

548+
#[cfg(all(feature = "blocking", any(feature = "async", feature = "async-https")))]
549+
#[tokio::test]
550+
async fn test_get_block_hash() {
551+
let (blocking_client, async_client) = setup_clients().await;
552+
553+
let block_hash = BITCOIND.client.get_block_hash(21).unwrap();
554+
555+
let block_hash_blocking = blocking_client.get_block_hash(21).unwrap();
556+
let block_hash_async = async_client.get_block_hash(21).await.unwrap();
557+
assert_eq!(block_hash, block_hash_blocking);
558+
assert_eq!(block_hash, block_hash_async);
559+
}
560+
548561
#[cfg(all(feature = "blocking", any(feature = "async", feature = "async-https")))]
549562
#[tokio::test]
550563
async fn test_get_txid_at_block_index() {

0 commit comments

Comments
 (0)