From c1bfaf9b1ebd92ac8952afd0d5867897672acfb4 Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Tue, 24 May 2022 19:26:41 -0700 Subject: [PATCH] Add blockchain tests for parsing, signing, finalizing taproot core psbts --- src/testutils/blockchain_tests.rs | 86 ++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/src/testutils/blockchain_tests.rs b/src/testutils/blockchain_tests.rs index 87a77630..297f2677 100644 --- a/src/testutils/blockchain_tests.rs +++ b/src/testutils/blockchain_tests.rs @@ -391,6 +391,8 @@ macro_rules! bdk_blockchain_tests { WpkhSingleSig, TaprootKeySpend, TaprootScriptSpend, + TaprootScriptSpend2, + TaprootScriptSpend3, } fn init_wallet(ty: WalletType) -> (Wallet, $blockchain, (String, Option), TestClient) { @@ -405,7 +407,13 @@ macro_rules! bdk_blockchain_tests { }, WalletType::TaprootScriptSpend => testutils! { @descriptors ( "tr(Key,and_v(v:pk(Script),older(6)))" ) ( "tr(Key,and_v(v:pk(Script),older(6)))" ) ( @keys ( "Key" => (@literal "30e14486f993d5a2d222770e97286c56cec5af115e1fb2e0065f476a0fcf8788"), "Script" => (@generate_xprv "/0/*", "/1/*") ) ) - } + }, + WalletType::TaprootScriptSpend2 => testutils! { + @descriptors ( "tr(Alice,pk(Bob))" ) ( "tr(Alice,pk(Bob))" ) ( @keys ( "Alice" => (@literal "30e14486f993d5a2d222770e97286c56cec5af115e1fb2e0065f476a0fcf8788"), "Bob" => (@generate_xprv "/0/*", "/1/*") ) ) + }, + WalletType::TaprootScriptSpend3 => testutils! { + @descriptors ( "tr(Alice,{pk(Bob),pk(Carol)})" ) ( "tr(Alice,{pk(Bob),pk(Carol)})" ) ( @keys ( "Alice" => (@literal "30e14486f993d5a2d222770e97286c56cec5af115e1fb2e0065f476a0fcf8788"), "Bob" => (@generate_xprv "/0/*", "/1/*"), "Carol" => (@generate_xprv "/0/*", "/1/*") ) ) + }, }; let test_client = TestClient::default(); @@ -1269,6 +1277,82 @@ macro_rules! bdk_blockchain_tests { }; blockchain.broadcast(&tx).unwrap(); } + + #[test] + fn test_sign_taproot_core_keyspend_psbt() { + test_sign_taproot_core_psbt(WalletType::TaprootKeySpend); + } + + #[test] + fn test_sign_taproot_core_scriptspend2_psbt() { + test_sign_taproot_core_psbt(WalletType::TaprootScriptSpend2); + } + + #[test] + fn test_sign_taproot_core_scriptspend3_psbt() { + test_sign_taproot_core_psbt(WalletType::TaprootScriptSpend3); + } + + fn test_sign_taproot_core_psbt(wallet_type: WalletType) { + use std::str::FromStr; + use serde_json; + use bitcoincore_rpc::jsonrpc::serde_json::Value; + use bitcoincore_rpc::{Auth, Client, RpcApi}; + + let (wallet, _blockchain, _descriptors, test_client) = init_wallet(wallet_type); + + // TODO replace once rust-bitcoincore-rpc with PR 174 released + // https://github.com/rust-bitcoin/rust-bitcoincore-rpc/pull/174 + let _createwallet_result: Value = test_client.bitcoind.client.call("createwallet", &["taproot_wallet".into(), true.into(), true.into(), serde_json::to_value("").unwrap(), false.into(), true.into(), true.into(), false.into()]).expect("created wallet"); + + let external_descriptor = wallet.get_descriptor_for_keychain(KeychainKind::External); + + // TODO replace once bitcoind released with support for rust-bitcoincore-rpc PR 174 + let taproot_wallet_client = Client::new(&test_client.bitcoind.rpc_url_with_wallet("taproot_wallet"), Auth::CookieFile(test_client.bitcoind.params.cookie_file.clone())).unwrap(); + + let descriptor_info = taproot_wallet_client.get_descriptor_info(external_descriptor.to_string().as_str()).expect("descriptor info"); + + let import_descriptor_args = json!([{ + "desc": descriptor_info.descriptor, + "active": true, + "timestamp": "now", + "label":"taproot key spend", + }]); + let _importdescriptors_result: Value = taproot_wallet_client.call("importdescriptors", &[import_descriptor_args]).expect("import wallet"); + let generate_to_address: bitcoin::Address = taproot_wallet_client.call("getnewaddress", &["test address".into(), "bech32m".into()]).expect("new address"); + let _generatetoaddress_result = taproot_wallet_client.generate_to_address(101, &generate_to_address).expect("generated to address"); + let send_to_address = wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address.to_string(); + let change_address = wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address.to_string(); + let send_addr_amounts = json!([{ + send_to_address: "0.4321" + }]); + let send_options = json!({ + "change_address": change_address, + "psbt": true, + }); + let send_result: Value = taproot_wallet_client.call("send", &[send_addr_amounts, Value::Null, "unset".into(), Value::Null, send_options]).expect("send psbt"); + let core_psbt = send_result["psbt"].as_str().expect("core psbt str"); + + use bitcoin::util::psbt::PartiallySignedTransaction; + + // Test parsing core created PSBT + let mut psbt = PartiallySignedTransaction::from_str(&core_psbt).expect("core taproot psbt"); + + // Test signing core created PSBT + let finalized = wallet.sign(&mut psbt, Default::default()).unwrap(); + assert_eq!(finalized, true); + + // Test with updated psbt + let update_result: Value = taproot_wallet_client.call("utxoupdatepsbt", &[core_psbt.into()]).expect("update psbt utxos"); + let core_updated_psbt = update_result.as_str().expect("core updated psbt"); + + // Test parsing core created and updated PSBT + let mut psbt = PartiallySignedTransaction::from_str(&core_updated_psbt).expect("core taproot psbt"); + + // Test signing core created and updated PSBT + let finalized = wallet.sign(&mut psbt, Default::default()).unwrap(); + assert_eq!(finalized, true); + } } };