Skip to content

Commit 2e69a52

Browse files
committed
Added wallet keypath to PSBT for local output of closing transaction.
1 parent a46c723 commit 2e69a52

File tree

6 files changed

+107
-1
lines changed

6 files changed

+107
-1
lines changed

closingd/closingd.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
3636
const struct chainparams *chainparams,
3737
struct per_peer_state *pps,
3838
const struct channel_id *channel_id,
39+
u32 local_wallet_index,
40+
const struct ext_key *local_wallet_ext_key,
3941
u8 *scriptpubkey[NUM_SIDES],
4042
const struct bitcoin_txid *funding_txid,
4143
unsigned int funding_txout,
@@ -69,6 +71,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
6971
/* FIXME: We need to allow this! */
7072
tx = create_close_tx(ctx,
7173
chainparams,
74+
local_wallet_index, local_wallet_ext_key,
7275
scriptpubkey[LOCAL], scriptpubkey[REMOTE],
7376
funding_wscript,
7477
funding_txid,
@@ -133,6 +136,8 @@ static void send_offer(struct per_peer_state *pps,
133136
const struct channel_id *channel_id,
134137
const struct pubkey funding_pubkey[NUM_SIDES],
135138
const u8 *funding_wscript,
139+
u32 local_wallet_index,
140+
const struct ext_key *local_wallet_ext_key,
136141
u8 *scriptpubkey[NUM_SIDES],
137142
const struct bitcoin_txid *funding_txid,
138143
unsigned int funding_txout,
@@ -154,6 +159,8 @@ static void send_offer(struct per_peer_state *pps,
154159
* #3](03-transactions.md#closing-transaction).
155160
*/
156161
tx = close_tx(tmpctx, chainparams, pps, channel_id,
162+
local_wallet_index,
163+
local_wallet_ext_key,
157164
scriptpubkey,
158165
funding_txid,
159166
funding_txout,
@@ -213,6 +220,8 @@ receive_offer(struct per_peer_state *pps,
213220
const struct channel_id *channel_id,
214221
const struct pubkey funding_pubkey[NUM_SIDES],
215222
const u8 *funding_wscript,
223+
u32 local_wallet_index,
224+
const struct ext_key *local_wallet_ext_key,
216225
u8 *scriptpubkey[NUM_SIDES],
217226
const struct bitcoin_txid *funding_txid,
218227
unsigned int funding_txout,
@@ -267,6 +276,8 @@ receive_offer(struct per_peer_state *pps,
267276
* - MUST fail the connection.
268277
*/
269278
tx = close_tx(tmpctx, chainparams, pps, channel_id,
279+
local_wallet_index,
280+
local_wallet_ext_key,
270281
scriptpubkey,
271282
funding_txid,
272283
funding_txout,
@@ -298,6 +309,8 @@ receive_offer(struct per_peer_state *pps,
298309
* - MAY eliminate its own output.
299310
*/
300311
trimmed = close_tx(tmpctx, chainparams, pps, channel_id,
312+
local_wallet_index,
313+
local_wallet_ext_key,
301314
scriptpubkey,
302315
funding_txid,
303316
funding_txout,
@@ -583,6 +596,8 @@ int main(int argc, char *argv[])
583596
u32 min_feerate, initial_feerate;
584597
struct feerange feerange;
585598
enum side opener;
599+
u32 local_wallet_index;
600+
struct ext_key local_wallet_ext_key;
586601
u8 *scriptpubkey[NUM_SIDES], *funding_wscript;
587602
u64 fee_negotiation_step;
588603
u8 fee_negotiation_step_unit;
@@ -608,8 +623,10 @@ int main(int argc, char *argv[])
608623
&out[LOCAL],
609624
&out[REMOTE],
610625
&our_dust_limit,
611-
&min_feerate, &initial_feerate,
626+
&min_fee_to_accept, &initial_feerate,
612627
&commitment_fee,
628+
&local_wallet_index,
629+
&local_wallet_ext_key,
613630
&scriptpubkey[LOCAL],
614631
&scriptpubkey[REMOTE],
615632
&fee_negotiation_step,
@@ -674,6 +691,8 @@ int main(int argc, char *argv[])
674691
if (whose_turn == LOCAL) {
675692
send_offer(pps, chainparams,
676693
&channel_id, funding_pubkey, funding_wscript,
694+
local_wallet_index,
695+
&local_wallet_ext_key,
677696
scriptpubkey, &funding_txid, funding_txout,
678697
funding, out, opener,
679698
our_dust_limit,
@@ -694,6 +713,8 @@ int main(int argc, char *argv[])
694713
= receive_offer(pps, chainparams,
695714
&channel_id, funding_pubkey,
696715
funding_wscript,
716+
local_wallet_index,
717+
&local_wallet_ext_key,
697718
scriptpubkey, &funding_txid,
698719
funding_txout, funding,
699720
out, opener,
@@ -725,6 +746,8 @@ int main(int argc, char *argv[])
725746
fee_negotiation_step_unit);
726747
send_offer(pps, chainparams, &channel_id,
727748
funding_pubkey, funding_wscript,
749+
local_wallet_index,
750+
&local_wallet_ext_key,
728751
scriptpubkey, &funding_txid, funding_txout,
729752
funding, out, opener,
730753
our_dust_limit,
@@ -740,6 +763,8 @@ int main(int argc, char *argv[])
740763
= receive_offer(pps, chainparams, &channel_id,
741764
funding_pubkey,
742765
funding_wscript,
766+
local_wallet_index,
767+
&local_wallet_ext_key,
743768
scriptpubkey, &funding_txid,
744769
funding_txout, funding,
745770
out, opener,

closingd/closingd_wire.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <bitcoin/tx.h>
2+
#include <common/bip32.h>
23
#include <common/channel_id.h>
34
#include <common/cryptomsg.h>
45
#include <common/htlc_wire.h>
@@ -20,6 +21,9 @@ msgdata,closingd_init,our_dust_limit,amount_sat,
2021
msgdata,closingd_init,min_feerate_perksipa,u32,
2122
msgdata,closingd_init,preferred_feerate_perksipa,u32,
2223
msgdata,closingd_init,fee_limit_satoshi,amount_sat,
24+
msgdata,closingd_init,initial_fee_satoshi,amount_sat,
25+
msgdata,closingd_init,local_wallet_index,u32,
26+
msgdata,closingd_init,local_wallet_ext_key,ext_key,
2327
msgdata,closingd_init,local_scriptpubkey_len,u16,
2428
msgdata,closingd_init,local_scriptpubkey,u8,local_scriptpubkey_len
2529
msgdata,closingd_init,remote_scriptpubkey_len,u16,

common/close_tx.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,39 @@
55
#include <assert.h>
66
#include <common/utils.h>
77

8+
static void add_keypath_item_to_last_output(struct bitcoin_tx *tx,
9+
u32 index,
10+
const struct ext_key *ext) {
11+
// Skip if there is no wallet keypath for this output.
12+
if (index == UINT32_MAX)
13+
return;
14+
15+
size_t outndx = tx->psbt->num_outputs - 1;
16+
struct wally_map *map_in = &tx->psbt->outputs[outndx].keypaths;
17+
18+
u8 fingerprint[BIP32_KEY_FINGERPRINT_LEN];
19+
if (bip32_key_get_fingerprint(
20+
(struct ext_key *) ext, fingerprint, sizeof(fingerprint)) != WALLY_OK) {
21+
abort();
22+
}
23+
24+
u32 path[1];
25+
path[0] = index;
26+
27+
tal_wally_start();
28+
if (wally_map_add_keypath_item(map_in,
29+
ext->pub_key, sizeof(ext->pub_key),
30+
fingerprint, sizeof(fingerprint),
31+
path, 1) != WALLY_OK) {
32+
abort();
33+
}
34+
tal_wally_end(tx->psbt);
35+
}
36+
837
struct bitcoin_tx *create_close_tx(const tal_t *ctx,
938
const struct chainparams *chainparams,
39+
u32 local_wallet_index,
40+
const struct ext_key *local_wallet_ext_key,
1041
const u8 *our_script,
1142
const u8 *their_script,
1243
const u8 *funding_wscript,
@@ -47,6 +78,7 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
4778
script = tal_dup_talarr(tx, u8, our_script);
4879
/* One output is to us. */
4980
bitcoin_tx_add_output(tx, script, NULL, to_us);
81+
add_keypath_item_to_last_output(tx, local_wallet_index, local_wallet_ext_key);
5082
num_outputs++;
5183
}
5284

common/close_tx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ struct pubkey;
1313
* input scriptsig. */
1414
struct bitcoin_tx *create_close_tx(const tal_t *ctx,
1515
const struct chainparams *chainparams,
16+
u32 local_wallet_index,
17+
const struct ext_key *local_wallet_ext_key,
1618
const u8 *our_script,
1719
const u8 *their_script,
1820
const u8 *funding_wscript,

contrib/remote_hsmd/proxy.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,26 @@ void marshal_single_input_tx(struct bitcoin_tx const *tx,
212212

213213
for (size_t ii = 0; ii < tx->wtx->num_outputs; ii++) {
214214
OutputDescriptor *odesc = o_tp->add_output_descs();
215+
216+
// Add witness script
215217
if (tx->psbt->outputs[ii].witness_script_len)
216218
odesc->set_witscript(
217219
(const char *)
218220
tx->psbt->outputs[ii].witness_script,
219221
tx->psbt->outputs[ii].witness_script_len);
222+
223+
// Add keypath
224+
struct wally_map *mp = &tx->psbt->outputs[ii].keypaths;
225+
if (mp->num_items == 1) {
226+
const struct wally_map_item *ip = &mp->items[0];
227+
size_t npath =
228+
(ip->value_len - BIP32_KEY_FINGERPRINT_LEN) / sizeof(uint32_t);
229+
uint32_t *path = (uint32_t *) (ip->value + BIP32_KEY_FINGERPRINT_LEN);
230+
for (size_t jj = 0; jj < npath; ++jj) {
231+
odesc->mutable_key_loc()->add_key_path(le32_to_cpu(path[jj]));
232+
}
233+
}
234+
220235
}
221236
}
222237

lightningd/closing_control.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,32 @@ void peer_start_closingd(struct channel *channel,
270270
return;
271271
}
272272

273+
// Determine the wallet index for our output, UINT32_MAX if not found.
274+
u32 local_wallet_index;
275+
struct ext_key local_wallet_ext_key;
276+
bool is_p2sh;
277+
if (wallet_can_spend(
278+
ld->wallet,
279+
channel->shutdown_scriptpubkey[LOCAL],
280+
&local_wallet_index,
281+
&is_p2sh)) {
282+
if (bip32_key_from_parent(
283+
ld->wallet->bip32_base,
284+
local_wallet_index,
285+
BIP32_FLAG_KEY_PUBLIC,
286+
&local_wallet_ext_key) != WALLY_OK) {
287+
abort();
288+
}
289+
} else {
290+
local_wallet_index = UINT32_MAX;
291+
char *dummy_bip32 =
292+
"tpubDAY5hwtonH4NE8zY46ZMFf6B6F3fqMis7cwfNihXXpAg6XzBZNo"
293+
"HAdAzAZx2peoU8nTWFqvUncXwJ9qgE5VxcnUKxdut8F6mptVmKjfiwDQ";
294+
if (bip32_key_from_base58(dummy_bip32, &local_wallet_ext_key) != WALLY_OK) {
295+
abort();
296+
}
297+
}
298+
273299
initmsg = towire_closingd_init(tmpctx,
274300
chainparams,
275301
pps,
@@ -284,6 +310,8 @@ void peer_start_closingd(struct channel *channel,
284310
amount_msat_to_sat_round_down(their_msat),
285311
channel->our_config.dust_limit,
286312
feerate_min(ld, NULL), feerate, feelimit,
313+
local_wallet_index,
314+
&local_wallet_ext_key,
287315
channel->shutdown_scriptpubkey[LOCAL],
288316
channel->shutdown_scriptpubkey[REMOTE],
289317
channel->closing_fee_negotiation_step,

0 commit comments

Comments
 (0)