Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/status.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::time::Duration;
use block_dn_client::Timeout;

const ENDPOINT: block_dn_client::Endpoint<'static> = block_dn_client::Endpoint::BLOCK_DN_ORG;
const TIMEOUT: Duration = Duration::from_secs(2);
const TIMEOUT: Timeout = Timeout::from_seconds(2);

fn main() {
let mut client_builder = block_dn_client::Builder::new();
Expand Down
5 changes: 3 additions & 2 deletions examples/taproot.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use core::time::Duration;
use std::time::Instant;

use block_dn_client::Timeout;

const ENDPOINT: block_dn_client::Endpoint<'static> = block_dn_client::Endpoint::BLOCK_DN_ORG;
const TIMEOUT: Duration = Duration::from_secs(5);
const TIMEOUT: Timeout = Timeout::from_seconds(5);
const TAPROOT_ACTIVATION_HEIGHT: u32 = 700_000;

fn main() {
Expand Down
46 changes: 27 additions & 19 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! A Rust client for [`block-dn`](https://github.com/guggero/block-dn#).
#![warn(missing_docs)]
use core::time::Duration;
use std::{borrow::Cow, io::Cursor, net::SocketAddr};

use bitcoin::{Block, BlockHash, bip158::BlockFilter, block::Header, consensus::Decodable};
Expand Down Expand Up @@ -42,24 +41,41 @@ impl<'e> Endpoint<'e> {
}
}

/// The response timeout permitted.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Timeout(u64);

impl Timeout {
/// Build a timeout from number of seconds.
pub const fn from_seconds(seconds: u64) -> Self {
Self(seconds)
}
}

impl Default for Timeout {
fn default() -> Self {
Self(1)
}
}

/// Build a new client to query data for.
#[derive(Debug)]
pub struct Builder<'e> {
endpoint: Endpoint<'e>,
timeout: Duration,
timeout: Timeout,
}

impl<'e> Builder<'e> {
/// Create a new builder [`ClientBuilder`].
pub fn new() -> Self {
Self {
endpoint: Endpoint::BLOCK_DN_ORG,
timeout: Duration::from_secs(1),
timeout: Timeout::default(),
}
}

/// Set the timeout the server has to respond.
pub fn timeout(mut self, timeout: Duration) -> Self {
pub fn timeout(mut self, timeout: Timeout) -> Self {
self.timeout = timeout;
self
}
Expand Down Expand Up @@ -89,15 +105,15 @@ impl<'e> Default for Builder<'e> {
#[derive(Debug)]
pub struct Client<'e> {
endpoint: Endpoint<'e>,
timeout: Duration,
timeout: Timeout,
}

impl<'e> Client<'e> {
const EXPECTED_HEADER_LIST_SIZE: usize = 100_000;
/// Return the root HTML of the server.
pub fn index_html(&self) -> Result<Html, Error> {
let response = bitreq::get(self.endpoint.0.to_string())
.with_timeout(self.timeout.as_secs())
.with_timeout(self.timeout.0)
.send()?;
let html = response.as_str()?;
Ok(Html(html.to_string()))
Expand All @@ -106,7 +122,7 @@ impl<'e> Client<'e> {
/// Get the status of the server. See [`ServerStatus`] for the response structure.
pub fn status(&self) -> Result<ServerStatus, Error> {
let status = bitreq::get(self.endpoint.append_route("status"))
.with_timeout(self.timeout.as_secs())
.with_timeout(self.timeout.0)
.send()?;
Ok(status.json::<ServerStatus>()?)
}
Expand All @@ -116,9 +132,7 @@ impl<'e> Client<'e> {
let route = self
.endpoint
.append_route(format!("headers/{start_height}"));
let response = bitreq::get(route)
.with_timeout(self.timeout.as_secs())
.send()?;
let response = bitreq::get(route).with_timeout(self.timeout.0).send()?;
let mut headers = Vec::with_capacity(Self::EXPECTED_HEADER_LIST_SIZE * 80);
for chunk in response.as_bytes().chunks_exact(80) {
headers.push(bitcoin::consensus::deserialize::<Header>(chunk)?);
Expand All @@ -131,9 +145,7 @@ impl<'e> Client<'e> {
let route = self
.endpoint
.append_route(format!("filters/{start_height}"));
let response = bitreq::get(route)
.with_timeout(self.timeout.as_secs())
.send()?;
let response = bitreq::get(route).with_timeout(self.timeout.0).send()?;
let mut cursor = Cursor::new(response.into_bytes());
let mut filters = Vec::new();
while let Ok(bytes) = Vec::<u8>::consensus_decode_from_finite_reader(&mut cursor) {
Expand All @@ -147,18 +159,14 @@ impl<'e> Client<'e> {
let route = self
.endpoint
.append_route(format!("sp/tweak-data/{start_height}"));
let response = bitreq::get(route)
.with_timeout(self.timeout.as_secs())
.send()?;
let response = bitreq::get(route).with_timeout(self.timeout.0).send()?;
Ok(response.json::<TapTweaks>()?)
}

/// Fetch the block by its hash.
pub fn block(&self, block_hash: BlockHash) -> Result<Block, Error> {
let route = self.endpoint.append_route(format!("block/{block_hash}"));
let response = bitreq::get(route)
.with_timeout(self.timeout.as_secs())
.send()?;
let response = bitreq::get(route).with_timeout(self.timeout.0).send()?;
let block = bitcoin::consensus::deserialize::<Block>(response.as_bytes())?;
Ok(block)
}
Expand Down
6 changes: 2 additions & 4 deletions tests/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use block_dn_client::{Builder, Client};
use block_dn_client::{Builder, Client, Timeout};

fn default_client() -> Client<'static> {
Builder::default().build()
Expand Down Expand Up @@ -31,9 +31,7 @@ fn test_filters() {

#[test]
fn test_tap_tweaks() {
let client = Builder::new()
.timeout(core::time::Duration::from_secs(10))
.build();
let client = Builder::new().timeout(Timeout::from_seconds(10)).build();
let tweaks = client.tweaks(900_000).unwrap();
assert!(!tweaks.blocks.is_empty());
let _ = tweaks.fallible_into_iterator();
Expand Down
Loading