Skip to content

Commit 5345e71

Browse files
committed
offers: fix fetchinvoice from using disconnected peers.
We didn't remove them from the graph if they were disconnected, leading to us trying to send an onion message to it: ``` ➜ ~ lightning-cli fetchinvoice lno1pg7y7s69g98zq5rp09hh2arnypnx7u3qvf3nzut68pmkcet2xdm8s7ngw5ux2am4wqekwmtkddkkk7nyv45ryefexum82anr8phpp6qrse80qf0aara4slvcjxrvu6j2rp5ftmjy4yntlsmsutpkvkt6878sy4xtpdc0j42xp72an4cl0unvzm7ckx2e6ltlzlgeekh0hhe0mgs2qgpetp66ufc9pwln9gmyv0gk3ndpqvvtynef8adzm3lxv0astkxunjcqx0fsq8kmx5cz574ft45vcweaf3tffp90fjdfl9gkdh4s6xfxaz7srtmsju9gnr3xerjhjqw4xtsmp55f4jjsxxrch703kx020l6wn2ttcd24w5h8f2lz723lk2kpa8ftkernz7h2qqkd3zecz2jmhucwh555xf0np4w45zm8tlka4ktw6d3ne4l9u678y37d24xjcy3el53faulcu5tzzquxrxvcyrvzgk7tyjeapt8wu858m2msgdznhqxl8fps04lef9dc9c 1sat { "code": -1, "message": "onion msg: unknown next peer 024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605" } ``` Fixes: #8225 Changelog-Fixed: JSON-RPC: `fetchinvoice` is now more reliable.
1 parent b76d9b3 commit 5345e71

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

plugins/establish_onion_path.c

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ static bool can_carry_onionmsg(const struct gossmap *map,
6969
{
7070
const struct gossmap_node *n;
7171

72+
/* Don't try to use disabled channels! */
73+
if (!c->half[dir].enabled)
74+
return false;
75+
7276
/* Our local additions are always fine, since we checked features then */
7377
if (gossmap_chan_is_localmod(map, c))
7478
return true;
@@ -78,11 +82,40 @@ static bool can_carry_onionmsg(const struct gossmap *map,
7882
return gossmap_node_get_feature(map, n, OPT_ONION_MESSAGES) != -1;
7983
}
8084

85+
static void local_mods_remove_channels(struct gossmap_localmods *mods,
86+
const struct gossmap *gossmap,
87+
const struct node_id *selfid,
88+
const struct node_id *peerid)
89+
{
90+
const struct gossmap_node *peer = gossmap_find_node(gossmap, peerid);
91+
const struct gossmap_node *self = gossmap_find_node(gossmap, selfid);
92+
const bool enabled_off = false;
93+
94+
if (!peer || !self)
95+
return;
96+
97+
for (size_t i = 0; i < self->num_chans; i++) {
98+
int dir;
99+
struct short_channel_id_dir scidd;
100+
struct gossmap_chan *c = gossmap_nth_chan(gossmap, self, i, &dir);
101+
102+
if (gossmap_nth_node(gossmap, c, !dir) != peer)
103+
continue;
104+
scidd.scid = gossmap_chan_scid(gossmap, c);
105+
scidd.dir = dir;
106+
107+
/* Set enabled -> false for this channel */
108+
gossmap_local_updatechan(mods, &scidd, &enabled_off,
109+
NULL, NULL, NULL, NULL, NULL);
110+
}
111+
}
112+
81113
/* We add fake channels to gossmap to represent current outgoing connections.
82114
* This allows dijkstra to find transient connections as well. */
83115
static struct gossmap_localmods *
84116
gossmods_from_listpeers(const tal_t *ctx,
85-
struct command *cmd,
117+
struct plugin *plugin,
118+
const struct gossmap *gossmap,
86119
const struct node_id *self,
87120
const char *buf,
88121
const jsmntok_t *toks)
@@ -108,12 +141,18 @@ gossmods_from_listpeers(const tal_t *ctx,
108141
JSON_SCAN(json_to_node_id, &peer_id),
109142
JSON_SCAN_TAL(tmpctx, json_tok_bin_from_hex, &features));
110143
if (err) {
111-
plugin_err(cmd->plugin, "Bad listpeers.peers %zu: %s", i, err);
144+
plugin_err(plugin, "Bad listpeers.peers %zu: %s", i, err);
112145
}
113146

114-
if (!connected || !feature_offered(features, OPT_ONION_MESSAGES))
147+
if (!feature_offered(features, OPT_ONION_MESSAGES))
115148
continue;
116149

150+
if (!connected) {
151+
/* Discard any channels we have with that. */
152+
local_mods_remove_channels(mods, gossmap, self, &peer_id);
153+
continue;
154+
}
155+
117156
/* Add a fake channel */
118157
fake_scidd.scid.u64 = i;
119158
fake_scidd.dir = node_id_idx(self, &peer_id);
@@ -145,7 +184,7 @@ static const struct pubkey *path_to_node(const tal_t *ctx,
145184

146185
node_id_from_pubkey(&local_nodeid, local_id);
147186
node_id_from_pubkey(&dst_nodeid, dst_key);
148-
mods = gossmods_from_listpeers(tmpctx, cmd, &local_nodeid, buf, listpeers);
187+
mods = gossmods_from_listpeers(tmpctx, cmd->plugin, gossmap, &local_nodeid, buf, listpeers);
149188

150189
gossmap_apply_localmods(gossmap, mods);
151190
dst = gossmap_find_node(gossmap, &dst_nodeid);

tests/test_pay.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4796,7 +4796,6 @@ def test_fetchinvoice_autoconnect_if_disconnected(node_factory, bitcoind):
47964796
l1.rpc.fetchinvoice(offer)
47974797

47984798

4799-
@pytest.mark.xfail(strict=True)
48004799
def test_fetchinvoice_disconnected_reply(node_factory, bitcoind):
48014800
"""We ask for invoice, but reply path doesn't lead directly from recipient"""
48024801
l1, l2, l3 = node_factory.get_nodes(3,

0 commit comments

Comments
 (0)