#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include struct channel *new_initial_channel(const tal_t *ctx, const struct channel_id *cid, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, u32 minimum_depth, struct amount_sat funding, struct amount_msat local_msatoshi, const struct fee_states *fee_states TAKES, const struct channel_config *local, const struct channel_config *remote, const struct basepoints *local_basepoints, const struct basepoints *remote_basepoints, const struct pubkey *local_funding_pubkey, const struct pubkey *remote_funding_pubkey, bool option_static_remotekey, bool option_anchor_outputs, enum side opener) { struct channel *channel = tal(ctx, struct channel); struct amount_msat remote_msatoshi; channel->cid = *cid; channel->funding_txid = *funding_txid; channel->funding_txout = funding_txout; channel->funding = funding; channel->minimum_depth = minimum_depth; if (!amount_sat_sub_msat(&remote_msatoshi, channel->funding, local_msatoshi)) return tal_free(channel); channel->opener = opener; channel->config[LOCAL] = *local; channel->config[REMOTE] = *remote; channel->funding_pubkey[LOCAL] = *local_funding_pubkey; channel->funding_pubkey[REMOTE] = *remote_funding_pubkey; channel->htlcs = NULL; /* takes() if necessary */ channel->fee_states = dup_fee_states(channel, fee_states); channel->view[LOCAL].owed[LOCAL] = channel->view[REMOTE].owed[LOCAL] = local_msatoshi; channel->view[REMOTE].owed[REMOTE] = channel->view[LOCAL].owed[REMOTE] = remote_msatoshi; channel->basepoints[LOCAL] = *local_basepoints; channel->basepoints[REMOTE] = *remote_basepoints; channel->commitment_number_obscurer = commit_number_obscurer(&channel->basepoints[opener].payment, &channel->basepoints[!opener].payment); channel->option_static_remotekey = option_static_remotekey; channel->option_anchor_outputs = option_anchor_outputs; if (option_anchor_outputs) assert(option_static_remotekey); return channel; } /* FIXME: We could cache this. */ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx, const u8 **wscript, const struct channel *channel, const struct pubkey *per_commitment_point, enum side side, struct wally_tx_output *direct_outputs[NUM_SIDES], char** err_reason) { struct keyset keyset; struct bitcoin_tx *init_tx; /* This assumes no HTLCs! */ assert(!channel->htlcs); if (!derive_keyset(per_commitment_point, &channel->basepoints[side], &channel->basepoints[!side], channel->option_static_remotekey, &keyset)) { *err_reason = "Cannot derive keyset"; return NULL; } *wscript = bitcoin_redeem_2of2(ctx, &channel->funding_pubkey[side], &channel->funding_pubkey[!side]); init_tx = initial_commit_tx(ctx, &channel->funding_txid, channel->funding_txout, channel->funding, channel->funding_pubkey, channel->opener, /* They specify our to_self_delay and v.v. */ channel->config[!side].to_self_delay, &keyset, channel_feerate(channel, side), channel->config[side].dust_limit, channel->view[side].owed[side], channel->view[side].owed[!side], channel->config[!side].channel_reserve, 0 ^ channel->commitment_number_obscurer, direct_outputs, side, channel->option_anchor_outputs, err_reason); if (init_tx) { psbt_input_add_pubkey(init_tx->psbt, 0, &channel->funding_pubkey[side]); psbt_input_add_pubkey(init_tx->psbt, 0, &channel->funding_pubkey[!side]); } return init_tx; } u32 channel_feerate(const struct channel *channel, enum side side) { return get_feerate(channel->fee_states, channel->opener, side); } static char *fmt_channel_view(const tal_t *ctx, const struct channel_view *view) { return tal_fmt(ctx, "{ owed_local=%s," " owed_remote=%s }", type_to_string(tmpctx, struct amount_msat, &view->owed[LOCAL]), type_to_string(tmpctx, struct amount_msat, &view->owed[REMOTE])); } /* FIXME: This should reference HTLCs somehow, and feerates! */ static char *fmt_channel(const tal_t *ctx, const struct channel *channel) { return tal_fmt(ctx, "{ funding=%s," " opener=%s," " local=%s," " remote=%s }", type_to_string(tmpctx, struct amount_sat, &channel->funding), side_to_str(channel->opener), fmt_channel_view(ctx, &channel->view[LOCAL]), fmt_channel_view(ctx, &channel->view[REMOTE])); } /* Magic comment. */ REGISTER_TYPE_TO_STRING(channel, fmt_channel);