Skip to content

Commit

Permalink
Add stop_gap param to electrum and esplora blockchain configs
Browse files Browse the repository at this point in the history
  • Loading branch information
notmandatory committed Jul 16, 2021
1 parent 77379e9 commit 7e986fd
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 39 deletions.
6 changes: 4 additions & 2 deletions src/blockchain/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ impl_from!(compact_filters::CompactFiltersBlockchain, AnyBlockchain, CompactFilt
/// r#"{
/// "type" : "electrum",
/// "url" : "ssl://electrum.blockstream.info:50002",
/// "retry": 2
/// "retry": 2,
/// "stop_gap": 20
/// }"#,
/// )
/// .unwrap();
Expand All @@ -198,7 +199,8 @@ impl_from!(compact_filters::CompactFiltersBlockchain, AnyBlockchain, CompactFilt
/// url: "ssl://electrum.blockstream.info:50002".into(),
/// retry: 2,
/// socks5: None,
/// timeout: None
/// timeout: None,
/// stop_gap: 20,
/// })
/// );
/// # }
Expand Down
34 changes: 21 additions & 13 deletions src/blockchain/electrum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,17 @@ use crate::FeeRate;
///
/// ## Example
/// See the [`blockchain::electrum`](crate::blockchain::electrum) module for a usage example.
pub struct ElectrumBlockchain(Client);
pub struct ElectrumBlockchain {
client: Client,
stop_gap: usize,
}

impl std::convert::From<Client> for ElectrumBlockchain {
fn from(client: Client) -> Self {
ElectrumBlockchain(client)
ElectrumBlockchain {
client,
stop_gap: 20,
}
}
}

Expand All @@ -64,34 +70,34 @@ impl Blockchain for ElectrumBlockchain {

fn setup<D: BatchDatabase, P: Progress>(
&self,
stop_gap: Option<usize>,
_stop_gap: Option<usize>,
database: &mut D,
progress_update: P,
) -> Result<(), Error> {
self.0
.electrum_like_setup(stop_gap, database, progress_update)
self.client
.electrum_like_setup(Some(self.stop_gap), database, progress_update)
}

fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
Ok(self.0.transaction_get(txid).map(Option::Some)?)
Ok(self.client.transaction_get(txid).map(Option::Some)?)
}

fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
Ok(self.0.transaction_broadcast(tx).map(|_| ())?)
Ok(self.client.transaction_broadcast(tx).map(|_| ())?)
}

fn get_height(&self) -> Result<u32, Error> {
// TODO: unsubscribe when added to the client, or is there a better call to use here?

Ok(self
.0
.client
.block_headers_subscribe()
.map(|data| data.height as u32)?)
}

fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
Ok(FeeRate::from_btc_per_kvb(
self.0.estimate_fee(target)? as f32
self.client.estimate_fee(target)? as f32
))
}
}
Expand Down Expand Up @@ -149,6 +155,8 @@ pub struct ElectrumBlockchainConfig {
pub retry: u8,
/// Request timeout (seconds)
pub timeout: Option<u8>,
/// Stop searching addresses for transactions after finding an unused gap of this length
pub stop_gap: usize,
}

impl ConfigurableBlockchain for ElectrumBlockchain {
Expand All @@ -162,10 +170,10 @@ impl ConfigurableBlockchain for ElectrumBlockchain {
.socks5(socks5)?
.build();

Ok(ElectrumBlockchain(Client::from_config(
config.url.as_str(),
electrum_config,
)?))
Ok(ElectrumBlockchain {
client: Client::from_config(config.url.as_str(), electrum_config)?,
stop_gap: config.stop_gap,
})
}
}

Expand Down
58 changes: 34 additions & 24 deletions src/blockchain/esplora.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,25 @@
use std::collections::{HashMap, HashSet};
use std::fmt;

use futures::stream::{self, FuturesOrdered, StreamExt, TryStreamExt};

#[allow(unused_imports)]
use log::{debug, error, info, trace};

use serde::Deserialize;

use reqwest::{Client, StatusCode};

use bitcoin::consensus::{self, deserialize, serialize};
use bitcoin::hashes::hex::{FromHex, ToHex};
use bitcoin::hashes::{sha256, Hash};
use bitcoin::{BlockHash, BlockHeader, Script, Transaction, Txid};
use futures::stream::{self, FuturesOrdered, StreamExt, TryStreamExt};
#[allow(unused_imports)]
use log::{debug, error, info, trace};
use reqwest::{Client, StatusCode};
use serde::Deserialize;

use self::utils::{ElectrumLikeSync, ElsGetHistoryRes};
use super::*;
use crate::database::BatchDatabase;
use crate::error::Error;
use crate::wallet::utils::ChunksIterator;
use crate::FeeRate;

use super::*;

use self::utils::{ElectrumLikeSync, ElsGetHistoryRes};

const DEFAULT_CONCURRENT_REQUESTS: u8 = 4;

#[derive(Debug)]
Expand All @@ -62,22 +60,31 @@ struct UrlClient {
/// ## Example
/// See the [`blockchain::esplora`](crate::blockchain::esplora) module for a usage example.
#[derive(Debug)]
pub struct EsploraBlockchain(UrlClient);
pub struct EsploraBlockchain {
url_client: UrlClient,
stop_gap: usize,
}

impl std::convert::From<UrlClient> for EsploraBlockchain {
fn from(url_client: UrlClient) -> Self {
EsploraBlockchain(url_client)
EsploraBlockchain {
url_client,
stop_gap: 20,
}
}
}

impl EsploraBlockchain {
/// Create a new instance of the client from a base URL
pub fn new(base_url: &str, concurrency: Option<u8>) -> Self {
EsploraBlockchain(UrlClient {
url: base_url.to_string(),
client: Client::new(),
concurrency: concurrency.unwrap_or(DEFAULT_CONCURRENT_REQUESTS),
})
pub fn new(base_url: &str, concurrency: Option<u8>, stop_gap: usize) -> Self {
EsploraBlockchain {
url_client: UrlClient {
url: base_url.to_string(),
client: Client::new(),
concurrency: concurrency.unwrap_or(DEFAULT_CONCURRENT_REQUESTS),
},
stop_gap,
}
}
}

Expand All @@ -100,24 +107,24 @@ impl Blockchain for EsploraBlockchain {
progress_update: P,
) -> Result<(), Error> {
maybe_await!(self
.0
.url_client
.electrum_like_setup(stop_gap, database, progress_update))
}

fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
Ok(await_or_block!(self.0._get_tx(txid))?)
Ok(await_or_block!(self.url_client._get_tx(txid))?)
}

fn broadcast(&self, tx: &Transaction) -> Result<(), Error> {
Ok(await_or_block!(self.0._broadcast(tx))?)
Ok(await_or_block!(self.url_client._broadcast(tx))?)
}

fn get_height(&self) -> Result<u32, Error> {
Ok(await_or_block!(self.0._get_height())?)
Ok(await_or_block!(self.url_client._get_height())?)
}

fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
let estimates = await_or_block!(self.0._get_fee_estimates())?;
let estimates = await_or_block!(self.url_client._get_fee_estimates())?;

let fee_val = estimates
.into_iter()
Expand Down Expand Up @@ -369,6 +376,8 @@ pub struct EsploraBlockchainConfig {
pub base_url: String,
/// Number of parallel requests sent to the esplora service (default: 4)
pub concurrency: Option<u8>,
/// Stop searching addresses for transactions after finding an unused gap of this length
pub stop_gap: usize,
}

impl ConfigurableBlockchain for EsploraBlockchain {
Expand All @@ -378,6 +387,7 @@ impl ConfigurableBlockchain for EsploraBlockchain {
Ok(EsploraBlockchain::new(
config.base_url.as_str(),
config.concurrency,
config.stop_gap,
))
}
}
Expand Down

0 comments on commit 7e986fd

Please sign in to comment.