use std::fmt::Display;
use bdk_wallet::{
chain::{CheckPoint, IndexedTxGraph},
Wallet,
};
pub use bip157::Builder;
use bip157::{chain::ChainState, HeaderCheckpoint};
use crate::{LightClient, ScanType, UpdateSubscriber};
const IMPOSSIBLE_REORG_DEPTH: usize = 7;
pub trait BuilderExt {
fn build_with_wallet(
self,
wallet: &Wallet,
scan_type: ScanType,
) -> Result<LightClient, BuilderError>;
}
impl BuilderExt for Builder {
fn build_with_wallet(
mut self,
wallet: &Wallet,
scan_type: ScanType,
) -> Result<LightClient, BuilderError> {
let network = wallet.network();
if self.network().ne(&network) {
return Err(BuilderError::NetworkMismatch);
}
match scan_type {
ScanType::Sync => {
let current_cp = wallet.latest_checkpoint();
let sync_start = walk_back_max_reorg(current_cp);
self = self.chain_state(ChainState::Checkpoint(sync_start));
}
ScanType::Recovery {
used_script_index: _,
checkpoint,
} => self = self.chain_state(ChainState::Checkpoint(checkpoint)),
}
let (node, client) = self.build();
let bip157::Client {
requester,
info_rx,
warn_rx,
event_rx,
} = client;
let indexed_graph = IndexedTxGraph::new(wallet.spk_index().clone());
let update_subscriber = UpdateSubscriber::new(
requester.clone(),
scan_type,
event_rx,
wallet.latest_checkpoint(),
indexed_graph,
);
Ok(LightClient {
requester,
info_subscriber: info_rx,
warning_subscriber: warn_rx,
update_subscriber,
node,
})
}
}
fn walk_back_max_reorg(checkpoint: CheckPoint) -> HeaderCheckpoint {
let mut ret_cp = HeaderCheckpoint::new(checkpoint.height(), checkpoint.hash());
let cp_iter = checkpoint.iter();
for (index, next) in cp_iter.enumerate() {
if index > IMPOSSIBLE_REORG_DEPTH {
return ret_cp;
}
ret_cp = HeaderCheckpoint::new(next.height(), next.hash());
}
ret_cp
}
#[derive(Debug)]
pub enum BuilderError {
NetworkMismatch,
}
impl Display for BuilderError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BuilderError::NetworkMismatch => {
write!(f, "wallet network and node network do not match")
}
}
}
}
impl std::error::Error for BuilderError {}