From 499aee29b2ab9223d684586df85c39863e5a335a Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Tue, 25 Jun 2019 15:27:35 +0800 Subject: [PATCH 01/10] plugin: A new notification type, 'sendpay_success' `sendpay_success` A notification for topic `sendpay_success` is sent every time a sendpay success(with `complete` status). The json is same as the return value of command `sendpay`/`waitsendpay` when these cammand succeeds. ```json { "sendpay_success": { "id": 1, "payment_hash": "5c85bf402b87d4860f4a728e2e58a2418bda92cd7aea0ce494f11670cfbfb206", "destination": "035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d", "msatoshi": 100000000, "amount_msat": "100000000msat", "msatoshi_sent": 100001001, "amount_sent_msat": "100001001msat", "created_at": 1561390572, "status": "complete", "payment_preimage": "9540d98095fd7f37687ebb7759e733934234d4f934e34433d4998a37de3733ee" } } ``` `sendpay` doesn't wait for the result of sendpay and `waitsendpay` returns the result of sendpay in specified time or timeout, but `sendpay_success` will always return the result anytime when sendpay successes if is was subscribed. --- lightningd/notification.c | 24 ++++++++++++++++++++++++ lightningd/notification.h | 4 ++++ lightningd/pay.c | 5 ++--- lightningd/pay.h | 6 ++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lightningd/notification.c b/lightningd/notification.c index f17750287eb1..30f031ee1d29 100644 --- a/lightningd/notification.c +++ b/lightningd/notification.c @@ -227,3 +227,27 @@ void notify_forward_event(struct lightningd *ld, jsonrpc_notification_end(n); plugins_notify(ld->plugins, take(n)); } + +static void sendpay_success_notification_serialize(struct json_stream *stream, + const struct wallet_payment *payment) +{ + json_object_start(stream, "sendpay_success"); + json_add_payment_fields(stream, payment); + json_object_end(stream); /* .sendpay_success */ +} + +REGISTER_NOTIFICATION(sendpay_success, + sendpay_success_notification_serialize); + +void notify_sendpay_success(struct lightningd *ld, + const struct wallet_payment *payment) +{ + void (*serialize)(struct json_stream *, + const struct wallet_payment *) = sendpay_success_notification_gen.serialize; + + struct jsonrpc_notification *n = + jsonrpc_notification_start(NULL, "sendpay_success"); + serialize(n->stream, payment); + jsonrpc_notification_end(n); + plugins_notify(ld->plugins, take(n)); +} diff --git a/lightningd/notification.h b/lightningd/notification.h index cf97d81bf4d7..9a57f41e7d14 100644 --- a/lightningd/notification.h +++ b/lightningd/notification.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -54,4 +55,7 @@ void notify_forward_event(struct lightningd *ld, enum onion_type failcode, struct timeabs *resolved_time); +void notify_sendpay_success(struct lightningd *ld, + const struct wallet_payment *payment); + #endif /* LIGHTNING_LIGHTNINGD_NOTIFICATION_H */ diff --git a/lightningd/pay.c b/lightningd/pay.c index ff52b9aa2f23..1b594a2b1ec3 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -73,9 +73,8 @@ add_waitsendpay_waiter(struct lightningd *ld, } /* Outputs fields, not a separate object*/ -static void -json_add_payment_fields(struct json_stream *response, - const struct wallet_payment *t) +void json_add_payment_fields(struct json_stream *response, + const struct wallet_payment *t) { json_add_u64(response, "id", t->id); json_add_sha256(response, "payment_hash", &t->payment_hash); diff --git a/lightningd/pay.h b/lightningd/pay.h index a3edef862d15..2a9a4d3511c9 100644 --- a/lightningd/pay.h +++ b/lightningd/pay.h @@ -6,6 +6,8 @@ struct htlc_out; struct lightningd; struct preimage; struct sha256; +struct json_stream; +struct wallet_payment; void payment_succeeded(struct lightningd *ld, struct htlc_out *hout, const struct preimage *rval); @@ -16,4 +18,8 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, /* Inform payment system to save the payment. */ void payment_store(struct lightningd *ld, const struct sha256 *payment_hash); +/* This json will be also used in 'sendpay_success' notifictaion. */ +void json_add_payment_fields(struct json_stream *response, + const struct wallet_payment *t); + #endif /* LIGHTNING_LIGHTNINGD_PAY_H */ From d0a737df5b16e8329aa1979b2bdfce7bf85d4eb9 Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Tue, 25 Jun 2019 15:55:09 +0800 Subject: [PATCH 02/10] pay: Warp the json process of payment fail field We will also call this warped function in the json process of the 'sendpay_failure' notification. --- lightningd/pay.c | 49 ++++++++++++++++++++++++++++++------------------ lightningd/pay.h | 8 ++++++++ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/lightningd/pay.c b/lightningd/pay.c index 1b594a2b1ec3..38a6035cf716 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -141,6 +141,23 @@ json_add_routefail_info(struct json_stream *js, json_add_hex_talarr(js, "raw_message", msg); } +void json_sendpay_fail_fields(struct json_stream *js, + int pay_errcode, + const u8 *onionreply, + const struct routing_failure *fail) +{ + if (pay_errcode == PAY_UNPARSEABLE_ONION) + json_add_hex_talarr(js, "onionreply", onionreply); + else + json_add_routefail_info(js, + fail->erring_index, + fail->failcode, + &fail->erring_node, + &fail->erring_channel, + fail->channel_dir, + fail->msg); +} + /* onionreply used if pay_errcode == PAY_UNPARSEABLE_ONION */ static struct command_result * sendpay_fail(struct command *cmd, @@ -150,27 +167,23 @@ sendpay_fail(struct command *cmd, const char *details) { struct json_stream *data; - - if (pay_errcode == PAY_UNPARSEABLE_ONION) { - data = json_stream_fail(cmd, PAY_UNPARSEABLE_ONION, - "Malformed error reply"); - json_add_hex_talarr(data, "onionreply", onionreply); - json_object_end(data); - return command_failed(cmd, data); + char *errmsg; + + if (pay_errcode == PAY_UNPARSEABLE_ONION) + errmsg = "Malformed error reply"; + else { + assert(fail); + errmsg = tal_fmt(tmpctx, "failed: %s (%s)", + onion_type_name(fail->failcode), + details); } - assert(fail); data = json_stream_fail(cmd, pay_errcode, - tal_fmt(tmpctx, "failed: %s (%s)", - onion_type_name(fail->failcode), - details)); - json_add_routefail_info(data, - fail->erring_index, - fail->failcode, - &fail->erring_node, - &fail->erring_channel, - fail->channel_dir, - fail->msg); + errmsg); + json_sendpay_fail_fields(data, + pay_errcode, + onionreply, + fail); json_object_end(data); return command_failed(cmd, data); } diff --git a/lightningd/pay.h b/lightningd/pay.h index 2a9a4d3511c9..f5ca389fb617 100644 --- a/lightningd/pay.h +++ b/lightningd/pay.h @@ -1,6 +1,7 @@ #ifndef LIGHTNING_LIGHTNINGD_PAY_H #define LIGHTNING_LIGHTNINGD_PAY_H #include "config.h" +#include struct htlc_out; struct lightningd; @@ -8,6 +9,7 @@ struct preimage; struct sha256; struct json_stream; struct wallet_payment; +struct routing_failure; void payment_succeeded(struct lightningd *ld, struct htlc_out *hout, const struct preimage *rval); @@ -22,4 +24,10 @@ void payment_store(struct lightningd *ld, const struct sha256 *payment_hash); void json_add_payment_fields(struct json_stream *response, const struct wallet_payment *t); +/* This json will be also used in 'sendpay_failure' notifictaion. */ +void json_sendpay_fail_fields(struct json_stream *js, + int pay_errcode, + const u8 *onionreply, + const struct routing_failure *fail); + #endif /* LIGHTNING_LIGHTNINGD_PAY_H */ From c7f2b817b24dcecb21d70787c1f75cf7936eaeae Mon Sep 17 00:00:00 2001 From: trueptolemy Date: Sun, 11 Aug 2019 21:29:16 +0800 Subject: [PATCH 03/10] API: Add payment fields(if not NULL) into return value when sendpay fails pPayment field includes the basic information of the payment, so the return valves of 'sendpay_success()' and 'sendpay_fail()' should include this field. Note "immediate_routing_failure" is before payment creation, and for this case, return won't include payment fields. --- lightningd/pay.c | 23 +++++++++++++++++------ lightningd/pay.h | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lightningd/pay.c b/lightningd/pay.c index 38a6035cf716..fd0b6c48faad 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -142,10 +142,14 @@ json_add_routefail_info(struct json_stream *js, } void json_sendpay_fail_fields(struct json_stream *js, + const struct wallet_payment *payment, int pay_errcode, const u8 *onionreply, const struct routing_failure *fail) { + /* "immediate_routing_failure" is before payment creation. */ + if (payment) + json_add_payment_fields(js, payment); if (pay_errcode == PAY_UNPARSEABLE_ONION) json_add_hex_talarr(js, "onionreply", onionreply); else @@ -161,6 +165,7 @@ void json_sendpay_fail_fields(struct json_stream *js, /* onionreply used if pay_errcode == PAY_UNPARSEABLE_ONION */ static struct command_result * sendpay_fail(struct command *cmd, + const struct wallet_payment *payment, int pay_errcode, const u8 *onionreply, const struct routing_failure *fail, @@ -181,6 +186,7 @@ sendpay_fail(struct command *cmd, data = json_stream_fail(cmd, pay_errcode, errmsg); json_sendpay_fail_fields(data, + payment, pay_errcode, onionreply, fail); @@ -202,6 +208,7 @@ json_sendpay_in_progress(struct command *cmd, static void tell_waiters_failed(struct lightningd *ld, const struct sha256 *payment_hash, + const struct wallet_payment *payment, int pay_errcode, const u8 *onionreply, const struct routing_failure *fail, @@ -215,7 +222,8 @@ static void tell_waiters_failed(struct lightningd *ld, if (!sha256_eq(payment_hash, &pc->payment_hash)) continue; - sendpay_fail(pc->cmd, pay_errcode, onionreply, fail, details); + sendpay_fail(pc->cmd, payment, + pay_errcode, onionreply, fail, details); } } @@ -510,8 +518,8 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, failmsg, fail ? fail->channel_dir : 0); - tell_waiters_failed(ld, &hout->payment_hash, pay_errcode, - hout->failuremsg, fail, failmsg); + tell_waiters_failed(ld, &hout->payment_hash, payment, + pay_errcode, hout->failuremsg, fail, failmsg); } /* Wait for a payment. If cmd is deleted, then json_waitsendpay_on_resolve @@ -567,7 +575,9 @@ static struct command_result *wait_payment(struct lightningd *ld, "Payment failure reason unknown"); } else if (failonionreply) { /* failed to parse returned onion error */ - return sendpay_fail(cmd, PAY_UNPARSEABLE_ONION, + return sendpay_fail(cmd, + payment, + PAY_UNPARSEABLE_ONION, failonionreply, NULL, faildetail); } else { @@ -583,6 +593,7 @@ static struct command_result *wait_payment(struct lightningd *ld, /* FIXME: We don't store this! */ fail->msg = NULL; return sendpay_fail(cmd, + payment, faildestperm ? PAY_DESTINATION_PERM_FAIL : PAY_TRY_OTHER_ROUTE, @@ -721,8 +732,8 @@ send_payment(struct lightningd *ld, &route[0].channel_id, &channel->peer->id); - return sendpay_fail(cmd, PAY_TRY_OTHER_ROUTE, NULL, - fail, "First peer not ready"); + return sendpay_fail(cmd, payment, PAY_TRY_OTHER_ROUTE, + NULL, fail, "First peer not ready"); } /* Copy channels used along the route. */ diff --git a/lightningd/pay.h b/lightningd/pay.h index f5ca389fb617..53f0e0cdd77a 100644 --- a/lightningd/pay.h +++ b/lightningd/pay.h @@ -26,6 +26,7 @@ void json_add_payment_fields(struct json_stream *response, /* This json will be also used in 'sendpay_failure' notifictaion. */ void json_sendpay_fail_fields(struct json_stream *js, + const struct wallet_payment *t, int pay_errcode, const u8 *onionreply, const struct routing_failure *fail); From d8535e73b164ea1e519e43c00b9ab42fac7a74ee Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Tue, 25 Jun 2019 15:45:16 +0800 Subject: [PATCH 04/10] plugin: Another new notification type, 'sendpay_failure' (The json when sendpay successes is too different when sendpay fails, so divide the sendpay result into two notifications: `sendpay_success` and `sendpay_failure`) `sendpay_failure` A notification for topic `sendpay_failure` is sent every time a sendpay success(with `failed` status). The json is same as the return value of command `sendpay`/`waitsendpay` when this cammand fails. ```json { "sendpay_failure": { "code": 204, "message": "failed: WIRE_UNKNOWN_NEXT_PEER (reply from remote)", "data": { "id": 2, "payment_hash": "9036e3bdbd2515f1e653cb9f22f8e4c49b73aa2c36e937c926f43e33b8db8851", "destination": "035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d", "msatoshi": 100000000, "amount_msat": "100000000msat", "msatoshi_sent": 100001001, "amount_sent_msat": "100001001msat", "created_at": 1561395134, "status": "failed", "erring_index": 1, "failcode": 16394, "failcodename": "WIRE_UNKNOWN_NEXT_PEER", "erring_node": "022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59", "erring_channel": "103x2x1", "erring_direction": 0 } } } ``` `sendpay` doesn't wait for the result of sendpay and `waitsendpay` returns the result of sendpay in specified time or timeout, but `sendpay_failure` will always return the result anytime when sendpay fails if is was subscribed. --- lightningd/notification.c | 49 +++++++++++++++++++++++++++++++++++++++ lightningd/notification.h | 7 ++++++ 2 files changed, 56 insertions(+) diff --git a/lightningd/notification.c b/lightningd/notification.c index 30f031ee1d29..4877805d537b 100644 --- a/lightningd/notification.c +++ b/lightningd/notification.c @@ -251,3 +251,52 @@ void notify_sendpay_success(struct lightningd *ld, jsonrpc_notification_end(n); plugins_notify(ld->plugins, take(n)); } + +static void sendpay_failure_notification_serialize(struct json_stream *stream, + const struct wallet_payment *payment, + int pay_errcode, + const u8 *onionreply, + const struct routing_failure *fail, + char *errmsg) +{ + json_object_start(stream, "sendpay_failure"); + + /* In line with the format of json error returned + * by sendpay_fail(). */ + json_add_member(stream, "code", false, "%d", pay_errcode); + json_add_string(stream, "message", errmsg); + + json_object_start(stream, "data"); + json_sendpay_fail_fields(stream, + payment, + pay_errcode, + onionreply, + fail); + + json_object_end(stream); /* .data */ + json_object_end(stream); /* .sendpay_failure */ +} + +REGISTER_NOTIFICATION(sendpay_failure, + sendpay_failure_notification_serialize); + +void notify_sendpay_failure(struct lightningd *ld, + const struct wallet_payment *payment, + int pay_errcode, + const u8 *onionreply, + const struct routing_failure *fail, + char *errmsg) +{ + void (*serialize)(struct json_stream *, + const struct wallet_payment *, + int, + const u8 *, + const struct routing_failure *, + char *) = sendpay_failure_notification_gen.serialize; + + struct jsonrpc_notification *n = + jsonrpc_notification_start(NULL, "sendpay_failure"); + serialize(n->stream, payment, pay_errcode, onionreply, fail, errmsg); + jsonrpc_notification_end(n); + plugins_notify(ld->plugins, take(n)); +} diff --git a/lightningd/notification.h b/lightningd/notification.h index 9a57f41e7d14..95026d08e0a5 100644 --- a/lightningd/notification.h +++ b/lightningd/notification.h @@ -58,4 +58,11 @@ void notify_forward_event(struct lightningd *ld, void notify_sendpay_success(struct lightningd *ld, const struct wallet_payment *payment); +void notify_sendpay_failure(struct lightningd *ld, + const struct wallet_payment *payment, + int pay_errcode, + const u8 *onionreply, + const struct routing_failure *fail, + char *errmsg); + #endif /* LIGHTNING_LIGHTNINGD_NOTIFICATION_H */ From df74cc2cd3b0432e5cef3f99b5b48fb3753ba807 Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Tue, 25 Jun 2019 16:32:53 +0800 Subject: [PATCH 05/10] Pay: Notify 'sendpay_success' and 'sendpay_failure' when sendpay succeeds and fails --- lightningd/pay.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lightningd/pay.c b/lightningd/pay.c index fd0b6c48faad..d7a0244410e8 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -113,6 +114,7 @@ static struct command_result *sendpay_success(struct command *cmd, assert(payment->status == PAYMENT_COMPLETE); + notify_sendpay_success(cmd->ld, payment); response = json_stream_success(cmd); json_add_payment_fields(response, payment); return command_success(cmd, response); @@ -183,6 +185,13 @@ sendpay_fail(struct command *cmd, details); } + notify_sendpay_failure(cmd->ld, + payment, + pay_errcode, + onionreply, + fail, + errmsg); + data = json_stream_fail(cmd, pay_errcode, errmsg); json_sendpay_fail_fields(data, From 8b986d8ea7d7ac84cc7bcc8934c1b11c646b979b Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Tue, 25 Jun 2019 16:48:11 +0800 Subject: [PATCH 06/10] pytest: Add a simple plugin to test 'sendpay_success' and 'sendpay_failure' --- tests/plugins/sendpay_notifications.py | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100755 tests/plugins/sendpay_notifications.py diff --git a/tests/plugins/sendpay_notifications.py b/tests/plugins/sendpay_notifications.py new file mode 100755 index 000000000000..35d3058fc80d --- /dev/null +++ b/tests/plugins/sendpay_notifications.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +"""This plugin is used to check that sendpay_success and sendpay_failure calls are working correctly. +""" +from lightning import Plugin + +plugin = Plugin() + + +@plugin.init() +def init(configuration, options, plugin): + plugin.success_list = [] + plugin.failure_list = [] + + +@plugin.subscribe("sendpay_success") +def notify_sendpay_success(plugin, sendpay_success): + plugin.log("receive a sendpay_success recored, id: {}, payment_hash: {}".format(sendpay_success['id'], sendpay_success['payment_hash'])) + plugin.success_list.append(sendpay_success) + + +@plugin.subscribe("sendpay_failure") +def notify_sendpay_failure(plugin, sendpay_failure): + plugin.log("receive a sendpay_failure recored, id: {}, payment_hash: {}".format(sendpay_failure['data']['id'], + sendpay_failure['data']['payment_hash'])) + plugin.failure_list.append(sendpay_failure) + + +@plugin.method('listsendpays_plugin') +def record_lookup(plugin): + return {'sendpay_success': plugin.success_list, + 'sendpay_failure': plugin.failure_list} + + +plugin.run() From 45d66fb07b63bd65e2ad2b2c97b57a7e6bd6ba92 Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Tue, 25 Jun 2019 16:53:25 +0800 Subject: [PATCH 07/10] pytest: Add a test for 'sendpay_success' and 'sendpay_failure' --- tests/test_plugin.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/test_plugin.py b/tests/test_plugin.py index cbe43cdcdb61..b6cc95149cbf 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -708,3 +708,34 @@ def test_plugin_deprecated_relpath(node_factory): assert l1.daemon.is_in_log('DEPRECATED WARNING.*plugin={}' .format(os.path.join(os.getcwd(), 'tests/plugins/millisatoshis.py'))) + + +def test_sendpay_notifications(node_factory, bitcoind): + """ test 'sendpay_success' and 'sendpay_failure' notifications + """ + amount = 10**8 + opts = [{'plugin': os.path.join(os.getcwd(), 'tests/plugins/sendpay_notifications.py')}, + {}, + {'may_reconnect': False}] + l1, l2, l3 = node_factory.line_graph(3, opts=opts, wait_for_announce=True) + chanid23 = l2.get_channel_scid(l3) + + payment_hash1 = l3.rpc.invoice(amount, "first", "desc")['payment_hash'] + payment_hash2 = l3.rpc.invoice(amount, "second", "desc")['payment_hash'] + route = l1.rpc.getroute(l3.info['id'], amount, 1)['route'] + + l1.rpc.sendpay(route, payment_hash1) + response1 = l1.rpc.waitsendpay(payment_hash1) + + l2.rpc.close(chanid23, 1) + + l1.rpc.sendpay(route, payment_hash2) + with pytest.raises(RpcError) as err: + l1.rpc.waitsendpay(payment_hash2) + + results = l1.rpc.call('listsendpays_plugin') + assert len(results['sendpay_success']) == 1 + assert len(results['sendpay_failure']) == 1 + + assert results['sendpay_success'][0] == response1 + assert results['sendpay_failure'][0] == err.value.error From 7ded5b00d7dcdc8dfbae265a4073a71989e7d5ca Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Tue, 25 Jun 2019 16:54:27 +0800 Subject: [PATCH 08/10] pay: A cleanup for the comment about wait_payment() json_waitsendpay_on_resolve() has been replaced by wait_payment(), so correct it here. --- lightningd/pay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightningd/pay.c b/lightningd/pay.c index d7a0244410e8..840376d63a1d 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -531,7 +531,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, pay_errcode, hout->failuremsg, fail, failmsg); } -/* Wait for a payment. If cmd is deleted, then json_waitsendpay_on_resolve +/* Wait for a payment. If cmd is deleted, then wait_payment() * no longer be called. * Return callback if we called already, otherwise NULL. */ static struct command_result *wait_payment(struct lightningd *ld, From a973cb8b7710efeda0e754db63f02fe3f164901f Mon Sep 17 00:00:00 2001 From: trueptolemy <823220586@qq.com> Date: Tue, 25 Jun 2019 22:06:04 +0800 Subject: [PATCH 09/10] doc: Add the description for 'sendpay_success' and 'sendpay_failure' notifications --- doc/PLUGINS.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/doc/PLUGINS.md b/doc/PLUGINS.md index bf6f1f9b2c2b..44861a5bdad7 100644 --- a/doc/PLUGINS.md +++ b/doc/PLUGINS.md @@ -384,6 +384,68 @@ or only `settled` and `failed` case contain `resolved_time`; - The `failcode` and `failreason` are defined in [BOLT 4][bolt4-failure-codes]. +#### `sendpay_success` + +A notification for topic `sendpay_success` is sent every time a sendpay +success(with `complete` status). The json is same as the return value of +command `sendpay`/`waitsendpay` when these cammand succeeds. + +```json +{ + "sendpay_success": { + "id": 1, + "payment_hash": "5c85bf402b87d4860f4a728e2e58a2418bda92cd7aea0ce494f11670cfbfb206", + "destination": "035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d", + "msatoshi": 100000000, + "amount_msat": "100000000msat", + "msatoshi_sent": 100001001, + "amount_sent_msat": "100001001msat", + "created_at": 1561390572, + "status": "complete", + "payment_preimage": "9540d98095fd7f37687ebb7759e733934234d4f934e34433d4998a37de3733ee" + } +} +``` +`sendpay` doesn't wait for the result of sendpay and `waitsendpay` +returns the result of sendpay in specified time or timeout, but +`sendpay_success` will always return the result anytime when sendpay +successes if is was subscribed. + +#### `sendpay_failure` + +A notification for topic `sendpay_failure` is sent every time a sendpay +success(with `failed` status). The json is same as the return value of +command `sendpay`/`waitsendpay` when this cammand fails. + +```json +{ + "sendpay_failure": { + "code": 204, + "message": "failed: WIRE_UNKNOWN_NEXT_PEER (reply from remote)", + "data": { + "id": 2, + "payment_hash": "9036e3bdbd2515f1e653cb9f22f8e4c49b73aa2c36e937c926f43e33b8db8851", + "destination": "035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d", + "msatoshi": 100000000, + "amount_msat": "100000000msat", + "msatoshi_sent": 100001001, + "amount_sent_msat": "100001001msat", + "created_at": 1561395134, + "status": "failed", + "erring_index": 1, + "failcode": 16394, + "failcodename": "WIRE_UNKNOWN_NEXT_PEER", + "erring_node": "022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59", + "erring_channel": "103x2x1", + "erring_direction": 0 + } + } +} +``` +`sendpay` doesn't wait for the result of sendpay and `waitsendpay` +returns the result of sendpay in specified time or timeout, but +`sendpay_failure` will always return the result anytime when sendpay +fails if is was subscribed. ## Hooks From 951fea4cbb99b131d9d641bf1a8e7f15a0b7581f Mon Sep 17 00:00:00 2001 From: trueptolemy Date: Fri, 23 Aug 2019 03:24:59 +0800 Subject: [PATCH 10/10] CHANGELOG: Add the entry for `sendpay_success` and `sendpay_failure` --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97b5e7891162..44e7874f2bf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - bolt11: support for parsing feature bits (field `9`). - Protocol: we now retransmit `funding_locked` upon reconnection while closing if there was no update +- Plugin: new notifications `sendpay_success` and `sendpay_failure`. + ### Changed - JSON API: `txprepare` now uses `outputs` as parameter other than `destination` and `satoshi`