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>
This commit is contained in:
Christian Decker
2018-05-26 15:19:24 +02:00
committed by Rusty Russell
parent 573f1b58c8
commit 9982e24a1c
3 changed files with 34 additions and 0 deletions

View File

@@ -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:

View File

@@ -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
1 #include <common/cryptomsg.h>
206 gossipctl_peer_disconnect_reply,3123 gossipctl_peer_disconnect,,id,struct pubkey
207 # Gossipd -> master: reply to gossip_peer_disconnect if we couldn't find the peer. # Gossipd -> master: reply to gossip_peer_disconnect with peer id.
208 gossipctl_peer_disconnect_replyfail,3223 gossipctl_peer_disconnect_reply,3123
209 # Gossipd -> master: reply to gossip_peer_disconnect if we couldn't find the peer.
210 gossipctl_peer_disconnect_replyfail,3223
211 gossipctl_peer_disconnect_replyfail,,isconnected,bool
212 gossipctl_peer_disconnect_replyfail,,isconnected,bool # master -> gossipd: a potential funding outpoint was spent, please forget the eventual channel
213 # master -> gossipd: a potential funding outpoint was spent, please forget the eventual channel gossip_outpoint_spent,3024
214 gossip_outpoint_spent,3024 gossip_outpoint_spent,,short_channel_id,struct short_channel_id

View File

@@ -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: