Browse Source

paymod: Add the contents of paystatus

This proved to be rather difficult given the tight coupling of the old structs
and the output of the command.
keysend
Christian Decker 5 years ago
parent
commit
3a35dd34ac
  1. 30
      plugins/libplugin-pay.c
  2. 100
      plugins/pay.c

30
plugins/libplugin-pay.c

@ -473,6 +473,34 @@ static void channel_hints_update(struct payment *root,
tal_arr_expand(&root->channel_hints, hint);
}
/* Try to infer the erring_node, erring_channel and erring_direction from what
* we know, but don't override the values that are returned by `waitsendpay`. */
static void payment_result_infer(struct route_hop *route,
struct payment_result *r)
{
int i, len = tal_count(route);
if (r->code == 0 || r->erring_index == NULL || route == NULL)
return;
i = *r->erring_index;
assert(i <= len);
if (r->erring_node == NULL)
r->erring_node = &route[i-1].nodeid;
/* The above assert was enough for the erring_node, but might be off
* by one on channel and direction, in case the destination failed on
* us. */
if (i == len)
return;
if (r->erring_channel == NULL)
r->erring_channel = &route[i].channel_id;
if (r->erring_direction == NULL)
r->erring_direction = &route[i].direction;
}
static struct command_result *
payment_waitsendpay_finished(struct command *cmd, const char *buffer,
const jsmntok_t *toks, struct payment *p)
@ -482,6 +510,7 @@ payment_waitsendpay_finished(struct command *cmd, const char *buffer,
assert(p->route != NULL);
p->result = tal_sendpay_result_from_json(p, buffer, toks);
payment_result_infer(p->route, p->result);
if (p->result == NULL)
plugin_err(
@ -490,6 +519,7 @@ payment_waitsendpay_finished(struct command *cmd, const char *buffer,
if (p->result->state == PAYMENT_COMPLETE) {
p->step = PAYMENT_STEP_SUCCESS;
p->end_time = time_now();
payment_continue(p);
return command_still_pending(cmd);
}

100
plugins/pay.c

@ -1453,6 +1453,77 @@ static void add_attempt(struct json_stream *ret,
json_object_end(ret);
}
static void json_add_sendpay_result(struct json_stream *s, const struct payment_result *r)
{
if (r->code != 0) {
/* This is a failure */
json_add_string(s, "message", r->message);
json_add_u32(s, "code", r->code);
json_object_start(s, "data");
json_add_u32(s, "id", r->id);
json_add_hex(s, "raw_message", r->raw_message, tal_bytelen(r->raw_message));
json_add_num(s, "failcode", r->failcode);
json_add_string(s, "failcodename", r->failcodename);
if (r->erring_index)
json_add_num(s, "erring_index", *r->erring_index);
if (r->erring_node)
json_add_node_id(s, "erring_node", r->erring_node);
if (r->erring_channel)
json_add_short_channel_id(s, "erring_channel",
r->erring_channel);
if (r->erring_direction)
json_add_num(s, "erring_direction",
*r->erring_direction);
if (r->erring_node)
json_add_node_id(s, "erring_node", r->erring_node);
json_object_end(s);
} else {
/* This is a success */
json_add_u32(s, "id", r->id);
json_add_preimage(s, "payment_preimage", r->payment_preimage);
}
}
static void paystatus_add_payment(struct json_stream *s, const struct payment *p)
{
char timestr[UTC_TIMELEN];
utc_timestring(&p->start_time, timestr);
json_object_start(s, NULL);
json_add_string(s, "start_time", timestr);
json_add_u64(s, "age_in_seconds",
time_to_sec(time_between(time_now(), p->start_time)));
/* Any final state will have an end time. */
if (p->step >= PAYMENT_STEP_SPLIT) {
utc_timestring(&p->end_time, timestr);
json_add_string(s, "end_time", timestr);
}
/* TODO Add routehint. */
/* TODO Add route details */
if (p->result != NULL) {
if (p->step == PAYMENT_STEP_SUCCESS)
json_object_start(s, "success");
else
json_object_start(s, "failure");
json_add_sendpay_result(s, p->result);
json_object_end(s);
}
json_object_end(s);
for (size_t i = 0; i < tal_count(p->children); i++)
paystatus_add_payment(s, p->children[i]);
}
static struct command_result *json_paystatus(struct command *cmd,
const char *buf,
const jsmntok_t *params)
@ -1460,6 +1531,7 @@ static struct command_result *json_paystatus(struct command *cmd,
struct pay_status *ps;
const char *b11str;
struct json_stream *ret;
struct payment *p;
if (!param(cmd, buf, params,
p_opt("bolt11", param_string, &b11str),
@ -1470,6 +1542,7 @@ static struct command_result *json_paystatus(struct command *cmd,
json_array_start(ret, "pay");
/* FIXME: Index by bolt11 string! */
/* TODO(cdecker) Remove once we migrated to `pay` with modifiers. */
list_for_each(&pay_status, ps, list) {
if (b11str && !streq(b11str, ps->bolt11))
continue;
@ -1499,6 +1572,33 @@ static struct command_result *json_paystatus(struct command *cmd,
json_array_end(ret);
json_object_end(ret);
}
list_for_each(&payments, p, list) {
assert(p->parent == NULL);
if (b11str && !streq(b11str, p->bolt11))
continue;
json_object_start(ret, NULL);
if (p->bolt11)
json_add_string(ret, "bolt11", p->bolt11);
json_add_amount_msat_only(ret, "amount_msat", p->amount);
json_add_string(
ret, "amount_msat",
type_to_string(tmpctx, struct amount_msat, &p->amount));
json_add_node_id(ret, "destination", p->destination);
/* TODO(cdecker) Add label in once we track labels. */
/* TODO(cdecker) Add routehint_modifications in once we track
* them. */
/* TODO(cdecker) Add shadow route once we support it. */
/* If it's in listpeers right now, this can be 0 */
json_array_start(ret, "attempts");
paystatus_add_payment(ret, p);
json_array_end(ret);
json_object_end(ret);
}
json_array_end(ret);
return command_finished(cmd, ret);

Loading…
Cancel
Save