mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-15 11:59:16 +01:00
gossipd: preserve unannounced channels across store compaction.
Otherwise we'd forget them on restart, again. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
c424c42668
commit
2bd7df93c6
6 changed files with 59 additions and 3 deletions
|
@ -25,6 +25,7 @@ changes.
|
|||
### Fixed
|
||||
|
||||
- `--bind-addr=<path>` fixed for nodes using local sockets (eg. testing).
|
||||
- Unannounced local channels were forgotten for routing on restart until reconnection occurred.
|
||||
|
||||
### Security
|
||||
|
||||
|
|
|
@ -150,6 +150,46 @@ static bool gossip_store_append(int fd, struct routing_state *rstate, const u8 *
|
|||
write(fd, msg, msglen) == msglen);
|
||||
}
|
||||
|
||||
/* Local unannounced channels don't appear in broadcast map, but we need to
|
||||
* remember them anyway, so we manually append to the store.
|
||||
*
|
||||
* Note these do *not* add to gs->count, since that's compared with
|
||||
* the broadcast map count.
|
||||
*/
|
||||
static bool add_local_unnannounced(int fd,
|
||||
struct routing_state *rstate,
|
||||
struct node *self)
|
||||
{
|
||||
struct chan_map_iter i;
|
||||
struct chan *c;
|
||||
|
||||
for (c = chan_map_first(&self->chans, &i);
|
||||
c;
|
||||
c = chan_map_next(&self->chans, &i)) {
|
||||
struct node *peer = other_node(self, c);
|
||||
const u8 *msg;
|
||||
|
||||
/* Ignore already announced. */
|
||||
if (c->channel_announce)
|
||||
continue;
|
||||
|
||||
msg = towire_gossipd_local_add_channel(tmpctx, &c->scid,
|
||||
&peer->id, c->sat);
|
||||
if (!gossip_store_append(fd, rstate, msg))
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
msg = c->half[i].channel_update;
|
||||
if (!msg)
|
||||
continue;
|
||||
if (!gossip_store_append(fd, rstate, msg))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite the on-disk gossip store, compacting it along the way
|
||||
*
|
||||
|
@ -162,6 +202,7 @@ bool gossip_store_compact(struct gossip_store *gs)
|
|||
u64 index = 0;
|
||||
int fd;
|
||||
const u8 *msg;
|
||||
struct node *self;
|
||||
|
||||
assert(gs->broadcast);
|
||||
status_trace(
|
||||
|
@ -187,11 +228,18 @@ bool gossip_store_compact(struct gossip_store *gs)
|
|||
status_broken("Failed writing to gossip store: %s",
|
||||
strerror(errno));
|
||||
goto unlink_disable;
|
||||
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
/* Local unannounced channels are not in the store! */
|
||||
self = get_node(gs->rstate, &gs->rstate->local_id);
|
||||
if (self && !add_local_unnannounced(fd, gs->rstate, self)) {
|
||||
status_broken("Failed writing unannounced to gossip store: %s",
|
||||
strerror(errno));
|
||||
goto unlink_disable;
|
||||
}
|
||||
|
||||
if (rename(GOSSIP_STORE_TEMP_FILENAME, GOSSIP_STORE_FILENAME) == -1) {
|
||||
status_broken(
|
||||
"Error swapping compacted gossip_store into place: %s",
|
||||
|
|
|
@ -95,6 +95,9 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
|
|||
const struct channel_id *channel UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossipd_local_add_channel */
|
||||
u8 *towire_gossipd_local_add_channel(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED, const struct pubkey *remote_node_id UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossipd_local_add_channel called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_channel_announcement */
|
||||
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_announcement called!\n"); abort(); }
|
||||
|
|
|
@ -84,6 +84,9 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
|
|||
const struct channel_id *channel UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossipd_local_add_channel */
|
||||
u8 *towire_gossipd_local_add_channel(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED, const struct pubkey *remote_node_id UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossipd_local_add_channel called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_channel_announcement */
|
||||
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_announcement called!\n"); abort(); }
|
||||
|
|
|
@ -82,6 +82,9 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
|
|||
const struct channel_id *channel UNNEEDED,
|
||||
const char *fmt UNNEEDED, ...)
|
||||
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossipd_local_add_channel */
|
||||
u8 *towire_gossipd_local_add_channel(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED, const struct pubkey *remote_node_id UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossipd_local_add_channel called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_store_channel_announcement */
|
||||
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, struct amount_sat satoshis UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_store_channel_announcement called!\n"); abort(); }
|
||||
|
|
|
@ -1033,7 +1033,6 @@ def test_getroute_exclude(node_factory, bitcoind):
|
|||
l1.rpc.getroute(l4.info['id'], 1, 1, exclude=[chan_l2l3, chan_l2l4])
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
@unittest.skipIf(not DEVELOPER, "need dev-compact-gossip-store")
|
||||
def test_gossip_store_local_channels(node_factory, bitcoind):
|
||||
l1, l2 = node_factory.line_graph(2, wait_for_announce=False)
|
||||
|
@ -1059,7 +1058,6 @@ def test_gossip_store_local_channels(node_factory, bitcoind):
|
|||
assert len(chans) == 2
|
||||
|
||||
|
||||
@pytest.mark.xfail(strict=True)
|
||||
@unittest.skipIf(not DEVELOPER, "need dev-compact-gossip-store")
|
||||
def test_gossip_store_private_channels(node_factory, bitcoind):
|
||||
l1, l2 = node_factory.line_graph(2, announce_channels=False)
|
||||
|
|
Loading…
Add table
Reference in a new issue