xpay: keep track of ongoing payments, to implement attempt_ongoing()
What changed, and why it matters
This commit is a straightforward internal bookkeeping change in the xpay plugin. It adds a list that tracks currently active payments and a helper function to check whether a payment is still in progress. There is no security fix or vulnerability here; it is preparation for a future feature (making listpays aware of xpay payments).
No security action required. Review as normal feature/refactoring code.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces an xpay.h header and modifies plugins/xpay/xpay.c to maintain a doubly-linked list of struct payment objects inside struct xpay. It initializes the list at plugin startup, adds payments to the list on creation, removes them via a tal destructor, and exports attempt_ongoing(plugin, payment_hash) to query whether a payment with a given hash is still active. The commit message explicitly frames this as groundwork for listpays integration.
Changed components
plugins/xpay/xpay.cplugins/xpay/xpay.hInspect captured patch +40 / −0
diff --git a/plugins/xpay/xpay.c b/plugins/xpay/xpay.c
index c5356158..385e9abc 100644
--- a/plugins/xpay/xpay.c
+++ b/plugins/xpay/xpay.c
@@ -25,13 +25,17 @@
#include <errno.h>
#include <inttypes.h>
#include <plugins/libplugin.h>
+#include <plugins/xpay/xpay.h>
#include <stdarg.h>
#define PREIMAGE_TLV_TYPE 5482373484
/* For the whole plugin */
struct xpay {
+ /* This is me. */
struct pubkey local_id;
+ /* These are my struct payments */
+ struct list_head payments;
/* Access via get_gossmap() */
struct gossmap *global_gossmap;
/* Creates unique layer names */
@@ -62,6 +66,8 @@ static struct gossmap *get_gossmap(struct xpay *xpay)
/* The unifies bolt11 and bolt12 handling */
struct payment {
+ /* Inside xpay->payments */
+ struct list_node list;
struct plugin *plugin;
/* Stop sending new payments after this */
struct timemono deadline;
@@ -2306,6 +2312,13 @@ static struct command_result *json_xpay_params(struct command *cmd,
label, localinvreqid, *dev_use_shadow, as_pay);
}
+static void destroy_payment(struct payment *payment)
+{
+ struct xpay *xpay = xpay_of(payment->plugin);
+
+ list_del_from(&xpay->payments, &payment->list);
+}
+
/* Does NOT set:
* ->maxparts
* ->use_shadow
@@ -2401,9 +2414,23 @@ static struct payment *new_payment(const tal_t *ctx,
payment->private_layer = tal_fmt(payment,
"xpay-%"PRIu64, payment->unique_id);
+ list_add_tail(&xpay->payments, &payment->list);
+ tal_add_destructor(payment, destroy_payment);
return payment;
}
+bool attempt_ongoing(struct plugin *plugin, const struct sha256 *payment_hash)
+{
+ struct xpay *xpay = xpay_of(plugin);
+ const struct payment *payment;
+
+ list_for_each(&xpay->payments, payment, list) {
+ if (sha256_eq(&payment->payment_hash, payment_hash))
+ return true;
+ }
+ return false;
+}
+
static struct command_result *xpay_core(struct command *cmd,
const char *invstring TAKES,
const struct amount_msat *msat,
@@ -3140,6 +3167,7 @@ int main(int argc, char *argv[])
xpay->take_over_pay = true;
xpay->slow_mode = false;
xpay->dev_no_age = false;
+ list_head_init(&xpay->payments);
plugin_main(argv, init, take(xpay),
PLUGIN_RESTARTABLE, true, NULL,
commands, ARRAY_SIZE(commands),
diff --git a/plugins/xpay/xpay.h b/plugins/xpay/xpay.h
new file mode 100644
index 00000000..886380d5
--- /dev/null
+++ b/plugins/xpay/xpay.h
@@ -0,0 +1,12 @@
+#ifndef LIGHTNING_PLUGINS_XPAY_XPAY_H
+#define LIGHTNING_PLUGINS_XPAY_XPAY_H
+#include "config.h"
+#include <stdbool.h>
+
+struct plugin;
+struct sha256;
+
+/* Are we still attempting this payment? If so, we won't list is as failed. */
+bool attempt_ongoing(struct plugin *plugin, const struct sha256 *payment_hash);
+
+#endif /* LIGHTNING_PLUGINS_XPAY_XPAY_H */
Why this scored 15/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.