df: move tx_sigs from channeld to dualopend

Non-functional yet, but this gets all the pieces in the right places,
rips the signature signing functionality out of channeld.
This commit is contained in:
niftynei
2020-11-03 13:43:48 -06:00
committed by Christian Decker
parent af46a4f57d
commit 260bd04adb
12 changed files with 450 additions and 511 deletions

View File

@@ -22,6 +22,7 @@
#include <lightningd/channel_control.h>
#include <lightningd/dual_open_control.h>
#include <lightningd/hsm_control.h>
#include <lightningd/notification.h>
#include <lightningd/opening_common.h>
#include <lightningd/peer_control.h>
#include <lightningd/plugin_hook.h>
@@ -1032,6 +1033,231 @@ static void accepter_got_offer(struct subd *dualopend,
plugin_hook_call_openchannel2(dualopend->ld, payload);
}
struct channel_send {
const struct wally_tx *wtx;
struct channel *channel;
};
static void sendfunding_done(struct bitcoind *bitcoind UNUSED,
bool success, const char *msg,
struct channel_send *cs)
{
struct lightningd *ld = cs->channel->peer->ld;
struct channel *channel = cs->channel;
const struct wally_tx *wtx = cs->wtx;
struct json_stream *response;
struct bitcoin_txid txid;
struct open_command *oc;
struct amount_sat unused;
int num_utxos;
oc = find_open_command(ld, channel);
if (!oc && channel->opener == LOCAL) {
log_broken(channel->log,
"No outstanding command for channel %s,"
" funding sent was success? %d",
type_to_string(tmpctx, struct channel_id,
&channel->cid),
success);
}
if (!success) {
if (oc)
was_pending(command_fail(oc->cmd,
FUNDING_BROADCAST_FAIL,
"Error broadcasting funding "
"tx: %s. Unsent tx discarded "
"%s.",
msg,
type_to_string(tmpctx,
struct wally_tx,
wtx)));
log_unusual(channel->log,
"Error broadcasting funding "
"tx: %s. Unsent tx discarded "
"%s.",
msg,
type_to_string(tmpctx, struct wally_tx, wtx));
tal_free(cs);
return;
}
/* This might have spent UTXOs from our wallet */
num_utxos = wallet_extract_owned_outputs(ld->wallet,
wtx, NULL,
&unused);
if (num_utxos) {
wallet_transaction_add(ld->wallet, wtx, 0, 0);
}
if (oc) {
response = json_stream_success(oc->cmd);
wally_txid(wtx, &txid);
json_add_hex_talarr(response, "tx", linearize_wtx(tmpctx, wtx));
json_add_txid(response, "txid", &txid);
json_add_string(response, "channel_id",
type_to_string(tmpctx, struct channel_id,
&channel->cid));
was_pending(command_success(oc->cmd, response));
}
tal_free(cs);
}
static void send_funding_tx(struct channel *channel,
const struct wally_tx *wtx TAKES)
{
struct lightningd *ld = channel->peer->ld;
struct channel_send *cs;
cs = tal(channel, struct channel_send);
cs->channel = channel;
if (taken(wtx))
cs->wtx = tal_steal(cs, wtx);
else {
tal_wally_start();
wally_tx_clone_alloc(wtx, 0,
cast_const2(struct wally_tx **,
&cs->wtx));
tal_wally_end(tal_steal(cs, cs->wtx));
}
log_debug(channel->log,
"Broadcasting funding tx for channel %s. %s",
type_to_string(tmpctx, struct channel_id, &channel->cid),
type_to_string(tmpctx, struct wally_tx, cs->wtx));
bitcoind_sendrawtx(ld->topology->bitcoind,
tal_hex(tmpctx, linearize_wtx(tmpctx, cs->wtx)),
sendfunding_done, cs);
}
static void peer_tx_sigs_msg(struct subd *dualopend,
const u8 *msg)
{
struct wally_psbt *psbt;
const struct wally_tx *wtx;
struct lightningd *ld = dualopend->ld;
struct channel *channel = dualopend->channel;
if (!fromwire_dualopend_funding_sigs(tmpctx, msg, &psbt)) {
channel_internal_error(channel,
"bad dualopend_funding_sigs: %s",
tal_hex(tmpctx, msg));
return;
}
tal_wally_start();
if (wally_psbt_combine(channel->psbt, psbt) != WALLY_OK) {
channel_internal_error(channel,
"Unable to combine PSBTs: %s, %s",
type_to_string(tmpctx,
struct wally_psbt,
channel->psbt),
type_to_string(tmpctx,
struct wally_psbt,
psbt));
return;
}
tal_wally_end(channel->psbt);
if (psbt_finalize(cast_const(struct wally_psbt *, channel->psbt))) {
wtx = psbt_final_tx(NULL, channel->psbt);
if (wtx)
send_funding_tx(channel, take(wtx));
}
wallet_channel_save(ld->wallet, channel);
/* Send notification with peer's signed PSBT */
notify_openchannel_peer_sigs(ld, &channel->cid,
channel->psbt);
}
static struct command_result *json_open_channel_signed(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
struct wally_psbt *psbt;
const struct wally_tx *wtx;
struct uncommitted_channel *uc;
struct channel_id *cid;
struct channel *channel;
struct bitcoin_txid txid;
if (!param(cmd, buffer, params,
p_req("channel_id", param_channel_id, &cid),
p_req("signed_psbt", param_psbt, &psbt),
NULL))
return command_param_failed();
channel = channel_by_cid(cmd->ld, cid, &uc);
if (uc)
return command_fail(cmd, LIGHTNINGD,
"Commitments for this channel not "
"yet secured, see `openchannl_update`");
if (!channel)
return command_fail(cmd, FUNDING_UNKNOWN_CHANNEL,
"Unknown channel");
if (channel->psbt && psbt_is_finalized(channel->psbt))
return command_fail(cmd, LIGHTNINGD,
"Already have a finalized PSBT for "
"this channel");
/* Verify that the psbt's txid matches that of the
* funding txid for this channel */
psbt_txid(NULL, psbt, &txid, NULL);
if (!bitcoin_txid_eq(&txid, &channel->funding_txid))
return command_fail(cmd, FUNDING_PSBT_INVALID,
"Txid for passed in PSBT does not match"
" funding txid for channel. Expected %s, "
"received %s",
type_to_string(tmpctx, struct bitcoin_txid,
&channel->funding_txid),
type_to_string(tmpctx, struct bitcoin_txid,
&txid));
/* Go ahead and try to finalize things, or what we can */
psbt_finalize(psbt);
/* Check that all of *our* outputs are finalized */
if (!psbt_side_finalized(psbt, TX_INITIATOR))
return command_fail(cmd, FUNDING_PSBT_INVALID,
"Local PSBT input(s) not finalized");
/* Now that we've got the signed PSBT, save it */
tal_wally_start();
if (wally_psbt_combine(cast_const(struct wally_psbt *,
channel->psbt),
psbt) != WALLY_OK) {
tal_wally_end(tal_free(channel->psbt));
return command_fail(cmd, FUNDING_PSBT_INVALID,
"Failed adding sigs");
}
tal_wally_end(tal_steal(channel, channel->psbt));
wallet_channel_save(cmd->ld->wallet, channel);
channel_watch_funding(cmd->ld, channel);
/* Return when the transaction is broadcast */
register_open_command(cmd->ld, cmd, channel);
/* Send our tx_sigs to the peer */
subd_send_msg(channel->owner,
take(towire_dualopend_send_tx_sigs(NULL, channel->psbt)));
if (psbt_finalize(cast_const(struct wally_psbt *, channel->psbt))) {
wtx = psbt_final_tx(NULL, channel->psbt);
if (wtx)
send_funding_tx(channel, take(wtx));
}
return command_still_pending(cmd);
}
static struct command_result *json_open_channel_update(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
@@ -1238,6 +1464,8 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
const u8 *msg, const int *fds)
{
enum dualopend_wire t = fromwire_peektype(msg);
/* FIXME: might be channel? */
struct uncommitted_channel *uc = dualopend->channel;
switch (t) {
@@ -1274,6 +1502,9 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
accepter_commit_received(dualopend,
uc, fds, msg);
return 0;
case WIRE_DUALOPEND_FUNDING_SIGS:
peer_tx_sigs_msg(dualopend, msg);
return 0;
case WIRE_DUALOPEND_FAILED:
case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY:
@@ -1283,6 +1514,7 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
case WIRE_DUALOPEND_GOT_OFFER_REPLY:
case WIRE_DUALOPEND_FAIL:
case WIRE_DUALOPEND_PSBT_UPDATED:
case WIRE_DUALOPEND_SEND_TX_SIGS:
case WIRE_DUALOPEND_DEV_MEMLEAK:
break;
}
@@ -1323,9 +1555,17 @@ static const struct json_command open_channel_update_command = {
"If {commitments_secured} is true, next call should be to openchannel_signed"
};
static const struct json_command open_channel_signed_command = {
"openchannel_signed",
"channels",
json_open_channel_signed,
"Send our {signed_psbt}'s tx sigs for {channel_id}."
};
#if EXPERIMENTAL_FEATURES
AUTODATA(json_command, &open_channel_init_command);
AUTODATA(json_command, &open_channel_update_command);
AUTODATA(json_command, &open_channel_signed_command);
#endif /* EXPERIMENTAL_FEATURES */
void peer_start_dualopend(struct peer *peer,