@@ -15,11 +15,13 @@ mod branch_and_bound;
1515mod coin_grinder;
1616mod single_random_draw;
1717
18+ mod weighted_utxo;
19+
20+ pub use crate :: weighted_utxo:: WeightedUtxo ;
21+
1822/// Possible returned error types if no match is found.
1923pub mod errors;
2024
21- use std:: cmp:: Ordering ;
22-
2325use bitcoin_units:: { Amount , FeeRate , SignedAmount , Weight } ;
2426#[ cfg( feature = "rand" ) ]
2527#[ cfg_attr( docsrs, doc( cfg( feature = "rand" ) ) ) ]
@@ -60,82 +62,6 @@ pub(crate) fn effective_value(
6062 Some ( eff_value)
6163}
6264
63- #[ derive( Debug , Clone , PartialEq , Eq ) ]
64- /// Represents the spendable conditions of a `UTXO`.
65- pub struct WeightedUtxo {
66- /// The `Amount` that the output contributes towards the selection target.
67- value : Amount ,
68- /// The estimated `Weight` (satisfaction weight + base weight) of the output.
69- weight : Weight ,
70- /// The positive effective value `(value - fee)`. This value is stored as a `u64` for
71- /// better performance.
72- effective_value : u64 ,
73- /// The `SignedAmount` required to spend the output at the given `fee_rate`.
74- fee : SignedAmount ,
75- /// The `SignedAmount` required to spend the output at the given `long_term_fee_rate`.
76- long_term_fee : SignedAmount ,
77- /// A metric for how wasteful it is to spend this `WeightedUtxo` given the current fee
78- /// environment.
79- waste : i64 ,
80- }
81-
82- impl WeightedUtxo {
83- /// Creates a new `WeightedUtxo`.
84- pub fn new (
85- value : Amount ,
86- weight : Weight ,
87- fee_rate : FeeRate ,
88- long_term_fee_rate : FeeRate ,
89- ) -> Option < WeightedUtxo > {
90- let positive_effective_value = Self :: positive_effective_value ( fee_rate, weight, value) ;
91-
92- if let Some ( effective_value) = positive_effective_value {
93- let fee = fee_rate. fee_wu ( weight) ?. to_signed ( ) ;
94- let long_term_fee: SignedAmount = long_term_fee_rate. fee_wu ( weight) ?. to_signed ( ) ;
95- let waste = Self :: calculate_waste_score ( fee, long_term_fee) ;
96- return Some ( Self { value, weight, effective_value, fee, long_term_fee, waste } ) ;
97- }
98-
99- None
100- }
101-
102- /// Calculates if the current fee environment is expensive.
103- pub fn is_fee_expensive ( & self ) -> bool { self . fee > self . long_term_fee }
104-
105- /// Returns the associated value.
106- pub fn value ( & self ) -> Amount { self . value }
107-
108- /// Returns the associated weight.
109- pub fn weight ( & self ) -> Weight { self . weight }
110-
111- /// Returns the calculated effective value.
112- pub fn effective_value ( & self ) -> Amount { Amount :: from_sat ( self . effective_value ) . unwrap ( ) }
113-
114- fn positive_effective_value ( fee_rate : FeeRate , weight : Weight , value : Amount ) -> Option < u64 > {
115- if let Some ( eff_value) = effective_value ( fee_rate, weight, value) {
116- if let Ok ( unsigned) = eff_value. to_unsigned ( ) {
117- return Some ( unsigned. to_sat ( ) ) ;
118- }
119- }
120-
121- None
122- }
123-
124- fn calculate_waste_score ( fee : SignedAmount , long_term_fee : SignedAmount ) -> i64 {
125- fee. to_sat ( ) - long_term_fee. to_sat ( )
126- }
127- }
128-
129- impl Ord for WeightedUtxo {
130- fn cmp ( & self , other : & Self ) -> Ordering {
131- other. effective_value . cmp ( & self . effective_value ) . then ( self . weight . cmp ( & other. weight ) )
132- }
133- }
134-
135- impl PartialOrd for WeightedUtxo {
136- fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > { Some ( self . cmp ( other) ) }
137- }
138-
13965/// Attempt a match with [`branch_and_bound`] falling back to [`single_random_draw`].
14066///
14167/// If [`branch_and_bound`] fails to find a changeless solution (basically, an exact match), then
0 commit comments