Enforce explicit claims on payments with even custom TLVs
[rust-lightning] / lightning / src / events / mod.rs
index 665fd0ed23a51ae27b7c260b33717ac9690f74db..f8d251c91c7f43616ddcf10d3d5e1653b8b0848a 100644 (file)
 //! future, as well as generate and broadcast funding transactions handle payment preimages and a
 //! few other things.
 
-#[cfg(anchors)]
 pub mod bump_transaction;
 
-#[cfg(anchors)]
 pub use bump_transaction::BumpTransactionEvent;
 
 use crate::sign::SpendableOutputDescriptor;
@@ -33,8 +31,6 @@ use crate::util::string::UntrustedString;
 use crate::routing::router::{BlindedTail, Path, RouteHop, RouteParameters};
 
 use bitcoin::{PackedLockTime, Transaction, OutPoint};
-#[cfg(anchors)]
-use bitcoin::{Txid, TxIn, TxOut, Witness};
 use bitcoin::blockdata::script::Script;
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
@@ -117,7 +113,7 @@ impl_writeable_tlv_based_enum_upgradable!(PathFailure,
 );
 
 #[derive(Clone, Debug, PartialEq, Eq)]
-/// The reason the channel was closed. See individual variants more details.
+/// The reason the channel was closed. See individual variants for more details.
 pub enum ClosureReason {
        /// Closure generated from receiving a peer error message.
        ///
@@ -168,7 +164,10 @@ pub enum ClosureReason {
        ///
        /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
        /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
-       OutdatedChannelManager
+       OutdatedChannelManager,
+       /// The counterparty requested a cooperative close of a channel that had not been funded yet.
+       /// The channel has been immediately closed.
+       CounterpartyCoopClosedUnfundedChannel,
 }
 
 impl core::fmt::Display for ClosureReason {
@@ -188,6 +187,7 @@ impl core::fmt::Display for ClosureReason {
                        },
                        ClosureReason::DisconnectedPeer => f.write_str("the peer disconnected prior to the channel being funded"),
                        ClosureReason::OutdatedChannelManager => f.write_str("the ChannelManager read from disk was stale compared to ChannelMonitor(s)"),
+                       ClosureReason::CounterpartyCoopClosedUnfundedChannel => f.write_str("the peer requested the unfunded channel be closed"),
                }
        }
 }
@@ -201,6 +201,7 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
        (8, ProcessingError) => { (1, err, required) },
        (10, DisconnectedPeer) => {},
        (12, OutdatedChannelManager) => {},
+       (13, CounterpartyCoopClosedUnfundedChannel) => {},
 );
 
 /// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`].
@@ -355,9 +356,19 @@ pub enum Event {
        /// Note that if the preimage is not known, you should call
        /// [`ChannelManager::fail_htlc_backwards`] or [`ChannelManager::fail_htlc_backwards_with_reason`]
        /// to free up resources for this HTLC and avoid network congestion.
-       /// If you fail to call either [`ChannelManager::claim_funds`], [`ChannelManager::fail_htlc_backwards`],
-       /// or [`ChannelManager::fail_htlc_backwards_with_reason`] within the HTLC's timeout, the HTLC will be
-       /// automatically failed.
+       ///
+       /// If [`Event::PaymentClaimable::onion_fields`] is `Some`, and includes custom TLVs with even type
+       /// numbers, you should use [`ChannelManager::fail_htlc_backwards_with_reason`] with
+       /// [`FailureCode::InvalidOnionPayload`] if you fail to understand and handle the contents, or
+       /// [`ChannelManager::claim_funds_with_known_custom_tlvs`] upon successful handling.
+       /// If you don't intend to check for custom TLVs, you can simply use
+       /// [`ChannelManager::claim_funds`], which will automatically fail back even custom TLVs.
+       ///
+       /// If you fail to call [`ChannelManager::claim_funds`],
+       /// [`ChannelManager::claim_funds_with_known_custom_tlvs`],
+       /// [`ChannelManager::fail_htlc_backwards`], or
+       /// [`ChannelManager::fail_htlc_backwards_with_reason`] within the HTLC's timeout, the HTLC will
+       /// be automatically failed.
        ///
        /// # Note
        /// LDK will not stop an inbound payment from being paid multiple times, so multiple
@@ -369,6 +380,8 @@ pub enum Event {
        /// 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::claim_funds_with_known_custom_tlvs`]: crate::ln::channelmanager::ChannelManager::claim_funds_with_known_custom_tlvs
+       /// [`FailureCode::InvalidOnionPayload`]: crate::ln::channelmanager::FailureCode::InvalidOnionPayload
        /// [`ChannelManager::fail_htlc_backwards`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards
        /// [`ChannelManager::fail_htlc_backwards_with_reason`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards_with_reason
        PaymentClaimable {
@@ -387,8 +400,25 @@ pub enum Event {
                ///
                /// Payments received on LDK versions prior to 0.0.115 will have this field unset.
                onion_fields: Option<RecipientOnionFields>,
-               /// The value, in thousandths of a satoshi, that this payment is for.
+               /// The value, in thousandths of a satoshi, that this payment is claimable for. May be greater
+               /// than the invoice amount.
+               ///
+               /// May be less than the invoice amount if [`ChannelConfig::accept_underpaying_htlcs`] is set
+               /// and the previous hop took an extra fee.
+               ///
+               /// # Note
+               /// If [`ChannelConfig::accept_underpaying_htlcs`] is set and you claim without verifying this
+               /// field, you may lose money!
+               ///
+               /// [`ChannelConfig::accept_underpaying_htlcs`]: crate::util::config::ChannelConfig::accept_underpaying_htlcs
                amount_msat: u64,
+               /// The value, in thousands of a satoshi, that was skimmed off of this payment as an extra fee
+               /// taken by our channel counterparty.
+               ///
+               /// Will always be 0 unless [`ChannelConfig::accept_underpaying_htlcs`] is set.
+               ///
+               /// [`ChannelConfig::accept_underpaying_htlcs`]: crate::util::config::ChannelConfig::accept_underpaying_htlcs
+               counterparty_skimmed_fee_msat: 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,
@@ -430,7 +460,8 @@ pub enum Event {
                /// 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.
+               /// The value, in thousandths of a satoshi, that this payment is for. May be greater than the
+               /// invoice amount.
                amount_msat: u64,
                /// The purpose of the claimed payment, i.e. whether the payment was for an invoice or a
                /// spontaneous payment.
@@ -623,6 +654,7 @@ pub enum Event {
                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.
+               /// Forwarding less than this amount may break compatibility with LDK versions prior to 0.0.116.
                ///
                /// 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,
@@ -815,12 +847,14 @@ pub enum Event {
                /// Destination of the HTLC that failed to be processed.
                failed_next_destination: HTLCDestination,
        },
-       #[cfg(anchors)]
        /// Indicates that a transaction originating from LDK needs to have its fee bumped. This event
        /// requires confirmed external funds to be readily available to spend.
        ///
-       /// LDK does not currently generate this event. It is limited to the scope of channels with
-       /// anchor outputs, which will be introduced in a future release.
+       /// LDK does not currently generate this event unless the
+       /// [`ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx`] config flag is set to true.
+       /// It is limited to the scope of channels with anchor outputs.
+       ///
+       /// [`ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx`]: crate::util::config::ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx
        BumpTransaction(BumpTransactionEvent),
 }
 
@@ -832,8 +866,8 @@ 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::PaymentClaimable { ref payment_hash, ref amount_msat, ref purpose,
-                               ref receiver_node_id, ref via_channel_id, ref via_user_channel_id,
+                       &Event::PaymentClaimable { ref payment_hash, ref amount_msat, counterparty_skimmed_fee_msat,
+                               ref purpose, ref receiver_node_id, ref via_channel_id, ref via_user_channel_id,
                                ref claim_deadline, ref onion_fields
                        } => {
                                1u8.write(writer)?;
@@ -848,6 +882,8 @@ impl Writeable for Event {
                                                payment_preimage = Some(*preimage);
                                        }
                                }
+                               let skimmed_fee_opt = if counterparty_skimmed_fee_msat == 0 { None }
+                                       else { Some(counterparty_skimmed_fee_msat) };
                                write_tlv_fields!(writer, {
                                        (0, payment_hash, required),
                                        (1, receiver_node_id, option),
@@ -855,10 +891,11 @@ impl Writeable for Event {
                                        (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
+                                       // Type 6 was `user_payment_id` on 0.0.103 and earlier
                                        (7, claim_deadline, option),
                                        (8, payment_preimage, option),
                                        (9, onion_fields, option),
+                                       (10, skimmed_fee_opt, option),
                                });
                        },
                        &Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => {
@@ -889,7 +926,7 @@ impl Writeable for Event {
                                        (2, payment_failed_permanently, required),
                                        (3, false, required), // all_paths_failed in LDK versions prior to 0.0.114
                                        (4, path.blinded_tail, option),
-                                       (5, path.hops, vec_type),
+                                       (5, path.hops, required_vec),
                                        (7, short_channel_id, option),
                                        (9, None::<RouteParameters>, option), // retry in LDK versions prior to 0.0.115
                                        (11, payment_id, option),
@@ -957,7 +994,7 @@ impl Writeable for Event {
                                write_tlv_fields!(writer, {
                                        (0, payment_id, required),
                                        (2, payment_hash, option),
-                                       (4, path.hops, vec_type),
+                                       (4, path.hops, required_vec),
                                        (6, path.blinded_tail, option),
                                })
                        },
@@ -988,7 +1025,7 @@ impl Writeable for Event {
                                write_tlv_fields!(writer, {
                                        (0, payment_id, required),
                                        (2, payment_hash, required),
-                                       (4, path.hops, vec_type),
+                                       (4, path.hops, required_vec),
                                        (6, path.blinded_tail, option),
                                })
                        },
@@ -997,7 +1034,7 @@ impl Writeable for Event {
                                write_tlv_fields!(writer, {
                                        (0, payment_id, required),
                                        (2, payment_hash, required),
-                                       (4, path.hops, vec_type),
+                                       (4, path.hops, required_vec),
                                        (6, short_channel_id, option),
                                        (8, path.blinded_tail, option),
                                })
@@ -1009,7 +1046,6 @@ impl Writeable for Event {
                                        (2, failed_next_destination, required),
                                })
                        },
-                       #[cfg(anchors)]
                        &Event::BumpTransaction(ref event)=> {
                                27u8.write(writer)?;
                                match event {
@@ -1058,8 +1094,9 @@ impl MaybeReadable for Event {
                                        let mut payment_preimage = None;
                                        let mut payment_secret = None;
                                        let mut amount_msat = 0;
+                                       let mut counterparty_skimmed_fee_msat_opt = None;
                                        let mut receiver_node_id = None;
-                                       let mut _user_payment_id = None::<u64>; // For compatibility with 0.0.103 and earlier
+                                       let mut _user_payment_id = None::<u64>; // Used in 0.0.103 and earlier, no longer written in 0.0.116+.
                                        let mut via_channel_id = None;
                                        let mut claim_deadline = None;
                                        let mut via_user_channel_id = None;
@@ -1075,6 +1112,7 @@ impl MaybeReadable for Event {
                                                (7, claim_deadline, option),
                                                (8, payment_preimage, option),
                                                (9, onion_fields, option),
+                                               (10, counterparty_skimmed_fee_msat_opt, option),
                                        });
                                        let purpose = match payment_secret {
                                                Some(secret) => PaymentPurpose::InvoicePayment {
@@ -1088,6 +1126,7 @@ impl MaybeReadable for Event {
                                                receiver_node_id,
                                                payment_hash,
                                                amount_msat,
+                                               counterparty_skimmed_fee_msat: counterparty_skimmed_fee_msat_opt.unwrap_or(0),
                                                purpose,
                                                via_channel_id,
                                                via_user_channel_id,
@@ -1140,7 +1179,9 @@ impl MaybeReadable for Event {
                                                (1, network_update, upgradable_option),
                                                (2, payment_failed_permanently, required),
                                                (4, blinded_tail, option),
-                                               (5, path, vec_type),
+                                               // Added as a part of LDK 0.0.101 and always filled in since.
+                                               // Defaults to an empty Vec, though likely should have been `Option`al.
+                                               (5, path, optional_vec),
                                                (7, short_channel_id, option),
                                                (11, payment_id, option),
                                                (13, failure_opt, upgradable_option),
@@ -1257,13 +1298,13 @@ impl MaybeReadable for Event {
                                        _init_and_read_tlv_fields!(reader, {
                                                (0, payment_id, required),
                                                (2, payment_hash, option),
-                                               (4, path, vec_type),
+                                               (4, path, required_vec),
                                                (6, blinded_tail, option),
                                        });
                                        Ok(Some(Event::PaymentPathSuccessful {
                                                payment_id: payment_id.0.unwrap(),
                                                payment_hash,
-                                               path: Path { hops: path.unwrap(), blinded_tail },
+                                               path: Path { hops: path, blinded_tail },
                                        }))
                                };
                                f()
@@ -1316,13 +1357,13 @@ impl MaybeReadable for Event {
                                        _init_and_read_tlv_fields!(reader, {
                                                (0, payment_id, required),
                                                (2, payment_hash, required),
-                                               (4, path, vec_type),
+                                               (4, path, required_vec),
                                                (6, blinded_tail, option),
                                        });
                                        Ok(Some(Event::ProbeSuccessful {
                                                payment_id: payment_id.0.unwrap(),
                                                payment_hash: payment_hash.0.unwrap(),
-                                               path: Path { hops: path.unwrap(), blinded_tail },
+                                               path: Path { hops: path, blinded_tail },
                                        }))
                                };
                                f()
@@ -1332,14 +1373,14 @@ impl MaybeReadable for Event {
                                        _init_and_read_tlv_fields!(reader, {
                                                (0, payment_id, required),
                                                (2, payment_hash, required),
-                                               (4, path, vec_type),
+                                               (4, path, required_vec),
                                                (6, short_channel_id, option),
                                                (8, blinded_tail, option),
                                        });
                                        Ok(Some(Event::ProbeFailed {
                                                payment_id: payment_id.0.unwrap(),
                                                payment_hash: payment_hash.0.unwrap(),
-                                               path: Path { hops: path.unwrap(), blinded_tail },
+                                               path: Path { hops: path, blinded_tail },
                                                short_channel_id,
                                        }))
                                };
@@ -1440,6 +1481,14 @@ pub enum MessageSendEvent {
                /// The message which should be sent.
                msg: msgs::AcceptChannel,
        },
+       /// Used to indicate that we've accepted a V2 channel open and should send the accept_channel2
+       /// message provided to the given peer.
+       SendAcceptChannelV2 {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::AcceptChannelV2,
+       },
        /// Used to indicate that we've initiated a channel open and should send the open_channel
        /// message provided to the given peer.
        SendOpenChannel {
@@ -1448,6 +1497,14 @@ pub enum MessageSendEvent {
                /// The message which should be sent.
                msg: msgs::OpenChannel,
        },
+       /// Used to indicate that we've initiated a V2 channel open and should send the open_channel2
+       /// message provided to the given peer.
+       SendOpenChannelV2 {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::OpenChannelV2,
+       },
        /// Used to indicate that a funding_created message should be sent to the peer with the given node_id.
        SendFundingCreated {
                /// The node_id of the node which should receive this message
@@ -1462,6 +1519,69 @@ pub enum MessageSendEvent {
                /// The message which should be sent.
                msg: msgs::FundingSigned,
        },
+       /// Used to indicate that a tx_add_input message should be sent to the peer with the given node_id.
+       SendTxAddInput {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxAddInput,
+       },
+       /// Used to indicate that a tx_add_output message should be sent to the peer with the given node_id.
+       SendTxAddOutput {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxAddOutput,
+       },
+       /// Used to indicate that a tx_remove_input message should be sent to the peer with the given node_id.
+       SendTxRemoveInput {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxRemoveInput,
+       },
+       /// Used to indicate that a tx_remove_output message should be sent to the peer with the given node_id.
+       SendTxRemoveOutput {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxRemoveOutput,
+       },
+       /// Used to indicate that a tx_complete message should be sent to the peer with the given node_id.
+       SendTxComplete {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxComplete,
+       },
+       /// Used to indicate that a tx_signatures message should be sent to the peer with the given node_id.
+       SendTxSignatures {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxSignatures,
+       },
+       /// Used to indicate that a tx_init_rbf message should be sent to the peer with the given node_id.
+       SendTxInitRbf {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxInitRbf,
+       },
+       /// Used to indicate that a tx_ack_rbf message should be sent to the peer with the given node_id.
+       SendTxAckRbf {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxAckRbf,
+       },
+       /// Used to indicate that a tx_abort message should be sent to the peer with the given node_id.
+       SendTxAbort {
+               /// The node_id of the node which should receive this message
+               node_id: PublicKey,
+               /// The message which should be sent.
+               msg: msgs::TxAddInput,
+       },
        /// Used to indicate that a channel_ready message should be sent to the peer with the given node_id.
        SendChannelReady {
                /// The node_id of the node which should receive these message(s)