parent
dc2fb2ac46
commit
6dd1d87228
@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
convert::TryInto,
|
||||
sync::Arc,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
@ -6,7 +7,7 @@ use std::{
|
||||
|
||||
use iced::Command;
|
||||
use liana::{
|
||||
miniscript::bitcoin::Txid,
|
||||
miniscript::bitcoin::{OutPoint, Txid},
|
||||
spend::{SpendCreationError, MAX_FEERATE},
|
||||
};
|
||||
use liana_ui::{
|
||||
@ -14,16 +15,19 @@ use liana_ui::{
|
||||
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,
|
||||
};
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
@ -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 {
|
||||
@ -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,
|
||||
);
|
||||
}
|
||||
@ -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(
|
||||
@ -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())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user