Skip to content

Commit 853f63b

Browse files
feat: allow self payment
This PR solves issue #2462. If we asked to pay an invoice that we generated ourselves. We generate PaymentSent and PaymentClaimable event and mark the payment as fulfilled in our set of outbound payments. This PR is important because we realized users can easily screw up self payments when they implement it themselves. See here: https://lists.linuxfoundation.org/pipermail/lightning-dev/2023-June/003983.html
1 parent aa3dbe8 commit 853f63b

File tree

2 files changed

+144
-17
lines changed

2 files changed

+144
-17
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 99 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ struct ClaimablePayment {
677677
purpose: events::PaymentPurpose,
678678
onion_fields: Option<RecipientOnionFields>,
679679
htlcs: Vec<ClaimableHTLC>,
680+
amount_msat: Option<u64>,
680681
}
681682

682683
/// Information about claimable or being-claimed payments
@@ -697,6 +698,17 @@ struct ClaimablePayments {
697698
pending_claiming_payments: HashMap<PaymentHash, ClaimingPayment>,
698699
}
699700

701+
/// Information about self claimable payments.
702+
struct ClaimableSelfPayments {
703+
claimable_payments: HashMap<PaymentHash, ClaimableSelfPayment>
704+
}
705+
706+
struct ClaimableSelfPayment {
707+
purpose: events::PaymentPurpose,
708+
amount_msat: u64,
709+
payment_id: PaymentId,
710+
}
711+
700712
/// Events which we process internally but cannot be processed immediately at the generation site
701713
/// usually because we're running pre-full-init. They are handled immediately once we detect we are
702714
/// running normally, and specifically must be processed before any other non-background
@@ -1267,6 +1279,12 @@ where
12671279
/// See `ChannelManager` struct-level documentation for lock order requirements.
12681280
claimable_payments: Mutex<ClaimablePayments>,
12691281

1282+
/// The set of self payments which are claimable. See [`ClaimableSelfPayments`]
1283+
/// individual field docs for more info.
1284+
///
1285+
/// See `ChannelManager` struct-level documentation for lock order requirements.
1286+
claimable_self_payments: Mutex<ClaimableSelfPayments>,
1287+
12701288
/// The set of outbound SCID aliases across all our channels, including unconfirmed channels
12711289
/// and some closed channels which reached a usable state prior to being closed. This is used
12721290
/// only to avoid duplicates, and is not persisted explicitly to disk, but rebuilt from the
@@ -2468,6 +2486,7 @@ where
24682486
pending_outbound_payments: OutboundPayments::new(),
24692487
forward_htlcs: Mutex::new(new_hash_map()),
24702488
claimable_payments: Mutex::new(ClaimablePayments { claimable_payments: new_hash_map(), pending_claiming_payments: new_hash_map() }),
2489+
claimable_self_payments: Mutex::new(ClaimableSelfPayments { claimable_payments: new_hash_map() }),
24712490
pending_intercepted_htlcs: Mutex::new(new_hash_map()),
24722491
outpoint_to_peer: Mutex::new(new_hash_map()),
24732492
short_to_chan_info: FairRwLock::new(new_hash_map()),
@@ -3549,11 +3568,38 @@ where
35493568
pub fn send_payment(&self, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields, payment_id: PaymentId, route_params: RouteParameters, retry_strategy: Retry) -> Result<(), RetryableSendFailure> {
35503569
let best_block_height = self.best_block.read().unwrap().height;
35513570
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
3571+
let mut preimage: Option<PaymentPreimage> = None;
3572+
let mut payment_secret = PaymentSecret([0; 32]);
3573+
let mut is_self_pay = false;
3574+
if let Some(secret) = recipient_onion.payment_secret {
3575+
payment_secret = secret;
3576+
if let Payee::Clear{ node_id, .. } = route_params.payment_params.payee {
3577+
let is_phantom_payee = match self.node_signer.get_node_id(Recipient::PhantomNode) {
3578+
Ok(phantom_node_id) => node_id == phantom_node_id,
3579+
Err(_) => false,
3580+
};
3581+
if node_id == self.get_our_node_id() || is_phantom_payee {
3582+
let payment_data = msgs::FinalOnionHopData{ payment_secret, total_msat: route_params.final_value_msat };
3583+
preimage = inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger).map_err(|_| RetryableSendFailure::RecipientRejected)?.0;
3584+
is_self_pay = true;
3585+
}
3586+
}
3587+
}
35523588
self.pending_outbound_payments
3553-
.send_payment(payment_hash, recipient_onion, payment_id, retry_strategy, route_params,
3589+
.send_payment(payment_hash, recipient_onion.clone(), payment_id, retry_strategy, route_params.clone(),
35543590
&self.router, self.list_usable_channels(), || self.compute_inflight_htlcs(),
35553591
&self.entropy_source, &self.node_signer, best_block_height, &self.logger,
3556-
&self.pending_events, |args| self.send_payment_along_path(args))
3592+
&self.pending_events, |args| self.send_payment_along_path(args))?;
3593+
3594+
if is_self_pay {
3595+
let mut claimable_self_payments = self.claimable_self_payments.lock().unwrap();
3596+
let purpose = events::PaymentPurpose::InvoicePayment { payment_preimage: preimage, payment_secret };
3597+
claimable_self_payments.claimable_payments.insert(payment_hash, ClaimableSelfPayment{ purpose: purpose.clone(), amount_msat: route_params.final_value_msat, payment_id });
3598+
let mut pending_events = self.pending_events.lock().unwrap();
3599+
pending_events.push_back((events::Event::PaymentClaimable { receiver_node_id: Some(self.get_our_node_id()), payment_hash, onion_fields: Some(recipient_onion), amount_msat: route_params.final_value_msat, counterparty_skimmed_fee_msat: 0, purpose, via_channel_id: None, via_user_channel_id: None, claim_deadline: None }, None));
3600+
}
3601+
3602+
Ok(())
35573603
}
35583604

35593605
#[cfg(test)]
@@ -4602,7 +4648,7 @@ where
46024648
.or_insert_with(|| {
46034649
committed_to_claimable = true;
46044650
ClaimablePayment {
4605-
purpose: $purpose.clone(), htlcs: Vec::new(), onion_fields: None,
4651+
purpose: $purpose.clone(), htlcs: Vec::new(), onion_fields: None, amount_msat: None,
46064652
}
46074653
});
46084654
if $purpose != claimable_payment.purpose {
@@ -5446,10 +5492,32 @@ where
54465492

54475493
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
54485494

5495+
// This handles fulfilling and claiming of Self payment.
5496+
{
5497+
let mut claimable_self_payments = self.claimable_self_payments.lock().unwrap();
5498+
if let Some(payment) = claimable_self_payments.claimable_payments.remove(&payment_hash) {
5499+
let mut pending_outbounds_lock = self.pending_outbound_payments.pending_outbound_payments.lock().unwrap();
5500+
let out_payment = pending_outbounds_lock.get_mut(&payment.payment_id).unwrap();
5501+
out_payment.mark_fulfilled();
5502+
let mut pending_events_lock = self.pending_events.lock().unwrap();
5503+
pending_events_lock.push_back((Event::PaymentSent { payment_id: Some(payment.payment_id), payment_preimage,
5504+
payment_hash, fee_paid_msat: None }, None));
5505+
pending_events_lock.push_back((Event::PaymentClaimed { receiver_node_id: None, payment_hash,
5506+
amount_msat: payment.amount_msat, purpose: payment.purpose, htlcs: vec![], sender_intended_total_msat: None }, None));
5507+
return;
5508+
}
5509+
}
5510+
54495511
let mut sources = {
54505512
let mut claimable_payments = self.claimable_payments.lock().unwrap();
54515513
if let Some(payment) = claimable_payments.claimable_payments.remove(&payment_hash) {
54525514
let mut receiver_node_id = self.our_network_pubkey;
5515+
if payment.htlcs.is_empty() {
5516+
let mut pending_events_lock = self.pending_events.lock().unwrap();
5517+
pending_events_lock.push_back((Event::PaymentClaimed { receiver_node_id: Some(receiver_node_id), payment_hash,
5518+
amount_msat: payment.amount_msat.unwrap(), purpose: payment.purpose, htlcs: vec![], sender_intended_total_msat: None }, None));
5519+
return;
5520+
}
54535521
for htlc in payment.htlcs.iter() {
54545522
if htlc.prev_hop.phantom_shared_secret.is_some() {
54555523
let phantom_pubkey = self.node_signer.get_node_id(Recipient::PhantomNode)
@@ -10111,6 +10179,7 @@ where
1011110179

1011210180
let pending_inbound_payments = self.pending_inbound_payments.lock().unwrap();
1011310181
let claimable_payments = self.claimable_payments.lock().unwrap();
10182+
let claimable_self_payments = self.claimable_self_payments.lock().unwrap();
1011410183
let pending_outbound_payments = self.pending_outbound_payments.pending_outbound_payments.lock().unwrap();
1011510184

1011610185
let mut htlc_purposes: Vec<&events::PaymentPurpose> = Vec::new();
@@ -10126,6 +10195,14 @@ where
1012610195
htlc_onion_fields.push(&payment.onion_fields);
1012710196
}
1012810197

10198+
(claimable_self_payments.claimable_payments.len() as u64).write(writer)?;
10199+
for (payment_hash, payment) in claimable_self_payments.claimable_payments.iter() {
10200+
payment_hash.write(writer)?;
10201+
payment.purpose.write(writer)?;
10202+
payment.amount_msat.write(writer)?;
10203+
payment.payment_id.write(writer)?;
10204+
}
10205+
1012910206
let mut monitor_update_blocked_actions_per_peer = None;
1013010207
let mut peer_states = Vec::new();
1013110208
for (_, peer_state_mutex) in per_peer_state.iter() {
@@ -10639,6 +10716,21 @@ where
1063910716
claimable_htlcs_list.push((payment_hash, previous_hops));
1064010717
}
1064110718

10719+
let claimable_self_payment_count: u64 = Readable::read(reader)?;
10720+
let mut claimable_self_payments = HashMap::with_capacity(claimable_self_payment_count as usize);
10721+
for _ in 0..claimable_self_payment_count {
10722+
//read each payment details and add an entry to the map of claimable payments.
10723+
let payment_hash = Readable::read(reader)?;
10724+
let purpose = Readable::read(reader)?;
10725+
let amount_msat = Readable::read(reader)?;
10726+
let payment_id = Readable::read(reader)?;
10727+
claimable_self_payments.insert(payment_hash, ClaimableSelfPayment {
10728+
purpose,
10729+
amount_msat,
10730+
payment_id,
10731+
});
10732+
}
10733+
1064210734
let peer_state_from_chans = |channel_by_id| {
1064310735
PeerState {
1064410736
channel_by_id,
@@ -11064,14 +11156,14 @@ where
1106411156
purposes.into_iter().zip(onion_fields.into_iter().zip(claimable_htlcs_list.into_iter()))
1106511157
{
1106611158
let existing_payment = claimable_payments.insert(payment_hash, ClaimablePayment {
11067-
purpose, htlcs, onion_fields: onion,
11159+
purpose, htlcs, onion_fields: onion, amount_msat: None,
1106811160
});
1106911161
if existing_payment.is_some() { return Err(DecodeError::InvalidValue); }
1107011162
}
1107111163
} else {
1107211164
for (purpose, (payment_hash, htlcs)) in purposes.into_iter().zip(claimable_htlcs_list.into_iter()) {
1107311165
let existing_payment = claimable_payments.insert(payment_hash, ClaimablePayment {
11074-
purpose, htlcs, onion_fields: None,
11166+
purpose, htlcs, onion_fields: None, amount_msat: None,
1107511167
});
1107611168
if existing_payment.is_some() { return Err(DecodeError::InvalidValue); }
1107711169
}
@@ -11105,7 +11197,7 @@ where
1110511197
events::PaymentPurpose::SpontaneousPayment(*payment_preimage),
1110611198
};
1110711199
claimable_payments.insert(payment_hash, ClaimablePayment {
11108-
purpose, htlcs, onion_fields: None,
11200+
purpose, htlcs, onion_fields: None, amount_msat: None,
1110911201
});
1111011202
}
1111111203
}
@@ -11272,6 +11364,7 @@ where
1127211364

1127311365
forward_htlcs: Mutex::new(forward_htlcs),
1127411366
claimable_payments: Mutex::new(ClaimablePayments { claimable_payments, pending_claiming_payments: pending_claiming_payments.unwrap() }),
11367+
claimable_self_payments: Mutex::new(ClaimableSelfPayments { claimable_payments: claimable_self_payments }),
1127511368
outbound_scid_aliases: Mutex::new(outbound_scid_aliases),
1127611369
outpoint_to_peer: Mutex::new(outpoint_to_peer),
1127711370
short_to_chan_info: FairRwLock::new(short_to_chan_info),

lightning/src/ln/outbound_payment.rs

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
1919
use crate::ln::channelmanager::{ChannelDetails, EventCompletionAction, HTLCSource, PaymentId};
2020
use crate::ln::onion_utils::{DecodedOnionFailure, HTLCFailReason};
2121
use crate::offers::invoice::Bolt12Invoice;
22-
use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, PaymentParameters, Route, RouteParameters, Router};
22+
use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, PaymentParameters, Route, RouteParameters, Router, Payee};
2323
use crate::util::errors::APIError;
2424
use crate::util::logger::Logger;
2525
use crate::util::time::Time;
@@ -170,8 +170,8 @@ impl PendingOutboundPayment {
170170
}
171171
}
172172

173-
fn mark_fulfilled(&mut self) {
174-
let mut session_privs = new_hash_set();
173+
pub fn mark_fulfilled(&mut self) {
174+
let mut session_privs = HashSet::new();
175175
core::mem::swap(&mut session_privs, match self {
176176
PendingOutboundPayment::Legacy { session_privs } |
177177
PendingOutboundPayment::Retryable { session_privs, .. } |
@@ -421,6 +421,8 @@ pub enum RetryableSendFailure {
421421
/// [`Event::PaymentSent`]: crate::events::Event::PaymentSent
422422
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
423423
DuplicatePayment,
424+
/// The intended recipient rejected our payment.
425+
RecipientRejected,
424426
}
425427

426428
/// If a payment fails to send with [`ChannelManager::send_payment_with_route`], it can be in one
@@ -907,16 +909,48 @@ impl OutboundPayments {
907909
}
908910
}
909911

910-
let mut route = router.find_route_with_id(
911-
&node_signer.get_node_id(Recipient::Node).unwrap(), &route_params,
912+
let payer = node_signer.get_node_id(Recipient::Node).unwrap();
913+
let route = match router.find_route_with_id(
914+
&payer,&route_params,
912915
Some(&first_hops.iter().collect::<Vec<_>>()), inflight_htlcs(),
913916
payment_hash, payment_id,
914-
).map_err(|_| {
915-
log_error!(logger, "Failed to find route for payment with id {} and hash {}",
916-
payment_id, payment_hash);
917-
RetryableSendFailure::RouteNotFound
918-
})?;
919-
917+
) {
918+
Ok(res) => Some(res),
919+
Err(_) => {
920+
// The following code handles self payments.
921+
if let Payee::Clear{node_id, .. } = route_params.payment_params.payee {
922+
let is_phantom_payee = match node_signer.get_node_id(Recipient::PhantomNode) {
923+
Ok(phantom_node_id) => node_id == phantom_node_id,
924+
Err(_) => false,
925+
};
926+
if node_id == payer || is_phantom_payee {
927+
let dummy_route = Route {
928+
paths: vec![Path {
929+
hops: vec![],
930+
blinded_tail: None,
931+
}],
932+
route_params: Some(route_params.clone()),
933+
};
934+
935+
let _ = self.add_new_pending_payment(payment_hash,
936+
recipient_onion.clone(), payment_id, keysend_preimage, &dummy_route, Some(retry_strategy),
937+
Some(route_params.payment_params.clone()), entropy_source, best_block_height)
938+
.map_err(|_| {
939+
log_error!(logger, "Payment with id {} is already pending. New payment had payment hash {}",
940+
payment_id, payment_hash);
941+
RetryableSendFailure::DuplicatePayment
942+
})?;
943+
return Ok(());
944+
}
945+
}
946+
None
947+
}
948+
};
949+
if route.is_none() {
950+
log_error!(logger, "Failed to find route for payment with id {} and hash {}", payment_id, payment_hash);
951+
return Err(RetryableSendFailure::RouteNotFound);
952+
}
953+
let mut route = route.unwrap();
920954
if route.route_params.as_ref() != Some(&route_params) {
921955
debug_assert!(false,
922956
"Routers are expected to return a Route which includes the requested RouteParameters");

0 commit comments

Comments
 (0)