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-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-05-03 16:15:11 +02:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum Capability {
|
|
|
|
FullHistory,
|
|
|
|
GetAnyTx,
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
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-07-15 18:49:24 +02:00
|
|
|
fn setup<D: BatchDatabase + DatabaseUtils, P: Progress>(
|
2020-05-03 16:15:11 +02:00
|
|
|
&mut self,
|
|
|
|
stop_gap: Option<usize>,
|
|
|
|
database: &mut D,
|
|
|
|
progress_update: P,
|
|
|
|
) -> Result<(), Error>;
|
2020-07-15 18:49:24 +02:00
|
|
|
fn sync<D: BatchDatabase + DatabaseUtils, P: Progress>(
|
2020-05-03 16:15:11 +02:00
|
|
|
&mut self,
|
|
|
|
stop_gap: Option<usize>,
|
|
|
|
database: &mut D,
|
|
|
|
progress_update: P,
|
|
|
|
) -> Result<(), Error> {
|
2020-07-15 18:49:24 +02:00
|
|
|
self.setup(stop_gap, database, progress_update)
|
2020-05-03 16:15:11 +02:00
|
|
|
}
|
|
|
|
|
2020-07-15 18:49:24 +02:00
|
|
|
fn get_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error>;
|
|
|
|
fn broadcast(&mut self, tx: &Transaction) -> Result<(), Error>;
|
2020-05-03 16:15:11 +02:00
|
|
|
|
2020-07-15 18:49:24 +02:00
|
|
|
fn get_height(&mut self) -> Result<usize, Error>;
|
2020-05-03 16:15:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type ProgressData = (f32, Option<String>);
|
|
|
|
|
|
|
|
pub trait Progress {
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct NoopProgress;
|
|
|
|
|
|
|
|
pub fn noop_progress() -> NoopProgress {
|
|
|
|
NoopProgress
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Progress for NoopProgress {
|
|
|
|
fn update(&self, _progress: f32, _message: Option<String>) -> Result<(), Error> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|