Skip to content

Commit d842a75

Browse files
committed
handle scid_to_chan lookup error
Normal lightning workflow does not know how to handle self payment as the route created is to self . This will not be found in short_to_chan_info as there cant be channel created where both the nodes are the same. This handles that scenario by handling the payment before the lookup is hit
1 parent 7d78e4e commit d842a75

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4907,8 +4907,6 @@ where
49074907
invoice_request, bolt12_invoice, session_priv_bytes
49084908
} = args;
49094909

4910-
4911-
49124910
// The top-level caller should hold the total_consistency_lock read lock.
49134911
debug_assert!(self.total_consistency_lock.try_write().is_err());
49144912
let prng_seed = self.entropy_source.get_secure_random_bytes();
@@ -4923,6 +4921,52 @@ where
49234921
e
49244922
})?;
49254923

4924+
// Check if this is a self-payment (indicated by short_channel_id == 0)
4925+
if path.hops.len() == 1 && path.hops.first().unwrap().short_channel_id == 0 {
4926+
// This is a self-payment, handle it directly
4927+
let logger = WithContext::from(&self.logger, Some(self.get_our_node_id()), None, Some(*payment_hash));
4928+
log_trace!(logger, "Processing self-payment with payment hash {}", payment_hash);
4929+
// For self-payments, we immediately generate the PaymentClaimable event
4930+
// since we are both the sender and receiver
4931+
let mut pending_events = self.pending_events.lock().unwrap();
4932+
// Generate PaymentClaimable event
4933+
let purpose = if let Some(preimage) = keysend_preimage {
4934+
events::PaymentPurpose::SpontaneousPayment(*preimage)
4935+
} else if let Some(payment_secret) = recipient_onion.payment_secret {
4936+
events::PaymentPurpose::Bolt11InvoicePayment {
4937+
payment_preimage: None,
4938+
payment_secret,
4939+
}
4940+
} else {
4941+
return Err(APIError::APIMisuseError{
4942+
err: "Self-payment requires either keysend preimage or payment secret".to_owned()
4943+
});
4944+
};
4945+
pending_events.push_back((events::Event::PaymentClaimable {
4946+
receiver_node_id: Some(self.get_our_node_id()),
4947+
payment_hash: *payment_hash,
4948+
onion_fields: Some(recipient_onion.clone()),
4949+
amount_msat: htlc_msat,
4950+
counterparty_skimmed_fee_msat: 0,
4951+
purpose,
4952+
via_channel_ids: Vec::new(),
4953+
claim_deadline: None,
4954+
payment_id: Some(payment_id),
4955+
}, None));
4956+
// For spontaneous payments, also generate PaymentSent event immediately
4957+
if keysend_preimage.is_some() {
4958+
pending_events.push_back((events::Event::PaymentSent {
4959+
payment_id: Some(payment_id),
4960+
payment_preimage: keysend_preimage.unwrap(),
4961+
payment_hash: *payment_hash,
4962+
amount_msat: Some(htlc_msat),
4963+
fee_paid_msat: Some(0), // No fees for self-payments
4964+
bolt12_invoice: None,
4965+
}, None));
4966+
}
4967+
return Ok(());
4968+
}
4969+
49264970
let err: Result<(), _> = loop {
49274971
let (counterparty_node_id, id) = match self.short_to_chan_info.read().unwrap().get(&path.hops.first().unwrap().short_channel_id) {
49284972
None => {
@@ -7707,7 +7751,8 @@ where
77077751
ComplFunc: FnOnce(
77087752
Option<u64>,
77097753
bool,
7710-
) -> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
7754+
)
7755+
-> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
77117756
>(
77127757
&self, prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage,
77137758
payment_info: Option<PaymentClaimDetails>, completion_action: ComplFunc,

0 commit comments

Comments
 (0)