Skip to content

Commit f05c414

Browse files
Move PendingOutboundPayment to new outbound_payment module
We want to move all outbound payment-related things to this new module, to help break up ChannelManager so future payment retries work doesn't increase the size of ChannelManager.
1 parent 56afbf5 commit f05c414

File tree

3 files changed

+195
-178
lines changed

3 files changed

+195
-178
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use crate::ln::msgs;
5151
use crate::ln::onion_utils;
5252
use crate::ln::onion_utils::HTLCFailReason;
5353
use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT};
54+
use crate::ln::outbound_payment::PendingOutboundPayment;
5455
use crate::ln::wire::Encode;
5556
use crate::chain::keysinterface::{Sign, KeysInterface, KeysManager, Recipient};
5657
use crate::util::config::{UserConfig, ChannelConfig};
@@ -480,160 +481,6 @@ struct PendingInboundPayment {
480481
min_value_msat: Option<u64>,
481482
}
482483

483-
/// Stores the session_priv for each part of a payment that is still pending. For versions 0.0.102
484-
/// and later, also stores information for retrying the payment.
485-
pub(crate) enum PendingOutboundPayment {
486-
Legacy {
487-
session_privs: HashSet<[u8; 32]>,
488-
},
489-
Retryable {
490-
session_privs: HashSet<[u8; 32]>,
491-
payment_hash: PaymentHash,
492-
payment_secret: Option<PaymentSecret>,
493-
pending_amt_msat: u64,
494-
/// Used to track the fee paid. Only present if the payment was serialized on 0.0.103+.
495-
pending_fee_msat: Option<u64>,
496-
/// The total payment amount across all paths, used to verify that a retry is not overpaying.
497-
total_msat: u64,
498-
/// Our best known block height at the time this payment was initiated.
499-
starting_block_height: u32,
500-
},
501-
/// When a pending payment is fulfilled, we continue tracking it until all pending HTLCs have
502-
/// been resolved. This ensures we don't look up pending payments in ChannelMonitors on restart
503-
/// and add a pending payment that was already fulfilled.
504-
Fulfilled {
505-
session_privs: HashSet<[u8; 32]>,
506-
payment_hash: Option<PaymentHash>,
507-
timer_ticks_without_htlcs: u8,
508-
},
509-
/// When a payer gives up trying to retry a payment, they inform us, letting us generate a
510-
/// `PaymentFailed` event when all HTLCs have irrevocably failed. This avoids a number of race
511-
/// conditions in MPP-aware payment retriers (1), where the possibility of multiple
512-
/// `PaymentPathFailed` events with `all_paths_failed` can be pending at once, confusing a
513-
/// downstream event handler as to when a payment has actually failed.
514-
///
515-
/// (1) https://github.com/lightningdevkit/rust-lightning/issues/1164
516-
Abandoned {
517-
session_privs: HashSet<[u8; 32]>,
518-
payment_hash: PaymentHash,
519-
},
520-
}
521-
522-
impl PendingOutboundPayment {
523-
fn is_fulfilled(&self) -> bool {
524-
match self {
525-
PendingOutboundPayment::Fulfilled { .. } => true,
526-
_ => false,
527-
}
528-
}
529-
fn abandoned(&self) -> bool {
530-
match self {
531-
PendingOutboundPayment::Abandoned { .. } => true,
532-
_ => false,
533-
}
534-
}
535-
fn get_pending_fee_msat(&self) -> Option<u64> {
536-
match self {
537-
PendingOutboundPayment::Retryable { pending_fee_msat, .. } => pending_fee_msat.clone(),
538-
_ => None,
539-
}
540-
}
541-
542-
fn payment_hash(&self) -> Option<PaymentHash> {
543-
match self {
544-
PendingOutboundPayment::Legacy { .. } => None,
545-
PendingOutboundPayment::Retryable { payment_hash, .. } => Some(*payment_hash),
546-
PendingOutboundPayment::Fulfilled { payment_hash, .. } => *payment_hash,
547-
PendingOutboundPayment::Abandoned { payment_hash, .. } => Some(*payment_hash),
548-
}
549-
}
550-
551-
fn mark_fulfilled(&mut self) {
552-
let mut session_privs = HashSet::new();
553-
core::mem::swap(&mut session_privs, match self {
554-
PendingOutboundPayment::Legacy { session_privs } |
555-
PendingOutboundPayment::Retryable { session_privs, .. } |
556-
PendingOutboundPayment::Fulfilled { session_privs, .. } |
557-
PendingOutboundPayment::Abandoned { session_privs, .. }
558-
=> session_privs,
559-
});
560-
let payment_hash = self.payment_hash();
561-
*self = PendingOutboundPayment::Fulfilled { session_privs, payment_hash, timer_ticks_without_htlcs: 0 };
562-
}
563-
564-
fn mark_abandoned(&mut self) -> Result<(), ()> {
565-
let mut session_privs = HashSet::new();
566-
let our_payment_hash;
567-
core::mem::swap(&mut session_privs, match self {
568-
PendingOutboundPayment::Legacy { .. } |
569-
PendingOutboundPayment::Fulfilled { .. } =>
570-
return Err(()),
571-
PendingOutboundPayment::Retryable { session_privs, payment_hash, .. } |
572-
PendingOutboundPayment::Abandoned { session_privs, payment_hash, .. } => {
573-
our_payment_hash = *payment_hash;
574-
session_privs
575-
},
576-
});
577-
*self = PendingOutboundPayment::Abandoned { session_privs, payment_hash: our_payment_hash };
578-
Ok(())
579-
}
580-
581-
/// panics if path is None and !self.is_fulfilled
582-
fn remove(&mut self, session_priv: &[u8; 32], path: Option<&Vec<RouteHop>>) -> bool {
583-
let remove_res = match self {
584-
PendingOutboundPayment::Legacy { session_privs } |
585-
PendingOutboundPayment::Retryable { session_privs, .. } |
586-
PendingOutboundPayment::Fulfilled { session_privs, .. } |
587-
PendingOutboundPayment::Abandoned { session_privs, .. } => {
588-
session_privs.remove(session_priv)
589-
}
590-
};
591-
if remove_res {
592-
if let PendingOutboundPayment::Retryable { ref mut pending_amt_msat, ref mut pending_fee_msat, .. } = self {
593-
let path = path.expect("Fulfilling a payment should always come with a path");
594-
let path_last_hop = path.last().expect("Outbound payments must have had a valid path");
595-
*pending_amt_msat -= path_last_hop.fee_msat;
596-
if let Some(fee_msat) = pending_fee_msat.as_mut() {
597-
*fee_msat -= path.get_path_fees();
598-
}
599-
}
600-
}
601-
remove_res
602-
}
603-
604-
fn insert(&mut self, session_priv: [u8; 32], path: &Vec<RouteHop>) -> bool {
605-
let insert_res = match self {
606-
PendingOutboundPayment::Legacy { session_privs } |
607-
PendingOutboundPayment::Retryable { session_privs, .. } => {
608-
session_privs.insert(session_priv)
609-
}
610-
PendingOutboundPayment::Fulfilled { .. } => false,
611-
PendingOutboundPayment::Abandoned { .. } => false,
612-
};
613-
if insert_res {
614-
if let PendingOutboundPayment::Retryable { ref mut pending_amt_msat, ref mut pending_fee_msat, .. } = self {
615-
let path_last_hop = path.last().expect("Outbound payments must have had a valid path");
616-
*pending_amt_msat += path_last_hop.fee_msat;
617-
if let Some(fee_msat) = pending_fee_msat.as_mut() {
618-
*fee_msat += path.get_path_fees();
619-
}
620-
}
621-
}
622-
insert_res
623-
}
624-
625-
fn remaining_parts(&self) -> usize {
626-
match self {
627-
PendingOutboundPayment::Legacy { session_privs } |
628-
PendingOutboundPayment::Retryable { session_privs, .. } |
629-
PendingOutboundPayment::Fulfilled { session_privs, .. } |
630-
PendingOutboundPayment::Abandoned { session_privs, .. } => {
631-
session_privs.len()
632-
}
633-
}
634-
}
635-
}
636-
637484
/// SimpleArcChannelManager is useful when you need a ChannelManager with a static lifetime, e.g.
638485
/// when you're using lightning-net-tokio (since tokio::spawn requires parameters with static
639486
/// lifetimes). Other times you can afford a reference, which is more efficient, in which case
@@ -6950,30 +6797,6 @@ impl_writeable_tlv_based!(PendingInboundPayment, {
69506797
(8, min_value_msat, required),
69516798
});
69526799

6953-
impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
6954-
(0, Legacy) => {
6955-
(0, session_privs, required),
6956-
},
6957-
(1, Fulfilled) => {
6958-
(0, session_privs, required),
6959-
(1, payment_hash, option),
6960-
(3, timer_ticks_without_htlcs, (default_value, 0)),
6961-
},
6962-
(2, Retryable) => {
6963-
(0, session_privs, required),
6964-
(1, pending_fee_msat, option),
6965-
(2, payment_hash, required),
6966-
(4, payment_secret, option),
6967-
(6, total_msat, required),
6968-
(8, pending_amt_msat, required),
6969-
(10, starting_block_height, required),
6970-
},
6971-
(3, Abandoned) => {
6972-
(0, session_privs, required),
6973-
(2, payment_hash, required),
6974-
},
6975-
);
6976-
69776800
impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<M, T, K, F, L>
69786801
where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
69796802
T::Target: BroadcasterInterface,

lightning/src/ln/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub mod peer_handler;
3232
pub mod chan_utils;
3333
pub mod features;
3434
pub mod script;
35+
mod outbound_payment;
3536

3637
#[cfg(fuzzing)]
3738
pub mod peer_channel_encryptor;

0 commit comments

Comments
 (0)