]> Untitled Git - bdk-cli/commitdiff
Require only one blockchain client feature at a time
authorSteve Myers <steve@notmandatory.org>
Thu, 5 Aug 2021 04:52:58 +0000 (21:52 -0700)
committerSteve Myers <steve@notmandatory.org>
Thu, 12 Aug 2021 14:06:54 +0000 (16:06 +0200)
.github/workflows/cont_integration.yml
Cargo.toml
src/bdk_cli.rs
src/lib.rs

index c0644c25bbcd3b0782633f1b6fc3e5b3f4d62413..a4e044188b831f13088956cfc92ea54d5ad804db 100644 (file)
@@ -19,7 +19,6 @@ jobs:
           - esplora
           - compiler
           - compact_filters
-          - repl,electrum,esplora,compiler
     steps:
       - name: Checkout
         uses: actions/checkout@v2
index 65e8ffdaab37df7d0ca45057e88a27af400e633b..507c2f5bfb6419b670862c42763d7e0496c1f784 100644 (file)
@@ -39,7 +39,7 @@ compact_filters = ["bdk/compact_filters"]
 [[bin]]
 name = "bdk-cli"
 path = "src/bdk_cli.rs"
-required-features = ["repl", "electrum"]
+required-features = ["repl"]
 
 [package.metadata.docs.rs]
-features = ["esplora", "compiler"]
+features = ["compiler"]
index 25df3b7a51783ff8bff82fc06e517bd1c6ae5da6..e6d8b8c469649f3addb935eabb6f33bf5cefabb8 100644 (file)
@@ -34,21 +34,25 @@ use structopt::StructOpt;
 
 #[cfg(feature = "compact_filters")]
 use bdk::blockchain::compact_filters::{BitcoinPeerConfig, CompactFiltersBlockchainConfig};
+#[cfg(feature = "electrum")]
+use bdk::blockchain::electrum::ElectrumBlockchainConfig;
 #[cfg(feature = "esplora")]
 use bdk::blockchain::esplora::EsploraBlockchainConfig;
-use bdk::blockchain::{
-    AnyBlockchain, AnyBlockchainConfig, ConfigurableBlockchain, ElectrumBlockchainConfig,
-};
+
+#[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
+use bdk::blockchain::{AnyBlockchain, AnyBlockchainConfig, ConfigurableBlockchain};
+
 use bdk::database::BatchDatabase;
 use bdk::sled;
 use bdk::sled::Tree;
 use bdk::Wallet;
 use bdk::{bitcoin, Error};
 use bdk_cli::WalletSubCommand;
-use bdk_cli::{
-    CliOpts, CliSubCommand, KeySubCommand, OfflineWalletSubCommand, OnlineWalletSubCommand,
-    WalletOpts,
-};
+use bdk_cli::{CliOpts, CliSubCommand, KeySubCommand, OfflineWalletSubCommand, WalletOpts};
+
+#[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
+use bdk_cli::OnlineWalletSubCommand;
+
 use regex::Regex;
 
 const REPL_LINE_SPLIT_REGEX: &str = r#""([^"]*)"|'([^']*)'|([\w\-]+)"#;
@@ -59,6 +63,7 @@ const REPL_LINE_SPLIT_REGEX: &str = r#""([^"]*)"|'([^']*)'|([\w\-]+)"#;
 version = option_env ! ("CARGO_PKG_VERSION").unwrap_or("unknown"),
 author = option_env ! ("CARGO_PKG_AUTHORS").unwrap_or(""))]
 pub enum ReplSubCommand {
+    #[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
     #[structopt(flatten)]
     OnlineWalletSubCommand(OnlineWalletSubCommand),
     #[structopt(flatten)]
@@ -96,6 +101,7 @@ fn open_database(wallet_opts: &WalletOpts) -> Tree {
     tree
 }
 
+#[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
 fn new_online_wallet<D>(
     network: Network,
     wallet_opts: &WalletOpts,
@@ -104,29 +110,40 @@ fn new_online_wallet<D>(
 where
     D: BatchDatabase,
 {
-    // Try to use Esplora config if "esplora" feature is enabled
-    #[cfg(feature = "esplora")]
-    let config_esplora: Option<AnyBlockchainConfig> = {
-        let esplora_concurrency = wallet_opts.esplora_opts.esplora_concurrency;
-        wallet_opts.esplora_opts.esplora.clone().map(|base_url| {
-            AnyBlockchainConfig::Esplora(EsploraBlockchainConfig {
-                base_url,
-                concurrency: Some(esplora_concurrency),
-            })
-        })
-    };
-    #[cfg(not(feature = "esplora"))]
-    let config_esplora = None;
-
-    let config_electrum = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
+    #[cfg(all(
+        feature = "electrum",
+        any(feature = "esplora", feature = "compact_filters")
+    ))]
+    compile_error!("Only one blockchain client feature can be enabled at a time. The 'electrum' feature can not be enabled with 'esplora' or 'compact_filters'.");
+
+    #[cfg(feature = "electrum")]
+    let config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
         url: wallet_opts.electrum_opts.electrum.clone(),
         socks5: wallet_opts.proxy_opts.proxy.clone(),
         retry: wallet_opts.proxy_opts.retries,
         timeout: wallet_opts.electrum_opts.timeout,
     });
 
+    #[cfg(all(
+        feature = "esplora",
+        any(feature = "electrum", feature = "compact_filters")
+    ))]
+    compile_error!("Only one blockchain client feature can be enabled at a time. The 'esplora' feature can not be enabled with 'electrum' or 'compact_filters'.");
+
+    #[cfg(feature = "esplora")]
+    let config = AnyBlockchainConfig::Esplora(EsploraBlockchainConfig {
+        base_url: wallet_opts.esplora_opts.server.clone(),
+        concurrency: Some(wallet_opts.esplora_opts.concurrency),
+    });
+
+    #[cfg(all(
+        feature = "compact_filters",
+        any(feature = "electrum", feature = "esplora")
+    ))]
+    compile_error!("Only one blockchain client feature can be enabled at a time. The 'esplora' feature can not be enabled with 'electrum' or 'compact_filters'.");
+
     #[cfg(feature = "compact_filters")]
-    let config_compact_filters: Option<AnyBlockchainConfig> = {
+    let config = {
         let mut peers = vec![];
         for addrs in wallet_opts.compactfilter_opts.address.clone() {
             for _ in 0..wallet_opts.compactfilter_opts.conn_count {
@@ -138,26 +155,17 @@ where
             }
         }
 
-        Some(AnyBlockchainConfig::CompactFilters(
-            CompactFiltersBlockchainConfig {
-                peers,
-                network,
-                storage_dir: prepare_home_dir().into_os_string().into_string().unwrap(),
-                skip_blocks: Some(wallet_opts.compactfilter_opts.skip_blocks),
-            },
-        ))
+        AnyBlockchainConfig::CompactFilters(CompactFiltersBlockchainConfig {
+            peers,
+            network,
+            storage_dir: prepare_home_dir().into_os_string().into_string().unwrap(),
+            skip_blocks: Some(wallet_opts.compactfilter_opts.skip_blocks),
+        })
     };
 
-    #[cfg(not(feature = "compact_filters"))]
-    let config_compact_filters = None;
-
-    // Fall back to Electrum config if Esplora or Compact Filter config isn't provided
-    let config = config_esplora
-        .or(config_compact_filters)
-        .unwrap_or(config_electrum);
-
     let descriptor = wallet_opts.descriptor.as_str();
     let change_descriptor = wallet_opts.change_descriptor.as_deref();
+
     let wallet = Wallet::new(
         descriptor,
         change_descriptor,
@@ -206,6 +214,7 @@ fn main() {
 
 fn handle_command(cli_opts: CliOpts, network: Network) -> Result<String, Error> {
     let result = match cli_opts.subcommand {
+        #[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
         CliSubCommand::Wallet {
             wallet_opts,
             subcommand: WalletSubCommand::OnlineWalletSubCommand(online_subcommand),
@@ -244,7 +253,16 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result<String, Error>
         }
         CliSubCommand::Repl { wallet_opts } => {
             let database = open_database(&wallet_opts);
-            let online_wallet = new_online_wallet(network, &wallet_opts, database)?;
+
+            #[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
+            let wallet = new_online_wallet(network, &wallet_opts, database)?;
+
+            #[cfg(not(any(
+                feature = "electrum",
+                feature = "esplora",
+                feature = "compact_filters"
+            )))]
+            let wallet = new_offline_wallet(network, &wallet_opts, database)?;
 
             let mut rl = Editor::<()>::new();
 
@@ -285,15 +303,17 @@ fn handle_command(cli_opts: CliOpts, network: Network) -> Result<String, Error>
                         let repl_subcommand = repl_subcommand.unwrap();
 
                         let result = match repl_subcommand {
+                            #[cfg(any(
+                                feature = "electrum",
+                                feature = "esplora",
+                                feature = "compact_filters"
+                            ))]
                             ReplSubCommand::OnlineWalletSubCommand(online_subcommand) => {
-                                bdk_cli::handle_online_wallet_subcommand(
-                                    &online_wallet,
-                                    online_subcommand,
-                                )
+                                bdk_cli::handle_online_wallet_subcommand(&wallet, online_subcommand)
                             }
                             ReplSubCommand::OfflineWalletSubCommand(offline_subcommand) => {
                                 bdk_cli::handle_offline_wallet_subcommand(
-                                    &online_wallet,
+                                    &wallet,
                                     &wallet_opts,
                                     offline_subcommand,
                                 )
index af54e8e3f7da2a6a17d84076a6f4ee8ee107c85a..19a3eafb88b63528a5a9f94b8ef2f78ed951a2a3 100644 (file)
@@ -138,6 +138,8 @@ use bdk::{FeeRate, KeychainKind, Wallet};
 /// # Example
 ///
 /// ```
+/// # #[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
+/// # {
 /// # use bdk::bitcoin::Network;
 /// # use structopt::StructOpt;
 /// # use bdk_cli::{CliOpts, WalletOpts, CliSubCommand, WalletSubCommand};
@@ -174,8 +176,8 @@ use bdk::{FeeRate, KeychainKind, Wallet};
 ///               },
 ///               #[cfg(feature = "esplora")]
 ///               esplora_opts: EsploraOpts {               
-///                   esplora: None,
-///                   esplora_concurrency: 4,
+///                   server: "https://blockstream.info/api/".to_string(),
+///                   concurrency: 4,
 ///               },
 ///                #[cfg(feature = "compact_filters")]
 ///                compactfilter_opts: CompactFilterOpts{
@@ -197,6 +199,7 @@ use bdk::{FeeRate, KeychainKind, Wallet};
 ///         };
 ///
 /// assert_eq!(expected_cli_opts, cli_opts);
+/// # }
 /// ```
 #[derive(Debug, StructOpt, Clone, PartialEq)]
 #[structopt(name = "BDK CLI",
@@ -268,6 +271,7 @@ pub enum CliSubCommand {
 /// client and network connection and an [`OfflineWalletSubCommand`] does not.
 #[derive(Debug, StructOpt, Clone, PartialEq)]
 pub enum WalletSubCommand {
+    #[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
     #[structopt(flatten)]
     OnlineWalletSubCommand(OnlineWalletSubCommand),
     #[structopt(flatten)]
@@ -315,8 +319,8 @@ pub enum WalletSubCommand {
 ///               },
 ///               #[cfg(feature = "esplora")]
 ///               esplora_opts: EsploraOpts {               
-///                   esplora: None,
-///                   esplora_concurrency: 4,
+///                   server: "https://blockstream.info/api/".to_string(),
+///                   concurrency: 4,
 ///               },
 ///                #[cfg(feature = "compact_filters")]
 ///                compactfilter_opts: CompactFilterOpts{
@@ -431,7 +435,7 @@ pub struct ElectrumOpts {
     pub timeout: Option<u8>,
     /// Sets the Electrum server to use
     #[structopt(
-        name = "SERVER:PORT",
+        name = "ELECTRUM_URL",
         short = "s",
         long = "server",
         default_value = "ssl://electrum.blockstream.info:60002"
@@ -446,15 +450,20 @@ pub struct ElectrumOpts {
 #[derive(Debug, StructOpt, Clone, PartialEq)]
 pub struct EsploraOpts {
     /// Use the esplora server if given as parameter
-    #[structopt(name = "ESPLORA_URL", short = "e", long = "esplora")]
-    pub esplora: Option<String>,
+    #[structopt(
+        name = "ESPLORA_URL",
+        short = "s",
+        long = "server",
+        default_value = "https://blockstream.info/api/"
+    )]
+    pub server: String,
     /// Concurrency of requests made to the esplora server
     #[structopt(
         name = "ESPLORA_CONCURRENCY",
-        long = "esplora_concurrency",
+        long = "concurrency",
         default_value = "4"
     )]
-    pub esplora_concurrency: u8,
+    pub concurrency: u8,
 }
 
 // This is a workaround for `structopt` issue #333, #391, #418; see https://github.com/TeXitoi/structopt/issues/333#issuecomment-712265332
@@ -1066,6 +1075,7 @@ mod test {
     #[cfg(feature = "esplora")]
     use crate::EsploraOpts;
     use crate::OfflineWalletSubCommand::{CreateTx, GetNewAddress};
+    #[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
     use crate::OnlineWalletSubCommand::{Broadcast, Sync};
     #[cfg(any(feature = "compact_filters", feature = "electrum"))]
     use crate::ProxyOpts;
@@ -1100,8 +1110,8 @@ mod test {
                     },
                     #[cfg(feature = "esplora")]
                     esplora_opts: EsploraOpts {
-                        esplora: None,
-                        esplora_concurrency: 4
+                        server: "https://blockstream.info/api/".to_string(),
+                        concurrency: 4
                     },
                     #[cfg(feature = "compact_filters")]
                     compactfilter_opts: CompactFilterOpts{
@@ -1150,8 +1160,8 @@ mod test {
                     },
                     #[cfg(feature = "esplora")]
                     esplora_opts: EsploraOpts {
-                        esplora: None,
-                        esplora_concurrency: 4,
+                        server: "https://blockstream.info/api/".to_string(),
+                        concurrency: 4,
                     },
                     #[cfg(feature = "compact_filters")]
                     compactfilter_opts: CompactFilterOpts{
@@ -1179,8 +1189,8 @@ mod test {
         let cli_args = vec!["bdk-cli", "--network", "bitcoin", "wallet",
                             "--descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
                             "--change_descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",             
-                            "--esplora", "https://blockstream.info/api/",
-                            "--esplora_concurrency", "5",
+                            "--server", "https://blockstream.info/api/",
+                            "--concurrency", "5",
                             "get_new_address"];
 
         let cli_opts = CliOpts::from_iter(&cli_args);
@@ -1200,8 +1210,8 @@ mod test {
                     },
                     #[cfg(feature = "esplora")]
                     esplora_opts: EsploraOpts {
-                        esplora: Some("https://blockstream.info/api/".to_string()),
-                        esplora_concurrency: 5,
+                        server: "https://blockstream.info/api/".to_string(),
+                        concurrency: 5,
                     },
                     #[cfg(feature = "compact_filters")]
                     compactfilter_opts: CompactFilterOpts{
@@ -1253,8 +1263,8 @@ mod test {
                     },
                     #[cfg(feature = "esplora")]
                     esplora_opts: EsploraOpts {
-                        esplora: None,
-                        esplora_concurrency: 4,
+                        server: "https://blockstream.info/api/".to_string(),
+                        concurrency: 4,
                     },
                     #[cfg(feature = "compact_filters")]
                     compactfilter_opts: CompactFilterOpts{
@@ -1276,6 +1286,7 @@ mod test {
         assert_eq!(expected_cli_opts, cli_opts);
     }
 
+    #[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
     #[test]
     fn test_parse_wallet_sync() {
         let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet",
@@ -1299,8 +1310,8 @@ mod test {
                     },
                     #[cfg(feature = "esplora")]
                     esplora_opts: EsploraOpts {
-                        esplora: None,
-                        esplora_concurrency: 4,
+                        server: "https://blockstream.info/api/".to_string(),
+                        concurrency: 4,
                     },
                     #[cfg(feature = "compact_filters")]
                     compactfilter_opts: CompactFilterOpts{
@@ -1365,8 +1376,8 @@ mod test {
                     },
                     #[cfg(feature = "esplora")]
                     esplora_opts: EsploraOpts {
-                        esplora: None,
-                        esplora_concurrency: 4,
+                        server: "https://blockstream.info/api/".to_string(),
+                        concurrency: 4,
                     },
                     #[cfg(feature = "compact_filters")]
                     compactfilter_opts: CompactFilterOpts{
@@ -1398,6 +1409,7 @@ mod test {
         assert_eq!(expected_cli_opts, cli_opts);
     }
 
+    #[cfg(any(feature = "electrum", feature = "esplora", feature = "compact_filters"))]
     #[test]
     fn test_parse_wallet_broadcast() {
         let cli_args = vec!["bdk-cli", "--network", "testnet", "wallet",
@@ -1422,8 +1434,8 @@ mod test {
                     },
                     #[cfg(feature = "esplora")]
                     esplora_opts: EsploraOpts {
-                        esplora: None,
-                        esplora_concurrency: 4,
+                        server: "https://blockstream.info/api/".to_string(),
+                        concurrency: 4,
                     },
                     #[cfg(feature = "compact_filters")]
                     compactfilter_opts: CompactFilterOpts{