Skip to content

Commit 4ced65f

Browse files
committed
Support p2tr deposit addresses
1 parent 72399b6 commit 4ced65f

37 files changed

+288
-124
lines changed

.msggen.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@
272272
"NewaddrAddresstype": {
273273
"all": 2,
274274
"bech32": 0,
275-
"p2sh-segwit": 1
275+
"p2sh-segwit": 1,
276+
"p2tr": 3
276277
},
277278
"PayStatus": {
278279
"complete": 0,
@@ -1257,7 +1258,9 @@
12571258
},
12581259
"NewaddrResponse": {
12591260
"NewAddr.bech32": 1,
1260-
"NewAddr.p2sh-segwit": 2
1261+
"NewAddr.p2sh-segwit": 2,
1262+
"NewAddr.p2tr": 3,
1263+
"NewAddr.script": 4
12611264
},
12621265
"PayRequest": {
12631266
"Pay.amount_msat": 13,
@@ -4608,6 +4611,10 @@
46084611
"added": "pre-v0.10.1",
46094612
"deprecated": "v23.02"
46104613
},
4614+
"NewAddr.p2tr": {
4615+
"added": "v23.05",
4616+
"deprecated": false
4617+
},
46114618
"Pay": {
46124619
"added": "pre-v0.10.1",
46134620
"deprecated": null

bitcoin/tx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,7 @@ struct amount_sat change_amount(struct amount_sat excess, u32 feerate_perkw,
972972
struct amount_sat change_fee;
973973

974974
/* Must be able to pay for its own additional weight */
975-
outweight = bitcoin_tx_output_weight(BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN);
975+
outweight = bitcoin_tx_output_weight(chainparams->is_elements ? BITCOIN_SCRIPTPUBKEY_P2WPKH_LEN : BITCOIN_SCRIPTPUBKEY_P2TR_LEN);
976976

977977
/* Rounding can cause off by one errors, so we do this */
978978
if (!amount_sat_sub(&change_fee,

bitcoin/tx.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,12 @@ size_t bitcoin_tx_simple_input_weight(bool p2sh);
320320
size_t bitcoin_tx_2of2_input_witness_weight(void);
321321

322322
/**
323-
* change_amount - Is it worth making a P2WPKH change output at this feerate?
323+
* change_amount - Is it worth making a change output at this feerate?
324324
* @excess: input amount we have above the tx fee and other outputs.
325325
* @feerate_perkw: feerate.
326326
*
327+
* Change script is P2TR for Bitcoin, P2WPKH for Elements
328+
*
327329
* If it's not worth (or possible) to make change, returns AMOUNT_SAT(0).
328330
* Otherwise returns the amount of the change output to add (@excess minus
329331
* the additional fee for the change output itself).

channeld/full_channel.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,9 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx,
338338

339339
/* Set the remote/local pubkeys on the commitment tx psbt */
340340
psbt_input_add_pubkey(txs[0]->psbt, 0,
341-
&channel->funding_pubkey[side]);
341+
&channel->funding_pubkey[side], false /* is_taproot */);
342342
psbt_input_add_pubkey(txs[0]->psbt, 0,
343-
&channel->funding_pubkey[!side]);
343+
&channel->funding_pubkey[!side], false /* is_taproot */);
344344

345345
add_htlcs(&txs, *htlcmap, channel, &keyset, side);
346346

channeld/watchtower.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ penalty_tx_create(const tal_t *ctx,
8181
bitcoin_tx_add_output(tx, final_scriptpubkey, NULL, to_them_sats);
8282
assert((final_index == NULL) == (final_ext_key == NULL));
8383
if (final_index)
84-
psbt_add_keypath_to_last_output(tx, *final_index, final_ext_key);
84+
psbt_add_keypath_to_last_output(tx, *final_index, final_ext_key, is_p2tr(final_scriptpubkey, NULL));
8585

8686
/* Worst-case sig is 73 bytes */
8787
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript);

cln-grpc/proto/node.proto

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cln-grpc/src/convert.rs

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cln-rpc/src/model.rs

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/close_tx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
5252
assert((local_wallet_index == NULL) == (local_wallet_ext_key == NULL));
5353
if (local_wallet_index)
5454
psbt_add_keypath_to_last_output(
55-
tx, *local_wallet_index, local_wallet_ext_key);
55+
tx, *local_wallet_index, local_wallet_ext_key, is_p2tr(script, NULL));
5656
num_outputs++;
5757
}
5858

common/initial_channel.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx,
138138

139139
if (init_tx) {
140140
psbt_input_add_pubkey(init_tx->psbt, 0,
141-
&channel->funding_pubkey[side]);
141+
&channel->funding_pubkey[side], false /* is_taproot */);
142142
psbt_input_add_pubkey(init_tx->psbt, 0,
143-
&channel->funding_pubkey[!side]);
143+
&channel->funding_pubkey[!side], false /* is_taproot */);
144144
}
145145

146146
return init_tx;

common/psbt_keypath.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
#include <common/psbt_keypath.h>
44
#include <common/utils.h>
55
#include <wally_bip32.h>
6-
#include <wally_psbt.h>
76

8-
void psbt_set_keypath(u32 index, const struct ext_key *ext, struct wally_map *map_in) {
7+
void psbt_output_set_keypath(u32 index, const struct ext_key *ext, bool is_taproot, struct wally_psbt_output *output) {
98
u8 fingerprint[BIP32_KEY_FINGERPRINT_LEN];
109
if (bip32_key_get_fingerprint(
1110
(struct ext_key *) ext, fingerprint, sizeof(fingerprint)) != WALLY_OK)
@@ -14,20 +13,30 @@ void psbt_set_keypath(u32 index, const struct ext_key *ext, struct wally_map *ma
1413
u32 path[1];
1514
path[0] = index;
1615

17-
if (wally_map_keypath_add(map_in,
18-
ext->pub_key, sizeof(ext->pub_key),
19-
fingerprint, sizeof(fingerprint),
20-
path, 1) != WALLY_OK)
21-
abort();
16+
if (is_taproot) {
17+
if (wally_psbt_output_taproot_keypath_add(output,
18+
ext->pub_key + 1, sizeof(ext->pub_key) - 1,
19+
NULL, 0,
20+
fingerprint, sizeof(fingerprint),
21+
path, 1) != WALLY_OK)
22+
abort();
23+
} else {
24+
if (wally_psbt_output_keypath_add(output,
25+
ext->pub_key, sizeof(ext->pub_key),
26+
fingerprint, sizeof(fingerprint),
27+
path, 1) != WALLY_OK)
28+
abort();
29+
}
30+
2231
}
2332

2433
void psbt_add_keypath_to_last_output(struct bitcoin_tx *tx,
2534
u32 key_index,
26-
const struct ext_key *ext) {
35+
const struct ext_key *ext,
36+
bool is_taproot) {
2737
size_t outndx = tx->psbt->num_outputs - 1;
28-
struct wally_map *map_in = &tx->psbt->outputs[outndx].keypaths;
2938

3039
tal_wally_start();
31-
psbt_set_keypath(key_index, ext, map_in);
40+
psbt_output_set_keypath(key_index, ext, is_taproot, &tx->psbt->outputs[outndx]);
3241
tal_wally_end(tx->psbt);
3342
}

common/psbt_keypath.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,35 @@
33

44
#include "config.h"
55
#include <ccan/short_types/short_types.h>
6+
#include <wally_psbt.h>
67

78
struct bitcoin_tx;
89
struct ext_key;
910
struct wally_map;
1011

11-
/* psbt_set_keypath - Set the keypath of a PSBT output.
12+
/* psbt_output_set_keypath- Set the keypath of a PSBT output.
1213
*
1314
* @index - child index of the wallet key
1415
* @ext - extended public key of the immediate parent of the wallet key
15-
* @map_in - wally keypaths map
16+
* @is_taproot - PSBT output has taproot script
17+
* @output - PSBT output to set
1618
*/
17-
void psbt_set_keypath(u32 index,
19+
void psbt_output_set_keypath(u32 index,
1820
const struct ext_key *ext,
19-
struct wally_map *map_in);
21+
bool is_taproot,
22+
struct wally_psbt_output *output);
2023

2124
/* psbt_add_keypath_to_last_output - augment the last output with the
2225
* given wallet keypath
2326
*
2427
* @tx - transaction to modify
2528
* @index - child index of the wallet key
2629
* @ext - extended public key of the immediate parent of the wallet key
30+
* @is_taproot - if the output is taproot
2731
*/
2832
void psbt_add_keypath_to_last_output(struct bitcoin_tx *tx,
2933
u32 index,
30-
const struct ext_key *ext);
34+
const struct ext_key *ext,
35+
bool is_taproot);
3136

3237
#endif /* LIGHTNING_COMMON_PSBT_KEYPATH_H */

common/psbt_open.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ static const u8 *linearize_input(const tal_t *ctx,
7575
wally_psbt_input_set_final_scriptsig(&psbt->inputs[0], NULL, 0);
7676
wally_psbt_input_set_witness_script(&psbt->inputs[0], NULL, 0);
7777
wally_psbt_input_set_redeem_script(&psbt->inputs[0], NULL, 0);
78+
wally_psbt_input_set_taproot_signature(&psbt->inputs[0], NULL, 0);
79+
psbt->inputs[0].taproot_leaf_hashes.num_items = 0;
80+
psbt->inputs[0].taproot_leaf_paths.num_items = 0;
7881
psbt->inputs[0].keypaths.num_items = 0;
7982
psbt->inputs[0].signatures.num_items = 0;
8083

@@ -104,6 +107,8 @@ static const u8 *linearize_output(const tal_t *ctx,
104107

105108
/* We don't care if the keypaths change */
106109
psbt->outputs[0].keypaths.num_items = 0;
110+
psbt->outputs[0].taproot_leaf_hashes.num_items = 0;
111+
psbt->outputs[0].taproot_leaf_paths.num_items = 0;
107112
/* And you can add scripts, no problem */
108113
wally_psbt_output_set_witness_script(&psbt->outputs[0], NULL, 0);
109114
wally_psbt_output_set_redeem_script(&psbt->outputs[0], NULL, 0);

contrib/pyln-testing/pyln/testing/grpc2py.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,7 @@ def waitsendpay2py(m):
613613

614614
def newaddr2py(m):
615615
return remove_default({
616+
"p2tr": m.p2tr, # PrimitiveField in generate_composite
616617
"bech32": m.bech32, # PrimitiveField in generate_composite
617618
"p2sh_segwit": m.p2sh_segwit, # PrimitiveField in generate_composite
618619
})

doc/lightning-newaddr.7.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ RETURN VALUE
3030
[comment]: # (GENERATE-FROM-SCHEMA-START)
3131
On success, an object is returned, containing:
3232

33+
- **p2tr** (string, optional): The taproot address *(added v23.05)*
3334
- **bech32** (string, optional): The bech32 (native segwit) address
3435
- **p2sh-segwit** (string, optional): The p2sh-wrapped address **deprecated, removal in v23.11**
3536

@@ -56,4 +57,4 @@ RESOURCES
5657

5758
Main web site: <https://github.com/ElementsProject/lightning>
5859

59-
[comment]: # ( SHA256STAMP:90d550bc2290dd2ab6ee67e377679fe45230a14ba6f4608fda8e51bb6670cc07)
60+
[comment]: # ( SHA256STAMP:409fe64b6c30c0c61b8d0e6b326985a8115cd5a655c5e4ab0ad23d88f9c79ba0)

doc/schemas/newaddr.request.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"type": "string",
99
"enum": [
1010
"bech32",
11+
"p2tr",
1112
"all"
1213
]
1314
}

doc/schemas/newaddr.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"additionalProperties": false,
55
"required": [],
66
"properties": {
7+
"p2tr": {
8+
"added": "v23.05",
9+
"type": "string",
10+
"description": "The taproot address"
11+
},
712
"bech32": {
813
"type": "string",
914
"description": "The bech32 (native segwit) address"

hsmd/libhsmd.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ static void sign_our_inputs(struct utxo **utxos, struct wally_psbt *psbt)
485485
* requires the HSM to find the pubkey, and we
486486
* skip doing that until now as a bit of a reduction
487487
* of complexity in the calling code */
488-
psbt_input_add_pubkey(psbt, j, &pubkey);
488+
psbt_input_add_pubkey(psbt, j, &pubkey, utxo->scriptPubkey && is_p2tr(utxo->scriptPubkey, NULL));
489489

490490
/* It's actually a P2WSH in this case. */
491491
if (utxo->close_info && utxo->close_info->option_anchor_outputs) {
@@ -503,6 +503,8 @@ static void sign_our_inputs(struct utxo **utxos, struct wally_psbt *psbt)
503503
sizeof(privkey.secret.data),
504504
EC_FLAG_GRIND_R) != WALLY_OK) {
505505
tal_wally_end(psbt);
506+
/* Converting to v0 for log consumption */
507+
psbt_set_version(psbt, 0);
506508
hsmd_status_failed(STATUS_FAIL_INTERNAL_ERROR,
507509
"Received wally_err attempting to "
508510
"sign utxo with key %s. PSBT: %s",

lightningd/channel.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -466,13 +466,18 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
466466
channel->shutdown_wrong_funding
467467
= tal_steal(channel, shutdown_wrong_funding);
468468
channel->closing_feerate_range = NULL;
469-
if (local_shutdown_scriptpubkey)
469+
if (local_shutdown_scriptpubkey) {
470470
channel->shutdown_scriptpubkey[LOCAL]
471471
= tal_steal(channel, local_shutdown_scriptpubkey);
472-
else
472+
} else if (!chainparams->is_elements && channel_type_has(type, OPT_SHUTDOWN_ANYSEGWIT)) {
473+
channel->shutdown_scriptpubkey[LOCAL]
474+
= p2tr_for_keyidx(channel, channel->peer->ld,
475+
channel->final_key_idx);
476+
} else {
473477
channel->shutdown_scriptpubkey[LOCAL]
474478
= p2wpkh_for_keyidx(channel, channel->peer->ld,
475-
channel->final_key_idx);
479+
channel->final_key_idx);
480+
}
476481
channel->last_was_revoke = last_was_revoke;
477482
channel->last_sent_commit = tal_steal(channel, last_sent_commit);
478483
channel->first_blocknum = first_blocknum;
@@ -523,9 +528,17 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
523528
channel->state_change_cause = reason;
524529

525530
/* Make sure we see any spends using this key */
526-
txfilter_add_scriptpubkey(peer->ld->owned_txfilter,
527-
take(p2wpkh_for_keyidx(NULL, peer->ld,
528-
channel->final_key_idx)));
531+
if (!local_shutdown_scriptpubkey) {
532+
if (!chainparams->is_elements && channel_type_has(type, OPT_SHUTDOWN_ANYSEGWIT)) {
533+
txfilter_add_scriptpubkey(peer->ld->owned_txfilter,
534+
take(p2tr_for_keyidx(NULL, peer->ld,
535+
channel->final_key_idx)));
536+
} else {
537+
txfilter_add_scriptpubkey(peer->ld->owned_txfilter,
538+
take(p2wpkh_for_keyidx(NULL, peer->ld,
539+
channel->final_key_idx)));
540+
}
541+
}
529542
/* scid is NULL when opening a new channel so we don't
530543
* need to set error in that case as well */
531544
if (is_stub_scid(scid))

lightningd/dual_open_control.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,7 @@ wallet_commit_channel(struct lightningd *ld,
12771277
= tal_steal(channel, our_upfront_shutdown_script);
12781278
else
12791279
channel->shutdown_scriptpubkey[LOCAL]
1280-
= p2wpkh_for_keyidx(channel, channel->peer->ld,
1280+
= p2tr_for_keyidx(channel, channel->peer->ld,
12811281
channel->final_key_idx);
12821282

12831283
/* Can't have gotten their alias for this channel yet. */

lightningd/onchain_control.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,9 +710,10 @@ static struct bitcoin_tx *onchaind_tx_unsigned(const tal_t *ctx,
710710
bitcoin_tx_add_input(tx, &info->out, info->to_self_delay,
711711
NULL, info->out_sats, NULL, info->wscript);
712712

713+
/* FIXME should this be p2tr now? */
713714
bitcoin_tx_add_output(
714715
tx, scriptpubkey_p2wpkh(tmpctx, &final_key), NULL, info->out_sats);
715-
psbt_add_keypath_to_last_output(tx, channel->final_key_idx, &final_wallet_ext_key);
716+
psbt_add_keypath_to_last_output(tx, channel->final_key_idx, &final_wallet_ext_key, false /* is_taproot */);
716717

717718
/* Worst-case sig is 73 bytes */
718719
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(info->wscript);

lightningd/peer_control.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ u8 *p2wpkh_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx)
218218
return scriptpubkey_p2wpkh(ctx, &shutdownkey);
219219
}
220220

221+
u8 *p2tr_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx)
222+
{
223+
struct pubkey shutdownkey;
224+
225+
bip32_pubkey(ld, &shutdownkey, keyidx);
226+
227+
return scriptpubkey_p2tr(ctx, &shutdownkey);
228+
}
229+
221230
static void sign_last_tx(struct channel *channel,
222231
struct bitcoin_tx *last_tx,
223232
struct bitcoin_signature *last_sig)

0 commit comments

Comments
 (0)