X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fevents.rs;h=28bd6978f6a5c9c7dad0563639e30a163bec5062;hb=de2acc0ee0166e9d6cbd3a89459e08ee4ac6a4d5;hp=3032aec75820d2d602a9ebf6d619ac7f13bf9cc1;hpb=babde3a3c5a1d11aead782f6a1aba9485016a80f;p=rust-lightning diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index 3032aec7..28bd6978 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -17,7 +17,7 @@ use crate::chain::keysinterface::SpendableOutputDescriptor; #[cfg(anchors)] use crate::ln::chan_utils::HTLCOutputInCommitment; -use crate::ln::channelmanager::PaymentId; +use crate::ln::channelmanager::{InterceptId, PaymentId}; use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS; use crate::ln::features::ChannelTypeFeatures; use crate::ln::msgs; @@ -182,6 +182,12 @@ pub enum HTLCDestination { /// Short channel id we are requesting to forward an HTLC to. requested_forward_scid: u64, }, + /// We couldn't forward to the outgoing scid. An example would be attempting to send a duplicate + /// intercept HTLC. + InvalidForward { + /// Short channel id we are requesting to forward an HTLC to. + requested_forward_scid: u64 + }, /// Failure scenario where an HTLC may have been forwarded to be intended for us, /// but is invalid for some reason, so we reject it. /// @@ -200,12 +206,15 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCDestination, (0, node_id, required), (2, channel_id, required), }, + (1, InvalidForward) => { + (0, requested_forward_scid, required), + }, (2, UnknownNextHop) => { (0, requested_forward_scid, required), }, (4, FailedPayment) => { (0, payment_hash, required), - } + }, ); #[cfg(anchors)] @@ -288,6 +297,22 @@ pub enum BumpTransactionEvent { }, } +/// Will be used in [`Event::HTLCIntercepted`] to identify the next hop in the HTLC's path. +/// Currently only used in serialization for the sake of maintaining compatibility. More variants +/// will be added for general-purpose HTLC forward intercepts as well as trampoline forward +/// intercepts in upcoming work. +enum InterceptNextHop { + FakeScid { + requested_next_hop_scid: u64, + }, +} + +impl_writeable_tlv_based_enum!(InterceptNextHop, + (0, FakeScid) => { + (0, requested_next_hop_scid, required), + }; +); + /// An Event which you should probably take some action in response to. /// /// Note that while Writeable and Readable are implemented for Event, you probably shouldn't use @@ -325,8 +350,8 @@ pub enum Event { /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel user_channel_id: u128, }, - /// Indicates we've received (an offer of) money! Just gotta dig out that payment preimage and - /// feed it to [`ChannelManager::claim_funds`] to get it.... + /// Indicates that we've been offered a payment and it needs to be claimed via calling + /// [`ChannelManager::claim_funds`] with the preimage given in [`PaymentPurpose`]. /// /// Note that if the preimage is not known, you should call /// [`ChannelManager::fail_htlc_backwards`] to free up resources for this HTLC and avoid @@ -337,17 +362,20 @@ pub enum Event { /// /// # Note /// LDK will not stop an inbound payment from being paid multiple times, so multiple - /// `PaymentReceived` events may be generated for the same payment. + /// `PaymentClaimable` events may be generated for the same payment. + /// + /// # Note + /// This event used to be called `PaymentReceived` in LDK versions 0.0.112 and earlier. /// /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds /// [`ChannelManager::fail_htlc_backwards`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards - PaymentReceived { - /// The node that received the payment. - /// This is useful to identify payments which were received via [phantom node payments]. + PaymentClaimable { + /// The node that will receive the payment after it has been claimed. + /// This is useful to identify payments received via [phantom nodes]. /// This field will always be filled in when the event was generated by LDK versions /// 0.0.113 and above. /// - /// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager + /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager receiver_node_id: Option, /// The hash for which the preimage should be handed to the ChannelManager. Note that LDK will /// not stop you from registering duplicate payment hashes for inbound payments. @@ -357,35 +385,39 @@ pub enum Event { /// Information for claiming this received payment, based on whether the purpose of the /// payment is to pay an invoice or to send a spontaneous payment. purpose: PaymentPurpose, + /// The `channel_id` indicating over which channel we received the payment. + via_channel_id: Option<[u8; 32]>, + /// The `user_channel_id` indicating over which channel we received the payment. + via_user_channel_id: Option, }, /// Indicates a payment has been claimed and we've received money! /// /// This most likely occurs when [`ChannelManager::claim_funds`] has been called in response - /// to an [`Event::PaymentReceived`]. However, if we previously crashed during a + /// to an [`Event::PaymentClaimable`]. However, if we previously crashed during a /// [`ChannelManager::claim_funds`] call you may see this event without a corresponding - /// [`Event::PaymentReceived`] event. + /// [`Event::PaymentClaimable`] event. /// /// # Note /// LDK will not stop an inbound payment from being paid multiple times, so multiple - /// `PaymentReceived` events may be generated for the same payment. If you then call - /// [`ChannelManager::claim_funds`] twice for the same [`Event::PaymentReceived`] you may get + /// `PaymentClaimable` events may be generated for the same payment. If you then call + /// [`ChannelManager::claim_funds`] twice for the same [`Event::PaymentClaimable`] you may get /// multiple `PaymentClaimed` events. /// /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds PaymentClaimed { /// The node that received the payment. - /// This is useful to identify payments which were received via [phantom node payments]. + /// This is useful to identify payments which were received via [phantom nodes]. /// This field will always be filled in when the event was generated by LDK versions /// 0.0.113 and above. /// - /// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager + /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager receiver_node_id: Option, /// The payment hash of the claimed payment. Note that LDK will not stop you from /// registering duplicate payment hashes for inbound payments. payment_hash: PaymentHash, /// The value, in thousandths of a satoshi, that this payment is for. amount_msat: u64, - /// The purpose of this claimed payment, i.e. whether the payment was for an invoice or a + /// The purpose of the claimed payment, i.e. whether the payment was for an invoice or a /// spontaneous payment. purpose: PaymentPurpose, }, @@ -581,6 +613,38 @@ pub enum Event { /// now + 5*time_forwardable). time_forwardable: Duration, }, + /// Used to indicate that we've intercepted an HTLC forward. This event will only be generated if + /// you've encoded an intercept scid in the receiver's invoice route hints using + /// [`ChannelManager::get_intercept_scid`] and have set [`UserConfig::accept_intercept_htlcs`]. + /// + /// [`ChannelManager::forward_intercepted_htlc`] or + /// [`ChannelManager::fail_intercepted_htlc`] MUST be called in response to this event. See + /// their docs for more information. + /// + /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid + /// [`UserConfig::accept_intercept_htlcs`]: crate::util::config::UserConfig::accept_intercept_htlcs + /// [`ChannelManager::forward_intercepted_htlc`]: crate::ln::channelmanager::ChannelManager::forward_intercepted_htlc + /// [`ChannelManager::fail_intercepted_htlc`]: crate::ln::channelmanager::ChannelManager::fail_intercepted_htlc + HTLCIntercepted { + /// An id to help LDK identify which HTLC is being forwarded or failed. + intercept_id: InterceptId, + /// The fake scid that was programmed as the next hop's scid, generated using + /// [`ChannelManager::get_intercept_scid`]. + /// + /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid + requested_next_hop_scid: u64, + /// The payment hash used for this HTLC. + payment_hash: PaymentHash, + /// How many msats were received on the inbound edge of this HTLC. + inbound_amount_msat: u64, + /// How many msats the payer intended to route to the next node. Depending on the reason you are + /// intercepting this payment, you might take a fee by forwarding less than this amount. + /// + /// Note that LDK will NOT check that expected fees were factored into this value. You MUST + /// check that whatever fee you want has been included here or subtract it as required. Further, + /// LDK will not stop you from forwarding more than you received. + expected_outbound_amount_msat: u64, + }, /// Used to indicate that an output which you should know how to spend was confirmed on chain /// and is now spendable. /// Such an output will *not* ever be spent by rust-lightning, and are not at risk of your @@ -753,7 +817,7 @@ impl Writeable for Event { // We never write out FundingGenerationReady events as, upon disconnection, peers // drop any channels which have not yet exchanged funding_signed. }, - &Event::PaymentReceived { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id } => { + &Event::PaymentClaimable { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id, ref via_channel_id, ref via_user_channel_id } => { 1u8.write(writer)?; let mut payment_secret = None; let payment_preimage; @@ -770,7 +834,9 @@ impl Writeable for Event { (0, payment_hash, required), (1, receiver_node_id, option), (2, payment_secret, option), + (3, via_channel_id, option), (4, amount_msat, required), + (5, via_user_channel_id, option), (6, 0u64, required), // user_payment_id required for compatibility with 0.0.103 and earlier (8, payment_preimage, option), }); @@ -819,6 +885,17 @@ impl Writeable for Event { (0, WithoutLength(outputs), required), }); }, + &Event::HTLCIntercepted { requested_next_hop_scid, payment_hash, inbound_amount_msat, expected_outbound_amount_msat, intercept_id } => { + 6u8.write(writer)?; + let intercept_scid = InterceptNextHop::FakeScid { requested_next_hop_scid }; + write_tlv_fields!(writer, { + (0, intercept_id, required), + (2, intercept_scid, required), + (4, payment_hash, required), + (6, inbound_amount_msat, required), + (8, expected_outbound_amount_msat, required), + }); + } &Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => { 7u8.write(writer)?; write_tlv_fields!(writer, { @@ -941,11 +1018,15 @@ impl MaybeReadable for Event { let mut amount_msat = 0; let mut receiver_node_id = None; let mut _user_payment_id = None::; // For compatibility with 0.0.103 and earlier + let mut via_channel_id = None; + let mut via_user_channel_id = None; read_tlv_fields!(reader, { (0, payment_hash, required), (1, receiver_node_id, option), (2, payment_secret, option), + (3, via_channel_id, option), (4, amount_msat, required), + (5, via_user_channel_id, option), (6, _user_payment_id, option), (8, payment_preimage, option), }); @@ -957,11 +1038,13 @@ impl MaybeReadable for Event { None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()), None => return Err(msgs::DecodeError::InvalidValue), }; - Ok(Some(Event::PaymentReceived { + Ok(Some(Event::PaymentClaimable { receiver_node_id, payment_hash, amount_msat, purpose, + via_channel_id, + via_user_channel_id, })) }; f() @@ -1042,6 +1125,30 @@ impl MaybeReadable for Event { }; f() }, + 6u8 => { + let mut payment_hash = PaymentHash([0; 32]); + let mut intercept_id = InterceptId([0; 32]); + let mut requested_next_hop_scid = InterceptNextHop::FakeScid { requested_next_hop_scid: 0 }; + let mut inbound_amount_msat = 0; + let mut expected_outbound_amount_msat = 0; + read_tlv_fields!(reader, { + (0, intercept_id, required), + (2, requested_next_hop_scid, required), + (4, payment_hash, required), + (6, inbound_amount_msat, required), + (8, expected_outbound_amount_msat, required), + }); + let next_scid = match requested_next_hop_scid { + InterceptNextHop::FakeScid { requested_next_hop_scid: scid } => scid + }; + Ok(Some(Event::HTLCIntercepted { + payment_hash, + requested_next_hop_scid: next_scid, + inbound_amount_msat, + expected_outbound_amount_msat, + intercept_id, + })) + }, 7u8 => { let f = || { let mut fee_earned_msat = None;