Skip to content

Commit 8369541

Browse files
author
Antoine Riard
committed
Add OnchainTxHandler::get_fully_signed_htlc
In case of channel force-closure, access to local commitment transactions and its dependent HTLCs is needed. Instead of using broadcast_by_local_state which registers outpoint to claim and outputs to watch which are going to be discarded in this case, we simply ask OnchainTxHandler to build and sign HTLC transactions through new API.
1 parent 6b8a516 commit 8369541

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

lightning/src/ln/channelmonitor.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,10 +1819,17 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
18191819
pub fn get_latest_local_commitment_txn(&mut self) -> Vec<Transaction> {
18201820
log_trace!(self, "Getting signed latest local commitment transaction!");
18211821
if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(self.channel_value_satoshis.unwrap()) {
1822+
let txid = commitment_tx.txid();
18221823
let mut res = vec![commitment_tx];
18231824
if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
1824-
let mut htlc_txn = self.broadcast_by_local_state(res.get(0).unwrap(), local_tx).0;
1825-
res.append(&mut htlc_txn);
1825+
for htlc in local_tx.htlc_outputs.iter() {
1826+
if let Some(htlc_index) = htlc.0.transaction_output_index {
1827+
let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None };
1828+
if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) {
1829+
res.push(htlc_tx);
1830+
}
1831+
}
1832+
}
18261833
// We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do.
18271834
// The data will be re-generated and tracked in check_spend_local_transaction if we get a confirmation.
18281835
}
@@ -1838,10 +1845,17 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
18381845
pub fn unsafe_get_latest_local_commitment_txn(&mut self) -> Vec<Transaction> {
18391846
log_trace!(self, "Getting signed copy of latest local commitment transaction!");
18401847
if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_copy_local_tx(self.channel_value_satoshis.unwrap()) {
1848+
let txid = commitment_tx.txid();
18411849
let mut res = vec![commitment_tx];
18421850
if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
1843-
let mut htlc_txn = self.broadcast_by_local_state(res.get(0).unwrap(), local_tx).0;
1844-
res.append(&mut htlc_txn);
1851+
for htlc in local_tx.htlc_outputs.iter() {
1852+
if let Some(htlc_index) = htlc.0.transaction_output_index {
1853+
let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None };
1854+
if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) {
1855+
res.push(htlc_tx);
1856+
}
1857+
}
1858+
}
18451859
}
18461860
return res
18471861
}

lightning/src/ln/onchaintx.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use secp256k1;
1515

1616
use ln::msgs::DecodeError;
1717
use ln::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER, InputMaterial, ClaimRequest};
18-
use ln::channelmanager::HTLCSource;
18+
use ln::channelmanager::{HTLCSource, PaymentPreimage};
1919
use ln::chan_utils;
2020
use ln::chan_utils::{HTLCType, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment};
2121
use chain::chaininterface::{FeeEstimator, BroadcasterInterface, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT};
@@ -893,4 +893,23 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
893893
}
894894
None
895895
}
896+
897+
pub(super) fn get_fully_signed_htlc_tx(&mut self, txid: Sha256dHash, htlc_index: u32, preimage: Option<PaymentPreimage>) -> Option<Transaction> {
898+
//TODO: store preimage in OnchainTxHandler
899+
if let Some(ref local_commitment) = self.local_commitment {
900+
if local_commitment.txid() == txid {
901+
if let Some(ref htlc_cache) = self.current_htlc_cache {
902+
if let Some(htlc) = htlc_cache.per_htlc.get(&htlc_index) {
903+
if !htlc.0.offered && preimage.is_none() { return None; }; // If we don't have preimage for HTLC-Success, don't try to generate
904+
let htlc_secret = if !htlc.0.offered { preimage } else { None }; // If we have a preimage for a HTLC-Timeout, don't use it that's likely a duplicate HTLC hash
905+
let mut htlc_tx = chan_utils::build_htlc_transaction(&txid, htlc_cache.feerate_per_kw, self.local_csv, &htlc.0, &htlc_cache.local_keys.a_delayed_payment_key, &htlc_cache.local_keys.revocation_key);
906+
self.key_storage.sign_htlc_transaction(&mut htlc_tx, htlc.1.as_ref().unwrap(), &htlc_secret, &htlc.0, &htlc_cache.local_keys.a_htlc_key, &htlc_cache.local_keys.b_htlc_key, &htlc_cache.local_keys.revocation_key, &htlc_cache.local_keys.per_commitment_point, &self.secp_ctx);
907+
return Some(htlc_tx);
908+
909+
}
910+
}
911+
}
912+
}
913+
None
914+
}
896915
}

0 commit comments

Comments
 (0)