@@ -161,16 +161,26 @@ fn test_psbt_fee_rate_with_missing_txout() {
161161fn test_psbt_multiple_internalkey_signers ( ) {
162162 use bdk:: signer:: { SignerContext , SignerOrdering , SignerWrapper } ;
163163 use bdk:: KeychainKind ;
164- use bitcoin:: { secp256k1:: Secp256k1 , PrivateKey } ;
165- use miniscript:: psbt:: PsbtExt ;
164+ use bitcoin:: key:: TapTweak ;
165+ use bitcoin:: secp256k1:: { schnorr, KeyPair , Message , Secp256k1 , XOnlyPublicKey } ;
166+ use bitcoin:: sighash:: { Prevouts , SighashCache , TapSighashType } ;
167+ use bitcoin:: { PrivateKey , TxOut } ;
166168 use std:: sync:: Arc ;
167169
168170 let secp = Secp256k1 :: new ( ) ;
169- let ( mut wallet, _) = get_funded_wallet ( get_test_tr_single_sig ( ) ) ;
171+ let wif = "cNJmN3fH9DDbDt131fQNkVakkpzawJBSeybCUNmP1BovpmGQ45xG" ;
172+ let desc = format ! ( "tr({})" , wif) ;
173+ let prv = PrivateKey :: from_wif ( wif) . unwrap ( ) ;
174+ let keypair = KeyPair :: from_secret_key ( & secp, & prv. inner ) ;
175+
176+ let ( mut wallet, _) = get_funded_wallet ( & desc) ;
177+ let to_spend = wallet. get_balance ( ) . total ( ) ;
170178 let send_to = wallet. get_address ( AddressIndex :: New ) ;
171179 let mut builder = wallet. build_tx ( ) ;
172- builder. add_recipient ( send_to. script_pubkey ( ) , 10_000 ) ;
180+ builder. drain_to ( send_to. script_pubkey ( ) ) . drain_wallet ( ) ;
173181 let mut psbt = builder. finish ( ) . unwrap ( ) ;
182+ let unsigned_tx = psbt. unsigned_tx . clone ( ) ;
183+
174184 // Adds a signer for the wrong internal key, bdk should not use this key to sign
175185 wallet. add_signer (
176186 KeychainKind :: External ,
@@ -183,10 +193,32 @@ fn test_psbt_multiple_internalkey_signers() {
183193 } ,
184194 ) ) ,
185195 ) ;
186- let _ = wallet. sign ( & mut psbt, SignOptions :: default ( ) ) . unwrap ( ) ;
187- // Checks that we signed using the right key
188- assert ! (
189- psbt. finalize_mut( & secp) . is_ok( ) ,
190- "The wrong internal key was used"
191- ) ;
196+ let finalized = wallet. sign ( & mut psbt, SignOptions :: default ( ) ) . unwrap ( ) ;
197+ assert ! ( finalized) ;
198+
199+ // To verify, we need the signature, message, and pubkey
200+ let witness = psbt. inputs [ 0 ] . final_script_witness . as_ref ( ) . unwrap ( ) ;
201+ assert ! ( !witness. is_empty( ) ) ;
202+ let signature = schnorr:: Signature :: from_slice ( witness. iter ( ) . next ( ) . unwrap ( ) ) . unwrap ( ) ;
203+
204+ // the prevout we're spending
205+ let prevouts = & [ TxOut {
206+ script_pubkey : send_to. script_pubkey ( ) ,
207+ value : to_spend,
208+ } ] ;
209+ let prevouts = Prevouts :: All ( prevouts) ;
210+ let input_index = 0 ;
211+ let mut sighash_cache = SighashCache :: new ( unsigned_tx) ;
212+ let sighash = sighash_cache
213+ . taproot_key_spend_signature_hash ( input_index, & prevouts, TapSighashType :: Default )
214+ . unwrap ( ) ;
215+ let message = Message :: from ( sighash) ;
216+
217+ // add tweak. this was taken from `signer::sign_psbt_schnorr`
218+ let keypair = keypair. tap_tweak ( & secp, None ) . to_inner ( ) ;
219+ let ( xonlykey, _parity) = XOnlyPublicKey :: from_keypair ( & keypair) ;
220+
221+ // Must verify if we used the correct key to sign
222+ let verify_res = secp. verify_schnorr ( & signature, & message, & xonlykey) ;
223+ assert ! ( verify_res. is_ok( ) , "The wrong internal key was used" ) ;
192224}
0 commit comments