Skip to content

Commit

Permalink
gui: reuse labels for rbf psbt
Browse files Browse the repository at this point in the history
close #861
  • Loading branch information
edouardparis committed Jan 31, 2024
1 parent dc2fb2a commit 6dd1d87
Showing 1 changed file with 54 additions and 17 deletions.
71 changes: 54 additions & 17 deletions gui/src/app/state/transactions.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
use std::{
collections::HashMap,
convert::TryInto,
sync::Arc,
time::{SystemTime, UNIX_EPOCH},
};

use iced::Command;
use liana::{
miniscript::bitcoin::Txid,
miniscript::bitcoin::{OutPoint, Txid},
spend::{SpendCreationError, MAX_FEERATE},
};
use liana_ui::{
component::{form, modal::Modal},
widget::*,
};

use crate::app::{
cache::Cache,
error::Error,
message::Message,
state::{label::LabelsEdited, State},
view,
use crate::{
app::{
cache::Cache,
error::Error,
message::Message,
state::{label::LabelsEdited, State},
view,
},
daemon::model,
};

use crate::daemon::{
model::{CreateSpendResult, HistoryTransaction, Labelled},
model::{CreateSpendResult, HistoryTransaction, LabelItem, Labelled},
Daemon,
};

Expand Down Expand Up @@ -125,8 +129,7 @@ impl State for TransactionsPanel {
.to_sat()
.checked_div(tx.tx.vsize().try_into().unwrap())
.unwrap();
let modal =
CreateRbfModal::new(tx.tx.txid(), is_cancel, prev_feerate_vb);
let modal = CreateRbfModal::new(tx.clone(), is_cancel, prev_feerate_vb);
self.create_rbf_modal = Some(modal);
}
}
Expand Down Expand Up @@ -239,7 +242,7 @@ impl From<TransactionsPanel> for Box<dyn State> {

pub struct CreateRbfModal {
/// Transaction to replace.
txid: Txid,
tx: model::HistoryTransaction,
/// Whether to cancel or bump fee.
is_cancel: bool,
/// Min feerate required for RBF.
Expand All @@ -256,10 +259,10 @@ pub struct CreateRbfModal {
}

impl CreateRbfModal {
fn new(txid: Txid, is_cancel: bool, prev_feerate_vb: u64) -> Self {
fn new(tx: model::HistoryTransaction, is_cancel: bool, prev_feerate_vb: u64) -> Self {
let min_feerate_vb = prev_feerate_vb.checked_add(1).unwrap();
Self {
txid,
tx,
is_cancel,
min_feerate_vb,
feerate_val: form::Value {
Expand Down Expand Up @@ -313,7 +316,7 @@ impl CreateRbfModal {
self.warning = None;
self.processing = true;
return Command::perform(
rbf(daemon, self.txid, self.is_cancel, self.feerate_vb),
rbf(daemon, self.tx.clone(), self.is_cancel, self.feerate_vb),
Message::RbfPsbt,
);
}
Expand Down Expand Up @@ -344,12 +347,12 @@ impl CreateRbfModal {

async fn rbf(
daemon: Arc<dyn Daemon + Sync + Send>,
txid: Txid,
previous_tx: model::HistoryTransaction,
is_cancel: bool,
feerate_vb: Option<u64>,
) -> Result<Txid, Error> {
let res = daemon.rbf_psbt(&txid, is_cancel, feerate_vb)?;
let psbt = match res {
let previous_txid = previous_tx.tx.txid();
let psbt = match daemon.rbf_psbt(&previous_txid, is_cancel, feerate_vb)? {
CreateSpendResult::Success { psbt, .. } => psbt,
CreateSpendResult::InsufficientFunds { missing } => {
return Err(
Expand All @@ -358,6 +361,40 @@ async fn rbf(
);
}
};

if !is_cancel {
let mut labels = HashMap::<LabelItem, Option<String>>::new();
let new_txid = psbt.unsigned_tx.txid();
for item in previous_tx.labelled() {
if let Some(label) = previous_tx.labels.get(&item.to_string()) {
match item {
LabelItem::Txid(_) => {
labels.insert(new_txid.into(), Some(label.to_string()));
}
LabelItem::OutPoint(o) => {
if let Some(previous_output) = previous_tx.tx.output.get(o.vout as usize) {
for (vout, output) in psbt.unsigned_tx.output.iter().enumerate() {
if output.script_pubkey == previous_output.script_pubkey {
labels.insert(
LabelItem::OutPoint(OutPoint {
txid: new_txid,
vout: vout as u32,
}),
Some(label.to_string()),
);
}
}
}
}
// Address label is already in database
LabelItem::Address(_) => {}
}
}
}

daemon.update_labels(&labels)?;
}

daemon.update_spend_tx(&psbt)?;
Ok(psbt.unsigned_tx.txid())
}

0 comments on commit 6dd1d87

Please sign in to comment.