Fix BOLT11 annotation loss after sendonion failure
What changed, and why it matters
This commit fixes a bookkeeping bug in Core Lightning's payment plugin. When a user pays a BOLT11 invoice using the `pay` command, the plugin can retry the payment if the first attempt fails early. Previously, a flag was set too soon, causing retries to omit the original invoice string. If a retry then succeeded, the stored payment record would permanently lack the BOLT11 invoice information. The fix moves the flag so it is only set after `sendonion` succeeds, ensuring the invoice string is included on every retry attempt. This is a data-integrity/user-experience bug, not a security vulnerability.
Treat as a routine bug fix. No immediate security response required. Users relying on accurate `listpays` BOLT11 metadata should upgrade to a release containing this commit.
Security signals we found
State-management bug in payment retry logic
Loss of BOLT11 invoice metadata in persistent payment records
Fix is localized and conservative (minor redundancy accepted for cleaner state)
No evidence of malicious exploitation or memory-safety issues
Evidence from the diff
In plugins/libplugin-pay.c, root->invstring_used was being set in payment_createonion_success, which runs when the onion is created but before the sendonion RPC completes. If sendonion failed before persisting the payment, subsequent retries would see invstring_used == true and skip adding the bolt11 parameter. A successful retry would then save the payment without the BOLT11 annotation. The patch moves the invstring_used = true assignment into payment_sendonion_success, so the flag is only set once sendonion has actually succeeded. The BOLT11 string is now redundantly included on every retry until the first success.
Changed components
plugins/libplugin-pay.cpayment_sendonion_successpayment_createonion_successBOLT11 invoice annotation in payment database recordsInspect captured patch +5 / −2
diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c
index 3c8b9d60..cb212236 100644
--- a/plugins/libplugin-pay.c
+++ b/plugins/libplugin-pay.c
@@ -1702,6 +1702,11 @@ static struct command_result *payment_sendonion_success(struct command *cmd,
struct payment *p)
{
struct out_req *req;
+ struct payment *root = payment_root(p);
+
+ if (p->invstring)
+ root->invstring_used = true;
+
req = jsonrpc_request_start(payment_cmd(p), "waitsendpay",
payment_waitsendpay_finished,
payment_waitsendpay_finished, p);
@@ -1764,8 +1769,6 @@ static struct command_result *payment_createonion_success(struct command *cmd,
if (p->description)
json_add_string(req->js, "description", p->description);
-
- root->invstring_used = true;
}
if (p->pay_destination)
Why this scored 30/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.