From: Wilmer Paulino Date: Tue, 7 Mar 2023 21:57:01 +0000 (-0800) Subject: Move events.rs into its own top-level module X-Git-Tag: v0.0.115~51^2~1 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=ca9ca75f082dec8dfc70f3e263a7c3789e17a054;p=rust-lightning Move events.rs into its own top-level module This is largely motivated by some follow-up work for anchors that will introduce an event handler for `BumpTransaction` events, which we can now include in this new top-level `events` module. --- diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 40106ffbb..f6be6cdaf 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -38,6 +38,8 @@ use lightning::chain::channelmonitor::{ChannelMonitor, MonitorEvent}; use lightning::chain::transaction::OutPoint; use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator}; use lightning::chain::keysinterface::{KeyMaterial, InMemorySigner, Recipient, EntropySource, NodeSigner, SignerProvider}; +use lightning::events; +use lightning::events::MessageSendEventsProvider; use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; use lightning::ln::channelmanager::{ChainParameters, ChannelDetails, ChannelManager, PaymentSendFailure, ChannelManagerReadArgs, PaymentId}; use lightning::ln::channel::FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE; @@ -45,10 +47,8 @@ use lightning::ln::msgs::{self, CommitmentUpdate, ChannelMessageHandler, DecodeE use lightning::ln::script::ShutdownScript; use lightning::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState}; use lightning::util::errors::APIError; -use lightning::util::events; use lightning::util::logger::Logger; use lightning::util::config::UserConfig; -use lightning::util::events::MessageSendEventsProvider; use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer}; use lightning::routing::router::{InFlightHtlcs, Route, RouteHop, RouteParameters, Router}; diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index c520d99fd..8ef0509a9 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -35,6 +35,7 @@ use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, use lightning::chain::chainmonitor; use lightning::chain::transaction::OutPoint; use lightning::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider}; +use lightning::events::Event; use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; use lightning::ln::channelmanager::{ChainParameters, ChannelDetails, ChannelManager, PaymentId}; use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor,IgnoringMessageHandler}; @@ -46,7 +47,6 @@ use lightning::routing::router::{find_route, InFlightHtlcs, PaymentParameters, R use lightning::routing::scoring::FixedPenaltyScorer; use lightning::util::config::UserConfig; use lightning::util::errors::APIError; -use lightning::util::events::Event; use lightning::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState}; use lightning::util::logger::Logger; use lightning::util::ser::{Readable, Writeable}; diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index e407c4fdb..f0ed77366 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -26,6 +26,9 @@ use lightning::chain; use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator}; use lightning::chain::chainmonitor::{ChainMonitor, Persist}; use lightning::chain::keysinterface::{EntropySource, NodeSigner, SignerProvider}; +use lightning::events::{Event, PathFailure}; +#[cfg(feature = "std")] +use lightning::events::{EventHandler, EventsProvider}; use lightning::ln::channelmanager::ChannelManager; use lightning::ln::msgs::{ChannelMessageHandler, OnionMessageHandler, RoutingMessageHandler}; use lightning::ln::peer_handler::{CustomMessageHandler, PeerManager, SocketDescriptor}; @@ -33,9 +36,6 @@ use lightning::routing::gossip::{NetworkGraph, P2PGossipSync}; use lightning::routing::utxo::UtxoLookup; use lightning::routing::router::Router; use lightning::routing::scoring::{Score, WriteableScore}; -use lightning::util::events::{Event, PathFailure}; -#[cfg(feature = "std")] -use lightning::util::events::{EventHandler, EventsProvider}; use lightning::util::logger::Logger; use lightning::util::persist::Persister; use lightning_rapid_gossip_sync::RapidGossipSync; @@ -80,7 +80,7 @@ use alloc::vec::Vec; /// unilateral chain closure fees are at risk. /// /// [`ChannelMonitor`]: lightning::chain::channelmonitor::ChannelMonitor -/// [`Event`]: lightning::util::events::Event +/// [`Event`]: lightning::events::Event #[cfg(feature = "std")] #[must_use = "BackgroundProcessor will immediately stop on drop. It should be stored until shutdown."] pub struct BackgroundProcessor { @@ -663,6 +663,7 @@ mod tests { use lightning::chain::channelmonitor::ANTI_REORG_DELAY; use lightning::chain::keysinterface::{InMemorySigner, KeysManager}; use lightning::chain::transaction::OutPoint; + use lightning::events::{Event, PathFailure, MessageSendEventsProvider, MessageSendEvent}; use lightning::get_event_msg; use lightning::ln::PaymentHash; use lightning::ln::channelmanager; @@ -674,7 +675,6 @@ mod tests { use lightning::routing::router::{DefaultRouter, RouteHop}; use lightning::routing::scoring::{ChannelUsage, Score}; use lightning::util::config::UserConfig; - use lightning::util::events::{Event, PathFailure, MessageSendEventsProvider, MessageSendEvent}; use lightning::util::ser::Writeable; use lightning::util::test_utils; use lightning::util::persist::KVStorePersister; diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 06f11a91e..99ac37f52 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -665,12 +665,12 @@ mod test { use bitcoin_hashes::{Hash, sha256}; use bitcoin_hashes::sha256::Hash as Sha256; use lightning::chain::keysinterface::{EntropySource, PhantomKeysManager}; + use lightning::events::{MessageSendEvent, MessageSendEventsProvider, Event}; use lightning::ln::{PaymentPreimage, PaymentHash}; use lightning::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId}; use lightning::ln::functional_test_utils::*; use lightning::ln::msgs::ChannelMessageHandler; use lightning::routing::router::{PaymentParameters, RouteParameters, find_route}; - use lightning::util::events::{MessageSendEvent, MessageSendEventsProvider, Event}; use lightning::util::test_utils; use lightning::util::config::UserConfig; use crate::utils::create_invoice_from_channelmanager_and_duration_since_epoch; diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index a513e603e..aeb5c5b7a 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -24,7 +24,7 @@ //! ``` //! use std::net::TcpStream; //! use bitcoin::secp256k1::PublicKey; -//! use lightning::util::events::{Event, EventHandler, EventsProvider}; +//! use lightning::events::{Event, EventHandler, EventsProvider}; //! use std::net::SocketAddr; //! use std::sync::Arc; //! @@ -586,7 +586,7 @@ mod tests { use lightning::ln::peer_handler::{MessageHandler, PeerManager}; use lightning::ln::features::NodeFeatures; use lightning::routing::gossip::NodeId; - use lightning::util::events::*; + use lightning::events::*; use lightning::util::test_utils::TestNodeSigner; use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey}; diff --git a/lightning-persister/src/lib.rs b/lightning-persister/src/lib.rs index 488378576..3bdf444dd 100644 --- a/lightning-persister/src/lib.rs +++ b/lightning-persister/src/lib.rs @@ -143,8 +143,8 @@ mod tests { use lightning::chain::chainmonitor::Persist; use lightning::chain::transaction::OutPoint; use lightning::{check_closed_broadcast, check_closed_event, check_added_monitors}; + use lightning::events::{ClosureReason, MessageSendEventsProvider}; use lightning::ln::functional_test_utils::*; - use lightning::util::events::{ClosureReason, MessageSendEventsProvider}; use lightning::util::test_utils; use std::fs; use bitcoin::hashes::Hash; diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index 9a74f891b..4bfb47de4 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -32,11 +32,11 @@ use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator}; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, Balance, MonitorEvent, TransactionOutputs, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::transaction::{OutPoint, TransactionData}; use crate::chain::keysinterface::WriteableEcdsaChannelSigner; +use crate::events; +use crate::events::{Event, EventHandler}; use crate::util::atomic_counter::AtomicCounter; use crate::util::logger::Logger; use crate::util::errors::APIError; -use crate::util::events; -use crate::util::events::{Event, EventHandler}; use crate::ln::channelmanager::ChannelDetails; use crate::prelude::*; @@ -490,7 +490,7 @@ where C::Target: chain::Filter, #[cfg(any(test, fuzzing, feature = "_test_utils"))] pub fn get_and_clear_pending_events(&self) -> Vec { - use crate::util::events::EventsProvider; + use crate::events::EventsProvider; let events = core::cell::RefCell::new(Vec::new()); let event_handler = |event: events::Event| events.borrow_mut().push(event); self.process_pending_events(&event_handler); @@ -502,7 +502,7 @@ where C::Target: chain::Filter, /// /// See the trait-level documentation of [`EventsProvider`] for requirements. /// - /// [`EventsProvider`]: crate::util::events::EventsProvider + /// [`EventsProvider`]: crate::events::EventsProvider pub async fn process_pending_events_async Future>( &self, handler: H ) { @@ -792,11 +792,11 @@ mod tests { use crate::{get_htlc_update_msgs, get_local_commitment_txn, get_revoke_commit_msgs, get_route_and_payment_hash, unwrap_send_err}; use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Watch}; use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS; + use crate::events::{Event, ClosureReason, MessageSendEvent, MessageSendEventsProvider}; use crate::ln::channelmanager::{PaymentSendFailure, PaymentId}; use crate::ln::functional_test_utils::*; use crate::ln::msgs::ChannelMessageHandler; use crate::util::errors::APIError; - use crate::util::events::{Event, ClosureReason, MessageSendEvent, MessageSendEventsProvider}; #[test] fn test_async_ooo_offchain_updates() { diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 1ebb65534..10b05c951 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -51,9 +51,9 @@ use crate::chain::Filter; use crate::util::logger::Logger; use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48}; use crate::util::byte_utils; -use crate::util::events::Event; +use crate::events::Event; #[cfg(anchors)] -use crate::util::events::{AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent}; +use crate::events::{AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent}; use crate::prelude::*; use core::{cmp, mem}; @@ -1279,7 +1279,7 @@ impl ChannelMonitor { /// This is called by the [`EventsProvider::process_pending_events`] implementation for /// [`ChainMonitor`]. /// - /// [`EventsProvider::process_pending_events`]: crate::util::events::EventsProvider::process_pending_events + /// [`EventsProvider::process_pending_events`]: crate::events::EventsProvider::process_pending_events /// [`ChainMonitor`]: crate::chain::chainmonitor::ChainMonitor pub fn get_and_clear_pending_events(&self) -> Vec { self.inner.lock().unwrap().get_and_clear_pending_events() @@ -4005,6 +4005,7 @@ mod tests { use crate::chain::package::{weight_offered_htlc, weight_received_htlc, weight_revoked_offered_htlc, weight_revoked_received_htlc, WEIGHT_REVOKED_OUTPUT}; use crate::chain::transaction::OutPoint; use crate::chain::keysinterface::InMemorySigner; + use crate::events::ClosureReason; use crate::ln::{PaymentPreimage, PaymentHash}; use crate::ln::chan_utils; use crate::ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters}; @@ -4012,7 +4013,6 @@ mod tests { use crate::ln::functional_test_utils::*; use crate::ln::script::ShutdownScript; use crate::util::errors::APIError; - use crate::util::events::ClosureReason; use crate::util::test_utils::{TestLogger, TestBroadcaster, TestFeeEstimator}; use crate::util::ser::{ReadableArgs, Writeable}; use crate::sync::{Arc, Mutex}; diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index 21331fff4..edd86e0bf 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -34,9 +34,9 @@ use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness}; use crate::util::transaction_utils; use crate::util::crypto::{hkdf_extract_expand_twice, sign}; use crate::util::ser::{Writeable, Writer, Readable}; -#[cfg(anchors)] -use crate::util::events::HTLCDescriptor; use crate::chain::transaction::OutPoint; +#[cfg(anchors)] +use crate::events::HTLCDescriptor; use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI; use crate::ln::{chan_utils, PaymentPreimage}; use crate::ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction}; @@ -135,7 +135,7 @@ impl_writeable_tlv_based!(StaticPaymentOutputDescriptor, { /// outpoint describing which `txid` and output `index` is available, the full output which exists /// at that `txid`/`index`, and any keys or other information required to sign. /// -/// [`SpendableOutputs`]: crate::util::events::Event::SpendableOutputs +/// [`SpendableOutputs`]: crate::events::Event::SpendableOutputs #[derive(Clone, Debug, PartialEq, Eq)] pub enum SpendableOutputDescriptor { /// An output to a script which was provided via [`SignerProvider`] directly, either from diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs new file mode 100644 index 000000000..43a2ae02c --- /dev/null +++ b/lightning/src/events/mod.rs @@ -0,0 +1,1746 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + +//! Events are returned from various bits in the library which indicate some action must be taken +//! by the client. +//! +//! Because we don't have a built-in runtime, it's up to the client to call events at a time in the +//! future, as well as generate and broadcast funding transactions handle payment preimages and a +//! few other things. + +use crate::chain::keysinterface::SpendableOutputDescriptor; +#[cfg(anchors)] +use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment}; +use crate::ln::channelmanager::{InterceptId, PaymentId}; +use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS; +use crate::ln::features::ChannelTypeFeatures; +use crate::ln::msgs; +use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret}; +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::{RouteHop, RouteParameters}; + +use bitcoin::{PackedLockTime, Transaction}; +#[cfg(anchors)] +use bitcoin::{OutPoint, Txid, TxIn, TxOut, Witness}; +use bitcoin::blockdata::script::Script; +use bitcoin::hashes::Hash; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::secp256k1::PublicKey; +#[cfg(anchors)] +use bitcoin::secp256k1::{self, Secp256k1}; +#[cfg(anchors)] +use bitcoin::secp256k1::ecdsa::Signature; +use crate::io; +use crate::prelude::*; +use core::time::Duration; +use core::ops::Deref; +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. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum PaymentPurpose { + /// Information for receiving a payment that we generated an invoice for. + InvoicePayment { + /// The preimage to the payment_hash, if the payment hash (and secret) were fetched via + /// [`ChannelManager::create_inbound_payment`]. If provided, this can be handed directly to + /// [`ChannelManager::claim_funds`]. + /// + /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment + /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds + payment_preimage: Option, + /// The "payment secret". This authenticates the sender to the recipient, preventing a + /// number of deanonymization attacks during the routing process. + /// It is provided here for your reference, however its accuracy is enforced directly by + /// [`ChannelManager`] using the values you previously provided to + /// [`ChannelManager::create_inbound_payment`] or + /// [`ChannelManager::create_inbound_payment_for_hash`]. + /// + /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager + /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment + /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash + payment_secret: PaymentSecret, + }, + /// Because this is a spontaneous payment, the payer generated their own preimage rather than us + /// (the payee) providing a preimage. + SpontaneousPayment(PaymentPreimage), +} + +impl_writeable_tlv_based_enum!(PaymentPurpose, + (0, InvoicePayment) => { + (0, payment_preimage, option), + (2, payment_secret, required), + }; + (2, SpontaneousPayment) +); + +/// When the payment path failure took place and extra details about it. [`PathFailure::OnPath`] may +/// contain a [`NetworkUpdate`] that needs to be applied to the [`NetworkGraph`]. +/// +/// [`NetworkUpdate`]: crate::routing::gossip::NetworkUpdate +/// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum PathFailure { + /// We failed to initially send the payment and no HTLC was committed to. Contains the relevant + /// error. + InitialSend { + /// The error surfaced from initial send. + err: APIError, + }, + /// A hop on the path failed to forward our payment. + OnPath { + /// If present, this [`NetworkUpdate`] should be applied to the [`NetworkGraph`] so that routing + /// decisions can take into account the update. + /// + /// [`NetworkUpdate`]: crate::routing::gossip::NetworkUpdate + /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph + network_update: Option, + }, +} + +impl_writeable_tlv_based_enum_upgradable!(PathFailure, + (0, OnPath) => { + (0, network_update, upgradable_option), + }, + (2, InitialSend) => { + (0, err, upgradable_required), + }, +); + +#[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. + /// + /// Our counterparty may have broadcasted their latest commitment state, and we have + /// as well. + CounterpartyForceClosed { + /// The error which the peer sent us. + /// + /// Be careful about printing the peer_msg, a well-crafted message could exploit + /// a security vulnerability in the terminal emulator or the logging subsystem. + /// To be safe, use `Display` on `UntrustedString` + /// + /// [`UntrustedString`]: crate::util::string::UntrustedString + peer_msg: UntrustedString, + }, + /// Closure generated from [`ChannelManager::force_close_channel`], called by the user. + /// + /// [`ChannelManager::force_close_channel`]: crate::ln::channelmanager::ChannelManager::force_close_channel. + HolderForceClosed, + /// 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. + //TODO: split between CounterpartyInitiated/LocallyInitiated + CooperativeClosure, + /// A commitment transaction was confirmed on chain, closing the channel. Most likely this + /// commitment transaction came from our counterparty, but it may also have come from + /// a copy of our own `ChannelMonitor`. + CommitmentTxConfirmed, + /// The funding transaction failed to confirm in a timely manner on an inbound channel. + FundingTimedOut, + /// Closure generated from processing an event, likely a HTLC forward/relay/reception. + ProcessingError { + /// A developer-readable error message which we generated. + err: String, + }, + /// 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. + /// + /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor + /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager + OutdatedChannelManager +} + +impl core::fmt::Display for ClosureReason { + fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { + f.write_str("Channel closed because ")?; + match self { + ClosureReason::CounterpartyForceClosed { peer_msg } => { + f.write_fmt(format_args!("counterparty force-closed with message: {}", peer_msg)) + }, + ClosureReason::HolderForceClosed => f.write_str("user manually force-closed the channel"), + ClosureReason::CooperativeClosure => f.write_str("the channel was cooperatively closed"), + ClosureReason::CommitmentTxConfirmed => f.write_str("commitment or closing transaction was confirmed on chain."), + ClosureReason::FundingTimedOut => write!(f, "funding transaction failed to confirm within {} blocks", FUNDING_CONF_DEADLINE_BLOCKS), + ClosureReason::ProcessingError { err } => { + f.write_str("of an exception: ")?; + f.write_str(&err) + }, + 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)"), + } + } +} + +impl_writeable_tlv_based_enum_upgradable!(ClosureReason, + (0, CounterpartyForceClosed) => { (1, peer_msg, required) }, + (1, FundingTimedOut) => {}, + (2, HolderForceClosed) => {}, + (6, CommitmentTxConfirmed) => {}, + (4, CooperativeClosure) => {}, + (8, ProcessingError) => { (1, err, required) }, + (10, DisconnectedPeer) => {}, + (12, OutdatedChannelManager) => {}, +); + +/// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`]. +#[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. + NextHopChannel { + /// The `node_id` of the next node. For backwards compatibility, this field is + /// marked as optional, versions prior to 0.0.110 may not always be able to provide + /// counterparty node information. + node_id: Option, + /// The outgoing `channel_id` between us and the next node. + channel_id: [u8; 32], + }, + /// Scenario where we are unsure of the next node to forward the HTLC to. + UnknownNextHop { + /// Short channel id we are requesting to forward an HTLC to. + requested_forward_scid: u64, + }, + /// We couldn't forward to the outgoing scid. An example would be attempting to send a duplicate + /// intercept HTLC. + InvalidForward { + /// Short channel id we are requesting to forward an HTLC to. + requested_forward_scid: u64 + }, + /// Failure scenario where an HTLC may have been forwarded to be intended for us, + /// but is invalid for some reason, so we reject it. + /// + /// Some of the reasons may include: + /// * HTLC Timeouts + /// * Expected MPP amount to claim does not equal HTLC total + /// * Claimable amount does not match expected amount + FailedPayment { + /// The payment hash of the payment we attempted to process. + payment_hash: PaymentHash + }, +} + +impl_writeable_tlv_based_enum_upgradable!(HTLCDestination, + (0, NextHopChannel) => { + (0, node_id, required), + (2, channel_id, required), + }, + (1, InvalidForward) => { + (0, requested_forward_scid, required), + }, + (2, UnknownNextHop) => { + (0, requested_forward_scid, required), + }, + (4, FailedPayment) => { + (0, payment_hash, required), + }, +); + +#[cfg(anchors)] +/// A descriptor used to sign for a commitment transaction's anchor output. +#[derive(Clone, Debug, PartialEq, Eq)] +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)] +/// A descriptor used to sign for a commitment transaction's HTLC output. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct HTLCDescriptor { + /// 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 necessary channel parameters that need to be provided to the re-derived + /// [`InMemorySigner`] through [`ChannelSigner::provide_channel_parameters`]. + /// + /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner + /// [`ChannelSigner::provide_channel_parameters`]: crate::chain::keysinterface::ChannelSigner::provide_channel_parameters + pub channel_parameters: ChannelTransactionParameters, + /// The txid of the commitment transaction in which the HTLC output lives. + pub commitment_txid: Txid, + /// The number of the commitment transaction in which the HTLC output lives. + pub per_commitment_number: u64, + /// The details of the HTLC as it appears in the commitment transaction. + pub htlc: HTLCOutputInCommitment, + /// The preimage, if `Some`, to claim the HTLC output with. If `None`, the timeout path must be + /// taken. + pub preimage: Option, + /// The counterparty's signature required to spend the HTLC output. + pub counterparty_sig: Signature +} + +#[cfg(anchors)] +impl HTLCDescriptor { + /// Returns the unsigned transaction input spending the HTLC output in the commitment + /// transaction. + pub fn unsigned_tx_input(&self) -> TxIn { + chan_utils::build_htlc_input(&self.commitment_txid, &self.htlc, true /* opt_anchors */) + } + + /// Returns the delayed output created as a result of spending the HTLC output in the commitment + /// transaction. + pub fn tx_output( + &self, per_commitment_point: &PublicKey, secp: &Secp256k1 + ) -> TxOut { + let channel_params = self.channel_parameters.as_holder_broadcastable(); + let broadcaster_keys = channel_params.broadcaster_pubkeys(); + let counterparty_keys = channel_params.countersignatory_pubkeys(); + let broadcaster_delayed_key = chan_utils::derive_public_key( + secp, per_commitment_point, &broadcaster_keys.delayed_payment_basepoint + ); + let counterparty_revocation_key = chan_utils::derive_public_revocation_key( + secp, per_commitment_point, &counterparty_keys.revocation_basepoint + ); + chan_utils::build_htlc_output( + 0 /* feerate_per_kw */, channel_params.contest_delay(), &self.htlc, true /* opt_anchors */, + false /* use_non_zero_fee_anchors */, &broadcaster_delayed_key, &counterparty_revocation_key + ) + } + + /// Returns the witness script of the HTLC output in the commitment transaction. + pub fn witness_script( + &self, per_commitment_point: &PublicKey, secp: &Secp256k1 + ) -> Script { + let channel_params = self.channel_parameters.as_holder_broadcastable(); + let broadcaster_keys = channel_params.broadcaster_pubkeys(); + let counterparty_keys = channel_params.countersignatory_pubkeys(); + let broadcaster_htlc_key = chan_utils::derive_public_key( + secp, per_commitment_point, &broadcaster_keys.htlc_basepoint + ); + let counterparty_htlc_key = chan_utils::derive_public_key( + secp, per_commitment_point, &counterparty_keys.htlc_basepoint + ); + let counterparty_revocation_key = chan_utils::derive_public_revocation_key( + secp, per_commitment_point, &counterparty_keys.revocation_basepoint + ); + chan_utils::get_htlc_redeemscript_with_explicit_keys( + &self.htlc, true /* opt_anchors */, &broadcaster_htlc_key, &counterparty_htlc_key, + &counterparty_revocation_key, + ) + } + + /// Returns the fully signed witness required to spend the HTLC output in the commitment + /// transaction. + pub fn tx_input_witness(&self, signature: &Signature, witness_script: &Script) -> Witness { + chan_utils::build_htlc_input_witness( + signature, &self.counterparty_sig, &self.preimage, witness_script, true /* opt_anchors */ + ) + } +} + +#[cfg(anchors)] +/// Represents the different types of transactions, originating from LDK, to be bumped. +#[derive(Clone, Debug, PartialEq, Eq)] +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 broadcast 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`]. The + /// anchor input signature can be computed with [`EcdsaChannelSigner::sign_holder_anchor_input`], + /// which can then be provided to [`build_anchor_input_witness`] along with the `funding_pubkey` + /// to obtain the full witness required to spend. + /// + /// 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 + /// [`EcdsaChannelSigner::sign_holder_anchor_input`]: crate::chain::keysinterface::EcdsaChannelSigner::sign_holder_anchor_input + /// [`build_anchor_input_witness`]: crate::ln::chan_utils::build_anchor_input_witness + 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, + }, + /// Indicates that a channel featuring anchor outputs has unilaterally closed on-chain by a + /// holder commitment transaction and its HTLC(s) need to be resolved on-chain. With the + /// zero-HTLC-transaction-fee variant of anchor outputs, the pre-signed HTLC + /// transactions have a zero fee, thus requiring additional inputs and/or outputs to be attached + /// for a timely confirmation within the chain. These additional inputs and/or outputs must be + /// appended to the resulting HTLC transaction to meet the target feerate. Failure to meet the + /// target feerate decreases the confirmation odds of the transaction, possibly resulting in a + /// loss of funds. Once the transaction meets the target feerate, it must be signed for and + /// broadcast by the consumer of the event. + /// + /// The consumer should be able to sign for any of the non-HTLC inputs added to the resulting + /// HTLC transaction. To sign HTLC inputs, an [`InMemorySigner`] should be re-derived through + /// [`KeysManager::derive_channel_keys`] with the help of `channel_keys_id` and + /// `channel_value_satoshis`. Each HTLC input's signature can be computed with + /// [`EcdsaChannelSigner::sign_holder_htlc_transaction`], which can then be provided to + /// [`HTLCDescriptor::tx_input_witness`] to obtain the fully signed witness required to spend. + /// + /// It is possible to receive more than one instance of this event if a valid HTLC 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 HTLC 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 either they are no + /// longer able to commit external confirmed funds to the HTLC transaction or the fee committed + /// to the HTLC transaction is greater in value than the HTLCs being claimed. + /// + /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner + /// [`KeysManager::derive_channel_keys`]: crate::chain::keysinterface::KeysManager::derive_channel_keys + /// [`EcdsaChannelSigner::sign_holder_htlc_transaction`]: crate::chain::keysinterface::EcdsaChannelSigner::sign_holder_htlc_transaction + /// [`HTLCDescriptor::tx_input_witness`]: HTLCDescriptor::tx_input_witness + HTLCResolution { + /// The target feerate that the resulting HTLC transaction must meet. + target_feerate_sat_per_1000_weight: u32, + /// The set of pending HTLCs on the confirmed commitment that need to be claimed, preferably + /// by the same transaction. + htlc_descriptors: Vec, + }, +} + +/// Will be used in [`Event::HTLCIntercepted`] to identify the next hop in the HTLC's path. +/// Currently only used in serialization for the sake of maintaining compatibility. More variants +/// will be added for general-purpose HTLC forward intercepts as well as trampoline forward +/// intercepts in upcoming work. +enum InterceptNextHop { + FakeScid { + requested_next_hop_scid: u64, + }, +} + +impl_writeable_tlv_based_enum!(InterceptNextHop, + (0, FakeScid) => { + (0, requested_next_hop_scid, required), + }; +); + +/// 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 +/// them directly as they don't round-trip exactly (for example FundingGenerationReady is never +/// written as it makes no sense to respond to it after reconnecting to peers). +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Event { + /// Used to indicate that the client should generate a funding transaction with the given + /// parameters and then call [`ChannelManager::funding_transaction_generated`]. + /// Generated in [`ChannelManager`] message handling. + /// Note that *all inputs* in the funding transaction must spend SegWit outputs or your + /// counterparty can steal your funds! + /// + /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager + /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated + FundingGenerationReady { + /// The random channel_id we picked which you'll need to pass into + /// [`ChannelManager::funding_transaction_generated`]. + /// + /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated + temporary_channel_id: [u8; 32], + /// The counterparty's node_id, which you'll need to pass back into + /// [`ChannelManager::funding_transaction_generated`]. + /// + /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated + counterparty_node_id: PublicKey, + /// 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, + /// 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: u128, + }, + /// Indicates that we've been offered a payment and it needs to be claimed via calling + /// [`ChannelManager::claim_funds`] with the preimage given in [`PaymentPurpose`]. + /// + /// Note that if the preimage is not known, you should call + /// [`ChannelManager::fail_htlc_backwards`] or [`ChannelManager::fail_htlc_backwards_with_reason`] + /// to free up resources for this HTLC and avoid network congestion. + /// If you fail to call either [`ChannelManager::claim_funds`], [`ChannelManager::fail_htlc_backwards`], + /// or [`ChannelManager::fail_htlc_backwards_with_reason`] within the HTLC's timeout, the HTLC will be + /// automatically failed. + /// + /// # Note + /// LDK will not stop an inbound payment from being paid multiple times, so multiple + /// `PaymentClaimable` events may be generated for the same payment. + /// + /// # Note + /// This event used to be called `PaymentReceived` in LDK versions 0.0.112 and earlier. + /// + /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds + /// [`ChannelManager::fail_htlc_backwards`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards + /// [`ChannelManager::fail_htlc_backwards_with_reason`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards_with_reason + PaymentClaimable { + /// The node that will receive the payment after it has been claimed. + /// This is useful to identify payments received via [phantom nodes]. + /// This field will always be filled in when the event was generated by LDK versions + /// 0.0.113 and above. + /// + /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager + receiver_node_id: Option, + /// The hash for which the preimage should be handed to the ChannelManager. Note that LDK will + /// not stop you from registering duplicate payment hashes for inbound payments. + payment_hash: PaymentHash, + /// The value, in thousandths of a satoshi, that this payment is for. + amount_msat: u64, + /// Information for claiming this received payment, based on whether the purpose of the + /// payment is to pay an invoice or to send a spontaneous payment. + purpose: PaymentPurpose, + /// The `channel_id` indicating over which channel we received the payment. + via_channel_id: Option<[u8; 32]>, + /// The `user_channel_id` indicating over which channel we received the payment. + via_user_channel_id: Option, + }, + /// Indicates a payment has been claimed and we've received money! + /// + /// This most likely occurs when [`ChannelManager::claim_funds`] has been called in response + /// to an [`Event::PaymentClaimable`]. However, if we previously crashed during a + /// [`ChannelManager::claim_funds`] call you may see this event without a corresponding + /// [`Event::PaymentClaimable`] event. + /// + /// # Note + /// LDK will not stop an inbound payment from being paid multiple times, so multiple + /// `PaymentClaimable` events may be generated for the same payment. If you then call + /// [`ChannelManager::claim_funds`] twice for the same [`Event::PaymentClaimable`] you may get + /// multiple `PaymentClaimed` events. + /// + /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds + PaymentClaimed { + /// The node that received the payment. + /// This is useful to identify payments which were received via [phantom nodes]. + /// This field will always be filled in when the event was generated by LDK versions + /// 0.0.113 and above. + /// + /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager + receiver_node_id: Option, + /// The payment hash of the claimed payment. Note that LDK will not stop you from + /// registering duplicate payment hashes for inbound payments. + payment_hash: PaymentHash, + /// The value, in thousandths of a satoshi, that this payment is for. + amount_msat: u64, + /// The purpose of the claimed payment, i.e. whether the payment was for an invoice or a + /// spontaneous payment. + purpose: PaymentPurpose, + }, + /// 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). + /// + /// 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`]. + /// + /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment + payment_id: Option, + /// The preimage to the hash given to ChannelManager::send_payment. + /// Note that this serves as a payment receipt, if you wish to have such a thing, you must + /// store it somehow! + payment_preimage: PaymentPreimage, + /// The hash that was given to [`ChannelManager::send_payment`]. + /// + /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment + payment_hash: PaymentHash, + /// The total fee which was spent at intermediate hops in this payment, across all paths. + /// + /// Note that, like [`Route::get_total_fees`] this does *not* include any potential + /// overpayment to the recipient node. + /// + /// If the recipient or an intermediate node misbehaves and gives us free money, this may + /// overstate the amount paid, though this is unlikely. + /// + /// [`Route::get_total_fees`]: crate::routing::router::Route::get_total_fees + fee_paid_msat: Option, + }, + /// Indicates an outbound payment failed. Individual [`Event::PaymentPathFailed`] events + /// provide failure information for each path attempt in the payment, including retries. + /// + /// This event is provided once there are no further pending HTLCs for the payment and the + /// payment is no longer retryable, due either to the [`Retry`] provided or + /// [`ChannelManager::abandon_payment`] having been called for the corresponding payment. + /// + /// [`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`]. + /// + /// [`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, + }, + /// 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`]. + /// + /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment + payment_id: PaymentId, + /// The hash that was given to [`ChannelManager::send_payment`]. + /// + /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment + payment_hash: Option, + /// The payment path that was successful. + /// + /// May contain a closed channel if the HTLC sent along the path was fulfilled on chain. + path: Vec, + }, + /// Indicates an outbound HTLC we sent failed, likely due to an intermediary node being unable to + /// handle the HTLC. + /// + /// Note that this does *not* indicate that all paths for an MPP payment have failed, see + /// [`Event::PaymentFailed`]. + /// + /// See [`ChannelManager::abandon_payment`] for giving up on this payment before its retries have + /// been exhausted. + /// + /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment + PaymentPathFailed { + /// The id returned by [`ChannelManager::send_payment`] and used with + /// [`ChannelManager::abandon_payment`]. + /// + /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment + /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment + payment_id: Option, + /// The hash that was given to [`ChannelManager::send_payment`]. + /// + /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment + payment_hash: PaymentHash, + /// 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, the payment may + /// be retried via a different route. + payment_failed_permanently: bool, + /// Extra error details based on the failure type. May contain an update that needs to be + /// applied to the [`NetworkGraph`]. + /// + /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph + failure: PathFailure, + /// The payment path that failed. + path: Vec, + /// The channel responsible for the failed payment path. + /// + /// Note that for route hints or for the first hop in a path this may be an SCID alias and + /// may not refer to a channel in the public network graph. These aliases may also collide + /// with channels in the public network graph. + /// + /// If this is `Some`, then the corresponding channel should be avoided when the payment is + /// retried. May be `None` for older [`Event`] serializations. + short_channel_id: Option, +#[cfg(test)] + error_code: Option, +#[cfg(test)] + error_data: Option>, + }, + /// Indicates that a probe payment we sent returned successful, i.e., only failed at the destination. + ProbeSuccessful { + /// The id returned by [`ChannelManager::send_probe`]. + /// + /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe + payment_id: PaymentId, + /// The hash generated by [`ChannelManager::send_probe`]. + /// + /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe + payment_hash: PaymentHash, + /// The payment path that was successful. + path: Vec, + }, + /// Indicates that a probe payment we sent failed at an intermediary node on the path. + ProbeFailed { + /// The id returned by [`ChannelManager::send_probe`]. + /// + /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe + payment_id: PaymentId, + /// The hash generated by [`ChannelManager::send_probe`]. + /// + /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe + payment_hash: PaymentHash, + /// The payment path that failed. + path: Vec, + /// The channel responsible for the failed probe. + /// + /// Note that for route hints or for the first hop in a path this may be an SCID alias and + /// may not refer to a channel in the public network graph. These aliases may also collide + /// with channels in the public network graph. + short_channel_id: Option, + }, + /// Used to indicate that [`ChannelManager::process_pending_htlc_forwards`] should be called at + /// a time in the future. + /// + /// [`ChannelManager::process_pending_htlc_forwards`]: crate::ln::channelmanager::ChannelManager::process_pending_htlc_forwards + PendingHTLCsForwardable { + /// The minimum amount of time that should be waited prior to calling + /// process_pending_htlc_forwards. To increase the effort required to correlate payments, + /// you should wait a random amount of time in roughly the range (now + time_forwardable, + /// now + 5*time_forwardable). + time_forwardable: Duration, + }, + /// Used to indicate that we've intercepted an HTLC forward. This event will only be generated if + /// you've encoded an intercept scid in the receiver's invoice route hints using + /// [`ChannelManager::get_intercept_scid`] and have set [`UserConfig::accept_intercept_htlcs`]. + /// + /// [`ChannelManager::forward_intercepted_htlc`] or + /// [`ChannelManager::fail_intercepted_htlc`] MUST be called in response to this event. See + /// their docs for more information. + /// + /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid + /// [`UserConfig::accept_intercept_htlcs`]: crate::util::config::UserConfig::accept_intercept_htlcs + /// [`ChannelManager::forward_intercepted_htlc`]: crate::ln::channelmanager::ChannelManager::forward_intercepted_htlc + /// [`ChannelManager::fail_intercepted_htlc`]: crate::ln::channelmanager::ChannelManager::fail_intercepted_htlc + HTLCIntercepted { + /// An id to help LDK identify which HTLC is being forwarded or failed. + intercept_id: InterceptId, + /// The fake scid that was programmed as the next hop's scid, generated using + /// [`ChannelManager::get_intercept_scid`]. + /// + /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid + requested_next_hop_scid: u64, + /// The payment hash used for this HTLC. + payment_hash: PaymentHash, + /// How many msats were received on the inbound edge of this HTLC. + inbound_amount_msat: u64, + /// How many msats the payer intended to route to the next node. Depending on the reason you are + /// intercepting this payment, you might take a fee by forwarding less than this amount. + /// + /// Note that LDK will NOT check that expected fees were factored into this value. You MUST + /// check that whatever fee you want has been included here or subtract it as required. Further, + /// LDK will not stop you from forwarding more than you received. + expected_outbound_amount_msat: u64, + }, + /// Used to indicate that an output which you should know how to spend was confirmed on chain + /// and is now spendable. + /// Such an output will *not* ever be spent by rust-lightning, and are not at risk of your + /// counterparty spending them due to some kind of timeout. Thus, you need to store them + /// somewhere and spend them when you create on-chain transactions. + SpendableOutputs { + /// The outputs which you should store as spendable by you. + outputs: Vec, + }, + /// This event is generated when a payment has been successfully forwarded through us and a + /// forwarding fee earned. + PaymentForwarded { + /// The incoming channel between the previous node and us. This is only `None` for events + /// generated or serialized by versions prior to 0.0.107. + prev_channel_id: Option<[u8; 32]>, + /// 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<[u8; 32]>, + /// The 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 + /// whole satoshi. Thus, the fee calculated here may be higher than expected as we still + /// claimed the full value in millisatoshis from the source. In this case, + /// `claim_from_onchain_tx` will be set. + /// + /// 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 + /// `None`. + fee_earned_msat: Option, + /// If this is `true`, the forwarded HTLC was claimed by our counterparty via an on-chain + /// 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 { + /// 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 + /// 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 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: u128, + /// The reason the channel was closed. + reason: ClosureReason + }, + /// Used to indicate to the user that they can abandon the funding transaction and recycle the + /// inputs for another purpose. + DiscardFunding { + /// The channel_id of the channel which has been closed. + channel_id: [u8; 32], + /// The full transaction received from the user + transaction: Transaction + }, + /// Indicates a request to open a new channel by a peer. + /// + /// To accept the request, call [`ChannelManager::accept_inbound_channel`]. To reject the + /// request, call [`ChannelManager::force_close_without_broadcasting_txn`]. + /// + /// The event is only triggered when a new open channel request is received and the + /// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. + /// + /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel + /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn + /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels + OpenChannelRequest { + /// The temporary channel ID of the channel requested to be opened. + /// + /// When responding to the request, the `temporary_channel_id` should be passed + /// back to the ChannelManager through [`ChannelManager::accept_inbound_channel`] to accept, + /// or through [`ChannelManager::force_close_without_broadcasting_txn`] to reject. + /// + /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel + /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn + temporary_channel_id: [u8; 32], + /// The node_id of the counterparty requesting to open the channel. + /// + /// When responding to the request, the `counterparty_node_id` should be passed + /// back to the `ChannelManager` through [`ChannelManager::accept_inbound_channel`] to + /// accept the request, or through [`ChannelManager::force_close_without_broadcasting_txn`] to reject the + /// request. + /// + /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel + /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn + counterparty_node_id: PublicKey, + /// The channel value of the requested channel. + funding_satoshis: u64, + /// Our starting balance in the channel if the request is accepted, in milli-satoshi. + push_msat: u64, + /// The features that this channel will operate with. If you reject the channel, a + /// well-behaved counterparty may automatically re-attempt the channel with a new set of + /// feature flags. + /// + /// Note that if [`ChannelTypeFeatures::supports_scid_privacy`] returns true on this type, + /// the resulting [`ChannelManager`] will not be readable by versions of LDK prior to + /// 0.0.106. + /// + /// Furthermore, note that if [`ChannelTypeFeatures::supports_zero_conf`] returns true on this type, + /// the resulting [`ChannelManager`] will not be readable by versions of LDK prior to + /// 0.0.107. Channels setting this type also need to get manually accepted via + /// [`crate::ln::channelmanager::ChannelManager::accept_inbound_channel_from_trusted_peer_0conf`], + /// or will be rejected otherwise. + /// + /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager + channel_type: ChannelTypeFeatures, + }, + /// Indicates that the HTLC was accepted, but could not be processed when or after attempting to + /// forward it. + /// + /// Some scenarios where this event may be sent include: + /// * 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 + /// * The HTLC has timed out + /// + /// This event, however, does not get generated if an HTLC fails to meet the forwarding + /// requirements (i.e. insufficient fees paid, or a CLTV that is too soon). + HTLCHandlingFailed { + /// The channel over which the HTLC was received. + prev_channel_id: [u8; 32], + /// 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 { + fn write(&self, writer: &mut W) -> Result<(), io::Error> { + match self { + &Event::FundingGenerationReady { .. } => { + 0u8.write(writer)?; + // 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 } => { + 1u8.write(writer)?; + let mut payment_secret = None; + let payment_preimage; + match &purpose { + PaymentPurpose::InvoicePayment { payment_preimage: preimage, payment_secret: secret } => { + payment_secret = Some(secret); + payment_preimage = *preimage; + }, + PaymentPurpose::SpontaneousPayment(preimage) => { + payment_preimage = Some(*preimage); + } + } + write_tlv_fields!(writer, { + (0, payment_hash, required), + (1, receiver_node_id, option), + (2, payment_secret, option), + (3, via_channel_id, option), + (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 + (8, payment_preimage, option), + }); + }, + &Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => { + 2u8.write(writer)?; + write_tlv_fields!(writer, { + (0, payment_preimage, required), + (1, payment_hash, required), + (3, payment_id, option), + (5, fee_paid_msat, option), + }); + }, + &Event::PaymentPathFailed { + ref payment_id, ref payment_hash, ref payment_failed_permanently, ref failure, + ref path, ref short_channel_id, + #[cfg(test)] + ref error_code, + #[cfg(test)] + ref error_data, + } => { + 3u8.write(writer)?; + #[cfg(test)] + error_code.write(writer)?; + #[cfg(test)] + error_data.write(writer)?; + write_tlv_fields!(writer, { + (0, payment_hash, required), + (1, None::, option), // network_update in LDK versions prior to 0.0.114 + (2, payment_failed_permanently, required), + (3, false, required), // all_paths_failed in LDK versions prior to 0.0.114 + (5, *path, vec_type), + (7, short_channel_id, option), + (9, None::, option), // retry in LDK versions prior to 0.0.115 + (11, payment_id, option), + (13, failure, required), + }); + }, + &Event::PendingHTLCsForwardable { time_forwardable: _ } => { + 4u8.write(writer)?; + // Note that we now ignore these on the read end as we'll re-generate them in + // ChannelManager, we write them here only for backwards compatibility. + }, + &Event::SpendableOutputs { ref outputs } => { + 5u8.write(writer)?; + write_tlv_fields!(writer, { + (0, WithoutLength(outputs), required), + }); + }, + &Event::HTLCIntercepted { requested_next_hop_scid, payment_hash, inbound_amount_msat, expected_outbound_amount_msat, intercept_id } => { + 6u8.write(writer)?; + let intercept_scid = InterceptNextHop::FakeScid { requested_next_hop_scid }; + write_tlv_fields!(writer, { + (0, intercept_id, required), + (2, intercept_scid, required), + (4, payment_hash, required), + (6, inbound_amount_msat, required), + (8, expected_outbound_amount_msat, required), + }); + } + &Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => { + 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), + }); + }, + &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_low, required), + (2, reason, required), + (3, user_channel_id_high, required), + }); + }, + &Event::DiscardFunding { ref channel_id, ref transaction } => { + 11u8.write(writer)?; + write_tlv_fields!(writer, { + (0, channel_id, required), + (2, transaction, required) + }) + }, + &Event::PaymentPathSuccessful { ref payment_id, ref payment_hash, ref path } => { + 13u8.write(writer)?; + write_tlv_fields!(writer, { + (0, payment_id, required), + (2, payment_hash, option), + (4, *path, vec_type) + }) + }, + &Event::PaymentFailed { ref payment_id, ref payment_hash } => { + 15u8.write(writer)?; + write_tlv_fields!(writer, { + (0, payment_id, required), + (2, payment_hash, required), + }) + }, + &Event::OpenChannelRequest { .. } => { + 17u8.write(writer)?; + // 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 } => { + 19u8.write(writer)?; + write_tlv_fields!(writer, { + (0, payment_hash, required), + (1, receiver_node_id, option), + (2, purpose, required), + (4, amount_msat, required), + }); + }, + &Event::ProbeSuccessful { ref payment_id, ref payment_hash, ref path } => { + 21u8.write(writer)?; + write_tlv_fields!(writer, { + (0, payment_id, required), + (2, payment_hash, required), + (4, *path, vec_type) + }) + }, + &Event::ProbeFailed { ref payment_id, ref payment_hash, ref path, ref short_channel_id } => { + 23u8.write(writer)?; + write_tlv_fields!(writer, { + (0, payment_id, required), + (2, payment_hash, required), + (4, *path, vec_type), + (6, short_channel_id, option), + }) + }, + &Event::HTLCHandlingFailed { ref prev_channel_id, ref failed_next_destination } => { + 25u8.write(writer)?; + write_tlv_fields!(writer, { + (0, prev_channel_id, required), + (2, failed_next_destination, required), + }) + }, + #[cfg(anchors)] + &Event::BumpTransaction(ref event)=> { + 27u8.write(writer)?; + match event { + // We never write the ChannelClose|HTLCResolution events as they'll be replayed + // upon restarting anyway if they remain unresolved. + BumpTransactionEvent::ChannelClose { .. } => {} + BumpTransactionEvent::HTLCResolution { .. } => {} + } + write_tlv_fields!(writer, {}); // Write a length field for forwards compat + } + &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`. + } + Ok(()) + } +} +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. + 0u8 => Ok(None), + 1u8 => { + let f = || { + let mut payment_hash = PaymentHash([0; 32]); + let mut payment_preimage = None; + let mut payment_secret = None; + let mut amount_msat = 0; + let mut receiver_node_id = None; + let mut _user_payment_id = None::; // For compatibility with 0.0.103 and earlier + let mut via_channel_id = None; + let mut via_user_channel_id = None; + read_tlv_fields!(reader, { + (0, payment_hash, required), + (1, receiver_node_id, option), + (2, payment_secret, option), + (3, via_channel_id, option), + (4, amount_msat, required), + (5, via_user_channel_id, option), + (6, _user_payment_id, option), + (8, payment_preimage, option), + }); + let purpose = match payment_secret { + Some(secret) => PaymentPurpose::InvoicePayment { + payment_preimage, + payment_secret: secret + }, + None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()), + None => return Err(msgs::DecodeError::InvalidValue), + }; + Ok(Some(Event::PaymentClaimable { + receiver_node_id, + payment_hash, + amount_msat, + purpose, + via_channel_id, + via_user_channel_id, + })) + }; + f() + }, + 2u8 => { + let f = || { + let mut payment_preimage = PaymentPreimage([0; 32]); + let mut payment_hash = None; + let mut payment_id = None; + let mut fee_paid_msat = None; + read_tlv_fields!(reader, { + (0, payment_preimage, required), + (1, payment_hash, option), + (3, payment_id, option), + (5, fee_paid_msat, option), + }); + if payment_hash.is_none() { + payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner())); + } + Ok(Some(Event::PaymentSent { + payment_id, + payment_preimage, + payment_hash: payment_hash.unwrap(), + fee_paid_msat, + })) + }; + f() + }, + 3u8 => { + let f = || { + #[cfg(test)] + let error_code = Readable::read(reader)?; + #[cfg(test)] + let error_data = Readable::read(reader)?; + let mut payment_hash = PaymentHash([0; 32]); + let mut payment_failed_permanently = false; + let mut network_update = None; + let mut path: Option> = Some(vec![]); + let mut short_channel_id = None; + let mut payment_id = None; + let mut failure_opt = None; + read_tlv_fields!(reader, { + (0, payment_hash, required), + (1, network_update, upgradable_option), + (2, payment_failed_permanently, required), + (5, path, vec_type), + (7, short_channel_id, option), + (11, payment_id, option), + (13, failure_opt, upgradable_option), + }); + let failure = failure_opt.unwrap_or_else(|| PathFailure::OnPath { network_update }); + Ok(Some(Event::PaymentPathFailed { + payment_id, + payment_hash, + payment_failed_permanently, + failure, + path: path.unwrap(), + short_channel_id, + #[cfg(test)] + error_code, + #[cfg(test)] + error_data, + })) + }; + f() + }, + 4u8 => Ok(None), + 5u8 => { + let f = || { + let mut outputs = WithoutLength(Vec::new()); + read_tlv_fields!(reader, { + (0, outputs, required), + }); + Ok(Some(Event::SpendableOutputs { outputs: outputs.0 })) + }; + f() + }, + 6u8 => { + let mut payment_hash = PaymentHash([0; 32]); + let mut intercept_id = InterceptId([0; 32]); + let mut requested_next_hop_scid = InterceptNextHop::FakeScid { requested_next_hop_scid: 0 }; + let mut inbound_amount_msat = 0; + let mut expected_outbound_amount_msat = 0; + read_tlv_fields!(reader, { + (0, intercept_id, required), + (2, requested_next_hop_scid, required), + (4, payment_hash, required), + (6, inbound_amount_msat, required), + (8, expected_outbound_amount_msat, required), + }); + let next_scid = match requested_next_hop_scid { + InterceptNextHop::FakeScid { requested_next_hop_scid: scid } => scid + }; + Ok(Some(Event::HTLCIntercepted { + payment_hash, + requested_next_hop_scid: next_scid, + inbound_amount_msat, + expected_outbound_amount_msat, + intercept_id, + })) + }, + 7u8 => { + let f = || { + let mut fee_earned_msat = None; + let mut prev_channel_id = None; + let mut claim_from_onchain_tx = false; + let mut next_channel_id = 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), + }); + Ok(Some(Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id })) + }; + f() + }, + 9u8 => { + let f = || { + let mut channel_id = [0; 32]; + let mut reason = UpgradableRequired(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_low_opt, option), + (2, reason, upgradable_required), + (3, user_channel_id_high_opt, option), + }); + + // `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: _init_tlv_based_struct_field!(reason, upgradable_required) })) + }; + f() + }, + 11u8 => { + let f = || { + let mut channel_id = [0; 32]; + let mut transaction = Transaction{ version: 2, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() }; + read_tlv_fields!(reader, { + (0, channel_id, required), + (2, transaction, required), + }); + Ok(Some(Event::DiscardFunding { channel_id, transaction } )) + }; + f() + }, + 13u8 => { + let f = || { + let mut payment_id = PaymentId([0; 32]); + let mut payment_hash = None; + let mut path: Option> = Some(vec![]); + read_tlv_fields!(reader, { + (0, payment_id, required), + (2, payment_hash, option), + (4, path, vec_type), + }); + Ok(Some(Event::PaymentPathSuccessful { + payment_id, + payment_hash, + path: path.unwrap(), + })) + }; + f() + }, + 15u8 => { + let f = || { + let mut payment_hash = PaymentHash([0; 32]); + let mut payment_id = PaymentId([0; 32]); + read_tlv_fields!(reader, { + (0, payment_id, required), + (2, payment_hash, required), + }); + Ok(Some(Event::PaymentFailed { + payment_id, + payment_hash, + })) + }; + f() + }, + 17u8 => { + // Value 17 is used for `Event::OpenChannelRequest`. + Ok(None) + }, + 19u8 => { + let f = || { + let mut payment_hash = PaymentHash([0; 32]); + let mut purpose = UpgradableRequired(None); + let mut amount_msat = 0; + let mut receiver_node_id = None; + read_tlv_fields!(reader, { + (0, payment_hash, required), + (1, receiver_node_id, option), + (2, purpose, upgradable_required), + (4, amount_msat, required), + }); + Ok(Some(Event::PaymentClaimed { + receiver_node_id, + payment_hash, + purpose: _init_tlv_based_struct_field!(purpose, upgradable_required), + amount_msat, + })) + }; + f() + }, + 21u8 => { + let f = || { + let mut payment_id = PaymentId([0; 32]); + let mut payment_hash = PaymentHash([0; 32]); + let mut path: Option> = Some(vec![]); + read_tlv_fields!(reader, { + (0, payment_id, required), + (2, payment_hash, required), + (4, path, vec_type), + }); + Ok(Some(Event::ProbeSuccessful { + payment_id, + payment_hash, + path: path.unwrap(), + })) + }; + f() + }, + 23u8 => { + let f = || { + let mut payment_id = PaymentId([0; 32]); + let mut payment_hash = PaymentHash([0; 32]); + let mut path: Option> = Some(vec![]); + let mut short_channel_id = None; + read_tlv_fields!(reader, { + (0, payment_id, required), + (2, payment_hash, required), + (4, path, vec_type), + (6, short_channel_id, option), + }); + Ok(Some(Event::ProbeFailed { + payment_id, + payment_hash, + path: path.unwrap(), + short_channel_id, + })) + }; + f() + }, + 25u8 => { + let f = || { + let mut prev_channel_id = [0; 32]; + let mut failed_next_destination_opt = UpgradableRequired(None); + read_tlv_fields!(reader, { + (0, prev_channel_id, required), + (2, failed_next_destination_opt, upgradable_required), + }); + Ok(Some(Event::HTLCHandlingFailed { + prev_channel_id, + failed_next_destination: _init_tlv_based_struct_field!(failed_next_destination_opt, upgradable_required), + })) + }; + 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 = RequiredWrapper(None); + let mut channel_type = RequiredWrapper(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. + x if x % 2 == 1 => { + // If the event is of unknown type, assume it was written with `write_tlv_fields`, + // which prefixes the whole thing with a length BigSize. Because the event is + // odd-type unknown, we should treat it as `Ok(None)` even if it has some TLV + // fields that are even. Thus, we avoid using `read_tlv_fields` and simply read + // exactly the number of bytes specified, ignoring them entirely. + let tlv_len: BigSize = Readable::read(reader)?; + FixedLengthReader::new(reader, tlv_len.0) + .eat_remaining().map_err(|_| msgs::DecodeError::ShortRead)?; + Ok(None) + }, + _ => Err(msgs::DecodeError::InvalidValue) + } + } +} + +/// An event generated by ChannelManager which indicates a message should be sent to a peer (or +/// broadcast to most peers). +/// These events are handled by PeerManager::process_events if you are using a PeerManager. +#[derive(Clone, Debug)] +pub enum MessageSendEvent { + /// Used to indicate that we've accepted a channel open and should send the accept_channel + /// message provided to the given peer. + SendAcceptChannel { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::AcceptChannel, + }, + /// Used to indicate that we've initiated a channel open and should send the open_channel + /// message provided to the given peer. + SendOpenChannel { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::OpenChannel, + }, + /// Used to indicate that a funding_created message should be sent to the peer with the given node_id. + SendFundingCreated { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::FundingCreated, + }, + /// Used to indicate that a funding_signed message should be sent to the peer with the given node_id. + SendFundingSigned { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::FundingSigned, + }, + /// Used to indicate that a channel_ready message should be sent to the peer with the given node_id. + SendChannelReady { + /// The node_id of the node which should receive these message(s) + node_id: PublicKey, + /// The channel_ready message which should be sent. + msg: msgs::ChannelReady, + }, + /// Used to indicate that an announcement_signatures message should be sent to the peer with the given node_id. + SendAnnouncementSignatures { + /// The node_id of the node which should receive these message(s) + node_id: PublicKey, + /// The announcement_signatures message which should be sent. + msg: msgs::AnnouncementSignatures, + }, + /// Used to indicate that a series of HTLC update messages, as well as a commitment_signed + /// message should be sent to the peer with the given node_id. + UpdateHTLCs { + /// The node_id of the node which should receive these message(s) + node_id: PublicKey, + /// The update messages which should be sent. ALL messages in the struct should be sent! + updates: msgs::CommitmentUpdate, + }, + /// Used to indicate that a revoke_and_ack message should be sent to the peer with the given node_id. + SendRevokeAndACK { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::RevokeAndACK, + }, + /// Used to indicate that a closing_signed message should be sent to the peer with the given node_id. + SendClosingSigned { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::ClosingSigned, + }, + /// Used to indicate that a shutdown message should be sent to the peer with the given node_id. + SendShutdown { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The message which should be sent. + msg: msgs::Shutdown, + }, + /// Used to indicate that a channel_reestablish message should be sent to the peer with the given node_id. + SendChannelReestablish { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// 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 + /// 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: Option, + }, + /// Used to indicate that a channel_update should be broadcast to all peers. + BroadcastChannelUpdate { + /// The channel_update which should be sent. + 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 sent to a single peer. + /// In contrast to [`Self::BroadcastChannelUpdate`], this is used when the channel is a + /// private channel and we shouldn't be informing all of our peers of channel parameters. + SendChannelUpdate { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The channel_update which should be sent. + msg: msgs::ChannelUpdate, + }, + /// Broadcast an error downstream to be handled + HandleError { + /// The node_id of the node which should receive this message + node_id: PublicKey, + /// The action which should be taken. + action: msgs::ErrorAction + }, + /// Query a peer for channels with funding transaction UTXOs in a block range. + SendChannelRangeQuery { + /// The node_id of this message recipient + node_id: PublicKey, + /// The query_channel_range which should be sent. + msg: msgs::QueryChannelRange, + }, + /// Request routing gossip messages from a peer for a list of channels identified by + /// their short_channel_ids. + SendShortIdsQuery { + /// The node_id of this message recipient + node_id: PublicKey, + /// The query_short_channel_ids which should be sent. + msg: msgs::QueryShortChannelIds, + }, + /// Sends a reply to a channel range query. This may be one of several SendReplyChannelRange events + /// emitted during processing of the query. + SendReplyChannelRange { + /// The node_id of this message recipient + node_id: PublicKey, + /// The reply_channel_range which should be sent. + msg: msgs::ReplyChannelRange, + }, + /// Sends a timestamp filter for inbound gossip. This should be sent on each new connection to + /// enable receiving gossip messages from the peer. + SendGossipTimestampFilter { + /// The node_id of this message recipient + node_id: PublicKey, + /// The gossip_timestamp_filter which should be sent. + msg: msgs::GossipTimestampFilter, + }, +} + +/// A trait indicating an object may generate message send events +pub trait MessageSendEventsProvider { + /// Gets the list of pending events which were generated by previous actions, clearing the list + /// in the process. + 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`]. +/// +/// 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 +/// 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 +/// may safely use the provider (e.g., see [`ChannelManager::process_pending_events`] and +/// [`ChainMonitor::process_pending_events`]). +/// +/// (C-not implementable) As there is likely no reason for a user to implement this trait on their +/// own type(s). +/// +/// [`process_pending_events`]: Self::process_pending_events +/// [`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. + /// + /// See the trait-level documentation for requirements. + fn process_pending_events(&self, handler: H) where H::Target: EventHandler; +} + +/// 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); +} + +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) { + self.deref().handle_event(event) + } +} diff --git a/lightning/src/lib.rs b/lightning/src/lib.rs index 71f82ed01..ad16914c3 100644 --- a/lightning/src/lib.rs +++ b/lightning/src/lib.rs @@ -81,6 +81,7 @@ pub mod ln; pub mod offers; pub mod routing; pub mod onion_message; +pub mod events; #[cfg(feature = "std")] /// Re-export of either `core2::io` or `std::io`, depending on the `std` feature flag. diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 5a39ef18c..b57f70d79 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -19,12 +19,12 @@ use bitcoin::network::constants::Network; use crate::chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor}; use crate::chain::transaction::OutPoint; use crate::chain::{ChannelMonitorUpdateStatus, Listen, Watch}; +use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose, ClosureReason, HTLCDestination}; use crate::ln::channelmanager::{ChannelManager, RAACommitmentOrder, PaymentSendFailure, PaymentId}; use crate::ln::channel::AnnouncementSigsState; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler}; use crate::util::enforcing_trait_impls::EnforcingSigner; -use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose, ClosureReason, HTLCDestination}; use crate::util::errors::APIError; use crate::util::ser::{ReadableArgs, Writeable}; use crate::util::test_utils::TestBroadcaster; diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 7a389b573..f47046942 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -36,8 +36,8 @@ use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBounde use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::transaction::{OutPoint, TransactionData}; use crate::chain::keysinterface::{WriteableEcdsaChannelSigner, EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient}; +use crate::events::ClosureReason; use crate::routing::gossip::NodeId; -use crate::util::events::ClosureReason; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter}; use crate::util::logger::Logger; use crate::util::errors::APIError; diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 3a0683c96..ad81ad99f 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -35,6 +35,8 @@ use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock}; use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator}; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, MonitorEvent, CLOSED_CHANNEL_UPDATE_ID}; use crate::chain::transaction::{OutPoint, TransactionData}; +use crate::events; +use crate::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination}; // Since this struct is returned in `list_channels` methods, expose it here in case users want to // construct one themselves. use crate::ln::{inbound_payment, PaymentHash, PaymentPreimage, PaymentSecret}; @@ -55,8 +57,6 @@ use crate::ln::outbound_payment::{OutboundPayments, PaymentAttempts, PendingOutb use crate::ln::wire::Encode; use crate::chain::keysinterface::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, ChannelSigner, WriteableEcdsaChannelSigner}; use crate::util::config::{UserConfig, ChannelConfig}; -use crate::util::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination}; -use crate::util::events; use crate::util::wakers::{Future, Notifier}; use crate::util::scid_utils::fake_scid; use crate::util::string::UntrustedString; @@ -1947,7 +1947,7 @@ where /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`]: crate::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal - /// [`SendShutdown`]: crate::util::events::MessageSendEvent::SendShutdown + /// [`SendShutdown`]: crate::events::MessageSendEvent::SendShutdown pub fn close_channel(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey) -> Result<(), APIError> { self.close_channel_internal(channel_id, counterparty_node_id, None) } @@ -1971,7 +1971,7 @@ where /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`]: crate::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal - /// [`SendShutdown`]: crate::util::events::MessageSendEvent::SendShutdown + /// [`SendShutdown`]: crate::events::MessageSendEvent::SendShutdown pub fn close_channel_with_target_feerate(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey, target_feerate_sats_per_1000_weight: u32) -> Result<(), APIError> { self.close_channel_internal(channel_id, counterparty_node_id, Some(target_feerate_sats_per_1000_weight)) } @@ -2845,8 +2845,8 @@ where /// implemented by Bitcoin Core wallet. See /// for more details. /// - /// [`Event::FundingGenerationReady`]: crate::util::events::Event::FundingGenerationReady - /// [`Event::ChannelClosed`]: crate::util::events::Event::ChannelClosed + /// [`Event::FundingGenerationReady`]: crate::events::Event::FundingGenerationReady + /// [`Event::ChannelClosed`]: crate::events::Event::ChannelClosed pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, funding_transaction: Transaction) -> Result<(), APIError> { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); @@ -3905,8 +3905,8 @@ where /// event matches your expectation. If you fail to do so and call this method, you may provide /// the sender "proof-of-payment" when they did not fulfill the full expected payment. /// - /// [`Event::PaymentClaimable`]: crate::util::events::Event::PaymentClaimable - /// [`Event::PaymentClaimed`]: crate::util::events::Event::PaymentClaimed + /// [`Event::PaymentClaimable`]: crate::events::Event::PaymentClaimable + /// [`Event::PaymentClaimed`]: crate::events::Event::PaymentClaimed /// [`process_pending_events`]: EventsProvider::process_pending_events /// [`create_inbound_payment`]: Self::create_inbound_payment /// [`create_inbound_payment_for_hash`]: Self::create_inbound_payment_for_hash @@ -7874,6 +7874,7 @@ mod tests { use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; use core::time::Duration; use core::sync::atomic::Ordering; + use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret}; use crate::ln::channelmanager::{inbound_payment, PaymentId, PaymentSendFailure, InterceptId}; use crate::ln::functional_test_utils::*; @@ -7881,7 +7882,6 @@ mod tests { use crate::ln::msgs::ChannelMessageHandler; use crate::routing::router::{PaymentParameters, RouteParameters, find_route}; use crate::util::errors::APIError; - use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; use crate::util::test_utils; use crate::util::config::ChannelConfig; use crate::chain::keysinterface::EntropySource; @@ -8782,6 +8782,7 @@ pub mod bench { use crate::chain::Listen; use crate::chain::chainmonitor::{ChainMonitor, Persist}; use crate::chain::keysinterface::{EntropySource, KeysManager, InMemorySigner}; + use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider}; use crate::ln::channelmanager::{self, BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId}; use crate::ln::functional_test_utils::*; use crate::ln::msgs::{ChannelMessageHandler, Init}; @@ -8789,7 +8790,6 @@ pub mod bench { use crate::routing::router::{PaymentParameters, get_route}; use crate::util::test_utils; use crate::util::config::UserConfig; - use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider}; use bitcoin::hashes::Hash; use bitcoin::hashes::sha256::Hash as Sha256; diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 51ad65949..0221b1187 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -13,6 +13,7 @@ use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, keysinterface::EntropySource}; use crate::chain::channelmonitor::ChannelMonitor; use crate::chain::transaction::OutPoint; +use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose}; use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret}; use crate::ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA}; use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate}; @@ -20,12 +21,10 @@ use crate::routing::router::{self, PaymentParameters, Route}; use crate::ln::features::InitFeatures; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler,RoutingMessageHandler}; -use crate::util::events::ClosureReason; use crate::util::enforcing_trait_impls::EnforcingSigner; use crate::util::scid_utils; use crate::util::test_utils; use crate::util::test_utils::{panicking, TestChainMonitor, TestScorer, TestKeysInterface}; -use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose}; use crate::util::errors::APIError; use crate::util::config::UserConfig; use crate::util::ser::{ReadableArgs, Writeable}; @@ -1412,8 +1411,8 @@ macro_rules! expect_htlc_handling_failed_destinations { ($events: expr, $expected_failures: expr) => {{ for event in $events { match event { - $crate::util::events::Event::PendingHTLCsForwardable { .. } => { }, - $crate::util::events::Event::HTLCHandlingFailed { ref failed_next_destination, .. } => { + $crate::events::Event::PendingHTLCsForwardable { .. } => { }, + $crate::events::Event::HTLCHandlingFailed { ref failed_next_destination, .. } => { assert!($expected_failures.contains(&failed_next_destination)) }, _ => panic!("Unexpected destination"), @@ -1579,7 +1578,7 @@ pub fn do_commitment_signed_dance(node_a: &Node<'_, '_, '_>, node_b: &Node<'_, ' if fail_backwards { expect_pending_htlcs_forwardable_and_htlc_handling_failed!(node_a, - vec![crate::util::events::HTLCDestination::NextHopChannel{ node_id: Some(node_b.node.get_our_node_id()), channel_id: commitment_signed.channel_id }]); + vec![crate::events::HTLCDestination::NextHopChannel{ node_id: Some(node_b.node.get_our_node_id()), channel_id: commitment_signed.channel_id }]); check_added_monitors!(node_a, 1); let node_a_per_peer_state = node_a.node.per_peer_state.read().unwrap(); @@ -1675,12 +1674,12 @@ macro_rules! expect_payment_claimable { let events = $node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - $crate::util::events::Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, receiver_node_id, via_channel_id: _, via_user_channel_id: _ } => { + $crate::events::Event::PaymentClaimable { ref payment_hash, ref purpose, amount_msat, receiver_node_id, via_channel_id: _, via_user_channel_id: _ } => { assert_eq!($expected_payment_hash, *payment_hash); assert_eq!($expected_recv_value, amount_msat); assert_eq!($expected_receiver_node_id, receiver_node_id.unwrap()); match purpose { - $crate::util::events::PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => { + $crate::events::PaymentPurpose::InvoicePayment { payment_preimage, payment_secret, .. } => { assert_eq!(&$expected_payment_preimage, payment_preimage); assert_eq!($expected_payment_secret, *payment_secret); }, @@ -1699,7 +1698,7 @@ macro_rules! expect_payment_claimed { let events = $node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - $crate::util::events::Event::PaymentClaimed { ref payment_hash, amount_msat, .. } => { + $crate::events::Event::PaymentClaimed { ref payment_hash, amount_msat, .. } => { assert_eq!($expected_payment_hash, *payment_hash); assert_eq!($expected_recv_value, amount_msat); }, @@ -1738,7 +1737,7 @@ macro_rules! expect_payment_sent { assert_eq!(events.len(), 1); } let expected_payment_id = match events[0] { - $crate::util::events::Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => { + $crate::events::Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => { assert_eq!($expected_payment_preimage, *payment_preimage); assert_eq!(expected_payment_hash, *payment_hash); assert!(fee_paid_msat.is_some()); @@ -1752,7 +1751,7 @@ macro_rules! expect_payment_sent { if $expect_paths { for i in 1..events.len() { match events[i] { - $crate::util::events::Event::PaymentPathSuccessful { payment_id, payment_hash, .. } => { + $crate::events::Event::PaymentPathSuccessful { payment_id, payment_hash, .. } => { assert_eq!(payment_id, expected_payment_id); assert_eq!(payment_hash, Some(expected_payment_hash)); }, @@ -1770,7 +1769,7 @@ macro_rules! expect_payment_path_successful { let events = $node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - $crate::util::events::Event::PaymentPathSuccessful { .. } => {}, + $crate::events::Event::PaymentPathSuccessful { .. } => {}, _ => panic!("Unexpected event"), } } @@ -1804,7 +1803,7 @@ pub fn expect_channel_ready_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, ex let events = node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - crate::util::events::Event::ChannelReady{ ref counterparty_node_id, .. } => { + crate::events::Event::ChannelReady{ ref counterparty_node_id, .. } => { assert_eq!(*expected_counterparty_node_id, *counterparty_node_id); }, _ => panic!("Unexpected event"), diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index ac0ba0ba8..265bd49ac 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -18,6 +18,7 @@ use crate::chain::channelmonitor; use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY}; use crate::chain::transaction::OutPoint; use crate::chain::keysinterface::{ChannelSigner, EcdsaChannelSigner, EntropySource}; +use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination}; use crate::ln::{PaymentPreimage, PaymentSecret, PaymentHash}; use crate::ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT}; use crate::ln::channelmanager::{self, PaymentId, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA}; @@ -31,7 +32,6 @@ use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction}; use crate::util::enforcing_trait_impls::EnforcingSigner; use crate::util::test_utils; -use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination}; use crate::util::errors::APIError; use crate::util::ser::{Writeable, ReadableArgs}; use crate::util::string::UntrustedString; diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index 3bd50293f..820a4c7fd 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -16,6 +16,9 @@ use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS; use crate::chain::channelmonitor::{ANTI_REORG_DELAY, Balance}; use crate::chain::transaction::OutPoint; use crate::chain::chaininterface::LowerBoundedFeeEstimator; +#[cfg(anchors)] +use crate::events::BumpTransactionEvent; +use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination}; use crate::ln::channel; #[cfg(anchors)] use crate::ln::chan_utils; @@ -28,9 +31,6 @@ use crate::util::config::UserConfig; #[cfg(anchors)] use crate::util::crypto::sign; #[cfg(anchors)] -use crate::util::events::BumpTransactionEvent; -use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination}; -#[cfg(anchors)] use crate::util::ser::Writeable; #[cfg(anchors)] use crate::util::test_utils; diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 6e49a46f0..6b85320b7 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -40,7 +40,7 @@ use core::fmt::Debug; use crate::io::{self, Read}; use crate::io_extras::read_to_end; -use crate::util::events::{MessageSendEventsProvider, OnionMessageProvider}; +use crate::events::{MessageSendEventsProvider, OnionMessageProvider}; use crate::util::logger; use crate::util::ser::{LengthReadable, Readable, ReadableArgs, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname}; diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index 36e9ddb06..a6fff59fd 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -13,6 +13,7 @@ use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient}; +use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure}; use crate::ln::{PaymentHash, PaymentSecret}; use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS; use crate::ln::channelmanager::{HTLCForwardInfo, FailureCode, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingAddHTLCInfo, PendingHTLCInfo, PendingHTLCRouting, PaymentId}; @@ -23,7 +24,6 @@ use crate::ln::features::{InitFeatures, InvoiceFeatures}; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, ChannelUpdate}; use crate::ln::wire::Encode; -use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure}; use crate::util::ser::{Writeable, Writer}; use crate::util::test_utils; use crate::util::config::{UserConfig, ChannelConfig}; diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index 6ede956b7..5326d33bc 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -14,12 +14,12 @@ use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::secp256k1::{self, Secp256k1, SecretKey}; use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient}; +use crate::events; use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; use crate::ln::channelmanager::{ChannelDetails, HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, PaymentId}; use crate::ln::onion_utils::HTLCFailReason; use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, RoutePath, Router}; use crate::util::errors::APIError; -use crate::util::events; use crate::util::logger::Logger; use crate::util::time::Time; #[cfg(all(not(feature = "no-std"), test))] @@ -314,8 +314,8 @@ impl Display for PaymentAttemptsUsingTime { /// may be surfaced later via [`Event::PaymentPathFailed`] and [`Event::PaymentFailed`]. /// /// [`ChannelManager::send_payment_with_retry`]: crate::ln::channelmanager::ChannelManager::send_payment_with_retry -/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed -/// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed +/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed +/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed #[derive(Clone, Debug)] pub enum RetryableSendFailure { /// The provided [`PaymentParameters::expiry_time`] indicated that the payment has expired. Note @@ -329,8 +329,8 @@ pub enum RetryableSendFailure { /// yet completed (i.e. generated an [`Event::PaymentSent`] or [`Event::PaymentFailed`]). /// /// [`PaymentId`]: crate::ln::channelmanager::PaymentId - /// [`Event::PaymentSent`]: crate::util::events::Event::PaymentSent - /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed + /// [`Event::PaymentSent`]: crate::events::Event::PaymentSent + /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed DuplicatePayment, } @@ -349,8 +349,8 @@ pub enum PaymentSendFailure { /// Because the payment failed outright, no payment tracking is done and no /// [`Event::PaymentPathFailed`] or [`Event::PaymentFailed`] events will be generated. /// - /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed - /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed + /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed + /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed ParameterError(APIError), /// A parameter in a single path which was passed to send_payment was invalid, preventing us /// from attempting to send the payment at all. @@ -363,8 +363,8 @@ pub enum PaymentSendFailure { /// The results here are ordered the same as the paths in the route object which was passed to /// send_payment. /// - /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed - /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed + /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed + /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed PathParameterError(Vec>), /// All paths which were attempted failed to send, with no channel state change taking place. /// You can freely resend the payment in full (though you probably want to do so over different @@ -373,15 +373,15 @@ pub enum PaymentSendFailure { /// Because the payment failed outright, no payment tracking is done and no /// [`Event::PaymentPathFailed`] or [`Event::PaymentFailed`] events will be generated. /// - /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed - /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed + /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed + /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed AllFailedResendSafe(Vec), /// Indicates that a payment for the provided [`PaymentId`] is already in-flight and has not /// yet completed (i.e. generated an [`Event::PaymentSent`] or [`Event::PaymentFailed`]). /// /// [`PaymentId`]: crate::ln::channelmanager::PaymentId - /// [`Event::PaymentSent`]: crate::util::events::Event::PaymentSent - /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed + /// [`Event::PaymentSent`]: crate::events::Event::PaymentSent + /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed DuplicatePayment, /// Some paths that were attempted failed to send, though some paths may have succeeded. At least /// some paths have irrevocably committed to the HTLC. @@ -567,8 +567,8 @@ impl OutboundPayments { /// Errors immediately on [`RetryableSendFailure`] error conditions. Otherwise, further errors may /// be surfaced asynchronously via [`Event::PaymentPathFailed`] and [`Event::PaymentFailed`]. /// - /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed - /// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed + /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed + /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed fn send_payment_internal( &self, payment_id: PaymentId, payment_hash: PaymentHash, payment_secret: &Option, keysend_preimage: Option, retry_strategy: Retry, route_params: RouteParameters, @@ -1313,6 +1313,7 @@ mod tests { use bitcoin::network::constants::Network; use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; + use crate::events::{Event, PathFailure}; use crate::ln::PaymentHash; use crate::ln::channelmanager::PaymentId; use crate::ln::features::{ChannelFeatures, NodeFeatures}; @@ -1322,7 +1323,6 @@ mod tests { use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters}; use crate::sync::{Arc, Mutex}; use crate::util::errors::APIError; - use crate::util::events::{Event, PathFailure}; use crate::util::test_utils; #[test] diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index 29972c901..c0c037fdb 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -15,6 +15,7 @@ use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch}; use crate::chain::channelmonitor::{ANTI_REORG_DELAY, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::keysinterface::EntropySource; use crate::chain::transaction::OutPoint; +use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure}; use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS; use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS, RecentPaymentDetails}; use crate::ln::features::InvoiceFeatures; @@ -24,7 +25,6 @@ use crate::ln::outbound_payment::Retry; use crate::routing::gossip::{EffectiveCapacity, RoutingFees}; use crate::routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RouteParameters}; use crate::routing::scoring::ChannelUsage; -use crate::util::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure}; use crate::util::test_utils; use crate::util::errors::APIError; use crate::util::ser::Writeable; @@ -934,7 +934,7 @@ fn successful_probe_yields_event() { let mut events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events.drain(..).next().unwrap() { - crate::util::events::Event::ProbeSuccessful { payment_id: ev_pid, payment_hash: ev_ph, .. } => { + crate::events::Event::ProbeSuccessful { payment_id: ev_pid, payment_hash: ev_ph, .. } => { assert_eq!(payment_id, ev_pid); assert_eq!(payment_hash, ev_ph); }, @@ -980,7 +980,7 @@ fn failed_probe_yields_event() { let mut events = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events.drain(..).next().unwrap() { - crate::util::events::Event::ProbeFailed { payment_id: ev_pid, payment_hash: ev_ph, .. } => { + crate::events::Event::ProbeFailed { payment_id: ev_pid, payment_hash: ev_ph, .. } => { assert_eq!(payment_id, ev_pid); assert_eq!(payment_hash, ev_ph); }, @@ -1414,7 +1414,7 @@ fn do_test_intercepted_payment(test: InterceptTest) { let events = nodes[1].node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); let (intercept_id, expected_outbound_amount_msat) = match events[0] { - crate::util::events::Event::HTLCIntercepted { + crate::events::Event::HTLCIntercepted { intercept_id, expected_outbound_amount_msat, payment_hash: pmt_hash, inbound_amount_msat, requested_next_hop_scid: short_channel_id } => { assert_eq!(pmt_hash, payment_hash); diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 913ece646..352eb763f 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -18,6 +18,7 @@ use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey}; use crate::chain::keysinterface::{KeysManager, NodeSigner, Recipient}; +use crate::events::{MessageSendEvent, MessageSendEventsProvider, OnionMessageProvider}; use crate::ln::features::{InitFeatures, NodeFeatures}; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, OnionMessageHandler, RoutingMessageHandler}; @@ -29,7 +30,6 @@ use crate::ln::wire::Encode; use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger}; use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId}; use crate::util::atomic_counter::AtomicCounter; -use crate::util::events::{MessageSendEvent, MessageSendEventsProvider, OnionMessageProvider}; use crate::util::logger::Logger; use crate::prelude::*; @@ -2194,11 +2194,11 @@ fn is_gossip_msg(type_id: u16) -> bool { #[cfg(test)] mod tests { use crate::chain::keysinterface::{NodeSigner, Recipient}; + use crate::events; use crate::ln::peer_channel_encryptor::PeerChannelEncryptor; use crate::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler, filter_addresses}; use crate::ln::{msgs, wire}; use crate::ln::msgs::NetAddress; - use crate::util::events; use crate::util::test_utils; use bitcoin::secp256k1::SecretKey; @@ -2349,7 +2349,7 @@ mod tests { if peers[0].read_event(&mut fd_a, &b_data).is_err() { break; } cfgs[0].chan_handler.pending_events.lock().unwrap() - .push(crate::util::events::MessageSendEvent::SendShutdown { + .push(crate::events::MessageSendEvent::SendShutdown { node_id: peers[1].node_signer.get_node_id(Recipient::Node).unwrap(), msg: msgs::Shutdown { channel_id: [0; 32], @@ -2357,7 +2357,7 @@ mod tests { }, }); cfgs[1].chan_handler.pending_events.lock().unwrap() - .push(crate::util::events::MessageSendEvent::SendShutdown { + .push(crate::events::MessageSendEvent::SendShutdown { node_id: peers[0].node_signer.get_node_id(Recipient::Node).unwrap(), msg: msgs::Shutdown { channel_id: [0; 32], diff --git a/lightning/src/ln/priv_short_conf_tests.rs b/lightning/src/ln/priv_short_conf_tests.rs index 330eee8be..6d1df42d1 100644 --- a/lightning/src/ln/priv_short_conf_tests.rs +++ b/lightning/src/ln/priv_short_conf_tests.rs @@ -13,6 +13,7 @@ use crate::chain::ChannelMonitorUpdateStatus; use crate::chain::keysinterface::NodeSigner; +use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider}; use crate::ln::channelmanager::{ChannelManager, MIN_CLTV_EXPIRY_DELTA, PaymentId}; use crate::routing::gossip::RoutingFees; use crate::routing::router::{PaymentParameters, RouteHint, RouteHintHop}; @@ -20,7 +21,6 @@ use crate::ln::features::ChannelTypeFeatures; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ChannelUpdate, ErrorAction}; use crate::ln::wire::Encode; -use crate::util::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider}; use crate::util::config::UserConfig; use crate::util::ser::Writeable; use crate::util::test_utils; diff --git a/lightning/src/ln/reload_tests.rs b/lightning/src/ln/reload_tests.rs index 2380eed78..bdd327382 100644 --- a/lightning/src/ln/reload_tests.rs +++ b/lightning/src/ln/reload_tests.rs @@ -14,13 +14,13 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator; use crate::chain::channelmonitor::ChannelMonitor; use crate::chain::keysinterface::EntropySource; use crate::chain::transaction::OutPoint; +use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider}; use crate::ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, PaymentId}; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction}; use crate::util::enforcing_trait_impls::EnforcingSigner; use crate::util::test_utils; use crate::util::errors::APIError; -use crate::util::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider}; use crate::util::ser::{Writeable, ReadableArgs}; use crate::util::config::UserConfig; use crate::util::string::UntrustedString; diff --git a/lightning/src/ln/reorg_tests.rs b/lightning/src/ln/reorg_tests.rs index 6af8acc1c..1a159bf32 100644 --- a/lightning/src/ln/reorg_tests.rs +++ b/lightning/src/ln/reorg_tests.rs @@ -12,9 +12,9 @@ use crate::chain::channelmonitor::ANTI_REORG_DELAY; use crate::chain::transaction::OutPoint; use crate::chain::Confirm; +use crate::events::{Event, MessageSendEventsProvider, ClosureReason, HTLCDestination}; use crate::ln::channelmanager::ChannelManager; use crate::ln::msgs::{ChannelMessageHandler, Init}; -use crate::util::events::{Event, MessageSendEventsProvider, ClosureReason, HTLCDestination}; use crate::util::test_utils; use crate::util::ser::Writeable; use crate::util::string::UntrustedString; diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index 6616ed9bf..6e7c0e12e 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -11,6 +11,7 @@ use crate::chain::keysinterface::{EntropySource, SignerProvider}; use crate::chain::transaction::OutPoint; +use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; use crate::ln::channelmanager::{self, PaymentSendFailure, PaymentId}; use crate::routing::router::{PaymentParameters, get_route}; use crate::ln::msgs; @@ -18,7 +19,6 @@ use crate::ln::msgs::{ChannelMessageHandler, ErrorAction}; use crate::ln::script::ShutdownScript; use crate::util::test_utils; use crate::util::test_utils::OnGetShutdownScriptpubkey; -use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; use crate::util::errors::APIError; use crate::util::config::UserConfig; use crate::util::string::UntrustedString; diff --git a/lightning/src/onion_message/messenger.rs b/lightning/src/onion_message/messenger.rs index 7814ccb65..64c3215ea 100644 --- a/lightning/src/onion_message/messenger.rs +++ b/lightning/src/onion_message/messenger.rs @@ -16,6 +16,7 @@ use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey}; use crate::chain::keysinterface::{EntropySource, KeysManager, NodeSigner, Recipient}; +use crate::events::OnionMessageProvider; use crate::ln::features::{InitFeatures, NodeFeatures}; use crate::ln::msgs::{self, OnionMessageHandler}; use crate::ln::onion_utils; @@ -24,7 +25,6 @@ use super::blinded_path::{BlindedPath, ForwardTlvs, ReceiveTlvs}; pub use super::packet::{CustomOnionMessageContents, OnionMessageContents}; use super::packet::{BIG_PACKET_HOP_DATA_LEN, ForwardControlTlvs, Packet, Payload, ReceiveControlTlvs, SMALL_PACKET_HOP_DATA_LEN}; use super::utils; -use crate::util::events::OnionMessageProvider; use crate::util::logger::Logger; use crate::util::ser::Writeable; diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index 513ff1a22..99d100513 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -21,6 +21,7 @@ use bitcoin::hash_types::BlockHash; use bitcoin::network::constants::Network; use bitcoin::blockdata::constants::genesis_block; +use crate::events::{MessageSendEvent, MessageSendEventsProvider}; use crate::ln::features::{ChannelFeatures, NodeFeatures, InitFeatures}; use crate::ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHandler, NetAddress, MAX_VALUE_MSAT}; use crate::ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, GossipTimestampFilter}; @@ -29,7 +30,6 @@ use crate::ln::msgs; use crate::routing::utxo::{self, UtxoLookup}; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, MaybeReadable}; use crate::util::logger::{Logger, Level}; -use crate::util::events::{MessageSendEvent, MessageSendEventsProvider}; use crate::util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK}; use crate::util::string::PrintableString; use crate::util::indexed_map::{IndexedMap, Entry as IndexedMapEntry}; @@ -310,7 +310,7 @@ where U::Target: UtxoLookup, L::Target: Logger impl NetworkGraph where L::Target: Logger { /// Handles any network updates originating from [`Event`]s. /// - /// [`Event`]: crate::util::events::Event + /// [`Event`]: crate::events::Event pub fn handle_network_update(&self, network_update: &NetworkUpdate) { match *network_update { NetworkUpdate::ChannelUpdateMessage { ref msg } => { @@ -1957,6 +1957,7 @@ impl ReadOnlyNetworkGraph<'_> { #[cfg(test)] pub(crate) mod tests { + use crate::events::{MessageSendEvent, MessageSendEventsProvider}; use crate::ln::channelmanager; use crate::ln::chan_utils::make_funding_redeemscript; #[cfg(feature = "std")] @@ -1969,7 +1970,6 @@ pub(crate) mod tests { use crate::util::config::UserConfig; use crate::util::test_utils; use crate::util::ser::{ReadableArgs, Readable, Writeable}; - use crate::util::events::{MessageSendEvent, MessageSendEventsProvider}; use crate::util::scid_utils::scid_from_parts; use crate::routing::gossip::REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS; diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index baa2ecce1..aadec563b 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -255,7 +255,7 @@ pub struct Route { /// This is used by `ChannelManager` to track information which may be required for retries, /// provided back to you via [`Event::PaymentPathFailed`]. /// - /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed + /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed pub payment_params: Option, } @@ -340,7 +340,7 @@ impl Readable for Route { /// Passed to [`find_route`] and [`build_route_from_hops`], but also provided in /// [`Event::PaymentPathFailed`]. /// -/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed +/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed #[derive(Clone, Debug, PartialEq, Eq)] pub struct RouteParameters { /// The parameters of the failed payment path. @@ -983,7 +983,7 @@ fn default_node_features() -> NodeFeatures { /// [`ChannelManager::list_usable_channels`] will never include such channels. /// /// [`ChannelManager::list_usable_channels`]: crate::ln::channelmanager::ChannelManager::list_usable_channels -/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed +/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph pub fn find_route( our_node_pubkey: &PublicKey, route_params: &RouteParameters, diff --git a/lightning/src/routing/utxo.rs b/lightning/src/routing/utxo.rs index 74abd4276..43338a159 100644 --- a/lightning/src/routing/utxo.rs +++ b/lightning/src/routing/utxo.rs @@ -16,10 +16,10 @@ use bitcoin::{BlockHash, TxOut}; use bitcoin::hashes::hex::ToHex; +use crate::events::MessageSendEvent; use crate::ln::chan_utils::make_funding_redeemscript_from_slices; use crate::ln::msgs::{self, LightningError, ErrorAction}; use crate::routing::gossip::{NetworkGraph, NodeId, P2PGossipSync}; -use crate::util::events::MessageSendEvent; use crate::util::logger::{Level, Logger}; use crate::util::ser::Writeable; diff --git a/lightning/src/util/config.rs b/lightning/src/util/config.rs index b32e8660d..ec34f5322 100644 --- a/lightning/src/util/config.rs +++ b/lightning/src/util/config.rs @@ -523,7 +523,7 @@ pub struct UserConfig { /// /// Default value: false. /// - /// [`Event::OpenChannelRequest`]: crate::util::events::Event::OpenChannelRequest + /// [`Event::OpenChannelRequest`]: crate::events::Event::OpenChannelRequest /// [`msgs::OpenChannel`]: crate::ln::msgs::OpenChannel /// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel pub manually_accept_inbound_channels: bool, @@ -536,7 +536,7 @@ pub struct UserConfig { /// Default value: false. /// /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid - /// [`Event::HTLCIntercepted`]: crate::util::events::Event::HTLCIntercepted + /// [`Event::HTLCIntercepted`]: crate::events::Event::HTLCIntercepted pub accept_intercept_htlcs: bool, } diff --git a/lightning/src/util/enforcing_trait_impls.rs b/lightning/src/util/enforcing_trait_impls.rs index 1f7b5221c..8ae661a65 100644 --- a/lightning/src/util/enforcing_trait_impls.rs +++ b/lightning/src/util/enforcing_trait_impls.rs @@ -24,7 +24,7 @@ use bitcoin::secp256k1; use bitcoin::secp256k1::{SecretKey, PublicKey}; use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature}; #[cfg(anchors)] -use crate::util::events::HTLCDescriptor; +use crate::events::HTLCDescriptor; use crate::util::ser::{Writeable, Writer}; use crate::io::Error; diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs deleted file mode 100644 index 43a2ae02c..000000000 --- a/lightning/src/util/events.rs +++ /dev/null @@ -1,1746 +0,0 @@ -// This file is Copyright its original authors, visible in version control -// history. -// -// This file is licensed under the Apache License, Version 2.0 or the MIT license -// , at your option. -// You may not use this file except in accordance with one or both of these -// licenses. - -//! Events are returned from various bits in the library which indicate some action must be taken -//! by the client. -//! -//! Because we don't have a built-in runtime, it's up to the client to call events at a time in the -//! future, as well as generate and broadcast funding transactions handle payment preimages and a -//! few other things. - -use crate::chain::keysinterface::SpendableOutputDescriptor; -#[cfg(anchors)] -use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment}; -use crate::ln::channelmanager::{InterceptId, PaymentId}; -use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS; -use crate::ln::features::ChannelTypeFeatures; -use crate::ln::msgs; -use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret}; -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::{RouteHop, RouteParameters}; - -use bitcoin::{PackedLockTime, Transaction}; -#[cfg(anchors)] -use bitcoin::{OutPoint, Txid, TxIn, TxOut, Witness}; -use bitcoin::blockdata::script::Script; -use bitcoin::hashes::Hash; -use bitcoin::hashes::sha256::Hash as Sha256; -use bitcoin::secp256k1::PublicKey; -#[cfg(anchors)] -use bitcoin::secp256k1::{self, Secp256k1}; -#[cfg(anchors)] -use bitcoin::secp256k1::ecdsa::Signature; -use crate::io; -use crate::prelude::*; -use core::time::Duration; -use core::ops::Deref; -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. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum PaymentPurpose { - /// Information for receiving a payment that we generated an invoice for. - InvoicePayment { - /// The preimage to the payment_hash, if the payment hash (and secret) were fetched via - /// [`ChannelManager::create_inbound_payment`]. If provided, this can be handed directly to - /// [`ChannelManager::claim_funds`]. - /// - /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment - /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds - payment_preimage: Option, - /// The "payment secret". This authenticates the sender to the recipient, preventing a - /// number of deanonymization attacks during the routing process. - /// It is provided here for your reference, however its accuracy is enforced directly by - /// [`ChannelManager`] using the values you previously provided to - /// [`ChannelManager::create_inbound_payment`] or - /// [`ChannelManager::create_inbound_payment_for_hash`]. - /// - /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager - /// [`ChannelManager::create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment - /// [`ChannelManager::create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash - payment_secret: PaymentSecret, - }, - /// Because this is a spontaneous payment, the payer generated their own preimage rather than us - /// (the payee) providing a preimage. - SpontaneousPayment(PaymentPreimage), -} - -impl_writeable_tlv_based_enum!(PaymentPurpose, - (0, InvoicePayment) => { - (0, payment_preimage, option), - (2, payment_secret, required), - }; - (2, SpontaneousPayment) -); - -/// When the payment path failure took place and extra details about it. [`PathFailure::OnPath`] may -/// contain a [`NetworkUpdate`] that needs to be applied to the [`NetworkGraph`]. -/// -/// [`NetworkUpdate`]: crate::routing::gossip::NetworkUpdate -/// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum PathFailure { - /// We failed to initially send the payment and no HTLC was committed to. Contains the relevant - /// error. - InitialSend { - /// The error surfaced from initial send. - err: APIError, - }, - /// A hop on the path failed to forward our payment. - OnPath { - /// If present, this [`NetworkUpdate`] should be applied to the [`NetworkGraph`] so that routing - /// decisions can take into account the update. - /// - /// [`NetworkUpdate`]: crate::routing::gossip::NetworkUpdate - /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph - network_update: Option, - }, -} - -impl_writeable_tlv_based_enum_upgradable!(PathFailure, - (0, OnPath) => { - (0, network_update, upgradable_option), - }, - (2, InitialSend) => { - (0, err, upgradable_required), - }, -); - -#[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. - /// - /// Our counterparty may have broadcasted their latest commitment state, and we have - /// as well. - CounterpartyForceClosed { - /// The error which the peer sent us. - /// - /// Be careful about printing the peer_msg, a well-crafted message could exploit - /// a security vulnerability in the terminal emulator or the logging subsystem. - /// To be safe, use `Display` on `UntrustedString` - /// - /// [`UntrustedString`]: crate::util::string::UntrustedString - peer_msg: UntrustedString, - }, - /// Closure generated from [`ChannelManager::force_close_channel`], called by the user. - /// - /// [`ChannelManager::force_close_channel`]: crate::ln::channelmanager::ChannelManager::force_close_channel. - HolderForceClosed, - /// 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. - //TODO: split between CounterpartyInitiated/LocallyInitiated - CooperativeClosure, - /// A commitment transaction was confirmed on chain, closing the channel. Most likely this - /// commitment transaction came from our counterparty, but it may also have come from - /// a copy of our own `ChannelMonitor`. - CommitmentTxConfirmed, - /// The funding transaction failed to confirm in a timely manner on an inbound channel. - FundingTimedOut, - /// Closure generated from processing an event, likely a HTLC forward/relay/reception. - ProcessingError { - /// A developer-readable error message which we generated. - err: String, - }, - /// 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. - /// - /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor - /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager - OutdatedChannelManager -} - -impl core::fmt::Display for ClosureReason { - fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { - f.write_str("Channel closed because ")?; - match self { - ClosureReason::CounterpartyForceClosed { peer_msg } => { - f.write_fmt(format_args!("counterparty force-closed with message: {}", peer_msg)) - }, - ClosureReason::HolderForceClosed => f.write_str("user manually force-closed the channel"), - ClosureReason::CooperativeClosure => f.write_str("the channel was cooperatively closed"), - ClosureReason::CommitmentTxConfirmed => f.write_str("commitment or closing transaction was confirmed on chain."), - ClosureReason::FundingTimedOut => write!(f, "funding transaction failed to confirm within {} blocks", FUNDING_CONF_DEADLINE_BLOCKS), - ClosureReason::ProcessingError { err } => { - f.write_str("of an exception: ")?; - f.write_str(&err) - }, - 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)"), - } - } -} - -impl_writeable_tlv_based_enum_upgradable!(ClosureReason, - (0, CounterpartyForceClosed) => { (1, peer_msg, required) }, - (1, FundingTimedOut) => {}, - (2, HolderForceClosed) => {}, - (6, CommitmentTxConfirmed) => {}, - (4, CooperativeClosure) => {}, - (8, ProcessingError) => { (1, err, required) }, - (10, DisconnectedPeer) => {}, - (12, OutdatedChannelManager) => {}, -); - -/// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`]. -#[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. - NextHopChannel { - /// The `node_id` of the next node. For backwards compatibility, this field is - /// marked as optional, versions prior to 0.0.110 may not always be able to provide - /// counterparty node information. - node_id: Option, - /// The outgoing `channel_id` between us and the next node. - channel_id: [u8; 32], - }, - /// Scenario where we are unsure of the next node to forward the HTLC to. - UnknownNextHop { - /// Short channel id we are requesting to forward an HTLC to. - requested_forward_scid: u64, - }, - /// We couldn't forward to the outgoing scid. An example would be attempting to send a duplicate - /// intercept HTLC. - InvalidForward { - /// Short channel id we are requesting to forward an HTLC to. - requested_forward_scid: u64 - }, - /// Failure scenario where an HTLC may have been forwarded to be intended for us, - /// but is invalid for some reason, so we reject it. - /// - /// Some of the reasons may include: - /// * HTLC Timeouts - /// * Expected MPP amount to claim does not equal HTLC total - /// * Claimable amount does not match expected amount - FailedPayment { - /// The payment hash of the payment we attempted to process. - payment_hash: PaymentHash - }, -} - -impl_writeable_tlv_based_enum_upgradable!(HTLCDestination, - (0, NextHopChannel) => { - (0, node_id, required), - (2, channel_id, required), - }, - (1, InvalidForward) => { - (0, requested_forward_scid, required), - }, - (2, UnknownNextHop) => { - (0, requested_forward_scid, required), - }, - (4, FailedPayment) => { - (0, payment_hash, required), - }, -); - -#[cfg(anchors)] -/// A descriptor used to sign for a commitment transaction's anchor output. -#[derive(Clone, Debug, PartialEq, Eq)] -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)] -/// A descriptor used to sign for a commitment transaction's HTLC output. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct HTLCDescriptor { - /// 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 necessary channel parameters that need to be provided to the re-derived - /// [`InMemorySigner`] through [`ChannelSigner::provide_channel_parameters`]. - /// - /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner - /// [`ChannelSigner::provide_channel_parameters`]: crate::chain::keysinterface::ChannelSigner::provide_channel_parameters - pub channel_parameters: ChannelTransactionParameters, - /// The txid of the commitment transaction in which the HTLC output lives. - pub commitment_txid: Txid, - /// The number of the commitment transaction in which the HTLC output lives. - pub per_commitment_number: u64, - /// The details of the HTLC as it appears in the commitment transaction. - pub htlc: HTLCOutputInCommitment, - /// The preimage, if `Some`, to claim the HTLC output with. If `None`, the timeout path must be - /// taken. - pub preimage: Option, - /// The counterparty's signature required to spend the HTLC output. - pub counterparty_sig: Signature -} - -#[cfg(anchors)] -impl HTLCDescriptor { - /// Returns the unsigned transaction input spending the HTLC output in the commitment - /// transaction. - pub fn unsigned_tx_input(&self) -> TxIn { - chan_utils::build_htlc_input(&self.commitment_txid, &self.htlc, true /* opt_anchors */) - } - - /// Returns the delayed output created as a result of spending the HTLC output in the commitment - /// transaction. - pub fn tx_output( - &self, per_commitment_point: &PublicKey, secp: &Secp256k1 - ) -> TxOut { - let channel_params = self.channel_parameters.as_holder_broadcastable(); - let broadcaster_keys = channel_params.broadcaster_pubkeys(); - let counterparty_keys = channel_params.countersignatory_pubkeys(); - let broadcaster_delayed_key = chan_utils::derive_public_key( - secp, per_commitment_point, &broadcaster_keys.delayed_payment_basepoint - ); - let counterparty_revocation_key = chan_utils::derive_public_revocation_key( - secp, per_commitment_point, &counterparty_keys.revocation_basepoint - ); - chan_utils::build_htlc_output( - 0 /* feerate_per_kw */, channel_params.contest_delay(), &self.htlc, true /* opt_anchors */, - false /* use_non_zero_fee_anchors */, &broadcaster_delayed_key, &counterparty_revocation_key - ) - } - - /// Returns the witness script of the HTLC output in the commitment transaction. - pub fn witness_script( - &self, per_commitment_point: &PublicKey, secp: &Secp256k1 - ) -> Script { - let channel_params = self.channel_parameters.as_holder_broadcastable(); - let broadcaster_keys = channel_params.broadcaster_pubkeys(); - let counterparty_keys = channel_params.countersignatory_pubkeys(); - let broadcaster_htlc_key = chan_utils::derive_public_key( - secp, per_commitment_point, &broadcaster_keys.htlc_basepoint - ); - let counterparty_htlc_key = chan_utils::derive_public_key( - secp, per_commitment_point, &counterparty_keys.htlc_basepoint - ); - let counterparty_revocation_key = chan_utils::derive_public_revocation_key( - secp, per_commitment_point, &counterparty_keys.revocation_basepoint - ); - chan_utils::get_htlc_redeemscript_with_explicit_keys( - &self.htlc, true /* opt_anchors */, &broadcaster_htlc_key, &counterparty_htlc_key, - &counterparty_revocation_key, - ) - } - - /// Returns the fully signed witness required to spend the HTLC output in the commitment - /// transaction. - pub fn tx_input_witness(&self, signature: &Signature, witness_script: &Script) -> Witness { - chan_utils::build_htlc_input_witness( - signature, &self.counterparty_sig, &self.preimage, witness_script, true /* opt_anchors */ - ) - } -} - -#[cfg(anchors)] -/// Represents the different types of transactions, originating from LDK, to be bumped. -#[derive(Clone, Debug, PartialEq, Eq)] -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 broadcast 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`]. The - /// anchor input signature can be computed with [`EcdsaChannelSigner::sign_holder_anchor_input`], - /// which can then be provided to [`build_anchor_input_witness`] along with the `funding_pubkey` - /// to obtain the full witness required to spend. - /// - /// 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 - /// [`EcdsaChannelSigner::sign_holder_anchor_input`]: crate::chain::keysinterface::EcdsaChannelSigner::sign_holder_anchor_input - /// [`build_anchor_input_witness`]: crate::ln::chan_utils::build_anchor_input_witness - 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, - }, - /// Indicates that a channel featuring anchor outputs has unilaterally closed on-chain by a - /// holder commitment transaction and its HTLC(s) need to be resolved on-chain. With the - /// zero-HTLC-transaction-fee variant of anchor outputs, the pre-signed HTLC - /// transactions have a zero fee, thus requiring additional inputs and/or outputs to be attached - /// for a timely confirmation within the chain. These additional inputs and/or outputs must be - /// appended to the resulting HTLC transaction to meet the target feerate. Failure to meet the - /// target feerate decreases the confirmation odds of the transaction, possibly resulting in a - /// loss of funds. Once the transaction meets the target feerate, it must be signed for and - /// broadcast by the consumer of the event. - /// - /// The consumer should be able to sign for any of the non-HTLC inputs added to the resulting - /// HTLC transaction. To sign HTLC inputs, an [`InMemorySigner`] should be re-derived through - /// [`KeysManager::derive_channel_keys`] with the help of `channel_keys_id` and - /// `channel_value_satoshis`. Each HTLC input's signature can be computed with - /// [`EcdsaChannelSigner::sign_holder_htlc_transaction`], which can then be provided to - /// [`HTLCDescriptor::tx_input_witness`] to obtain the fully signed witness required to spend. - /// - /// It is possible to receive more than one instance of this event if a valid HTLC 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 HTLC 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 either they are no - /// longer able to commit external confirmed funds to the HTLC transaction or the fee committed - /// to the HTLC transaction is greater in value than the HTLCs being claimed. - /// - /// [`InMemorySigner`]: crate::chain::keysinterface::InMemorySigner - /// [`KeysManager::derive_channel_keys`]: crate::chain::keysinterface::KeysManager::derive_channel_keys - /// [`EcdsaChannelSigner::sign_holder_htlc_transaction`]: crate::chain::keysinterface::EcdsaChannelSigner::sign_holder_htlc_transaction - /// [`HTLCDescriptor::tx_input_witness`]: HTLCDescriptor::tx_input_witness - HTLCResolution { - /// The target feerate that the resulting HTLC transaction must meet. - target_feerate_sat_per_1000_weight: u32, - /// The set of pending HTLCs on the confirmed commitment that need to be claimed, preferably - /// by the same transaction. - htlc_descriptors: Vec, - }, -} - -/// Will be used in [`Event::HTLCIntercepted`] to identify the next hop in the HTLC's path. -/// Currently only used in serialization for the sake of maintaining compatibility. More variants -/// will be added for general-purpose HTLC forward intercepts as well as trampoline forward -/// intercepts in upcoming work. -enum InterceptNextHop { - FakeScid { - requested_next_hop_scid: u64, - }, -} - -impl_writeable_tlv_based_enum!(InterceptNextHop, - (0, FakeScid) => { - (0, requested_next_hop_scid, required), - }; -); - -/// 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 -/// them directly as they don't round-trip exactly (for example FundingGenerationReady is never -/// written as it makes no sense to respond to it after reconnecting to peers). -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum Event { - /// Used to indicate that the client should generate a funding transaction with the given - /// parameters and then call [`ChannelManager::funding_transaction_generated`]. - /// Generated in [`ChannelManager`] message handling. - /// Note that *all inputs* in the funding transaction must spend SegWit outputs or your - /// counterparty can steal your funds! - /// - /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager - /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated - FundingGenerationReady { - /// The random channel_id we picked which you'll need to pass into - /// [`ChannelManager::funding_transaction_generated`]. - /// - /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated - temporary_channel_id: [u8; 32], - /// The counterparty's node_id, which you'll need to pass back into - /// [`ChannelManager::funding_transaction_generated`]. - /// - /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated - counterparty_node_id: PublicKey, - /// 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, - /// 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: u128, - }, - /// Indicates that we've been offered a payment and it needs to be claimed via calling - /// [`ChannelManager::claim_funds`] with the preimage given in [`PaymentPurpose`]. - /// - /// Note that if the preimage is not known, you should call - /// [`ChannelManager::fail_htlc_backwards`] or [`ChannelManager::fail_htlc_backwards_with_reason`] - /// to free up resources for this HTLC and avoid network congestion. - /// If you fail to call either [`ChannelManager::claim_funds`], [`ChannelManager::fail_htlc_backwards`], - /// or [`ChannelManager::fail_htlc_backwards_with_reason`] within the HTLC's timeout, the HTLC will be - /// automatically failed. - /// - /// # Note - /// LDK will not stop an inbound payment from being paid multiple times, so multiple - /// `PaymentClaimable` events may be generated for the same payment. - /// - /// # Note - /// This event used to be called `PaymentReceived` in LDK versions 0.0.112 and earlier. - /// - /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds - /// [`ChannelManager::fail_htlc_backwards`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards - /// [`ChannelManager::fail_htlc_backwards_with_reason`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards_with_reason - PaymentClaimable { - /// The node that will receive the payment after it has been claimed. - /// This is useful to identify payments received via [phantom nodes]. - /// This field will always be filled in when the event was generated by LDK versions - /// 0.0.113 and above. - /// - /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager - receiver_node_id: Option, - /// The hash for which the preimage should be handed to the ChannelManager. Note that LDK will - /// not stop you from registering duplicate payment hashes for inbound payments. - payment_hash: PaymentHash, - /// The value, in thousandths of a satoshi, that this payment is for. - amount_msat: u64, - /// Information for claiming this received payment, based on whether the purpose of the - /// payment is to pay an invoice or to send a spontaneous payment. - purpose: PaymentPurpose, - /// The `channel_id` indicating over which channel we received the payment. - via_channel_id: Option<[u8; 32]>, - /// The `user_channel_id` indicating over which channel we received the payment. - via_user_channel_id: Option, - }, - /// Indicates a payment has been claimed and we've received money! - /// - /// This most likely occurs when [`ChannelManager::claim_funds`] has been called in response - /// to an [`Event::PaymentClaimable`]. However, if we previously crashed during a - /// [`ChannelManager::claim_funds`] call you may see this event without a corresponding - /// [`Event::PaymentClaimable`] event. - /// - /// # Note - /// LDK will not stop an inbound payment from being paid multiple times, so multiple - /// `PaymentClaimable` events may be generated for the same payment. If you then call - /// [`ChannelManager::claim_funds`] twice for the same [`Event::PaymentClaimable`] you may get - /// multiple `PaymentClaimed` events. - /// - /// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds - PaymentClaimed { - /// The node that received the payment. - /// This is useful to identify payments which were received via [phantom nodes]. - /// This field will always be filled in when the event was generated by LDK versions - /// 0.0.113 and above. - /// - /// [phantom nodes]: crate::chain::keysinterface::PhantomKeysManager - receiver_node_id: Option, - /// The payment hash of the claimed payment. Note that LDK will not stop you from - /// registering duplicate payment hashes for inbound payments. - payment_hash: PaymentHash, - /// The value, in thousandths of a satoshi, that this payment is for. - amount_msat: u64, - /// The purpose of the claimed payment, i.e. whether the payment was for an invoice or a - /// spontaneous payment. - purpose: PaymentPurpose, - }, - /// 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). - /// - /// 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`]. - /// - /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment - payment_id: Option, - /// The preimage to the hash given to ChannelManager::send_payment. - /// Note that this serves as a payment receipt, if you wish to have such a thing, you must - /// store it somehow! - payment_preimage: PaymentPreimage, - /// The hash that was given to [`ChannelManager::send_payment`]. - /// - /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment - payment_hash: PaymentHash, - /// The total fee which was spent at intermediate hops in this payment, across all paths. - /// - /// Note that, like [`Route::get_total_fees`] this does *not* include any potential - /// overpayment to the recipient node. - /// - /// If the recipient or an intermediate node misbehaves and gives us free money, this may - /// overstate the amount paid, though this is unlikely. - /// - /// [`Route::get_total_fees`]: crate::routing::router::Route::get_total_fees - fee_paid_msat: Option, - }, - /// Indicates an outbound payment failed. Individual [`Event::PaymentPathFailed`] events - /// provide failure information for each path attempt in the payment, including retries. - /// - /// This event is provided once there are no further pending HTLCs for the payment and the - /// payment is no longer retryable, due either to the [`Retry`] provided or - /// [`ChannelManager::abandon_payment`] having been called for the corresponding payment. - /// - /// [`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`]. - /// - /// [`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, - }, - /// 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`]. - /// - /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment - payment_id: PaymentId, - /// The hash that was given to [`ChannelManager::send_payment`]. - /// - /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment - payment_hash: Option, - /// The payment path that was successful. - /// - /// May contain a closed channel if the HTLC sent along the path was fulfilled on chain. - path: Vec, - }, - /// Indicates an outbound HTLC we sent failed, likely due to an intermediary node being unable to - /// handle the HTLC. - /// - /// Note that this does *not* indicate that all paths for an MPP payment have failed, see - /// [`Event::PaymentFailed`]. - /// - /// See [`ChannelManager::abandon_payment`] for giving up on this payment before its retries have - /// been exhausted. - /// - /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment - PaymentPathFailed { - /// The id returned by [`ChannelManager::send_payment`] and used with - /// [`ChannelManager::abandon_payment`]. - /// - /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment - /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment - payment_id: Option, - /// The hash that was given to [`ChannelManager::send_payment`]. - /// - /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment - payment_hash: PaymentHash, - /// 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, the payment may - /// be retried via a different route. - payment_failed_permanently: bool, - /// Extra error details based on the failure type. May contain an update that needs to be - /// applied to the [`NetworkGraph`]. - /// - /// [`NetworkGraph`]: crate::routing::gossip::NetworkGraph - failure: PathFailure, - /// The payment path that failed. - path: Vec, - /// The channel responsible for the failed payment path. - /// - /// Note that for route hints or for the first hop in a path this may be an SCID alias and - /// may not refer to a channel in the public network graph. These aliases may also collide - /// with channels in the public network graph. - /// - /// If this is `Some`, then the corresponding channel should be avoided when the payment is - /// retried. May be `None` for older [`Event`] serializations. - short_channel_id: Option, -#[cfg(test)] - error_code: Option, -#[cfg(test)] - error_data: Option>, - }, - /// Indicates that a probe payment we sent returned successful, i.e., only failed at the destination. - ProbeSuccessful { - /// The id returned by [`ChannelManager::send_probe`]. - /// - /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe - payment_id: PaymentId, - /// The hash generated by [`ChannelManager::send_probe`]. - /// - /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe - payment_hash: PaymentHash, - /// The payment path that was successful. - path: Vec, - }, - /// Indicates that a probe payment we sent failed at an intermediary node on the path. - ProbeFailed { - /// The id returned by [`ChannelManager::send_probe`]. - /// - /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe - payment_id: PaymentId, - /// The hash generated by [`ChannelManager::send_probe`]. - /// - /// [`ChannelManager::send_probe`]: crate::ln::channelmanager::ChannelManager::send_probe - payment_hash: PaymentHash, - /// The payment path that failed. - path: Vec, - /// The channel responsible for the failed probe. - /// - /// Note that for route hints or for the first hop in a path this may be an SCID alias and - /// may not refer to a channel in the public network graph. These aliases may also collide - /// with channels in the public network graph. - short_channel_id: Option, - }, - /// Used to indicate that [`ChannelManager::process_pending_htlc_forwards`] should be called at - /// a time in the future. - /// - /// [`ChannelManager::process_pending_htlc_forwards`]: crate::ln::channelmanager::ChannelManager::process_pending_htlc_forwards - PendingHTLCsForwardable { - /// The minimum amount of time that should be waited prior to calling - /// process_pending_htlc_forwards. To increase the effort required to correlate payments, - /// you should wait a random amount of time in roughly the range (now + time_forwardable, - /// now + 5*time_forwardable). - time_forwardable: Duration, - }, - /// Used to indicate that we've intercepted an HTLC forward. This event will only be generated if - /// you've encoded an intercept scid in the receiver's invoice route hints using - /// [`ChannelManager::get_intercept_scid`] and have set [`UserConfig::accept_intercept_htlcs`]. - /// - /// [`ChannelManager::forward_intercepted_htlc`] or - /// [`ChannelManager::fail_intercepted_htlc`] MUST be called in response to this event. See - /// their docs for more information. - /// - /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid - /// [`UserConfig::accept_intercept_htlcs`]: crate::util::config::UserConfig::accept_intercept_htlcs - /// [`ChannelManager::forward_intercepted_htlc`]: crate::ln::channelmanager::ChannelManager::forward_intercepted_htlc - /// [`ChannelManager::fail_intercepted_htlc`]: crate::ln::channelmanager::ChannelManager::fail_intercepted_htlc - HTLCIntercepted { - /// An id to help LDK identify which HTLC is being forwarded or failed. - intercept_id: InterceptId, - /// The fake scid that was programmed as the next hop's scid, generated using - /// [`ChannelManager::get_intercept_scid`]. - /// - /// [`ChannelManager::get_intercept_scid`]: crate::ln::channelmanager::ChannelManager::get_intercept_scid - requested_next_hop_scid: u64, - /// The payment hash used for this HTLC. - payment_hash: PaymentHash, - /// How many msats were received on the inbound edge of this HTLC. - inbound_amount_msat: u64, - /// How many msats the payer intended to route to the next node. Depending on the reason you are - /// intercepting this payment, you might take a fee by forwarding less than this amount. - /// - /// Note that LDK will NOT check that expected fees were factored into this value. You MUST - /// check that whatever fee you want has been included here or subtract it as required. Further, - /// LDK will not stop you from forwarding more than you received. - expected_outbound_amount_msat: u64, - }, - /// Used to indicate that an output which you should know how to spend was confirmed on chain - /// and is now spendable. - /// Such an output will *not* ever be spent by rust-lightning, and are not at risk of your - /// counterparty spending them due to some kind of timeout. Thus, you need to store them - /// somewhere and spend them when you create on-chain transactions. - SpendableOutputs { - /// The outputs which you should store as spendable by you. - outputs: Vec, - }, - /// This event is generated when a payment has been successfully forwarded through us and a - /// forwarding fee earned. - PaymentForwarded { - /// The incoming channel between the previous node and us. This is only `None` for events - /// generated or serialized by versions prior to 0.0.107. - prev_channel_id: Option<[u8; 32]>, - /// 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<[u8; 32]>, - /// The 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 - /// whole satoshi. Thus, the fee calculated here may be higher than expected as we still - /// claimed the full value in millisatoshis from the source. In this case, - /// `claim_from_onchain_tx` will be set. - /// - /// 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 - /// `None`. - fee_earned_msat: Option, - /// If this is `true`, the forwarded HTLC was claimed by our counterparty via an on-chain - /// 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 { - /// 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 - /// 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 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: u128, - /// The reason the channel was closed. - reason: ClosureReason - }, - /// Used to indicate to the user that they can abandon the funding transaction and recycle the - /// inputs for another purpose. - DiscardFunding { - /// The channel_id of the channel which has been closed. - channel_id: [u8; 32], - /// The full transaction received from the user - transaction: Transaction - }, - /// Indicates a request to open a new channel by a peer. - /// - /// To accept the request, call [`ChannelManager::accept_inbound_channel`]. To reject the - /// request, call [`ChannelManager::force_close_without_broadcasting_txn`]. - /// - /// The event is only triggered when a new open channel request is received and the - /// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. - /// - /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel - /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn - /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels - OpenChannelRequest { - /// The temporary channel ID of the channel requested to be opened. - /// - /// When responding to the request, the `temporary_channel_id` should be passed - /// back to the ChannelManager through [`ChannelManager::accept_inbound_channel`] to accept, - /// or through [`ChannelManager::force_close_without_broadcasting_txn`] to reject. - /// - /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel - /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn - temporary_channel_id: [u8; 32], - /// The node_id of the counterparty requesting to open the channel. - /// - /// When responding to the request, the `counterparty_node_id` should be passed - /// back to the `ChannelManager` through [`ChannelManager::accept_inbound_channel`] to - /// accept the request, or through [`ChannelManager::force_close_without_broadcasting_txn`] to reject the - /// request. - /// - /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel - /// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn - counterparty_node_id: PublicKey, - /// The channel value of the requested channel. - funding_satoshis: u64, - /// Our starting balance in the channel if the request is accepted, in milli-satoshi. - push_msat: u64, - /// The features that this channel will operate with. If you reject the channel, a - /// well-behaved counterparty may automatically re-attempt the channel with a new set of - /// feature flags. - /// - /// Note that if [`ChannelTypeFeatures::supports_scid_privacy`] returns true on this type, - /// the resulting [`ChannelManager`] will not be readable by versions of LDK prior to - /// 0.0.106. - /// - /// Furthermore, note that if [`ChannelTypeFeatures::supports_zero_conf`] returns true on this type, - /// the resulting [`ChannelManager`] will not be readable by versions of LDK prior to - /// 0.0.107. Channels setting this type also need to get manually accepted via - /// [`crate::ln::channelmanager::ChannelManager::accept_inbound_channel_from_trusted_peer_0conf`], - /// or will be rejected otherwise. - /// - /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager - channel_type: ChannelTypeFeatures, - }, - /// Indicates that the HTLC was accepted, but could not be processed when or after attempting to - /// forward it. - /// - /// Some scenarios where this event may be sent include: - /// * 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 - /// * The HTLC has timed out - /// - /// This event, however, does not get generated if an HTLC fails to meet the forwarding - /// requirements (i.e. insufficient fees paid, or a CLTV that is too soon). - HTLCHandlingFailed { - /// The channel over which the HTLC was received. - prev_channel_id: [u8; 32], - /// 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 { - fn write(&self, writer: &mut W) -> Result<(), io::Error> { - match self { - &Event::FundingGenerationReady { .. } => { - 0u8.write(writer)?; - // 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 } => { - 1u8.write(writer)?; - let mut payment_secret = None; - let payment_preimage; - match &purpose { - PaymentPurpose::InvoicePayment { payment_preimage: preimage, payment_secret: secret } => { - payment_secret = Some(secret); - payment_preimage = *preimage; - }, - PaymentPurpose::SpontaneousPayment(preimage) => { - payment_preimage = Some(*preimage); - } - } - write_tlv_fields!(writer, { - (0, payment_hash, required), - (1, receiver_node_id, option), - (2, payment_secret, option), - (3, via_channel_id, option), - (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 - (8, payment_preimage, option), - }); - }, - &Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash, ref fee_paid_msat } => { - 2u8.write(writer)?; - write_tlv_fields!(writer, { - (0, payment_preimage, required), - (1, payment_hash, required), - (3, payment_id, option), - (5, fee_paid_msat, option), - }); - }, - &Event::PaymentPathFailed { - ref payment_id, ref payment_hash, ref payment_failed_permanently, ref failure, - ref path, ref short_channel_id, - #[cfg(test)] - ref error_code, - #[cfg(test)] - ref error_data, - } => { - 3u8.write(writer)?; - #[cfg(test)] - error_code.write(writer)?; - #[cfg(test)] - error_data.write(writer)?; - write_tlv_fields!(writer, { - (0, payment_hash, required), - (1, None::, option), // network_update in LDK versions prior to 0.0.114 - (2, payment_failed_permanently, required), - (3, false, required), // all_paths_failed in LDK versions prior to 0.0.114 - (5, *path, vec_type), - (7, short_channel_id, option), - (9, None::, option), // retry in LDK versions prior to 0.0.115 - (11, payment_id, option), - (13, failure, required), - }); - }, - &Event::PendingHTLCsForwardable { time_forwardable: _ } => { - 4u8.write(writer)?; - // Note that we now ignore these on the read end as we'll re-generate them in - // ChannelManager, we write them here only for backwards compatibility. - }, - &Event::SpendableOutputs { ref outputs } => { - 5u8.write(writer)?; - write_tlv_fields!(writer, { - (0, WithoutLength(outputs), required), - }); - }, - &Event::HTLCIntercepted { requested_next_hop_scid, payment_hash, inbound_amount_msat, expected_outbound_amount_msat, intercept_id } => { - 6u8.write(writer)?; - let intercept_scid = InterceptNextHop::FakeScid { requested_next_hop_scid }; - write_tlv_fields!(writer, { - (0, intercept_id, required), - (2, intercept_scid, required), - (4, payment_hash, required), - (6, inbound_amount_msat, required), - (8, expected_outbound_amount_msat, required), - }); - } - &Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => { - 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), - }); - }, - &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_low, required), - (2, reason, required), - (3, user_channel_id_high, required), - }); - }, - &Event::DiscardFunding { ref channel_id, ref transaction } => { - 11u8.write(writer)?; - write_tlv_fields!(writer, { - (0, channel_id, required), - (2, transaction, required) - }) - }, - &Event::PaymentPathSuccessful { ref payment_id, ref payment_hash, ref path } => { - 13u8.write(writer)?; - write_tlv_fields!(writer, { - (0, payment_id, required), - (2, payment_hash, option), - (4, *path, vec_type) - }) - }, - &Event::PaymentFailed { ref payment_id, ref payment_hash } => { - 15u8.write(writer)?; - write_tlv_fields!(writer, { - (0, payment_id, required), - (2, payment_hash, required), - }) - }, - &Event::OpenChannelRequest { .. } => { - 17u8.write(writer)?; - // 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 } => { - 19u8.write(writer)?; - write_tlv_fields!(writer, { - (0, payment_hash, required), - (1, receiver_node_id, option), - (2, purpose, required), - (4, amount_msat, required), - }); - }, - &Event::ProbeSuccessful { ref payment_id, ref payment_hash, ref path } => { - 21u8.write(writer)?; - write_tlv_fields!(writer, { - (0, payment_id, required), - (2, payment_hash, required), - (4, *path, vec_type) - }) - }, - &Event::ProbeFailed { ref payment_id, ref payment_hash, ref path, ref short_channel_id } => { - 23u8.write(writer)?; - write_tlv_fields!(writer, { - (0, payment_id, required), - (2, payment_hash, required), - (4, *path, vec_type), - (6, short_channel_id, option), - }) - }, - &Event::HTLCHandlingFailed { ref prev_channel_id, ref failed_next_destination } => { - 25u8.write(writer)?; - write_tlv_fields!(writer, { - (0, prev_channel_id, required), - (2, failed_next_destination, required), - }) - }, - #[cfg(anchors)] - &Event::BumpTransaction(ref event)=> { - 27u8.write(writer)?; - match event { - // We never write the ChannelClose|HTLCResolution events as they'll be replayed - // upon restarting anyway if they remain unresolved. - BumpTransactionEvent::ChannelClose { .. } => {} - BumpTransactionEvent::HTLCResolution { .. } => {} - } - write_tlv_fields!(writer, {}); // Write a length field for forwards compat - } - &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`. - } - Ok(()) - } -} -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. - 0u8 => Ok(None), - 1u8 => { - let f = || { - let mut payment_hash = PaymentHash([0; 32]); - let mut payment_preimage = None; - let mut payment_secret = None; - let mut amount_msat = 0; - let mut receiver_node_id = None; - let mut _user_payment_id = None::; // For compatibility with 0.0.103 and earlier - let mut via_channel_id = None; - let mut via_user_channel_id = None; - read_tlv_fields!(reader, { - (0, payment_hash, required), - (1, receiver_node_id, option), - (2, payment_secret, option), - (3, via_channel_id, option), - (4, amount_msat, required), - (5, via_user_channel_id, option), - (6, _user_payment_id, option), - (8, payment_preimage, option), - }); - let purpose = match payment_secret { - Some(secret) => PaymentPurpose::InvoicePayment { - payment_preimage, - payment_secret: secret - }, - None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()), - None => return Err(msgs::DecodeError::InvalidValue), - }; - Ok(Some(Event::PaymentClaimable { - receiver_node_id, - payment_hash, - amount_msat, - purpose, - via_channel_id, - via_user_channel_id, - })) - }; - f() - }, - 2u8 => { - let f = || { - let mut payment_preimage = PaymentPreimage([0; 32]); - let mut payment_hash = None; - let mut payment_id = None; - let mut fee_paid_msat = None; - read_tlv_fields!(reader, { - (0, payment_preimage, required), - (1, payment_hash, option), - (3, payment_id, option), - (5, fee_paid_msat, option), - }); - if payment_hash.is_none() { - payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner())); - } - Ok(Some(Event::PaymentSent { - payment_id, - payment_preimage, - payment_hash: payment_hash.unwrap(), - fee_paid_msat, - })) - }; - f() - }, - 3u8 => { - let f = || { - #[cfg(test)] - let error_code = Readable::read(reader)?; - #[cfg(test)] - let error_data = Readable::read(reader)?; - let mut payment_hash = PaymentHash([0; 32]); - let mut payment_failed_permanently = false; - let mut network_update = None; - let mut path: Option> = Some(vec![]); - let mut short_channel_id = None; - let mut payment_id = None; - let mut failure_opt = None; - read_tlv_fields!(reader, { - (0, payment_hash, required), - (1, network_update, upgradable_option), - (2, payment_failed_permanently, required), - (5, path, vec_type), - (7, short_channel_id, option), - (11, payment_id, option), - (13, failure_opt, upgradable_option), - }); - let failure = failure_opt.unwrap_or_else(|| PathFailure::OnPath { network_update }); - Ok(Some(Event::PaymentPathFailed { - payment_id, - payment_hash, - payment_failed_permanently, - failure, - path: path.unwrap(), - short_channel_id, - #[cfg(test)] - error_code, - #[cfg(test)] - error_data, - })) - }; - f() - }, - 4u8 => Ok(None), - 5u8 => { - let f = || { - let mut outputs = WithoutLength(Vec::new()); - read_tlv_fields!(reader, { - (0, outputs, required), - }); - Ok(Some(Event::SpendableOutputs { outputs: outputs.0 })) - }; - f() - }, - 6u8 => { - let mut payment_hash = PaymentHash([0; 32]); - let mut intercept_id = InterceptId([0; 32]); - let mut requested_next_hop_scid = InterceptNextHop::FakeScid { requested_next_hop_scid: 0 }; - let mut inbound_amount_msat = 0; - let mut expected_outbound_amount_msat = 0; - read_tlv_fields!(reader, { - (0, intercept_id, required), - (2, requested_next_hop_scid, required), - (4, payment_hash, required), - (6, inbound_amount_msat, required), - (8, expected_outbound_amount_msat, required), - }); - let next_scid = match requested_next_hop_scid { - InterceptNextHop::FakeScid { requested_next_hop_scid: scid } => scid - }; - Ok(Some(Event::HTLCIntercepted { - payment_hash, - requested_next_hop_scid: next_scid, - inbound_amount_msat, - expected_outbound_amount_msat, - intercept_id, - })) - }, - 7u8 => { - let f = || { - let mut fee_earned_msat = None; - let mut prev_channel_id = None; - let mut claim_from_onchain_tx = false; - let mut next_channel_id = 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), - }); - Ok(Some(Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id })) - }; - f() - }, - 9u8 => { - let f = || { - let mut channel_id = [0; 32]; - let mut reason = UpgradableRequired(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_low_opt, option), - (2, reason, upgradable_required), - (3, user_channel_id_high_opt, option), - }); - - // `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: _init_tlv_based_struct_field!(reason, upgradable_required) })) - }; - f() - }, - 11u8 => { - let f = || { - let mut channel_id = [0; 32]; - let mut transaction = Transaction{ version: 2, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() }; - read_tlv_fields!(reader, { - (0, channel_id, required), - (2, transaction, required), - }); - Ok(Some(Event::DiscardFunding { channel_id, transaction } )) - }; - f() - }, - 13u8 => { - let f = || { - let mut payment_id = PaymentId([0; 32]); - let mut payment_hash = None; - let mut path: Option> = Some(vec![]); - read_tlv_fields!(reader, { - (0, payment_id, required), - (2, payment_hash, option), - (4, path, vec_type), - }); - Ok(Some(Event::PaymentPathSuccessful { - payment_id, - payment_hash, - path: path.unwrap(), - })) - }; - f() - }, - 15u8 => { - let f = || { - let mut payment_hash = PaymentHash([0; 32]); - let mut payment_id = PaymentId([0; 32]); - read_tlv_fields!(reader, { - (0, payment_id, required), - (2, payment_hash, required), - }); - Ok(Some(Event::PaymentFailed { - payment_id, - payment_hash, - })) - }; - f() - }, - 17u8 => { - // Value 17 is used for `Event::OpenChannelRequest`. - Ok(None) - }, - 19u8 => { - let f = || { - let mut payment_hash = PaymentHash([0; 32]); - let mut purpose = UpgradableRequired(None); - let mut amount_msat = 0; - let mut receiver_node_id = None; - read_tlv_fields!(reader, { - (0, payment_hash, required), - (1, receiver_node_id, option), - (2, purpose, upgradable_required), - (4, amount_msat, required), - }); - Ok(Some(Event::PaymentClaimed { - receiver_node_id, - payment_hash, - purpose: _init_tlv_based_struct_field!(purpose, upgradable_required), - amount_msat, - })) - }; - f() - }, - 21u8 => { - let f = || { - let mut payment_id = PaymentId([0; 32]); - let mut payment_hash = PaymentHash([0; 32]); - let mut path: Option> = Some(vec![]); - read_tlv_fields!(reader, { - (0, payment_id, required), - (2, payment_hash, required), - (4, path, vec_type), - }); - Ok(Some(Event::ProbeSuccessful { - payment_id, - payment_hash, - path: path.unwrap(), - })) - }; - f() - }, - 23u8 => { - let f = || { - let mut payment_id = PaymentId([0; 32]); - let mut payment_hash = PaymentHash([0; 32]); - let mut path: Option> = Some(vec![]); - let mut short_channel_id = None; - read_tlv_fields!(reader, { - (0, payment_id, required), - (2, payment_hash, required), - (4, path, vec_type), - (6, short_channel_id, option), - }); - Ok(Some(Event::ProbeFailed { - payment_id, - payment_hash, - path: path.unwrap(), - short_channel_id, - })) - }; - f() - }, - 25u8 => { - let f = || { - let mut prev_channel_id = [0; 32]; - let mut failed_next_destination_opt = UpgradableRequired(None); - read_tlv_fields!(reader, { - (0, prev_channel_id, required), - (2, failed_next_destination_opt, upgradable_required), - }); - Ok(Some(Event::HTLCHandlingFailed { - prev_channel_id, - failed_next_destination: _init_tlv_based_struct_field!(failed_next_destination_opt, upgradable_required), - })) - }; - 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 = RequiredWrapper(None); - let mut channel_type = RequiredWrapper(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. - x if x % 2 == 1 => { - // If the event is of unknown type, assume it was written with `write_tlv_fields`, - // which prefixes the whole thing with a length BigSize. Because the event is - // odd-type unknown, we should treat it as `Ok(None)` even if it has some TLV - // fields that are even. Thus, we avoid using `read_tlv_fields` and simply read - // exactly the number of bytes specified, ignoring them entirely. - let tlv_len: BigSize = Readable::read(reader)?; - FixedLengthReader::new(reader, tlv_len.0) - .eat_remaining().map_err(|_| msgs::DecodeError::ShortRead)?; - Ok(None) - }, - _ => Err(msgs::DecodeError::InvalidValue) - } - } -} - -/// An event generated by ChannelManager which indicates a message should be sent to a peer (or -/// broadcast to most peers). -/// These events are handled by PeerManager::process_events if you are using a PeerManager. -#[derive(Clone, Debug)] -pub enum MessageSendEvent { - /// Used to indicate that we've accepted a channel open and should send the accept_channel - /// message provided to the given peer. - SendAcceptChannel { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The message which should be sent. - msg: msgs::AcceptChannel, - }, - /// Used to indicate that we've initiated a channel open and should send the open_channel - /// message provided to the given peer. - SendOpenChannel { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The message which should be sent. - msg: msgs::OpenChannel, - }, - /// Used to indicate that a funding_created message should be sent to the peer with the given node_id. - SendFundingCreated { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The message which should be sent. - msg: msgs::FundingCreated, - }, - /// Used to indicate that a funding_signed message should be sent to the peer with the given node_id. - SendFundingSigned { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The message which should be sent. - msg: msgs::FundingSigned, - }, - /// Used to indicate that a channel_ready message should be sent to the peer with the given node_id. - SendChannelReady { - /// The node_id of the node which should receive these message(s) - node_id: PublicKey, - /// The channel_ready message which should be sent. - msg: msgs::ChannelReady, - }, - /// Used to indicate that an announcement_signatures message should be sent to the peer with the given node_id. - SendAnnouncementSignatures { - /// The node_id of the node which should receive these message(s) - node_id: PublicKey, - /// The announcement_signatures message which should be sent. - msg: msgs::AnnouncementSignatures, - }, - /// Used to indicate that a series of HTLC update messages, as well as a commitment_signed - /// message should be sent to the peer with the given node_id. - UpdateHTLCs { - /// The node_id of the node which should receive these message(s) - node_id: PublicKey, - /// The update messages which should be sent. ALL messages in the struct should be sent! - updates: msgs::CommitmentUpdate, - }, - /// Used to indicate that a revoke_and_ack message should be sent to the peer with the given node_id. - SendRevokeAndACK { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The message which should be sent. - msg: msgs::RevokeAndACK, - }, - /// Used to indicate that a closing_signed message should be sent to the peer with the given node_id. - SendClosingSigned { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The message which should be sent. - msg: msgs::ClosingSigned, - }, - /// Used to indicate that a shutdown message should be sent to the peer with the given node_id. - SendShutdown { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The message which should be sent. - msg: msgs::Shutdown, - }, - /// Used to indicate that a channel_reestablish message should be sent to the peer with the given node_id. - SendChannelReestablish { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// 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 - /// 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: Option, - }, - /// Used to indicate that a channel_update should be broadcast to all peers. - BroadcastChannelUpdate { - /// The channel_update which should be sent. - 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 sent to a single peer. - /// In contrast to [`Self::BroadcastChannelUpdate`], this is used when the channel is a - /// private channel and we shouldn't be informing all of our peers of channel parameters. - SendChannelUpdate { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The channel_update which should be sent. - msg: msgs::ChannelUpdate, - }, - /// Broadcast an error downstream to be handled - HandleError { - /// The node_id of the node which should receive this message - node_id: PublicKey, - /// The action which should be taken. - action: msgs::ErrorAction - }, - /// Query a peer for channels with funding transaction UTXOs in a block range. - SendChannelRangeQuery { - /// The node_id of this message recipient - node_id: PublicKey, - /// The query_channel_range which should be sent. - msg: msgs::QueryChannelRange, - }, - /// Request routing gossip messages from a peer for a list of channels identified by - /// their short_channel_ids. - SendShortIdsQuery { - /// The node_id of this message recipient - node_id: PublicKey, - /// The query_short_channel_ids which should be sent. - msg: msgs::QueryShortChannelIds, - }, - /// Sends a reply to a channel range query. This may be one of several SendReplyChannelRange events - /// emitted during processing of the query. - SendReplyChannelRange { - /// The node_id of this message recipient - node_id: PublicKey, - /// The reply_channel_range which should be sent. - msg: msgs::ReplyChannelRange, - }, - /// Sends a timestamp filter for inbound gossip. This should be sent on each new connection to - /// enable receiving gossip messages from the peer. - SendGossipTimestampFilter { - /// The node_id of this message recipient - node_id: PublicKey, - /// The gossip_timestamp_filter which should be sent. - msg: msgs::GossipTimestampFilter, - }, -} - -/// A trait indicating an object may generate message send events -pub trait MessageSendEventsProvider { - /// Gets the list of pending events which were generated by previous actions, clearing the list - /// in the process. - 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`]. -/// -/// 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 -/// 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 -/// may safely use the provider (e.g., see [`ChannelManager::process_pending_events`] and -/// [`ChainMonitor::process_pending_events`]). -/// -/// (C-not implementable) As there is likely no reason for a user to implement this trait on their -/// own type(s). -/// -/// [`process_pending_events`]: Self::process_pending_events -/// [`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. - /// - /// See the trait-level documentation for requirements. - fn process_pending_events(&self, handler: H) where H::Target: EventHandler; -} - -/// 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); -} - -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) { - self.deref().handle_event(event) - } -} diff --git a/lightning/src/util/mod.rs b/lightning/src/util/mod.rs index 7bcbc5a41..3dbf4f896 100644 --- a/lightning/src/util/mod.rs +++ b/lightning/src/util/mod.rs @@ -15,7 +15,6 @@ pub(crate) mod fuzz_wrappers; #[macro_use] pub mod ser_macros; -pub mod events; pub mod errors; pub mod ser; pub mod message_signing; diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index ddc09f0b3..a34cb0cf3 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -17,6 +17,7 @@ use crate::chain::channelmonitor; use crate::chain::channelmonitor::MonitorEvent; use crate::chain::transaction::OutPoint; use crate::chain::keysinterface; +use crate::events; use crate::ln::channelmanager; use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; use crate::ln::{msgs, wire}; @@ -28,7 +29,6 @@ use crate::routing::router::{find_route, InFlightHtlcs, Route, RouteHop, RoutePa use crate::routing::scoring::{ChannelUsage, Score}; use crate::util::config::UserConfig; use crate::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState}; -use crate::util::events; use crate::util::logger::{Logger, Level, Record}; use crate::util::ser::{Readable, ReadableArgs, Writer, Writeable};