Move PaymentSendFailure into outbound_payment module
[rust-lightning] / lightning / src / ln / outbound_payment.rs
1 // This file is Copyright its original authors, visible in version control
2 // history.
3 //
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
8 // licenses.
9
10 //! Utilities to send payments and manage outbound payment information.
11
12 use crate::ln::{PaymentHash, PaymentSecret};
13 use crate::ln::channelmanager::PaymentId;
14 use crate::ln::msgs::DecodeError;
15 use crate::routing::router::{RouteHop, RouteParameters, RoutePath};
16 use crate::util::errors::APIError;
17 use crate::prelude::*;
18
19 /// Stores the session_priv for each part of a payment that is still pending. For versions 0.0.102
20 /// and later, also stores information for retrying the payment.
21 pub(crate) enum PendingOutboundPayment {
22         Legacy {
23                 session_privs: HashSet<[u8; 32]>,
24         },
25         Retryable {
26                 session_privs: HashSet<[u8; 32]>,
27                 payment_hash: PaymentHash,
28                 payment_secret: Option<PaymentSecret>,
29                 pending_amt_msat: u64,
30                 /// Used to track the fee paid. Only present if the payment was serialized on 0.0.103+.
31                 pending_fee_msat: Option<u64>,
32                 /// The total payment amount across all paths, used to verify that a retry is not overpaying.
33                 total_msat: u64,
34                 /// Our best known block height at the time this payment was initiated.
35                 starting_block_height: u32,
36         },
37         /// When a pending payment is fulfilled, we continue tracking it until all pending HTLCs have
38         /// been resolved. This ensures we don't look up pending payments in ChannelMonitors on restart
39         /// and add a pending payment that was already fulfilled.
40         Fulfilled {
41                 session_privs: HashSet<[u8; 32]>,
42                 payment_hash: Option<PaymentHash>,
43                 timer_ticks_without_htlcs: u8,
44         },
45         /// When a payer gives up trying to retry a payment, they inform us, letting us generate a
46         /// `PaymentFailed` event when all HTLCs have irrevocably failed. This avoids a number of race
47         /// conditions in MPP-aware payment retriers (1), where the possibility of multiple
48         /// `PaymentPathFailed` events with `all_paths_failed` can be pending at once, confusing a
49         /// downstream event handler as to when a payment has actually failed.
50         ///
51         /// (1) https://github.com/lightningdevkit/rust-lightning/issues/1164
52         Abandoned {
53                 session_privs: HashSet<[u8; 32]>,
54                 payment_hash: PaymentHash,
55         },
56 }
57
58 impl PendingOutboundPayment {
59         pub(super) fn is_fulfilled(&self) -> bool {
60                 match self {
61                         PendingOutboundPayment::Fulfilled { .. } => true,
62                         _ => false,
63                 }
64         }
65         pub(super) fn abandoned(&self) -> bool {
66                 match self {
67                         PendingOutboundPayment::Abandoned { .. } => true,
68                         _ => false,
69                 }
70         }
71         pub(super) fn get_pending_fee_msat(&self) -> Option<u64> {
72                 match self {
73                         PendingOutboundPayment::Retryable { pending_fee_msat, .. } => pending_fee_msat.clone(),
74                         _ => None,
75                 }
76         }
77
78         pub(super) fn payment_hash(&self) -> Option<PaymentHash> {
79                 match self {
80                         PendingOutboundPayment::Legacy { .. } => None,
81                         PendingOutboundPayment::Retryable { payment_hash, .. } => Some(*payment_hash),
82                         PendingOutboundPayment::Fulfilled { payment_hash, .. } => *payment_hash,
83                         PendingOutboundPayment::Abandoned { payment_hash, .. } => Some(*payment_hash),
84                 }
85         }
86
87         pub(super) fn mark_fulfilled(&mut self) {
88                 let mut session_privs = HashSet::new();
89                 core::mem::swap(&mut session_privs, match self {
90                         PendingOutboundPayment::Legacy { session_privs } |
91                                 PendingOutboundPayment::Retryable { session_privs, .. } |
92                                 PendingOutboundPayment::Fulfilled { session_privs, .. } |
93                                 PendingOutboundPayment::Abandoned { session_privs, .. }
94                         => session_privs,
95                 });
96                 let payment_hash = self.payment_hash();
97                 *self = PendingOutboundPayment::Fulfilled { session_privs, payment_hash, timer_ticks_without_htlcs: 0 };
98         }
99
100         pub(super) fn mark_abandoned(&mut self) -> Result<(), ()> {
101                 let mut session_privs = HashSet::new();
102                 let our_payment_hash;
103                 core::mem::swap(&mut session_privs, match self {
104                         PendingOutboundPayment::Legacy { .. } |
105                                 PendingOutboundPayment::Fulfilled { .. } =>
106                                 return Err(()),
107                                 PendingOutboundPayment::Retryable { session_privs, payment_hash, .. } |
108                                         PendingOutboundPayment::Abandoned { session_privs, payment_hash, .. } => {
109                                                 our_payment_hash = *payment_hash;
110                                                 session_privs
111                                         },
112                 });
113                 *self = PendingOutboundPayment::Abandoned { session_privs, payment_hash: our_payment_hash };
114                 Ok(())
115         }
116
117         /// panics if path is None and !self.is_fulfilled
118         pub(super) fn remove(&mut self, session_priv: &[u8; 32], path: Option<&Vec<RouteHop>>) -> bool {
119                 let remove_res = match self {
120                         PendingOutboundPayment::Legacy { session_privs } |
121                                 PendingOutboundPayment::Retryable { session_privs, .. } |
122                                 PendingOutboundPayment::Fulfilled { session_privs, .. } |
123                                 PendingOutboundPayment::Abandoned { session_privs, .. } => {
124                                         session_privs.remove(session_priv)
125                                 }
126                 };
127                 if remove_res {
128                         if let PendingOutboundPayment::Retryable { ref mut pending_amt_msat, ref mut pending_fee_msat, .. } = self {
129                                 let path = path.expect("Fulfilling a payment should always come with a path");
130                                 let path_last_hop = path.last().expect("Outbound payments must have had a valid path");
131                                 *pending_amt_msat -= path_last_hop.fee_msat;
132                                 if let Some(fee_msat) = pending_fee_msat.as_mut() {
133                                         *fee_msat -= path.get_path_fees();
134                                 }
135                         }
136                 }
137                 remove_res
138         }
139
140         pub(super) fn insert(&mut self, session_priv: [u8; 32], path: &Vec<RouteHop>) -> bool {
141                 let insert_res = match self {
142                         PendingOutboundPayment::Legacy { session_privs } |
143                                 PendingOutboundPayment::Retryable { session_privs, .. } => {
144                                         session_privs.insert(session_priv)
145                                 }
146                         PendingOutboundPayment::Fulfilled { .. } => false,
147                         PendingOutboundPayment::Abandoned { .. } => false,
148                 };
149                 if insert_res {
150                         if let PendingOutboundPayment::Retryable { ref mut pending_amt_msat, ref mut pending_fee_msat, .. } = self {
151                                 let path_last_hop = path.last().expect("Outbound payments must have had a valid path");
152                                 *pending_amt_msat += path_last_hop.fee_msat;
153                                 if let Some(fee_msat) = pending_fee_msat.as_mut() {
154                                         *fee_msat += path.get_path_fees();
155                                 }
156                         }
157                 }
158                 insert_res
159         }
160
161         pub(super) fn remaining_parts(&self) -> usize {
162                 match self {
163                         PendingOutboundPayment::Legacy { session_privs } |
164                                 PendingOutboundPayment::Retryable { session_privs, .. } |
165                                 PendingOutboundPayment::Fulfilled { session_privs, .. } |
166                                 PendingOutboundPayment::Abandoned { session_privs, .. } => {
167                                         session_privs.len()
168                                 }
169                 }
170         }
171 }
172
173 /// If a payment fails to send, it can be in one of several states. This enum is returned as the
174 /// Err() type describing which state the payment is in, see the description of individual enum
175 /// states for more.
176 #[derive(Clone, Debug)]
177 pub enum PaymentSendFailure {
178         /// A parameter which was passed to send_payment was invalid, preventing us from attempting to
179         /// send the payment at all.
180         ///
181         /// You can freely resend the payment in full (with the parameter error fixed).
182         ///
183         /// Because the payment failed outright, no payment tracking is done, you do not need to call
184         /// [`ChannelManager::abandon_payment`] and [`ChannelManager::retry_payment`] will *not* work
185         /// for this payment.
186         ///
187         /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
188         /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
189         ParameterError(APIError),
190         /// A parameter in a single path which was passed to send_payment was invalid, preventing us
191         /// from attempting to send the payment at all.
192         ///
193         /// You can freely resend the payment in full (with the parameter error fixed).
194         ///
195         /// The results here are ordered the same as the paths in the route object which was passed to
196         /// send_payment.
197         ///
198         /// Because the payment failed outright, no payment tracking is done, you do not need to call
199         /// [`ChannelManager::abandon_payment`] and [`ChannelManager::retry_payment`] will *not* work
200         /// for this payment.
201         ///
202         /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
203         /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
204         PathParameterError(Vec<Result<(), APIError>>),
205         /// All paths which were attempted failed to send, with no channel state change taking place.
206         /// You can freely resend the payment in full (though you probably want to do so over different
207         /// paths than the ones selected).
208         ///
209         /// Because the payment failed outright, no payment tracking is done, you do not need to call
210         /// [`ChannelManager::abandon_payment`] and [`ChannelManager::retry_payment`] will *not* work
211         /// for this payment.
212         ///
213         /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
214         /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
215         AllFailedResendSafe(Vec<APIError>),
216         /// Indicates that a payment for the provided [`PaymentId`] is already in-flight and has not
217         /// yet completed (i.e. generated an [`Event::PaymentSent`]) or been abandoned (via
218         /// [`ChannelManager::abandon_payment`]).
219         ///
220         /// [`PaymentId`]: crate::ln::channelmanager::PaymentId
221         /// [`Event::PaymentSent`]: crate::util::events::Event::PaymentSent
222         /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
223         DuplicatePayment,
224         /// Some paths which were attempted failed to send, though possibly not all. At least some
225         /// paths have irrevocably committed to the HTLC and retrying the payment in full would result
226         /// in over-/re-payment.
227         ///
228         /// The results here are ordered the same as the paths in the route object which was passed to
229         /// send_payment, and any `Err`s which are not [`APIError::MonitorUpdateInProgress`] can be
230         /// safely retried via [`ChannelManager::retry_payment`].
231         ///
232         /// Any entries which contain `Err(APIError::MonitorUpdateInprogress)` or `Ok(())` MUST NOT be
233         /// retried as they will result in over-/re-payment. These HTLCs all either successfully sent
234         /// (in the case of `Ok(())`) or will send once a [`MonitorEvent::Completed`] is provided for
235         /// the next-hop channel with the latest update_id.
236         ///
237         /// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
238         /// [`MonitorEvent::Completed`]: crate::chain::channelmonitor::MonitorEvent::Completed
239         PartialFailure {
240                 /// The errors themselves, in the same order as the route hops.
241                 results: Vec<Result<(), APIError>>,
242                 /// If some paths failed without irrevocably committing to the new HTLC(s), this will
243                 /// contain a [`RouteParameters`] object which can be used to calculate a new route that
244                 /// will pay all remaining unpaid balance.
245                 failed_paths_retry: Option<RouteParameters>,
246                 /// The payment id for the payment, which is now at least partially pending.
247                 payment_id: PaymentId,
248         },
249 }
250
251 impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
252         (0, Legacy) => {
253                 (0, session_privs, required),
254         },
255         (1, Fulfilled) => {
256                 (0, session_privs, required),
257                 (1, payment_hash, option),
258                 (3, timer_ticks_without_htlcs, (default_value, 0)),
259         },
260         (2, Retryable) => {
261                 (0, session_privs, required),
262                 (1, pending_fee_msat, option),
263                 (2, payment_hash, required),
264                 (4, payment_secret, option),
265                 (6, total_msat, required),
266                 (8, pending_amt_msat, required),
267                 (10, starting_block_height, required),
268         },
269         (3, Abandoned) => {
270                 (0, session_privs, required),
271                 (2, payment_hash, required),
272         },
273 );