@@ -16,6 +16,7 @@ use bitcoin::blockdata::transaction::{Transaction, TxOut, TxIn, EcdsaSighashType
1616use  bitcoin:: blockdata:: script:: { Script ,  Builder } ; 
1717use  bitcoin:: blockdata:: opcodes; 
1818use  bitcoin:: network:: constants:: Network ; 
19+ use  bitcoin:: psbt:: PartiallySignedTransaction ; 
1920use  bitcoin:: util:: bip32:: { ExtendedPrivKey ,  ExtendedPubKey ,  ChildNumber } ; 
2021use  bitcoin:: util:: sighash; 
2122
@@ -218,6 +219,126 @@ impl_writeable_tlv_based_enum!(SpendableOutputDescriptor,
218219	( 2 ,  StaticPaymentOutput ) , 
219220) ; 
220221
222+ impl  SpendableOutputDescriptor  { 
223+ 	/// Turns this into a [`bitcoin::psbt::Input`] which can be used to create a 
224+  	/// [`PartiallySignedTransaction`] which spends the given descriptor. 
225+  	/// 
226+  	/// Note that this does not include any signatures, just the information required to 
227+  	/// construct the transaction and sign it. 
228+  	pub  fn  to_psbt_input ( & self )  -> bitcoin:: psbt:: Input  { 
229+ 		match  self  { 
230+ 			SpendableOutputDescriptor :: StaticOutput  {  output,  .. }  => { 
231+ 				// Is a standard P2WPKH, no need for witness script 
232+ 				bitcoin:: psbt:: Input  { 
233+ 					witness_utxo :  Some ( output. clone ( ) ) , 
234+ 					..Default :: default ( ) 
235+ 				} 
236+ 			} , 
237+ 			SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor)  => { 
238+ 				// TODO we could add the witness script as well 
239+ 				bitcoin:: psbt:: Input  { 
240+ 					witness_utxo :  Some ( descriptor. output . clone ( ) ) , 
241+ 					..Default :: default ( ) 
242+ 				} 
243+ 			} , 
244+ 			SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor)  => { 
245+ 				// TODO we could add the witness script as well 
246+ 				bitcoin:: psbt:: Input  { 
247+ 					witness_utxo :  Some ( descriptor. output . clone ( ) ) , 
248+ 					..Default :: default ( ) 
249+ 				} 
250+ 			} , 
251+ 		} 
252+ 	} 
253+ 
254+ 	/// Creates an unsigned [`PartiallySignedTransaction`] which spends the given descriptors to 
255+  	/// the given outputs, plus an output to the given change destination (if sufficient 
256+  	/// change value remains). The PSBT will have a feerate, at least, of the given value. 
257+  	/// 
258+  	/// The `locktime` argument is used to set the transaction's locktime. If `None`, the 
259+  	/// transaction will have a locktime of 0. It it recommended to set this to the current block 
260+  	/// height to avoid fee sniping, unless you have some specific reason to use a different 
261+  	/// locktime. 
262+  	/// 
263+  	/// Returns the PSBT and expected max transaction weight. 
264+  	/// 
265+  	/// Returns `Err(())` if the output value is greater than the input value minus required fee, 
266+  	/// if a descriptor was duplicated, or if an output descriptor `script_pubkey` 
267+  	/// does not match the one we can spend. 
268+  	/// 
269+  	/// We do not enforce that outputs meet the dust limit or that any output scripts are standard. 
270+  	pub  fn  create_spendable_outputs_psbt ( descriptors :  & [ & SpendableOutputDescriptor ] ,  outputs :  Vec < TxOut > ,  change_destination_script :  Script ,  feerate_sat_per_1000_weight :  u32 ,  locktime :  Option < PackedLockTime > )  -> Result < ( PartiallySignedTransaction ,  usize ) ,  ( ) >  { 
271+ 		let  mut  input = Vec :: with_capacity ( descriptors. len ( ) ) ; 
272+ 		let  mut  input_value = 0 ; 
273+ 		let  mut  witness_weight = 0 ; 
274+ 		let  mut  output_set = HashSet :: with_capacity ( descriptors. len ( ) ) ; 
275+ 		for  outp in  descriptors { 
276+ 			match  outp { 
277+ 				SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor)  => { 
278+ 					if  !output_set. insert ( descriptor. outpoint )  {  return  Err ( ( ) ) ;  } 
279+ 					input. push ( TxIn  { 
280+ 						previous_output :  descriptor. outpoint . into_bitcoin_outpoint ( ) , 
281+ 						script_sig :  Script :: new ( ) , 
282+ 						sequence :  Sequence :: ZERO , 
283+ 						witness :  Witness :: new ( ) , 
284+ 					} ) ; 
285+ 					witness_weight += StaticPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ; 
286+ 					#[ cfg( feature = "grind_signatures" ) ]  
287+ 					{  witness_weight -= 1 ;  }  // Guarantees a low R signature 
288+ 					input_value += descriptor. output . value ; 
289+ 				} , 
290+ 				SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor)  => { 
291+ 					if  !output_set. insert ( descriptor. outpoint )  {  return  Err ( ( ) ) ;  } 
292+ 					input. push ( TxIn  { 
293+ 						previous_output :  descriptor. outpoint . into_bitcoin_outpoint ( ) , 
294+ 						script_sig :  Script :: new ( ) , 
295+ 						sequence :  Sequence ( descriptor. to_self_delay  as  u32 ) , 
296+ 						witness :  Witness :: new ( ) , 
297+ 					} ) ; 
298+ 					witness_weight += DelayedPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ; 
299+ 					#[ cfg( feature = "grind_signatures" ) ]  
300+ 					{  witness_weight -= 1 ;  }  // Guarantees a low R signature 
301+ 					input_value += descriptor. output . value ; 
302+ 				} , 
303+ 				SpendableOutputDescriptor :: StaticOutput  {  ref  outpoint,  ref  output }  => { 
304+ 					if  !output_set. insert ( * outpoint)  {  return  Err ( ( ) ) ;  } 
305+ 					input. push ( TxIn  { 
306+ 						previous_output :  outpoint. into_bitcoin_outpoint ( ) , 
307+ 						script_sig :  Script :: new ( ) , 
308+ 						sequence :  Sequence :: ZERO , 
309+ 						witness :  Witness :: new ( ) , 
310+ 					} ) ; 
311+ 					witness_weight += 1  + 73  + 34 ; 
312+ 					#[ cfg( feature = "grind_signatures" ) ]  
313+ 					{  witness_weight -= 1 ;  }  // Guarantees a low R signature 
314+ 					input_value += output. value ; 
315+ 				} 
316+ 			} 
317+ 			if  input_value > MAX_VALUE_MSAT  / 1000  {  return  Err ( ( ) ) ;  } 
318+ 		} 
319+ 		let  mut  tx = Transaction  { 
320+ 			version :  2 , 
321+ 			lock_time :  locktime. unwrap_or ( PackedLockTime :: ZERO ) , 
322+ 			input, 
323+ 			output :  outputs, 
324+ 		} ; 
325+ 		let  expected_max_weight =
326+ 			transaction_utils:: maybe_add_change_output ( & mut  tx,  input_value,  witness_weight,  feerate_sat_per_1000_weight,  change_destination_script) ?; 
327+ 
328+ 		let  psbt_inputs = descriptors. iter ( ) . map ( |d| d. to_psbt_input ( ) ) . collect :: < Vec < _ > > ( ) ; 
329+ 		let  psbt = PartiallySignedTransaction  { 
330+ 			inputs :  psbt_inputs, 
331+ 			outputs :  vec ! [ Default :: default ( ) ;  tx. output. len( ) ] , 
332+ 			unsigned_tx :  tx, 
333+ 			xpub :  Default :: default ( ) , 
334+ 			version :  0 , 
335+ 			proprietary :  Default :: default ( ) , 
336+ 			unknown :  Default :: default ( ) , 
337+ 		} ; 
338+ 		Ok ( ( psbt,  expected_max_weight) ) 
339+ 	} 
340+ } 
341+ 
221342/// A trait to handle Lightning channel key material without concretizing the channel type or 
222343/// the signature mechanism. 
223344pub  trait  ChannelSigner  { 
@@ -1171,97 +1292,40 @@ impl KeysManager {
11711292		) 
11721293	} 
11731294
1174- 	/// Creates a [`Transaction `] which spends the given descriptors to the given outputs, plus an  
1175-  	/// output to the given change destination (if sufficient change value remains). The  
1176-  	/// transaction will have a feerate, at least, of the given value . 
1295+ 	/// Signs the given [`PartiallySignedTransaction `] which spends the given [`SpendableOutputDescriptor`]s.  
1296+  	/// The resulting inputs will be finalized and the PSBT will be ready for broadcast if there  
1297+  	/// are no other inputs that need signing . 
11771298 	/// 
1178-  	/// Returns `Err(())` if the output value is greater than the input value minus required fee, 
1179-  	/// if a descriptor was duplicated, or if an output descriptor `script_pubkey` 
1180-  	/// does not match the one we can spend. 
1181-  	/// 
1182-  	/// We do not enforce that outputs meet the dust limit or that any output scripts are standard. 
1299+  	/// Returns `Err(())` if the PSBT is missing a descriptor or if we fail to sign. 
11831300 	/// 
11841301 	/// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used 
11851302 	/// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`]. 
1186-  	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 ,  ( ) >  { 
1187- 		let  mut  input = Vec :: new ( ) ; 
1188- 		let  mut  input_value = 0 ; 
1189- 		let  mut  witness_weight = 0 ; 
1190- 		let  mut  output_set = HashSet :: with_capacity ( descriptors. len ( ) ) ; 
1191- 		for  outp in  descriptors { 
1192- 			match  outp { 
1193- 				SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor)  => { 
1194- 					input. push ( TxIn  { 
1195- 						previous_output :  descriptor. outpoint . into_bitcoin_outpoint ( ) , 
1196- 						script_sig :  Script :: new ( ) , 
1197- 						sequence :  Sequence :: ZERO , 
1198- 						witness :  Witness :: new ( ) , 
1199- 					} ) ; 
1200- 					witness_weight += StaticPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ; 
1201- 					#[ cfg( feature = "grind_signatures" ) ]  
1202- 					{  witness_weight -= 1 ;  }  // Guarantees a low R signature 
1203- 					input_value += descriptor. output . value ; 
1204- 					if  !output_set. insert ( descriptor. outpoint )  {  return  Err ( ( ) ) ;  } 
1205- 				} , 
1206- 				SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor)  => { 
1207- 					input. push ( TxIn  { 
1208- 						previous_output :  descriptor. outpoint . into_bitcoin_outpoint ( ) , 
1209- 						script_sig :  Script :: new ( ) , 
1210- 						sequence :  Sequence ( descriptor. to_self_delay  as  u32 ) , 
1211- 						witness :  Witness :: new ( ) , 
1212- 					} ) ; 
1213- 					witness_weight += DelayedPaymentOutputDescriptor :: MAX_WITNESS_LENGTH ; 
1214- 					#[ cfg( feature = "grind_signatures" ) ]  
1215- 					{  witness_weight -= 1 ;  }  // Guarantees a low R signature 
1216- 					input_value += descriptor. output . value ; 
1217- 					if  !output_set. insert ( descriptor. outpoint )  {  return  Err ( ( ) ) ;  } 
1218- 				} , 
1219- 				SpendableOutputDescriptor :: StaticOutput  {  ref  outpoint,  ref  output }  => { 
1220- 					input. push ( TxIn  { 
1221- 						previous_output :  outpoint. into_bitcoin_outpoint ( ) , 
1222- 						script_sig :  Script :: new ( ) , 
1223- 						sequence :  Sequence :: ZERO , 
1224- 						witness :  Witness :: new ( ) , 
1225- 					} ) ; 
1226- 					witness_weight += 1  + 73  + 34 ; 
1227- 					#[ cfg( feature = "grind_signatures" ) ]  
1228- 					{  witness_weight -= 1 ;  }  // Guarantees a low R signature 
1229- 					input_value += output. value ; 
1230- 					if  !output_set. insert ( * outpoint)  {  return  Err ( ( ) ) ;  } 
1231- 				} 
1232- 			} 
1233- 			if  input_value > MAX_VALUE_MSAT  / 1000  {  return  Err ( ( ) ) ;  } 
1234- 		} 
1235- 		let  mut  spend_tx = Transaction  { 
1236- 			version :  2 , 
1237- 			lock_time :  PackedLockTime ( 0 ) , 
1238- 			input, 
1239- 			output :  outputs, 
1240- 		} ; 
1241- 		let  expected_max_weight =
1242- 			transaction_utils:: maybe_add_change_output ( & mut  spend_tx,  input_value,  witness_weight,  feerate_sat_per_1000_weight,  change_destination_script) ?; 
1243- 
1303+  	pub  fn  sign_spendable_outputs_psbt < C :  Signing > ( & self ,  descriptors :  & [ & SpendableOutputDescriptor ] ,  psbt :  & mut  PartiallySignedTransaction ,  secp_ctx :  & Secp256k1 < C > )  -> Result < ( ) ,  ( ) >  { 
12441304		let  mut  keys_cache:  Option < ( InMemorySigner ,  [ u8 ;  32 ] ) >  = None ; 
1245- 		let  mut  input_idx = 0 ; 
12461305		for  outp in  descriptors { 
12471306			match  outp { 
12481307				SpendableOutputDescriptor :: StaticPaymentOutput ( descriptor)  => { 
1308+ 					let  input_idx = psbt. unsigned_tx . input . iter ( ) . position ( |i| i. previous_output  == descriptor. outpoint . into_bitcoin_outpoint ( ) ) . ok_or ( ( ) ) ?; 
12491309					if  keys_cache. is_none ( )  || keys_cache. as_ref ( ) . unwrap ( ) . 1  != descriptor. channel_keys_id  { 
12501310						keys_cache = Some ( ( 
12511311							self . derive_channel_keys ( descriptor. channel_value_satoshis ,  & descriptor. channel_keys_id ) , 
12521312							descriptor. channel_keys_id ) ) ; 
12531313					} 
1254- 					spend_tx. input [ input_idx] . witness  = Witness :: from_vec ( keys_cache. as_ref ( ) . unwrap ( ) . 0 . sign_counterparty_payment_input ( & spend_tx,  input_idx,  & descriptor,  & secp_ctx) ?) ; 
1314+ 					let  witness = Witness :: from_vec ( keys_cache. as_ref ( ) . unwrap ( ) . 0 . sign_counterparty_payment_input ( & psbt. unsigned_tx ,  input_idx,  & descriptor,  & secp_ctx) ?) ; 
1315+ 					psbt. inputs [ input_idx] . final_script_witness  = Some ( witness) ; 
12551316				} , 
12561317				SpendableOutputDescriptor :: DelayedPaymentOutput ( descriptor)  => { 
1318+ 					let  input_idx = psbt. unsigned_tx . input . iter ( ) . position ( |i| i. previous_output  == descriptor. outpoint . into_bitcoin_outpoint ( ) ) . ok_or ( ( ) ) ?; 
12571319					if  keys_cache. is_none ( )  || keys_cache. as_ref ( ) . unwrap ( ) . 1  != descriptor. channel_keys_id  { 
12581320						keys_cache = Some ( ( 
12591321							self . derive_channel_keys ( descriptor. channel_value_satoshis ,  & descriptor. channel_keys_id ) , 
12601322							descriptor. channel_keys_id ) ) ; 
12611323					} 
1262- 					spend_tx. input [ input_idx] . witness  = Witness :: from_vec ( keys_cache. as_ref ( ) . unwrap ( ) . 0 . sign_dynamic_p2wsh_input ( & spend_tx,  input_idx,  & descriptor,  & secp_ctx) ?) ; 
1324+ 					let  witness = Witness :: from_vec ( keys_cache. as_ref ( ) . unwrap ( ) . 0 . sign_dynamic_p2wsh_input ( & psbt. unsigned_tx ,  input_idx,  & descriptor,  & secp_ctx) ?) ; 
1325+ 					psbt. inputs [ input_idx] . final_script_witness  = Some ( witness) ; 
12631326				} , 
1264- 				SpendableOutputDescriptor :: StaticOutput  {  ref  output,  .. }  => { 
1327+ 				SpendableOutputDescriptor :: StaticOutput  {  ref  outpoint,  ref  output }  => { 
1328+ 					let  input_idx = psbt. unsigned_tx . input . iter ( ) . position ( |i| i. previous_output  == outpoint. into_bitcoin_outpoint ( ) ) . ok_or ( ( ) ) ?; 
12651329					let  derivation_idx = if  output. script_pubkey  == self . destination_script  { 
12661330						1 
12671331					}  else  { 
@@ -1288,17 +1352,42 @@ impl KeysManager {
12881352
12891353					if  payment_script != output. script_pubkey  {  return  Err ( ( ) ) ;  } ; 
12901354
1291- 					let  sighash = hash_to_message ! ( & sighash:: SighashCache :: new( & spend_tx ) . segwit_signature_hash( input_idx,  & witness_script,  output. value,  EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ; 
1355+ 					let  sighash = hash_to_message ! ( & sighash:: SighashCache :: new( & psbt . unsigned_tx ) . segwit_signature_hash( input_idx,  & witness_script,  output. value,  EcdsaSighashType :: All ) . unwrap( ) [ ..] ) ; 
12921356					let  sig = sign_with_aux_rand ( secp_ctx,  & sighash,  & secret. private_key ,  & self ) ; 
12931357					let  mut  sig_ser = sig. serialize_der ( ) . to_vec ( ) ; 
12941358					sig_ser. push ( EcdsaSighashType :: All  as  u8 ) ; 
1295- 					spend_tx . input [ input_idx ] . witness . push ( sig_ser ) ; 
1296- 					spend_tx . input [ input_idx] . witness . push ( pubkey . inner . serialize ( ) . to_vec ( ) ) ; 
1359+ 					let  witness =  Witness :: from_vec ( vec ! [ sig_ser ,  pubkey . inner . serialize ( ) . to_vec ( ) ] ) ; 
1360+ 					psbt . inputs [ input_idx] . final_script_witness  =  Some ( witness ) ; 
12971361				} , 
12981362			} 
1299- 			input_idx += 1 ; 
13001363		} 
13011364
1365+ 		Ok ( ( ) ) 
1366+ 	} 
1367+ 
1368+ 	/// Creates a [`Transaction`] which spends the given descriptors to the given outputs, plus an 
1369+  	/// output to the given change destination (if sufficient change value remains). The 
1370+  	/// transaction will have a feerate, at least, of the given value. 
1371+  	/// 
1372+  	/// The `locktime` argument is used to set the transaction's locktime. If `None`, the 
1373+  	/// transaction will have a locktime of 0. It it recommended to set this to the current block 
1374+  	/// height to avoid fee sniping, unless you have some specific reason to use a different 
1375+  	/// locktime. 
1376+  	/// 
1377+  	/// Returns `Err(())` if the output value is greater than the input value minus required fee, 
1378+  	/// if a descriptor was duplicated, or if an output descriptor `script_pubkey` 
1379+  	/// does not match the one we can spend. 
1380+  	/// 
1381+  	/// We do not enforce that outputs meet the dust limit or that any output scripts are standard. 
1382+  	/// 
1383+  	/// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used 
1384+  	/// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`]. 
1385+  	pub  fn  spend_spendable_outputs < C :  Signing > ( & self ,  descriptors :  & [ & SpendableOutputDescriptor ] ,  outputs :  Vec < TxOut > ,  change_destination_script :  Script ,  feerate_sat_per_1000_weight :  u32 ,  locktime :  Option < PackedLockTime > ,  secp_ctx :  & Secp256k1 < C > )  -> Result < Transaction ,  ( ) >  { 
1386+ 		let  ( mut  psbt,  expected_max_weight)  = SpendableOutputDescriptor :: create_spendable_outputs_psbt ( descriptors,  outputs,  change_destination_script,  feerate_sat_per_1000_weight,  locktime) ?; 
1387+ 		self . sign_spendable_outputs_psbt ( descriptors,  & mut  psbt,  secp_ctx) ?; 
1388+ 
1389+ 		let  spend_tx = psbt. extract_tx ( ) ; 
1390+ 
13021391		debug_assert ! ( expected_max_weight >= spend_tx. weight( ) ) ; 
13031392		// Note that witnesses with a signature vary somewhat in size, so allow 
13041393		// `expected_max_weight` to overshoot by up to 3 bytes per input. 
@@ -1512,8 +1601,8 @@ impl PhantomKeysManager {
15121601	} 
15131602
15141603	/// See [`KeysManager::spend_spendable_outputs`] for documentation on this method. 
1515-  	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 ,  ( ) >  { 
1516- 		self . inner . spend_spendable_outputs ( descriptors,  outputs,  change_destination_script,  feerate_sat_per_1000_weight,  secp_ctx) 
1604+  	pub  fn  spend_spendable_outputs < C :  Signing > ( & self ,  descriptors :  & [ & SpendableOutputDescriptor ] ,  outputs :  Vec < TxOut > ,  change_destination_script :  Script ,  feerate_sat_per_1000_weight :  u32 ,  locktime :   Option < PackedLockTime > ,   secp_ctx :  & Secp256k1 < C > )  -> Result < Transaction ,  ( ) >  { 
1605+ 		self . inner . spend_spendable_outputs ( descriptors,  outputs,  change_destination_script,  feerate_sat_per_1000_weight,  locktime ,   secp_ctx) 
15171606	} 
15181607
15191608	/// See [`KeysManager::derive_channel_keys`] for documentation on this method. 
0 commit comments