Skip to content

Commit

Permalink
lightningd: always broadcast our own gossip when it changes.
Browse files Browse the repository at this point in the history
When a peer connects, we always send all our own gossip (even if they
had set the timestamp filters to filter it out).  But we weren't
forcing it out to them when it changed, so this logic only applied to
unstable or frequently-restarting nodes.

So now, we tell all the peers whenever we tell gossipd about our new
gossip.

Fixes: #7276
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Protocol: We now send current peers our changed gossip (even if they set timestamp_filter otherwise), not just on reconnect.
  • Loading branch information
rustyrussell committed Aug 12, 2024
1 parent b525207 commit 48259af
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 79 deletions.
147 changes: 69 additions & 78 deletions lightningd/channel_gossip.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "config.h"
#include <ccan/cast/cast.h>
#include <ccan/mem/mem.h>
#include <common/memleak.h>
#include <common/timeout.h>
Expand Down Expand Up @@ -135,6 +136,66 @@ static void check_channel_gossip(const struct channel *channel)
fatal("Bad channel_gossip_state %u", cg->state);
}

static void msg_to_peer(const struct peer *peer, const u8 *msg TAKES)
{
struct lightningd *ld = peer->ld;

/* Shutting down, or peer not connected? */
if (ld->connectd && peer->connected == PEER_CONNECTED) {
subd_send_msg(ld->connectd,
take(towire_connectd_peer_send_msg(NULL,
&peer->id,
peer->connectd_counter,
msg)));
}

if (taken(msg))
tal_free(msg);
}

static void addgossip_reply(struct subd *gossipd,
const u8 *reply,
const int *fds UNUSED,
char *desc)
{
char *err;

if (!fromwire_gossipd_addgossip_reply(reply, reply, &err))
fatal("Reading gossipd_addgossip_reply for %s: %s",
desc, tal_hex(tmpctx, reply));

if (strlen(err))
log_broken(gossipd->log, "gossipd rejected our %s: %s", desc, err);
}

static void broadcast_new_gossip(struct lightningd *ld,
const u8 *msg TAKES,
struct amount_sat *known_channel,
const char *desc)
{
struct peer *peer;
struct peer_node_id_map_iter it;

if (taken(msg))
tal_steal(tmpctx, msg);

/* Tell gossipd about it */
subd_req(ld->gossip, ld->gossip,
take(towire_gossipd_addgossip(NULL, msg, known_channel)),
-1, 0, addgossip_reply, cast_const(char *, desc));

/* Don't tell them if we're supposed to be suppressing gossip for tests */
if (ld->dev_suppress_gossip)
return;

/* Tell all our peers about it, too! */
for (peer = peer_node_id_map_first(ld->peers, &it);
peer;
peer = peer_node_id_map_next(ld->peers, &it)) {
msg_to_peer(peer, msg);
}
}

/* Recursion */
static void cupdate_timer_refresh(struct channel *channel);

Expand Down Expand Up @@ -182,24 +243,6 @@ static void set_public_cupdate(struct channel *channel,
channel);
}

static void msg_to_peer(const struct channel *channel, const u8 *msg TAKES)
{
struct peer *peer = channel->peer;
struct lightningd *ld = peer->ld;

/* Shutting down, or peer not connected? */
if (ld->connectd && peer->connected == PEER_CONNECTED) {
subd_send_msg(ld->connectd,
take(towire_connectd_peer_send_msg(NULL,
&peer->id,
peer->connectd_counter,
msg)));
}

if (taken(msg))
tal_free(msg);
}

static enum channel_gossip_state init_public_state(struct channel *channel,
const struct remote_announce_sigs *remote_sigs)
{
Expand Down Expand Up @@ -280,22 +323,7 @@ static void send_private_cupdate(struct channel *channel, bool even_if_redundant
}

cg->cupdate = sign_update(cg, channel->peer->ld, cupdate);
msg_to_peer(channel, cg->cupdate);
}

static void broadcast_public_cupdate_addgossip_reply(struct subd *gossip UNUSED,
const u8 *reply,
const int *fds UNUSED,
struct channel *channel)
{
char *err;

if (!fromwire_gossipd_addgossip_reply(reply, reply, &err))
fatal("Reading broadcast_public_cupdate_addgossip_reply: %s",
tal_hex(tmpctx, reply));

if (strlen(err))
log_broken(channel->log, "gossipd rejected our channel update: %s", err);
msg_to_peer(channel->peer, cg->cupdate);
}

/* Send gossipd a channel_update, if not redundant. */
Expand Down Expand Up @@ -340,10 +368,7 @@ static void broadcast_public_cupdate(struct channel *channel,
set_public_cupdate(channel,
take(sign_update(NULL, channel->peer->ld, cupdate)),
true);

subd_req(ld->gossip, ld->gossip,
take(towire_gossipd_addgossip(NULL, cg->cupdate, NULL)),
-1, 0, broadcast_public_cupdate_addgossip_reply, channel);
broadcast_new_gossip(ld, cg->cupdate, NULL, "channel update");
}

static void cupdate_timer_refresh(struct channel *channel)
Expand Down Expand Up @@ -460,22 +485,7 @@ static void send_channel_announce_sigs(struct channel *channel)
msg = towire_announcement_signatures(NULL,
&channel->cid, *channel->scid,
&local_node_sig, &local_bitcoin_sig);
msg_to_peer(channel, take(msg));
}

static void send_channel_announce_addgossip_reply(struct subd *gossip UNUSED,
const u8 *reply,
const int *fds UNUSED,
struct channel *channel)
{
char *err;

if (!fromwire_gossipd_addgossip_reply(reply, reply, &err))
fatal("Reading send_channel_announce_addgossip_reply: %s",
tal_hex(tmpctx, reply));

if (strlen(err))
log_broken(channel->log, "gossipd rejected our channel announcement: %s", err);
msg_to_peer(channel->peer, take(msg));
}

static void send_channel_announcement(struct channel *channel)
Expand Down Expand Up @@ -509,9 +519,8 @@ static void send_channel_announcement(struct channel *channel)
&cg->remote_sigs->node_sig,
&cg->remote_sigs->bitcoin_sig);

subd_req(ld->gossip, ld->gossip,
take(towire_gossipd_addgossip(NULL, ca, &channel->funding_sats)),
-1, 0, send_channel_announce_addgossip_reply, channel);
/* Send everyone our new channel announcement */
broadcast_new_gossip(ld, ca, &channel->funding_sats, "channel announcement");
/* We can also send our first public channel_update now */
broadcast_public_cupdate(channel, true);
/* And maybe our first node_announcement */
Expand Down Expand Up @@ -651,7 +660,7 @@ void channel_gossip_got_announcement_sigs(struct channel *channel,
u8 *warning = towire_warningfmt(NULL,
&channel->cid,
"You sent announcement_signatures for private channel");
msg_to_peer(channel, take(warning));
msg_to_peer(channel->peer, take(warning));
return;
case CGOSSIP_NOT_USABLE:
case CGOSSIP_NOT_DEEP_ENOUGH:
Expand Down Expand Up @@ -1059,22 +1068,6 @@ static bool has_announced_channels(struct lightningd *ld)
return false;
}

static void node_announce_addgossip_reply(struct subd *gossipd,
const u8 *reply,
const int *fds UNUSED,
void *unused)
{
char *err;

if (!fromwire_gossipd_addgossip_reply(reply, reply, &err))
fatal("Reading node_announce_addgossip_reply: %s",
tal_hex(tmpctx, reply));

if (strlen(err))
log_broken(gossipd->ld->log,
"gossipd rejected our node announcement: %s", err);
}

void channel_gossip_node_announce(struct lightningd *ld)
{
u8 *nannounce;
Expand Down Expand Up @@ -1112,8 +1105,6 @@ void channel_gossip_node_announce(struct lightningd *ld)
tal_free(ld->node_announcement);
ld->node_announcement = tal_steal(ld, nannounce);

/* Tell gossipd. */
subd_req(ld->gossip, ld->gossip,
take(towire_gossipd_addgossip(NULL, nannounce, NULL)),
-1, 0, node_announce_addgossip_reply, NULL);
/* Tell gossipd and peers. */
broadcast_new_gossip(ld, nannounce, NULL, "node announcement");
}
1 change: 0 additions & 1 deletion tests/test_gossip.py
Original file line number Diff line number Diff line change
Expand Up @@ -2246,7 +2246,6 @@ def test_seeker_first_peer(node_factory, bitcoind):
timeout=TIMEOUT + 10)


@pytest.mark.xfail(strict=True)
def test_gossip_force_broadcast_channel_msgs(node_factory, bitcoind):
""" Send our own channel_update, node_announcement or channel_announcement to existing peers, even if they say they're not interested.
"""
Expand Down

0 comments on commit 48259af

Please sign in to comment.