common: don't abort() if wally_psbt_output_taproot_keypath_add() fails.

It fails on duplicates.  It would ideally succeed, but bug reported:

	https://github.com/ElementsProject/libwally-core/issues/509

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: JSON-RPC: `signpsbt` no longer crashes if asked to sign an already-signed PSBT with taproot paths.
This commit is contained in:
Rusty Russell
2025-11-18 14:33:04 +10:30
parent eaf7ac19c1
commit f284489c96
7 changed files with 58 additions and 27 deletions

View File

@@ -54,9 +54,11 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
assert((local_wallet_index == NULL) == (local_wallet_ext_key == NULL));
if (local_wallet_index) {
size_t script_len = tal_bytelen(script);
psbt_add_keypath_to_last_output(
tx, *local_wallet_index, local_wallet_ext_key,
is_p2tr(script, script_len, NULL));
/* Should not happen! */
if (!psbt_add_keypath_to_last_output(
tx, *local_wallet_index, local_wallet_ext_key,
is_p2tr(script, script_len, NULL)))
return tal_free(tx);
}
num_outputs++;
}

View File

@@ -3,7 +3,11 @@
#include <common/psbt_keypath.h>
#include <common/utils.h>
void psbt_output_set_keypath(u32 index, const struct ext_key *ext, bool is_taproot, struct wally_psbt_output *output) {
bool psbt_output_set_keypath(u32 index,
const struct ext_key *ext,
bool is_taproot,
struct wally_psbt_output *output)
{
u8 fingerprint[BIP32_KEY_FINGERPRINT_LEN];
if (bip32_key_get_fingerprint(
(struct ext_key *) ext, fingerprint, sizeof(fingerprint)) != WALLY_OK)
@@ -18,24 +22,29 @@ void psbt_output_set_keypath(u32 index, const struct ext_key *ext, bool is_tapro
NULL, 0,
fingerprint, sizeof(fingerprint),
path, 1) != WALLY_OK)
abort();
return false;
} else {
if (wally_psbt_output_keypath_add(output,
ext->pub_key, sizeof(ext->pub_key),
fingerprint, sizeof(fingerprint),
path, 1) != WALLY_OK)
abort();
return false;
}
return true;
}
void psbt_add_keypath_to_last_output(struct bitcoin_tx *tx,
bool psbt_add_keypath_to_last_output(struct bitcoin_tx *tx,
u32 key_index,
const struct ext_key *ext,
bool is_taproot) {
const struct ext_key *ext,
bool is_taproot)
{
size_t outndx = tx->psbt->num_outputs - 1;
bool ok;
tal_wally_start();
psbt_output_set_keypath(key_index, ext, is_taproot, &tx->psbt->outputs[outndx]);
ok = psbt_output_set_keypath(key_index, ext, is_taproot, &tx->psbt->outputs[outndx]);
tal_wally_end(tx->psbt);
return ok;
}

View File

@@ -2,6 +2,7 @@
#define LIGHTNING_COMMON_PSBT_KEYPATH_H
#include "config.h"
#include <ccan/compiler/compiler.h>
#include <ccan/short_types/short_types.h>
#include <wally_psbt.h>
@@ -15,11 +16,14 @@ struct wally_map;
* @ext - extended public key of the immediate parent of the wallet key
* @is_taproot - PSBT output has taproot script
* @output - PSBT output to set
*
* This can fail, if it's adding the same thing twice (taproot only)
*/
void psbt_output_set_keypath(u32 index,
const struct ext_key *ext,
bool is_taproot,
struct wally_psbt_output *output);
WARN_UNUSED_RESULT
bool psbt_output_set_keypath(u32 index,
const struct ext_key *ext,
bool is_taproot,
struct wally_psbt_output *output);
/* psbt_add_keypath_to_last_output - augment the last output with the
* given wallet keypath
@@ -29,9 +33,10 @@ void psbt_output_set_keypath(u32 index,
* @ext - extended public key of the immediate parent of the wallet key
* @is_taproot - if the output is taproot
*/
void psbt_add_keypath_to_last_output(struct bitcoin_tx *tx,
WARN_UNUSED_RESULT
bool psbt_add_keypath_to_last_output(struct bitcoin_tx *tx,
u32 index,
const struct ext_key *ext,
bool is_taproot);
bool is_taproot);
#endif /* LIGHTNING_COMMON_PSBT_KEYPATH_H */