diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 0524cc599..2eeda1d44 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -2355,11 +2355,99 @@ static struct io_plan *peer_important(struct io_conn *conn, return daemon_conn_read_next(conn, &daemon->master); } +static void gossip_disable_channel(struct routing_state *rstate, struct chan *chan) +{ + struct short_channel_id scid; + u8 direction; + struct half_chan *hc; + u16 flags, cltv_expiry_delta; + u32 timestamp, fee_base_msat, fee_proportional_millionths; + struct bitcoin_blkid chain_hash; + secp256k1_ecdsa_signature sig; + u64 htlc_minimum_msat; + u8 *err, *msg; + + direction = pubkey_eq(&chan->nodes[0]->id, &rstate->local_id)?0:1; + + assert(chan); + hc = &chan->half[direction]; + + status_trace("Disabling channel %s/%d, active %d -> %d", + type_to_string(tmpctx, struct short_channel_id, &chan->scid), + direction, is_halfchan_enabled(hc), 0); + + if (!is_halfchan_defined(hc)) { + status_trace( + "Channel %s/%d doesn't have a channel_update yet, can't " + "disable", + type_to_string(tmpctx, struct short_channel_id, &scid), + direction); + return; + } + + if (!fromwire_channel_update( + hc->channel_update, &sig, &chain_hash, &scid, ×tamp, + &flags, &cltv_expiry_delta, &htlc_minimum_msat, &fee_base_msat, + &fee_proportional_millionths)) { + status_failed( + STATUS_FAIL_INTERNAL_ERROR, + "Unable to parse previously accepted channel_update"); + } + + status_trace("Disabling channel %s", type_to_string(tmpctx, struct short_channel_id, &scid)); + + timestamp = time_now().ts.tv_sec; + if (timestamp <= hc->last_timestamp) + timestamp = hc->last_timestamp + 1; + + status_trace("Disabling channel %s: %d", type_to_string(tmpctx, struct short_channel_id, &scid), 0); + + flags = flags | ROUTING_FLAGS_DISABLED; + + msg = towire_channel_update(tmpctx, &sig, &chain_hash, &scid, timestamp, + flags, cltv_expiry_delta, htlc_minimum_msat, + fee_base_msat, fee_proportional_millionths); + + if (!wire_sync_write(HSM_FD, + towire_hsm_cupdate_sig_req(tmpctx, msg))) { + status_failed(STATUS_FAIL_HSM_IO, "Writing cupdate_sig_req: %s", + strerror(errno)); + } + + msg = wire_sync_read(tmpctx, HSM_FD); + if (!msg || !fromwire_hsm_cupdate_sig_reply(tmpctx, msg, &msg)) { + status_failed(STATUS_FAIL_HSM_IO, + "Reading cupdate_sig_req: %s", + strerror(errno)); + } + + err = handle_channel_update(rstate, msg, "disable_channel"); + if (err) + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "rejected disabling channel_update: %s", + tal_hex(tmpctx, err)); +} + +static void peer_disable_channels(struct routing_state *rstate, struct node *node) +{ + struct chan *c; + size_t i; + for (i=0; ichans); i++) { + c = node->chans[i]; + if (pubkey_eq(&other_node(node, c)->id, &rstate->local_id)) { + c->half[0].flags |= ROUTING_FLAGS_DISABLED; + c->half[1].flags |= ROUTING_FLAGS_DISABLED; + gossip_disable_channel(rstate, c); + } + } +} + static struct io_plan *peer_disconnected(struct io_conn *conn, struct daemon *daemon, const u8 *msg) { struct pubkey id; struct peer *peer; + struct node *node; if (!fromwire_gossipctl_peer_disconnected(msg, &id)) master_badmsg(WIRE_GOSSIPCTL_PEER_DISCONNECTED, msg); @@ -2375,6 +2463,11 @@ static struct io_plan *peer_disconnected(struct io_conn *conn, status_trace("Forgetting remote peer %s", type_to_string(tmpctx, struct pubkey, &peer->id)); + /* Disable any channels to and from this peer */ + node = get_node(daemon->rstate, &id); + if (node) + peer_disable_channels(daemon->rstate, node); + tal_free(peer); /* If there was a connecting peer waiting, wake it now */ @@ -2440,92 +2533,6 @@ static struct io_plan *handle_txout_reply(struct io_conn *conn, return daemon_conn_read_next(conn, &daemon->master); } -static struct io_plan *handle_disable_channel(struct io_conn *conn, - struct daemon *daemon, u8 *msg) -{ - struct short_channel_id scid; - u8 direction; - struct chan *chan; - struct half_chan *hc; - bool active; - u16 flags, cltv_expiry_delta; - u32 timestamp, fee_base_msat, fee_proportional_millionths; - struct bitcoin_blkid chain_hash; - secp256k1_ecdsa_signature sig; - u64 htlc_minimum_msat; - u8 *err; - - if (!fromwire_gossip_disable_channel(msg, &scid, &direction, &active) ) { - status_unusual("Unable to parse %s", - gossip_wire_type_name(fromwire_peektype(msg))); - goto fail; - } - - chan = get_channel(daemon->rstate, &scid); - if (!chan) { - status_trace( - "Unable to find channel %s", - type_to_string(msg, struct short_channel_id, &scid)); - goto fail; - } - hc = &chan->half[direction]; - - status_trace("Disabling channel %s/%d, active %d -> %d", - type_to_string(msg, struct short_channel_id, &scid), - direction, is_halfchan_enabled(hc), active); - - if (!is_halfchan_defined(hc)) { - status_trace( - "Channel %s/%d doesn't have a channel_update yet, can't " - "disable", - type_to_string(msg, struct short_channel_id, &scid), - direction); - goto fail; - } - - if (!fromwire_channel_update( - hc->channel_update, &sig, &chain_hash, &scid, ×tamp, - &flags, &cltv_expiry_delta, &htlc_minimum_msat, &fee_base_msat, - &fee_proportional_millionths)) { - status_failed( - STATUS_FAIL_INTERNAL_ERROR, - "Unable to parse previously accepted channel_update"); - } - - timestamp = time_now().ts.tv_sec; - if (timestamp <= hc->last_timestamp) - timestamp = hc->last_timestamp + 1; - - flags = direction; - if (!active) - flags |= ROUTING_FLAGS_DISABLED; - - msg = towire_channel_update(tmpctx, &sig, &chain_hash, &scid, timestamp, - flags, cltv_expiry_delta, htlc_minimum_msat, - fee_base_msat, fee_proportional_millionths); - - if (!wire_sync_write(HSM_FD, - towire_hsm_cupdate_sig_req(tmpctx, msg))) { - status_failed(STATUS_FAIL_HSM_IO, "Writing cupdate_sig_req: %s", - strerror(errno)); - } - - msg = wire_sync_read(tmpctx, HSM_FD); - if (!msg || !fromwire_hsm_cupdate_sig_reply(tmpctx, msg, &msg)) { - status_failed(STATUS_FAIL_HSM_IO, - "Reading cupdate_sig_req: %s", - strerror(errno)); - } - - err = handle_channel_update(daemon->rstate, msg, "disable_channel"); - if (err) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "rejected disabling channel_update: %s", - tal_hex(tmpctx, err)); - -fail: - return daemon_conn_read_next(conn, &daemon->master); -} static struct io_plan *handle_routing_failure(struct io_conn *conn, struct daemon *daemon, const u8 *msg) @@ -2615,6 +2622,7 @@ static struct io_plan *handle_local_channel_close(struct io_conn *conn, if (chan) { chan->half[0].flags |= ROUTING_FLAGS_DISABLED; chan->half[1].flags |= ROUTING_FLAGS_DISABLED; + gossip_disable_channel(rstate, chan); } return daemon_conn_read_next(conn, &daemon->master); } @@ -2670,9 +2678,6 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master case WIRE_GOSSIP_GET_TXOUT_REPLY: return handle_txout_reply(conn, daemon, master->msg_in); - case WIRE_GOSSIP_DISABLE_CHANNEL: - return handle_disable_channel(conn, daemon, master->msg_in); - case WIRE_GOSSIP_ROUTING_FAILURE: return handle_routing_failure(conn, daemon, master->msg_in); diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index 9019fbebf..53acd72df 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -220,12 +220,6 @@ gossip_get_txout_reply,,satoshis,u64 gossip_get_txout_reply,,len,u16 gossip_get_txout_reply,,outscript,len*u8 -# client->gossipd: Disable the channel matching the short_channel_id -gossip_disable_channel,3019 -gossip_disable_channel,,short_channel_id,struct short_channel_id -gossip_disable_channel,,direction,u8 -gossip_disable_channel,,active,bool - # master->gossipd a routing failure occurred gossip_routing_failure,3021 gossip_routing_failure,,erring_node,struct pubkey diff --git a/lightningd/channel.c b/lightningd/channel.c index 26d74a368..d20d4036f 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -329,14 +329,6 @@ void channel_fail_permanent(struct channel *channel, const char *fmt, ...) why = tal_vfmt(channel, fmt, ap); va_end(ap); - if (channel->scid) { - u8 *msg = towire_gossip_disable_channel(NULL, - channel->scid, - channel->peer->direction, - false); - subd_send_msg(ld->gossip, take(msg)); - } - log_unusual(channel->log, "Peer permanent failure in %s: %s", channel_state_name(channel), why); diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 85073118d..39e553bd4 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -133,7 +133,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIP_GET_UPDATE: case WIRE_GOSSIP_SEND_GOSSIP: case WIRE_GOSSIP_GET_TXOUT_REPLY: - case WIRE_GOSSIP_DISABLE_CHANNEL: case WIRE_GOSSIP_OUTPOINT_SPENT: case WIRE_GOSSIP_ROUTING_FAILURE: case WIRE_GOSSIP_MARK_CHANNEL_UNROUTABLE: diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index ed26dd16c..73e5c9929 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -52,7 +52,7 @@ bool channel_tell_funding_locked(struct lightningd *ld UNNEEDED, { fprintf(stderr, "channel_tell_funding_locked called!\n"); abort(); } /* Generated stub for command_fail */ void command_fail(struct command *cmd UNNEEDED, int code UNNEEDED, - const char *fmt UNNEEDED, ...) + const char *fmt UNNEEDED, ...) { fprintf(stderr, "command_fail called!\n"); abort(); } /* Generated stub for command_still_pending */ void command_still_pending(struct command *cmd UNNEEDED) @@ -388,9 +388,6 @@ u8 *towire_gossipctl_peer_disconnected(const tal_t *ctx UNNEEDED, const struct p /* Generated stub for towire_gossipctl_peer_important */ u8 *towire_gossipctl_peer_important(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED, bool important UNNEEDED) { fprintf(stderr, "towire_gossipctl_peer_important called!\n"); abort(); } -/* Generated stub for towire_gossip_disable_channel */ -u8 *towire_gossip_disable_channel(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED, u8 direction UNNEEDED, bool active UNNEEDED) -{ fprintf(stderr, "towire_gossip_disable_channel called!\n"); abort(); } /* Generated stub for towire_gossip_getpeers_request */ u8 *towire_gossip_getpeers_request(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED) { fprintf(stderr, "towire_gossip_getpeers_request called!\n"); abort(); }