1414use bitcoin:: blockdata:: transaction:: { Transaction , TxOut , TxIn , SigHashType } ;
1515use bitcoin:: blockdata:: script:: { Script , Builder } ;
1616use bitcoin:: blockdata:: opcodes;
17- use bitcoin:: consensus:: Encodable ;
18- use bitcoin:: consensus:: encode:: VarInt ;
1917use bitcoin:: network:: constants:: Network ;
2018use bitcoin:: util:: bip32:: { ExtendedPrivKey , ExtendedPubKey , ChildNumber } ;
2119use bitcoin:: util:: bip143;
@@ -30,7 +28,7 @@ use bitcoin::secp256k1::key::{SecretKey, PublicKey};
3028use bitcoin:: secp256k1:: { Secp256k1 , Signature , Signing } ;
3129use bitcoin:: secp256k1;
3230
33- use util:: byte_utils;
31+ use util:: { byte_utils, transaction_utils } ;
3432use util:: ser:: { Writeable , Writer , Readable } ;
3533
3634use chain:: transaction:: OutPoint ;
@@ -891,6 +889,8 @@ impl KeysManager {
891889 /// Returns `Err(())` if the output value is greater than the input value minus required fee or
892890 /// if a descriptor was duplicated.
893891 ///
892+ /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
893+ ///
894894 /// May panic if the `SpendableOutputDescriptor`s were not generated by Channels which used
895895 /// this KeysManager or one of the `InMemoryChannelKeys` created by this KeysManager.
896896 pub fn spend_spendable_outputs < C : Signing > ( & self , descriptors : & [ SpendableOutputDescriptor ] , outputs : Vec < TxOut > , change_destination_script : Script , feerate_sat_per_1000_weight : u32 , secp_ctx : & Secp256k1 < C > ) -> Result < Transaction , ( ) > {
@@ -936,36 +936,13 @@ impl KeysManager {
936936 }
937937 if input_value > MAX_VALUE_MSAT / 1000 { return Err ( ( ) ) ; }
938938 }
939- let mut output_value = 0 ;
940- for output in outputs. iter ( ) {
941- output_value += output. value ;
942- if output_value >= input_value { return Err ( ( ) ) ; }
943- }
944939 let mut spend_tx = Transaction {
945940 version : 2 ,
946941 lock_time : 0 ,
947942 input,
948943 output : outputs,
949944 } ;
950-
951- let mut change_output = TxOut {
952- script_pubkey : change_destination_script,
953- value : 0 ,
954- } ;
955- let change_len = change_output. consensus_encode ( & mut std:: io:: sink ( ) ) . unwrap ( ) ;
956- let mut weight_with_change: i64 = spend_tx. get_weight ( ) as i64 + 2 + witness_weight as i64 + change_len as i64 * 4 ;
957- // Include any extra bytes required to push an extra output.
958- weight_with_change += ( VarInt ( spend_tx. output . len ( ) as u64 + 1 ) . len ( ) - VarInt ( spend_tx. output . len ( ) as u64 ) . len ( ) ) as i64 * 4 ;
959- // When calculating weight, add two for the flag bytes
960- let change_value: i64 = ( input_value - output_value) as i64 - weight_with_change * feerate_sat_per_1000_weight as i64 / 1000 ;
961- if change_value > 0 {
962- change_output. value = change_value as u64 ;
963- spend_tx. output . push ( change_output) ;
964- } else if ( input_value - output_value) as i64 - ( spend_tx. get_weight ( ) as i64 + 2 + witness_weight as i64 ) * feerate_sat_per_1000_weight as i64 / 1000 < 0 {
965- return Err ( ( ) ) ;
966- }
967-
968- spend_tx. output [ 0 ] . value -= ( spend_tx. get_weight ( ) + 2 + witness_weight + 3 ) as u64 * feerate_sat_per_1000_weight as u64 / 1000 ;
945+ transaction_utils:: maybe_add_change_output ( & mut spend_tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script) ?;
969946
970947 let mut keys_cache: Option < ( InMemoryChannelKeys , ( u64 , u64 ) ) > = None ;
971948 let mut input_idx = 0 ;
0 commit comments