From fe85cf9a4fa41cc9afa9e88e1a84541907489814 Mon Sep 17 00:00:00 2001 From: "Dr. Maxim Orlovsky" Date: Tue, 18 Feb 2020 04:50:18 +0100 Subject: [PATCH] Removing duplicated wscript generation for channel txs --- channeld/channeld.c | 25 ++++++++++---------- channeld/full_channel.c | 37 ++++++++++++----------------- channeld/full_channel.h | 4 ++-- channeld/test/run-full_channel.c | 21 ++++++++--------- common/htlc_tx.c | 6 +++++ devtools/mkcommit.c | 40 +++++++++++++++++--------------- external/libwally-core | 2 +- 7 files changed, 68 insertions(+), 67 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 480dfdb39..6e2a3b21e 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -810,14 +810,14 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx, { size_t i; struct bitcoin_tx **txs; - const u8 **wscripts; + const u8 *funding_wscript; const struct htlc **htlc_map; struct pubkey local_htlckey; const u8 *msg; secp256k1_ecdsa_signature *htlc_sigs; txs = channel_txs(tmpctx, &htlc_map, - &wscripts, peer->channel, &peer->remote_per_commit, + &funding_wscript, peer->channel, &peer->remote_per_commit, commit_index, REMOTE); msg = towire_hsm_sign_remote_commitment_tx(NULL, txs[0], @@ -838,7 +838,7 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx, type_to_string(tmpctx, struct bitcoin_signature, commit_sig), type_to_string(tmpctx, struct bitcoin_tx, txs[0]), - tal_hex(tmpctx, wscripts[0]), + tal_hex(tmpctx, funding_wscript), type_to_string(tmpctx, struct pubkey, &peer->channel->funding_pubkey[LOCAL])); dump_htlcs(peer->channel, "Sending commit_sig"); @@ -861,7 +861,7 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx, for (i = 0; i < tal_count(htlc_sigs); i++) { struct bitcoin_signature sig; msg = towire_hsm_sign_remote_htlc_tx(NULL, txs[i + 1], - wscripts[i + 1], + txs[i+1]->output_witscripts[0]->ptr, *txs[i+1]->input_amounts[0], &peer->remote_per_commit); @@ -876,10 +876,11 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx, type_to_string(tmpctx, struct bitcoin_signature, &sig), type_to_string(tmpctx, struct bitcoin_tx, txs[1+i]), - tal_hex(tmpctx, wscripts[1+i]), + tal_hex(tmpctx, txs[i+1]->output_witscripts[0]->ptr), type_to_string(tmpctx, struct pubkey, &local_htlckey)); - assert(check_tx_sig(txs[1+i], 0, NULL, wscripts[1+i], + assert(check_tx_sig(txs[1+i], 0, NULL, + txs[i+1]->output_witscripts[0]->ptr, &local_htlckey, &sig)); } @@ -1201,7 +1202,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) struct pubkey remote_htlckey; struct bitcoin_tx **txs; const struct htlc **htlc_map, **changed_htlcs; - const u8 **wscripts; + const u8 *funding_wscript; size_t i; changed_htlcs = tal_arr(msg, const struct htlc *, 0); @@ -1241,7 +1242,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) txs = channel_txs(tmpctx, &htlc_map, - &wscripts, peer->channel, &peer->next_local_per_commit, + &funding_wscript, peer->channel, &peer->next_local_per_commit, peer->next_index[LOCAL], LOCAL); if (!derive_simple_key(&peer->channel->basepoints[REMOTE].htlc, @@ -1261,7 +1262,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) * - if `signature` is not valid for its local commitment transaction: * - MUST fail the channel. */ - if (!check_tx_sig(txs[0], 0, NULL, wscripts[0], + if (!check_tx_sig(txs[0], 0, NULL, funding_wscript, &peer->channel->funding_pubkey[REMOTE], &commit_sig)) { dump_htlcs(peer->channel, "receiving commit_sig"); peer_failed(peer->pps, @@ -1271,7 +1272,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) type_to_string(msg, struct bitcoin_signature, &commit_sig), type_to_string(msg, struct bitcoin_tx, txs[0]), - tal_hex(msg, wscripts[0]), + tal_hex(msg, funding_wscript), type_to_string(msg, struct pubkey, &peer->channel->funding_pubkey [REMOTE]), @@ -1305,14 +1306,14 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) sig.s = htlc_sigs[i]; sig.sighash_type = SIGHASH_ALL; - if (!check_tx_sig(txs[1+i], 0, NULL, wscripts[1+i], + if (!check_tx_sig(txs[1+i], 0, NULL, txs[1+i]->output_witscripts[0]->ptr, &remote_htlckey, &sig)) peer_failed(peer->pps, &peer->channel_id, "Bad commit_sig signature %s for htlc %s wscript %s key %s", type_to_string(msg, struct bitcoin_signature, &sig), type_to_string(msg, struct bitcoin_tx, txs[1+i]), - tal_hex(msg, wscripts[1+i]), + tal_hex(msg, txs[1+i]->output_witscripts[0]->ptr), type_to_string(msg, struct pubkey, &remote_htlckey)); } diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 02847fdcc..39afc7d6a 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -222,7 +222,6 @@ static bool sum_offered_msatoshis(struct amount_msat *total, } static void add_htlcs(struct bitcoin_tx ***txs, - const u8 ***wscripts, const struct htlc **htlcmap, const struct channel *channel, const struct keyset *keyset, @@ -238,7 +237,7 @@ 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; - u8 *wscript; + struct witscript *witscript; if (!htlc) continue; @@ -250,29 +249,22 @@ static void add_htlcs(struct bitcoin_tx ***txs, channel->config[!side].to_self_delay, feerate_per_kw, keyset); - wscript = bitcoin_wscript_htlc_offer(*wscripts, - &keyset->self_htlc_key, - &keyset->other_htlc_key, - &htlc->rhash, - &keyset->self_revocation_key); } else { tx = htlc_success_tx(*txs, chainparams, &txid, i, htlc->amount, channel->config[!side].to_self_delay, feerate_per_kw, keyset); - wscript = bitcoin_wscript_htlc_receive(*wscripts, - &htlc->expiry, - &keyset->self_htlc_key, - &keyset->other_htlc_key, - &htlc->rhash, - &keyset->self_revocation_key); } + /* Re-use the previously-generated witness script */ + witscript = (*txs)[0]->output_witscripts[i]; + tx->output_witscripts[0] = + tal(tx->output_witscripts, struct witscript); + tx->output_witscripts[0]->ptr = + tal_dup_arr(tx->output_witscripts[0], u8, + witscript->ptr, tal_count(witscript->ptr), 0); /* Append to array. */ - assert(tal_count(*txs) == tal_count(*wscripts)); - - tal_arr_expand(wscripts, wscript); tal_arr_expand(txs, tx); } } @@ -280,7 +272,7 @@ static void add_htlcs(struct bitcoin_tx ***txs, /* FIXME: We could cache these. */ struct bitcoin_tx **channel_txs(const tal_t *ctx, const struct htlc ***htlcmap, - const u8 ***wscripts, + const u8 **funding_wscript, const struct channel *channel, const struct pubkey *per_commitment_point, u64 commitment_number, @@ -310,12 +302,13 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, channel->view[side].owed[!side], committed, htlcmap, commitment_number ^ channel->commitment_number_obscurer, side); - *wscripts = tal_arr(ctx, const u8 *, 1); - (*wscripts)[0] = bitcoin_redeem_2of2(*wscripts, - &channel->funding_pubkey[side], - &channel->funding_pubkey[!side]); + /* Generating and saving witness script required to spend + * the funding output */ + *funding_wscript = bitcoin_redeem_2of2(*funding_wscript, + &channel->funding_pubkey[side], + &channel->funding_pubkey[!side]); - add_htlcs(&txs, wscripts, *htlcmap, channel, &keyset, side); + add_htlcs(&txs, *htlcmap, channel, &keyset, side); tal_free(committed); return txs; diff --git a/channeld/full_channel.h b/channeld/full_channel.h index 216a69209..3485e039a 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -50,7 +50,7 @@ struct channel *new_full_channel(const tal_t *ctx, * @ctx: tal context to allocate return value from. * @channel: The channel to evaluate * @htlc_map: Pointer to htlcs for each tx output (allocated off @ctx). - * @wscripts: Pointer to array of wscript for each tx returned (alloced off @ctx) + * @funding_wscript: Pointer to wscript for the funding tx output * @per_commitment_point: Per-commitment point to determine keys * @commitment_number: The index of this commitment. * @side: which side to get the commitment transaction for @@ -61,7 +61,7 @@ struct channel *new_full_channel(const tal_t *ctx, */ struct bitcoin_tx **channel_txs(const tal_t *ctx, const struct htlc ***htlcmap, - const u8 ***wscripts, + const u8 **funding_wscript, const struct channel *channel, const struct pubkey *per_commitment_point, u64 commitment_number, diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 63dbaec3e..3c1564511 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -355,7 +355,7 @@ int main(void) struct channel_config *local_config, *remote_config; struct amount_msat to_local, to_remote; const struct htlc **htlc_map, **htlcs; - const u8 *funding_wscript, **wscripts; + const u8 *funding_wscript, *funding_wscript_alt; size_t i; wally_init(0); @@ -521,16 +521,15 @@ int main(void) NULL, &htlc_map, 0x2bb038521914 ^ 42, LOCAL); txs = channel_txs(tmpctx, - &htlc_map, &wscripts, + &htlc_map, &funding_wscript_alt, lchannel, &local_per_commitment_point, 42, LOCAL); assert(tal_count(txs) == 1); assert(tal_count(htlc_map) == 2); - assert(tal_count(wscripts) == 1); - assert(scripteq(wscripts[0], funding_wscript)); + assert(scripteq(funding_wscript_alt, funding_wscript)); tx_must_be_eq(txs[0], raw_tx); txs2 = channel_txs(tmpctx, - &htlc_map, &wscripts, + &htlc_map, &funding_wscript, rchannel, &local_per_commitment_point, 42, REMOTE); txs_must_be_eq(txs, txs2); @@ -557,10 +556,10 @@ int main(void) assert(lchannel->view[REMOTE].owed[REMOTE].millisatoshis == rchannel->view[LOCAL].owed[LOCAL].millisatoshis); - txs = channel_txs(tmpctx, &htlc_map, &wscripts, + txs = channel_txs(tmpctx, &htlc_map, &funding_wscript, lchannel, &local_per_commitment_point, 42, LOCAL); assert(tal_count(txs) == 1); - txs2 = channel_txs(tmpctx, &htlc_map, &wscripts, + txs2 = channel_txs(tmpctx, &htlc_map, &funding_wscript, rchannel, &local_per_commitment_point, 42, REMOTE); txs_must_be_eq(txs, txs2); @@ -575,10 +574,10 @@ int main(void) assert(lchannel->view[REMOTE].owed[REMOTE].millisatoshis == rchannel->view[LOCAL].owed[LOCAL].millisatoshis); - txs = channel_txs(tmpctx, &htlc_map, &wscripts, + txs = channel_txs(tmpctx, &htlc_map, &funding_wscript, lchannel, &local_per_commitment_point, 42, LOCAL); assert(tal_count(txs) == 6); - txs2 = channel_txs(tmpctx, &htlc_map, &wscripts, + txs2 = channel_txs(tmpctx, &htlc_map, &funding_wscript, rchannel, &local_per_commitment_point, 42, REMOTE); txs_must_be_eq(txs, txs2); @@ -644,12 +643,12 @@ int main(void) to_local, to_remote, htlcs, &htlc_map, 0x2bb038521914 ^ 42, LOCAL); - txs = channel_txs(tmpctx, &htlc_map, &wscripts, + txs = channel_txs(tmpctx, &htlc_map, &funding_wscript, lchannel, &local_per_commitment_point, 42, LOCAL); tx_must_be_eq(txs[0], raw_tx); - txs2 = channel_txs(tmpctx, &htlc_map, &wscripts, + txs2 = channel_txs(tmpctx, &htlc_map, &funding_wscript, rchannel, &local_per_commitment_point, 42, REMOTE); txs_must_be_eq(txs, txs2); diff --git a/common/htlc_tx.c b/common/htlc_tx.c index d3669b174..f4844b09e 100644 --- a/common/htlc_tx.c +++ b/common/htlc_tx.c @@ -65,6 +65,12 @@ static struct bitcoin_tx *htlc_tx(const tal_t *ctx, bitcoin_tx_finalize(tx); assert(bitcoin_tx_check(tx)); + tx->output_witscripts[0] = + tal(tx->output_witscripts, struct witscript); + tx->output_witscripts[0]->ptr = + tal_dup_arr(tx->output_witscripts[0], u8, + wscript, tal_count(wscript), 0); + tal_free(wscript); return tx; diff --git a/devtools/mkcommit.c b/devtools/mkcommit.c index 1bbff00f4..076e55d3c 100644 --- a/devtools/mkcommit.c +++ b/devtools/mkcommit.c @@ -259,7 +259,7 @@ int main(int argc, char *argv[]) struct bitcoin_tx **local_txs, **remote_txs; enum side fee_payer; u8 **witness; - const u8 **wscripts; + const u8 *funding_wscript; struct channel *channel; struct existing_htlc **htlcs = tal_arr(NULL, struct existing_htlc *, 0); const struct htlc **htlcmap; @@ -393,15 +393,11 @@ int main(int argc, char *argv[]) cast_const2(const struct existing_htlc **, htlcs))) errx(1, "Cannot add HTLCs"); - u8 *funding_wscript = bitcoin_redeem_2of2(NULL, - &funding_localkey, - &funding_remotekey); - /* Create the local commitment_tx */ if (!per_commit_point(&localseed, &local_per_commit_point, commitnum)) errx(1, "Bad deriving local per-commitment-point"); - local_txs = channel_txs(NULL, &htlcmap, &wscripts, channel, + local_txs = channel_txs(NULL, &htlcmap, &funding_wscript, channel, &local_per_commit_point, commitnum, LOCAL); printf("## local_commitment\n" @@ -477,14 +473,17 @@ int main(int argc, char *argv[]) local_txs[1+i]->input_amounts[0] = tal_dup(local_txs[1+i], struct amount_sat, &amt); - printf("# wscript: %s\n", tal_hex(NULL, wscripts[1+i])); + printf("# wscript: %s\n", tal_hex(NULL, local_txs[1+i]->output_witscripts[1+i]->ptr)); - bitcoin_tx_hash_for_sig(local_txs[1+i], 0, wscripts[1+i], + bitcoin_tx_hash_for_sig(local_txs[1+i], 0, + local_txs[1+i]->output_witscripts[1+i]->ptr, SIGHASH_ALL, &hash); - sign_tx_input(local_txs[1+i], 0, NULL, wscripts[1+i], + sign_tx_input(local_txs[1+i], 0, NULL, + local_txs[1+i]->output_witscripts[1+i]->ptr, &local_htlc_privkey, &local_htlc_pubkey, SIGHASH_ALL, &local_htlc_sig); - sign_tx_input(local_txs[1+i], 0, NULL, wscripts[1+i], + sign_tx_input(local_txs[1+i], 0, NULL, + local_txs[1+i]->output_witscripts[1+i]->ptr, &remote_htlc_privkey, &remote_htlc_pubkey, SIGHASH_ALL, &remote_htlc_sig); printf("localsig_on_local output %zu: %s\n", @@ -496,13 +495,13 @@ int main(int argc, char *argv[]) witness = bitcoin_witness_htlc_timeout_tx(NULL, &local_htlc_sig, &remote_htlc_sig, - wscripts[1+i]); + local_txs[1+i]->output_witscripts[1+i]->ptr); else witness = bitcoin_witness_htlc_success_tx(NULL, &local_htlc_sig, &remote_htlc_sig, preimage_of(&htlcmap[i]->rhash, cast_const2(const struct existing_htlc **, htlcs)), - wscripts[1+i]); + local_txs[1+i]->output_witscripts[1+i]->ptr); bitcoin_tx_input_set_witness(local_txs[1+i], 0, witness); printf("htlc tx for output %zu: %s\n", i, tal_hex(NULL, linearize_tx(NULL, local_txs[1+i]))); @@ -512,7 +511,7 @@ int main(int argc, char *argv[]) /* Create the remote commitment tx */ if (!per_commit_point(&remoteseed, &remote_per_commit_point, commitnum)) errx(1, "Bad deriving remote per-commitment-point"); - remote_txs = channel_txs(NULL, &htlcmap, &wscripts, channel, + remote_txs = channel_txs(NULL, &htlcmap, &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); @@ -589,13 +588,16 @@ int main(int argc, char *argv[]) remote_txs[1+i]->input_amounts[0] = tal_dup(remote_txs[1+i], struct amount_sat, &amt); - printf("# wscript: %s\n", tal_hex(NULL, wscripts[1+i])); - bitcoin_tx_hash_for_sig(remote_txs[1+i], 0, wscripts[1+i], + printf("# wscript: %s\n", tal_hex(NULL, remote_txs[1+i]->output_witscripts[1+i]->ptr)); + bitcoin_tx_hash_for_sig(remote_txs[1+i], 0, + remote_txs[1+i]->output_witscripts[1+i]->ptr, SIGHASH_ALL, &hash); - sign_tx_input(remote_txs[1+i], 0, NULL, wscripts[1+i], + sign_tx_input(remote_txs[1+i], 0, NULL, + remote_txs[1+i]->output_witscripts[1+i]->ptr, &local_htlc_privkey, &local_htlc_pubkey, SIGHASH_ALL, &local_htlc_sig); - sign_tx_input(remote_txs[1+i], 0, NULL, wscripts[1+i], + sign_tx_input(remote_txs[1+i], 0, NULL, + remote_txs[1+i]->output_witscripts[1+i]->ptr, &remote_htlc_privkey, &remote_htlc_pubkey, SIGHASH_ALL, &remote_htlc_sig); printf("localsig_on_remote output %zu: %s\n", @@ -607,13 +609,13 @@ int main(int argc, char *argv[]) witness = bitcoin_witness_htlc_timeout_tx(NULL, &remote_htlc_sig, &local_htlc_sig, - wscripts[1+i]); + remote_txs[1+i]->output_witscripts[1+i]->ptr); else witness = bitcoin_witness_htlc_success_tx(NULL, &remote_htlc_sig, &local_htlc_sig, preimage_of(&htlcmap[i]->rhash, cast_const2(const struct existing_htlc **, htlcs)), - wscripts[1+i]); + remote_txs[1+i]->output_witscripts[1+i]->ptr); bitcoin_tx_input_set_witness(remote_txs[1+i], 0, witness); printf("htlc tx for output %zu: %s\n", i, tal_hex(NULL, linearize_tx(NULL, remote_txs[1+i]))); diff --git a/external/libwally-core b/external/libwally-core index ae84c2651..0041b0464 160000 --- a/external/libwally-core +++ b/external/libwally-core @@ -1 +1 @@ -Subproject commit ae84c26519b6c513332c19bc183dc0b584f4bf33 +Subproject commit 0041b04644687e0aac7c1611fe31c810babac66d