Merge #260: fix spend change detection
a56cab73c5c0193a90732f3ba0c2c5be7b993928 fix spend change detection (edouard)
Pull request description:
Use the presence of bip32_derivation
in the spend outputs to detect the
change outputs.
ACKs for top commit:
edouardparis:
Self-ACK a56cab73c5c0193a90732f3ba0c2c5be7b993928
Tree-SHA512: 092f8929ebed4ff4c80d8425a1c83831d165a5d31d0c80bc9aac26edf3dffb0241d547fe4fc5208e0dcb4caa39c09f85f3898af56cd0cd03136e5404b503d02e
This commit is contained in:
commit
4f2e19b2a6
@ -5,9 +5,7 @@ use std::sync::Arc;
|
||||
use iced::{Command, Element};
|
||||
use liana::{
|
||||
config::Config as DaemonConfig,
|
||||
miniscript::bitcoin::{
|
||||
self, util::psbt::Psbt, Address, Amount, Denomination, OutPoint, Script,
|
||||
},
|
||||
miniscript::bitcoin::{self, util::psbt::Psbt, Address, Amount, Denomination, OutPoint},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@ -416,26 +414,9 @@ impl SaveSpend {
|
||||
|
||||
impl Step for SaveSpend {
|
||||
fn load(&mut self, draft: &TransactionDraft) {
|
||||
let outputs_script_pubkeys: Vec<Script> = draft
|
||||
.outputs
|
||||
.keys()
|
||||
.map(|addr| addr.script_pubkey())
|
||||
.collect();
|
||||
let index = if let Some(psbt) = &draft.generated {
|
||||
psbt.unsigned_tx
|
||||
.output
|
||||
.iter()
|
||||
.position(|output| !outputs_script_pubkeys.contains(&output.script_pubkey))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.spend = Some(detail::SpendTxState::new(
|
||||
self.config.clone(),
|
||||
SpendTx::new(
|
||||
draft.generated.clone().unwrap(),
|
||||
index,
|
||||
draft.inputs.clone(),
|
||||
),
|
||||
SpendTx::new(draft.generated.clone().unwrap(), draft.inputs.clone()),
|
||||
false,
|
||||
));
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ pub fn spend_view<'a, T: Into<Element<'a, Message>>>(
|
||||
&tx.coins,
|
||||
&tx.psbt.unsigned_tx,
|
||||
network,
|
||||
tx.change_index.map(|i| vec![i]),
|
||||
Some(tx.change_indexes.clone()),
|
||||
None,
|
||||
)),
|
||||
)
|
||||
|
||||
@ -88,7 +88,7 @@ pub trait Daemon: Debug {
|
||||
})
|
||||
.copied()
|
||||
.collect();
|
||||
model::SpendTx::new(tx.psbt, tx.change_index.map(|i| i as usize), coins)
|
||||
model::SpendTx::new(tx.psbt, coins)
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ pub fn remaining_sequence(coin: &Coin, blockheight: u32, timelock: u32) -> u32 {
|
||||
pub struct SpendTx {
|
||||
pub coins: Vec<Coin>,
|
||||
pub psbt: Psbt,
|
||||
pub change_index: Option<usize>,
|
||||
pub change_indexes: Vec<usize>,
|
||||
pub spend_amount: Amount,
|
||||
pub fee_amount: Amount,
|
||||
pub status: SpendStatus,
|
||||
@ -38,11 +38,13 @@ pub enum SpendStatus {
|
||||
}
|
||||
|
||||
impl SpendTx {
|
||||
pub fn new(psbt: Psbt, change_index: Option<usize>, coins: Vec<Coin>) -> Self {
|
||||
pub fn new(psbt: Psbt, coins: Vec<Coin>) -> Self {
|
||||
let mut change_indexes = Vec::new();
|
||||
let (change_amount, spend_amount) = psbt.unsigned_tx.output.iter().enumerate().fold(
|
||||
(Amount::from_sat(0), Amount::from_sat(0)),
|
||||
|(change, spend), (i, output)| {
|
||||
if Some(i) == change_index {
|
||||
if !psbt.outputs[i].bip32_derivation.is_empty() {
|
||||
change_indexes.push(i);
|
||||
(change + Amount::from_sat(output.value), spend)
|
||||
} else {
|
||||
(change, spend + Amount::from_sat(output.value))
|
||||
@ -66,7 +68,7 @@ impl SpendTx {
|
||||
Self {
|
||||
coins,
|
||||
psbt,
|
||||
change_index,
|
||||
change_indexes,
|
||||
spend_amount,
|
||||
fee_amount: inputs_amount - spend_amount - change_amount,
|
||||
status,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user