mod fetched;
pub use fetched::Fetched;
use brk_error::Result;
use brk_rpc::{Client, RawTx};
use brk_types::{MempoolEntryInfo, Txid};
use rustc_hash::{FxHashMap, FxHashSet};
use crate::stores::{TxGraveyard, TxStore};
const MAX_TX_FETCHES_PER_CYCLE: usize = 10_000;
pub struct Fetcher;
impl Fetcher {
pub fn fetch(client: &Client, known: &TxStore, graveyard: &TxGraveyard) -> Result<Fetched> {
let entries_info = client.get_raw_mempool_verbose()?;
let new_txids = Self::new_txids(&entries_info, known, graveyard);
let new_raws = client.get_raw_transactions(&new_txids)?;
let parent_txids = Self::unique_confirmed_parents(&new_raws, known);
let parent_raws = client.get_raw_transactions(&parent_txids)?;
Ok(Fetched {
entries_info,
new_raws,
parent_raws,
})
}
fn new_txids(
entries_info: &[MempoolEntryInfo],
known: &TxStore,
graveyard: &TxGraveyard,
) -> Vec<Txid> {
entries_info
.iter()
.filter(|info| !known.contains(&info.txid) && !graveyard.contains(&info.txid))
.take(MAX_TX_FETCHES_PER_CYCLE)
.map(|info| info.txid.clone())
.collect()
}
fn unique_confirmed_parents(new_raws: &FxHashMap<Txid, RawTx>, known: &TxStore) -> Vec<Txid> {
let mut set: FxHashSet<Txid> = FxHashSet::default();
for raw in new_raws.values() {
for txin in &raw.tx.input {
let prev: Txid = txin.previous_output.txid.into();
if !known.contains_key(&prev) && !new_raws.contains_key(&prev) {
set.insert(prev);
}
}
}
set.into_iter().collect()
}
}