Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions plugins/establish_onion_path.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ static bool can_carry_onionmsg(const struct gossmap *map,
{
const struct gossmap_node *n;

/* Don't try to use disabled channels! */
if (!c->half[dir].enabled)
return false;

/* Our local additions are always fine, since we checked features then */
if (gossmap_chan_is_localmod(map, c))
return true;
Expand All @@ -78,11 +82,40 @@ static bool can_carry_onionmsg(const struct gossmap *map,
return gossmap_node_get_feature(map, n, OPT_ONION_MESSAGES) != -1;
}

static void local_mods_remove_channels(struct gossmap_localmods *mods,
const struct gossmap *gossmap,
const struct node_id *selfid,
const struct node_id *peerid)
{
const struct gossmap_node *peer = gossmap_find_node(gossmap, peerid);
const struct gossmap_node *self = gossmap_find_node(gossmap, selfid);
const bool enabled_off = false;

if (!peer || !self)
return;

for (size_t i = 0; i < self->num_chans; i++) {
int dir;
struct short_channel_id_dir scidd;
struct gossmap_chan *c = gossmap_nth_chan(gossmap, self, i, &dir);

if (gossmap_nth_node(gossmap, c, !dir) != peer)
continue;
scidd.scid = gossmap_chan_scid(gossmap, c);
scidd.dir = dir;

/* Set enabled -> false for this channel */
gossmap_local_updatechan(mods, &scidd, &enabled_off,
NULL, NULL, NULL, NULL, NULL);
}
}

/* We add fake channels to gossmap to represent current outgoing connections.
* This allows dijkstra to find transient connections as well. */
static struct gossmap_localmods *
gossmods_from_listpeers(const tal_t *ctx,
struct command *cmd,
struct plugin *plugin,
const struct gossmap *gossmap,
const struct node_id *self,
const char *buf,
const jsmntok_t *toks)
Expand All @@ -108,12 +141,18 @@ gossmods_from_listpeers(const tal_t *ctx,
JSON_SCAN(json_to_node_id, &peer_id),
JSON_SCAN_TAL(tmpctx, json_tok_bin_from_hex, &features));
if (err) {
plugin_err(cmd->plugin, "Bad listpeers.peers %zu: %s", i, err);
plugin_err(plugin, "Bad listpeers.peers %zu: %s", i, err);
}

if (!connected || !feature_offered(features, OPT_ONION_MESSAGES))
if (!feature_offered(features, OPT_ONION_MESSAGES))
continue;

if (!connected) {
/* Discard any channels we have with that. */
local_mods_remove_channels(mods, gossmap, self, &peer_id);
continue;
}

/* Add a fake channel */
fake_scidd.scid.u64 = i;
fake_scidd.dir = node_id_idx(self, &peer_id);
Expand Down Expand Up @@ -145,7 +184,7 @@ static const struct pubkey *path_to_node(const tal_t *ctx,

node_id_from_pubkey(&local_nodeid, local_id);
node_id_from_pubkey(&dst_nodeid, dst_key);
mods = gossmods_from_listpeers(tmpctx, cmd, &local_nodeid, buf, listpeers);
mods = gossmods_from_listpeers(tmpctx, cmd->plugin, gossmap, &local_nodeid, buf, listpeers);

gossmap_apply_localmods(gossmap, mods);
dst = gossmap_find_node(gossmap, &dst_nodeid);
Expand Down
12 changes: 12 additions & 0 deletions tests/test_pay.py
Original file line number Diff line number Diff line change
Expand Up @@ -4784,6 +4784,18 @@ def test_fetchinvoice_autoconnect(node_factory, bitcoind):
assert l3.rpc.listpeers(l2.info['id'])['peers'] != []


def test_fetchinvoice_autoconnect_if_disconnected(node_factory, bitcoind):
"""If peer is disconnected, we should NOT try to use it"""
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True,
opts={'dev-allow-localhost': None})

offer = l3.rpc.offer(amount='2msat', description='test_fetchinvoice_autoconnect_if_disconnected1')['bolt12']
l1.rpc.fetchinvoice(offer)

l1.rpc.disconnect(l2.info['id'], force=True)
l1.rpc.fetchinvoice(offer)


def test_fetchinvoice_disconnected_reply(node_factory, bitcoind):
"""We ask for invoice, but reply path doesn't lead directly from recipient"""
l1, l2, l3 = node_factory.get_nodes(3,
Expand Down
Loading