diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 5f456c7bfe8..75183d976f9 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -167,12 +167,14 @@ pub struct HTLCUpdate { pub(crate) payment_preimage: Option, pub(crate) source: HTLCSource, pub(crate) onchain_value_satoshis: Option, + pub(crate) forward_channel_id: [u8; 32], } impl_writeable_tlv_based!(HTLCUpdate, { (0, payment_hash, required), (1, onchain_value_satoshis, option), (2, source, required), (4, payment_preimage, option), + (6, forward_channel_id, required) }); /// If an HTLC expires within this many blocks, don't try to claim it in a shared transaction, @@ -2512,6 +2514,7 @@ impl ChannelMonitorImpl { payment_preimage: None, source: source.clone(), onchain_value_satoshis, + forward_channel_id: self.funding_info.0.to_channel_id(), })); if let Some(idx) = input_idx { self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC { input_idx: idx, payment_preimage: None }); @@ -2851,6 +2854,7 @@ impl ChannelMonitorImpl { payment_preimage: Some(payment_preimage), payment_hash, onchain_value_satoshis: Some(amount_msat / 1000), + forward_channel_id: self.funding_info.0.to_channel_id(), })); } } else if offered_preimage_claim { @@ -2872,6 +2876,7 @@ impl ChannelMonitorImpl { payment_preimage: Some(payment_preimage), payment_hash, onchain_value_satoshis: Some(amount_msat / 1000), + forward_channel_id: self.funding_info.0.to_channel_id(), })); } } else { diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 95f1e86b9c3..122fdebb9b8 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -3952,7 +3952,7 @@ impl ChannelMana } } - fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard>, source: HTLCSource, payment_preimage: PaymentPreimage, forwarded_htlc_value_msat: Option, from_onchain: bool) { + fn claim_funds_internal(&self, mut channel_state_lock: MutexGuard>, source: HTLCSource, payment_preimage: PaymentPreimage, forwarded_htlc_value_msat: Option, from_onchain: bool, to_channel_id: [u8; 32]) { match source { HTLCSource::OutboundRoute { session_priv, payment_id, path, .. } => { mem::drop(channel_state_lock); @@ -4030,6 +4030,10 @@ impl ChannelMana // update to. Instead, we simply document in `PaymentForwarded` that this // can happen. } + + // Seems like if the prev hop force closed then we wont be able to get the channel_id from short_channel_id + let from_channel_id = channel_state_lock.short_to_id.get(&hop_data.short_channel_id).map(|chan_id| chan_id.clone()); + mem::drop(channel_state_lock); if let ClaimFundsFromHop::MonitorUpdateFail(pk, err, _) = res { let result: Result<(), _> = Err(err); @@ -4044,6 +4048,8 @@ impl ChannelMana let mut pending_events = self.pending_events.lock().unwrap(); pending_events.push(events::Event::PaymentForwarded { + from_channel_id, + to_channel_id, fee_earned_msat, claim_from_onchain_tx: from_onchain, }); @@ -4458,7 +4464,7 @@ impl ChannelMana hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id)) } }; - self.claim_funds_internal(channel_lock, htlc_source, msg.payment_preimage.clone(), Some(forwarded_htlc_value), false); + self.claim_funds_internal(channel_lock, htlc_source, msg.payment_preimage.clone(), Some(forwarded_htlc_value), false, msg.channel_id); Ok(()) } @@ -4777,7 +4783,7 @@ impl ChannelMana MonitorEvent::HTLCEvent(htlc_update) => { if let Some(preimage) = htlc_update.payment_preimage { log_trace!(self.logger, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0)); - self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage, htlc_update.onchain_value_satoshis.map(|v| v * 1000), true); + self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage, htlc_update.onchain_value_satoshis.map(|v| v * 1000), true, htlc_update.forward_channel_id); } else { log_trace!(self.logger, "Failing HTLC with hash {} from our monitor", log_bytes!(htlc_update.payment_hash.0)); self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index a4a733c8e50..36b5718980f 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -360,6 +360,11 @@ pub enum Event { /// If this is `true`, the forwarded HTLC was claimed by our counterparty via an on-chain /// transaction. claim_from_onchain_tx: bool, + /// The channel_id of the channel which sent us the payment. If the channel has been + /// force-closed this will be None + from_channel_id: Option<[u8; 32]>, + /// The channel_id of the channel which we forwarded the payment along + to_channel_id: [u8; 32], }, /// Used to indicate that a channel with the given `channel_id` is in the process of closure. ChannelClosed { @@ -478,13 +483,20 @@ impl Writeable for Event { (0, VecWriteWrapper(outputs), required), }); }, - &Event::PaymentForwarded { fee_earned_msat, claim_from_onchain_tx } => { + &Event::PaymentForwarded { + fee_earned_msat, + claim_from_onchain_tx, + from_channel_id, + to_channel_id, + } => { 7u8.write(writer)?; write_tlv_fields!(writer, { (0, fee_earned_msat, option), (2, claim_from_onchain_tx, required), + (4, from_channel_id, option), + (6, to_channel_id, required) }); - }, + } &Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason } => { 9u8.write(writer)?; write_tlv_fields!(writer, { @@ -638,11 +650,20 @@ impl MaybeReadable for Event { let f = || { let mut fee_earned_msat = None; let mut claim_from_onchain_tx = false; + let mut from_channel_id = None; + let mut to_channel_id = [0; 32]; read_tlv_fields!(reader, { (0, fee_earned_msat, option), (2, claim_from_onchain_tx, required), + (4, from_channel_id, option), + (6, to_channel_id, required) }); - Ok(Some(Event::PaymentForwarded { fee_earned_msat, claim_from_onchain_tx })) + Ok(Some(Event::PaymentForwarded { + fee_earned_msat, + claim_from_onchain_tx, + from_channel_id, + to_channel_id, + })) }; f() },