X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fevents.rs;h=1780483cb8b9e01bcab8d5f0c18e812522d27a7f;hb=69ee4860848d5992b238eca3343141004d9d1572;hp=dbb4178fb50e4643db6e2332d0e257bab18f8e29;hpb=4353d4a11c12c148fbf3e95dd2e2f824f60433df;p=rust-lightning diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index dbb4178f..1780483c 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -23,10 +23,50 @@ use bitcoin::blockdata::script::Script; use bitcoin::secp256k1::key::PublicKey; +use io; use prelude::*; use core::time::Duration; use core::ops::Deref; +/// Some information provided on receipt of payment depends on whether the payment received is a +/// spontaneous payment or a "conventional" lightning payment that's paying an invoice. +#[derive(Clone, Debug)] +pub enum PaymentPurpose { + /// Information for receiving a payment that we generated an invoice for. + InvoicePayment { + /// The preimage to the payment_hash, if the payment hash (and secret) were fetched via + /// [`ChannelManager::create_inbound_payment`]. If provided, this can be handed directly to + /// [`ChannelManager::claim_funds`]. + /// + /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment + /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds + payment_preimage: Option, + /// The "payment secret". This authenticates the sender to the recipient, preventing a + /// number of deanonymization attacks during the routing process. + /// It is provided here for your reference, however its accuracy is enforced directly by + /// [`ChannelManager`] using the values you previously provided to + /// [`ChannelManager::create_inbound_payment`] or + /// [`ChannelManager::create_inbound_payment_for_hash`]. + /// + /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager + /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment + /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash + payment_secret: PaymentSecret, + /// This is the `user_payment_id` which was provided to + /// [`ChannelManager::create_inbound_payment_for_hash`] or + /// [`ChannelManager::create_inbound_payment`]. It has no meaning inside of LDK and is + /// simply copied here. It may be used to correlate PaymentReceived events with invoice + /// metadata stored elsewhere. + /// + /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment + /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash + user_payment_id: u64, + }, + /// Because this is a spontaneous payment, the payer generated their own preimage rather than us + /// (the payee) providing a preimage. + SpontaneousPayment(PaymentPreimage), +} + /// 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 @@ -63,37 +103,13 @@ pub enum Event { PaymentReceived { /// The hash for which the preimage should be handed to the ChannelManager. payment_hash: PaymentHash, - /// The preimage to the payment_hash, if the payment hash (and secret) were fetched via - /// [`ChannelManager::create_inbound_payment`]. If provided, this can be handed directly to - /// [`ChannelManager::claim_funds`]. - /// - /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment - /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds - payment_preimage: Option, - /// The "payment secret". This authenticates the sender to the recipient, preventing a - /// number of deanonymization attacks during the routing process. - /// It is provided here for your reference, however its accuracy is enforced directly by - /// [`ChannelManager`] using the values you previously provided to - /// [`ChannelManager::create_inbound_payment`] or - /// [`ChannelManager::create_inbound_payment_for_hash`]. - /// - /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager - /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment - /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash - payment_secret: PaymentSecret, /// The value, in thousandths of a satoshi, that this payment is for. Note that you must /// compare this to the expected value before accepting the payment (as otherwise you are /// providing proof-of-payment for less than the value you expected!). amt: u64, - /// This is the `user_payment_id` which was provided to - /// [`ChannelManager::create_inbound_payment_for_hash`] or - /// [`ChannelManager::create_inbound_payment`]. It has no meaning inside of LDK and is - /// simply copied here. It may be used to correlate PaymentReceived events with invoice - /// metadata stored elsewhere. - /// - /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment - /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash - user_payment_id: u64, + /// 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, }, /// Indicates an outbound payment we made succeeded (ie it made it all the way to its target /// and we got back the payment preimage for it). @@ -135,23 +151,57 @@ pub enum Event { /// The outputs which you should store as spendable by you. outputs: Vec, }, + /// This event is generated when a payment has been successfully forwarded through us and a + /// forwarding fee earned. + PaymentForwarded { + /// The fee, in milli-satoshis, which was earned as a result of the payment. + /// + /// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC + /// was pending, the amount the next hop claimed will have been rounded down to the nearest + /// whole satoshi. Thus, the fee calculated here may be higher than expected as we still + /// claimed the full value in millisatoshis from the source. In this case, + /// `claim_from_onchain_tx` will be set. + /// + /// If the channel which sent us the payment has been force-closed, we will claim the funds + /// via an on-chain transaction. In that case we do not yet know the on-chain transaction + /// fees which we will spend and will instead set this to `None`. It is possible duplicate + /// `PaymentForwarded` events are generated for the same payment iff `fee_earned_msat` is + /// `None`. + fee_earned_msat: Option, + /// If this is `true`, the forwarded HTLC was claimed by our counterparty via an on-chain + /// transaction. + claim_from_onchain_tx: bool, + }, } impl Writeable for Event { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { match self { &Event::FundingGenerationReady { .. } => { 0u8.write(writer)?; // 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 payment_preimage, ref payment_secret, ref amt, ref user_payment_id } => { + &Event::PaymentReceived { ref payment_hash, ref amt, ref purpose } => { 1u8.write(writer)?; + let mut payment_secret = None; + let mut user_payment_id = None; + let payment_preimage; + match &purpose { + PaymentPurpose::InvoicePayment { payment_preimage: preimage, payment_secret: secret, user_payment_id: id } => { + payment_secret = Some(secret); + payment_preimage = *preimage; + user_payment_id = Some(id); + }, + PaymentPurpose::SpontaneousPayment(preimage) => { + payment_preimage = Some(*preimage); + } + } write_tlv_fields!(writer, { (0, payment_hash, required), - (2, payment_secret, required), + (2, payment_secret, option), (4, amt, required), - (6, user_payment_id, required), + (6, user_payment_id, option), (8, payment_preimage, option), }); }, @@ -189,34 +239,50 @@ impl Writeable for Event { (0, VecWriteWrapper(outputs), required), }); }, + &Event::PaymentForwarded { fee_earned_msat, claim_from_onchain_tx } => { + 7u8.write(writer)?; + write_tlv_fields!(writer, { + (0, fee_earned_msat, option), + (2, claim_from_onchain_tx, required), + }); + }, } Ok(()) } } impl MaybeReadable for Event { - fn read(reader: &mut R) -> Result, msgs::DecodeError> { + fn read(reader: &mut R) -> Result, msgs::DecodeError> { match Readable::read(reader)? { 0u8 => Ok(None), 1u8 => { let f = || { let mut payment_hash = PaymentHash([0; 32]); let mut payment_preimage = None; - let mut payment_secret = PaymentSecret([0; 32]); + let mut payment_secret = None; let mut amt = 0; - let mut user_payment_id = 0; + let mut user_payment_id = None; read_tlv_fields!(reader, { (0, payment_hash, required), - (2, payment_secret, required), + (2, payment_secret, option), (4, amt, required), - (6, user_payment_id, required), + (6, user_payment_id, option), (8, payment_preimage, option), }); + let purpose = match payment_secret { + Some(secret) => PaymentPurpose::InvoicePayment { + payment_preimage, + payment_secret: secret, + user_payment_id: if let Some(id) = user_payment_id { + id + } else { return Err(msgs::DecodeError::InvalidValue) } + }, + None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()), + None => return Err(msgs::DecodeError::InvalidValue), + }; Ok(Some(Event::PaymentReceived { payment_hash, - payment_preimage, - payment_secret, amt, - user_payment_id, + purpose, })) }; f() @@ -275,6 +341,20 @@ impl MaybeReadable for Event { }; f() }, + 7u8 => { + let f = || { + let mut fee_earned_msat = None; + let mut claim_from_onchain_tx = false; + read_tlv_fields!(reader, { + (0, fee_earned_msat, option), + (2, claim_from_onchain_tx, required), + }); + Ok(Some(Event::PaymentForwarded { fee_earned_msat, claim_from_onchain_tx })) + }; + f() + }, + // Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue. + x if x % 2 == 1 => Ok(None), _ => Err(msgs::DecodeError::InvalidValue) } } @@ -389,6 +469,15 @@ pub enum MessageSendEvent { /// The channel_update which should be sent. msg: msgs::ChannelUpdate, }, + /// Used to indicate that a channel_update should be sent to a single peer. + /// In contrast to [`Self::BroadcastChannelUpdate`], this is used when the channel is a + /// private channel and we shouldn't be informing all of our peers of channel parameters. + SendChannelUpdate { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The channel_update which should be sent. + msg: msgs::ChannelUpdate, + }, /// Broadcast an error downstream to be handled HandleError { /// The node_id of the node which should receive this message