Skip to content
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

feat: Support re-attempt LN invoice payment #3322

Merged
merged 4 commits into from
Oct 18, 2023

Conversation

m1sterc001guy
Copy link
Contributor

Builds on: #3318 #3319

Fixes: #3248

Intuition: adds an index into the OperationId hash so that multiple attempts to pay the same invoice are allowed. When creating the contract, the client checks to see if the contract (incoming or outgoing) already exists, and returns an error if it already does. If it does not, the index is incremented and committed to the database (this serves as a de-facto lock which prevents multiple threads from payment the same invoice at the same time).

When the payment is successful, the PayType and ContractId are stored in the database, which allows subsequent payment attempts to just lookup the succuessful payment in the operation log, rather than re-initiating the payment.

Open to suggestions on how to better test this.

@codecov
Copy link

codecov bot commented Oct 2, 2023

Codecov Report

Attention: 34 lines in your changes are missing coverage. Please review.

Comparison is base (c83d7a9) 60.16% compared to head (f049733) 60.34%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3322       /-   ##
==========================================
  Coverage   60.16%   60.34%    0.18%     
==========================================
  Files         193      193              
  Lines       40361    40510      149     
==========================================
  Hits        24283    24447      164     
  Misses      16078    16063      -15     
Files Coverage Δ
fedimint-client/src/lib.rs 77.68% <100.00%> ( 0.18%) ⬆️
gateway/ln-gateway/src/state_machine/mod.rs 91.38% <100.00%> ( 0.02%) ⬆️
modules/fedimint-ln-client/src/db.rs 33.33% <66.66%> ( 16.66%) ⬆️
modules/fedimint-ln-client/src/incoming.rs 88.43% <93.33%> ( 0.16%) ⬆️
modules/fedimint-ln-client/src/pay.rs 90.47% <96.87%> ( 4.62%) ⬆️
fedimint-load-test-tool/src/common.rs 0.00% <0.00%> (ø)
fedimint-wasm-tests/src/lib.rs 0.00% <0.00%> (ø)
fedimint-cli/src/client.rs 0.00% <0.00%> (ø)
modules/fedimint-ln-client/src/lib.rs 87.92% <80.19%> (-0.58%) ⬇️

... and 18 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@m1sterc001guy m1sterc001guy marked this pull request as ready for review October 3, 2023 18:58
@m1sterc001guy m1sterc001guy requested review from a team as code owners October 3, 2023 18:58
modules/fedimint-ln-common/src/api.rs Outdated Show resolved Hide resolved
modules/fedimint-ln-client/src/lib.rs Outdated Show resolved Hide resolved
elsirion
elsirion previously approved these changes Oct 13, 2023
Copy link
Contributor

@elsirion elsirion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good enough, I have some ideas how to improve, but happy to merge.

modules/fedimint-ln-client/src/lib.rs Show resolved Hide resolved
@elsirion elsirion added this pull request to the merge queue Oct 18, 2023
Merged via the queue into fedimint:master with commit e536500 Oct 18, 2023
19 checks passed
@justinmoon
Copy link
Contributor

Call: @m1sterc001guy could you backport if easy

@m1sterc001guy
Copy link
Contributor Author

This one is unfortunately difficult. Major conflicts in lots of files :/

@TonyGiorgio
Copy link
Contributor

@justinmoon @m1sterc001guy curious if this one ended up being backported to 0.2. I ran into this, and combined with the lack of canceled state update (#4014), causes some problems on our side. I think it's pretty common for users to attempt a payment again if the first one failed.

@m1sterc001guy
Copy link
Contributor Author

Yes, I see it in the release branch, here is one of the commits. What issue are you seeing? Maybe it's not covered by this fix.

@TonyGiorgio
Copy link
Contributor

TonyGiorgio commented Jan 9, 2024

Seems like it timed out making the payment, refunded the ecash, then another attempt at paying the same invoice has issues.

Here's some logs:

docker-lnd-1          | 2024-01-09 16:15:38.764 [ERR] CRTR: Payment 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757 failed: timeout                                                                           
docker-gatewayd-1     | 2024-01-09T16:15:38.763931Z  INFO ln_gateway::lnd: LND payment failed for invoice PrunedInvoice { amount: Amount { msats: 200000000 }, ....

...

docker-gatewayd-1     | 2024-01-09T16:15:38.764442Z  WARN ln_gateway::state_machine::pay: Failed to buy preimage with Payment failed: FailureReasonTimeout for contract OutgoingContractAccount { amount: Amount { msats: 20200
1000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12c
b436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(37fafdb56876e649ef187b4e77f28ca5f7b9617acc7e38133419a236ed8cc55f1a67468217c71267d06afae9be094b3f14ba8173e6a7e5229557ee67fd948c1b), cancelled: fal
se } }
docker-gatewayd-1     | 2024-01-09T16:15:38.764637Z  INFO state_machine_transition{operation_id=ea3cde29a10e9a9305bb5d9f27b9acad70074f79b28db4c7b499f7676f674f68}: fedimint_client::sm::executor: Executing state transition
docker-gatewayd-1     | 2024-01-09T16:15:38.765518Z  INFO state_machine_transition{operation_id=ea3cde29a10e9a9305bb5d9f27b9acad70074f79b28db4c7b499f7676f674f68}: fedimint_client::sm::executor: Executing state transition
docker-gatewayd-1     | 2024-01-09T16:15:38.765563Z  INFO state_machine_transition{operation_id=ea3cde29a10e9a9305bb5d9f27b9acad70074f79b28db4c7b499f7676f674f68}: ln_gateway::state_machine::pay: Canceling outgoing contract 
OutgoingContractAccount { amount: Amount { msats: 202001000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d
53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(37fafdb56876e649ef187b4e77f28ca5f7b9617acc7e38133419a236ed8cc55f1a67468217c71267d06afae9be
094b3f14ba8173e6a7e5229557ee67fd948c1b), cancelled: false } }
docker-gatewayd-1     | 2024-01-09T16:15:38.765919Z  INFO state_machine_transition{operation_id=ea3cde29a10e9a9305bb5d9f27b9acad70074f79b28db4c7b499f7676f674f68}: ln_gateway::state_machine::pay: Canceled outgoing contract O
utgoingContractAccount { amount: Amount { msats: 202001000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d5
3b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(37fafdb56876e649ef187b4e77f28ca5f7b9617acc7e38133419a236ed8cc55f1a67468217c71267d06afae9be0
94b3f14ba8173e6a7e5229557ee67fd948c1b), cancelled: false } } with txid ad780a45debf7f64c538312c542b771e5edb92dbfc70c8b65bda878ad8385d21
docker-gatewayd-1     | 2024-01-09T16:15:39.781542Z  INFO state_machine_transition{operation_id=ea3cde29a10e9a9305bb5d9f27b9acad70074f79b28db4c7b499f7676f674f68}: fedimint_client::sm::executor: Executing state transition

...

docker-gatewayd-1     | 2024-01-09T16:23:59.084254Z  INFO ln_gateway::lnd: LND Paying invoice PrunedInvoice { amount: Amount { msats: 200000000 }, 
destination: PublicKey(028fe7cb1b6cd6bac7f5c9c4eff166fdb73ab861595e5b7f69b099bb32091dccede5828671f691268fc4cf1937989d30aa0a6213c0117103d3e7b553455cf313), destination_features: [2, 66, 0], payment_hash: 1444022cb98afdaf1197c
bc005918b49f7c0f6171f25457a5ef51307a84b8757, payment_secret: [160, 183, 202, 202, 171, 76, 233, 139, 132, 87, 249, 15, 23, 245, 253, 87, 189, 160, 1, 55, 83, 107, 20, 248, 209, 13, 209, 45, 229, 240, 253, 150], route_hints:
 [], min_final_cltv_delta: 80, expiry_timestamp: 1704820307 }
docker-gatewayd-1     | 2024-01-09T16:23:59.133717Z  WARN ln_gateway::state_machine::pay: Failed to buy preimage with Payment failed: FailureReasonTimeout for contract OutgoingContractAccount { amount: Amount { msats: 20200
1000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12c
b436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e423131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: fal
se } }
docker-gatewayd-1     | 2024-01-09T16:23:59.134071Z  INFO state_machine_transition{operation_id=2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5}: fedimint_client::sm::executor: Executing state transition
docker-gatewayd-1     | 2024-01-09T16:23:59.134937Z  INFO state_machine_transition{operation_id=2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5}: fedimint_client::sm::executor: Executing state transition
docker-gatewayd-1     | 2024-01-09T16:23:59.135112Z  INFO pay_invoice: ln_gateway::state_machine: Got state CancelContract(GatewayPayCancelContract { contract: OutgoingContractAccount { amount: Amount { msats: 202001000 }, 
contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f8
64b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e423131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } }, 
error: OutgoingPaymentError { error_type: LightningPayError { lightning_error: FailedPayment { failure_reason: "FailureReasonTimeout" } }, contract_id: 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5, contr
act: Some(OutgoingContractAccount { amount: Amount { msats: 202001000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a9
23ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e4
23131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } }) } }) while awaiting for output of 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5
docker-gatewayd-1     | 2024-01-09T16:23:59.134980Z  INFO state_machine_transition{operation_id=2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5}: ln_gateway::state_machine::pay: Canceling outgoing contract 
OutgoingContractAccount { amount: Amount { msats: 202001000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d
53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e423131b8b3a
dd388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } }
docker-gatewayd-1     | 2024-01-09T16:23:59.136268Z  INFO state_machine_transition{operation_id=2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5}: ln_gateway::state_machine::pay: Canceled outgoing contract O
utgoingContractAccount { amount: Amount { msats: 202001000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d5
3b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e423131b8b3ad
d388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } } with txid a7ce28ee28ae4c9a1c58b04346c083f0e473ab558d5e1a1ee3feece3c1f21d5a
docker-gatewayd-1     | 2024-01-09T16:24:00.149419Z  INFO state_machine_transition{operation_id=2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5}: fedimint_client::sm::executor: Executing state transition
docker-gatewayd-1     | 2024-01-09T16:24:00.150476Z ERROR pay_invoice: ln_gateway: Cancelled with OutgoingContractError: An error occurred while paying the lightning invoice. while paying invoice: 2688a6c02cce1c07af8fe0f0e1
fb13fc9f03da80c8b9c2154b530dc7bd6bded5
docker-gatewayd-1     | 2024-01-09T16:24:00.150534Z ERROR pay_invoice: ln_gateway::rpc::rpc_server: error=Outgoing Payment Error OutgoingContractError: An error occurred while paying the lightning invoice.
docker-gatewayd-1     | 2024-01-09T16:24:02.142045Z  INFO pay_invoice: ln_gateway::state_machine: State machine for operation 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5 already exists, will not add a n
ew one
docker-gatewayd-1     | 2024-01-09T16:24:02.142793Z  INFO pay_invoice: ln_gateway::state_machine: Got state CancelContract(GatewayPayCancelContract { contract: OutgoingContractAccount { amount: Amount { msats: 202001000 }, 
contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f8
64b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e423131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } }, 
error: OutgoingPaymentError { error_type: LightningPayError { lightning_error: FailedPayment { failure_reason: "FailureReasonTimeout" } }, contract_id: 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5, contr
act: Some(OutgoingContractAccount { amount: Amount { msats: 202001000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a9
23ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e4
23131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } }) } }) while awaiting for output of 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5
docker-gatewayd-1     | 2024-01-09T16:24:02.143237Z ERROR pay_invoice: ln_gateway: Cancelled with OutgoingContractError: An error occurred while paying the lightning invoice. while paying invoice: 2688a6c02cce1c07af8fe0f0e1
fb13fc9f03da80c8b9c2154b530dc7bd6bded5
docker-gatewayd-1     | 2024-01-09T16:24:02.143558Z ERROR pay_invoice: ln_gateway::rpc::rpc_server: error=Outgoing Payment Error OutgoingContractError: An error occurred while paying the lightning invoice.
docker-gatewayd-1     | 2024-01-09T16:24:04.369326Z  INFO pay_invoice: ln_gateway::state_machine: State machine for operation 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5 already exists, will not add a n
ew one
docker-gatewayd-1     | 2024-01-09T16:24:04.370007Z  INFO pay_invoice: ln_gateway::state_machine: Got state CancelContract(GatewayPayCancelContract { contract: OutgoingContractAccount { amount: Amount { msats: 202001000 }, 
contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f8
64b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e423131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } }, 
error: OutgoingPaymentError { error_type: LightningPayError { lightning_error: FailedPayment { failure_reason: "FailureReasonTimeout" } }, contract_id: 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5, contr
act: Some(OutgoingContractAccount { amount: Amount { msats: 202001000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a9
23ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e4
23131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } }) } }) while awaiting for output of 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5
docker-gatewayd-1     | 2024-01-09T16:24:04.370180Z ERROR pay_invoice: ln_gateway: Cancelled with OutgoingContractError: An error occurred while paying the lightning invoice. while paying invoice: 2688a6c02cce1c07af8fe0f0e1
fb13fc9f03da80c8b9c2154b530dc7bd6bded5
docker-gatewayd-1     | 2024-01-09T16:24:04.370203Z ERROR pay_invoice: ln_gateway::rpc::rpc_server: error=Outgoing Payment Error OutgoingContractError: An error occurred while paying the lightning invoice.

...

And that error repeats over and over again, presumably due to the lack of canceled update. Is there anything I should do on the client side to ensure that it's a new contract/operational id?

@m1sterc001guy
Copy link
Contributor Author

I think this is another instance of the LN state update stream not yielding the Cancelled state. From your logs, it looks like the previous contract hasn't been cancelled yet:

docker-gatewayd-1     | 2024-01-09T16:24:04.370007Z  INFO pay_invoice: ln_gateway::state_machine: Got state CancelContract(GatewayPayCancelContract { contract: OutgoingContractAccount { amount: Amount { msats: 202001000 },
contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a923ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f8
64b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e423131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } },
error: OutgoingPaymentError { error_type: LightningPayError { lightning_error: FailedPayment { failure_reason: "FailureReasonTimeout" } }, contract_id: 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5, contr
act: Some(OutgoingContractAccount { amount: Amount { msats: 202001000 }, contract: OutgoingContract { hash: 1444022cb98afdaf1197cbc005918b49f7c0f6171f25457a5ef51307a84b8757, gateway_key: PublicKey(b81ca3e6ea9ed786736fa265a9
23ac7af71d53b6b48a40d06c7593433f4cf18d14dc2ce8d12e3771905629cb12cb436f9f864b3f569f5b5f4ba905a3f41cf737), timelock: 825521, user_key: PublicKey(1ef999da47fb3b55d2547a3a0934b4c1ebccd92a651a69f515b9eba7626bc823e48d3415e83ee3e4
23131b8b3add388789f9f6177f6fd01a19555cdcee2c9769), cancelled: false } }) } }) while awaiting for output of 2688a6c02cce1c07af8fe0f0e1fb13fc9f03da80c8b9c2154b530dc7bd6bded5

And since the payment has the same contract id, the gateway won't attempt to re-pay the same contract until the previous one is gone. #4014

Also, when investigating this, I think we also have a bug on the client side where it's possible the client transitions after 30 seconds, but the payment could be successful after that. #4021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support re-attempting LN invoice payment
4 participants