Skip to content

Commit

Permalink
gossip: Add local_channel_close message to disable channels upon close
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
cdecker authored and rustyrussell committed May 31, 2018
1 parent 573f1b5 commit 9982e24
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
30 changes: 30 additions & 0 deletions gossipd/gossip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions gossipd/gossip_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions lightningd/gossip_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 9982e24

Please sign in to comment.