@@ -2,13 +2,12 @@ use alloc::sync::Arc;
22use alloc:: vec:: Vec ;
33use core:: fmt;
44
5+ use bitcoin:: { psbt, OutPoint , Sequence , Transaction , TxOut , Txid } ;
6+ use miniscript:: { bitcoin, plan:: Plan } ;
7+
58use crate :: {
6- collections:: HashMap , input:: CoinbaseMismatch , CPFPError , CPFPSet , FromPsbtInputError , Input ,
7- RbfSet , TxStatus ,
9+ collections:: HashMap , input:: CoinbaseMismatch , FromPsbtInputError , Input , RbfSet , TxStatus ,
810} ;
9- use bdk_chain:: TxGraph ;
10- use bitcoin:: { psbt, Amount , OutPoint , Sequence , Transaction , TxOut , Txid , Weight } ;
11- use miniscript:: { bitcoin, plan:: Plan } ;
1211
1312/// Tx with confirmation status.
1413pub type TxWithStatus < T > = ( T , Option < TxStatus > ) ;
@@ -21,22 +20,6 @@ pub struct CanonicalUnspents {
2120 spends : HashMap < OutPoint , Txid > ,
2221}
2322
24- fn select_upper_middle_output ( candidates : & [ ( OutPoint , & TxOut ) ] ) -> OutPoint {
25- let len = candidates. len ( ) ;
26-
27- let index = match len {
28- 1 ..=2 => len - 1 , // select the largest for small sets
29- 3 ..=5 => len - 2 , // select second largest for medium sets
30- _ => {
31- let upper_third_start = ( len * 2 ) / 3 ;
32- let upper_third_end = len - 1 ;
33- ( upper_third_start + upper_third_end) / 2
34- }
35- } ;
36-
37- candidates[ index] . 0
38- }
39-
4023impl CanonicalUnspents {
4124 /// Construct [`CanonicalUnspents`] from an iterator of txs with confirmation status.
4225 pub fn new < T > ( canonical_txs : impl IntoIterator < Item = TxWithStatus < T > > ) -> Self
@@ -143,83 +126,6 @@ impl CanonicalUnspents {
143126 )
144127 }
145128
146- /// Constructs a '[CPFPSet]' from a set of parent transaction IDs.
147- pub fn build_cpfp_set_from_txids < F > (
148- & self ,
149- parent_txids : impl IntoIterator < Item = Txid > ,
150- graph : & TxGraph ,
151- ownership_check : F ,
152- ) -> Result < CPFPSet , CPFPError >
153- where
154- F : Fn ( OutPoint ) -> bool + Clone ,
155- {
156- let parent_txids: Vec < Txid > = parent_txids. into_iter ( ) . collect ( ) ;
157-
158- const MAX_ANCESTORS : usize = 25 ;
159- if parent_txids. len ( ) > MAX_ANCESTORS {
160- return Err ( CPFPError :: ExcessUnconfirmedAncestor ) ;
161- }
162-
163- let ( parent_weight, parent_fee, selected_outpoints) = parent_txids. iter ( ) . try_fold (
164- ( Weight :: ZERO , Amount :: ZERO , Vec :: new ( ) ) ,
165- |( mut weight, mut fee, mut outpoints) , txid| -> Result < _ , CPFPError > {
166- let tx = self . get_tx ( txid) . ok_or ( CPFPError :: MissingParent ( * txid) ) ?;
167-
168- weight += tx. weight ( ) ;
169- fee += graph. calculate_fee ( tx) ?;
170-
171- let selected_outpoint =
172- self . select_owned_unspent_output ( tx. clone ( ) , ownership_check. clone ( ) ) ?;
173- outpoints. push ( selected_outpoint) ;
174-
175- Ok ( ( weight, fee, outpoints) )
176- } ,
177- ) ?;
178-
179- Ok ( CPFPSet :: new ( parent_fee, parent_weight, selected_outpoints) )
180- }
181-
182- /// Selects the unspent output from a given transaction
183- pub fn select_owned_unspent_output < F > (
184- & self ,
185- tx : Arc < Transaction > ,
186- ownership_check : F ,
187- ) -> Result < OutPoint , CPFPError >
188- where
189- F : Fn ( OutPoint ) -> bool ,
190- {
191- let txid = tx. compute_txid ( ) ;
192- let mut candidates: Vec < _ > = tx
193- . output
194- . iter ( )
195- . enumerate ( )
196- . map ( |( vout, txout) | {
197- (
198- OutPoint {
199- txid,
200- vout : vout as u32 ,
201- } ,
202- txout,
203- )
204- } )
205- . filter ( |( op, tx_out) | {
206- // Must be unspent, owned and above dust threshold
207- self . is_unspent ( * op)
208- && ownership_check ( * op)
209- && tx_out. value >= tx_out. script_pubkey . minimal_non_dust ( )
210- } )
211- . collect ( ) ;
212-
213- if candidates. is_empty ( ) {
214- return Err ( CPFPError :: NoUnspentOutput ( txid) ) ;
215- }
216-
217- candidates. sort_by_key ( |( _, txout) | txout. value ) ;
218- let selected_outpoint = select_upper_middle_output ( & candidates) ;
219-
220- Ok ( selected_outpoint)
221- }
222-
223129 /// Whether outpoint is a leaf (unspent).
224130 pub fn is_unspent ( & self , outpoint : OutPoint ) -> bool {
225131 if self . spends . contains_key ( & outpoint) {
@@ -323,6 +229,11 @@ impl CanonicalUnspents {
323229 pub fn get_tx ( & self , txid : & Txid ) -> Option < & Arc < Transaction > > {
324230 self . txs . get ( txid)
325231 }
232+
233+ /// Retrieves a status by its transaction ID.
234+ pub fn get_status ( & self , txid : & Txid ) -> Option < & TxStatus > {
235+ self . statuses . get ( txid)
236+ }
326237}
327238
328239/// Canonical unspents error
0 commit comments