@@ -6,11 +6,15 @@ use crate::{
6
6
/// Metric that aims to minimize transaction fees. The future fee for spending the change output is
7
7
/// included in this calculation.
8
8
///
9
- /// The scoring function for changeless solutions is:
10
- /// > input_weight * feerate + excess
9
+ /// The fee is simply:
11
10
///
12
- /// The scoring function for solutions with change:
13
- /// > (input_weight + change_output_weight) * feerate + change_spend_weight * long_term_feerate
11
+ /// > `inputs - outputs` where `outputs = target.value + change_value`
12
+ ///
13
+ /// But the total value includes the cost of spending the change output if it exists:
14
+ ///
15
+ /// > `change_spend_weight * long_term_feerate`
16
+ ///
17
+ /// The `change_spend_weight` and `change_value` are determined by the `change_policy`
14
18
#[ derive( Clone , Copy ) ]
15
19
pub struct LowestFee {
16
20
/// The target parameters for the resultant selection.
@@ -55,13 +59,19 @@ impl BnbMetric for LowestFee {
55
59
return None ;
56
60
}
57
61
58
- let drain_weights = if drain. is_some ( ) {
59
- Some ( drain. weights )
60
- } else {
61
- None
62
+ let long_term_fee = {
63
+ let fee_for_the_tx = cs. fee ( self . target . value , drain. value ) ;
64
+ assert ! (
65
+ fee_for_the_tx > 0 ,
66
+ "must not be called unless selection has met target"
67
+ ) ;
68
+ // Why `spend_fee` rounds up here. We could use floats but I felt it was just better to
69
+ // accept the extra 1 sat penality to having a change output
70
+ let fee_for_spending_drain = drain. weights . spend_fee ( self . long_term_feerate ) ;
71
+ fee_for_the_tx as u64 + fee_for_spending_drain
62
72
} ;
63
73
64
- Some ( Ordf32 ( self . calc_metric ( cs , drain_weights ) ) )
74
+ Some ( Ordf32 ( long_term_fee as f32 ) )
65
75
}
66
76
67
77
fn bound ( & mut self , cs : & CoinSelector < ' _ > ) -> Option < Ordf32 > {
0 commit comments