Browse Source

gossip: Add local_channel_close message to disable channels upon close

This was failing some of our integration tests, i.e., the ones closing a channel
and not waiting for sigexchange. The remote node would often not be quick enough
to send us its disabling channel_update, and hence we'd still remember the
incoming direction. That could then be sent out as part of an invoice, and fail
subsequently. So just set both directions to be disabled and let the onchain
spend clean up once it happens.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
ppa-0.6.1
Christian Decker 7 years ago
committed by Rusty Russell
parent
commit
9982e24a1c
  1. 30
      gossipd/gossip.c
  2. 3
      gossipd/gossip_wire.csv
  3. 1
      lightningd/gossip_control.c

30
gossipd/gossip.c

@ -2591,6 +2591,33 @@ static struct io_plan *handle_outpoint_spent(struct io_conn *conn,
return daemon_conn_read_next(conn, &daemon->master);
}
/**
* Disable both directions of a channel due to an imminent close.
*
* We'll leave it to handle_outpoint_spent to delete the channel from our view
* once the close gets confirmed. This avoids having strange states in which the
* channel is list in our peer list but won't be returned when listing public
* channels. This does not send out updates since that's triggered by the peer
* connection closing.
*/
static struct io_plan *handle_local_channel_close(struct io_conn *conn,
struct daemon *daemon,
const u8 *msg)
{
struct short_channel_id scid;
struct chan *chan;
struct routing_state *rstate = daemon->rstate;
if (!fromwire_gossip_local_channel_close(msg, &scid))
master_badmsg(WIRE_GOSSIP_ROUTING_FAILURE, msg);
chan = get_channel(rstate, &scid);
if (chan) {
chan->half[0].flags |= ROUTING_FLAGS_DISABLED;
chan->half[1].flags |= ROUTING_FLAGS_DISABLED;
}
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master)
{
struct daemon *daemon = container_of(master, struct daemon, master);
@ -2657,6 +2684,9 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIP_OUTPOINT_SPENT:
return handle_outpoint_spent(conn, daemon, master->msg_in);
case WIRE_GOSSIP_LOCAL_CHANNEL_CLOSE:
return handle_local_channel_close(conn, daemon, master->msg_in);
/* We send these, we don't receive them */
case WIRE_GOSSIPCTL_ACTIVATE_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:

3
gossipd/gossip_wire.csv

@ -206,6 +206,9 @@ gossip_local_channel_update,,htlc_minimum_msat,u64
gossip_local_channel_update,,fee_base_msat,u32
gossip_local_channel_update,,fee_proportional_millionths,u32
gossip_local_channel_close,3027
gossip_local_channel_close,,short_channel_id,struct short_channel_id
# Gossipd->master get this tx output please.
gossip_get_txout,3018
gossip_get_txout,,short_channel_id,struct short_channel_id

Can't render this file because it has a wrong number of fields in line 6.

1
lightningd/gossip_control.c

@ -156,6 +156,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
/* These are inter-daemon messages, not received by us */
case WIRE_GOSSIP_LOCAL_ADD_CHANNEL:
case WIRE_GOSSIP_LOCAL_CHANNEL_UPDATE:
case WIRE_GOSSIP_LOCAL_CHANNEL_CLOSE:
break;
case WIRE_GOSSIP_PEER_CONNECTED:

Loading…
Cancel
Save