14
14
use bitcoin:: blockdata:: transaction:: { Transaction , TxOut , TxIn , SigHashType } ;
15
15
use bitcoin:: blockdata:: script:: { Script , Builder } ;
16
16
use bitcoin:: blockdata:: opcodes;
17
- use bitcoin:: consensus:: Encodable ;
18
- use bitcoin:: consensus:: encode:: VarInt ;
19
17
use bitcoin:: network:: constants:: Network ;
20
18
use bitcoin:: util:: bip32:: { ExtendedPrivKey , ExtendedPubKey , ChildNumber } ;
21
19
use bitcoin:: util:: bip143;
@@ -30,7 +28,7 @@ use bitcoin::secp256k1::key::{SecretKey, PublicKey};
30
28
use bitcoin:: secp256k1:: { Secp256k1 , Signature , Signing } ;
31
29
use bitcoin:: secp256k1;
32
30
33
- use util:: byte_utils;
31
+ use util:: { byte_utils, transaction_utils } ;
34
32
use util:: ser:: { Writeable , Writer , Readable } ;
35
33
36
34
use chain:: transaction:: OutPoint ;
@@ -895,6 +893,8 @@ impl KeysManager {
895
893
/// Returns `Err(())` if the output value is greater than the input value minus required fee or
896
894
/// if a descriptor was duplicated.
897
895
///
896
+ /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
897
+ ///
898
898
/// May panic if the `SpendableOutputDescriptor`s were not generated by Channels which used
899
899
/// this KeysManager or one of the `InMemoryChannelKeys` created by this KeysManager.
900
900
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 , ( ) > {
@@ -940,36 +940,13 @@ impl KeysManager {
940
940
}
941
941
if input_value > MAX_VALUE_MSAT / 1000 { return Err ( ( ) ) ; }
942
942
}
943
- let mut output_value = 0 ;
944
- for output in outputs. iter ( ) {
945
- output_value += output. value ;
946
- if output_value >= input_value { return Err ( ( ) ) ; }
947
- }
948
943
let mut spend_tx = Transaction {
949
944
version : 2 ,
950
945
lock_time : 0 ,
951
946
input,
952
947
output : outputs,
953
948
} ;
954
-
955
- let mut change_output = TxOut {
956
- script_pubkey : change_destination_script,
957
- value : 0 ,
958
- } ;
959
- let change_len = change_output. consensus_encode ( & mut std:: io:: sink ( ) ) . unwrap ( ) ;
960
- let mut weight_with_change: i64 = spend_tx. get_weight ( ) as i64 + 2 + witness_weight as i64 + change_len as i64 * 4 ;
961
- // Include any extra bytes required to push an extra output.
962
- weight_with_change += ( VarInt ( spend_tx. output . len ( ) as u64 + 1 ) . len ( ) - VarInt ( spend_tx. output . len ( ) as u64 ) . len ( ) ) as i64 * 4 ;
963
- // When calculating weight, add two for the flag bytes
964
- let change_value: i64 = ( input_value - output_value) as i64 - weight_with_change * feerate_sat_per_1000_weight as i64 / 1000 ;
965
- if change_value > 0 {
966
- change_output. value = change_value as u64 ;
967
- spend_tx. output . push ( change_output) ;
968
- } 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 {
969
- return Err ( ( ) ) ;
970
- }
971
-
972
- spend_tx. output [ 0 ] . value -= ( spend_tx. get_weight ( ) + 2 + witness_weight + 3 ) as u64 * feerate_sat_per_1000_weight as u64 / 1000 ;
949
+ transaction_utils:: maybe_add_change_output ( & mut spend_tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script) ?;
973
950
974
951
let mut keys_cache: Option < ( InMemoryChannelKeys , ( u64 , u64 ) ) > = None ;
975
952
let mut input_idx = 0 ;
0 commit comments