From 6356c783beaaeb0a4d3843b94b8bcaf5908458e1 Mon Sep 17 00:00:00 2001 From: Mariusz Klochowicz Date: Mon, 20 Sep 2021 13:56:19 +0930 Subject: [PATCH] Wrap bdk::wallet inside a struct Removes code duplication in maker and taker wallet initialisation and avoids generics in the cfd actors. --- daemon/src/maker.rs | 23 +++++----------- daemon/src/maker_cfd_actor.rs | 12 +++------ daemon/src/taker.rs | 23 +++++----------- daemon/src/taker_cfd_actor.rs | 12 +++------ daemon/src/wallet.rs | 49 +++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 48 deletions(-) create mode 100644 daemon/src/wallet.rs diff --git a/daemon/src/maker.rs b/daemon/src/maker.rs index a16ea8c..ae6564c 100644 --- a/daemon/src/maker.rs +++ b/daemon/src/maker.rs @@ -1,9 +1,8 @@ use crate::seed::Seed; +use crate::wallet::Wallet; use anyhow::Result; use bdk::bitcoin::secp256k1::{schnorrsig, SECP256K1}; use bdk::bitcoin::{Amount, Network}; -use bdk::blockchain::{ElectrumBlockchain, NoopProgress}; -use bdk::KeychainKind; use clap::Clap; use model::cfd::{Cfd, Order}; use rocket::fairing::AdHoc; @@ -21,6 +20,7 @@ mod seed; mod send_wire_message_actor; mod setup_contract_actor; mod to_sse_event; +mod wallet; mod wire; #[derive(Database)] @@ -64,23 +64,14 @@ async fn main() -> Result<()> { let seed = Seed::initialize(&data_dir.join("maker_seed"), opts.generate_seed).await?; - let client = bdk::electrum_client::Client::new(&opts.electrum).unwrap(); - - // TODO: Replace with sqlite once https://github.com/bitcoindevkit/bdk/pull/376 is merged. - let db = bdk::sled::open(data_dir.join("maker_wallet_db"))?; - let wallet_db = db.open_tree("wallet")?; - let ext_priv_key = seed.derive_extended_priv_key(Network::Testnet)?; - let wallet = bdk::Wallet::new( - bdk::template::Bip84(ext_priv_key, KeychainKind::External), - Some(bdk::template::Bip84(ext_priv_key, KeychainKind::Internal)), - ext_priv_key.network, - wallet_db, - ElectrumBlockchain::from(client), + let wallet = Wallet::new( + &opts.electrum, + &data_dir.join("maker_wallet_db"), + ext_priv_key, ) - .unwrap(); - wallet.sync(NoopProgress, None).unwrap(); // TODO: Use LogProgress once we have logging. + .await?; let oracle = schnorrsig::KeyPair::new(SECP256K1, &mut rand::thread_rng()); // TODO: Fetch oracle public key from oracle. diff --git a/daemon/src/maker_cfd_actor.rs b/daemon/src/maker_cfd_actor.rs index 829b8ec..9bb4c6d 100644 --- a/daemon/src/maker_cfd_actor.rs +++ b/daemon/src/maker_cfd_actor.rs @@ -3,12 +3,11 @@ use std::time::SystemTime; use crate::db::{insert_cfd, insert_order, load_all_cfds, load_order_by_id}; use crate::model::cfd::{Cfd, CfdState, CfdStateCommon, FinalizedCfd, Order, OrderId}; use crate::model::{TakerId, Usd}; +use crate::wallet::Wallet; use crate::wire::SetupMsg; use crate::{maker_cfd_actor, maker_inc_connections_actor, setup_contract_actor}; use bdk::bitcoin::secp256k1::schnorrsig; use bdk::bitcoin::{self}; -use bdk::database::BatchDatabase; -use cfd_protocol::WalletExt; use futures::Future; use tokio::sync::{mpsc, watch}; @@ -32,9 +31,9 @@ pub enum Command { CfdSetupCompleted(FinalizedCfd), } -pub fn new( +pub fn new( db: sqlx::SqlitePool, - wallet: bdk::Wallet, + wallet: Wallet, oracle_pk: schnorrsig::PublicKey, takers: mpsc::UnboundedSender, cfd_feed_actor_inbox: watch::Sender>, @@ -42,10 +41,7 @@ pub fn new( ) -> ( impl Future, mpsc::UnboundedSender, -) -where - D: BatchDatabase, -{ +) { let (sender, mut receiver) = mpsc::unbounded_channel(); let mut current_contract_setup = None; diff --git a/daemon/src/taker.rs b/daemon/src/taker.rs index 1f081fd..f8499d2 100644 --- a/daemon/src/taker.rs +++ b/daemon/src/taker.rs @@ -1,8 +1,7 @@ +use crate::wallet::Wallet; use anyhow::Result; use bdk::bitcoin::secp256k1::{schnorrsig, SECP256K1}; use bdk::bitcoin::{Amount, Network}; -use bdk::blockchain::{ElectrumBlockchain, NoopProgress}; -use bdk::KeychainKind; use clap::Clap; use model::cfd::{Cfd, Order}; use rocket::fairing::AdHoc; @@ -24,6 +23,7 @@ mod setup_contract_actor; mod taker_cfd_actor; mod taker_inc_message_actor; mod to_sse_event; +mod wallet; mod wire; const CONNECTION_RETRY_INTERVAL: Duration = Duration::from_secs(5); @@ -69,23 +69,14 @@ async fn main() -> Result<()> { let seed = Seed::initialize(&data_dir.join("taker_seed"), opts.generate_seed).await?; - let client = bdk::electrum_client::Client::new(&opts.electrum).unwrap(); - - // TODO: Replace with sqlite once https://github.com/bitcoindevkit/bdk/pull/376 is merged. - let db = bdk::sled::open(data_dir.join("taker_wallet_db"))?; - let wallet_db = db.open_tree("wallet")?; - let ext_priv_key = seed.derive_extended_priv_key(Network::Testnet)?; - let wallet = bdk::Wallet::new( - bdk::template::Bip84(ext_priv_key, KeychainKind::External), - Some(bdk::template::Bip84(ext_priv_key, KeychainKind::Internal)), - ext_priv_key.network, - wallet_db, - ElectrumBlockchain::from(client), + let wallet = Wallet::new( + &opts.electrum, + &data_dir.join("taker_wallet_db"), + ext_priv_key, ) - .unwrap(); - wallet.sync(NoopProgress, None).unwrap(); // TODO: Use LogProgress once we have logging. + .await?; let oracle = schnorrsig::KeyPair::new(SECP256K1, &mut rand::thread_rng()); // TODO: Fetch oracle public key from oracle. diff --git a/daemon/src/taker_cfd_actor.rs b/daemon/src/taker_cfd_actor.rs index d0cfb1c..d8b18fb 100644 --- a/daemon/src/taker_cfd_actor.rs +++ b/daemon/src/taker_cfd_actor.rs @@ -3,12 +3,11 @@ use crate::db::{ }; use crate::model::cfd::{Cfd, CfdState, CfdStateCommon, FinalizedCfd, Order, OrderId}; use crate::model::Usd; +use crate::wallet::Wallet; use crate::wire::SetupMsg; use crate::{setup_contract_actor, wire}; use bdk::bitcoin::secp256k1::schnorrsig; use bdk::bitcoin::{self}; -use bdk::database::BatchDatabase; -use cfd_protocol::WalletExt; use core::panic; use futures::Future; use std::time::SystemTime; @@ -24,17 +23,14 @@ pub enum Command { CfdSetupCompleted(FinalizedCfd), } -pub fn new( +pub fn new( db: sqlx::SqlitePool, - wallet: bdk::Wallet, + wallet: Wallet, oracle_pk: schnorrsig::PublicKey, cfd_feed_actor_inbox: watch::Sender>, order_feed_actor_inbox: watch::Sender>, out_msg_maker_inbox: mpsc::UnboundedSender, -) -> (impl Future, mpsc::UnboundedSender) -where - D: BatchDatabase, -{ +) -> (impl Future, mpsc::UnboundedSender) { let (sender, mut receiver) = mpsc::unbounded_channel(); let mut current_contract_setup = None; diff --git a/daemon/src/wallet.rs b/daemon/src/wallet.rs new file mode 100644 index 0000000..1ec26ec --- /dev/null +++ b/daemon/src/wallet.rs @@ -0,0 +1,49 @@ +use anyhow::{Context, Result}; +use bdk::bitcoin::util::bip32::ExtendedPrivKey; +use bdk::bitcoin::{Amount, PublicKey}; +use bdk::blockchain::{ElectrumBlockchain, NoopProgress}; +use bdk::KeychainKind; +use cfd_protocol::{PartyParams, WalletExt}; +use std::path::Path; + +const SLED_TREE_NAME: &str = "wallet"; + +pub struct Wallet { + wallet: bdk::Wallet, +} + +impl Wallet { + pub async fn new( + electrum_rpc_url: &str, + wallet_dir: &Path, + ext_priv_key: ExtendedPrivKey, + ) -> Result { + let client = bdk::electrum_client::Client::new(electrum_rpc_url) + .context("Failed to initialize Electrum RPC client")?; + + // TODO: Replace with sqlite once https://github.com/bitcoindevkit/bdk/pull/376 is merged. + let db = bdk::sled::open(wallet_dir)?.open_tree(SLED_TREE_NAME)?; + + let wallet = bdk::Wallet::new( + bdk::template::Bip84(ext_priv_key, KeychainKind::External), + Some(bdk::template::Bip84(ext_priv_key, KeychainKind::Internal)), + ext_priv_key.network, + db, + ElectrumBlockchain::from(client), + )?; + + wallet + .sync(NoopProgress, None) + .context("Failed to sync the wallet")?; // TODO: Use LogProgress once we have logging. + + Ok(Self { wallet }) + } + + pub fn build_party_params( + &self, + amount: Amount, + identity_pk: PublicKey, + ) -> Result { + self.wallet.build_party_params(amount, identity_pk) + } +}