[bdk_chain_redesign] Add balance methods to IndexedTxGraph

This commit is contained in:
志宇
2023-03-27 19:55:57 +08:00
parent d0a2aa83be
commit db7883d813
2 changed files with 104 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ use alloc::collections::BTreeSet;
use bitcoin::{OutPoint, Transaction, TxOut};
use crate::{
keychain::Balance,
sparse_chain::ChainPosition,
tx_graph::{Additions, TxGraph, TxInGraph},
BlockAnchor, ChainOracle, FullTxOut, ObservedIn, TxIndex, TxIndexAdditions,
@@ -260,4 +261,86 @@ impl<A: BlockAnchor, I: TxIndex> IndexedTxGraph<A, I> {
self.try_list_chain_utxos(chain)
.map(|r| r.expect("error is infallible"))
}
pub fn try_balance<C, F>(
&self,
chain: C,
tip: u32,
mut should_trust: F,
) -> Result<Balance, C::Error>
where
C: ChainOracle,
ObservedIn<A>: ChainPosition + Clone,
F: FnMut(&I::SpkIndex) -> bool,
{
let mut immature = 0;
let mut trusted_pending = 0;
let mut untrusted_pending = 0;
let mut confirmed = 0;
for res in self.try_list_chain_txouts(&chain) {
let TxOutInChain { spk_index, txout } = res?;
let txout = txout.into_owned();
match &txout.chain_position {
ObservedIn::Block(_) => {
if txout.is_on_coinbase {
if txout.is_mature(tip) {
confirmed += txout.txout.value;
} else {
immature += txout.txout.value;
}
}
}
ObservedIn::Mempool(_) => {
if should_trust(spk_index) {
trusted_pending += txout.txout.value;
} else {
untrusted_pending += txout.txout.value;
}
}
}
}
Ok(Balance {
immature,
trusted_pending,
untrusted_pending,
confirmed,
})
}
pub fn balance<C, F>(&self, chain: C, tip: u32, should_trust: F) -> Balance
where
C: ChainOracle<Error = Infallible>,
ObservedIn<A>: ChainPosition + Clone,
F: FnMut(&I::SpkIndex) -> bool,
{
self.try_balance(chain, tip, should_trust)
.expect("error is infallible")
}
pub fn try_balance_at<C>(&self, chain: C, height: u32) -> Result<u64, C::Error>
where
C: ChainOracle,
ObservedIn<A>: ChainPosition + Clone,
{
let mut sum = 0;
for res in self.try_list_chain_txouts(chain) {
let txo = res?.txout.into_owned();
if txo.is_spendable_at(height) {
sum += txo.txout.value;
}
}
Ok(sum)
}
pub fn balance_at<C>(&self, chain: C, height: u32) -> u64
where
C: ChainOracle<Error = Infallible>,
ObservedIn<A>: ChainPosition + Clone,
{
self.try_balance_at(chain, height)
.expect("error is infallible")
}
}