From fa0d9b6d2a452c867210210d180d546fde053886 Mon Sep 17 00:00:00 2001 From: Dusty Daemon Date: Mon, 11 Nov 2024 11:00:31 +1030 Subject: [PATCH] psbt: Add ability to extract signature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A routine for getting a signature back out of an input’s list of pending signatures via pubkey search. This is needed for certain kinds of restarts as we lose our peer’s signature from memory but a copy is kept in the PSBT. --- bitcoin/psbt.c | 30 ++++++++++++++++++++++++++++++ bitcoin/psbt.h | 8 ++++++++ bitcoin/test/run-psbt-from-tx.c | 3 +++ 3 files changed, 41 insertions(+) diff --git a/bitcoin/psbt.c b/bitcoin/psbt.c index 5a1a24946..7afb5a4fe 100644 --- a/bitcoin/psbt.c +++ b/bitcoin/psbt.c @@ -311,6 +311,36 @@ bool psbt_input_have_signature(const struct wally_psbt *psbt, return ok; } +bool psbt_input_get_signature(const tal_t *ctx, + const struct wally_psbt *psbt, + size_t in, + const struct pubkey *pubkey, + struct bitcoin_signature **sig) +{ + u8 pk_der[PUBKEY_CMPR_LEN]; + size_t index_plus_one; + struct wally_map_item *item; + bool ok; + + assert(in < psbt->num_inputs); + + pubkey_to_der(pk_der, pubkey); + *sig = NULL; + + ok = wally_psbt_input_find_signature(&psbt->inputs[in], pk_der, + sizeof(pk_der), + &index_plus_one) == WALLY_OK; + if (ok) { + item = &psbt->inputs[in].signatures.items[index_plus_one - 1]; + *sig = tal(ctx, struct bitcoin_signature); + if (!signature_from_der(item->value, item->value_len, *sig)) { + *sig = tal_free(*sig); + return false; + } + } + return ok; +} + void psbt_input_set_wit_utxo(struct wally_psbt *psbt, size_t in, const u8 *scriptPubkey, struct amount_sat amt) { diff --git a/bitcoin/psbt.h b/bitcoin/psbt.h index 31abd2d42..8d9eda2a0 100644 --- a/bitcoin/psbt.h +++ b/bitcoin/psbt.h @@ -186,6 +186,14 @@ WARN_UNUSED_RESULT bool psbt_input_have_signature(const struct wally_psbt *psbt, const struct pubkey *pubkey, bool *signature_found); +/* Returns false on error. On success *sig is set to the signature otherwise + * *sig is set to NULL. */ +WARN_UNUSED_RESULT bool psbt_input_get_signature(const tal_t *ctx, + const struct wally_psbt *psbt, + size_t in, + const struct pubkey *pubkey, + struct bitcoin_signature **sig); + void psbt_input_set_witscript(struct wally_psbt *psbt, size_t in, const u8 *wscript); /* psbt_input_set_unknown - Set the given Key-Value in the psbt's input keymap diff --git a/bitcoin/test/run-psbt-from-tx.c b/bitcoin/test/run-psbt-from-tx.c index 3c71675e5..85e2ca677 100644 --- a/bitcoin/test/run-psbt-from-tx.c +++ b/bitcoin/test/run-psbt-from-tx.c @@ -68,6 +68,9 @@ void sha256_double(struct sha256_double *shadouble UNNEEDED, const void *p UNNEE /* Generated stub for signature_to_der */ size_t signature_to_der(u8 der[73] UNNEEDED, const struct bitcoin_signature *sig UNNEEDED) { fprintf(stderr, "signature_to_der called!\n"); abort(); } +/* Generated stub for signature_to_der */ +bool signature_from_der(const u8 *der UNNEEDED, size_t len UNNEEDED, struct bitcoin_signature *sig UNNEEDED) +{ fprintf(stderr, "signature_from_der called!\n"); abort(); } /* Generated stub for towire_sha256_double */ void towire_sha256_double(u8 **pptr UNNEEDED, const struct sha256_double *sha256d UNNEEDED) { fprintf(stderr, "towire_sha256_double called!\n"); abort(); }