diff --git a/bitcoin/psbt.c b/bitcoin/psbt.c index a57d5514b..5c8a7b4eb 100644 --- a/bitcoin/psbt.c +++ b/bitcoin/psbt.c @@ -463,3 +463,34 @@ struct wally_psbt *fromwire_wally_psbt(const tal_t *ctx, return psbt; } +/* This only works on a non-final psbt because we're ALL SEGWIT! */ +void psbt_txid(const struct wally_psbt *psbt, struct bitcoin_txid *txid, + struct wally_tx **wtx) +{ + struct wally_tx *tx; + + /* You can *almost* take txid of global tx. But @niftynei thought + * about this far more than me and pointed out that P2SH + * inputs would not be represented, so here we go. */ + + wally_tx_clone_alloc(psbt->tx, 0, &tx); + + for (size_t i = 0; i < tx->num_inputs; i++) { + u8 *script; + if (!psbt->inputs[i].redeem_script) + continue; + + /* P2SH requires push of the redeemscript, from libwally src */ + script = tal_arr(tmpctx, u8, 0); + script_push_bytes(&script, + psbt->inputs[i].redeem_script, + psbt->inputs[i].redeem_script_len); + wally_tx_set_input_script(tx, i, script, tal_bytelen(script)); + } + + wally_txid(tx, txid); + if (wtx) + *wtx = tx; + else + wally_tx_free(tx); +} diff --git a/bitcoin/psbt.h b/bitcoin/psbt.h index 512bdd9b5..ff154d985 100644 --- a/bitcoin/psbt.h +++ b/bitcoin/psbt.h @@ -13,6 +13,7 @@ struct wally_tx; struct amount_asset; struct amount_sat; struct bitcoin_signature; +struct bitcoin_txid; struct pubkey; void psbt_destroy(struct wally_psbt *psbt); @@ -31,6 +32,15 @@ struct wally_psbt *new_psbt(const tal_t *ctx, */ bool psbt_is_finalized(const struct wally_psbt *psbt); +/** + * psbt_txid - get the txid of the psbt (what it would be after finalization) + * @psbt: the psbt. + * @txid: the transaction id (output) + * @wtx: if non-NULL, returns a copy of the transaction (caller must wally_tx_free). + */ +void psbt_txid(const struct wally_psbt *psbt, struct bitcoin_txid *txid, + struct wally_tx **wtx); + struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place); struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, diff --git a/bitcoin/test/run-bitcoin_block_from_hex.c b/bitcoin/test/run-bitcoin_block_from_hex.c index 384142cee..97a80d798 100644 --- a/bitcoin/test/run-bitcoin_block_from_hex.c +++ b/bitcoin/test/run-bitcoin_block_from_hex.c @@ -78,6 +78,9 @@ void pubkey_to_der(u8 der[PUBKEY_CMPR_LEN] UNNEEDED, const struct pubkey *key UN /* Generated stub for pubkey_to_hash160 */ void pubkey_to_hash160(const struct pubkey *pk UNNEEDED, struct ripemd160 *hash UNNEEDED) { fprintf(stderr, "pubkey_to_hash160 called!\n"); abort(); } +/* Generated stub for script_push_bytes */ +void script_push_bytes(u8 **scriptp UNNEEDED, const void *mem UNNEEDED, size_t len UNNEEDED) +{ fprintf(stderr, "script_push_bytes called!\n"); abort(); } /* Generated stub for scriptpubkey_p2wsh */ u8 *scriptpubkey_p2wsh(const tal_t *ctx UNNEEDED, const u8 *witnessscript UNNEEDED) { fprintf(stderr, "scriptpubkey_p2wsh called!\n"); abort(); } diff --git a/bitcoin/test/run-tx-encode.c b/bitcoin/test/run-tx-encode.c index 3c67638b7..e46718449 100644 --- a/bitcoin/test/run-tx-encode.c +++ b/bitcoin/test/run-tx-encode.c @@ -79,6 +79,9 @@ void pubkey_to_der(u8 der[PUBKEY_CMPR_LEN] UNNEEDED, const struct pubkey *key UN /* Generated stub for pubkey_to_hash160 */ void pubkey_to_hash160(const struct pubkey *pk UNNEEDED, struct ripemd160 *hash UNNEEDED) { fprintf(stderr, "pubkey_to_hash160 called!\n"); abort(); } +/* Generated stub for script_push_bytes */ +void script_push_bytes(u8 **scriptp UNNEEDED, const void *mem UNNEEDED, size_t len UNNEEDED) +{ fprintf(stderr, "script_push_bytes called!\n"); abort(); } /* Generated stub for scriptpubkey_p2wsh */ u8 *scriptpubkey_p2wsh(const tal_t *ctx UNNEEDED, const u8 *witnessscript UNNEEDED) { fprintf(stderr, "scriptpubkey_p2wsh called!\n"); abort(); }