core-lightning/lightningd/channel_control.c
Rusty Russell d2b4e09e27 lightningd: re-allow closing negotiation when CLOSINGD_COMPLETE
d822ba1ee accidentally removed this case, which is important: if the
other side didn't get our final matching closing_signed, it will
reconnect and try again.  We consider the channel no longer "active"
and thus ignore it, and get upset when it send the
`channel_reestablish` message.

We could just consider CLOSINGD_COMPLETE to be active, but then we'd
have to wait for the closing transaction to be mined before we'd allow
another connection.

We can't special case it when the peer reconnects, because there
could be (in theory) multiple channels for that peer in CLOSINGD_COMPLETE,
and we don't know which one to reestablish.

So, we need to catch this when they send the reestablish, and hand
that msg to closingd to do negotiation again.  We already have code
to note that we're in CLOSINGD_COMPLETE and thus ignore any result
it gives us.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-04-23 20:18:15 +00:00

319 lines
9.7 KiB
C

#include <bitcoin/script.h>
#include <ccan/fdpass/fdpass.h>
#include <channeld/gen_channel_wire.h>
#include <errno.h>
#include <hsmd/capabilities.h>
#include <hsmd/gen_hsm_client_wire.h>
#include <inttypes.h>
#include <lightningd/channel_control.h>
#include <lightningd/closing_control.h>
#include <lightningd/hsm_control.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/peer_control.h>
#include <lightningd/subd.h>
#include <wire/wire_sync.h>
static void lockin_complete(struct channel *channel)
{
/* We set this once we're locked in. */
assert(channel->scid);
/* We set this once they're locked in. */
assert(channel->remote_funding_locked);
channel_set_state(channel, CHANNELD_AWAITING_LOCKIN, CHANNELD_NORMAL);
}
/* We were informed by channeld that it announced the channel and sent
* an update, so we can now start sending a node_announcement. The
* first step is to build the provisional announcement and ask the HSM
* to sign it. */
static void peer_got_funding_locked(struct channel *channel, const u8 *msg)
{
struct pubkey next_per_commitment_point;
if (!fromwire_channel_got_funding_locked(msg,
&next_per_commitment_point)) {
channel_internal_error(channel,
"bad channel_got_funding_locked %s",
tal_hex(channel, msg));
return;
}
if (channel->remote_funding_locked) {
channel_internal_error(channel,
"channel_got_funding_locked twice");
return;
}
update_per_commit_point(channel, &next_per_commitment_point);
log_debug(channel->log, "Got funding_locked");
channel->remote_funding_locked = true;
if (channel->scid)
lockin_complete(channel);
}
static void peer_got_shutdown(struct channel *channel, const u8 *msg)
{
u8 *scriptpubkey;
struct lightningd *ld = channel->peer->ld;
if (!fromwire_channel_got_shutdown(channel, msg, &scriptpubkey)) {
channel_internal_error(channel, "bad channel_got_shutdown %s",
tal_hex(msg, msg));
return;
}
/* FIXME: Add to spec that we must allow repeated shutdown! */
tal_free(channel->remote_shutdown_scriptpubkey);
channel->remote_shutdown_scriptpubkey = scriptpubkey;
/* BOLT #2:
*
* A sending node MUST set `scriptpubkey` to one of the following forms:
*
* 1. `OP_DUP` `OP_HASH160` `20` 20-bytes `OP_EQUALVERIFY` `OP_CHECKSIG`
* (pay to pubkey hash), OR
* 2. `OP_HASH160` `20` 20-bytes `OP_EQUAL` (pay to script hash), OR
* 3. `OP_0` `20` 20-bytes (version 0 pay to witness pubkey), OR
* 4. `OP_0` `32` 32-bytes (version 0 pay to witness script hash)
*
* A receiving node SHOULD fail the connection if the `scriptpubkey`
* is not one of those forms. */
if (!is_p2pkh(scriptpubkey, NULL) && !is_p2sh(scriptpubkey, NULL)
&& !is_p2wpkh(scriptpubkey, NULL) && !is_p2wsh(scriptpubkey, NULL)) {
channel_fail_permanent(channel, "Bad shutdown scriptpubkey %s",
tal_hex(channel, scriptpubkey));
return;
}
/* If we weren't already shutting down, we are now */
if (channel->state != CHANNELD_SHUTTING_DOWN)
channel_set_state(channel,
channel->state, CHANNELD_SHUTTING_DOWN);
/* TODO(cdecker) Selectively save updated fields to DB */
wallet_channel_save(ld->wallet, channel);
}
static void peer_start_closingd_after_shutdown(struct channel *channel,
const u8 *msg,
const int *fds)
{
struct crypto_state cs;
u64 gossip_index;
/* We expect 2 fds. */
assert(tal_count(fds) == 2);
if (!fromwire_channel_shutdown_complete(msg, &cs, &gossip_index)) {
channel_internal_error(channel, "bad shutdown_complete: %s",
tal_hex(msg, msg));
return;
}
/* This sets channel->owner, closes down channeld. */
peer_start_closingd(channel, &cs, gossip_index, fds[0], fds[1],
false, NULL);
channel_set_state(channel, CHANNELD_SHUTTING_DOWN, CLOSINGD_SIGEXCHANGE);
}
static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
{
enum channel_wire_type t = fromwire_peektype(msg);
switch (t) {
case WIRE_CHANNEL_SENDING_COMMITSIG:
peer_sending_commitsig(sd->channel, msg);
break;
case WIRE_CHANNEL_GOT_COMMITSIG:
peer_got_commitsig(sd->channel, msg);
break;
case WIRE_CHANNEL_GOT_REVOKE:
peer_got_revoke(sd->channel, msg);
break;
case WIRE_CHANNEL_GOT_FUNDING_LOCKED:
peer_got_funding_locked(sd->channel, msg);
break;
case WIRE_CHANNEL_GOT_SHUTDOWN:
peer_got_shutdown(sd->channel, msg);
break;
case WIRE_CHANNEL_SHUTDOWN_COMPLETE:
/* We expect 2 fds. */
if (!fds)
return 2;
peer_start_closingd_after_shutdown(sd->channel, msg, fds);
break;
/* And we never get these from channeld. */
case WIRE_CHANNEL_INIT:
case WIRE_CHANNEL_FUNDING_LOCKED:
case WIRE_CHANNEL_FUNDING_ANNOUNCE_DEPTH:
case WIRE_CHANNEL_OFFER_HTLC:
case WIRE_CHANNEL_FULFILL_HTLC:
case WIRE_CHANNEL_FAIL_HTLC:
case WIRE_CHANNEL_PING:
case WIRE_CHANNEL_GOT_COMMITSIG_REPLY:
case WIRE_CHANNEL_GOT_REVOKE_REPLY:
case WIRE_CHANNEL_SENDING_COMMITSIG_REPLY:
case WIRE_CHANNEL_SEND_SHUTDOWN:
case WIRE_CHANNEL_DEV_REENABLE_COMMIT:
case WIRE_CHANNEL_FEERATES:
/* Replies go to requests. */
case WIRE_CHANNEL_OFFER_HTLC_REPLY:
case WIRE_CHANNEL_PING_REPLY:
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY:
break;
}
return 0;
}
bool peer_start_channeld(struct channel *channel,
const struct crypto_state *cs,
u64 gossip_index,
int peer_fd, int gossip_fd,
const u8 *funding_signed,
bool reconnected)
{
u8 *msg, *initmsg;
int hsmfd;
struct added_htlc *htlcs;
enum htlc_state *htlc_states;
struct fulfilled_htlc *fulfilled_htlcs;
enum side *fulfilled_sides;
const struct failed_htlc **failed_htlcs;
enum side *failed_sides;
struct short_channel_id funding_channel_id;
u64 num_revocations;
struct lightningd *ld = channel->peer->ld;
const struct config *cfg = &ld->config;
msg = towire_hsm_client_hsmfd(tmpctx, &channel->peer->id, HSM_CAP_SIGN_GOSSIP | HSM_CAP_ECDH);
if (!wire_sync_write(ld->hsm_fd, take(msg)))
fatal("Could not write to HSM: %s", strerror(errno));
msg = hsm_sync_read(tmpctx, ld);
if (!fromwire_hsm_client_hsmfd_reply(msg))
fatal("Bad reply from HSM: %s", tal_hex(tmpctx, msg));
hsmfd = fdpass_recv(ld->hsm_fd);
if (hsmfd < 0)
fatal("Could not read fd from HSM: %s", strerror(errno));
channel_set_owner(channel, new_channel_subd(ld,
"lightning_channeld", channel,
channel->log,
channel_wire_type_name,
channel_msg,
channel_errmsg,
channel_set_billboard,
take(&peer_fd),
take(&gossip_fd),
take(&hsmfd), NULL));
if (!channel->owner) {
log_unusual(channel->log, "Could not subdaemon channel: %s",
strerror(errno));
channel_fail_transient(channel, "Failed to subdaemon channel");
return true;
}
peer_htlcs(tmpctx, channel, &htlcs, &htlc_states, &fulfilled_htlcs,
&fulfilled_sides, &failed_htlcs, &failed_sides);
if (channel->scid) {
funding_channel_id = *channel->scid;
log_debug(channel->log, "Already have funding locked in");
} else {
log_debug(channel->log, "Waiting for funding confirmations");
memset(&funding_channel_id, 0, sizeof(funding_channel_id));
}
num_revocations = revocations_received(&channel->their_shachain.chain);
/* Warn once. */
if (ld->config.ignore_fee_limits)
log_debug(channel->log, "Ignoring fee limits!");
initmsg = towire_channel_init(tmpctx,
&get_chainparams(ld)->genesis_blockhash,
&channel->funding_txid,
channel->funding_outnum,
channel->funding_satoshi,
&channel->our_config,
&channel->channel_info.their_config,
channel->channel_info.feerate_per_kw,
feerate_min(ld),
feerate_max(ld),
&channel->last_sig,
cs, gossip_index,
&channel->channel_info.remote_fundingkey,
&channel->channel_info.theirbase.revocation,
&channel->channel_info.theirbase.payment,
&channel->channel_info.theirbase.htlc,
&channel->channel_info.theirbase.delayed_payment,
&channel->channel_info.remote_per_commit,
&channel->channel_info.old_remote_per_commit,
channel->funder,
cfg->fee_base,
cfg->fee_per_satoshi,
channel->our_msatoshi,
&channel->seed,
&ld->id,
&channel->peer->id,
time_to_msec(cfg->commit_time),
cfg->cltv_expiry_delta,
channel->last_was_revoke,
channel->last_sent_commit,
channel->next_index[LOCAL],
channel->next_index[REMOTE],
num_revocations,
channel->next_htlc_id,
htlcs, htlc_states,
fulfilled_htlcs, fulfilled_sides,
failed_htlcs, failed_sides,
channel->scid != NULL,
channel->remote_funding_locked,
&funding_channel_id,
reconnected,
channel->state == CHANNELD_SHUTTING_DOWN,
channel->remote_shutdown_scriptpubkey != NULL,
p2wpkh_for_keyidx(tmpctx, ld,
channel->final_key_idx),
channel->channel_flags,
funding_signed);
/* We don't expect a response: we are triggered by funding_depth_cb. */
subd_send_msg(channel->owner, take(initmsg));
return true;
}
bool channel_tell_funding_locked(struct lightningd *ld,
struct channel *channel,
const struct bitcoin_txid *txid)
{
/* If not awaiting lockin, it doesn't care any more */
if (channel->state != CHANNELD_AWAITING_LOCKIN) {
log_debug(channel->log,
"Funding tx confirmed, but peer in state %s",
channel_state_name(channel));
return true;
}
if (!channel->owner) {
log_debug(channel->log,
"Funding tx confirmed, but peer disconnected");
return false;
}
subd_send_msg(channel->owner,
take(towire_channel_funding_locked(NULL, channel->scid)));
if (channel->remote_funding_locked)
lockin_complete(channel);
return true;
}