dual-fund: rework where we send our tx-sigs message, allow peers in

Prior to this patch update, we expected a client to call
`openchannel_signed` before checking for peer's tx-sigs messages on the
wire.

When moving to a 'multifundchannel' approach, we'll need to be able to
collect sigs from our peers before sending our tx_sigs message. There's
no strict ordering on when tx-sigs messages are sent/received, so this
is fine.

To do this, we go ahead and start up channeld as soon as
commitment_sigs are secured, so that we process incoming tx-sigs from
our peers as soon as we get them.
This commit is contained in:
niftynei 2020-10-08 17:12:20 -05:00 committed by Rusty Russell
parent c6ad4f9b20
commit f9aab50ee8
7 changed files with 256 additions and 131 deletions

View file

@ -2002,12 +2002,46 @@ static void send_onionmsg(struct peer *peer, const u8 *msg)
tlvs))); tlvs)));
} }
static void handle_send_tx_sigs(struct peer *peer, const u8 *msg)
{
struct wally_psbt *psbt;
struct bitcoin_txid txid;
if (!fromwire_channeld_send_tx_sigs(tmpctx, msg, &psbt))
master_badmsg(WIRE_CHANNELD_SEND_TX_SIGS, msg);
/* Check that we've got the same / correct PSBT */
psbt_txid(NULL, psbt, &txid, NULL);
if (!bitcoin_txid_eq(&txid, &peer->channel->funding_txid))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Txid for passed in PSBT does not match"
" funding txid for channel. Expected %s, "
"received %s",
type_to_string(tmpctx, struct bitcoin_txid,
&peer->channel->funding_txid),
type_to_string(tmpctx, struct bitcoin_txid,
&txid));
tal_wally_start();
if (wally_psbt_combine(peer->psbt, psbt) != WALLY_OK) {
tal_wally_end(tal_free(peer->psbt));
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Unable to combine PSBTs");
}
tal_wally_end(tal_steal(peer, peer->psbt));
#if EXPERIMENTAL_FEATURES
sync_crypto_write(peer->pps,
take(psbt_to_tx_sigs_msg(NULL, peer->channel,
psbt)));
#endif /* EXPERIMENTAL_FEATURES */
}
static void handle_tx_sigs(struct peer *peer, const u8 *msg) static void handle_tx_sigs(struct peer *peer, const u8 *msg)
{ {
struct channel_id cid; struct channel_id cid;
struct bitcoin_txid txid; struct bitcoin_txid txid;
const struct witness_stack **ws; const struct witness_stack **ws;
const struct wally_tx *wtx;
size_t j = 0; size_t j = 0;
enum tx_role role = peer->channel->opener == REMOTE enum tx_role role = peer->channel->opener == REMOTE
? TX_INITIATOR : TX_ACCEPTER; ? TX_INITIATOR : TX_ACCEPTER;
@ -2073,22 +2107,10 @@ static void handle_tx_sigs(struct peer *peer, const u8 *msg)
psbt_input_set_final_witness_stack(peer->psbt, in, elem); psbt_input_set_final_witness_stack(peer->psbt, in, elem);
} }
/* Then we broadcast it, and let the command know we did it */ /* Send to the peer controller, who will broadcast the funding_tx
if (!psbt_finalize(peer->psbt)) * as soon as we've got our sigs */
peer_failed(peer->pps, &peer->channel_id,
"Unable to finalize PSBT %s",
type_to_string(tmpctx, struct wally_psbt, peer->psbt));
wtx = psbt_final_tx(tmpctx, peer->psbt);
if (!wtx)
peer_failed(peer->pps, &peer->channel_id,
"Unable to extract funding_tx from finalized PSBT %s",
type_to_string(tmpctx, struct wally_psbt, peer->psbt));
/* We need the peer controller to broadcast the tx for us */
wire_sync_write(MASTER_FD, wire_sync_write(MASTER_FD,
take(towire_channeld_funding_tx(NULL, wtx))); take(towire_channeld_funding_sigs(NULL, peer->psbt)));
peer->psbt = tal_free(peer->psbt); peer->psbt = tal_free(peer->psbt);
} }
@ -3296,6 +3318,14 @@ static void req_in(struct peer *peer, const u8 *msg)
case WIRE_CHANNELD_SEND_ERROR: case WIRE_CHANNELD_SEND_ERROR:
handle_send_error(peer, msg); handle_send_error(peer, msg);
return; return;
#if EXPERIMENTAL_FEATURES
case WIRE_CHANNELD_SEND_TX_SIGS:
handle_send_tx_sigs(peer, msg);
return;
#else
case WIRE_CHANNELD_SEND_TX_SIGS:
break;
#endif /* !EXPERIMENTAL_FEATURES */
#if EXPERIMENTAL_FEATURES #if EXPERIMENTAL_FEATURES
case WIRE_SEND_ONIONMSG: case WIRE_SEND_ONIONMSG:
send_onionmsg(peer, msg); send_onionmsg(peer, msg);
@ -3316,7 +3346,7 @@ static void req_in(struct peer *peer, const u8 *msg)
case WIRE_CHANNELD_DEV_MEMLEAK: case WIRE_CHANNELD_DEV_MEMLEAK:
#endif /* DEVELOPER */ #endif /* DEVELOPER */
case WIRE_CHANNELD_INIT: case WIRE_CHANNELD_INIT:
case WIRE_CHANNELD_FUNDING_TX: case WIRE_CHANNELD_FUNDING_SIGS:
case WIRE_CHANNELD_OFFER_HTLC_REPLY: case WIRE_CHANNELD_OFFER_HTLC_REPLY:
case WIRE_CHANNELD_SENDING_COMMITSIG: case WIRE_CHANNELD_SENDING_COMMITSIG:
case WIRE_CHANNELD_GOT_COMMITSIG: case WIRE_CHANNELD_GOT_COMMITSIG:

View file

@ -75,8 +75,13 @@ msgdata,channeld_init,num_penalty_bases,u32,
msgdata,channeld_init,pbases,penalty_base,num_penalty_bases msgdata,channeld_init,pbases,penalty_base,num_penalty_bases
msgdata,channeld_init,psbt,wally_psbt, msgdata,channeld_init,psbt,wally_psbt,
msgtype,channeld_funding_tx,1010 # channeld->master received tx_sigs from peer
msgdata,channeld_funding_tx,funding_tx,wally_tx, msgtype,channeld_funding_sigs,1010
msgdata,channeld_funding_sigs,signed_psbt,wally_psbt,
# master->channeld send our tx_sigs to peer
msgtype,channeld_send_tx_sigs,1011
msgdata,channeld_send_tx_sigs,signed_psbt,wally_psbt,
# master->channeld funding hit new depth(funding locked if >= lock depth) # master->channeld funding hit new depth(funding locked if >= lock depth)
msgtype,channeld_funding_depth,1002 msgtype,channeld_funding_depth,1002

Can't render this file because it has a wrong number of fields in line 12.

View file

@ -21,7 +21,8 @@ const char *channeld_wire_name(int e)
switch ((enum channeld_wire)e) { switch ((enum channeld_wire)e) {
case WIRE_CHANNELD_INIT: return "WIRE_CHANNELD_INIT"; case WIRE_CHANNELD_INIT: return "WIRE_CHANNELD_INIT";
case WIRE_CHANNELD_FUNDING_TX: return "WIRE_CHANNELD_FUNDING_TX"; case WIRE_CHANNELD_FUNDING_SIGS: return "WIRE_CHANNELD_FUNDING_SIGS";
case WIRE_CHANNELD_SEND_TX_SIGS: return "WIRE_CHANNELD_SEND_TX_SIGS";
case WIRE_CHANNELD_FUNDING_DEPTH: return "WIRE_CHANNELD_FUNDING_DEPTH"; case WIRE_CHANNELD_FUNDING_DEPTH: return "WIRE_CHANNELD_FUNDING_DEPTH";
case WIRE_CHANNELD_OFFER_HTLC: return "WIRE_CHANNELD_OFFER_HTLC"; case WIRE_CHANNELD_OFFER_HTLC: return "WIRE_CHANNELD_OFFER_HTLC";
case WIRE_CHANNELD_OFFER_HTLC_REPLY: return "WIRE_CHANNELD_OFFER_HTLC_REPLY"; case WIRE_CHANNELD_OFFER_HTLC_REPLY: return "WIRE_CHANNELD_OFFER_HTLC_REPLY";
@ -60,7 +61,8 @@ bool channeld_wire_is_defined(u16 type)
{ {
switch ((enum channeld_wire)type) { switch ((enum channeld_wire)type) {
case WIRE_CHANNELD_INIT:; case WIRE_CHANNELD_INIT:;
case WIRE_CHANNELD_FUNDING_TX:; case WIRE_CHANNELD_FUNDING_SIGS:;
case WIRE_CHANNELD_SEND_TX_SIGS:;
case WIRE_CHANNELD_FUNDING_DEPTH:; case WIRE_CHANNELD_FUNDING_DEPTH:;
case WIRE_CHANNELD_OFFER_HTLC:; case WIRE_CHANNELD_OFFER_HTLC:;
case WIRE_CHANNELD_OFFER_HTLC_REPLY:; case WIRE_CHANNELD_OFFER_HTLC_REPLY:;
@ -301,24 +303,47 @@ bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainp
return cursor != NULL; return cursor != NULL;
} }
/* WIRE: CHANNELD_FUNDING_TX */ /* WIRE: CHANNELD_FUNDING_SIGS */
u8 *towire_channeld_funding_tx(const tal_t *ctx, const struct wally_tx *funding_tx) /* channeld->master received tx_sigs from peer */
u8 *towire_channeld_funding_sigs(const tal_t *ctx, const struct wally_psbt *signed_psbt)
{ {
u8 *p = tal_arr(ctx, u8, 0); u8 *p = tal_arr(ctx, u8, 0);
towire_u16(&p, WIRE_CHANNELD_FUNDING_TX); towire_u16(&p, WIRE_CHANNELD_FUNDING_SIGS);
towire_wally_tx(&p, funding_tx); towire_wally_psbt(&p, signed_psbt);
return memcheck(p, tal_count(p)); return memcheck(p, tal_count(p));
} }
bool fromwire_channeld_funding_tx(const tal_t *ctx, const void *p, struct wally_tx **funding_tx) bool fromwire_channeld_funding_sigs(const tal_t *ctx, const void *p, struct wally_psbt **signed_psbt)
{ {
const u8 *cursor = p; const u8 *cursor = p;
size_t plen = tal_count(p); size_t plen = tal_count(p);
if (fromwire_u16(&cursor, &plen) != WIRE_CHANNELD_FUNDING_TX) if (fromwire_u16(&cursor, &plen) != WIRE_CHANNELD_FUNDING_SIGS)
return false; return false;
*funding_tx = fromwire_wally_tx(ctx, &cursor, &plen); *signed_psbt = fromwire_wally_psbt(ctx, &cursor, &plen);
return cursor != NULL;
}
/* WIRE: CHANNELD_SEND_TX_SIGS */
/* master->channeld send our tx_sigs to peer */
u8 *towire_channeld_send_tx_sigs(const tal_t *ctx, const struct wally_psbt *signed_psbt)
{
u8 *p = tal_arr(ctx, u8, 0);
towire_u16(&p, WIRE_CHANNELD_SEND_TX_SIGS);
towire_wally_psbt(&p, signed_psbt);
return memcheck(p, tal_count(p));
}
bool fromwire_channeld_send_tx_sigs(const tal_t *ctx, const void *p, struct wally_psbt **signed_psbt)
{
const u8 *cursor = p;
size_t plen = tal_count(p);
if (fromwire_u16(&cursor, &plen) != WIRE_CHANNELD_SEND_TX_SIGS)
return false;
*signed_psbt = fromwire_wally_psbt(ctx, &cursor, &plen);
return cursor != NULL; return cursor != NULL;
} }
@ -1211,4 +1236,4 @@ bool fromwire_send_onionmsg(const tal_t *ctx, const void *p, u8 onion[1366], str
} }
return cursor != NULL; return cursor != NULL;
} }
// SHA256STAMP:5614b61d80352e94f974d018c391102579d76c5db11648d18ed0dd198ab6838a // SHA256STAMP:0ddc4d686d50049ed4c8500919e415dde43baea52adc651b8a606765b09ab001

View file

@ -23,7 +23,10 @@
enum channeld_wire { enum channeld_wire {
/* Begin! (passes gossipd-client fd) */ /* Begin! (passes gossipd-client fd) */
WIRE_CHANNELD_INIT = 1000, WIRE_CHANNELD_INIT = 1000,
WIRE_CHANNELD_FUNDING_TX = 1010, /* channeld->master received tx_sigs from peer */
WIRE_CHANNELD_FUNDING_SIGS = 1010,
/* master->channeld send our tx_sigs to peer */
WIRE_CHANNELD_SEND_TX_SIGS = 1011,
/* master->channeld funding hit new depth(funding locked if >= lock depth) */ /* master->channeld funding hit new depth(funding locked if >= lock depth) */
WIRE_CHANNELD_FUNDING_DEPTH = 1002, WIRE_CHANNELD_FUNDING_DEPTH = 1002,
/* Tell channel to offer this htlc */ /* Tell channel to offer this htlc */
@ -95,9 +98,15 @@ bool channeld_wire_is_defined(u16 type);
u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases, const struct wally_psbt *psbt); u8 *towire_channeld_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct channel_id *channel_id, const struct bitcoin_txid *funding_txid, u16 funding_txout, struct amount_sat funding_satoshi, u32 minimum_depth, const struct channel_config *our_config, const struct channel_config *their_config, const struct fee_states *fee_states, u32 feerate_min, u32 feerate_max, u32 feerate_penalty, const struct bitcoin_signature *first_commit_sig, const struct per_peer_state *per_peer_state, const struct pubkey *remote_fundingkey, const struct basepoints *remote_basepoints, const struct pubkey *remote_per_commit, const struct pubkey *old_remote_per_commit, enum side opener, u32 fee_base, u32 fee_proportional, struct amount_msat local_msatoshi, const struct basepoints *our_basepoints, const struct pubkey *our_funding_pubkey, const struct node_id *local_node_id, const struct node_id *remote_node_id, u32 commit_msec, u16 cltv_delta, bool last_was_revoke, const struct changed_htlc *last_sent_commit, u64 next_index_local, u64 next_index_remote, u64 revocations_received, u64 next_htlc_id, const struct existing_htlc **htlcs, bool local_funding_locked, bool remote_funding_locked, const struct short_channel_id *funding_short_id, bool reestablish, bool send_shutdown, bool remote_shutdown_received, const u8 *final_scriptpubkey, u8 flags, const u8 *init_peer_pkt, bool reached_announce_depth, const struct secret *last_remote_secret, const u8 *their_features, const u8 *upfront_shutdown_script, const secp256k1_ecdsa_signature *remote_ann_node_sig, const secp256k1_ecdsa_signature *remote_ann_bitcoin_sig, bool option_static_remotekey, bool option_anchor_outputs, bool dev_fast_gossip, bool dev_fail_process_onionpacket, const struct penalty_base *pbases, const struct wally_psbt *psbt);
bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases, struct wally_psbt **psbt); bool fromwire_channeld_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct channel_id *channel_id, struct bitcoin_txid *funding_txid, u16 *funding_txout, struct amount_sat *funding_satoshi, u32 *minimum_depth, struct channel_config *our_config, struct channel_config *their_config, struct fee_states **fee_states, u32 *feerate_min, u32 *feerate_max, u32 *feerate_penalty, struct bitcoin_signature *first_commit_sig, struct per_peer_state **per_peer_state, struct pubkey *remote_fundingkey, struct basepoints *remote_basepoints, struct pubkey *remote_per_commit, struct pubkey *old_remote_per_commit, enum side *opener, u32 *fee_base, u32 *fee_proportional, struct amount_msat *local_msatoshi, struct basepoints *our_basepoints, struct pubkey *our_funding_pubkey, struct node_id *local_node_id, struct node_id *remote_node_id, u32 *commit_msec, u16 *cltv_delta, bool *last_was_revoke, struct changed_htlc **last_sent_commit, u64 *next_index_local, u64 *next_index_remote, u64 *revocations_received, u64 *next_htlc_id, struct existing_htlc ***htlcs, bool *local_funding_locked, bool *remote_funding_locked, struct short_channel_id *funding_short_id, bool *reestablish, bool *send_shutdown, bool *remote_shutdown_received, u8 **final_scriptpubkey, u8 *flags, u8 **init_peer_pkt, bool *reached_announce_depth, struct secret *last_remote_secret, u8 **their_features, u8 **upfront_shutdown_script, secp256k1_ecdsa_signature **remote_ann_node_sig, secp256k1_ecdsa_signature **remote_ann_bitcoin_sig, bool *option_static_remotekey, bool *option_anchor_outputs, bool *dev_fast_gossip, bool *dev_fail_process_onionpacket, struct penalty_base **pbases, struct wally_psbt **psbt);
/* WIRE: CHANNELD_FUNDING_TX */ /* WIRE: CHANNELD_FUNDING_SIGS */
u8 *towire_channeld_funding_tx(const tal_t *ctx, const struct wally_tx *funding_tx); /* channeld->master received tx_sigs from peer */
bool fromwire_channeld_funding_tx(const tal_t *ctx, const void *p, struct wally_tx **funding_tx); u8 *towire_channeld_funding_sigs(const tal_t *ctx, const struct wally_psbt *signed_psbt);
bool fromwire_channeld_funding_sigs(const tal_t *ctx, const void *p, struct wally_psbt **signed_psbt);
/* WIRE: CHANNELD_SEND_TX_SIGS */
/* master->channeld send our tx_sigs to peer */
u8 *towire_channeld_send_tx_sigs(const tal_t *ctx, const struct wally_psbt *signed_psbt);
bool fromwire_channeld_send_tx_sigs(const tal_t *ctx, const void *p, struct wally_psbt **signed_psbt);
/* WIRE: CHANNELD_FUNDING_DEPTH */ /* WIRE: CHANNELD_FUNDING_DEPTH */
/* master->channeld funding hit new depth(funding locked if >= lock depth) */ /* master->channeld funding hit new depth(funding locked if >= lock depth) */
@ -237,4 +246,4 @@ bool fromwire_send_onionmsg(const tal_t *ctx, const void *p, u8 onion[1366], str
#endif /* LIGHTNING_CHANNELD_CHANNELD_WIREGEN_H */ #endif /* LIGHTNING_CHANNELD_CHANNELD_WIREGEN_H */
// SHA256STAMP:5614b61d80352e94f974d018c391102579d76c5db11648d18ed0dd198ab6838a // SHA256STAMP:0ddc4d686d50049ed4c8500919e415dde43baea52adc651b8a606765b09ab001

View file

@ -151,10 +151,6 @@ struct channel {
/* PSBT, for v2 channels. Saved until it's sent */ /* PSBT, for v2 channels. Saved until it's sent */
struct wally_psbt *psbt; struct wally_psbt *psbt;
/* Stashed pps, saved until channeld is started.
* Needed only for v2 channel open flow */
struct per_peer_state *pps;
}; };
struct channel *new_channel(struct peer *peer, u64 dbid, struct channel *new_channel(struct peer *peer, u64 dbid,

View file

@ -11,7 +11,9 @@
#include <common/jsonrpc_errors.h> #include <common/jsonrpc_errors.h>
#include <common/memleak.h> #include <common/memleak.h>
#include <common/per_peer_state.h> #include <common/per_peer_state.h>
#include <common/psbt_open.h>
#include <common/timeout.h> #include <common/timeout.h>
#include <common/tx_roles.h>
#include <common/utils.h> #include <common/utils.h>
#include <common/wire_error.h> #include <common/wire_error.h>
#include <errno.h> #include <errno.h>
@ -316,7 +318,7 @@ static void handle_error_channel(struct channel *channel,
} }
struct channel_send { struct channel_send {
struct wally_tx *wtx; const struct wally_tx *wtx;
struct channel *channel; struct channel *channel;
}; };
@ -326,7 +328,7 @@ static void sendfunding_done(struct bitcoind *bitcoind UNUSED,
{ {
struct lightningd *ld = cs->channel->peer->ld; struct lightningd *ld = cs->channel->peer->ld;
struct channel *channel = cs->channel; struct channel *channel = cs->channel;
struct wally_tx *wtx = cs->wtx; const struct wally_tx *wtx = cs->wtx;
struct json_stream *response; struct json_stream *response;
struct bitcoin_txid txid; struct bitcoin_txid txid;
struct open_command *oc; struct open_command *oc;
@ -386,20 +388,22 @@ static void sendfunding_done(struct bitcoind *bitcoind UNUSED,
tal_free(cs); tal_free(cs);
} }
static void handle_funding_tx(struct channel *channel, static void send_funding_tx(struct channel *channel,
const u8 *msg) const struct wally_tx *wtx TAKES)
{ {
struct channel_send *cs;
struct lightningd *ld = channel->peer->ld; struct lightningd *ld = channel->peer->ld;
struct channel_send *cs;
cs = tal(channel, struct channel_send); cs = tal(channel, struct channel_send);
cs->channel = channel; cs->channel = channel;
if (taken(wtx))
if (!fromwire_channeld_funding_tx(tmpctx, msg, &cs->wtx)) { cs->wtx = tal_steal(cs, wtx);
channel_internal_error(channel, else {
"bad channeld_funding_tx: %s", tal_wally_start();
tal_hex(tmpctx, msg)); wally_tx_clone_alloc(wtx, 0,
return; cast_const2(struct wally_tx **,
&cs->wtx));
tal_wally_end(tal_steal(cs, cs->wtx));
} }
log_debug(channel->log, log_debug(channel->log,
@ -412,6 +416,41 @@ static void handle_funding_tx(struct channel *channel,
sendfunding_done, cs); sendfunding_done, cs);
} }
static void peer_tx_sigs_msg(struct channel *channel, const u8 *msg)
{
struct wally_psbt *psbt;
const struct wally_tx *wtx;
struct lightningd *ld = channel->peer->ld;
if (!fromwire_channeld_funding_sigs(tmpctx, msg, &psbt)) {
channel_internal_error(channel,
"bad channeld_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));
}
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);
}
void forget_channel(struct channel *channel, const char *why) void forget_channel(struct channel *channel, const char *why)
{ {
channel->error = towire_errorfmt(channel, &channel->cid, "%s", why); channel->error = towire_errorfmt(channel, &channel->cid, "%s", why);
@ -436,6 +475,9 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
case WIRE_CHANNELD_GOT_COMMITSIG: case WIRE_CHANNELD_GOT_COMMITSIG:
peer_got_commitsig(sd->channel, msg); peer_got_commitsig(sd->channel, msg);
break; break;
case WIRE_CHANNELD_FUNDING_SIGS:
peer_tx_sigs_msg(sd->channel, msg);
break;
case WIRE_CHANNELD_GOT_REVOKE: case WIRE_CHANNELD_GOT_REVOKE:
peer_got_revoke(sd->channel, msg); peer_got_revoke(sd->channel, msg);
break; break;
@ -460,9 +502,6 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
case WIRE_CHANNELD_SEND_ERROR_REPLY: case WIRE_CHANNELD_SEND_ERROR_REPLY:
handle_error_channel(sd->channel, msg); handle_error_channel(sd->channel, msg);
break; break;
case WIRE_CHANNELD_FUNDING_TX:
handle_funding_tx(sd->channel, msg);
break;
#if EXPERIMENTAL_FEATURES #if EXPERIMENTAL_FEATURES
case WIRE_GOT_ONIONMSG_TO_US: case WIRE_GOT_ONIONMSG_TO_US:
handle_onionmsg_to_us(sd->channel, msg); handle_onionmsg_to_us(sd->channel, msg);
@ -476,6 +515,7 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
#endif #endif
/* And we never get these from channeld. */ /* And we never get these from channeld. */
case WIRE_CHANNELD_INIT: case WIRE_CHANNELD_INIT:
case WIRE_CHANNELD_SEND_TX_SIGS:
case WIRE_CHANNELD_FUNDING_DEPTH: case WIRE_CHANNELD_FUNDING_DEPTH:
case WIRE_CHANNELD_OFFER_HTLC: case WIRE_CHANNELD_OFFER_HTLC:
case WIRE_CHANNELD_FULFILL_HTLC: case WIRE_CHANNELD_FULFILL_HTLC:
@ -931,6 +971,97 @@ struct command_result *cancel_channel_before_broadcast(struct command *cmd,
return command_still_pending(cmd); return command_still_pending(cmd);
} }
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_channeld_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 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}."
};
AUTODATA(json_command, &open_channel_signed_command);
#if DEVELOPER #if DEVELOPER
static struct command_result *json_dev_feerate(struct command *cmd, static struct command_result *json_dev_feerate(struct command *cmd,
const char *buffer, const char *buffer,

View file

@ -879,7 +879,6 @@ static void opener_commit_received(struct subd *dualopend,
goto failed; goto failed;
} }
channel->pps = tal_steal(channel, pps);
if (pbase) if (pbase)
wallet_penalty_base_add(ld->wallet, channel->dbid, pbase); wallet_penalty_base_add(ld->wallet, channel->dbid, pbase);
@ -890,14 +889,18 @@ static void opener_commit_received(struct subd *dualopend,
json_add_bool(response, "commitments_secured", true); json_add_bool(response, "commitments_secured", true);
was_pending(command_success(uc->fc->cmd, response)); was_pending(command_success(uc->fc->cmd, response));
subd_release_channel(dualopend, uc); /* Now that we've got the final PSBT, save it */
uc->open_daemon = NULL; channel->psbt = tal_steal(channel, psbt);
tal_free(uc); wallet_channel_save(uc->fc->cmd->ld->wallet, channel);
return;
peer_start_channeld(channel, pps,
NULL, psbt, false);
goto cleanup;
failed: failed:
was_pending(command_fail(uc->fc->cmd, LIGHTNINGD, was_pending(command_fail(uc->fc->cmd, LIGHTNINGD,
"%s", err_reason)); "%s", err_reason));
cleanup:
subd_release_channel(dualopend, uc); subd_release_channel(dualopend, uc);
uc->open_daemon = NULL; uc->open_daemon = NULL;
tal_free(uc); tal_free(uc);
@ -968,71 +971,6 @@ static void accepter_got_offer(struct subd *dualopend,
plugin_hook_call_openchannel2(dualopend->ld, payload); plugin_hook_call_openchannel2(dualopend->ld, payload);
} }
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;
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, NULL);
if (!channel)
return command_fail(cmd, FUNDING_UNKNOWN_CHANNEL,
"Unknown channel");
if (!channel->pps)
return command_fail(cmd, LIGHTNINGD,
"Missing per-peer-state for channel, "
"are you in the right state to call "
"this method?");
if (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 */
channel->psbt = tal_steal(channel, psbt);
wallet_channel_save(cmd->ld->wallet, channel);
channel_watch_funding(cmd->ld, channel);
register_open_command(cmd->ld, cmd, channel);
peer_start_channeld(channel, channel->pps,
NULL, psbt, false);
channel->pps = tal_free(channel->pps);
return command_still_pending(cmd);
}
static struct command_result *json_open_channel_update(struct command *cmd, static struct command_result *json_open_channel_update(struct command *cmd,
const char *buffer, const char *buffer,
const jsmntok_t *obj UNNEEDED, const jsmntok_t *obj UNNEEDED,
@ -1086,7 +1024,6 @@ static struct command_result *json_open_channel_update(struct command *cmd,
return command_still_pending(cmd); return command_still_pending(cmd);
} }
static struct command_result *json_open_channel_init(struct command *cmd, static struct command_result *json_open_channel_init(struct command *cmd,
const char *buffer, const char *buffer,
const jsmntok_t *obj UNNEEDED, const jsmntok_t *obj UNNEEDED,
@ -1325,17 +1262,9 @@ static const struct json_command open_channel_update_command = {
"If {commitments_secured} is true, next call should be to openchannel_signed" "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,
"Finish opening {channel_id} with {signed_psbt}. "
};
#if EXPERIMENTAL_FEATURES #if EXPERIMENTAL_FEATURES
AUTODATA(json_command, &open_channel_init_command); AUTODATA(json_command, &open_channel_init_command);
AUTODATA(json_command, &open_channel_update_command); AUTODATA(json_command, &open_channel_update_command);
AUTODATA(json_command, &open_channel_signed_command);
#endif /* EXPERIMENTAL_FEATURES */ #endif /* EXPERIMENTAL_FEATURES */
void peer_start_dualopend(struct peer *peer, void peer_start_dualopend(struct peer *peer,