Browse Source

Simplify wallet actor

We don't need to `Clone` the wallet actor ever so we can remove this
custom derive which allows us to also drop the `Arc<Mutex>` of the
`bdk::Wallet`, thus simplifying all of the handlers quite a bit.

We also add `&mut` to all handlers. Even though not strictly necessary
(because they are processed by `xtra-productivity`), it is more correct
to write `&mut self` because that is what the macro will output anyway.
feature/force-stop-button
Thomas Eizinger 3 years ago
parent
commit
4e9c9d6c6d
No known key found for this signature in database GPG Key ID: 651AC83A6C6C8B96
  1. 3
      daemon/src/maker.rs
  2. 3
      daemon/src/taker.rs
  3. 74
      daemon/src/wallet.rs

3
daemon/src/maker.rs

@ -161,8 +161,7 @@ async fn main() -> Result<()> {
opts.network.electrum(), opts.network.electrum(),
&data_dir.join("maker_wallet.sqlite"), &data_dir.join("maker_wallet.sqlite"),
ext_priv_key, ext_priv_key,
) )?
.await?
.create(None) .create(None)
.run(); .run();
let _wallet_handle = wallet_fut.spawn_with_handle(); let _wallet_handle = wallet_fut.spawn_with_handle();

3
daemon/src/taker.rs

@ -171,8 +171,7 @@ async fn main() -> Result<()> {
opts.network.electrum(), opts.network.electrum(),
&data_dir.join("taker_wallet.sqlite"), &data_dir.join("taker_wallet.sqlite"),
ext_priv_key, ext_priv_key,
) )?
.await?
.create(None) .create(None)
.run(); .run();
let _wallet_handle = wallet_fut.spawn_with_handle(); let _wallet_handle = wallet_fut.spawn_with_handle();

74
daemon/src/wallet.rs

@ -11,15 +11,12 @@ use maia::{PartyParams, WalletExt};
use rocket::serde::json::Value; use rocket::serde::json::Value;
use std::path::Path; use std::path::Path;
use std::sync::Arc;
use tokio::sync::Mutex;
use xtra_productivity::xtra_productivity; use xtra_productivity::xtra_productivity;
const DUST_AMOUNT: u64 = 546; const DUST_AMOUNT: u64 = 546;
#[derive(Clone)]
pub struct Actor { pub struct Actor {
wallet: Arc<Mutex<bdk::Wallet<ElectrumBlockchain, bdk::database::SqliteDatabase>>>, wallet: bdk::Wallet<ElectrumBlockchain, bdk::database::SqliteDatabase>,
} }
#[derive(thiserror::Error, Debug, Clone, Copy)] #[derive(thiserror::Error, Debug, Clone, Copy)]
@ -27,7 +24,7 @@ pub struct Actor {
pub struct TransactionAlreadyInBlockchain; pub struct TransactionAlreadyInBlockchain;
impl Actor { impl Actor {
pub async fn new( pub fn new(
electrum_rpc_url: &str, electrum_rpc_url: &str,
wallet_dir: &Path, wallet_dir: &Path,
ext_priv_key: ExtendedPrivKey, ext_priv_key: ExtendedPrivKey,
@ -45,8 +42,6 @@ impl Actor {
ElectrumBlockchain::from(client), ElectrumBlockchain::from(client),
)?; )?;
let wallet = Arc::new(Mutex::new(wallet));
Ok(Self { wallet }) Ok(Self { wallet })
} }
@ -54,13 +49,8 @@ impl Actor {
/// ///
/// We define this as the maximum amount we can pay to a single output, /// We define this as the maximum amount we can pay to a single output,
/// given a fee rate. /// given a fee rate.
pub async fn max_giveable( pub fn max_giveable(&self, locking_script_size: usize, fee_rate: FeeRate) -> Result<Amount> {
&self, let balance = self.wallet.get_balance()?;
locking_script_size: usize,
fee_rate: FeeRate,
) -> Result<Amount> {
let wallet = self.wallet.lock().await;
let balance = wallet.get_balance()?;
// TODO: Do we have to deal with the min_relay_fee here as well, i.e. if balance below // TODO: Do we have to deal with the min_relay_fee here as well, i.e. if balance below
// min_relay_fee we should return Amount::ZERO? // min_relay_fee we should return Amount::ZERO?
@ -68,7 +58,7 @@ impl Actor {
return Ok(Amount::ZERO); return Ok(Amount::ZERO);
} }
let mut tx_builder = wallet.build_tx(); let mut tx_builder = self.wallet.build_tx();
let dummy_script = Script::from(vec![0u8; locking_script_size]); let dummy_script = Script::from(vec![0u8; locking_script_size]);
tx_builder.drain_to(dummy_script); tx_builder.drain_to(dummy_script);
@ -92,15 +82,14 @@ impl Actor {
#[xtra_productivity] #[xtra_productivity]
impl Actor { impl Actor {
pub async fn handle_sync(&self, _msg: Sync) -> Result<WalletInfo> { pub fn handle_sync(&mut self, _msg: Sync) -> Result<WalletInfo> {
let wallet = self.wallet.lock().await; self.wallet
wallet
.sync(NoopProgress, None) .sync(NoopProgress, None)
.context("Failed to sync wallet")?; .context("Failed to sync wallet")?;
let balance = wallet.get_balance()?; let balance = self.wallet.get_balance()?;
let address = wallet.get_address(AddressIndex::LastUnused)?.address; let address = self.wallet.get_address(AddressIndex::LastUnused)?.address;
let wallet_info = WalletInfo { let wallet_info = WalletInfo {
balance: Amount::from_sat(balance), balance: Amount::from_sat(balance),
@ -111,11 +100,10 @@ impl Actor {
Ok(wallet_info) Ok(wallet_info)
} }
pub async fn handle_sign(&self, msg: Sign) -> Result<PartiallySignedTransaction> { pub fn handle_sign(&mut self, msg: Sign) -> Result<PartiallySignedTransaction> {
let mut psbt = msg.psbt; let mut psbt = msg.psbt;
let wallet = self.wallet.lock().await;
wallet self.wallet
.sign( .sign(
&mut psbt, &mut psbt,
SignOptions { SignOptions {
@ -128,26 +116,24 @@ impl Actor {
Ok(psbt) Ok(psbt)
} }
pub async fn build_party_params( pub fn build_party_params(
&self, &mut self,
BuildPartyParams { BuildPartyParams {
amount, amount,
identity_pk, identity_pk,
}: BuildPartyParams, }: BuildPartyParams,
) -> Result<PartyParams> { ) -> Result<PartyParams> {
let wallet = self.wallet.lock().await; self.wallet.build_party_params(amount, identity_pk)
wallet.build_party_params(amount, identity_pk)
} }
pub async fn handle_try_broadcast_transaction( pub fn handle_try_broadcast_transaction(
&self, &mut self,
msg: TryBroadcastTransaction, msg: TryBroadcastTransaction,
) -> Result<Txid> { ) -> Result<Txid> {
let tx = msg.tx; let tx = msg.tx;
let wallet = self.wallet.lock().await;
let txid = tx.txid(); let txid = tx.txid();
let result = wallet.broadcast(&tx); let result = self.wallet.broadcast(&tx);
if let Err(&bdk::Error::Electrum(electrum_client::Error::Protocol(ref value))) = if let Err(&bdk::Error::Electrum(electrum_client::Error::Protocol(ref value))) =
result.as_ref() result.as_ref()
@ -176,16 +162,13 @@ impl Actor {
Ok(txid) Ok(txid)
} }
pub async fn handle_withdraw(&self, msg: Withdraw) -> Result<Txid> { pub fn handle_withdraw(&mut self, msg: Withdraw) -> Result<Txid> {
{ if msg.address.network != self.wallet.network() {
let wallet = self.wallet.lock().await; bail!(
if msg.address.network != wallet.network() { "Address has invalid network. It was {} but the wallet is connected to {}",
bail!( msg.address.network,
"Address has invalid network. It was {} but the wallet is connected to {}", self.wallet.network()
msg.address.network, )
wallet.network()
)
}
} }
let fee_rate = msg.fee.unwrap_or_else(FeeRate::default_min_relay_fee); let fee_rate = msg.fee.unwrap_or_else(FeeRate::default_min_relay_fee);
@ -195,15 +178,12 @@ impl Actor {
amount amount
} else { } else {
self.max_giveable(address.script_pubkey().len(), fee_rate) self.max_giveable(address.script_pubkey().len(), fee_rate)
.await
.context("Unable to drain wallet")? .context("Unable to drain wallet")?
}; };
tracing::info!(%amount, %address, "Amount to be sent to address"); tracing::info!(%amount, %address, "Amount to be sent to address");
let wallet = self.wallet.lock().await; let mut tx_builder = self.wallet.build_tx();
let mut tx_builder = wallet.build_tx();
tx_builder tx_builder
.add_recipient(address.script_pubkey(), amount.as_sat()) .add_recipient(address.script_pubkey(), amount.as_sat())
@ -213,9 +193,9 @@ impl Actor {
let (mut psbt, _) = tx_builder.finish()?; let (mut psbt, _) = tx_builder.finish()?;
wallet.sign(&mut psbt, SignOptions::default())?; self.wallet.sign(&mut psbt, SignOptions::default())?;
let txid = wallet.broadcast(&psbt.extract_tx())?; let txid = self.wallet.broadcast(&psbt.extract_tx())?;
tracing::info!(%txid, "Withdraw successful"); tracing::info!(%txid, "Withdraw successful");

Loading…
Cancel
Save