Browse Source

lightningd: rename peer_fail functions to channel_fail.

And move them into channel.c.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
b7680412e3
  1. 102
      lightningd/channel.c
  2. 8
      lightningd/channel.h
  3. 210
      lightningd/peer_control.c
  4. 9
      lightningd/peer_control.h
  5. 80
      lightningd/peer_htlcs.c
  6. 14
      lightningd/subd.c

102
lightningd/channel.c

@ -121,3 +121,105 @@ struct peer *channel2peer(const struct channel *channel)
{ {
return channel->peer; 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));
}
}

8
lightningd/channel.h

@ -97,6 +97,14 @@ void derive_channel_seed(struct lightningd *ld, struct privkey *seed,
const struct pubkey *peer_id, const struct pubkey *peer_id,
const u64 dbid); 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. */ /* FIXME: Temporary mapping from peer to channel, while we only have one. */
struct channel *peer2channel(const struct peer *peer); struct channel *peer2channel(const struct peer *peer);
struct peer *channel2peer(const struct channel *channel); struct peer *channel2peer(const struct channel *channel);

210
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); 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, /* Keep broadcasting until we say stop (can fail due to dup,
* if they beat us to the broadcast). */ * if they beat us to the broadcast). */
broadcast_tx(peer->ld->topology, peer, peer2channel(peer)->last_tx, NULL); broadcast_tx(ld->topology, channel2peer(channel), channel->last_tx, NULL);
remove_sig(peer2channel(peer)->last_tx); remove_sig(channel->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));
}
} }
void peer_set_condition(struct peer *peer, enum peer_state old_state, 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 DEVELOPER
if (dev_disconnect_permanent(ld)) { if (dev_disconnect_permanent(ld)) {
peer_internal_error(peer, "dev_disconnect permfail"); channel_internal_error(channel, "dev_disconnect permfail");
error = channel->error; error = channel->error;
goto send_error; goto send_error;
} }
@ -955,8 +857,9 @@ struct funding_channel {
static void funding_broadcast_failed(struct peer *peer, static void funding_broadcast_failed(struct peer *peer,
int exitstatus, const char *err) int exitstatus, const char *err)
{ {
peer_internal_error(peer, "Funding broadcast exited with %i: %s", channel_internal_error(peer2channel(peer),
exitstatus, err); "Funding broadcast exited with %i: %s",
exitstatus, err);
} }
static enum watch_result funding_announce_cb(struct peer *peer, 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) static void handle_onchain_init_reply(struct peer *peer, const u8 *msg)
{ {
u8 state; u8 state;
struct channel *channel = peer2channel(peer);
if (!fromwire_onchain_init_reply(msg, NULL, &state)) { 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; return;
} }
if (!channel_state_on_chain(state)) { if (!channel_state_on_chain(state)) {
peer_internal_error(peer, channel_internal_error(channel,
"Invalid onchain_init_reply state %u (%s)", "Invalid onchain_init_reply state %u (%s)",
state, peer_state_name(state)); state, peer_state_name(state));
return; 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) static void handle_onchain_broadcast_tx(struct peer *peer, const u8 *msg)
{ {
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
struct channel *channel = peer2channel(peer);
if (!fromwire_onchain_broadcast_tx(msg, msg, NULL, &tx)) { 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; return;
} }
@ -1126,9 +1031,10 @@ static void handle_onchain_unwatch_tx(struct peer *peer, const u8 *msg)
{ {
struct bitcoin_txid txid; struct bitcoin_txid txid;
struct txwatch *txw; struct txwatch *txw;
struct channel *channel = peer2channel(peer);
if (!fromwire_onchain_unwatch_tx(msg, NULL, &txid)) { 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; 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) static void handle_extracted_preimage(struct peer *peer, const u8 *msg)
{ {
struct preimage preimage; struct preimage preimage;
struct channel *channel = peer2channel(peer);
if (!fromwire_onchain_extracted_preimage(msg, NULL, &preimage)) { if (!fromwire_onchain_extracted_preimage(msg, NULL, &preimage)) {
peer_internal_error(peer, "Invalid extracted_preimage"); channel_internal_error(channel, "Invalid extracted_preimage");
return; 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) static void handle_missing_htlc_output(struct peer *peer, const u8 *msg)
{ {
struct htlc_stub htlc; struct htlc_stub htlc;
struct channel *channel = peer2channel(peer);
if (!fromwire_onchain_missing_htlc_output(msg, NULL, &htlc)) { 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; 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) static void handle_onchain_htlc_timeout(struct peer *peer, const u8 *msg)
{ {
struct htlc_stub htlc; struct htlc_stub htlc;
struct channel *channel = peer2channel(peer);
if (!fromwire_onchain_htlc_timeout(msg, NULL, &htlc)) { 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; return;
} }
@ -1366,7 +1275,7 @@ static enum watch_result funding_spent(struct peer *peer,
const tal_t *tmpctx = tal_tmpctx(peer); const tal_t *tmpctx = tal_tmpctx(peer);
struct channel *channel = peer2channel(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. */ /* We could come from almost any state. */
peer_set_condition(peer, channel->state, FUNDING_SPEND_SEEN); 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); scriptpubkey = p2wpkh_for_keyidx(tmpctx, peer->ld, keyindex);
if (!scriptpubkey) { if (!scriptpubkey) {
peer_internal_error(peer, channel_internal_error(channel,
"Can't get shutdown script %"PRIu64, "Can't get shutdown script %"PRIu64,
keyindex); keyindex);
tal_free(tmpctx); tal_free(tmpctx);
@ -1413,7 +1322,7 @@ static enum watch_result funding_spent(struct peer *peer,
txfilter_add_scriptpubkey(peer->ld->owned_txfilter, scriptpubkey); txfilter_add_scriptpubkey(peer->ld->owned_txfilter, scriptpubkey);
if (!bip32_pubkey(peer->ld->wallet->bip32_base, &ourkey, keyindex)) { if (!bip32_pubkey(peer->ld->wallet->bip32_base, &ourkey, keyindex)) {
peer_internal_error(peer, channel_internal_error(channel,
"Can't get shutdown key %"PRIu64, "Can't get shutdown key %"PRIu64,
keyindex); keyindex);
tal_free(tmpctx); 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, if (!fromwire_channel_got_funding_locked(msg, NULL,
&next_per_commitment_point)) { &next_per_commitment_point)) {
peer_internal_error(peer, "bad channel_got_funding_locked %s", channel_internal_error(channel,
tal_hex(peer, msg)); "bad channel_got_funding_locked %s",
tal_hex(channel, msg));
return; return;
} }
if (channel->remote_funding_locked) { if (channel->remote_funding_locked) {
peer_internal_error(peer, "channel_got_funding_locked twice"); channel_internal_error(channel,
"channel_got_funding_locked twice");
return; return;
} }
update_per_commit_point(peer, &next_per_commitment_point); 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); struct channel *channel = peer2channel(peer);
if (!fromwire_channel_got_shutdown(peer, msg, NULL, &scriptpubkey)) { if (!fromwire_channel_got_shutdown(peer, msg, NULL, &scriptpubkey)) {
peer_internal_error(peer, "bad channel_got_shutdown %s", channel_internal_error(channel, "bad channel_got_shutdown %s",
tal_hex(peer, msg)); tal_hex(msg, msg));
return; return;
} }
@ -1641,8 +1552,8 @@ static void peer_got_shutdown(struct peer *peer, const u8 *msg)
* is not one of those forms. */ * is not one of those forms. */
if (!is_p2pkh(scriptpubkey, NULL) && !is_p2sh(scriptpubkey, NULL) if (!is_p2pkh(scriptpubkey, NULL) && !is_p2sh(scriptpubkey, NULL)
&& !is_p2wpkh(scriptpubkey, NULL) && !is_p2wsh(scriptpubkey, NULL)) { && !is_p2wpkh(scriptpubkey, NULL) && !is_p2wsh(scriptpubkey, NULL)) {
peer_fail_permanent(peer, "Bad shutdown scriptpubkey %s", channel_fail_permanent(channel, "Bad shutdown scriptpubkey %s",
tal_hex(peer, scriptpubkey)); tal_hex(channel, scriptpubkey));
return; 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); channel->local_shutdown_idx = wallet_get_newindex(peer->ld);
if (channel->local_shutdown_idx == -1) { if (channel->local_shutdown_idx == -1) {
peer_internal_error(peer, channel_internal_error(channel,
"Can't get local shutdown index"); "Can't get local shutdown index");
return; return;
} }
@ -1668,7 +1579,7 @@ static void peer_got_shutdown(struct peer *peer, const u8 *msg)
scriptpubkey = p2wpkh_for_keyidx(msg, peer->ld, scriptpubkey = p2wpkh_for_keyidx(msg, peer->ld,
channel->local_shutdown_idx); channel->local_shutdown_idx);
if (!scriptpubkey) { if (!scriptpubkey) {
peer_internal_error(peer, channel_internal_error(channel,
"Can't get shutdown script %"PRIu64, "Can't get shutdown script %"PRIu64,
channel->local_shutdown_idx); channel->local_shutdown_idx);
return; return;
@ -1763,8 +1674,8 @@ static void peer_received_closing_signature(struct peer *peer, const u8 *msg)
struct channel *channel = peer2channel(peer); struct channel *channel = peer2channel(peer);
if (!fromwire_closing_received_signature(msg, msg, NULL, &sig, &tx)) { if (!fromwire_closing_received_signature(msg, msg, NULL, &sig, &tx)) {
peer_internal_error(peer, "Bad closing_received_signature %s", channel_internal_error(channel, "Bad closing_received_signature %s",
tal_hex(peer, msg)); tal_hex(msg, msg));
return; 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) 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 */ /* FIXME: We should save this, to return to gossipd */
u64 gossip_index; u64 gossip_index;
if (!fromwire_closing_complete(msg, NULL, &gossip_index)) { if (!fromwire_closing_complete(msg, NULL, &gossip_index)) {
peer_internal_error(peer, "Bad closing_complete %s", channel_internal_error(channel, "Bad closing_complete %s",
tal_hex(peer, msg)); tal_hex(msg, msg));
return; return;
} }
@ -1795,7 +1707,7 @@ static void peer_closing_complete(struct peer *peer, const u8 *msg)
if (peer2channel(peer)->state == CLOSINGD_COMPLETE) if (peer2channel(peer)->state == CLOSINGD_COMPLETE)
return; return;
drop_to_chain(peer); drop_to_chain(peer->ld, channel);
peer_set_condition(peer, CLOSINGD_SIGEXCHANGE, CLOSINGD_COMPLETE); 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 if (channel->local_shutdown_idx == -1
|| !channel->remote_shutdown_scriptpubkey) { || !channel->remote_shutdown_scriptpubkey) {
peer_internal_error(peer, channel_internal_error(channel,
"Can't start closing: local %s remote %s", "Can't start closing: local %s remote %s",
channel->local_shutdown_idx == -1 channel->local_shutdown_idx == -1
? "not shutdown" : "shutdown", ? "not shutdown" : "shutdown",
@ -1854,7 +1766,7 @@ static void peer_start_closingd(struct peer *peer,
if (!channel->owner) { if (!channel->owner) {
log_unusual(peer->log, "Could not subdaemon closing: %s", log_unusual(peer->log, "Could not subdaemon closing: %s",
strerror(errno)); strerror(errno));
peer_fail_transient(peer, "Failed to subdaemon closing"); channel_fail_transient(channel, "Failed to subdaemon closing");
tal_free(tmpctx); tal_free(tmpctx);
return; return;
} }
@ -1862,7 +1774,7 @@ static void peer_start_closingd(struct peer *peer,
local_scriptpubkey = p2wpkh_for_keyidx(tmpctx, peer->ld, local_scriptpubkey = p2wpkh_for_keyidx(tmpctx, peer->ld,
channel->local_shutdown_idx); channel->local_shutdown_idx);
if (!local_scriptpubkey) { if (!local_scriptpubkey) {
peer_internal_error(peer, channel_internal_error(channel,
"Can't generate local shutdown scriptpubkey"); "Can't generate local shutdown scriptpubkey");
tal_free(tmpctx); tal_free(tmpctx);
return; 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, static void peer_start_closingd_after_shutdown(struct peer *peer, const u8 *msg,
const int *fds) const int *fds)
{ {
struct channel *channel = peer2channel(peer);
struct crypto_state cs; struct crypto_state cs;
u64 gossip_index; 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); assert(tal_count(fds) == 2);
if (!fromwire_channel_shutdown_complete(msg, NULL, &cs, &gossip_index)) { 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)); tal_hex(peer, msg));
return; return;
} }
@ -2082,7 +1995,7 @@ static bool peer_start_channeld(struct peer *peer,
if (!channel->owner) { if (!channel->owner) {
log_unusual(peer->log, "Could not subdaemon channel: %s", log_unusual(peer->log, "Could not subdaemon channel: %s",
strerror(errno)); strerror(errno));
peer_fail_transient(peer, "Failed to subdaemon channel"); channel_fail_transient(channel, "Failed to subdaemon channel");
tal_free(tmpctx); tal_free(tmpctx);
return true; return true;
} }
@ -2213,7 +2126,7 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
&channel_info->remote_fundingkey, &channel_info->remote_fundingkey,
&funding_txid, &funding_txid,
&channel_info->feerate_per_kw[REMOTE])) { &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)); tal_hex(resp, resp));
return; return;
} }
@ -2258,7 +2171,7 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
bitcoin_txid(fundingtx, channel->funding_txid); bitcoin_txid(fundingtx, channel->funding_txid);
if (!structeq(channel->funding_txid, &funding_txid)) { if (!structeq(channel->funding_txid, &funding_txid)) {
peer_internal_error(fc->peer, channel_internal_error(channel,
"Funding txid mismatch:" "Funding txid mismatch:"
" satoshi %"PRIu64" change %"PRIu64 " satoshi %"PRIu64" change %"PRIu64
" changeidx %u" " changeidx %u"
@ -2273,7 +2186,7 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
} }
if (!peer_commit_initial(fc->peer)) { 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; return;
} }
@ -2339,7 +2252,7 @@ static void opening_fundee_finished(struct subd *opening,
&channel->channel_flags, &channel->channel_flags,
&channel_info->feerate_per_kw[REMOTE], &channel_info->feerate_per_kw[REMOTE],
&funding_signed)) { &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_hex(reply, reply));
tal_free(tmpctx); tal_free(tmpctx);
return; return;
@ -2388,6 +2301,7 @@ static unsigned int opening_negotiation_failed(struct subd *openingd,
struct crypto_state cs; struct crypto_state cs;
u64 gossip_index; u64 gossip_index;
struct peer *peer = openingd->peer; struct peer *peer = openingd->peer;
struct channel *channel = peer2channel(peer);
char *why; char *why;
/* We need the peer fd and gossip fd. */ /* 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, if (!fromwire_opening_negotiation_failed(msg, msg, NULL,
&cs, &gossip_index, &why)) { &cs, &gossip_index, &why)) {
peer_internal_error(peer, channel_internal_error(channel,
"bad OPENING_NEGOTIATION_FAILED %s", "bad OPENING_NEGOTIATION_FAILED %s",
tal_hex(msg, msg)); tal_hex(msg, msg));
return 0; return 0;
@ -2449,8 +2363,9 @@ static void peer_accept_channel(struct lightningd *ld,
opening_negotiation_failed, opening_negotiation_failed,
take(&peer_fd), take(&gossip_fd), NULL)); take(&peer_fd), take(&gossip_fd), NULL));
if (!channel->owner) { if (!channel->owner) {
peer_fail_transient(peer, "Failed to subdaemon opening: %s", channel_fail_transient(channel,
strerror(errno)); "Failed to subdaemon opening: %s",
strerror(errno));
return; return;
} }
@ -2708,8 +2623,8 @@ static void json_close(struct command *cmd,
/* Easy case: peer can simply be forgotten. */ /* Easy case: peer can simply be forgotten. */
if (!peer_persists(peer)) { if (!peer_persists(peer)) {
peer_fail_permanent(peer, "Peer closed in state %s", channel_fail_permanent(channel, "Peer closed in state %s",
channel_state_name(peer2channel(peer))); channel_state_name(channel));
command_success(cmd, null_response(cmd)); command_success(cmd, null_response(cmd));
return; return;
} }
@ -2855,6 +2770,7 @@ static void json_dev_fail(struct command *cmd,
{ {
jsmntok_t *peertok; jsmntok_t *peertok;
struct peer *peer; struct peer *peer;
struct channel *channel;
if (!json_get_params(cmd, buffer, params, if (!json_get_params(cmd, buffer, params,
"id", &peertok, "id", &peertok,
@ -2868,7 +2784,13 @@ static void json_dev_fail(struct command *cmd,
return; 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)); command_success(cmd, null_response(cmd));
} }

9
lightningd/peer_control.h

@ -90,13 +90,6 @@ void peer_sent_nongossip(struct lightningd *ld,
/* Could be configurable. */ /* Could be configurable. */
#define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL #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. */ /* Peer has failed to open; return to gossipd. */
void opening_failed(struct peer *peer, const u8 *msg TAKES); 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. */ /* We've loaded peers from database, set them going. */
void activate_peers(struct lightningd *ld); 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); void free_htlcs(struct lightningd *ld, const struct peer *peer);
/* Get range of feerates to insist other side abide by for normal channels. */ /* Get range of feerates to insist other side abide by for normal channels. */

80
lightningd/peer_htlcs.c

@ -27,6 +27,7 @@ static bool state_update_ok(struct peer *peer,
u64 htlc_id, const char *dir) u64 htlc_id, const char *dir)
{ {
enum htlc_state expected = oldstate + 1; enum htlc_state expected = oldstate + 1;
struct channel *channel = peer2channel(peer);
/* We never get told about RCVD_REMOVE_HTLC, so skip over that /* We never get told about RCVD_REMOVE_HTLC, so skip over that
* (we initialize in SENT_ADD_HTLC / RCVD_ADD_COMMIT, so those * (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; expected = RCVD_REMOVE_COMMIT;
if (newstate != expected) { if (newstate != expected) {
peer_internal_error(peer, channel_internal_error(channel,
"HTLC %s %"PRIu64" invalid update %s->%s", "HTLC %s %"PRIu64" invalid update %s->%s",
dir, htlc_id, dir, htlc_id,
htlc_state_name(oldstate), htlc_state_name(oldstate),
htlc_state_name(newstate)); htlc_state_name(newstate));
return false; return false;
} }
@ -333,7 +334,8 @@ static void rcvd_htlc_reply(struct subd *subd, const u8 *msg, const int *fds,
&hout->key.id, &hout->key.id,
&failure_code, &failure_code,
&failurestr)) { &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); tal_free(hout);
return; 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) if (find_htlc_out(&subd->ld->htlcs_out, hout->key.peer, hout->key.id)
|| hout->key.id == HTLC_INVALID_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 "Bad offer_htlc_reply HTLC id %"PRIu64
" is a duplicate", " is a duplicate",
hout->key.id); hout->key.id);
@ -551,10 +553,11 @@ static bool peer_accepted_htlc(struct peer *peer,
struct route_step *rs; struct route_step *rs;
struct onionpacket *op; struct onionpacket *op;
const tal_t *tmpctx = tal_tmpctx(peer); const tal_t *tmpctx = tal_tmpctx(peer);
struct channel *channel = peer2channel(peer);
hin = find_htlc_in(&peer->ld->htlcs_in, peer, id); hin = find_htlc_in(&peer->ld->htlcs_in, peer, id);
if (!hin) { if (!hin) {
peer_internal_error(peer, channel_internal_error(channel,
"peer_got_revoke unknown htlc %"PRIu64, id); "peer_got_revoke unknown htlc %"PRIu64, id);
return false; 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 * A sending node SHOULD fail to route any HTLC added after it
* sent `shutdown`. */ * sent `shutdown`. */
if (peer2channel(peer)->state == CHANNELD_SHUTTING_DOWN) { if (channel->state == CHANNELD_SHUTTING_DOWN) {
*failcode = WIRE_PERMANENT_CHANNEL_FAILURE; *failcode = WIRE_PERMANENT_CHANNEL_FAILURE;
goto out; goto out;
} }
@ -586,9 +589,9 @@ static bool peer_accepted_htlc(struct peer *peer,
sizeof(hin->onion_routing_packet)); sizeof(hin->onion_routing_packet));
if (!op) { if (!op) {
if (!memeqzero(&hin->shared_secret, sizeof(hin->shared_secret))){ if (!memeqzero(&hin->shared_secret, sizeof(hin->shared_secret))){
peer_internal_error(peer, channel_internal_error(channel,
"bad onion in got_revoke: %s", "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))); sizeof(hin->onion_routing_packet)));
tal_free(tmpctx); tal_free(tmpctx);
return false; 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); hout = find_htlc_out(&peer->ld->htlcs_out, peer, fulfilled->id);
if (!hout) { if (!hout) {
peer_internal_error(peer, channel_internal_error(channel,
"fulfilled_our_htlc unknown htlc %"PRIu64, "fulfilled_our_htlc unknown htlc %"PRIu64,
fulfilled->id); fulfilled->id);
return false; 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); hout = find_htlc_out(&peer->ld->htlcs_out, peer, failed->id);
if (!hout) { if (!hout) {
peer_internal_error(peer, channel_internal_error(channel,
"failed_our_htlc unknown htlc %"PRIu64, "failed_our_htlc unknown htlc %"PRIu64,
failed->id); failed->id);
return false; 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) static bool update_in_htlc(struct peer *peer, u64 id, enum htlc_state newstate)
{ {
struct htlc_in *hin; struct htlc_in *hin;
struct channel *channel = peer2channel(peer);
hin = find_htlc_in(&peer->ld->htlcs_in, peer, id); hin = find_htlc_in(&peer->ld->htlcs_in, peer, id);
if (!hin) { 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; 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) static bool update_out_htlc(struct peer *peer, u64 id, enum htlc_state newstate)
{ {
struct htlc_out *hout; struct htlc_out *hout;
struct channel *channel = peer2channel(peer);
hout = find_htlc_out(&peer->ld->htlcs_out, peer, id); hout = find_htlc_out(&peer->ld->htlcs_out, peer, id);
if (!hout) { 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; return false;
} }
@ -901,8 +906,10 @@ static bool peer_save_commitsig_received(struct peer *peer, u64 commitnum,
struct bitcoin_tx *tx, struct bitcoin_tx *tx,
const secp256k1_ecdsa_signature *commit_sig) const secp256k1_ecdsa_signature *commit_sig)
{ {
if (commitnum != peer2channel(peer)->next_index[LOCAL]) { struct channel *channel = peer2channel(peer);
peer_internal_error(peer,
if (commitnum != channel->next_index[LOCAL]) {
channel_internal_error(channel,
"channel_got_commitsig: expected commitnum %"PRIu64 "channel_got_commitsig: expected commitnum %"PRIu64
" got %"PRIu64, " got %"PRIu64,
peer2channel(peer)->next_index[LOCAL], commitnum); 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) static bool peer_save_commitsig_sent(struct peer *peer, u64 commitnum)
{ {
if (commitnum != peer2channel(peer)->next_index[REMOTE]) { struct channel *channel = peer2channel(peer);
peer_internal_error(peer,
if (commitnum != channel->next_index[REMOTE]) {
channel_internal_error(channel,
"channel_sent_commitsig: expected commitnum %"PRIu64 "channel_sent_commitsig: expected commitnum %"PRIu64
" got %"PRIu64, " got %"PRIu64,
peer2channel(peer)->next_index[REMOTE], commitnum); 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; size_t i, maxid = 0, num_local_added = 0;
secp256k1_ecdsa_signature commit_sig; secp256k1_ecdsa_signature commit_sig;
secp256k1_ecdsa_signature *htlc_sigs; secp256k1_ecdsa_signature *htlc_sigs;
struct channel *channel = peer2channel(peer);
if (!fromwire_channel_sending_commitsig(msg, msg, NULL, if (!fromwire_channel_sending_commitsig(msg, msg, NULL,
&commitnum, &commitnum,
&feerate, &feerate,
&changed_htlcs, &changed_htlcs,
&commit_sig, &htlc_sigs)) { &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)); tal_hex(peer, msg));
return; return;
} }
for (i = 0; i < tal_count(changed_htlcs); i++) { for (i = 0; i < tal_count(changed_htlcs); i++) {
if (!changed_htlc(peer, changed_htlcs + i)) { if (!changed_htlc(peer, changed_htlcs + i)) {
peer_internal_error(peer, channel_internal_error(channel,
"channel_sending_commitsig: update failed"); "channel_sending_commitsig: update failed");
return; return;
} }
@ -971,7 +981,7 @@ void peer_sending_commitsig(struct peer *peer, const u8 *msg)
if (num_local_added != 0) { if (num_local_added != 0) {
if (maxid != peer2channel(peer)->next_htlc_id + num_local_added - 1) { if (maxid != peer2channel(peer)->next_htlc_id + num_local_added - 1) {
peer_internal_error(peer, channel_internal_error(channel,
"channel_sending_commitsig:" "channel_sending_commitsig:"
" Added %"PRIu64", maxid now %"PRIu64 " Added %"PRIu64", maxid now %"PRIu64
" from %"PRIu64, " from %"PRIu64,
@ -1011,7 +1021,7 @@ static bool channel_added_their_htlc(struct channel *channel,
*/ */
if (added->amount_msat == 0 if (added->amount_msat == 0
|| added->amount_msat < channel->our_config.htlc_minimum_msat) { || added->amount_msat < channel->our_config.htlc_minimum_msat) {
peer_internal_error(channel2peer(channel), channel_internal_error(channel,
"trying to add HTLC msat %"PRIu64 "trying to add HTLC msat %"PRIu64
" but minimum is %"PRIu64, " but minimum is %"PRIu64,
added->amount_msat, added->amount_msat,
@ -1100,7 +1110,7 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg)
&failed, &failed,
&changed, &changed,
&tx)) { &tx)) {
peer_internal_error(peer, channel_internal_error(channel,
"bad fromwire_channel_got_commitsig %s", "bad fromwire_channel_got_commitsig %s",
tal_hex(peer, msg)); tal_hex(peer, msg));
return; return;
@ -1131,7 +1141,7 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg)
for (i = 0; i < tal_count(changed); i++) { for (i = 0; i < tal_count(changed); i++) {
if (!changed_htlc(peer, &changed[i])) { if (!changed_htlc(peer, &changed[i])) {
peer_internal_error(peer, channel_internal_error(channel,
"got_commitsig: update failed"); "got_commitsig: update failed");
return; return;
} }
@ -1185,7 +1195,7 @@ void peer_got_revoke(struct peer *peer, const u8 *msg)
&revokenum, &per_commitment_secret, &revokenum, &per_commitment_secret,
&next_per_commitment_point, &next_per_commitment_point,
&changed)) { &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)); tal_hex(peer, msg));
return; return;
} }
@ -1204,7 +1214,7 @@ void peer_got_revoke(struct peer *peer, const u8 *msg)
return; return;
} else { } else {
if (!changed_htlc(peer, &changed[i])) { if (!changed_htlc(peer, &changed[i])) {
peer_internal_error(peer, channel_internal_error(channel,
"got_revoke: update failed"); "got_revoke: update failed");
return; return;
} }
@ -1212,13 +1222,13 @@ void peer_got_revoke(struct peer *peer, const u8 *msg)
} }
if (revokenum >= (1ULL << 48)) { 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); revokenum);
return; return;
} }
if (revokenum != revocations_received(&channel->their_shachain.chain)) { 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, " got %"PRIu64,
revocations_received(&channel->their_shachain.chain), revokenum); revocations_received(&channel->their_shachain.chain), revokenum);
return; return;
@ -1233,7 +1243,7 @@ void peer_got_revoke(struct peer *peer, const u8 *msg)
&channel->their_shachain, &channel->their_shachain,
shachain_index(revokenum), shachain_index(revokenum),
&per_commitment_secret)) { &per_commitment_secret)) {
peer_fail_permanent(peer, channel_fail_permanent(channel,
"Bad per_commitment_secret %s for %"PRIu64, "Bad per_commitment_secret %s for %"PRIu64,
type_to_string(msg, struct sha256, type_to_string(msg, struct sha256,
&per_commitment_secret), &per_commitment_secret),
@ -1448,7 +1458,7 @@ void notify_new_block(struct lightningd *ld, u32 height)
if (peer2channel(hout->key.peer)->error) if (peer2channel(hout->key.peer)->error)
continue; continue;
peer_fail_permanent(hout->key.peer, channel_fail_permanent(peer2channel(hout->key.peer),
"Offered HTLC %"PRIu64 "Offered HTLC %"PRIu64
" %s cltv %u hit deadline", " %s cltv %u hit deadline",
hout->key.id, 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); for (hin = htlc_in_map_first(&ld->htlcs_in, &ini);
hin; hin;
hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { hin = htlc_in_map_next(&ld->htlcs_in, &ini)) {
struct channel *channel = peer2channel(hin->key.peer);
/* Not fulfilled? If overdue, that's their problem... */ /* Not fulfilled? If overdue, that's their problem... */
if (!hin->preimage) if (!hin->preimage)
continue; continue;
@ -1485,14 +1497,14 @@ void notify_new_block(struct lightningd *ld, u32 height)
continue; continue;
/* Peer on chain already? */ /* Peer on chain already? */
if (peer_on_chain(hin->key.peer)) if (channel_on_chain(channel))
continue; continue;
/* Peer already failed, or we hit it? */ /* Peer already failed, or we hit it? */
if (peer2channel(hin->key.peer)->error) if (channel->error)
continue; continue;
peer_fail_permanent(hin->key.peer, channel_fail_permanent(channel,
"Fulfilled HTLC %"PRIu64 "Fulfilled HTLC %"PRIu64
" %s cltv %u hit deadline", " %s cltv %u hit deadline",
hin->key.id, hin->key.id,

14
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. */ /* Don't free sd; we're may be about to free peer. */
sd->peer = NULL; 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; 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. */ /* Don't free sd; we're may be about to free peer. */
sd->peer = NULL; 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; return true;
} }
@ -563,7 +565,7 @@ static void destroy_subd(struct subd *sd)
fatal("Subdaemon %s killed with signal %i", fatal("Subdaemon %s killed with signal %i",
sd->name, WTERMSIG(status)); 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) if (sd->conn)
sd->conn = tal_free(sd->conn); sd->conn = tal_free(sd->conn);
@ -580,9 +582,9 @@ static void destroy_subd(struct subd *sd)
outer_transaction = db->in_transaction; outer_transaction = db->in_transaction;
if (!outer_transaction) if (!outer_transaction)
db_begin_transaction(db); db_begin_transaction(db);
peer_fail_transient(peer, channel_fail_transient(peer2channel(peer),
"Owning subdaemon %s died (%i)", "Owning subdaemon %s died (%i)",
sd->name, status); sd->name, status);
if (!outer_transaction) if (!outer_transaction)
db_commit_transaction(db); db_commit_transaction(db);
} }

Loading…
Cancel
Save