-
Notifications
You must be signed in to change notification settings - Fork 117
Allow to manually register and claim payments #308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
018a5b6
be6e8c2
d5709b7
74943cd
a678c5e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,6 +84,28 @@ pub enum Event { | |
| /// The value, in thousandths of a satoshi, that has been received. | ||
| amount_msat: u64, | ||
| }, | ||
| /// A payment for a previously-registered payment hash has been received. | ||
| /// | ||
| /// This needs to be manually claimed by supplying the correct preimage to [`claim_for_hash`]. | ||
| /// | ||
| /// If the the provided parameters don't match the expectations or the preimage can't be | ||
| /// retrieved in time, should be failed-back via [`fail_for_hash`]. | ||
| /// | ||
| /// Note claiming will necessarily fail after the `claim_deadline` has been reached. | ||
| /// | ||
| /// [`claim_for_hash`]: crate::payment::Bolt11Payment::claim_for_hash | ||
| /// [`fail_for_hash`]: crate::payment::Bolt11Payment::fail_for_hash | ||
| PaymentClaimable { | ||
| /// A local identifier used to track the payment. | ||
| payment_id: PaymentId, | ||
| /// The hash of the payment. | ||
| payment_hash: PaymentHash, | ||
| /// The value, in thousandths of a satoshi, that is claimable. | ||
| claimable_amount_msat: u64, | ||
| /// The block height at which this payment will be failed back and will no longer be | ||
| /// eligible for claiming. | ||
| claim_deadline: Option<u32>, | ||
| }, | ||
| /// A channel has been created and is pending confirmation on-chain. | ||
| ChannelPending { | ||
| /// The `channel_id` of the channel. | ||
|
|
@@ -156,6 +178,12 @@ impl_writeable_tlv_based_enum!(Event, | |
| (1, counterparty_node_id, option), | ||
| (2, user_channel_id, required), | ||
| (3, reason, upgradable_option), | ||
| }, | ||
| (6, PaymentClaimable) => { | ||
| (0, payment_hash, required), | ||
| (2, payment_id, required), | ||
| (4, claimable_amount_msat, required), | ||
| (6, claim_deadline, option), | ||
| }; | ||
| ); | ||
|
|
||
|
|
@@ -434,12 +462,31 @@ where | |
| receiver_node_id: _, | ||
| via_channel_id: _, | ||
| via_user_channel_id: _, | ||
| claim_deadline: _, | ||
| claim_deadline, | ||
| onion_fields: _, | ||
| counterparty_skimmed_fee_msat, | ||
| } => { | ||
| let payment_id = PaymentId(payment_hash.0); | ||
| if let Some(info) = self.payment_store.get(&payment_id) { | ||
| if info.direction == PaymentDirection::Outbound { | ||
| log_info!( | ||
| self.logger, | ||
| "Refused inbound payment with ID {}: circular payments are unsupported.", | ||
| payment_id | ||
| ); | ||
| self.channel_manager.fail_htlc_backwards(&payment_hash); | ||
|
|
||
| let update = PaymentDetailsUpdate { | ||
| status: Some(PaymentStatus::Failed), | ||
| ..PaymentDetailsUpdate::new(payment_id) | ||
| }; | ||
| self.payment_store.update(&update).unwrap_or_else(|e| { | ||
| log_error!(self.logger, "Failed to access payment store: {}", e); | ||
| panic!("Failed to access payment store"); | ||
| }); | ||
| return; | ||
| } | ||
|
|
||
| if info.status == PaymentStatus::Succeeded | ||
| || matches!(info.kind, PaymentKind::Spontaneous { .. }) | ||
| { | ||
|
|
@@ -500,6 +547,38 @@ where | |
| }); | ||
| return; | ||
| } | ||
|
|
||
| // If this is known by the store but ChannelManager doesn't know the preimage, | ||
| // the payment has been registered via `_for_hash` variants and needs to be manually claimed via | ||
| // user interaction. | ||
| match info.kind { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I'm currently not fully sure how we'll be able to cover the BOLT12 flow, I refrained from adding a new
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to differentiate them? Checking
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Well, for BOLT12 the flow will be a bit different, as we currently don't register inbound payments with the payment store. We'll then need to mark them as pending in the new event I guess. At that point we could consider whether we want to add a different |
||
| PaymentKind::Bolt11 { preimage, .. } => { | ||
| if purpose.preimage().is_none() { | ||
| debug_assert!( | ||
| preimage.is_none(), | ||
| "We would have registered the preimage if we knew" | ||
| ); | ||
|
|
||
| self.event_queue | ||
| .add_event(Event::PaymentClaimable { | ||
| payment_id, | ||
| payment_hash, | ||
| claimable_amount_msat: amount_msat, | ||
| claim_deadline, | ||
| }) | ||
| .unwrap_or_else(|e| { | ||
| log_error!( | ||
| self.logger, | ||
| "Failed to push to event queue: {}", | ||
| e | ||
| ); | ||
| panic!("Failed to push to event queue"); | ||
| }); | ||
| return; | ||
| } | ||
| }, | ||
| _ => {}, | ||
| } | ||
| } | ||
|
|
||
| log_info!( | ||
|
|
@@ -519,19 +598,21 @@ where | |
| .. | ||
| } => { | ||
| let offer_id = payment_context.offer_id; | ||
| let payment = PaymentDetails { | ||
| id: payment_id, | ||
| kind: PaymentKind::Bolt12Offer { | ||
| hash: Some(payment_hash), | ||
| preimage: payment_preimage, | ||
| secret: Some(payment_secret), | ||
| offer_id, | ||
| }, | ||
| amount_msat: Some(amount_msat), | ||
| direction: PaymentDirection::Inbound, | ||
| status: PaymentStatus::Pending, | ||
| let kind = PaymentKind::Bolt12Offer { | ||
| hash: Some(payment_hash), | ||
| preimage: payment_preimage, | ||
| secret: Some(payment_secret), | ||
| offer_id, | ||
| }; | ||
|
|
||
| let payment = PaymentDetails::new( | ||
| payment_id, | ||
| kind, | ||
| Some(amount_msat), | ||
| PaymentDirection::Inbound, | ||
| PaymentStatus::Pending, | ||
| ); | ||
jkczyz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| match self.payment_store.insert(payment) { | ||
| Ok(false) => (), | ||
| Ok(true) => { | ||
|
|
@@ -559,17 +640,19 @@ where | |
| }, | ||
| PaymentPurpose::SpontaneousPayment(preimage) => { | ||
| // Since it's spontaneous, we insert it now into our store. | ||
| let payment = PaymentDetails { | ||
| id: payment_id, | ||
| kind: PaymentKind::Spontaneous { | ||
| hash: payment_hash, | ||
| preimage: Some(preimage), | ||
| }, | ||
| amount_msat: Some(amount_msat), | ||
| direction: PaymentDirection::Inbound, | ||
| status: PaymentStatus::Pending, | ||
| let kind = PaymentKind::Spontaneous { | ||
| hash: payment_hash, | ||
| preimage: Some(preimage), | ||
| }; | ||
|
|
||
| let payment = PaymentDetails::new( | ||
| payment_id, | ||
| kind, | ||
| Some(amount_msat), | ||
| PaymentDirection::Inbound, | ||
| PaymentStatus::Pending, | ||
| ); | ||
|
|
||
| match self.payment_store.insert(payment) { | ||
| Ok(false) => (), | ||
| Ok(true) => { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.