From 04906a938babb6a533c53c5a9fd12cf47e48988a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 6 Oct 2021 12:41:09 +1100 Subject: [PATCH] Allow application to run on mainnet or testnet I decided to use a sub-command because it allows me to keep the default values for the electrum client within clap. --- .github/workflows/ci.yml | 4 +-- .gitignore | 2 ++ daemon/src/maker.rs | 64 +++++++++++++++++++++++++++++++++------- daemon/src/taker.rs | 54 ++++++++++++++++++++++++++++----- 4 files changed, 104 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c474a2..3188a86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,10 +76,10 @@ jobs: - name: Smoke test ${{ matrix.os }} binary shell: bash run: | - target/debug/maker --data-dir=/tmp/maker --generate-seed & + target/debug/maker --data-dir=/tmp/maker --generate-seed testnet & sleep 10s # Wait for maker to start - target/debug/taker --data-dir=/tmp/taker --generate-seed & + target/debug/taker --data-dir=/tmp/taker --generate-seed testnet & sleep 10s # Wait for taker to start curl --fail http://localhost:8000/api/alive diff --git a/.gitignore b/.gitignore index 41e4651..276d4de 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ /*.sqlite* /maker_seed /taker_seed +/mainnet +/testnet diff --git a/daemon/src/maker.rs b/daemon/src/maker.rs index 5935a8c..3e68d97 100644 --- a/daemon/src/maker.rs +++ b/daemon/src/maker.rs @@ -4,8 +4,8 @@ use crate::model::cfd::SettlementProposals; use crate::seed::Seed; use crate::wallet::Wallet; use anyhow::{Context, Result}; +use bdk::bitcoin; use bdk::bitcoin::secp256k1::{schnorrsig, SECP256K1}; -use bdk::bitcoin::Network; use clap::Clap; use model::cfd::Order; use model::WalletInfo; @@ -57,10 +57,6 @@ struct Opts { #[clap(long, default_value = "8001")] http_port: u16, - /// URL to the electrum backend to use for the wallet. - #[clap(long, default_value = "ssl://electrum.blockstream.info:60002")] - electrum: String, - /// Where to permanently store data, defaults to the current working directory. #[clap(long)] data_dir: Option, @@ -72,6 +68,48 @@ struct Opts { /// If enabled logs will be in json format #[clap(short, long)] json: bool, + + #[clap(subcommand)] + network: Network, +} + +#[derive(Clap)] +enum Network { + /// Run on mainnet. + Mainnet { + /// URL to the electrum backend to use for the wallet. + #[clap(long, default_value = "ssl://electrum.blockstream.info:50002")] + electrum: String, + }, + /// Run on testnet. + Testnet { + /// URL to the electrum backend to use for the wallet. + #[clap(long, default_value = "ssl://electrum.blockstream.info:60002")] + electrum: String, + }, +} + +impl Network { + fn electrum(&self) -> &str { + match self { + Network::Mainnet { electrum } => electrum, + Network::Testnet { electrum } => electrum, + } + } + + fn bitcoin_network(&self) -> bitcoin::Network { + match self { + Network::Mainnet { .. } => bitcoin::Network::Bitcoin, + Network::Testnet { .. } => bitcoin::Network::Testnet, + } + } + + fn data_dir(&self, base: PathBuf) -> PathBuf { + match self { + Network::Mainnet { .. } => base.join("mainnet"), + Network::Testnet { .. } => base.join("testnet"), + } + } } #[rocket::main] @@ -85,16 +123,18 @@ async fn main() -> Result<()> { .clone() .unwrap_or_else(|| std::env::current_dir().expect("unable to get cwd")); + let data_dir = opts.network.data_dir(data_dir); + if !data_dir.exists() { tokio::fs::create_dir_all(&data_dir).await?; } let seed = Seed::initialize(&data_dir.join("maker_seed"), opts.generate_seed).await?; - let ext_priv_key = seed.derive_extended_priv_key(Network::Testnet)?; + let ext_priv_key = seed.derive_extended_priv_key(opts.network.bitcoin_network())?; let wallet = Wallet::new( - &opts.electrum, + opts.network.electrum(), &data_dir.join("maker_wallet.sqlite"), ext_priv_key, ) @@ -200,9 +240,13 @@ async fn main() -> Result<()> { ); tokio::spawn( monitor_actor_context.run( - monitor::Actor::new(&opts.electrum, cfd_maker_actor_inbox.clone(), cfds) - .await - .unwrap(), + monitor::Actor::new( + opts.network.electrum(), + cfd_maker_actor_inbox.clone(), + cfds, + ) + .await + .unwrap(), ), ); diff --git a/daemon/src/taker.rs b/daemon/src/taker.rs index 940e1cf..90d2e3b 100644 --- a/daemon/src/taker.rs +++ b/daemon/src/taker.rs @@ -3,8 +3,8 @@ use crate::model::cfd::SettlementProposals; use crate::model::WalletInfo; use crate::wallet::Wallet; use anyhow::{Context, Result}; +use bdk::bitcoin; use bdk::bitcoin::secp256k1::{schnorrsig, SECP256K1}; -use bdk::bitcoin::Network; use clap::Clap; use futures::StreamExt; use model::cfd::Order; @@ -60,10 +60,6 @@ struct Opts { #[clap(long, default_value = "8000")] http_port: u16, - /// URL to the electrum backend to use for the wallet. - #[clap(long, default_value = "ssl://electrum.blockstream.info:60002")] - electrum: String, - /// Where to permanently store data, defaults to the current working directory. #[clap(long)] data_dir: Option, @@ -75,6 +71,46 @@ struct Opts { /// If enabled logs will be in json format #[clap(short, long)] json: bool, + + #[clap(subcommand)] + network: Network, +} + +#[derive(Clap)] +enum Network { + Mainnet { + /// URL to the electrum backend to use for the wallet. + #[clap(long, default_value = "ssl://electrum.blockstream.info:50002")] + electrum: String, + }, + Testnet { + /// URL to the electrum backend to use for the wallet. + #[clap(long, default_value = "ssl://electrum.blockstream.info:60002")] + electrum: String, + }, +} + +impl Network { + fn electrum(&self) -> &str { + match self { + Network::Mainnet { electrum } => electrum, + Network::Testnet { electrum } => electrum, + } + } + + fn bitcoin_network(&self) -> bitcoin::Network { + match self { + Network::Mainnet { .. } => bitcoin::Network::Bitcoin, + Network::Testnet { .. } => bitcoin::Network::Testnet, + } + } + + fn data_dir(&self, base: PathBuf) -> PathBuf { + match self { + Network::Mainnet { .. } => base.join("mainnet"), + Network::Testnet { .. } => base.join("testnet"), + } + } } #[rocket::main] @@ -88,16 +124,18 @@ async fn main() -> Result<()> { .clone() .unwrap_or_else(|| std::env::current_dir().expect("unable to get cwd")); + let data_dir = opts.network.data_dir(data_dir); + if !data_dir.exists() { tokio::fs::create_dir_all(&data_dir).await?; } let seed = Seed::initialize(&data_dir.join("taker_seed"), opts.generate_seed).await?; - let ext_priv_key = seed.derive_extended_priv_key(Network::Testnet)?; + let ext_priv_key = seed.derive_extended_priv_key(opts.network.bitcoin_network())?; let wallet = Wallet::new( - &opts.electrum, + opts.network.electrum(), &data_dir.join("taker_wallet.sqlite"), ext_priv_key, ) @@ -201,7 +239,7 @@ async fn main() -> Result<()> { ); tokio::spawn( monitor_actor_context.run( - monitor::Actor::new(&opts.electrum, cfd_actor_inbox.clone(), cfds) + monitor::Actor::new(opts.network.electrum(), cfd_actor_inbox.clone(), cfds) .await .unwrap(), ),