@@ -35,6 +35,7 @@ use bitcoin::{OutPoint, PubkeyHash, Sequence, ScriptBuf, Transaction, TxIn, TxOu
3535use  bitcoin:: blockdata:: constants:: WITNESS_SCALE_FACTOR ; 
3636use  bitcoin:: blockdata:: locktime:: absolute:: LockTime ; 
3737use  bitcoin:: consensus:: Encodable ; 
38+ use  bitcoin:: psbt:: PartiallySignedTransaction ; 
3839use  bitcoin:: secp256k1; 
3940use  bitcoin:: secp256k1:: Secp256k1 ; 
4041use  bitcoin:: secp256k1:: ecdsa:: Signature ; 
@@ -343,7 +344,7 @@ pub trait CoinSelectionSource {
343344	)  -> Result < CoinSelection ,  ( ) > ; 
344345	/// Signs and provides the full witness for all inputs within the transaction known to the 
345346/// trait (i.e., any provided via [`CoinSelectionSource::select_confirmed_utxos`]). 
346- fn  sign_tx ( & self ,  tx :  Transaction )  -> Result < Transaction ,  ( ) > ; 
347+ fn  sign_psbt ( & self ,  tx :  PartiallySignedTransaction )  -> Result < Transaction ,  ( ) > ; 
347348} 
348349
349350/// An alternative to [`CoinSelectionSource`] that can be implemented and used along [`Wallet`] to 
@@ -357,7 +358,7 @@ pub trait WalletSource {
357358	/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within 
358359/// the transaction known to the wallet (i.e., any provided via 
359360/// [`WalletSource::list_confirmed_utxos`]). 
360- fn  sign_tx ( & self ,  tx :   Transaction )  -> Result < Transaction ,  ( ) > ; 
361+ fn  sign_psbt ( & self ,  psbt :   PartiallySignedTransaction )  -> Result < Transaction ,  ( ) > ; 
361362} 
362363
363364/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would 
@@ -504,8 +505,8 @@ where
504505			. or_else ( |_| do_coin_selection ( true ,  true ) ) 
505506	} 
506507
507- 	fn  sign_tx ( & self ,  tx :   Transaction )  -> Result < Transaction ,  ( ) >  { 
508- 		self . source . sign_tx ( tx ) 
508+ 	fn  sign_psbt ( & self ,  psbt :   PartiallySignedTransaction )  -> Result < Transaction ,  ( ) >  { 
509+ 		self . source . sign_psbt ( psbt ) 
509510	} 
510511} 
511512
@@ -549,16 +550,16 @@ where
549550	} 
550551
551552	/// Updates a transaction with the result of a successful coin selection attempt. 
552- fn  process_coin_selection ( & self ,  tx :  & mut  Transaction ,  mut   coin_selection :  CoinSelection )  { 
553- 		for  utxo in  coin_selection. confirmed_utxos . drain ( .. )  { 
553+ fn  process_coin_selection ( & self ,  tx :  & mut  Transaction ,  coin_selection :  & CoinSelection )  { 
554+ 		for  utxo in  coin_selection. confirmed_utxos . iter ( )  { 
554555			tx. input . push ( TxIn  { 
555556				previous_output :  utxo. outpoint , 
556557				script_sig :  ScriptBuf :: new ( ) , 
557558				sequence :  Sequence :: ZERO , 
558559				witness :  Witness :: new ( ) , 
559560			} ) ; 
560561		} 
561- 		if  let  Some ( change_output)  = coin_selection. change_output . take ( )  { 
562+ 		if  let  Some ( change_output)  = coin_selection. change_output . clone ( )  { 
562563			tx. output . push ( change_output) ; 
563564		}  else  if  tx. output . is_empty ( )  { 
564565			// We weren't provided a change output, likely because the input set was a perfect 
@@ -613,15 +614,28 @@ where
613614		let  total_input_amount = must_spend_amount +
614615			coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum :: < u64 > ( ) ; 
615616
616- 		self . process_coin_selection ( & mut  anchor_tx,  coin_selection) ; 
617+ 		self . process_coin_selection ( & mut  anchor_tx,  & coin_selection) ; 
617618		let  anchor_txid = anchor_tx. txid ( ) ; 
618619
620+ 		// construct psbt 
621+ 		let  mut  anchor_psbt = PartiallySignedTransaction :: from_unsigned_tx ( anchor_tx. clone ( ) ) . unwrap ( ) ; 
622+ 		// add witness_utxo to anchor input 
623+ 		anchor_psbt. inputs [ 0 ] . witness_utxo  = Some ( anchor_descriptor. previous_utxo ( ) ) ; 
624+ 		// add witness_utxo to remaining inputs 
625+ 		for  ( idx,  utxo)  in  coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( )  { 
626+ 			// add 1 to skip the anchor input 
627+ 			let  index = idx + 1 ; 
628+ 			debug_assert_eq ! ( anchor_psbt. unsigned_tx. input[ index] . previous_output,  utxo. outpoint) ; 
629+ 			anchor_psbt. inputs [ index] . witness_utxo  = Some ( utxo. output ) ; 
630+ 		} 
631+ 
619632		debug_assert_eq ! ( anchor_tx. output. len( ) ,  1 ) ; 
620633		#[ cfg( debug_assertions) ]  
621634		let  unsigned_tx_weight = anchor_tx. weight ( ) . to_wu ( )  - ( anchor_tx. input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
622635
623636		log_debug ! ( self . logger,  "Signing anchor transaction {}" ,  anchor_txid) ; 
624- 		anchor_tx = self . utxo_source . sign_tx ( anchor_tx) ?; 
637+ 		debug_assert ! ( anchor_psbt. inputs. iter( ) . all( |i| i. witness_utxo. is_some( ) ) ) ; 
638+ 		anchor_tx = self . utxo_source . sign_psbt ( anchor_psbt) ?; 
625639
626640		let  signer = anchor_descriptor. derive_channel_signer ( & self . signer_provider ) ; 
627641		let  anchor_sig = signer. sign_holder_anchor_input ( & anchor_tx,  0 ,  & self . secp ) ?; 
@@ -701,13 +715,29 @@ where
701715		let  total_input_amount = must_spend_amount +
702716			coin_selection. confirmed_utxos . iter ( ) . map ( |utxo| utxo. output . value ) . sum :: < u64 > ( ) ; 
703717
704- 		self . process_coin_selection ( & mut  htlc_tx,  coin_selection) ; 
718+ 		self . process_coin_selection ( & mut  htlc_tx,  & coin_selection) ; 
719+ 
720+ 		// construct psbt 
721+ 		let  mut  htlc_psbt = PartiallySignedTransaction :: from_unsigned_tx ( htlc_tx. clone ( ) ) . unwrap ( ) ; 
722+ 		// add witness_utxo to htlc inputs 
723+ 		for  ( i,  htlc_descriptor)  in  htlc_descriptors. iter ( ) . enumerate ( )  { 
724+ 			debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ i] . previous_output,  htlc_descriptor. outpoint( ) ) ; 
725+ 			htlc_psbt. inputs [ i] . witness_utxo  = Some ( htlc_descriptor. previous_utxo ( & self . secp ) ) ; 
726+ 		} 
727+ 		// add witness_utxo to remaining inputs 
728+ 		for  ( idx,  utxo)  in  coin_selection. confirmed_utxos . into_iter ( ) . enumerate ( )  { 
729+ 			// offset to skip the htlc inputs 
730+ 			let  index = idx + htlc_descriptors. len ( ) ; 
731+ 			debug_assert_eq ! ( htlc_psbt. unsigned_tx. input[ index] . previous_output,  utxo. outpoint) ; 
732+ 			htlc_psbt. inputs [ index] . witness_utxo  = Some ( utxo. output ) ; 
733+ 		} 
705734
706735		#[ cfg( debug_assertions) ]  
707736		let  unsigned_tx_weight = htlc_tx. weight ( ) . to_wu ( )  - ( htlc_tx. input . len ( )  as  u64  *  EMPTY_SCRIPT_SIG_WEIGHT ) ; 
708737
709738		log_debug ! ( self . logger,  "Signing HTLC transaction {}" ,  htlc_tx. txid( ) ) ; 
710- 		htlc_tx = self . utxo_source . sign_tx ( htlc_tx) ?; 
739+ 		debug_assert ! ( htlc_psbt. inputs. iter( ) . all( |i| i. witness_utxo. is_some( ) ) ) ; 
740+ 		htlc_tx = self . utxo_source . sign_psbt ( htlc_psbt) ?; 
711741
712742		let  mut  signers = BTreeMap :: new ( ) ; 
713743		for  ( idx,  htlc_descriptor)  in  htlc_descriptors. iter ( ) . enumerate ( )  { 
0 commit comments