From b7680412e3b73ba95f372f637aac44017bfb4bcb Mon Sep 17 00:00:00 2001
From: Rusty Russell <rusty@rustcorp.com.au>
Date: Mon, 12 Feb 2018 20:43:04 +1030
Subject: [PATCH] lightningd: rename peer_fail functions to channel_fail.

And move them into channel.c.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 lightningd/channel.c      | 102 ++++++++++++++++++
 lightningd/channel.h      |   8 ++
 lightningd/peer_control.c | 210 ++++++++++++--------------------------
 lightningd/peer_control.h |   9 +-
 lightningd/peer_htlcs.c   |  80 +++++++++------
 lightningd/subd.c         |  14 +--
 6 files changed, 232 insertions(+), 191 deletions(-)

diff --git a/lightningd/channel.c b/lightningd/channel.c
index 1b380bf2b..b1024933a 100644
--- a/lightningd/channel.c
+++ b/lightningd/channel.c
@@ -121,3 +121,105 @@ struct peer *channel2peer(const struct channel *channel)
 {
 	return channel->peer;
 }
+
+void channel_fail_permanent(struct channel *channel, const char *fmt, ...)
+{
+	struct lightningd *ld = channel->peer->ld;
+	va_list ap;
+	char *why;
+	u8 *msg;
+
+	va_start(ap, fmt);
+	why = tal_vfmt(channel, fmt, ap);
+	va_end(ap);
+
+	if (channel->scid) {
+		msg = towire_gossip_disable_channel(channel,
+						    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);
+
+	/* We can have multiple errors, eg. onchaind failures. */
+	if (!channel->error) {
+		/* BOLT #1:
+		 *
+		 * The channel is referred to by `channel_id` unless `channel_id` is
+		 * zero (ie. all bytes zero), in which case it refers to all
+		 * channels. */
+		static const struct channel_id all_channels;
+		u8 *msg = tal_dup_arr(NULL, u8, (const u8 *)why, strlen(why), 0);
+		channel->error = towire_error(channel, &all_channels, msg);
+		tal_free(msg);
+	}
+
+	channel_set_owner(channel, NULL);
+	if (channel_persists(channel)) {
+		drop_to_chain(ld, channel);
+		tal_free(why);
+	} else
+		free_channel(channel, why);
+}
+
+void channel_internal_error(struct channel *channel, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	log_broken(channel->log, "Peer internal error %s: ",
+		   channel_state_name(channel));
+	logv_add(channel->log, fmt, ap);
+	va_end(ap);
+
+	channel_fail_permanent(channel, "Internal error");
+}
+
+void channel_fail_transient(struct channel *channel, const char *fmt, ...)
+{
+	va_list ap;
+	const char *why;
+
+	va_start(ap, fmt);
+	why = tal_vfmt(channel, fmt, ap);
+	va_end(ap);
+	log_info(channel->log, "Peer transient failure in %s: %s",
+		 channel_state_name(channel), why);
+
+#if DEVELOPER
+	if (dev_disconnect_permanent(channel->peer->ld)) {
+		tal_free(why);
+		channel_internal_error(channel, "dev_disconnect permfail");
+		return;
+	}
+#endif
+
+	channel_set_owner(channel, NULL);
+
+	/* If we haven't reached awaiting locked, we don't need to reconnect */
+	if (!channel_persists(channel)) {
+		log_info(channel->log, "Only reached state %s: forgetting",
+			 channel_state_name(channel));
+		free_channel(channel, why);
+		return;
+	}
+	tal_free(why);
+
+	/* Reconnect unless we've dropped/are dropping to chain. */
+	if (channel_active(channel)) {
+		struct lightningd *ld = channel->peer->ld;
+
+#if DEVELOPER
+		/* Don't schedule an attempt if we disabled reconnections with
+		 * the `--dev-no-reconnect` flag */
+		if (ld->no_reconnect)
+			return;
+#endif /* DEVELOPER */
+		u8 *msg = towire_gossipctl_reach_peer(channel,
+						      &channel->peer->id);
+		subd_send_msg(ld->gossip, take(msg));
+	}
+}
diff --git a/lightningd/channel.h b/lightningd/channel.h
index 0445d30a7..9d78e37e6 100644
--- a/lightningd/channel.h
+++ b/lightningd/channel.h
@@ -97,6 +97,14 @@ void derive_channel_seed(struct lightningd *ld, struct privkey *seed,
 			 const struct pubkey *peer_id,
 			 const u64 dbid);
 
+/* Channel has failed, but can try again. */
+PRINTF_FMT(2,3) void channel_fail_transient(struct channel *channel,
+					    const char *fmt,...);
+/* Channel has failed, give up on it. */
+void channel_fail_permanent(struct channel *channel, const char *fmt, ...);
+/* Permanent error, but due to internal problems, not peer. */
+void channel_internal_error(struct channel *channel, const char *fmt, ...);
+
 /* FIXME: Temporary mapping from peer to channel, while we only have one. */
 struct channel *peer2channel(const struct peer *peer);
 struct peer *channel2peer(const struct channel *channel);
diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c
index 0dbe92930..2dabb4e1f 100644
--- a/lightningd/peer_control.c
+++ b/lightningd/peer_control.c
@@ -206,112 +206,14 @@ static void remove_sig(struct bitcoin_tx *signed_tx)
 	signed_tx->input[0].witness = tal_free(signed_tx->input[0].witness);
 }
 
-static void drop_to_chain(struct peer *peer)
+void drop_to_chain(struct lightningd *ld, struct channel *channel)
 {
-	sign_last_tx(peer);
+	sign_last_tx(channel2peer(channel));
 
 	/* Keep broadcasting until we say stop (can fail due to dup,
 	 * if they beat us to the broadcast). */
-	broadcast_tx(peer->ld->topology, peer, peer2channel(peer)->last_tx, NULL);
-	remove_sig(peer2channel(peer)->last_tx);
-}
-
-void peer_fail_permanent(struct peer *peer, const char *fmt, ...)
-{
-	va_list ap;
-	char *why;
-	u8 *msg;
-	struct channel *channel = peer2channel(peer);
-
-	va_start(ap, fmt);
-	why = tal_vfmt(peer, fmt, ap);
-	va_end(ap);
-
-	if (channel->scid) {
-		msg = towire_gossip_disable_channel(peer,
-						    channel->scid,
-						    peer->direction, false);
-		subd_send_msg(peer->ld->gossip, take(msg));
-	}
-
-	log_unusual(peer->log, "Peer permanent failure in %s: %s",
-		    peer_state_name(channel->state), why);
-
-	/* We can have multiple errors, eg. onchaind failures. */
-	if (!channel->error) {
-		/* BOLT #1:
-		 *
-		 * The channel is referred to by `channel_id` unless `channel_id` is
-		 * zero (ie. all bytes zero), in which case it refers to all
-		 * channels. */
-		static const struct channel_id all_channels;
-		u8 *msg = tal_dup_arr(peer, u8, (const u8 *)why, strlen(why), 0);
-		channel->error = towire_error(peer, &all_channels, msg);
-		tal_free(msg);
-	}
-
-	peer_set_owner(peer, NULL);
-	if (peer_persists(peer)) {
-		drop_to_chain(peer);
-		tal_free(why);
-	} else
-		free_channel(channel, why);
-}
-
-void peer_internal_error(struct peer *peer, const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	log_broken(peer->log, "Peer internal error %s: ",
-		   channel_state_name(peer2channel(peer)));
-	logv_add(peer->log, fmt, ap);
-	va_end(ap);
-
-	peer_fail_permanent(peer, "Internal error");
-}
-
-void peer_fail_transient(struct peer *peer, const char *fmt, ...)
-{
-	va_list ap;
-	const char *why;
-
-	va_start(ap, fmt);
-	why = tal_vfmt(peer, fmt, ap);
-	va_end(ap);
-	log_info(peer->log, "Peer transient failure in %s: %s",
-		 channel_state_name(peer2channel(peer)), why);
-
-#if DEVELOPER
-	if (dev_disconnect_permanent(peer->ld)) {
-		tal_free(why);
-		peer_internal_error(peer, "dev_disconnect permfail");
-		return;
-	}
-#endif
-
-	peer_set_owner(peer, NULL);
-
-	/* If we haven't reached awaiting locked, we don't need to reconnect */
-	if (!peer_persists(peer)) {
-		log_info(peer->log, "Only reached state %s: forgetting",
-			 channel_state_name(peer2channel(peer)));
-		free_channel(peer2channel(peer), why);
-		return;
-	}
-	tal_free(why);
-
-	/* Reconnect unless we've dropped/are dropping to chain. */
-	if (!peer_on_chain(peer) && peer2channel(peer)->state != CLOSINGD_COMPLETE) {
-#if DEVELOPER
-		/* Don't schedule an attempt if we disabled reconnections with
-		 * the `--dev-no-reconnect` flag */
-		if (peer->ld->no_reconnect)
-			return;
-#endif /* DEVELOPER */
-		u8 *msg = towire_gossipctl_reach_peer(peer, &peer->id);
-		subd_send_msg(peer->ld->gossip, take(msg));
-	}
+	broadcast_tx(ld->topology, channel2peer(channel), channel->last_tx, NULL);
+	remove_sig(channel->last_tx);
 }
 
 void peer_set_condition(struct peer *peer, enum peer_state old_state,
@@ -481,7 +383,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
 
 #if DEVELOPER
 		if (dev_disconnect_permanent(ld)) {
-			peer_internal_error(peer, "dev_disconnect permfail");
+			channel_internal_error(channel, "dev_disconnect permfail");
 			error = channel->error;
 			goto send_error;
 	}
@@ -955,8 +857,9 @@ struct funding_channel {
 static void funding_broadcast_failed(struct peer *peer,
 				     int exitstatus, const char *err)
 {
-	peer_internal_error(peer, "Funding broadcast exited with %i: %s",
-			    exitstatus, err);
+	channel_internal_error(peer2channel(peer),
+			       "Funding broadcast exited with %i: %s",
+			       exitstatus, err);
 }
 
 static enum watch_result funding_announce_cb(struct peer *peer,
@@ -1023,14 +926,15 @@ static void onchaind_tell_fulfill(struct peer *peer)
 static void handle_onchain_init_reply(struct peer *peer, const u8 *msg)
 {
 	u8 state;
+	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_onchain_init_reply(msg, NULL, &state)) {
-		peer_internal_error(peer, "Invalid onchain_init_reply");
+		channel_internal_error(channel, "Invalid onchain_init_reply");
 		return;
 	}
 
 	if (!channel_state_on_chain(state)) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "Invalid onchain_init_reply state %u (%s)",
 				    state, peer_state_name(state));
 		return;
@@ -1112,9 +1016,10 @@ static void watch_tx_and_outputs(struct peer *peer,
 static void handle_onchain_broadcast_tx(struct peer *peer, const u8 *msg)
 {
 	struct bitcoin_tx *tx;
+	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_onchain_broadcast_tx(msg, msg, NULL, &tx)) {
-		peer_internal_error(peer, "Invalid onchain_broadcast_tx");
+		channel_internal_error(channel, "Invalid onchain_broadcast_tx");
 		return;
 	}
 
@@ -1126,9 +1031,10 @@ static void handle_onchain_unwatch_tx(struct peer *peer, const u8 *msg)
 {
 	struct bitcoin_txid txid;
 	struct txwatch *txw;
+	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_onchain_unwatch_tx(msg, NULL, &txid)) {
-		peer_internal_error(peer, "Invalid onchain_unwatch_tx");
+		channel_internal_error(channel, "Invalid onchain_unwatch_tx");
 		return;
 	}
 
@@ -1143,9 +1049,10 @@ static void handle_onchain_unwatch_tx(struct peer *peer, const u8 *msg)
 static void handle_extracted_preimage(struct peer *peer, const u8 *msg)
 {
 	struct preimage preimage;
+	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_onchain_extracted_preimage(msg, NULL, &preimage)) {
-		peer_internal_error(peer, "Invalid extracted_preimage");
+		channel_internal_error(channel, "Invalid extracted_preimage");
 		return;
 	}
 
@@ -1155,9 +1062,10 @@ static void handle_extracted_preimage(struct peer *peer, const u8 *msg)
 static void handle_missing_htlc_output(struct peer *peer, const u8 *msg)
 {
 	struct htlc_stub htlc;
+	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_onchain_missing_htlc_output(msg, NULL, &htlc)) {
-		peer_internal_error(peer, "Invalid missing_htlc_output");
+		channel_internal_error(channel, "Invalid missing_htlc_output");
 		return;
 	}
 
@@ -1175,9 +1083,10 @@ static void handle_missing_htlc_output(struct peer *peer, const u8 *msg)
 static void handle_onchain_htlc_timeout(struct peer *peer, const u8 *msg)
 {
 	struct htlc_stub htlc;
+	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_onchain_htlc_timeout(msg, NULL, &htlc)) {
-		peer_internal_error(peer, "Invalid onchain_htlc_timeout");
+		channel_internal_error(channel, "Invalid onchain_htlc_timeout");
 		return;
 	}
 
@@ -1366,7 +1275,7 @@ static enum watch_result funding_spent(struct peer *peer,
 	const tal_t *tmpctx = tal_tmpctx(peer);
 	struct channel *channel = peer2channel(peer);
 
-	peer_fail_permanent(peer, "Funding transaction spent");
+	channel_fail_permanent(channel, "Funding transaction spent");
 
 	/* We could come from almost any state. */
 	peer_set_condition(peer, channel->state, FUNDING_SPEND_SEEN);
@@ -1404,7 +1313,7 @@ static enum watch_result funding_spent(struct peer *peer,
 	}
 	scriptpubkey = p2wpkh_for_keyidx(tmpctx, peer->ld, keyindex);
 	if (!scriptpubkey) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "Can't get shutdown script %"PRIu64,
 				    keyindex);
 		tal_free(tmpctx);
@@ -1413,7 +1322,7 @@ static enum watch_result funding_spent(struct peer *peer,
 	txfilter_add_scriptpubkey(peer->ld->owned_txfilter, scriptpubkey);
 
 	if (!bip32_pubkey(peer->ld->wallet->bip32_base, &ourkey, keyindex)) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "Can't get shutdown key %"PRIu64,
 				    keyindex);
 		tal_free(tmpctx);
@@ -1597,13 +1506,15 @@ static void peer_got_funding_locked(struct peer *peer, const u8 *msg)
 
 	if (!fromwire_channel_got_funding_locked(msg, NULL,
 						 &next_per_commitment_point)) {
-		peer_internal_error(peer, "bad channel_got_funding_locked %s",
-				    tal_hex(peer, msg));
+		channel_internal_error(channel,
+				       "bad channel_got_funding_locked %s",
+				       tal_hex(channel, msg));
 		return;
 	}
 
 	if (channel->remote_funding_locked) {
-		peer_internal_error(peer, "channel_got_funding_locked twice");
+		channel_internal_error(channel,
+				       "channel_got_funding_locked twice");
 		return;
 	}
 	update_per_commit_point(peer, &next_per_commitment_point);
@@ -1618,8 +1529,8 @@ static void peer_got_shutdown(struct peer *peer, const u8 *msg)
 	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_channel_got_shutdown(peer, msg, NULL, &scriptpubkey)) {
-		peer_internal_error(peer, "bad channel_got_shutdown %s",
-				    tal_hex(peer, msg));
+		channel_internal_error(channel, "bad channel_got_shutdown %s",
+				       tal_hex(msg, msg));
 		return;
 	}
 
@@ -1641,8 +1552,8 @@ static void peer_got_shutdown(struct peer *peer, const u8 *msg)
 	 * is not one of those forms. */
 	if (!is_p2pkh(scriptpubkey, NULL) && !is_p2sh(scriptpubkey, NULL)
 	    && !is_p2wpkh(scriptpubkey, NULL) && !is_p2wsh(scriptpubkey, NULL)) {
-		peer_fail_permanent(peer, "Bad shutdown scriptpubkey %s",
-				    tal_hex(peer, scriptpubkey));
+		channel_fail_permanent(channel, "Bad shutdown scriptpubkey %s",
+				       tal_hex(channel, scriptpubkey));
 		return;
 	}
 
@@ -1651,7 +1562,7 @@ static void peer_got_shutdown(struct peer *peer, const u8 *msg)
 
 		channel->local_shutdown_idx = wallet_get_newindex(peer->ld);
 		if (channel->local_shutdown_idx == -1) {
-			peer_internal_error(peer,
+			channel_internal_error(channel,
 					    "Can't get local shutdown index");
 			return;
 		}
@@ -1668,7 +1579,7 @@ static void peer_got_shutdown(struct peer *peer, const u8 *msg)
 		scriptpubkey = p2wpkh_for_keyidx(msg, peer->ld,
 						 channel->local_shutdown_idx);
 		if (!scriptpubkey) {
-			peer_internal_error(peer,
+			channel_internal_error(channel,
 					    "Can't get shutdown script %"PRIu64,
 					    channel->local_shutdown_idx);
 			return;
@@ -1763,8 +1674,8 @@ static void peer_received_closing_signature(struct peer *peer, const u8 *msg)
 	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_closing_received_signature(msg, msg, NULL, &sig, &tx)) {
-		peer_internal_error(peer, "Bad closing_received_signature %s",
-				    tal_hex(peer, msg));
+		channel_internal_error(channel, "Bad closing_received_signature %s",
+				       tal_hex(msg, msg));
 		return;
 	}
 
@@ -1782,12 +1693,13 @@ static void peer_received_closing_signature(struct peer *peer, const u8 *msg)
 
 static void peer_closing_complete(struct peer *peer, const u8 *msg)
 {
+	struct channel *channel = peer2channel(peer);
 	/* FIXME: We should save this, to return to gossipd */
 	u64 gossip_index;
 
 	if (!fromwire_closing_complete(msg, NULL, &gossip_index)) {
-		peer_internal_error(peer, "Bad closing_complete %s",
-				    tal_hex(peer, msg));
+		channel_internal_error(channel, "Bad closing_complete %s",
+				       tal_hex(msg, msg));
 		return;
 	}
 
@@ -1795,7 +1707,7 @@ static void peer_closing_complete(struct peer *peer, const u8 *msg)
 	if (peer2channel(peer)->state == CLOSINGD_COMPLETE)
 		return;
 
-	drop_to_chain(peer);
+	drop_to_chain(peer->ld, channel);
 	peer_set_condition(peer, CLOSINGD_SIGEXCHANGE, CLOSINGD_COMPLETE);
 }
 
@@ -1836,7 +1748,7 @@ static void peer_start_closingd(struct peer *peer,
 
 	if (channel->local_shutdown_idx == -1
 	    || !channel->remote_shutdown_scriptpubkey) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "Can't start closing: local %s remote %s",
 				    channel->local_shutdown_idx == -1
 				    ? "not shutdown" : "shutdown",
@@ -1854,7 +1766,7 @@ static void peer_start_closingd(struct peer *peer,
 	if (!channel->owner) {
 		log_unusual(peer->log, "Could not subdaemon closing: %s",
 			    strerror(errno));
-		peer_fail_transient(peer, "Failed to subdaemon closing");
+		channel_fail_transient(channel, "Failed to subdaemon closing");
 		tal_free(tmpctx);
 		return;
 	}
@@ -1862,7 +1774,7 @@ static void peer_start_closingd(struct peer *peer,
 	local_scriptpubkey = p2wpkh_for_keyidx(tmpctx, peer->ld,
 					       channel->local_shutdown_idx);
 	if (!local_scriptpubkey) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "Can't generate local shutdown scriptpubkey");
 		tal_free(tmpctx);
 		return;
@@ -1930,6 +1842,7 @@ static void peer_start_closingd(struct peer *peer,
 static void peer_start_closingd_after_shutdown(struct peer *peer, const u8 *msg,
 					       const int *fds)
 {
+	struct channel *channel = peer2channel(peer);
 	struct crypto_state cs;
 	u64 gossip_index;
 
@@ -1937,7 +1850,7 @@ static void peer_start_closingd_after_shutdown(struct peer *peer, const u8 *msg,
 	assert(tal_count(fds) == 2);
 
 	if (!fromwire_channel_shutdown_complete(msg, NULL, &cs, &gossip_index)) {
-		peer_internal_error(peer, "bad shutdown_complete: %s",
+		channel_internal_error(channel, "bad shutdown_complete: %s",
 				    tal_hex(peer, msg));
 		return;
 	}
@@ -2082,7 +1995,7 @@ static bool peer_start_channeld(struct peer *peer,
 	if (!channel->owner) {
 		log_unusual(peer->log, "Could not subdaemon channel: %s",
 			    strerror(errno));
-		peer_fail_transient(peer, "Failed to subdaemon channel");
+		channel_fail_transient(channel, "Failed to subdaemon channel");
 		tal_free(tmpctx);
 		return true;
 	}
@@ -2213,7 +2126,7 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
 					   &channel_info->remote_fundingkey,
 					   &funding_txid,
 					   &channel_info->feerate_per_kw[REMOTE])) {
-		peer_internal_error(fc->peer, "bad funder_reply: %s",
+		channel_internal_error(channel, "bad funder_reply: %s",
 				    tal_hex(resp, resp));
 		return;
 	}
@@ -2258,7 +2171,7 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
 	bitcoin_txid(fundingtx, channel->funding_txid);
 
 	if (!structeq(channel->funding_txid, &funding_txid)) {
-		peer_internal_error(fc->peer,
+		channel_internal_error(channel,
 				    "Funding txid mismatch:"
 				    " satoshi %"PRIu64" change %"PRIu64
 				    " changeidx %u"
@@ -2273,7 +2186,7 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
 	}
 
 	if (!peer_commit_initial(fc->peer)) {
-		peer_internal_error(fc->peer, "Initial peer to db failed");
+		channel_internal_error(channel, "Initial peer to db failed");
 		return;
 	}
 
@@ -2339,7 +2252,7 @@ static void opening_fundee_finished(struct subd *opening,
 					   &channel->channel_flags,
 					   &channel_info->feerate_per_kw[REMOTE],
 					   &funding_signed)) {
-		peer_internal_error(peer, "bad OPENING_FUNDEE_REPLY %s",
+		channel_internal_error(channel, "bad OPENING_FUNDEE_REPLY %s",
 				    tal_hex(reply, reply));
 		tal_free(tmpctx);
 		return;
@@ -2388,6 +2301,7 @@ static unsigned int opening_negotiation_failed(struct subd *openingd,
 	struct crypto_state cs;
 	u64 gossip_index;
 	struct peer *peer = openingd->peer;
+	struct channel *channel = peer2channel(peer);
 	char *why;
 
 	/* We need the peer fd and gossip fd. */
@@ -2396,7 +2310,7 @@ static unsigned int opening_negotiation_failed(struct subd *openingd,
 
 	if (!fromwire_opening_negotiation_failed(msg, msg, NULL,
 						 &cs, &gossip_index, &why)) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "bad OPENING_NEGOTIATION_FAILED %s",
 				    tal_hex(msg, msg));
 		return 0;
@@ -2449,8 +2363,9 @@ static void peer_accept_channel(struct lightningd *ld,
 				     opening_negotiation_failed,
 				     take(&peer_fd), take(&gossip_fd), NULL));
 	if (!channel->owner) {
-		peer_fail_transient(peer, "Failed to subdaemon opening: %s",
-				    strerror(errno));
+		channel_fail_transient(channel,
+				       "Failed to subdaemon opening: %s",
+				       strerror(errno));
 		return;
 	}
 
@@ -2708,8 +2623,8 @@ static void json_close(struct command *cmd,
 
 	/* Easy case: peer can simply be forgotten. */
 	if (!peer_persists(peer)) {
-		peer_fail_permanent(peer, "Peer closed in state %s",
-				    channel_state_name(peer2channel(peer)));
+		channel_fail_permanent(channel, "Peer closed in state %s",
+				       channel_state_name(channel));
 		command_success(cmd, null_response(cmd));
 		return;
 	}
@@ -2855,6 +2770,7 @@ static void json_dev_fail(struct command *cmd,
 {
 	jsmntok_t *peertok;
 	struct peer *peer;
+	struct channel *channel;
 
 	if (!json_get_params(cmd, buffer, params,
 			     "id", &peertok,
@@ -2868,7 +2784,13 @@ static void json_dev_fail(struct command *cmd,
 		return;
 	}
 
-	peer_internal_error(peer, "Failing due to dev-fail command");
+	channel = peer_active_channel(peer);
+	if (!channel) {
+		command_fail(cmd, "Could not find active channel with peer");
+		return;
+	}
+
+	channel_internal_error(channel, "Failing due to dev-fail command");
 	command_success(cmd, null_response(cmd));
 }
 
diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h
index 260539d65..be01dac89 100644
--- a/lightningd/peer_control.h
+++ b/lightningd/peer_control.h
@@ -90,13 +90,6 @@ void peer_sent_nongossip(struct lightningd *ld,
 /* Could be configurable. */
 #define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL
 
-/* Peer has failed, but try reconnected. */
-PRINTF_FMT(2,3) void peer_fail_transient(struct peer *peer, const char *fmt,...);
-/* Peer has failed, give up on it. */
-void peer_fail_permanent(struct peer *peer, const char *fmt, ...);
-/* Permanent error, but due to internal problems, not peer. */
-void peer_internal_error(struct peer *peer, const char *fmt, ...);
-
 /* Peer has failed to open; return to gossipd. */
 void opening_failed(struct peer *peer, const u8 *msg TAKES);
 
@@ -108,6 +101,8 @@ void setup_listeners(struct lightningd *ld);
 /* We've loaded peers from database, set them going. */
 void activate_peers(struct lightningd *ld);
 
+void drop_to_chain(struct lightningd *ld, struct channel *channel);
+
 void free_htlcs(struct lightningd *ld, const struct peer *peer);
 
 /* Get range of feerates to insist other side abide by for normal channels. */
diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c
index 0a3195392..7d15ea671 100644
--- a/lightningd/peer_htlcs.c
+++ b/lightningd/peer_htlcs.c
@@ -27,6 +27,7 @@ static bool state_update_ok(struct peer *peer,
 			    u64 htlc_id, const char *dir)
 {
 	enum htlc_state expected = oldstate + 1;
+	struct channel *channel = peer2channel(peer);
 
 	/* We never get told about RCVD_REMOVE_HTLC, so skip over that
 	 * (we initialize in SENT_ADD_HTLC / RCVD_ADD_COMMIT, so those
@@ -35,11 +36,11 @@ static bool state_update_ok(struct peer *peer,
 		expected = RCVD_REMOVE_COMMIT;
 
 	if (newstate != expected) {
-		peer_internal_error(peer,
-				    "HTLC %s %"PRIu64" invalid update %s->%s",
-				    dir, htlc_id,
-				    htlc_state_name(oldstate),
-				    htlc_state_name(newstate));
+		channel_internal_error(channel,
+				       "HTLC %s %"PRIu64" invalid update %s->%s",
+				       dir, htlc_id,
+				       htlc_state_name(oldstate),
+				       htlc_state_name(newstate));
 		return false;
 	}
 
@@ -333,7 +334,8 @@ static void rcvd_htlc_reply(struct subd *subd, const u8 *msg, const int *fds,
 					       &hout->key.id,
 					       &failure_code,
 					       &failurestr)) {
-		peer_internal_error(subd->peer, "Bad channel_offer_htlc_reply");
+		channel_internal_error(peer2channel(subd->peer),
+				       "Bad channel_offer_htlc_reply");
 		tal_free(hout);
 		return;
 	}
@@ -357,7 +359,7 @@ static void rcvd_htlc_reply(struct subd *subd, const u8 *msg, const int *fds,
 
 	if (find_htlc_out(&subd->ld->htlcs_out, hout->key.peer, hout->key.id)
 	    || hout->key.id == HTLC_INVALID_ID) {
-		peer_internal_error(subd->peer,
+		channel_internal_error(peer2channel(subd->peer),
 				    "Bad offer_htlc_reply HTLC id %"PRIu64
 				    " is a duplicate",
 				    hout->key.id);
@@ -551,10 +553,11 @@ static bool peer_accepted_htlc(struct peer *peer,
 	struct route_step *rs;
 	struct onionpacket *op;
 	const tal_t *tmpctx = tal_tmpctx(peer);
+	struct channel *channel = peer2channel(peer);
 
 	hin = find_htlc_in(&peer->ld->htlcs_in, peer, id);
 	if (!hin) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "peer_got_revoke unknown htlc %"PRIu64, id);
 		return false;
 	}
@@ -566,7 +569,7 @@ static bool peer_accepted_htlc(struct peer *peer,
 	 *
 	 * A sending node SHOULD fail to route any HTLC added after it
 	 * sent `shutdown`. */
-	if (peer2channel(peer)->state == CHANNELD_SHUTTING_DOWN) {
+	if (channel->state == CHANNELD_SHUTTING_DOWN) {
 		*failcode = WIRE_PERMANENT_CHANNEL_FAILURE;
 		goto out;
 	}
@@ -586,9 +589,9 @@ static bool peer_accepted_htlc(struct peer *peer,
 			       sizeof(hin->onion_routing_packet));
 	if (!op) {
 		if (!memeqzero(&hin->shared_secret, sizeof(hin->shared_secret))){
-			peer_internal_error(peer,
+			channel_internal_error(channel,
 				   "bad onion in got_revoke: %s",
-				   tal_hexstr(peer, hin->onion_routing_packet,
+				   tal_hexstr(channel, hin->onion_routing_packet,
 					     sizeof(hin->onion_routing_packet)));
 			tal_free(tmpctx);
 			return false;
@@ -672,7 +675,7 @@ static bool peer_fulfilled_our_htlc(struct channel *channel,
 
 	hout = find_htlc_out(&peer->ld->htlcs_out, peer, fulfilled->id);
 	if (!hout) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "fulfilled_our_htlc unknown htlc %"PRIu64,
 				    fulfilled->id);
 		return false;
@@ -721,7 +724,7 @@ static bool peer_failed_our_htlc(struct channel *channel,
 
 	hout = find_htlc_out(&peer->ld->htlcs_out, peer, failed->id);
 	if (!hout) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "failed_our_htlc unknown htlc %"PRIu64,
 				    failed->id);
 		return false;
@@ -839,10 +842,11 @@ static void remove_htlc_out(struct peer *peer, struct htlc_out *hout)
 static bool update_in_htlc(struct peer *peer, u64 id, enum htlc_state newstate)
 {
 	struct htlc_in *hin;
+	struct channel *channel = peer2channel(peer);
 
 	hin = find_htlc_in(&peer->ld->htlcs_in, peer, id);
 	if (!hin) {
-		peer_internal_error(peer, "Can't find in HTLC %"PRIu64, id);
+		channel_internal_error(channel, "Can't find in HTLC %"PRIu64, id);
 		return false;
 	}
 
@@ -858,10 +862,11 @@ static bool update_in_htlc(struct peer *peer, u64 id, enum htlc_state newstate)
 static bool update_out_htlc(struct peer *peer, u64 id, enum htlc_state newstate)
 {
 	struct htlc_out *hout;
+	struct channel *channel = peer2channel(peer);
 
 	hout = find_htlc_out(&peer->ld->htlcs_out, peer, id);
 	if (!hout) {
-		peer_internal_error(peer, "Can't find out HTLC %"PRIu64, id);
+		channel_internal_error(channel, "Can't find out HTLC %"PRIu64, id);
 		return false;
 	}
 
@@ -901,8 +906,10 @@ static bool peer_save_commitsig_received(struct peer *peer, u64 commitnum,
 					 struct bitcoin_tx *tx,
 					 const secp256k1_ecdsa_signature *commit_sig)
 {
-	if (commitnum != peer2channel(peer)->next_index[LOCAL]) {
-		peer_internal_error(peer,
+	struct channel *channel = peer2channel(peer);
+
+	if (commitnum != channel->next_index[LOCAL]) {
+		channel_internal_error(channel,
 			   "channel_got_commitsig: expected commitnum %"PRIu64
 			   " got %"PRIu64,
 			   peer2channel(peer)->next_index[LOCAL], commitnum);
@@ -919,8 +926,10 @@ static bool peer_save_commitsig_received(struct peer *peer, u64 commitnum,
 
 static bool peer_save_commitsig_sent(struct peer *peer, u64 commitnum)
 {
-	if (commitnum != peer2channel(peer)->next_index[REMOTE]) {
-		peer_internal_error(peer,
+	struct channel *channel = peer2channel(peer);
+
+	if (commitnum != channel->next_index[REMOTE]) {
+		channel_internal_error(channel,
 			   "channel_sent_commitsig: expected commitnum %"PRIu64
 			   " got %"PRIu64,
 			   peer2channel(peer)->next_index[REMOTE], commitnum);
@@ -942,20 +951,21 @@ void peer_sending_commitsig(struct peer *peer, const u8 *msg)
 	size_t i, maxid = 0, num_local_added = 0;
 	secp256k1_ecdsa_signature commit_sig;
 	secp256k1_ecdsa_signature *htlc_sigs;
+	struct channel *channel = peer2channel(peer);
 
 	if (!fromwire_channel_sending_commitsig(msg, msg, NULL,
 						&commitnum,
 						&feerate,
 						&changed_htlcs,
 						&commit_sig, &htlc_sigs)) {
-		peer_internal_error(peer, "bad channel_sending_commitsig %s",
+		channel_internal_error(channel, "bad channel_sending_commitsig %s",
 				    tal_hex(peer, msg));
 		return;
 	}
 
 	for (i = 0; i < tal_count(changed_htlcs); i++) {
 		if (!changed_htlc(peer, changed_htlcs + i)) {
-			peer_internal_error(peer,
+			channel_internal_error(channel,
 				   "channel_sending_commitsig: update failed");
 			return;
 		}
@@ -971,7 +981,7 @@ void peer_sending_commitsig(struct peer *peer, const u8 *msg)
 
 	if (num_local_added != 0) {
 		if (maxid != peer2channel(peer)->next_htlc_id + num_local_added - 1) {
-			peer_internal_error(peer,
+			channel_internal_error(channel,
 				   "channel_sending_commitsig:"
 				   " Added %"PRIu64", maxid now %"PRIu64
 				   " from %"PRIu64,
@@ -1011,7 +1021,7 @@ static bool channel_added_their_htlc(struct channel *channel,
 	 */
 	if (added->amount_msat == 0
 	    || added->amount_msat < channel->our_config.htlc_minimum_msat) {
-		peer_internal_error(channel2peer(channel),
+		channel_internal_error(channel,
 				    "trying to add HTLC msat %"PRIu64
 				    " but minimum is %"PRIu64,
 				    added->amount_msat,
@@ -1100,7 +1110,7 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg)
 					    &failed,
 					    &changed,
 					    &tx)) {
-		peer_internal_error(peer,
+		channel_internal_error(channel,
 				    "bad fromwire_channel_got_commitsig %s",
 				    tal_hex(peer, msg));
 		return;
@@ -1131,7 +1141,7 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg)
 
 	for (i = 0; i < tal_count(changed); i++) {
 		if (!changed_htlc(peer, &changed[i])) {
-			peer_internal_error(peer,
+			channel_internal_error(channel,
 					    "got_commitsig: update failed");
 			return;
 		}
@@ -1185,7 +1195,7 @@ void peer_got_revoke(struct peer *peer, const u8 *msg)
 					 &revokenum, &per_commitment_secret,
 					 &next_per_commitment_point,
 					 &changed)) {
-		peer_internal_error(peer, "bad fromwire_channel_got_revoke %s",
+		channel_internal_error(channel, "bad fromwire_channel_got_revoke %s",
 				    tal_hex(peer, msg));
 		return;
 	}
@@ -1204,7 +1214,7 @@ void peer_got_revoke(struct peer *peer, const u8 *msg)
 				return;
 		} else {
 			if (!changed_htlc(peer, &changed[i])) {
-				peer_internal_error(peer,
+				channel_internal_error(channel,
 						    "got_revoke: update failed");
 				return;
 			}
@@ -1212,13 +1222,13 @@ void peer_got_revoke(struct peer *peer, const u8 *msg)
 	}
 
 	if (revokenum >= (1ULL << 48)) {
-		peer_internal_error(peer, "got_revoke: too many txs %"PRIu64,
+		channel_internal_error(channel, "got_revoke: too many txs %"PRIu64,
 				    revokenum);
 		return;
 	}
 
 	if (revokenum != revocations_received(&channel->their_shachain.chain)) {
-		peer_internal_error(peer, "got_revoke: expected %"PRIu64
+		channel_internal_error(channel, "got_revoke: expected %"PRIu64
 				    " got %"PRIu64,
 				    revocations_received(&channel->their_shachain.chain), revokenum);
 		return;
@@ -1233,7 +1243,7 @@ void peer_got_revoke(struct peer *peer, const u8 *msg)
 				      &channel->their_shachain,
 				      shachain_index(revokenum),
 				      &per_commitment_secret)) {
-		peer_fail_permanent(peer,
+		channel_fail_permanent(channel,
 				    "Bad per_commitment_secret %s for %"PRIu64,
 				    type_to_string(msg, struct sha256,
 						   &per_commitment_secret),
@@ -1448,7 +1458,7 @@ void notify_new_block(struct lightningd *ld, u32 height)
 			if (peer2channel(hout->key.peer)->error)
 				continue;
 
-			peer_fail_permanent(hout->key.peer,
+			channel_fail_permanent(peer2channel(hout->key.peer),
 					    "Offered HTLC %"PRIu64
 					    " %s cltv %u hit deadline",
 					    hout->key.id,
@@ -1476,6 +1486,8 @@ void notify_new_block(struct lightningd *ld, u32 height)
 		for (hin = htlc_in_map_first(&ld->htlcs_in, &ini);
 		     hin;
 		     hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
+			struct channel *channel = peer2channel(hin->key.peer);
+
 			/* Not fulfilled?  If overdue, that's their problem... */
 			if (!hin->preimage)
 				continue;
@@ -1485,14 +1497,14 @@ void notify_new_block(struct lightningd *ld, u32 height)
 				continue;
 
 			/* Peer on chain already? */
-			if (peer_on_chain(hin->key.peer))
+			if (channel_on_chain(channel))
 				continue;
 
 			/* Peer already failed, or we hit it? */
-			if (peer2channel(hin->key.peer)->error)
+			if (channel->error)
 				continue;
 
-			peer_fail_permanent(hin->key.peer,
+			channel_fail_permanent(channel,
 					    "Fulfilled HTLC %"PRIu64
 					    " %s cltv %u hit deadline",
 					    hin->key.id,
diff --git a/lightningd/subd.c b/lightningd/subd.c
index 710f00aee..b679091e8 100644
--- a/lightningd/subd.c
+++ b/lightningd/subd.c
@@ -400,7 +400,8 @@ static bool handle_received_errmsg(struct subd *sd, const u8 *msg)
 
 	/* Don't free sd; we're may be about to free peer. */
 	sd->peer = NULL;
-	peer_fail_permanent(peer, "%s: received ERROR %s", sd->name, desc);
+	channel_fail_permanent(peer2channel(peer),
+			       "%s: received ERROR %s", sd->name, desc);
 	return true;
 }
 
@@ -421,7 +422,8 @@ static bool handle_sent_errmsg(struct subd *sd, const u8 *msg)
 
 	/* Don't free sd; we're may be about to free peer. */
 	sd->peer = NULL;
-	peer_fail_permanent(peer, "%s: sent ERROR %s", sd->name, desc);
+	channel_fail_permanent(peer2channel(peer),
+			       "%s: sent ERROR %s", sd->name, desc);
 	return true;
 }
 
@@ -563,7 +565,7 @@ static void destroy_subd(struct subd *sd)
 		fatal("Subdaemon %s killed with signal %i",
 		      sd->name, WTERMSIG(status));
 
-	/* In case we're freed manually, such as peer_fail_permanent */
+	/* In case we're freed manually, such as channel_fail_permanent */
 	if (sd->conn)
 		sd->conn = tal_free(sd->conn);
 
@@ -580,9 +582,9 @@ static void destroy_subd(struct subd *sd)
 		outer_transaction = db->in_transaction;
 		if (!outer_transaction)
 			db_begin_transaction(db);
-		peer_fail_transient(peer,
-				    "Owning subdaemon %s died (%i)",
-				    sd->name, status);
+		channel_fail_transient(peer2channel(peer),
+				       "Owning subdaemon %s died (%i)",
+				       sd->name, status);
 		if (!outer_transaction)
 			db_commit_transaction(db);
 	}