Merge #1508: [GUI] Improve coin selection logic when creating spend
e8d2fe2717583c071fc878b6d3f1fdb42c120bed send max from all owned coins only (Michael Mallan) 021c8e2a43239c39fffac26dc2f8a04eda3efda0 gui(spend): improve insufficient funds handling (Michael Mallan) 1b33e74a7a8b1d185a3aaea84a3ec6520ee05976 refactor: add `coin_is_owned` method (Michael Mallan) Pull request description: This is to resolve #1326. In case of insufficient funds when creating a spend, the selected coins will be updated to correspond to the missing amount. Previously, no changes were made to selected coins. Furthermore, if a user selects the max option for a recipient, only owned coins (confirmed or unconfirmed from self) will be considered rather than all coins, since unconfirmed coins that are not from self should only be used if the user has selected them manually. ACKs for top commit: edouardparis: utACK e8d2fe2717583c071fc878b6d3f1fdb42c120bed Tree-SHA512: 57869e04d486bb1debab323453183536f3d0ef65522a26aeb2be205262da52881f45a47035a8d0ad62c2e28366e4f23b44df70d41dd8cb017aad29dda651e5ed
This commit is contained in:
commit
36f47df60c
@ -29,7 +29,7 @@ use super::{
|
||||
|
||||
pub const HISTORY_EVENT_PAGE_SIZE: u64 = 20;
|
||||
|
||||
use crate::daemon::model::LabelsLoader;
|
||||
use crate::daemon::model::{coin_is_owned, LabelsLoader};
|
||||
use crate::daemon::{
|
||||
model::{remaining_sequence, Coin, HistoryTransaction, Payment},
|
||||
Daemon,
|
||||
@ -94,7 +94,7 @@ fn coins_summary(
|
||||
for coin in coins {
|
||||
if coin.spend_info.is_none() {
|
||||
// Include unconfirmed coins from self in confirmed balance.
|
||||
if coin.block_height.is_some() || coin.is_from_self {
|
||||
if coin_is_owned(coin) {
|
||||
balance += coin.amount;
|
||||
// Only consider confirmed coins for remaining seq
|
||||
// (they would not be considered as expiring so we can also skip that part)
|
||||
|
||||
@ -21,7 +21,7 @@ use liana_ui::{component::form, widget::Element};
|
||||
use crate::{
|
||||
app::{cache::Cache, error::Error, message::Message, state::psbt, view, wallet::Wallet},
|
||||
daemon::{
|
||||
model::{remaining_sequence, Coin, CreateSpendResult, SpendTx},
|
||||
model::{coin_is_owned, remaining_sequence, Coin, CreateSpendResult, SpendTx},
|
||||
Daemon,
|
||||
},
|
||||
};
|
||||
@ -283,8 +283,11 @@ impl DefineSpend {
|
||||
}
|
||||
outpoints
|
||||
} else if self.send_max_to_recipient.is_some() {
|
||||
// If user has not selected coins, send the max available from all coins.
|
||||
self.coins.iter().map(|(c, _)| c.outpoint).collect()
|
||||
// If user has not selected coins, send the max available from all owned coins.
|
||||
self.coins
|
||||
.iter()
|
||||
.filter_map(|(c, _)| coin_is_owned(c).then_some(c.outpoint))
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new() // pass empty list for auto-selection
|
||||
};
|
||||
@ -354,13 +357,15 @@ impl DefineSpend {
|
||||
);
|
||||
}
|
||||
}
|
||||
// For coin selection error (insufficient funds), do not make any changes to
|
||||
// selected coins on screen and just show user how much is left to select.
|
||||
// User can then either:
|
||||
// - modify recipient amounts and/or feerate and let coin selection run again, or
|
||||
// - select coins manually.
|
||||
Ok(CreateSpendResult::InsufficientFunds { missing }) => {
|
||||
self.amount_left_to_select = Some(Amount::from_sat(missing));
|
||||
if !self.is_user_coin_selection {
|
||||
// The missing amount is based on all candidates for coin selection
|
||||
// being used, which are all owned coins.
|
||||
for (coin, selected) in &mut self.coins {
|
||||
*selected = coin_is_owned(coin);
|
||||
}
|
||||
}
|
||||
if let Some((i, recipient)) = recipient_with_max {
|
||||
let amount = Amount::from_sat(if destinations.is_empty() {
|
||||
// If there are no other recipients, then the missing value will
|
||||
|
||||
@ -29,6 +29,13 @@ pub fn remaining_sequence(coin: &Coin, blockheight: u32, timelock: u16) -> u32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the coin is owned by this wallet.
|
||||
/// This comprises all confirmed coins together with those
|
||||
/// unconfirmed coins from self.
|
||||
pub fn coin_is_owned(coin: &Coin) -> bool {
|
||||
coin.block_height.is_some() || coin.is_from_self
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SpendTx {
|
||||
pub network: Network,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user