diff --git a/bitcoin/psbt.c b/bitcoin/psbt.c index f3c34f1b2549..56706fb54dc5 100644 --- a/bitcoin/psbt.c +++ b/bitcoin/psbt.c @@ -1,6 +1,12 @@ #include #include +#include +#include +#include #include +#include +#include +#include #include #include #include @@ -14,6 +20,18 @@ memmove((arr) + (pos), (arr) + (pos) + 1, \ sizeof(*(arr)) * ((num) - ((pos) + 1))) +/* FIXME: someday this will break, because it's been exposed in libwally */ +int wally_psbt_clone(const struct wally_psbt *psbt, struct wally_psbt **output) +{ + int ret; + size_t byte_len; + const u8 *bytes = psbt_get_bytes(NULL, psbt, &byte_len); + + ret = wally_psbt_from_bytes(bytes, byte_len, output); + tal_free(bytes); + return ret; +} + void psbt_destroy(struct wally_psbt *psbt) { wally_psbt_free(psbt); @@ -50,9 +68,26 @@ struct wally_psbt *new_psbt(const tal_t *ctx, const struct wally_tx *wtx) /* set the scripts + witnesses back */ for (size_t i = 0; i < wtx->num_inputs; i++) { + int wally_err; + wtx->inputs[i].script = (unsigned char *)scripts[i]; wtx->inputs[i].script_len = script_lens[i]; wtx->inputs[i].witness = witnesses[i]; + + /* add these scripts + witnesses to the psbt */ + if (scripts[i]) { + wally_err = + wally_psbt_input_set_final_script_sig(&psbt->inputs[i], + (unsigned char *)scripts[i], + script_lens[i]); + assert(wally_err == WALLY_OK); + } + if (witnesses[i]) { + wally_err = + wally_psbt_input_set_final_witness(&psbt->inputs[i], + witnesses[i]); + assert(wally_err == WALLY_OK); + } } tal_free(witnesses); @@ -62,6 +97,17 @@ struct wally_psbt *new_psbt(const tal_t *ctx, const struct wally_tx *wtx) return tal_steal(ctx, psbt); } +bool psbt_is_finalized(struct wally_psbt *psbt) +{ + for (size_t i = 0; i < psbt->num_inputs; i++) { + if (!psbt->inputs[i].final_script_sig && + !psbt->inputs[i].final_witness) + return false; + } + + return true; +} + struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, struct wally_tx_input *input, size_t insert_at) @@ -72,6 +118,7 @@ struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, tx = psbt->tx; assert(insert_at <= tx->num_inputs); wally_tx_add_input(tx, input); + tmp_in = tx->inputs[tx->num_inputs - 1]; MAKE_ROOM(tx->inputs, insert_at, tx->num_inputs); tx->inputs[insert_at] = tmp_in; @@ -138,22 +185,169 @@ void psbt_rm_output(struct wally_psbt *psbt, psbt->num_outputs -= 1; } +void psbt_input_add_pubkey(struct wally_psbt *psbt, size_t in, + const struct pubkey *pubkey) +{ + int wally_err; + u32 empty_path[1] = {0}; + unsigned char fingerprint[4]; + struct ripemd160 hash; + u8 pk_der[PUBKEY_CMPR_LEN]; + + assert(in < psbt->num_inputs); + + /* Find the key identifier fingerprint: + * the first 32 bits of the identifier, where the identifier + * is the hash160 of the ECDSA serialized public key + * https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#key-identifiers + * */ + pubkey_to_hash160(pubkey, &hash); + memcpy(fingerprint, hash.u.u8, sizeof(fingerprint)); + + /* we serialize the compressed version of the key, wally likes this */ + pubkey_to_der(pk_der, pubkey); + + if (!psbt->inputs[in].keypaths) + if (wally_keypath_map_init_alloc(1, &psbt->inputs[in].keypaths) != WALLY_OK) + abort(); + + wally_err = wally_add_new_keypath(psbt->inputs[in].keypaths, + pk_der, sizeof(pk_der), + fingerprint, sizeof(fingerprint), + empty_path, ARRAY_SIZE(empty_path)); + + assert(wally_err == WALLY_OK); +} + +void psbt_input_set_partial_sig(struct wally_psbt *psbt, size_t in, + const struct pubkey *pubkey, + const struct bitcoin_signature *sig) +{ + int wally_err; + u8 pk_der[PUBKEY_CMPR_LEN]; + + assert(in < psbt->num_inputs); + if (!psbt->inputs[in].partial_sigs) + if (wally_partial_sigs_map_init_alloc(1, &psbt->inputs[in].partial_sigs) != WALLY_OK) + abort(); + + /* we serialize the compressed version of the key, wally likes this */ + pubkey_to_der(pk_der, pubkey); + wally_err = wally_add_new_partial_sig(psbt->inputs[in].partial_sigs, + pk_der, sizeof(pk_der), + cast_const(unsigned char *, sig->s.data), + sizeof(sig->s.data)); + assert(wally_err == WALLY_OK); + + wally_err = wally_psbt_input_set_sighash_type(&psbt->inputs[in], + sig->sighash_type); + assert(wally_err == WALLY_OK); +} + +void psbt_input_set_prev_utxo(struct wally_psbt *psbt, size_t in, + const u8 *scriptPubkey, struct amount_sat amt) +{ + struct wally_tx_output *prev_out; + int wally_err; + u8 *scriptpk; + + assert(psbt->num_inputs > in); + if (scriptPubkey) { + assert(is_p2wsh(scriptPubkey, NULL) || is_p2wpkh(scriptPubkey, NULL) + || is_p2sh(scriptPubkey, NULL)); + scriptpk = cast_const(u8 *, scriptPubkey); + } else { + /* Adding a NULL scriptpubkey is an error, *however* there is the + * possiblity we're spending a UTXO that we didn't save the + * scriptpubkey data for. in this case we set it to an 'empty' + * or zero-len script */ + scriptpk = tal_arr(psbt, u8, 1); + scriptpk[0] = 0x00; + } + + wally_err = wally_tx_output_init_alloc(amt.satoshis, /* Raw: type conv */ + scriptpk, + tal_bytelen(scriptpk), + &prev_out); + assert(wally_err == WALLY_OK); + wally_err = wally_psbt_input_set_witness_utxo(&psbt->inputs[in], + prev_out); + assert(wally_err == WALLY_OK); + tal_steal(psbt, psbt->inputs[in].witness_utxo); +} + +void psbt_input_set_prev_utxo_wscript(struct wally_psbt *psbt, size_t in, + const u8 *wscript, struct amount_sat amt) +{ + int wally_err; + const u8 *scriptPubkey; + + if (wscript) { + scriptPubkey = scriptpubkey_p2wsh(psbt, wscript); + wally_err = wally_psbt_input_set_witness_script(&psbt->inputs[in], + cast_const(u8 *, wscript), + tal_bytelen(wscript)); + assert(wally_err == WALLY_OK); + } else + scriptPubkey = NULL; + psbt_input_set_prev_utxo(psbt, in, scriptPubkey, amt); +} + +struct amount_sat psbt_input_get_amount(struct wally_psbt *psbt, + size_t in) +{ + struct amount_sat val; + assert(in < psbt->num_inputs); + if (psbt->inputs[in].witness_utxo) { + val.satoshis = psbt->inputs[in].witness_utxo->satoshi; /* Raw: type conversion */ + } else if (psbt->inputs[in].non_witness_utxo) { + int idx = psbt->tx->inputs[in].index; + struct wally_tx *prev_tx = psbt->inputs[in].non_witness_utxo; + val.satoshis = prev_tx->outputs[idx].satoshi; /* Raw: type conversion */ + } else + abort(); + + return val; +} + +const u8 *psbt_get_bytes(const tal_t *ctx, const struct wally_psbt *psbt, + size_t *bytes_written) +{ + /* the libwally API doesn't do anything helpful for allocating + * things here -- to compensate we do a single shot large alloc + */ + size_t room = 1024 * 1000; + u8 *pbt_bytes = tal_arr(ctx, u8, room); + if (wally_psbt_to_bytes(psbt, pbt_bytes, room, bytes_written) != WALLY_OK) { + /* something went wrong. bad libwally ?? */ + abort(); + } + tal_resize(&pbt_bytes, *bytes_written); + return pbt_bytes; +} + +struct wally_psbt *psbt_from_bytes(const tal_t *ctx, const u8 *bytes, + size_t byte_len) +{ + struct wally_psbt *psbt; + + if (wally_psbt_from_bytes(bytes, byte_len, &psbt) != WALLY_OK) + return NULL; + + /* We promised it would be owned by ctx: libwally uses a dummy owner */ + tal_steal(ctx, psbt); + tal_add_destructor(psbt, psbt_destroy); + return psbt; +} + void towire_psbt(u8 **pptr, const struct wally_psbt *psbt) { /* Let's include the PSBT bytes */ - for (size_t room = 1024; room < 1024 * 1000; room *= 2) { - u8 *pbt_bytes = tal_arr(NULL, u8, room); - size_t bytes_written; - if (wally_psbt_to_bytes(psbt, pbt_bytes, room, &bytes_written) == WALLY_OK) { - towire_u32(pptr, bytes_written); - towire_u8_array(pptr, pbt_bytes, bytes_written); - tal_free(pbt_bytes); - return; - } - tal_free(pbt_bytes); - } - /* PSBT is too big */ - abort(); + size_t bytes_written; + const u8 *pbt_bytes = psbt_get_bytes(NULL, psbt, &bytes_written); + towire_u32(pptr, bytes_written); + towire_u8_array(pptr, pbt_bytes, bytes_written); + tal_free(pbt_bytes); } struct wally_psbt *fromwire_psbt(const tal_t *ctx, @@ -168,13 +362,10 @@ struct wally_psbt *fromwire_psbt(const tal_t *ctx, if (!psbt_buf) return NULL; - if (wally_psbt_from_bytes(psbt_buf, psbt_byte_len, &psbt) != WALLY_OK) + psbt = psbt_from_bytes(ctx, psbt_buf, psbt_byte_len); + if (!psbt) return fromwire_fail(cursor, max); - /* We promised it would be owned by ctx: libwally uses a dummy owner */ - tal_steal(ctx, psbt); - tal_add_destructor(psbt, psbt_destroy); - #if DEVELOPER /* Re-marshall for sanity check! */ u8 *tmpbuf = tal_arr(NULL, u8, psbt_byte_len); diff --git a/bitcoin/psbt.h b/bitcoin/psbt.h index f38008544b7a..218125c2453d 100644 --- a/bitcoin/psbt.h +++ b/bitcoin/psbt.h @@ -10,12 +10,28 @@ struct wally_tx_output; struct wally_psbt; struct wally_psbt_input; struct wally_tx; +struct amount_sat; +struct bitcoin_signature; +struct pubkey; + +int wally_psbt_clone(const struct wally_psbt *psbt, struct wally_psbt **output); void psbt_destroy(struct wally_psbt *psbt); struct wally_psbt *new_psbt(const tal_t *ctx, const struct wally_tx *wtx); +/** + * psbt_is_finalized - Check if tx is ready to be extracted + * + * The libwally library requires a transaction be *ready* for + * extraction before it will add/append all of the sigs/witnesses + * onto the global transaction. This check returns true if + * a psbt has the finalized script sig and/or witness data populated + * for such a call + */ +bool psbt_is_finalized(struct wally_psbt *psbt); + struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt, struct wally_tx_input *input, size_t insert_at); @@ -30,6 +46,24 @@ struct wally_psbt_output *psbt_add_output(struct wally_psbt *psbt, void psbt_rm_output(struct wally_psbt *psbt, size_t remove_at); +void psbt_input_add_pubkey(struct wally_psbt *psbt, size_t in, + const struct pubkey *pubkey); + +void psbt_input_set_partial_sig(struct wally_psbt *psbt, size_t in, + const struct pubkey *pubkey, + const struct bitcoin_signature *sig); + +void psbt_input_set_prev_utxo(struct wally_psbt *psbt, size_t in, + const u8 *wscript, struct amount_sat amt); +void psbt_input_set_prev_utxo_wscript(struct wally_psbt *psbt, size_t in, + const u8 *wscript, struct amount_sat amt); +struct amount_sat psbt_input_get_amount(struct wally_psbt *psbt, + size_t in); + +const u8 *psbt_get_bytes(const tal_t *ctx, const struct wally_psbt *psbt, + size_t *bytes_written); +struct wally_psbt *psbt_from_bytes(const tal_t *ctx, const u8 *bytes, + size_t byte_len); void towire_psbt(u8 **pptr, const struct wally_psbt *psbt); struct wally_psbt *fromwire_psbt(const tal_t *ctx, const u8 **curosr, size_t *max); diff --git a/bitcoin/signature.c b/bitcoin/signature.c index ffed8aaac990..d8c6306c31b4 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -5,6 +5,7 @@ #include "signature.h" #include "tx.h" #include +#include #include #include #include @@ -119,11 +120,15 @@ void bitcoin_tx_hash_for_sig(const struct bitcoin_tx *tx, unsigned int in, { int ret; u8 value[9]; - u64 satoshis = tx->input_amounts[in]->satoshis /* Raw: sig-helper */; + u64 input_val_sats; + struct amount_sat input_amt; int flags = WALLY_TX_FLAG_USE_WITNESS; + input_amt = psbt_input_get_amount(tx->psbt, in); + input_val_sats = input_amt.satoshis; /* Raw: type conversion */ + if (is_elements(chainparams)) { - ret = wally_tx_confidential_value_from_satoshi(satoshis, value, sizeof(value)); + ret = wally_tx_confidential_value_from_satoshi(input_val_sats, value, sizeof(value)); assert(ret == WALLY_OK); ret = wally_tx_get_elements_signature_hash( tx->wtx, in, script, tal_bytelen(script), value, @@ -132,7 +137,7 @@ void bitcoin_tx_hash_for_sig(const struct bitcoin_tx *tx, unsigned int in, assert(ret == WALLY_OK); } else { ret = wally_tx_get_btc_signature_hash( - tx->wtx, in, script, tal_bytelen(script), satoshis, + tx->wtx, in, script, tal_bytelen(script), input_val_sats, sighash_type, flags, dest->sha.u.u8, sizeof(*dest)); assert(ret == WALLY_OK); } diff --git a/bitcoin/test/run-bitcoin_block_from_hex.c b/bitcoin/test/run-bitcoin_block_from_hex.c index a2cbc1923a9a..6cf84bc2fcc5 100644 --- a/bitcoin/test/run-bitcoin_block_from_hex.c +++ b/bitcoin/test/run-bitcoin_block_from_hex.c @@ -49,6 +49,24 @@ u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) /* Generated stub for fromwire_u32 */ u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u32 called!\n"); abort(); } +/* Generated stub for is_p2sh */ +bool is_p2sh(const u8 *script UNNEEDED, struct ripemd160 *addr UNNEEDED) +{ fprintf(stderr, "is_p2sh called!\n"); abort(); } +/* Generated stub for is_p2wpkh */ +bool is_p2wpkh(const u8 *script UNNEEDED, struct bitcoin_address *addr UNNEEDED) +{ fprintf(stderr, "is_p2wpkh called!\n"); abort(); } +/* Generated stub for is_p2wsh */ +bool is_p2wsh(const u8 *script UNNEEDED, struct sha256 *addr UNNEEDED) +{ fprintf(stderr, "is_p2wsh called!\n"); abort(); } +/* Generated stub for pubkey_to_der */ +void pubkey_to_der(u8 der[PUBKEY_CMPR_LEN] UNNEEDED, const struct pubkey *key UNNEEDED) +{ fprintf(stderr, "pubkey_to_der called!\n"); abort(); } +/* 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 scriptpubkey_p2wsh */ +u8 *scriptpubkey_p2wsh(const tal_t *ctx UNNEEDED, const u8 *witnessscript UNNEEDED) +{ fprintf(stderr, "scriptpubkey_p2wsh called!\n"); abort(); } /* Generated stub for towire_amount_sat */ void towire_amount_sat(u8 **pptr UNNEEDED, const struct amount_sat sat UNNEEDED) { fprintf(stderr, "towire_amount_sat called!\n"); abort(); } diff --git a/bitcoin/test/run-tx-encode.c b/bitcoin/test/run-tx-encode.c index 934200628ef9..6bc269a1d029 100644 --- a/bitcoin/test/run-tx-encode.c +++ b/bitcoin/test/run-tx-encode.c @@ -50,6 +50,24 @@ u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) /* Generated stub for fromwire_u32 */ u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u32 called!\n"); abort(); } +/* Generated stub for is_p2sh */ +bool is_p2sh(const u8 *script UNNEEDED, struct ripemd160 *addr UNNEEDED) +{ fprintf(stderr, "is_p2sh called!\n"); abort(); } +/* Generated stub for is_p2wpkh */ +bool is_p2wpkh(const u8 *script UNNEEDED, struct bitcoin_address *addr UNNEEDED) +{ fprintf(stderr, "is_p2wpkh called!\n"); abort(); } +/* Generated stub for is_p2wsh */ +bool is_p2wsh(const u8 *script UNNEEDED, struct sha256 *addr UNNEEDED) +{ fprintf(stderr, "is_p2wsh called!\n"); abort(); } +/* Generated stub for pubkey_to_der */ +void pubkey_to_der(u8 der[PUBKEY_CMPR_LEN] UNNEEDED, const struct pubkey *key UNNEEDED) +{ fprintf(stderr, "pubkey_to_der called!\n"); abort(); } +/* 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 scriptpubkey_p2wsh */ +u8 *scriptpubkey_p2wsh(const tal_t *ctx UNNEEDED, const u8 *witnessscript UNNEEDED) +{ fprintf(stderr, "scriptpubkey_p2wsh called!\n"); abort(); } /* Generated stub for towire_amount_sat */ void towire_amount_sat(u8 **pptr UNNEEDED, const struct amount_sat sat UNNEEDED) { fprintf(stderr, "towire_amount_sat called!\n"); abort(); } diff --git a/bitcoin/tx.c b/bitcoin/tx.c index fe25cc355314..2dc66c6c7756 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,21 @@ #define SEGREGATED_WITNESS_FLAG 0x1 +/* FIXME: When wally exposes this, we will clash and can remove this one */ +int wally_tx_clone(struct wally_tx *tx, struct wally_tx **output) +{ + u8 *txlin = linearize_wtx(NULL, tx); + int flags = WALLY_TX_FLAG_USE_WITNESS; + int ret; + + if (chainparams->is_elements) + flags |= WALLY_TX_FLAG_USE_ELEMENTS; + + ret = wally_tx_from_bytes(txlin, tal_bytelen(txlin), flags, output); + tal_free(txlin); + return ret; +} + int bitcoin_tx_add_output(struct bitcoin_tx *tx, const u8 *script, u8 *wscript, struct amount_sat amount) { @@ -102,18 +118,15 @@ struct amount_sat bitcoin_tx_compute_fee_w_inputs(const struct bitcoin_tx *tx, /** * Compute how much fee we are actually sending with this transaction. - * Note that using this with a transaction without the input_amounts - * initialized/populated is an error. */ struct amount_sat bitcoin_tx_compute_fee(const struct bitcoin_tx *tx) { - struct amount_sat input_total = AMOUNT_SAT(0); + struct amount_sat input_total = AMOUNT_SAT(0), input_amt; bool ok; - for (size_t i = 0; i < tal_count(tx->input_amounts); i++) { - assert(tx->input_amounts[i]); - ok = amount_sat_add(&input_total, input_total, - *tx->input_amounts[i]); + for (size_t i = 0; i < tx->psbt->num_inputs; i++) { + input_amt = psbt_input_get_amount(tx->psbt, i); + ok = amount_sat_add(&input_total, input_total, input_amt); assert(ok); } @@ -153,31 +166,52 @@ static int elements_tx_add_fee_output(struct bitcoin_tx *tx) } } +void bitcoin_tx_set_locktime(struct bitcoin_tx *tx, u32 locktime) +{ + tx->wtx->locktime = locktime; + tx->psbt->tx->locktime = locktime; +} + int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid, - u32 outnum, u32 sequence, - struct amount_sat amount, u8 *script) + u32 outnum, u32 sequence, const u8 *scriptSig, + struct amount_sat amount, const u8 *scriptPubkey, + const u8 *input_wscript) { struct wally_tx_input *input; + int wally_err; size_t i; assert(tx->wtx != NULL); i = tx->wtx->num_inputs; - wally_tx_input_init_alloc(txid->shad.sha.u.u8, - sizeof(struct bitcoin_txid), outnum, sequence, - script, tal_bytelen(script), - NULL /* Empty witness stack */, &input); + wally_err = wally_tx_input_init_alloc(txid->shad.sha.u.u8, + sizeof(struct bitcoin_txid), + outnum, sequence, + scriptSig, tal_bytelen(scriptSig), + NULL /* Empty witness stack */, + &input); + assert(wally_err == WALLY_OK); input->features = chainparams->is_elements ? WALLY_TX_IS_ELEMENTS : 0; wally_tx_add_input(tx->wtx, input); psbt_add_input(tx->psbt, input, i); - wally_tx_input_free(input); - /* Now store the input amount if we know it, so we can sign later */ - if (tal_count(tx->input_amounts) < tx->wtx->num_inputs) - tal_resize(&tx->input_amounts, tx->wtx->num_inputs); - - tx->input_amounts[i] = tal_free(tx->input_amounts[i]); - tx->input_amounts[i] = tal_dup(tx, struct amount_sat, &amount); + if (input_wscript) { + /* Add the prev output's data into the PSBT struct */ + psbt_input_set_prev_utxo_wscript(tx->psbt, i, input_wscript, amount); + } else if (scriptPubkey) { + if (is_p2wsh(scriptPubkey, NULL) || is_p2wpkh(scriptPubkey, NULL) || + /* FIXME: assert that p2sh inputs are witness/are accompanied by a redeemscript+witnessscript */ + is_p2sh(scriptPubkey, NULL)) { + /* the only way to get here currently with a p2sh script is via a p2sh-p2wpkh script + * that we've created ...*/ + /* Relevant section from bip-0174, emphasis mine: + * ** Value: The entire transaction output in network serialization which the current input spends from. + * This should only be present for inputs which spend segwit outputs, _including P2SH embedded ones._ + */ + psbt_input_set_prev_utxo(tx->psbt, i, scriptPubkey, amount); + } + } + wally_tx_input_free(input); return i; } @@ -188,9 +222,6 @@ bool bitcoin_tx_check(const struct bitcoin_tx *tx) size_t written; int flags = WALLY_TX_FLAG_USE_WITNESS; - if (tal_count(tx->input_amounts) != tx->wtx->num_inputs) - return false; - if (wally_tx_get_length(tx->wtx, flags, &written) != WALLY_OK) return false; @@ -278,7 +309,6 @@ void bitcoin_tx_input_set_witness(struct bitcoin_tx *tx, int innum, { struct wally_tx_witness_stack *stack = NULL; size_t stack_size = tal_count(witness); - struct wally_psbt_input *in; /* Free any lingering witness */ if (witness) { @@ -290,17 +320,21 @@ void bitcoin_tx_input_set_witness(struct bitcoin_tx *tx, int innum, wally_tx_set_input_witness(tx->wtx, innum, stack); /* Also add to the psbt */ - if (stack) { - assert(innum < tx->psbt->num_inputs); - in = &tx->psbt->inputs[innum]; - wally_psbt_input_set_final_witness(in, stack); + if (stack) + wally_psbt_input_set_final_witness(&tx->psbt->inputs[innum], stack); + else { + /* FIXME: libwally-psbt doesn't allow 'unsetting' of witness via + * the set method at the moment, so we do it manually*/ + struct wally_psbt_input *in = &tx->psbt->inputs[innum]; + if (in->final_witness) + wally_tx_witness_stack_free(in->final_witness); + in->final_witness = NULL; } if (stack) wally_tx_witness_stack_free(stack); if (taken(witness)) tal_free(witness); - } void bitcoin_tx_input_set_script(struct bitcoin_tx *tx, int innum, u8 *script) @@ -436,7 +470,6 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, &tx->wtx); tal_add_destructor(tx, bitcoin_tx_destroy); - tx->input_amounts = tal_arrz(tx, struct amount_sat*, input_count); tx->wtx->locktime = nlocktime; tx->wtx->version = 2; tx->chainparams = chainparams; @@ -447,11 +480,7 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, void bitcoin_tx_finalize(struct bitcoin_tx *tx) { - size_t num_inputs; elements_tx_add_fee_output(tx); - - num_inputs = tx->wtx->num_inputs; - tal_resize(&tx->input_amounts, num_inputs); assert(bitcoin_tx_check(tx)); } @@ -468,6 +497,38 @@ char *bitcoin_tx_to_psbt_base64(const tal_t *ctx, struct bitcoin_tx *tx) return ret_val; } +struct bitcoin_tx *bitcoin_tx_with_psbt(const tal_t *ctx, struct wally_psbt *psbt STEALS) +{ + struct wally_psbt *tmppsbt; + struct bitcoin_tx *tx = bitcoin_tx(ctx, chainparams, + psbt->tx->num_inputs, + psbt->tx->num_outputs, + psbt->tx->locktime); + wally_tx_free(tx->wtx); + + /* We want the 'finalized' tx since that includes any signature + * data, not the global tx. But 'finalizing' a tx destroys some fields + * so we 'clone' it first and then finalize it */ + if (wally_psbt_clone(psbt, &tmppsbt) != WALLY_OK) + abort(); + + if (wally_finalize_psbt(tmppsbt) != WALLY_OK) + abort(); + + if (psbt_is_finalized(tmppsbt)) { + if (wally_extract_psbt(tmppsbt, &tx->wtx) != WALLY_OK) + abort(); + } else if (wally_tx_clone(psbt->tx, &tx->wtx) != WALLY_OK) + abort(); + + + wally_psbt_free(tmppsbt); + + tal_free(tx->psbt); + tx->psbt = tal_steal(tx, psbt); + return tx; +} + struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, const u8 **cursor, size_t *max) { @@ -494,9 +555,6 @@ struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, const u8 **cursor, wally_tx_get_length(tx->wtx, flags & ~WALLY_TX_FLAG_USE_ELEMENTS, &wsize); - /* We don't know the input amounts yet, so set them all to NULL */ - tx->input_amounts = - tal_arrz(tx, struct amount_sat *, tx->wtx->inputs_allocation_len); tx->chainparams = chainparams; tx->psbt = new_psbt(tx, tx->wtx); @@ -533,9 +591,6 @@ struct bitcoin_tx *bitcoin_tx_from_hex(const tal_t *ctx, const char *hex, tal_free(linear_tx); - tx->input_amounts = - tal_arrz(tx, struct amount_sat *, tx->wtx->num_inputs); - return tx; fail_free_tx: @@ -612,13 +667,6 @@ struct bitcoin_tx *fromwire_bitcoin_tx(const tal_t *ctx, tal_free(tx->psbt); tx->psbt = fromwire_psbt(tx, cursor, max); - for (size_t i = 0; i < tal_count(tx->input_amounts); i++) { - struct amount_sat sat; - sat = fromwire_amount_sat(cursor, max); - tx->input_amounts[i] = - tal_dup(tx, struct amount_sat, &sat); - } - return tx; } @@ -633,8 +681,6 @@ void towire_bitcoin_tx(u8 **pptr, const struct bitcoin_tx *tx) towire_u8_array(pptr, lin, tal_count(lin)); towire_psbt(pptr, tx->psbt); - for (size_t i = 0; i < tal_count(tx->input_amounts); i++) - towire_amount_sat(pptr, *tx->input_amounts[i]); } struct bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx, diff --git a/bitcoin/tx.h b/bitcoin/tx.h index baade48581a8..31f81b02070f 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -21,9 +21,6 @@ struct bitcoin_txid { STRUCTEQ_DEF(bitcoin_txid, 0, shad.sha.u); struct bitcoin_tx { - /* Keep track of input amounts, this is needed for signatures (NULL if - * unknown) */ - struct amount_sat **input_amounts; struct wally_tx *wtx; /* Keep a reference to the ruleset we have to abide by */ @@ -68,6 +65,9 @@ bool bitcoin_txid_from_hex(const char *hexstr, size_t hexstr_len, bool bitcoin_txid_to_hex(const struct bitcoin_txid *txid, char *hexstr, size_t hexstr_len); +/* Create a bitcoin_tx from a psbt */ +struct bitcoin_tx *bitcoin_tx_with_psbt(const tal_t *ctx, struct wally_psbt *psbt); + /* Internal de-linearization functions. */ struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, const u8 **cursor, size_t *max); @@ -80,9 +80,19 @@ int bitcoin_tx_add_output(struct bitcoin_tx *tx, const u8 *script, int bitcoin_tx_add_multi_outputs(struct bitcoin_tx *tx, struct bitcoin_tx_output **outputs); +/* Set the locktime for a transaction */ +void bitcoin_tx_set_locktime(struct bitcoin_tx *tx, u32 locktime); + +/* Add a new input to a bitcoin tx. + * + * For P2WSH inputs, we'll also store the wscript and/or scriptPubkey + * Passing in just the {input_wscript}, we'll generate the scriptPubkey for you. + * In some cases we may not have the wscript, in which case the scriptPubkey + * should be provided. We'll check that it's P2WSH before saving it */ int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid, - u32 outnum, u32 sequence, - struct amount_sat amount, u8 *script); + u32 outnum, u32 sequence, const u8 *scriptSig, + struct amount_sat amount, const u8 *scriptPubkey, + const u8 *input_wscript); /* This helps is useful because wally uses a raw byte array for txids */ bool wally_tx_input_spends(const struct wally_tx_input *input, @@ -189,8 +199,8 @@ struct amount_sat bitcoin_tx_compute_fee(const struct bitcoin_tx *tx); /* * Calculate the fees for this transaction, given a pre-computed input balance. * - * This is needed for cases where the input_amounts aren't properly initialized, - * typically due to being passed across the wire. + * This is needed for cases where the transaction's psbt metadata isn't properly filled + * in typically due to being instantiated from a tx hex (i.e. from a block scan) */ struct amount_sat bitcoin_tx_compute_fee_w_inputs(const struct bitcoin_tx *tx, struct amount_sat input_val); @@ -210,4 +220,6 @@ void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output) * Get the base64 string encoded PSBT of a bitcoin transaction. */ char *bitcoin_tx_to_psbt_base64(const tal_t *ctx, struct bitcoin_tx *tx); + +int wally_tx_clone(struct wally_tx *tx, struct wally_tx **output); #endif /* LIGHTNING_BITCOIN_TX_H */ diff --git a/channeld/channeld.c b/channeld/channeld.c index 6331dbc92446..99aba4523e86 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -12,6 +12,7 @@ */ #include #include +#include #include #include #include @@ -841,7 +842,6 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx, msg = towire_hsm_sign_remote_commitment_tx(NULL, txs[0], &peer->channel->funding_pubkey[REMOTE], - *txs[0]->input_amounts[0], &peer->remote_per_commit, peer->channel->option_static_remotekey); @@ -883,7 +883,6 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx, wscript = bitcoin_tx_output_get_witscript(tmpctx, txs[0], txs[i+1]->wtx->inputs[0].index); msg = towire_hsm_sign_remote_htlc_tx(NULL, txs[i + 1], wscript, - *txs[i+1]->input_amounts[0], &peer->remote_per_commit); msg = hsm_req(tmpctx, take(msg)); @@ -1291,6 +1290,10 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) &funding_wscript, peer->channel, &peer->next_local_per_commit, peer->next_index[LOCAL], LOCAL); + /* Set the commit_sig on the commitment tx psbt */ + psbt_input_set_partial_sig(txs[0]->psbt, 0, + &peer->channel->funding_pubkey[REMOTE], &commit_sig); + if (!derive_simple_key(&peer->channel->basepoints[REMOTE].htlc, &peer->next_local_per_commit, &remote_htlckey)) status_failed(STATUS_FAIL_INTERNAL_ERROR, diff --git a/channeld/commit_tx.c b/channeld/commit_tx.c index b3cdebf257a9..3819708c2a4a 100644 --- a/channeld/commit_tx.c +++ b/channeld/commit_tx.c @@ -79,6 +79,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, struct amount_sat funding, + const u8 *funding_wscript, enum side opener, u16 to_self_delay, const struct keyset *keyset, @@ -275,8 +276,8 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, * * * locktime: upper 8 bits are 0x20, lower 24 bits are the lower 24 bits of the obscured commitment number */ - tx->wtx->locktime - = (0x20000000 | (obscured_commitment_number & 0xFFFFFF)); + bitcoin_tx_set_locktime(tx, + (0x20000000 | (obscured_commitment_number & 0xFFFFFF))); /* BOLT #3: * @@ -289,7 +290,8 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, * * `txin[0]` sequence: upper 8 bits are 0x80, lower 24 bits are upper 24 bits of the obscured commitment number */ u32 sequence = (0x80000000 | ((obscured_commitment_number>>24) & 0xFFFFFF)); - bitcoin_tx_add_input(tx, funding_txid, funding_txout, sequence, funding, NULL); + bitcoin_tx_add_input(tx, funding_txid, funding_txout, + sequence, NULL, funding, NULL, funding_wscript); /* Identify the direct outputs (to_us, to_them). */ if (direct_outputs != NULL) { diff --git a/channeld/commit_tx.h b/channeld/commit_tx.h index aab2c0ca56d8..471d82ed5859 100644 --- a/channeld/commit_tx.h +++ b/channeld/commit_tx.h @@ -48,6 +48,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, struct amount_sat funding, + const u8 *funding_wscript, enum side opener, u16 to_self_delay, const struct keyset *keyset, diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 3e8e571093d8..38fd1602b5a1 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -1,9 +1,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -237,19 +239,27 @@ static void add_htlcs(struct bitcoin_tx ***txs, for (i = 0; i < tal_count(htlcmap); i++) { const struct htlc *htlc = htlcmap[i]; struct bitcoin_tx *tx; + struct ripemd160 ripemd; + const u8 *wscript; if (!htlc) continue; if (htlc_owner(htlc) == side) { + ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8)); + wscript = htlc_offered_wscript(tmpctx, &ripemd, keyset); tx = htlc_timeout_tx(*txs, chainparams, &txid, i, + wscript, htlc->amount, htlc->expiry.locktime, channel->config[!side].to_self_delay, feerate_per_kw, keyset); } else { + ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8)); + wscript = htlc_received_wscript(tmpctx, &ripemd, &htlc->expiry, keyset); tx = htlc_success_tx(*txs, chainparams, &txid, i, + wscript, htlc->amount, channel->config[!side].to_self_delay, feerate_per_kw, @@ -285,10 +295,16 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, /* Figure out what @side will already be committed to. */ gather_htlcs(ctx, channel, side, &committed, NULL, NULL); + /* Generating and saving witness script required to spend + * the funding output */ + *funding_wscript = bitcoin_redeem_2of2(ctx, + &channel->funding_pubkey[side], + &channel->funding_pubkey[!side]); + txs = tal_arr(ctx, struct bitcoin_tx *, 1); txs[0] = commit_tx( ctx, &channel->funding_txid, channel->funding_txout, - channel->funding, channel->opener, + channel->funding, cast_const(u8 *, *funding_wscript), channel->opener, channel->config[!side].to_self_delay, &keyset, channel_feerate(channel, side), channel->config[side].dust_limit, channel->view[side].owed[side], @@ -296,11 +312,11 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, commitment_number ^ channel->commitment_number_obscurer, side); - /* Generating and saving witness script required to spend - * the funding output */ - *funding_wscript = bitcoin_redeem_2of2(ctx, - &channel->funding_pubkey[side], - &channel->funding_pubkey[!side]); + /* Set the remote/local pubkeys on the commitment tx psbt */ + psbt_input_add_pubkey(txs[0]->psbt, 0, + &channel->funding_pubkey[side]); + psbt_input_add_pubkey(txs[0]->psbt, 0, + &channel->funding_pubkey[!side]); add_htlcs(&txs, *htlcmap, channel, &keyset, side); diff --git a/channeld/test/run-commit_tx.c b/channeld/test/run-commit_tx.c index eb97787ea510..fe0fa5b68bcc 100644 --- a/channeld/test/run-commit_tx.c +++ b/channeld/test/run-commit_tx.c @@ -245,31 +245,31 @@ static void report_htlcs(const struct bitcoin_tx *tx, continue; if (htlc_owner(htlc) == LOCAL) { - htlc_tx[i] = htlc_timeout_tx(htlc_tx, tx->chainparams, - &txid, i, - htlc->amount, - htlc->expiry.locktime, - to_self_delay, - feerate_per_kw, - &keyset); wscript[i] = bitcoin_wscript_htlc_offer(tmpctx, local_htlckey, remote_htlckey, &htlc->rhash, remote_revocation_key); - } else { - htlc_tx[i] = htlc_success_tx(htlc_tx, tx->chainparams, - &txid, i, + htlc_tx[i] = htlc_timeout_tx(htlc_tx, tx->chainparams, + &txid, i, wscript[i], htlc->amount, + htlc->expiry.locktime, to_self_delay, feerate_per_kw, &keyset); + } else { wscript[i] = bitcoin_wscript_htlc_receive(tmpctx, &htlc->expiry, local_htlckey, remote_htlckey, &htlc->rhash, remote_revocation_key); + htlc_tx[i] = htlc_success_tx(htlc_tx, tx->chainparams, + &txid, i, wscript[i], + htlc->amount, + to_self_delay, + feerate_per_kw, + &keyset); } sign_tx_input(htlc_tx[i], 0, NULL, @@ -737,7 +737,7 @@ int main(int argc, const char *argv[]) print_superverbose = true; tx = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, LOCAL, to_self_delay, &keyset, feerate_per_kw, @@ -749,7 +749,7 @@ int main(int argc, const char *argv[]) print_superverbose = false; tx2 = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, REMOTE, to_self_delay, &keyset, feerate_per_kw, @@ -793,7 +793,7 @@ int main(int argc, const char *argv[]) print_superverbose = true; tx = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, LOCAL, to_self_delay, &keyset, feerate_per_kw, @@ -805,7 +805,7 @@ int main(int argc, const char *argv[]) print_superverbose = false; tx2 = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, REMOTE, to_self_delay, &keyset, feerate_per_kw, @@ -837,7 +837,7 @@ int main(int argc, const char *argv[]) print_superverbose = false; newtx = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, LOCAL, to_self_delay, &keyset, feerate_per_kw, @@ -850,7 +850,7 @@ int main(int argc, const char *argv[]) /* This is what it would look like for peer generating it! */ tx2 = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, REMOTE, to_self_delay, &keyset, feerate_per_kw, @@ -882,7 +882,7 @@ int main(int argc, const char *argv[]) print_superverbose = true; tx = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, LOCAL, to_self_delay, &keyset, feerate_per_kw-1, @@ -919,7 +919,7 @@ int main(int argc, const char *argv[]) print_superverbose = true; newtx = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, LOCAL, to_self_delay, &keyset, feerate_per_kw, @@ -978,7 +978,7 @@ int main(int argc, const char *argv[]) to_local.millisatoshis, to_remote.millisatoshis, feerate_per_kw); tx = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, wscript, LOCAL, to_self_delay, &keyset, feerate_per_kw, diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 5a96fa09fe86..21cfa1bc5fab 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -524,7 +524,7 @@ int main(int argc, const char *argv[]) raw_tx = commit_tx(tmpctx, &funding_txid, funding_output_index, - funding_amount, + funding_amount, funding_wscript, LOCAL, remote_config->to_self_delay, &keyset, feerate_per_kw[LOCAL], @@ -651,7 +651,7 @@ int main(int argc, const char *argv[]) raw_tx = commit_tx( tmpctx, &funding_txid, funding_output_index, - funding_amount, LOCAL, remote_config->to_self_delay, + funding_amount, funding_wscript, LOCAL, remote_config->to_self_delay, &keyset, feerate_per_kw[LOCAL], local_config->dust_limit, to_local, to_remote, htlcs, &htlc_map, NULL, 0x2bb038521914 ^ 42, LOCAL); diff --git a/channeld/watchtower.c b/channeld/watchtower.c index 99622781a39c..46a1c11b43ee 100644 --- a/channeld/watchtower.c +++ b/channeld/watchtower.c @@ -69,7 +69,7 @@ penalty_tx_create(const tal_t *ctx, tx = bitcoin_tx(ctx, chainparams, 1, 1, locktime); bitcoin_tx_add_input(tx, commitment_txid, to_them_outnum, 0xFFFFFFFF, - to_them_sats, NULL); + NULL, to_them_sats, NULL, wscript); bitcoin_tx_add_output(tx, final_scriptpubkey, NULL, to_them_sats); @@ -102,8 +102,8 @@ penalty_tx_create(const tal_t *ctx, bitcoin_tx_finalize(tx); u8 *hsm_sign_msg = - towire_hsm_sign_penalty_to_us(ctx, &remote_per_commitment_secret, tx, - wscript, *tx->input_amounts[0]); + towire_hsm_sign_penalty_to_us(ctx, &remote_per_commitment_secret, + tx, wscript); if (!wire_sync_write(hsm_fd, take(hsm_sign_msg))) status_failed(STATUS_FAIL_INTERNAL_ERROR, diff --git a/closingd/closingd.c b/closingd/closingd.c index 505d968d35c0..1f454d3a34a9 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -39,6 +39,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, struct amount_sat funding, + const u8 *funding_wscript, const struct amount_sat out[NUM_SIDES], enum side opener, struct amount_sat fee, @@ -67,6 +68,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, tx = create_close_tx(ctx, chainparams, scriptpubkey[LOCAL], scriptpubkey[REMOTE], + funding_wscript, funding_txid, funding_txout, funding, @@ -238,6 +240,7 @@ static void send_offer(struct per_peer_state *pps, const struct chainparams *chainparams, const struct channel_id *channel_id, const struct pubkey funding_pubkey[NUM_SIDES], + const u8 *funding_wscript, u8 *scriptpubkey[NUM_SIDES], const struct bitcoin_txid *funding_txid, unsigned int funding_txout, @@ -262,6 +265,7 @@ static void send_offer(struct per_peer_state *pps, funding_txid, funding_txout, funding, + funding_wscript, out, opener, fee_to_offer, our_dust_limit); @@ -276,8 +280,7 @@ static void send_offer(struct per_peer_state *pps, wire_sync_write(HSM_FD, take(towire_hsm_sign_mutual_close_tx(NULL, tx, - &funding_pubkey[REMOTE], - funding))); + &funding_pubkey[REMOTE]))); msg = wire_sync_read(tmpctx, HSM_FD); if (!fromwire_hsm_sign_tx_reply(msg, &our_sig)) status_failed(STATUS_FAIL_HSM_IO, @@ -372,6 +375,7 @@ receive_offer(struct per_peer_state *pps, funding_txid, funding_txout, funding, + funding_wscript, out, opener, received_fee, our_dust_limit); if (!check_tx_sig(tx, 0, NULL, funding_wscript, @@ -401,6 +405,7 @@ receive_offer(struct per_peer_state *pps, funding_txid, funding_txout, funding, + funding_wscript, trimming_out, opener, received_fee, our_dust_limit); if (!trimmed @@ -696,7 +701,7 @@ int main(int argc, char *argv[]) for (size_t i = 0; i < 2; i++, whose_turn = !whose_turn) { if (whose_turn == LOCAL) { send_offer(pps, chainparams, - &channel_id, funding_pubkey, + &channel_id, funding_pubkey, funding_wscript, scriptpubkey, &funding_txid, funding_txout, funding, out, opener, our_dust_limit, @@ -745,7 +750,7 @@ int main(int argc, char *argv[]) fee_negotiation_step, fee_negotiation_step_unit); send_offer(pps, chainparams, &channel_id, - funding_pubkey, + funding_pubkey, funding_wscript, scriptpubkey, &funding_txid, funding_txout, funding, out, opener, our_dust_limit, diff --git a/common/close_tx.c b/common/close_tx.c index 0bb31b2de1be..6b58986ff17f 100644 --- a/common/close_tx.c +++ b/common/close_tx.c @@ -9,6 +9,7 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, const struct chainparams *chainparams, const u8 *our_script, const u8 *their_script, + const u8 *funding_wscript, const struct bitcoin_txid *anchor_txid, unsigned int anchor_index, struct amount_sat funding, @@ -39,7 +40,8 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, /* Our input spends the anchor tx output. */ bitcoin_tx_add_input(tx, anchor_txid, anchor_index, - BITCOIN_TX_DEFAULT_SEQUENCE, funding, NULL); + BITCOIN_TX_DEFAULT_SEQUENCE, NULL, + funding, NULL, funding_wscript); if (amount_sat_greater_eq(to_us, dust_limit)) { script = tal_dup_talarr(tx, u8, our_script); diff --git a/common/close_tx.h b/common/close_tx.h index 57bd1d3c0cf3..8767737a7d24 100644 --- a/common/close_tx.h +++ b/common/close_tx.h @@ -15,6 +15,7 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx, const struct chainparams *chainparams, const u8 *our_script, const u8 *their_script, + const u8 *funding_wscript, const struct bitcoin_txid *anchor_txid, unsigned int anchor_index, struct amount_sat funding, diff --git a/common/htlc_tx.c b/common/htlc_tx.c index c59976009669..264b0dfbfb38 100644 --- a/common/htlc_tx.c +++ b/common/htlc_tx.c @@ -8,6 +8,7 @@ static struct bitcoin_tx *htlc_tx(const tal_t *ctx, const struct chainparams *chainparams, const struct bitcoin_txid *commit_txid, unsigned int commit_output_number, + const u8 *commit_wscript, struct amount_msat msat, u16 to_self_delay, const struct pubkey *revocation_pubkey, @@ -45,8 +46,8 @@ static struct bitcoin_tx *htlc_tx(const tal_t *ctx, * * `txin[0]` sequence: `0` */ amount = amount_msat_to_sat_round_down(msat); - bitcoin_tx_add_input(tx, commit_txid, commit_output_number, 0, amount, - NULL); + bitcoin_tx_add_input(tx, commit_txid, commit_output_number, 0, + NULL, amount, NULL, commit_wscript); /* BOLT #3: * * txout count: 1 @@ -75,6 +76,7 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx, const struct chainparams *chainparams, const struct bitcoin_txid *commit_txid, unsigned int commit_output_number, + const u8 *commit_wscript, struct amount_msat htlc_msatoshi, u16 to_self_delay, u32 feerate_per_kw, @@ -83,7 +85,8 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx, /* BOLT #3: * * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout */ - return htlc_tx(ctx, chainparams, commit_txid, commit_output_number, htlc_msatoshi, + return htlc_tx(ctx, chainparams, commit_txid, commit_output_number, + commit_wscript, htlc_msatoshi, to_self_delay, &keyset->self_revocation_key, &keyset->self_delayed_payment_key, @@ -120,6 +123,7 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, const struct chainparams *chainparams, const struct bitcoin_txid *commit_txid, unsigned int commit_output_number, + const u8 *commit_wscript, struct amount_msat htlc_msatoshi, u32 cltv_expiry, u16 to_self_delay, @@ -130,7 +134,7 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, * * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout */ return htlc_tx(ctx, chainparams, commit_txid, commit_output_number, - htlc_msatoshi, to_self_delay, + commit_wscript, htlc_msatoshi, to_self_delay, &keyset->self_revocation_key, &keyset->self_delayed_payment_key, htlc_timeout_fee(feerate_per_kw), cltv_expiry); diff --git a/common/htlc_tx.h b/common/htlc_tx.h index 9c643d080dae..5f0c7c50a6cc 100644 --- a/common/htlc_tx.h +++ b/common/htlc_tx.h @@ -69,6 +69,7 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx, const struct chainparams *chainparams, const struct bitcoin_txid *commit_txid, unsigned int commit_output_number, + const u8 *commit_wscript, struct amount_msat htlc_msatoshi, u16 to_self_delay, u32 feerate_per_kw, @@ -90,6 +91,7 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, const struct chainparams *chainparams, const struct bitcoin_txid *commit_txid, unsigned int commit_output_number, + const u8 *commit_wscript, struct amount_msat htlc_msatoshi, u32 cltv_expiry, u16 to_self_delay, diff --git a/common/initial_channel.c b/common/initial_channel.c index 5f12ade0e7a0..2508969a5a57 100644 --- a/common/initial_channel.c +++ b/common/initial_channel.c @@ -1,7 +1,9 @@ #include #include +#include #include #include +#include #include #include #include @@ -75,6 +77,7 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx, char** err_reason) { struct keyset keyset; + struct bitcoin_tx *init_tx; /* This assumes no HTLCs! */ assert(!channel->htlcs); @@ -92,23 +95,32 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx, &channel->funding_pubkey[side], &channel->funding_pubkey[!side]); - return initial_commit_tx(ctx, - &channel->funding_txid, - channel->funding_txout, - channel->funding, - channel->opener, - /* They specify our to_self_delay and v.v. */ - channel->config[!side].to_self_delay, - &keyset, - channel_feerate(channel, side), - channel->config[side].dust_limit, - channel->view[side].owed[side], - channel->view[side].owed[!side], - channel->config[!side].channel_reserve, - 0 ^ channel->commitment_number_obscurer, - direct_outputs, - side, - err_reason); + init_tx = initial_commit_tx(ctx, &channel->funding_txid, + channel->funding_txout, + channel->funding, + cast_const(u8 *, *wscript), + channel->opener, + /* They specify our to_self_delay and v.v. */ + channel->config[!side].to_self_delay, + &keyset, + channel_feerate(channel, side), + channel->config[side].dust_limit, + channel->view[side].owed[side], + channel->view[side].owed[!side], + channel->config[!side].channel_reserve, + 0 ^ channel->commitment_number_obscurer, + direct_outputs, + side, + err_reason); + + if (init_tx) { + psbt_input_add_pubkey(init_tx->psbt, 0, + &channel->funding_pubkey[side]); + psbt_input_add_pubkey(init_tx->psbt, 0, + &channel->funding_pubkey[!side]); + } + + return init_tx; } u32 channel_feerate(const struct channel *channel, enum side side) diff --git a/common/initial_commit_tx.c b/common/initial_commit_tx.c index 4a020f9d1ed3..8d10bcda647c 100644 --- a/common/initial_commit_tx.c +++ b/common/initial_commit_tx.c @@ -62,6 +62,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, struct amount_sat funding, + u8 *funding_wscript, enum side opener, u16 to_self_delay, const struct keyset *keyset, @@ -227,8 +228,8 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, * * locktime: upper 8 bits are 0x20, lower 24 bits are the * lower 24 bits of the obscured commitment number */ - tx->wtx->locktime = - (0x20000000 | (obscured_commitment_number & 0xFFFFFF)); + bitcoin_tx_set_locktime(tx, + (0x20000000 | (obscured_commitment_number & 0xFFFFFF))); /* BOLT #3: * @@ -239,7 +240,8 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, * * `txin[0]` script bytes: 0 */ sequence = (0x80000000 | ((obscured_commitment_number>>24) & 0xFFFFFF)); - bitcoin_tx_add_input(tx, funding_txid, funding_txout, sequence, funding, NULL); + bitcoin_tx_add_input(tx, funding_txid, funding_txout, sequence, + NULL, funding, NULL, funding_wscript); if (direct_outputs != NULL) { direct_outputs[LOCAL] = direct_outputs[REMOTE] = NULL; diff --git a/common/initial_commit_tx.h b/common/initial_commit_tx.h index f016fc2b8577..c155a09c4419 100644 --- a/common/initial_commit_tx.h +++ b/common/initial_commit_tx.h @@ -76,6 +76,7 @@ static inline struct amount_sat commit_tx_base_fee(u32 feerate_per_kw, * initial_commit_tx: create (unsigned) commitment tx to spend the funding tx output * @ctx: context to allocate transaction and @htlc_map from. * @funding_txid, @funding_out, @funding: funding outpoint. + * @funding_wscript: scriptPubkey of the funding output * @opener: is the LOCAL or REMOTE paying the fee? * @keyset: keys derived for this commit tx. * @feerate_per_kw: feerate to use @@ -96,6 +97,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, const struct bitcoin_txid *funding_txid, unsigned int funding_txout, struct amount_sat funding, + u8 *funding_wscript, enum side opener, u16 to_self_delay, const struct keyset *keyset, diff --git a/common/permute_tx.c b/common/permute_tx.c index b26b6f7e7d47..08de4fd58271 100644 --- a/common/permute_tx.c +++ b/common/permute_tx.c @@ -69,14 +69,6 @@ static void swap_wally_inputs(struct wally_tx_input *inputs, } } -static void swap_input_amounts(struct amount_sat **amounts, size_t i1, - size_t i2) -{ - struct amount_sat *tmp = amounts[i1]; - amounts[i1] = amounts[i2]; - amounts[i2] = tmp; -} - void permute_inputs(struct bitcoin_tx *tx, const void **map) { size_t i, best_pos; @@ -95,7 +87,6 @@ void permute_inputs(struct bitcoin_tx *tx, const void **map) tx->psbt->tx->inputs, tx->psbt->inputs, map, i, best_pos); - swap_input_amounts(tx->input_amounts, i, best_pos); } } diff --git a/common/test/run-funding_tx.c b/common/test/run-funding_tx.c index 942cbd0887c7..f57a7149b892 100644 --- a/common/test/run-funding_tx.c +++ b/common/test/run-funding_tx.c @@ -177,6 +177,7 @@ int main(int argc, const char *argv[]) utxo.amount = AMOUNT_SAT(5000000000); utxo.is_p2sh = false; utxo.close_info = NULL; + utxo.scriptPubkey = tal_hexdata(tmpctx, "a914a5996075e4b468c9fb01d131bf9d4052a6fee19e87", strlen("a914a5996075e4b468c9fb01d131bf9d4052a6fee19e87")); funding_sat = AMOUNT_SAT(10000000); fee = AMOUNT_SAT(13920); diff --git a/common/utxo.c b/common/utxo.c index 456a95149485..d2da66702bfb 100644 --- a/common/utxo.c +++ b/common/utxo.c @@ -87,7 +87,8 @@ struct bitcoin_tx *tx_spending_utxos(const tal_t *ctx, } bitcoin_tx_add_input(tx, &utxos[i]->txid, utxos[i]->outnum, - nsequence, utxos[i]->amount, script); + nsequence, script, utxos[i]->amount, + utxos[i]->scriptPubkey, NULL); } return tx; diff --git a/devtools/mkclose.c b/devtools/mkclose.c index 227f980bdd2c..01253c965608 100644 --- a/devtools/mkclose.c +++ b/devtools/mkclose.c @@ -130,10 +130,6 @@ int main(int argc, char *argv[]) tx = bitcoin_tx(NULL, chainparams, 1, 2, 0); - /* Our input spends the anchor tx output. */ - bitcoin_tx_add_input(tx, &funding_txid, funding_outnum, - BITCOIN_TX_DEFAULT_SEQUENCE, funding_amount, NULL); - num_outputs = 0; if (amount_msat_greater_eq_sat(local_msat, dust_limit)) { u8 *script = scriptpubkey_p2wpkh(NULL, &outkey[LOCAL]); @@ -165,8 +161,11 @@ int main(int argc, char *argv[]) printf("# funding witness script = %s\n", tal_hex(NULL, funding_wscript)); - /* Need input amount for signing */ - tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &funding_amount); + /* Our input spends the anchor tx output. */ + bitcoin_tx_add_input(tx, &funding_txid, funding_outnum, + BITCOIN_TX_DEFAULT_SEQUENCE, NULL, + funding_amount, NULL, funding_wscript); + sign_tx_input(tx, 0, NULL, funding_wscript, &funding_privkey[LOCAL], &funding_pubkey[LOCAL], diff --git a/devtools/mkcommit.c b/devtools/mkcommit.c index 06cd4ff7f4f3..c0d4844e6d8d 100644 --- a/devtools/mkcommit.c +++ b/devtools/mkcommit.c @@ -464,7 +464,6 @@ int main(int argc, char *argv[]) for (size_t i = 0; i < tal_count(htlcmap); i++) { struct bitcoin_signature local_htlc_sig, remote_htlc_sig; - struct amount_sat amt; u8 *wscript; if (!htlcmap[i]) @@ -473,9 +472,6 @@ int main(int argc, char *argv[]) i, side_to_str(htlc_owner(htlcmap[i])), htlcmap[i]->id); printf("# unsigned htlc tx for output %zu: %s\n", i, tal_hex(NULL, linearize_tx(NULL, local_txs[1+i]))); - amt = amount_msat_to_sat_round_down(htlcmap[i]->amount); - local_txs[1+i]->input_amounts[0] - = tal_dup(local_txs[1+i], struct amount_sat, &amt); wscript = bitcoin_tx_output_get_witscript(NULL, local_txs[1+i], 1+i); printf("# wscript: %s\n", tal_hex(NULL, wscript)); @@ -516,8 +512,6 @@ int main(int argc, char *argv[]) remote_txs = channel_txs(NULL, &htlcmap, NULL, &funding_wscript, channel, &remote_per_commit_point, commitnum, REMOTE); - remote_txs[0]->input_amounts[0] - = tal_dup(remote_txs[0], struct amount_sat, &funding_amount); printf("## remote_commitment\n" "# input amount %s, funding_wscript %s, key %s\n", @@ -579,7 +573,6 @@ int main(int argc, char *argv[]) for (size_t i = 0; i < tal_count(htlcmap); i++) { struct bitcoin_signature local_htlc_sig, remote_htlc_sig; - struct amount_sat amt; u8 *wscript; if (!htlcmap[i]) @@ -588,9 +581,6 @@ int main(int argc, char *argv[]) i, side_to_str(htlc_owner(htlcmap[i])), htlcmap[i]->id); printf("# unsigned htlc tx for output %zu: %s\n", i, tal_hex(NULL, linearize_tx(NULL, remote_txs[1+i]))); - amt = amount_msat_to_sat_round_down(htlcmap[i]->amount); - remote_txs[1+i]->input_amounts[0] - = tal_dup(remote_txs[1+i], struct amount_sat, &amt); wscript = bitcoin_tx_output_get_witscript(NULL, remote_txs[1+i], 1+i); printf("# wscript: %s\n", tal_hex(NULL, wscript)); diff --git a/external/libwally-core b/external/libwally-core index bb2e7d1779ba..5642664b6159 160000 --- a/external/libwally-core +++ b/external/libwally-core @@ -1 +1 @@ -Subproject commit bb2e7d1779ba0e54c7a0037e7d3ddedccddb90b5 +Subproject commit 5642664b6159b0fe3940a1276f23998dcfce5481 diff --git a/hsmd/hsm_wire.csv b/hsmd/hsm_wire.csv index c9697b0d3a63..106f9777208a 100644 --- a/hsmd/hsm_wire.csv +++ b/hsmd/hsm_wire.csv @@ -117,7 +117,6 @@ msgdata,hsm_sign_commitment_tx,peer_id,node_id, msgdata,hsm_sign_commitment_tx,channel_dbid,u64, msgdata,hsm_sign_commitment_tx,tx,bitcoin_tx, msgdata,hsm_sign_commitment_tx,remote_funding_key,pubkey, -msgdata,hsm_sign_commitment_tx,funding_amount,amount_sat, msgtype,hsm_sign_commitment_tx_reply,105 msgdata,hsm_sign_commitment_tx_reply,sig,bitcoin_signature, @@ -130,21 +129,18 @@ msgdata,hsm_sign_delayed_payment_to_us,commit_num,u64, msgdata,hsm_sign_delayed_payment_to_us,tx,bitcoin_tx, msgdata,hsm_sign_delayed_payment_to_us,wscript_len,u16, msgdata,hsm_sign_delayed_payment_to_us,wscript,u8,wscript_len -msgdata,hsm_sign_delayed_payment_to_us,input_amount,amount_sat, msgtype,hsm_sign_remote_htlc_to_us,13 msgdata,hsm_sign_remote_htlc_to_us,remote_per_commitment_point,pubkey, msgdata,hsm_sign_remote_htlc_to_us,tx,bitcoin_tx, msgdata,hsm_sign_remote_htlc_to_us,wscript_len,u16, msgdata,hsm_sign_remote_htlc_to_us,wscript,u8,wscript_len -msgdata,hsm_sign_remote_htlc_to_us,input_amount,amount_sat, msgtype,hsm_sign_penalty_to_us,14 msgdata,hsm_sign_penalty_to_us,revocation_secret,secret, msgdata,hsm_sign_penalty_to_us,tx,bitcoin_tx, msgdata,hsm_sign_penalty_to_us,wscript_len,u16, msgdata,hsm_sign_penalty_to_us,wscript,u8,wscript_len -msgdata,hsm_sign_penalty_to_us,input_amount,amount_sat, # Onchaind asks HSM to sign a local HTLC success or HTLC timeout tx. msgtype,hsm_sign_local_htlc_tx,16 @@ -152,13 +148,11 @@ msgdata,hsm_sign_local_htlc_tx,commit_num,u64, msgdata,hsm_sign_local_htlc_tx,tx,bitcoin_tx, msgdata,hsm_sign_local_htlc_tx,wscript_len,u16, msgdata,hsm_sign_local_htlc_tx,wscript,u8,wscript_len -msgdata,hsm_sign_local_htlc_tx,input_amount,amount_sat, # Openingd/channeld asks HSM to sign the other sides' commitment tx. msgtype,hsm_sign_remote_commitment_tx,19 msgdata,hsm_sign_remote_commitment_tx,tx,bitcoin_tx, msgdata,hsm_sign_remote_commitment_tx,remote_funding_key,pubkey, -msgdata,hsm_sign_remote_commitment_tx,funding_amount,amount_sat, msgdata,hsm_sign_remote_commitment_tx,remote_per_commit,pubkey, msgdata,hsm_sign_remote_commitment_tx,option_static_remotekey,bool, @@ -167,14 +161,12 @@ msgtype,hsm_sign_remote_htlc_tx,20 msgdata,hsm_sign_remote_htlc_tx,tx,bitcoin_tx, msgdata,hsm_sign_remote_htlc_tx,len,u16, msgdata,hsm_sign_remote_htlc_tx,wscript,u8,len -msgdata,hsm_sign_remote_htlc_tx,amounts_satoshi,amount_sat, msgdata,hsm_sign_remote_htlc_tx,remote_per_commit_point,pubkey, # closingd asks HSM to sign mutual close tx. msgtype,hsm_sign_mutual_close_tx,21 msgdata,hsm_sign_mutual_close_tx,tx,bitcoin_tx, msgdata,hsm_sign_mutual_close_tx,remote_funding_key,pubkey, -msgdata,hsm_sign_mutual_close_tx,funding,amount_sat, # Reply for all the above requests. msgtype,hsm_sign_tx_reply,112 diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index c28ba305f1d8..7b517699b9c9 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -928,7 +928,6 @@ static struct io_plan *handle_sign_commitment_tx(struct io_conn *conn, struct pubkey remote_funding_pubkey, local_funding_pubkey; struct node_id peer_id; u64 dbid; - struct amount_sat funding; struct secret channel_seed; struct bitcoin_tx *tx; struct bitcoin_signature sig; @@ -938,8 +937,7 @@ static struct io_plan *handle_sign_commitment_tx(struct io_conn *conn, if (!fromwire_hsm_sign_commitment_tx(tmpctx, msg_in, &peer_id, &dbid, &tx, - &remote_funding_pubkey, - &funding)) + &remote_funding_pubkey)) return bad_req(conn, c, msg_in); tx->chainparams = c->chainparams; @@ -960,13 +958,6 @@ static struct io_plan *handle_sign_commitment_tx(struct io_conn *conn, funding_wscript = bitcoin_redeem_2of2(tmpctx, &local_funding_pubkey, &remote_funding_pubkey); - /*~ Segregated Witness also added the input amount to the signing - * algorithm; it's only part of the input implicitly (it's part of the - * output it's spending), so in our 'bitcoin_tx' structure it's a - * pointer, as we don't always know it (and zero is a valid amount, so - * NULL is better to mean 'unknown' and has the nice property that - * you'll crash if you assume it's there and you're wrong.) */ - tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &funding); sign_tx_input(tx, 0, NULL, funding_wscript, &secrets.funding_privkey, &local_funding_pubkey, @@ -990,7 +981,6 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn, const u8 *msg_in) { struct pubkey remote_funding_pubkey, local_funding_pubkey; - struct amount_sat funding; struct secret channel_seed; struct bitcoin_tx *tx; struct bitcoin_signature sig; @@ -1002,7 +992,6 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn, if (!fromwire_hsm_sign_remote_commitment_tx(tmpctx, msg_in, &tx, &remote_funding_pubkey, - &funding, &remote_per_commit, &option_static_remotekey)) return bad_req(conn, c, msg_in); @@ -1021,8 +1010,6 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn, funding_wscript = bitcoin_redeem_2of2(tmpctx, &local_funding_pubkey, &remote_funding_pubkey); - /* Need input amount for signing */ - tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &funding); sign_tx_input(tx, 0, NULL, funding_wscript, &secrets.funding_privkey, &local_funding_pubkey, @@ -1044,13 +1031,12 @@ static struct io_plan *handle_sign_remote_htlc_tx(struct io_conn *conn, struct secrets secrets; struct basepoints basepoints; struct pubkey remote_per_commit_point; - struct amount_sat amount; u8 *wscript; struct privkey htlc_privkey; struct pubkey htlc_pubkey; if (!fromwire_hsm_sign_remote_htlc_tx(tmpctx, msg_in, - &tx, &wscript, &amount, + &tx, &wscript, &remote_per_commit_point)) return bad_req(conn, c, msg_in); tx->chainparams = c->chainparams; @@ -1070,8 +1056,6 @@ static struct io_plan *handle_sign_remote_htlc_tx(struct io_conn *conn, return bad_req_fmt(conn, c, msg_in, "Failed deriving htlc pubkey"); - /* Need input amount for signing */ - tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &amount); sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey, SIGHASH_ALL, &sig); @@ -1086,8 +1070,7 @@ static struct io_plan *handle_sign_to_us_tx(struct io_conn *conn, const u8 *msg_in, struct bitcoin_tx *tx, const struct privkey *privkey, - const u8 *wscript, - struct amount_sat input_sat) + const u8 *wscript) { struct bitcoin_signature sig; struct pubkey pubkey; @@ -1098,7 +1081,6 @@ static struct io_plan *handle_sign_to_us_tx(struct io_conn *conn, if (tx->wtx->num_inputs != 1) return bad_req_fmt(conn, c, msg_in, "bad txinput count"); - tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &input_sat); sign_tx_input(tx, 0, NULL, wscript, privkey, &pubkey, SIGHASH_ALL, &sig); return req_reply(conn, c, take(towire_hsm_sign_tx_reply(NULL, &sig))); @@ -1113,7 +1095,6 @@ static struct io_plan *handle_sign_delayed_payment_to_us(struct io_conn *conn, const u8 *msg_in) { u64 commit_num; - struct amount_sat input_sat; struct secret channel_seed, basepoint_secret; struct pubkey basepoint; struct bitcoin_tx *tx; @@ -1125,8 +1106,7 @@ static struct io_plan *handle_sign_delayed_payment_to_us(struct io_conn *conn, /*~ We don't derive the wscript ourselves, but perhaps we should? */ if (!fromwire_hsm_sign_delayed_payment_to_us(tmpctx, msg_in, &commit_num, - &tx, &wscript, - &input_sat)) + &tx, &wscript)) return bad_req(conn, c, msg_in); tx->chainparams = c->chainparams; get_channel_seed(&c->id, c->dbid, &channel_seed); @@ -1159,7 +1139,7 @@ static struct io_plan *handle_sign_delayed_payment_to_us(struct io_conn *conn, return bad_req_fmt(conn, c, msg_in, "failed deriving privkey"); return handle_sign_to_us_tx(conn, c, msg_in, - tx, &privkey, wscript, input_sat); + tx, &privkey, wscript); } /*~ This is used when a commitment transaction is onchain, and has an HTLC @@ -1169,7 +1149,6 @@ static struct io_plan *handle_sign_remote_htlc_to_us(struct io_conn *conn, struct client *c, const u8 *msg_in) { - struct amount_sat input_sat; struct secret channel_seed, htlc_basepoint_secret; struct pubkey htlc_basepoint; struct bitcoin_tx *tx; @@ -1179,8 +1158,7 @@ static struct io_plan *handle_sign_remote_htlc_to_us(struct io_conn *conn, if (!fromwire_hsm_sign_remote_htlc_to_us(tmpctx, msg_in, &remote_per_commitment_point, - &tx, &wscript, - &input_sat)) + &tx, &wscript)) return bad_req(conn, c, msg_in); tx->chainparams = c->chainparams; @@ -1199,7 +1177,7 @@ static struct io_plan *handle_sign_remote_htlc_to_us(struct io_conn *conn, "Failed deriving htlc privkey"); return handle_sign_to_us_tx(conn, c, msg_in, - tx, &privkey, wscript, input_sat); + tx, &privkey, wscript); } /*~ This is used when the remote peer's commitment transaction is revoked; @@ -1209,7 +1187,6 @@ static struct io_plan *handle_sign_penalty_to_us(struct io_conn *conn, struct client *c, const u8 *msg_in) { - struct amount_sat input_sat; struct secret channel_seed, revocation_secret, revocation_basepoint_secret; struct pubkey revocation_basepoint; struct bitcoin_tx *tx; @@ -1219,8 +1196,7 @@ static struct io_plan *handle_sign_penalty_to_us(struct io_conn *conn, if (!fromwire_hsm_sign_penalty_to_us(tmpctx, msg_in, &revocation_secret, - &tx, &wscript, - &input_sat)) + &tx, &wscript)) return bad_req(conn, c, msg_in); tx->chainparams = c->chainparams; @@ -1243,7 +1219,7 @@ static struct io_plan *handle_sign_penalty_to_us(struct io_conn *conn, "Failed deriving revocation privkey"); return handle_sign_to_us_tx(conn, c, msg_in, - tx, &privkey, wscript, input_sat); + tx, &privkey, wscript); } /*~ This is used when a commitment transaction is onchain, and has an HTLC @@ -1254,7 +1230,6 @@ static struct io_plan *handle_sign_local_htlc_tx(struct io_conn *conn, const u8 *msg_in) { u64 commit_num; - struct amount_sat input_sat; struct secret channel_seed, htlc_basepoint_secret; struct sha256 shaseed; struct pubkey per_commitment_point, htlc_basepoint; @@ -1265,8 +1240,7 @@ static struct io_plan *handle_sign_local_htlc_tx(struct io_conn *conn, struct pubkey htlc_pubkey; if (!fromwire_hsm_sign_local_htlc_tx(tmpctx, msg_in, - &commit_num, &tx, &wscript, - &input_sat)) + &commit_num, &tx, &wscript)) return bad_req(conn, c, msg_in); tx->chainparams = c->chainparams; @@ -1300,7 +1274,6 @@ static struct io_plan *handle_sign_local_htlc_tx(struct io_conn *conn, return bad_req_fmt(conn, c, msg_in, "bad txinput count"); /* FIXME: Check that output script is correct! */ - tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &input_sat); sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey, SIGHASH_ALL, &sig); @@ -1395,13 +1368,11 @@ static struct io_plan *handle_sign_mutual_close_tx(struct io_conn *conn, struct pubkey remote_funding_pubkey, local_funding_pubkey; struct bitcoin_signature sig; struct secrets secrets; - struct amount_sat funding; const u8 *funding_wscript; if (!fromwire_hsm_sign_mutual_close_tx(tmpctx, msg_in, &tx, - &remote_funding_pubkey, - &funding)) + &remote_funding_pubkey)) return bad_req(conn, c, msg_in); tx->chainparams = c->chainparams; @@ -1415,8 +1386,6 @@ static struct io_plan *handle_sign_mutual_close_tx(struct io_conn *conn, funding_wscript = bitcoin_redeem_2of2(tmpctx, &local_funding_pubkey, &remote_funding_pubkey); - /* Need input amount for signing */ - tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &funding); sign_tx_input(tx, 0, NULL, funding_wscript, &secrets.funding_privkey, &local_funding_pubkey, diff --git a/lightningd/hsm_control.c b/lightningd/hsm_control.c index 22b6b715eb9a..3a97a516ffbb 100644 --- a/lightningd/hsm_control.c +++ b/lightningd/hsm_control.c @@ -84,10 +84,11 @@ static unsigned int hsm_msg(struct subd *hsmd, return 0; } -void hsm_init(struct lightningd *ld) +struct ext_key *hsm_init(struct lightningd *ld) { u8 *msg; int fds[2]; + struct ext_key *bip32_base; /* We actually send requests synchronously: only status is async. */ if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) @@ -121,14 +122,16 @@ void hsm_init(struct lightningd *ld) IFDEV(ld->dev_force_channel_secrets_shaseed, NULL)))) err(1, "Writing init msg to hsm"); - ld->wallet->bip32_base = tal(ld->wallet, struct ext_key); + bip32_base = tal(ld, struct ext_key); msg = wire_sync_read(tmpctx, ld->hsm_fd); if (!fromwire_hsm_init_reply(msg, - &ld->id, ld->wallet->bip32_base)) { + &ld->id, bip32_base)) { if (ld->config.keypass) errx(1, "Wrong password for encrypted hsm_secret."); errx(1, "HSM did not give init reply"); } + + return bip32_base; } static struct command_result *json_getsharedsecret(struct command *cmd, diff --git a/lightningd/hsm_control.h b/lightningd/hsm_control.h index 26533ceafc12..8060c721ddf4 100644 --- a/lightningd/hsm_control.h +++ b/lightningd/hsm_control.h @@ -8,6 +8,7 @@ struct lightningd; struct node_id; +struct ext_key; /* Ask HSM for a new fd for a subdaemon to use. */ int hsm_get_client_fd(struct lightningd *ld, @@ -18,5 +19,5 @@ int hsm_get_client_fd(struct lightningd *ld, /* Ask HSM for an fd for a global subdaemon to use (gossipd, connectd) */ int hsm_get_global_fd(struct lightningd *ld, int capabilities); -void hsm_init(struct lightningd *ld); +struct ext_key *hsm_init(struct lightningd *ld); #endif /* LIGHTNING_LIGHTNINGD_HSM_CONTROL_H */ diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 2d4599d93dd5..b44e7be301bf 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -759,6 +759,7 @@ int main(int argc, char *argv[]) struct timers *timers; const char *stop_response; struct htlc_in_map *unconnected_htlcs_in; + struct ext_key *bip32_base; struct rlimit nofile = {1024, 1024}; /*~ Make sure that we limit ourselves to something reasonable. Modesty @@ -822,10 +823,20 @@ int main(int argc, char *argv[]) /*~ Make sure we can reach the subdaemons, and versions match. */ test_subdaemons(ld); + /*~ Set up the HSM daemon, which knows our node secret key, so tells + * us who we are. + * + * HSM stands for Hardware Security Module, which is the industry + * standard of key storage; ours is in software for now, so the name + * doesn't really make sense, but we can't call it the Badly-named + * Daemon Software Module. */ + bip32_base = hsm_init(ld); + /*~ Our "wallet" code really wraps the db, which is more than a simple * bitcoin wallet (though it's that too). It also stores channel * states, invoices, payments, blocks and bitcoin transactions. */ ld->wallet = wallet_new(ld, ld->timers); + ld->wallet->bip32_base = tal_steal(ld->wallet, bip32_base); /*~ We keep track of how many 'coin moves' we've ever made. * Initialize the starting value from the database here. */ @@ -837,15 +848,6 @@ int main(int argc, char *argv[]) /*~ This is the ccan/io central poll override from above. */ io_poll_override(io_poll_lightningd); - /*~ Set up the HSM daemon, which knows our node secret key, so tells - * us who we are. - * - * HSM stands for Hardware Security Module, which is the industry - * standard of key storage; ours is in software for now, so the name - * doesn't really make sense, but we can't call it the Badly-named - * Daemon Software Module. */ - hsm_init(ld); - /*~ If hsm_secret is encrypted, we don't need its encryption key * anymore. Note that sodium_munlock() also zeroes the memory.*/ if (ld->config.keypass) diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index 32e8f346bdae..e4b767dca0dc 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -334,6 +334,7 @@ static void onchain_add_utxo(struct channel *channel, const u8 *msg) u->close_info->channel_id = channel->dbid; u->close_info->peer_id = channel->peer->id; u->spendheight = NULL; + u->scriptPubkey = NULL; if (!fromwire_onchain_add_utxo( u, msg, &u->txid, &u->outnum, &u->close_info->commitment_point, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index c88075feab7a..6cf21234acaf 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -184,20 +184,12 @@ static void sign_last_tx(struct channel *channel) u8 *msg, **witness; assert(!channel->last_tx->wtx->inputs[0].witness); - /* Attach input amount, to complete transaction for marshaling */ - if (!channel->last_tx->input_amounts[0]) { - channel->last_tx->input_amounts[0] - = tal_dup(channel->last_tx->input_amounts, - struct amount_sat, - &channel->funding); - } msg = towire_hsm_sign_commitment_tx(tmpctx, &channel->peer->id, channel->dbid, channel->last_tx, &channel->channel_info - .remote_fundingkey, - channel->funding); + .remote_fundingkey); if (!wire_sync_write(ld->hsm_fd, take(msg))) fatal("Could not write to HSM: %s", strerror(errno)); diff --git a/lightningd/test/run-find_my_abspath.c b/lightningd/test/run-find_my_abspath.c index 241aa797a490..41c74e071580 100644 --- a/lightningd/test/run-find_my_abspath.c +++ b/lightningd/test/run-find_my_abspath.c @@ -110,7 +110,7 @@ void handle_opts(struct lightningd *ld UNNEEDED, int argc UNNEEDED, char *argv[] size_t hash_htlc_key(const struct htlc_key *htlc_key UNNEEDED) { fprintf(stderr, "hash_htlc_key called!\n"); abort(); } /* Generated stub for hsm_init */ -void hsm_init(struct lightningd *ld UNNEEDED) +struct ext_key *hsm_init(struct lightningd *ld UNNEEDED) { fprintf(stderr, "hsm_init called!\n"); abort(); } /* Generated stub for htlcs_notify_new_block */ void htlcs_notify_new_block(struct lightningd *ld UNNEEDED, u32 height UNNEEDED) diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 5ecdea4d6874..e7d426b0c0d5 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -492,7 +492,7 @@ u8 *towire_gossip_get_incoming_channels(const tal_t *ctx UNNEEDED) u8 *towire_hsm_get_channel_basepoints(const tal_t *ctx UNNEEDED, const struct node_id *peerid UNNEEDED, u64 dbid UNNEEDED) { fprintf(stderr, "towire_hsm_get_channel_basepoints called!\n"); abort(); } /* Generated stub for towire_hsm_sign_commitment_tx */ -u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, struct amount_sat funding_amount UNNEEDED) +u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED) { fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); } /* Generated stub for towire_hsm_sign_invoice */ u8 *towire_hsm_sign_invoice(const tal_t *ctx UNNEEDED, const u8 *u5bytes UNNEEDED, const u8 *hrp UNNEEDED) diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index 4b2eac23e43c..8327fdc80e33 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -193,7 +194,7 @@ static void update_ledger_chain_fees(const struct bitcoin_txid *txid, /* Log the fees paid on this transaction as 'chain fees'. note that * you *cannot* pass a chaintopology-originated tx to this method, - * as they don't have the input_amounts populated */ + * as they don't have input amounts populated */ static struct amount_sat record_chain_fees_tx(const struct bitcoin_txid *txid, const struct bitcoin_tx *tx, u32 blockheight) @@ -400,7 +401,8 @@ static bool grind_htlc_tx_fee(struct amount_sat *fee, const u8 *wscript, u64 weight) { - struct amount_sat prev_fee = AMOUNT_SAT(UINT64_MAX); + struct amount_sat prev_fee = AMOUNT_SAT(UINT64_MAX), input_amt; + input_amt = psbt_input_get_amount(tx->psbt, 0); for (u64 i = min_possible_feerate; i <= max_possible_feerate; i++) { /* BOLT #3: @@ -424,7 +426,7 @@ static bool grind_htlc_tx_fee(struct amount_sat *fee, continue; prev_fee = *fee; - if (!amount_sat_sub(&out, *tx->input_amounts[0], *fee)) + if (!amount_sat_sub(&out, input_amt, *fee)) break; bitcoin_tx_output_set_amount(tx, 0, out); @@ -560,8 +562,7 @@ static u8 *delayed_payment_to_us(const tal_t *ctx, const u8 *wscript) { return towire_hsm_sign_delayed_payment_to_us(ctx, commit_num, - tx, wscript, - *tx->input_amounts[0]); + tx, wscript); } static u8 *remote_htlc_to_us(const tal_t *ctx, @@ -570,8 +571,7 @@ static u8 *remote_htlc_to_us(const tal_t *ctx, { return towire_hsm_sign_remote_htlc_to_us(ctx, remote_per_commitment_point, - tx, wscript, - *tx->input_amounts[0]); + tx, wscript); } static u8 *penalty_to_us(const tal_t *ctx, @@ -579,7 +579,7 @@ static u8 *penalty_to_us(const tal_t *ctx, const u8 *wscript) { return towire_hsm_sign_penalty_to_us(ctx, remote_per_commitment_secret, - tx, wscript, *tx->input_amounts[0]); + tx, wscript); } /* @@ -613,7 +613,7 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx, tx = bitcoin_tx(ctx, chainparams, 1, 1, locktime); bitcoin_tx_add_input(tx, &out->txid, out->outnum, to_self_delay, - out->sat, NULL); + NULL, out->sat, NULL, wscript); bitcoin_tx_add_output( tx, scriptpubkey_p2wpkh(tx, &our_wallet_pubkey), NULL, out->sat); @@ -675,8 +675,7 @@ static void hsm_sign_local_htlc_tx(struct bitcoin_tx *tx, struct bitcoin_signature *sig) { u8 *msg = towire_hsm_sign_local_htlc_tx(NULL, commit_num, - tx, wscript, - *tx->input_amounts[0]); + tx, wscript); if (!wire_sync_write(HSM_FD, take(msg))) status_failed(STATUS_FAIL_HSM_IO, @@ -1680,6 +1679,7 @@ static void handle_preimage(struct tracked_output **outs, tx = htlc_success_tx(outs[i], chainparams, &outs[i]->txid, outs[i]->outnum, + outs[i]->wscript, htlc_amount, to_self_delay[LOCAL], 0, @@ -1924,7 +1924,7 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out, */ tx = htlc_timeout_tx(tmpctx, chainparams, &out->txid, out->outnum, - htlc_amount, + htlc_scripts[matches[i]], htlc_amount, htlcs[matches[i]].cltv_expiry, to_self_delay[LOCAL], 0, keyset); diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c index f714af2d69d3..633a15a6232f 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -100,6 +100,7 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED, const struct chainparams *chainparams UNNEEDED, const struct bitcoin_txid *commit_txid UNNEEDED, unsigned int commit_output_number UNNEEDED, + const u8 *commit_wscript UNNEEDED, struct amount_msat htlc_msatoshi UNNEEDED, u16 to_self_delay UNNEEDED, u32 feerate_per_kw UNNEEDED, @@ -221,13 +222,13 @@ void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED) u8 *towire_hsm_get_per_commitment_point(const tal_t *ctx UNNEEDED, u64 n UNNEEDED) { fprintf(stderr, "towire_hsm_get_per_commitment_point called!\n"); abort(); } /* Generated stub for towire_hsm_sign_delayed_payment_to_us */ -u8 *towire_hsm_sign_delayed_payment_to_us(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED) +u8 *towire_hsm_sign_delayed_payment_to_us(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_hsm_sign_delayed_payment_to_us called!\n"); abort(); } /* Generated stub for towire_hsm_sign_penalty_to_us */ -u8 *towire_hsm_sign_penalty_to_us(const tal_t *ctx UNNEEDED, const struct secret *revocation_secret UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED) +u8 *towire_hsm_sign_penalty_to_us(const tal_t *ctx UNNEEDED, const struct secret *revocation_secret UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_hsm_sign_penalty_to_us called!\n"); abort(); } /* Generated stub for towire_hsm_sign_remote_htlc_to_us */ -u8 *towire_hsm_sign_remote_htlc_to_us(const tal_t *ctx UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED) +u8 *towire_hsm_sign_remote_htlc_to_us(const tal_t *ctx UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_hsm_sign_remote_htlc_to_us called!\n"); abort(); } /* Generated stub for towire_onchain_add_utxo */ u8 *towire_onchain_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *prev_out_tx UNNEEDED, u32 prev_out_index UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, struct amount_sat value UNNEEDED, u32 blockheight UNNEEDED, const u8 *scriptpubkey UNNEEDED) @@ -290,7 +291,7 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE /* AUTOGENERATED MOCKS END */ /* Stubs which do get called. */ -u8 *towire_hsm_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED) +u8 *towire_hsm_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED) { return NULL; } @@ -338,6 +339,7 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, const struct chainparams *chainparams, const struct bitcoin_txid *commit_txid UNNEEDED, unsigned int commit_output_number UNNEEDED, + const u8* commit_wscript, struct amount_msat htlc_msatoshi, u32 cltv_expiry, u16 to_self_delay UNNEEDED, @@ -352,10 +354,10 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx, assert(tx); in_amount = amount_msat_to_sat_round_down(htlc_msatoshi); - tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &in_amount); + psbt_input_set_prev_utxo_wscript(tx->psbt, 0, commit_wscript, in_amount); tx->chainparams = chainparams; - tx->wtx->locktime = cltv_expiry; + bitcoin_tx_set_locktime(tx, cltv_expiry); return tx; } diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index bbfa1d964e68..3dbe8ce48b60 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -101,6 +101,7 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED, const struct chainparams *chainparams UNNEEDED, const struct bitcoin_txid *commit_txid UNNEEDED, unsigned int commit_output_number UNNEEDED, + const u8 *commit_wscript UNNEEDED, struct amount_msat htlc_msatoshi UNNEEDED, u16 to_self_delay UNNEEDED, u32 feerate_per_kw UNNEEDED, @@ -111,6 +112,7 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx UNNEEDED, const struct chainparams *chainparams UNNEEDED, const struct bitcoin_txid *commit_txid UNNEEDED, unsigned int commit_output_number UNNEEDED, + const u8 *commit_wscript UNNEEDED, struct amount_msat htlc_msatoshi UNNEEDED, u32 cltv_expiry UNNEEDED, u16 to_self_delay UNNEEDED, @@ -236,16 +238,16 @@ void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED) u8 *towire_hsm_get_per_commitment_point(const tal_t *ctx UNNEEDED, u64 n UNNEEDED) { fprintf(stderr, "towire_hsm_get_per_commitment_point called!\n"); abort(); } /* Generated stub for towire_hsm_sign_delayed_payment_to_us */ -u8 *towire_hsm_sign_delayed_payment_to_us(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED) +u8 *towire_hsm_sign_delayed_payment_to_us(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_hsm_sign_delayed_payment_to_us called!\n"); abort(); } /* Generated stub for towire_hsm_sign_local_htlc_tx */ -u8 *towire_hsm_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED) +u8 *towire_hsm_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_hsm_sign_local_htlc_tx called!\n"); abort(); } /* Generated stub for towire_hsm_sign_penalty_to_us */ -u8 *towire_hsm_sign_penalty_to_us(const tal_t *ctx UNNEEDED, const struct secret *revocation_secret UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED) +u8 *towire_hsm_sign_penalty_to_us(const tal_t *ctx UNNEEDED, const struct secret *revocation_secret UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_hsm_sign_penalty_to_us called!\n"); abort(); } /* Generated stub for towire_hsm_sign_remote_htlc_to_us */ -u8 *towire_hsm_sign_remote_htlc_to_us(const tal_t *ctx UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED) +u8 *towire_hsm_sign_remote_htlc_to_us(const tal_t *ctx UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_hsm_sign_remote_htlc_to_us called!\n"); abort(); } /* Generated stub for towire_onchain_add_utxo */ u8 *towire_onchain_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *prev_out_tx UNNEEDED, u32 prev_out_index UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, struct amount_sat value UNNEEDED, u32 blockheight UNNEEDED, const u8 *scriptpubkey UNNEEDED) @@ -330,8 +332,7 @@ int main(int argc, char *argv[]) tx = bitcoin_tx_from_hex(tmpctx, "0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000", strlen("0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000")); tx->chainparams = chainparams_for_network("regtest"); - tx->input_amounts[0] = tal(tx, struct amount_sat); - *tx->input_amounts[0] = AMOUNT_SAT(700000); + psbt_input_set_prev_utxo(tx->psbt, 0, NULL, AMOUNT_SAT(700000)); tx->chainparams = chainparams_for_network("bitcoin"); der = tal_hexdata(tmpctx, "30450221009b2e0eef267b94c3899fb0dc7375012e2cee4c10348a068fe78d1b82b4b14036022077c3fad3adac2ddf33f415e45f0daf6658b7a0b09647de4443938ae2dbafe2b9" "01", strlen("30450221009b2e0eef267b94c3899fb0dc7375012e2cee4c10348a068fe78d1b82b4b14036022077c3fad3adac2ddf33f415e45f0daf6658b7a0b09647de4443938ae2dbafe2b9" "01")); diff --git a/openingd/openingd.c b/openingd/openingd.c index 6e6d0f67209e..b72be7cdaebb 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -735,7 +736,6 @@ static bool funder_finalize_channel_setup(struct state *state, msg = towire_hsm_sign_remote_commitment_tx(NULL, *tx, &state->channel->funding_pubkey[REMOTE], - state->channel->funding, &state->first_per_commitment_point[REMOTE], state->channel->option_static_remotekey); @@ -845,6 +845,12 @@ static bool funder_finalize_channel_setup(struct state *state, &state->their_funding_pubkey)); } + /* We save their sig to our first commitment tx */ + psbt_input_set_partial_sig((*tx)->psbt, 0, + &state->their_funding_pubkey, + sig); + + peer_billboard(false, "Funding channel: opening negotiation succeeded"); return true; @@ -1269,7 +1275,6 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) msg = towire_hsm_sign_remote_commitment_tx(NULL, remote_commit, &state->channel->funding_pubkey[REMOTE], - state->channel->funding, &state->first_per_commitment_point[REMOTE], state->channel->option_static_remotekey); diff --git a/tests/data/last_tx_upgrade.sqlite3.xz b/tests/data/last_tx_upgrade.sqlite3.xz new file mode 100644 index 000000000000..765e24458774 Binary files /dev/null and b/tests/data/last_tx_upgrade.sqlite3.xz differ diff --git a/tests/test_db.py b/tests/test_db.py index 8379dd3480d1..e4e3a61991c6 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -1,7 +1,10 @@ +from decimal import Decimal from fixtures import * # noqa: F401,F403 from fixtures import TEST_NETWORK from pyln.client import RpcError -from utils import wait_for, sync_blockheight, COMPAT, VALGRIND, DEVELOPER +from utils import wait_for, sync_blockheight, COMPAT, VALGRIND, DEVELOPER, only_one + +import base64 import os import pytest import time @@ -140,6 +143,29 @@ def test_scid_upgrade(node_factory, bitcoind): assert l1.db_query('SELECT failchannel from payments;') == [{'failchannel': '103x1x1'}] +@unittest.skipIf(not COMPAT, "needs COMPAT to convert obsolete db") +@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "This test is based on a sqlite3 snapshot") +@unittest.skipIf(TEST_NETWORK != 'regtest', "The network must match the DB snapshot") +def test_last_tx_psbt_upgrade(node_factory, bitcoind): + bitcoind.generate_block(12) + + prior_txs = ['02000000018DD699861B00061E50937A233DB584BF8ED4C0BF50B44C0411F71B031A06455000000000000EF7A9800350C300000000000022002073356CFF7E1588F14935EF138E142ABEFB5F7E3D51DE942758DCD5A179449B6250A90600000000002200202DF545EA882889846C52FC5E111AC07CE07E0C09418AC15743A6F6284C2A4FA720A1070000000000160014E89954FAC8F7A2DCE51E095D7BEB5271C3F7DA56EF81DC20', '02000000018A0AE4C63BCDF9D78B07EB4501BB23404FDDBC73973C592793F047BE1495074B010000000074D99980010A2D0F00000000002200203B8CB644781CBECA96BE8B2BF1827AFD908B3CFB5569AC74DAB9395E8DDA39E4C9555420', '020000000135DAB2996E57762E3EC158C0D57D39F43CA657E882D93FC24F5FEBAA8F36ED9A0100000000566D1D800350C30000000000002200205679A7D06E1BD276AA25F56E9E4DF7E07D9837EFB0C5F63604F10CD9F766A03ED4DD0600000000001600147E5B5C8F4FC1A9484E259F92CA4CBB7FA2814EA49A6C070000000000220020AB6226DEBFFEFF4A741C01367FA3C875172483CFB3E327D0F8C7AA4C51EDECAA27AA4720'] + + l1 = node_factory.get_node(dbfile='last_tx_upgrade.sqlite3.xz') + + b64_last_txs = [base64.b64encode(x['last_tx']).decode('utf-8') for x in l1.db_query('SELECT last_tx FROM channels ORDER BY id;')] + for i in range(len(b64_last_txs)): + bpsbt = b64_last_txs[i] + psbt = bitcoind.rpc.decodepsbt(bpsbt) + tx = prior_txs[i] + assert psbt['tx']['txid'] == bitcoind.rpc.decoderawtransaction(tx)['txid'] + funding_input = only_one(psbt['inputs']) + # Every opened channel was funded with the same amount: 1M sats + assert funding_input['witness_utxo']['amount'] == Decimal('0.01') + assert funding_input['witness_utxo']['scriptPubKey']['type'] == 'witness_v0_scripthash' + assert funding_input['witness_script']['type'] == 'multisig' + + @unittest.skipIf(VALGRIND and not DEVELOPER, "Without developer valgrind will complain about debug symbols missing") def test_optimistic_locking(node_factory, bitcoind): """Have a node run against a DB, then change it under its feet, crashing it. diff --git a/wallet/db.c b/wallet/db.c index cdb9829292bb..b5eb29c5e80b 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -1,11 +1,15 @@ #include "db.h" +#include +#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -612,6 +616,7 @@ static struct migration dbmigrations[] = { {SQL("ALTER TABLE channel_htlcs ADD we_filled INTEGER;"), NULL}, /* We track the counter for coin_moves, as a convenience for notification consumers */ {SQL("INSERT INTO vars (name, intval) VALUES ('coin_moves_count', 0);"), NULL}, + {NULL, migrate_last_tx_to_psbt}, }; /* Leak tracking. */ @@ -1110,6 +1115,78 @@ static void migrate_our_funding(struct lightningd *ld, struct db *db) tal_free(stmt); } +/* We're moving everything over to PSBTs from tx's, particularly our last_tx's + * which are commitment transactions for channels. + * This migration loads all of the last_tx's and 're-formats' them into psbts, + * adds the required input witness utxo information, and then saves it back to disk + * */ +void migrate_last_tx_to_psbt(struct lightningd *ld, struct db *db) +{ + struct db_stmt *stmt, *update_stmt; + + stmt = db_prepare_v2(db, SQL("SELECT " + " c.id" + ", p.node_id" + ", c.last_tx" + ", c.funding_satoshi" + ", c.fundingkey_remote" + ", c.last_sig" + " FROM channels c" + " LEFT OUTER JOIN peers p" + " ON p.id = c.peer_id;")); + + db_query_prepared(stmt); + while (db_step(stmt)) { + struct bitcoin_tx *last_tx; + struct amount_sat funding_sat; + struct node_id peer_id; + struct pubkey local_funding_pubkey, remote_funding_pubkey; + struct basepoints local_basepoints UNUSED; + struct bitcoin_signature last_sig; + u64 cdb_id; + u8 *funding_wscript; + + cdb_id = db_column_u64(stmt, 0); + last_tx = db_column_tx(stmt, stmt, 2); + assert(last_tx != NULL); + + db_column_node_id(stmt, 1, &peer_id); + db_column_amount_sat(stmt, 3, &funding_sat); + db_column_pubkey(stmt, 4, &remote_funding_pubkey); + + get_channel_basepoints(ld, &peer_id, cdb_id, + &local_basepoints, &local_funding_pubkey); + + funding_wscript = bitcoin_redeem_2of2(stmt, &local_funding_pubkey, + &remote_funding_pubkey); + + psbt_input_set_prev_utxo_wscript(last_tx->psbt, + 0, funding_wscript, + funding_sat); + + if (!db_column_signature(stmt, 5, &last_sig.s)) + abort(); + + last_sig.sighash_type = SIGHASH_ALL; + psbt_input_set_partial_sig(last_tx->psbt, 0, + &remote_funding_pubkey, &last_sig); + psbt_input_add_pubkey(last_tx->psbt, 0, + &local_funding_pubkey); + psbt_input_add_pubkey(last_tx->psbt, 0, + &remote_funding_pubkey); + + update_stmt = db_prepare_v2(db, SQL("UPDATE channels" + " SET last_tx = ?" + " WHERE id = ?;")); + db_bind_psbt(update_stmt, 0, last_tx->psbt); + db_bind_int(update_stmt, 1, cdb_id); + db_exec_prepared_v2(update_stmt); + tal_free(update_stmt); + } + + tal_free(stmt); +} + void db_bind_null(struct db_stmt *stmt, int pos) { assert(pos < tal_count(stmt->bindings)); @@ -1253,6 +1330,14 @@ void db_bind_tx(struct db_stmt *stmt, int col, const struct bitcoin_tx *tx) db_bind_blob(stmt, col, ser, tal_count(ser)); } +void db_bind_psbt(struct db_stmt *stmt, int col, const struct wally_psbt *psbt) +{ + size_t bytes_written; + const u8 *ser = psbt_get_bytes(stmt, psbt, &bytes_written); + assert(ser); + db_bind_blob(stmt, col, ser, bytes_written); +} + void db_bind_amount_msat(struct db_stmt *stmt, int pos, const struct amount_msat *msat) { @@ -1372,6 +1457,17 @@ struct bitcoin_tx *db_column_tx(const tal_t *ctx, struct db_stmt *stmt, int col) return pull_bitcoin_tx(ctx, &src, &len); } +struct bitcoin_tx *db_column_psbt_to_tx(const tal_t *ctx, struct db_stmt *stmt, int col) +{ + struct wally_psbt *psbt; + const u8 *src = db_column_blob(stmt, col); + size_t len = db_column_bytes(stmt, col); + psbt = psbt_from_bytes(ctx, src, len); + if (!psbt) + return NULL; + return bitcoin_tx_with_psbt(ctx, psbt); +} + void *db_column_arr_(const tal_t *ctx, struct db_stmt *stmt, int col, size_t bytes, const char *label, const char *caller) { diff --git a/wallet/db.h b/wallet/db.h index dace782e3e54..f8b6c112e999 100644 --- a/wallet/db.h +++ b/wallet/db.h @@ -21,7 +21,9 @@ struct node_id; struct onionreply; struct db_stmt; struct db; +struct wally_psbt; +void migrate_last_tx_to_psbt(struct lightningd *ld, struct db *db); /** * Macro to annotate a named SQL query. * @@ -115,6 +117,7 @@ void db_bind_signature(struct db_stmt *stmt, int col, const secp256k1_ecdsa_signature *sig); void db_bind_timeabs(struct db_stmt *stmt, int col, struct timeabs t); void db_bind_tx(struct db_stmt *stmt, int col, const struct bitcoin_tx *tx); +void db_bind_psbt(struct db_stmt *stmt, int col, const struct wally_psbt *psbt); void db_bind_amount_msat(struct db_stmt *stmt, int pos, const struct amount_msat *msat); void db_bind_amount_sat(struct db_stmt *stmt, int pos, @@ -153,6 +156,7 @@ bool db_column_signature(struct db_stmt *stmt, int col, secp256k1_ecdsa_signature *sig); struct timeabs db_column_timeabs(struct db_stmt *stmt, int col); struct bitcoin_tx *db_column_tx(const tal_t *ctx, struct db_stmt *stmt, int col); +struct bitcoin_tx *db_column_psbt_to_tx(const tal_t *ctx, struct db_stmt *stmt, int col); struct onionreply *db_column_onionreply(const tal_t *ctx, struct db_stmt *stmt, int col); diff --git a/wallet/test/run-db.c b/wallet/test/run-db.c index 5a75a5793fbb..aeeed1ea2ee3 100644 --- a/wallet/test/run-db.c +++ b/wallet/test/run-db.c @@ -21,6 +21,13 @@ static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, const s /* Generated stub for fatal */ void fatal(const char *fmt UNNEEDED, ...) { fprintf(stderr, "fatal called!\n"); abort(); } +/* Generated stub for get_channel_basepoints */ +void get_channel_basepoints(struct lightningd *ld UNNEEDED, + const struct node_id *peer_id UNNEEDED, + const u64 dbid UNNEEDED, + struct basepoints *local_basepoints UNNEEDED, + struct pubkey *local_funding_pubkey UNNEEDED) +{ fprintf(stderr, "get_channel_basepoints called!\n"); abort(); } /* Generated stub for new_log */ struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, const struct node_id *default_node_id UNNEEDED, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index b101e1bf208d..469de169ea36 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -693,7 +693,7 @@ u8 *towire_final_incorrect_htlc_amount(const tal_t *ctx UNNEEDED, struct amount_ u8 *towire_gossip_get_stripped_cupdate(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED) { fprintf(stderr, "towire_gossip_get_stripped_cupdate called!\n"); abort(); } /* Generated stub for towire_hsm_sign_commitment_tx */ -u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, struct amount_sat funding_amount UNNEEDED) +u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED) { fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); } /* Generated stub for towire_incorrect_cltv_expiry */ u8 *towire_incorrect_cltv_expiry(const tal_t *ctx UNNEEDED, u32 cltv_expiry UNNEEDED, const u8 *channel_update UNNEEDED) diff --git a/wallet/wallet.c b/wallet/wallet.c index 620c9ec32428..5421aef317a8 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1,6 +1,7 @@ #include "invoices.h" #include "wallet.h" +#include #include #include #include @@ -1054,7 +1055,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm our_msat, msat_to_us_min, /* msatoshi_to_us_min */ msat_to_us_max, /* msatoshi_to_us_max */ - db_column_tx(tmpctx, stmt, 33), + db_column_psbt_to_tx(tmpctx, stmt, 33), &last_sig, wallet_htlc_sigs_load(tmpctx, w, db_column_u64(stmt, 0)), @@ -1075,6 +1076,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm db_column_int(stmt, 44), db_column_arr(tmpctx, stmt, 45, u8), db_column_int(stmt, 46)); + return chan; } @@ -1446,7 +1448,7 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) db_bind_u64(stmt, 17, chan->final_key_idx); db_bind_u64(stmt, 18, chan->our_config.id); - db_bind_tx(stmt, 19, chan->last_tx); + db_bind_psbt(stmt, 19, chan->last_tx->psbt); db_bind_signature(stmt, 20, &chan->last_sig.s); db_bind_int(stmt, 21, chan->last_was_revoke); db_bind_int(stmt, 22, chan->min_possible_feerate);