[bdk_chain_redesign] Add balance methods to IndexedTxGraph
				
					
				
			This commit is contained in:
		
							parent
							
								
									d0a2aa83be
								
							
						
					
					
						commit
						db7883d813
					
				| @ -14,6 +14,15 @@ pub enum ObservedIn<A> { | |||||||
|     Mempool(u64), |     Mempool(u64), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl<A: Clone> ObservedIn<&A> { | ||||||
|  |     pub fn into_owned(self) -> ObservedIn<A> { | ||||||
|  |         match self { | ||||||
|  |             ObservedIn::Block(a) => ObservedIn::Block(a.clone()), | ||||||
|  |             ObservedIn::Mempool(last_seen) => ObservedIn::Mempool(last_seen), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| impl ChainPosition for ObservedIn<BlockId> { | impl ChainPosition for ObservedIn<BlockId> { | ||||||
|     fn height(&self) -> TxHeight { |     fn height(&self) -> TxHeight { | ||||||
|         match self { |         match self { | ||||||
| @ -259,4 +268,16 @@ impl<I: ChainPosition> FullTxOut<I> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl<A: Clone> FullTxOut<ObservedIn<&A>> { | ||||||
|  |     pub fn into_owned(self) -> FullTxOut<ObservedIn<A>> { | ||||||
|  |         FullTxOut { | ||||||
|  |             outpoint: self.outpoint, | ||||||
|  |             txout: self.txout, | ||||||
|  |             chain_position: self.chain_position.into_owned(), | ||||||
|  |             spent_by: self.spent_by.map(|(o, txid)| (o.into_owned(), txid)), | ||||||
|  |             is_on_coinbase: self.is_on_coinbase, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // TODO: make test
 | // TODO: make test
 | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ use alloc::collections::BTreeSet; | |||||||
| use bitcoin::{OutPoint, Transaction, TxOut}; | use bitcoin::{OutPoint, Transaction, TxOut}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|  |     keychain::Balance, | ||||||
|     sparse_chain::ChainPosition, |     sparse_chain::ChainPosition, | ||||||
|     tx_graph::{Additions, TxGraph, TxInGraph}, |     tx_graph::{Additions, TxGraph, TxInGraph}, | ||||||
|     BlockAnchor, ChainOracle, FullTxOut, ObservedIn, TxIndex, TxIndexAdditions, |     BlockAnchor, ChainOracle, FullTxOut, ObservedIn, TxIndex, TxIndexAdditions, | ||||||
| @ -260,4 +261,86 @@ impl<A: BlockAnchor, I: TxIndex> IndexedTxGraph<A, I> { | |||||||
|         self.try_list_chain_utxos(chain) |         self.try_list_chain_utxos(chain) | ||||||
|             .map(|r| r.expect("error is infallible")) |             .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") | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user