diff --git a/bitcoin/tx.c b/bitcoin/tx.c index 3df2c31aa6af..37883e74a251 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -399,6 +399,7 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, tx->input_amounts = tal_arrz(tx, struct amount_sat*, input_count); tx->wtx->locktime = nlocktime; tx->wtx->version = 2; + tx->output_witscripts = tal_arrz(tx, struct witscript*, output_count); tx->chainparams = chainparams; return tx; } diff --git a/bitcoin/tx.h b/bitcoin/tx.h index 4168b5e36d24..d36f66ba9cce 100644 --- a/bitcoin/tx.h +++ b/bitcoin/tx.h @@ -12,6 +12,10 @@ #define BITCOIN_TX_DEFAULT_SEQUENCE 0xFFFFFFFF +struct witscript { + u8 *ptr; +}; + struct bitcoin_txid { struct sha256_double shad; }; @@ -24,6 +28,9 @@ struct bitcoin_tx { struct amount_sat **input_amounts; struct wally_tx *wtx; + /* Need the output wscripts in the HSM to validate transaction */ + struct witscript **output_witscripts; + /* Keep a reference to the ruleset we have to abide by */ const struct chainparams *chainparams; }; diff --git a/channeld/channeld.c b/channeld/channeld.c index 4dbb8b6a7d67..31037d798fa6 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -995,7 +995,10 @@ 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]); + *txs[0]->input_amounts[0], + (const struct witscript **) txs[0]->output_witscripts, + &peer->remote_per_commit, + peer->channel->option_static_remotekey); msg = hsm_req(tmpctx, take(msg)); if (!fromwire_hsm_sign_tx_reply(msg, commit_sig)) diff --git a/channeld/commit_tx.c b/channeld/commit_tx.c index c8f336ff0562..05a2c1602fbf 100644 --- a/channeld/commit_tx.c +++ b/channeld/commit_tx.c @@ -36,7 +36,8 @@ size_t commit_tx_num_untrimmed(const struct htlc **htlcs, static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n, const struct htlc *htlc, - const struct keyset *keyset) + const struct keyset *keyset, + struct witscript *o_wscript) { struct ripemd160 ripemd; u8 *wscript, *p2wsh; @@ -49,12 +50,15 @@ static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n, SUPERVERBOSE("# HTLC %" PRIu64 " offered %s wscript %s\n", htlc->id, type_to_string(tmpctx, struct amount_sat, &amount), tal_hex(wscript, wscript)); + o_wscript->ptr = tal_dup_arr(o_wscript, u8, wscript, + tal_count(wscript), 0); tal_free(wscript); } static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n, const struct htlc *htlc, - const struct keyset *keyset) + const struct keyset *keyset, + struct witscript *o_wscript) { struct ripemd160 ripemd; u8 *wscript, *p2wsh; @@ -72,6 +76,8 @@ static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n, type_to_string(tmpctx, struct amount_sat, &amount), tal_hex(wscript, wscript)); + o_wscript->ptr = tal_dup_arr(o_wscript, u8, + wscript, tal_count(wscript), 0); tal_free(wscript); } @@ -169,7 +175,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, continue; if (trim(htlcs[i], feerate_per_kw, dust_limit, side)) continue; - add_offered_htlc_out(tx, n, htlcs[i], keyset); + tx->output_witscripts[n] = + tal(tx->output_witscripts, struct witscript); + add_offered_htlc_out(tx, n, htlcs[i], + keyset, tx->output_witscripts[n]); (*htlcmap)[n] = htlcs[i]; cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry); n++; @@ -185,7 +194,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, continue; if (trim(htlcs[i], feerate_per_kw, dust_limit, side)) continue; - add_received_htlc_out(tx, n, htlcs[i], keyset); + tx->output_witscripts[n] = + tal(tx->output_witscripts, struct witscript); + add_received_htlc_out(tx, n, htlcs[i], keyset, + tx->output_witscripts[n]); (*htlcmap)[n] = htlcs[i]; cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry); n++; @@ -209,6 +221,11 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, SUPERVERBOSE("# to-local amount %s wscript %s\n", type_to_string(tmpctx, struct amount_sat, &amount), tal_hex(tmpctx, wscript)); + tx->output_witscripts[n] = + tal(tx->output_witscripts, struct witscript); + tx->output_witscripts[n]->ptr = + tal_dup_arr(tx->output_witscripts[n], u8, + wscript, tal_count(wscript), 0); n++; } @@ -252,6 +269,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, assert(n <= tx->wtx->outputs_allocation_len); tal_resize(htlcmap, n); + tal_resize(&(tx->output_witscripts), n); /* BOLT #3: * diff --git a/common/initial_commit_tx.c b/common/initial_commit_tx.c index 78bdf156665d..de983c46337c 100644 --- a/common/initial_commit_tx.c +++ b/common/initial_commit_tx.c @@ -175,6 +175,11 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, int pos = bitcoin_tx_add_output( tx, scriptpubkey_p2wsh(tx, wscript), amount); assert(pos == n); + tx->output_witscripts[n] = + tal(tx->output_witscripts, struct witscript); + tx->output_witscripts[n]->ptr = + tal_dup_arr(tx->output_witscripts[n], u8, + wscript, tal_count(wscript), 0); n++; } @@ -202,6 +207,8 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx, assert(n <= tx->wtx->num_outputs); + tal_resize(&(tx->output_witscripts), n); + /* BOLT #3: * * 7. Sort the outputs into [BIP 69+CLTV diff --git a/common/permute_tx.c b/common/permute_tx.c index c1f70570fc26..4ad32df49c6e 100644 --- a/common/permute_tx.c +++ b/common/permute_tx.c @@ -174,5 +174,12 @@ void permute_outputs(struct bitcoin_tx *tx, u32 *cltvs, const void **map) /* Swap best into first place. */ swap_wally_outputs(tx->wtx->outputs, map, cltvs, i, best_pos); + + /* If output_witscripts are present, swap them to match. */ + if (tx->output_witscripts) { + struct witscript *tmp = tx->output_witscripts[i]; + tx->output_witscripts[i] = tx->output_witscripts[best_pos]; + tx->output_witscripts[best_pos] = tmp; + } } } diff --git a/hsmd/hsm_wire.csv b/hsmd/hsm_wire.csv index 9cada00f30c7..eb1eb96e32ba 100644 --- a/hsmd/hsm_wire.csv +++ b/hsmd/hsm_wire.csv @@ -159,6 +159,10 @@ 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,num_witscripts,u16, +msgdata,hsm_sign_remote_commitment_tx,output_witscripts,witscript,num_witscripts +msgdata,hsm_sign_remote_commitment_tx,remote_per_commit,pubkey, +msgdata,hsm_sign_remote_commitment_tx,option_static_remotekey,bool, # channeld asks HSM to sign remote HTLC tx. msgtype,hsm_sign_remote_htlc_tx,20 diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index b5e95e700e0a..156de032482d 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -996,11 +996,17 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn, struct bitcoin_signature sig; struct secrets secrets; const u8 *funding_wscript; + struct witscript **output_witscripts; + struct pubkey remote_per_commit; + bool option_static_remotekey; if (!fromwire_hsm_sign_remote_commitment_tx(tmpctx, msg_in, &tx, &remote_funding_pubkey, - &funding)) + &funding, + &output_witscripts, + &remote_per_commit, + &option_static_remotekey)) bad_req(conn, c, msg_in); tx->chainparams = c->chainparams; @@ -1009,6 +1015,8 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn, return bad_req_fmt(conn, c, msg_in, "tx must have 1 input"); if (tx->wtx->num_outputs == 0) return bad_req_fmt(conn, c, msg_in, "tx must have > 0 outputs"); + if (tal_count(output_witscripts) != tx->wtx->num_outputs) + return bad_req_fmt(conn, c, msg_in, "tx must have matching witscripts"); get_channel_seed(&c->id, c->dbid, &channel_seed); derive_basepoints(&channel_seed, diff --git a/openingd/openingd.c b/openingd/openingd.c index 82004735613d..b7fb61b97215 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -719,7 +719,10 @@ 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->channel->funding, + (const struct witscript **) (*tx)->output_witscripts, + &state->first_per_commitment_point[REMOTE], + state->channel->option_static_remotekey); wire_sync_write(HSM_FD, take(msg)); msg = wire_sync_read(tmpctx, HSM_FD); @@ -1234,7 +1237,10 @@ 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->channel->funding, + (const struct witscript **) remote_commit->output_witscripts, + &state->first_per_commitment_point[REMOTE], + state->channel->option_static_remotekey); wire_sync_write(HSM_FD, take(msg)); msg = wire_sync_read(tmpctx, HSM_FD); diff --git a/tools/generate-wire.py b/tools/generate-wire.py index 1ff6e9e788af..abaff78eba8e 100755 --- a/tools/generate-wire.py +++ b/tools/generate-wire.py @@ -225,6 +225,7 @@ class Type(FieldSet): 'exclude_entry', 'fee_states', 'onionreply', + 'witscript', ] # Some BOLT types are re-typed based on their field name diff --git a/wire/fromwire.c b/wire/fromwire.c index 1d17c02f2cb5..e2bbc047a4b4 100644 --- a/wire/fromwire.c +++ b/wire/fromwire.c @@ -403,6 +403,18 @@ struct bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx, return output; } +struct witscript *fromwire_witscript(const tal_t *ctx, const u8 **cursor, size_t *max) +{ + struct witscript *retval; + u16 len = fromwire_u16(cursor, max); + if (!len) + return NULL; + retval = tal(ctx, struct witscript); + retval->ptr = tal_arr(retval, u8, len); + fromwire_u8_array(cursor, max, retval->ptr, len); + return retval; +} + void fromwire_chainparams(const u8 **cursor, size_t *max, const struct chainparams **chainparams) { diff --git a/wire/towire.c b/wire/towire.c index 1c85c865c16b..d7677826d221 100644 --- a/wire/towire.c +++ b/wire/towire.c @@ -263,6 +263,17 @@ void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output) towire_u8_array(pptr, output->script, tal_count(output->script)); } +void towire_witscript(u8 **pptr, const struct witscript *script) +{ + if (script == NULL) { + towire_u16(pptr, 0); + } else { + assert(script->ptr != NULL); + towire_u16(pptr, tal_count(script->ptr)); + towire_u8_array(pptr, script->ptr, tal_count(script->ptr)); + } +} + void towire_chainparams(u8 **cursor, const struct chainparams *chainparams) { towire_bitcoin_blkid(cursor, &chainparams->genesis_blockhash); diff --git a/wire/wire.h b/wire/wire.h index 4d77a1c563d0..ca1ca248101b 100644 --- a/wire/wire.h +++ b/wire/wire.h @@ -30,6 +30,7 @@ struct bitcoin_txid; struct preimage; struct ripemd160; struct siphash_seed; +struct witscript; /* Makes generate-wire.py work */ typedef char wirestring; @@ -91,6 +92,7 @@ void towire_siphash_seed(u8 **cursor, const struct siphash_seed *seed); void towire_bip32_key_version(u8 **cursor, const struct bip32_key_version *version); void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output); +void towire_witscript(u8 **pptr, const struct witscript *script); void towire_chainparams(u8 **cursor, const struct chainparams *chainparams); const u8 *fromwire(const u8 **cursor, size_t *max, void *copy, size_t n); @@ -145,6 +147,8 @@ void fromwire_bip32_key_version(const u8 **cursor, size_t *max, struct bip32_key_version *version); struct bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx, const u8 **cursor, size_t *max); +struct witscript *fromwire_witscript(const tal_t *ctx, + const u8 **cursor, size_t *max); void fromwire_chainparams(const u8 **cursor, size_t *max, const struct chainparams **chainparams);