use crate::util::string::UntrustedString;
use crate::routing::router::{RouteHop, RouteParameters};
-use bitcoin::{PackedLockTime, Transaction};
+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;
///
/// Some of the reasons may include:
/// * HTLC Timeouts
- /// * Expected MPP amount to claim does not equal HTLC total
+ /// * Expected MPP amount has already been reached
/// * Claimable amount does not match expected amount
FailedPayment {
/// The payment hash of the payment we attempted to process.
};
);
+/// The reason the payment failed. Used in [`Event::PaymentFailed`].
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum PaymentFailureReason {
+ /// The intended recipient rejected our payment.
+ RecipientRejected,
+ /// The user chose to abandon this payment by calling [`ChannelManager::abandon_payment`].
+ ///
+ /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
+ UserAbandoned,
+ /// We exhausted all of our retry attempts while trying to send the payment, or we
+ /// exhausted the [`Retry::Timeout`] if the user set one. If at any point a retry
+ /// attempt failed while being forwarded along the path, an [`Event::PaymentPathFailed`] will
+ /// have come before this.
+ ///
+ /// [`Retry::Timeout`]: crate::ln::channelmanager::Retry::Timeout
+ RetriesExhausted,
+ /// The payment expired while retrying, based on the provided
+ /// [`PaymentParameters::expiry_time`].
+ ///
+ /// [`PaymentParameters::expiry_time`]: crate::routing::router::PaymentParameters::expiry_time
+ PaymentExpired,
+ /// We failed to find a route while retrying the payment.
+ RouteNotFound,
+ /// This error should generally never happen. This likely means that there is a problem with
+ /// your router.
+ UnexpectedError,
+}
+
+impl_writeable_tlv_based_enum!(PaymentFailureReason,
+ (0, RecipientRejected) => {},
+ (2, UserAbandoned) => {},
+ (4, RetriesExhausted) => {},
+ (6, PaymentExpired) => {},
+ (8, RouteNotFound) => {},
+ (10, UnexpectedError) => {}, ;
+);
+
/// 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
///
/// # Note
/// LDK will not stop an inbound payment from being paid multiple times, so multiple
- /// `PaymentClaimable` events may be generated for the same payment.
+ /// `PaymentClaimable` events may be generated for the same payment. In such a case it is
+ /// polite (and required in the lightning specification) to fail the payment the second time
+ /// and give the sender their money back rather than accepting double payment.
///
/// # Note
/// This event used to be called `PaymentReceived` in LDK versions 0.0.112 and earlier.
via_channel_id: Option<[u8; 32]>,
/// The `user_channel_id` indicating over which channel we received the payment.
via_user_channel_id: Option<u128>,
+ /// The block height at which this payment will be failed back and will no longer be
+ /// eligible for claiming.
+ ///
+ /// Prior to this height, a call to [`ChannelManager::claim_funds`] is guaranteed to
+ /// succeed, however you should wait for [`Event::PaymentClaimed`] to be sure.
+ ///
+ /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds
+ claim_deadline: Option<u32>,
},
/// Indicates a payment has been claimed and we've received money!
///
/// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentPathFailed`
/// event. In this situation, you SHOULD treat this payment as having succeeded.
PaymentSent {
- /// The id returned by [`ChannelManager::send_payment`].
+ /// The `payment_id` passed to [`ChannelManager::send_payment`].
///
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
payment_id: Option<PaymentId>,
/// [`Retry`]: crate::ln::channelmanager::Retry
/// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
PaymentFailed {
- /// The id returned by [`ChannelManager::send_payment`] and used with
- /// [`ChannelManager::abandon_payment`].
+ /// The `payment_id` passed to [`ChannelManager::send_payment`].
///
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
- /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
payment_id: PaymentId,
/// The hash that was given to [`ChannelManager::send_payment`].
///
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
payment_hash: PaymentHash,
+ /// The reason the payment failed. This is only `None` for events generated or serialized
+ /// by versions prior to 0.0.115.
+ reason: Option<PaymentFailureReason>,
},
/// Indicates that a path for an outbound payment was successful.
///
/// Always generated after [`Event::PaymentSent`] and thus useful for scoring channels. See
/// [`Event::PaymentSent`] for obtaining the payment preimage.
PaymentPathSuccessful {
- /// The id returned by [`ChannelManager::send_payment`].
+ /// The `payment_id` passed to [`ChannelManager::send_payment`].
///
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
payment_id: PaymentId,
///
/// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
PaymentPathFailed {
- /// The id returned by [`ChannelManager::send_payment`] and used with
- /// [`ChannelManager::abandon_payment`].
+ /// The `payment_id` passed to [`ChannelManager::send_payment`].
///
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
/// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
/// If this is `true`, the forwarded HTLC was claimed by our counterparty via an on-chain
/// transaction.
claim_from_onchain_tx: bool,
+ /// The final amount forwarded, in milli-satoshis, after the fee is deducted.
+ ///
+ /// The caveat described above the `fee_earned_msat` field applies here as well.
+ outbound_amount_forwarded_msat: Option<u64>,
+ },
+ /// Used to indicate that a channel with the given `channel_id` is being opened and pending
+ /// confirmation on-chain.
+ ///
+ /// This event is emitted when the funding transaction has been signed and is broadcast to the
+ /// network. For 0conf channels it will be immediately followed by the corresponding
+ /// [`Event::ChannelReady`] event.
+ ChannelPending {
+ /// The `channel_id` of the channel that is pending confirmation.
+ channel_id: [u8; 32],
+ /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
+ /// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
+ /// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise
+ /// `user_channel_id` will be randomized for an inbound channel.
+ ///
+ /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
+ /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
+ /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
+ user_channel_id: u128,
+ /// The `temporary_channel_id` this channel used to be known by during channel establishment.
+ ///
+ /// Will be `None` for channels created prior to LDK version 0.0.115.
+ former_temporary_channel_id: Option<[u8; 32]>,
+ /// The `node_id` of the channel counterparty.
+ counterparty_node_id: PublicKey,
+ /// The outpoint of the channel's funding transaction.
+ funding_txo: OutPoint,
},
/// Used to indicate that a channel with the given `channel_id` is ready to
/// be used. This event is emitted either when the funding transaction has been confirmed
/// on-chain, or, in case of a 0conf channel, when both parties have confirmed the channel
/// establishment.
ChannelReady {
- /// The channel_id of the channel that is ready.
+ /// The `channel_id` of the channel that is ready.
channel_id: [u8; 32],
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
/// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
/// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
/// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
user_channel_id: u128,
- /// The node_id of the channel counterparty.
+ /// The `node_id` of the channel counterparty.
counterparty_node_id: PublicKey,
/// The features that this channel will operate with.
channel_type: ChannelTypeFeatures,
/// Used to indicate that a previously opened channel with the given `channel_id` is in the
/// process of closure.
ChannelClosed {
- /// The channel_id of the channel which has been closed. Note that on-chain transactions
+ /// The `channel_id` of the channel which has been closed. Note that on-chain transactions
/// resolving the channel are likely still awaiting confirmation.
channel_id: [u8; 32],
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
/// * Insufficient capacity in the outbound channel
/// * While waiting to forward the HTLC, the channel it is meant to be forwarded through closes
/// * When an unknown SCID is requested for forwarding a payment.
- /// * Claiming an amount for an MPP payment that exceeds the HTLC total
+ /// * Expected MPP amount has already been reached
/// * The HTLC has timed out
///
/// This event, however, does not get generated if an HTLC fails to meet the forwarding
// 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, ref purpose, ref receiver_node_id, ref via_channel_id, ref via_user_channel_id, ref claim_deadline } => {
1u8.write(writer)?;
let mut payment_secret = None;
let payment_preimage;
(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
+ (7, claim_deadline, option),
(8, payment_preimage, option),
});
},
(8, expected_outbound_amount_msat, required),
});
}
- &Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => {
+ &Event::PaymentForwarded {
+ fee_earned_msat, prev_channel_id, claim_from_onchain_tx,
+ next_channel_id, outbound_amount_forwarded_msat
+ } => {
7u8.write(writer)?;
write_tlv_fields!(writer, {
(0, fee_earned_msat, option),
(1, prev_channel_id, option),
(2, claim_from_onchain_tx, required),
(3, next_channel_id, option),
+ (5, outbound_amount_forwarded_msat, option),
});
},
&Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason } => {
(4, *path, vec_type)
})
},
- &Event::PaymentFailed { ref payment_id, ref payment_hash } => {
+ &Event::PaymentFailed { ref payment_id, ref payment_hash, ref reason } => {
15u8.write(writer)?;
write_tlv_fields!(writer, {
(0, payment_id, required),
+ (1, reason, option),
(2, payment_hash, required),
})
},
(6, channel_type, required),
});
},
+ &Event::ChannelPending { ref channel_id, ref user_channel_id, ref former_temporary_channel_id, ref counterparty_node_id, ref funding_txo } => {
+ 31u8.write(writer)?;
+ write_tlv_fields!(writer, {
+ (0, channel_id, required),
+ (2, user_channel_id, required),
+ (4, former_temporary_channel_id, required),
+ (6, counterparty_node_id, required),
+ (8, funding_txo, required),
+ });
+ },
// Note that, going forward, all new events must only write data inside of
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
// data via `write_tlv_fields`.
let mut receiver_node_id = None;
let mut _user_payment_id = None::<u64>; // For compatibility with 0.0.103 and earlier
let mut via_channel_id = None;
+ let mut claim_deadline = None;
let mut via_user_channel_id = None;
read_tlv_fields!(reader, {
(0, payment_hash, required),
(4, amount_msat, required),
(5, via_user_channel_id, option),
(6, _user_payment_id, option),
+ (7, claim_deadline, option),
(8, payment_preimage, option),
});
let purpose = match payment_secret {
purpose,
via_channel_id,
via_user_channel_id,
+ claim_deadline,
}))
};
f()
let mut prev_channel_id = None;
let mut claim_from_onchain_tx = false;
let mut next_channel_id = None;
+ let mut outbound_amount_forwarded_msat = None;
read_tlv_fields!(reader, {
(0, fee_earned_msat, option),
(1, prev_channel_id, option),
(2, claim_from_onchain_tx, required),
(3, next_channel_id, option),
+ (5, outbound_amount_forwarded_msat, option),
});
- Ok(Some(Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id }))
+ Ok(Some(Event::PaymentForwarded {
+ fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id,
+ outbound_amount_forwarded_msat
+ }))
};
f()
},
let f = || {
let mut payment_hash = PaymentHash([0; 32]);
let mut payment_id = PaymentId([0; 32]);
+ let mut reason = None;
read_tlv_fields!(reader, {
(0, payment_id, required),
+ (1, reason, upgradable_option),
(2, payment_hash, required),
});
Ok(Some(Event::PaymentFailed {
payment_id,
payment_hash,
+ reason,
}))
};
f()
};
f()
},
+ 31u8 => {
+ let f = || {
+ let mut channel_id = [0; 32];
+ let mut user_channel_id: u128 = 0;
+ let mut former_temporary_channel_id = None;
+ let mut counterparty_node_id = RequiredWrapper(None);
+ let mut funding_txo = RequiredWrapper(None);
+ read_tlv_fields!(reader, {
+ (0, channel_id, required),
+ (2, user_channel_id, required),
+ (4, former_temporary_channel_id, required),
+ (6, counterparty_node_id, required),
+ (8, funding_txo, required),
+ });
+
+ Ok(Some(Event::ChannelPending {
+ channel_id,
+ user_channel_id,
+ former_temporary_channel_id,
+ counterparty_node_id: counterparty_node_id.0.unwrap(),
+ funding_txo: funding_txo.0.unwrap()
+ }))
+ };
+ f()
+ },
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
// Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt
// reads.