@@ -30,6 +30,7 @@ use crate::sign::{
3030	ChannelDerivationParameters ,  HTLCDescriptor ,  SignerProvider ,  P2WPKH_WITNESS_WEIGHT , 
3131} ; 
3232use  crate :: sync:: Mutex ; 
33+ use  crate :: util:: async_poll:: { AsyncResult ,  MaybeSend ,  MaybeSync } ; 
3334use  crate :: util:: logger:: Logger ; 
3435
3536use  bitcoin:: amount:: Amount ; 
@@ -346,42 +347,42 @@ pub trait CoinSelectionSource {
346347 	/// other claims, implementations must be willing to double spend their UTXOs. The choice of 
347348 	/// which UTXOs to double spend is left to the implementation, but it must strive to keep the 
348349 	/// set of other claims being double spent to a minimum. 
349-  	fn  select_confirmed_utxos ( 
350- 		& self ,  claim_id :  ClaimId ,  must_spend :  Vec < Input > ,  must_pay_to :  & [ TxOut ] , 
350+  	fn  select_confirmed_utxos < ' a > ( 
351+ 		& ' a   self ,  claim_id :  ClaimId ,  must_spend :  Vec < Input > ,  must_pay_to :  & ' a   [ TxOut ] , 
351352		target_feerate_sat_per_1000_weight :  u32 , 
352- 	)  -> Result < CoinSelection ,   ( ) > ; 
353+ 	)  -> AsyncResult < ' a ,   CoinSelection > ; 
353354	/// Signs and provides the full witness for all inputs within the transaction known to the 
354355 	/// trait (i.e., any provided via [`CoinSelectionSource::select_confirmed_utxos`]). 
355356 	/// 
356357 	/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the 
357358 	/// unsigned transaction and then sign it with your wallet. 
358-  	fn  sign_psbt ( & self ,  psbt :  Psbt )  -> Result < Transaction ,   ( ) > ; 
359+  	fn  sign_psbt < ' a > ( & ' a   self ,  psbt :  Psbt )  -> AsyncResult < ' a ,   Transaction > ; 
359360} 
360361
361362/// An alternative to [`CoinSelectionSource`] that can be implemented and used along [`Wallet`] to 
362363/// provide a default implementation to [`CoinSelectionSource`]. 
363364pub  trait  WalletSource  { 
364365	/// Returns all UTXOs, with at least 1 confirmation each, that are available to spend. 
365-  	fn  list_confirmed_utxos ( & self )  -> Result < Vec < Utxo > ,   ( ) > ; 
366+  	fn  list_confirmed_utxos < ' a > ( & ' a   self )  -> AsyncResult < ' a ,   Vec < Utxo > > ; 
366367	/// Returns a script to use for change above dust resulting from a successful coin selection 
367368 	/// attempt. 
368-  	fn  get_change_script ( & self )  -> Result < ScriptBuf ,   ( ) > ; 
369+  	fn  get_change_script < ' a > ( & ' a   self )  -> AsyncResult < ' a ,   ScriptBuf > ; 
369370	/// Signs and provides the full [`TxIn::script_sig`] and [`TxIn::witness`] for all inputs within 
370371 	/// the transaction known to the wallet (i.e., any provided via 
371372 	/// [`WalletSource::list_confirmed_utxos`]). 
372373 	/// 
373374 	/// If your wallet does not support signing PSBTs you can call `psbt.extract_tx()` to get the 
374375 	/// unsigned transaction and then sign it with your wallet. 
375-  	fn  sign_psbt ( & self ,  psbt :  Psbt )  -> Result < Transaction ,   ( ) > ; 
376+  	fn  sign_psbt < ' a > ( & ' a   self ,  psbt :  Psbt )  -> AsyncResult < ' a ,   Transaction > ; 
376377} 
377378
378379/// A wrapper over [`WalletSource`] that implements [`CoinSelection`] by preferring UTXOs that would 
379380/// avoid conflicting double spends. If not enough UTXOs are available to do so, conflicting double 
380381/// spends may happen. 
381- pub  struct  Wallet < W :  Deref ,  L :  Deref > 
382+ pub  struct  Wallet < W :  Deref  +  MaybeSync  +  MaybeSend ,  L :  Deref  +  MaybeSync  +  MaybeSend > 
382383where 
383- 	W :: Target :  WalletSource , 
384- 	L :: Target :  Logger , 
384+ 	W :: Target :  WalletSource  +  MaybeSend , 
385+ 	L :: Target :  Logger  +  MaybeSend , 
385386{ 
386387	source :  W , 
387388	logger :  L , 
@@ -391,10 +392,10 @@ where
391392	locked_utxos :  Mutex < HashMap < OutPoint ,  ClaimId > > , 
392393} 
393394
394- impl < W :  Deref ,  L :  Deref >  Wallet < W ,  L > 
395+ impl < W :  Deref  +  MaybeSync  +  MaybeSend ,  L :  Deref  +  MaybeSync  +  MaybeSend >  Wallet < W ,  L > 
395396where 
396- 	W :: Target :  WalletSource , 
397- 	L :: Target :  Logger , 
397+ 	W :: Target :  WalletSource  +  MaybeSend , 
398+ 	L :: Target :  Logger  +  MaybeSend , 
398399{ 
399400	/// Returns a new instance backed by the given [`WalletSource`] that serves as an implementation 
400401 	/// of [`CoinSelectionSource`]. 
@@ -410,7 +411,7 @@ where
410411 	/// `tolerate_high_network_feerates` is set, we'll attempt to spend UTXOs that contribute at 
411412 	/// least 1 satoshi at the current feerate, otherwise, we'll only attempt to spend those which 
412413 	/// contribute at least twice their fee. 
413-  	fn  select_confirmed_utxos_internal ( 
414+  	async   fn  select_confirmed_utxos_internal ( 
414415		& self ,  utxos :  & [ Utxo ] ,  claim_id :  ClaimId ,  force_conflicting_utxo_spend :  bool , 
415416		tolerate_high_network_feerates :  bool ,  target_feerate_sat_per_1000_weight :  u32 , 
416417		preexisting_tx_weight :  u64 ,  input_amount_sat :  Amount ,  target_amount_sat :  Amount , 
@@ -484,7 +485,7 @@ where
484485		} 
485486
486487		let  remaining_amount = selected_amount - target_amount_sat - total_fees; 
487- 		let  change_script = self . source . get_change_script ( ) ?; 
488+ 		let  change_script = self . source . get_change_script ( ) . await ?; 
488489		let  change_output_fee = fee_for_weight ( 
489490			target_feerate_sat_per_1000_weight, 
490491			( 8  /* value */  + change_script. consensus_encode ( & mut  sink ( ) ) . unwrap ( )  as  u64 ) 
@@ -503,60 +504,67 @@ where
503504	} 
504505} 
505506
506- impl < W :  Deref ,  L :  Deref >  CoinSelectionSource  for  Wallet < W ,  L > 
507+ impl < W :  Deref  + MaybeSync  + MaybeSend ,  L :  Deref  + MaybeSync  + MaybeSend >  CoinSelectionSource 
508+ 	for  Wallet < W ,  L > 
507509where 
508- 	W :: Target :  WalletSource , 
509- 	L :: Target :  Logger , 
510+ 	W :: Target :  WalletSource  +  MaybeSend  +  MaybeSync , 
511+ 	L :: Target :  Logger  +  MaybeSend  +  MaybeSync , 
510512{ 
511- 	fn  select_confirmed_utxos ( 
512- 		& self ,  claim_id :  ClaimId ,  must_spend :  Vec < Input > ,  must_pay_to :  & [ TxOut ] , 
513+ 	fn  select_confirmed_utxos < ' a > ( 
514+ 		& ' a   self ,  claim_id :  ClaimId ,  must_spend :  Vec < Input > ,  must_pay_to :  & ' a   [ TxOut ] , 
513515		target_feerate_sat_per_1000_weight :  u32 , 
514- 	)  -> Result < CoinSelection ,  ( ) >  { 
515- 		let  utxos = self . source . list_confirmed_utxos ( ) ?; 
516- 		// TODO: Use fee estimation utils when we upgrade to bitcoin v0.30.0. 
517- 		const  BASE_TX_SIZE :  u64  = 4  /* version */  + 1  /* input count */  + 1  /* output count */  + 4  /* locktime */ ; 
518- 		let  total_output_size:  u64  = must_pay_to
519- 			. iter ( ) 
520- 			. map ( |output| 8  /* value */  + 1  /* script len */  + output. script_pubkey . len ( )  as  u64 ) 
521- 			. sum ( ) ; 
522- 		let  total_satisfaction_weight:  u64  =
523- 			must_spend. iter ( ) . map ( |input| input. satisfaction_weight ) . sum ( ) ; 
524- 		let  total_input_weight =
525- 			( BASE_INPUT_WEIGHT  *  must_spend. len ( )  as  u64 )  + total_satisfaction_weight; 
526- 
527- 		let  preexisting_tx_weight = 2  /* segwit marker & flag */  + total_input_weight +
516+ 	)  -> AsyncResult < ' a ,  CoinSelection >  { 
517+ 		Box :: pin ( async  move  { 
518+ 			let  utxos = self . source . list_confirmed_utxos ( ) . await ?; 
519+ 			// TODO: Use fee estimation utils when we upgrade to bitcoin v0.30.0. 
520+ 			const  BASE_TX_SIZE :  u64  = 4  /* version */  + 1  /* input count */  + 1  /* output count */  + 4  /* locktime */ ; 
521+ 			let  total_output_size:  u64  = must_pay_to
522+ 				. iter ( ) 
523+ 				. map ( 
524+ 					|output| 8  /* value */  + 1  /* script len */  + output. script_pubkey . len ( )  as  u64 , 
525+ 				) 
526+ 				. sum ( ) ; 
527+ 			let  total_satisfaction_weight:  u64  =
528+ 				must_spend. iter ( ) . map ( |input| input. satisfaction_weight ) . sum ( ) ; 
529+ 			let  total_input_weight =
530+ 				( BASE_INPUT_WEIGHT  *  must_spend. len ( )  as  u64 )  + total_satisfaction_weight; 
531+ 
532+ 			let  preexisting_tx_weight = 2  /* segwit marker & flag */  + total_input_weight +
528533			( ( BASE_TX_SIZE  + total_output_size)  *  WITNESS_SCALE_FACTOR  as  u64 ) ; 
529- 		let  input_amount_sat = must_spend. iter ( ) . map ( |input| input. previous_utxo . value ) . sum ( ) ; 
530- 		let  target_amount_sat = must_pay_to. iter ( ) . map ( |output| output. value ) . sum ( ) ; 
534+ 			 let  input_amount_sat = must_spend. iter ( ) . map ( |input| input. previous_utxo . value ) . sum ( ) ; 
535+ 			 let  target_amount_sat = must_pay_to. iter ( ) . map ( |output| output. value ) . sum ( ) ; 
531536
532- 		let  configs = [ ( false ,  false ) ,  ( false ,  true ) ,  ( true ,  false ) ,  ( true ,  true ) ] ; 
533- 		for  ( force_conflicting_utxo_spend,  tolerate_high_network_feerates)  in  configs { 
534- 			log_debug ! ( 
535- 				self . logger, 
536- 				"Attempting coin selection targeting {} sat/kW (force_conflicting_utxo_spend = {}, tolerate_high_network_feerates = {})" , 
537- 				target_feerate_sat_per_1000_weight, 
538- 				force_conflicting_utxo_spend, 
539- 				tolerate_high_network_feerates
540- 			) ; 
541- 			let  attempt = self . select_confirmed_utxos_internal ( 
542- 				& utxos, 
543- 				claim_id, 
544- 				force_conflicting_utxo_spend, 
545- 				tolerate_high_network_feerates, 
546- 				target_feerate_sat_per_1000_weight, 
547- 				preexisting_tx_weight, 
548- 				input_amount_sat, 
549- 				target_amount_sat, 
550- 			) ; 
551- 			if  attempt. is_ok ( )  { 
552- 				return  attempt; 
537+ 			let  configs = [ ( false ,  false ) ,  ( false ,  true ) ,  ( true ,  false ) ,  ( true ,  true ) ] ; 
538+ 			for  ( force_conflicting_utxo_spend,  tolerate_high_network_feerates)  in  configs { 
539+ 				log_debug ! ( 
540+ 					self . logger, 
541+ 					"Attempting coin selection targeting {} sat/kW (force_conflicting_utxo_spend = {}, tolerate_high_network_feerates = {})" , 
542+ 					target_feerate_sat_per_1000_weight, 
543+ 					force_conflicting_utxo_spend, 
544+ 					tolerate_high_network_feerates
545+ 				) ; 
546+ 				let  attempt = self 
547+ 					. select_confirmed_utxos_internal ( 
548+ 						& utxos, 
549+ 						claim_id, 
550+ 						force_conflicting_utxo_spend, 
551+ 						tolerate_high_network_feerates, 
552+ 						target_feerate_sat_per_1000_weight, 
553+ 						preexisting_tx_weight, 
554+ 						input_amount_sat, 
555+ 						target_amount_sat, 
556+ 					) 
557+ 					. await ; 
558+ 				if  attempt. is_ok ( )  { 
559+ 					return  attempt; 
560+ 				} 
553561			} 
554- 		} 
555- 		Err ( ( ) ) 
562+ 			 Err ( ( ) ) 
563+ 		} ) 
556564	} 
557565
558- 	fn  sign_psbt ( & self ,  psbt :  Psbt )  -> Result < Transaction ,   ( ) >  { 
559- 		self . source . sign_psbt ( psbt) 
566+ 	fn  sign_psbt < ' a > ( & ' a   self ,  psbt :  Psbt )  -> AsyncResult < ' a ,   Transaction >  { 
567+ 		Box :: pin ( async   move   {   self . source . sign_psbt ( psbt) . await   } ) 
560568	} 
561569} 
562570
@@ -635,7 +643,7 @@ where
635643	/// Handles a [`BumpTransactionEvent::ChannelClose`] event variant by producing a fully-signed 
636644 	/// transaction spending an anchor output of the commitment transaction to bump its fee and 
637645 	/// broadcasts them to the network as a package. 
638-  	fn  handle_channel_close ( 
646+  	async   fn  handle_channel_close ( 
639647		& self ,  claim_id :  ClaimId ,  package_target_feerate_sat_per_1000_weight :  u32 , 
640648		commitment_tx :  & Transaction ,  commitment_tx_fee_sat :  u64 , 
641649		anchor_descriptor :  & AnchorDescriptor , 
@@ -662,12 +670,15 @@ where
662670
663671			log_debug ! ( self . logger,  "Performing coin selection for commitment package (commitment and anchor transaction) targeting {} sat/kW" , 
664672				package_target_feerate_sat_per_1000_weight) ; 
665- 			let  coin_selection:  CoinSelection  = self . utxo_source . select_confirmed_utxos ( 
666- 				claim_id, 
667- 				must_spend, 
668- 				& [ ] , 
669- 				package_target_feerate_sat_per_1000_weight, 
670- 			) ?; 
673+ 			let  coin_selection:  CoinSelection  = self 
674+ 				. utxo_source 
675+ 				. select_confirmed_utxos ( 
676+ 					claim_id, 
677+ 					must_spend, 
678+ 					& [ ] , 
679+ 					package_target_feerate_sat_per_1000_weight, 
680+ 				) 
681+ 				. await ?; 
671682
672683			let  mut  anchor_tx = Transaction  { 
673684				version :  Version :: TWO , 
@@ -733,7 +744,7 @@ where
733744			} 
734745
735746			log_debug ! ( self . logger,  "Signing anchor transaction {}" ,  anchor_txid) ; 
736- 			anchor_tx = self . utxo_source . sign_psbt ( anchor_psbt) ?; 
747+ 			anchor_tx = self . utxo_source . sign_psbt ( anchor_psbt) . await ?; 
737748
738749			let  signer = self 
739750				. signer_provider 
@@ -780,7 +791,7 @@ where
780791
781792	/// Handles a [`BumpTransactionEvent::HTLCResolution`] event variant by producing a 
782793 	/// fully-signed, fee-bumped HTLC transaction that is broadcast to the network. 
783-  	fn  handle_htlc_resolution ( 
794+  	async   fn  handle_htlc_resolution ( 
784795		& self ,  claim_id :  ClaimId ,  target_feerate_sat_per_1000_weight :  u32 , 
785796		htlc_descriptors :  & [ HTLCDescriptor ] ,  tx_lock_time :  LockTime , 
786797	)  -> Result < ( ) ,  ( ) >  { 
@@ -821,12 +832,15 @@ where
821832		let  must_spend_amount =
822833			must_spend. iter ( ) . map ( |input| input. previous_utxo . value . to_sat ( ) ) . sum :: < u64 > ( ) ; 
823834
824- 		let  coin_selection:  CoinSelection  = self . utxo_source . select_confirmed_utxos ( 
825- 			claim_id, 
826- 			must_spend, 
827- 			& htlc_tx. output , 
828- 			target_feerate_sat_per_1000_weight, 
829- 		) ?; 
835+ 		let  coin_selection:  CoinSelection  = self 
836+ 			. utxo_source 
837+ 			. select_confirmed_utxos ( 
838+ 				claim_id, 
839+ 				must_spend, 
840+ 				& htlc_tx. output , 
841+ 				target_feerate_sat_per_1000_weight, 
842+ 			) 
843+ 			. await ?; 
830844
831845		#[ cfg( debug_assertions) ]  
832846		let  input_satisfaction_weight:  u64  =
@@ -870,7 +884,7 @@ where
870884			"Signing HTLC transaction {}" , 
871885			htlc_psbt. unsigned_tx. compute_txid( ) 
872886		) ; 
873- 		htlc_tx = self . utxo_source . sign_psbt ( htlc_psbt) ?; 
887+ 		htlc_tx = self . utxo_source . sign_psbt ( htlc_psbt) . await ?; 
874888
875889		let  mut  signers = BTreeMap :: new ( ) ; 
876890		for  ( idx,  htlc_descriptor)  in  htlc_descriptors. iter ( ) . enumerate ( )  { 
@@ -909,7 +923,7 @@ where
909923	} 
910924
911925	/// Handles all variants of [`BumpTransactionEvent`]. 
912-  	pub  fn  handle_event ( & self ,  event :  & BumpTransactionEvent )  { 
926+  	pub  async   fn  handle_event ( & self ,  event :  & BumpTransactionEvent )  { 
913927		match  event { 
914928			BumpTransactionEvent :: ChannelClose  { 
915929				claim_id, 
@@ -925,19 +939,21 @@ where
925939					log_bytes!( claim_id. 0 ) , 
926940					commitment_tx. compute_txid( ) 
927941				) ; 
928- 				if   let   Err ( _ )  =  self . handle_channel_close ( 
942+ 				self . handle_channel_close ( 
929943					* claim_id, 
930944					* package_target_feerate_sat_per_1000_weight, 
931945					commitment_tx, 
932946					* commitment_tx_fee_satoshis, 
933947					anchor_descriptor, 
934- 				)  { 
948+ 				) 
949+ 				. await 
950+ 				. unwrap_or_else ( |_| { 
935951					log_error ! ( 
936952						self . logger, 
937953						"Failed bumping commitment transaction fee for {}" , 
938954						commitment_tx. compute_txid( ) 
939955					) ; 
940- 				} 
956+ 				} ) ; 
941957			} , 
942958			BumpTransactionEvent :: HTLCResolution  { 
943959				claim_id, 
@@ -952,18 +968,20 @@ where
952968					log_bytes!( claim_id. 0 ) , 
953969					log_iter!( htlc_descriptors. iter( ) . map( |d| d. outpoint( ) ) ) 
954970				) ; 
955- 				if   let   Err ( _ )  =  self . handle_htlc_resolution ( 
971+ 				self . handle_htlc_resolution ( 
956972					* claim_id, 
957973					* target_feerate_sat_per_1000_weight, 
958974					htlc_descriptors, 
959975					* tx_lock_time, 
960- 				)  { 
976+ 				) 
977+ 				. await 
978+ 				. unwrap_or_else ( |_| { 
961979					log_error ! ( 
962980						self . logger, 
963981						"Failed bumping HTLC transaction fee for commitment {}" , 
964982						htlc_descriptors[ 0 ] . commitment_txid
965983					) ; 
966- 				} 
984+ 				} ) ; 
967985			} , 
968986		} 
969987	} 
@@ -973,6 +991,9 @@ where
973991mod  tests { 
974992	use  super :: * ; 
975993
994+ 	use  crate :: events:: bump_transaction_sync:: { 
995+ 		BumpTransactionEventHandlerSync ,  CoinSelectionSourceSync , 
996+ 	} ; 
976997	use  crate :: io:: Cursor ; 
977998	use  crate :: ln:: chan_utils:: ChannelTransactionParameters ; 
978999	use  crate :: sign:: KeysManager ; 
@@ -988,7 +1009,7 @@ mod tests {
9881009		// (commitment + anchor value, commitment + input weight, target feerate, result) 
9891010		expected_selects :  Mutex < Vec < ( u64 ,  u64 ,  u32 ,  CoinSelection ) > > , 
9901011	} 
991- 	impl  CoinSelectionSource  for  TestCoinSelectionSource  { 
1012+ 	impl  CoinSelectionSourceSync  for  TestCoinSelectionSource  { 
9921013		fn  select_confirmed_utxos ( 
9931014			& self ,  _claim_id :  ClaimId ,  must_spend :  Vec < Input > ,  _must_pay_to :  & [ TxOut ] , 
9941015			target_feerate_sat_per_1000_weight :  u32 , 
@@ -1073,7 +1094,7 @@ mod tests {
10731094		} ; 
10741095		let  signer = KeysManager :: new ( & [ 42 ;  32 ] ,  42 ,  42 ) ; 
10751096		let  logger = TestLogger :: new ( ) ; 
1076- 		let  handler = BumpTransactionEventHandler :: new ( & broadcaster,  & source,  & signer,  & logger) ; 
1097+ 		let  handler = BumpTransactionEventHandlerSync :: new ( & broadcaster,  & source,  & signer,  & logger) ; 
10771098
10781099		let  mut  transaction_parameters = ChannelTransactionParameters :: test_dummy ( 42_000_000 ) ; 
10791100		transaction_parameters. channel_type_features  =
0 commit comments