use brk_types::{Transaction, Txid, TxidPrefix, Vout};
use rustc_hash::{FxHashMap, FxHashSet};
use super::TxAddition;
use crate::stores::TxStore;
#[derive(Debug)]
pub enum TxRemoval {
Replaced { by: Txid },
Vanished,
}
type SpentBy = FxHashMap<(Txid, Vout), Txid>;
impl TxRemoval {
pub(super) fn classify(
live: &FxHashSet<TxidPrefix>,
added: &[TxAddition],
known: &TxStore,
) -> Vec<(TxidPrefix, Self)> {
let spent_by = Self::build_spent_by(added);
known
.records()
.filter_map(|(prefix, record)| {
if live.contains(prefix) {
return None;
}
Some((*prefix, Self::find_removal(&record.tx, &spent_by)))
})
.collect()
}
fn find_removal(tx: &Transaction, spent_by: &SpentBy) -> Self {
tx.input
.iter()
.find_map(|i| spent_by.get(&(i.txid, i.vout)).cloned())
.map_or(Self::Vanished, |by| Self::Replaced { by })
}
fn build_spent_by(added: &[TxAddition]) -> SpentBy {
let mut spent_by: SpentBy = FxHashMap::default();
for addition in added {
if let TxAddition::Fresh { tx, .. } = addition {
for txin in &tx.input {
spent_by.insert((txin.txid, txin.vout), tx.txid);
}
}
}
spent_by
}
}