@@ -34,7 +34,8 @@ use crate::ln::types::ChannelId;
3434use crate :: prelude:: * ;
3535use crate :: sign:: ecdsa:: EcdsaChannelSigner ;
3636use crate :: sign:: {
37- ChannelDerivationParameters , HTLCDescriptor , SignerProvider , P2WPKH_WITNESS_WEIGHT ,
37+ ChannelDerivationParameters , HTLCDescriptor , SignerProvider , P2TR_KEY_PATH_WITNESS_WEIGHT ,
38+ P2WPKH_WITNESS_WEIGHT ,
3839} ;
3940use crate :: sync:: Mutex ;
4041use crate :: util:: async_poll:: { MaybeSend , MaybeSync } ;
@@ -43,6 +44,7 @@ use crate::util::logger::Logger;
4344use bitcoin:: amount:: Amount ;
4445use bitcoin:: consensus:: Encodable ;
4546use bitcoin:: constants:: WITNESS_SCALE_FACTOR ;
47+ use bitcoin:: key:: TweakedPublicKey ;
4648use bitcoin:: locktime:: absolute:: LockTime ;
4749use bitcoin:: policy:: MAX_STANDARD_TX_WEIGHT ;
4850use bitcoin:: secp256k1;
@@ -332,6 +334,17 @@ impl Utxo {
332334 satisfaction_weight : EMPTY_SCRIPT_SIG_WEIGHT + P2WPKH_WITNESS_WEIGHT ,
333335 }
334336 }
337+
338+ /// Returns a `Utxo` with the `satisfaction_weight` estimate for a keypath spend of a SegWit v1 P2TR output.
339+ pub fn new_v1_p2tr (
340+ outpoint : OutPoint , value : Amount , tweaked_public_key : TweakedPublicKey ,
341+ ) -> Self {
342+ Self {
343+ outpoint,
344+ output : TxOut { value, script_pubkey : ScriptBuf :: new_p2tr_tweaked ( tweaked_public_key) } ,
345+ satisfaction_weight : EMPTY_SCRIPT_SIG_WEIGHT + P2TR_KEY_PATH_WITNESS_WEIGHT ,
346+ }
347+ }
335348}
336349
337350/// The result of a successful coin selection attempt for a transaction requiring additional UTXOs
@@ -1272,7 +1285,9 @@ mod tests {
12721285
12731286 use bitcoin:: hashes:: Hash ;
12741287 use bitcoin:: hex:: FromHex ;
1275- use bitcoin:: { Network , ScriptBuf , Transaction , Txid } ;
1288+ use bitcoin:: {
1289+ Network , ScriptBuf , Transaction , Txid , WitnessProgram , WitnessVersion , XOnlyPublicKey ,
1290+ } ;
12761291
12771292 struct TestCoinSelectionSource {
12781293 // (commitment + anchor value, commitment + input weight, target feerate, result)
@@ -1389,4 +1404,30 @@ mod tests {
13891404 pending_htlcs : Vec :: new ( ) ,
13901405 } ) ;
13911406 }
1407+
1408+ #[ test]
1409+ fn test_utxo_new_v1_p2tr ( ) {
1410+ // Transaction 33e794d097969002ee05d336686fc03c9e15a597c1b9827669460fac98799036
1411+ let p2tr_tx: Transaction = bitcoin:: consensus:: deserialize ( & <Vec < u8 > >:: from_hex ( "01000000000101d1f1c1f8cdf6759167b90f52c9ad358a369f95284e841d7a2536cef31c0549580100000000fdffffff020000000000000000316a2f49206c696b65205363686e6f7272207369677320616e6420492063616e6e6f74206c69652e204062697462756734329e06010000000000225120a37c3903c8d0db6512e2b40b0dffa05e5a3ab73603ce8c9c4b7771e5412328f90140a60c383f71bac0ec919b1d7dbc3eb72dd56e7aa99583615564f9f99b8ae4e837b758773a5b2e4c51348854c8389f008e05029db7f464a5ff2e01d5e6e626174affd30a00" ) . unwrap ( ) ) . unwrap ( ) ;
1412+
1413+ let script_pubkey = & p2tr_tx. output [ 1 ] . script_pubkey ;
1414+ assert_eq ! ( script_pubkey. witness_version( ) , Some ( WitnessVersion :: V1 ) ) ;
1415+ let witness_bytes = & script_pubkey. as_bytes ( ) [ 2 ..] ;
1416+ let witness_program = WitnessProgram :: new ( WitnessVersion :: V1 , witness_bytes) . unwrap ( ) ;
1417+ let tweaked_key = TweakedPublicKey :: dangerous_assume_tweaked (
1418+ XOnlyPublicKey :: from_slice ( & witness_program. program ( ) . as_bytes ( ) ) . unwrap ( ) ,
1419+ ) ;
1420+
1421+ let utxo = Utxo :: new_v1_p2tr (
1422+ OutPoint { txid : p2tr_tx. compute_txid ( ) , vout : 1 } ,
1423+ p2tr_tx. output [ 1 ] . value ,
1424+ tweaked_key,
1425+ ) ;
1426+ assert_eq ! ( utxo. output, p2tr_tx. output[ 1 ] ) ;
1427+ assert_eq ! (
1428+ utxo. satisfaction_weight,
1429+ 1 /* empty script_sig */ * WITNESS_SCALE_FACTOR as u64 +
1430+ 1 /* witness items */ + 1 /* schnorr sig len */ + 64 /* schnorr sig */
1431+ ) ;
1432+ }
13921433}
0 commit comments