Skip to content

Commit

Permalink
refactor spend_from_wallet and add checks for spend_amount.
Browse files Browse the repository at this point in the history
- check whether the given amount is feasible to spend or not.
- refactor the api to improve efficiency.
  • Loading branch information
KnowWhoami committed Sep 13, 2024
1 parent 7996388 commit 7b90d5b
Showing 1 changed file with 25 additions and 26 deletions.
51 changes: 25 additions & 26 deletions src/wallet/direct_send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,18 @@ impl Wallet {
coins_to_spend: &[(ListUnspentResultEntry, UTXOSpendInfo)],
) -> Result<Transaction, WalletError> {
log::info!("Creating Direct-Spend from Wallet.");
let mut tx_inputs = Vec::<TxIn>::new();
let mut spend_infos = Vec::new();

// Set the Anti-Fee-Snipping locktime
let current_height = self.rpc.get_block_count()?;
let lock_time = LockTime::from_height(current_height as u32)?;

let mut tx = Transaction {
version: Version::TWO,
lock_time,
input: vec![],
output: vec![],
};

let mut total_input_value = Amount::ZERO;

for (utxo_data, spend_info) in coins_to_spend {
Expand All @@ -93,24 +103,16 @@ impl Wallet {
_ => 0,
};

tx_inputs.push(TxIn {
tx.input.push(TxIn {
previous_output: OutPoint::new(utxo_data.txid, utxo_data.vout),
sequence: Sequence(sequence),
witness: Witness::new(),
script_sig: ScriptBuf::new(),
});

spend_infos.push(spend_info);

total_input_value += utxo_data.amount;
}

if tx_inputs.len() != coins_to_spend.len() {
return Err(WalletError::Protocol(
"Could not fetch all inputs.".to_string(),
));
}

log::info!("Total Input Amount: {} | Fees: {}", total_input_value, fee);

let dest_addr = match destination {
Expand All @@ -133,12 +135,19 @@ impl Wallet {
}
};

let mut output = Vec::<TxOut>::new();

let txout = {
let value = match send_amount {
SendAmount::Max => (total_input_value - fee).to_sat(),
SendAmount::Amount(a) => a.to_sat(),
SendAmount::Amount(a) => {
if a + fee <= total_input_value {
a.to_sat()
} else {
return Err(WalletError::Protocol(
"Insufficient funds: Amount plus fees exceeds available UTXOs."
.to_string(),
));
}
}
};
log::info!("Sending {} to {}.", value, dest_addr);
TxOut {
Expand All @@ -147,31 +156,21 @@ impl Wallet {
}
};

output.push(txout);
tx.output.push(txout);

// Only include change if remaining > dust
if let SendAmount::Amount(amount) = send_amount {
let internal_spk = self.get_next_internal_addresses(1)?[0].script_pubkey();
let remaining = total_input_value - amount - fee;
if remaining > internal_spk.minimal_non_dust() {
log::info!("Adding Change {}:{}", internal_spk, remaining);
output.push(TxOut {
tx.output.push(TxOut {
script_pubkey: internal_spk,
value: remaining,
});
}
}

// Set the Anti-Fee-Snipping locktime
let current_height = self.rpc.get_block_count()?;
let lock_time = LockTime::from_height(current_height as u32)?;

let mut tx = Transaction {
input: tx_inputs,
output,
lock_time,
version: Version::TWO,
};
self.sign_transaction(
&mut tx,
&mut coins_to_spend.iter().map(|(_, usi)| usi.clone()),
Expand Down

0 comments on commit 7b90d5b

Please sign in to comment.