From 8f56f9680159765c41f53a915061f16f68de0e99 Mon Sep 17 00:00:00 2001 From: Ken Sedgwick Date: Thu, 23 Dec 2021 12:16:35 -0800 Subject: [PATCH] hsmd: Add wallet index metadata to existing messages --- channeld/Makefile | 1 + channeld/channeld.c | 24 +++++++++- channeld/channeld_wire.csv | 6 +++ channeld/watchtower.c | 6 +++ channeld/watchtower.h | 4 ++ closingd/Makefile | 1 + closingd/closingd.c | 42 ++++++++++++++++- closingd/closingd_wire.csv | 4 ++ common/close_tx.c | 7 +++ common/close_tx.h | 4 ++ lightningd/channel_control.c | 15 ++++++ lightningd/closing_control.c | 66 ++++++++++++++++++++++++++- lightningd/onchain_control.c | 13 ++++++ onchaind/Makefile | 1 + onchaind/onchaind.c | 12 ++++- onchaind/onchaind_wire.csv | 3 ++ onchaind/test/Makefile | 1 + onchaind/test/run-grind_feerate-bug.c | 2 +- onchaind/test/run-grind_feerate.c | 2 +- 19 files changed, 206 insertions(+), 8 deletions(-) diff --git a/channeld/Makefile b/channeld/Makefile index bef41c69a..bdab8ffa0 100644 --- a/channeld/Makefile +++ b/channeld/Makefile @@ -73,6 +73,7 @@ CHANNELD_COMMON_OBJS := \ common/per_peer_state.o \ common/permute_tx.o \ common/ping.o \ + common/psbt_keypath.o \ common/psbt_open.o \ common/private_channel_announcement.o \ common/pseudorand.o \ diff --git a/channeld/channeld.c b/channeld/channeld.c index f47dc404e..1d85ff2ed 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -122,6 +123,8 @@ struct peer { u32 fee_per_satoshi; /* The scriptpubkey to use for shutting down. */ + u32 *final_index; + struct ext_key *final_ext_key; u8 *final_scriptpubkey; /* If master told us to shut down */ @@ -1722,6 +1725,7 @@ static u8 *got_revoke_msg(struct peer *peer, u64 revoke_num, if (pbase) { ptx = penalty_tx_create( NULL, peer->channel, peer->feerate_penalty, + peer->final_index, peer->final_ext_key, peer->final_scriptpubkey, per_commitment_secret, &pbase->txid, pbase->outnum, pbase->amount, HSM_FD); @@ -3470,12 +3474,23 @@ static void handle_fail(struct peer *peer, const u8 *inmsg) static void handle_shutdown_cmd(struct peer *peer, const u8 *inmsg) { + u32 *final_index; + struct ext_key *final_ext_key; u8 *local_shutdown_script; - if (!fromwire_channeld_send_shutdown(peer, inmsg, &local_shutdown_script, + if (!fromwire_channeld_send_shutdown(peer, inmsg, + &final_index, + &final_ext_key, + &local_shutdown_script, &peer->shutdown_wrong_funding)) master_badmsg(WIRE_CHANNELD_SEND_SHUTDOWN, inmsg); + tal_free(peer->final_index); + peer->final_index = final_index; + + tal_free(peer->final_ext_key); + peer->final_ext_key = final_ext_key; + tal_free(peer->final_scriptpubkey); peer->final_scriptpubkey = local_shutdown_script; @@ -3652,6 +3667,8 @@ static void init_channel(struct peer *peer) enum side opener; struct existing_htlc **htlcs; bool reconnected; + u32 final_index; + struct ext_key final_ext_key; u8 *fwd_msg; const u8 *msg; struct fee_states *fee_states; @@ -3715,6 +3732,8 @@ static void init_channel(struct peer *peer) &reconnected, &peer->send_shutdown, &peer->shutdown_sent[REMOTE], + &final_index, + &final_ext_key, &peer->final_scriptpubkey, &peer->channel_flags, &fwd_msg, @@ -3734,6 +3753,9 @@ static void init_channel(struct peer *peer) master_badmsg(WIRE_CHANNELD_INIT, msg); } + peer->final_index = tal_dup(peer, u32, &final_index); + peer->final_ext_key = tal_dup(peer, struct ext_key, &final_ext_key); + #if DEVELOPER peer->dev_disable_commit = dev_disable_commit; peer->dev_fast_gossip = dev_fast_gossip; diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index a444125ce..b84ca73c4 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -56,6 +57,8 @@ msgdata,channeld_init,funding_short_id,short_channel_id, msgdata,channeld_init,reestablish,bool, msgdata,channeld_init,send_shutdown,bool, msgdata,channeld_init,remote_shutdown_received,bool, +msgdata,channeld_init,final_index,u32, +msgdata,channeld_init,final_ext_key,ext_key, msgdata,channeld_init,final_scriptpubkey_len,u16, msgdata,channeld_init,final_scriptpubkey,u8,final_scriptpubkey_len msgdata,channeld_init,flags,u8, @@ -173,8 +176,11 @@ msgdata,channeld_got_revoke,penalty_tx,?bitcoin_tx, # (eg. if we sent another commitment_signed, that would implicitly ack). msgtype,channeld_got_revoke_reply,1122 +#include # Tell peer to shut down channel. msgtype,channeld_send_shutdown,1023 +msgdata,channeld_send_shutdown,final_index,?u32, +msgdata,channeld_send_shutdown,final_ext_key,?ext_key, msgdata,channeld_send_shutdown,shutdown_len,u16, msgdata,channeld_send_shutdown,shutdown_scriptpubkey,u8,shutdown_len msgdata,channeld_send_shutdown,wrong_funding,?bitcoin_outpoint, diff --git a/channeld/watchtower.c b/channeld/watchtower.c index e91dc4f89..269b4f405 100644 --- a/channeld/watchtower.c +++ b/channeld/watchtower.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,8 @@ const struct bitcoin_tx * penalty_tx_create(const tal_t *ctx, const struct channel *channel, u32 penalty_feerate, + u32 *final_index, + struct ext_key *final_ext_key, u8 *final_scriptpubkey, const struct secret *revocation_preimage, const struct bitcoin_txid *commitment_txid, @@ -76,6 +79,9 @@ penalty_tx_create(const tal_t *ctx, NULL, to_them_sats, NULL, wscript); bitcoin_tx_add_output(tx, final_scriptpubkey, NULL, to_them_sats); + assert((final_index == NULL) == (final_ext_key == NULL)); + if (final_index) + psbt_add_keypath_to_last_output(tx, *final_index, final_ext_key); /* Worst-case sig is 73 bytes */ weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript); diff --git a/channeld/watchtower.h b/channeld/watchtower.h index 90fe01e90..e4e339b7a 100644 --- a/channeld/watchtower.h +++ b/channeld/watchtower.h @@ -3,10 +3,14 @@ #include "config.h" #include +struct ext_key; + const struct bitcoin_tx * penalty_tx_create(const tal_t *ctx, const struct channel *channel, u32 penalty_feerate, + u32 *final_index, + struct ext_key *final_ext_key, u8 *final_scriptpubkey, const struct secret *revocation_preimage, const struct bitcoin_txid *commitment_txid, diff --git a/closingd/Makefile b/closingd/Makefile index 5c3373471..7ee284fbb 100644 --- a/closingd/Makefile +++ b/closingd/Makefile @@ -45,6 +45,7 @@ CLOSINGD_COMMON_OBJS := \ common/per_peer_state.o \ common/permute_tx.o \ common/ping.o \ + common/psbt_keypath.o \ common/psbt_open.o \ common/pseudorand.o \ common/status_wiregen.o \ diff --git a/closingd/closingd.c b/closingd/closingd.c index 05c45cfc2..345f2c26c 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,8 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, const struct chainparams *chainparams, struct per_peer_state *pps, const struct channel_id *channel_id, + u32 *local_wallet_index, + const struct ext_key *local_wallet_ext_key, u8 *scriptpubkey[NUM_SIDES], const struct bitcoin_outpoint *funding, struct amount_sat funding_sats, @@ -83,6 +86,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, /* FIXME: We need to allow this! */ tx = create_close_tx(ctx, chainparams, + local_wallet_index, local_wallet_ext_key, scriptpubkey[LOCAL], scriptpubkey[REMOTE], funding_wscript, funding, @@ -130,6 +134,8 @@ static void send_offer(struct per_peer_state *pps, const struct channel_id *channel_id, const struct pubkey funding_pubkey[NUM_SIDES], const u8 *funding_wscript, + u32 *local_wallet_index, + const struct ext_key *local_wallet_ext_key, u8 *scriptpubkey[NUM_SIDES], const struct bitcoin_outpoint *funding, struct amount_sat funding_sats, @@ -152,6 +158,8 @@ static void send_offer(struct per_peer_state *pps, * #3](03-transactions.md#closing-transaction). */ tx = close_tx(tmpctx, chainparams, pps, channel_id, + local_wallet_index, + local_wallet_ext_key, scriptpubkey, funding, funding_sats, @@ -225,6 +233,8 @@ receive_offer(struct per_peer_state *pps, const struct channel_id *channel_id, const struct pubkey funding_pubkey[NUM_SIDES], const u8 *funding_wscript, + u32 *local_wallet_index, + const struct ext_key *local_wallet_ext_key, u8 *scriptpubkey[NUM_SIDES], const struct bitcoin_outpoint *funding, struct amount_sat funding_sats, @@ -285,6 +295,8 @@ receive_offer(struct per_peer_state *pps, * - MUST fail the connection. */ tx = close_tx(tmpctx, chainparams, pps, channel_id, + local_wallet_index, + local_wallet_ext_key, scriptpubkey, funding, funding_sats, @@ -315,6 +327,8 @@ receive_offer(struct per_peer_state *pps, * - MAY eliminate its own output. */ trimmed = close_tx(tmpctx, chainparams, pps, channel_id, + local_wallet_index, + local_wallet_ext_key, scriptpubkey, funding, funding_sats, @@ -559,7 +573,9 @@ static size_t closing_tx_weight_estimate(u8 *scriptpubkey[NUM_SIDES], const u8 *funding_wscript, const struct amount_sat *out, struct amount_sat funding_sats, - struct amount_sat dust_limit) + struct amount_sat dust_limit, + u32 *local_wallet_index, + const struct ext_key *local_wallet_ext_key) { /* We create a dummy close */ struct bitcoin_tx *tx; @@ -567,6 +583,7 @@ static size_t closing_tx_weight_estimate(u8 *scriptpubkey[NUM_SIDES], memset(&dummy_funding, 0, sizeof(dummy_funding)); tx = create_close_tx(tmpctx, chainparams, + local_wallet_index, local_wallet_ext_key, scriptpubkey[LOCAL], scriptpubkey[REMOTE], funding_wscript, &dummy_funding, @@ -671,6 +688,8 @@ static void do_quickclose(struct amount_sat offer[NUM_SIDES], const struct channel_id *channel_id, const struct pubkey funding_pubkey[NUM_SIDES], const u8 *funding_wscript, + u32 *local_wallet_index, + const struct ext_key *local_wallet_ext_key, u8 *scriptpubkey[NUM_SIDES], const struct bitcoin_outpoint *funding, struct amount_sat funding_sats, @@ -750,6 +769,7 @@ static void do_quickclose(struct amount_sat offer[NUM_SIDES], offer[LOCAL] = offer[REMOTE]; send_offer(pps, chainparams, channel_id, funding_pubkey, funding_wscript, + local_wallet_index, local_wallet_ext_key, scriptpubkey, funding, funding_sats, out, opener, our_dust_limit, @@ -789,6 +809,7 @@ static void do_quickclose(struct amount_sat offer[NUM_SIDES], } send_offer(pps, chainparams, channel_id, funding_pubkey, funding_wscript, + local_wallet_index, local_wallet_ext_key, scriptpubkey, funding, funding_sats, out, opener, our_dust_limit, @@ -802,6 +823,7 @@ static void do_quickclose(struct amount_sat offer[NUM_SIDES], = receive_offer(pps, chainparams, channel_id, funding_pubkey, funding_wscript, + local_wallet_index, local_wallet_ext_key, scriptpubkey, funding, funding_sats, out, opener, @@ -851,6 +873,8 @@ int main(int argc, char *argv[]) u32 min_feerate, initial_feerate, *max_feerate; struct feerange feerange; enum side opener; + u32 *local_wallet_index; + struct ext_key *local_wallet_ext_key; u8 *scriptpubkey[NUM_SIDES], *funding_wscript; u64 fee_negotiation_step; u8 fee_negotiation_step_unit; @@ -879,6 +903,8 @@ int main(int argc, char *argv[]) &our_dust_limit, &min_feerate, &initial_feerate, &max_feerate, &commitment_fee, + &local_wallet_index, + &local_wallet_ext_key, &scriptpubkey[LOCAL], &scriptpubkey[REMOTE], &fee_negotiation_step, @@ -899,7 +925,9 @@ int main(int argc, char *argv[]) calc_fee_bounds(closing_tx_weight_estimate(scriptpubkey, funding_wscript, out, funding_sats, - our_dust_limit), + our_dust_limit, + local_wallet_index, + local_wallet_ext_key), min_feerate, initial_feerate, max_feerate, commitment_fee, funding_sats, opener, &min_fee_to_accept, &offer[LOCAL], &max_fee_to_accept); @@ -957,6 +985,7 @@ int main(int argc, char *argv[]) if (whose_turn == LOCAL) { send_offer(pps, chainparams, &channel_id, funding_pubkey, funding_wscript, + local_wallet_index, local_wallet_ext_key, scriptpubkey, &funding, funding_sats, out, opener, our_dust_limit, @@ -978,6 +1007,8 @@ int main(int argc, char *argv[]) = receive_offer(pps, chainparams, &channel_id, funding_pubkey, funding_wscript, + local_wallet_index, + local_wallet_ext_key, scriptpubkey, &funding, funding_sats, out, opener, @@ -991,6 +1022,7 @@ int main(int argc, char *argv[]) do_quickclose(offer, pps, &channel_id, funding_pubkey, funding_wscript, + local_wallet_index, local_wallet_ext_key, scriptpubkey, &funding, funding_sats, out, opener, @@ -1024,6 +1056,8 @@ int main(int argc, char *argv[]) fee_negotiation_step_unit); send_offer(pps, chainparams, &channel_id, funding_pubkey, funding_wscript, + local_wallet_index, + local_wallet_ext_key, scriptpubkey, &funding, funding_sats, out, opener, our_dust_limit, @@ -1040,6 +1074,8 @@ int main(int argc, char *argv[]) = receive_offer(pps, chainparams, &channel_id, funding_pubkey, funding_wscript, + local_wallet_index, + local_wallet_ext_key, scriptpubkey, &funding, funding_sats, out, opener, @@ -1064,6 +1100,8 @@ exit_thru_the_giftshop: tal_free(our_feerange); tal_free(their_feerange); tal_free(max_feerate); + tal_free(local_wallet_index); + tal_free(local_wallet_ext_key); closing_dev_memleak(ctx, scriptpubkey, funding_wscript); #endif diff --git a/closingd/closingd_wire.csv b/closingd/closingd_wire.csv index 94ab71c75..29f6eccab 100644 --- a/closingd/closingd_wire.csv +++ b/closingd/closingd_wire.csv @@ -1,8 +1,10 @@ #include +#include #include #include #include #include +#include # Begin! (passes peer fd, gossipd-client fd) msgtype,closingd_init,2001 msgdata,closingd_init,chainparams,chainparams, @@ -19,6 +21,8 @@ msgdata,closingd_init,min_feerate_perksipa,u32, msgdata,closingd_init,preferred_feerate_perksipa,u32, msgdata,closingd_init,max_feerate_perksipa,?u32, msgdata,closingd_init,fee_limit_satoshi,amount_sat, +msgdata,closingd_init,local_wallet_index,?u32, +msgdata,closingd_init,local_wallet_ext_key,?ext_key, msgdata,closingd_init,local_scriptpubkey_len,u16, msgdata,closingd_init,local_scriptpubkey,u8,local_scriptpubkey_len msgdata,closingd_init,remote_scriptpubkey_len,u16, diff --git a/common/close_tx.c b/common/close_tx.c index e1eb16ba6..48e54d1e9 100644 --- a/common/close_tx.c +++ b/common/close_tx.c @@ -3,10 +3,13 @@ #include #include #include +#include #include struct bitcoin_tx *create_close_tx(const tal_t *ctx, const struct chainparams *chainparams, + u32 *local_wallet_index, + const struct ext_key *local_wallet_ext_key, const u8 *our_script, const u8 *their_script, const u8 *funding_wscript, @@ -46,6 +49,10 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, script = tal_dup_talarr(tx, u8, our_script); /* One output is to us. */ bitcoin_tx_add_output(tx, script, NULL, to_us); + assert((local_wallet_index == NULL) == (local_wallet_ext_key == NULL)); + if (local_wallet_index) + psbt_add_keypath_to_last_output( + tx, *local_wallet_index, local_wallet_ext_key); num_outputs++; } diff --git a/common/close_tx.h b/common/close_tx.h index 6f9886556..2c3aad61d 100644 --- a/common/close_tx.h +++ b/common/close_tx.h @@ -3,10 +3,14 @@ #include "config.h" #include +struct ext_key; + /* Create close tx to spend the anchor tx output; doesn't fill in * input scriptsig. */ struct bitcoin_tx *create_close_tx(const tal_t *ctx, const struct chainparams *chainparams, + u32 *local_wallet_index, + const struct ext_key *local_wallet_ext_key, const u8 *our_script, const u8 *their_script, const u8 *funding_wscript, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 0d70aa039..e07db69d0 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -22,6 +22,7 @@ #include #include #include +#include static void update_feerates(struct lightningd *ld, struct channel *channel) { @@ -665,6 +666,18 @@ void peer_start_channeld(struct channel *channel, pbases = wallet_penalty_base_load_for_channel( tmpctx, channel->peer->ld->wallet, channel->dbid); + struct ext_key final_ext_key; + if (bip32_key_from_parent( + ld->wallet->bip32_base, + channel->final_key_idx, + BIP32_FLAG_KEY_PUBLIC, + &final_ext_key) != WALLY_OK) { + channel_internal_error(channel, + "Could not derive final_ext_key %"PRIu64, + channel->final_key_idx); + return; + } + initmsg = towire_channeld_init(tmpctx, chainparams, ld->our_features, @@ -713,6 +726,8 @@ void peer_start_channeld(struct channel *channel, || channel->state == CLOSINGD_SIGEXCHANGE || channel_closed(channel), channel->shutdown_scriptpubkey[REMOTE] != NULL, + channel->final_key_idx, + &final_ext_key, channel->shutdown_scriptpubkey[LOCAL], channel->channel_flags, fwd_msg, diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 0590e154c..ef85657f7 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -38,6 +38,7 @@ #include #include #include +#include struct close_command { /* Inside struct lightningd close_commands. */ @@ -443,6 +444,29 @@ void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd) return; } + // Determine the wallet index for our output or NULL if not found. + u32 *local_wallet_index = NULL; + struct ext_key *local_wallet_ext_key = NULL; + u32 index_val; + struct ext_key ext_key_val; + bool is_p2sh; + if (wallet_can_spend( + ld->wallet, + channel->shutdown_scriptpubkey[LOCAL], + &index_val, + &is_p2sh)) { + if (bip32_key_from_parent( + ld->wallet->bip32_base, + index_val, + BIP32_FLAG_KEY_PUBLIC, + &ext_key_val) != WALLY_OK) { + channel_internal_error(channel, "Could not derive ext public key"); + return; + } + local_wallet_index = &index_val; + local_wallet_ext_key = &ext_key_val; + } + initmsg = towire_closingd_init(tmpctx, chainparams, &channel->cid, @@ -456,6 +480,8 @@ void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd) channel->our_config.dust_limit, min_feerate, feerate, max_feerate, feelimit, + local_wallet_index, + local_wallet_ext_key, channel->shutdown_scriptpubkey[LOCAL], channel->shutdown_scriptpubkey[REMOTE], channel->closing_fee_negotiation_step, @@ -527,6 +553,8 @@ static struct command_result *json_close(struct command *cmd, struct channel *channel; unsigned int *timeout; const u8 *close_to_script = NULL; + u32 *final_index; + u32 index_val; bool close_script_set, wrong_funding_changed, *force_lease_close; const char *fee_negotiation_step_str; struct bitcoin_outpoint *wrong_funding; @@ -584,6 +612,14 @@ static struct command_result *json_close(struct command *cmd, channel->lease_expiry, get_block_height(cmd->ld->topology)); + /* Set the wallet index to the default value; it is updated + * below if the close_to_script is found to be in the + * wallet. If the close_to_script is not in the wallet + * final_index will be set to NULL instead.*/ + assert(channel->final_key_idx <= UINT32_MAX); + index_val = (u32) channel->final_key_idx; + final_index = &index_val; + /* If we've set a local shutdown script for this peer, and it's not the * default upfront script, try to close to a different channel. * Error is an operator error */ @@ -613,6 +649,17 @@ static struct command_result *json_close(struct command *cmd, channel->shutdown_scriptpubkey[LOCAL] = tal_steal(channel, cast_const(u8 *, close_to_script)); close_script_set = true; + /* Is the close script in our wallet? */ + bool is_p2sh; + if (wallet_can_spend( + cmd->ld->wallet, + channel->shutdown_scriptpubkey[LOCAL], + &index_val, + &is_p2sh)) { + /* index_val has been set to the discovered wallet index */ + } else { + final_index = NULL; + } } else if (!channel->shutdown_scriptpubkey[LOCAL]) { channel->shutdown_scriptpubkey[LOCAL] = p2wpkh_for_keyidx(channel, cmd->ld, channel->final_key_idx); @@ -735,11 +782,28 @@ static struct command_result *json_close(struct command *cmd, msg = towire_dualopend_send_shutdown( NULL, channel->shutdown_scriptpubkey[LOCAL]); - } else + } else { + struct ext_key ext_key_val; + struct ext_key *final_ext_key = NULL; + if (final_index) { + if (bip32_key_from_parent( + channel->peer->ld->wallet->bip32_base, + *final_index, + BIP32_FLAG_KEY_PUBLIC, + &ext_key_val) != WALLY_OK) { + return command_fail( + cmd, LIGHTNINGD, + "Could not derive final_ext_key"); + } + final_ext_key = &ext_key_val; + } msg = towire_channeld_send_shutdown( NULL, + final_index, + final_ext_key, channel->shutdown_scriptpubkey[LOCAL], channel->shutdown_wrong_funding); + } subd_send_msg(channel->owner, take(msg)); } diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index f980565c6..850ae1913 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -15,6 +15,7 @@ #include #include #include +#include /* We dump all the known preimages when onchaind starts up. */ static void onchaind_tell_fulfill(struct channel *channel) @@ -642,6 +643,16 @@ enum watch_result onchaind_funding_spent(struct channel *channel, channel->final_key_idx); return KEEP_WATCHING; } + struct ext_key final_wallet_ext_key; + if (bip32_key_from_parent( + ld->wallet->bip32_base, + channel->final_key_idx, + BIP32_FLAG_KEY_PUBLIC, + &final_wallet_ext_key) != WALLY_OK) { + log_broken(channel->log, "Could not derive final_wallet_ext_key %"PRIu64, + channel->final_key_idx); + return KEEP_WATCHING; + } /* This could be a mutual close, but it doesn't matter. */ bitcoin_txid(channel->last_tx, &our_last_txid); @@ -706,6 +717,8 @@ enum watch_result onchaind_funding_spent(struct channel *channel, &our_last_txid, channel->shutdown_scriptpubkey[LOCAL], channel->shutdown_scriptpubkey[REMOTE], + channel->final_key_idx, + &final_wallet_ext_key, &final_key, channel->opener, &channel->local_basepoints, diff --git a/onchaind/Makefile b/onchaind/Makefile index 1db28e425..28c8b6a32 100644 --- a/onchaind/Makefile +++ b/onchaind/Makefile @@ -54,6 +54,7 @@ ONCHAIND_COMMON_OBJS := \ common/onionreply.o \ common/peer_billboard.o \ common/permute_tx.o \ + common/psbt_keypath.o \ common/psbt_open.o \ common/pseudorand.o \ common/setup.o \ diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index d210590ad..df8902cbc 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include #include "onchain_types_names_gen.h" @@ -53,6 +55,8 @@ static struct amount_sat dust_limit; static u32 to_self_delay[NUM_SIDES]; /* Where we send money to (our wallet) */ +static u32 our_wallet_index; +static struct ext_key our_wallet_ext_key; static struct pubkey our_wallet_pubkey; /* Their revocation secret (only if they cheated). */ @@ -618,6 +622,7 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx, bitcoin_tx_add_output( tx, scriptpubkey_p2wpkh(tmpctx, &our_wallet_pubkey), NULL, out->sat); + psbt_add_keypath_to_last_output(tx, our_wallet_index, &our_wallet_ext_key); /* Worst-case sig is 73 bytes */ weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript); @@ -738,13 +743,14 @@ replace_penalty_tx_to_us(const tal_t *ctx, BITCOIN_TX_RBF_SEQUENCE, NULL, input_amount, NULL, input_wscript); /* Reconstruct the output with a smaller amount. */ - if (amount_sat_greater(*output_amount, dust_limit)) + if (amount_sat_greater(*output_amount, dust_limit)) { bitcoin_tx_add_output(tx, scriptpubkey_p2wpkh(tx, &our_wallet_pubkey), NULL, *output_amount); - else { + psbt_add_keypath_to_last_output(tx, our_wallet_index, &our_wallet_ext_key); + } else { bitcoin_tx_add_output(tx, scriptpubkey_opreturn_padded(tx), NULL, @@ -3845,6 +3851,8 @@ int main(int argc, char *argv[]) &our_broadcast_txid, &scriptpubkey[LOCAL], &scriptpubkey[REMOTE], + &our_wallet_index, + &our_wallet_ext_key, &our_wallet_pubkey, &opener, &basepoints[LOCAL], diff --git a/onchaind/onchaind_wire.csv b/onchaind/onchaind_wire.csv index a5204086c..e2dfd0316 100644 --- a/onchaind/onchaind_wire.csv +++ b/onchaind/onchaind_wire.csv @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -29,6 +30,8 @@ msgdata,onchaind_init,local_scriptpubkey_len,u16, msgdata,onchaind_init,local_scriptpubkey,u8,local_scriptpubkey_len msgdata,onchaind_init,remote_scriptpubkey_len,u16, msgdata,onchaind_init,remote_scriptpubkey,u8,remote_scriptpubkey_len +msgdata,onchaind_init,ourwallet_index,u32, +msgdata,onchaind_init,ourwallet_ext_key,ext_key, msgdata,onchaind_init,ourwallet_pubkey,pubkey, # We need these two for commit number obscurer msgdata,onchaind_init,opener,enum side, diff --git a/onchaind/test/Makefile b/onchaind/test/Makefile index 96fd2b865..2bb2269e0 100644 --- a/onchaind/test/Makefile +++ b/onchaind/test/Makefile @@ -13,6 +13,7 @@ ONCHAIND_TEST_COMMON_OBJS := \ common/amount.o \ common/autodata.o \ common/features.o \ + common/psbt_keypath.o \ common/pseudorand.o \ common/setup.o \ common/type_to_string.o \ diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c index 0d17accd7..8726dbaf3 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -49,7 +49,7 @@ bool fromwire_onchaind_dev_memleak(const void *p UNNEEDED) bool fromwire_onchaind_htlcs(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct htlc_stub **htlc UNNEEDED, bool **tell_if_missing UNNEEDED, bool **tell_immediately UNNEEDED) { fprintf(stderr, "fromwire_onchaind_htlcs called!\n"); abort(); } /* Generated stub for fromwire_onchaind_init */ -bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED) +bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, u32 *ourwallet_index UNNEEDED, struct ext_key *ourwallet_ext_key UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED) { fprintf(stderr, "fromwire_onchaind_init called!\n"); abort(); } /* Generated stub for fromwire_onchaind_known_preimage */ bool fromwire_onchaind_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED) diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index 9e3be0904..e800b371c 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -54,7 +54,7 @@ bool fromwire_onchaind_dev_memleak(const void *p UNNEEDED) bool fromwire_onchaind_htlcs(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct htlc_stub **htlc UNNEEDED, bool **tell_if_missing UNNEEDED, bool **tell_immediately UNNEEDED) { fprintf(stderr, "fromwire_onchaind_htlcs called!\n"); abort(); } /* Generated stub for fromwire_onchaind_init */ -bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED) +bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, u32 *ourwallet_index UNNEEDED, struct ext_key *ourwallet_ext_key UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED) { fprintf(stderr, "fromwire_onchaind_init called!\n"); abort(); } /* Generated stub for fromwire_onchaind_known_preimage */ bool fromwire_onchaind_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED)