Skip to content

Commit

Permalink
Add payment claimable path
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimirfomene committed Jan 26, 2024
1 parent 4b31747 commit c1a2bf4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
40 changes: 32 additions & 8 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ struct ClaimablePayment {
purpose: events::PaymentPurpose,
onion_fields: Option<RecipientOnionFields>,
htlcs: Vec<ClaimableHTLC>,
amount_msat: Option<u64>,
}

/// Information about claimable or being-claimed payments
Expand Down Expand Up @@ -3555,7 +3556,10 @@ where
let best_block_height = self.best_block.read().unwrap().height();
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
let mut preimage: Option<PaymentPreimage> = None;
if let Some(payment_secret) = recipient_onion.payment_secret {
let mut payment_secret = PaymentSecret([0; 32]);
let mut is_self_pay = false;
if let Some(secret) = recipient_onion.payment_secret {
payment_secret = secret;
if let Payee::Clear{node_id, .. } = route_params.payment_params.payee {
let is_phantom_payee = match self.node_signer.get_node_id(Recipient::PhantomNode) {
Ok(phantom_node_id) => node_id == phantom_node_id,
Expand All @@ -3564,15 +3568,26 @@ where
if node_id == self.get_our_node_id() || is_phantom_payee {
let payment_data = msgs::FinalOnionHopData{ payment_secret, total_msat: route_params.final_value_msat};
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;
// create a pending inbound payment
is_self_pay = true;
}
}
}

self.pending_outbound_payments
.send_payment(payment_hash, recipient_onion, payment_id, retry_strategy, route_params, preimage,
.send_payment(payment_hash, recipient_onion.clone(), payment_id, retry_strategy, route_params.clone(), preimage,
&self.router, self.list_usable_channels(), || self.compute_inflight_htlcs(),
&self.entropy_source, &self.node_signer, best_block_height, &self.logger,
&self.pending_events, |args| self.send_payment_along_path(args))
&self.pending_events, |args| self.send_payment_along_path(args))?;

if is_self_pay {
let mut claimable_payments = self.claimable_payments.lock().unwrap();
let purpose = events::PaymentPurpose::InvoicePayment { payment_preimage: preimage, payment_secret };
claimable_payments.claimable_payments.insert(payment_hash, ClaimablePayment{ purpose: purpose.clone(), onion_fields: Some(recipient_onion.clone()), htlcs: vec![], amount_msat: Some(route_params.final_value_msat)});
let mut pending_events = self.pending_events.lock().unwrap();
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));
}

Ok(())
}

#[cfg(test)]
Expand Down Expand Up @@ -4555,7 +4570,7 @@ where
.or_insert_with(|| {
committed_to_claimable = true;
ClaimablePayment {
purpose: $purpose.clone(), htlcs: Vec::new(), onion_fields: None,
purpose: $purpose.clone(), htlcs: Vec::new(), onion_fields: None, amount_msat: None,
}
});
if $purpose != claimable_payment.purpose {
Expand Down Expand Up @@ -5358,13 +5373,22 @@ where

fn claim_payment_internal(&self, payment_preimage: PaymentPreimage, custom_tlvs_known: bool) {
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());


let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);

let mut sources = {
let mut claimable_payments = self.claimable_payments.lock().unwrap();
if let Some(payment) = claimable_payments.claimable_payments.remove(&payment_hash) {
let mut receiver_node_id = self.our_network_pubkey;
if let events::PaymentPurpose::InvoicePayment { payment_secret, .. } = payment.purpose {
if let Ok(_) = self.get_payment_preimage(payment_hash, payment_secret) {
let mut pending_events_lock = self.pending_events.lock().unwrap();
pending_events_lock.push_back((Event::PaymentClaimed { receiver_node_id: Some(receiver_node_id), payment_hash,
amount_msat: payment.amount_msat.unwrap(), purpose: payment.purpose, htlcs: vec![], sender_intended_total_msat: None }, None));
return;
}
}
for htlc in payment.htlcs.iter() {
if htlc.prev_hop.phantom_shared_secret.is_some() {
let phantom_pubkey = self.node_signer.get_node_id(Recipient::PhantomNode)
Expand Down Expand Up @@ -10584,14 +10608,14 @@ where
purposes.into_iter().zip(onion_fields.into_iter().zip(claimable_htlcs_list.into_iter()))
{
let existing_payment = claimable_payments.insert(payment_hash, ClaimablePayment {
purpose, htlcs, onion_fields: onion,
purpose, htlcs, onion_fields: onion, amount_msat: None,
});
if existing_payment.is_some() { return Err(DecodeError::InvalidValue); }
}
} else {
for (purpose, (payment_hash, htlcs)) in purposes.into_iter().zip(claimable_htlcs_list.into_iter()) {
let existing_payment = claimable_payments.insert(payment_hash, ClaimablePayment {
purpose, htlcs, onion_fields: None,
purpose, htlcs, onion_fields: None, amount_msat: None,
});
if existing_payment.is_some() { return Err(DecodeError::InvalidValue); }
}
Expand Down Expand Up @@ -10625,7 +10649,7 @@ where
events::PaymentPurpose::SpontaneousPayment(*payment_preimage),
};
claimable_payments.insert(payment_hash, ClaimablePayment {
purpose, htlcs, onion_fields: None,
purpose, htlcs, onion_fields: None, amount_msat: None,
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/ln/outbound_payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::secp256k1::{self, Secp256k1, SecretKey};

use crate::sign::{EntropySource, NodeSigner, Recipient};
use crate::events::{self, PaymentFailureReason, Event, PaymentPurpose};
use crate::events::{self, PaymentFailureReason, Event};
use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use crate::ln::channelmanager::{ChannelDetails, EventCompletionAction, HTLCSource, PaymentId};
use crate::ln::onion_utils::{DecodedOnionFailure, HTLCFailReason};
Expand Down

0 comments on commit c1a2bf4

Please sign in to comment.