@@ -1700,6 +1700,9 @@ pub(super) fn calculate_change_output_value(
17001700 }
17011701 }
17021702
1703+ let total_output_satoshis = funding_outputs. iter ( ) . fold ( 0u64 , |total, out| {
1704+ total. saturating_add ( out. value . to_sat ( ) )
1705+ } ) ;
17031706 let our_funding_outputs_weight = funding_outputs. iter ( ) . fold ( 0u64 , |weight, out| {
17041707 weight. saturating_add ( get_output_weight ( & out. script_pubkey ) . to_wu ( ) )
17051708 } ) ;
@@ -1715,12 +1718,14 @@ pub(super) fn calculate_change_output_value(
17151718 let fees_sats = fee_for_weight ( funding_feerate_sat_per_1000_weight, weight) ;
17161719 // Note: in case of additional outputs, they will have to be subtracted here
17171720
1718- let total_inputs_less_fees = total_input_satoshis. saturating_sub ( fees_sats) ;
1719- if total_inputs_less_fees < our_contribution {
1721+ let net_total_less_fees = total_input_satoshis
1722+ . saturating_sub ( total_output_satoshis)
1723+ . saturating_sub ( fees_sats) ;
1724+ if net_total_less_fees < our_contribution {
17201725 // Not enough to cover contribution plus fees
17211726 return Err ( AbortReason :: InsufficientFees ) ;
17221727 }
1723- let remaining_value = total_inputs_less_fees . saturating_sub ( our_contribution) ;
1728+ let remaining_value = net_total_less_fees . saturating_sub ( our_contribution) ;
17241729 if remaining_value < change_output_dust_limit {
17251730 // Enough to cover contribution plus fees, but leftover is below dust limit; no change
17261731 Ok ( None )
@@ -2596,16 +2601,15 @@ mod tests {
25962601 } )
25972602 . collect :: < Vec < ( TxIn , TransactionU16LenLimited ) > > ( ) ;
25982603 let our_contributed = 110_000 ;
2599- let txout = TxOut { value : Amount :: from_sat ( 128_000 ) , script_pubkey : ScriptBuf :: new ( ) } ;
2600- let _value = txout. value . to_sat ( ) ;
2601- // let outputs = OutputOwned::Shared(SharedOwnedOutput::new(txout, value))];
2602- let outputs = vec ! [ ] ;
2604+ let txout = TxOut { value : Amount :: from_sat ( 10_000 ) , script_pubkey : ScriptBuf :: new ( ) } ;
2605+ let outputs = vec ! [ txout] ;
26032606 let funding_feerate_sat_per_1000_weight = 3000 ;
26042607
26052608 let total_inputs: u64 = input_prevouts. iter ( ) . map ( |o| o. value . to_sat ( ) ) . sum ( ) ;
2606- let gross_change = total_inputs - our_contributed;
2607- let fees = 1638 ; // 1746 - 108;
2608- let common_fees = 234 ; // 126 + 108;
2609+ let total_outputs: u64 = outputs. iter ( ) . map ( |o| o. value . to_sat ( ) ) . sum ( ) ;
2610+ let gross_change = total_inputs - total_outputs - our_contributed;
2611+ let fees = 1746 ;
2612+ let common_fees = 234 ;
26092613 {
26102614 // There is leftover for change
26112615 let res = calculate_change_output_value (
@@ -2617,7 +2621,7 @@ mod tests {
26172621 funding_feerate_sat_per_1000_weight,
26182622 300 ,
26192623 ) ;
2620- assert_eq ! ( res. unwrap ( ) . unwrap ( ) , gross_change - fees - common_fees) ;
2624+ assert_eq ! ( res, Ok ( Some ( gross_change - fees - common_fees) ) ) ;
26212625 }
26222626 {
26232627 // There is leftover for change, without common fees
@@ -2630,7 +2634,7 @@ mod tests {
26302634 funding_feerate_sat_per_1000_weight,
26312635 300 ,
26322636 ) ;
2633- assert_eq ! ( res. unwrap ( ) . unwrap ( ) , gross_change - fees) ;
2637+ assert_eq ! ( res, Ok ( Some ( gross_change - fees) ) ) ;
26342638 }
26352639 {
26362640 // Larger fee, smaller change
@@ -2640,10 +2644,10 @@ mod tests {
26402644 & ScriptBuf :: new ( ) ,
26412645 & inputs,
26422646 & outputs,
2643- 9000 ,
2647+ funding_feerate_sat_per_1000_weight * 3 ,
26442648 300 ,
26452649 ) ;
2646- assert_eq ! ( res. unwrap ( ) . unwrap ( ) , 14384 ) ;
2650+ assert_eq ! ( res, Ok ( Some ( 4060 ) ) ) ;
26472651 }
26482652 {
26492653 // Insufficient inputs, no leftover
@@ -2656,33 +2660,33 @@ mod tests {
26562660 funding_feerate_sat_per_1000_weight,
26572661 300 ,
26582662 ) ;
2659- assert_eq ! ( res. err ( ) . unwrap ( ) , AbortReason :: InsufficientFees ) ;
2663+ assert_eq ! ( res, Err ( AbortReason :: InsufficientFees ) ) ;
26602664 }
26612665 {
26622666 // Very small leftover
26632667 let res = calculate_change_output_value (
26642668 false ,
2665- 128_100 ,
2669+ 118_000 ,
26662670 & ScriptBuf :: new ( ) ,
26672671 & inputs,
26682672 & outputs,
26692673 funding_feerate_sat_per_1000_weight,
26702674 300 ,
26712675 ) ;
2672- assert ! ( res. unwrap ( ) . is_none ( ) ) ;
2676+ assert_eq ! ( res, Ok ( None ) ) ;
26732677 }
26742678 {
26752679 // Small leftover, but not dust
26762680 let res = calculate_change_output_value (
26772681 false ,
2678- 128_100 ,
2682+ 117_992 ,
26792683 & ScriptBuf :: new ( ) ,
26802684 & inputs,
26812685 & outputs,
26822686 funding_feerate_sat_per_1000_weight,
26832687 100 ,
26842688 ) ;
2685- assert_eq ! ( res. unwrap ( ) . unwrap ( ) , 262 ) ;
2689+ assert_eq ! ( res, Ok ( Some ( 262 ) ) ) ;
26862690 }
26872691 }
26882692}
0 commit comments