diff --git a/src/bitcoin/d/mod.rs b/src/bitcoin/d/mod.rs index faaaf371..f77c6666 100644 --- a/src/bitcoin/d/mod.rs +++ b/src/bitcoin/d/mod.rs @@ -45,6 +45,9 @@ const BITCOIND_RETRY_LIMIT: usize = 60; // The minimum bitcoind version that can be used with lianad. const MIN_BITCOIND_VERSION: u64 = 240000; +// The minimum bitcoind version that can be used with lianad and a Taproot descriptor. +const MIN_TAPROOT_BITCOIND_VERSION: u64 = 260000; + /// An error in the bitcoind interface. #[derive(Debug)] pub enum BitcoindError { @@ -129,8 +132,8 @@ impl std::fmt::Display for BitcoindError { BitcoindError::InvalidVersion(v) => { write!( f, - "Invalid bitcoind version '{}', minimum supported is '{}'.", - v, MIN_BITCOIND_VERSION + "Invalid bitcoind version '{}', minimum supported is '{}' and minimum supported if using Taproot is '{}'.", + v, MIN_BITCOIND_VERSION, MIN_TAPROOT_BITCOIND_VERSION ) } BitcoindError::NetworkMismatch(conf_net, bitcoind_net) => { @@ -699,12 +702,16 @@ impl BitcoinD { pub fn node_sanity_checks( &self, config_network: bitcoin::Network, + is_taproot: bool, ) -> Result<(), BitcoindError> { // Check the minimum supported bitcoind version let version = self.get_bitcoind_version(); if version < MIN_BITCOIND_VERSION { return Err(BitcoindError::InvalidVersion(version)); } + if is_taproot && version < MIN_TAPROOT_BITCOIND_VERSION { + return Err(BitcoindError::InvalidVersion(version)); + } // Check bitcoind is running on the right network let bitcoind_net = self.get_network_bip70(); diff --git a/src/descriptors/mod.rs b/src/descriptors/mod.rs index d47f8137..022faeef 100644 --- a/src/descriptors/mod.rs +++ b/src/descriptors/mod.rs @@ -267,6 +267,11 @@ impl LianaDescriptor { 32 + 4 + 4 + 1 + self.max_sat_vbytes() } + /// Whether this is a Taproot descriptor. + pub fn is_taproot(&self) -> bool { + matches!(self.multi_desc, descriptor::Descriptor::Tr(..)) + } + /// Get some information about a PSBT input spending Liana coins. /// This analysis assumes that: /// - The PSBT input actually spend a Liana coin for this descriptor. Otherwise the analysis will be off. @@ -276,7 +281,7 @@ impl LianaDescriptor { psbt_in: &PsbtIn, txin: &bitcoin::TxIn, ) -> PartialSpendInfo { - let is_taproot = matches!(self.multi_desc, descriptor::Descriptor::Tr(..)); + let is_taproot = self.is_taproot(); // Get the origin ECDSA or Schnorr signatures, depending on the descriptor type. let pubkeys_signed = (!is_taproot) .then(|| { diff --git a/src/lib.rs b/src/lib.rs index c3a3b52e..b608b24e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -229,7 +229,10 @@ fn setup_bitcoind( .as_ref() .ok_or(StartupError::MissingBitcoindConfig)?; let bitcoind = BitcoinD::new(bitcoind_config, wo_path_str)?; - bitcoind.node_sanity_checks(config.bitcoin_config.network)?; + bitcoind.node_sanity_checks( + config.bitcoin_config.network, + config.main_descriptor.is_taproot(), + )?; if fresh_data_dir { log::info!("Creating a new watchonly wallet on bitcoind."); bitcoind.create_watchonly_wallet(&config.main_descriptor)?;