X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Futil%2Fevents.rs;h=3593cbf97e6f69ad54fb92010903b56993beec09;hb=4b8b17d72f9928220f44820247027ec497e79062;hp=455263ee26f266046ab171feeefe0859e52e6447;hpb=e61f3a238a70cbac87209e223b7c396108a49b97;p=rust-lightning diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index 455263ee..3593cbf9 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -14,27 +14,31 @@ //! 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; +#[cfg(anchors)] +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, WithoutLength, OptionDeserWrapper}; +use crate::routing::router::{RouteHop, RouteParameters}; use bitcoin::{PackedLockTime, Transaction}; +#[cfg(anchors)] +use bitcoin::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. @@ -111,11 +115,19 @@ pub enum ClosureReason { /// 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 } @@ -196,6 +208,86 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCDestination, } ); +#[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, + }, +} + /// 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 @@ -226,11 +318,12 @@ pub enum Event { channel_value_satoshis: u64, /// The script which should be used in the transaction output. output_script: Script, - /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`], or 0 for - /// an inbound channel. + /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`], or a + /// random value for an inbound channel. This may be zero for objects serialized with LDK + /// versions prior to 0.0.113. /// /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel - user_channel_id: u64, + user_channel_id: u128, }, /// Indicates we've received (an offer of) money! Just gotta dig out that payment preimage and /// feed it to [`ChannelManager::claim_funds`] to get it.... @@ -317,8 +410,8 @@ pub enum Event { /// provide failure information for each MPP part in the payment. /// /// This event is provided once there are no further pending HTLCs for the payment and the - /// payment is no longer retryable, either due to a several-block timeout or because - /// [`ChannelManager::abandon_payment`] was previously called for the corresponding payment. + /// payment is no longer retryable due to [`ChannelManager::abandon_payment`] having been + /// called for the corresponding payment. /// /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment PaymentFailed { @@ -357,9 +450,14 @@ pub enum Event { /// Indicates an outbound HTLC we sent failed. Probably some intermediary node dropped /// something. You may wish to retry with a different route. /// + /// If you have given up retrying this payment and wish to fail it, you MUST call + /// [`ChannelManager::abandon_payment`] at least once for a given [`PaymentId`] or memory + /// related to payment tracking will leak. + /// /// Note that this does *not* indicate that all paths for an MPP payment have failed, see /// [`Event::PaymentFailed`] and [`all_paths_failed`]. /// + /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment /// [`all_paths_failed`]: Self::PaymentPathFailed::all_paths_failed PaymentPathFailed { /// The id returned by [`ChannelManager::send_payment`] and used with @@ -505,6 +603,27 @@ pub enum Event { /// transaction. claim_from_onchain_tx: bool, }, + /// 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. + 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 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 { @@ -514,13 +633,14 @@ pub enum Event { /// 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 0 for an inbound channel. - /// This will always be zero for objects serialized with LDK versions prior to 0.0.102. + /// `user_channel_id` will be randomized for inbound channels. + /// This may be zero for inbound channels serialized prior to 0.0.113 and will always be + /// zero for objects serialized with LDK versions prior to 0.0.102. /// /// [`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: u64, + user_channel_id: u128, /// The reason the channel was closed. reason: ClosureReason }, @@ -602,6 +722,13 @@ 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. + BumpTransaction(BumpTransactionEvent), } impl Writeable for Event { @@ -660,7 +787,7 @@ impl Writeable for Event { (1, network_update, option), (2, payment_failed_permanently, required), (3, all_paths_failed, required), - (5, path, vec_type), + (5, *path, vec_type), (7, short_channel_id, option), (9, retry, option), (11, payment_id, option), @@ -674,7 +801,7 @@ impl Writeable for Event { &Event::SpendableOutputs { ref outputs } => { 5u8.write(writer)?; write_tlv_fields!(writer, { - (0, VecWriteWrapper(outputs), required), + (0, WithoutLength(outputs), required), }); }, &Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => { @@ -688,10 +815,16 @@ impl Writeable for Event { }, &Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason } => { 9u8.write(writer)?; + // `user_channel_id` used to be a single u64 value. In order to remain backwards + // compatible with versions prior to 0.0.113, the u128 is serialized as two + // separate u64 values. + let user_channel_id_low = *user_channel_id as u64; + let user_channel_id_high = (*user_channel_id >> 64) as u64; write_tlv_fields!(writer, { (0, channel_id, required), - (1, user_channel_id, required), - (2, reason, required) + (1, user_channel_id_low, required), + (2, reason, required), + (3, user_channel_id_high, required), }); }, &Event::DiscardFunding { ref channel_id, ref transaction } => { @@ -706,7 +839,7 @@ impl Writeable for Event { write_tlv_fields!(writer, { (0, payment_id, required), (2, payment_hash, option), - (4, path, vec_type) + (4, *path, vec_type) }) }, &Event::PaymentFailed { ref payment_id, ref payment_hash } => { @@ -734,7 +867,7 @@ impl Writeable for Event { write_tlv_fields!(writer, { (0, payment_id, required), (2, payment_hash, required), - (4, path, vec_type) + (4, *path, vec_type) }) }, &Event::ProbeFailed { ref payment_id, ref payment_hash, ref path, ref short_channel_id } => { @@ -742,7 +875,7 @@ impl Writeable for Event { write_tlv_fields!(writer, { (0, payment_id, required), (2, payment_hash, required), - (4, path, vec_type), + (4, *path, vec_type), (6, short_channel_id, option), }) }, @@ -753,6 +886,24 @@ impl Writeable for Event { (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 { .. } => {} + } + } + &Event::ChannelReady { ref channel_id, ref user_channel_id, ref counterparty_node_id, ref channel_type } => { + 29u8.write(writer)?; + write_tlv_fields!(writer, { + (0, channel_id, required), + (2, user_channel_id, required), + (4, counterparty_node_id, required), + (6, channel_type, 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`. @@ -864,7 +1015,7 @@ impl MaybeReadable for Event { 4u8 => Ok(None), 5u8 => { let f = || { - let mut outputs = VecReadWrapper(Vec::new()); + let mut outputs = WithoutLength(Vec::new()); read_tlv_fields!(reader, { (0, outputs, required), }); @@ -892,14 +1043,22 @@ impl MaybeReadable for Event { let f = || { let mut channel_id = [0; 32]; let mut reason = None; - let mut user_channel_id_opt = None; + let mut user_channel_id_low_opt: Option = None; + let mut user_channel_id_high_opt: Option = None; read_tlv_fields!(reader, { (0, channel_id, required), - (1, user_channel_id_opt, option), + (1, user_channel_id_low_opt, option), (2, reason, ignorable), + (3, user_channel_id_high_opt, option), }); if reason.is_none() { return Ok(None); } - let user_channel_id = if let Some(id) = user_channel_id_opt { id } else { 0 }; + + // `user_channel_id` used to be a single u64 value. In order to remain + // backwards compatible with versions prior to 0.0.113, the u128 is serialized + // as two separate u64 values. + let user_channel_id = (user_channel_id_low_opt.unwrap_or(0) as u128) + + ((user_channel_id_high_opt.unwrap_or(0) as u128) << 64); + Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: reason.unwrap() })) }; f() @@ -1033,6 +1192,29 @@ impl MaybeReadable for Event { }; f() }, + 27u8 => Ok(None), + 29u8 => { + let f = || { + let mut channel_id = [0; 32]; + let mut user_channel_id: u128 = 0; + let mut counterparty_node_id = OptionDeserWrapper(None); + let mut channel_type = OptionDeserWrapper(None); + read_tlv_fields!(reader, { + (0, channel_id, required), + (2, user_channel_id, required), + (4, counterparty_node_id, required), + (6, channel_type, required), + }); + + Ok(Some(Event::ChannelReady { + channel_id, + user_channel_id, + counterparty_node_id: counterparty_node_id.0.unwrap(), + channel_type: channel_type.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. @@ -1234,6 +1416,10 @@ pub trait OnionMessageProvider { /// /// Events are processed by passing an [`EventHandler`] to [`process_pending_events`]. /// +/// Implementations of this trait may also feature an async version of event handling, as shown with +/// [`ChannelManager::process_pending_events_async`] and +/// [`ChainMonitor::process_pending_events_async`]. +/// /// # Requirements /// /// When using this trait, [`process_pending_events`] will call [`handle_event`] for each pending @@ -1260,6 +1446,8 @@ pub trait OnionMessageProvider { /// [`handle_event`]: EventHandler::handle_event /// [`ChannelManager::process_pending_events`]: crate::ln::channelmanager::ChannelManager#method.process_pending_events /// [`ChainMonitor::process_pending_events`]: crate::chain::chainmonitor::ChainMonitor#method.process_pending_events +/// [`ChannelManager::process_pending_events_async`]: crate::ln::channelmanager::ChannelManager::process_pending_events_async +/// [`ChainMonitor::process_pending_events_async`]: crate::chain::chainmonitor::ChainMonitor::process_pending_events_async pub trait EventsProvider { /// Processes any events generated since the last call using the given event handler. /// @@ -1268,21 +1456,25 @@ pub trait EventsProvider { } /// A trait implemented for objects handling events from [`EventsProvider`]. +/// +/// An async variation also exists for implementations of [`EventsProvider`] that support async +/// event handling. The async event handler should satisfy the generic bounds: `F: +/// core::future::Future, H: Fn(Event) -> F`. pub trait EventHandler { /// Handles the given [`Event`]. /// /// See [`EventsProvider`] for details that must be considered when implementing this method. - fn handle_event(&self, event: &Event); + fn handle_event(&self, event: Event); } -impl EventHandler for F where F: Fn(&Event) { - fn handle_event(&self, event: &Event) { +impl EventHandler for F where F: Fn(Event) { + fn handle_event(&self, event: Event) { self(event) } } impl EventHandler for Arc { - fn handle_event(&self, event: &Event) { + fn handle_event(&self, event: Event) { self.deref().handle_event(event) } }