Skip to content

Commit a0bd38f

Browse files
jkczyzbenthecarman
authored andcommitted
Handle LdkEvent::FundingTransactionReadyForSigning
When the interactive-tx construction protocol completes in LDK during splicing (and in the future dual-funding), LDK Node must provide signatures for any non-shared inputs belonging to its on-chain wallet. This commit implements this when handling the corresponding FundingTransactionReadyForSigning event.
1 parent e139312 commit a0bd38f

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

src/event.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,8 +1642,35 @@ where
16421642
}
16431643
}
16441644
},
1645-
LdkEvent::FundingTransactionReadyForSigning { .. } => {
1646-
debug_assert!(false, "We currently don't support interactive-tx, so this event should never be emitted.");
1645+
LdkEvent::FundingTransactionReadyForSigning {
1646+
channel_id,
1647+
counterparty_node_id,
1648+
unsigned_transaction,
1649+
..
1650+
} => {
1651+
let partially_signed_tx =
1652+
self.wallet.sign_owned_inputs(unsigned_transaction).map_err(|()| {
1653+
log_error!(self.logger, "Failed signing funding transaction");
1654+
ReplayEvent()
1655+
})?;
1656+
1657+
self.channel_manager
1658+
.funding_transaction_signed(
1659+
&channel_id,
1660+
&counterparty_node_id,
1661+
partially_signed_tx,
1662+
)
1663+
.map_err(|e| {
1664+
log_error!(self.logger, "Failed signing funding transaction: {:?}", e);
1665+
ReplayEvent()
1666+
})?;
1667+
1668+
log_info!(
1669+
self.logger,
1670+
"Signed funding transaction for channel {} with counterparty {}",
1671+
channel_id,
1672+
counterparty_node_id
1673+
);
16471674
},
16481675
LdkEvent::SplicePending {
16491676
channel_id,

src/wallet/mod.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,40 @@ impl Wallet {
664664
Ok(address_info.address.script_pubkey())
665665
}
666666

667+
#[allow(deprecated)]
668+
pub(crate) fn sign_owned_inputs(&self, unsigned_tx: Transaction) -> Result<Transaction, ()> {
669+
let locked_wallet = self.inner.lock().unwrap();
670+
671+
let mut psbt = Psbt::from_unsigned_tx(unsigned_tx).map_err(|e| {
672+
log_error!(self.logger, "Failed to construct PSBT: {}", e);
673+
})?;
674+
for (i, txin) in psbt.unsigned_tx.input.iter().enumerate() {
675+
if let Some(utxo) = locked_wallet.get_utxo(txin.previous_output) {
676+
psbt.inputs[i] = locked_wallet.get_psbt_input(utxo, None, true).map_err(|e| {
677+
log_error!(self.logger, "Failed to construct PSBT input: {}", e);
678+
})?;
679+
}
680+
}
681+
682+
let mut sign_options = SignOptions::default();
683+
sign_options.trust_witness_utxo = true;
684+
685+
match locked_wallet.sign(&mut psbt, sign_options) {
686+
Ok(finalized) => debug_assert!(!finalized),
687+
Err(e) => {
688+
log_error!(self.logger, "Failed to sign owned inputs: {}", e);
689+
return Err(());
690+
},
691+
}
692+
693+
let mut tx = psbt.unsigned_tx;
694+
for (txin, input) in tx.input.iter_mut().zip(psbt.inputs.into_iter()) {
695+
txin.witness = input.final_script_witness.unwrap_or_default();
696+
}
697+
698+
Ok(tx)
699+
}
700+
667701
#[allow(deprecated)]
668702
fn sign_psbt_inner(&self, mut psbt: Psbt) -> Result<Transaction, ()> {
669703
let locked_wallet = self.inner.lock().unwrap();

0 commit comments

Comments
 (0)