@@ -1850,7 +1850,7 @@ pub(crate) mod test {
18501850 }
18511851
18521852 pub ( crate ) fn get_test_tr_single_sig ( ) -> & ' static str {
1853- "tr(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/* )"
1853+ "tr(cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG )"
18541854 }
18551855
18561856 pub ( crate ) fn get_test_tr_with_taptree ( ) -> & ' static str {
@@ -1861,6 +1861,14 @@ pub(crate) mod test {
18611861 "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(100)),and_v(v:pk(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW),after(200))})"
18621862 }
18631863
1864+ pub ( crate ) fn get_test_tr_single_sig_xprv ( ) -> & ' static str {
1865+ "tr(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*)"
1866+ }
1867+
1868+ pub ( crate ) fn get_test_tr_with_taptree_xprv ( ) -> & ' static str {
1869+ "tr(b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55,{pk(tprv8ZgxMBicQKsPdDArR4xSAECuVxeX1jwwSXR4ApKbkYgZiziDc4LdBy2WvJeGDfUSE4UT4hHhbgEwbdq8ajjUHiKDegkwrNU6V55CxcxonVN/*),pk(8aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642)})"
1870+ }
1871+
18641872 macro_rules! assert_fee_rate {
18651873 ( $tx: expr, $fees: expr, $fee_rate: expr $( , @dust_change $( $dust_change: expr ) * ) * $( , @add_signature $( $add_signature: expr ) * ) * ) => ( {
18661874 let mut tx = $tx. clone( ) ;
@@ -4180,7 +4188,7 @@ pub(crate) mod test {
41804188
41814189 #[ test]
41824190 fn test_taproot_psbt_populate_tap_key_origins ( ) {
4183- let ( wallet, _, _) = get_funded_wallet ( get_test_tr_single_sig ( ) ) ;
4191+ let ( wallet, _, _) = get_funded_wallet ( get_test_tr_single_sig_xprv ( ) ) ;
41844192 let addr = wallet. get_address ( AddressIndex :: New ) . unwrap ( ) ;
41854193
41864194 let mut builder = wallet. build_tx ( ) ;
@@ -4317,9 +4325,7 @@ pub(crate) mod test {
43174325 ) ;
43184326 }
43194327
4320- #[ test]
4321- fn test_taproot_key_spend ( ) {
4322- let ( wallet, _, _) = get_funded_wallet ( get_test_tr_single_sig ( ) ) ;
4328+ fn test_spend_from_wallet ( wallet : Wallet < AnyDatabase > ) {
43234329 let addr = wallet. get_address ( AddressIndex :: New ) . unwrap ( ) ;
43244330
43254331 let mut builder = wallet. build_tx ( ) ;
@@ -4328,22 +4334,120 @@ pub(crate) mod test {
43284334
43294335 assert ! (
43304336 wallet. sign( & mut psbt, Default :: default ( ) ) . unwrap( ) ,
4331- "Unable to finalize taproot key spend "
4337+ "Unable to finalize tx "
43324338 ) ;
43334339 }
43344340
4341+ #[ test]
4342+ fn test_taproot_key_spend ( ) {
4343+ let ( wallet, _, _) = get_funded_wallet ( get_test_tr_single_sig ( ) ) ;
4344+ test_spend_from_wallet ( wallet) ;
4345+
4346+ let ( wallet, _, _) = get_funded_wallet ( get_test_tr_single_sig_xprv ( ) ) ;
4347+ test_spend_from_wallet ( wallet) ;
4348+ }
4349+
43354350 #[ test]
43364351 fn test_taproot_script_spend ( ) {
43374352 let ( wallet, _, _) = get_funded_wallet ( get_test_tr_with_taptree ( ) ) ;
4353+ test_spend_from_wallet ( wallet) ;
4354+
4355+ let ( wallet, _, _) = get_funded_wallet ( get_test_tr_with_taptree_xprv ( ) ) ;
4356+ test_spend_from_wallet ( wallet) ;
4357+ }
4358+
4359+ #[ test]
4360+ fn test_taproot_sign_derive_index_from_psbt ( ) {
4361+ env_logger:: init ( ) ;
4362+
4363+ let ( wallet, _, _) = get_funded_wallet ( get_test_tr_single_sig_xprv ( ) ) ;
4364+
43384365 let addr = wallet. get_address ( AddressIndex :: New ) . unwrap ( ) ;
43394366
43404367 let mut builder = wallet. build_tx ( ) ;
43414368 builder. add_recipient ( addr. script_pubkey ( ) , 25_000 ) ;
43424369 let ( mut psbt, _) = builder. finish ( ) . unwrap ( ) ;
43434370
4371+ // re-create the wallet with an empty db
4372+ let wallet_empty = Wallet :: new (
4373+ get_test_tr_single_sig_xprv ( ) ,
4374+ None ,
4375+ Network :: Regtest ,
4376+ AnyDatabase :: Memory ( MemoryDatabase :: new ( ) ) ,
4377+ )
4378+ . unwrap ( ) ;
4379+
4380+ // signing with an empty db means that we will only look at the psbt to infer the
4381+ // derivation index
43444382 assert ! (
4345- wallet. sign( & mut psbt, Default :: default ( ) ) . unwrap( ) ,
4346- "Unable to finalize taproot script spend"
4383+ wallet_empty. sign( & mut psbt, Default :: default ( ) ) . unwrap( ) ,
4384+ "Unable to finalize tx"
4385+ ) ;
4386+ }
4387+
4388+ #[ test]
4389+ fn test_taproot_sign_explicit_sighash_all ( ) {
4390+ let ( wallet, _, _) = get_funded_wallet ( get_test_tr_single_sig ( ) ) ;
4391+ let addr = wallet. get_address ( New ) . unwrap ( ) ;
4392+ let mut builder = wallet. build_tx ( ) ;
4393+ builder
4394+ . drain_to ( addr. script_pubkey ( ) )
4395+ . sighash ( SchnorrSighashType :: All . into ( ) )
4396+ . drain_wallet ( ) ;
4397+ let ( mut psbt, _) = builder. finish ( ) . unwrap ( ) ;
4398+
4399+ let result = wallet. sign ( & mut psbt, Default :: default ( ) ) ;
4400+ assert ! (
4401+ result. is_ok( ) ,
4402+ "Signing should work because SIGHASH_ALL is safe"
4403+ )
4404+ }
4405+
4406+ #[ test]
4407+ fn test_taproot_sign_non_default_sighash ( ) {
4408+ let sighash = SchnorrSighashType :: NonePlusAnyoneCanPay ;
4409+
4410+ let ( wallet, _, _) = get_funded_wallet ( get_test_tr_single_sig ( ) ) ;
4411+ let addr = wallet. get_address ( New ) . unwrap ( ) ;
4412+ let mut builder = wallet. build_tx ( ) ;
4413+ builder
4414+ . drain_to ( addr. script_pubkey ( ) )
4415+ . sighash ( sighash. into ( ) )
4416+ . drain_wallet ( ) ;
4417+ let ( mut psbt, _) = builder. finish ( ) . unwrap ( ) ;
4418+
4419+ let result = wallet. sign ( & mut psbt, Default :: default ( ) ) ;
4420+ assert ! (
4421+ result. is_err( ) ,
4422+ "Signing should have failed because the TX uses non-standard sighashes"
4423+ ) ;
4424+ assert ! (
4425+ matches!(
4426+ result. unwrap_err( ) ,
4427+ Error :: Signer ( SignerError :: NonStandardSighash )
4428+ ) ,
4429+ "Signing failed with the wrong error type"
4430+ ) ;
4431+
4432+ // try again after opting-in
4433+ let result = wallet. sign (
4434+ & mut psbt,
4435+ SignOptions {
4436+ allow_all_sighashes : true ,
4437+ ..Default :: default ( )
4438+ } ,
4439+ ) ;
4440+ assert ! ( result. is_ok( ) , "Signing should have worked" ) ;
4441+ assert ! (
4442+ result. unwrap( ) ,
4443+ "Should finalize the input since we can produce signatures"
4444+ ) ;
4445+
4446+ let extracted = psbt. extract_tx ( ) ;
4447+ assert_eq ! (
4448+ * extracted. input[ 0 ] . witness. to_vec( ) [ 0 ] . last( ) . unwrap( ) ,
4449+ sighash as u8 ,
4450+ "The signature should have been made with the right sighash"
43474451 ) ;
43484452 }
43494453}
0 commit comments