mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 17:47:30 +01:00
Let the callers do that (only channeld needs to do this). We temporarily send an error on unknown reestablish in openingd, as this mimic previous behavior and avoids breaking tests (it does leave a BROKEN message in the logs though, so test_funding_external_wallet_corners needs to ignore that for now. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1464 lines
47 KiB
C
1464 lines
47 KiB
C
/*~ Welcome to the opening daemon: gateway to channels!
|
|
*
|
|
* This daemon handles a single peer. It's happy to trade gossip with the
|
|
* peer until either lightningd asks it to fund a channel, or the peer itself
|
|
* asks to fund a channel. Then it goes through with the channel opening
|
|
* negotiations. It's important to note that until this negotiation is complete,
|
|
* there's nothing permanent about the channel: lightningd will only have to
|
|
* commit to the database once openingd succeeds.
|
|
*/
|
|
#include <bitcoin/block.h>
|
|
#include <bitcoin/chainparams.h>
|
|
#include <bitcoin/privkey.h>
|
|
#include <bitcoin/psbt.h>
|
|
#include <bitcoin/script.h>
|
|
#include <ccan/array_size/array_size.h>
|
|
#include <ccan/breakpoint/breakpoint.h>
|
|
#include <ccan/cast/cast.h>
|
|
#include <ccan/fdpass/fdpass.h>
|
|
#include <ccan/mem/mem.h>
|
|
#include <ccan/tal/str/str.h>
|
|
#include <common/crypto_sync.h>
|
|
#include <common/derive_basepoints.h>
|
|
#include <common/features.h>
|
|
#include <common/fee_states.h>
|
|
#include <common/gossip_rcvd_filter.h>
|
|
#include <common/gossip_store.h>
|
|
#include <common/initial_channel.h>
|
|
#include <common/initial_commit_tx.h>
|
|
#include <common/key_derive.h>
|
|
#include <common/memleak.h>
|
|
#include <common/overflows.h>
|
|
#include <common/peer_billboard.h>
|
|
#include <common/peer_failed.h>
|
|
#include <common/peer_status_wiregen.h>
|
|
#include <common/penalty_base.h>
|
|
#include <common/read_peer_msg.h>
|
|
#include <common/shutdown_scriptpubkey.h>
|
|
#include <common/status.h>
|
|
#include <common/subdaemon.h>
|
|
#include <common/type_to_string.h>
|
|
#include <common/version.h>
|
|
#include <common/wire_error.h>
|
|
#include <errno.h>
|
|
#include <gossipd/gossipd_peerd_wiregen.h>
|
|
#include <hsmd/hsmd_wiregen.h>
|
|
#include <inttypes.h>
|
|
#include <openingd/common.h>
|
|
#include <openingd/openingd_wiregen.h>
|
|
#include <poll.h>
|
|
#include <secp256k1.h>
|
|
#include <stdio.h>
|
|
#include <wally_bip32.h>
|
|
#include <wire/common_wiregen.h>
|
|
#include <wire/peer_wire.h>
|
|
#include <wire/wire.h>
|
|
#include <wire/wire_sync.h>
|
|
|
|
/* stdin == lightningd, 3 == peer, 4 == gossipd, 5 = gossip_store, 6 = hsmd */
|
|
#define REQ_FD STDIN_FILENO
|
|
#define HSM_FD 6
|
|
|
|
#if DEVELOPER
|
|
/* If --dev-force-tmp-channel-id is set, it ends up here */
|
|
static struct channel_id *dev_force_tmp_channel_id;
|
|
#endif /* DEVELOPER */
|
|
|
|
/* Global state structure. This is only for the one specific peer and channel */
|
|
struct state {
|
|
struct per_peer_state *pps;
|
|
|
|
/* Features they offered */
|
|
u8 *their_features;
|
|
|
|
/* Constraints on a channel they open. */
|
|
u32 minimum_depth;
|
|
u32 min_feerate, max_feerate;
|
|
struct amount_msat min_effective_htlc_capacity;
|
|
|
|
/* Limits on what remote config we accept. */
|
|
u32 max_to_self_delay;
|
|
|
|
/* These are the points lightningd told us to use when accepting or
|
|
* opening a channel. */
|
|
struct basepoints our_points;
|
|
struct pubkey our_funding_pubkey;
|
|
|
|
/* Information we need between funding_start and funding_complete */
|
|
struct basepoints their_points;
|
|
struct pubkey their_funding_pubkey;
|
|
|
|
/* hsmd gives us our first per-commitment point, and peer tells us
|
|
* theirs */
|
|
struct pubkey first_per_commitment_point[NUM_SIDES];
|
|
|
|
/* Initially temporary, then final channel id. */
|
|
struct channel_id channel_id;
|
|
|
|
/* Funding and feerate: set by opening peer. */
|
|
struct amount_sat funding;
|
|
struct amount_msat push_msat;
|
|
u32 feerate_per_kw;
|
|
struct bitcoin_txid funding_txid;
|
|
u16 funding_txout;
|
|
|
|
/* If non-NULL, this is the scriptpubkey we/they *must* close with */
|
|
u8 *upfront_shutdown_script[NUM_SIDES];
|
|
|
|
/* This is a cluster of fields in open_channel and accept_channel which
|
|
* indicate the restrictions each side places on the channel. */
|
|
struct channel_config localconf, remoteconf;
|
|
|
|
/* The channel structure, as defined in common/initial_channel.h. While
|
|
* the structure has room for HTLCs, those routines are channeld-specific
|
|
* as initial channels never have HTLCs. */
|
|
struct channel *channel;
|
|
|
|
bool option_static_remotekey;
|
|
bool option_anchor_outputs;
|
|
|
|
struct feature_set *our_features;
|
|
};
|
|
|
|
/*~ If we can't agree on parameters, we fail to open the channel. If we're
|
|
* the opener, we need to tell lightningd, otherwise it never really notices. */
|
|
static void negotiation_aborted(struct state *state, bool am_opener,
|
|
const char *why)
|
|
{
|
|
status_debug("aborted opening negotiation: %s", why);
|
|
/*~ The "billboard" (exposed as "status" in the JSON listpeers RPC
|
|
* call) is a transient per-channel area which indicates important
|
|
* information about what is happening. It has a "permanent" area for
|
|
* each state, which can be used to indicate what went wrong in that
|
|
* state (such as here), and a single transient area for current
|
|
* status. */
|
|
peer_billboard(true, why);
|
|
|
|
/* If necessary, tell master that funding failed. */
|
|
if (am_opener) {
|
|
u8 *msg = towire_openingd_funder_failed(NULL, why);
|
|
wire_sync_write(REQ_FD, take(msg));
|
|
}
|
|
|
|
/* Default is no shutdown_scriptpubkey: free any leftover ones. */
|
|
state->upfront_shutdown_script[LOCAL]
|
|
= tal_free(state->upfront_shutdown_script[LOCAL]);
|
|
state->upfront_shutdown_script[REMOTE]
|
|
= tal_free(state->upfront_shutdown_script[REMOTE]);
|
|
|
|
/*~ Reset state. We keep gossipping with them, even though this open
|
|
* failed. */
|
|
memset(&state->channel_id, 0, sizeof(state->channel_id));
|
|
state->channel = tal_free(state->channel);
|
|
}
|
|
|
|
/*~ For negotiation failures: we tell them the parameter we didn't like. */
|
|
static void negotiation_failed(struct state *state, bool am_opener,
|
|
const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
const char *errmsg;
|
|
u8 *msg;
|
|
|
|
va_start(ap, fmt);
|
|
errmsg = tal_vfmt(tmpctx, fmt, ap);
|
|
va_end(ap);
|
|
|
|
msg = towire_errorfmt(NULL, &state->channel_id,
|
|
"You gave bad parameters: %s", errmsg);
|
|
sync_crypto_write(state->pps, take(msg));
|
|
|
|
negotiation_aborted(state, am_opener, errmsg);
|
|
}
|
|
|
|
/* We always set channel_reserve_satoshis to 1%, rounded down. */
|
|
static void set_reserve(struct state *state, const struct amount_sat dust_limit)
|
|
{
|
|
state->localconf.channel_reserve = amount_sat_div(state->funding, 100);
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The sending node:
|
|
*...
|
|
* - MUST set `channel_reserve_satoshis` greater than or equal to
|
|
* `dust_limit_satoshis` from the `open_channel` message.
|
|
*/
|
|
if (amount_sat_greater(dust_limit,
|
|
state->localconf.channel_reserve))
|
|
state->localconf.channel_reserve
|
|
= dust_limit;
|
|
}
|
|
|
|
/*~ Handle random messages we might get during opening negotiation, (eg. gossip)
|
|
* returning the first non-handled one, or NULL if we aborted negotiation. */
|
|
static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state,
|
|
bool am_opener)
|
|
{
|
|
/* This is an event loop of its own. That's generally considered poor
|
|
* form, but we use it in a very limited way. */
|
|
for (;;) {
|
|
u8 *msg;
|
|
bool from_gossipd;
|
|
char *err;
|
|
bool warning;
|
|
struct channel_id actual;
|
|
|
|
/* The event loop is responsible for freeing tmpctx, so our
|
|
* temporary allocations don't grow unbounded. */
|
|
clean_tmpctx();
|
|
|
|
/* This helper routine polls both the peer and gossipd. */
|
|
msg = peer_or_gossip_sync_read(ctx, state->pps, &from_gossipd);
|
|
|
|
/* Use standard helper for gossip msgs (forwards, if it's an
|
|
* error, exits). */
|
|
if (from_gossipd) {
|
|
handle_gossip_msg(state->pps, take(msg));
|
|
continue;
|
|
}
|
|
|
|
/* Some messages go straight to gossipd. */
|
|
if (is_msg_for_gossipd(msg)) {
|
|
gossip_rcvd_filter_add(state->pps->grf, msg);
|
|
wire_sync_write(state->pps->gossip_fd, take(msg));
|
|
continue;
|
|
}
|
|
|
|
/* BOLT #1:
|
|
*
|
|
* A receiving node:
|
|
* - upon receiving a message of _odd_, unknown type:
|
|
* - MUST ignore the received message.
|
|
*/
|
|
if (is_unknown_msg_discardable(msg))
|
|
continue;
|
|
|
|
/* Might be a timestamp filter request: handle. */
|
|
if (handle_timestamp_filter(state->pps, msg))
|
|
continue;
|
|
|
|
/* A helper which decodes an error. */
|
|
if (is_peer_error(tmpctx, msg, &state->channel_id,
|
|
&err, &warning)) {
|
|
/* BOLT #1:
|
|
*
|
|
* - if no existing channel is referred to by the
|
|
* message:
|
|
* - MUST ignore the message.
|
|
*/
|
|
/* In this case, is_peer_error returns true, but sets
|
|
* err to NULL */
|
|
if (!err) {
|
|
tal_free(msg);
|
|
continue;
|
|
}
|
|
negotiation_aborted(state, am_opener,
|
|
tal_fmt(tmpctx, "They sent %s",
|
|
err));
|
|
/* Return NULL so caller knows to stop negotiating. */
|
|
return NULL;
|
|
}
|
|
|
|
/*~ We do not support multiple "live" channels, though the
|
|
* protocol has a "channel_id" field in all non-gossip messages
|
|
* so it's possible. Our one-process-one-channel mechanism
|
|
* keeps things simple: if we wanted to change this, we would
|
|
* probably be best with another daemon to de-multiplex them;
|
|
* this could be connectd itself, in fact. */
|
|
if (is_wrong_channel(msg, &state->channel_id, &actual)) {
|
|
status_debug("Rejecting %s for unknown channel_id %s",
|
|
peer_wire_name(fromwire_peektype(msg)),
|
|
type_to_string(tmpctx, struct channel_id,
|
|
&actual));
|
|
sync_crypto_write(state->pps,
|
|
take(towire_errorfmt(NULL, &actual,
|
|
"Multiple channels"
|
|
" unsupported")));
|
|
tal_free(msg);
|
|
continue;
|
|
}
|
|
|
|
/* If we get here, it's an interesting message. */
|
|
return msg;
|
|
}
|
|
}
|
|
|
|
static bool setup_channel_funder(struct state *state)
|
|
{
|
|
/*~ For symmetry, we calculate our own reserve even though lightningd
|
|
* could do it for the we-are-funding case. */
|
|
set_reserve(state, state->localconf.dust_limit);
|
|
|
|
/*~ Grab a random ID until the funding tx is created (we can't do that
|
|
* until we know their funding_pubkey) */
|
|
temporary_channel_id(&state->channel_id);
|
|
|
|
#if DEVELOPER
|
|
/* --dev-force-tmp-channel-id specified */
|
|
if (dev_force_tmp_channel_id)
|
|
state->channel_id = *dev_force_tmp_channel_id;
|
|
#endif
|
|
/* BOLT #2:
|
|
*
|
|
* The sending node:
|
|
*...
|
|
* - if both nodes advertised `option_support_large_channel`:
|
|
* - MAY set `funding_satoshis` greater than or equal to 2^24 satoshi.
|
|
* - otherwise:
|
|
* - MUST set `funding_satoshis` to less than 2^24 satoshi.
|
|
*/
|
|
if (!feature_negotiated(state->our_features,
|
|
state->their_features, OPT_LARGE_CHANNELS)
|
|
&& amount_sat_greater(state->funding, chainparams->max_funding)) {
|
|
status_failed(STATUS_FAIL_MASTER_IO,
|
|
"funding_satoshis must be < %s, not %s",
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&chainparams->max_funding),
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->funding));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void set_remote_upfront_shutdown(struct state *state,
|
|
u8 *shutdown_scriptpubkey STEALS)
|
|
{
|
|
bool anysegwit = feature_negotiated(state->our_features,
|
|
state->their_features,
|
|
OPT_SHUTDOWN_ANYSEGWIT);
|
|
|
|
state->upfront_shutdown_script[REMOTE]
|
|
= tal_steal(state, shutdown_scriptpubkey);
|
|
|
|
if (shutdown_scriptpubkey
|
|
&& !valid_shutdown_scriptpubkey(shutdown_scriptpubkey, anysegwit))
|
|
peer_failed_err(state->pps,
|
|
&state->channel_id,
|
|
"Unacceptable upfront_shutdown_script %s",
|
|
tal_hex(tmpctx, shutdown_scriptpubkey));
|
|
}
|
|
|
|
/* We start the 'open a channel' negotation with the supplied peer, but
|
|
* stop when we get to the part where we need the funding txid */
|
|
static u8 *funder_channel_start(struct state *state, u8 channel_flags)
|
|
{
|
|
u8 *msg;
|
|
u8 *funding_output_script;
|
|
struct channel_id id_in;
|
|
struct tlv_open_channel_tlvs *open_tlvs;
|
|
struct tlv_accept_channel_tlvs *accept_tlvs;
|
|
char *err_reason;
|
|
|
|
if (!setup_channel_funder(state))
|
|
return NULL;
|
|
|
|
if (!state->upfront_shutdown_script[LOCAL])
|
|
state->upfront_shutdown_script[LOCAL]
|
|
= no_upfront_shutdown_script(state,
|
|
state->our_features,
|
|
state->their_features);
|
|
|
|
open_tlvs = tlv_open_channel_tlvs_new(tmpctx);
|
|
open_tlvs->upfront_shutdown_script
|
|
= state->upfront_shutdown_script[LOCAL];
|
|
|
|
msg = towire_open_channel(NULL,
|
|
&chainparams->genesis_blockhash,
|
|
&state->channel_id,
|
|
state->funding,
|
|
state->push_msat,
|
|
state->localconf.dust_limit,
|
|
state->localconf.max_htlc_value_in_flight,
|
|
state->localconf.channel_reserve,
|
|
state->localconf.htlc_minimum,
|
|
state->feerate_per_kw,
|
|
state->localconf.to_self_delay,
|
|
state->localconf.max_accepted_htlcs,
|
|
&state->our_funding_pubkey,
|
|
&state->our_points.revocation,
|
|
&state->our_points.payment,
|
|
&state->our_points.delayed_payment,
|
|
&state->our_points.htlc,
|
|
&state->first_per_commitment_point[LOCAL],
|
|
channel_flags,
|
|
open_tlvs);
|
|
sync_crypto_write(state->pps, take(msg));
|
|
|
|
/* This is usually a very transient state... */
|
|
peer_billboard(false,
|
|
"Funding channel start: offered, now waiting for accept_channel");
|
|
|
|
/* ... since their reply should be immediate. */
|
|
msg = opening_negotiate_msg(tmpctx, state, true);
|
|
if (!msg)
|
|
return NULL;
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The receiving node MUST fail the channel if:
|
|
*...
|
|
* - `funding_pubkey`, `revocation_basepoint`, `htlc_basepoint`,
|
|
* `payment_basepoint`, or `delayed_payment_basepoint` are not
|
|
* valid secp256k1 pubkeys in compressed format.
|
|
*/
|
|
accept_tlvs = tlv_accept_channel_tlvs_new(tmpctx);
|
|
if (!fromwire_accept_channel(msg, &id_in,
|
|
&state->remoteconf.dust_limit,
|
|
&state->remoteconf.max_htlc_value_in_flight,
|
|
&state->remoteconf.channel_reserve,
|
|
&state->remoteconf.htlc_minimum,
|
|
&state->minimum_depth,
|
|
&state->remoteconf.to_self_delay,
|
|
&state->remoteconf.max_accepted_htlcs,
|
|
&state->their_funding_pubkey,
|
|
&state->their_points.revocation,
|
|
&state->their_points.payment,
|
|
&state->their_points.delayed_payment,
|
|
&state->their_points.htlc,
|
|
&state->first_per_commitment_point[REMOTE],
|
|
accept_tlvs)) {
|
|
peer_failed_err(state->pps,
|
|
&state->channel_id,
|
|
"Parsing accept_channel %s", tal_hex(msg, msg));
|
|
}
|
|
set_remote_upfront_shutdown(state, accept_tlvs->upfront_shutdown_script);
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The `temporary_channel_id` MUST be the same as the
|
|
* `temporary_channel_id` in the `open_channel` message. */
|
|
if (!channel_id_eq(&id_in, &state->channel_id))
|
|
/* In this case we exit, since we don't know what's going on. */
|
|
peer_failed_err(state->pps, &id_in,
|
|
"accept_channel ids don't match: sent %s got %s",
|
|
type_to_string(msg, struct channel_id, &id_in),
|
|
type_to_string(msg, struct channel_id,
|
|
&state->channel_id));
|
|
|
|
if (amount_sat_greater(state->remoteconf.dust_limit,
|
|
state->localconf.channel_reserve)) {
|
|
negotiation_failed(state, true,
|
|
"dust limit %s"
|
|
" would be above our reserve %s",
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->remoteconf.dust_limit),
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->localconf.channel_reserve));
|
|
return NULL;
|
|
}
|
|
|
|
if (!check_config_bounds(tmpctx, state->funding,
|
|
state->feerate_per_kw,
|
|
state->max_to_self_delay,
|
|
state->min_effective_htlc_capacity,
|
|
&state->remoteconf,
|
|
&state->localconf,
|
|
true,
|
|
state->option_anchor_outputs,
|
|
&err_reason)) {
|
|
negotiation_failed(state, true, "%s", err_reason);
|
|
return NULL;
|
|
}
|
|
|
|
funding_output_script =
|
|
scriptpubkey_p2wsh(tmpctx,
|
|
bitcoin_redeem_2of2(tmpctx,
|
|
&state->our_funding_pubkey,
|
|
&state->their_funding_pubkey));
|
|
|
|
/* Update the billboard with our infos */
|
|
peer_billboard(false,
|
|
"Funding channel start: awaiting funding_txid with output to %s",
|
|
tal_hex(tmpctx, funding_output_script));
|
|
|
|
return towire_openingd_funder_start_reply(state,
|
|
funding_output_script,
|
|
feature_negotiated(
|
|
state->our_features,
|
|
state->their_features,
|
|
OPT_UPFRONT_SHUTDOWN_SCRIPT));
|
|
}
|
|
|
|
static bool funder_finalize_channel_setup(struct state *state,
|
|
struct amount_msat local_msat,
|
|
struct bitcoin_signature *sig,
|
|
struct bitcoin_tx **tx,
|
|
struct penalty_base **pbase)
|
|
{
|
|
u8 *msg;
|
|
struct channel_id id_in;
|
|
const u8 *wscript;
|
|
struct channel_id cid;
|
|
char *err_reason;
|
|
struct wally_tx_output *direct_outputs[NUM_SIDES];
|
|
|
|
/*~ Now we can initialize the `struct channel`. This represents
|
|
* the current channel state and is how we can generate the current
|
|
* commitment transaction.
|
|
*
|
|
* The routines to support `struct channel` are split into a common
|
|
* part (common/initial_channel) which doesn't support HTLCs and is
|
|
* enough for us here, and the complete channel support required by
|
|
* `channeld` which lives in channeld/full_channel. */
|
|
derive_channel_id(&cid,
|
|
&state->funding_txid, state->funding_txout);
|
|
|
|
state->channel = new_initial_channel(state,
|
|
&cid,
|
|
&state->funding_txid,
|
|
state->funding_txout,
|
|
state->minimum_depth,
|
|
state->funding,
|
|
local_msat,
|
|
take(new_fee_states(NULL, LOCAL,
|
|
&state->feerate_per_kw)),
|
|
&state->localconf,
|
|
&state->remoteconf,
|
|
&state->our_points,
|
|
&state->their_points,
|
|
&state->our_funding_pubkey,
|
|
&state->their_funding_pubkey,
|
|
state->option_static_remotekey,
|
|
state->option_anchor_outputs,
|
|
/* Opener is local */
|
|
LOCAL);
|
|
/* We were supposed to do enough checks above, but just in case,
|
|
* new_initial_channel will fail to create absurd channels */
|
|
if (!state->channel)
|
|
peer_failed_err(state->pps,
|
|
&state->channel_id,
|
|
"could not create channel with given config");
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* ### The `funding_created` Message
|
|
*
|
|
* This message describes the outpoint which the funder has created
|
|
* for the initial commitment transactions. After receiving the
|
|
* peer's signature, via `funding_signed`, it will broadcast the funding
|
|
* transaction.
|
|
*/
|
|
/* This gives us their first commitment transaction. */
|
|
*tx = initial_channel_tx(state, &wscript, state->channel,
|
|
&state->first_per_commitment_point[REMOTE],
|
|
REMOTE, direct_outputs, &err_reason);
|
|
if (!*tx) {
|
|
/* This should not happen: we should never create channels we
|
|
* can't afford the fees for after reserve. */
|
|
negotiation_failed(state, true,
|
|
"Could not meet their fees and reserve: %s", err_reason);
|
|
goto fail;
|
|
}
|
|
|
|
if (direct_outputs[LOCAL])
|
|
*pbase = penalty_base_new(state, 0, *tx, direct_outputs[LOCAL]);
|
|
else
|
|
*pbase = NULL;
|
|
|
|
/* We ask the HSM to sign their commitment transaction for us: it knows
|
|
* our funding key, it just needs the remote funding key to create the
|
|
* witness script. It also needs the amount of the funding output,
|
|
* as segwit signatures commit to that as well, even though it doesn't
|
|
* explicitly appear in the transaction itself. */
|
|
msg = towire_hsmd_sign_remote_commitment_tx(NULL,
|
|
*tx,
|
|
&state->channel->funding_pubkey[REMOTE],
|
|
&state->first_per_commitment_point[REMOTE],
|
|
state->channel->option_static_remotekey);
|
|
|
|
wire_sync_write(HSM_FD, take(msg));
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
|
if (!fromwire_hsmd_sign_tx_reply(msg, sig))
|
|
status_failed(STATUS_FAIL_HSM_IO, "Bad sign_tx_reply %s",
|
|
tal_hex(tmpctx, msg));
|
|
|
|
/* You can tell this has been a problem before, since there's a debug
|
|
* message here: */
|
|
status_debug("signature %s on tx %s using key %s",
|
|
type_to_string(tmpctx, struct bitcoin_signature, sig),
|
|
type_to_string(tmpctx, struct bitcoin_tx, *tx),
|
|
type_to_string(tmpctx, struct pubkey,
|
|
&state->our_funding_pubkey));
|
|
|
|
/* Now we give our peer the signature for their first commitment
|
|
* transaction. */
|
|
msg = towire_funding_created(state, &state->channel_id,
|
|
&state->funding_txid,
|
|
state->funding_txout,
|
|
&sig->s);
|
|
sync_crypto_write(state->pps, msg);
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* ### The `funding_signed` Message
|
|
*
|
|
* This message gives the funder the signature it needs for the first
|
|
* commitment transaction, so it can broadcast the transaction knowing
|
|
* that funds can be redeemed, if need be.
|
|
*/
|
|
peer_billboard(false,
|
|
"Funding channel: create first tx, now waiting for their signature");
|
|
|
|
/* Now they send us their signature for that first commitment
|
|
* transaction. */
|
|
msg = opening_negotiate_msg(tmpctx, state, true);
|
|
if (!msg)
|
|
goto fail;
|
|
|
|
sig->sighash_type = SIGHASH_ALL;
|
|
if (!fromwire_funding_signed(msg, &id_in, &sig->s))
|
|
peer_failed_err(state->pps, &state->channel_id,
|
|
"Parsing funding_signed: %s", tal_hex(msg, msg));
|
|
/* BOLT #2:
|
|
*
|
|
* This message introduces the `channel_id` to identify the channel.
|
|
* It's derived from the funding transaction by combining the
|
|
* `funding_txid` and the `funding_output_index`, using big-endian
|
|
* exclusive-OR (i.e. `funding_output_index` alters the last 2
|
|
* bytes).
|
|
*/
|
|
|
|
/*~ Back in Milan, we chose to allow multiple channels between peers in
|
|
* the protocol. I insisted that we multiplex these over the same
|
|
* socket, and (even though I didn't plan on implementing it anytime
|
|
* soon) that we put it into the first version of the protocol
|
|
* because it would be painful to add in later.
|
|
*
|
|
* My logic seemed sound: we treat new connections as an implication
|
|
* that the old connection has disconnected, which happens more often
|
|
* than you'd hope on modern networks. However, supporting multiple
|
|
* channels via multiple connections would be far easier for us to
|
|
* support with our (introduced-since) separate daemon model.
|
|
*
|
|
* Let this be a lesson: beware premature specification, even if you
|
|
* suspect "we'll need it later!". */
|
|
state->channel_id = cid;
|
|
|
|
if (!channel_id_eq(&id_in, &state->channel_id))
|
|
peer_failed_err(state->pps, &id_in,
|
|
"funding_signed ids don't match: expected %s got %s",
|
|
type_to_string(msg, struct channel_id,
|
|
&state->channel_id),
|
|
type_to_string(msg, struct channel_id, &id_in));
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The recipient:
|
|
* - if `signature` is incorrect OR non-compliant with LOW-S-standard rule...:
|
|
* - MUST fail the channel
|
|
*/
|
|
/* So we create *our* initial commitment transaction, and check the
|
|
* signature they sent against that. */
|
|
*tx = initial_channel_tx(state, &wscript, state->channel,
|
|
&state->first_per_commitment_point[LOCAL],
|
|
LOCAL, direct_outputs, &err_reason);
|
|
if (!*tx) {
|
|
negotiation_failed(state, true,
|
|
"Could not meet our fees and reserve: %s", err_reason);
|
|
goto fail;
|
|
}
|
|
|
|
if (!check_tx_sig(*tx, 0, NULL, wscript, &state->their_funding_pubkey, sig)) {
|
|
peer_failed_err(state->pps, &state->channel_id,
|
|
"Bad signature %s on tx %s using key %s",
|
|
type_to_string(tmpctx, struct bitcoin_signature,
|
|
sig),
|
|
type_to_string(tmpctx, struct bitcoin_tx, *tx),
|
|
type_to_string(tmpctx, struct pubkey,
|
|
&state->their_funding_pubkey));
|
|
}
|
|
|
|
/* We save their sig to our first commitment tx */
|
|
if (!psbt_input_set_signature((*tx)->psbt, 0,
|
|
&state->their_funding_pubkey,
|
|
sig))
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
"Unable to set signature internally");
|
|
|
|
peer_billboard(false, "Funding channel: opening negotiation succeeded");
|
|
|
|
return true;
|
|
|
|
fail:
|
|
tal_free(wscript);
|
|
return false;
|
|
}
|
|
|
|
static u8 *funder_channel_complete(struct state *state)
|
|
{
|
|
/* Remote commitment tx */
|
|
struct bitcoin_tx *tx;
|
|
struct bitcoin_signature sig;
|
|
struct amount_msat local_msat;
|
|
struct penalty_base *pbase;
|
|
|
|
/* Update the billboard about what we're doing*/
|
|
peer_billboard(false,
|
|
"Funding channel con't: continuing with funding_txid %s",
|
|
type_to_string(tmpctx, struct bitcoin_txid, &state->funding_txid));
|
|
|
|
/* We recalculate the local_msat from cached values; should
|
|
* succeed because we checked it earlier */
|
|
if (!amount_sat_sub_msat(&local_msat, state->funding, state->push_msat))
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
"push_msat %s > funding %s?",
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
&state->push_msat),
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->funding));
|
|
|
|
if (!funder_finalize_channel_setup(state, local_msat, &sig, &tx,
|
|
&pbase))
|
|
return NULL;
|
|
|
|
return towire_openingd_funder_reply(state,
|
|
&state->remoteconf,
|
|
tx,
|
|
pbase,
|
|
&sig,
|
|
state->pps,
|
|
&state->their_points.revocation,
|
|
&state->their_points.payment,
|
|
&state->their_points.htlc,
|
|
&state->their_points.delayed_payment,
|
|
&state->first_per_commitment_point[REMOTE],
|
|
state->minimum_depth,
|
|
&state->their_funding_pubkey,
|
|
&state->funding_txid,
|
|
state->funding_txout,
|
|
state->feerate_per_kw,
|
|
state->localconf.channel_reserve,
|
|
state->upfront_shutdown_script[REMOTE]);
|
|
}
|
|
|
|
/*~ The peer sent us an `open_channel`, that means we're the fundee. */
|
|
static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
|
{
|
|
struct channel_id id_in;
|
|
struct basepoints theirs;
|
|
struct pubkey their_funding_pubkey;
|
|
struct bitcoin_signature theirsig, sig;
|
|
struct bitcoin_tx *local_commit, *remote_commit;
|
|
struct bitcoin_blkid chain_hash;
|
|
u8 *msg;
|
|
const u8 *wscript;
|
|
u8 channel_flags;
|
|
char* err_reason;
|
|
struct wally_tx_output *direct_outputs[NUM_SIDES];
|
|
struct penalty_base *pbase;
|
|
struct tlv_accept_channel_tlvs *accept_tlvs;
|
|
struct tlv_open_channel_tlvs *open_tlvs
|
|
= tlv_open_channel_tlvs_new(tmpctx);
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The receiving node MUST fail the channel if:
|
|
*...
|
|
* - `funding_pubkey`, `revocation_basepoint`, `htlc_basepoint`,
|
|
* `payment_basepoint`, or `delayed_payment_basepoint` are not valid
|
|
* secp256k1 pubkeys in compressed format.
|
|
*/
|
|
if (!fromwire_open_channel(open_channel_msg, &chain_hash,
|
|
&state->channel_id,
|
|
&state->funding,
|
|
&state->push_msat,
|
|
&state->remoteconf.dust_limit,
|
|
&state->remoteconf.max_htlc_value_in_flight,
|
|
&state->remoteconf.channel_reserve,
|
|
&state->remoteconf.htlc_minimum,
|
|
&state->feerate_per_kw,
|
|
&state->remoteconf.to_self_delay,
|
|
&state->remoteconf.max_accepted_htlcs,
|
|
&their_funding_pubkey,
|
|
&theirs.revocation,
|
|
&theirs.payment,
|
|
&theirs.delayed_payment,
|
|
&theirs.htlc,
|
|
&state->first_per_commitment_point[REMOTE],
|
|
&channel_flags,
|
|
open_tlvs))
|
|
peer_failed_err(state->pps,
|
|
&state->channel_id,
|
|
"Parsing open_channel %s", tal_hex(tmpctx, open_channel_msg));
|
|
set_remote_upfront_shutdown(state, open_tlvs->upfront_shutdown_script);
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The receiving node MUST fail the channel if:
|
|
* - the `chain_hash` value is set to a hash of a chain
|
|
* that is unknown to the receiver.
|
|
*/
|
|
if (!bitcoin_blkid_eq(&chain_hash, &chainparams->genesis_blockhash)) {
|
|
negotiation_failed(state, false,
|
|
"Unknown chain-hash %s",
|
|
type_to_string(tmpctx,
|
|
struct bitcoin_blkid,
|
|
&chain_hash));
|
|
return NULL;
|
|
}
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The receiving node MUST fail the channel if:
|
|
*...
|
|
* - `funding_satoshis` is greater than or equal to 2^24 and the receiver does not support
|
|
* `option_support_large_channel`. */
|
|
/* We choose to require *negotiation*, not just support! */
|
|
if (!feature_negotiated(state->our_features, state->their_features,
|
|
OPT_LARGE_CHANNELS)
|
|
&& amount_sat_greater(state->funding, chainparams->max_funding)) {
|
|
negotiation_failed(state, false,
|
|
"funding_satoshis %s too large",
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->funding));
|
|
return NULL;
|
|
}
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The receiving node MUST fail the channel if:
|
|
* ...
|
|
* - `push_msat` is greater than `funding_satoshis` * 1000.
|
|
*/
|
|
if (amount_msat_greater_sat(state->push_msat, state->funding)) {
|
|
peer_failed_err(state->pps, &state->channel_id,
|
|
"Their push_msat %s"
|
|
" would be too large for funding_satoshis %s",
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
&state->push_msat),
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->funding));
|
|
return NULL;
|
|
}
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The receiving node MUST fail the channel if:
|
|
*...
|
|
* - it considers `feerate_per_kw` too small for timely processing or
|
|
* unreasonably large.
|
|
*/
|
|
if (state->feerate_per_kw < state->min_feerate) {
|
|
negotiation_failed(state, false,
|
|
"feerate_per_kw %u below minimum %u",
|
|
state->feerate_per_kw, state->min_feerate);
|
|
return NULL;
|
|
}
|
|
|
|
if (state->feerate_per_kw > state->max_feerate) {
|
|
negotiation_failed(state, false,
|
|
"feerate_per_kw %u above maximum %u",
|
|
state->feerate_per_kw, state->max_feerate);
|
|
return NULL;
|
|
}
|
|
|
|
/* This reserves 1% of the channel (rounded up) */
|
|
set_reserve(state, state->remoteconf.dust_limit);
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The sender:
|
|
*...
|
|
* - MUST set `channel_reserve_satoshis` greater than or equal to
|
|
* `dust_limit_satoshis` from the `open_channel` message.
|
|
* - MUST set `dust_limit_satoshis` less than or equal to
|
|
* `channel_reserve_satoshis` from the `open_channel` message.
|
|
*/
|
|
if (amount_sat_greater(state->remoteconf.dust_limit,
|
|
state->localconf.channel_reserve)) {
|
|
negotiation_failed(state, false,
|
|
"Our channel reserve %s"
|
|
" would be below their dust %s",
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->localconf.channel_reserve),
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->remoteconf.dust_limit));
|
|
return NULL;
|
|
}
|
|
if (amount_sat_greater(state->localconf.dust_limit,
|
|
state->remoteconf.channel_reserve)) {
|
|
negotiation_failed(state, false,
|
|
"Our dust limit %s"
|
|
" would be above their reserve %s",
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->localconf.dust_limit),
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
&state->remoteconf.channel_reserve));
|
|
return NULL;
|
|
}
|
|
|
|
/* These checks are the same whether we're opener or accepter... */
|
|
if (!check_config_bounds(tmpctx, state->funding,
|
|
state->feerate_per_kw,
|
|
state->max_to_self_delay,
|
|
state->min_effective_htlc_capacity,
|
|
&state->remoteconf,
|
|
&state->localconf,
|
|
false,
|
|
state->option_anchor_outputs,
|
|
&err_reason)) {
|
|
negotiation_failed(state, false, "%s", err_reason);
|
|
return NULL;
|
|
}
|
|
|
|
/* Check with lightningd that we can accept this? In particular,
|
|
* if we have an existing channel, we don't support it. */
|
|
msg = towire_openingd_got_offer(NULL,
|
|
state->funding,
|
|
state->push_msat,
|
|
state->remoteconf.dust_limit,
|
|
state->remoteconf.max_htlc_value_in_flight,
|
|
state->remoteconf.channel_reserve,
|
|
state->remoteconf.htlc_minimum,
|
|
state->feerate_per_kw,
|
|
state->remoteconf.to_self_delay,
|
|
state->remoteconf.max_accepted_htlcs,
|
|
channel_flags,
|
|
state->upfront_shutdown_script[REMOTE]);
|
|
wire_sync_write(REQ_FD, take(msg));
|
|
msg = wire_sync_read(tmpctx, REQ_FD);
|
|
|
|
/* We don't allocate off tmpctx, because that's freed inside
|
|
* opening_negotiate_msg */
|
|
if (!fromwire_openingd_got_offer_reply(state, msg, &err_reason,
|
|
&state->upfront_shutdown_script[LOCAL]))
|
|
master_badmsg(WIRE_OPENINGD_GOT_OFFER_REPLY, msg);
|
|
|
|
/* If they give us a reason to reject, do so. */
|
|
if (err_reason) {
|
|
u8 *errmsg = towire_errorfmt(NULL, &state->channel_id,
|
|
"%s", err_reason);
|
|
sync_crypto_write(state->pps, take(errmsg));
|
|
tal_free(err_reason);
|
|
return NULL;
|
|
}
|
|
|
|
if (!state->upfront_shutdown_script[LOCAL])
|
|
state->upfront_shutdown_script[LOCAL]
|
|
= no_upfront_shutdown_script(state,
|
|
state->our_features,
|
|
state->their_features);
|
|
|
|
/* OK, we accept! */
|
|
accept_tlvs = tlv_accept_channel_tlvs_new(tmpctx);
|
|
accept_tlvs->upfront_shutdown_script
|
|
= state->upfront_shutdown_script[LOCAL];
|
|
|
|
msg = towire_accept_channel(NULL, &state->channel_id,
|
|
state->localconf.dust_limit,
|
|
state->localconf.max_htlc_value_in_flight,
|
|
state->localconf.channel_reserve,
|
|
state->localconf.htlc_minimum,
|
|
state->minimum_depth,
|
|
state->localconf.to_self_delay,
|
|
state->localconf.max_accepted_htlcs,
|
|
&state->our_funding_pubkey,
|
|
&state->our_points.revocation,
|
|
&state->our_points.payment,
|
|
&state->our_points.delayed_payment,
|
|
&state->our_points.htlc,
|
|
&state->first_per_commitment_point[LOCAL],
|
|
accept_tlvs);
|
|
|
|
sync_crypto_write(state->pps, take(msg));
|
|
|
|
peer_billboard(false,
|
|
"Incoming channel: accepted, now waiting for them to create funding tx");
|
|
|
|
/* This is a loop which handles gossip until we get a non-gossip msg */
|
|
msg = opening_negotiate_msg(tmpctx, state, false);
|
|
if (!msg)
|
|
return NULL;
|
|
|
|
/* The message should be "funding_created" which tells us what funding
|
|
* tx they generated; the sighash type is implied, so we set it here. */
|
|
theirsig.sighash_type = SIGHASH_ALL;
|
|
if (!fromwire_funding_created(msg, &id_in,
|
|
&state->funding_txid,
|
|
&state->funding_txout,
|
|
&theirsig.s))
|
|
peer_failed_err(state->pps, &state->channel_id,
|
|
"Parsing funding_created");
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The `temporary_channel_id` MUST be the same as the
|
|
* `temporary_channel_id` in the `open_channel` message.
|
|
*/
|
|
if (!channel_id_eq(&id_in, &state->channel_id))
|
|
peer_failed_err(state->pps, &id_in,
|
|
"funding_created ids don't match: sent %s got %s",
|
|
type_to_string(msg, struct channel_id,
|
|
&state->channel_id),
|
|
type_to_string(msg, struct channel_id, &id_in));
|
|
|
|
/* Now we can create the channel structure. */
|
|
state->channel = new_initial_channel(state,
|
|
&state->channel_id,
|
|
&state->funding_txid,
|
|
state->funding_txout,
|
|
state->minimum_depth,
|
|
state->funding,
|
|
state->push_msat,
|
|
take(new_fee_states(NULL, REMOTE,
|
|
&state->feerate_per_kw)),
|
|
&state->localconf,
|
|
&state->remoteconf,
|
|
&state->our_points, &theirs,
|
|
&state->our_funding_pubkey,
|
|
&their_funding_pubkey,
|
|
state->option_static_remotekey,
|
|
state->option_anchor_outputs,
|
|
REMOTE);
|
|
/* We don't expect this to fail, but it does do some additional
|
|
* internal sanity checks. */
|
|
if (!state->channel)
|
|
peer_failed_err(state->pps, &state->channel_id,
|
|
"We could not create channel with given config");
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* The recipient:
|
|
* - if `signature` is incorrect OR non-compliant with LOW-S-standard
|
|
* rule...:
|
|
* - MUST fail the channel.
|
|
*/
|
|
local_commit = initial_channel_tx(state, &wscript, state->channel,
|
|
&state->first_per_commitment_point[LOCAL],
|
|
LOCAL, NULL, &err_reason);
|
|
/* This shouldn't happen either, AFAICT. */
|
|
if (!local_commit) {
|
|
negotiation_failed(state, false,
|
|
"Could not meet our fees and reserve: %s", err_reason);
|
|
return NULL;
|
|
}
|
|
|
|
if (!check_tx_sig(local_commit, 0, NULL, wscript, &their_funding_pubkey,
|
|
&theirsig)) {
|
|
/* BOLT #1:
|
|
*
|
|
* ### The `error` Message
|
|
*...
|
|
* - when failure was caused by an invalid signature check:
|
|
* - SHOULD include the raw, hex-encoded transaction in reply
|
|
* to a `funding_created`, `funding_signed`,
|
|
* `closing_signed`, or `commitment_signed` message.
|
|
*/
|
|
/*~ This verbosity is not only useful for our own testing, but
|
|
* a courtesy to other implementaters whose brains may be so
|
|
* twisted by coding in Go, Scala and Rust that they can no
|
|
* longer read C code. */
|
|
peer_failed_err(state->pps, &state->channel_id,
|
|
"Bad signature %s on tx %s using key %s",
|
|
type_to_string(tmpctx, struct bitcoin_signature,
|
|
&theirsig),
|
|
type_to_string(tmpctx, struct bitcoin_tx, local_commit),
|
|
type_to_string(tmpctx, struct pubkey,
|
|
&their_funding_pubkey));
|
|
}
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* This message introduces the `channel_id` to identify the
|
|
* channel. It's derived from the funding transaction by combining the
|
|
* `funding_txid` and the `funding_output_index`, using big-endian
|
|
* exclusive-OR (i.e. `funding_output_index` alters the last 2 bytes).
|
|
*/
|
|
derive_channel_id(&state->channel_id,
|
|
&state->funding_txid, state->funding_txout);
|
|
|
|
/*~ We generate the `funding_signed` message here, since we have all
|
|
* the data and it's only applicable in the fundee case.
|
|
*
|
|
* FIXME: Perhaps we should have channeld generate this, so we
|
|
* can't possibly send before channel committed to disk?
|
|
*/
|
|
|
|
/* BOLT #2:
|
|
*
|
|
* ### The `funding_signed` Message
|
|
*
|
|
* This message gives the funder the signature it needs for the first
|
|
* commitment transaction, so it can broadcast the transaction knowing
|
|
* that funds can be redeemed, if need be.
|
|
*/
|
|
remote_commit = initial_channel_tx(state, &wscript, state->channel,
|
|
&state->first_per_commitment_point[REMOTE],
|
|
REMOTE, direct_outputs, &err_reason);
|
|
if (!remote_commit) {
|
|
negotiation_failed(state, false,
|
|
"Could not meet their fees and reserve: %s", err_reason);
|
|
return NULL;
|
|
}
|
|
|
|
/* Make HSM sign it */
|
|
msg = towire_hsmd_sign_remote_commitment_tx(NULL,
|
|
remote_commit,
|
|
&state->channel->funding_pubkey[REMOTE],
|
|
&state->first_per_commitment_point[REMOTE],
|
|
state->channel->option_static_remotekey);
|
|
|
|
wire_sync_write(HSM_FD, take(msg));
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
|
if (!fromwire_hsmd_sign_tx_reply(msg, &sig))
|
|
status_failed(STATUS_FAIL_HSM_IO,
|
|
"Bad sign_tx_reply %s", tal_hex(tmpctx, msg));
|
|
|
|
/* We don't send this ourselves: channeld does, because master needs
|
|
* to save state to disk before doing so. */
|
|
assert(sig.sighash_type == SIGHASH_ALL);
|
|
msg = towire_funding_signed(state, &state->channel_id, &sig.s);
|
|
|
|
if (direct_outputs[LOCAL] != NULL)
|
|
pbase = penalty_base_new(tmpctx, 0, remote_commit,
|
|
direct_outputs[LOCAL]);
|
|
else
|
|
pbase = NULL;
|
|
|
|
return towire_openingd_fundee(state,
|
|
&state->remoteconf,
|
|
local_commit,
|
|
pbase,
|
|
&theirsig,
|
|
state->pps,
|
|
&theirs.revocation,
|
|
&theirs.payment,
|
|
&theirs.htlc,
|
|
&theirs.delayed_payment,
|
|
&state->first_per_commitment_point[REMOTE],
|
|
&their_funding_pubkey,
|
|
&state->funding_txid,
|
|
state->funding_txout,
|
|
state->funding,
|
|
state->push_msat,
|
|
channel_flags,
|
|
state->feerate_per_kw,
|
|
msg,
|
|
state->localconf.channel_reserve,
|
|
state->upfront_shutdown_script[LOCAL],
|
|
state->upfront_shutdown_script[REMOTE]);
|
|
}
|
|
|
|
/*~ Standard "peer sent a message, handle it" demuxer. Though it really only
|
|
* handles one message, we use the standard form as principle of least
|
|
* surprise. */
|
|
static u8 *handle_peer_in(struct state *state)
|
|
{
|
|
u8 *msg = sync_crypto_read(tmpctx, state->pps);
|
|
enum peer_wire t = fromwire_peektype(msg);
|
|
struct channel_id channel_id;
|
|
|
|
if (t == WIRE_OPEN_CHANNEL)
|
|
return fundee_channel(state, msg);
|
|
|
|
#if DEVELOPER
|
|
/* Handle custommsgs */
|
|
enum peer_wire type = fromwire_peektype(msg);
|
|
if (type % 2 == 1 && !peer_wire_is_defined(type)) {
|
|
/* The message is not part of the messages we know how to
|
|
* handle. Assuming this is a custommsg, we just forward it to the
|
|
* master. */
|
|
wire_sync_write(REQ_FD, take(towire_custommsg_in(NULL, msg)));
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
/* Handles standard cases, and legal unknown ones. */
|
|
if (handle_peer_gossip_or_error(state->pps,
|
|
&state->channel_id, false, msg))
|
|
return NULL;
|
|
|
|
if (extract_channel_id(msg, &channel_id)) {
|
|
sync_crypto_write(state->pps,
|
|
take(towire_errorfmt(NULL,
|
|
&channel_id,
|
|
"Unexpected message %s: %s",
|
|
peer_wire_name(t),
|
|
tal_hex(tmpctx, msg))));
|
|
} else {
|
|
sync_crypto_write(state->pps,
|
|
take(towire_warningfmt(NULL,
|
|
NULL,
|
|
"Unexpected message %s: %s",
|
|
peer_wire_name(t),
|
|
tal_hex(tmpctx, msg))));
|
|
}
|
|
|
|
/* FIXME: We don't actually want master to try to send an
|
|
* error, since peer is transient. This is a hack.
|
|
*/
|
|
status_broken("Unexpected message %s", peer_wire_name(t));
|
|
peer_failed_connection_lost();
|
|
}
|
|
|
|
/*~ If we see the gossip_fd readable, we read a whole message. Sure, we might
|
|
* block, but we trust gossipd. */
|
|
static void handle_gossip_in(struct state *state)
|
|
{
|
|
u8 *msg = wire_sync_read(NULL, state->pps->gossip_fd);
|
|
|
|
if (!msg)
|
|
status_failed(STATUS_FAIL_GOSSIP_IO,
|
|
"Reading gossip: %s", strerror(errno));
|
|
|
|
handle_gossip_msg(state->pps, take(msg));
|
|
}
|
|
|
|
/* Memory leak detection is DEVELOPER-only because we go to great lengths to
|
|
* record the backtrace when allocations occur: without that, the leak
|
|
* detection tends to be useless for diagnosing where the leak came from, but
|
|
* it has significant overhead. */
|
|
#if DEVELOPER
|
|
static void handle_dev_memleak(struct state *state, const u8 *msg)
|
|
{
|
|
struct htable *memtable;
|
|
bool found_leak;
|
|
|
|
/* Populate a hash table with all our allocations (except msg, which
|
|
* is in use right now). */
|
|
memtable = memleak_find_allocations(tmpctx, msg, msg);
|
|
|
|
/* Now delete state and things it has pointers to. */
|
|
memleak_remove_region(memtable, state, sizeof(*state));
|
|
|
|
/* If there's anything left, dump it to logs, and return true. */
|
|
found_leak = dump_memleak(memtable);
|
|
wire_sync_write(REQ_FD,
|
|
take(towire_openingd_dev_memleak_reply(NULL,
|
|
found_leak)));
|
|
}
|
|
|
|
/* We were told to send a custommsg to the peer by `lightningd`. All the
|
|
* verification is done on the side of `lightningd` so we should be good to
|
|
* just forward it here. */
|
|
static void openingd_send_custommsg(struct state *state, const u8 *msg)
|
|
{
|
|
u8 *inner;
|
|
if (!fromwire_custommsg_out(tmpctx, msg, &inner))
|
|
master_badmsg(WIRE_CUSTOMMSG_OUT, msg);
|
|
sync_crypto_write(state->pps, take(inner));
|
|
}
|
|
#endif /* DEVELOPER */
|
|
|
|
/* Standard lightningd-fd-is-ready-to-read demux code. Again, we could hang
|
|
* here, but if we can't trust our parent, who can we trust? */
|
|
static u8 *handle_master_in(struct state *state)
|
|
{
|
|
u8 *msg = wire_sync_read(tmpctx, REQ_FD);
|
|
enum openingd_wire t = fromwire_peektype(msg);
|
|
u8 channel_flags;
|
|
struct bitcoin_txid funding_txid;
|
|
u16 funding_txout;
|
|
|
|
switch (t) {
|
|
case WIRE_OPENINGD_FUNDER_START:
|
|
if (!fromwire_openingd_funder_start(state, msg, &state->funding,
|
|
&state->push_msat,
|
|
&state->upfront_shutdown_script[LOCAL],
|
|
&state->feerate_per_kw,
|
|
&channel_flags))
|
|
master_badmsg(WIRE_OPENINGD_FUNDER_START, msg);
|
|
msg = funder_channel_start(state, channel_flags);
|
|
|
|
/* We want to keep openingd alive, since we're not done yet */
|
|
if (msg)
|
|
wire_sync_write(REQ_FD, take(msg));
|
|
return NULL;
|
|
case WIRE_OPENINGD_FUNDER_COMPLETE:
|
|
if (!fromwire_openingd_funder_complete(msg,
|
|
&funding_txid,
|
|
&funding_txout))
|
|
master_badmsg(WIRE_OPENINGD_FUNDER_COMPLETE, msg);
|
|
state->funding_txid = funding_txid;
|
|
state->funding_txout = funding_txout;
|
|
return funder_channel_complete(state);
|
|
case WIRE_OPENINGD_FUNDER_CANCEL:
|
|
/* We're aborting this, simple */
|
|
if (!fromwire_openingd_funder_cancel(msg))
|
|
master_badmsg(WIRE_OPENINGD_FUNDER_CANCEL, msg);
|
|
|
|
msg = towire_errorfmt(NULL, &state->channel_id, "Channel open canceled by us");
|
|
sync_crypto_write(state->pps, take(msg));
|
|
negotiation_aborted(state, true, "Channel open canceled by RPC");
|
|
return NULL;
|
|
case WIRE_OPENINGD_DEV_MEMLEAK:
|
|
#if DEVELOPER
|
|
handle_dev_memleak(state, msg);
|
|
return NULL;
|
|
#endif
|
|
case WIRE_OPENINGD_DEV_MEMLEAK_REPLY:
|
|
case WIRE_OPENINGD_INIT:
|
|
case WIRE_OPENINGD_FUNDER_REPLY:
|
|
case WIRE_OPENINGD_FUNDER_START_REPLY:
|
|
case WIRE_OPENINGD_FUNDEE:
|
|
case WIRE_OPENINGD_FUNDER_FAILED:
|
|
case WIRE_OPENINGD_GOT_OFFER:
|
|
case WIRE_OPENINGD_GOT_OFFER_REPLY:
|
|
break;
|
|
}
|
|
|
|
/* Now handle common messages. */
|
|
switch ((enum common_wire)t) {
|
|
#if DEVELOPER
|
|
case WIRE_CUSTOMMSG_OUT:
|
|
openingd_send_custommsg(state, msg);
|
|
return NULL;
|
|
#else
|
|
case WIRE_CUSTOMMSG_OUT:
|
|
#endif
|
|
/* We send these. */
|
|
case WIRE_CUSTOMMSG_IN:
|
|
break;
|
|
}
|
|
|
|
status_failed(STATUS_FAIL_MASTER_IO,
|
|
"Unknown msg %s", tal_hex(tmpctx, msg));
|
|
}
|
|
|
|
static void try_read_gossip_store(struct state *state)
|
|
{
|
|
u8 *msg = gossip_store_next(tmpctx, state->pps);
|
|
|
|
if (msg)
|
|
sync_crypto_write(state->pps, take(msg));
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
setup_locale();
|
|
|
|
u8 *msg;
|
|
struct pollfd pollfd[3];
|
|
struct state *state = tal(NULL, struct state);
|
|
struct secret *none;
|
|
struct channel_id *force_tmp_channel_id;
|
|
|
|
subdaemon_setup(argc, argv);
|
|
|
|
/*~ This makes status_failed, status_debug etc work synchronously by
|
|
* writing to REQ_FD */
|
|
status_setup_sync(REQ_FD);
|
|
|
|
/*~ The very first thing we read from lightningd is our init msg */
|
|
msg = wire_sync_read(tmpctx, REQ_FD);
|
|
if (!fromwire_openingd_init(state, msg,
|
|
&chainparams,
|
|
&state->our_features,
|
|
&state->localconf,
|
|
&state->max_to_self_delay,
|
|
&state->min_effective_htlc_capacity,
|
|
&state->pps,
|
|
&state->our_points,
|
|
&state->our_funding_pubkey,
|
|
&state->minimum_depth,
|
|
&state->min_feerate, &state->max_feerate,
|
|
&state->their_features,
|
|
&state->option_static_remotekey,
|
|
&state->option_anchor_outputs,
|
|
&force_tmp_channel_id,
|
|
&dev_fast_gossip))
|
|
master_badmsg(WIRE_OPENINGD_INIT, msg);
|
|
|
|
#if DEVELOPER
|
|
dev_force_tmp_channel_id = force_tmp_channel_id;
|
|
#endif
|
|
|
|
/* 3 == peer, 4 == gossipd, 5 = gossip_store, 6 = hsmd */
|
|
per_peer_state_set_fds(state->pps, 3, 4, 5);
|
|
|
|
/*~ Initially we're not associated with a channel, but
|
|
* handle_peer_gossip_or_error compares this. */
|
|
memset(&state->channel_id, 0, sizeof(state->channel_id));
|
|
state->channel = NULL;
|
|
|
|
/*~ We set these to NULL, meaning no requirements on shutdown */
|
|
state->upfront_shutdown_script[LOCAL]
|
|
= state->upfront_shutdown_script[REMOTE]
|
|
= NULL;
|
|
|
|
/*~ We need an initial per-commitment point whether we're funding or
|
|
* they are, and lightningd has reserved a unique dbid for us already,
|
|
* so we might as well get the hsm daemon to generate it now. */
|
|
wire_sync_write(HSM_FD,
|
|
take(towire_hsmd_get_per_commitment_point(NULL, 0)));
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
|
if (!fromwire_hsmd_get_per_commitment_point_reply(tmpctx, msg,
|
|
&state->first_per_commitment_point[LOCAL],
|
|
&none))
|
|
status_failed(STATUS_FAIL_HSM_IO,
|
|
"Bad get_per_commitment_point_reply %s",
|
|
tal_hex(tmpctx, msg));
|
|
/*~ The HSM gives us the N-2'th per-commitment secret when we get the
|
|
* N'th per-commitment point. But since N=0, it won't give us one. */
|
|
assert(none == NULL);
|
|
|
|
/*~ Turns out this is useful for testing, to make sure we're ready. */
|
|
status_debug("Handed peer, entering loop");
|
|
|
|
/*~ We manually run a little poll() loop here. With only three fds */
|
|
pollfd[0].fd = REQ_FD;
|
|
pollfd[0].events = POLLIN;
|
|
pollfd[1].fd = state->pps->gossip_fd;
|
|
pollfd[1].events = POLLIN;
|
|
pollfd[2].fd = state->pps->peer_fd;
|
|
pollfd[2].events = POLLIN;
|
|
|
|
/* We exit when we get a conclusion to write to lightningd: either
|
|
* opening_funder_reply or opening_fundee. */
|
|
msg = NULL;
|
|
while (!msg) {
|
|
int t;
|
|
struct timerel trel;
|
|
if (time_to_next_gossip(state->pps, &trel))
|
|
t = time_to_msec(trel);
|
|
else
|
|
t = -1;
|
|
|
|
/*~ If we get a signal which aborts the poll() call, valgrind
|
|
* complains about revents being uninitialized. I'm not sure
|
|
* that's correct, but it's easy to be sure. */
|
|
pollfd[0].revents = pollfd[1].revents = pollfd[2].revents = 0;
|
|
|
|
poll(pollfd, ARRAY_SIZE(pollfd), t);
|
|
/* Subtle: handle_master_in can do its own poll loop, so
|
|
* don't try to service more than one fd per loop. */
|
|
/* First priority: messages from lightningd. */
|
|
if (pollfd[0].revents & POLLIN)
|
|
msg = handle_master_in(state);
|
|
/* Second priority: messages from peer. */
|
|
else if (pollfd[2].revents & POLLIN)
|
|
msg = handle_peer_in(state);
|
|
/* Last priority: chit-chat from gossipd. */
|
|
else if (pollfd[1].revents & POLLIN)
|
|
handle_gossip_in(state);
|
|
else
|
|
try_read_gossip_store(state);
|
|
|
|
/* Since we're the top-level event loop, we clean up */
|
|
clean_tmpctx();
|
|
}
|
|
|
|
/*~ Write message and hand back the peer fd and gossipd fd. This also
|
|
* means that if the peer or gossipd wrote us any messages we didn't
|
|
* read yet, it will simply be read by the next daemon. */
|
|
wire_sync_write(REQ_FD, msg);
|
|
per_peer_state_fdpass_send(REQ_FD, state->pps);
|
|
status_debug("Sent %s with fds",
|
|
openingd_wire_name(fromwire_peektype(msg)));
|
|
|
|
/* This frees the entire tal tree. */
|
|
tal_free(state);
|
|
|
|
/* This frees up everything else. */
|
|
daemon_shutdown();
|
|
return 0;
|
|
}
|
|
|
|
/*~ Note that there are no other source files in openingd: it really is a fairly
|
|
* straight-line daemon.
|
|
*
|
|
* From here the channel is established: lightningd hands the peer off to
|
|
* channeld/channeld.c which runs the normal channel routine for this peer.
|
|
*/
|