X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fevents%2Fmod.rs;h=ac35a71e03922dd751c4854badf74f75f1662a04;hb=2e61d920449e9bd898049581ec00c9ec90b6bd95;hp=95f2eb357dcd57a395227b828704ad9587c7dac5;hpb=61d896d5193bad813ce53cc823e9f2afa17e09a8;p=rust-lightning diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs index 95f2eb35..ac35a71e 100644 --- a/lightning/src/events/mod.rs +++ b/lightning/src/events/mod.rs @@ -24,14 +24,16 @@ use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS; use crate::ln::features::ChannelTypeFeatures; use crate::ln::msgs; use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret}; +use crate::chain::transaction; use crate::routing::gossip::NetworkUpdate; 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::{PackedLockTime, Transaction, OutPoint}; -use bitcoin::blockdata::script::Script; +use bitcoin::{Transaction, OutPoint}; +use bitcoin::blockdata::locktime::absolute::LockTime; +use bitcoin::blockdata::script::ScriptBuf; use bitcoin::hashes::Hash; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::secp256k1::PublicKey; @@ -71,6 +73,16 @@ pub enum PaymentPurpose { SpontaneousPayment(PaymentPreimage), } +impl PaymentPurpose { + /// Returns the preimage for this payment, if it is known. + pub fn preimage(&self) -> Option { + match self { + PaymentPurpose::InvoicePayment { payment_preimage, .. } => *payment_preimage, + PaymentPurpose::SpontaneousPayment(preimage) => Some(*preimage), + } + } +} + impl_writeable_tlv_based_enum!(PaymentPurpose, (0, InvoicePayment) => { (0, payment_preimage, option), @@ -102,9 +114,15 @@ pub struct ClaimedHTLC { pub cltv_expiry: u32, /// The amount (in msats) of this part of an MPP. pub value_msat: u64, + /// The extra fee our counterparty skimmed off the top of this HTLC, if any. + /// + /// This value will always be 0 for [`ClaimedHTLC`]s serialized with LDK versions prior to + /// 0.0.119. + pub counterparty_skimmed_fee_msat: u64, } impl_writeable_tlv_based!(ClaimedHTLC, { (0, channel_id, required), + (1, counterparty_skimmed_fee_msat, (default_value, 0u64)), (2, user_channel_id, required), (4, cltv_expiry, required), (6, value_msat, required), @@ -199,6 +217,9 @@ pub enum ClosureReason { /// The counterparty requested a cooperative close of a channel that had not been funded yet. /// The channel has been immediately closed. CounterpartyCoopClosedUnfundedChannel, + /// Another channel in the same funding batch closed before the funding transaction + /// was ready to be broadcast. + FundingBatchClosure, } impl core::fmt::Display for ClosureReason { @@ -219,6 +240,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"), + ClosureReason::FundingBatchClosure => f.write_str("another channel in the same funding batch closed"), } } } @@ -233,6 +255,7 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason, (10, DisconnectedPeer) => {}, (12, OutdatedChannelManager) => {}, (13, CounterpartyCoopClosedUnfundedChannel) => {}, + (15, FundingBatchClosure) => {} ); /// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`]. @@ -373,7 +396,7 @@ pub enum Event { /// The value, in satoshis, that the output should have. channel_value_satoshis: u64, /// The script which should be used in the transaction output. - output_script: Script, + output_script: ScriptBuf, /// 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 @@ -508,6 +531,37 @@ pub enum Event { /// serialized prior to LDK version 0.0.117. sender_intended_total_msat: Option, }, + /// Indicates that a peer connection with a node is needed in order to send an [`OnionMessage`]. + /// + /// Typically, this happens when a [`MessageRouter`] is unable to find a complete path to a + /// [`Destination`]. Once a connection is established, any messages buffered by an + /// [`OnionMessageHandler`] may be sent. + /// + /// This event will not be generated for onion message forwards; only for sends including + /// replies. Handlers should connect to the node otherwise any buffered messages may be lost. + /// + /// [`OnionMessage`]: msgs::OnionMessage + /// [`MessageRouter`]: crate::onion_message::messenger::MessageRouter + /// [`Destination`]: crate::onion_message::messenger::Destination + /// [`OnionMessageHandler`]: crate::ln::msgs::OnionMessageHandler + ConnectionNeeded { + /// The node id for the node needing a connection. + node_id: PublicKey, + /// Sockets for connecting to the node. + addresses: Vec, + }, + /// Indicates a request for an invoice failed to yield a response in a reasonable amount of time + /// or was explicitly abandoned by [`ChannelManager::abandon_payment`]. This may be for an + /// [`InvoiceRequest`] sent for an [`Offer`] or for a [`Refund`] that hasn't been redeemed. + /// + /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment + /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest + /// [`Offer`]: crate::offers::offer::Offer + /// [`Refund`]: crate::offers::refund::Refund + InvoiceRequestFailed { + /// The `payment_id` to have been associated with payment for the requested invoice. + payment_id: PaymentId, + }, /// 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). /// @@ -729,7 +783,7 @@ pub enum Event { /// The outgoing channel between the next node and us. This is only `None` for events /// generated or serialized by versions prior to 0.0.107. next_channel_id: Option, - /// The fee, in milli-satoshis, which was earned as a result of the payment. + /// The total fee, in milli-satoshis, which was earned as a result of the payment. /// /// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC /// was pending, the amount the next hop claimed will have been rounded down to the nearest @@ -740,15 +794,29 @@ pub enum Event { /// If the channel which sent us the payment has been force-closed, we will claim the funds /// via an on-chain transaction. In that case we do not yet know the on-chain transaction /// fees which we will spend and will instead set this to `None`. It is possible duplicate - /// `PaymentForwarded` events are generated for the same payment iff `fee_earned_msat` is + /// `PaymentForwarded` events are generated for the same payment iff `total_fee_earned_msat` is /// `None`. - fee_earned_msat: Option, + total_fee_earned_msat: Option, + /// The share of the total fee, in milli-satoshis, which was withheld in addition to the + /// forwarding fee. + /// + /// This will only be `Some` if we forwarded an intercepted HTLC with less than the + /// expected amount. This means our counterparty accepted to receive less than the invoice + /// amount, e.g., by claiming the payment featuring a corresponding + /// [`PaymentClaimable::counterparty_skimmed_fee_msat`]. + /// + /// Will also always be `None` for events serialized with LDK prior to version 0.0.122. + /// + /// The caveat described above the `total_fee_earned_msat` field applies here as well. + /// + /// [`PaymentClaimable::counterparty_skimmed_fee_msat`]: Self::PaymentClaimable::counterparty_skimmed_fee_msat + skimmed_fee_msat: Option, /// 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. + /// The caveat described above the `total_fee_earned_msat` field applies here as well. outbound_amount_forwarded_msat: Option, }, /// Used to indicate that a channel with the given `channel_id` is being opened and pending @@ -777,6 +845,10 @@ pub enum Event { counterparty_node_id: PublicKey, /// The outpoint of the channel's funding transaction. funding_txo: OutPoint, + /// The features that this channel will operate with. + /// + /// Will be `None` for channels created prior to LDK version 0.0.122. + channel_type: Option, }, /// 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 @@ -808,7 +880,7 @@ pub enum Event { /// /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels - ChannelClosed { + ChannelClosed { /// 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: ChannelId, @@ -833,9 +905,15 @@ pub enum Event { /// /// This field will be `None` for objects serialized prior to LDK 0.0.117. channel_capacity_sats: Option, + /// The original channel funding TXO; this helps checking for the existence and confirmation + /// status of the closing tx. + /// Note that for instances serialized in v0.0.119 or prior this will be missing (None). + channel_funding_txo: Option, }, /// Used to indicate to the user that they can abandon the funding transaction and recycle the /// inputs for another purpose. + /// + /// This event is not guaranteed to be generated for channels that are closed due to a restart. DiscardFunding { /// The channel_id of the channel which has been closed. channel_id: ChannelId, @@ -1023,20 +1101,21 @@ impl Writeable for Event { }); } &Event::PaymentForwarded { - fee_earned_msat, prev_channel_id, claim_from_onchain_tx, - next_channel_id, outbound_amount_forwarded_msat + total_fee_earned_msat, prev_channel_id, claim_from_onchain_tx, + next_channel_id, outbound_amount_forwarded_msat, skimmed_fee_msat, } => { 7u8.write(writer)?; write_tlv_fields!(writer, { - (0, fee_earned_msat, option), + (0, total_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), + (7, skimmed_fee_msat, option), }); }, &Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason, - ref counterparty_node_id, ref channel_capacity_sats + ref counterparty_node_id, ref channel_capacity_sats, ref channel_funding_txo } => { 9u8.write(writer)?; // `user_channel_id` used to be a single u64 value. In order to remain backwards @@ -1051,6 +1130,7 @@ impl Writeable for Event { (3, user_channel_id_high, required), (5, counterparty_node_id, option), (7, channel_capacity_sats, option), + (9, channel_funding_txo, option), }); }, &Event::DiscardFunding { ref channel_id, ref transaction } => { @@ -1138,16 +1218,30 @@ impl Writeable for Event { (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 } => { + &Event::ChannelPending { ref channel_id, ref user_channel_id, + ref former_temporary_channel_id, ref counterparty_node_id, ref funding_txo, + ref channel_type + } => { 31u8.write(writer)?; write_tlv_fields!(writer, { (0, channel_id, required), + (1, channel_type, option), (2, user_channel_id, required), (4, former_temporary_channel_id, required), (6, counterparty_node_id, required), (8, funding_txo, required), }); }, + &Event::InvoiceRequestFailed { ref payment_id } => { + 33u8.write(writer)?; + write_tlv_fields!(writer, { + (0, payment_id, required), + }) + }, + &Event::ConnectionNeeded { .. } => { + 35u8.write(writer)?; + // Never write ConnectionNeeded events as buffered onion messages aren't serialized. + }, // 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`. @@ -1158,8 +1252,7 @@ impl Writeable for Event { impl MaybeReadable for Event { fn read(reader: &mut R) -> Result, msgs::DecodeError> { match Readable::read(reader)? { - // Note that we do not write a length-prefixed TLV for FundingGenerationReady events, - // unlike all other events, thus we return immediately here. + // Note that we do not write a length-prefixed TLV for FundingGenerationReady events. 0u8 => Ok(None), 1u8 => { let f = || { @@ -1222,7 +1315,7 @@ impl MaybeReadable for Event { (5, fee_paid_msat, option), }); if payment_hash.is_none() { - payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner())); + payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array())); } Ok(Some(Event::PaymentSent { payment_id, @@ -1314,21 +1407,23 @@ impl MaybeReadable for Event { }, 7u8 => { let f = || { - let mut fee_earned_msat = None; + let mut total_fee_earned_msat = None; 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; + let mut skimmed_fee_msat = None; read_tlv_fields!(reader, { - (0, fee_earned_msat, option), + (0, total_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), + (7, skimmed_fee_msat, option), }); Ok(Some(Event::PaymentForwarded { - fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id, - outbound_amount_forwarded_msat + total_fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id, + outbound_amount_forwarded_msat, skimmed_fee_msat, })) }; f() @@ -1341,6 +1436,7 @@ impl MaybeReadable for Event { let mut user_channel_id_high_opt: Option = None; let mut counterparty_node_id = None; let mut channel_capacity_sats = None; + let mut channel_funding_txo = None; read_tlv_fields!(reader, { (0, channel_id, required), (1, user_channel_id_low_opt, option), @@ -1348,6 +1444,7 @@ impl MaybeReadable for Event { (3, user_channel_id_high_opt, option), (5, counterparty_node_id, option), (7, channel_capacity_sats, option), + (9, channel_funding_txo, option), }); // `user_channel_id` used to be a single u64 value. In order to remain @@ -1357,14 +1454,14 @@ impl MaybeReadable for Event { ((user_channel_id_high_opt.unwrap_or(0) as u128) << 64); Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: _init_tlv_based_struct_field!(reason, upgradable_required), - counterparty_node_id, channel_capacity_sats })) + counterparty_node_id, channel_capacity_sats, channel_funding_txo })) }; f() }, 11u8 => { let f = || { let mut channel_id = ChannelId::new_zero(); - let mut transaction = Transaction{ version: 2, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() }; + let mut transaction = Transaction{ version: 2, lock_time: LockTime::ZERO, input: Vec::new(), output: Vec::new() }; read_tlv_fields!(reader, { (0, channel_id, required), (2, transaction, required), @@ -1517,8 +1614,10 @@ impl MaybeReadable for Event { let mut former_temporary_channel_id = None; let mut counterparty_node_id = RequiredWrapper(None); let mut funding_txo = RequiredWrapper(None); + let mut channel_type = None; read_tlv_fields!(reader, { (0, channel_id, required), + (1, channel_type, option), (2, user_channel_id, required), (4, former_temporary_channel_id, required), (6, counterparty_node_id, required), @@ -1530,11 +1629,25 @@ impl MaybeReadable for Event { user_channel_id, former_temporary_channel_id, counterparty_node_id: counterparty_node_id.0.unwrap(), - funding_txo: funding_txo.0.unwrap() + funding_txo: funding_txo.0.unwrap(), + channel_type, })) }; f() }, + 33u8 => { + let f = || { + _init_and_read_len_prefixed_tlv_fields!(reader, { + (0, payment_id, required), + }); + Ok(Some(Event::InvoiceRequestFailed { + payment_id: payment_id.0.unwrap(), + })) + }; + f() + }, + // Note that we do not write a length-prefixed TLV for ConnectionNeeded events. + 35u8 => Ok(None), // 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. @@ -1606,6 +1719,34 @@ pub enum MessageSendEvent { /// The message which should be sent. msg: msgs::FundingSigned, }, + /// Used to indicate that a stfu message should be sent to the peer with the given node id. + SendStfu { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::Stfu, + }, + /// Used to indicate that a splice message should be sent to the peer with the given node id. + SendSplice { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::Splice, + }, + /// Used to indicate that a splice_ack message should be sent to the peer with the given node id. + SendSpliceAck { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::SpliceAck, + }, + /// Used to indicate that a splice_locked message should be sent to the peer with the given node id. + SendSpliceLocked { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::SpliceLocked, + }, /// 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 @@ -1667,7 +1808,7 @@ pub enum MessageSendEvent { /// The node_id of the node which should receive this message node_id: PublicKey, /// The message which should be sent. - msg: msgs::TxAddInput, + msg: msgs::TxAbort, }, /// Used to indicate that a channel_ready message should be sent to the peer with the given node_id. SendChannelReady { @@ -1811,12 +1952,6 @@ pub trait MessageSendEventsProvider { fn get_and_clear_pending_msg_events(&self) -> Vec; } -/// A trait indicating an object may generate onion messages to send -pub trait OnionMessageProvider { - /// Gets the next pending onion message for the peer with the given node id. - fn next_onion_message_for_peer(&self, peer_node_id: PublicKey) -> Option; -} - /// A trait indicating an object may generate events. /// /// Events are processed by passing an [`EventHandler`] to [`process_pending_events`].