2020-05-03 16:15:11 +02:00
|
|
|
use std::collections::HashSet;
|
|
|
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
|
|
|
|
|
|
|
use bitcoin::{Transaction, Txid};
|
|
|
|
|
|
|
|
use crate::database::{BatchDatabase, DatabaseUtils};
|
|
|
|
use crate::error::Error;
|
2020-08-07 11:23:01 +02:00
|
|
|
use crate::FeeRate;
|
2020-05-03 16:15:11 +02:00
|
|
|
|
2020-05-07 15:14:05 +02:00
|
|
|
pub mod utils;
|
|
|
|
|
2020-05-03 16:15:11 +02:00
|
|
|
#[cfg(feature = "electrum")]
|
|
|
|
pub mod electrum;
|
|
|
|
#[cfg(feature = "electrum")]
|
|
|
|
pub use self::electrum::ElectrumBlockchain;
|
|
|
|
|
2020-05-07 15:14:05 +02:00
|
|
|
#[cfg(feature = "esplora")]
|
|
|
|
pub mod esplora;
|
|
|
|
#[cfg(feature = "esplora")]
|
|
|
|
pub use self::esplora::EsploraBlockchain;
|
|
|
|
|
2020-08-25 16:07:26 +02:00
|
|
|
#[cfg(feature = "compact_filters")]
|
|
|
|
pub mod compact_filters;
|
|
|
|
|
2020-05-03 16:15:11 +02:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum Capability {
|
|
|
|
FullHistory,
|
|
|
|
GetAnyTx,
|
2020-08-25 16:07:26 +02:00
|
|
|
AccurateFees,
|
2020-05-03 16:15:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait Blockchain {
|
2020-05-06 17:17:14 +02:00
|
|
|
fn is_online(&self) -> bool;
|
|
|
|
|
2020-05-03 16:15:11 +02:00
|
|
|
fn offline() -> Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct OfflineBlockchain;
|
|
|
|
impl Blockchain for OfflineBlockchain {
|
|
|
|
fn offline() -> Self {
|
|
|
|
OfflineBlockchain
|
|
|
|
}
|
2020-05-06 17:17:14 +02:00
|
|
|
|
|
|
|
fn is_online(&self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
2020-05-03 16:15:11 +02:00
|
|
|
}
|
|
|
|
|
2020-07-20 15:51:57 +02:00
|
|
|
#[maybe_async]
|
2020-05-03 16:15:11 +02:00
|
|
|
pub trait OnlineBlockchain: Blockchain {
|
2020-07-15 18:49:24 +02:00
|
|
|
fn get_capabilities(&self) -> HashSet<Capability>;
|
2020-05-03 16:15:11 +02:00
|
|
|
|
2020-08-25 16:07:26 +02:00
|
|
|
fn setup<D: BatchDatabase + DatabaseUtils, P: 'static + Progress>(
|
2020-08-06 10:44:40 +02:00
|
|
|
&self,
|
2020-05-03 16:15:11 +02:00
|
|
|
stop_gap: Option<usize>,
|
|
|
|
database: &mut D,
|
|
|
|
progress_update: P,
|
|
|
|
) -> Result<(), Error>;
|
2020-08-25 16:07:26 +02:00
|
|
|
fn sync<D: BatchDatabase + DatabaseUtils, P: 'static + Progress>(
|
2020-08-06 10:44:40 +02:00
|
|
|
&self,
|
2020-05-03 16:15:11 +02:00
|
|
|
stop_gap: Option<usize>,
|
|
|
|
database: &mut D,
|
|
|
|
progress_update: P,
|
|
|
|
) -> Result<(), Error> {
|
2020-07-20 15:51:57 +02:00
|
|
|
maybe_await!(self.setup(stop_gap, database, progress_update))
|
2020-05-03 16:15:11 +02:00
|
|
|
}
|
|
|
|
|
2020-08-06 10:44:40 +02:00
|
|
|
fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
|
|
|
|
fn broadcast(&self, tx: &Transaction) -> Result<(), Error>;
|
2020-05-03 16:15:11 +02:00
|
|
|
|
2020-08-08 12:06:40 +02:00
|
|
|
fn get_height(&self) -> Result<u32, Error>;
|
2020-08-07 11:23:01 +02:00
|
|
|
fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error>;
|
2020-05-03 16:15:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type ProgressData = (f32, Option<String>);
|
|
|
|
|
2020-08-25 16:07:26 +02:00
|
|
|
pub trait Progress: Send {
|
2020-05-03 16:15:11 +02:00
|
|
|
fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn progress() -> (Sender<ProgressData>, Receiver<ProgressData>) {
|
|
|
|
channel()
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Progress for Sender<ProgressData> {
|
|
|
|
fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error> {
|
|
|
|
if progress < 0.0 || progress > 100.0 {
|
|
|
|
return Err(Error::InvalidProgressValue(progress));
|
|
|
|
}
|
|
|
|
|
|
|
|
self.send((progress, message))
|
|
|
|
.map_err(|_| Error::ProgressUpdateError)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-25 16:07:26 +02:00
|
|
|
#[derive(Clone)]
|
2020-05-03 16:15:11 +02:00
|
|
|
pub struct NoopProgress;
|
|
|
|
|
|
|
|
pub fn noop_progress() -> NoopProgress {
|
|
|
|
NoopProgress
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Progress for NoopProgress {
|
|
|
|
fn update(&self, _progress: f32, _message: Option<String>) -> Result<(), Error> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
2020-08-25 16:07:26 +02:00
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct LogProgress;
|
|
|
|
|
|
|
|
pub fn log_progress() -> LogProgress {
|
|
|
|
LogProgress
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Progress for LogProgress {
|
|
|
|
fn update(&self, progress: f32, message: Option<String>) -> Result<(), Error> {
|
|
|
|
log::info!("Sync {:.3}%: `{}`", progress, message.unwrap_or("".into()));
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|