pub use bump_transaction::BumpTransactionEvent;
use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, PaymentContext, PaymentContextRef};
-use crate::sign::SpendableOutputDescriptor;
+use crate::chain::transaction;
use crate::ln::channelmanager::{InterceptId, PaymentId, RecipientOnionFields};
use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
use crate::ln::features::ChannelTypeFeatures;
use crate::ln::msgs;
use crate::ln::types::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
-use crate::chain::transaction;
+use crate::offers::invoice::Bolt12Invoice;
+use crate::onion_message::messenger::Responder;
use crate::routing::gossip::NetworkUpdate;
+use crate::routing::router::{BlindedTail, Path, RouteHop, RouteParameters};
+use crate::sign::SpendableOutputDescriptor;
use crate::util::errors::APIError;
use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, RequiredWrapper, UpgradableRequired, WithoutLength};
use crate::util::string::UntrustedString;
-use crate::routing::router::{BlindedTail, Path, RouteHop, RouteParameters};
use bitcoin::{Transaction, OutPoint};
use bitcoin::blockdata::locktime::absolute::LockTime;
use bitcoin::hashes::Hash;
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::secp256k1::PublicKey;
+use bitcoin::transaction::Version;
use crate::io;
use core::time::Duration;
use core::ops::Deref;
/// Closure generated from [`ChannelManager::force_close_channel`], called by the user.
///
/// [`ChannelManager::force_close_channel`]: crate::ln::channelmanager::ChannelManager::force_close_channel.
- HolderForceClosed,
+ HolderForceClosed {
+ /// Whether or not the latest transaction was broadcasted when the channel was force
+ /// closed.
+ ///
+ /// Channels closed using [`ChannelManager::force_close_broadcasting_latest_txn`] will have
+ /// this field set to true, whereas channels closed using [`ChannelManager::force_close_without_broadcasting_txn`]
+ /// or force-closed prior to being funded will have this field set to false.
+ ///
+ /// This will be `None` for objects generated or written by LDK 0.0.123 and
+ /// earlier.
+ ///
+ /// [`ChannelManager::force_close_broadcasting_latest_txn`]: crate::ln::channelmanager::ChannelManager::force_close_broadcasting_latest_txn.
+ /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn.
+ broadcasted_latest_txn: Option<bool>
+ },
/// The channel was closed after negotiating a cooperative close and we've now broadcasted
/// the cooperative close transaction. Note the shutdown may have been initiated by us.
///
FundingBatchClosure,
/// One of our HTLCs timed out in a channel, causing us to force close the channel.
HTLCsTimedOut,
+ /// Our peer provided a feerate which violated our required minimum (fetched from our
+ /// [`FeeEstimator`] either as [`ConfirmationTarget::MinAllowedAnchorChannelRemoteFee`] or
+ /// [`ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee`]).
+ ///
+ /// [`FeeEstimator`]: crate::chain::chaininterface::FeeEstimator
+ /// [`ConfirmationTarget::MinAllowedAnchorChannelRemoteFee`]: crate::chain::chaininterface::ConfirmationTarget::MinAllowedAnchorChannelRemoteFee
+ /// [`ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee`]: crate::chain::chaininterface::ConfirmationTarget::MinAllowedNonAnchorChannelRemoteFee
+ PeerFeerateTooLow {
+ /// The feerate on our channel set by our peer.
+ peer_feerate_sat_per_kw: u32,
+ /// The required feerate we enforce, from our [`FeeEstimator`].
+ ///
+ /// [`FeeEstimator`]: crate::chain::chaininterface::FeeEstimator
+ required_feerate_sat_per_kw: u32,
+ },
}
impl core::fmt::Display for ClosureReason {
ClosureReason::CounterpartyForceClosed { peer_msg } => {
f.write_fmt(format_args!("counterparty force-closed with message: {}", peer_msg))
},
- ClosureReason::HolderForceClosed => f.write_str("user force-closed the channel"),
+ ClosureReason::HolderForceClosed { broadcasted_latest_txn } => {
+ f.write_str("user force-closed the channel")?;
+ if let Some(brodcasted) = broadcasted_latest_txn {
+ write!(f, " and {} the latest transaction", if *brodcasted { "broadcasted" } else { "elected not to broadcast" })
+ } else {
+ Ok(())
+ }
+ },
ClosureReason::LegacyCooperativeClosure => f.write_str("the channel was cooperatively closed"),
ClosureReason::CounterpartyInitiatedCooperativeClosure => f.write_str("the channel was cooperatively closed by our peer"),
ClosureReason::LocallyInitiatedCooperativeClosure => f.write_str("the channel was cooperatively closed by us"),
ClosureReason::CounterpartyCoopClosedUnfundedChannel => f.write_str("the peer requested the unfunded channel be closed"),
ClosureReason::FundingBatchClosure => f.write_str("another channel in the same funding batch closed"),
ClosureReason::HTLCsTimedOut => f.write_str("htlcs on the channel timed out"),
+ ClosureReason::PeerFeerateTooLow { peer_feerate_sat_per_kw, required_feerate_sat_per_kw } =>
+ f.write_fmt(format_args!(
+ "peer provided a feerate ({} sat/kw) which was below our lower bound ({} sat/kw)",
+ peer_feerate_sat_per_kw, required_feerate_sat_per_kw,
+ )),
}
}
}
impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
(0, CounterpartyForceClosed) => { (1, peer_msg, required) },
(1, FundingTimedOut) => {},
- (2, HolderForceClosed) => {},
+ (2, HolderForceClosed) => { (1, broadcasted_latest_txn, option) },
(6, CommitmentTxConfirmed) => {},
(4, LegacyCooperativeClosure) => {},
(8, ProcessingError) => { (1, err, required) },
(17, CounterpartyInitiatedCooperativeClosure) => {},
(19, LocallyInitiatedCooperativeClosure) => {},
(21, HTLCsTimedOut) => {},
+ (23, PeerFeerateTooLow) => {
+ (0, peer_feerate_sat_per_kw, required),
+ (2, required_feerate_sat_per_kw, required),
+ },
);
/// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`].
/// The sender-intended sum total of all the MPP parts. This will be `None` for events
/// serialized prior to LDK version 0.0.117.
sender_intended_total_msat: Option<u64>,
+ /// The fields in the onion which were received with each HTLC. Only fields which were
+ /// identical in each HTLC involved in the payment will be included here.
+ ///
+ /// Payments received on LDK versions prior to 0.0.124 will have this field unset.
+ onion_fields: Option<RecipientOnionFields>,
},
/// Indicates that a peer connection with a node is needed in order to send an [`OnionMessage`].
///
/// The `payment_id` to have been associated with payment for the requested invoice.
payment_id: PaymentId,
},
+ /// Indicates a [`Bolt12Invoice`] in response to an [`InvoiceRequest`] or a [`Refund`] was
+ /// received.
+ ///
+ /// This event will only be generated if [`UserConfig::manually_handle_bolt12_invoices`] is set.
+ /// Use [`ChannelManager::send_payment_for_bolt12_invoice`] to pay the invoice or
+ /// [`ChannelManager::abandon_payment`] to abandon the associated payment. See those docs for
+ /// further details.
+ ///
+ /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
+ /// [`Refund`]: crate::offers::refund::Refund
+ /// [`UserConfig::manually_handle_bolt12_invoices`]: crate::util::config::UserConfig::manually_handle_bolt12_invoices
+ /// [`ChannelManager::send_payment_for_bolt12_invoice`]: crate::ln::channelmanager::ChannelManager::send_payment_for_bolt12_invoice
+ /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
+ InvoiceReceived {
+ /// The `payment_id` associated with payment for the invoice.
+ payment_id: PaymentId,
+ /// The invoice to pay.
+ invoice: Bolt12Invoice,
+ /// A responder for replying with an [`InvoiceError`] if needed.
+ ///
+ /// `None` if the invoice wasn't sent with a reply path.
+ ///
+ /// [`InvoiceError`]: crate::offers::invoice_error::InvoiceError
+ responder: Option<Responder>,
+ },
/// Indicates an outbound payment we made succeeded (i.e. it made it all the way to its target
/// and we got back the payment preimage for it).
///
/// If the recipient or an intermediate node misbehaves and gives us free money, this may
/// overstate the amount paid, though this is unlikely.
///
+ /// This is only `None` for payments initiated on LDK versions prior to 0.0.103.
+ ///
/// [`Route::get_total_fees`]: crate::routing::router::Route::get_total_fees
fee_paid_msat: Option<u64>,
},
///
/// [`ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx`]: crate::util::config::ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx
BumpTransaction(BumpTransactionEvent),
+ /// We received an onion message that is intended to be forwarded to a peer
+ /// that is currently offline. This event will only be generated if the
+ /// `OnionMessenger` was initialized with
+ /// [`OnionMessenger::new_with_offline_peer_interception`], see its docs.
+ ///
+ /// [`OnionMessenger::new_with_offline_peer_interception`]: crate::onion_message::messenger::OnionMessenger::new_with_offline_peer_interception
+ OnionMessageIntercepted {
+ /// The node id of the offline peer.
+ peer_node_id: PublicKey,
+ /// The onion message intended to be forwarded to `peer_node_id`.
+ message: msgs::OnionMessage,
+ },
+ /// Indicates that an onion message supporting peer has come online and it may
+ /// be time to forward any onion messages that were previously intercepted for
+ /// them. This event will only be generated if the `OnionMessenger` was
+ /// initialized with
+ /// [`OnionMessenger::new_with_offline_peer_interception`], see its docs.
+ ///
+ /// [`OnionMessenger::new_with_offline_peer_interception`]: crate::onion_message::messenger::OnionMessenger::new_with_offline_peer_interception
+ OnionMessagePeerConnected {
+ /// The node id of the peer we just connected to, who advertises support for
+ /// onion messages.
+ peer_node_id: PublicKey,
+ }
}
impl Writeable for Event {
// We never write the OpenChannelRequest events as, upon disconnection, peers
// drop any channels which have not yet exchanged funding_signed.
},
- &Event::PaymentClaimed { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id, ref htlcs, ref sender_intended_total_msat } => {
+ &Event::PaymentClaimed { ref payment_hash, ref amount_msat, ref purpose, ref receiver_node_id, ref htlcs, ref sender_intended_total_msat, ref onion_fields } => {
19u8.write(writer)?;
write_tlv_fields!(writer, {
(0, payment_hash, required),
(4, amount_msat, required),
(5, *htlcs, optional_vec),
(7, sender_intended_total_msat, option),
+ (9, onion_fields, option),
});
},
&Event::ProbeSuccessful { ref payment_id, ref payment_hash, ref path } => {
35u8.write(writer)?;
// Never write ConnectionNeeded events as buffered onion messages aren't serialized.
},
+ &Event::OnionMessageIntercepted { ref peer_node_id, ref message } => {
+ 37u8.write(writer)?;
+ write_tlv_fields!(writer, {
+ (0, peer_node_id, required),
+ (2, message, required),
+ });
+ },
+ &Event::OnionMessagePeerConnected { ref peer_node_id } => {
+ 39u8.write(writer)?;
+ write_tlv_fields!(writer, {
+ (0, peer_node_id, required),
+ });
+ },
+ &Event::InvoiceReceived { ref payment_id, ref invoice, ref responder } => {
+ 41u8.write(writer)?;
+ write_tlv_fields!(writer, {
+ (0, payment_id, required),
+ (2, invoice, required),
+ (4, responder, option),
+ })
+ },
// 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`.
11u8 => {
let mut f = || {
let mut channel_id = ChannelId::new_zero();
- let mut transaction = Transaction{ version: 2, lock_time: LockTime::ZERO, input: Vec::new(), output: Vec::new() };
+ let mut transaction = Transaction{ version: Version::TWO, lock_time: LockTime::ZERO, input: Vec::new(), output: Vec::new() };
read_tlv_fields!(reader, {
(0, channel_id, required),
(2, transaction, required),
let mut receiver_node_id = None;
let mut htlcs: Option<Vec<ClaimedHTLC>> = Some(vec![]);
let mut sender_intended_total_msat: Option<u64> = None;
+ let mut onion_fields = None;
read_tlv_fields!(reader, {
(0, payment_hash, required),
(1, receiver_node_id, option),
(4, amount_msat, required),
(5, htlcs, optional_vec),
(7, sender_intended_total_msat, option),
+ (9, onion_fields, option),
});
Ok(Some(Event::PaymentClaimed {
receiver_node_id,
amount_msat,
htlcs: htlcs.unwrap_or(vec![]),
sender_intended_total_msat,
+ onion_fields,
}))
};
f()
},
// Note that we do not write a length-prefixed TLV for ConnectionNeeded events.
35u8 => Ok(None),
+ 37u8 => {
+ let mut f = || {
+ _init_and_read_len_prefixed_tlv_fields!(reader, {
+ (0, peer_node_id, required),
+ (2, message, required),
+ });
+ Ok(Some(Event::OnionMessageIntercepted {
+ peer_node_id: peer_node_id.0.unwrap(), message: message.0.unwrap()
+ }))
+ };
+ f()
+ },
+ 39u8 => {
+ let mut f = || {
+ _init_and_read_len_prefixed_tlv_fields!(reader, {
+ (0, peer_node_id, required),
+ });
+ Ok(Some(Event::OnionMessagePeerConnected {
+ peer_node_id: peer_node_id.0.unwrap()
+ }))
+ };
+ f()
+ },
+ 41u8 => {
+ let mut f = || {
+ _init_and_read_len_prefixed_tlv_fields!(reader, {
+ (0, payment_id, required),
+ (2, invoice, required),
+ (4, responder, option),
+ });
+ Ok(Some(Event::InvoiceReceived {
+ payment_id: payment_id.0.unwrap(),
+ invoice: invoice.0.unwrap(),
+ responder,
+ }))
+ };
+ 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.