rgb-cln/lightningd/channel_control.c

509 lines
15 KiB
C

#include <bitcoin/pubkey.h>
#include <bitcoin/script.h>
#include <channeld/gen_channel_wire.h>
#include <common/memleak.h>
#include <common/timeout.h>
#include <common/utils.h>
#include <common/wire_error.h>
#include <errno.h>
#include <gossipd/gossip_constants.h>
#include <hsmd/gen_hsm_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 update_feerates(struct lightningd *ld, struct channel *channel)
{
u8 *msg;
u32 feerate = unilateral_feerate(ld->topology);
/* Nothing to do if we don't know feerate. */
if (!feerate)
return;
msg = towire_channel_feerates(NULL, feerate,
feerate_min(ld, NULL),
feerate_max(ld, NULL));
subd_send_msg(channel->owner, take(msg));
}
static void try_update_feerates(struct lightningd *ld, struct channel *channel)
{
/* No point until funding locked in */
if (!channel_fees_can_change(channel))
return;
/* Can't if no daemon listening. */
if (!channel->owner)
return;
update_feerates(ld, channel);
}
void notify_feerate_change(struct lightningd *ld)
{
struct peer *peer;
/* FIXME: We should notify onchaind about NORMAL fee change in case
* it's going to generate more txs. */
list_for_each(&ld->peers, peer, list) {
struct channel *channel = peer_active_channel(peer);
if (!channel)
continue;
/* FIXME: We choose not to drop to chain if we can't contact
* peer. We *could* do so, however. */
try_update_feerates(ld, channel);
}
}
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);
/* Fees might have changed (and we use IMMEDIATE once we're funded),
* so update now. */
try_update_feerates(channel->peer->ld, channel);
}
/* 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:
*
* 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:
*...
* - if the `scriptpubkey` is not in one of the above forms:
* - SHOULD fail the connection.
*/
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 channel_fail_fallen_behind(struct channel *channel, const u8 *msg)
{
struct pubkey per_commitment_point;
if (!fromwire_channel_fail_fallen_behind(msg, &per_commitment_point)) {
channel_internal_error(channel,
"bad channel_fail_fallen_behind %s",
tal_hex(tmpctx, msg));
return;
}
channel->future_per_commitment_point
= tal_dup(channel, struct pubkey, &per_commitment_point);
/* Peer sees this, so send a generic msg about unilateral close. */
channel_fail_permanent(channel, "Awaiting unilateral close");
}
static void peer_start_closingd_after_shutdown(struct channel *channel,
const u8 *msg,
const int *fds)
{
struct crypto_state cs;
/* We expect 2 fds. */
assert(tal_count(fds) == 2);
if (!fromwire_channel_shutdown_complete(msg, &cs)) {
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, 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;
case WIRE_CHANNEL_FAIL_FALLEN_BEHIND:
channel_fail_fallen_behind(sd->channel, msg);
break;
/* And we never get these from channeld. */
case WIRE_CHANNEL_INIT:
case WIRE_CHANNEL_FUNDING_LOCKED:
case WIRE_CHANNEL_OFFER_HTLC:
case WIRE_CHANNEL_FULFILL_HTLC:
case WIRE_CHANNEL_FAIL_HTLC:
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:
case WIRE_CHANNEL_DEV_MEMLEAK:
/* Replies go to requests. */
case WIRE_CHANNEL_OFFER_HTLC_REPLY:
case WIRE_CHANNEL_DEV_REENABLE_COMMIT_REPLY:
case WIRE_CHANNEL_DEV_MEMLEAK_REPLY:
break;
}
return 0;
}
void peer_start_channeld(struct channel *channel,
const struct crypto_state *cs,
int peer_fd, int gossip_fd,
const u8 *funding_signed,
bool reconnected)
{
u8 *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;
bool reached_announce_depth;
struct secret last_remote_per_commit_secret;
hsmfd = hsm_get_client_fd(ld, &channel->peer->id,
channel->dbid,
HSM_CAP_SIGN_GOSSIP
| HSM_CAP_ECDH
| HSM_CAP_COMMITMENT_POINT
| HSM_CAP_SIGN_REMOTE_TX);
channel_set_owner(channel,
new_channel_subd(ld,
"lightning_channeld", channel,
channel->log, true,
channel_wire_type_name,
channel_msg,
channel_errmsg,
channel_set_billboard,
take(&peer_fd),
take(&gossip_fd),
take(&hsmfd), NULL),
false);
if (!channel->owner) {
log_unusual(channel->log, "Could not subdaemon channel: %s",
strerror(errno));
channel_fail_transient(channel, "Failed to subdaemon channel");
return;
}
peer_htlcs(tmpctx, channel, &htlcs, &htlc_states, &fulfilled_htlcs,
&fulfilled_sides, &failed_htlcs, &failed_sides);
if (channel->scid) {
funding_channel_id = *channel->scid;
reached_announce_depth
= (short_channel_id_blocknum(&funding_channel_id)
+ ANNOUNCE_MIN_DEPTH <= get_block_height(ld->topology));
log_debug(channel->log, "Already have funding locked in%s",
reached_announce_depth
? " (and ready to announce)" : "");
} else {
log_debug(channel->log, "Waiting for funding confirmations");
memset(&funding_channel_id, 0, sizeof(funding_channel_id));
reached_announce_depth = false;
}
num_revocations = revocations_received(&channel->their_shachain.chain);
/* BOLT #2:
*
* - if it supports `option_data_loss_protect`:
* - if `next_remote_revocation_number` equals 0:
* - MUST set `your_last_per_commitment_secret` to all zeroes
* - otherwise:
* - MUST set `your_last_per_commitment_secret` to the last
* `per_commitment_secret` it received
*/
if (num_revocations == 0)
memset(&last_remote_per_commit_secret, 0,
sizeof(last_remote_per_commit_secret));
else if (!shachain_get_secret(&channel->their_shachain.chain,
num_revocations-1,
&last_remote_per_commit_secret)) {
channel_fail_permanent(channel,
"Could not get revocation secret %"PRIu64,
num_revocations-1);
return;
}
/* 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, NULL),
feerate_max(ld, NULL),
&channel->last_sig,
cs,
&channel->channel_info.remote_fundingkey,
&channel->channel_info.theirbase,
&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->local_basepoints,
&channel->local_funding_pubkey,
&ld->id,
&channel->peer->id,
cfg->commit_time_ms,
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,
reached_announce_depth,
&last_remote_per_commit_secret,
channel->peer->localfeatures);
/* We don't expect a response: we are triggered by funding_depth_cb. */
subd_send_msg(channel->owner, take(initmsg));
/* On restart, feerate might not be what we expect: adjust now. */
if (channel->funder == LOCAL)
try_update_feerates(ld, channel);
}
bool channel_tell_funding_locked(struct lightningd *ld,
struct channel *channel,
const struct bitcoin_txid *txid,
u32 depth)
{
/* If not awaiting lockin/announce, it doesn't care any more */
if (channel->state != CHANNELD_AWAITING_LOCKIN
&& channel->state != CHANNELD_NORMAL) {
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,
depth)));
if (channel->remote_funding_locked
&& channel->state == CHANNELD_AWAITING_LOCKIN)
lockin_complete(channel);
return true;
}
/* Check if we are the fundee of this channel, the channel
* funding transaction is still not yet seen onchain, and
* it has been too long since the channel was first opened.
* If so, we should forget the channel. */
static bool
is_fundee_should_forget(struct lightningd *ld,
struct channel *channel,
u32 block_height)
{
u32 max_funding_unconfirmed = ld->max_funding_unconfirmed;
/* BOLT #2:
*
* A non-funding node (fundee):
* - SHOULD forget the channel if it does not see the
* funding transaction after a reasonable timeout.
*/
/* Only applies if we are fundee. */
if (channel->funder == LOCAL)
return false;
/* Does not apply if we already saw the funding tx. */
if (channel->scid)
return false;
/* Not even reached previous starting blocknum.
* (e.g. if --rescan option is used) */
if (block_height < channel->first_blocknum)
return false;
/* Timeout in blocks not yet reached. */
if (block_height - channel->first_blocknum < max_funding_unconfirmed)
return false;
/* Ah forget it! */
return true;
}
/* Notify all channels of new blocks. */
void channel_notify_new_block(struct lightningd *ld,
u32 block_height)
{
struct peer *peer;
struct channel *channel;
struct channel **to_forget = tal_arr(NULL, struct channel *, 0);
size_t i;
list_for_each (&ld->peers, peer, list) {
list_for_each (&peer->channels, channel, list)
if (is_fundee_should_forget(ld, channel, block_height)) {
*tal_arr_expand(&to_forget) = channel;
}
}
/* Need to forget in a separate loop, else the above
* nested loops may crash due to the last channel of
* a peer also deleting the peer, making the inner
* loop crash.
* list_for_each_safe does not work because it is not
* just the freeing of the channel that occurs, but the
* potential destruction of the peer that invalidates
* memory the inner loop is accessing. */
for (i = 0; i < tal_count(to_forget); ++i) {
channel = to_forget[i];
/* Report it first. */
log_unusual(channel->log,
"Forgetting channel: "
"It has been %"PRIu32" blocks without the "
"funding transaction %s getting deeply "
"confirmed. "
"We are fundee and can forget channel without "
"loss of funds.",
block_height - channel->first_blocknum,
type_to_string(tmpctx, struct bitcoin_txid,
&channel->funding_txid));
/* FIXME: Send an error packet for this case! */
/* And forget it. */
delete_channel(channel);
}
tal_free(to_forget);
}