From 7499a4bf9bf7c1b6b29de0b563080dae490e02e3 Mon Sep 17 00:00:00 2001 From: Antoine Riard Date: Mon, 10 Dec 2018 14:28:24 -0500 Subject: [PATCH] Detect onchain timeout of a HTLC in ChannelManager block_connected Pass failure backward --- src/ln/channelmanager.rs | 4 +++- src/ln/channelmonitor.rs | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index 52819526..c2082f6e 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -1558,7 +1558,7 @@ impl ChannelManager { rejected_by_dest: !payment_retryable, }); } else { - panic!("should have onion error packet here"); + //TODO: Pass this back (see GH #243) } }, HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret }) => { @@ -2715,6 +2715,8 @@ impl ChainListener for ChannelManager { for htlc_update in self.monitor.fetch_pending_htlc_updated() { if let Some(preimage) = htlc_update.payment_preimage { self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage); + } else { + self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() }); } } } diff --git a/src/ln/channelmonitor.rs b/src/ln/channelmonitor.rs index 7c4dd735..59c50061 100644 --- a/src/ln/channelmonitor.rs +++ b/src/ln/channelmonitor.rs @@ -1295,6 +1295,31 @@ impl ChannelMonitor { txn_to_broadcast.push(single_htlc_tx); } } + if !htlc.offered { + // TODO: If the HTLC has already expired, potentially merge it with the + // rest of the claim transaction, as above. + let input = TxIn { + previous_output: BitcoinOutPoint { + txid: commitment_txid, + vout: htlc.transaction_output_index, + }, + script_sig: Script::new(), + sequence: idx as u32, + witness: Vec::new(), + }; + let mut timeout_tx = Transaction { + version: 2, + lock_time: htlc.cltv_expiry, + input: vec![input], + output: vec!(TxOut { + script_pubkey: self.destination_script.clone(), + value: htlc.amount_msat / 1000, + }), + }; + let sighash_parts = bip143::SighashComponents::new(&timeout_tx); + sign_input!(sighash_parts, timeout_tx.input[0], htlc.amount_msat / 1000, vec![0]); + txn_to_broadcast.push(timeout_tx); + } } if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs, htlc_updated); } // Nothing to be done...probably a false positive/local tx -- 2.30.2