Skip to content

Commit d21043e

Browse files
committed
fix(api)!: re-add BlockSummary and get_blocks
Add `BlockSummary` and `get_blocks` with a deprecation warning. These should be removed for the v0.14.0 release.
1 parent 3968952 commit d21043e

4 files changed

Lines changed: 111 additions & 11 deletions

File tree

src/api.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ pub use bitcoin::consensus::{deserialize, serialize};
2626
pub use bitcoin::hex::FromHex;
2727
pub use bitcoin::{
2828
absolute, block, transaction, Address, Amount, Block, BlockHash, CompactTarget, FeeRate,
29-
OutPoint, Script, ScriptBuf, ScriptHash, Transaction, TxIn, TxOut, Txid, Weight, Witness,
30-
Wtxid,
29+
OutPoint, Script, ScriptBuf, ScriptHash, Transaction, TxIn, TxMerkleNode, TxOut, Txid, Weight,
30+
Witness, Wtxid,
3131
};
3232

3333
// ----> TRANSACTION
@@ -219,6 +219,15 @@ pub struct OutputStatus {
219219

220220
// ----> BLOCK
221221

222+
/// The timestamp and height of a [`Block`].
223+
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
224+
pub struct BlockTime {
225+
/// The [`Block`]'s timestamp.
226+
pub timestamp: u64,
227+
/// The [`Block`]'s height.
228+
pub height: u32,
229+
}
230+
222231
/// The status of a [`Block`].
223232
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
224233
pub struct BlockStatus {
@@ -231,6 +240,22 @@ pub struct BlockStatus {
231240
pub next_best: Option<BlockHash>,
232241
}
233242

243+
// TODO(@luisschwab): remove on `v0.14.0`
244+
/// Summary about a [`Block`].
245+
#[deprecated(since = "0.12.3", note = "use `BlockInfo` instead")]
246+
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
247+
pub struct BlockSummary {
248+
/// The [`Block`]'s hash.
249+
pub id: BlockHash,
250+
/// The [`Block`]'s timestamp and height.
251+
#[serde(flatten)]
252+
pub time: BlockTime,
253+
/// The [`BlockHash`] of the previous [`Block`] (`None` for the genesis [`Block`]).
254+
pub previousblockhash: Option<BlockHash>,
255+
/// The Merkle root of the [`Block`]'s [`Transaction`]s.
256+
pub merkle_root: TxMerkleNode,
257+
}
258+
234259
/// A summary of a bitcoin [`Block`].
235260
///
236261
/// Contains block metadata as returned by the Esplora API, but not the
@@ -292,15 +317,6 @@ impl PartialEq for BlockInfo {
292317
}
293318
impl Eq for BlockInfo {}
294319

295-
/// The timestamp and height of a [`Block`].
296-
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
297-
pub struct BlockTime {
298-
/// The [`Block`]'s timestamp.
299-
pub timestamp: u64,
300-
/// The [`Block`]'s height.
301-
pub height: u32,
302-
}
303-
304320
// ----> ADDRESS
305321

306322
/// Statistics about an [`Address`].

src/async.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ use crate::{
4747
SubmitPackageResult, TxStatus, Utxo, BASE_BACKOFF_MILLIS, RETRYABLE_ERROR_CODES,
4848
};
4949

50+
// TODO(@luisschwab): remove on `v0.14.0`
51+
#[allow(deprecated)]
52+
use crate::BlockSummary;
53+
5054
/// Returns `true` if the given HTTP status code should trigger a retry.
5155
///
5256
/// See [`RETRYABLE_ERROR_CODES`] for the list of retryable status codes.
@@ -564,6 +568,26 @@ impl<S: Sleeper> AsyncClient<S> {
564568
.await
565569
}
566570

571+
// TODO(@luisschwab): remove on `v0.14.0`
572+
/// Gets some recent block summaries starting at the tip or at `height` if
573+
/// provided.
574+
///
575+
/// The maximum number of summaries returned depends on the backend itself:
576+
/// esplora returns `10` while [mempool.space](https://mempool.space/docs/api) returns `15`.
577+
#[allow(deprecated)]
578+
#[deprecated(since = "0.12.3", note = "use `get_block_infos` instead")]
579+
pub async fn get_blocks(&self, height: Option<u32>) -> Result<Vec<BlockSummary>, Error> {
580+
let path = match height {
581+
Some(height) => format!("/blocks/{height}"),
582+
None => "/blocks".to_string(),
583+
};
584+
let blocks: Vec<BlockSummary> = self.get_response_json(&path).await?;
585+
if blocks.is_empty() {
586+
return Err(Error::InvalidResponse);
587+
}
588+
Ok(blocks)
589+
}
590+
567591
/// Get a [`BlockInfo`] summary for the [`Block`] with the given [`BlockHash`].
568592
///
569593
/// [`BlockInfo`] includes metadata such as the height, timestamp,

src/blocking.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ use crate::{
4444
TxStatus, Utxo, BASE_BACKOFF_MILLIS, RETRYABLE_ERROR_CODES,
4545
};
4646

47+
// TODO(@luisschwab): remove on `v0.14.0`
48+
#[allow(deprecated)]
49+
use crate::BlockSummary;
50+
4751
/// Returns `true` if the given HTTP status code indicates a successful response.
4852
fn is_status_ok(status: i32) -> bool {
4953
status == 200
@@ -554,6 +558,26 @@ impl BlockingClient {
554558
self.get_response_json(&format!("/block/{block_hash}/status"))
555559
}
556560

561+
// TODO(@luisschwab): remove on `v0.14.0`
562+
/// Gets some recent block summaries starting at the tip or at `height` if
563+
/// provided.
564+
///
565+
/// The maximum number of summaries returned depends on the backend itself:
566+
/// esplora returns `10` while [mempool.space](https://mempool.space/docs/api) returns `15`.
567+
#[allow(deprecated)]
568+
#[deprecated(since = "0.12.3", note = "use `get_block_infos` instead")]
569+
pub fn get_blocks(&self, height: Option<u32>) -> Result<Vec<BlockSummary>, Error> {
570+
let path = match height {
571+
Some(height) => format!("/blocks/{height}"),
572+
None => "/blocks".to_string(),
573+
};
574+
let blocks: Vec<BlockSummary> = self.get_response_json(&path)?;
575+
if blocks.is_empty() {
576+
return Err(Error::InvalidResponse);
577+
}
578+
Ok(blocks)
579+
}
580+
557581
/// Get a [`BlockInfo`] summary for the [`Block`] with the given [`BlockHash`].
558582
///
559583
/// [`BlockInfo`] includes metadata such as the height, timestamp,

src/lib.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,42 @@ mod test {
767767
assert_eq!(expected, block_status_async);
768768
}
769769

770+
// TODO(@luisschwab): remove on `v0.14.0`
771+
#[allow(deprecated)]
772+
#[cfg(all(feature = "blocking", feature = "async"))]
773+
#[tokio::test]
774+
async fn test_get_blocks() {
775+
let env = TestEnv::new();
776+
let (blocking_client, async_client) = env.setup_clients();
777+
778+
let start_height = env.bitcoind_client().get_block_count().unwrap().0;
779+
let blocks1 = blocking_client.get_blocks(None).unwrap();
780+
let blocks_async1 = async_client.get_blocks(None).await.unwrap();
781+
assert_eq!(blocks1[0].time.height, start_height as u32);
782+
assert_eq!(blocks1, blocks_async1);
783+
env.mine_and_wait(1);
784+
785+
let blocks2 = blocking_client.get_blocks(None).unwrap();
786+
let blocks_async2 = async_client.get_blocks(None).await.unwrap();
787+
assert_eq!(blocks2, blocks_async2);
788+
assert_ne!(blocks2, blocks1);
789+
790+
let blocks3 = blocking_client
791+
.get_blocks(Some(start_height as u32))
792+
.unwrap();
793+
let blocks_async3 = async_client
794+
.get_blocks(Some(start_height as u32))
795+
.await
796+
.unwrap();
797+
assert_eq!(blocks3, blocks_async3);
798+
assert_eq!(blocks3[0].time.height, start_height as u32);
799+
assert_eq!(blocks3, blocks1);
800+
801+
let blocks_genesis = blocking_client.get_blocks(Some(0)).unwrap();
802+
let blocks_genesis_async = async_client.get_blocks(Some(0)).await.unwrap();
803+
assert_eq!(blocks_genesis, blocks_genesis_async);
804+
}
805+
770806
#[cfg(all(feature = "blocking", feature = "async"))]
771807
#[tokio::test]
772808
async fn test_get_block_by_hash() {

0 commit comments

Comments
 (0)