/*! This models a how a sync happens where you have a server that you send your script pubkeys to and it returns associated transactions i.e. electrum. */ #![allow(dead_code)] use crate::{ database::{BatchDatabase, BatchOperations, DatabaseUtils}, ConfirmationTime, Error, KeychainKind, LocalUtxo, TransactionDetails, }; use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid}; use std::collections::{HashMap, HashSet, VecDeque}; /// A reqeust for on-chain information pub enum Request<'a, D: BatchDatabase> { /// A request for transactions related to script pubkeys. Script(ScriptReq<'a, D>), /// A request for confirmation times for some transactions. Conftime(ConftimeReq<'a, D>), /// A request for full transaction details of some transactions. Tx(TxReq<'a, D>), /// Requests are finished here's a batch database update to reflect data gathered. Finish(D::Batch), } /// starts a sync pub fn start(db: &D, stop_gap: usize) -> Result, Error> { use rand::seq::SliceRandom; let mut keychains = vec![KeychainKind::Internal, KeychainKind::External]; // shuffling improve privacy, the server doesn't know my first request is from my internal or external addresses keychains.shuffle(&mut rand::thread_rng()); let keychain = keychains.pop().unwrap(); let scripts_needed = db .iter_script_pubkeys(Some(keychain))? .into_iter() .collect(); let state = State { db, last_active_index: HashMap::default(), conftime_needed: VecDeque::default(), observed_txs: vec![], tx_needed: VecDeque::default(), tx_missing_conftime: HashMap::default(), }; Ok(Request::Script(ScriptReq { state, scripts_needed, script_index: 0, stop_gap, keychain, next_keychains: keychains, tx_interested: HashSet::default(), tx_conftime_interested: HashSet::default(), })) } pub struct ScriptReq<'a, D: BatchDatabase> { state: State<'a, D>, script_index: usize, scripts_needed: VecDeque