lightningd/opening_control: routines to control openingd (move from peer_control.c)
We also fold opening_got_hsm_funding_sig() into the caller; it was previously a callback before we decided to always use the HSM synchronously. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
d2265cd3d2
commit
4cf274b1c0
|
@ -61,6 +61,7 @@ LIGHTNINGD_SRC := \
|
|||
lightningd/log.c \
|
||||
lightningd/log_status.c \
|
||||
lightningd/netaddress.c \
|
||||
lightningd/opening_control.c \
|
||||
lightningd/opt_time.c \
|
||||
lightningd/options.c \
|
||||
lightningd/pay.c \
|
||||
|
|
|
@ -0,0 +1,831 @@
|
|||
#include <bitcoin/privkey.h>
|
||||
#include <bitcoin/script.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/channel_config.h>
|
||||
#include <common/funding_tx.h>
|
||||
#include <common/key_derive.h>
|
||||
#include <common/wire_error.h>
|
||||
#include <errno.h>
|
||||
#include <gossipd/gen_gossip_wire.h>
|
||||
#include <hsmd/gen_hsm_client_wire.h>
|
||||
#include <lightningd/build_utxos.h>
|
||||
#include <lightningd/chaintopology.h>
|
||||
#include <lightningd/hsm_control.h>
|
||||
#include <lightningd/jsonrpc.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/opening_control.h>
|
||||
#include <lightningd/peer_control.h>
|
||||
#include <lightningd/subd.h>
|
||||
#include <openingd/gen_opening_wire.h>
|
||||
#include <wire/wire_sync.h>
|
||||
|
||||
/* Channel we're still opening. */
|
||||
struct uncommitted_channel {
|
||||
/* peer->uncommitted_channel == this */
|
||||
struct peer *peer;
|
||||
|
||||
/* openingd which is running now */
|
||||
struct subd *openingd;
|
||||
|
||||
/* Reserved dbid for if we become a real struct channel */
|
||||
u64 dbid;
|
||||
|
||||
/* For logging */
|
||||
struct log *log;
|
||||
|
||||
/* If we offered channel, this contains information, otherwise NULL */
|
||||
struct funding_channel *fc;
|
||||
|
||||
/* Secret seed (FIXME: Move to hsm!) */
|
||||
struct privkey seed;
|
||||
|
||||
/* Blockheight at creation, scans for funding confirmations
|
||||
* will start here */
|
||||
u64 first_blocknum;
|
||||
|
||||
/* These are *not* filled in by new_uncommitted_channel: */
|
||||
|
||||
/* Minimum funding depth (if funder == REMOTE). */
|
||||
u32 minimum_depth;
|
||||
|
||||
/* Our channel config. */
|
||||
struct channel_config our_config;
|
||||
};
|
||||
|
||||
struct funding_channel {
|
||||
struct command *cmd; /* Which also owns us. */
|
||||
|
||||
/* Peer we're trying to reach. */
|
||||
struct pubkey peerid;
|
||||
|
||||
/* Details of how to make funding. */
|
||||
const struct utxo **utxomap;
|
||||
u64 change;
|
||||
u32 change_keyindex;
|
||||
u64 funding_satoshi, push_msat;
|
||||
u8 channel_flags;
|
||||
|
||||
/* Channel. */
|
||||
struct uncommitted_channel *uc;
|
||||
};
|
||||
|
||||
/* Opening failed: hand back to gossipd (sending errpkt if not NULL) */
|
||||
static void uncommitted_channel_to_gossipd(struct lightningd *ld,
|
||||
struct uncommitted_channel *uc,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
int peer_fd, int gossip_fd,
|
||||
const u8 *errorpkt,
|
||||
const char *fmt,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
char *errstr;
|
||||
u8 *msg;
|
||||
|
||||
va_start(ap, fmt);
|
||||
errstr = tal_vfmt(uc, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
log_unusual(uc->log, "Opening channel: %s", errstr);
|
||||
if (uc->fc)
|
||||
command_fail(uc->fc->cmd, "%s", errstr);
|
||||
|
||||
/* Hand back to gossipd, (maybe) with an error packet to send. */
|
||||
msg = towire_gossipctl_hand_back_peer(errstr, &uc->peer->id, cs,
|
||||
gossip_index,
|
||||
errorpkt);
|
||||
subd_send_msg(ld->gossip, take(msg));
|
||||
subd_send_fd(ld->gossip, peer_fd);
|
||||
subd_send_fd(ld->gossip, gossip_fd);
|
||||
}
|
||||
|
||||
void kill_uncommitted_channel(struct uncommitted_channel *uc,
|
||||
const char *why)
|
||||
{
|
||||
log_info(uc->log, "Killing openingd: %s", why);
|
||||
|
||||
/* Close openingd. */
|
||||
subd_release_channel(uc->openingd, uc);
|
||||
|
||||
if (uc->fc)
|
||||
command_fail(uc->fc->cmd, "%s", why);
|
||||
tal_free(uc);
|
||||
}
|
||||
|
||||
void json_add_uncommitted_channel(struct json_result *response,
|
||||
const struct uncommitted_channel *uc)
|
||||
{
|
||||
if (!uc)
|
||||
return;
|
||||
|
||||
json_object_start(response, NULL);
|
||||
json_add_string(response, "state", "OPENINGD");
|
||||
json_add_string(response, "owner", "lightning_openingd");
|
||||
json_add_string(response, "funder",
|
||||
uc->fc ? "LOCAL" : "REMOTE");
|
||||
if (uc->fc) {
|
||||
u64 msatoshi_total, our_msatoshi;
|
||||
|
||||
msatoshi_total = uc->fc->funding_satoshi * 1000;
|
||||
our_msatoshi = msatoshi_total - uc->fc->push_msat;
|
||||
json_add_u64(response, "msatoshi_to_us", our_msatoshi);
|
||||
json_add_u64(response, "msatoshi_total", msatoshi_total);
|
||||
}
|
||||
json_object_end(response);
|
||||
}
|
||||
|
||||
/* Steals fields from uncommitted_channel */
|
||||
static struct channel *
|
||||
wallet_commit_channel(struct lightningd *ld,
|
||||
struct uncommitted_channel *uc,
|
||||
struct bitcoin_tx *remote_commit,
|
||||
secp256k1_ecdsa_signature *remote_commit_sig,
|
||||
const struct bitcoin_txid *funding_txid,
|
||||
u16 funding_outnum,
|
||||
u64 funding_satoshi,
|
||||
u64 push_msat,
|
||||
u8 channel_flags,
|
||||
struct channel_info *channel_info,
|
||||
u32 feerate)
|
||||
{
|
||||
struct channel *channel;
|
||||
u64 our_msatoshi;
|
||||
|
||||
if (uc->fc)
|
||||
our_msatoshi = funding_satoshi * 1000 - push_msat;
|
||||
else
|
||||
our_msatoshi = push_msat;
|
||||
|
||||
/* Feerates begin identical. */
|
||||
channel_info->feerate_per_kw[LOCAL]
|
||||
= channel_info->feerate_per_kw[REMOTE]
|
||||
= feerate;
|
||||
|
||||
/* old_remote_per_commit not valid yet, copy valid one. */
|
||||
channel_info->old_remote_per_commit = channel_info->remote_per_commit;
|
||||
|
||||
channel = new_channel(uc->peer, uc->dbid,
|
||||
NULL, /* No shachain yet */
|
||||
CHANNELD_AWAITING_LOCKIN,
|
||||
uc->fc ? LOCAL : REMOTE,
|
||||
uc->log,
|
||||
channel_flags,
|
||||
&uc->our_config,
|
||||
uc->minimum_depth,
|
||||
1, 1, 0,
|
||||
funding_txid,
|
||||
funding_outnum,
|
||||
funding_satoshi,
|
||||
push_msat,
|
||||
false, /* !remote_funding_locked */
|
||||
NULL, /* no scid yet */
|
||||
our_msatoshi,
|
||||
remote_commit,
|
||||
remote_commit_sig,
|
||||
NULL, /* No HTLC sigs yet */
|
||||
channel_info,
|
||||
NULL, /* No remote_shutdown_scriptpubkey yet */
|
||||
-1, false,
|
||||
NULL, /* No commit sent yet */
|
||||
uc->first_blocknum);
|
||||
|
||||
/* Now we finally put it in the database. */
|
||||
wallet_channel_insert(ld->wallet, channel);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void funding_broadcast_failed(struct channel *channel,
|
||||
int exitstatus, const char *err)
|
||||
{
|
||||
channel_internal_error(channel,
|
||||
"Funding broadcast exited with %i: %s",
|
||||
exitstatus, err);
|
||||
}
|
||||
|
||||
static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
||||
const int *fds,
|
||||
struct funding_channel *fc)
|
||||
{
|
||||
tal_t *tmpctx = tal_tmpctx(fc);
|
||||
u8 *msg, *linear;
|
||||
struct channel_info channel_info;
|
||||
struct bitcoin_tx *fundingtx;
|
||||
struct bitcoin_txid funding_txid, expected_txid;
|
||||
struct pubkey changekey;
|
||||
struct pubkey local_fundingkey;
|
||||
struct crypto_state cs;
|
||||
secp256k1_ecdsa_signature remote_commit_sig;
|
||||
struct bitcoin_tx *remote_commit;
|
||||
u16 funding_outnum;
|
||||
u64 gossip_index;
|
||||
u32 feerate;
|
||||
u64 change_satoshi;
|
||||
struct channel *channel;
|
||||
struct json_result *response;
|
||||
struct lightningd *ld = openingd->ld;
|
||||
|
||||
assert(tal_count(fds) == 2);
|
||||
|
||||
/* This is a new channel_info.their_config so set its ID to 0 */
|
||||
channel_info.their_config.id = 0;
|
||||
|
||||
if (!fromwire_opening_funder_reply(resp, resp, NULL,
|
||||
&channel_info.their_config,
|
||||
&remote_commit,
|
||||
&remote_commit_sig,
|
||||
&cs,
|
||||
&gossip_index,
|
||||
&channel_info.theirbase.revocation,
|
||||
&channel_info.theirbase.payment,
|
||||
&channel_info.theirbase.htlc,
|
||||
&channel_info.theirbase.delayed_payment,
|
||||
&channel_info.remote_per_commit,
|
||||
&fc->uc->minimum_depth,
|
||||
&channel_info.remote_fundingkey,
|
||||
&expected_txid,
|
||||
&feerate)) {
|
||||
log_broken(fc->uc->log,
|
||||
"bad OPENING_FUNDER_REPLY %s",
|
||||
tal_hex(resp, resp));
|
||||
command_fail(fc->cmd, "bad OPENING_FUNDER_REPLY %s",
|
||||
tal_hex(fc->cmd, resp));
|
||||
goto failed;
|
||||
}
|
||||
log_debug(ld->log,
|
||||
"%s", type_to_string(ltmp, struct pubkey,
|
||||
&channel_info.remote_per_commit));
|
||||
|
||||
/* Generate the funding tx. */
|
||||
if (fc->change
|
||||
&& !bip32_pubkey(ld->wallet->bip32_base,
|
||||
&changekey, fc->change_keyindex))
|
||||
fatal("Error deriving change key %u", fc->change_keyindex);
|
||||
|
||||
derive_basepoints(&fc->uc->seed, &local_fundingkey, NULL, NULL, NULL);
|
||||
|
||||
fundingtx = funding_tx(tmpctx, &funding_outnum,
|
||||
fc->utxomap, fc->funding_satoshi,
|
||||
&local_fundingkey,
|
||||
&channel_info.remote_fundingkey,
|
||||
fc->change, &changekey,
|
||||
ld->wallet->bip32_base);
|
||||
|
||||
log_debug(fc->uc->log, "Funding tx has %zi inputs, %zu outputs:",
|
||||
tal_count(fundingtx->input),
|
||||
tal_count(fundingtx->output));
|
||||
|
||||
for (size_t i = 0; i < tal_count(fundingtx->input); i++) {
|
||||
log_debug(fc->uc->log, "%zi: %"PRIu64" satoshi (%s) %s\n",
|
||||
i, fc->utxomap[i]->amount,
|
||||
fc->utxomap[i]->is_p2sh ? "P2SH" : "SEGWIT",
|
||||
type_to_string(ltmp, struct bitcoin_txid,
|
||||
&fundingtx->input[i].txid));
|
||||
}
|
||||
|
||||
bitcoin_txid(fundingtx, &funding_txid);
|
||||
|
||||
if (!structeq(&funding_txid, &expected_txid)) {
|
||||
log_broken(fc->uc->log,
|
||||
"Funding txid mismatch:"
|
||||
" satoshi %"PRIu64" change %"PRIu64
|
||||
" changeidx %u"
|
||||
" localkey %s remotekey %s",
|
||||
fc->funding_satoshi,
|
||||
fc->change, fc->change_keyindex,
|
||||
type_to_string(fc, struct pubkey,
|
||||
&local_fundingkey),
|
||||
type_to_string(fc, struct pubkey,
|
||||
&channel_info.remote_fundingkey));
|
||||
command_fail(fc->cmd,
|
||||
"Funding txid mismatch:"
|
||||
" satoshi %"PRIu64" change %"PRIu64
|
||||
" changeidx %u"
|
||||
" localkey %s remotekey %s",
|
||||
fc->funding_satoshi,
|
||||
fc->change, fc->change_keyindex,
|
||||
type_to_string(fc, struct pubkey,
|
||||
&local_fundingkey),
|
||||
type_to_string(fc, struct pubkey,
|
||||
&channel_info.remote_fundingkey));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Steals fields from uc */
|
||||
channel = wallet_commit_channel(ld, fc->uc,
|
||||
remote_commit,
|
||||
&remote_commit_sig,
|
||||
&funding_txid,
|
||||
funding_outnum,
|
||||
fc->funding_satoshi,
|
||||
fc->push_msat,
|
||||
fc->channel_flags,
|
||||
&channel_info,
|
||||
feerate);
|
||||
|
||||
/* Get HSM to sign the funding tx. */
|
||||
log_debug(channel->log, "Getting HSM to sign funding tx");
|
||||
|
||||
msg = towire_hsm_sign_funding(tmpctx, channel->funding_satoshi,
|
||||
fc->change, fc->change_keyindex,
|
||||
&local_fundingkey,
|
||||
&channel_info.remote_fundingkey,
|
||||
fc->utxomap);
|
||||
|
||||
if (!wire_sync_write(ld->hsm_fd, take(msg)))
|
||||
fatal("Could not write to HSM: %s", strerror(errno));
|
||||
|
||||
msg = hsm_sync_read(fc, ld);
|
||||
if (!fromwire_hsm_sign_funding_reply(tmpctx, msg, NULL, &fundingtx))
|
||||
fatal("HSM gave bad sign_funding_reply %s",
|
||||
tal_hex(msg, resp));
|
||||
|
||||
/* Extract the change output and add it to the DB */
|
||||
wallet_extract_owned_outputs(ld->wallet, fundingtx, &change_satoshi);
|
||||
|
||||
/* Send it out and watch for confirms. */
|
||||
broadcast_tx(ld->topology, channel, fundingtx, funding_broadcast_failed);
|
||||
|
||||
channel_watch_funding(ld, channel);
|
||||
|
||||
/* Start normal channel daemon. */
|
||||
peer_start_channeld(channel, &cs, gossip_index,
|
||||
fds[0], fds[1], NULL, false);
|
||||
|
||||
wallet_confirm_utxos(ld->wallet, fc->utxomap);
|
||||
|
||||
response = new_json_result(fc->cmd);
|
||||
json_object_start(response, NULL);
|
||||
linear = linearize_tx(response, fundingtx);
|
||||
json_add_hex(response, "tx", linear, tal_len(linear));
|
||||
json_add_txid(response, "txid", &channel->funding_txid);
|
||||
json_object_end(response);
|
||||
command_success(fc->cmd, response);
|
||||
|
||||
subd_release_channel(openingd, fc->uc);
|
||||
/* Frees fc too, and tmpctx */
|
||||
tal_free(fc->uc);
|
||||
return;
|
||||
|
||||
failed:
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
subd_release_channel(openingd, fc->uc);
|
||||
/* Frees fc too, and tmpctx */
|
||||
tal_free(fc->uc);
|
||||
}
|
||||
|
||||
static void opening_fundee_finished(struct subd *openingd,
|
||||
const u8 *reply,
|
||||
const int *fds,
|
||||
struct uncommitted_channel *uc)
|
||||
{
|
||||
u8 *funding_signed;
|
||||
struct channel_info channel_info;
|
||||
struct crypto_state cs;
|
||||
u64 gossip_index;
|
||||
secp256k1_ecdsa_signature remote_commit_sig;
|
||||
struct bitcoin_tx *remote_commit;
|
||||
const tal_t *tmpctx = tal_tmpctx(uc);
|
||||
struct lightningd *ld = openingd->ld;
|
||||
struct bitcoin_txid funding_txid;
|
||||
u16 funding_outnum;
|
||||
u64 funding_satoshi, push_msat;
|
||||
u32 feerate;
|
||||
u8 channel_flags;
|
||||
struct channel *channel;
|
||||
|
||||
log_debug(uc->log, "Got opening_fundee_finish_response");
|
||||
assert(tal_count(fds) == 2);
|
||||
|
||||
/* This is a new channel_info.their_config, set its ID to 0 */
|
||||
channel_info.their_config.id = 0;
|
||||
|
||||
if (!fromwire_opening_fundee_reply(tmpctx, reply, NULL,
|
||||
&channel_info.their_config,
|
||||
&remote_commit,
|
||||
&remote_commit_sig,
|
||||
&cs,
|
||||
&gossip_index,
|
||||
&channel_info.theirbase.revocation,
|
||||
&channel_info.theirbase.payment,
|
||||
&channel_info.theirbase.htlc,
|
||||
&channel_info.theirbase.delayed_payment,
|
||||
&channel_info.remote_per_commit,
|
||||
&channel_info.remote_fundingkey,
|
||||
&funding_txid,
|
||||
&funding_outnum,
|
||||
&funding_satoshi,
|
||||
&push_msat,
|
||||
&channel_flags,
|
||||
&feerate,
|
||||
&funding_signed)) {
|
||||
log_broken(uc->log, "bad OPENING_FUNDEE_REPLY %s",
|
||||
tal_hex(reply, reply));
|
||||
tal_free(uc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Consumes uc */
|
||||
channel = wallet_commit_channel(ld, uc,
|
||||
remote_commit,
|
||||
&remote_commit_sig,
|
||||
&funding_txid,
|
||||
funding_outnum,
|
||||
funding_satoshi,
|
||||
push_msat,
|
||||
channel_flags,
|
||||
&channel_info,
|
||||
feerate);
|
||||
|
||||
log_debug(channel->log, "Watching funding tx %s",
|
||||
type_to_string(reply, struct bitcoin_txid,
|
||||
&channel->funding_txid));
|
||||
|
||||
channel_watch_funding(ld, channel);
|
||||
|
||||
/* On to normal operation! */
|
||||
peer_start_channeld(channel, &cs, gossip_index,
|
||||
fds[0], fds[1], funding_signed, false);
|
||||
|
||||
subd_release_channel(openingd, uc);
|
||||
tal_free(uc);
|
||||
}
|
||||
|
||||
static void opening_channel_errmsg(struct uncommitted_channel *uc,
|
||||
int peer_fd, int gossip_fd,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const struct channel_id *channel_id,
|
||||
const char *desc,
|
||||
const u8 *err_for_them)
|
||||
{
|
||||
if (peer_fd == -1) {
|
||||
log_info(uc->log, "%s", desc);
|
||||
if (uc->fc)
|
||||
command_fail(uc->fc->cmd, "%s", desc);
|
||||
} else {
|
||||
/* An error occurred (presumably negotiation fail). */
|
||||
const char *errsrc = err_for_them ? "sent" : "received";
|
||||
|
||||
uncommitted_channel_to_gossipd(uc->peer->ld, uc,
|
||||
cs, gossip_index,
|
||||
peer_fd, gossip_fd,
|
||||
err_for_them,
|
||||
"%s ERROR %s", errsrc, desc);
|
||||
}
|
||||
tal_free(uc);
|
||||
}
|
||||
|
||||
static void destroy_uncommitted_channel(struct uncommitted_channel *uc)
|
||||
{
|
||||
uc->peer->uncommitted_channel = NULL;
|
||||
|
||||
/* Last one out frees */
|
||||
if (list_empty(&uc->peer->channels))
|
||||
delete_peer(uc->peer);
|
||||
}
|
||||
|
||||
/* Returns NULL if there's already an opening or active channel for this peer */
|
||||
static struct uncommitted_channel *
|
||||
new_uncommitted_channel(struct lightningd *ld,
|
||||
struct funding_channel *fc,
|
||||
const struct pubkey *peer_id,
|
||||
const struct wireaddr *addr)
|
||||
{
|
||||
struct uncommitted_channel *uc = tal(ld, struct uncommitted_channel);
|
||||
char *idname;
|
||||
|
||||
/* We make a new peer if necessary. */
|
||||
uc->peer = peer_by_id(ld, peer_id);
|
||||
if (!uc->peer)
|
||||
uc->peer = new_peer(ld, 0, peer_id, addr);
|
||||
|
||||
if (uc->peer->uncommitted_channel)
|
||||
return tal_free(uc);
|
||||
|
||||
if (peer_active_channel(uc->peer))
|
||||
return tal_free(uc);
|
||||
|
||||
uc->dbid = wallet_get_channel_dbid(ld->wallet);
|
||||
|
||||
idname = type_to_string(uc, struct pubkey, &uc->peer->id);
|
||||
uc->log = new_log(uc, uc->peer->log_book, "%s chan #%"PRIu64":",
|
||||
idname, uc->dbid);
|
||||
tal_free(idname);
|
||||
|
||||
uc->fc = fc;
|
||||
uc->first_blocknum = get_block_height(ld->topology);
|
||||
uc->our_config.id = 0;
|
||||
|
||||
derive_channel_seed(ld, &uc->seed, &uc->peer->id, uc->dbid);
|
||||
uc->peer->uncommitted_channel = uc;
|
||||
tal_add_destructor(uc, destroy_uncommitted_channel);
|
||||
|
||||
return uc;
|
||||
}
|
||||
|
||||
static void channel_config(struct lightningd *ld,
|
||||
struct channel_config *ours,
|
||||
u32 *max_to_self_delay,
|
||||
u32 *max_minimum_depth,
|
||||
u64 *min_effective_htlc_capacity_msat)
|
||||
{
|
||||
/* FIXME: depend on feerate. */
|
||||
*max_to_self_delay = ld->config.locktime_max;
|
||||
*max_minimum_depth = ld->config.anchor_confirms_max;
|
||||
/* This is 1c at $1000/BTC */
|
||||
*min_effective_htlc_capacity_msat = 1000000;
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The sender SHOULD set `dust_limit_satoshis` to a sufficient
|
||||
* value to allow commitment transactions to propagate through
|
||||
* the Bitcoin network.
|
||||
*/
|
||||
ours->dust_limit_satoshis = 546;
|
||||
ours->max_htlc_value_in_flight_msat = UINT64_MAX;
|
||||
|
||||
/* Don't care */
|
||||
ours->htlc_minimum_msat = 0;
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The sender SHOULD set `to_self_delay` sufficient to ensure
|
||||
* the sender can irreversibly spend a commitment transaction
|
||||
* output in case of misbehavior by the receiver.
|
||||
*/
|
||||
ours->to_self_delay = ld->config.locktime_blocks;
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* It MUST fail the channel if `max_accepted_htlcs` is greater than
|
||||
* 483.
|
||||
*/
|
||||
ours->max_accepted_htlcs = 483;
|
||||
|
||||
/* This is filled in by lightning_openingd, for consistency. */
|
||||
ours->channel_reserve_satoshis = 0;
|
||||
};
|
||||
|
||||
/* Peer has spontaneously exited from gossip due to open msg. Return
|
||||
* NULL if we took over, otherwise hand back to gossipd with this
|
||||
* error.
|
||||
*/
|
||||
u8 *peer_accept_channel(struct lightningd *ld,
|
||||
const struct pubkey *peer_id,
|
||||
const struct wireaddr *addr,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const u8 *gfeatures, const u8 *lfeatures,
|
||||
int peer_fd, int gossip_fd,
|
||||
const struct channel_id *channel_id,
|
||||
const u8 *open_msg)
|
||||
{
|
||||
u32 max_to_self_delay, max_minimum_depth;
|
||||
u64 min_effective_htlc_capacity_msat;
|
||||
u8 *msg;
|
||||
struct uncommitted_channel *uc;
|
||||
|
||||
assert(fromwire_peektype(open_msg) == WIRE_OPEN_CHANNEL);
|
||||
|
||||
/* Fails if there's already one */
|
||||
uc = new_uncommitted_channel(ld, NULL, peer_id, addr);
|
||||
if (!uc)
|
||||
return towire_errorfmt(open_msg, channel_id,
|
||||
"Multiple channels unsupported");
|
||||
|
||||
uc->openingd = new_channel_subd(ld, "lightning_openingd", uc, uc->log,
|
||||
opening_wire_type_name, NULL,
|
||||
opening_channel_errmsg,
|
||||
take(&peer_fd), take(&gossip_fd),
|
||||
NULL);
|
||||
if (!uc->openingd) {
|
||||
u8 *errpkt;
|
||||
char *errmsg;
|
||||
|
||||
errmsg = tal_fmt(uc, "INTERNAL ERROR:"
|
||||
" Failed to subdaemon opening: %s",
|
||||
strerror(errno));
|
||||
errpkt = towire_errorfmt(uc, channel_id, "%s", errmsg);
|
||||
|
||||
uncommitted_channel_to_gossipd(ld, uc,
|
||||
cs, gossip_index,
|
||||
peer_fd, gossip_fd,
|
||||
errpkt, "%s", errmsg);
|
||||
tal_free(uc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The sender SHOULD set `minimum_depth` to a number of blocks it
|
||||
* considers reasonable to avoid double-spending of the funding
|
||||
* transaction.
|
||||
*/
|
||||
uc->minimum_depth = ld->config.anchor_confirms;
|
||||
|
||||
channel_config(ld, &uc->our_config,
|
||||
&max_to_self_delay, &max_minimum_depth,
|
||||
&min_effective_htlc_capacity_msat);
|
||||
|
||||
msg = towire_opening_init(uc, get_chainparams(ld)->index,
|
||||
&uc->our_config,
|
||||
max_to_self_delay,
|
||||
min_effective_htlc_capacity_msat,
|
||||
cs, gossip_index, &uc->seed);
|
||||
|
||||
subd_send_msg(uc->openingd, take(msg));
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* Given the variance in fees, and the fact that the transaction may
|
||||
* be spent in the future, it's a good idea for the fee payer to keep
|
||||
* a good margin, say 5x the expected fee requirement */
|
||||
msg = towire_opening_fundee(uc, uc->minimum_depth,
|
||||
get_feerate(ld->topology, FEERATE_SLOW),
|
||||
get_feerate(ld->topology, FEERATE_IMMEDIATE)
|
||||
* 5,
|
||||
open_msg);
|
||||
|
||||
subd_req(uc, uc->openingd, take(msg), -1, 2,
|
||||
opening_fundee_finished, uc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void peer_offer_channel(struct lightningd *ld,
|
||||
struct funding_channel *fc,
|
||||
const struct wireaddr *addr,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const u8 *gfeatures, const u8 *lfeatures,
|
||||
int peer_fd, int gossip_fd)
|
||||
{
|
||||
u8 *msg;
|
||||
u32 max_to_self_delay, max_minimum_depth;
|
||||
u64 min_effective_htlc_capacity_msat;
|
||||
|
||||
fc->uc = new_uncommitted_channel(ld, fc, &fc->peerid, addr);
|
||||
|
||||
/* We asked to release this peer, but another raced in? Corner case,
|
||||
* close this is easiest. */
|
||||
if (!fc->uc) {
|
||||
command_fail(fc->cmd, "Peer already active");
|
||||
close(peer_fd);
|
||||
close(gossip_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Channel now owns fc; if it dies, we free fc. */
|
||||
tal_steal(fc->uc, fc);
|
||||
|
||||
fc->uc->openingd = new_channel_subd(ld,
|
||||
"lightning_openingd", fc->uc, fc->uc->log,
|
||||
opening_wire_type_name, NULL,
|
||||
opening_channel_errmsg,
|
||||
take(&peer_fd), take(&gossip_fd),
|
||||
NULL);
|
||||
if (!fc->uc->openingd) {
|
||||
/* We don't send them an error packet: for them, nothing
|
||||
* happened! */
|
||||
uncommitted_channel_to_gossipd(ld, fc->uc, NULL,
|
||||
gossip_index,
|
||||
peer_fd, gossip_fd,
|
||||
NULL,
|
||||
"Failed to launch openingd: %s",
|
||||
strerror(errno));
|
||||
tal_free(fc->uc);
|
||||
return;
|
||||
}
|
||||
|
||||
channel_config(ld, &fc->uc->our_config,
|
||||
&max_to_self_delay, &max_minimum_depth,
|
||||
&min_effective_htlc_capacity_msat);
|
||||
|
||||
msg = towire_opening_init(fc,
|
||||
get_chainparams(ld)->index,
|
||||
&fc->uc->our_config,
|
||||
max_to_self_delay,
|
||||
min_effective_htlc_capacity_msat,
|
||||
cs, gossip_index, &fc->uc->seed);
|
||||
subd_send_msg(fc->uc->openingd, take(msg));
|
||||
|
||||
msg = towire_opening_funder(fc, fc->funding_satoshi,
|
||||
fc->push_msat,
|
||||
get_feerate(ld->topology, FEERATE_NORMAL),
|
||||
max_minimum_depth,
|
||||
fc->change, fc->change_keyindex,
|
||||
fc->channel_flags,
|
||||
fc->utxomap,
|
||||
ld->wallet->bip32_base);
|
||||
|
||||
subd_req(fc, fc->uc->openingd,
|
||||
take(msg), -1, 2, opening_funder_finished, fc);
|
||||
}
|
||||
|
||||
/* Peer has been released from gossip. Start opening. */
|
||||
static void gossip_peer_released(struct subd *gossip,
|
||||
const u8 *resp,
|
||||
const int *fds,
|
||||
struct funding_channel *fc)
|
||||
{
|
||||
struct lightningd *ld = gossip->ld;
|
||||
struct crypto_state cs;
|
||||
u64 gossip_index;
|
||||
u8 *gfeatures, *lfeatures;
|
||||
struct wireaddr addr;
|
||||
struct channel *c;
|
||||
struct uncommitted_channel *uc;
|
||||
|
||||
c = active_channel_by_id(ld, &fc->peerid, &uc);
|
||||
|
||||
if (!fromwire_gossipctl_release_peer_reply(fc, resp, NULL, &addr, &cs,
|
||||
&gossip_index,
|
||||
&gfeatures, &lfeatures)) {
|
||||
if (!fromwire_gossipctl_release_peer_replyfail(resp, NULL)) {
|
||||
fatal("Gossip daemon gave invalid reply %s",
|
||||
tal_hex(gossip, resp));
|
||||
}
|
||||
if (uc)
|
||||
command_fail(fc->cmd, "Peer already OPENING");
|
||||
else if (c)
|
||||
command_fail(fc->cmd, "Peer already %s",
|
||||
channel_state_name(c));
|
||||
else
|
||||
command_fail(fc->cmd, "Peer not connected");
|
||||
return;
|
||||
}
|
||||
assert(tal_count(fds) == 2);
|
||||
|
||||
/* Gossipd should guarantee peer is unique: we would have killed any
|
||||
* old connection when it was told us peer reconnected. */
|
||||
assert(!c);
|
||||
assert(!uc);
|
||||
|
||||
/* OK, offer peer a channel. */
|
||||
peer_offer_channel(ld, fc, &addr, &cs, gossip_index,
|
||||
gfeatures, lfeatures,
|
||||
fds[0], fds[1]);
|
||||
}
|
||||
|
||||
static void json_fund_channel(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
jsmntok_t *peertok, *satoshitok;
|
||||
struct funding_channel *fc = tal(cmd, struct funding_channel);
|
||||
u8 *msg;
|
||||
|
||||
if (!json_get_params(cmd, buffer, params,
|
||||
"id", &peertok,
|
||||
"satoshi", &satoshitok,
|
||||
NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fc->cmd = cmd;
|
||||
|
||||
if (!pubkey_from_hexstr(buffer + peertok->start,
|
||||
peertok->end - peertok->start, &fc->peerid)) {
|
||||
command_fail(cmd, "Could not parse id");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!json_tok_u64(buffer, satoshitok, &fc->funding_satoshi)) {
|
||||
command_fail(cmd, "Invalid satoshis");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fc->funding_satoshi > MAX_FUNDING_SATOSHI) {
|
||||
command_fail(cmd, "Funding satoshi must be <= %d",
|
||||
MAX_FUNDING_SATOSHI);
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: Support push_msat? */
|
||||
fc->push_msat = 0;
|
||||
fc->channel_flags = OUR_CHANNEL_FLAGS;
|
||||
|
||||
/* Try to do this now, so we know if insufficient funds. */
|
||||
/* FIXME: dustlimit */
|
||||
fc->utxomap = build_utxos(fc, cmd->ld, fc->funding_satoshi,
|
||||
get_feerate(cmd->ld->topology, FEERATE_NORMAL),
|
||||
600, BITCOIN_SCRIPTPUBKEY_P2WSH_LEN,
|
||||
&fc->change, &fc->change_keyindex);
|
||||
if (!fc->utxomap) {
|
||||
command_fail(cmd, "Cannot afford funding transaction");
|
||||
return;
|
||||
}
|
||||
|
||||
msg = towire_gossipctl_release_peer(cmd, &fc->peerid);
|
||||
subd_req(fc, cmd->ld->gossip, msg, -1, 2, gossip_peer_released, fc);
|
||||
command_still_pending(cmd);
|
||||
}
|
||||
|
||||
static const struct json_command fund_channel_command = {
|
||||
"fundchannel",
|
||||
json_fund_channel,
|
||||
"Fund channel with {id} using {satoshi} satoshis"
|
||||
};
|
||||
AUTODATA(json_command, &fund_channel_command);
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef LIGHTNING_LIGHTNINGD_OPENING_CONTROL_H
|
||||
#define LIGHTNING_LIGHTNINGD_OPENING_CONTROL_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
|
||||
struct channel_id;
|
||||
struct crypto_state;
|
||||
struct json_result;
|
||||
struct lightningd;
|
||||
struct pubkey;
|
||||
struct uncommitted_channel;
|
||||
struct wireaddr;
|
||||
|
||||
void json_add_uncommitted_channel(struct json_result *response,
|
||||
const struct uncommitted_channel *uc);
|
||||
|
||||
/* Peer has spontaneously exited from gossip due to open msg. Return
|
||||
* NULL if we took over, otherwise hand back to gossipd with this
|
||||
* error.
|
||||
*/
|
||||
u8 *peer_accept_channel(struct lightningd *ld,
|
||||
const struct pubkey *peer_id,
|
||||
const struct wireaddr *addr,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const u8 *gfeatures, const u8 *lfeatures,
|
||||
int peer_fd, int gossip_fd,
|
||||
const struct channel_id *channel_id,
|
||||
const u8 *open_msg);
|
||||
|
||||
|
||||
void kill_uncommitted_channel(struct uncommitted_channel *uc,
|
||||
const char *why);
|
||||
#endif /* LIGHTNING_LIGHTNINGD_OPENING_CONTROL_H */
|
|
@ -15,7 +15,6 @@
|
|||
#include <common/close_tx.h>
|
||||
#include <common/dev_disconnect.h>
|
||||
#include <common/features.h>
|
||||
#include <common/funding_tx.h>
|
||||
#include <common/initial_commit_tx.h>
|
||||
#include <common/key_derive.h>
|
||||
#include <common/status.h>
|
||||
|
@ -35,11 +34,11 @@
|
|||
#include <lightningd/jsonrpc.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/netaddress.h>
|
||||
#include <lightningd/opening_control.h>
|
||||
#include <lightningd/options.h>
|
||||
#include <lightningd/peer_htlcs.h>
|
||||
#include <onchaind/gen_onchain_wire.h>
|
||||
#include <onchaind/onchain_wire.h>
|
||||
#include <openingd/gen_opening_wire.h>
|
||||
#include <unistd.h>
|
||||
#include <wally_bip32.h>
|
||||
#include <wire/gen_onion_wire.h>
|
||||
|
@ -52,56 +51,6 @@ struct connect {
|
|||
struct command *cmd;
|
||||
};
|
||||
|
||||
/* Channel we're still opening. */
|
||||
struct uncommitted_channel {
|
||||
/* peer->uncommitted_channel == this */
|
||||
struct peer *peer;
|
||||
|
||||
/* openingd which is running now */
|
||||
struct subd *openingd;
|
||||
|
||||
/* Reserved dbid for if we become a real struct channel */
|
||||
u64 dbid;
|
||||
|
||||
/* For logging */
|
||||
struct log *log;
|
||||
|
||||
/* If we offered channel, this contains information, otherwise NULL */
|
||||
struct funding_channel *fc;
|
||||
|
||||
/* Secret seed (FIXME: Move to hsm!) */
|
||||
struct privkey seed;
|
||||
|
||||
/* Blockheight at creation, scans for funding confirmations
|
||||
* will start here */
|
||||
u64 first_blocknum;
|
||||
|
||||
/* These are *not* filled in by new_uncommitted_channel: */
|
||||
|
||||
/* Minimum funding depth (if funder == REMOTE). */
|
||||
u32 minimum_depth;
|
||||
|
||||
/* Our channel config. */
|
||||
struct channel_config our_config;
|
||||
};
|
||||
|
||||
struct funding_channel {
|
||||
struct command *cmd; /* Which also owns us. */
|
||||
|
||||
/* Peer we're trying to reach. */
|
||||
struct pubkey peerid;
|
||||
|
||||
/* Details of how to make funding. */
|
||||
const struct utxo **utxomap;
|
||||
u64 change;
|
||||
u32 change_keyindex;
|
||||
u64 funding_satoshi, push_msat;
|
||||
u8 channel_flags;
|
||||
|
||||
/* Channel. */
|
||||
struct uncommitted_channel *uc;
|
||||
};
|
||||
|
||||
/* FIXME: Reorder */
|
||||
static void copy_to_parent_log(const char *prefix,
|
||||
enum log_level level,
|
||||
|
@ -110,33 +59,11 @@ static void copy_to_parent_log(const char *prefix,
|
|||
const char *str,
|
||||
const u8 *io,
|
||||
struct log *parent_log);
|
||||
static void peer_offer_channel(struct lightningd *ld,
|
||||
struct funding_channel *fc,
|
||||
const struct wireaddr *addr,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const u8 *gfeatures, const u8 *lfeatures,
|
||||
int peer_fd, int gossip_fd);
|
||||
static 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);
|
||||
static void peer_start_closingd(struct channel *channel,
|
||||
struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
int peer_fd, int gossip_fd,
|
||||
bool reconnected);
|
||||
static u8 *peer_accept_channel(struct lightningd *ld,
|
||||
const struct pubkey *peer_id,
|
||||
const struct wireaddr *addr,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const u8 *gfeatures, const u8 *lfeatures,
|
||||
int peer_fd, int gossip_fd,
|
||||
const struct channel_id *channel_id,
|
||||
const u8 *open_msg);
|
||||
|
||||
static void destroy_peer(struct peer *peer)
|
||||
{
|
||||
|
@ -288,80 +215,6 @@ static void connect_failed(struct lightningd *ld, const struct pubkey *id,
|
|||
}
|
||||
}
|
||||
|
||||
/* Opening failed: hand back to gossipd (sending errpkt if not NULL) */
|
||||
static void uncommitted_channel_to_gossipd(struct lightningd *ld,
|
||||
struct uncommitted_channel *uc,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
int peer_fd, int gossip_fd,
|
||||
const u8 *errorpkt,
|
||||
const char *fmt,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
char *errstr;
|
||||
u8 *msg;
|
||||
|
||||
va_start(ap, fmt);
|
||||
errstr = tal_vfmt(uc, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
log_unusual(uc->log, "Opening channel: %s", errstr);
|
||||
if (uc->fc)
|
||||
command_fail(uc->fc->cmd, "%s", errstr);
|
||||
|
||||
/* Hand back to gossipd, (maybe) with an error packet to send. */
|
||||
msg = towire_gossipctl_hand_back_peer(errstr, &uc->peer->id, cs,
|
||||
gossip_index,
|
||||
errorpkt);
|
||||
subd_send_msg(ld->gossip, take(msg));
|
||||
subd_send_fd(ld->gossip, peer_fd);
|
||||
subd_send_fd(ld->gossip, gossip_fd);
|
||||
}
|
||||
|
||||
static void channel_config(struct lightningd *ld,
|
||||
struct channel_config *ours,
|
||||
u32 *max_to_self_delay,
|
||||
u32 *max_minimum_depth,
|
||||
u64 *min_effective_htlc_capacity_msat)
|
||||
{
|
||||
/* FIXME: depend on feerate. */
|
||||
*max_to_self_delay = ld->config.locktime_max;
|
||||
*max_minimum_depth = ld->config.anchor_confirms_max;
|
||||
/* This is 1c at $1000/BTC */
|
||||
*min_effective_htlc_capacity_msat = 1000000;
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The sender SHOULD set `dust_limit_satoshis` to a sufficient
|
||||
* value to allow commitment transactions to propagate through
|
||||
* the Bitcoin network.
|
||||
*/
|
||||
ours->dust_limit_satoshis = 546;
|
||||
ours->max_htlc_value_in_flight_msat = UINT64_MAX;
|
||||
|
||||
/* Don't care */
|
||||
ours->htlc_minimum_msat = 0;
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The sender SHOULD set `to_self_delay` sufficient to ensure
|
||||
* the sender can irreversibly spend a commitment transaction
|
||||
* output in case of misbehavior by the receiver.
|
||||
*/
|
||||
ours->to_self_delay = ld->config.locktime_blocks;
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* It MUST fail the channel if `max_accepted_htlcs` is greater than
|
||||
* 483.
|
||||
*/
|
||||
ours->max_accepted_htlcs = 483;
|
||||
|
||||
/* This is filled in by lightning_openingd, for consistency. */
|
||||
ours->channel_reserve_satoshis = 0;
|
||||
};
|
||||
|
||||
static void channel_errmsg(struct channel *channel,
|
||||
int peer_fd, int gossip_fd,
|
||||
const struct crypto_state *cs,
|
||||
|
@ -466,11 +319,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
|
|||
|
||||
/* Opening now? Kill it */
|
||||
if (uc) {
|
||||
log_info(uc->log, "Peer reconnected, killing openingd");
|
||||
|
||||
/* Close openingd. */
|
||||
subd_release_channel(uc->openingd, uc);
|
||||
tal_free(uc);
|
||||
kill_uncommitted_channel(uc, "Peer reconnected");
|
||||
goto return_to_gossipd;
|
||||
}
|
||||
|
||||
|
@ -854,26 +703,7 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg,
|
|||
}
|
||||
|
||||
json_array_start(response, "channels");
|
||||
if (p->uncommitted_channel) {
|
||||
const struct uncommitted_channel *uc
|
||||
= p->uncommitted_channel;
|
||||
json_object_start(response, NULL);
|
||||
json_add_string(response, "state", "OPENINGD");
|
||||
json_add_string(response, "owner", "lightning_openingd");
|
||||
json_add_string(response, "funder",
|
||||
uc->fc ? "LOCAL" : "REMOTE");
|
||||
if (uc->fc) {
|
||||
u64 msatoshi_total, our_msatoshi;
|
||||
|
||||
msatoshi_total = uc->fc->funding_satoshi * 1000;
|
||||
our_msatoshi = msatoshi_total - uc->fc->push_msat;
|
||||
json_add_u64(response, "msatoshi_to_us",
|
||||
our_msatoshi);
|
||||
json_add_u64(response, "msatoshi_total",
|
||||
msatoshi_total);
|
||||
}
|
||||
json_object_end(response);
|
||||
}
|
||||
json_add_uncommitted_channel(response, p->uncommitted_channel);
|
||||
|
||||
list_for_each(&p->channels, channel, list) {
|
||||
json_object_start(response, NULL);
|
||||
|
@ -1003,14 +833,6 @@ struct peer *peer_from_json(struct lightningd *ld,
|
|||
return peer_by_id(ld, &peerid);
|
||||
}
|
||||
|
||||
static void funding_broadcast_failed(struct channel *channel,
|
||||
int exitstatus, const char *err)
|
||||
{
|
||||
channel_internal_error(channel,
|
||||
"Funding broadcast exited with %i: %s",
|
||||
exitstatus, err);
|
||||
}
|
||||
|
||||
static enum watch_result funding_announce_cb(struct channel *channel,
|
||||
const struct bitcoin_tx *tx,
|
||||
unsigned int depth,
|
||||
|
@ -1606,48 +1428,14 @@ static enum watch_result funding_lockin_cb(struct channel *channel,
|
|||
return DELETE_WATCH;
|
||||
}
|
||||
|
||||
static void opening_got_hsm_funding_sig(struct channel *channel,
|
||||
struct command *cmd,
|
||||
const struct utxo **utxomap,
|
||||
int peer_fd, int gossip_fd,
|
||||
const u8 *resp,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index)
|
||||
void channel_watch_funding(struct lightningd *ld, struct channel *channel)
|
||||
{
|
||||
struct bitcoin_tx *tx;
|
||||
u8 *linear;
|
||||
u64 change_satoshi;
|
||||
struct json_result *response = new_json_result(cmd);
|
||||
struct lightningd *ld = channel->peer->ld;
|
||||
|
||||
if (!fromwire_hsm_sign_funding_reply(cmd, resp, NULL, &tx))
|
||||
fatal("HSM gave bad sign_funding_reply %s",
|
||||
tal_hex(cmd, resp));
|
||||
|
||||
/* Send it out and watch for confirms. */
|
||||
broadcast_tx(ld->topology, channel, tx, funding_broadcast_failed);
|
||||
watch_tx(channel, ld->topology, channel, tx, funding_lockin_cb, NULL);
|
||||
|
||||
/* Extract the change output and add it to the DB */
|
||||
wallet_extract_owned_outputs(ld->wallet, tx, &change_satoshi);
|
||||
|
||||
/* FIXME: Remove arg from cb? */
|
||||
watch_txid(channel, ld->topology, channel,
|
||||
&channel->funding_txid, funding_lockin_cb, NULL);
|
||||
watch_txo(channel, ld->topology, channel,
|
||||
&channel->funding_txid, channel->funding_outnum,
|
||||
funding_spent, NULL);
|
||||
|
||||
json_object_start(response, NULL);
|
||||
linear = linearize_tx(response, tx);
|
||||
json_add_hex(response, "tx", linear, tal_len(linear));
|
||||
json_add_txid(response, "txid", &channel->funding_txid);
|
||||
json_object_end(response);
|
||||
command_success(cmd, response);
|
||||
|
||||
/* Start normal channel daemon. */
|
||||
peer_start_channeld(channel, cs, gossip_index,
|
||||
peer_fd, gossip_fd, NULL, false);
|
||||
|
||||
wallet_confirm_utxos(ld->wallet, utxomap);
|
||||
}
|
||||
|
||||
/* We were informed by channeld that it announced the channel and sent
|
||||
|
@ -2084,12 +1872,12 @@ u32 feerate_max(struct lightningd *ld)
|
|||
return get_feerate(ld->topology, FEERATE_IMMEDIATE) * 5;
|
||||
}
|
||||
|
||||
static 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)
|
||||
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)
|
||||
{
|
||||
const tal_t *tmpctx = tal_tmpctx(channel);
|
||||
u8 *msg, *initmsg;
|
||||
|
@ -2213,630 +2001,6 @@ static bool peer_start_channeld(struct channel *channel,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Steals fields from uncommitted_channel */
|
||||
static struct channel *
|
||||
wallet_commit_channel(struct lightningd *ld,
|
||||
struct uncommitted_channel *uc,
|
||||
struct bitcoin_tx *remote_commit,
|
||||
secp256k1_ecdsa_signature *remote_commit_sig,
|
||||
const struct bitcoin_txid *funding_txid,
|
||||
u16 funding_outnum,
|
||||
u64 funding_satoshi,
|
||||
u64 push_msat,
|
||||
u8 channel_flags,
|
||||
struct channel_info *channel_info,
|
||||
u32 feerate)
|
||||
{
|
||||
struct channel *channel;
|
||||
u64 our_msatoshi;
|
||||
|
||||
if (uc->fc)
|
||||
our_msatoshi = funding_satoshi * 1000 - push_msat;
|
||||
else
|
||||
our_msatoshi = push_msat;
|
||||
|
||||
/* Feerates begin identical. */
|
||||
channel_info->feerate_per_kw[LOCAL]
|
||||
= channel_info->feerate_per_kw[REMOTE]
|
||||
= feerate;
|
||||
|
||||
/* old_remote_per_commit not valid yet, copy valid one. */
|
||||
channel_info->old_remote_per_commit = channel_info->remote_per_commit;
|
||||
|
||||
channel = new_channel(uc->peer, uc->dbid,
|
||||
NULL, /* No shachain yet */
|
||||
CHANNELD_AWAITING_LOCKIN,
|
||||
uc->fc ? LOCAL : REMOTE,
|
||||
uc->log,
|
||||
channel_flags,
|
||||
&uc->our_config,
|
||||
uc->minimum_depth,
|
||||
1, 1, 0,
|
||||
funding_txid,
|
||||
funding_outnum,
|
||||
funding_satoshi,
|
||||
push_msat,
|
||||
false, /* !remote_funding_locked */
|
||||
NULL, /* no scid yet */
|
||||
our_msatoshi,
|
||||
remote_commit,
|
||||
remote_commit_sig,
|
||||
NULL, /* No HTLC sigs yet */
|
||||
channel_info,
|
||||
NULL, /* No remote_shutdown_scriptpubkey yet */
|
||||
-1, false,
|
||||
NULL, /* No commit sent yet */
|
||||
uc->first_blocknum);
|
||||
|
||||
/* Now we finally put it in the database. */
|
||||
wallet_channel_insert(ld->wallet, channel);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
||||
const int *fds,
|
||||
struct funding_channel *fc)
|
||||
{
|
||||
tal_t *tmpctx = tal_tmpctx(fc);
|
||||
u8 *msg;
|
||||
struct channel_info channel_info;
|
||||
struct bitcoin_tx *fundingtx;
|
||||
struct bitcoin_txid funding_txid, expected_txid;
|
||||
struct pubkey changekey;
|
||||
struct pubkey local_fundingkey;
|
||||
struct crypto_state cs;
|
||||
secp256k1_ecdsa_signature remote_commit_sig;
|
||||
struct bitcoin_tx *remote_commit;
|
||||
u16 funding_outnum;
|
||||
u64 gossip_index;
|
||||
u32 feerate;
|
||||
struct channel *channel;
|
||||
struct lightningd *ld = openingd->ld;
|
||||
|
||||
assert(tal_count(fds) == 2);
|
||||
|
||||
/* This is a new channel_info.their_config so set its ID to 0 */
|
||||
channel_info.their_config.id = 0;
|
||||
|
||||
if (!fromwire_opening_funder_reply(resp, resp, NULL,
|
||||
&channel_info.their_config,
|
||||
&remote_commit,
|
||||
&remote_commit_sig,
|
||||
&cs,
|
||||
&gossip_index,
|
||||
&channel_info.theirbase.revocation,
|
||||
&channel_info.theirbase.payment,
|
||||
&channel_info.theirbase.htlc,
|
||||
&channel_info.theirbase.delayed_payment,
|
||||
&channel_info.remote_per_commit,
|
||||
&fc->uc->minimum_depth,
|
||||
&channel_info.remote_fundingkey,
|
||||
&expected_txid,
|
||||
&feerate)) {
|
||||
log_broken(fc->uc->log,
|
||||
"bad OPENING_FUNDER_REPLY %s",
|
||||
tal_hex(resp, resp));
|
||||
command_fail(fc->cmd, "bad OPENING_FUNDER_REPLY %s",
|
||||
tal_hex(fc->cmd, resp));
|
||||
goto failed;
|
||||
}
|
||||
log_debug(ld->log,
|
||||
"%s", type_to_string(ltmp, struct pubkey,
|
||||
&channel_info.remote_per_commit));
|
||||
|
||||
/* Generate the funding tx. */
|
||||
if (fc->change
|
||||
&& !bip32_pubkey(ld->wallet->bip32_base,
|
||||
&changekey, fc->change_keyindex))
|
||||
fatal("Error deriving change key %u", fc->change_keyindex);
|
||||
|
||||
derive_basepoints(&fc->uc->seed, &local_fundingkey, NULL, NULL, NULL);
|
||||
|
||||
fundingtx = funding_tx(tmpctx, &funding_outnum,
|
||||
fc->utxomap, fc->funding_satoshi,
|
||||
&local_fundingkey,
|
||||
&channel_info.remote_fundingkey,
|
||||
fc->change, &changekey,
|
||||
ld->wallet->bip32_base);
|
||||
|
||||
log_debug(fc->uc->log, "Funding tx has %zi inputs, %zu outputs:",
|
||||
tal_count(fundingtx->input),
|
||||
tal_count(fundingtx->output));
|
||||
|
||||
for (size_t i = 0; i < tal_count(fundingtx->input); i++) {
|
||||
log_debug(fc->uc->log, "%zi: %"PRIu64" satoshi (%s) %s\n",
|
||||
i, fc->utxomap[i]->amount,
|
||||
fc->utxomap[i]->is_p2sh ? "P2SH" : "SEGWIT",
|
||||
type_to_string(ltmp, struct bitcoin_txid,
|
||||
&fundingtx->input[i].txid));
|
||||
}
|
||||
|
||||
bitcoin_txid(fundingtx, &funding_txid);
|
||||
|
||||
if (!structeq(&funding_txid, &expected_txid)) {
|
||||
log_broken(fc->uc->log,
|
||||
"Funding txid mismatch:"
|
||||
" satoshi %"PRIu64" change %"PRIu64
|
||||
" changeidx %u"
|
||||
" localkey %s remotekey %s",
|
||||
fc->funding_satoshi,
|
||||
fc->change, fc->change_keyindex,
|
||||
type_to_string(fc, struct pubkey,
|
||||
&local_fundingkey),
|
||||
type_to_string(fc, struct pubkey,
|
||||
&channel_info.remote_fundingkey));
|
||||
command_fail(fc->cmd,
|
||||
"Funding txid mismatch:"
|
||||
" satoshi %"PRIu64" change %"PRIu64
|
||||
" changeidx %u"
|
||||
" localkey %s remotekey %s",
|
||||
fc->funding_satoshi,
|
||||
fc->change, fc->change_keyindex,
|
||||
type_to_string(fc, struct pubkey,
|
||||
&local_fundingkey),
|
||||
type_to_string(fc, struct pubkey,
|
||||
&channel_info.remote_fundingkey));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Steals fields from uc */
|
||||
channel = wallet_commit_channel(ld, fc->uc,
|
||||
remote_commit,
|
||||
&remote_commit_sig,
|
||||
&funding_txid,
|
||||
funding_outnum,
|
||||
fc->funding_satoshi,
|
||||
fc->push_msat,
|
||||
fc->channel_flags,
|
||||
&channel_info,
|
||||
feerate);
|
||||
|
||||
/* Get HSM to sign the funding tx. */
|
||||
log_debug(channel->log, "Getting HSM to sign funding tx");
|
||||
|
||||
msg = towire_hsm_sign_funding(tmpctx, channel->funding_satoshi,
|
||||
fc->change, fc->change_keyindex,
|
||||
&local_fundingkey,
|
||||
&channel_info.remote_fundingkey,
|
||||
fc->utxomap);
|
||||
|
||||
if (!wire_sync_write(ld->hsm_fd, take(msg)))
|
||||
fatal("Could not write to HSM: %s", strerror(errno));
|
||||
|
||||
tal_free(tmpctx);
|
||||
|
||||
msg = hsm_sync_read(fc, ld);
|
||||
opening_got_hsm_funding_sig(channel, fc->cmd, fc->utxomap,
|
||||
fds[0], fds[1], msg, &cs, gossip_index);
|
||||
|
||||
subd_release_channel(openingd, fc->uc);
|
||||
/* Frees fc too */
|
||||
tal_free(fc->uc);
|
||||
return;
|
||||
|
||||
failed:
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
subd_release_channel(openingd, fc->uc);
|
||||
/* Frees fc too */
|
||||
tal_free(fc->uc);
|
||||
}
|
||||
|
||||
static void opening_fundee_finished(struct subd *openingd,
|
||||
const u8 *reply,
|
||||
const int *fds,
|
||||
struct uncommitted_channel *uc)
|
||||
{
|
||||
u8 *funding_signed;
|
||||
struct channel_info channel_info;
|
||||
struct crypto_state cs;
|
||||
u64 gossip_index;
|
||||
secp256k1_ecdsa_signature remote_commit_sig;
|
||||
struct bitcoin_tx *remote_commit;
|
||||
const tal_t *tmpctx = tal_tmpctx(uc);
|
||||
struct lightningd *ld = openingd->ld;
|
||||
struct bitcoin_txid funding_txid;
|
||||
u16 funding_outnum;
|
||||
u64 funding_satoshi, push_msat;
|
||||
u32 feerate;
|
||||
u8 channel_flags;
|
||||
struct channel *channel;
|
||||
|
||||
log_debug(uc->log, "Got opening_fundee_finish_response");
|
||||
assert(tal_count(fds) == 2);
|
||||
|
||||
/* This is a new channel_info.their_config, set its ID to 0 */
|
||||
channel_info.their_config.id = 0;
|
||||
|
||||
if (!fromwire_opening_fundee_reply(tmpctx, reply, NULL,
|
||||
&channel_info.their_config,
|
||||
&remote_commit,
|
||||
&remote_commit_sig,
|
||||
&cs,
|
||||
&gossip_index,
|
||||
&channel_info.theirbase.revocation,
|
||||
&channel_info.theirbase.payment,
|
||||
&channel_info.theirbase.htlc,
|
||||
&channel_info.theirbase.delayed_payment,
|
||||
&channel_info.remote_per_commit,
|
||||
&channel_info.remote_fundingkey,
|
||||
&funding_txid,
|
||||
&funding_outnum,
|
||||
&funding_satoshi,
|
||||
&push_msat,
|
||||
&channel_flags,
|
||||
&feerate,
|
||||
&funding_signed)) {
|
||||
log_broken(uc->log, "bad OPENING_FUNDEE_REPLY %s",
|
||||
tal_hex(reply, reply));
|
||||
tal_free(uc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Consumes uc */
|
||||
channel = wallet_commit_channel(ld, uc,
|
||||
remote_commit,
|
||||
&remote_commit_sig,
|
||||
&funding_txid,
|
||||
funding_outnum,
|
||||
funding_satoshi,
|
||||
push_msat,
|
||||
channel_flags,
|
||||
&channel_info,
|
||||
feerate);
|
||||
|
||||
log_debug(channel->log, "Watching funding tx %s",
|
||||
type_to_string(reply, struct bitcoin_txid,
|
||||
&channel->funding_txid));
|
||||
watch_txid(channel, ld->topology, channel, &channel->funding_txid,
|
||||
funding_lockin_cb, NULL);
|
||||
|
||||
/* FIXME: Remove arg from cb? */
|
||||
watch_txo(channel, ld->topology, channel, &channel->funding_txid,
|
||||
channel->funding_outnum, funding_spent, NULL);
|
||||
|
||||
/* On to normal operation! */
|
||||
peer_start_channeld(channel, &cs, gossip_index,
|
||||
fds[0], fds[1], funding_signed, false);
|
||||
|
||||
subd_release_channel(openingd, uc);
|
||||
tal_free(uc);
|
||||
}
|
||||
|
||||
static void opening_channel_errmsg(struct uncommitted_channel *uc,
|
||||
int peer_fd, int gossip_fd,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const struct channel_id *channel_id,
|
||||
const char *desc,
|
||||
const u8 *err_for_them)
|
||||
{
|
||||
if (peer_fd == -1) {
|
||||
log_info(uc->log, "%s", desc);
|
||||
if (uc->fc)
|
||||
command_fail(uc->fc->cmd, "%s", desc);
|
||||
} else {
|
||||
/* An error occurred (presumably negotiation fail). */
|
||||
const char *errsrc = err_for_them ? "sent" : "received";
|
||||
|
||||
uncommitted_channel_to_gossipd(uc->peer->ld, uc,
|
||||
cs, gossip_index,
|
||||
peer_fd, gossip_fd,
|
||||
err_for_them,
|
||||
"%s ERROR %s", errsrc, desc);
|
||||
}
|
||||
tal_free(uc);
|
||||
}
|
||||
|
||||
static void destroy_uncommitted_channel(struct uncommitted_channel *uc)
|
||||
{
|
||||
uc->peer->uncommitted_channel = NULL;
|
||||
|
||||
/* Last one out frees */
|
||||
if (list_empty(&uc->peer->channels))
|
||||
delete_peer(uc->peer);
|
||||
}
|
||||
|
||||
/* Returns NULL if there's already an opening or active channel for this peer */
|
||||
static struct uncommitted_channel *
|
||||
new_uncommitted_channel(struct lightningd *ld,
|
||||
struct funding_channel *fc,
|
||||
const struct pubkey *peer_id,
|
||||
const struct wireaddr *addr)
|
||||
{
|
||||
struct uncommitted_channel *uc = tal(ld, struct uncommitted_channel);
|
||||
char *idname;
|
||||
|
||||
/* We make a new peer if necessary. */
|
||||
uc->peer = peer_by_id(ld, peer_id);
|
||||
if (!uc->peer)
|
||||
uc->peer = new_peer(ld, 0, peer_id, addr);
|
||||
|
||||
if (uc->peer->uncommitted_channel)
|
||||
return tal_free(uc);
|
||||
|
||||
if (peer_active_channel(uc->peer))
|
||||
return tal_free(uc);
|
||||
|
||||
uc->dbid = wallet_get_channel_dbid(ld->wallet);
|
||||
|
||||
idname = type_to_string(uc, struct pubkey, &uc->peer->id);
|
||||
uc->log = new_log(uc, uc->peer->log_book, "%s chan #%"PRIu64":",
|
||||
idname, uc->dbid);
|
||||
tal_free(idname);
|
||||
|
||||
uc->fc = fc;
|
||||
uc->first_blocknum = get_block_height(ld->topology);
|
||||
uc->our_config.id = 0;
|
||||
|
||||
derive_channel_seed(ld, &uc->seed, &uc->peer->id, uc->dbid);
|
||||
uc->peer->uncommitted_channel = uc;
|
||||
tal_add_destructor(uc, destroy_uncommitted_channel);
|
||||
|
||||
return uc;
|
||||
}
|
||||
|
||||
/* Peer has spontaneously exited from gossip due to open msg. Return
|
||||
* NULL if we took over, otherwise hand back to gossipd with this
|
||||
* error.
|
||||
*/
|
||||
static u8 *peer_accept_channel(struct lightningd *ld,
|
||||
const struct pubkey *peer_id,
|
||||
const struct wireaddr *addr,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const u8 *gfeatures, const u8 *lfeatures,
|
||||
int peer_fd, int gossip_fd,
|
||||
const struct channel_id *channel_id,
|
||||
const u8 *open_msg)
|
||||
{
|
||||
u32 max_to_self_delay, max_minimum_depth;
|
||||
u64 min_effective_htlc_capacity_msat;
|
||||
u8 *msg;
|
||||
struct uncommitted_channel *uc;
|
||||
|
||||
assert(fromwire_peektype(open_msg) == WIRE_OPEN_CHANNEL);
|
||||
|
||||
/* Fails if there's already one */
|
||||
uc = new_uncommitted_channel(ld, NULL, peer_id, addr);
|
||||
if (!uc)
|
||||
return towire_errorfmt(open_msg, channel_id,
|
||||
"Multiple channels unsupported");
|
||||
|
||||
uc->openingd = new_channel_subd(ld, "lightning_openingd", uc, uc->log,
|
||||
opening_wire_type_name, NULL,
|
||||
opening_channel_errmsg,
|
||||
take(&peer_fd), take(&gossip_fd),
|
||||
NULL);
|
||||
if (!uc->openingd) {
|
||||
u8 *errpkt;
|
||||
char *errmsg;
|
||||
|
||||
errmsg = tal_fmt(uc, "INTERNAL ERROR:"
|
||||
" Failed to subdaemon opening: %s",
|
||||
strerror(errno));
|
||||
errpkt = towire_errorfmt(uc, channel_id, "%s", errmsg);
|
||||
|
||||
uncommitted_channel_to_gossipd(ld, uc,
|
||||
cs, gossip_index,
|
||||
peer_fd, gossip_fd,
|
||||
errpkt, "%s", errmsg);
|
||||
tal_free(uc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The sender SHOULD set `minimum_depth` to a number of blocks it
|
||||
* considers reasonable to avoid double-spending of the funding
|
||||
* transaction.
|
||||
*/
|
||||
uc->minimum_depth = ld->config.anchor_confirms;
|
||||
|
||||
channel_config(ld, &uc->our_config,
|
||||
&max_to_self_delay, &max_minimum_depth,
|
||||
&min_effective_htlc_capacity_msat);
|
||||
|
||||
msg = towire_opening_init(uc, get_chainparams(ld)->index,
|
||||
&uc->our_config,
|
||||
max_to_self_delay,
|
||||
min_effective_htlc_capacity_msat,
|
||||
cs, gossip_index, &uc->seed);
|
||||
|
||||
subd_send_msg(uc->openingd, take(msg));
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* Given the variance in fees, and the fact that the transaction may
|
||||
* be spent in the future, it's a good idea for the fee payer to keep
|
||||
* a good margin, say 5x the expected fee requirement */
|
||||
msg = towire_opening_fundee(uc, uc->minimum_depth,
|
||||
get_feerate(ld->topology, FEERATE_SLOW),
|
||||
get_feerate(ld->topology, FEERATE_IMMEDIATE)
|
||||
* 5,
|
||||
open_msg);
|
||||
|
||||
subd_req(uc, uc->openingd, take(msg), -1, 2,
|
||||
opening_fundee_finished, uc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void peer_offer_channel(struct lightningd *ld,
|
||||
struct funding_channel *fc,
|
||||
const struct wireaddr *addr,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index,
|
||||
const u8 *gfeatures, const u8 *lfeatures,
|
||||
int peer_fd, int gossip_fd)
|
||||
{
|
||||
u8 *msg;
|
||||
u32 max_to_self_delay, max_minimum_depth;
|
||||
u64 min_effective_htlc_capacity_msat;
|
||||
|
||||
fc->uc = new_uncommitted_channel(ld, fc, &fc->peerid, addr);
|
||||
|
||||
/* We asked to release this peer, but another raced in? Corner case,
|
||||
* close this is easiest. */
|
||||
if (!fc->uc) {
|
||||
command_fail(fc->cmd, "Peer already active");
|
||||
close(peer_fd);
|
||||
close(gossip_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Channel now owns fc; if it dies, we free fc. */
|
||||
tal_steal(fc->uc, fc);
|
||||
|
||||
fc->uc->openingd = new_channel_subd(ld,
|
||||
"lightning_openingd", fc->uc, fc->uc->log,
|
||||
opening_wire_type_name, NULL,
|
||||
opening_channel_errmsg,
|
||||
take(&peer_fd), take(&gossip_fd),
|
||||
NULL);
|
||||
if (!fc->uc->openingd) {
|
||||
/* We don't send them an error packet: for them, nothing
|
||||
* happened! */
|
||||
uncommitted_channel_to_gossipd(ld, fc->uc, NULL,
|
||||
gossip_index,
|
||||
peer_fd, gossip_fd,
|
||||
NULL,
|
||||
"Failed to launch openingd: %s",
|
||||
strerror(errno));
|
||||
tal_free(fc->uc);
|
||||
return;
|
||||
}
|
||||
|
||||
channel_config(ld, &fc->uc->our_config,
|
||||
&max_to_self_delay, &max_minimum_depth,
|
||||
&min_effective_htlc_capacity_msat);
|
||||
|
||||
msg = towire_opening_init(fc,
|
||||
get_chainparams(ld)->index,
|
||||
&fc->uc->our_config,
|
||||
max_to_self_delay,
|
||||
min_effective_htlc_capacity_msat,
|
||||
cs, gossip_index, &fc->uc->seed);
|
||||
subd_send_msg(fc->uc->openingd, take(msg));
|
||||
|
||||
msg = towire_opening_funder(fc, fc->funding_satoshi,
|
||||
fc->push_msat,
|
||||
get_feerate(ld->topology, FEERATE_NORMAL),
|
||||
max_minimum_depth,
|
||||
fc->change, fc->change_keyindex,
|
||||
fc->channel_flags,
|
||||
fc->utxomap,
|
||||
ld->wallet->bip32_base);
|
||||
|
||||
subd_req(fc, fc->uc->openingd,
|
||||
take(msg), -1, 2, opening_funder_finished, fc);
|
||||
}
|
||||
|
||||
/* Peer has been released from gossip. Start opening. */
|
||||
static void gossip_peer_released(struct subd *gossip,
|
||||
const u8 *resp,
|
||||
const int *fds,
|
||||
struct funding_channel *fc)
|
||||
{
|
||||
struct lightningd *ld = gossip->ld;
|
||||
struct crypto_state cs;
|
||||
u64 gossip_index;
|
||||
u8 *gfeatures, *lfeatures;
|
||||
struct wireaddr addr;
|
||||
struct channel *c;
|
||||
struct uncommitted_channel *uc;
|
||||
|
||||
c = active_channel_by_id(ld, &fc->peerid, &uc);
|
||||
|
||||
if (!fromwire_gossipctl_release_peer_reply(fc, resp, NULL, &addr, &cs,
|
||||
&gossip_index,
|
||||
&gfeatures, &lfeatures)) {
|
||||
if (!fromwire_gossipctl_release_peer_replyfail(resp, NULL)) {
|
||||
fatal("Gossip daemon gave invalid reply %s",
|
||||
tal_hex(gossip, resp));
|
||||
}
|
||||
if (uc)
|
||||
command_fail(fc->cmd, "Peer already OPENING");
|
||||
else if (c)
|
||||
command_fail(fc->cmd, "Peer already %s",
|
||||
channel_state_name(c));
|
||||
else
|
||||
command_fail(fc->cmd, "Peer not connected");
|
||||
return;
|
||||
}
|
||||
assert(tal_count(fds) == 2);
|
||||
|
||||
/* Gossipd should guarantee peer is unique: we would have killed any
|
||||
* old connection when it was told us peer reconnected. */
|
||||
assert(!c);
|
||||
assert(!uc);
|
||||
|
||||
/* OK, offer peer a channel. */
|
||||
peer_offer_channel(ld, fc, &addr, &cs, gossip_index,
|
||||
gfeatures, lfeatures,
|
||||
fds[0], fds[1]);
|
||||
}
|
||||
|
||||
static void json_fund_channel(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
jsmntok_t *peertok, *satoshitok;
|
||||
struct funding_channel *fc = tal(cmd, struct funding_channel);
|
||||
u8 *msg;
|
||||
|
||||
if (!json_get_params(cmd, buffer, params,
|
||||
"id", &peertok,
|
||||
"satoshi", &satoshitok,
|
||||
NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fc->cmd = cmd;
|
||||
|
||||
if (!pubkey_from_hexstr(buffer + peertok->start,
|
||||
peertok->end - peertok->start, &fc->peerid)) {
|
||||
command_fail(cmd, "Could not parse id");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!json_tok_u64(buffer, satoshitok, &fc->funding_satoshi)) {
|
||||
command_fail(cmd, "Invalid satoshis");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fc->funding_satoshi > MAX_FUNDING_SATOSHI) {
|
||||
command_fail(cmd, "Funding satoshi must be <= %d",
|
||||
MAX_FUNDING_SATOSHI);
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: Support push_msat? */
|
||||
fc->push_msat = 0;
|
||||
fc->channel_flags = OUR_CHANNEL_FLAGS;
|
||||
|
||||
/* Try to do this now, so we know if insufficient funds. */
|
||||
/* FIXME: dustlimit */
|
||||
fc->utxomap = build_utxos(fc, cmd->ld, fc->funding_satoshi,
|
||||
get_feerate(cmd->ld->topology, FEERATE_NORMAL),
|
||||
600, BITCOIN_SCRIPTPUBKEY_P2WSH_LEN,
|
||||
&fc->change, &fc->change_keyindex);
|
||||
if (!fc->utxomap) {
|
||||
command_fail(cmd, "Cannot afford funding transaction");
|
||||
return;
|
||||
}
|
||||
|
||||
msg = towire_gossipctl_release_peer(cmd, &fc->peerid);
|
||||
subd_req(fc, cmd->ld->gossip, msg, -1, 2, gossip_peer_released, fc);
|
||||
command_still_pending(cmd);
|
||||
}
|
||||
|
||||
static const struct json_command fund_channel_command = {
|
||||
"fundchannel",
|
||||
json_fund_channel,
|
||||
"Fund channel with {id} using {satoshi} satoshis"
|
||||
};
|
||||
AUTODATA(json_command, &fund_channel_command);
|
||||
|
||||
static void json_close(struct command *cmd,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
|
@ -2861,14 +2025,8 @@ static void json_close(struct command *cmd,
|
|||
struct uncommitted_channel *uc = peer->uncommitted_channel;
|
||||
if (uc) {
|
||||
/* Easy case: peer can simply be forgotten. */
|
||||
log_info(uc->log, "close command called");
|
||||
kill_uncommitted_channel(uc, "close command called");
|
||||
|
||||
/* Close openingd. */
|
||||
subd_release_channel(uc->openingd, uc);
|
||||
if (uc->fc)
|
||||
command_fail(uc->fc->cmd,
|
||||
"close command called");
|
||||
tal_free(uc);
|
||||
command_success(cmd, null_response(cmd));
|
||||
return;
|
||||
}
|
||||
|
@ -2932,14 +2090,8 @@ static void activate_peer(struct peer *peer)
|
|||
}
|
||||
|
||||
list_for_each(&peer->channels, channel, list) {
|
||||
/* This may be unnecessary, but it's harmless. */
|
||||
watch_txid(channel, ld->topology, channel,
|
||||
&channel->funding_txid,
|
||||
funding_lockin_cb, NULL);
|
||||
|
||||
watch_txo(channel, ld->topology, channel,
|
||||
&channel->funding_txid, channel->funding_outnum,
|
||||
funding_spent, NULL);
|
||||
/* Watching lockin may be unnecessary, but it's harmless. */
|
||||
channel_watch_funding(ld, channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,4 +106,12 @@ void free_htlcs(struct lightningd *ld, const struct channel *channel);
|
|||
u32 feerate_min(struct lightningd *ld);
|
||||
u32 feerate_max(struct lightningd *ld);
|
||||
|
||||
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);
|
||||
|
||||
void channel_watch_funding(struct lightningd *ld, struct channel *channel);
|
||||
#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */
|
||||
|
|
|
@ -2448,7 +2448,7 @@ class LightningDTests(BaseLightningDTests):
|
|||
l1.rpc.connect(l2.info['id'], 'localhost', l2.info['port'])
|
||||
|
||||
# We should get a message about reconnecting.
|
||||
l2.daemon.wait_for_log('Peer reconnected, killing openingd')
|
||||
l2.daemon.wait_for_log('Killing openingd: Peer reconnected')
|
||||
|
||||
# Should work fine.
|
||||
l1.rpc.fundchannel(l2.info['id'], 20000)
|
||||
|
|
|
@ -47,13 +47,6 @@ void broadcast_tx(struct chain_topology *topo UNNEEDED,
|
|||
int exitstatus UNNEEDED,
|
||||
const char *err))
|
||||
{ fprintf(stderr, "broadcast_tx called!\n"); abort(); }
|
||||
/* Generated stub for build_utxos */
|
||||
const struct utxo **build_utxos(const tal_t *ctx UNNEEDED,
|
||||
struct lightningd *ld UNNEEDED, u64 satoshi_out UNNEEDED,
|
||||
u32 feerate_per_kw UNNEEDED, u64 dust_limit UNNEEDED,
|
||||
size_t outputscriptlen UNNEEDED,
|
||||
u64 *change_satoshis UNNEEDED, u32 *change_keyindex UNNEEDED)
|
||||
{ fprintf(stderr, "build_utxos called!\n"); abort(); }
|
||||
/* Generated stub for channel_wire_type_name */
|
||||
const char *channel_wire_type_name(int e UNNEEDED)
|
||||
{ fprintf(stderr, "channel_wire_type_name called!\n"); abort(); }
|
||||
|
@ -103,12 +96,6 @@ bool fromwire_closing_complete(const void *p UNNEEDED, size_t *plen UNNEEDED, u6
|
|||
/* Generated stub for fromwire_closing_received_signature */
|
||||
bool fromwire_closing_received_signature(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_closing_received_signature called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossipctl_release_peer_reply */
|
||||
bool fromwire_gossipctl_release_peer_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct wireaddr *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u64 *gossip_index UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossipctl_release_peer_reply called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossipctl_release_peer_replyfail */
|
||||
bool fromwire_gossipctl_release_peer_replyfail(const void *p UNNEEDED, size_t *plen UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossipctl_release_peer_replyfail called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_getpeers_reply */
|
||||
bool fromwire_gossip_getpeers_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct pubkey **id UNNEEDED, struct wireaddr **addr UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_getpeers_reply called!\n"); abort(); }
|
||||
|
@ -124,9 +111,6 @@ bool fromwire_gossip_peer_connection_failed(const void *p UNNEEDED, size_t *plen
|
|||
/* Generated stub for fromwire_hsm_client_hsmfd_reply */
|
||||
bool fromwire_hsm_client_hsmfd_reply(const void *p UNNEEDED, size_t *plen UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_hsm_client_hsmfd_reply called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_hsm_sign_funding_reply */
|
||||
bool fromwire_hsm_sign_funding_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_hsm_sign_funding_reply called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_onchain_add_utxo */
|
||||
bool fromwire_onchain_add_utxo(const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_txid *prev_out_tx UNNEEDED, u32 *prev_out_index UNNEEDED, struct pubkey *per_commit_point UNNEEDED, u64 *value UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_onchain_add_utxo called!\n"); abort(); }
|
||||
|
@ -148,26 +132,6 @@ bool fromwire_onchain_missing_htlc_output(const void *p UNNEEDED, size_t *plen U
|
|||
/* Generated stub for fromwire_onchain_unwatch_tx */
|
||||
bool fromwire_onchain_unwatch_tx(const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_txid *txid UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_onchain_unwatch_tx called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_opening_fundee_reply */
|
||||
bool fromwire_opening_fundee_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct channel_config *their_config UNNEEDED, struct bitcoin_tx **first_commit UNNEEDED, secp256k1_ecdsa_signature *first_commit_sig UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u64 *gossip_index UNNEEDED, struct pubkey *revocation_basepoint UNNEEDED, struct pubkey *payment_basepoint UNNEEDED, struct pubkey *htlc_basepoint UNNEEDED, struct pubkey *delayed_payment_basepoint UNNEEDED, struct pubkey *their_per_commit_point UNNEEDED, struct pubkey *remote_fundingkey UNNEEDED, struct bitcoin_txid *funding_txid UNNEEDED, u16 *funding_txout UNNEEDED, u64 *funding_satoshis UNNEEDED, u64 *push_msat UNNEEDED, u8 *channel_flags UNNEEDED, u32 *feerate_per_kw UNNEEDED, u8 **funding_signed_msg UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_opening_fundee_reply called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_opening_funder_reply */
|
||||
bool fromwire_opening_funder_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct channel_config *their_config UNNEEDED, struct bitcoin_tx **first_commit UNNEEDED, secp256k1_ecdsa_signature *first_commit_sig UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u64 *gossip_index UNNEEDED, struct pubkey *revocation_basepoint UNNEEDED, struct pubkey *payment_basepoint UNNEEDED, struct pubkey *htlc_basepoint UNNEEDED, struct pubkey *delayed_payment_basepoint UNNEEDED, struct pubkey *their_per_commit_point UNNEEDED, u32 *minimum_depth UNNEEDED, struct pubkey *remote_fundingkey UNNEEDED, struct bitcoin_txid *funding_txid UNNEEDED, u32 *feerate_per_kw UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_opening_funder_reply called!\n"); abort(); }
|
||||
/* Generated stub for funding_tx */
|
||||
struct bitcoin_tx *funding_tx(const tal_t *ctx UNNEEDED,
|
||||
u16 *outnum UNNEEDED,
|
||||
const struct utxo **utxomap UNNEEDED,
|
||||
u64 funding_satoshis UNNEEDED,
|
||||
const struct pubkey *local_fundingkey UNNEEDED,
|
||||
const struct pubkey *remote_fundingkey UNNEEDED,
|
||||
u64 change_satoshis UNNEEDED,
|
||||
const struct pubkey *changekey UNNEEDED,
|
||||
const struct ext_key *bip32_base UNNEEDED)
|
||||
{ fprintf(stderr, "funding_tx called!\n"); abort(); }
|
||||
/* Generated stub for get_block_height */
|
||||
u32 get_block_height(const struct chain_topology *topo UNNEEDED)
|
||||
{ fprintf(stderr, "get_block_height called!\n"); abort(); }
|
||||
/* Generated stub for get_chainparams */
|
||||
struct chainparams *get_chainparams(const struct lightningd *ld UNNEEDED)
|
||||
{ fprintf(stderr, "get_chainparams called!\n"); abort(); }
|
||||
|
@ -270,6 +234,10 @@ void json_add_txid(struct json_result *result UNNEEDED, const char *fieldname UN
|
|||
void json_add_u64(struct json_result *result UNNEEDED, const char *fieldname UNNEEDED,
|
||||
uint64_t value UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_u64 called!\n"); abort(); }
|
||||
/* Generated stub for json_add_uncommitted_channel */
|
||||
void json_add_uncommitted_channel(struct json_result *response UNNEEDED,
|
||||
const struct uncommitted_channel *uc UNNEEDED)
|
||||
{ fprintf(stderr, "json_add_uncommitted_channel called!\n"); abort(); }
|
||||
/* Generated stub for json_array_end */
|
||||
void json_array_end(struct json_result *ptr UNNEEDED)
|
||||
{ fprintf(stderr, "json_array_end called!\n"); abort(); }
|
||||
|
@ -305,10 +273,10 @@ bool json_tok_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
|||
bool json_tok_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_short_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for json_tok_u64 */
|
||||
bool json_tok_u64(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
uint64_t *num UNNEEDED)
|
||||
{ fprintf(stderr, "json_tok_u64 called!\n"); abort(); }
|
||||
/* Generated stub for kill_uncommitted_channel */
|
||||
void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,
|
||||
const char *why UNNEEDED)
|
||||
{ fprintf(stderr, "kill_uncommitted_channel called!\n"); abort(); }
|
||||
/* Generated stub for locate_tx */
|
||||
struct txlocator *locate_tx(const void *ctx UNNEEDED, const struct chain_topology *topo UNNEEDED, const struct bitcoin_txid *txid UNNEEDED)
|
||||
{ fprintf(stderr, "locate_tx called!\n"); abort(); }
|
||||
|
@ -357,9 +325,17 @@ void onchain_fulfilled_htlc(struct channel *channel UNNEEDED,
|
|||
/* Generated stub for onchain_wire_type_name */
|
||||
const char *onchain_wire_type_name(int e UNNEEDED)
|
||||
{ fprintf(stderr, "onchain_wire_type_name called!\n"); abort(); }
|
||||
/* Generated stub for opening_wire_type_name */
|
||||
const char *opening_wire_type_name(int e UNNEEDED)
|
||||
{ fprintf(stderr, "opening_wire_type_name called!\n"); abort(); }
|
||||
/* Generated stub for peer_accept_channel */
|
||||
u8 *peer_accept_channel(struct lightningd *ld UNNEEDED,
|
||||
const struct pubkey *peer_id UNNEEDED,
|
||||
const struct wireaddr *addr UNNEEDED,
|
||||
const struct crypto_state *cs UNNEEDED,
|
||||
u64 gossip_index UNNEEDED,
|
||||
const u8 *gfeatures UNNEEDED, const u8 *lfeatures UNNEEDED,
|
||||
int peer_fd UNNEEDED, int gossip_fd UNNEEDED,
|
||||
const struct channel_id *channel_id UNNEEDED,
|
||||
const u8 *open_msg UNNEEDED)
|
||||
{ fprintf(stderr, "peer_accept_channel called!\n"); abort(); }
|
||||
/* Generated stub for peer_got_commitsig */
|
||||
void peer_got_commitsig(struct channel *channel UNNEEDED, const u8 *msg UNNEEDED)
|
||||
{ fprintf(stderr, "peer_got_commitsig called!\n"); abort(); }
|
||||
|
@ -438,9 +414,6 @@ u8 *towire_gossipctl_peer_addrhint(const tal_t *ctx UNNEEDED, const struct pubke
|
|||
/* Generated stub for towire_gossipctl_reach_peer */
|
||||
u8 *towire_gossipctl_reach_peer(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossipctl_reach_peer called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossipctl_release_peer */
|
||||
u8 *towire_gossipctl_release_peer(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossipctl_release_peer called!\n"); abort(); }
|
||||
/* Generated stub for towire_gossip_disable_channel */
|
||||
u8 *towire_gossip_disable_channel(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED, u8 direction UNNEEDED, bool active UNNEEDED)
|
||||
{ fprintf(stderr, "towire_gossip_disable_channel called!\n"); abort(); }
|
||||
|
@ -450,9 +423,6 @@ u8 *towire_gossip_getpeers_request(const tal_t *ctx UNNEEDED, const struct pubke
|
|||
/* Generated stub for towire_hsm_client_hsmfd */
|
||||
u8 *towire_hsm_client_hsmfd(const tal_t *ctx UNNEEDED, const struct pubkey *pubkey UNNEEDED, u64 capabilities UNNEEDED)
|
||||
{ fprintf(stderr, "towire_hsm_client_hsmfd called!\n"); abort(); }
|
||||
/* Generated stub for towire_hsm_sign_funding */
|
||||
u8 *towire_hsm_sign_funding(const tal_t *ctx UNNEEDED, u64 satoshi_out UNNEEDED, u64 change_out UNNEEDED, u32 change_keyindex UNNEEDED, const struct pubkey *our_pubkey UNNEEDED, const struct pubkey *their_pubkey UNNEEDED, const struct utxo **inputs UNNEEDED)
|
||||
{ fprintf(stderr, "towire_hsm_sign_funding called!\n"); abort(); }
|
||||
/* Generated stub for towire_onchain_depth */
|
||||
u8 *towire_onchain_depth(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 depth UNNEEDED)
|
||||
{ fprintf(stderr, "towire_onchain_depth called!\n"); abort(); }
|
||||
|
@ -468,15 +438,6 @@ u8 *towire_onchain_known_preimage(const tal_t *ctx UNNEEDED, const struct preima
|
|||
/* Generated stub for towire_onchain_spent */
|
||||
u8 *towire_onchain_spent(const tal_t *ctx UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, u32 input_num UNNEEDED, u32 blockheight UNNEEDED)
|
||||
{ fprintf(stderr, "towire_onchain_spent called!\n"); abort(); }
|
||||
/* Generated stub for towire_opening_fundee */
|
||||
u8 *towire_opening_fundee(const tal_t *ctx UNNEEDED, u32 minimum_depth UNNEEDED, u32 min_feerate UNNEEDED, u32 max_feerate UNNEEDED, const u8 *msg UNNEEDED)
|
||||
{ fprintf(stderr, "towire_opening_fundee called!\n"); abort(); }
|
||||
/* Generated stub for towire_opening_funder */
|
||||
u8 *towire_opening_funder(const tal_t *ctx UNNEEDED, u64 funding_satoshis UNNEEDED, u64 push_msat UNNEEDED, u32 feerate_per_kw UNNEEDED, u32 max_minimum_depth UNNEEDED, u64 change_satoshis UNNEEDED, u32 change_keyindex UNNEEDED, u8 channel_flags UNNEEDED, const struct utxo **inputs UNNEEDED, const struct ext_key *bip32 UNNEEDED)
|
||||
{ fprintf(stderr, "towire_opening_funder called!\n"); abort(); }
|
||||
/* Generated stub for towire_opening_init */
|
||||
u8 *towire_opening_init(const tal_t *ctx UNNEEDED, u32 network_index UNNEEDED, const struct channel_config *our_config UNNEEDED, u32 max_to_self_delay UNNEEDED, u64 min_effective_htlc_capacity_msat UNNEEDED, const struct crypto_state *crypto_state UNNEEDED, u64 gossip_index UNNEEDED, const struct privkey *seed UNNEEDED)
|
||||
{ fprintf(stderr, "towire_opening_init called!\n"); abort(); }
|
||||
/* Generated stub for txfilter_add_scriptpubkey */
|
||||
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, u8 *script UNNEEDED)
|
||||
{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); }
|
||||
|
|
Loading…
Reference in New Issue