diff --git a/swap/src/bin/swap_cli.rs b/swap/src/bin/swap_cli.rs index 5b238b64..c2a9ed4c 100644 --- a/swap/src/bin/swap_cli.rs +++ b/swap/src/bin/swap_cli.rs @@ -19,7 +19,7 @@ use std::{path::Path, sync::Arc, time::Duration}; use structopt::StructOpt; use swap::{ bitcoin, - bitcoin::Amount, + bitcoin::{Amount, TxLock}, cli::{ command::{Arguments, Command}, config::{read_config, Config}, @@ -112,7 +112,7 @@ async fn main() -> Result<()> { debug!("Received {}", bitcoin_wallet.balance().await?); } - let send_bitcoin = bitcoin_wallet.max_giveable().await?; + let send_bitcoin = bitcoin_wallet.max_giveable(TxLock::script_size()).await?; info!("Swapping {} ...", send_bitcoin); diff --git a/swap/src/bitcoin/lock.rs b/swap/src/bitcoin/lock.rs index 46666fe3..486c23ca 100644 --- a/swap/src/bitcoin/lock.rs +++ b/swap/src/bitcoin/lock.rs @@ -3,7 +3,9 @@ use crate::bitcoin::{ }; use ::bitcoin::{util::psbt::PartiallySignedTransaction, OutPoint, TxIn, TxOut, Txid}; use anyhow::Result; +use ecdsa_fun::fun::Point; use miniscript::{Descriptor, DescriptorTrait}; +use rand::thread_rng; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -42,6 +44,16 @@ impl TxLock { OutPoint::new(self.txid(), self.lock_output_vout() as u32) } + /// Calculate the size of the script used by this transaction. + pub fn script_size() -> usize { + build_shared_output_descriptor( + Point::random(&mut thread_rng()), + Point::random(&mut thread_rng()), + ) + .script_pubkey() + .len() + } + /// Retreive the index of the locked output in the transaction outputs /// vector fn lock_output_vout(&self) -> usize { diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index 466a5f4c..1e018b49 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -132,17 +132,13 @@ impl Wallet { /// We define this as the maximum amount we can pay to a single output, /// already accounting for the fees we need to spend to get the /// transaction confirmed. - pub async fn max_giveable(&self) -> Result { + pub async fn max_giveable(&self, locking_script_size: usize) -> Result { let wallet = self.inner.lock().await; let mut tx_builder = wallet.build_tx(); - // create a dummy script to make the txbuilder pass - // we don't intend to send this transaction, we just want to know the max amount - // we can spend - let dummy_script = Script::default(); + let dummy_script = Script::from(vec![0u8; locking_script_size]); tx_builder.set_single_recipient(dummy_script); - tx_builder.drain_wallet(); tx_builder.fee_rate(self.select_feerate()); let (_, details) = tx_builder.finish()?;