mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-03 05:04:21 +01:00
wallet, payalgo: Save detail of payment failures for later reporting. (#1345)
Pointless for remote failures as those are never sent by the erring node, but for local failures we can give more detail.
This commit is contained in:
committed by
Christian Decker
parent
0eff28c80f
commit
11ca729d85
@@ -515,7 +515,8 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
||||
fail ? fail->failcode : 0,
|
||||
fail ? &fail->erring_node : NULL,
|
||||
fail ? &fail->erring_channel : NULL,
|
||||
fail ? fail->channel_update : NULL);
|
||||
fail ? fail->channel_update : NULL,
|
||||
failmsg);
|
||||
|
||||
/* Report to gossipd if we decided we should. */
|
||||
if (report_to_gossipd)
|
||||
@@ -549,6 +550,7 @@ bool wait_payment(const tal_t *cxt,
|
||||
struct pubkey *failnode;
|
||||
struct short_channel_id *failchannel;
|
||||
u8 *failupdate;
|
||||
char *faildetail;
|
||||
struct routing_failure *fail;
|
||||
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment_hash);
|
||||
@@ -588,7 +590,8 @@ bool wait_payment(const tal_t *cxt,
|
||||
&failcode,
|
||||
&failnode,
|
||||
&failchannel,
|
||||
&failupdate);
|
||||
&failupdate,
|
||||
&faildetail);
|
||||
/* Old DB might not save failure information */
|
||||
if (!failonionreply && !failnode)
|
||||
result = sendpay_result_simple_fail(tmpctx,
|
||||
@@ -596,7 +599,7 @@ bool wait_payment(const tal_t *cxt,
|
||||
"Payment failure reason unknown");
|
||||
else if (failonionreply) {
|
||||
/* failed to parse returned onion error */
|
||||
result = sendpay_result_route_failure(tmpctx, true, NULL, failonionreply, "reply from remote");
|
||||
result = sendpay_result_route_failure(tmpctx, true, NULL, failonionreply, faildetail);
|
||||
} else {
|
||||
/* Parsed onion error, get its details */
|
||||
assert(failnode);
|
||||
@@ -607,7 +610,7 @@ bool wait_payment(const tal_t *cxt,
|
||||
fail->erring_node = *failnode;
|
||||
fail->erring_channel = *failchannel;
|
||||
fail->channel_update = failupdate;
|
||||
result = sendpay_result_route_failure(tmpctx, !faildestperm, fail, NULL, "route failure");
|
||||
result = sendpay_result_route_failure(tmpctx, !faildestperm, fail, NULL, faildetail);
|
||||
}
|
||||
|
||||
cb(result, cbarg);
|
||||
|
||||
@@ -39,6 +39,9 @@ struct pay_failure {
|
||||
/* The routing failure, if TYPE_PAYMENT_REPLY, a tal
|
||||
* object whose parent is this struct */
|
||||
struct routing_failure *routing_failure;
|
||||
/* The detail of the routing failure. A tal_arr
|
||||
* string whose parent is this struct. */
|
||||
char *details;
|
||||
};
|
||||
|
||||
/* Output a pay failure */
|
||||
@@ -48,12 +51,12 @@ json_add_failure(struct json_result *r, char const *n,
|
||||
{
|
||||
struct routing_failure *rf;
|
||||
json_object_start(r, n);
|
||||
json_add_string(r, "message", f->details);
|
||||
switch (f->type) {
|
||||
case FAIL_UNPARSEABLE_ONION:
|
||||
json_add_string(r, "type", "FAIL_UNPARSEABLE_ONION");
|
||||
json_add_hex(r, "onionreply", f->onionreply,
|
||||
tal_len(f->onionreply));
|
||||
json_add_route(r, "route", f->route, tal_count(f->route));
|
||||
break;
|
||||
|
||||
case FAIL_PAYMENT_REPLY:
|
||||
@@ -68,9 +71,9 @@ json_add_failure(struct json_result *r, char const *n,
|
||||
json_add_hex(r, "channel_update",
|
||||
rf->channel_update,
|
||||
tal_len(rf->channel_update));
|
||||
json_add_route(r, "route", f->route, tal_count(f->route));
|
||||
break;
|
||||
}
|
||||
json_add_route(r, "route", f->route, tal_count(f->route));
|
||||
json_object_end(r);
|
||||
}
|
||||
|
||||
@@ -173,6 +176,7 @@ add_pay_failure(struct pay *pay,
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
f->details = tal_strdup(f, r->details);
|
||||
/* Grab the route */
|
||||
f->route = tal_steal(f, pay->route);
|
||||
pay->route = NULL;
|
||||
|
||||
@@ -300,6 +300,12 @@ char *dbmigrations[] = {
|
||||
", rawtx BLOB"
|
||||
", PRIMARY KEY (id)"
|
||||
");",
|
||||
/* -- Detailed payment failure -- */
|
||||
"ALTER TABLE payments ADD faildetail TEXT;",
|
||||
"UPDATE payments"
|
||||
" SET faildetail = 'unspecified payment failure reason'"
|
||||
" WHERE status = 2;", /* PAYMENT_FAILED */
|
||||
/* -- Detailed payment faiure ends -- */
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/peer_control.h>
|
||||
#include <lightningd/peer_htlcs.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SQLITE_MAX_UINT 0x7FFFFFFFFFFFFFFF
|
||||
#define DIRECTION_INCOMING 0
|
||||
@@ -1770,7 +1771,8 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
|
||||
enum onion_type *failcode,
|
||||
struct pubkey **failnode,
|
||||
struct short_channel_id **failchannel,
|
||||
u8 **failupdate)
|
||||
u8 **failupdate,
|
||||
char **faildetail)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
int res;
|
||||
@@ -1781,7 +1783,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
|
||||
"SELECT failonionreply, faildestperm"
|
||||
" , failindex, failcode"
|
||||
" , failnode, failchannel"
|
||||
" , failupdate"
|
||||
" , failupdate, faildetail"
|
||||
" FROM payments"
|
||||
" WHERE payment_hash=?;");
|
||||
sqlite3_bind_sha256(stmt, 1, payment_hash);
|
||||
@@ -1818,6 +1820,8 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
|
||||
*failupdate = tal_arr(ctx, u8, len);
|
||||
memcpy(*failupdate, sqlite3_column_blob(stmt, 6), len);
|
||||
}
|
||||
*faildetail = tal_strndup(ctx, sqlite3_column_blob(stmt, 7),
|
||||
sqlite3_column_bytes(stmt, 7));
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
@@ -1830,7 +1834,8 @@ void wallet_payment_set_failinfo(struct wallet *wallet,
|
||||
enum onion_type failcode,
|
||||
const struct pubkey *failnode,
|
||||
const struct short_channel_id *failchannel,
|
||||
const u8 *failupdate /*tal_arr*/)
|
||||
const u8 *failupdate /*tal_arr*/,
|
||||
const char *faildetail)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
|
||||
@@ -1843,6 +1848,7 @@ void wallet_payment_set_failinfo(struct wallet *wallet,
|
||||
" , failnode=?"
|
||||
" , failchannel=?"
|
||||
" , failupdate=?"
|
||||
" , faildetail=?"
|
||||
" WHERE payment_hash=?;");
|
||||
if (failonionreply)
|
||||
sqlite3_bind_blob(stmt, 1,
|
||||
@@ -1871,8 +1877,11 @@ void wallet_payment_set_failinfo(struct wallet *wallet,
|
||||
SQLITE_TRANSIENT);
|
||||
else
|
||||
sqlite3_bind_null(stmt, 7);
|
||||
sqlite3_bind_blob(stmt, 8,
|
||||
faildetail, strlen(faildetail),
|
||||
SQLITE_TRANSIENT);
|
||||
|
||||
sqlite3_bind_sha256(stmt, 8, payment_hash);
|
||||
sqlite3_bind_sha256(stmt, 9, payment_hash);
|
||||
|
||||
db_exec_prepared(wallet->db, stmt);
|
||||
}
|
||||
|
||||
@@ -735,7 +735,8 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
|
||||
enum onion_type *failcode,
|
||||
struct pubkey **failnode,
|
||||
struct short_channel_id **failchannel,
|
||||
u8 **failupdate);
|
||||
u8 **failupdate,
|
||||
char **faildetail);
|
||||
/**
|
||||
* wallet_payment_set_failinfo - Set failure information for a given
|
||||
* `payment_hash`.
|
||||
@@ -748,7 +749,8 @@ void wallet_payment_set_failinfo(struct wallet *wallet,
|
||||
enum onion_type failcode,
|
||||
const struct pubkey *failnode,
|
||||
const struct short_channel_id *failchannel,
|
||||
const u8 *failupdate);
|
||||
const u8 *failupdate,
|
||||
const char *faildetail);
|
||||
|
||||
/**
|
||||
* wallet_payment_list - Retrieve a list of payments
|
||||
|
||||
Reference in New Issue
Block a user