mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-23 09:04:22 +01:00
fetchinvoice: try direct peers if we can't route.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -548,42 +548,61 @@ static struct command_result *send_message(struct command *cmd,
|
|||||||
const jsmntok_t *result UNUSED,
|
const jsmntok_t *result UNUSED,
|
||||||
struct sent *sent))
|
struct sent *sent))
|
||||||
{
|
{
|
||||||
const struct dijkstra *dij;
|
const struct gossmap_node *dst;
|
||||||
const struct gossmap_node *dst, *src;
|
|
||||||
struct route **r;
|
|
||||||
struct gossmap *gossmap = get_gossmap(cmd->plugin);
|
struct gossmap *gossmap = get_gossmap(cmd->plugin);
|
||||||
const struct pubkey *backwards;
|
const struct pubkey *backwards;
|
||||||
struct onionmsg_path **path;
|
struct onionmsg_path **path;
|
||||||
struct pubkey blinding;
|
struct pubkey blinding;
|
||||||
struct out_req *req;
|
struct out_req *req;
|
||||||
struct node_id dstid;
|
struct node_id dstid, *nodes;
|
||||||
|
|
||||||
/* FIXME: Use blinded path if avail. */
|
/* FIXME: Use blinded path if avail. */
|
||||||
gossmap_guess_node_id(gossmap, sent->offer->node_id, &dstid);
|
gossmap_guess_node_id(gossmap, sent->offer->node_id, &dstid);
|
||||||
dst = gossmap_find_node(gossmap, &dstid);
|
dst = gossmap_find_node(gossmap, &dstid);
|
||||||
if (!dst)
|
if (!dst) {
|
||||||
return command_fail(cmd, LIGHTNINGD,
|
/* Try direct. */
|
||||||
"Unknown destination %s",
|
struct pubkey *us = tal_arr(tmpctx, struct pubkey, 1);
|
||||||
type_to_string(tmpctx, struct node_id,
|
if (!pubkey_from_node_id(&us[0], &local_id))
|
||||||
&dstid));
|
abort();
|
||||||
|
backwards = us;
|
||||||
|
|
||||||
/* If we don't exist in gossip, routing can't happen. */
|
nodes = tal_arr(tmpctx, struct node_id, 1);
|
||||||
src = gossmap_find_node(gossmap, &local_id);
|
/* We don't know the pubkey y-sign, but sendonionmessage will
|
||||||
if (!src)
|
* fix it up if we guess wrong. */
|
||||||
return command_fail(cmd, PAY_ROUTE_NOT_FOUND,
|
nodes[0].k[0] = SECP256K1_TAG_PUBKEY_EVEN;
|
||||||
"We don't have any channels");
|
secp256k1_xonly_pubkey_serialize(secp256k1_ctx,
|
||||||
|
nodes[0].k+1,
|
||||||
|
&sent->offer->node_id->pubkey);
|
||||||
|
} else {
|
||||||
|
struct route **r;
|
||||||
|
const struct dijkstra *dij;
|
||||||
|
const struct gossmap_node *src;
|
||||||
|
|
||||||
dij = dijkstra(tmpctx, gossmap, dst, AMOUNT_MSAT(0), 0,
|
/* If we don't exist in gossip, routing can't happen. */
|
||||||
can_carry_onionmsg, route_score_shorter, NULL);
|
src = gossmap_find_node(gossmap, &local_id);
|
||||||
|
if (!src)
|
||||||
|
return command_fail(cmd, PAY_ROUTE_NOT_FOUND,
|
||||||
|
"We don't have any channels");
|
||||||
|
|
||||||
r = route_from_dijkstra(tmpctx, gossmap, dij, src);
|
dij = dijkstra(tmpctx, gossmap, dst, AMOUNT_MSAT(0), 0,
|
||||||
if (!r)
|
can_carry_onionmsg, route_score_shorter, NULL);
|
||||||
/* FIXME: We need to retry kind of like keysend here... */
|
|
||||||
return command_fail(cmd, OFFER_ROUTE_NOT_FOUND,
|
r = route_from_dijkstra(tmpctx, gossmap, dij, src);
|
||||||
"Can't find route");
|
if (!r)
|
||||||
|
/* FIXME: try connecting directly. */
|
||||||
|
return command_fail(cmd, OFFER_ROUTE_NOT_FOUND,
|
||||||
|
"Can't find route");
|
||||||
|
|
||||||
|
backwards = route_backwards(tmpctx, gossmap, r);
|
||||||
|
nodes = tal_arr(tmpctx, struct node_id, tal_count(r));
|
||||||
|
for (size_t i = 0; i < tal_count(r); i++) {
|
||||||
|
gossmap_node_get_id(gossmap,
|
||||||
|
gossmap_nth_node(gossmap, r[i]->c, !r[i]->dir),
|
||||||
|
&nodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Ok, now make reply for onion_message */
|
/* Ok, now make reply for onion_message */
|
||||||
backwards = route_backwards(tmpctx, gossmap, r);
|
|
||||||
path = make_blindedpath(tmpctx, backwards, &blinding,
|
path = make_blindedpath(tmpctx, backwards, &blinding,
|
||||||
&sent->reply_blinding);
|
&sent->reply_blinding);
|
||||||
|
|
||||||
@@ -592,15 +611,10 @@ static struct command_result *send_message(struct command *cmd,
|
|||||||
forward_error,
|
forward_error,
|
||||||
sent);
|
sent);
|
||||||
json_array_start(req->js, "hops");
|
json_array_start(req->js, "hops");
|
||||||
for (size_t i = 0; i < tal_count(r); i++) {
|
for (size_t i = 0; i < tal_count(nodes); i++) {
|
||||||
struct node_id id;
|
|
||||||
|
|
||||||
json_object_start(req->js, NULL);
|
json_object_start(req->js, NULL);
|
||||||
gossmap_node_get_id(gossmap,
|
json_add_node_id(req->js, "id", &nodes[i]);
|
||||||
gossmap_nth_node(gossmap, r[i]->c, !r[i]->dir),
|
if (i == tal_count(nodes) - 1)
|
||||||
&id);
|
|
||||||
json_add_node_id(req->js, "id", &id);
|
|
||||||
if (i == tal_count(r) - 1)
|
|
||||||
json_add_hex_talarr(req->js, msgfield, msgval);
|
json_add_hex_talarr(req->js, msgfield, msgval);
|
||||||
json_object_end(req->js);
|
json_object_end(req->js);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3930,6 +3930,13 @@ def test_fetchinvoice(node_factory, bitcoind):
|
|||||||
'recurrence_counter': 2,
|
'recurrence_counter': 2,
|
||||||
'recurrence_label': 'test recurrence'})
|
'recurrence_label': 'test recurrence'})
|
||||||
|
|
||||||
|
# Check we can request invoice without a channel.
|
||||||
|
l4 = node_factory.get_node()
|
||||||
|
l4.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||||
|
ret = l4.rpc.call('fetchinvoice', {'offer': offer3,
|
||||||
|
'recurrence_counter': 0,
|
||||||
|
'recurrence_label': 'test nochannel'})
|
||||||
|
|
||||||
# Test timeout.
|
# Test timeout.
|
||||||
l3.stop()
|
l3.stop()
|
||||||
with pytest.raises(RpcError, match='Timeout waiting for response'):
|
with pytest.raises(RpcError, match='Timeout waiting for response'):
|
||||||
|
|||||||
Reference in New Issue
Block a user