Skip to content

Commit c3a5aee

Browse files
committed
psbt: add psbt_get_input_signature_type to get the type of sig required for an input
As a first cut, this uses the pre-existing logic for differentiating segwit and non-segwit inputs (the presence of a witness UTXO).
1 parent 26438eb commit c3a5aee

File tree

8 files changed

+45
-39
lines changed

8 files changed

+45
-39
lines changed

include/wally_psbt_members.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ WALLY_CORE_API int wally_psbt_get_input_unknown(const struct wally_psbt *psbt, s
6060
WALLY_CORE_API int wally_psbt_get_input_unknown_len(const struct wally_psbt *psbt, size_t index, size_t subindex, size_t *written);
6161
WALLY_CORE_API int wally_psbt_get_input_sighash(const struct wally_psbt *psbt, size_t index, size_t *written);
6262

63+
/**
64+
* Return the signature type of a PSBT input.
65+
*
66+
* :param psbt: The PSBT to get the signature type from.
67+
* :param index: The zero-based index of the input to get the signature type from.
68+
* :param value_out: Destination for the :ref:`tx-sig-type` of the input.
69+
*/
70+
WALLY_CORE_API int wally_psbt_get_input_signature_type(const struct wally_psbt *psbt, size_t index, uint32_t *value_out);
71+
6372
/**
6473
* FIXED_SIZED_OUTPUT(len, bytes_out, WALLY_TXHASH_LEN)
6574
*/

src/psbt.c

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -155,34 +155,32 @@ static const struct wally_tx_output *utxo_from_input(const struct wally_psbt *ps
155155
return NULL;
156156
}
157157

158-
/* Try to determine if a PSBT input is taproot.
159-
* TODO: We could verify that the script and field checks are in sync
160-
* here, i.e. that an input with taproot fields has a taproot script,
161-
* and return an error otherwise.
162-
*/
163-
static bool is_taproot_input(const struct wally_psbt *psbt,
164-
const struct wally_psbt_input *inp)
158+
struct wally_psbt_input *psbt_get_input_signature_type(const struct wally_psbt *psbt,
159+
size_t index, uint32_t *value_out)
165160
{
166-
if (!inp)
167-
return false;
168-
else {
169-
const struct wally_tx_output *utxo = utxo_from_input(psbt, inp);
170-
if (utxo) {
171-
/* Determine from the scriptpubkey if possible */
172-
size_t script_type;
173-
int ret = wally_scriptpubkey_get_type(utxo->script, utxo->script_len,
174-
&script_type);
175-
if (ret == WALLY_OK)
176-
return script_type == WALLY_SCRIPT_TYPE_P2TR;
177-
}
178-
/* No usable UTXO/script for this input, check for taproot fields */
179-
return inp->taproot_leaf_hashes.num_items ||
180-
inp->taproot_leaf_scripts.num_items ||
181-
inp->taproot_leaf_signatures.num_items ||
182-
wally_map_get_integer(&inp->psbt_fields, PSBT_IN_TAP_INTERNAL_KEY) ||
183-
wally_map_get_integer(&inp->psbt_fields, PSBT_IN_TAP_MERKLE_ROOT) ||
184-
wally_map_get_integer(&inp->psbt_fields, PSBT_IN_TAP_KEY_SIG);
161+
struct wally_psbt_input *inp = psbt_get_input(psbt, index);
162+
const struct wally_tx_output *utxo = utxo_from_input(psbt, inp);
163+
164+
if (value_out)
165+
*value_out = 0;
166+
if (!utxo || !value_out)
167+
return NULL;
168+
169+
if (scriptpubkey_is_p2tr(utxo->script, utxo->script_len)) {
170+
*value_out = WALLY_SIGTYPE_SW_V1;
171+
return inp;
185172
}
173+
174+
/* Otherwise, follow core and use whether a witness utxo is present */
175+
*value_out = inp->witness_utxo ? WALLY_SIGTYPE_SW_V0 : WALLY_SIGTYPE_PRE_SW;
176+
return inp;
177+
}
178+
179+
int wally_psbt_get_input_signature_type(const struct wally_psbt *psbt,
180+
size_t index, uint32_t *value_out)
181+
{
182+
struct wally_psbt_input *inp = psbt_get_input_signature_type(psbt, index, value_out);
183+
return inp ? WALLY_OK : WALLY_EINVAL;
186184
}
187185

188186
/* Set a struct member on a parent struct */
@@ -4579,12 +4577,10 @@ int wally_psbt_get_input_signature_hash(struct wally_psbt *psbt, size_t index,
45794577
unsigned char *bytes_out, size_t len)
45804578
{
45814579
struct wally_map scripts, assets, values, *assets_p;
4582-
const struct wally_psbt_input *inp = psbt_get_input(psbt, index);
45834580
size_t is_pset;
45844581
uint32_t sighash, sighash_type;
4585-
const bool is_taproot = is_taproot_input(psbt, inp);
4586-
/* FIXME: Determine segwitness in a smarter way (e.g. prevout script */
4587-
const bool is_segwit = inp && inp->witness_utxo != NULL;
4582+
const struct wally_psbt_input *inp = psbt_get_input_signature_type(psbt, index, &sighash_type);
4583+
const bool is_taproot = sighash_type == WALLY_SIGTYPE_SW_V1;
45884584
int ret;
45894585

45904586
if (!tx || !inp || flags)
@@ -4608,11 +4604,7 @@ int wally_psbt_get_input_signature_hash(struct wally_psbt *psbt, size_t index,
46084604
/* FIXME: Support script path spends */
46094605
script = NULL;
46104606
script_len = 0;
4611-
sighash_type = WALLY_SIGTYPE_SW_V1;
4612-
} else if (is_segwit)
4613-
sighash_type = WALLY_SIGTYPE_SW_V0;
4614-
else
4615-
sighash_type = WALLY_SIGTYPE_PRE_SW;
4607+
}
46164608

46174609
ret = get_signing_data(psbt, &scripts, assets_p, &values);
46184610
if (ret == WALLY_OK)
@@ -4640,9 +4632,9 @@ int wally_psbt_sign_input_bip32(struct wally_psbt *psbt,
46404632
unsigned char sig[EC_SIGNATURE_LEN + 1], der[EC_SIGNATURE_DER_MAX_LEN + 1];
46414633
unsigned char signing_key[EC_PRIVATE_KEY_LEN];
46424634
size_t sig_len = EC_SIGNATURE_LEN, der_len, pubkey_idx;
4643-
uint32_t sighash;
4644-
struct wally_psbt_input *inp = psbt_get_input(psbt, index);
4645-
const bool is_taproot = is_taproot_input(psbt, inp);
4635+
uint32_t sighash, sighash_type;
4636+
struct wally_psbt_input *inp = psbt_get_input_signature_type(psbt, index, &sighash_type);
4637+
const bool is_taproot = sighash_type == WALLY_SIGTYPE_SW_V1;
46464638
int ret;
46474639

46484640
if (!inp || !hdkey || hdkey->priv_key[0] != BIP32_FLAG_KEY_PRIVATE ||

src/swig_java/swig.i

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
809809
%returns_size_t(wally_psbt_get_input_required_locktime);
810810
%returns_size_t(wally_psbt_get_input_scriptcode);
811811
%returns_size_t(wally_psbt_get_input_scriptcode_len);
812+
%returns_size_t(wally_psbt_get_input_signature_type);
812813
%returns_size_t(wally_psbt_get_input_signing_script);
813814
%returns_size_t(wally_psbt_get_input_signing_script_len);
814815
%returns_size_t(wally_psbt_get_input_sequence);

src/test/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,7 @@ class wally_psbt(Structure):
859859
('wally_psbt_get_input_sighash', c_int, [POINTER(wally_psbt), c_size_t, c_size_t_p]),
860860
('wally_psbt_get_input_signature', c_int, [POINTER(wally_psbt), c_size_t, c_size_t, c_void_p, c_size_t, c_size_t_p]),
861861
('wally_psbt_get_input_signature_len', c_int, [POINTER(wally_psbt), c_size_t, c_size_t, c_size_t_p]),
862+
('wally_psbt_get_input_signature_type', c_int, [POINTER(wally_psbt), c_size_t, c_uint32_p]),
862863
('wally_psbt_get_input_signatures_size', c_int, [POINTER(wally_psbt), c_size_t, c_size_t_p]),
863864
('wally_psbt_get_input_taproot_internal_key', c_int, [POINTER(wally_psbt), c_size_t, c_void_p, c_size_t, c_size_t_p]),
864865
('wally_psbt_get_input_taproot_internal_key_len', c_int, [POINTER(wally_psbt), c_size_t, c_size_t_p]),

src/wasm_package/src/const.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ export const WALLY_SIGHASH_NONE = 0x02;
223223
export const WALLY_SIGHASH_RANGEPROOF = 0x40 ; /* Liquid/Elements only */
224224
export const WALLY_SIGHASH_SINGLE = 0x03;
225225
export const WALLY_SIGHASH_TR_IN_MASK = 0xc0; /* Taproot mask for determining input hash type */
226-
export const WALLY_SIGTYPE_MASK = 0xf; /* Mask for signature hash in signature hash flags */
226+
export const WALLY_SIGTYPE_MASK = 0xf; /* Mask for signature type in in flags */
227227
export const WALLY_SIGTYPE_PRE_SW = 0x1; /* Pre-segwit signature hash */
228228
export const WALLY_SIGTYPE_SW_V0 = 0x2; /* Segwit v0 signature hash */
229229
export const WALLY_SIGTYPE_SW_V1 = 0x3; /* Segwit v1 (taproot) signature hash */

src/wasm_package/src/functions.js

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

src/wasm_package/src/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ export function psbt_get_input_sequence(psbt: Ref_wally_psbt, index: number): nu
333333
export function psbt_get_input_sighash(psbt: Ref_wally_psbt, index: number): number;
334334
export function psbt_get_input_signature_hash(psbt: Ref_wally_psbt, index: number, tx: Ref_wally_tx, script: Buffer|Uint8Array, flags: number): Buffer;
335335
export function psbt_get_input_signature_len(psbt: Ref_wally_psbt, index: number, subindex: number): number;
336+
export function psbt_get_input_signature_type(psbt: Ref_wally_psbt, index: number): number;
336337
export function psbt_get_input_signatures_size(psbt: Ref_wally_psbt, index: number): number;
337338
export function psbt_get_input_signing_script_len(psbt: Ref_wally_psbt, index: number): number;
338339
export function psbt_get_input_taproot_internal_key_len(psbt: Ref_wally_psbt, index: number): number;

tools/wasm_exports.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ EXPORTED_FUNCTIONS="['_malloc','_free','_bip32_key_free' \
247247
,'_wally_psbt_get_input_signature' \
248248
,'_wally_psbt_get_input_signature_hash' \
249249
,'_wally_psbt_get_input_signature_len' \
250+
,'_wally_psbt_get_input_signature_type' \
250251
,'_wally_psbt_get_input_signatures_size' \
251252
,'_wally_psbt_get_input_signing_script' \
252253
,'_wally_psbt_get_input_signing_script_len' \

0 commit comments

Comments
 (0)