xpay: added subtrace to measure getroutes
What changed, and why it matters
This change adds a small tracing wrapper around an internal function call so developers can measure how long route-finding takes. It does not change payment logic, amounts, routing decisions, or network behavior. There is no indication it fixes a security issue or introduces a vulnerability.
No security action required. Treat as a normal observability/instrumentation change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit introduces a struct getroutes_request that holds a struct payment * and wraps the existing getroutes JSON-RPC request in xpay. Callback signatures for getroutes_done and getroutes_done_err are updated to receive the wrapper, which is freed in both success and error paths. Trace span calls (trace_span_resume, trace_span_start, trace_span_end, trace_span_suspend) are added around the getroutes call to measure its execution time. The functional code that builds the request, parses the response, and continues the payment is unchanged.
Changed components
plugins/xpay/xpay.cInspect captured patch +29 / −4
diff --git a/plugins/xpay/xpay.c b/plugins/xpay/xpay.c
index 9dc7b1cd..7d214ae9 100644
--- a/plugins/xpay/xpay.c
+++ b/plugins/xpay/xpay.c
@@ -1606,16 +1606,28 @@ static void add_cltv_shadow(struct payment *payment,
}
}
+/* Just a wrapper around payment so that we can trace the execution time of a
+ * getroutes request. */
+struct getroutes_request {
+ struct payment *payment;
+};
+
static struct command_result *getroutes_done(struct command *aux_cmd,
const char *method,
const char *buf,
const jsmntok_t *result,
- struct payment *payment)
+ struct getroutes_request *getroutes_request)
{
const jsmntok_t *t, *routes;
size_t i;
struct amount_msat needs_routing, was_routing;
+ struct payment *payment = getroutes_request->payment;
struct gossmap *gossmap = get_gossmap(xpay_of(payment->plugin));
+ trace_span_resume(payment);
+ trace_span_resume(getroutes_request);
+ trace_span_end(getroutes_request);
+ trace_span_suspend(payment);
+ tal_free(getroutes_request);
payment_log(payment, LOG_DBG, "getroutes_done: %s",
payment->cmd ? "continuing" : "ignoring");
@@ -1726,8 +1738,14 @@ static struct command_result *getroutes_done_err(struct command *aux_cmd,
const char *method,
const char *buf,
const jsmntok_t *error,
- struct payment *payment)
-{
+ struct getroutes_request *getroutes_request)
+{
+ struct payment *payment = getroutes_request->payment;
+ trace_span_resume(payment);
+ trace_span_resume(getroutes_request);
+ trace_span_end(getroutes_request);
+ trace_span_suspend(payment);
+ tal_free(getroutes_request);
int code;
const char *msg, *complaint;
@@ -1856,10 +1874,17 @@ static struct command_result *getroutes_for(struct command *aux_cmd,
maxfee = AMOUNT_MSAT(0);
}
+ struct getroutes_request *getroutes_request =
+ tal(payment, struct getroutes_request);
+ getroutes_request->payment = payment;
+ trace_span_resume(payment); // payment is the parent span
+ trace_span_start("xpay/getroutes", getroutes_request);
+ trace_span_suspend(getroutes_request);
+ trace_span_suspend(payment);
req = jsonrpc_request_start(aux_cmd, "getroutes",
getroutes_done,
getroutes_done_err,
- payment);
+ getroutes_request);
json_add_pubkey(req->js, "source", &xpay->local_id);
json_add_pubkey(req->js, "destination", dst);
Why this scored 13/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.