mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 07:04:22 +01:00
plugins/libplugin-pay.c: Give cmd id and partid for each log message.
Changelog-None: internal debugging Makes it easier to debug payments with tons of splits.
This commit is contained in:
committed by
Christian Decker
parent
e80d733399
commit
98583e84b5
@@ -13,6 +13,9 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
||||
struct payment_modifier **mods)
|
||||
{
|
||||
struct payment *p = tal(ctx, struct payment);
|
||||
|
||||
static u64 next_id = 0;
|
||||
|
||||
p->children = tal_arr(p, struct payment *, 0);
|
||||
p->parent = parent;
|
||||
p->modifiers = mods;
|
||||
@@ -46,6 +49,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
||||
p->deadline = parent->deadline;
|
||||
|
||||
p->invoice = parent->invoice;
|
||||
p->id = parent->id;
|
||||
} else {
|
||||
assert(cmd != NULL);
|
||||
p->partid = 0;
|
||||
@@ -53,6 +57,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
|
||||
p->plugin = cmd->plugin;
|
||||
p->channel_hints = tal_arr(p, struct channel_hint, 0);
|
||||
p->excluded_nodes = tal_arr(p, struct node_id, 0);
|
||||
p->id = next_id++;
|
||||
}
|
||||
|
||||
/* Initialize all modifier data so we can point to the fields when
|
||||
@@ -79,6 +84,59 @@ struct payment *payment_root(struct payment *p)
|
||||
return payment_root(p->parent);
|
||||
}
|
||||
|
||||
static void
|
||||
paymod_log_header(struct payment *p, const char **type, u64 *id)
|
||||
{
|
||||
struct payment *root = payment_root(p);
|
||||
/* We prefer to show the command ID here since it is also known
|
||||
* by `lightningd`, so in theory it can be used to correlate
|
||||
* debugging logs between the main `lightningd` and whatever
|
||||
* plugin is using the paymod system.
|
||||
* We only fall back to a unique id per root payment if there
|
||||
* is no command with an id associated with this payment.
|
||||
*/
|
||||
if (root->cmd && root->cmd->id) {
|
||||
*type = "cmd";
|
||||
*id = *root->cmd->id;
|
||||
} else {
|
||||
*type = "id";
|
||||
*id = root->id;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
paymod_log(struct payment *p, enum log_level l, const char *fmt, ...)
|
||||
{
|
||||
const char *type;
|
||||
u64 id;
|
||||
char *txt;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
txt = tal_vfmt(tmpctx, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
paymod_log_header(p, &type, &id);
|
||||
plugin_log(p->plugin, l, "%s %"PRIu64" partid %"PRIu32": %s",
|
||||
type, id, p->partid, txt);
|
||||
}
|
||||
static void
|
||||
paymod_err(struct payment *p, const char *fmt, ...)
|
||||
{
|
||||
const char *type;
|
||||
u64 id;
|
||||
char *txt;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
txt = tal_vfmt(tmpctx, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
paymod_log_header(p, &type, &id);
|
||||
plugin_err(p->plugin, "%s %"PRIu64" partid %"PRIu32": %s",
|
||||
type, id, p->partid, txt);
|
||||
}
|
||||
|
||||
/* Generic handler for RPC failures that should end up failing the payment. */
|
||||
static struct command_result *payment_rpc_failure(struct command *cmd,
|
||||
const char *buffer,
|
||||
@@ -119,8 +177,8 @@ struct payment_tree_result payment_collect_result(struct payment *p)
|
||||
/* Some of our subpayments have succeeded, aggregate how much
|
||||
* we sent in total. */
|
||||
if (!amount_msat_add(&res.sent, res.sent, cres.sent))
|
||||
plugin_err(
|
||||
p->plugin,
|
||||
paymod_err(
|
||||
p,
|
||||
"Number overflow summing partial payments: %s + %s",
|
||||
type_to_string(tmpctx, struct amount_msat,
|
||||
&res.sent),
|
||||
@@ -228,8 +286,8 @@ static void channel_hints_update(struct payment *p,
|
||||
|
||||
tal_arr_expand(&root->channel_hints, hint);
|
||||
|
||||
plugin_log(
|
||||
root->plugin, LOG_DBG,
|
||||
paymod_log(
|
||||
p, LOG_DBG,
|
||||
"Added a channel hint for %s: enabled %s, estimated capacity %s",
|
||||
type_to_string(tmpctx, struct short_channel_id_dir, &hint.scid),
|
||||
hint.enabled ? "true" : "false",
|
||||
@@ -244,7 +302,7 @@ static void payment_exclude_most_expensive(struct payment *p)
|
||||
|
||||
for (size_t i = 0; i < tal_count(p->route)-1; i++) {
|
||||
if (!amount_msat_sub(&fee, p->route[i].amount, p->route[i+1].amount))
|
||||
plugin_err(p->plugin, "Negative fee in a route.");
|
||||
paymod_err(p, "Negative fee in a route.");
|
||||
|
||||
if (amount_msat_greater_eq(fee, worst)) {
|
||||
e = &p->route[i];
|
||||
@@ -275,8 +333,8 @@ static struct amount_msat payment_route_fee(struct payment *p)
|
||||
{
|
||||
struct amount_msat fee;
|
||||
if (!amount_msat_sub(&fee, p->route[0].amount, p->amount)) {
|
||||
plugin_log(
|
||||
p->plugin,
|
||||
paymod_log(
|
||||
p,
|
||||
LOG_BROKEN,
|
||||
"gossipd returned a route with a negative fee: sending %s "
|
||||
"to deliver %s",
|
||||
@@ -353,8 +411,8 @@ static void payment_chanhints_apply_route(struct payment *p, bool remove)
|
||||
* concurrent getroute calls using the
|
||||
* same channel_hints, no biggy, it's
|
||||
* an estimation anyway. */
|
||||
plugin_log(
|
||||
p->plugin, LOG_UNUSUAL,
|
||||
paymod_log(
|
||||
p, LOG_UNUSUAL,
|
||||
"Could not update the channel hint "
|
||||
"for %s. Could be a concurrent "
|
||||
"`getroute` call.",
|
||||
@@ -405,7 +463,7 @@ static struct command_result *payment_getroute_result(struct command *cmd,
|
||||
/* Now update the constraints in fee_budget and cltv_budget so
|
||||
* modifiers know what constraints they need to adhere to. */
|
||||
if (!payment_constraints_update(&p->constraints, fee, p->route[0].delay)) {
|
||||
plugin_log(p->plugin, LOG_BROKEN,
|
||||
paymod_log(p, LOG_BROKEN,
|
||||
"Could not update constraints.");
|
||||
abort();
|
||||
}
|
||||
@@ -704,13 +762,13 @@ static void report_tampering(struct payment *p,
|
||||
const struct node_id *id = &p->route[report_pos].nodeid;
|
||||
|
||||
if (report_pos == 0) {
|
||||
plugin_log(p->plugin, LOG_UNUSUAL,
|
||||
paymod_log(p, LOG_UNUSUAL,
|
||||
"Node #%zu (%s) claimed we sent them invalid %s",
|
||||
report_pos + 1,
|
||||
type_to_string(tmpctx, struct node_id, id),
|
||||
style);
|
||||
} else {
|
||||
plugin_log(p->plugin, LOG_UNUSUAL,
|
||||
paymod_log(p, LOG_UNUSUAL,
|
||||
"Node #%zu (%s) claimed #%zu (%s) sent them invalid %s",
|
||||
report_pos + 1,
|
||||
type_to_string(tmpctx, struct node_id, id),
|
||||
@@ -760,7 +818,7 @@ handle_final_failure(struct command *cmd,
|
||||
* otherwise we would set the abort flag too eagerly.
|
||||
*/
|
||||
if (failure_is_blockheight_disagreement(p, &unused)) {
|
||||
plugin_log(p->plugin, LOG_DBG,
|
||||
paymod_log(p, LOG_DBG,
|
||||
"Blockheight disagreement, not aborting.");
|
||||
goto nonerror;
|
||||
}
|
||||
@@ -834,7 +892,7 @@ handle_final_failure(struct command *cmd,
|
||||
}
|
||||
|
||||
strange_error:
|
||||
plugin_log(p->plugin, LOG_UNUSUAL,
|
||||
paymod_log(p, LOG_UNUSUAL,
|
||||
"Final node %s reported strange error code %u",
|
||||
type_to_string(tmpctx, struct node_id, final_id),
|
||||
failcode);
|
||||
@@ -924,7 +982,7 @@ handle_intermediate_failure(struct command *cmd,
|
||||
}
|
||||
|
||||
strange_error:
|
||||
plugin_log(p->plugin, LOG_UNUSUAL,
|
||||
paymod_log(p, LOG_UNUSUAL,
|
||||
"Intermediate node %s reported strange error code %u",
|
||||
type_to_string(tmpctx, struct node_id, errnode),
|
||||
failcode);
|
||||
@@ -988,7 +1046,7 @@ payment_waitsendpay_finished(struct command *cmd, const char *buffer,
|
||||
p->result = tal_sendpay_result_from_json(p, buffer, toks);
|
||||
|
||||
if (p->result == NULL) {
|
||||
plugin_log(p->plugin, LOG_UNUSUAL,
|
||||
paymod_log(p, LOG_UNUSUAL,
|
||||
"Unable to parse `waitsendpay` result: %.*s",
|
||||
json_tok_full_len(toks),
|
||||
json_tok_full(buffer, toks));
|
||||
@@ -1008,7 +1066,7 @@ payment_waitsendpay_finished(struct command *cmd, const char *buffer,
|
||||
payment_chanhints_apply_route(p, true);
|
||||
|
||||
if (!assign_blame(p, &errnode, &errchan)) {
|
||||
plugin_log(p->plugin, LOG_UNUSUAL,
|
||||
paymod_log(p, LOG_UNUSUAL,
|
||||
"No erring_index set in `waitsendpay` result: %.*s",
|
||||
json_tok_full_len(toks),
|
||||
json_tok_full(buffer, toks));
|
||||
@@ -1525,7 +1583,7 @@ void payment_fail(struct payment *p, const char *fmt, ...)
|
||||
p->failreason = tal_vfmt(p, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
plugin_log(p->plugin, LOG_INFORM, "%s", p->failreason);
|
||||
paymod_log(p, LOG_INFORM, "%s", p->failreason);
|
||||
|
||||
payment_continue(p);
|
||||
}
|
||||
@@ -1633,8 +1691,8 @@ static inline void retry_step_cb(struct retry_mod_data *rd,
|
||||
return payment_continue(p);
|
||||
|
||||
if (time_after(now, p->deadline)) {
|
||||
plugin_log(
|
||||
p->plugin, LOG_INFORM,
|
||||
paymod_log(
|
||||
p, LOG_INFORM,
|
||||
"Payment deadline expired, not retrying (partial-)payment "
|
||||
"%s/%d",
|
||||
type_to_string(tmpctx, struct sha256, p->payment_hash),
|
||||
@@ -1663,8 +1721,8 @@ static inline void retry_step_cb(struct retry_mod_data *rd,
|
||||
subpayment->why =
|
||||
tal_fmt(subpayment, "Still have %d attempts left",
|
||||
rdata->retries - 1);
|
||||
plugin_log(
|
||||
p->plugin, LOG_DBG,
|
||||
paymod_log(
|
||||
p, LOG_DBG,
|
||||
"Retrying %s/%d (%s), new partid %d. %d attempts left\n",
|
||||
type_to_string(tmpctx, struct sha256, p->payment_hash),
|
||||
p->partid,
|
||||
@@ -1990,8 +2048,8 @@ static void routehint_pre_getroute(struct routehints_data *d, struct payment *p)
|
||||
p->getroute->cltv =
|
||||
route_cltv(p->getroute->cltv, d->current_routehint,
|
||||
tal_count(d->current_routehint));
|
||||
plugin_log(
|
||||
p->plugin, LOG_DBG, "Using routehint %s (%s) cltv_delta=%d",
|
||||
paymod_log(
|
||||
p, LOG_DBG, "Using routehint %s (%s) cltv_delta=%d",
|
||||
type_to_string(tmpctx, struct node_id,
|
||||
&d->current_routehint->pubkey),
|
||||
type_to_string(tmpctx, struct short_channel_id,
|
||||
@@ -2002,7 +2060,7 @@ static void routehint_pre_getroute(struct routehints_data *d, struct payment *p)
|
||||
* going through the destination to the entrypoint. */
|
||||
p->temp_exclusion = routehint_generate_exclusion_list(p, d->current_routehint, p);
|
||||
} else
|
||||
plugin_log(p->plugin, LOG_DBG, "Not using a routehint");
|
||||
paymod_log(p, LOG_DBG, "Not using a routehint");
|
||||
}
|
||||
|
||||
static struct command_result *routehint_getroute_result(struct command *cmd,
|
||||
@@ -2023,7 +2081,7 @@ static struct command_result *routehint_getroute_result(struct command *cmd,
|
||||
|
||||
routehint_pre_getroute(d, p);
|
||||
|
||||
plugin_log(p->plugin, LOG_DBG,
|
||||
paymod_log(p, LOG_DBG,
|
||||
"The destination is%s directly reachable %s attempts "
|
||||
"without routehints",
|
||||
d->destination_reachable ? "" : " not",
|
||||
@@ -2051,7 +2109,7 @@ static void routehint_check_reachable(struct payment *p)
|
||||
json_add_num(req->js, "maxhops", 20);
|
||||
json_add_num(req->js, "riskfactor", 10);
|
||||
send_outreq(p->plugin, req);
|
||||
plugin_log(p->plugin, LOG_DBG,
|
||||
paymod_log(p, LOG_DBG,
|
||||
"Asking gossipd whether %s is reachable "
|
||||
"without routehints.",
|
||||
type_to_string(tmpctx, struct node_id, p->destination));
|
||||
@@ -2073,7 +2131,7 @@ static void routehint_step_cb(struct routehints_data *d, struct payment *p)
|
||||
d->routehints = filter_routehints(d, p->local_id,
|
||||
p->invoice->routes);
|
||||
|
||||
plugin_log(p->plugin, LOG_DBG,
|
||||
paymod_log(p, LOG_DBG,
|
||||
"After filtering routehints we're left with "
|
||||
"%zu usable hints",
|
||||
tal_count(d->routehints));
|
||||
@@ -2176,8 +2234,8 @@ static void exemptfee_cb(struct exemptfee_data *d, struct payment *p)
|
||||
return payment_continue(p);
|
||||
|
||||
if (amount_msat_greater_eq(d->amount, p->constraints.fee_budget)) {
|
||||
plugin_log(
|
||||
p->plugin, LOG_INFORM,
|
||||
paymod_log(
|
||||
p, LOG_INFORM,
|
||||
"Payment fee constraint %s is below exemption threshold, "
|
||||
"allowing a maximum fee of %s",
|
||||
type_to_string(tmpctx, struct amount_msat, &p->constraints.fee_budget),
|
||||
@@ -2343,8 +2401,8 @@ static struct command_result *shadow_route_listchannels(struct command *cmd,
|
||||
}
|
||||
|
||||
/* Now we can be sure that adding the shadow route will succeed */
|
||||
plugin_log(
|
||||
p->plugin, LOG_DBG,
|
||||
paymod_log(
|
||||
p, LOG_DBG,
|
||||
"Adding shadow_route hop over channel %s: adding %s "
|
||||
"in fees and %d CLTV delta",
|
||||
type_to_string(tmpctx, struct short_channel_id,
|
||||
@@ -2368,7 +2426,7 @@ static struct command_result *shadow_route_listchannels(struct command *cmd,
|
||||
d->constraints.fee_budget, best_fee) ||
|
||||
!amount_msat_sub(&p->constraints.fee_budget,
|
||||
p->constraints.fee_budget, best_fee))
|
||||
plugin_err(p->plugin,
|
||||
paymod_err(p,
|
||||
"Could not update fee constraints "
|
||||
"for shadow route extension. "
|
||||
"payment fee budget %s, modifier "
|
||||
@@ -2455,7 +2513,7 @@ static void direct_pay_override(struct payment *p) {
|
||||
p->route[0].direction = hint->scid.dir;
|
||||
p->route[0].nodeid = *p->destination;
|
||||
p->route[0].style = ROUTE_HOP_TLV;
|
||||
plugin_log(p->plugin, LOG_DBG,
|
||||
paymod_log(p, LOG_DBG,
|
||||
"Found a direct channel (%s) with sufficient "
|
||||
"capacity, skipping route computation.",
|
||||
type_to_string(tmpctx, struct short_channel_id_dir,
|
||||
@@ -2565,7 +2623,7 @@ static void waitblockheight_cb(void *d, struct payment *p)
|
||||
if (!failure_is_blockheight_disagreement(p, &blockheight))
|
||||
return payment_continue(p);
|
||||
|
||||
plugin_log(p->plugin, LOG_INFORM,
|
||||
paymod_log(p, LOG_INFORM,
|
||||
"Remote node appears to be on a longer chain, which causes "
|
||||
"CLTV timeouts to be incorrect. Waiting up to %" PRIu64
|
||||
" seconds to catch up to block %d before retrying.",
|
||||
@@ -2742,8 +2800,8 @@ static void presplit_cb(struct presplit_mod_data *d, struct payment *p)
|
||||
c->amount = fuzzed_near(target, amt);
|
||||
|
||||
if (!amount_msat_sub(&amt, amt, c->amount))
|
||||
plugin_err(
|
||||
p->plugin,
|
||||
paymod_err(
|
||||
p,
|
||||
"Cannot subtract %s from %s in splitter",
|
||||
type_to_string(tmpctx, struct amount_msat,
|
||||
&c->amount),
|
||||
@@ -2769,7 +2827,7 @@ static void presplit_cb(struct presplit_mod_data *d, struct payment *p)
|
||||
count,
|
||||
type_to_string(tmpctx, struct amount_msat, &root->amount),
|
||||
type_to_string(tmpctx, struct amount_msat, &target));
|
||||
plugin_log(p->plugin, LOG_INFORM, "%s", p->why);
|
||||
paymod_log(p, LOG_INFORM, "%s", p->why);
|
||||
}
|
||||
payment_continue(p);
|
||||
}
|
||||
@@ -2900,7 +2958,7 @@ static void adaptive_splitter_cb(struct adaptive_split_mod_data *d, struct payme
|
||||
* may end up using an HTLC. */
|
||||
root_data->htlc_budget--;
|
||||
} else {
|
||||
plugin_log(p->plugin, LOG_INFORM,
|
||||
paymod_log(p, LOG_INFORM,
|
||||
"Lower limit of adaptive splitter reached "
|
||||
"(%s < %s), not splitting further.",
|
||||
type_to_string(tmpctx, struct amount_msat,
|
||||
|
||||
@@ -262,6 +262,9 @@ struct payment {
|
||||
* if we switch any of the parameters such as destination or
|
||||
* amount. */
|
||||
bool failroute_retry;
|
||||
|
||||
/* A unique id for the root of this payment. */
|
||||
u64 id;
|
||||
};
|
||||
|
||||
struct payment_modifier {
|
||||
|
||||
Reference in New Issue
Block a user