//! future, as well as generate and broadcast funding transactions handle payment preimages and a
//! few other things.
-use chain::keysinterface::SpendableOutputDescriptor;
-use ln::channelmanager::PaymentId;
-use ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
-use ln::features::ChannelTypeFeatures;
-use ln::msgs;
-use ln::msgs::DecodeError;
-use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
-use routing::gossip::NetworkUpdate;
-use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
-use routing::router::{RouteHop, RouteParameters};
+use crate::chain::keysinterface::SpendableOutputDescriptor;
+use crate::ln::chan_utils::HTLCOutputInCommitment;
+use crate::ln::channelmanager::PaymentId;
+use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
+use crate::ln::features::ChannelTypeFeatures;
+use crate::ln::msgs;
+use crate::ln::msgs::DecodeError;
+use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
+use crate::routing::gossip::NetworkUpdate;
+use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
+use crate::routing::router::{RouteHop, RouteParameters};
-use bitcoin::{PackedLockTime, Transaction};
+use bitcoin::{PackedLockTime, Transaction, OutPoint};
use bitcoin::blockdata::script::Script;
use bitcoin::hashes::Hash;
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::secp256k1::PublicKey;
-use io;
-use prelude::*;
+use crate::io;
+use crate::prelude::*;
use core::time::Duration;
use core::ops::Deref;
-use sync::Arc;
+use crate::sync::Arc;
/// 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.
(2, SpontaneousPayment)
);
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
/// The reason the channel was closed. See individual variants more details.
pub enum ClosureReason {
/// Closure generated from receiving a peer error message.
/// The peer disconnected prior to funding completing. In this case the spec mandates that we
/// forget the channel entirely - we can attempt again if the peer reconnects.
///
+ /// This includes cases where we restarted prior to funding completion, including prior to the
+ /// initial [`ChannelMonitor`] persistence completing.
+ ///
/// In LDK versions prior to 0.0.107 this could also occur if we were unable to connect to the
/// peer because of mutual incompatibility between us and our channel counterparty.
+ ///
+ /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
DisconnectedPeer,
- /// Closure generated from `ChannelManager::read` if the ChannelMonitor is newer than
- /// the ChannelManager deserialized.
+ /// Closure generated from `ChannelManager::read` if the [`ChannelMonitor`] is newer than
+ /// the [`ChannelManager`] deserialized.
+ ///
+ /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
+ /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
OutdatedChannelManager
}
);
/// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`].
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
pub enum HTLCDestination {
/// We tried forwarding to a channel but failed to do so. An example of such an instance is when
/// there is insufficient capacity in our outbound channel.
}
);
+#[cfg(anchors)]
+/// A descriptor used to sign for a commitment transaction's anchor output.
+#[derive(Clone, Debug)]
+pub struct AnchorDescriptor {
+ /// A unique identifier used along with `channel_value_satoshis` to re-derive the
+ /// [`InMemorySigner`] required to sign `input`.
+ ///
+ /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
+ pub channel_keys_id: [u8; 32],
+ /// The value in satoshis of the channel we're attempting to spend the anchor output of. This is
+ /// used along with `channel_keys_id` to re-derive the [`InMemorySigner`] required to sign
+ /// `input`.
+ ///
+ /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
+ pub channel_value_satoshis: u64,
+ /// The transaction input's outpoint corresponding to the commitment transaction's anchor
+ /// output.
+ pub outpoint: OutPoint,
+}
+
+#[cfg(anchors)]
+/// Represents the different types of transactions, originating from LDK, to be bumped.
+#[derive(Clone, Debug)]
+pub enum BumpTransactionEvent {
+ /// Indicates that a channel featuring anchor outputs is to be closed by broadcasting the local
+ /// commitment transaction. Since commitment transactions have a static feerate pre-agreed upon,
+ /// they may need additional fees to be attached through a child transaction using the popular
+ /// [Child-Pays-For-Parent](https://bitcoinops.org/en/topics/cpfp) fee bumping technique. This
+ /// child transaction must include the anchor input described within `anchor_descriptor` along
+ /// with additional inputs to meet the target feerate. Failure to meet the target feerate
+ /// decreases the confirmation odds of the transaction package (which includes the commitment
+ /// and child anchor transactions), possibly resulting in a loss of funds. Once the transaction
+ /// is constructed, it must be fully signed for and broadcasted by the consumer of the event
+ /// along with the `commitment_tx` enclosed. Note that the `commitment_tx` must always be
+ /// broadcast first, as the child anchor transaction depends on it.
+ ///
+ /// The consumer should be able to sign for any of the additional inputs included within the
+ /// child anchor transaction. To sign its anchor input, an [`InMemorySigner`] should be
+ /// re-derived through [`KeysManager::derive_channel_keys`] with the help of
+ /// [`AnchorDescriptor::channel_keys_id`] and [`AnchorDescriptor::channel_value_satoshis`].
+ ///
+ /// It is possible to receive more than one instance of this event if a valid child anchor
+ /// transaction is never broadcast or is but not with a sufficient fee to be mined. Care should
+ /// be taken by the consumer of the event to ensure any future iterations of the child anchor
+ /// transaction adhere to the [Replace-By-Fee
+ /// rules](https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md)
+ /// for fee bumps to be accepted into the mempool, and eventually the chain. As the frequency of
+ /// these events is not user-controlled, users may ignore/drop the event if they are no longer
+ /// able to commit external confirmed funds to the child anchor transaction.
+ ///
+ /// The set of `pending_htlcs` on the commitment transaction to be broadcast can be inspected to
+ /// determine whether a significant portion of the channel's funds are allocated to HTLCs,
+ /// enabling users to make their own decisions regarding the importance of the commitment
+ /// transaction's confirmation. Note that this is not required, but simply exists as an option
+ /// for users to override LDK's behavior. On commitments with no HTLCs (indicated by those with
+ /// an empty `pending_htlcs`), confirmation of the commitment transaction can be considered to
+ /// be not urgent.
+ ///
+ /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner
+ /// [`KeysManager::derive_channel_keys`]: crate::chain::keysinterface::KeysManager::derive_channel_keys
+ ChannelClose {
+ /// The target feerate that the transaction package, which consists of the commitment
+ /// transaction and the to-be-crafted child anchor transaction, must meet.
+ package_target_feerate_sat_per_1000_weight: u32,
+ /// The channel's commitment transaction to bump the fee of. This transaction should be
+ /// broadcast along with the anchor transaction constructed as a result of consuming this
+ /// event.
+ commitment_tx: Transaction,
+ /// The absolute fee in satoshis of the commitment transaction. This can be used along the
+ /// with weight of the commitment transaction to determine its feerate.
+ commitment_tx_fee_satoshis: u64,
+ /// The descriptor to sign the anchor input of the anchor transaction constructed as a
+ /// result of consuming this event.
+ anchor_descriptor: AnchorDescriptor,
+ /// The set of pending HTLCs on the commitment transaction that need to be resolved once the
+ /// commitment transaction confirms.
+ pending_htlcs: Vec<HTLCOutputInCommitment>,
+ },
+}
+
/// 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
/// Indicates the payment was rejected for some reason by the recipient. This implies that
/// the payment has failed, not just the route in question. If this is not set, you may
/// retry the payment via a different route.
- rejected_by_dest: bool,
+ payment_failed_permanently: bool,
/// Any failure information conveyed via the Onion return packet by a node along the failed
/// payment route.
///
/// 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.
+ BumpTransaction(BumpTransactionEvent),
}
impl Writeable for Event {
});
},
&Event::PaymentPathFailed {
- ref payment_id, ref payment_hash, ref rejected_by_dest, ref network_update,
+ ref payment_id, ref payment_hash, ref payment_failed_permanently, ref network_update,
ref all_paths_failed, ref path, ref short_channel_id, ref retry,
#[cfg(test)]
ref error_code,
write_tlv_fields!(writer, {
(0, payment_hash, required),
(1, network_update, option),
- (2, rejected_by_dest, required),
+ (2, payment_failed_permanently, required),
(3, all_paths_failed, required),
(5, path, vec_type),
(7, short_channel_id, option),
(2, failed_next_destination, required),
})
},
+ #[cfg(anchors)]
+ &Event::BumpTransaction(ref event)=> {
+ 27u8.write(writer)?;
+ match event {
+ // We never write the ChannelClose events as they'll be replayed upon restarting
+ // anyway if the commitment transaction remains unconfirmed.
+ BumpTransactionEvent::ChannelClose { .. } => {}
+ }
+ }
// 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`.
#[cfg(test)]
let error_data = Readable::read(reader)?;
let mut payment_hash = PaymentHash([0; 32]);
- let mut rejected_by_dest = false;
+ let mut payment_failed_permanently = false;
let mut network_update = None;
let mut all_paths_failed = Some(true);
let mut path: Option<Vec<RouteHop>> = Some(vec![]);
read_tlv_fields!(reader, {
(0, payment_hash, required),
(1, network_update, ignorable),
- (2, rejected_by_dest, required),
+ (2, payment_failed_permanently, required),
(3, all_paths_failed, option),
(5, path, vec_type),
(7, short_channel_id, option),
Ok(Some(Event::PaymentPathFailed {
payment_id,
payment_hash,
- rejected_by_dest,
+ payment_failed_permanently,
network_update,
all_paths_failed: all_paths_failed.unwrap(),
path: path.unwrap(),
/// The message which should be sent.
msg: msgs::ChannelReestablish,
},
+ /// Used to send a channel_announcement and channel_update to a specific peer, likely on
+ /// initial connection to ensure our peers know about our channels.
+ SendChannelAnnouncement {
+ /// The node_id of the node which should receive this message
+ node_id: PublicKey,
+ /// The channel_announcement which should be sent.
+ msg: msgs::ChannelAnnouncement,
+ /// The followup channel_update which should be sent.
+ update_msg: msgs::ChannelUpdate,
+ },
/// Used to indicate that a channel_announcement and channel_update should be broadcast to all
/// peers (except the peer with node_id either msg.contents.node_id_1 or msg.contents.node_id_2).
///
- /// Note that after doing so, you very likely (unless you did so very recently) want to call
- /// ChannelManager::broadcast_node_announcement to trigger a BroadcastNodeAnnouncement event.
- /// This ensures that any nodes which see our channel_announcement also have a relevant
+ /// Note that after doing so, you very likely (unless you did so very recently) want to
+ /// broadcast a node_announcement (e.g. via [`PeerManager::broadcast_node_announcement`]). This
+ /// ensures that any nodes which see our channel_announcement also have a relevant
/// node_announcement, including relevant feature flags which may be important for routing
/// through or to us.
+ ///
+ /// [`PeerManager::broadcast_node_announcement`]: crate::ln::peer_handler::PeerManager::broadcast_node_announcement
BroadcastChannelAnnouncement {
/// The channel_announcement which should be sent.
msg: msgs::ChannelAnnouncement,
/// The followup channel_update which should be sent.
update_msg: msgs::ChannelUpdate,
},
- /// Used to indicate that a node_announcement should be broadcast to all peers.
- BroadcastNodeAnnouncement {
- /// The node_announcement which should be sent.
- msg: msgs::NodeAnnouncement,
- },
/// Used to indicate that a channel_update should be broadcast to all peers.
BroadcastChannelUpdate {
/// The channel_update which should be sent.
///
/// # Requirements
///
-/// See [`process_pending_events`] for requirements around event processing.
-///
/// When using this trait, [`process_pending_events`] will call [`handle_event`] for each pending
-/// event since the last invocation. The handler must either act upon the event immediately
-/// or preserve it for later handling.
+/// event since the last invocation.
+///
+/// In order to ensure no [`Event`]s are lost, implementors of this trait will persist [`Event`]s
+/// and replay any unhandled events on startup. An [`Event`] is considered handled when
+/// [`process_pending_events`] returns, thus handlers MUST fully handle [`Event`]s and persist any
+/// relevant changes to disk *before* returning.
+///
+/// Further, because an application may crash between an [`Event`] being handled and the
+/// implementor of this trait being re-serialized, [`Event`] handling must be idempotent - in
+/// effect, [`Event`]s may be replayed.
///
/// Note, handlers may call back into the provider and thus deadlocking must be avoided. Be sure to
/// consult the provider's documentation on the implication of processing events and how a handler
pub trait EventsProvider {
/// Processes any events generated since the last call using the given event handler.
///
- /// Subsequent calls must only process new events. However, handlers must be capable of handling
- /// duplicate events across process restarts. This may occur if the provider was recovered from
- /// an old state (i.e., it hadn't been successfully persisted after processing pending events).
+ /// See the trait-level documentation for requirements.
fn process_pending_events<H: Deref>(&self, handler: H) where H::Target: EventHandler;
}