rpc: use importdescriptors with Core >= 0.21
				
					
				
			Only use the old `importmulti` with Core versions that don't support descriptor-based (sqlite) wallets. Add an extra feature to test against Core 0.20 called `test-rpc-legacy`
This commit is contained in:
		
							parent
							
								
									32699234b6
								
							
						
					
					
						commit
						e1a1372bae
					
				
							
								
								
									
										3
									
								
								.github/workflows/cont_integration.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/cont_integration.yml
									
									
									
									
										vendored
									
									
								
							| @ -95,6 +95,9 @@ jobs: | |||||||
|           - name: rpc |           - name: rpc | ||||||
|             testprefix: blockchain::rpc::test |             testprefix: blockchain::rpc::test | ||||||
|             features: test-rpc |             features: test-rpc | ||||||
|  |           - name: rpc-legacy | ||||||
|  |             testprefix: blockchain::rpc::test | ||||||
|  |             features: test-rpc-legacy | ||||||
|           - name: esplora |           - name: esplora | ||||||
|             testprefix: esplora |             testprefix: esplora | ||||||
|             features: test-esplora,use-esplora-reqwest,verify |             features: test-esplora,use-esplora-reqwest,verify | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||||||
|   - Creation of Taproot PSBTs (BIP-371) |   - Creation of Taproot PSBTs (BIP-371) | ||||||
|   - Signing Taproot PSBTs (key spend and script spend) |   - Signing Taproot PSBTs (key spend and script spend) | ||||||
|   - Support for `tr()` descriptors in the `descriptor!()` macro |   - Support for `tr()` descriptors in the `descriptor!()` macro | ||||||
|  | - Add support for Bitcoin Core 23.0 when using the `rpc` blockchain | ||||||
| 
 | 
 | ||||||
| ## [v0.18.0] - [v0.17.0] | ## [v0.18.0] - [v0.17.0] | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -88,16 +88,17 @@ reqwest-default-tls = ["reqwest/default-tls"] | |||||||
| 
 | 
 | ||||||
| # Debug/Test features | # Debug/Test features | ||||||
| test-blockchains = ["bitcoincore-rpc", "electrum-client"] | test-blockchains = ["bitcoincore-rpc", "electrum-client"] | ||||||
| test-electrum = ["electrum", "electrsd/electrs_0_8_10", "test-blockchains"] | test-electrum = ["electrum", "electrsd/electrs_0_8_10", "electrsd/bitcoind_22_0", "test-blockchains"] | ||||||
| test-rpc = ["rpc", "electrsd/electrs_0_8_10", "test-blockchains"] | test-rpc = ["rpc", "electrsd/electrs_0_8_10", "electrsd/bitcoind_22_0", "test-blockchains"] | ||||||
| test-esplora = ["electrsd/legacy", "electrsd/esplora_a33e97e1", "test-blockchains"] | test-rpc-legacy = ["rpc", "electrsd/electrs_0_8_10", "electrsd/bitcoind_0_20_0", "test-blockchains"] | ||||||
|  | test-esplora = ["electrsd/legacy", "electrsd/esplora_a33e97e1", "electrsd/bitcoind_22_0", "test-blockchains"] | ||||||
| test-md-docs = ["electrum"] | test-md-docs = ["electrum"] | ||||||
| 
 | 
 | ||||||
| [dev-dependencies] | [dev-dependencies] | ||||||
| lazy_static = "1.4" | lazy_static = "1.4" | ||||||
| env_logger = "0.7" | env_logger = "0.7" | ||||||
| clap = "2.33" | clap = "2.33" | ||||||
| electrsd = { version= "0.19.1", features = ["bitcoind_22_0"] } | electrsd = "0.19.1" | ||||||
| 
 | 
 | ||||||
| [[example]] | [[example]] | ||||||
| name = "address_validator" | name = "address_validator" | ||||||
|  | |||||||
| @ -166,7 +166,7 @@ Integration testing require testing features, for example: | |||||||
| cargo test --features test-electrum | cargo test --features test-electrum | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| The other options are `test-esplora` or `test-rpc`. | The other options are `test-esplora`, `test-rpc` or `test-rpc-legacy` which runs against an older version of Bitcoin Core. | ||||||
| Note that `electrs` and `bitcoind` binaries are automatically downloaded (on mac and linux), to specify you already have installed binaries you must use `--no-default-features` and provide `BITCOIND_EXE` and `ELECTRS_EXE` as environment variables. | Note that `electrs` and `bitcoind` binaries are automatically downloaded (on mac and linux), to specify you already have installed binaries you must use `--no-default-features` and provide `BITCOIND_EXE` and `ELECTRS_EXE` as environment variables. | ||||||
| 
 | 
 | ||||||
| ## License | ## License | ||||||
|  | |||||||
| @ -32,15 +32,17 @@ | |||||||
| //! ```
 | //! ```
 | ||||||
| 
 | 
 | ||||||
| use crate::bitcoin::consensus::deserialize; | use crate::bitcoin::consensus::deserialize; | ||||||
|  | use crate::bitcoin::hashes::hex::ToHex; | ||||||
| use crate::bitcoin::{Address, Network, OutPoint, Transaction, TxOut, Txid}; | use crate::bitcoin::{Address, Network, OutPoint, Transaction, TxOut, Txid}; | ||||||
| use crate::blockchain::*; | use crate::blockchain::*; | ||||||
| use crate::database::{BatchDatabase, DatabaseUtils}; | use crate::database::{BatchDatabase, DatabaseUtils}; | ||||||
|  | use crate::descriptor::get_checksum; | ||||||
| use crate::{BlockTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails}; | use crate::{BlockTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails}; | ||||||
| use bitcoincore_rpc::json::{ | use bitcoincore_rpc::json::{ | ||||||
|     GetAddressInfoResultLabel, ImportMultiOptions, ImportMultiRequest, |     GetAddressInfoResultLabel, ImportMultiOptions, ImportMultiRequest, | ||||||
|     ImportMultiRequestScriptPubkey, ImportMultiRescanSince, |     ImportMultiRequestScriptPubkey, ImportMultiRescanSince, | ||||||
| }; | }; | ||||||
| use bitcoincore_rpc::jsonrpc::serde_json::Value; | use bitcoincore_rpc::jsonrpc::serde_json::{json, Value}; | ||||||
| use bitcoincore_rpc::Auth as RpcAuth; | use bitcoincore_rpc::Auth as RpcAuth; | ||||||
| use bitcoincore_rpc::{Client, RpcApi}; | use bitcoincore_rpc::{Client, RpcApi}; | ||||||
| use log::debug; | use log::debug; | ||||||
| @ -54,6 +56,8 @@ use std::str::FromStr; | |||||||
| pub struct RpcBlockchain { | pub struct RpcBlockchain { | ||||||
|     /// Rpc client to the node, includes the wallet name
 |     /// Rpc client to the node, includes the wallet name
 | ||||||
|     client: Client, |     client: Client, | ||||||
|  |     /// Whether the wallet is a "descriptor" or "legacy" wallet in Core
 | ||||||
|  |     is_descriptors: bool, | ||||||
|     /// Blockchain capabilities, cached here at startup
 |     /// Blockchain capabilities, cached here at startup
 | ||||||
|     capabilities: HashSet<Capability>, |     capabilities: HashSet<Capability>, | ||||||
|     /// Skip this many blocks of the blockchain at the first rescan, if None the rescan is done from the genesis block
 |     /// Skip this many blocks of the blockchain at the first rescan, if None the rescan is done from the genesis block
 | ||||||
| @ -177,6 +181,39 @@ impl WalletSync for RpcBlockchain { | |||||||
|             "importing {} script_pubkeys (some maybe already imported)", |             "importing {} script_pubkeys (some maybe already imported)", | ||||||
|             scripts_pubkeys.len() |             scripts_pubkeys.len() | ||||||
|         ); |         ); | ||||||
|  | 
 | ||||||
|  |         if self.is_descriptors { | ||||||
|  |             // Core still doesn't support complex descriptors like BDK, but when the wallet type is
 | ||||||
|  |             // "descriptors" we should import individual addresses using `importdescriptors` rather
 | ||||||
|  |             // than `importmulti`, using the `raw()` descriptor which allows us to specify an
 | ||||||
|  |             // arbitrary script
 | ||||||
|  |             let requests = Value::Array( | ||||||
|  |                 scripts_pubkeys | ||||||
|  |                     .iter() | ||||||
|  |                     .map(|s| { | ||||||
|  |                         let desc = format!("raw({})", s.to_hex()); | ||||||
|  |                         json!({ | ||||||
|  |                             "timestamp": "now", | ||||||
|  |                             "desc": format!("{}#{}", desc, get_checksum(&desc).unwrap()), | ||||||
|  |                         }) | ||||||
|  |                     }) | ||||||
|  |                     .collect(), | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |             let res: Vec<Value> = self.client.call("importdescriptors", &[requests])?; | ||||||
|  |             res.into_iter() | ||||||
|  |                 .map(|v| match v["success"].as_bool() { | ||||||
|  |                     Some(true) => Ok(()), | ||||||
|  |                     Some(false) => Err(Error::Generic( | ||||||
|  |                         v["error"]["message"] | ||||||
|  |                             .as_str() | ||||||
|  |                             .unwrap_or("Unknown error") | ||||||
|  |                             .to_string(), | ||||||
|  |                     )), | ||||||
|  |                     _ => Err(Error::Generic("Unexpected response from Core".to_string())), | ||||||
|  |                 }) | ||||||
|  |                 .collect::<Result<Vec<_>, _>>()?; | ||||||
|  |         } else { | ||||||
|             let requests: Vec<_> = scripts_pubkeys |             let requests: Vec<_> = scripts_pubkeys | ||||||
|                 .iter() |                 .iter() | ||||||
|                 .map(|s| ImportMultiRequest { |                 .map(|s| ImportMultiRequest { | ||||||
| @ -189,10 +226,8 @@ impl WalletSync for RpcBlockchain { | |||||||
|             let options = ImportMultiOptions { |             let options = ImportMultiOptions { | ||||||
|                 rescan: Some(false), |                 rescan: Some(false), | ||||||
|             }; |             }; | ||||||
|         // Note we use import_multi because as of bitcoin core 0.21.0 many descriptors are not supported
 |  | ||||||
|         // https://bitcoindevkit.org/descriptors/#compatibility-matrix
 |  | ||||||
|         //TODO maybe convenient using import_descriptor for compatible descriptor and import_multi as fallback
 |  | ||||||
|             self.client.import_multi(&requests, Some(&options))?; |             self.client.import_multi(&requests, Some(&options))?; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         loop { |         loop { | ||||||
|             let current_height = self.get_height()?; |             let current_height = self.get_height()?; | ||||||
| @ -369,19 +404,35 @@ impl ConfigurableBlockchain for RpcBlockchain { | |||||||
|         debug!("connecting to {} auth:{:?}", wallet_url, config.auth); |         debug!("connecting to {} auth:{:?}", wallet_url, config.auth); | ||||||
| 
 | 
 | ||||||
|         let client = Client::new(wallet_url.as_str(), config.auth.clone().into())?; |         let client = Client::new(wallet_url.as_str(), config.auth.clone().into())?; | ||||||
|  |         let rpc_version = client.version()?; | ||||||
|  | 
 | ||||||
|         let loaded_wallets = client.list_wallets()?; |         let loaded_wallets = client.list_wallets()?; | ||||||
|         if loaded_wallets.contains(&wallet_name) { |         if loaded_wallets.contains(&wallet_name) { | ||||||
|             debug!("wallet already loaded {:?}", wallet_name); |             debug!("wallet already loaded {:?}", wallet_name); | ||||||
|         } else { |         } else if list_wallet_dir(&client)?.contains(&wallet_name) { | ||||||
|             let existing_wallets = list_wallet_dir(&client)?; |  | ||||||
|             if existing_wallets.contains(&wallet_name) { |  | ||||||
|             client.load_wallet(&wallet_name)?; |             client.load_wallet(&wallet_name)?; | ||||||
|             debug!("wallet loaded {:?}", wallet_name); |             debug!("wallet loaded {:?}", wallet_name); | ||||||
|         } else { |         } else { | ||||||
|  |             // pre-0.21 use legacy wallets
 | ||||||
|  |             if rpc_version < 210_000 { | ||||||
|                 client.create_wallet(&wallet_name, Some(true), None, None, None)?; |                 client.create_wallet(&wallet_name, Some(true), None, None, None)?; | ||||||
|  |             } else { | ||||||
|  |                 // TODO: move back to api call when https://github.com/rust-bitcoin/rust-bitcoincore-rpc/issues/225 is closed
 | ||||||
|  |                 let args = [ | ||||||
|  |                     Value::String(wallet_name.clone()), | ||||||
|  |                     Value::Bool(true), | ||||||
|  |                     Value::Bool(false), | ||||||
|  |                     Value::Null, | ||||||
|  |                     Value::Bool(false), | ||||||
|  |                     Value::Bool(true), | ||||||
|  |                 ]; | ||||||
|  |                 let _: Value = client.call("createwallet", &args)?; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             debug!("wallet created {:?}", wallet_name); |             debug!("wallet created {:?}", wallet_name); | ||||||
|         } |         } | ||||||
|         } | 
 | ||||||
|  |         let is_descriptors = is_wallet_descriptor(&client)?; | ||||||
| 
 | 
 | ||||||
|         let blockchain_info = client.get_blockchain_info()?; |         let blockchain_info = client.get_blockchain_info()?; | ||||||
|         let network = match blockchain_info.chain.as_str() { |         let network = match blockchain_info.chain.as_str() { | ||||||
| @ -399,7 +450,6 @@ impl ConfigurableBlockchain for RpcBlockchain { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let mut capabilities: HashSet<_> = vec![Capability::FullHistory].into_iter().collect(); |         let mut capabilities: HashSet<_> = vec![Capability::FullHistory].into_iter().collect(); | ||||||
|         let rpc_version = client.version()?; |  | ||||||
|         if rpc_version >= 210_000 { |         if rpc_version >= 210_000 { | ||||||
|             let info: HashMap<String, Value> = client.call("getindexinfo", &[]).unwrap(); |             let info: HashMap<String, Value> = client.call("getindexinfo", &[]).unwrap(); | ||||||
|             if info.contains_key("txindex") { |             if info.contains_key("txindex") { | ||||||
| @ -416,6 +466,7 @@ impl ConfigurableBlockchain for RpcBlockchain { | |||||||
|         Ok(RpcBlockchain { |         Ok(RpcBlockchain { | ||||||
|             client, |             client, | ||||||
|             capabilities, |             capabilities, | ||||||
|  |             is_descriptors, | ||||||
|             _storage_address: storage_address, |             _storage_address: storage_address, | ||||||
|             skip_blocks: config.skip_blocks, |             skip_blocks: config.skip_blocks, | ||||||
|         }) |         }) | ||||||
| @ -438,6 +489,20 @@ fn list_wallet_dir(client: &Client) -> Result<Vec<String>, Error> { | |||||||
|     Ok(result.wallets.into_iter().map(|n| n.name).collect()) |     Ok(result.wallets.into_iter().map(|n| n.name).collect()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /// Returns whether a wallet is legacy or descriptors by calling `getwalletinfo`.
 | ||||||
|  | ///
 | ||||||
|  | /// This API is mapped by bitcoincore_rpc, but it doesn't have the fields we need (either
 | ||||||
|  | /// "descriptors" or "format") so we have to call the RPC manually
 | ||||||
|  | fn is_wallet_descriptor(client: &Client) -> Result<bool, Error> { | ||||||
|  |     #[derive(Deserialize)] | ||||||
|  |     struct CallResult { | ||||||
|  |         descriptors: Option<bool>, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     let result: CallResult = client.call("getwalletinfo", &[])?; | ||||||
|  |     Ok(result.descriptors.unwrap_or(false)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// Factory of [`RpcBlockchain`] instances, implements [`BlockchainFactory`]
 | /// Factory of [`RpcBlockchain`] instances, implements [`BlockchainFactory`]
 | ||||||
| ///
 | ///
 | ||||||
| /// Internally caches the node url and authentication params and allows getting many different [`RpcBlockchain`]
 | /// Internally caches the node url and authentication params and allows getting many different [`RpcBlockchain`]
 | ||||||
| @ -500,7 +565,7 @@ impl BlockchainFactory for RpcBlockchainFactory { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| #[cfg(feature = "test-rpc")] | #[cfg(any(feature = "test-rpc", feature = "test-rpc-legacy"))] | ||||||
| mod test { | mod test { | ||||||
|     use super::*; |     use super::*; | ||||||
|     use crate::testutils::blockchain_tests::TestClient; |     use crate::testutils::blockchain_tests::TestClient; | ||||||
| @ -514,7 +579,7 @@ mod test { | |||||||
|                 url: test_client.bitcoind.rpc_url(), |                 url: test_client.bitcoind.rpc_url(), | ||||||
|                 auth: Auth::Cookie { file: test_client.bitcoind.params.cookie_file.clone() }, |                 auth: Auth::Cookie { file: test_client.bitcoind.params.cookie_file.clone() }, | ||||||
|                 network: Network::Regtest, |                 network: Network::Regtest, | ||||||
|                 wallet_name: format!("client-wallet-test-{:?}", std::time::SystemTime::now() ), |                 wallet_name: format!("client-wallet-test-{}", std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_nanos() ), | ||||||
|                 skip_blocks: None, |                 skip_blocks: None, | ||||||
|             }; |             }; | ||||||
|             RpcBlockchain::from_config(&config).unwrap() |             RpcBlockchain::from_config(&config).unwrap() | ||||||
|  | |||||||
| @ -387,6 +387,7 @@ macro_rules! bdk_blockchain_tests { | |||||||
|                 Wallet::new(&descriptors.0.to_string(), descriptors.1.as_ref(), Network::Regtest, MemoryDatabase::new()).unwrap() |                 Wallet::new(&descriptors.0.to_string(), descriptors.1.as_ref(), Network::Regtest, MemoryDatabase::new()).unwrap() | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             #[allow(dead_code)] | ||||||
|             enum WalletType { |             enum WalletType { | ||||||
|                 WpkhSingleSig, |                 WpkhSingleSig, | ||||||
|                 TaprootKeySpend, |                 TaprootKeySpend, | ||||||
| @ -421,7 +422,7 @@ macro_rules! bdk_blockchain_tests { | |||||||
|                 let wallet = get_wallet_from_descriptors(&descriptors); |                 let wallet = get_wallet_from_descriptors(&descriptors); | ||||||
| 
 | 
 | ||||||
|                 // rpc need to call import_multi before receiving any tx, otherwise will not see tx in the mempool
 |                 // rpc need to call import_multi before receiving any tx, otherwise will not see tx in the mempool
 | ||||||
|                 #[cfg(feature = "test-rpc")] |                 #[cfg(any(feature = "test-rpc", feature = "test-rpc-legacy"))] | ||||||
|                 wallet.sync(&blockchain, SyncOptions::default()).unwrap(); |                 wallet.sync(&blockchain, SyncOptions::default()).unwrap(); | ||||||
| 
 | 
 | ||||||
|                 (wallet, blockchain, descriptors, test_client) |                 (wallet, blockchain, descriptors, test_client) | ||||||
| @ -446,7 +447,7 @@ macro_rules! bdk_blockchain_tests { | |||||||
| 
 | 
 | ||||||
|                 // the RPC blockchain needs to call `sync()` during initialization to import the
 |                 // the RPC blockchain needs to call `sync()` during initialization to import the
 | ||||||
|                 // addresses (see `init_single_sig()`), so we skip this assertion
 |                 // addresses (see `init_single_sig()`), so we skip this assertion
 | ||||||
|                 #[cfg(not(feature = "test-rpc"))] |                 #[cfg(not(any(feature = "test-rpc", feature = "test-rpc-legacy")))] | ||||||
|                 assert!(wallet.database().deref().get_sync_time().unwrap().is_none(), "initial sync_time not none"); |                 assert!(wallet.database().deref().get_sync_time().unwrap().is_none(), "initial sync_time not none"); | ||||||
| 
 | 
 | ||||||
|                 wallet.sync(&blockchain, SyncOptions::default()).unwrap(); |                 wallet.sync(&blockchain, SyncOptions::default()).unwrap(); | ||||||
| @ -1021,6 +1022,7 @@ macro_rules! bdk_blockchain_tests { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             #[test] |             #[test] | ||||||
|  |             #[cfg(not(feature = "test-rpc-legacy"))] | ||||||
|             fn test_send_to_bech32m_addr() { |             fn test_send_to_bech32m_addr() { | ||||||
|                 use std::str::FromStr; |                 use std::str::FromStr; | ||||||
|                 use serde; |                 use serde; | ||||||
| @ -1207,7 +1209,7 @@ macro_rules! bdk_blockchain_tests { | |||||||
|                 let blockchain = get_blockchain(&test_client); |                 let blockchain = get_blockchain(&test_client); | ||||||
| 
 | 
 | ||||||
|                 let wallet = get_wallet_from_descriptors(&descriptors); |                 let wallet = get_wallet_from_descriptors(&descriptors); | ||||||
|                 #[cfg(feature = "test-rpc")] |                 #[cfg(any(feature = "test-rpc", feature = "test-rpc-legacy"))] | ||||||
|                 wallet.sync(&blockchain, SyncOptions::default()).unwrap(); |                 wallet.sync(&blockchain, SyncOptions::default()).unwrap(); | ||||||
| 
 | 
 | ||||||
|                 let _ = test_client.receive(testutils! { |                 let _ = test_client.receive(testutils! { | ||||||
| @ -1231,6 +1233,7 @@ macro_rules! bdk_blockchain_tests { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             #[test] |             #[test] | ||||||
|  |             #[cfg(not(feature = "test-rpc-legacy"))] | ||||||
|             fn test_taproot_key_spend() { |             fn test_taproot_key_spend() { | ||||||
|                 let (wallet, blockchain, descriptors, mut test_client) = init_wallet(WalletType::TaprootKeySpend); |                 let (wallet, blockchain, descriptors, mut test_client) = init_wallet(WalletType::TaprootKeySpend); | ||||||
| 
 | 
 | ||||||
| @ -1251,6 +1254,7 @@ macro_rules! bdk_blockchain_tests { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             #[test] |             #[test] | ||||||
|  |             #[cfg(not(feature = "test-rpc-legacy"))] | ||||||
|             fn test_taproot_script_spend() { |             fn test_taproot_script_spend() { | ||||||
|                 let (wallet, blockchain, descriptors, mut test_client) = init_wallet(WalletType::TaprootScriptSpend); |                 let (wallet, blockchain, descriptors, mut test_client) = init_wallet(WalletType::TaprootScriptSpend); | ||||||
| 
 | 
 | ||||||
| @ -1279,20 +1283,24 @@ macro_rules! bdk_blockchain_tests { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             #[test] |             #[test] | ||||||
|  |             #[cfg(not(feature = "test-rpc-legacy"))] | ||||||
|             fn test_sign_taproot_core_keyspend_psbt() { |             fn test_sign_taproot_core_keyspend_psbt() { | ||||||
|                 test_sign_taproot_core_psbt(WalletType::TaprootKeySpend); |                 test_sign_taproot_core_psbt(WalletType::TaprootKeySpend); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             #[test] |             #[test] | ||||||
|  |             #[cfg(not(feature = "test-rpc-legacy"))] | ||||||
|             fn test_sign_taproot_core_scriptspend2_psbt() { |             fn test_sign_taproot_core_scriptspend2_psbt() { | ||||||
|                 test_sign_taproot_core_psbt(WalletType::TaprootScriptSpend2); |                 test_sign_taproot_core_psbt(WalletType::TaprootScriptSpend2); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             #[test] |             #[test] | ||||||
|  |             #[cfg(not(feature = "test-rpc-legacy"))] | ||||||
|             fn test_sign_taproot_core_scriptspend3_psbt() { |             fn test_sign_taproot_core_scriptspend3_psbt() { | ||||||
|                 test_sign_taproot_core_psbt(WalletType::TaprootScriptSpend3); |                 test_sign_taproot_core_psbt(WalletType::TaprootScriptSpend3); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             #[cfg(not(feature = "test-rpc-legacy"))] | ||||||
|             fn test_sign_taproot_core_psbt(wallet_type: WalletType) { |             fn test_sign_taproot_core_psbt(wallet_type: WalletType) { | ||||||
|                 use std::str::FromStr; |                 use std::str::FromStr; | ||||||
|                 use serde_json; |                 use serde_json; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user