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 ;
@@ -891,6 +889,8 @@ impl KeysManager {
891
889
/// Returns `Err(())` if the output value is greater than the input value minus required fee or
892
890
/// if a descriptor was duplicated.
893
891
///
892
+ /// We do not enforce that outputs meet the dust limit or that any output scripts are standard.
893
+ ///
894
894
/// May panic if the `SpendableOutputDescriptor`s were not generated by Channels which used
895
895
/// this KeysManager or one of the `InMemoryChannelKeys` created by this KeysManager.
896
896
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 {
936
936
}
937
937
if input_value > MAX_VALUE_MSAT / 1000 { return Err ( ( ) ) ; }
938
938
}
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
- }
944
939
let mut spend_tx = Transaction {
945
940
version : 2 ,
946
941
lock_time : 0 ,
947
942
input,
948
943
output : outputs,
949
944
} ;
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) ?;
969
946
970
947
let mut keys_cache: Option < ( InMemoryChannelKeys , ( u64 , u64 ) ) > = None ;
971
948
let mut input_idx = 0 ;
0 commit comments