Skip to content

Commit

Permalink
keysend: Check that the destination supports keysend upon init
Browse files Browse the repository at this point in the history
We were blindly initiating the keysend payment, which could lead to
confusing outcomes. This adds a very specific error message to the
error returned.

Changelog-Fixed: keysend: Keysend now checks whether the destination supports keysend before attempting a payment. If not a more informative error is returned.
  • Loading branch information
cdecker authored and rustyrussell committed Dec 10, 2020
1 parent 86176e8 commit e45eac7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
19 changes: 19 additions & 0 deletions plugins/keysend.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <bitcoin/preimage.h>
#include <ccan/array_size/array_size.h>
#include <ccan/tal/str/str.h>
#include <common/gossmap.h>
#include <plugins/libplugin-pay.h>
#include <plugins/libplugin.h>
#include <wire/onion_wire.h>
Expand Down Expand Up @@ -54,6 +55,24 @@ static struct keysend_data *keysend_init(struct payment *p)
static void keysend_cb(struct keysend_data *d, struct payment *p) {
struct createonion_hop *last_payload;
size_t hopcount;
struct gossmap_node *node;
bool enabled;
const struct gossmap *gossmap = get_gossmap(p->plugin);

/* On the root payment we perform the featurebit check. */
if (p->parent == NULL && p->step == PAYMENT_STEP_INITIALIZED) {
node = gossmap_find_node(gossmap, p->destination);

enabled = gossmap_node_get_feature(gossmap, node,
KEYSEND_FEATUREBIT) != -1;
if (!enabled)
return payment_fail(
p,
"Recipient %s does not support keysend payments "
"(feature bit %d missing in node announcement)",
node_id_to_hexstr(tmpctx, p->destination),
KEYSEND_FEATUREBIT);
}

if (p->step != PAYMENT_STEP_ONION_PAYLOAD)
return payment_continue(p);
Expand Down
2 changes: 1 addition & 1 deletion tests/test_pay.py
Original file line number Diff line number Diff line change
Expand Up @@ -3373,7 +3373,7 @@ def test_listpay_result_with_paymod(node_factory, bitcoind):

amount_sat = 10 ** 6

l1, l2, l3 = node_factory.line_graph(3)
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True)

invl2 = l2.rpc.invoice(amount_sat * 2, "inv_l2", "inv_l2")
l1.rpc.pay(invl2['bolt11'])
Expand Down

0 comments on commit e45eac7

Please sign in to comment.