]> Untitled Git - bdk/commitdiff
taproot-tests: Test taproot key and script spend in the blockchain tests
authorAlekos Filini <alekos.filini@gmail.com>
Wed, 18 May 2022 09:36:15 +0000 (11:36 +0200)
committerAlekos Filini <alekos.filini@gmail.com>
Wed, 1 Jun 2022 12:51:30 +0000 (14:51 +0200)
This is to ensure a Bitcoin node accepts our transactions

src/testutils/blockchain_tests.rs

index 556d98f64932dc6d5383b17cd2b13b7f49af3108..87a776302e47d2162bd5af7c48d858357a57626f 100644 (file)
@@ -387,11 +387,25 @@ macro_rules! bdk_blockchain_tests {
                 Wallet::new(&descriptors.0.to_string(), descriptors.1.as_ref(), Network::Regtest, MemoryDatabase::new()).unwrap()
             }
 
-            fn init_single_sig() -> (Wallet<MemoryDatabase>, $blockchain, (String, Option<String>), TestClient) {
+            enum WalletType {
+                WpkhSingleSig,
+                TaprootKeySpend,
+                TaprootScriptSpend,
+            }
+
+            fn init_wallet(ty: WalletType) -> (Wallet<MemoryDatabase>, $blockchain, (String, Option<String>), TestClient) {
                 let _ = env_logger::try_init();
 
-                let descriptors = testutils! {
-                    @descriptors ( "wpkh(Alice)" ) ( "wpkh(Alice)" ) ( @keys ( "Alice" => (@generate_xprv "/44'/0'/0'/0/*", "/44'/0'/0'/1/*") ) )
+                let descriptors = match ty {
+                    WalletType::WpkhSingleSig => testutils! {
+                        @descriptors ( "wpkh(Alice)" ) ( "wpkh(Alice)" ) ( @keys ( "Alice" => (@generate_xprv "/44'/0'/0'/0/*", "/44'/0'/0'/1/*") ) )
+                    },
+                    WalletType::TaprootKeySpend => testutils! {
+                        @descriptors ( "tr(Alice)" ) ( "tr(Alice)" ) ( @keys ( "Alice" => (@generate_xprv "/44'/0'/0'/0/*", "/44'/0'/0'/1/*") ) )
+                    },
+                    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/*") ) )
+                    }
                 };
 
                 let test_client = TestClient::default();
@@ -405,6 +419,10 @@ macro_rules! bdk_blockchain_tests {
                 (wallet, blockchain, descriptors, test_client)
             }
 
+            fn init_single_sig() -> (Wallet<MemoryDatabase>, $blockchain, (String, Option<String>), TestClient) {
+                init_wallet(WalletType::WpkhSingleSig)
+            }
+
             #[test]
             fn test_sync_simple() {
                 use std::ops::Deref;
@@ -1203,6 +1221,54 @@ macro_rules! bdk_blockchain_tests {
 
                 wallet.sync(&blockchain, SyncOptions::default()).unwrap();
             }
+
+            #[test]
+            fn test_taproot_key_spend() {
+                let (wallet, blockchain, descriptors, mut test_client) = init_wallet(WalletType::TaprootKeySpend);
+
+                let _ = test_client.receive(testutils! {
+                    @tx ( (@external descriptors, 0) => 50_000 )
+                });
+                wallet.sync(&blockchain, SyncOptions::default()).unwrap();
+                assert_eq!(wallet.get_balance().unwrap(), 50_000);
+
+                let tx = {
+                    let mut builder = wallet.build_tx();
+                    builder.add_recipient(test_client.get_node_address(None).script_pubkey(), 25_000);
+                    let (mut psbt, _details) = builder.finish().unwrap();
+                    wallet.sign(&mut psbt, Default::default()).unwrap();
+                    psbt.extract_tx()
+                };
+                blockchain.broadcast(&tx).unwrap();
+            }
+
+            #[test]
+            fn test_taproot_script_spend() {
+                let (wallet, blockchain, descriptors, mut test_client) = init_wallet(WalletType::TaprootScriptSpend);
+
+                let _ = test_client.receive(testutils! {
+                    @tx ( (@external descriptors, 0) => 50_000 ) ( @confirmations 6 )
+                });
+                wallet.sync(&blockchain, SyncOptions::default()).unwrap();
+                assert_eq!(wallet.get_balance().unwrap(), 50_000);
+
+                let ext_policy = wallet.policies(KeychainKind::External).unwrap().unwrap();
+                let int_policy = wallet.policies(KeychainKind::Internal).unwrap().unwrap();
+
+                let ext_path = vec![(ext_policy.id.clone(), vec![1])].into_iter().collect();
+                let int_path = vec![(int_policy.id.clone(), vec![1])].into_iter().collect();
+
+                let tx = {
+                    let mut builder = wallet.build_tx();
+                    builder.add_recipient(test_client.get_node_address(None).script_pubkey(), 25_000)
+                        .policy_path(ext_path, KeychainKind::External)
+                        .policy_path(int_path, KeychainKind::Internal);
+                    let (mut psbt, _details) = builder.finish().unwrap();
+                    wallet.sign(&mut psbt, Default::default()).unwrap();
+                    psbt.extract_tx()
+                };
+                blockchain.broadcast(&tx).unwrap();
+            }
         }
     };